@whoz-oss/coday-server 0.99.0 → 0.101.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/server.js +9 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whoz-oss/coday-server",
3
- "version": "0.99.0",
3
+ "version": "0.101.0",
4
4
  "repository": "https://github.com/whoz-oss/coday",
5
5
  "type": "module",
6
6
  "main": "server/server.js",
package/server.js CHANGED
@@ -306,8 +306,8 @@ ${a}\r
306
306
  }
307
307
 
308
308
  More details: https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md#removed-logprovider-and-loglevel-options
309
- `)),t}function UZ(r){let e=r.logProvider&&r.logProvider();return e&&(r.logger=e),(0,ixt.getLogger)(r)}});var Txe=_(HZ=>{"use strict";Object.defineProperty(HZ,"__esModule",{value:!0});HZ.legacyCreateProxyMiddleware=lxt;var sxt=MZ(),cxt=vl(),uxt=Axe(),Cxe=cxt.Debug.extend("legacy-create-proxy-middleware");function lxt(r,e){Cxe("init");let t=(0,uxt.legacyOptionsAdapter)(r,e),n=(0,sxt.createProxyMiddleware)(t);return Cxe("add marker for patching req.url (old behavior)"),n.__LEGACY_HTTP_PROXY_MIDDLEWARE__=!0,n}});var Pxe=_(aP=>{"use strict";Object.defineProperty(aP,"__esModule",{value:!0});aP.legacyCreateProxyMiddleware=void 0;var fxt=Txe();Object.defineProperty(aP,"legacyCreateProxyMiddleware",{enumerable:!0,get:function(){return fxt.legacyCreateProxyMiddleware}})});var Dxe=_(i3=>{"use strict";var pxt=i3&&i3.__createBinding||(Object.create?(function(r,e,t,n){n===void 0&&(n=t);var i=Object.getOwnPropertyDescriptor(e,t);(!i||("get"in i?!e.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(r,n,i)}):(function(r,e,t,n){n===void 0&&(n=t),r[n]=e[t]})),dxt=i3&&i3.__exportStar||function(r,e){for(var t in r)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&pxt(e,r,t)};Object.defineProperty(i3,"__esModule",{value:!0});dxt(Pxe(),i3)});var WZ=_(uu=>{"use strict";var hxt=uu&&uu.__createBinding||(Object.create?(function(r,e,t,n){n===void 0&&(n=t);var i=Object.getOwnPropertyDescriptor(e,t);(!i||("get"in i?!e.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(r,n,i)}):(function(r,e,t,n){n===void 0&&(n=t),r[n]=e[t]})),oP=uu&&uu.__exportStar||function(r,e){for(var t in r)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&hxt(e,r,t)};Object.defineProperty(uu,"__esModule",{value:!0});oP(MZ(),uu);oP(kxe(),uu);oP(pZ(),uu);oP(Dxe(),uu)});var pP=vr(qte(),1);import bl from"path";import sP from"fs";import*as C7e from"path";var Fe=class{commandWord;description;requiredIntegrations=[];isInternal=!1;constructor(e){this.commandWord=e.commandWord,this.description=e.description,this.requiredIntegrations=e.requiredIntegrations||[],this.isInternal=!!e?.isInternal}getSubCommand(e){return e.slice(this.commandWord.length).trim()}accept(e,t){return!!e&&e.toLowerCase().startsWith(this.commandWord)}};function VI(r,e=80){if(r.length<=e)return r;try{if(r.trim().startsWith("{")||r.trim().startsWith("[")){let t=JSON.parse(r),n=JSON.stringify(t);return n.length<=e?n:n.substring(0,e)+`...(${n.length} chars)`}}catch{}return r.substring(0,e)+"..."}var Xn=class{constructor(e,t){this.type=t;if(e.timestamp)this.timestamp=e.timestamp;else{let n=Math.random().toString(36).substring(2,7);this.timestamp=`${new Date().toISOString()}-${n}`}this.parentKey=e.parentKey,this.threadId=e.threadId,this.length=0}timestamp;parentKey;static type;length;threadId;get date(){let e=this.timestamp.lastIndexOf("-");if(e>0){let t=this.timestamp.substring(e+1);if(t.length===5&&/^[a-z0-9]+$/.test(t))return new Date(this.timestamp.substring(0,e))}return new Date(this.timestamp)}},av=class extends Xn{invite;constructor(e,t){super(e,t),this.invite=e.invite}buildAnswer(e){return new _r({answer:e,parentKey:this.timestamp,invite:this.invite})}},O3=class r extends Xn{static type="heartbeat";constructor(e){super(e,r.type)}},Di=class r extends av{defaultValue;static type="invite";constructor(e){super(e,r.type),this.defaultValue=e.defaultValue}},zte="InviteEventDefault",_r=class r extends Xn{answer;invite;static type="answer";constructor(e){super(e,r.type),this.answer=e.answer??"No answer",this.invite=e.invite}},vu=class r extends Xn{speaker;text;static type="text";constructor(e){super(e,r.type),this.speaker=e.speaker,this.text=e.text}},Il=class r extends Xn{chunk;static type="text_chunk";constructor(e){super(e,r.type),this.chunk=e.chunk,this.length=this.chunk.length}},$3=class r extends Xn{warning;static type="warn";constructor(e){super(e,r.type),this.warning=e.warning}},$a=class r extends Xn{error;static type="error";constructor(e){super(e,r.type),this.error=e.error}},Ii=class r extends av{options;optionalQuestion;allowFreeText;static type="choice";constructor(e){super(e,r.type),this.options=e.options,this.optionalQuestion=e.optionalQuestion,this.allowFreeText=e.allowFreeText??!1}},ln=class r extends Xn{toolRequestId;name;args;static type="tool_request";constructor(e){super(e,r.type),this.toolRequestId=e.toolRequestId??this.timestamp,this.name=e.name,this.args=e.args,this.length=this.args.length+this.name.length+this.toolRequestId.length+20}buildResponse(e){return new kn({output:e,toolRequestId:this.toolRequestId,parentKey:this.timestamp})}toSingleLineString(e=50){let t=VI(this.args,e);return`\u{1F527} ${this.name}(${t})`}},kn=class r extends Xn{toolRequestId;output;static type="tool_response";constructor(e){if(super(e,r.type),this.toolRequestId=e.toolRequestId||this.timestamp||new Date().toISOString(),this.output=e.output,typeof this.output=="string")this.length=this.output.length+this.toolRequestId.length+20;else if(this.output.type==="text")this.length=this.output.content.length+this.toolRequestId.length+20;else if(this.output.type==="image"){let t=(this.output.width??0)*(this.output.height??0)/750;this.length=(t?t*3.5:this.output.content.length)+this.toolRequestId.length+20}else this.length=this.toolRequestId.length+20}getTextOutput(){return typeof this.output=="string"?this.output:this.output.type==="text"?this.output.content:this.output.type==="image"?`[Image: ${this.output.mimeType}]`:""}toSingleLineString(e=50){let t=this.getTextOutput(),n=VI(t,e),i=typeof this.output!="string"&&this.output.type==="image"?" [image]":"";return`\u2B91 ${n}${i}`}},qf=class r extends Xn{static type="thinking";static debounce=5e3;constructor(e){super(e,r.type)}},da=class r extends Xn{summary;static type="summary";constructor(e){super(e,r.type),this.summary=e.summary,this.length=this.summary.length}toSingleLineString(e=80){return`\u{1F4CB} Summary: ${VI(this.summary,e)}`}},Rt=class r extends Xn{role;name;content;static type="message";constructor(e){super(e,r.type),this.role=e.role,this.name=e.name,this.content=e.content,this.length=this.content.map(t=>{if(t.type==="text")return t.content.length;if(t.type==="image"){let n=(t.width||0)*(t.height||0)/750;return n?n*3.5:t.content.length}return 0}).reduce((t,n)=>t+n,0)}getTextContent(){return this.content.filter(e=>e.type==="text").map(e=>e.content).join(`
310
- `)}},uc=class r extends Xn{threadId;name;summary;users;static type="thread_update";constructor(e){super(e,r.type),this.threadId=e.threadId,this.name=e.name,this.summary=e.summary,this.users=e.users}},lc=class r extends Xn{filename;operation;size;mimeType;static type="file";constructor(e){super(e,r.type),this.filename=e.filename,this.operation=e.operation,this.size=e.size,this.mimeType=e.mimeType}toSingleLineString(){let e=this.operation==="created"?"\u{1F4C4}":this.operation==="updated"?"\u{1F4DD}":"\u{1F5D1}\uFE0F",t=this.size?` (${(this.size/1024).toFixed(1)} KB)`:"";return`${e} ${this.operation}: ${this.filename}${t}`}},Ol=class r extends Xn{authUrl;state;integrationName;static type="oauth_request";constructor(e){super(e,r.type),this.authUrl=e.authUrl,this.state=e.state,this.integrationName=e.integrationName}},fo=class r extends Xn{subThreadId;agentName;static type="delegation";constructor(e){super(e,r.type),this.subThreadId=e.subThreadId,this.agentName=e.agentName}},ov=class r extends Xn{code;state;integrationName;error;errorDescription;static type="oauth_callback";constructor(e){super(e,r.type),this.code=e.code,this.state=e.state,this.integrationName=e.integrationName,this.error=e.error,this.errorDescription=e.errorDescription}},KDe={[Rt.type]:Rt,[_r.type]:_r,[Ii.type]:Ii,[fo.type]:fo,[$a.type]:$a,[O3.type]:O3,[Di.type]:Di,[ln.type]:ln,[kn.type]:kn,[vu.type]:vu,[Il.type]:Il,[qf.type]:qf,[$3.type]:$3,[uc.type]:uc,[da.type]:da,[lc.type]:lc,[Ol.type]:Ol,[ov.type]:ov};function sv(r){let e=KDe[r.type];return e?new e(r):void 0}var cv=class{constructor(e,t,n,i=!1){this.aiClient=t;this.tools=n;this.internal=i;this.name=e.name,this.description=e.description,this.definition={...e}}name;description;definition;get systemInstructions(){return this.definition.instructions}getAiClient(){return this.aiClient}async run(e,t){let n=e.trim(),i=new _r({answer:n});return t.addAnswerEvent(i),await this.aiClient.run(this,t)}};var uv={name:"Coday",description:"Default fallback agent with neutral character and access to all tools",instructions:`
309
+ `)),t}function UZ(r){let e=r.logProvider&&r.logProvider();return e&&(r.logger=e),(0,ixt.getLogger)(r)}});var Txe=_(HZ=>{"use strict";Object.defineProperty(HZ,"__esModule",{value:!0});HZ.legacyCreateProxyMiddleware=lxt;var sxt=MZ(),cxt=vl(),uxt=Axe(),Cxe=cxt.Debug.extend("legacy-create-proxy-middleware");function lxt(r,e){Cxe("init");let t=(0,uxt.legacyOptionsAdapter)(r,e),n=(0,sxt.createProxyMiddleware)(t);return Cxe("add marker for patching req.url (old behavior)"),n.__LEGACY_HTTP_PROXY_MIDDLEWARE__=!0,n}});var Pxe=_(aP=>{"use strict";Object.defineProperty(aP,"__esModule",{value:!0});aP.legacyCreateProxyMiddleware=void 0;var fxt=Txe();Object.defineProperty(aP,"legacyCreateProxyMiddleware",{enumerable:!0,get:function(){return fxt.legacyCreateProxyMiddleware}})});var Dxe=_(i3=>{"use strict";var pxt=i3&&i3.__createBinding||(Object.create?(function(r,e,t,n){n===void 0&&(n=t);var i=Object.getOwnPropertyDescriptor(e,t);(!i||("get"in i?!e.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(r,n,i)}):(function(r,e,t,n){n===void 0&&(n=t),r[n]=e[t]})),dxt=i3&&i3.__exportStar||function(r,e){for(var t in r)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&pxt(e,r,t)};Object.defineProperty(i3,"__esModule",{value:!0});dxt(Pxe(),i3)});var WZ=_(uu=>{"use strict";var hxt=uu&&uu.__createBinding||(Object.create?(function(r,e,t,n){n===void 0&&(n=t);var i=Object.getOwnPropertyDescriptor(e,t);(!i||("get"in i?!e.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(r,n,i)}):(function(r,e,t,n){n===void 0&&(n=t),r[n]=e[t]})),oP=uu&&uu.__exportStar||function(r,e){for(var t in r)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&hxt(e,r,t)};Object.defineProperty(uu,"__esModule",{value:!0});oP(MZ(),uu);oP(kxe(),uu);oP(pZ(),uu);oP(Dxe(),uu)});var pP=vr(qte(),1);import bl from"path";import sP from"fs";import*as C7e from"path";var Fe=class{commandWord;description;requiredIntegrations=[];isInternal=!1;constructor(e){this.commandWord=e.commandWord,this.description=e.description,this.requiredIntegrations=e.requiredIntegrations||[],this.isInternal=!!e?.isInternal}getSubCommand(e){return e.slice(this.commandWord.length).trim()}accept(e,t){return!!e&&e.toLowerCase().startsWith(this.commandWord)}};function VI(r,e=80){if(r.length<=e)return r;try{if(r.trim().startsWith("{")||r.trim().startsWith("[")){let t=JSON.parse(r),n=JSON.stringify(t);return n.length<=e?n:n.substring(0,e)+`...(${n.length} chars)`}}catch{}return r.substring(0,e)+"..."}var Xn=class{constructor(e,t){this.type=t;if(e.timestamp)this.timestamp=e.timestamp;else{let n=Math.random().toString(36).substring(2,7);this.timestamp=`${new Date().toISOString()}-${n}`}this.parentKey=e.parentKey,this.threadId=e.threadId,this.length=0}timestamp;parentKey;static type;length;threadId;get date(){let e=this.timestamp.lastIndexOf("-");if(e>0){let t=this.timestamp.substring(e+1);if(t.length===5&&/^[a-z0-9]+$/.test(t))return new Date(this.timestamp.substring(0,e))}return new Date(this.timestamp)}},av=class extends Xn{invite;constructor(e,t){super(e,t),this.invite=e.invite}buildAnswer(e){return new _r({answer:e,parentKey:this.timestamp,invite:this.invite})}},O3=class r extends Xn{static type="heartbeat";constructor(e){super(e,r.type)}},Di=class r extends av{defaultValue;static type="invite";constructor(e){super(e,r.type),this.defaultValue=e.defaultValue}},zte="InviteEventDefault",_r=class r extends Xn{answer;invite;name;static type="answer";constructor(e){super(e,r.type),this.answer=e.answer??"No answer",this.invite=e.invite,this.name=e.name}},vu=class r extends Xn{speaker;text;static type="text";constructor(e){super(e,r.type),this.speaker=e.speaker,this.text=e.text}},Il=class r extends Xn{chunk;static type="text_chunk";constructor(e){super(e,r.type),this.chunk=e.chunk,this.length=this.chunk.length}},$3=class r extends Xn{warning;static type="warn";constructor(e){super(e,r.type),this.warning=e.warning}},$a=class r extends Xn{error;static type="error";constructor(e){super(e,r.type),this.error=e.error}},Ii=class r extends av{options;optionalQuestion;allowFreeText;static type="choice";constructor(e){super(e,r.type),this.options=e.options,this.optionalQuestion=e.optionalQuestion,this.allowFreeText=e.allowFreeText??!1}},ln=class r extends Xn{toolRequestId;name;args;static type="tool_request";constructor(e){super(e,r.type),this.toolRequestId=e.toolRequestId??this.timestamp,this.name=e.name,this.args=e.args,this.length=this.args.length+this.name.length+this.toolRequestId.length+20}buildResponse(e){return new kn({output:e,toolRequestId:this.toolRequestId,parentKey:this.timestamp})}toSingleLineString(e=50){let t=VI(this.args,e);return`\u{1F527} ${this.name}(${t})`}},kn=class r extends Xn{toolRequestId;output;static type="tool_response";constructor(e){if(super(e,r.type),this.toolRequestId=e.toolRequestId||this.timestamp||new Date().toISOString(),this.output=e.output,typeof this.output=="string")this.length=this.output.length+this.toolRequestId.length+20;else if(this.output.type==="text")this.length=this.output.content.length+this.toolRequestId.length+20;else if(this.output.type==="image"){let t=(this.output.width??0)*(this.output.height??0)/750;this.length=(t?t*3.5:this.output.content.length)+this.toolRequestId.length+20}else this.length=this.toolRequestId.length+20}getTextOutput(){return typeof this.output=="string"?this.output:this.output.type==="text"?this.output.content:this.output.type==="image"?`[Image: ${this.output.mimeType}]`:""}toSingleLineString(e=50){let t=this.getTextOutput(),n=VI(t,e),i=typeof this.output!="string"&&this.output.type==="image"?" [image]":"";return`\u2B91 ${n}${i}`}},qf=class r extends Xn{static type="thinking";static debounce=5e3;constructor(e){super(e,r.type)}},da=class r extends Xn{summary;static type="summary";constructor(e){super(e,r.type),this.summary=e.summary,this.length=this.summary.length}toSingleLineString(e=80){return`\u{1F4CB} Summary: ${VI(this.summary,e)}`}},Rt=class r extends Xn{role;name;content;static type="message";constructor(e){super(e,r.type),this.role=e.role,this.name=e.name,this.content=e.content,this.length=this.content.map(t=>{if(t.type==="text")return t.content.length;if(t.type==="image"){let n=(t.width||0)*(t.height||0)/750;return n?n*3.5:t.content.length}return 0}).reduce((t,n)=>t+n,0)}getTextContent(){return this.content.filter(e=>e.type==="text").map(e=>e.content).join(`
310
+ `)}},uc=class r extends Xn{threadId;name;summary;users;static type="thread_update";constructor(e){super(e,r.type),this.threadId=e.threadId,this.name=e.name,this.summary=e.summary,this.users=e.users}},lc=class r extends Xn{filename;operation;size;mimeType;static type="file";constructor(e){super(e,r.type),this.filename=e.filename,this.operation=e.operation,this.size=e.size,this.mimeType=e.mimeType}toSingleLineString(){let e=this.operation==="created"?"\u{1F4C4}":this.operation==="updated"?"\u{1F4DD}":"\u{1F5D1}\uFE0F",t=this.size?` (${(this.size/1024).toFixed(1)} KB)`:"";return`${e} ${this.operation}: ${this.filename}${t}`}},Ol=class r extends Xn{authUrl;state;integrationName;static type="oauth_request";constructor(e){super(e,r.type),this.authUrl=e.authUrl,this.state=e.state,this.integrationName=e.integrationName}},fo=class r extends Xn{subThreadId;agentName;static type="delegation";constructor(e){super(e,r.type),this.subThreadId=e.subThreadId,this.agentName=e.agentName}},ov=class r extends Xn{code;state;integrationName;error;errorDescription;static type="oauth_callback";constructor(e){super(e,r.type),this.code=e.code,this.state=e.state,this.integrationName=e.integrationName,this.error=e.error,this.errorDescription=e.errorDescription}},KDe={[Rt.type]:Rt,[_r.type]:_r,[Ii.type]:Ii,[fo.type]:fo,[$a.type]:$a,[O3.type]:O3,[Di.type]:Di,[ln.type]:ln,[kn.type]:kn,[vu.type]:vu,[Il.type]:Il,[qf.type]:qf,[$3.type]:$3,[uc.type]:uc,[da.type]:da,[lc.type]:lc,[Ol.type]:Ol,[ov.type]:ov};function sv(r){let e=KDe[r.type];return e?new e(r):void 0}var cv=class{constructor(e,t,n,i=!1){this.aiClient=t;this.tools=n;this.internal=i;this.name=e.name,this.description=e.description,this.definition={...e}}name;description;definition;get systemInstructions(){return this.definition.instructions}getAiClient(){return this.aiClient}async run(e,t,n){let i=e.trim(),a=new _r({answer:i,name:n??t.username});return t.addAnswerEvent(a),await this.aiClient.run(this,t)}};var uv={name:"Coday",description:"Default fallback agent with neutral character and access to all tools",instructions:`
311
311
  You are Coday, an AI assistant designed for interactive usage by users through various chat-like interfaces.
312
312
 
313
313
  When other agents are available, you should redirect the user request to the appropriate agent, given the topic.
@@ -594,7 +594,7 @@ Proceeding will:
594
594
  Stopping will:
595
595
  - End the current run
596
596
  - Clear pending commands
597
- - Return to prompt`;if(await this.interactor.chooseOption(["proceed","stop"],u,"What do you want to do?")==="stop")return i.runStatus="STOPPED",!1;a.price>0?(a.priceThreshold*=2,this.interactor.displayText(`Cost threshold increased to ${a.priceThreshold.toFixed(2)}`)):(a.iterationsThreshold*=2,this.interactor.displayText(`Iteration threshold increased to ${a.iterationsThreshold}`))}return await Promise.all(t.map(async o=>{let s;try{o.threadId=i.id,this.interactor.sendEvent(o),s=await n.tools.run(o,i)}catch(c){let u=`Error running tool ${o.name}: ${c}`;console.error(u),s=o.buildResponse(u)}s.threadId=i.id,this.interactor.sendEvent(s),i.addToolRequests(n.name,[o]),i.addToolResponseEvents([s])})),this.shouldProceed(i)}handleError(e,t,n){let i=`${n} error occurred`;if(e instanceof Error){i=`${n} error: ${e.message}`;let a=e;a.status===401||a.statusCode===401?i=`${n} authentication failed. Please check your API key.`:a.status===429||a.statusCode===429?i=`${n} rate limit exceeded. Please try again later.`:a.code==="ECONNREFUSED"||a.code==="ENOTFOUND"||a.code==="ETIMEDOUT"?i=`Network error connecting to ${n}. Please check your internet connection.`:e.message?.includes("Max tokens")&&(i=`${n} response exceeded token limit. Try simplifying your request or splitting it into smaller parts.`)}console.error(`${n} client error:`,e),t.next(new $a({error:e instanceof Error?e:new Error(i)})),this.interactor.displayText(`\u26A0\uFE0F ${i}`)}shouldProceed(e){return e.runStatus==="RUNNING"&&!this.killed}showAgentAndUsage(e,t,n,i){let a=`\u{1F916} ${e.name} | ${t} - ${n} `;if(!i.usage)return;let o=`Loop${i.usage.iterations>1?"s":""}: ${i.usage.iterations} | `,s=`Input: ${i.usage.input}, Output: ${i.usage.output} | `,c=`Cache write: ${i.usage.cache_write}, Cache read: ${i.usage.cache_read}`,u=`\u{1F3C3}${i.usage.price.toFixed(3)} / \u{1F9F5}${i.price.toFixed(3)}`;this.interactor.sendEvent(new vu({text:a+u,threadId:i.id})),this.interactor.debug(o+s+c)}getModel(e){let t=e.definition.modelName?.toLowerCase(),n=this.models.find(i=>i.alias?.toLowerCase()===t);return n||this.models.find(i=>i.name.toLowerCase()===t)}supportsModel(e){return this.models.some(t=>t.name.toLowerCase()===e||t?.alias?.toLowerCase()===e)}returnError(e){return(0,Uie.of)(new $a({error:e}))}logAgentUsage(e,t,n,i){let a=i?.usage?.input??0,o=i?.usage?.output??0,s=a+o;this.logger?.logAgentUsage(i?.username??this.username??"no_username",e.name,t,n,this.name,a,o,s)}};var Vt=class{constructor(e,t,n){this.interactor=e;this.name=t,this.config=n}tools=[];name;config;async kill(){}async getTools(e,t,n){return this.tools=await this.buildTools(e,n),this.tools.filter(i=>{if(!t||!t.length)return!0;let a=i.function.name.split("__")[1]??i.function.name;return t.includes(a)})}};var k0=class r{constructor(e,t){this.project=e;this.username=t}commandQueue=[];clearCommands(){this.commandQueue=[]}oneshot=!1;fileReadOnly=!1;threadFilesRoot;stackDepth=10;data={};aiThread;addCommands(...e){this.commandQueue.unshift(...e)}getFirstCommand(){return this.commandQueue.shift()}getSubContext(...e){let t=new r(this.project,this.username);return t.oneshot=this.oneshot,t.fileReadOnly=this.fileReadOnly,t.addCommands(...e),t.stackDepth=this.stackDepth-1,t}cloneWithoutCommands(){let e=new r(this.project,this.username);return e.oneshot=this.oneshot,e.fileReadOnly=this.fileReadOnly,e.stackDepth=this.stackDepth,e.data=this.data,e}};var cZe=["project","user"],Ri=class{static validate(e){if(!cZe.includes(e))throw new Error(`Invalid configuration level: ${e}. Only PROJECT and USER levels are allowed.`)}};var Bie=[".pdf",".doc",".docx",".odt",".rtf",".xls",".xlsx",".ods",".csv",".tsv",".txt",".md",".markdown",".rst",".json",".xml",".yaml",".yml",".toml",".html",".htm",".css",".svg",".ts",".tsx",".js",".jsx",".py",".java",".cpp",".c",".h",".hpp",".cs",".go",".rs",".rb",".php",".swift",".kt",".scala",".sh",".bash",".sql",".env",".properties",".ini",".conf",".config",".log"];function $x(r){let e=r.toLowerCase().substring(r.lastIndexOf("."));return Bie.includes(e)}function Hie(){return Bie.join(", ")}var jx=class{constructor(e){this.tools=e;this.charLength=JSON.stringify(e).length}charLength=0;getTools(){return[...this.tools]}async run(e,t){let n=this.tools.find(c=>c.function.name===e.name);if(!n)throw new Error(`Tool '${e.name}' not found`);let i,a=n.function.function,o=JSON.parse(e.args),s=Array.isArray(o)?o:[o];if(i=await a(...s,t),i||(i=`Tool function ${e.name} finished without error.`),typeof i!="string"){if(i&&typeof i=="object"&&"type"in i&&(i.type==="text"||i.type==="image"))return e.buildResponse(i);i=JSON.stringify(i)}return e.buildResponse(i)}};var Rx={CONFLUENCE:[],GIT:[],GIT_WORKTREE:[],GITLAB:[],JIRA:[],SLACK:[],ZENDESK:[],BASECAMP:[]},Xf=Object.keys(Rx).filter(r=>Rx[r]?.length===0);var Qn=vr(Go(),1),Nx=class{events=new Qn.Subject;thinking$=new Qn.Subject;subs=[];lastInviteEvent;debugLevelEnabled=!1;constructor(){this.subs.push(this.thinking$.pipe((0,Qn.throttleTime)(qf.debounce)).subscribe(()=>this.sendEvent(new qf({}))))}async promptText(e,t){let n=new Di({invite:e,defaultValue:t});this.lastInviteEvent=n;let i=this.events.pipe((0,Qn.filter)(a=>a.parentKey===n.timestamp),(0,Qn.filter)(a=>a instanceof _r),(0,Qn.take)(1),(0,Qn.map)(a=>a.answer));this.sendEvent(n);try{return await(0,Qn.firstValueFrom)(i)}catch(a){throw new Error(`No answer received over invite ${n.timestamp} : ${a.message}`)}}async promptSecretText(e,t,n="********"){let i=t?n:"",a=await this.promptText(e,i);if(a===n&&t)return t;if(a)return a}async chooseOption(e,t,n,i){let a=new Ii({options:e,invite:t,optionalQuestion:n,allowFreeText:i??!1}),o=this.events.pipe((0,Qn.filter)(s=>s.parentKey===a.timestamp),(0,Qn.filter)(s=>s instanceof _r),(0,Qn.take)(1),(0,Qn.map)(s=>s.answer));this.sendEvent(a);try{return await(0,Qn.firstValueFrom)(o)}catch(s){throw new Error(`No answer received over choice ${a.timestamp} : ${s.message}`)}}displayText(e,t){this.sendEvent(new vu({text:e,speaker:t}))}debug(e){if(!this.debugLevelEnabled)return;let t=`${new Date().toISOString()} DEBUG: ${e.toString()}`;console.log(t),this.sendEvent(new vu({text:t}))}warn(e){this.sendEvent(new $3({warning:e}))}error(e){this.sendEvent(new $a({error:e}))}thinking(){this.thinking$.next(null)}sendEvent(e){this.events.next(e)}replayLastInvite(){this.lastInviteEvent&&this.sendEvent(this.lastInviteEvent)}kill(){this.subs.forEach(e=>e.unsubscribe()),this.events.complete()}};var K4=class{title;content;level;agentName;createdAt;updatedAt;constructor(e){this.title=e.title??"no title",this.content=e.content??"no content",this.level=e.level??"PROJECT",this.agentName=e.agentName,this.createdAt=e.createdAt??new Date,this.updatedAt=e.updatedAt}update(e){return this.title=e.title??this.title,this.content=e.content??this.content,this.level=e.level??this.level,this.agentName=e.agentName,this.createdAt=e.createdAt??new Date,this.updatedAt=e.updatedAt??new Date,this}};var yc=class extends Nx{constructor(t){super();this.clientId=t}addAnswerEvent(t,n){let i=new _r({answer:t,parentKey:n});this.sendEvent(i)}kill(){console.log(`Interactor for clientId ${this.clientId} killed`),super.kill()}};var Wie={version:1};var Fx=class extends Fe{constructor(t){super({commandWord:"add-query",description:"[internal] used to allow user feedback between flow commands.",isInternal:!0});this.interactor=t}async handle(t,n){let i=this.getSubCommand(t),a=i||"What message would you want to add ?",o=await this.interactor.promptText(`${a}
597
+ - Return to prompt`;if(await this.interactor.chooseOption(["proceed","stop"],u,"What do you want to do?")==="stop")return i.runStatus="STOPPED",!1;a.price>0?(a.priceThreshold*=2,this.interactor.displayText(`Cost threshold increased to ${a.priceThreshold.toFixed(2)}`)):(a.iterationsThreshold*=2,this.interactor.displayText(`Iteration threshold increased to ${a.iterationsThreshold}`))}return await Promise.all(t.map(async o=>{let s;try{o.threadId=i.id,this.interactor.sendEvent(o),s=await n.tools.run(o,i)}catch(c){let u=`Error running tool ${o.name}: ${c}`;console.error(u),s=o.buildResponse(u)}s.threadId=i.id,this.interactor.sendEvent(s),i.addToolRequests(n.name,[o]),i.addToolResponseEvents([s])})),this.shouldProceed(i)}handleError(e,t,n){let i=`${n} error occurred`;if(e instanceof Error){i=`${n} error: ${e.message}`;let a=e;a.status===401||a.statusCode===401?i=`${n} authentication failed. Please check your API key.`:a.status===429||a.statusCode===429?i=`${n} rate limit exceeded. Please try again later.`:a.code==="ECONNREFUSED"||a.code==="ENOTFOUND"||a.code==="ETIMEDOUT"?i=`Network error connecting to ${n}. Please check your internet connection.`:e.message?.includes("Max tokens")&&(i=`${n} response exceeded token limit. Try simplifying your request or splitting it into smaller parts.`)}console.error(`${n} client error:`,e),t.next(new $a({error:e instanceof Error?e:new Error(i)})),this.interactor.displayText(`\u26A0\uFE0F ${i}`)}shouldProceed(e){return e.runStatus==="RUNNING"&&!this.killed}showAgentAndUsage(e,t,n,i){let a=`\u{1F916} ${e.name} | ${t} - ${n} `;if(!i.usage)return;let o=`Loop${i.usage.iterations>1?"s":""}: ${i.usage.iterations} | `,s=`Input: ${i.usage.input}, Output: ${i.usage.output} | `,c=`Cache write: ${i.usage.cache_write}, Cache read: ${i.usage.cache_read}`,u=`\u{1F3C3}${i.usage.price.toFixed(3)} / \u{1F9F5}${i.price.toFixed(3)}`;this.interactor.sendEvent(new vu({text:a+u,threadId:i.id})),this.interactor.debug(o+s+c)}getModel(e){let t=e.definition.modelName?.toLowerCase(),n=this.models.find(i=>i.alias?.toLowerCase()===t);return n||this.models.find(i=>i.name.toLowerCase()===t)}supportsModel(e){return this.models.some(t=>t.name.toLowerCase()===e||t?.alias?.toLowerCase()===e)}returnError(e){return(0,Uie.of)(new $a({error:e}))}logAgentUsage(e,t,n,i){let a=i?.usage?.input??0,o=i?.usage?.output??0,s=a+o;this.logger?.logAgentUsage(i?.username??this.username??"no_username",e.name,t,n,this.name,a,o,s)}};var Vt=class{constructor(e,t,n){this.interactor=e;this.name=t,this.config=n}tools=[];name;config;async kill(){}async getTools(e,t,n){return this.tools=await this.buildTools(e,n),this.tools.filter(i=>{if(!t||!t.length)return!0;let a=i.function.name.split("__")[1]??i.function.name;return t.includes(a)})}};var k0=class r{constructor(e,t){this.project=e;this.username=t}commandQueue=[];clearCommands(){this.commandQueue=[]}oneshot=!1;fileReadOnly=!1;threadFilesRoot;stackDepth=10;data={};aiThread;addCommands(...e){this.commandQueue.unshift(...e)}getFirstCommand(){return this.commandQueue.shift()}getSubContext(...e){let t=new r(this.project,this.username);return t.oneshot=this.oneshot,t.fileReadOnly=this.fileReadOnly,t.addCommands(...e),t.stackDepth=this.stackDepth-1,t}cloneWithoutCommands(){let e=new r(this.project,this.username);return e.oneshot=this.oneshot,e.fileReadOnly=this.fileReadOnly,e.stackDepth=this.stackDepth,e.data=this.data,e}};var cZe=["project","user"],Ri=class{static validate(e){if(!cZe.includes(e))throw new Error(`Invalid configuration level: ${e}. Only PROJECT and USER levels are allowed.`)}};var Bie=[".pdf",".doc",".docx",".odt",".rtf",".xls",".xlsx",".ods",".csv",".tsv",".txt",".md",".markdown",".rst",".json",".xml",".yaml",".yml",".toml",".html",".htm",".css",".svg",".ts",".tsx",".js",".jsx",".py",".java",".cpp",".c",".h",".hpp",".cs",".go",".rs",".rb",".php",".swift",".kt",".scala",".sh",".bash",".sql",".env",".properties",".ini",".conf",".config",".log"];function $x(r){let e=r.toLowerCase().substring(r.lastIndexOf("."));return Bie.includes(e)}function Hie(){return Bie.join(", ")}var jx=class{constructor(e){this.tools=e;this.charLength=JSON.stringify(e).length}charLength=0;getTools(){return[...this.tools]}async run(e,t){let n=this.tools.find(c=>c.function.name===e.name);if(!n)throw new Error(`Tool '${e.name}' not found`);let i,a=n.function.function,o=JSON.parse(e.args),s=Array.isArray(o)?o:[o];if(i=await a(...s,t),i||(i=`Tool function ${e.name} finished without error.`),typeof i!="string"){if(i&&typeof i=="object"&&"type"in i&&(i.type==="text"||i.type==="image"))return e.buildResponse(i);i=JSON.stringify(i)}return e.buildResponse(i)}};var Rx={CONFLUENCE:[],GIT:[],GIT_WORKTREE:[],GITLAB:[],JIRA:[],SLACK:[],ZENDESK:[],BASECAMP:[]},Xf=Object.keys(Rx).filter(r=>Rx[r]?.length===0);var Qn=vr(Go(),1),Nx=class{events=new Qn.Subject;thinking$=new Qn.Subject;subs=[];lastInviteEvent;debugLevelEnabled=!1;constructor(){this.subs.push(this.thinking$.pipe((0,Qn.throttleTime)(qf.debounce)).subscribe(()=>this.sendEvent(new qf({}))))}lastAnswerName=void 0;async promptText(e,t){let n=new Di({invite:e,defaultValue:t});this.lastInviteEvent=n;let i=this.events.pipe((0,Qn.filter)(a=>a.parentKey===n.timestamp),(0,Qn.filter)(a=>a instanceof _r),(0,Qn.take)(1),(0,Qn.map)(a=>a));this.sendEvent(n);try{let a=await(0,Qn.firstValueFrom)(i);return this.lastAnswerName=a.name,a.answer}catch(a){throw new Error(`No answer received over invite ${n.timestamp} : ${a.message}`)}}async promptSecretText(e,t,n="********"){let i=t?n:"",a=await this.promptText(e,i);if(a===n&&t)return t;if(a)return a}async chooseOption(e,t,n,i){let a=new Ii({options:e,invite:t,optionalQuestion:n,allowFreeText:i??!1}),o=this.events.pipe((0,Qn.filter)(s=>s.parentKey===a.timestamp),(0,Qn.filter)(s=>s instanceof _r),(0,Qn.take)(1),(0,Qn.map)(s=>s.answer));this.sendEvent(a);try{return await(0,Qn.firstValueFrom)(o)}catch(s){throw new Error(`No answer received over choice ${a.timestamp} : ${s.message}`)}}displayText(e,t){this.sendEvent(new vu({text:e,speaker:t}))}debug(e){if(!this.debugLevelEnabled)return;let t=`${new Date().toISOString()} DEBUG: ${e.toString()}`;console.log(t),this.sendEvent(new vu({text:t}))}warn(e){this.sendEvent(new $3({warning:e}))}error(e){this.sendEvent(new $a({error:e}))}thinking(){this.thinking$.next(null)}sendEvent(e){this.events.next(e)}replayLastInvite(){this.lastInviteEvent&&this.sendEvent(this.lastInviteEvent)}kill(){this.subs.forEach(e=>e.unsubscribe()),this.events.complete()}};var K4=class{title;content;level;agentName;createdAt;updatedAt;constructor(e){this.title=e.title??"no title",this.content=e.content??"no content",this.level=e.level??"PROJECT",this.agentName=e.agentName,this.createdAt=e.createdAt??new Date,this.updatedAt=e.updatedAt}update(e){return this.title=e.title??this.title,this.content=e.content??this.content,this.level=e.level??this.level,this.agentName=e.agentName,this.createdAt=e.createdAt??new Date,this.updatedAt=e.updatedAt??new Date,this}};var yc=class extends Nx{constructor(t){super();this.clientId=t}addAnswerEvent(t,n){let i=new _r({answer:t,parentKey:n});this.sendEvent(i)}kill(){console.log(`Interactor for clientId ${this.clientId} killed`),super.kill()}};var Wie={version:1};var Fx=class extends Fe{constructor(t){super({commandWord:"add-query",description:"[internal] used to allow user feedback between flow commands.",isInternal:!0});this.interactor=t}async handle(t,n){let i=this.getSubCommand(t),a=i||"What message would you want to add ?",o=await this.interactor.promptText(`${a}
598
598
  (type nothing to proceed) `),s=i?`To the following query: "${i}"
599
599
  I answer: `:"",c=o?`"${o}"`:i?'nothing."':"";return(o||i)&&n.addCommands(`@ ${s}${c}`),n}};function Ze(r,e,t,n,i){if(n==="m")throw new TypeError("Private method is not writable");if(n==="a"&&!i)throw new TypeError("Private accessor was defined without a setter");if(typeof e=="function"?r!==e||!i:!e.has(r))throw new TypeError("Cannot write private member to an object whose class did not declare it");return n==="a"?i.call(r,t):i?i.value=t:e.set(r,t),t}function me(r,e,t,n){if(t==="a"&&!n)throw new TypeError("Private accessor was defined without a getter");if(typeof e=="function"?r!==e||!n:!e.has(r))throw new TypeError("Cannot read private member from an object whose class did not declare it");return t==="m"?n:t==="a"?n.call(r):n?n.value:e.get(r)}var vj=function(){let{crypto:r}=globalThis;if(r?.randomUUID)return vj=r.randomUUID.bind(r),r.randomUUID();let e=new Uint8Array(1),t=r?()=>r.getRandomValues(e)[0]:()=>Math.random()*255&255;return"10000000-1000-4000-8000-100000000000".replace(/[018]/g,n=>(+n^t()&15>>+n/4).toString(16))};function Au(r){return typeof r=="object"&&r!==null&&("name"in r&&r.name==="AbortError"||"message"in r&&String(r.message).includes("FetchRequestCanceledException"))}var Y4=r=>{if(r instanceof Error)return r;if(typeof r=="object"&&r!==null){try{if(Object.prototype.toString.call(r)==="[object Error]"){let e=new Error(r.message,r.cause?{cause:r.cause}:{});return r.stack&&(e.stack=r.stack),r.cause&&!e.cause&&(e.cause=r.cause),r.name&&(e.name=r.name),e}}catch{}try{return new Error(JSON.stringify(r))}catch{}}return new Error(r)};var ot=class extends Error{},di=class r extends ot{constructor(e,t,n,i){super(`${r.makeMessage(e,t,n)}`),this.status=e,this.headers=i,this.requestID=i?.get("request-id"),this.error=t}static makeMessage(e,t,n){let i=t?.message?typeof t.message=="string"?t.message:JSON.stringify(t.message):t?JSON.stringify(t):n;return e&&i?`${e} ${i}`:e?`${e} status code (no body)`:i||"(no status code or body)"}static generate(e,t,n,i){if(!e||!i)return new t2({message:n,cause:Y4(t)});let a=t;return e===400?new C0(e,a,n,i):e===401?new T0(e,a,n,i):e===403?new P0(e,a,n,i):e===404?new D0(e,a,n,i):e===409?new I0(e,a,n,i):e===422?new O0(e,a,n,i):e===429?new $0(e,a,n,i):e>=500?new j0(e,a,n,i):new r(e,a,n,i)}},Ni=class extends di{constructor({message:e}={}){super(void 0,void 0,e||"Request was aborted.",void 0)}},t2=class extends di{constructor({message:e,cause:t}){super(void 0,void 0,e||"Connection error.",void 0),t&&(this.cause=t)}},A0=class extends t2{constructor({message:e}={}){super({message:e??"Request timed out."})}},C0=class extends di{},T0=class extends di{},P0=class extends di{},D0=class extends di{},I0=class extends di{},O0=class extends di{},$0=class extends di{},j0=class extends di{};var lZe=/^[a-z][a-z0-9+.-]*:/i,Gie=r=>lZe.test(r),yj=r=>(yj=Array.isArray,yj(r)),bj=yj;function xj(r){return typeof r!="object"?{}:r??{}}function Zie(r){if(!r)return!0;for(let e in r)return!1;return!0}function Jie(r,e){return Object.prototype.hasOwnProperty.call(r,e)}var Kie=(r,e)=>{if(typeof e!="number"||!Number.isInteger(e))throw new ot(`${r} must be an integer`);if(e<0)throw new ot(`${r} must be a positive integer`);return e};var Mx=r=>{try{return JSON.parse(r)}catch{return}};var Yie=r=>new Promise(e=>setTimeout(e,r));var r2="0.65.0";var tae=()=>typeof window<"u"&&typeof window.document<"u"&&typeof navigator<"u";function fZe(){return typeof Deno<"u"&&Deno.build!=null?"deno":typeof EdgeRuntime<"u"?"edge":Object.prototype.toString.call(typeof globalThis.process<"u"?globalThis.process:0)==="[object process]"?"node":"unknown"}var pZe=()=>{let r=fZe();if(r==="deno")return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":r2,"X-Stainless-OS":Qie(Deno.build.os),"X-Stainless-Arch":Xie(Deno.build.arch),"X-Stainless-Runtime":"deno","X-Stainless-Runtime-Version":typeof Deno.version=="string"?Deno.version:Deno.version?.deno??"unknown"};if(typeof EdgeRuntime<"u")return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":r2,"X-Stainless-OS":"Unknown","X-Stainless-Arch":`other:${EdgeRuntime}`,"X-Stainless-Runtime":"edge","X-Stainless-Runtime-Version":globalThis.process.version};if(r==="node")return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":r2,"X-Stainless-OS":Qie(globalThis.process.platform??"unknown"),"X-Stainless-Arch":Xie(globalThis.process.arch??"unknown"),"X-Stainless-Runtime":"node","X-Stainless-Runtime-Version":globalThis.process.version??"unknown"};let e=dZe();return e?{"X-Stainless-Lang":"js","X-Stainless-Package-Version":r2,"X-Stainless-OS":"Unknown","X-Stainless-Arch":"unknown","X-Stainless-Runtime":`browser:${e.browser}`,"X-Stainless-Runtime-Version":e.version}:{"X-Stainless-Lang":"js","X-Stainless-Package-Version":r2,"X-Stainless-OS":"Unknown","X-Stainless-Arch":"unknown","X-Stainless-Runtime":"unknown","X-Stainless-Runtime-Version":"unknown"}};function dZe(){if(typeof navigator>"u"||!navigator)return null;let r=[{key:"edge",pattern:/Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"ie",pattern:/MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"ie",pattern:/Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"chrome",pattern:/Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"firefox",pattern:/Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"safari",pattern:/(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/}];for(let{key:e,pattern:t}of r){let n=t.exec(navigator.userAgent);if(n){let i=n[1]||0,a=n[2]||0,o=n[3]||0;return{browser:e,version:`${i}.${a}.${o}`}}}return null}var Xie=r=>r==="x32"?"x32":r==="x86_64"||r==="x64"?"x64":r==="arm"?"arm":r==="aarch64"||r==="arm64"?"arm64":r?`other:${r}`:"unknown",Qie=r=>(r=r.toLowerCase(),r.includes("ios")?"iOS":r==="android"?"Android":r==="darwin"?"MacOS":r==="win32"?"Windows":r==="freebsd"?"FreeBSD":r==="openbsd"?"OpenBSD":r==="linux"?"Linux":r?`Other:${r}`:"Unknown"),eae,rae=()=>eae??(eae=pZe());function nae(){if(typeof fetch<"u")return fetch;throw new Error("`fetch` is not defined as a global; Either pass `fetch` to the client, `new Anthropic({ fetch })` or polyfill the global, `globalThis.fetch = fetch`")}function wj(...r){let e=globalThis.ReadableStream;if(typeof e>"u")throw new Error("`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`");return new e(...r)}function Lx(r){let e=Symbol.asyncIterator in r?r[Symbol.asyncIterator]():r[Symbol.iterator]();return wj({start(){},async pull(t){let{done:n,value:i}=await e.next();n?t.close():t.enqueue(i)},async cancel(){await e.return?.()}})}function X4(r){if(r[Symbol.asyncIterator])return r;let e=r.getReader();return{async next(){try{let t=await e.read();return t?.done&&e.releaseLock(),t}catch(t){throw e.releaseLock(),t}},async return(){let t=e.cancel();return e.releaseLock(),await t,{done:!0,value:void 0}},[Symbol.asyncIterator](){return this}}}async function iae(r){if(r===null||typeof r!="object")return;if(r[Symbol.asyncIterator]){await r[Symbol.asyncIterator]().return?.();return}let e=r.getReader(),t=e.cancel();e.releaseLock(),await t}var aae=({headers:r,body:e})=>({bodyHeaders:{"content-type":"application/json"},body:JSON.stringify(e)});function cae(r){let e=0;for(let i of r)e+=i.length;let t=new Uint8Array(e),n=0;for(let i of r)t.set(i,n),n+=i.length;return t}var oae;function Q4(r){let e;return(oae??(e=new globalThis.TextEncoder,oae=e.encode.bind(e)))(r)}var sae;function _j(r){let e;return(sae??(e=new globalThis.TextDecoder,sae=e.decode.bind(e)))(r)}var ho,mo,Cu=class{constructor(){ho.set(this,void 0),mo.set(this,void 0),Ze(this,ho,new Uint8Array,"f"),Ze(this,mo,null,"f")}decode(e){if(e==null)return[];let t=e instanceof ArrayBuffer?new Uint8Array(e):typeof e=="string"?Q4(e):e;Ze(this,ho,cae([me(this,ho,"f"),t]),"f");let n=[],i;for(;(i=gZe(me(this,ho,"f"),me(this,mo,"f")))!=null;){if(i.carriage&&me(this,mo,"f")==null){Ze(this,mo,i.index,"f");continue}if(me(this,mo,"f")!=null&&(i.index!==me(this,mo,"f")+1||i.carriage)){n.push(_j(me(this,ho,"f").subarray(0,me(this,mo,"f")-1))),Ze(this,ho,me(this,ho,"f").subarray(me(this,mo,"f")),"f"),Ze(this,mo,null,"f");continue}let a=me(this,mo,"f")!==null?i.preceding-1:i.preceding,o=_j(me(this,ho,"f").subarray(0,a));n.push(o),Ze(this,ho,me(this,ho,"f").subarray(i.index),"f"),Ze(this,mo,null,"f")}return n}flush(){return me(this,ho,"f").length?this.decode(`
600
600
  `):[]}};ho=new WeakMap,mo=new WeakMap;Cu.NEWLINE_CHARS=new Set([`
@@ -874,7 +874,7 @@ Are you sure you want to delete this MCP server configuration?
874
874
 
875
875
  Here are the information collected during previous chats:
876
876
  `),n.join(`
877
- `)):""}loadMemoriesFrom(e){this.memories=[],this.userMemoriesPath=this.readMemories(this.userMemoriesPath)?this.userMemoriesPath:void 0;let t=e?.configPath?eE.join(e.configPath,vM):void 0;this.projectMemoriesPath=this.readMemories(t)?t:void 0,e&&this.checkInit()}readMemories(e){if(!e)return!1;try{if(!qit(e)){let n=xfe.stringify({memories:[]});zit(e,n)}let t=ta(e);return t?(this.memories.push(...t.memories),!0):!1}catch{return!1}}checkInit(){if(!this.userMemoriesPath||!this.projectMemoriesPath)throw new Error("user or project path not set for memory service")}saveMemories(){this.checkInit();let e=this.memories.filter(n=>n.level==="USER"),t=this.memories.filter(n=>n.level==="PROJECT");Mn(this.userMemoriesPath,{memories:e}),Mn(this.projectMemoriesPath,{memories:t})}};import*as _fe from"crypto";import*as Va from"node:fs/promises";import*as Fc from"path";var bm=class r{constructor(e,t,n){this.repository=e;this.defaultProject=t;this.isForcedMode=n}maskingService=new B2;listProjects(){let e=this.repository.listProjects();return this.isForcedMode&&this.defaultProject?e.filter(t=>t===this.defaultProject).map(t=>{let n=this.repository.getConfig(t);return{name:t,volatile:n?.volatile}}):e.map(t=>{let n=this.repository.getConfig(t);return{name:t,volatile:n?.volatile}})}getDefaultProject(){return this.defaultProject||null}getForcedMode(){return this.isForcedMode}getProject(e){this.checkAgainstForced(e);let t=this.repository.getConfig(e);if(t)return{name:e,config:t};if(!this.isForcedMode&&this.defaultProject){let n=process.cwd(),i=r.generateProjectId(n),a=Fc.basename(n);if(e===a||e===i||e===this.defaultProject){console.log(`[PROJECT_SERVICE] Creating volatile project for '${e}' at ${n}`);let o=this.getOrCreateVolatileProject(n);if(t=this.repository.getConfig(o),t)return{name:o,config:t}}}return null}exists(e){return this.checkAgainstForced(e),this.repository.exists(e)}createProject(e,t){if(this.checkAgainstForced(e),!e||!t)throw new Error("Project name and path are required");if(!this.repository.createProject(e,t))throw new Error(`Project '${e}' already exists`)}updateProjectConfig(e,t){if(this.checkAgainstForced(e),!this.repository.exists(e))throw new Error(`Project '${e}' does not exist`);this.repository.saveConfig(e,t)}deleteProject(e){if(this.checkAgainstForced(e),!this.repository.deleteProject(e))throw new Error(`Project '${e}' does not exist`)}getProjectConfigForClient(e){this.checkAgainstForced(e);let t=this.repository.getConfig(e);return t?this.maskingService.maskConfig(t):null}updateProjectConfigFromClient(e,t){this.checkAgainstForced(e);let n=this.repository.getConfig(e);if(!n)throw new Error(`Project '${e}' does not exist`);let i=this.maskingService.unmaskConfig(t,n);this.repository.saveConfig(e,i)}checkAgainstForced(e){if(this.isForcedMode&&this.defaultProject&&this.defaultProject!==e)throw Error(`Project selection outside of ${this.defaultProject} not allowed`)}getOrCreateVolatileProject(e){let t=r.generateProjectId(e);if(this.repository.exists(t))return t;this.repository.createProject(t,e);let n=this.repository.getConfig(t);return n&&(n.volatile=!0,n.createdAt=Date.now(),this.repository.saveConfig(t,n)),t}async registerWorktreeProject(e,t,n){let i=this.repository.getConfig(n),a=i?{...i,path:t,volatile:void 0,createdAt:void 0}:{version:1,path:t,integration:{},storage:{type:"file"},agents:[]};this.repository.createProject(e,t),this.repository.saveConfig(e,a);let o=this.repository.getProjectInfo(n);if(o){let s=this.repository.getProjectInfo(e);if(s)for(let c of["agents","prompts","schedulers","memories"]){let u=Fc.join(o.configPath,c),l=Fc.join(s.configPath,c);try{await Va.access(u),await Va.symlink(u,l)}catch{}}}}async unregisterWorktreeProject(e){let t=this.repository.getProjectInfo(e);if(!t)return;let n=e.lastIndexOf("__");if(n!==-1){let i=e.substring(0,n),a=this.repository.getProjectInfo(i);a&&await this.migrateThreadsToParent(t.configPath,a.configPath)}await Va.rm(t.configPath,{recursive:!0,force:!0})}async migrateThreadsToParent(e,t){let n=Fc.join(e,"threads"),i=Fc.join(t,"threads");try{await Va.access(n)}catch{return}await Va.mkdir(i,{recursive:!0});let a=await Va.readdir(n);for(let o of a){let s=Fc.join(n,o),c=Fc.join(i,o);try{await Va.access(c)}catch{await Va.rename(s,c)}}}static generateProjectId(e){let t=Fc.basename(e),n=_fe.createHash("sha256").update(e).digest("hex").substring(0,8);return`${t}_${n}`}};var kfe=vr(Go(),1);import*as xm from"node:path";import*as Efe from"node:os";import{mkdirSync as Uit}from"fs";var Bit="projects",Sfe="project.yaml",wm=class{constructor(e,t,n){this.interactor=e;this.projectService=t;let i=xm.join(Efe.userInfo().homedir,".coday");this.projectsConfigPath=xm.join(n??i,Bit),Uit(this.projectsConfigPath,{recursive:!0}),this.projects=this.projectService.listProjects().map(a=>a.name)}projectsConfigPath;maskingService=new B2;projects;selectedProjectBehaviorSubject=new kfe.BehaviorSubject(null);selectedProject$=this.selectedProjectBehaviorSubject.asObservable();selectProject(e){let t=xm.join(this.projectsConfigPath,e),n=xm.join(t,Sfe),i=this.projectService.getProject(e)?.config;if(!i?.path){console.log(`[PROJECT_STATE_SERVICE] ERROR: No project path in config for '${e}'`),this.interactor.error("Invalid selection, project path needed \u{1F622}.");return}let o={name:e,config:i,configPath:t};console.log(`[PROJECT_STATE_SERVICE] Selected '${e}' \u2192 ${i.path}`),this.updateSelectedProject(o),this.interactor.displayText(`Project local configuration used: ${n}`)}updateSelectedProject(e){this.selectedProjectBehaviorSubject.next(e)}get selectedProject(){return this.selectedProjectBehaviorSubject.value}save(e){let t=this.selectedProjectBehaviorSubject.value;if(!t){this.interactor.error("No current project selected, save not possible");return}let n={...t.config,...e};Mn(xm.join(t.configPath,Sfe),n),t.config=n,this.updateSelectedProject(t)}getConfigForClient(){let e=this.selectedProjectBehaviorSubject.value;return e?this.maskingService.maskConfig(e.config):null}updateConfigFromClient(e){let t=this.selectedProjectBehaviorSubject.value;if(!t){this.interactor.error("No current project selected, update not possible");return}let n=this.maskingService.unmaskConfig(e,t.config);this.save(n)}};import*as Gu from"node:path";import*as Tfe from"node:os";import{randomUUID as Wit}from"node:crypto";import{existsSync as W2,mkdirSync as Vit,readdirSync as Cfe,unlinkSync as Git}from"fs";import*as yM from"node:path";import*as Afe from"node:os";function Hit(r){return r.replace(/[^a-zA-Z0-9]/g,"_")}function _m(r,e){try{let t=yM.join(Afe.userInfo().homedir,".coday"),n=Hit(r),i=yM.join(e??t,"users",n,"user.yaml"),a=ta(i);return a?a.groups?.includes("CODAY_ADMIN")??!1:!1}catch{return!1}}var tE=class{codayConfigDir;projectService;constructor(e,t){let n=Gu.join(Tfe.userInfo().homedir,".coday");this.codayConfigDir=e??n,this.projectService=t}getProjectPath(e){if(this.projectService)return this.projectService.getProject(e)?.config.path}async getOrCreatePromptsDir(e,t){let n;if(t==="local")n=Gu.join(this.codayConfigDir,"projects",e,"prompts");else{let i=this.getProjectPath(e);if(!i)throw new Error("Project path not configured, cannot access project prompts");let a=await f2({text:"coday.yaml",root:i});if(a.length===0)throw new Error(`coday.yaml not found in project path: ${i}`);let o=Gu.dirname(a[0]);n=Gu.join(i,o,"prompts")}return W2(n)||(Vit(n,{recursive:!0}),console.log(`[PROMPT] Created prompts directory: ${n}`)),n}async getOrCreatePromptFilePath(e,t,n){let i=await this.getOrCreatePromptsDir(e,n);return Gu.join(i,`${t}.yml`)}async findPromptSource(e,t){let n=await this.getOrCreatePromptFilePath(e,t,"local");if(W2(n))return"local";if(this.projectService)try{let i=await this.getOrCreatePromptFilePath(e,t,"project");if(W2(i))return"project"}catch{}return null}async findProjectForPrompt(e){let t=Gu.join(this.codayConfigDir,"projects");if(!W2(t))return null;let n=Cfe(t,{withFileTypes:!0}).filter(i=>i.isDirectory()).map(i=>i.name);for(let i of n){let a=Gu.join(this.codayConfigDir,"projects",i,"prompts",`${e}.yml`);if(W2(a))return i;if(this.projectService)try{let o=await this.getOrCreatePromptFilePath(i,e,"project");if(W2(o))return i}catch{}}return null}validatePlaceholders(e){let t=/\{\{(\w+)\}\}/g,n=[],i=/^[A-Za-z][A-Za-z0-9-]*$/;if(e.forEach(a=>{let o;for(;(o=t.exec(a))!==null;){let s=o[1];s&&s!=="PARAMETERS"&&!i.test(s)&&n.push(s)}}),n.length>0)throw new Error(`Invalid parameter keys: ${n.join(", ")}. Keys must start with a letter and contain only letters, digits, and hyphens.`)}async create(e,t,n="local"){try{this.validatePlaceholders(t.commands);let i=Wit(),a={...t,id:i,source:n,createdAt:new Date().toISOString(),parameterFormat:this.getParameterFormat(t.commands)},o=await this.getOrCreatePromptFilePath(e,i,n);if(W2(o))throw new Error(`Prompt with ID ${i} already exists`);return Mn(o,a),console.log(`[PROMPT] Created prompt ${i} in ${n} for project ${e}`),a}catch(i){throw new Error(`Failed to create prompt: ${i instanceof Error?i.message:"Unknown error"}`)}}async get(e,t){try{let n=await this.findPromptSource(e,t);if(!n)return null;let i=await this.getOrCreatePromptFilePath(e,t,n),a=ta(i);return a?(a.source||(a.source=n),a):null}catch(n){return console.error(`Failed to get prompt ${t}:`,n),null}}async getById(e){try{let t=await this.findProjectForPrompt(e);if(!t)return null;let n=await this.get(t,e);return n?{prompt:n,projectName:t}:null}catch(t){return console.error(`Failed to get prompt ${e}:`,t),null}}async update(e,t,n,i){try{let a=await this.get(e,t);if(!a)return null;if(n.webhookEnabled!==void 0&&n.webhookEnabled!==a.webhookEnabled&&!_m(i,this.codayConfigDir))throw new Error("Only CODAY_ADMIN can enable/disable webhook for prompts");let{id:o,createdAt:s,source:c,...u}=n;n.commands&&this.validatePlaceholders(n.commands);let l={...a,...u,updatedAt:new Date().toISOString()};n.commands&&(l.parameterFormat=this.getParameterFormat(n.commands));let f=await this.getOrCreatePromptFilePath(e,t,a.source);return Mn(f,l),console.log(`[PROMPT] Updated prompt ${t} (${a.source}) by user ${i}`),l}catch(a){throw console.error(`Failed to update prompt ${t}:`,a),a}}async delete(e,t){try{let n=await this.findPromptSource(e,t);if(!n)return!1;let i=await this.getOrCreatePromptFilePath(e,t,n);return Git(i),console.log(`[PROMPT] Deleted prompt ${t} from ${n}`),!0}catch(n){return console.error(`Failed to delete prompt ${t}:`,n),!1}}getParameterFormat(e){if(e.some(a=>/\{\{PARAMETERS\}\}/.test(a)))return"";let n=/\{\{(\w+)\}\}/g,i=new Set;return e.forEach(a=>{let o;for(;(o=n.exec(a))!==null;){let s=o[1];s&&s!=="PARAMETERS"&&i.add(s)}}),i.size===0?"":Array.from(i).map(a=>`${a}=""`).join(" ")}async list(e){try{let t=[],n=["local"];this.projectService&&n.push("project");for(let i of n)try{let a=await this.getOrCreatePromptsDir(e,i);if(!W2(a))continue;let s=Cfe(a).filter(c=>c.endsWith(".yml"));for(let c of s){let u=c.replace(".yml",""),l=await this.get(e,u);l&&t.push({id:l.id,name:l.name,description:l.description,webhookEnabled:l.webhookEnabled,createdBy:l.createdBy,createdAt:l.createdAt,updatedAt:l.updatedAt,source:l.source||i,parameterFormat:l.parameterFormat})}}catch(a){console.log(`[PROMPT] Could not access ${i} prompts for ${e}:`,a)}return t.push(...j3),t.sort((i,a)=>new Date(a.createdAt).getTime()-new Date(i.createdAt).getTime())}catch(t){return console.error(`Failed to list prompts for project ${e}:`,t),[]}}async enableWebhook(e,t,n){return this.update(e,t,{webhookEnabled:!0},n)}async disableWebhook(e,t,n){return this.update(e,t,{webhookEnabled:!1},n)}};var Pfe=vr(Go(),1),rE=class{constructor(e){this.promptService=e}threadCodayManager;threadService;codayOptions;logger;initialize(e,t,n,i){this.threadCodayManager=e,this.threadService=t,this.codayOptions=n,this.logger=i}processCommands(e,t){let n;if(typeof t=="string"){let a=e.some(s=>/\{\{PARAMETERS\}\}/.test(s));if(e.some(s=>/\{\{(?!PARAMETERS\}\})\w+\}\}/.test(s)))throw new Error("Prompt contains structured placeholders ({{key}}). Use an object parameter instead of a string.");a?n=e.map(s=>s.replace(/\{\{PARAMETERS\}\}/g,t)):n=e.map((s,c)=>c===0?`${s} ${t}`.trim():s)}else typeof t=="object"&&t!==null?n=e.map(a=>{let o=a;return Object.entries(t).forEach(([s,c])=>{let u=`{{${s}}}`;o=o.replaceAll(u,String(c))}),o}):n=[...e];let i=new Set;if(n.forEach(a=>{let o=a.match(/\{\{(\w+)\}\}/g);o&&o.forEach(s=>i.add(s))}),i.size>0){let a=Array.from(i).map(o=>o.replace(/[{}]/g,"")).join(", ");throw new Error(`Missing required parameters: ${a}`)}return n}async executePrompt(e,t,n,i,a){if(!this.threadCodayManager||!this.threadService||!this.codayOptions||!this.logger)throw new Error("PromptExecutionService not initialized. Call initialize() first.");let{title:o,awaitFinalAnswer:s=!1,projectName:c}=a||{},u,l;if(c){if(l=c,u=await this.promptService.get(l,e),!u)throw new Error(`Prompt ${e} not found in project ${l}`)}else{let y=await this.promptService.getById(e);if(!y)throw new Error(`Prompt not found: ${e}`);u=y.prompt,l=y.projectName}if(i==="webhook"&&!u.webhookEnabled)throw new Error(`Prompt ${e} is not enabled for webhook execution`);if(!u.commands||u.commands.length===0)throw new Error("Prompt has no commands configured");let f=this.processCommands(u.commands,t);if(!n)throw new Error("Username is required");let d=(await this.threadService.createThread(l,n,o)).id;console.log(`[PROMPT_EXEC] Created new thread: ${d} for ${i} execution`);let m={...this.codayOptions,oneshot:!0,project:l,thread:d,prompts:f};console.log(`[PROMPT_EXEC] Creating instance for ${i} execution with ${f.length} prompts:`,f);let h=this.threadCodayManager.createWithoutConnection(d,l,n,m);h.prepareCoday();let g=h.coday.interactor,v={project:l,title:o??"Untitled",username:n,clientId:d,promptCount:f.length,awaitFinalAnswer:!!s,promptName:u.name,promptId:u.id,executionMode:i};if(i==="webhook"?this.logger.logWebhook(v):this.logger.logWebhook({...v,webhookName:u.name,webhookUuid:u.id}),s){let y=[],x=g.events.pipe((0,Pfe.filter)(k=>(console.log(`[PROMPT_EXEC] Received event type: ${k.type}, role: ${k instanceof Rt?k.role:"N/A"}`),k instanceof Rt&&k.role==="assistant"&&!!k.name))).subscribe(k=>{y.push(k)});try{await h.coday.run(),x.unsubscribe();let k=y[y.length-1];return await this.threadCodayManager.cleanup(d),{threadId:d,lastEvent:k}}catch(k){x.unsubscribe();let S=k instanceof Error?k.message:"Unknown error";throw this.logger.logWebhookError({error:`Prompt execution failed: ${S}`,username:n,project:l,clientId:d}),console.error("[PROMPT_EXEC] Error waiting for prompt completion:",k),await this.threadCodayManager.cleanup(d),k}}else return h.coday.run().catch(y=>{console.error("[PROMPT_EXEC] Error during prompt Coday run:",y)}),setTimeout(()=>{this.threadCodayManager.cleanup(d).catch(y=>{console.error("[PROMPT_EXEC] Error cleaning up prompt thread after timeout:",y)})},300*1e3),{threadId:d}}};var Y6=vr(Pc(),1);import*as ai from"fs";import*as Sm from"path";import{randomUUID as Zit}from"node:crypto";var nE=class{constructor(e,t,n){this.logger=e;this.promptService=t;this.codayConfigDir=n}schedulers=new Map;checkInterval;CHECK_INTERVAL_MS=3e4;promptExecutionService;initializeExecution(e){this.promptExecutionService=e}async initialize(){console.log("[SCHEDULER] Initializing SchedulerService..."),await this.loadAllSchedulers(),this.startScheduler(),console.log(`[SCHEDULER] SchedulerService initialized with ${this.schedulers.size} schedulers`)}stop(){this.checkInterval&&(clearInterval(this.checkInterval),this.checkInterval=void 0,console.log("[SCHEDULER] SchedulerService stopped"))}async loadAllSchedulers(){this.schedulers.clear();let e=Sm.join(this.codayConfigDir,"projects");if(!ai.existsSync(e))return;let t=ai.readdirSync(e,{withFileTypes:!0}).filter(n=>n.isDirectory()).map(n=>n.name);for(let n of t)try{let i=await this.loadProjectSchedulers(n);for(let a of i)this.schedulers.set(a.id,a)}catch(i){console.error(`[SCHEDULER] Failed to load schedulers for project ${n}:`,i)}}async loadProjectSchedulers(e){let t=this.getSchedulersDir(e);if(!ai.existsSync(t))return[];let n=ai.readdirSync(t),i=[];for(let a of n)if(a.endsWith(".yml"))try{let o=Sm.join(t,a),s=ai.readFileSync(o,"utf-8"),c=Y6.parse(s),u=this.calculateNextRunSkippingMissed(c),l=u.occurrenceCount!==c.occurrenceCount;c.nextRun=u.nextRun,c.occurrenceCount=u.occurrenceCount,l&&await this.saveScheduler(c,e),i.push(c)}catch(o){console.error(`[SCHEDULER] Failed to load scheduler from ${a}:`,o)}return i}startScheduler(){this.checkInterval=setInterval(()=>{this.checkAndExecuteSchedulers()},this.CHECK_INTERVAL_MS),this.checkAndExecuteSchedulers()}async checkAndExecuteSchedulers(){for(let e of this.schedulers.values())e.enabled&&dce(e.schedule,e.nextRun??null,e.occurrenceCount??0)&&this.executeScheduler(e).catch(t=>{console.error(`[SCHEDULER] Failed to execute scheduler ${e.id}:`,t)})}async executeSchedulerInternal(e,t,n){if(!this.promptExecutionService)throw new Error("PromptExecutionService not initialized");console.log(`[SCHEDULER] Executing scheduler "${e.name}" (${e.id}) [${n}]`);let i=e.parameters;e.parameters&&typeof e.parameters=="object"&&Object.keys(e.parameters).length===1&&"PARAMETERS"in e.parameters&&(i=String(e.parameters.PARAMETERS));let a=await this.promptExecutionService.executePrompt(e.promptId,i,e.createdBy,"scheduled",{title:n==="scheduled"?`Scheduled: ${e.name}`:`Manual: ${e.name}`,awaitFinalAnswer:!1,projectName:t});return console.log(`[SCHEDULER] Scheduler "${e.name}" executed successfully. Thread: ${a.threadId}`),a.threadId}async executeScheduler(e){let t=new Date().toISOString();console.log(`[SCHEDULER] Executing scheduler "${e.name}" (${e.id})`);let n=this.findProjectForScheduler(e.id);if(!n){console.error(`[SCHEDULER] Cannot find project for scheduler ${e.id}, skipping execution`);return}let i,a,o;e.lastRun=t,e.occurrenceCount=(e.occurrenceCount??0)+1,e.nextRun=uh(e.schedule,new Date,e.occurrenceCount);try{await this.saveScheduler(e,n),console.log(`[SCHEDULER] Next execution for "${e.name}": ${e.nextRun}`),this.schedulers.set(e.id,e),a=await this.executeSchedulerInternal(e,n,"scheduled"),i=!0}catch(s){i=!1,o=s instanceof Error?s.message:String(s),console.error(`[SCHEDULER] Scheduler "${e.name}" failed:`,s)}this.logger.logTriggerExecution({triggerId:e.id,triggerName:e.name,webhookUuid:e.promptId,projectName:n,success:i,threadId:a,error:o})}validateSchedule(e){return pce(e)}calculateNextRunSkippingMissed(e){let t=new Date,n=e.occurrenceCount??0,i=e.nextRun;if(!i)return{nextRun:uh(e.schedule,t,n),occurrenceCount:n};if(new Date(i)>=t)return{nextRun:i,occurrenceCount:n};let a=1e3,o=0,s=0;for(;o<a;){if(n++,s++,i=uh(e.schedule,t,n),!i)return s>0&&console.log(`[SCHEDULER] Scheduler "${e.name}" (${e.id}) expired after skipping ${s} missed occurrence(s)`),{nextRun:null,occurrenceCount:n};if(new Date(i)>=t)return s>0&&console.log(`[SCHEDULER] Scheduler "${e.name}" (${e.id}) skipped ${s} missed occurrence(s), next run: ${i}`),{nextRun:i,occurrenceCount:n};o++}return console.warn(`[SCHEDULER] Could not find future nextRun for scheduler ${e.id} after ${a} iterations`),{nextRun:null,occurrenceCount:n}}getSchedulersDir(e){return Sm.join(this.codayConfigDir,"projects",e,"schedulers")}getSchedulerFilePath(e,t){return Sm.join(this.getSchedulersDir(e),`${t}.yml`)}findProjectForScheduler(e){let t=Sm.join(this.codayConfigDir,"projects");if(!ai.existsSync(t))return null;let n=ai.readdirSync(t,{withFileTypes:!0}).filter(i=>i.isDirectory()).map(i=>i.name);for(let i of n){let a=this.getSchedulerFilePath(i,e);if(ai.existsSync(a))return i}return null}canAccessScheduler(e,t){return e.createdBy===t?!0:_m(t,this.codayConfigDir)}async listSchedulers(e,t){return(await this.loadProjectSchedulers(e)).filter(i=>this.canAccessScheduler(i,t)).map(i=>({id:i.id,name:i.name,enabled:i.enabled,promptId:i.promptId,schedule:i.schedule,parameters:i.parameters,lastRun:i.lastRun,nextRun:i.nextRun,createdBy:i.createdBy}))}async getScheduler(e,t,n){let i=this.getSchedulerFilePath(e,t);if(!ai.existsSync(i))return null;try{let a=ai.readFileSync(i,"utf-8"),o=Y6.parse(a),s=this.calculateNextRunSkippingMissed(o);return o.nextRun=s.nextRun,o.occurrenceCount=s.occurrenceCount,n&&!this.canAccessScheduler(o,n)?(console.log(`[SCHEDULER] Access denied for user ${n} to scheduler ${t}`),null):o}catch(a){return console.error(`[SCHEDULER] Failed to load scheduler ${t}:`,a),null}}async createScheduler(e,t,n){let i=this.validateSchedule(t.schedule);if(!i.valid)throw new Error(`Invalid schedule: ${i.error}`);if(!await this.promptService.getById(t.promptId))throw new Error(`Prompt not found: ${t.promptId}`);let o={id:Zit(),name:t.name,enabled:t.enabled??!0,promptId:t.promptId,schedule:t.schedule,parameters:t.parameters,createdBy:n,createdAt:new Date().toISOString(),nextRun:uh(t.schedule,new Date,0),occurrenceCount:0};return await this.saveScheduler(o,e),this.schedulers.set(o.id,o),console.log(`[SCHEDULER] Created scheduler "${o.name}" (${o.id}) for project ${e}`),o}async updateScheduler(e,t,n,i){let a=await this.getScheduler(e,t,i);if(!a)throw new Error(`Scheduler not found or access denied: ${t}`);if(console.log(`[SCHEDULER] Updating scheduler ${t} by user ${i}`),n.name!==void 0&&(a.name=n.name),n.enabled!==void 0&&(a.enabled=n.enabled),n.parameters!==void 0&&(a.parameters=n.parameters),n.promptId!==void 0){if(!await this.promptService.getById(n.promptId))throw new Error(`Prompt not found: ${n.promptId}`);a.promptId=n.promptId}if(n.schedule!==void 0){let o=this.validateSchedule(n.schedule);if(!o.valid)throw new Error(`Invalid schedule: ${o.error}`);a.schedule=n.schedule,a.occurrenceCount=0,a.nextRun=uh(n.schedule,new Date,0)}return await this.saveScheduler(a,e),this.schedulers.set(a.id,a),console.log(`[SCHEDULER] Updated scheduler "${a.name}" (${a.id})`),a}async deleteScheduler(e,t,n){if(!await this.getScheduler(e,t,n))return!1;let a=this.getSchedulerFilePath(e,t);return ai.unlinkSync(a),this.schedulers.delete(t),console.log(`[SCHEDULER] Deleted scheduler ${t} by user ${n}`),!0}async enableScheduler(e,t,n){return this.updateScheduler(e,t,{enabled:!0},n)}async disableScheduler(e,t,n){return this.updateScheduler(e,t,{enabled:!1},n)}async runSchedulerNow(e,t,n){let i=await this.getScheduler(e,t,n);if(!i)throw new Error(`Scheduler not found or access denied: ${t}`);let a=await this.executeSchedulerInternal(i,e,"manual");return i.lastRun=new Date().toISOString(),await this.saveScheduler(i,e),this.schedulers.set(i.id,i),this.logger.logTriggerExecution({triggerId:i.id,triggerName:i.name,webhookUuid:i.promptId,projectName:e,success:!0,threadId:a}),a}async saveScheduler(e,t){if(!t&&(t=this.findProjectForScheduler(e.id),!t))throw new Error(`Cannot find project for scheduler ${e.id}`);let n=this.getSchedulersDir(t);ai.mkdirSync(n,{recursive:!0});let i=this.getSchedulerFilePath(t,e.id),a=Y6.stringify(e);ai.writeFileSync(i,a,"utf-8")}};import*as Mc from"node:path";import*as Ofe from"node:os";import{existsSync as Dfe,lstatSync as Jit,mkdirSync as Ife,readdirSync as Kit}from"fs";var iE=class r{projectsConfigPath;static PROJECT_FILENAME="project.yaml";constructor(e){let t=Mc.join(Ofe.userInfo().homedir,".coday");this.projectsConfigPath=Mc.join(e??t,"projects"),Ife(this.projectsConfigPath,{recursive:!0})}listProjects(){return Kit(this.projectsConfigPath).filter(t=>Jit(Mc.join(this.projectsConfigPath,t)).isDirectory())}getProjectInfo(e){let t=Mc.join(this.projectsConfigPath,e),n=Mc.join(t,r.PROJECT_FILENAME);return Dfe(n)?{name:e,configPath:t}:null}exists(e){return this.getProjectInfo(e)!==null}getConfig(e){let t=this.getProjectInfo(e);if(!t)return console.log(`[PROJECT_REPO] No project info found for: '${e}'`),null;let n=Mc.join(t.configPath,r.PROJECT_FILENAME),i=ta(n);if(!i)return console.log(`[PROJECT_REPO] Failed to load config for '${e}' from ${n}`),null;let a=ch(i,hce);return a!==i&&(console.log(`[PROJECT_REPO] Config migrated for '${e}', saving...`),Mn(n,a)),a}saveConfig(e,t){let n=this.getProjectInfo(e);if(!n)throw new Error(`Project '${e}' does not exist`);let i=Mc.join(n.configPath,r.PROJECT_FILENAME);Mn(i,t)}createProject(e,t){let n=Mc.join(this.projectsConfigPath,e),i=Mc.join(n,r.PROJECT_FILENAME);return Dfe(i)?!1:(console.log(`[PROJECT_REPO] Creating project '${e}' with path: ${t}`),Ife(n,{recursive:!0}),Mn(i,{version:1,path:t,integration:{},storage:{type:"file"},agents:[]}),console.log(`[PROJECT_REPO] Project '${e}' created successfully`),!0)}deleteProject(e){return this.getProjectInfo(e),!1}};var bM=vr(Pc(),1);import{promises as Zu}from"fs";import Zp from"path";var $fe=async r=>{try{let e=await Zu.readFile(r,"utf-8");return bM.default.parse(e)}catch{return null}},aE=class{constructor(e){this.projectsDir=e}getThreadsDir(e){return Zp.join(this.projectsDir,e,"threads")}async ensureThreadsDir(e){let t=this.getThreadsDir(e);try{await Zu.mkdir(t,{recursive:!0})}catch(n){throw new yu(`Failed to initialize threads directory for project ${e}`,n)}}getThreadFileName(e){return`${e.id}.yml`}async findThreadFile(e,t){try{let n=this.getThreadsDir(e),i=`${t}.yml`;try{return await Zu.access(Zp.join(n,i)),i}catch{}return(await Zu.readdir(n)).find(s=>s.endsWith(`-${t}.yml`))||null}catch(n){throw new yu(`Error finding thread ${t} in project ${e}`,n)}}async getById(e,t){try{let n=await this.findThreadFile(e,t);if(!n)return null;let i=this.getThreadsDir(e),a=Zp.join(i,n),o=await $fe(a);if(!o)return null;let s=ch(o,ZR);return s.projectId||(s.projectId=e),s!==o&&Mn(a,s),new bu(s)}catch(n){throw new yu(`Failed to read thread ${t} from project ${e}`,n)}}async save(e,t){await this.ensureThreadsDir(e);try{if(t.id||(t.id=crypto.randomUUID()),t.projectId||(t.projectId=e),t.projectId!==e)throw new Error(`Thread projectId mismatch: expected ${e}, got ${t.projectId}`);let n=this.getThreadsDir(e),i=this.getThreadFileName(t),a=Zp.join(n,i),o=await this.findThreadFile(e,t.id);if(o&&o!==i){let u=Zp.join(n,o);try{await Zu.unlink(u),console.log(`[THREAD-REPO] Migrated/renamed thread file: ${o} \u2192 ${i}`)}catch(l){console.warn(`[THREAD-REPO] Could not delete old thread file: ${o}`,l)}}let s={...t.serialize(),version:ZR.length+1},c=bM.default.stringify(s);return await Zu.writeFile(a,c,"utf-8"),t}catch(n){throw new yu(`Failed to save thread ${t.id} to project ${e}`,n)}}async listByProject(e){try{let t=this.getThreadsDir(e);try{await Zu.access(t)}catch{return[]}let n=await Zu.readdir(t);return(await Promise.all(n.filter(a=>a.endsWith(".yml")).map(async a=>{let o=await $fe(Zp.join(t,a));if(!o)return null;let s=o.projectId||e;return{id:o.id,username:o.username,projectId:s,name:o.name??"...",summary:o.summary??"",createdDate:o.createdDate??"",modifiedDate:o.modifiedDate??"",price:o.price??0,starring:o.starring??[],users:Array.isArray(o.users)?o.users.map(c=>typeof c=="string"?{userId:c}:c):o.username?[{userId:o.username}]:[],parentThreadId:o.parentThreadId,parentEventId:o.parentEventId,delegatedAgentName:o.delegatedAgentName,delegatedTask:o.delegatedTask}}))).filter(a=>!!a).sort((a,o)=>a.modifiedDate>o.modifiedDate?-1:1)}catch(t){throw new yu(`Failed to list threads for project ${e}`,t)}}async delete(e,t){try{let n=await this.findThreadFile(e,t);if(!n)return!1;let i=this.getThreadsDir(e);return await Zu.unlink(Zp.join(i,n)),!0}catch(n){throw new yu(`Failed to delete thread ${t} from project ${e}`,n)}}};var oE=class{constructor(e,t,n){this.projectRepository=e;this.projectsDir=t;this.threadFileService=n}repositoryCache=new Map;threadListCache=new Map;CACHE_TTL_MS=14400*1e3;loadingPromises=new Map;getThreadRepository(e){let t=this.repositoryCache.get(e);if(t)return t;if(!this.projectRepository.getProjectInfo(e))throw new Error(`Project '${e}' not found`);let i=new aE(this.projectsDir);return this.repositoryCache.set(e,i),i}clearCache(e){e?this.repositoryCache.delete(e):this.repositoryCache.clear()}async listThreads(e,t){let n=this.threadListCache.get(e);if(n&&Date.now()-n.timestamp<this.CACHE_TTL_MS)return n.data.filter(o=>rn(o,t)).sort((o,s)=>o.modifiedDate>s.modifiedDate?-1:1);let i=this.loadingPromises.get(e);if(i)return await i,this.listThreads(e,t);let a=this.loadThreadListFromDisk(e);this.loadingPromises.set(e,a);try{return(await a).filter(s=>rn(s,t)).sort((s,c)=>s.modifiedDate>c.modifiedDate?-1:1)}catch(o){throw this.threadListCache.delete(e),o}finally{this.loadingPromises.delete(e)}}async loadThreadListFromDisk(e){let n=await this.getThreadRepository(e).listByProject(e);return this.threadListCache.set(e,{data:n,timestamp:Date.now()}),n}updateThreadInCache(e,t){let n=this.threadListCache.get(e);if(!n)return;let i=n.data.findIndex(a=>a.id===t.id);i!==-1?n.data[i]=t:n.data.push(t)}removeThreadFromCache(e,t){let n=this.threadListCache.get(e);n&&(n.data=n.data.filter(i=>i.id!==t))}async getThread(e,t){return await this.getThreadRepository(e).getById(e,t)}async createThread(e,t,n){let i=this.getThreadRepository(e),a=new bu({id:crypto.randomUUID(),username:t,projectId:e,name:n||"",price:0}),o=await i.save(e,a);return this.updateThreadInCache(e,{id:o.id,username:o.username,projectId:o.projectId,name:o.name,summary:o.summary,createdDate:o.createdDate,modifiedDate:o.modifiedDate,price:o.price,starring:o.starring,users:o.users}),o}async updateThread(e,t,n){let i=this.getThreadRepository(e),a=await i.getById(e,t);if(!a){let c=this.threadListCache.get(e)?.data.find(u=>u.id===t);if(c)a=new bu({id:c.id,username:c.username,projectId:c.projectId,name:c.name,price:c.price});else throw new Error(`Thread '${t}' not found in project '${e}'`)}n.name!==void 0&&(a.name=n.name),n.summary!==void 0&&(a.summary=n.summary),n.users!==void 0&&(a.users=n.users);let o=await i.save(e,a);return this.updateThreadInCache(e,{id:o.id,username:o.username,projectId:o.projectId,name:o.name,summary:o.summary,createdDate:o.createdDate,modifiedDate:o.modifiedDate,price:o.price,starring:o.starring,users:o.users}),o}async starThread(e,t,n){let i=this.getThreadRepository(e),a=await i.getById(e,t);if(!a)throw new Error(`Thread '${t}' not found in project '${e}'`);a.starring.includes(n)||a.starring.push(n);let o=await i.save(e,a);return this.updateThreadInCache(e,{id:o.id,username:o.username,projectId:o.projectId,name:o.name,summary:o.summary,createdDate:o.createdDate,modifiedDate:o.modifiedDate,price:o.price,starring:o.starring,users:o.users}),o}async unstarThread(e,t,n){let i=this.getThreadRepository(e),a=await i.getById(e,t);if(!a)throw new Error(`Thread '${t}' not found in project '${e}'`);a.starring=a.starring.filter(s=>s!==n);let o=await i.save(e,a);return this.updateThreadInCache(e,{id:o.id,username:o.username,projectId:o.projectId,name:o.name,summary:o.summary,createdDate:o.createdDate,modifiedDate:o.modifiedDate,price:o.price,starring:o.starring,users:o.users}),o}async deleteThread(e,t){let i=await this.getThreadRepository(e).delete(e,t);return i&&(await this.threadFileService.deleteThreadFiles(e,t),this.removeThreadFromCache(e,t)),i}async saveThread(e,t){let i=await this.getThreadRepository(e).save(e,t);return this.updateThreadInCache(e,{createdDate:i.createdDate,delegatedAgentName:i.delegatedAgentName,delegatedTask:i.delegatedTask,id:i.id,modifiedDate:i.modifiedDate,name:i.name,parentEventId:i.parentEventId,parentThreadId:i.parentThreadId,price:i.price,projectId:i.projectId,starring:i.starring,summary:i.summary,username:i.username,users:i.users}),i}async listAllThreads(e){let t=this.threadListCache.get(e);if(t&&Date.now()-t.timestamp<this.CACHE_TTL_MS)return t.data.sort((a,o)=>a.modifiedDate>o.modifiedDate?-1:1);let n=this.loadingPromises.get(e);if(n)return await n,this.listAllThreads(e);let i=this.loadThreadListFromDisk(e);this.loadingPromises.set(e,i);try{return(await i).sort((o,s)=>o.modifiedDate>s.modifiedDate?-1:1)}catch(a){throw this.threadListCache.delete(e),a}finally{this.loadingPromises.delete(e)}}async exists(e,t){return await this.getThread(e,t)!==null}};var Mfe=vr(Pc(),1);import*as ba from"fs/promises";import*as X6 from"path";var jfe=5,Rfe=24,Nfe=100,Ffe={SHORT_THREADS:7,LONG_THREADS:30},sE=class{constructor(e,t){this.projectsConfigPath=e;this.logger=t}cleanupTimer=null;initialTimer=null;isRunning=!1;async start(){if(this.isRunning){this.log("Thread cleanup service already running");return}this.isRunning=!0,this.log("Starting thread cleanup service with user message-based retention"),this.initialTimer=setTimeout(async()=>{await this.performCleanup(),this.cleanupTimer=setInterval(async()=>{await this.performCleanup()},Rfe*60*60*1e3),this.log(`Thread cleanup scheduled every ${Rfe} hours`)},jfe*60*1e3),this.log(`Initial cleanup scheduled in ${jfe} minutes`)}async stop(){this.initialTimer&&(clearTimeout(this.initialTimer),this.initialTimer=null),this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=null),this.isRunning=!1,this.log("Thread cleanup service stopped (all timers cleared)")}async performCleanup(){let e=Date.now(),t=0,n=0,i=0;try{this.log("Starting thread cleanup...");let a=await ba.readdir(this.projectsConfigPath);this.log(`Found ${a.length} projects to scan`);for(let s of a)try{let c=X6.join(this.projectsConfigPath,s);if(!(await ba.lstat(c)).isDirectory())continue;let l=X6.join(c,"threads");try{await ba.access(l)}catch{continue}let{scanned:f,deleted:p,errors:d}=await this.cleanupProjectThreads(s,l);t+=f,n+=p,i+=d}catch(c){this.logError(`Error processing project ${s}: ${c}`),i++}let o=Date.now()-e;this.log(`Cleanup completed: ${n}/${t} threads deleted across all projects in ${o}ms (${i} errors)`)}catch(a){let o=Date.now()-e;this.logError(`Cleanup failed after ${o}ms: ${a}`)}}async cleanupProjectThreads(e,t){let n=0,i=0,a=0;try{let s=(await ba.readdir(t)).filter(c=>c.endsWith(".yml"));if(n=s.length,s.length===0)return{scanned:n,deleted:i,errors:a};this.log(`Scanning ${s.length} threads in project ${e}`);for(let c=0;c<s.length;c+=Nfe){let u=s.slice(c,c+Nfe),l=await this.processBatch(u,t,e);i+=l.deleted,a+=l.errors}i>0&&this.log(`Project ${e}: deleted ${i}/${n} expired threads`)}catch(o){this.logError(`Error scanning project ${e}: ${o}`),a++}return{scanned:n,deleted:i,errors:a}}async processBatch(e,t,n){let i=0,a=0;return await Promise.all(e.map(async o=>{let s=X6.join(t,o),c;try{let u=await ba.readFile(s,"utf-8");c=Mfe.parse(u)}catch(u){await ba.unlink(s),this.logError(`Error processing file ${o} in project ${n}: ${u}`)}if(!(!c||!c.modifiedDate)&&!(c.starring&&Array.isArray(c.starring)&&c.starring.length>0)&&this.shouldDeleteThread(c)){let u=this.countUserMessages(c.messages||[]),l=this.getDaysSinceModified(c.modifiedDate),f=c.id||o.replace(".yml","");await ba.unlink(s),await this.deleteThreadFiles(t,f),i++,this.logger.logThreadCleanup(n,o),console.log(`ThreadCleanup: Deleted thread ${f} and its files directory (${u} user messages, ${l} days old)`)}})),{deleted:i,errors:a}}shouldDeleteThread(e){if(!e||!e.modifiedDate)return!1;let n=this.countUserMessages(e.messages||[])<=3?Ffe.SHORT_THREADS:Ffe.LONG_THREADS;return this.getDaysSinceModified(e.modifiedDate)>n}countUserMessages(e){return e.filter(t=>t&&t.type==="message"&&t.role==="user").length}getDaysSinceModified(e){let t=new Date(e),i=new Date().getTime()-t.getTime();return Math.floor(i/(1e3*60*60*24))}async deleteThreadFiles(e,t){try{let n=X6.join(e,`${t}-files`);try{await ba.access(n),await ba.rm(n,{recursive:!0,force:!0}),console.log(`ThreadCleanup: Deleted files directory ${n}`)}catch(i){if(i.code!=="ENOENT")throw i}}catch(n){console.error(`ThreadCleanup: Error deleting files for ${t}:`,n)}}log(e){let t=new Date().toISOString();console.log(`[${t}] ThreadCleanup: ${e}`)}logError(e){let t=new Date().toISOString();console.error(`[${t}] ThreadCleanup ERROR: ${e}`)}async forceCleanup(){this.log("Manual cleanup triggered"),await this.performCleanup()}};import*as qi from"path";import*as Jp from"fs";import*as xa from"fs/promises";var cE=class{constructor(e){this.projectsDir=e}getThreadFilesDir(e,t){return qi.join(this.projectsDir,e,"threads",`${t}-files`)}async ensureThreadFilesDir(e,t){let n=this.getThreadFilesDir(e,t);Jp.existsSync(n)||await xa.mkdir(n,{recursive:!0})}async listFiles(e,t){await this.ensureThreadFilesDir(e,t);let n=this.getThreadFilesDir(e,t),i=await xa.readdir(n);return await Promise.all(i.map(async o=>{let s=qi.join(n,o),c=await xa.stat(s);return{filename:o,size:c.size,lastModified:c.mtime.toISOString()}}))}async saveFile(e,t,n,i){let a=this.getThreadFilesDir(e,t);await xa.mkdir(a,{recursive:!0});let o=qi.join(a,n);await xa.writeFile(o,i)}async getFile(e,t,n){await this.ensureThreadFilesDir(e,t);let i=this.getThreadFilesDir(e,t),a=qi.join(i,n),o=qi.resolve(a),s=qi.resolve(i);if(!o.startsWith(s))throw new Error("Access denied: invalid file path");if(!Jp.existsSync(a))throw new Error(`File '${n}' not found`);return await xa.readFile(a)}async getFilePath(e,t,n){await this.ensureThreadFilesDir(e,t);let i=this.getThreadFilesDir(e,t),a=qi.join(i,n),o=qi.resolve(a),s=qi.resolve(i);if(!o.startsWith(s))throw new Error("Access denied: invalid file path");if(!Jp.existsSync(a))throw new Error(`File '${n}' not found`);return a}fileExists(e,t,n){let i=this.getThreadFilesDir(e,t),a=qi.join(i,n),o=qi.resolve(a),s=qi.resolve(i);return o.startsWith(s)?Jp.existsSync(a):!1}async deleteFile(e,t,n){await this.ensureThreadFilesDir(e,t);let i=this.getThreadFilesDir(e,t),a=qi.join(i,n),o=qi.resolve(a),s=qi.resolve(i);if(!o.startsWith(s))throw new Error("Access denied: invalid file path");if(!Jp.existsSync(a))throw new Error(`File '${n}' not found`);await xa.unlink(a)}async deleteThreadFiles(e,t){try{let n=this.getThreadFilesDir(e,t);Jp.existsSync(n)&&(await xa.rm(n,{recursive:!0,force:!0}),console.log(`Deleted thread files directory: ${n}`))}catch(n){console.error(`Error deleting thread files for ${t}:`,n)}}};var Lfe=vr(Go(),1);var uE=class{constructor(e,t,n,i){this.threadRepository=t;this.projectId=n;this.interactor=i;this.username=e.username}activeThread$=new Lfe.BehaviorSubject(null);isKilled=!1;activeThread=this.activeThread$.asObservable();username;async kill(){this.isKilled=!0,this.activeThread$.complete()}async create(e){let t=new bu({id:"",username:this.username,name:e??"",price:0});return this.activeThread$.next(t),t}async select(e){let t=await this.threadRepository.getById(this.projectId,e);if(!t)throw new Error(`Thread ${e} not found`);return this.activeThread$.next(t),t}async save(e){let t=this.activeThread$.value;if(!t){console.error(`No thread existing when save attempt with name '${e}'`);return}e&&(t.name=e);let n=await this.threadRepository.save(this.projectId,t);this.activeThread$.next(n)}async autoSave(e){if(this.isKilled){console.log("Autosave skipped: service has been killed");return}let t=this.activeThread$.value;if(!t||t.messagesLength==0){console.log(`Autosave of an empty or falsy thread aborted, threadId: ${t?.id}, user: ${this.username}`);return}try{e&&(t.name=e),await this.threadRepository.save(this.projectId,t),this.interactor&&this.interactor.sendEvent(new uc({threadId:t.id,name:t.name||void 0}))}catch(n){console.log("Autosave failed (service may have been killed):",n instanceof Error?n.message:n)}}async truncateAtUserMessage(e){let t=this.activeThread$.value;if(!t)return console.error("No active thread available for truncation"),!1;let n=t.truncateAtUserMessage(e);return n||this.interactor?.warn("Failed to truncate thread."),n}getCurrentThread(){return this.activeThread$.value}};async function qfe(r,e){let t=e.project.selectedProject,n=e.user.getUserData(t.name),i=await QS(t.config.path,r,n),a=new k0({...i,root:t.config.path,name:t.name},e.user.username);return console.log(`[BUILD_CONTEXT] Context for '${a.project.name}' \u2192 root: ${a.project.root}, desc: ${a.project.description?.length||0} chars`),a}var lE=class extends Fe{constructor(t,n){super({commandWord:"select-project",description:"Select an existing project"});this.interactor=t;this.services=n}async handle(t,n){try{let i=this.getSubCommand(t);return await this.selectProject(i)??n}catch(i){return this.interactor.error(`Invalid project selection because: ${i.toString()}`),n}}async selectProject(t){return this.services.project.selectProject(t),this.services.project.selectedProject?qfe(this.interactor,this.services):null}};var fE=class extends Fe{constructor(t,n,i){super({commandWord:"add",description:"Add a new integration configuration. User level is default, use --project/-p for project level."});this.interactor=t;this.service=n;this.editHandler=i}async handle(t,n){let a=!!Tt(this.getSubCommand(t),[{key:"project",alias:"p"}]).project,o=a?"project":"user",s=this.service.getMergedIntegrations(),c=Object.keys(s),u=Xf.filter(h=>!c.includes(h));if(u.length===0)return this.interactor.displayText(`All available integrations (${Xf.join(", ")}) are already configured.`),n;let l=await this.interactor.chooseOption(u.sort(),"Select integration to add:",`Available integrations to configure:
877
+ `)):""}loadMemoriesFrom(e){this.memories=[],this.userMemoriesPath=this.readMemories(this.userMemoriesPath)?this.userMemoriesPath:void 0;let t=e?.configPath?eE.join(e.configPath,vM):void 0;this.projectMemoriesPath=this.readMemories(t)?t:void 0,e&&this.checkInit()}readMemories(e){if(!e)return!1;try{if(!qit(e)){let n=xfe.stringify({memories:[]});zit(e,n)}let t=ta(e);return t?(this.memories.push(...t.memories),!0):!1}catch{return!1}}checkInit(){if(!this.userMemoriesPath||!this.projectMemoriesPath)throw new Error("user or project path not set for memory service")}saveMemories(){this.checkInit();let e=this.memories.filter(n=>n.level==="USER"),t=this.memories.filter(n=>n.level==="PROJECT");Mn(this.userMemoriesPath,{memories:e}),Mn(this.projectMemoriesPath,{memories:t})}};import*as _fe from"crypto";import*as Va from"node:fs/promises";import*as Fc from"path";var bm=class r{constructor(e,t,n){this.repository=e;this.defaultProject=t;this.isForcedMode=n}maskingService=new B2;listProjects(){let e=this.repository.listProjects();return this.isForcedMode&&this.defaultProject?e.filter(t=>t===this.defaultProject).map(t=>{let n=this.repository.getConfig(t);return{name:t,volatile:n?.volatile}}):e.map(t=>{let n=this.repository.getConfig(t);return{name:t,volatile:n?.volatile}})}getDefaultProject(){return this.defaultProject||null}getForcedMode(){return this.isForcedMode}getProject(e){this.checkAgainstForced(e);let t=this.repository.getConfig(e);if(t)return{name:e,config:t};if(!this.isForcedMode&&this.defaultProject){let n=process.cwd(),i=r.generateProjectId(n),a=Fc.basename(n);if(e===a||e===i||e===this.defaultProject){console.log(`[PROJECT_SERVICE] Creating volatile project for '${e}' at ${n}`);let o=this.getOrCreateVolatileProject(n);if(t=this.repository.getConfig(o),t)return{name:o,config:t}}}return null}exists(e){return this.checkAgainstForced(e),this.repository.exists(e)}createProject(e,t){if(this.checkAgainstForced(e),!e||!t)throw new Error("Project name and path are required");if(!this.repository.createProject(e,t))throw new Error(`Project '${e}' already exists`)}updateProjectConfig(e,t){if(this.checkAgainstForced(e),!this.repository.exists(e))throw new Error(`Project '${e}' does not exist`);this.repository.saveConfig(e,t)}deleteProject(e){if(this.checkAgainstForced(e),!this.repository.deleteProject(e))throw new Error(`Project '${e}' does not exist`)}getProjectConfigForClient(e){this.checkAgainstForced(e);let t=this.repository.getConfig(e);return t?this.maskingService.maskConfig(t):null}updateProjectConfigFromClient(e,t){this.checkAgainstForced(e);let n=this.repository.getConfig(e);if(!n)throw new Error(`Project '${e}' does not exist`);let i=this.maskingService.unmaskConfig(t,n);this.repository.saveConfig(e,i)}checkAgainstForced(e){if(this.isForcedMode&&this.defaultProject&&this.defaultProject!==e)throw Error(`Project selection outside of ${this.defaultProject} not allowed`)}getOrCreateVolatileProject(e){let t=r.generateProjectId(e);if(this.repository.exists(t))return t;this.repository.createProject(t,e);let n=this.repository.getConfig(t);return n&&(n.volatile=!0,n.createdAt=Date.now(),this.repository.saveConfig(t,n)),t}async registerWorktreeProject(e,t,n){let i=this.repository.getConfig(n),a=i?{...i,path:t,volatile:void 0,createdAt:void 0}:{version:1,path:t,integration:{},storage:{type:"file"},agents:[]};this.repository.createProject(e,t),this.repository.saveConfig(e,a);let o=this.repository.getProjectInfo(n);if(o){let s=this.repository.getProjectInfo(e);if(s)for(let c of["agents","prompts","schedulers","memories"]){let u=Fc.join(o.configPath,c),l=Fc.join(s.configPath,c);try{await Va.access(u),await Va.symlink(u,l)}catch{}}}}async unregisterWorktreeProject(e){let t=this.repository.getProjectInfo(e);if(!t)return;let n=e.lastIndexOf("__");if(n!==-1){let i=e.substring(0,n),a=this.repository.getProjectInfo(i);a&&await this.migrateThreadsToParent(t.configPath,a.configPath)}await Va.rm(t.configPath,{recursive:!0,force:!0})}async migrateThreadsToParent(e,t){let n=Fc.join(e,"threads"),i=Fc.join(t,"threads");try{await Va.access(n)}catch{return}await Va.mkdir(i,{recursive:!0});let a=await Va.readdir(n);for(let o of a){let s=Fc.join(n,o),c=Fc.join(i,o);try{await Va.access(c)}catch{await Va.rename(s,c)}}}static generateProjectId(e){let t=Fc.basename(e),n=_fe.createHash("sha256").update(e).digest("hex").substring(0,8);return`${t}_${n}`}};var kfe=vr(Go(),1);import*as xm from"node:path";import*as Efe from"node:os";import{mkdirSync as Uit}from"fs";var Bit="projects",Sfe="project.yaml",wm=class{constructor(e,t,n){this.interactor=e;this.projectService=t;let i=xm.join(Efe.userInfo().homedir,".coday");this.projectsConfigPath=xm.join(n??i,Bit),Uit(this.projectsConfigPath,{recursive:!0}),this.projects=this.projectService.listProjects().map(a=>a.name)}projectsConfigPath;maskingService=new B2;projects;selectedProjectBehaviorSubject=new kfe.BehaviorSubject(null);selectedProject$=this.selectedProjectBehaviorSubject.asObservable();selectProject(e){let t=xm.join(this.projectsConfigPath,e),n=xm.join(t,Sfe),i=this.projectService.getProject(e)?.config;if(!i?.path){console.log(`[PROJECT_STATE_SERVICE] ERROR: No project path in config for '${e}'`),this.interactor.error("Invalid selection, project path needed \u{1F622}.");return}let o={name:e,config:i,configPath:t};console.log(`[PROJECT_STATE_SERVICE] Selected '${e}' \u2192 ${i.path}`),this.updateSelectedProject(o),this.interactor.displayText(`Project local configuration used: ${n}`)}updateSelectedProject(e){this.selectedProjectBehaviorSubject.next(e)}get selectedProject(){return this.selectedProjectBehaviorSubject.value}save(e){let t=this.selectedProjectBehaviorSubject.value;if(!t){this.interactor.error("No current project selected, save not possible");return}let n={...t.config,...e};Mn(xm.join(t.configPath,Sfe),n),t.config=n,this.updateSelectedProject(t)}getConfigForClient(){let e=this.selectedProjectBehaviorSubject.value;return e?this.maskingService.maskConfig(e.config):null}updateConfigFromClient(e){let t=this.selectedProjectBehaviorSubject.value;if(!t){this.interactor.error("No current project selected, update not possible");return}let n=this.maskingService.unmaskConfig(e,t.config);this.save(n)}};import*as Gu from"node:path";import*as Tfe from"node:os";import{randomUUID as Wit}from"node:crypto";import{existsSync as W2,mkdirSync as Vit,readdirSync as Cfe,unlinkSync as Git}from"fs";import*as yM from"node:path";import*as Afe from"node:os";function Hit(r){return r.replace(/[^a-zA-Z0-9]/g,"_")}function _m(r,e){try{let t=yM.join(Afe.userInfo().homedir,".coday"),n=Hit(r),i=yM.join(e??t,"users",n,"user.yaml"),a=ta(i);return a?a.groups?.includes("CODAY_ADMIN")??!1:!1}catch{return!1}}var tE=class{codayConfigDir;projectService;constructor(e,t){let n=Gu.join(Tfe.userInfo().homedir,".coday");this.codayConfigDir=e??n,this.projectService=t}getProjectPath(e){if(this.projectService)return this.projectService.getProject(e)?.config.path}async getOrCreatePromptsDir(e,t){let n;if(t==="local")n=Gu.join(this.codayConfigDir,"projects",e,"prompts");else{let i=this.getProjectPath(e);if(!i)throw new Error("Project path not configured, cannot access project prompts");let a=await f2({text:"coday.yaml",root:i});if(a.length===0)throw new Error(`coday.yaml not found in project path: ${i}`);let o=Gu.dirname(a[0]);n=Gu.join(i,o,"prompts")}return W2(n)||(Vit(n,{recursive:!0}),console.log(`[PROMPT] Created prompts directory: ${n}`)),n}async getOrCreatePromptFilePath(e,t,n){let i=await this.getOrCreatePromptsDir(e,n);return Gu.join(i,`${t}.yml`)}async findPromptSource(e,t){let n=await this.getOrCreatePromptFilePath(e,t,"local");if(W2(n))return"local";if(this.projectService)try{let i=await this.getOrCreatePromptFilePath(e,t,"project");if(W2(i))return"project"}catch{}return null}async findProjectForPrompt(e){let t=Gu.join(this.codayConfigDir,"projects");if(!W2(t))return null;let n=Cfe(t,{withFileTypes:!0}).filter(i=>i.isDirectory()).map(i=>i.name);for(let i of n){let a=Gu.join(this.codayConfigDir,"projects",i,"prompts",`${e}.yml`);if(W2(a))return i;if(this.projectService)try{let o=await this.getOrCreatePromptFilePath(i,e,"project");if(W2(o))return i}catch{}}return null}validatePlaceholders(e){let t=/\{\{(\w+)\}\}/g,n=[],i=/^[A-Za-z][A-Za-z0-9-]*$/;if(e.forEach(a=>{let o;for(;(o=t.exec(a))!==null;){let s=o[1];s&&s!=="PARAMETERS"&&!i.test(s)&&n.push(s)}}),n.length>0)throw new Error(`Invalid parameter keys: ${n.join(", ")}. Keys must start with a letter and contain only letters, digits, and hyphens.`)}async create(e,t,n="local"){try{this.validatePlaceholders(t.commands);let i=Wit(),a={...t,id:i,source:n,createdAt:new Date().toISOString(),parameterFormat:this.getParameterFormat(t.commands)},o=await this.getOrCreatePromptFilePath(e,i,n);if(W2(o))throw new Error(`Prompt with ID ${i} already exists`);return Mn(o,a),console.log(`[PROMPT] Created prompt ${i} in ${n} for project ${e}`),a}catch(i){throw new Error(`Failed to create prompt: ${i instanceof Error?i.message:"Unknown error"}`)}}async get(e,t){try{let n=await this.findPromptSource(e,t);if(!n)return null;let i=await this.getOrCreatePromptFilePath(e,t,n),a=ta(i);return a?(a.source||(a.source=n),a):null}catch(n){return console.error(`Failed to get prompt ${t}:`,n),null}}async getById(e){try{let t=await this.findProjectForPrompt(e);if(!t)return null;let n=await this.get(t,e);return n?{prompt:n,projectName:t}:null}catch(t){return console.error(`Failed to get prompt ${e}:`,t),null}}async update(e,t,n,i){try{let a=await this.get(e,t);if(!a)return null;if(n.webhookEnabled!==void 0&&n.webhookEnabled!==a.webhookEnabled&&!_m(i,this.codayConfigDir))throw new Error("Only CODAY_ADMIN can enable/disable webhook for prompts");let{id:o,createdAt:s,source:c,...u}=n;n.commands&&this.validatePlaceholders(n.commands);let l={...a,...u,updatedAt:new Date().toISOString()};n.commands&&(l.parameterFormat=this.getParameterFormat(n.commands));let f=await this.getOrCreatePromptFilePath(e,t,a.source);return Mn(f,l),console.log(`[PROMPT] Updated prompt ${t} (${a.source}) by user ${i}`),l}catch(a){throw console.error(`Failed to update prompt ${t}:`,a),a}}async delete(e,t){try{let n=await this.findPromptSource(e,t);if(!n)return!1;let i=await this.getOrCreatePromptFilePath(e,t,n);return Git(i),console.log(`[PROMPT] Deleted prompt ${t} from ${n}`),!0}catch(n){return console.error(`Failed to delete prompt ${t}:`,n),!1}}getParameterFormat(e){if(e.some(a=>/\{\{PARAMETERS\}\}/.test(a)))return"";let n=/\{\{(\w+)\}\}/g,i=new Set;return e.forEach(a=>{let o;for(;(o=n.exec(a))!==null;){let s=o[1];s&&s!=="PARAMETERS"&&i.add(s)}}),i.size===0?"":Array.from(i).map(a=>`${a}=""`).join(" ")}async list(e){try{let t=[],n=["local"];this.projectService&&n.push("project");for(let i of n)try{let a=await this.getOrCreatePromptsDir(e,i);if(!W2(a))continue;let s=Cfe(a).filter(c=>c.endsWith(".yml"));for(let c of s){let u=c.replace(".yml",""),l=await this.get(e,u);l&&t.push({id:l.id,name:l.name,description:l.description,webhookEnabled:l.webhookEnabled,createdBy:l.createdBy,createdAt:l.createdAt,updatedAt:l.updatedAt,source:l.source||i,parameterFormat:l.parameterFormat})}}catch(a){console.log(`[PROMPT] Could not access ${i} prompts for ${e}:`,a)}return t.push(...j3),t.sort((i,a)=>new Date(a.createdAt).getTime()-new Date(i.createdAt).getTime())}catch(t){return console.error(`Failed to list prompts for project ${e}:`,t),[]}}async enableWebhook(e,t,n){return this.update(e,t,{webhookEnabled:!0},n)}async disableWebhook(e,t,n){return this.update(e,t,{webhookEnabled:!1},n)}};var Pfe=vr(Go(),1),rE=class{constructor(e){this.promptService=e}threadCodayManager;threadService;codayOptions;logger;initialize(e,t,n,i){this.threadCodayManager=e,this.threadService=t,this.codayOptions=n,this.logger=i}processCommands(e,t){let n;if(typeof t=="string"){let a=e.some(s=>/\{\{PARAMETERS\}\}/.test(s));if(e.some(s=>/\{\{(?!PARAMETERS\}\})\w+\}\}/.test(s)))throw new Error("Prompt contains structured placeholders ({{key}}). Use an object parameter instead of a string.");a?n=e.map(s=>s.replace(/\{\{PARAMETERS\}\}/g,t)):n=e.map((s,c)=>c===0?`${s} ${t}`.trim():s)}else typeof t=="object"&&t!==null?n=e.map(a=>{let o=a;return Object.entries(t).forEach(([s,c])=>{let u=`{{${s}}}`;o=o.replaceAll(u,String(c))}),o}):n=[...e];let i=new Set;if(n.forEach(a=>{let o=a.match(/\{\{(\w+)\}\}/g);o&&o.forEach(s=>i.add(s))}),i.size>0){let a=Array.from(i).map(o=>o.replace(/[{}]/g,"")).join(", ");throw new Error(`Missing required parameters: ${a}`)}return n}async executePrompt(e,t,n,i,a){if(!this.threadCodayManager||!this.threadService||!this.codayOptions||!this.logger)throw new Error("PromptExecutionService not initialized. Call initialize() first.");let{title:o,awaitFinalAnswer:s=!1,projectName:c}=a||{},u,l;if(c){if(l=c,u=await this.promptService.get(l,e),!u)throw new Error(`Prompt ${e} not found in project ${l}`)}else{let y=await this.promptService.getById(e);if(!y)throw new Error(`Prompt not found: ${e}`);u=y.prompt,l=y.projectName}if(i==="webhook"&&!u.webhookEnabled)throw new Error(`Prompt ${e} is not enabled for webhook execution`);if(!u.commands||u.commands.length===0)throw new Error("Prompt has no commands configured");let f=this.processCommands(u.commands,t);if(!n)throw new Error("Username is required");let d=(await this.threadService.createThread(l,n,o)).id;console.log(`[PROMPT_EXEC] Created new thread: ${d} for ${i} execution`);let m={...this.codayOptions,oneshot:!0,project:l,thread:d,prompts:f};console.log(`[PROMPT_EXEC] Creating instance for ${i} execution with ${f.length} prompts:`,f);let h=this.threadCodayManager.createWithoutConnection(d,l,n,m);h.prepareCoday();let g=h.coday.interactor,v={project:l,title:o??"Untitled",username:n,clientId:d,promptCount:f.length,awaitFinalAnswer:!!s,promptName:u.name,promptId:u.id,executionMode:i};if(i==="webhook"?this.logger.logWebhook(v):this.logger.logWebhook({...v,webhookName:u.name,webhookUuid:u.id}),s){let y=[],x=g.events.pipe((0,Pfe.filter)(k=>(console.log(`[PROMPT_EXEC] Received event type: ${k.type}, role: ${k instanceof Rt?k.role:"N/A"}`),k instanceof Rt&&k.role==="assistant"&&!!k.name))).subscribe(k=>{y.push(k)});try{await h.coday.run(),x.unsubscribe();let k=y[y.length-1];return await this.threadCodayManager.cleanup(d),{threadId:d,lastEvent:k}}catch(k){x.unsubscribe();let S=k instanceof Error?k.message:"Unknown error";throw this.logger.logWebhookError({error:`Prompt execution failed: ${S}`,username:n,project:l,clientId:d}),console.error("[PROMPT_EXEC] Error waiting for prompt completion:",k),await this.threadCodayManager.cleanup(d),k}}else return h.coday.run().catch(y=>{console.error("[PROMPT_EXEC] Error during prompt Coday run:",y)}),setTimeout(()=>{this.threadCodayManager.cleanup(d).catch(y=>{console.error("[PROMPT_EXEC] Error cleaning up prompt thread after timeout:",y)})},300*1e3),{threadId:d}}};var Y6=vr(Pc(),1);import*as ai from"fs";import*as Sm from"path";import{randomUUID as Zit}from"node:crypto";var nE=class{constructor(e,t,n){this.logger=e;this.promptService=t;this.codayConfigDir=n}schedulers=new Map;checkInterval;CHECK_INTERVAL_MS=3e4;promptExecutionService;initializeExecution(e){this.promptExecutionService=e}async initialize(){console.log("[SCHEDULER] Initializing SchedulerService..."),await this.loadAllSchedulers(),this.startScheduler(),console.log(`[SCHEDULER] SchedulerService initialized with ${this.schedulers.size} schedulers`)}stop(){this.checkInterval&&(clearInterval(this.checkInterval),this.checkInterval=void 0,console.log("[SCHEDULER] SchedulerService stopped"))}async loadAllSchedulers(){this.schedulers.clear();let e=Sm.join(this.codayConfigDir,"projects");if(!ai.existsSync(e))return;let t=ai.readdirSync(e,{withFileTypes:!0}).filter(n=>n.isDirectory()).map(n=>n.name);for(let n of t)try{let i=await this.loadProjectSchedulers(n);for(let a of i)this.schedulers.set(a.id,a)}catch(i){console.error(`[SCHEDULER] Failed to load schedulers for project ${n}:`,i)}}async loadProjectSchedulers(e){let t=this.getSchedulersDir(e);if(!ai.existsSync(t))return[];let n=ai.readdirSync(t),i=[];for(let a of n)if(a.endsWith(".yml"))try{let o=Sm.join(t,a),s=ai.readFileSync(o,"utf-8"),c=Y6.parse(s),u=this.calculateNextRunSkippingMissed(c),l=u.occurrenceCount!==c.occurrenceCount;c.nextRun=u.nextRun,c.occurrenceCount=u.occurrenceCount,l&&await this.saveScheduler(c,e),i.push(c)}catch(o){console.error(`[SCHEDULER] Failed to load scheduler from ${a}:`,o)}return i}startScheduler(){this.checkInterval=setInterval(()=>{this.checkAndExecuteSchedulers()},this.CHECK_INTERVAL_MS),this.checkAndExecuteSchedulers()}async checkAndExecuteSchedulers(){for(let e of this.schedulers.values())e.enabled&&dce(e.schedule,e.nextRun??null,e.occurrenceCount??0)&&this.executeScheduler(e).catch(t=>{console.error(`[SCHEDULER] Failed to execute scheduler ${e.id}:`,t)})}async executeSchedulerInternal(e,t,n){if(!this.promptExecutionService)throw new Error("PromptExecutionService not initialized");console.log(`[SCHEDULER] Executing scheduler "${e.name}" (${e.id}) [${n}]`);let i=e.parameters;e.parameters&&typeof e.parameters=="object"&&Object.keys(e.parameters).length===1&&"PARAMETERS"in e.parameters&&(i=String(e.parameters.PARAMETERS));let a=await this.promptExecutionService.executePrompt(e.promptId,i,e.createdBy,"scheduled",{title:n==="scheduled"?`Scheduled: ${e.name}`:`Manual: ${e.name}`,awaitFinalAnswer:!1,projectName:t});return console.log(`[SCHEDULER] Scheduler "${e.name}" executed successfully. Thread: ${a.threadId}`),a.threadId}async executeScheduler(e){let t=new Date().toISOString();console.log(`[SCHEDULER] Executing scheduler "${e.name}" (${e.id})`);let n=this.findProjectForScheduler(e.id);if(!n){console.error(`[SCHEDULER] Cannot find project for scheduler ${e.id}, skipping execution`);return}let i,a,o;e.lastRun=t,e.occurrenceCount=(e.occurrenceCount??0)+1,e.nextRun=uh(e.schedule,new Date,e.occurrenceCount);try{await this.saveScheduler(e,n),console.log(`[SCHEDULER] Next execution for "${e.name}": ${e.nextRun}`),this.schedulers.set(e.id,e),a=await this.executeSchedulerInternal(e,n,"scheduled"),i=!0}catch(s){i=!1,o=s instanceof Error?s.message:String(s),console.error(`[SCHEDULER] Scheduler "${e.name}" failed:`,s)}this.logger.logTriggerExecution({triggerId:e.id,triggerName:e.name,webhookUuid:e.promptId,projectName:n,success:i,threadId:a,error:o})}validateSchedule(e){return pce(e)}calculateNextRunSkippingMissed(e){let t=new Date,n=e.occurrenceCount??0,i=e.nextRun;if(!i)return{nextRun:uh(e.schedule,t,n),occurrenceCount:n};if(new Date(i)>=t)return{nextRun:i,occurrenceCount:n};let a=1e3,o=0,s=0;for(;o<a;){if(n++,s++,i=uh(e.schedule,t,n),!i)return s>0&&console.log(`[SCHEDULER] Scheduler "${e.name}" (${e.id}) expired after skipping ${s} missed occurrence(s)`),{nextRun:null,occurrenceCount:n};if(new Date(i)>=t)return s>0&&console.log(`[SCHEDULER] Scheduler "${e.name}" (${e.id}) skipped ${s} missed occurrence(s), next run: ${i}`),{nextRun:i,occurrenceCount:n};o++}return console.warn(`[SCHEDULER] Could not find future nextRun for scheduler ${e.id} after ${a} iterations`),{nextRun:null,occurrenceCount:n}}getSchedulersDir(e){return Sm.join(this.codayConfigDir,"projects",e,"schedulers")}getSchedulerFilePath(e,t){return Sm.join(this.getSchedulersDir(e),`${t}.yml`)}findProjectForScheduler(e){let t=Sm.join(this.codayConfigDir,"projects");if(!ai.existsSync(t))return null;let n=ai.readdirSync(t,{withFileTypes:!0}).filter(i=>i.isDirectory()).map(i=>i.name);for(let i of n){let a=this.getSchedulerFilePath(i,e);if(ai.existsSync(a))return i}return null}canAccessScheduler(e,t){return e.createdBy===t?!0:_m(t,this.codayConfigDir)}async listSchedulers(e,t){return(await this.loadProjectSchedulers(e)).filter(i=>this.canAccessScheduler(i,t)).map(i=>({id:i.id,name:i.name,enabled:i.enabled,promptId:i.promptId,schedule:i.schedule,parameters:i.parameters,lastRun:i.lastRun,nextRun:i.nextRun,createdBy:i.createdBy}))}async getScheduler(e,t,n){let i=this.getSchedulerFilePath(e,t);if(!ai.existsSync(i))return null;try{let a=ai.readFileSync(i,"utf-8"),o=Y6.parse(a),s=this.calculateNextRunSkippingMissed(o);return o.nextRun=s.nextRun,o.occurrenceCount=s.occurrenceCount,n&&!this.canAccessScheduler(o,n)?(console.log(`[SCHEDULER] Access denied for user ${n} to scheduler ${t}`),null):o}catch(a){return console.error(`[SCHEDULER] Failed to load scheduler ${t}:`,a),null}}async createScheduler(e,t,n){let i=this.validateSchedule(t.schedule);if(!i.valid)throw new Error(`Invalid schedule: ${i.error}`);if(!await this.promptService.getById(t.promptId))throw new Error(`Prompt not found: ${t.promptId}`);let o={id:Zit(),name:t.name,enabled:t.enabled??!0,promptId:t.promptId,schedule:t.schedule,parameters:t.parameters,createdBy:n,createdAt:new Date().toISOString(),nextRun:uh(t.schedule,new Date,0),occurrenceCount:0};return await this.saveScheduler(o,e),this.schedulers.set(o.id,o),console.log(`[SCHEDULER] Created scheduler "${o.name}" (${o.id}) for project ${e}`),o}async updateScheduler(e,t,n,i){let a=await this.getScheduler(e,t,i);if(!a)throw new Error(`Scheduler not found or access denied: ${t}`);if(console.log(`[SCHEDULER] Updating scheduler ${t} by user ${i}`),n.name!==void 0&&(a.name=n.name),n.enabled!==void 0&&(a.enabled=n.enabled),n.parameters!==void 0&&(a.parameters=n.parameters),n.promptId!==void 0){if(!await this.promptService.getById(n.promptId))throw new Error(`Prompt not found: ${n.promptId}`);a.promptId=n.promptId}if(n.schedule!==void 0){let o=this.validateSchedule(n.schedule);if(!o.valid)throw new Error(`Invalid schedule: ${o.error}`);a.schedule=n.schedule,a.occurrenceCount=0,a.nextRun=uh(n.schedule,new Date,0)}return await this.saveScheduler(a,e),this.schedulers.set(a.id,a),console.log(`[SCHEDULER] Updated scheduler "${a.name}" (${a.id})`),a}async deleteScheduler(e,t,n){if(!await this.getScheduler(e,t,n))return!1;let a=this.getSchedulerFilePath(e,t);return ai.unlinkSync(a),this.schedulers.delete(t),console.log(`[SCHEDULER] Deleted scheduler ${t} by user ${n}`),!0}async enableScheduler(e,t,n){return this.updateScheduler(e,t,{enabled:!0},n)}async disableScheduler(e,t,n){return this.updateScheduler(e,t,{enabled:!1},n)}async runSchedulerNow(e,t,n){let i=await this.getScheduler(e,t,n);if(!i)throw new Error(`Scheduler not found or access denied: ${t}`);let a=await this.executeSchedulerInternal(i,e,"manual");return i.lastRun=new Date().toISOString(),await this.saveScheduler(i,e),this.schedulers.set(i.id,i),this.logger.logTriggerExecution({triggerId:i.id,triggerName:i.name,webhookUuid:i.promptId,projectName:e,success:!0,threadId:a}),a}async saveScheduler(e,t){if(!t&&(t=this.findProjectForScheduler(e.id),!t))throw new Error(`Cannot find project for scheduler ${e.id}`);let n=this.getSchedulersDir(t);ai.mkdirSync(n,{recursive:!0});let i=this.getSchedulerFilePath(t,e.id),a=Y6.stringify(e);ai.writeFileSync(i,a,"utf-8")}};import*as Mc from"node:path";import*as Ofe from"node:os";import{existsSync as Dfe,lstatSync as Jit,mkdirSync as Ife,readdirSync as Kit}from"fs";var iE=class r{projectsConfigPath;static PROJECT_FILENAME="project.yaml";constructor(e){let t=Mc.join(Ofe.userInfo().homedir,".coday");this.projectsConfigPath=Mc.join(e??t,"projects"),Ife(this.projectsConfigPath,{recursive:!0})}listProjects(){return Kit(this.projectsConfigPath).filter(t=>Jit(Mc.join(this.projectsConfigPath,t)).isDirectory())}getProjectInfo(e){let t=Mc.join(this.projectsConfigPath,e),n=Mc.join(t,r.PROJECT_FILENAME);return Dfe(n)?{name:e,configPath:t}:null}exists(e){return this.getProjectInfo(e)!==null}getConfig(e){let t=this.getProjectInfo(e);if(!t)return console.log(`[PROJECT_REPO] No project info found for: '${e}'`),null;let n=Mc.join(t.configPath,r.PROJECT_FILENAME),i=ta(n);if(!i)return console.log(`[PROJECT_REPO] Failed to load config for '${e}' from ${n}`),null;let a=ch(i,hce);return a!==i&&(console.log(`[PROJECT_REPO] Config migrated for '${e}', saving...`),Mn(n,a)),a}saveConfig(e,t){let n=this.getProjectInfo(e);if(!n)throw new Error(`Project '${e}' does not exist`);let i=Mc.join(n.configPath,r.PROJECT_FILENAME);Mn(i,t)}createProject(e,t){let n=Mc.join(this.projectsConfigPath,e),i=Mc.join(n,r.PROJECT_FILENAME);return Dfe(i)?!1:(console.log(`[PROJECT_REPO] Creating project '${e}' with path: ${t}`),Ife(n,{recursive:!0}),Mn(i,{version:1,path:t,integration:{},storage:{type:"file"},agents:[]}),console.log(`[PROJECT_REPO] Project '${e}' created successfully`),!0)}deleteProject(e){return this.getProjectInfo(e),!1}};var bM=vr(Pc(),1);import{promises as Zu}from"fs";import Zp from"path";var $fe=async r=>{try{let e=await Zu.readFile(r,"utf-8");return bM.default.parse(e)}catch{return null}},aE=class{constructor(e){this.projectsDir=e}getThreadsDir(e){return Zp.join(this.projectsDir,e,"threads")}async ensureThreadsDir(e){let t=this.getThreadsDir(e);try{await Zu.mkdir(t,{recursive:!0})}catch(n){throw new yu(`Failed to initialize threads directory for project ${e}`,n)}}getThreadFileName(e){return`${e.id}.yml`}async findThreadFile(e,t){try{let n=this.getThreadsDir(e),i=`${t}.yml`;try{return await Zu.access(Zp.join(n,i)),i}catch{}return(await Zu.readdir(n)).find(s=>s.endsWith(`-${t}.yml`))||null}catch(n){throw new yu(`Error finding thread ${t} in project ${e}`,n)}}async getById(e,t){try{let n=await this.findThreadFile(e,t);if(!n)return null;let i=this.getThreadsDir(e),a=Zp.join(i,n),o=await $fe(a);if(!o)return null;let s=ch(o,ZR);return s.projectId||(s.projectId=e),s!==o&&Mn(a,s),new bu(s)}catch(n){throw new yu(`Failed to read thread ${t} from project ${e}`,n)}}async save(e,t){await this.ensureThreadsDir(e);try{if(t.id||(t.id=crypto.randomUUID()),t.projectId||(t.projectId=e),t.projectId!==e)throw new Error(`Thread projectId mismatch: expected ${e}, got ${t.projectId}`);let n=this.getThreadsDir(e),i=this.getThreadFileName(t),a=Zp.join(n,i),o=await this.findThreadFile(e,t.id);if(o&&o!==i){let u=Zp.join(n,o);try{await Zu.unlink(u),console.log(`[THREAD-REPO] Migrated/renamed thread file: ${o} \u2192 ${i}`)}catch(l){console.warn(`[THREAD-REPO] Could not delete old thread file: ${o}`,l)}}let s={...t.serialize(),version:ZR.length+1},c=bM.default.stringify(s);return await Zu.writeFile(a,c,"utf-8"),t}catch(n){throw new yu(`Failed to save thread ${t.id} to project ${e}`,n)}}async listByProject(e){try{let t=this.getThreadsDir(e);try{await Zu.access(t)}catch{return[]}let n=await Zu.readdir(t);return(await Promise.all(n.filter(a=>a.endsWith(".yml")).map(async a=>{let o=await $fe(Zp.join(t,a));if(!o)return null;let s=o.projectId||e;return{id:o.id,username:o.username,projectId:s,name:o.name??"...",summary:o.summary??"",createdDate:o.createdDate??"",modifiedDate:o.modifiedDate??"",price:o.price??0,starring:o.starring??[],users:Array.isArray(o.users)?o.users.map(c=>typeof c=="string"?{userId:c}:c):o.username?[{userId:o.username}]:[],parentThreadId:o.parentThreadId,parentEventId:o.parentEventId,delegatedAgentName:o.delegatedAgentName,delegatedTask:o.delegatedTask}}))).filter(a=>!!a).sort((a,o)=>a.modifiedDate>o.modifiedDate?-1:1)}catch(t){throw new yu(`Failed to list threads for project ${e}`,t)}}async delete(e,t){try{let n=await this.findThreadFile(e,t);if(!n)return!1;let i=this.getThreadsDir(e);return await Zu.unlink(Zp.join(i,n)),!0}catch(n){throw new yu(`Failed to delete thread ${t} from project ${e}`,n)}}};var oE=class{constructor(e,t,n){this.projectRepository=e;this.projectsDir=t;this.threadFileService=n}repositoryCache=new Map;threadListCache=new Map;CACHE_TTL_MS=14400*1e3;loadingPromises=new Map;getThreadRepository(e){let t=this.repositoryCache.get(e);if(t)return t;if(!this.projectRepository.getProjectInfo(e))throw new Error(`Project '${e}' not found`);let i=new aE(this.projectsDir);return this.repositoryCache.set(e,i),i}clearCache(e){e?this.repositoryCache.delete(e):this.repositoryCache.clear()}async listThreads(e,t){let n=this.threadListCache.get(e);if(n&&Date.now()-n.timestamp<this.CACHE_TTL_MS)return n.data.filter(o=>rn(o,t)).sort((o,s)=>o.modifiedDate>s.modifiedDate?-1:1);let i=this.loadingPromises.get(e);if(i)return await i,this.listThreads(e,t);let a=this.loadThreadListFromDisk(e);this.loadingPromises.set(e,a);try{return(await a).filter(s=>rn(s,t)).sort((s,c)=>s.modifiedDate>c.modifiedDate?-1:1)}catch(o){throw this.threadListCache.delete(e),o}finally{this.loadingPromises.delete(e)}}async loadThreadListFromDisk(e){let n=await this.getThreadRepository(e).listByProject(e);return this.threadListCache.set(e,{data:n,timestamp:Date.now()}),n}toThreadSummary(e){return{id:e.id,username:e.username,projectId:e.projectId,name:e.name,summary:e.summary,createdDate:e.createdDate,modifiedDate:e.modifiedDate,price:e.price,starring:e.starring,users:e.users,parentThreadId:e.parentThreadId,parentEventId:e.parentEventId,delegatedAgentName:e.delegatedAgentName,delegatedTask:e.delegatedTask}}updateThreadInCache(e,t){let n=this.threadListCache.get(e);if(!n)return;let i=n.data.findIndex(a=>a.id===t.id);i!==-1?n.data[i]=t:n.data.push(t)}removeThreadFromCache(e,t){let n=this.threadListCache.get(e);n&&(n.data=n.data.filter(i=>i.id!==t))}async getThread(e,t){return await this.getThreadRepository(e).getById(e,t)}async createThread(e,t,n){let i=this.getThreadRepository(e),a=new bu({id:crypto.randomUUID(),username:t,projectId:e,name:n||"",price:0}),o=await i.save(e,a);return this.updateThreadInCache(e,this.toThreadSummary(o)),o}async updateThread(e,t,n){let i=this.getThreadRepository(e),a=await i.getById(e,t);if(!a){let c=this.threadListCache.get(e)?.data.find(u=>u.id===t);if(c)a=new bu({id:c.id,username:c.username,projectId:c.projectId,name:c.name,price:c.price});else throw new Error(`Thread '${t}' not found in project '${e}'`)}n.name!==void 0&&(a.name=n.name),n.summary!==void 0&&(a.summary=n.summary),n.users!==void 0&&(a.users=n.users);let o=await i.save(e,a);return this.updateThreadInCache(e,this.toThreadSummary(o)),o}async starThread(e,t,n){let i=this.getThreadRepository(e),a=await i.getById(e,t);if(!a)throw new Error(`Thread '${t}' not found in project '${e}'`);a.starring.includes(n)||a.starring.push(n);let o=await i.save(e,a);return this.updateThreadInCache(e,this.toThreadSummary(o)),o}async unstarThread(e,t,n){let i=this.getThreadRepository(e),a=await i.getById(e,t);if(!a)throw new Error(`Thread '${t}' not found in project '${e}'`);a.starring=a.starring.filter(s=>s!==n);let o=await i.save(e,a);return this.updateThreadInCache(e,this.toThreadSummary(o)),o}async deleteThread(e,t){let i=await this.getThreadRepository(e).delete(e,t);return i&&(await this.threadFileService.deleteThreadFiles(e,t),this.removeThreadFromCache(e,t)),i}async saveThread(e,t){let i=await this.getThreadRepository(e).save(e,t);return this.updateThreadInCache(e,this.toThreadSummary(i)),i}async listAllThreads(e){let t=this.threadListCache.get(e);if(t&&Date.now()-t.timestamp<this.CACHE_TTL_MS)return t.data.sort((a,o)=>a.modifiedDate>o.modifiedDate?-1:1);let n=this.loadingPromises.get(e);if(n)return await n,this.listAllThreads(e);let i=this.loadThreadListFromDisk(e);this.loadingPromises.set(e,i);try{return(await i).sort((o,s)=>o.modifiedDate>s.modifiedDate?-1:1)}catch(a){throw this.threadListCache.delete(e),a}finally{this.loadingPromises.delete(e)}}async exists(e,t){return await this.getThread(e,t)!==null}};var Mfe=vr(Pc(),1);import*as ba from"fs/promises";import*as X6 from"path";var jfe=5,Rfe=24,Nfe=100,Ffe={SHORT_THREADS:7,LONG_THREADS:30},sE=class{constructor(e,t){this.projectsConfigPath=e;this.logger=t}cleanupTimer=null;initialTimer=null;isRunning=!1;async start(){if(this.isRunning){this.log("Thread cleanup service already running");return}this.isRunning=!0,this.log("Starting thread cleanup service with user message-based retention"),this.initialTimer=setTimeout(async()=>{await this.performCleanup(),this.cleanupTimer=setInterval(async()=>{await this.performCleanup()},Rfe*60*60*1e3),this.log(`Thread cleanup scheduled every ${Rfe} hours`)},jfe*60*1e3),this.log(`Initial cleanup scheduled in ${jfe} minutes`)}async stop(){this.initialTimer&&(clearTimeout(this.initialTimer),this.initialTimer=null),this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=null),this.isRunning=!1,this.log("Thread cleanup service stopped (all timers cleared)")}async performCleanup(){let e=Date.now(),t=0,n=0,i=0;try{this.log("Starting thread cleanup...");let a=await ba.readdir(this.projectsConfigPath);this.log(`Found ${a.length} projects to scan`);for(let s of a)try{let c=X6.join(this.projectsConfigPath,s);if(!(await ba.lstat(c)).isDirectory())continue;let l=X6.join(c,"threads");try{await ba.access(l)}catch{continue}let{scanned:f,deleted:p,errors:d}=await this.cleanupProjectThreads(s,l);t+=f,n+=p,i+=d}catch(c){this.logError(`Error processing project ${s}: ${c}`),i++}let o=Date.now()-e;this.log(`Cleanup completed: ${n}/${t} threads deleted across all projects in ${o}ms (${i} errors)`)}catch(a){let o=Date.now()-e;this.logError(`Cleanup failed after ${o}ms: ${a}`)}}async cleanupProjectThreads(e,t){let n=0,i=0,a=0;try{let s=(await ba.readdir(t)).filter(c=>c.endsWith(".yml"));if(n=s.length,s.length===0)return{scanned:n,deleted:i,errors:a};this.log(`Scanning ${s.length} threads in project ${e}`);for(let c=0;c<s.length;c+=Nfe){let u=s.slice(c,c+Nfe),l=await this.processBatch(u,t,e);i+=l.deleted,a+=l.errors}i>0&&this.log(`Project ${e}: deleted ${i}/${n} expired threads`)}catch(o){this.logError(`Error scanning project ${e}: ${o}`),a++}return{scanned:n,deleted:i,errors:a}}async processBatch(e,t,n){let i=0,a=0;return await Promise.all(e.map(async o=>{let s=X6.join(t,o),c;try{let u=await ba.readFile(s,"utf-8");c=Mfe.parse(u)}catch(u){await ba.unlink(s),this.logError(`Error processing file ${o} in project ${n}: ${u}`)}if(!(!c||!c.modifiedDate)&&!(c.starring&&Array.isArray(c.starring)&&c.starring.length>0)&&this.shouldDeleteThread(c)){let u=this.countUserMessages(c.messages||[]),l=this.getDaysSinceModified(c.modifiedDate),f=c.id||o.replace(".yml","");await ba.unlink(s),await this.deleteThreadFiles(t,f),i++,this.logger.logThreadCleanup(n,o),console.log(`ThreadCleanup: Deleted thread ${f} and its files directory (${u} user messages, ${l} days old)`)}})),{deleted:i,errors:a}}shouldDeleteThread(e){if(!e||!e.modifiedDate)return!1;let n=this.countUserMessages(e.messages||[])<=3?Ffe.SHORT_THREADS:Ffe.LONG_THREADS;return this.getDaysSinceModified(e.modifiedDate)>n}countUserMessages(e){return e.filter(t=>t&&t.type==="message"&&t.role==="user").length}getDaysSinceModified(e){let t=new Date(e),i=new Date().getTime()-t.getTime();return Math.floor(i/(1e3*60*60*24))}async deleteThreadFiles(e,t){try{let n=X6.join(e,`${t}-files`);try{await ba.access(n),await ba.rm(n,{recursive:!0,force:!0}),console.log(`ThreadCleanup: Deleted files directory ${n}`)}catch(i){if(i.code!=="ENOENT")throw i}}catch(n){console.error(`ThreadCleanup: Error deleting files for ${t}:`,n)}}log(e){let t=new Date().toISOString();console.log(`[${t}] ThreadCleanup: ${e}`)}logError(e){let t=new Date().toISOString();console.error(`[${t}] ThreadCleanup ERROR: ${e}`)}async forceCleanup(){this.log("Manual cleanup triggered"),await this.performCleanup()}};import*as qi from"path";import*as Jp from"fs";import*as xa from"fs/promises";var cE=class{constructor(e){this.projectsDir=e}getThreadFilesDir(e,t){return qi.join(this.projectsDir,e,"threads",`${t}-files`)}async ensureThreadFilesDir(e,t){let n=this.getThreadFilesDir(e,t);Jp.existsSync(n)||await xa.mkdir(n,{recursive:!0})}async listFiles(e,t){await this.ensureThreadFilesDir(e,t);let n=this.getThreadFilesDir(e,t),i=await xa.readdir(n);return await Promise.all(i.map(async o=>{let s=qi.join(n,o),c=await xa.stat(s);return{filename:o,size:c.size,lastModified:c.mtime.toISOString()}}))}async saveFile(e,t,n,i){let a=this.getThreadFilesDir(e,t);await xa.mkdir(a,{recursive:!0});let o=qi.join(a,n);await xa.writeFile(o,i)}async getFile(e,t,n){await this.ensureThreadFilesDir(e,t);let i=this.getThreadFilesDir(e,t),a=qi.join(i,n),o=qi.resolve(a),s=qi.resolve(i);if(!o.startsWith(s))throw new Error("Access denied: invalid file path");if(!Jp.existsSync(a))throw new Error(`File '${n}' not found`);return await xa.readFile(a)}async getFilePath(e,t,n){await this.ensureThreadFilesDir(e,t);let i=this.getThreadFilesDir(e,t),a=qi.join(i,n),o=qi.resolve(a),s=qi.resolve(i);if(!o.startsWith(s))throw new Error("Access denied: invalid file path");if(!Jp.existsSync(a))throw new Error(`File '${n}' not found`);return a}fileExists(e,t,n){let i=this.getThreadFilesDir(e,t),a=qi.join(i,n),o=qi.resolve(a),s=qi.resolve(i);return o.startsWith(s)?Jp.existsSync(a):!1}async deleteFile(e,t,n){await this.ensureThreadFilesDir(e,t);let i=this.getThreadFilesDir(e,t),a=qi.join(i,n),o=qi.resolve(a),s=qi.resolve(i);if(!o.startsWith(s))throw new Error("Access denied: invalid file path");if(!Jp.existsSync(a))throw new Error(`File '${n}' not found`);await xa.unlink(a)}async deleteThreadFiles(e,t){try{let n=this.getThreadFilesDir(e,t);Jp.existsSync(n)&&(await xa.rm(n,{recursive:!0,force:!0}),console.log(`Deleted thread files directory: ${n}`))}catch(n){console.error(`Error deleting thread files for ${t}:`,n)}}};var Lfe=vr(Go(),1);var uE=class{constructor(e,t,n,i){this.threadRepository=t;this.projectId=n;this.interactor=i;this.username=e.username}activeThread$=new Lfe.BehaviorSubject(null);isKilled=!1;activeThread=this.activeThread$.asObservable();username;async kill(){this.isKilled=!0,this.activeThread$.complete()}async create(e){let t=new bu({id:"",username:this.username,name:e??"",price:0});return this.activeThread$.next(t),t}async select(e){let t=await this.threadRepository.getById(this.projectId,e);if(!t)throw new Error(`Thread ${e} not found`);return this.activeThread$.next(t),t}async save(e){let t=this.activeThread$.value;if(!t){console.error(`No thread existing when save attempt with name '${e}'`);return}e&&(t.name=e);let n=await this.threadRepository.save(this.projectId,t);this.activeThread$.next(n)}async autoSave(e){if(this.isKilled){console.log("Autosave skipped: service has been killed");return}let t=this.activeThread$.value;if(!t||t.messagesLength==0){console.log(`Autosave of an empty or falsy thread aborted, threadId: ${t?.id}, user: ${this.username}`);return}try{e&&(t.name=e),await this.threadRepository.save(this.projectId,t),this.interactor&&this.interactor.sendEvent(new uc({threadId:t.id,name:t.name||void 0}))}catch(n){console.log("Autosave failed (service may have been killed):",n instanceof Error?n.message:n)}}async truncateAtUserMessage(e){let t=this.activeThread$.value;if(!t)return console.error("No active thread available for truncation"),!1;let n=t.truncateAtUserMessage(e);return n||this.interactor?.warn("Failed to truncate thread."),n}getCurrentThread(){return this.activeThread$.value}};async function qfe(r,e){let t=e.project.selectedProject,n=e.user.getUserData(t.name),i=await QS(t.config.path,r,n),a=new k0({...i,root:t.config.path,name:t.name},e.user.username);return console.log(`[BUILD_CONTEXT] Context for '${a.project.name}' \u2192 root: ${a.project.root}, desc: ${a.project.description?.length||0} chars`),a}var lE=class extends Fe{constructor(t,n){super({commandWord:"select-project",description:"Select an existing project"});this.interactor=t;this.services=n}async handle(t,n){try{let i=this.getSubCommand(t);return await this.selectProject(i)??n}catch(i){return this.interactor.error(`Invalid project selection because: ${i.toString()}`),n}}async selectProject(t){return this.services.project.selectProject(t),this.services.project.selectedProject?qfe(this.interactor,this.services):null}};var fE=class extends Fe{constructor(t,n,i){super({commandWord:"add",description:"Add a new integration configuration. User level is default, use --project/-p for project level."});this.interactor=t;this.service=n;this.editHandler=i}async handle(t,n){let a=!!Tt(this.getSubCommand(t),[{key:"project",alias:"p"}]).project,o=a?"project":"user",s=this.service.getMergedIntegrations(),c=Object.keys(s),u=Xf.filter(h=>!c.includes(h));if(u.length===0)return this.interactor.displayText(`All available integrations (${Xf.join(", ")}) are already configured.`),n;let l=await this.interactor.chooseOption(u.sort(),"Select integration to add:",`Available integrations to configure:
878
878
 
879
879
  ${u.map(h=>`- **${h}**`).join(`
880
880
  `)}
@@ -1046,7 +1046,7 @@ Summary:
1046
1046
  - Unique projects used: ${new Set(t.flatMap(u=>Array.from(u.projects))).size}`;return o+`
1047
1047
  `+s.join(`
1048
1048
  `)+c}};var OE=class extends Zn{constructor(t,n){super({commandWord:"stats",description:"Show usage statistics and analytics",isInternal:!0},t);this.services=n;this.handlers=[new DE(this.interactor,this.services),new IE(this.interactor,this.services)]}};var wat=100,$E=class{constructor(e,t,n,i){this.interactor=e;this.aiHandler=t;this.configHandler=n;this.services=i}handlers=[];maxIterations=wat;killed=!1;processing=!1;async init(e){try{let t=new Fx(this.interactor),n=new EE(this.interactor,this.services);if(this.handlers=[this.configHandler,new $S(this.interactor),new pw(this.interactor),t,n,new Q_(this.interactor),new PE(this.interactor),new OE(this.interactor,this.services)],e?.prompts)for(let[i,a]of Object.entries(e.prompts))this.handlers.push(new DS(a,i));if(this.services.project.selectedProject){let i=await this.services.prompt.list(this.services.project.selectedProject.name),a=new OS(this.interactor,this.services.prompt,this.services.project.selectedProject.name,i);this.handlers.push(a)}this.handlers.push(this.aiHandler),this.handlers=this.handlers.filter(i=>i.requiredIntegrations.every(a=>this.services.integration.hasIntegration(a)))}catch(t){this.interactor.error(`Error initializing handlers: ${t}`)}}async handle(e){if(!e)throw new Error("Invalid command context");let t=0,n;this.processing=!0;try{do{if(this.killed)return e;if(n=e.getFirstCommand(),t++,this.isHelpAsked(n)){let a=["Available commands:",this.formatHelp("help/h/[nothing]","displays this help message"),...this.handlers.slice().filter(o=>!o.isInternal).map(o=>this.formatHelp(o.commandWord,o.description)).sort(),this.formatHelp("[any other text]","defaults to asking the AI with the current context.")];this.interactor.displayText(a.join(`
1049
- `));continue}if(!n)break;let i=this.handlers.find(a=>a.accept(n,e));try{if(i){if(e=await i.handle(n,e),e.aiThread?.runStatus==="STOPPED")return e.clearCommands(),this.processing=!1,e}else n.startsWith(this.aiHandler.commandWord)?this.interactor.error(`Could not handle request ${n}, check your AI integration`):e.addCommands(`${this.aiHandler.commandWord} ${n}`)}catch(a){this.interactor.error(`An error occurred while trying to process your request: ${a}`)}}while((n||t<this.maxIterations)&&this.processing)}finally{this.processing=!1}return t>=this.maxIterations&&this.interactor.warn("Maximum iterations reached for a command"),e}isHelpAsked(e){return e===""||e==="help"||e==="h"}formatHelp(e,t){return` - ${e.padEnd(15," ")} : ${t}`}stop(){this.processing=!1}kill(){this.stop(),this.killed=!0,this.aiHandler.kill()}};var Qfe=vr(Go(),1);function Xfe(r){let e=r.match(/^@(\S*)(?:\s+([\s\S]*))?$/);if(!e)return["",r];let t=e[1],n=e[2]||"";return[t?.toLowerCase()??"",n]}var jE=class extends Fe{constructor(t,n,i){super({commandWord:"@",description:"calls the AI with the given command and current context. 'reset' for using a new thread. You can call whatever assistant in your openai account by its name, ex: joke_generator called by @jok (choice prompt if multiple matches)."});this.interactor=t;this.agentService=n;this.threadService=i}async handle(t,n){let[i,a]=Xfe(t),o=i?t:a;this.interactor.debug(`Agent name extracted from command: ${i}`);let s=await this.selectAgent(i,n);return s?a.trim()?this.runAgent(s,o,n):(this.interactor.debug(`Agent ${s.name} selected.`),n):(this.interactor.error("Failed to find any agent"),n)}async selectAgent(t,n){if(t){let s=await this.agentService.findAgentByNameStart(t,n);return s&&this.interactor.debug(`Selected agent: ${s.name}`),s}let i=n?.aiThread?.getLastAgentName();if(i){let s=await this.agentService.findByName(i,n);if(s)return this.interactor.debug(`Select last used agent: ${s.name}`),s;this.interactor.warn("Previously selected agent not available anymore")}let a=this.agentService.getPreferredAgent();if(a){let s=await this.agentService.findByName(a,n);if(s)return this.interactor.debug(`Selected default agent: ${a}`),s;this.interactor.warn(`Preferred agent '${a}' not found, using default.`)}let o=await this.agentService.findByName("coday",n);return o?this.interactor.debug("Selected default 'Coday' agent"):this.interactor.error("Critical failure: Cannot initialize default Coday agent!"),o}async runAgent(t,n,i){let a=await t.run(n,i.aiThread);await this.checkAndAutoSave(i.aiThread,t),a.subscribe({next:o=>{this.interactor.sendEvent(o)},error:o=>{o.message==="Processing interrupted by user request"?this.interactor.debug("Processing stopped gracefully"):this.interactor.error(`Error in AI processing: ${o.message}`)}});try{await(0,Qfe.lastValueFrom)(a,{defaultValue:void 0})}catch(o){this.interactor.error(`Could not run agent ${t.name} : ${o.message}`)}finally{try{await this.threadService.autoSave()}catch(o){this.interactor.debug(`Final auto-save failed: ${o}`)}}return i}async checkAndAutoSave(t,n){if(t.getUserMessageCount()!==0)if(t.name)try{await this.threadService.autoSave()}catch(i){this.interactor.debug(`Auto-save failed: ${i}`)}else try{let i=await o2e(t,n);await this.threadService.autoSave(i),this.interactor.displayText(`Thread auto-renamed to "${i}"`)}catch(i){this.interactor.warn(`Auto-rename failed: ${i}`)}}async kill(){await this.agentService.kill()}};var xG=vr(Go(),1);var A7e=vr(Pc(),1);import*as sT from"fs/promises";import*as Fd from"path";var epe={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY",google:"GEMINI_API_KEY"},km=class{constructor(e,t,n,i){this.interactor=e;this.userService=t;this.projectStateService=n;this.logger=i}aiClients=[];aiProviderConfigs;init(e){if(this.aiProviderConfigs)return;let t=e.project.ai||[],n=this.projectStateService.selectedProject?.config?.ai||[],i=this.userService.config.ai||[],a=this.detectProvidersFromEnvironment(),o=new Set([...t.map(l=>l.name.toLowerCase()),...n.map(l=>l.name.toLowerCase()),...i.map(l=>l.name.toLowerCase())]);this.aiProviderConfigs=[];for(let l of[...a,...t,...n,...i]){let f=this.aiProviderConfigs.findIndex(p=>p.name===l.name);if(f===-1)this.aiProviderConfigs.push(l);else{let p=this.aiProviderConfigs[f],d=p.models?[...p.models]:[];(l.models??[]).forEach(h=>{let g=d.findIndex(v=>v.alias===h.alias||v.name===h.name);if(g===-1)d.push(h);else{let v=d[g];d[g]={...v,...h,price:{...v.price,...h.price}}}}),this.aiProviderConfigs[f]={...p,...l,models:d}}}this.aiClients=this.aiProviderConfigs.map(l=>this.createClient(l)).filter(l=>!!l);let s=a.filter(l=>!o.has(l.name.toLowerCase())).map(l=>l.name.toLowerCase()),c=new Set(s),u=`AI providers (models listed as: name (alias)):
1049
+ `));continue}if(!n)break;let i=this.handlers.find(a=>a.accept(n,e));try{if(i){if(e=await i.handle(n,e),e.aiThread?.runStatus==="STOPPED")return e.clearCommands(),this.processing=!1,e}else n.startsWith(this.aiHandler.commandWord)?this.interactor.error(`Could not handle request ${n}, check your AI integration`):e.addCommands(`${this.aiHandler.commandWord} ${n}`)}catch(a){this.interactor.error(`An error occurred while trying to process your request: ${a}`)}}while((n||t<this.maxIterations)&&this.processing)}finally{this.processing=!1}return t>=this.maxIterations&&this.interactor.warn("Maximum iterations reached for a command"),e}isHelpAsked(e){return e===""||e==="help"||e==="h"}formatHelp(e,t){return` - ${e.padEnd(15," ")} : ${t}`}stop(){this.processing=!1}kill(){this.stop(),this.killed=!0,this.aiHandler.kill()}};var Qfe=vr(Go(),1);function Xfe(r){let e=r.match(/^@(\S*)(?:\s+([\s\S]*))?$/);if(!e)return["",r];let t=e[1],n=e[2]||"";return[t?.toLowerCase()??"",n]}var jE=class extends Fe{constructor(t,n,i){super({commandWord:"@",description:"calls the AI with the given command and current context. 'reset' for using a new thread. You can call whatever assistant in your openai account by its name, ex: joke_generator called by @jok (choice prompt if multiple matches)."});this.interactor=t;this.agentService=n;this.threadService=i}async handle(t,n){let[i,a]=Xfe(t),o=i?t:a;this.interactor.debug(`Agent name extracted from command: ${i}`);let s=await this.selectAgent(i,n);return s?a.trim()?this.runAgent(s,o,n):(this.interactor.debug(`Agent ${s.name} selected.`),n):(this.interactor.error("Failed to find any agent"),n)}async selectAgent(t,n){if(t){let s=await this.agentService.findAgentByNameStart(t,n);return s&&this.interactor.debug(`Selected agent: ${s.name}`),s}let i=n?.aiThread?.getLastAgentName();if(i){let s=await this.agentService.findByName(i,n);if(s)return this.interactor.debug(`Select last used agent: ${s.name}`),s;this.interactor.warn("Previously selected agent not available anymore")}let a=this.agentService.getPreferredAgent();if(a){let s=await this.agentService.findByName(a,n);if(s)return this.interactor.debug(`Selected default agent: ${a}`),s;this.interactor.warn(`Preferred agent '${a}' not found, using default.`)}let o=await this.agentService.findByName("coday",n);return o?this.interactor.debug("Selected default 'Coday' agent"):this.interactor.error("Critical failure: Cannot initialize default Coday agent!"),o}async runAgent(t,n,i){let a=await t.run(n,i.aiThread,i.username);await this.checkAndAutoSave(i.aiThread,t),a.subscribe({next:o=>{this.interactor.sendEvent(o)},error:o=>{o.message==="Processing interrupted by user request"?this.interactor.debug("Processing stopped gracefully"):this.interactor.error(`Error in AI processing: ${o.message}`)}});try{await(0,Qfe.lastValueFrom)(a,{defaultValue:void 0})}catch(o){this.interactor.error(`Could not run agent ${t.name} : ${o.message}`)}finally{try{await this.threadService.autoSave()}catch(o){this.interactor.debug(`Final auto-save failed: ${o}`)}}return i}async checkAndAutoSave(t,n){if(t.getUserMessageCount()!==0)if(t.name)try{await this.threadService.autoSave()}catch(i){this.interactor.debug(`Auto-save failed: ${i}`)}else try{let i=await o2e(t,n);await this.threadService.autoSave(i),this.interactor.displayText(`Thread auto-renamed to "${i}"`)}catch(i){this.interactor.warn(`Auto-rename failed: ${i}`)}}async kill(){await this.agentService.kill()}};var xG=vr(Go(),1);var A7e=vr(Pc(),1);import*as sT from"fs/promises";import*as Fd from"path";var epe={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY",google:"GEMINI_API_KEY"},km=class{constructor(e,t,n,i){this.interactor=e;this.userService=t;this.projectStateService=n;this.logger=i}aiClients=[];aiProviderConfigs;init(e){if(this.aiProviderConfigs)return;let t=e.project.ai||[],n=this.projectStateService.selectedProject?.config?.ai||[],i=this.userService.config.ai||[],a=this.detectProvidersFromEnvironment(),o=new Set([...t.map(l=>l.name.toLowerCase()),...n.map(l=>l.name.toLowerCase()),...i.map(l=>l.name.toLowerCase())]);this.aiProviderConfigs=[];for(let l of[...a,...t,...n,...i]){let f=this.aiProviderConfigs.findIndex(p=>p.name===l.name);if(f===-1)this.aiProviderConfigs.push(l);else{let p=this.aiProviderConfigs[f],d=p.models?[...p.models]:[];(l.models??[]).forEach(h=>{let g=d.findIndex(v=>v.alias===h.alias||v.name===h.name);if(g===-1)d.push(h);else{let v=d[g];d[g]={...v,...h,price:{...v.price,...h.price}}}}),this.aiProviderConfigs[f]={...p,...l,models:d}}}this.aiClients=this.aiProviderConfigs.map(l=>this.createClient(l)).filter(l=>!!l);let s=a.filter(l=>!o.has(l.name.toLowerCase())).map(l=>l.name.toLowerCase()),c=new Set(s),u=`AI providers (models listed as: name (alias)):
1050
1050
  `+this.aiProviderConfigs.map(l=>{let f=this.aiClients.find(v=>v.name.toLowerCase()===l.name.toLowerCase()),p=!!f,d=p?"\u2705":"\u274C",h=c.has(l.name.toLowerCase())?" (auto-detected)":"",g=` - ${d} ${l.name}${h}`;if(p&&Array.isArray(f.models)&&f.models.length>0){let v=f.models.map(y=>y.alias&&y.alias!==y.name?`${y.name} (${y.alias})`:y.name).join(", ");g+=`, models: ${v}`}return g}).join(`
1051
1051
  `);this.interactor.displayText(u)}getClient(e,t){let n=this.aiClients.filter(i=>{let a=!e||i.name.toLowerCase()===e.toLowerCase(),o=!t||i.supportsModel(t.toLowerCase());return a&&o});return n.length?n[0]:void 0}getAllModels(){let e=[];for(let t of this.aiClients)if(t.models)for(let n of t.models)e.push({name:n.name,providerName:t.name});return e}cleanup(){this.aiClients.forEach(e=>e.kill()),this.aiClients=[]}kill(){this.cleanup(),this.aiProviderConfigs=void 0}getApiKey(e){let t=epe[e.name];return(t?process.env[t]??process.env[`${e.name.toUpperCase()}_API_KEY`]:void 0)??e.apiKey}detectProvidersFromEnvironment(){let e=[];for(let[t,n]of Object.entries(epe)){let i=process.env[n];if(i){let a={name:t,apiKey:i};e.push(a),this.interactor.debug(`\u{1F50D} Auto-detected ${t} provider from ${n} environment variable`)}}return e}createClient(e){let t=this.getApiKey(e);if(!t){this.interactor.displayText(`\u2139\uFE0F no api key for AI provider '${e.name}'`);return}let n={...e,apiKey:t};switch(e.name.toLowerCase()){case"anthropic":return new lw(this.interactor,n,this.logger);case"google":return new PS(this.interactor,n,this.logger);default:return new fm(this.interactor,n,this.logger)}}};function tpe(r){return({query:t,agentName:n})=>{try{let i=`@${n} ${t}`;return r.addCommands(i),`Query successfully redirected to agent '${n}'. The agent will process the query with full context after this run completes.`}catch(i){return`Error during redirection: ${i.message}`}}}var tg=class extends Vt{constructor(t,n,i,a){super(t,i,a);this.agentSummaries=n}static TYPE="AI";async buildTools(t,n){let i=[];if(!t.oneshot){let a=async({message:s,options:c})=>`User answered: ${c?.length?await this.interactor.chooseOption(c,s,void 0,!0):await this.interactor.promptText(s)}`,o={type:"function",function:{name:`${this.name}__queryUser`,description:`Allows to ask the user a question.
1052
1052
  IMPORTANT: Use this tool only when necessary, as it is intrusive for the user.
@@ -1070,7 +1070,7 @@ The redirected agent will run after this conversation completes and will have ac
1070
1070
 
1071
1071
  ---
1072
1072
 
1073
- `)}}function jst(r,e,t,n,i,a,o){let s=r.threadId??crypto.randomUUID();return Rst({...r,threadId:s},e,t,n,i,a,o).catch(c=>{n.error(`Async delegation to '${r.agentName}' failed to launch: ${c?.message??c}`)}),s}async function Rst(r,e,t,n,i,a,o){let{agentName:s,task:c}=r,u=new Date().toISOString(),l,f=await a.getThread(o,r.threadId);if(f)l=f,l.delegationDepth=t.delegationDepth+1,l.runStatus="RUNNING";else{l=t.fork(s,c,u),l.id=r.threadId;try{await a.saveThread(o,l)}catch(h){n.debug(`Could not persist async sub-thread ${l.id}: ${h}`)}}let p=new fo({subThreadId:l.id,agentName:s,threadId:t.id});t.addDelegationEvent(p),n.sendEvent(p);let d=await i(s,e);if(!d){n.error(`Async delegation: agent '${s}' not found.`);return}n.sendEvent(new _r({answer:c,threadId:l.id}));let m=setInterval(()=>{t.runStatus==="STOPPED"&&l.runStatus!=="STOPPED"&&(n.debug(`Propagating stop signal to async sub-thread ${l.id}`),l.runStatus="STOPPED")},1e3);try{let h=(await d.run(c,l)).pipe((0,AM.filter)(g=>g instanceof Rt));await(0,kM.lastValueFrom)(h,{defaultValue:void 0});try{await a.saveThread(o,l)}catch(g){n.debug(`Could not persist async sub-thread ${l.id}: ${g}`)}try{let g=await a.getThread(o,t.id);g?(g.merge(l),await a.saveThread(o,g)):t.merge(l)}catch(g){t.merge(l),n.debug(`Could not persist price merge for parent thread ${t.id}: ${g}`)}}catch(h){n.error(`Async delegation to '${s}' failed: ${h?.message??h}`)}finally{clearInterval(m)}}async function Nst(r,e,t,n,i,a,o){let{agentName:s,task:c}=r,u=new Date().toISOString(),l,f=!1;if(r.threadId){let g=await a.getThread(o,r.threadId);if(!g)return{result:`Thread '${r.threadId}' not found in project '${o}'.`,threadId:r.threadId};l=g,f=!0,l.delegationDepth=t.delegationDepth+1,l.runStatus="RUNNING"}else l=t.fork(s,c,u);if(!f)try{await a.saveThread(o,l)}catch(g){n.debug(`Could not persist sub-thread ${l.id}: ${g}`)}let p=new fo({subThreadId:l.id,agentName:s,threadId:t.id});t.addDelegationEvent(p),n.sendEvent(p);let d=await i(s,e);if(!d)return{result:`Agent ${s} not found.`,threadId:l.id};let m=setInterval(()=>{t.runStatus==="STOPPED"&&l.runStatus!=="STOPPED"&&(n.debug(`Propagating stop signal to sub-thread ${l.id}`),l.runStatus="STOPPED")},1e3),h="Delegation did not produce a result.";try{n.sendEvent(new _r({answer:c,threadId:l.id}));let g=(await d.run(c,l)).pipe((0,AM.filter)(y=>y instanceof Rt)),v=await(0,kM.lastValueFrom)(g,{defaultValue:void 0});l.runStatus==="STOPPED"?h="Delegation was interrupted before completion. No result available.":v?h=v.getTextContent():h="Delegation completed but produced no message.";try{await a.saveThread(o,l)}catch(y){n.debug(`Could not persist final sub-thread ${l.id}: ${y}`)}try{let y=await a.getThread(o,t.id);y?(y.merge(l),await a.saveThread(o,y)):t.merge(l)}catch(y){t.merge(l),n.debug(`Could not persist price merge for parent thread ${t.id}: ${y}`)}}catch(g){h=`Error during delegation: ${g.message}`,console.error(`Error in delegation for agent ${s}:`,g),n.error(h)}finally{clearInterval(m)}return{result:h,threadId:l.id}}var rg=class extends Vt{constructor(t,n,i,a,o,s){super(t,a,o);this.agentFind=n;this.agentSummaries=i;this.threadService=s}static TYPE="DELEGATE";async getTools(t,n,i){return this.buildTools(t,i,n)}async buildTools(t,n,i){let a=t.project.name,o=i&&i.length>0?i.map(m=>m.trim().toLowerCase()).filter(Boolean):void 0,s=this.agentSummaries(),u=(o?s.filter(m=>o.includes(m.name.toLowerCase())):s).map(m=>` - ${m.name} : ${m.description}`).join(`
1073
+ `)}}function jst(r,e,t,n,i,a,o){let s=r.threadId??crypto.randomUUID();return Rst({...r,threadId:s},e,t,n,i,a,o).catch(c=>{n.error(`Async delegation to '${r.agentName}' failed to launch: ${c?.message??c}`)}),s}async function Rst(r,e,t,n,i,a,o){let{agentName:s,task:c}=r,u=new Date().toISOString(),l,f=await a.getThread(o,r.threadId);if(f)l=f,l.delegationDepth=t.delegationDepth+1,l.runStatus="RUNNING";else{l=t.fork(s,c,u),l.id=r.threadId;try{await a.saveThread(o,l)}catch(h){n.debug(`Could not persist async sub-thread ${l.id}: ${h}`)}}let p=new fo({subThreadId:l.id,agentName:s,threadId:t.id});t.addDelegationEvent(p),n.sendEvent(p);let d=await i(s,e);if(!d){n.error(`Async delegation: agent '${s}' not found.`);return}n.sendEvent(new _r({answer:c,threadId:l.id}));let m=setInterval(()=>{t.runStatus==="STOPPED"&&l.runStatus!=="STOPPED"&&(n.debug(`Propagating stop signal to async sub-thread ${l.id}`),l.runStatus="STOPPED")},1e3);try{let h=(await d.run(c,l)).pipe((0,AM.filter)(g=>g instanceof Rt));await(0,kM.lastValueFrom)(h,{defaultValue:void 0});try{await a.saveThread(o,l)}catch(g){n.debug(`Could not persist async sub-thread ${l.id}: ${g}`)}try{let g=await a.getThread(o,t.id);g?(g.merge(l),await a.saveThread(o,g)):t.merge(l)}catch(g){t.merge(l),n.debug(`Could not persist price merge for parent thread ${t.id}: ${g}`)}}catch(h){n.error(`Async delegation to '${s}' failed: ${h?.message??h}`)}finally{clearInterval(m)}}async function Nst(r,e,t,n,i,a,o){let{agentName:s,task:c}=r,u=new Date().toISOString(),l,f=!1;if(r.threadId){let g=await a.getThread(o,r.threadId);if(!g)return{result:`Thread '${r.threadId}' not found in project '${o}'.`,threadId:r.threadId};l=g,f=!0,l.delegationDepth=t.delegationDepth+1,l.runStatus="RUNNING"}else l=t.fork(s,c,u);if(!f)try{await a.saveThread(o,l)}catch(g){n.debug(`Could not persist sub-thread ${l.id}: ${g}`)}let p=new fo({subThreadId:l.id,agentName:s,threadId:t.id});t.addDelegationEvent(p),n.sendEvent(p);let d=await i(s,e);if(!d)return{result:`Agent ${s} not found.`,threadId:l.id};let m=setInterval(()=>{t.runStatus==="STOPPED"&&l.runStatus!=="STOPPED"&&(n.debug(`Propagating stop signal to sub-thread ${l.id}`),l.runStatus="STOPPED")},1e3),h="Delegation did not produce a result.";try{n.sendEvent(new _r({answer:c,threadId:l.id,name:e.username}));let g=(await d.run(c,l,e.username)).pipe((0,AM.filter)(y=>y instanceof Rt)),v=await(0,kM.lastValueFrom)(g,{defaultValue:void 0});l.runStatus==="STOPPED"?h="Delegation was interrupted before completion. No result available.":v?h=v.getTextContent():h="Delegation completed but produced no message.";try{await a.saveThread(o,l)}catch(y){n.debug(`Could not persist final sub-thread ${l.id}: ${y}`)}try{let y=await a.getThread(o,t.id);y?(y.merge(l),await a.saveThread(o,y)):t.merge(l)}catch(y){t.merge(l),n.debug(`Could not persist price merge for parent thread ${t.id}: ${y}`)}}catch(g){h=`Error during delegation: ${g.message}`,console.error(`Error in delegation for agent ${s}:`,g),n.error(h)}finally{clearInterval(m)}return{result:h,threadId:l.id}}var rg=class extends Vt{constructor(t,n,i,a,o,s){super(t,a,o);this.agentFind=n;this.agentSummaries=i;this.threadService=s}static TYPE="DELEGATE";async getTools(t,n,i){return this.buildTools(t,i,n)}async buildTools(t,n,i){let a=t.project.name,o=i&&i.length>0?i.map(m=>m.trim().toLowerCase()).filter(Boolean):void 0,s=this.agentSummaries(),u=(o?s.filter(m=>o.includes(m.name.toLowerCase())):s).map(m=>` - ${m.name} : ${m.description}`).join(`
1074
1074
  `),l=ope({context:t,interactor:this.interactor,agentFind:this.agentFind,threadService:this.threadService}),f=async({delegations:m},h)=>{if(o){let g=m.filter(v=>!o.includes(v.agentName.toLowerCase()));if(g.length>0){let y=`Delegation denied: agent(s) '${g.map(x=>x.agentName).join(", ")}' are not allowed for delegation.`;return this.interactor.displayText(y),y}}return l({delegations:m},h)},p={type:"function",function:{name:`${this.name}__delegate`,description:`Delegate one or more tasks to available agents, running them in parallel. Available agents:
1075
1075
  ${u||"(No allowed agents for delegation)"}
1076
1076
 
@@ -1401,7 +1401,7 @@ ${this.services.memory.getFormattedMemories("PROJECT",n.name)}
1401
1401
 
1402
1402
  ${l}
1403
1403
 
1404
- `;let p=n.integrations?new Map(Object.entries(n.integrations).map(([x,k])=>{let S=k&&k.length>0?k:[];return[x,S]})):void 0;this.interactor.debug(`Agent '${n.name}' integrations: ${p?Array.from(p.keys()).join(", "):"ALL (undefined)"}`);let d=performance.now(),m=await this.toolbox.getTools({context:t,integrations:p,agentName:n.name}),h=performance.now()-d;this.interactor.debug(` \u{1F4E6} Tools available for '${n.name}': ${m.map(x=>x.function.name).join(", ")}`);let g=new jx([...m]),v=new cv(n,o,g),y=performance.now()-i;return this.interactor.debug(`\u2728 Agent '${n.name}' created: ${y.toFixed(2)}ms (client: ${s.toFixed(2)}ms, docs: ${f.toFixed(2)}ms, tools: ${h.toFixed(2)}ms)`),v}catch(a){let o=`Failed to create agent ${n.name}`;console.error(`${o}:`,a),this.interactor.error(o);return}}};var W9t=100,cT=class{constructor(e,t,n){this.interactor=e;this.options=t;this.services=n;this.interactor.debugLevelEnabled=t.debug,this.interactor.debug("Coday started with debug"),this.configHandler=new bE(e,this.services),this.maxIterations=W9t,this.aiThreadService=new uE(n.user,n.thread.getThreadRepository(t.project),t.project,e),this.aiThreadService.activeThread.subscribe(i=>{!this.context||!i||(this.context.aiThread=i,this.replayThread(i))}),this.aiClientProvider=new km(this.interactor,this.services.user,this.services.project,this.services.logger),this.interactor.events.pipe((0,xG.filter)(i=>i instanceof Di||i instanceof Ii||i instanceof _r),(0,xG.filter)(()=>!this.isReplaying)).subscribe(i=>{i instanceof Di||i instanceof Ii?this.pendingQuestionEvent=i:i instanceof _r&&this.pendingQuestionEvent&&i.parentKey===this.pendingQuestionEvent.timestamp&&(this.pendingQuestionEvent=null)})}context=null;configHandler;handlerLooper;aiHandler;maxIterations;initialPrompts=[];aiThreadService;killed=!1;isReplaying=!1;pendingQuestionEvent=null;messageQueue=[];aiClientProvider;addUserMessage(e,t){if(this.pendingQuestionEvent){let n=this.pendingQuestionEvent.buildAnswer(t);this.interactor.sendEvent(n)}else{let n=new Rt({role:"user",content:[{type:"text",content:t}],name:e});this.interactor.sendEvent(n),this.messageQueue.push({username:e,message:t})}}replay(){let e=this.aiThreadService.getCurrentThread();if(!e){console.log("No active thread to replay");return}this.replayThread(e),!this.options.oneshot&&e.runStatus!=="RUNNING"&&this.interactor.replayLastInvite()}upload(e){let t=this.aiThreadService.getCurrentThread();if(!t){this.interactor.error("No active thread available for upload");return}let n=this.services.user.username;e.forEach(a=>{t.addUserMessage(n,a)});let i=new Rt({role:"user",content:e,name:n});this.interactor.sendEvent(i)}async run(){this.initialPrompts=this.options.prompts?[...this.options.prompts]:[],this.interactor.debug(`[CODAY] Starting run with ${this.initialPrompts.length} initial prompts`);try{do{if(this.killed)return;if(await this.initContext(),await this.initThread(),!this.context){this.interactor.error("Could not initialize context \u{1F62D}");break}let e=await this.initCommand();if(!e&&this.options.oneshot)break;let t=this.context?.aiThread;t&&(t.runStatus="RUNNING"),this.context?.addCommands(e),this.context=await this.handlerLooper?.handle(this.context)??null}while(!this.context?.oneshot)}finally{this.stop()}await this.cleanup()}stop(){let e=this.context?.aiThread;e&&(e.runStatus="STOPPED"),this.handlerLooper?.stop(),this.aiThreadService.autoSave()}async cleanup(){try{this.services.agent&&await this.services.agent.kill(),this.aiThreadService.kill(),this.aiClientProvider.cleanup(),this.context=null,this.handlerLooper=void 0,this.aiHandler=void 0,this.messageQueue=[],this.pendingQuestionEvent=null}catch(e){console.error("Error during agent cleanup:",e)}}async kill(){this.killed=!0,this.stop();try{await this.cleanup()}catch(e){console.error("Error during kill cleanup:",e)}this.handlerLooper?.kill(),this.interactor.kill()}async replayThread(e){this.isReplaying=!0;try{let t=(await e.getMessages(void 0,void 0)).messages;if(!t?.length)return;let n=[...t].sort((i,a)=>new Date(i.timestamp).getTime()-new Date(a.timestamp).getTime());for(let i of n)(i instanceof Rt||i instanceof ln||i instanceof kn||i instanceof Di||i instanceof Ii||i instanceof _r)&&this.interactor.sendEvent(i);this.interactor.displayText(`Selected thread '${e.name}'`)}finally{this.isReplaying=!1}}async initContext(){if(this.context){this.interactor.debug("[CODAY] Context already initialized, skipping");return}if(this.interactor.debug(`[CODAY] Initializing context for project: ${this.options.project}`),this.context=await this.configHandler.selectProjectHandler.selectProject(this.options.project),!this.context){console.log("[CODAY] ERROR: Failed to create context from selectProject");return}console.log(`[CODAY] Context initialized: '${this.context.project.name}' at ${this.context.project.root}`),this.context&&(this.context.oneshot=this.options.oneshot,this.context.fileReadOnly=this.options.fileReadOnly,this.options.thread&&this.options.project&&(this.context.threadFilesRoot=C7e.join(this.options.configDir,"projects",this.options.project,"threads",`${this.options.thread}-files`),this.interactor.debug(`[CODAY] Thread files root: ${this.context.threadFilesRoot}`)),this.services.aiConfig=new YS(this.services.user,this.services.project),this.services.aiConfig.initialize(this.context),this.services.mcp.initialize(this.context),this.services.agent=new G1(this.interactor,this.aiClientProvider,this.services,this.context.project.root,this.options.agentFolders),this.aiHandler=new jE(this.interactor,this.services.agent,this.aiThreadService),this.handlerLooper=new $E(this.interactor,this.aiHandler,this.configHandler,this.services),this.aiClientProvider.init(this.context),await this.handlerLooper.init(this.context.project),console.log("[CODAY] Initializing services..."),await this.services.agent.initialize(this.context),console.log("[CODAY] Services initialized"))}async initThread(){if(!this.context?.aiThread){if(!this.options.thread)throw Error("No thread given, cannot start Coday instance");await this.aiThreadService.select(this.options.thread)}}async initCommand(){let e;if(this.interactor.debug(`[CODAY] initCommand: ${this.initialPrompts.length} prompts available, oneshot=${this.options.oneshot}`),this.initialPrompts.length)e=this.initialPrompts.shift(),this.interactor.debug(`[CODAY] Using initial prompt: ${e}`),this.initialPrompts.length&&(this.interactor.debug(`[CODAY] Adding ${this.initialPrompts.length} remaining prompts to queue`),this.context?.addCommands(...this.initialPrompts),this.initialPrompts=[]);else if(this.messageQueue.length>0){let t=this.messageQueue.shift();this.interactor.debug(`[CODAY] Consuming queued message from ${t.username}`),e=t.message}else this.options.oneshot?this.interactor.debug("[CODAY] No initial prompts and oneshot mode, exiting"):(this.interactor.debug("[CODAY] No initial prompts, waiting for user input"),e=await this.interactor.promptText(zte));return e}};function ce(r,...e){console.log(`${new Date().toISOString()} ${r}`,...e)}var V9t=4,uT=class{constructor(e,t){this.aiClient=e;this.threadService=t}process(e,t){this.run(e,t).catch(n=>ce("POST_PROCESSOR",`Unhandled error for thread ${e.id}:`,n))}async run(e,t){let n=e.getUserMessageCount();if(n<V9t){ce("POST_PROCESSOR",`Skipping thread ${e.id}: only ${n} user message(s)`);return}ce("POST_PROCESSOR",`Processing thread ${e.id} (${n} user messages)`);let{messages:i}=await e.getMessages(void 0,void 0),a=i.filter(f=>f instanceof Rt).slice(-40).map(f=>{let p=f.role==="user"?"User":f.name||"Assistant",d=f.content.filter(m=>m.type==="text").map(m=>m.content).join(" ").slice(0,500);return`${p}: ${d}`});if(!a.length){ce("POST_PROCESSOR",`Skipping thread ${e.id}: no text messages`);return}let s=`You are given a conversation transcript. Reply ONLY with a valid JSON object (no markdown, no explanation) with two fields:
1404
+ `;let p=n.integrations?new Map(Object.entries(n.integrations).map(([x,k])=>{let S=k&&k.length>0?k:[];return[x,S]})):void 0;this.interactor.debug(`Agent '${n.name}' integrations: ${p?Array.from(p.keys()).join(", "):"ALL (undefined)"}`);let d=performance.now(),m=await this.toolbox.getTools({context:t,integrations:p,agentName:n.name}),h=performance.now()-d;this.interactor.debug(` \u{1F4E6} Tools available for '${n.name}': ${m.map(x=>x.function.name).join(", ")}`);let g=new jx([...m]),v=new cv(n,o,g),y=performance.now()-i;return this.interactor.debug(`\u2728 Agent '${n.name}' created: ${y.toFixed(2)}ms (client: ${s.toFixed(2)}ms, docs: ${f.toFixed(2)}ms, tools: ${h.toFixed(2)}ms)`),v}catch(a){let o=`Failed to create agent ${n.name}`;console.error(`${o}:`,a),this.interactor.error(o);return}}};var W9t=100,cT=class{constructor(e,t,n){this.interactor=e;this.options=t;this.services=n;this.interactor.debugLevelEnabled=t.debug,this.interactor.debug("Coday started with debug"),this.configHandler=new bE(e,this.services),this.maxIterations=W9t,this.aiThreadService=new uE(n.user,n.thread.getThreadRepository(t.project),t.project,e),this.aiThreadService.activeThread.subscribe(i=>{!this.context||!i||(this.context.aiThread=i,this.replayThread(i))}),this.aiClientProvider=new km(this.interactor,this.services.user,this.services.project,this.services.logger),this.interactor.events.pipe((0,xG.filter)(i=>i instanceof Di||i instanceof Ii||i instanceof _r),(0,xG.filter)(()=>!this.isReplaying)).subscribe(i=>{i instanceof Di||i instanceof Ii?this.pendingQuestionEvent=i:i instanceof _r&&this.pendingQuestionEvent&&i.parentKey===this.pendingQuestionEvent.timestamp&&(this.pendingQuestionEvent=null)})}context=null;configHandler;handlerLooper;aiHandler;maxIterations;initialPrompts=[];aiThreadService;killed=!1;isReplaying=!1;pendingQuestionEvent=null;messageQueue=[];aiClientProvider;addUserMessage(e,t){if(this.pendingQuestionEvent){let n=this.pendingQuestionEvent.buildAnswer(t);n.name=e,this.interactor.sendEvent(n)}else{let n=new Rt({role:"user",content:[{type:"text",content:t}],name:e});this.interactor.sendEvent(n),this.messageQueue.push({username:e,message:t})}}replay(){let e=this.aiThreadService.getCurrentThread();if(!e){console.log("No active thread to replay");return}this.replayThread(e),!this.options.oneshot&&e.runStatus!=="RUNNING"&&this.interactor.replayLastInvite()}upload(e){let t=this.aiThreadService.getCurrentThread();if(!t){this.interactor.error("No active thread available for upload");return}let n=this.services.user.username;e.forEach(a=>{t.addUserMessage(n,a)});let i=new Rt({role:"user",content:e,name:n});this.interactor.sendEvent(i)}async run(){this.initialPrompts=this.options.prompts?[...this.options.prompts]:[],this.interactor.debug(`[CODAY] Starting run with ${this.initialPrompts.length} initial prompts`);try{do{if(this.killed)return;if(await this.initContext(),await this.initThread(),!this.context){this.interactor.error("Could not initialize context \u{1F62D}");break}let e=await this.initCommand();if(!e&&this.options.oneshot)break;let t=this.context?.aiThread;t&&(t.runStatus="RUNNING"),this.context?.addCommands(e),this.context=await this.handlerLooper?.handle(this.context)??null}while(!this.context?.oneshot)}finally{this.stop()}await this.cleanup()}stop(){let e=this.context?.aiThread;e&&(e.runStatus="STOPPED"),this.handlerLooper?.stop(),this.aiThreadService.autoSave()}async cleanup(){try{this.services.agent&&await this.services.agent.kill(),this.aiThreadService.kill(),this.aiClientProvider.cleanup(),this.context=null,this.handlerLooper=void 0,this.aiHandler=void 0,this.messageQueue=[],this.pendingQuestionEvent=null}catch(e){console.error("Error during agent cleanup:",e)}}async kill(){this.killed=!0,this.stop();try{await this.cleanup()}catch(e){console.error("Error during kill cleanup:",e)}this.handlerLooper?.kill(),this.interactor.kill()}async replayThread(e){this.isReplaying=!0;try{let t=(await e.getMessages(void 0,void 0)).messages;if(!t?.length)return;let n=[...t].sort((i,a)=>new Date(i.timestamp).getTime()-new Date(a.timestamp).getTime());for(let i of n)(i instanceof Rt||i instanceof ln||i instanceof kn||i instanceof Di||i instanceof Ii||i instanceof _r)&&this.interactor.sendEvent(i);this.interactor.displayText(`Selected thread '${e.name}'`)}finally{this.isReplaying=!1}}async initContext(){if(this.context){this.interactor.debug("[CODAY] Context already initialized, skipping");return}if(this.interactor.debug(`[CODAY] Initializing context for project: ${this.options.project}`),this.context=await this.configHandler.selectProjectHandler.selectProject(this.options.project),!this.context){console.log("[CODAY] ERROR: Failed to create context from selectProject");return}console.log(`[CODAY] Context initialized: '${this.context.project.name}' at ${this.context.project.root}`),this.context&&(this.context.oneshot=this.options.oneshot,this.context.fileReadOnly=this.options.fileReadOnly,this.options.thread&&this.options.project&&(this.context.threadFilesRoot=C7e.join(this.options.configDir,"projects",this.options.project,"threads",`${this.options.thread}-files`),this.interactor.debug(`[CODAY] Thread files root: ${this.context.threadFilesRoot}`)),this.services.aiConfig=new YS(this.services.user,this.services.project),this.services.aiConfig.initialize(this.context),this.services.mcp.initialize(this.context),this.services.agent=new G1(this.interactor,this.aiClientProvider,this.services,this.context.project.root,this.options.agentFolders),this.aiHandler=new jE(this.interactor,this.services.agent,this.aiThreadService),this.handlerLooper=new $E(this.interactor,this.aiHandler,this.configHandler,this.services),this.aiClientProvider.init(this.context),await this.handlerLooper.init(this.context.project),console.log("[CODAY] Initializing services..."),await this.services.agent.initialize(this.context),console.log("[CODAY] Services initialized"))}async initThread(){if(!this.context?.aiThread){if(!this.options.thread)throw Error("No thread given, cannot start Coday instance");await this.aiThreadService.select(this.options.thread)}}async initCommand(){let e;if(this.interactor.debug(`[CODAY] initCommand: ${this.initialPrompts.length} prompts available, oneshot=${this.options.oneshot}`),this.initialPrompts.length)e=this.initialPrompts.shift(),this.interactor.debug(`[CODAY] Using initial prompt: ${e}`),this.initialPrompts.length&&(this.interactor.debug(`[CODAY] Adding ${this.initialPrompts.length} remaining prompts to queue`),this.context?.addCommands(...this.initialPrompts),this.initialPrompts=[]);else if(this.messageQueue.length>0){let t=this.messageQueue.shift();this.interactor.debug(`[CODAY] Consuming queued message from ${t.username}`),e=t.message,this.context&&(this.context.username=t.username)}else this.options.oneshot?this.interactor.debug("[CODAY] No initial prompts and oneshot mode, exiting"):(this.interactor.debug("[CODAY] No initial prompts, waiting for user input"),e=await this.interactor.promptText(zte),this.context&&this.interactor.lastAnswerName&&(this.context.username=this.interactor.lastAnswerName));return e}};function ce(r,...e){console.log(`${new Date().toISOString()} ${r}`,...e)}var V9t=4,uT=class{constructor(e,t){this.aiClient=e;this.threadService=t}process(e,t){this.run(e,t).catch(n=>ce("POST_PROCESSOR",`Unhandled error for thread ${e.id}:`,n))}async run(e,t){let n=e.getUserMessageCount();if(n<V9t){ce("POST_PROCESSOR",`Skipping thread ${e.id}: only ${n} user message(s)`);return}ce("POST_PROCESSOR",`Processing thread ${e.id} (${n} user messages)`);let{messages:i}=await e.getMessages(void 0,void 0),a=i.filter(f=>f instanceof Rt).slice(-40).map(f=>{let p=f.role==="user"?"User":f.name||"Assistant",d=f.content.filter(m=>m.type==="text").map(m=>m.content).join(" ").slice(0,500);return`${p}: ${d}`});if(!a.length){ce("POST_PROCESSOR",`Skipping thread ${e.id}: no text messages`);return}let s=`You are given a conversation transcript. Reply ONLY with a valid JSON object (no markdown, no explanation) with two fields:
1405
1405
  - "name": a short title for the conversation (max 60 chars, no quotes)
1406
1406
  - "summary": 2-4 sentences summarising the main topics and outcomes
1407
1407
 
@@ -1413,13 +1413,13 @@ JSON:`,c,u;try{let p=(await this.aiClient.complete(s,{maxTokens:300})).replace(/
1413
1413
 
1414
1414
  `;e.writableEnded||e.write(o)}}catch(t){ce("THREAD_CODAY","Error replaying thread history:",t)}}removeConnection(e){this.connections.delete(e),ce("THREAD_CODAY",`Removed SSE connection from thread ${this.threadId} (remaining: ${this.connections.size})`),this.connections.size===0&&!this.disconnectTimeout&&(ce("THREAD_CODAY",`No connections remaining for thread ${this.threadId}, starting disconnect timeout`),this.disconnectTimeout=setTimeout(()=>{ce("THREAD_CODAY",`Disconnect timeout reached for thread ${this.threadId}`),this.onTimeout(this.threadId)},r.DISCONNECT_TIMEOUT))}get connectionCount(){return this.connections.size}updateActivity(){this.lastActivity=Date.now(),this.resetInactivityTimeout()}resetInactivityTimeout(){this.inactivityTimeout&&clearTimeout(this.inactivityTimeout);let e=this.isOneshot?r.ONESHOT_TIMEOUT:r.INTERACTIVE_TIMEOUT;this.inactivityTimeout=setTimeout(()=>{let t=Date.now()-this.lastActivity;ce("THREAD_CODAY",`Inactivity timeout reached for thread ${this.threadId} after ${Math.round(t/1e3)}s`),this.onTimeout(this.threadId)},e)}markAsOneshot(){this.isOneshot=!0,this.resetInactivityTimeout()}getInactiveTime(){return Date.now()-this.lastActivity}prepareCoday(){if(this.updateActivity(),this.coday)return ce("THREAD_CODAY",`Coday already running for thread ${this.threadId}`),!1;ce("THREAD_CODAY",`Creating Coday instance for thread ${this.threadId}`),console.log(`[THREAD_CODAY] Preparing instance for thread '${this.threadId}' (project: ${this.projectName}, user: ${this.username})`);let e=new yc(this.threadId),t=new H2(this.options.configDir,this.username,e),n=new wm(e,this.projectService,this.options.configDir),i=new hm(n,t),a=new dm(t,n,e),o=new vm(n,t),s=new gm(t,n,e);return e.events.subscribe(c=>{this.broadcastEvent(c)}),this.coday=new cT(e,this.options,{user:t,project:n,projectService:this.projectService,integration:i,integrationConfig:a,memory:o,mcp:s,mcpPool:this.mcpPool,thread:this.threadService,prompt:this.promptService,logger:this.logger,options:this.options}),console.log(`[THREAD_CODAY] Instance created for thread '${this.threadId}'`),!0}startCoday(){this.updateActivity();let e=this.prepareCoday();return this.coday?(this.coday.run().catch(t=>{ce("THREAD_CODAY",`Error during Coday run for thread ${this.threadId}:`,t),console.error(`Coday run failed for thread ${this.threadId}:`,t)}).finally(()=>{ce("THREAD_CODAY",`Coday run finished for thread ${this.threadId}`)}),e):!1}sendHeartbeat(){if(this.connections.size!==0)try{let e=new O3({});this.broadcastEvent(e)}catch(e){ce("THREAD_CODAY",`Error sending heartbeat for thread ${this.threadId}:`,e)}}broadcastEvent(e){e instanceof uc&&(e.name||e.summary)&&(ce("THREAD_CODAY",`Updating thread cache for ${this.threadId} name/summary`),this.threadService.updateThread(this.projectName,this.threadId,{name:e.name,summary:e.summary}).catch(n=>{ce("THREAD_CODAY","Error updating thread cache:",n)}));let t=`data: ${JSON.stringify(e)}
1415
1415
 
1416
- `;for(let n of this.connections)try{n.writableEnded?this.connections.delete(n):n.write(t)}catch(i){ce("THREAD_CODAY","Error broadcasting to connection:",i),this.connections.delete(n)}}stop(){this.coday?.stop()}async handleOAuthCallback(e){if(!this.coday){ce("THREAD_CODAY",`Cannot handle OAuth callback: Coday not initialized for thread ${this.threadId}`);return}if(!this.coday.services.agent){ce("THREAD_CODAY","Cannot handle OAuth callback: Agent service not initialized");return}let n=this.coday.services.agent?.toolbox;if(!n){ce("THREAD_CODAY","Cannot handle OAuth callback: Toolbox not initialized");return}ce("THREAD_CODAY",`Routing OAuth callback for ${e.integrationName}`),await n.handleOAuthCallback(e)}async cleanup(){ce("THREAD_CODAY",`Cleaning up thread ${this.threadId}`),this.disconnectTimeout&&(clearTimeout(this.disconnectTimeout),this.disconnectTimeout=void 0),this.inactivityTimeout&&(clearTimeout(this.inactivityTimeout),this.inactivityTimeout=void 0);for(let e of this.connections)try{e.end()}catch(t){ce("THREAD_CODAY","Error closing connection:",t)}if(this.connections.clear(),this.coday){let e=this.coday.context?.aiThread,t=this.coday.aiClientProvider,n=t?.getClient(void 0,"SMALL")??t?.getClient(void 0);e&&n?new uT(n,this.threadService).process(e,this.projectName):ce("THREAD_CODAY",`Skipping post-processing for thread ${this.threadId}: no thread or AI client`)}if(this.coday){try{await this.coday.kill()}catch(e){ce("THREAD_CODAY","Error during Coday kill:",e)}this.coday=void 0}}},fT=class r{constructor(e,t,n,i,a){this.logger=e;this.projectService=t;this.threadService=n;this.promptService=i;this.mcpPool=a;this.heartbeatInterval=setInterval(()=>this.sendHeartbeats(),r.HEARTBEAT_INTERVAL),ce("THREAD_CODAY_MANAGER","Heartbeat mechanism started")}instances=new Map;heartbeatInterval;static HEARTBEAT_INTERVAL=3e4;sendHeartbeats(){for(let e of this.instances.values())e.connectionCount>0&&e.sendHeartbeat()}handleInstanceTimeout=async e=>{ce("THREAD_CODAY_MANAGER",`Handling timeout for thread ${e}`),await this.cleanup(e)};getOrCreate(e,t,n,i,a){let o=this.instances.get(e);return o?ce("THREAD_CODAY",`Reusing existing instance for thread ${e}`):(ce("THREAD_CODAY",`Creating new instance for thread ${e}`),o=new lT(e,t,n,i,this.logger,this.projectService,this.threadService,this.promptService,this.mcpPool,this.handleInstanceTimeout),this.instances.set(e,o)),o.addConnection(a),o}createWithoutConnection(e,t,n,i){let a=this.instances.get(e);return a?ce("THREAD_CODAY",`Reusing existing instance for thread ${e}`):(ce("THREAD_CODAY",`Creating new instance for thread ${e} (no SSE connection)`),a=new lT(e,t,n,i,this.logger,this.projectService,this.threadService,this.promptService,this.mcpPool,this.handleInstanceTimeout),a.markAsOneshot(),this.instances.set(e,a)),a}get(e){return this.instances.get(e)}removeConnection(e,t){let n=this.instances.get(e);n&&(n.removeConnection(t),n.connectionCount===0&&ce("THREAD_CODAY",`Thread ${e} has no active connections but instance kept alive`))}stop(e){let t=this.instances.get(e);t&&t.stop()}async cleanup(e){let t=this.instances.get(e);t&&(await this.mcpPool.releaseThread(e),await t.cleanup(),this.instances.delete(e),ce("THREAD_CODAY",`Removed instance for thread ${e}`))}getStats(){let e=0,t=0;for(let n of this.instances.values())n.connectionCount>0&&e++,n.isOneshot&&t++;return{total:this.instances.size,withConnections:e,oneshot:t}}async shutdown(){ce("THREAD_CODAY_MANAGER",`Shutting down ${this.instances.size} thread instances`),this.heartbeatInterval&&(clearInterval(this.heartbeatInterval),ce("THREAD_CODAY_MANAGER","Heartbeat mechanism stopped"));let e=[];for(let[t,n]of this.instances.entries())ce("THREAD_CODAY_MANAGER",`Cleaning up thread ${t}`),e.push(n.cleanup());await Promise.all(e),this.instances.clear(),await this.mcpPool.shutdown(),ce("THREAD_CODAY_MANAGER","All thread instances cleaned up")}};import*as Ixe from"node:os";async function T7e(r,e=100){let t=await import("node:net");return new Promise((n,i)=>{function a(o,s){let c=t.createServer();c.listen(o,()=>{c.close(()=>{ce("PORT",`Port ${o} is available`),n(o)})}),c.on("error",u=>{u.code==="EADDRINUSE"?s>0?(ce("PORT",`Port ${o} is in use, trying next`),a(o+1,s-1)):i(new Error(`Could not find an available port starting from ${r}`)):i(u)})}a(r,e)})}function P7e(r,e,t){r.get("/api/config/user",(n,i)=>{try{let a=t(n);if(!a){i.status(401).json({error:"Username not found in request headers"});return}ce("CONFIG",`GET user config for: ${a}`);let c={...e.getUserService(a).getConfigForClient(),username:a};i.status(200).json(c)}catch(a){console.error("Error retrieving user config:",a),i.status(500).json({error:"Failed to retrieve user configuration"})}}),r.put("/api/config/user",(n,i)=>{try{let a=t(n);if(!a){i.status(401).json({error:"Username not found in request headers"});return}let o=n.body;if(!o||typeof o!="object"){i.status(422).json({error:"Invalid configuration format"});return}if(typeof o.version!="number"){i.status(422).json({error:"Configuration must have a version number"});return}ce("CONFIG",`PUT user config for: ${a}`),e.getUserService(a).updateConfigFromClient(o),i.status(200).json({success:!0,message:"User configuration updated successfully"})}catch(a){console.error("Error updating user config:",a);let o=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to update user configuration: ${o}`})}})}function je(r){return Array.isArray(r)?r[0]||"":r||""}function D7e(r,e){r.get("/api/projects",(t,n)=>{try{ce("PROJECT","GET all projects");let i=e.listProjects(),a=e.getDefaultProject(),o=e.getForcedMode();n.status(200).json({projects:i,defaultProject:a,forcedProject:o?a:null})}catch(i){console.error("Error listing projects:",i),n.status(500).json({error:"Failed to list projects"})}}),r.get("/api/projects/:name",(t,n)=>{try{let i=je(t.params.name);if(!i){n.status(400).json({error:"Project name is required"});return}ce("PROJECT",`GET project: ${i}`);let a=e.getProject(i);if(!a){n.status(404).json({error:`Project '${i}' not found`});return}n.status(200).json(a)}catch(i){console.error("Error retrieving project:",i),n.status(500).json({error:"Failed to retrieve project"})}}),r.post("/api/projects",(t,n)=>{try{let{name:i,path:a}=t.body;if(!i||!a){n.status(400).json({error:"Project name and path are required"});return}ce("PROJECT",`POST create project: ${i} at ${a}`),e.createProject(i,a),n.status(201).json({success:!0,message:`Project '${i}' created successfully`})}catch(i){console.error("Error creating project:",i);let a=i instanceof Error?i.message:"Unknown error";n.status(500).json({error:`Failed to create project: ${a}`})}}),r.get("/api/projects/:name/config",(t,n)=>{try{let i=je(t.params.name);if(!i){n.status(400).json({error:"Project name is required"});return}ce("PROJECT",`GET project config: ${i}`);let a=e.getProjectConfigForClient(i);if(!a){n.status(404).json({error:`Project '${i}' not found`});return}n.status(200).json(a)}catch(i){console.error("Error retrieving project config:",i),n.status(500).json({error:"Failed to retrieve project configuration"})}}),r.put("/api/projects/:name/config",(t,n)=>{try{let i=je(t.params.name);if(!i){n.status(400).json({error:"Project name is required"});return}let a=t.body;if(!a||typeof a!="object"){n.status(422).json({error:"Invalid configuration format"});return}if(typeof a.version!="number"){n.status(422).json({error:"Configuration must have a version number"});return}if(!a.path||typeof a.path!="string"){n.status(422).json({error:"Configuration must have a valid path"});return}ce("PROJECT",`PUT project config: ${i}`),e.updateProjectConfigFromClient(i,a),n.status(200).json({success:!0,message:"Project configuration updated successfully"})}catch(i){console.error("Error updating project config:",i);let a=i instanceof Error?i.message:"Unknown error";n.status(500).json({error:`Failed to update project configuration: ${a}`})}}),r.delete("/api/projects/:name",(t,n)=>{try{let i=je(t.params.name);if(!i){n.status(400).json({error:"Project name is required"});return}ce("PROJECT",`DELETE project: ${i}`),e.deleteProject(i),n.status(200).json({success:!0,message:`Project '${i}' deleted successfully`})}catch(i){console.error("Error deleting project:",i);let a=i instanceof Error?i.message:"Unknown error";n.status(500).json({error:`Failed to delete project: ${a}`})}})}import{existsSync as G9t,readFileSync as Z9t}from"fs";function I7e(r,e,t,n,i,a){r.get("/api/projects/:projectName/threads",async(o,s)=>{try{let c=je(o.params.projectName);if(!c){s.status(400).json({error:"Project name is required"});return}let u=i(o);if(!u){s.status(401).json({error:"Authentication required"});return}ce("THREAD",`GET threads for project: ${c}, user: ${u}`);let l=await e.listThreads(c,u);s.status(200).json(l)}catch(c){console.error("Error listing threads:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to list threads: ${u}`})}}),r.post("/api/projects/:projectName/threads",async(o,s)=>{try{let c=je(o.params.projectName);if(!c){s.status(400).json({error:"Project name is required"});return}let u=i(o);if(!u){s.status(401).json({error:"Authentication required"});return}let{name:l}=o.body;ce("THREAD",`POST create thread in project: ${c}, user: ${u}, name: ${l||"untitled"}`);let f=await e.createThread(c,u,l);s.status(201).json({success:!0,thread:{id:f.id,name:f.name,projectId:f.projectId,username:f.username,createdDate:f.createdDate,modifiedDate:f.modifiedDate}})}catch(c){console.error("Error creating thread:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to create thread: ${u}`})}}),r.get("/api/projects/:projectName/threads/:threadId",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId);if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}let l=i(o);if(!l){s.status(401).json({error:"Authentication required"});return}ce("THREAD",`GET thread: ${u} from project: ${c}`);let f=await e.getThread(c,u);if(!f){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}if(!rn(f,l)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}s.status(200).json({id:f.id,name:f.name,projectId:f.projectId,username:f.username,summary:f.summary,createdDate:f.createdDate,modifiedDate:f.modifiedDate,price:f.price,messageCount:f.messagesLength,users:f.users})}catch(c){console.error("Error retrieving thread:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to retrieve thread: ${u}`})}}),r.put("/api/projects/:projectName/threads/:threadId",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId);if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}let l=i(o);if(!l){s.status(401).json({error:"Authentication required"});return}let{name:f,users:p}=o.body,d=await e.getThread(c,u);if(!d){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}if(!rn(d,l)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}let m;if(p!==void 0){if(!rn(d,l)){s.status(403).json({error:"Access denied: only thread participants can modify the users list"});return}if(!Array.isArray(p)){s.status(400).json({error:"Invalid users format: must be an array"});return}for(let v of p)if(!v||typeof v.userId!="string"||v.userId.trim()===""){s.status(400).json({error:"Invalid users format: each user must have a non-empty userId string"});return}m=p.some(v=>v.userId===l)?p:[{userId:l},...p]}ce("THREAD",`PUT update thread: ${u} in project: ${c}`);let h=await e.updateThread(c,u,{name:f,users:m});if(m!==void 0){let v=n.get(u)?.coday?.context?.aiThread;v&&(v.users=m,ce("THREAD",`Synced users to live AiThread for thread ${u}`))}s.status(200).json({success:!0,thread:{id:h.id,name:h.name,projectId:h.projectId,modifiedDate:h.modifiedDate}})}catch(c){console.error("Error updating thread:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to update thread: ${u}`})}}),r.get("/api/projects/:projectName/threads/:threadId/messages",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId);if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}let l=i(o);if(!l){s.status(401).json({error:"Authentication required"});return}ce("THREAD",`GET messages for thread: ${u} in project: ${c}`);let f=await e.getThread(c,u);if(!f){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}if(!rn(f,l)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}let{messages:p}=await f.getMessages(void 0,void 0);s.status(200).json({messages:p})}catch(c){console.error("Error retrieving thread messages:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to retrieve thread messages: ${u}`})}}),r.post("/api/projects/:projectName/threads/:threadId/star",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId);if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}let l=i(o);if(!l){s.status(401).json({error:"Authentication required"});return}if(!await e.getThread(c,u)){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}ce("THREAD",`POST star thread: ${u} in project: ${c} by user: ${l}`);let p=await e.starThread(c,u,l);s.status(200).json({success:!0,thread:{id:p.id,starring:p.starring,modifiedDate:p.modifiedDate}})}catch(c){console.error("Error starring thread:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to star thread: ${u}`})}}),r.delete("/api/projects/:projectName/threads/:threadId/star",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId);if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}let l=i(o);if(!l){s.status(401).json({error:"Authentication required"});return}if(!await e.getThread(c,u)){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}ce("THREAD",`DELETE unstar thread: ${u} in project: ${c} by user: ${l}`);let p=await e.unstarThread(c,u,l);s.status(200).json({success:!0,thread:{id:p.id,starring:p.starring,modifiedDate:p.modifiedDate}})}catch(c){console.error("Error unstarring thread:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to unstar thread: ${u}`})}}),r.post("/api/projects/:projectName/threads/:threadId/stop",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId);if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}let l=i(o);if(!l){s.status(401).json({error:"Authentication required"});return}let f=await e.getThread(c,u);if(!f){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}if(!rn(f,l)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}ce("THREAD",`POST stop thread: ${u} in project: ${c}`),n.stop(u),s.status(200).json({success:!0,message:"Stop signal sent successfully"})}catch(c){console.error("Error stopping thread:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to stop thread: ${u}`})}}),r.delete("/api/projects/:projectName/threads/:threadId",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId);if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}let l=i(o);if(!l){s.status(401).json({error:"Authentication required"});return}let f=await e.getThread(c,u);if(!f){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}if(!rn(f,l)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}ce("THREAD",`DELETE
1416
+ `;for(let n of this.connections)try{n.writableEnded?this.connections.delete(n):n.write(t)}catch(i){ce("THREAD_CODAY","Error broadcasting to connection:",i),this.connections.delete(n)}}stop(){this.coday?.stop()}async handleOAuthCallback(e){if(!this.coday){ce("THREAD_CODAY",`Cannot handle OAuth callback: Coday not initialized for thread ${this.threadId}`);return}if(!this.coday.services.agent){ce("THREAD_CODAY","Cannot handle OAuth callback: Agent service not initialized");return}let n=this.coday.services.agent?.toolbox;if(!n){ce("THREAD_CODAY","Cannot handle OAuth callback: Toolbox not initialized");return}ce("THREAD_CODAY",`Routing OAuth callback for ${e.integrationName}`),await n.handleOAuthCallback(e)}async cleanup(){ce("THREAD_CODAY",`Cleaning up thread ${this.threadId}`),this.disconnectTimeout&&(clearTimeout(this.disconnectTimeout),this.disconnectTimeout=void 0),this.inactivityTimeout&&(clearTimeout(this.inactivityTimeout),this.inactivityTimeout=void 0);for(let e of this.connections)try{e.end()}catch(t){ce("THREAD_CODAY","Error closing connection:",t)}if(this.connections.clear(),this.coday){let e=this.coday.context?.aiThread,t=this.coday.aiClientProvider,n=t?.getClient(void 0,"SMALL")??t?.getClient(void 0);e&&n?new uT(n,this.threadService).process(e,this.projectName):ce("THREAD_CODAY",`Skipping post-processing for thread ${this.threadId}: no thread or AI client`)}if(this.coday){try{await this.coday.kill()}catch(e){ce("THREAD_CODAY","Error during Coday kill:",e)}this.coday=void 0}}},fT=class r{constructor(e,t,n,i,a){this.logger=e;this.projectService=t;this.threadService=n;this.promptService=i;this.mcpPool=a;this.heartbeatInterval=setInterval(()=>this.sendHeartbeats(),r.HEARTBEAT_INTERVAL),ce("THREAD_CODAY_MANAGER","Heartbeat mechanism started")}instances=new Map;heartbeatInterval;static HEARTBEAT_INTERVAL=3e4;sendHeartbeats(){for(let e of this.instances.values())e.connectionCount>0&&e.sendHeartbeat()}handleInstanceTimeout=async e=>{ce("THREAD_CODAY_MANAGER",`Handling timeout for thread ${e}`),await this.cleanup(e)};getOrCreate(e,t,n,i,a){let o=this.instances.get(e);return o?ce("THREAD_CODAY",`Reusing existing instance for thread ${e}`):(ce("THREAD_CODAY",`Creating new instance for thread ${e}`),o=new lT(e,t,n,i,this.logger,this.projectService,this.threadService,this.promptService,this.mcpPool,this.handleInstanceTimeout),this.instances.set(e,o)),o.addConnection(a),o}createWithoutConnection(e,t,n,i){let a=this.instances.get(e);return a?ce("THREAD_CODAY",`Reusing existing instance for thread ${e}`):(ce("THREAD_CODAY",`Creating new instance for thread ${e} (no SSE connection)`),a=new lT(e,t,n,i,this.logger,this.projectService,this.threadService,this.promptService,this.mcpPool,this.handleInstanceTimeout),a.markAsOneshot(),this.instances.set(e,a)),a}get(e){return this.instances.get(e)}removeConnection(e,t){let n=this.instances.get(e);n&&(n.removeConnection(t),n.connectionCount===0&&ce("THREAD_CODAY",`Thread ${e} has no active connections but instance kept alive`))}stop(e){let t=this.instances.get(e);t&&t.stop()}async cleanup(e){let t=this.instances.get(e);t&&(await this.mcpPool.releaseThread(e),await t.cleanup(),this.instances.delete(e),ce("THREAD_CODAY",`Removed instance for thread ${e}`))}getStats(){let e=0,t=0;for(let n of this.instances.values())n.connectionCount>0&&e++,n.isOneshot&&t++;return{total:this.instances.size,withConnections:e,oneshot:t}}async shutdown(){ce("THREAD_CODAY_MANAGER",`Shutting down ${this.instances.size} thread instances`),this.heartbeatInterval&&(clearInterval(this.heartbeatInterval),ce("THREAD_CODAY_MANAGER","Heartbeat mechanism stopped"));let e=[];for(let[t,n]of this.instances.entries())ce("THREAD_CODAY_MANAGER",`Cleaning up thread ${t}`),e.push(n.cleanup());await Promise.all(e),this.instances.clear(),await this.mcpPool.shutdown(),ce("THREAD_CODAY_MANAGER","All thread instances cleaned up")}};import*as Ixe from"node:os";async function T7e(r,e=100){let t=await import("node:net");return new Promise((n,i)=>{function a(o,s){let c=t.createServer();c.listen(o,()=>{c.close(()=>{ce("PORT",`Port ${o} is available`),n(o)})}),c.on("error",u=>{u.code==="EADDRINUSE"?s>0?(ce("PORT",`Port ${o} is in use, trying next`),a(o+1,s-1)):i(new Error(`Could not find an available port starting from ${r}`)):i(u)})}a(r,e)})}function P7e(r,e,t){r.get("/api/config/user",(n,i)=>{try{let a=t(n);if(!a){i.status(401).json({error:"Username not found in request headers"});return}ce("CONFIG",`GET user config for: ${a}`);let c={...e.getUserService(a).getConfigForClient(),username:a};i.status(200).json(c)}catch(a){console.error("Error retrieving user config:",a),i.status(500).json({error:"Failed to retrieve user configuration"})}}),r.put("/api/config/user",(n,i)=>{try{let a=t(n);if(!a){i.status(401).json({error:"Username not found in request headers"});return}let o=n.body;if(!o||typeof o!="object"){i.status(422).json({error:"Invalid configuration format"});return}if(typeof o.version!="number"){i.status(422).json({error:"Configuration must have a version number"});return}ce("CONFIG",`PUT user config for: ${a}`),e.getUserService(a).updateConfigFromClient(o),i.status(200).json({success:!0,message:"User configuration updated successfully"})}catch(a){console.error("Error updating user config:",a);let o=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to update user configuration: ${o}`})}})}function je(r){return Array.isArray(r)?r[0]||"":r||""}function D7e(r,e){r.get("/api/projects",(t,n)=>{try{ce("PROJECT","GET all projects");let i=e.listProjects(),a=e.getDefaultProject(),o=e.getForcedMode();n.status(200).json({projects:i,defaultProject:a,forcedProject:o?a:null})}catch(i){console.error("Error listing projects:",i),n.status(500).json({error:"Failed to list projects"})}}),r.get("/api/projects/:name",(t,n)=>{try{let i=je(t.params.name);if(!i){n.status(400).json({error:"Project name is required"});return}ce("PROJECT",`GET project: ${i}`);let a=e.getProject(i);if(!a){n.status(404).json({error:`Project '${i}' not found`});return}n.status(200).json(a)}catch(i){console.error("Error retrieving project:",i),n.status(500).json({error:"Failed to retrieve project"})}}),r.post("/api/projects",(t,n)=>{try{let{name:i,path:a}=t.body;if(!i||!a){n.status(400).json({error:"Project name and path are required"});return}ce("PROJECT",`POST create project: ${i} at ${a}`),e.createProject(i,a),n.status(201).json({success:!0,message:`Project '${i}' created successfully`})}catch(i){console.error("Error creating project:",i);let a=i instanceof Error?i.message:"Unknown error";n.status(500).json({error:`Failed to create project: ${a}`})}}),r.get("/api/projects/:name/config",(t,n)=>{try{let i=je(t.params.name);if(!i){n.status(400).json({error:"Project name is required"});return}ce("PROJECT",`GET project config: ${i}`);let a=e.getProjectConfigForClient(i);if(!a){n.status(404).json({error:`Project '${i}' not found`});return}n.status(200).json(a)}catch(i){console.error("Error retrieving project config:",i),n.status(500).json({error:"Failed to retrieve project configuration"})}}),r.put("/api/projects/:name/config",(t,n)=>{try{let i=je(t.params.name);if(!i){n.status(400).json({error:"Project name is required"});return}let a=t.body;if(!a||typeof a!="object"){n.status(422).json({error:"Invalid configuration format"});return}if(typeof a.version!="number"){n.status(422).json({error:"Configuration must have a version number"});return}if(!a.path||typeof a.path!="string"){n.status(422).json({error:"Configuration must have a valid path"});return}ce("PROJECT",`PUT project config: ${i}`),e.updateProjectConfigFromClient(i,a),n.status(200).json({success:!0,message:"Project configuration updated successfully"})}catch(i){console.error("Error updating project config:",i);let a=i instanceof Error?i.message:"Unknown error";n.status(500).json({error:`Failed to update project configuration: ${a}`})}}),r.delete("/api/projects/:name",(t,n)=>{try{let i=je(t.params.name);if(!i){n.status(400).json({error:"Project name is required"});return}ce("PROJECT",`DELETE project: ${i}`),e.deleteProject(i),n.status(200).json({success:!0,message:`Project '${i}' deleted successfully`})}catch(i){console.error("Error deleting project:",i);let a=i instanceof Error?i.message:"Unknown error";n.status(500).json({error:`Failed to delete project: ${a}`})}})}import{existsSync as G9t,readFileSync as Z9t}from"fs";function I7e(r,e,t,n,i,a){r.get("/api/projects/:projectName/threads",async(o,s)=>{try{let c=je(o.params.projectName);if(!c){s.status(400).json({error:"Project name is required"});return}let u=i(o);if(!u){s.status(401).json({error:"Authentication required"});return}ce("THREAD",`GET threads for project: ${c}, user: ${u}`);let l=await e.listThreads(c,u);s.status(200).json(l)}catch(c){console.error("Error listing threads:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to list threads: ${u}`})}}),r.post("/api/projects/:projectName/threads",async(o,s)=>{try{let c=je(o.params.projectName);if(!c){s.status(400).json({error:"Project name is required"});return}let u=i(o);if(!u){s.status(401).json({error:"Authentication required"});return}let{name:l}=o.body;ce("THREAD",`POST create thread in project: ${c}, user: ${u}, name: ${l||"untitled"}`);let f=await e.createThread(c,u,l);s.status(201).json({success:!0,thread:{id:f.id,name:f.name,projectId:f.projectId,username:f.username,createdDate:f.createdDate,modifiedDate:f.modifiedDate}})}catch(c){console.error("Error creating thread:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to create thread: ${u}`})}}),r.get("/api/projects/:projectName/threads/:threadId",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId);if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}let l=i(o);if(!l){s.status(401).json({error:"Authentication required"});return}ce("THREAD",`GET thread: ${u} from project: ${c}`);let f=await e.getThread(c,u);if(!f){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}if(!rn(f,l)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}s.status(200).json({id:f.id,name:f.name,projectId:f.projectId,username:f.username,summary:f.summary,createdDate:f.createdDate,modifiedDate:f.modifiedDate,price:f.price,messageCount:f.messagesLength,users:f.users})}catch(c){console.error("Error retrieving thread:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to retrieve thread: ${u}`})}}),r.put("/api/projects/:projectName/threads/:threadId",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId);if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}let l=i(o);if(!l){s.status(401).json({error:"Authentication required"});return}let{name:f,users:p}=o.body,d=await e.getThread(c,u);if(!d){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}if(!rn(d,l)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}let m;if(p!==void 0){if(!rn(d,l)){s.status(403).json({error:"Access denied: only thread participants can modify the users list"});return}if(!Array.isArray(p)){s.status(400).json({error:"Invalid users format: must be an array"});return}for(let g of p)if(!g||typeof g.userId!="string"||g.userId.trim()===""){s.status(400).json({error:"Invalid users format: each user must have a non-empty userId string"});return}m=p}ce("THREAD",`PUT update thread: ${u} in project: ${c}`);let h=await e.updateThread(c,u,{name:f,users:m});if(m!==void 0){let v=n.get(u)?.coday?.context?.aiThread;v&&(v.users=m,ce("THREAD",`Synced users to live AiThread for thread ${u}`))}s.status(200).json({success:!0,thread:{id:h.id,name:h.name,projectId:h.projectId,modifiedDate:h.modifiedDate}})}catch(c){console.error("Error updating thread:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to update thread: ${u}`})}}),r.get("/api/projects/:projectName/threads/:threadId/messages",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId);if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}let l=i(o);if(!l){s.status(401).json({error:"Authentication required"});return}ce("THREAD",`GET messages for thread: ${u} in project: ${c}`);let f=await e.getThread(c,u);if(!f){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}if(!rn(f,l)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}let{messages:p}=await f.getMessages(void 0,void 0);s.status(200).json({messages:p})}catch(c){console.error("Error retrieving thread messages:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to retrieve thread messages: ${u}`})}}),r.post("/api/projects/:projectName/threads/:threadId/star",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId);if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}let l=i(o);if(!l){s.status(401).json({error:"Authentication required"});return}if(!await e.getThread(c,u)){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}ce("THREAD",`POST star thread: ${u} in project: ${c} by user: ${l}`);let p=await e.starThread(c,u,l);s.status(200).json({success:!0,thread:{id:p.id,starring:p.starring,modifiedDate:p.modifiedDate}})}catch(c){console.error("Error starring thread:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to star thread: ${u}`})}}),r.delete("/api/projects/:projectName/threads/:threadId/star",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId);if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}let l=i(o);if(!l){s.status(401).json({error:"Authentication required"});return}if(!await e.getThread(c,u)){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}ce("THREAD",`DELETE unstar thread: ${u} in project: ${c} by user: ${l}`);let p=await e.unstarThread(c,u,l);s.status(200).json({success:!0,thread:{id:p.id,starring:p.starring,modifiedDate:p.modifiedDate}})}catch(c){console.error("Error unstarring thread:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to unstar thread: ${u}`})}}),r.post("/api/projects/:projectName/threads/:threadId/stop",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId);if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}let l=i(o);if(!l){s.status(401).json({error:"Authentication required"});return}let f=await e.getThread(c,u);if(!f){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}if(!rn(f,l)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}ce("THREAD",`POST stop thread: ${u} in project: ${c}`),n.stop(u),s.status(200).json({success:!0,message:"Stop signal sent successfully"})}catch(c){console.error("Error stopping thread:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to stop thread: ${u}`})}}),r.delete("/api/projects/:projectName/threads/:threadId",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId);if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}let l=i(o);if(!l){s.status(401).json({error:"Authentication required"});return}let f=await e.getThread(c,u);if(!f){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}if(!rn(f,l)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}ce("THREAD",`DELETE
1417
1417
  thread:
1418
1418
  ${u}
1419
1419
  from
1420
1420
  project
1421
1421
  :
1422
- ${c}`),await e.deleteThread(c,u)?s.status(200).json({success:!0,message:`Thread '${u}' deleted successfully`}):s.status(404).json({error:`Thread '${u}' not found`})}catch(c){console.error("Error deleting thread:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to delete thread: ${u}`})}}),r.post("/api/projects/:projectName/threads/:threadId/upload",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId),{content:l,mimeType:f,filename:p}=o.body;if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}if(!l||!f||!p){s.status(400).json({error:"Missing required fields: content, mimeType, filename"});return}let d=i(o);if(!d){s.status(401).json({error:"Authentication required"});return}ce("UPLOAD",`threadId: ${u}, project: ${c}, uploading: ${p}`);let m=n.get(u);if(!m?.coday){s.status(404).json({error:"Thread not found or not active"});return}let h=await e.getThread(c,u);if(!h||!rn(h,d)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}let g=Buffer.from(l,"base64");if(g.length>10485760){s.status(400).json({error:`File too large: ${(g.length/1024/1024).toFixed(2)} MB exceeds maximum of ${10485760/1024/1024} MB`});return}if(f.startsWith("image/")){let y=await Xw(g,f),x={type:"image",content:y.content,mimeType:y.mimeType,width:y.width,height:y.height,source:`${p} (${(y.processedSize/1024).toFixed(1)} KB)`};m.coday.upload([x]),s.status(200).json({success:!0,type:"image",processedSize:y.processedSize,dimensions:{width:y.width,height:y.height}})}else{if(!$x(p)){s.status(400).json({error:`File type not allowed. Allowed extensions: ${Hie()}`});return}await t.saveFile(c,u,p,g);let y=(g.length/1024).toFixed(1),x={type:"text",content:`\u{1F4CE} Document uploaded: ${p} (${y} KB)`};m.coday.upload([x]),ce("UPLOAD",`File saved to thread workspace: ${p}`),s.status(200).json({success:!0,type:"file",filename:p,size:g.length,path:`thread://${p}`})}}catch(c){console.error("Error processing file upload:",c);let u=c instanceof Error?c.message:"Upload failed";s.status(400).json({error:u})}}),r.get("/api/projects/:projectName/threads/:threadId/files",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId);if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}let l=i(o);if(!l){s.status(401).json({error:"Authentication required"});return}let f=await e.getThread(c,u);if(!f){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}if(!rn(f,l)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}let p=await t.listFiles(c,u);s.status(200).json({files:p})}catch(c){console.error("Error listing files:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to list files: ${u}`})}}),r.get("/api/projects/:projectName/threads/:threadId/files/:filename",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId),l=je(o.params.filename);if(!c||!u||!l){s.status(400).json({error:"Project name, thread ID, and filename are required"});return}let f=i(o);if(!f){s.status(401).json({error:"Authentication required"});return}let p=await e.getThread(c,u);if(!p){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}if(!rn(p,f)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}let d=l,m=await t.getFilePath(c,u,d);if(!G9t(m)){s.status(404).json({error:`File '${d}' not found`});return}let h=encodeURIComponent(d);s.setHeader("Content-Disposition",`attachment; filename="${d.replace(/"/g,'\\"')}"; filename*=UTF-8''${h}`);try{let g=Z9t(m);s.send(g)}catch(g){s.status(500).json({error:`Failed to read file: ${g instanceof Error?g.message:"Unknown error"}`})}}catch(c){console.error("Error downloading file:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to download file: ${u}`})}}),r.delete("/api/projects/:projectName/threads/:threadId/files/:filename",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId),l=je(o.params.filename);if(!c||!u||!l){s.status(400).json({error:"Project name, thread ID, and filename are required"});return}let f=i(o);if(!f){s.status(401).json({error:"Authentication required"});return}let p=await e.getThread(c,u);if(!p){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}if(!rn(p,f)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}await t.deleteFile(c,u,l),s.status(200).json({success:!0,message:`File '${l}' deleted successfully`})}catch(c){console.error("Error deleting file:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to delete file: ${u}`})}}),r.get("/api/projects/:projectName/threads/:threadId/event-stream",async(o,s)=>{let c=je(o.params.projectName),u=je(o.params.threadId),l=i(o);if(!c||!u){s.status(400).send("Project name and thread ID are required");return}if(ce("THREAD_SSE",`New connection request for thread ${u} in project ${c}`),!l){ce("THREAD_SSE","Rejected: No username provided"),s.status(401).send("Authentication required");return}s.setHeader("Content-Type","text/event-stream"),s.setHeader("Cache-Control","no-cache"),s.setHeader("Connection","keep-alive");let f={...a,project:c,thread:u},p=n.getOrCreate(u,c,l,f,s);o.on("close",()=>{ce("THREAD_SSE",`Client disconnected from thread ${u}`),n.removeConnection(u,s)}),p.startCoday()?ce("THREAD_SSE",`New Coday instance started for thread ${u}`):ce("THREAD_SSE",`Reconnected to existing Coday instance for thread ${u}`)})}function O7e(r,e,t){r.get("/api/projects/:projectName/threads/:threadId/messages",async(n,i)=>{try{let{projectName:a,threadId:o}=n.params;if(!a||!o){i.status(400).json({error:"Project name and thread ID are required"});return}let s=t(n);if(!s){i.status(401).json({error:"Authentication required"});return}ce("MESSAGE",`GET messages for thread: ${o} in project: ${a}`);let c=e.get(o);if(!c?.coday){i.status(404).json({error:`Thread '${o}' not found or not active`});return}let u=c.coday.context?.aiThread;if(!u||!rn(u,s)){i.status(403).json({error:"Access denied: thread belongs to another user"});return}if(!u){i.status(500).json({error:"Thread not properly initialized"});return}let f=(await u.getMessages(void 0,void 0)).messages;i.status(200).json(f)}catch(a){console.error("Error listing messages:",a);let o=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to list messages: ${o}`})}}),r.post("/api/projects/:projectName/threads/:threadId/messages",async(n,i)=>{try{let{projectName:a,threadId:o}=n.params,s=n.body;if(!a||!o){i.status(400).send("Project name and thread ID are required");return}let c=t(n);if(!c){i.status(401).send("Authentication required");return}ce("MESSAGE",`threadId: ${o}, project: ${a}, received message of type: ${s.type||"answer"}`);let u=e.get(o);if(!u?.coday){i.status(404).send("Thread not found or not connected");return}let l=u.coday.context?.aiThread;if(!l||!rn(l,c)){i.status(403).send("Access denied: thread belongs to another user");return}if(s.type==="oauth_callback"){let f=sv(s);if(f&&u.coday.services.agent){ce("MESSAGE",`Routing OAuth callback for ${f.integrationName}`);let p=u.coday.services.agent.toolbox;if(p&&"handleOAuthCallback"in p){await p.handleOAuthCallback(f),i.status(200).send("OAuth callback handled successfully!");return}}else ce("MESSAGE","No agent service available for OAuth callback routing")}if(s.type==="answer"){u.coday.interactor.sendEvent(new _r(s)),i.status(200).send("Message received successfully!");return}if(s.message){ce("MESSAGE",`Free-form message from ${c}: ${s.message.substring(0,50)}`),u.coday.addUserMessage(c,s.message),i.status(200).json({queued:!0});return}i.status(400).send("Invalid message payload: must include either type or message field")}catch(a){console.error("Error processing event:",a),i.status(400).send("Invalid event data!")}}),r.get("/api/projects/:projectName/threads/:threadId/messages/:eventId",async(n,i)=>{try{let{projectName:a,threadId:o,eventId:s}=n.params;if(!a||!o||!s){i.status(400).json({error:"Project name, thread ID, and event ID are required"});return}let c=decodeURIComponent(s),u=t(n);if(!u){i.status(401).json({error:"Authentication required"});return}ce("MESSAGE",`GET message: ${c} from thread: ${o} in project: ${a}`);let l=e.get(o);if(!l?.coday){i.status(404).json({error:`Thread '${o}' not found or not active`});return}let f=l.coday.context?.aiThread;if(!f||!rn(f,u)){i.status(403).json({error:"Access denied: thread belongs to another user"});return}let p=f.getEventById(c);if(!p){i.status(404).json({error:`Message '${c}' not found in thread '${o}'`});return}i.status(200).json(p)}catch(a){console.error("Error retrieving message:",a);let o=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to retrieve message: ${o}`})}}),r.get("/api/projects/:projectName/threads/:threadId/messages/:eventId/formatted",async(n,i)=>{try{let{projectName:a,threadId:o,eventId:s}=n.params;if(!a||!o||!s){i.status(400).send("Project name, thread ID, and event ID are required");return}let c=decodeURIComponent(s),u=t(n);if(!u){i.status(401).send("Authentication required");return}ce("MESSAGE",`GET formatted message: ${c} from thread: ${o} in project: ${a}`);let l=e.get(o);if(!l?.coday){i.status(404).send("Thread not found or not active");return}let f=l.coday.context?.aiThread;if(!f||!rn(f,u)){i.status(403).send("Access denied: thread belongs to another user");return}let p=f.getEventById(c);if(!p){i.status(404).send(`Message '${c}' not found in thread '${o}'`);return}i.setHeader("Content-Type","text/plain");let d="";if(p.type==="tool_request")d=`Tool Request: ${p.name}
1422
+ ${c}`),await e.deleteThread(c,u)?s.status(200).json({success:!0,message:`Thread '${u}' deleted successfully`}):s.status(404).json({error:`Thread '${u}' not found`})}catch(c){console.error("Error deleting thread:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to delete thread: ${u}`})}}),r.post("/api/projects/:projectName/threads/:threadId/upload",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId),{content:l,mimeType:f,filename:p}=o.body;if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}if(!l||!f||!p){s.status(400).json({error:"Missing required fields: content, mimeType, filename"});return}let d=i(o);if(!d){s.status(401).json({error:"Authentication required"});return}ce("UPLOAD",`threadId: ${u}, project: ${c}, uploading: ${p}`);let m=n.get(u);if(!m?.coday){s.status(404).json({error:"Thread not found or not active"});return}let h=await e.getThread(c,u);if(!h||!rn(h,d)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}let g=Buffer.from(l,"base64");if(g.length>10485760){s.status(400).json({error:`File too large: ${(g.length/1024/1024).toFixed(2)} MB exceeds maximum of ${10485760/1024/1024} MB`});return}if(f.startsWith("image/")){let y=await Xw(g,f),x={type:"image",content:y.content,mimeType:y.mimeType,width:y.width,height:y.height,source:`${p} (${(y.processedSize/1024).toFixed(1)} KB)`};m.coday.upload([x]),s.status(200).json({success:!0,type:"image",processedSize:y.processedSize,dimensions:{width:y.width,height:y.height}})}else{if(!$x(p)){s.status(400).json({error:`File type not allowed. Allowed extensions: ${Hie()}`});return}await t.saveFile(c,u,p,g);let y=(g.length/1024).toFixed(1),x={type:"text",content:`\u{1F4CE} Document uploaded: ${p} (${y} KB)`};m.coday.upload([x]),ce("UPLOAD",`File saved to thread workspace: ${p}`),s.status(200).json({success:!0,type:"file",filename:p,size:g.length,path:`thread://${p}`})}}catch(c){console.error("Error processing file upload:",c);let u=c instanceof Error?c.message:"Upload failed";s.status(400).json({error:u})}}),r.get("/api/projects/:projectName/threads/:threadId/files",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId);if(!c||!u){s.status(400).json({error:"Project name and thread ID are required"});return}let l=i(o);if(!l){s.status(401).json({error:"Authentication required"});return}let f=await e.getThread(c,u);if(!f){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}if(!rn(f,l)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}let p=await t.listFiles(c,u);s.status(200).json({files:p})}catch(c){console.error("Error listing files:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to list files: ${u}`})}}),r.get("/api/projects/:projectName/threads/:threadId/files/:filename",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId),l=je(o.params.filename);if(!c||!u||!l){s.status(400).json({error:"Project name, thread ID, and filename are required"});return}let f=i(o);if(!f){s.status(401).json({error:"Authentication required"});return}let p=await e.getThread(c,u);if(!p){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}if(!rn(p,f)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}let d=l,m=await t.getFilePath(c,u,d);if(!G9t(m)){s.status(404).json({error:`File '${d}' not found`});return}let h=encodeURIComponent(d);s.setHeader("Content-Disposition",`attachment; filename="${d.replace(/"/g,'\\"')}"; filename*=UTF-8''${h}`);try{let g=Z9t(m);s.send(g)}catch(g){s.status(500).json({error:`Failed to read file: ${g instanceof Error?g.message:"Unknown error"}`})}}catch(c){console.error("Error downloading file:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to download file: ${u}`})}}),r.delete("/api/projects/:projectName/threads/:threadId/files/:filename",async(o,s)=>{try{let c=je(o.params.projectName),u=je(o.params.threadId),l=je(o.params.filename);if(!c||!u||!l){s.status(400).json({error:"Project name, thread ID, and filename are required"});return}let f=i(o);if(!f){s.status(401).json({error:"Authentication required"});return}let p=await e.getThread(c,u);if(!p){s.status(404).json({error:`Thread '${u}' not found in project '${c}'`});return}if(!rn(p,f)){s.status(403).json({error:"Access denied: thread belongs to another user"});return}await t.deleteFile(c,u,l),s.status(200).json({success:!0,message:`File '${l}' deleted successfully`})}catch(c){console.error("Error deleting file:",c);let u=c instanceof Error?c.message:"Unknown error";s.status(500).json({error:`Failed to delete file: ${u}`})}}),r.get("/api/projects/:projectName/threads/:threadId/event-stream",async(o,s)=>{let c=je(o.params.projectName),u=je(o.params.threadId),l=i(o);if(!c||!u){s.status(400).send("Project name and thread ID are required");return}if(ce("THREAD_SSE",`New connection request for thread ${u} in project ${c}`),!l){ce("THREAD_SSE","Rejected: No username provided"),s.status(401).send("Authentication required");return}s.setHeader("Content-Type","text/event-stream"),s.setHeader("Cache-Control","no-cache"),s.setHeader("Connection","keep-alive");let f={...a,project:c,thread:u},p=n.getOrCreate(u,c,l,f,s);o.on("close",()=>{ce("THREAD_SSE",`Client disconnected from thread ${u}`),n.removeConnection(u,s)}),p.startCoday()?ce("THREAD_SSE",`New Coday instance started for thread ${u}`):ce("THREAD_SSE",`Reconnected to existing Coday instance for thread ${u}`)})}function O7e(r,e,t){r.get("/api/projects/:projectName/threads/:threadId/messages",async(n,i)=>{try{let{projectName:a,threadId:o}=n.params;if(!a||!o){i.status(400).json({error:"Project name and thread ID are required"});return}let s=t(n);if(!s){i.status(401).json({error:"Authentication required"});return}ce("MESSAGE",`GET messages for thread: ${o} in project: ${a}`);let c=e.get(o);if(!c?.coday){i.status(404).json({error:`Thread '${o}' not found or not active`});return}let u=c.coday.context?.aiThread;if(!u||!rn(u,s)){i.status(403).json({error:"Access denied: thread belongs to another user"});return}if(!u){i.status(500).json({error:"Thread not properly initialized"});return}let f=(await u.getMessages(void 0,void 0)).messages;i.status(200).json(f)}catch(a){console.error("Error listing messages:",a);let o=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to list messages: ${o}`})}}),r.post("/api/projects/:projectName/threads/:threadId/messages",async(n,i)=>{try{let{projectName:a,threadId:o}=n.params,s=n.body;if(!a||!o){i.status(400).send("Project name and thread ID are required");return}let c=t(n);if(!c){i.status(401).send("Authentication required");return}ce("MESSAGE",`threadId: ${o}, project: ${a}, received message of type: ${s.type||"answer"}`);let u=e.get(o);if(!u?.coday){i.status(404).send("Thread not found or not connected");return}let l=u.coday.context?.aiThread;if(!l||!rn(l,c)){i.status(403).send("Access denied: thread belongs to another user");return}if(s.type==="oauth_callback"){let f=sv(s);if(f&&u.coday.services.agent){ce("MESSAGE",`Routing OAuth callback for ${f.integrationName}`);let p=u.coday.services.agent.toolbox;if(p&&"handleOAuthCallback"in p){await p.handleOAuthCallback(f),i.status(200).send("OAuth callback handled successfully!");return}}else ce("MESSAGE","No agent service available for OAuth callback routing")}if(s.type==="answer"){u.coday.interactor.sendEvent(new _r({...s,name:c})),i.status(200).send("Message received successfully!");return}if(s.message){ce("MESSAGE",`Free-form message from ${c}: ${s.message.substring(0,50)}`),u.coday.addUserMessage(c,s.message),i.status(200).json({queued:!0});return}i.status(400).send("Invalid message payload: must include either type or message field")}catch(a){console.error("Error processing event:",a),i.status(400).send("Invalid event data!")}}),r.get("/api/projects/:projectName/threads/:threadId/messages/:eventId",async(n,i)=>{try{let{projectName:a,threadId:o,eventId:s}=n.params;if(!a||!o||!s){i.status(400).json({error:"Project name, thread ID, and event ID are required"});return}let c=decodeURIComponent(s),u=t(n);if(!u){i.status(401).json({error:"Authentication required"});return}ce("MESSAGE",`GET message: ${c} from thread: ${o} in project: ${a}`);let l=e.get(o);if(!l?.coday){i.status(404).json({error:`Thread '${o}' not found or not active`});return}let f=l.coday.context?.aiThread;if(!f||!rn(f,u)){i.status(403).json({error:"Access denied: thread belongs to another user"});return}let p=f.getEventById(c);if(!p){i.status(404).json({error:`Message '${c}' not found in thread '${o}'`});return}i.status(200).json(p)}catch(a){console.error("Error retrieving message:",a);let o=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to retrieve message: ${o}`})}}),r.get("/api/projects/:projectName/threads/:threadId/messages/:eventId/formatted",async(n,i)=>{try{let{projectName:a,threadId:o,eventId:s}=n.params;if(!a||!o||!s){i.status(400).send("Project name, thread ID, and event ID are required");return}let c=decodeURIComponent(s),u=t(n);if(!u){i.status(401).send("Authentication required");return}ce("MESSAGE",`GET formatted message: ${c} from thread: ${o} in project: ${a}`);let l=e.get(o);if(!l?.coday){i.status(404).send("Thread not found or not active");return}let f=l.coday.context?.aiThread;if(!f||!rn(f,u)){i.status(403).send("Access denied: thread belongs to another user");return}let p=f.getEventById(c);if(!p){i.status(404).send(`Message '${c}' not found in thread '${o}'`);return}i.setHeader("Content-Type","text/plain");let d="";if(p.type==="tool_request")d=`Tool Request: ${p.name}
1423
1423
 
1424
1424
  Arguments:
1425
1425
  ${JSON.stringify(JSON.parse(p.args),null,2)}`;else if(p.type==="tool_response"){let m=p.output;if(typeof m=="object"&&m!==null)d=`Tool Response: