@whoz-oss/coday-server 0.224.2 → 0.225.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.
- package/package.json +1 -1
- package/server.js +7 -7
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -548,7 +548,7 @@ ${a}\r
|
|
|
548
548
|
}
|
|
549
549
|
|
|
550
550
|
More details: https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md#removed-logprovider-and-loglevel-options
|
|
551
|
-
`)),r}function E5e(t){let e=t.logProvider&&t.logProvider();return e&&(t.logger=e),(0,vjr.getLogger)(t)}});var h0t=x(C5e=>{"use strict";Object.defineProperty(C5e,"__esModule",{value:!0});C5e.legacyCreateProxyMiddleware=Sjr;var xjr=x5e(),wjr=dh(),_jr=d0t(),p0t=wjr.Debug.extend("legacy-create-proxy-middleware");function Sjr(t,e){p0t("init");let r=(0,_jr.legacyOptionsAdapter)(t,e),n=(0,xjr.createProxyMiddleware)(r);return p0t("add marker for patching req.url (old behavior)"),n.__LEGACY_HTTP_PROXY_MIDDLEWARE__=!0,n}});var m0t=x(UH=>{"use strict";Object.defineProperty(UH,"__esModule",{value:!0});UH.legacyCreateProxyMiddleware=void 0;var Ejr=h0t();Object.defineProperty(UH,"legacyCreateProxyMiddleware",{enumerable:!0,get:function(){return Ejr.legacyCreateProxyMiddleware}})});var g0t=x(v4=>{"use strict";var kjr=v4&&v4.__createBinding||(Object.create?(function(t,e,r,n){n===void 0&&(n=r);var i=Object.getOwnPropertyDescriptor(e,r);(!i||("get"in i?!e.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,n,i)}):(function(t,e,r,n){n===void 0&&(n=r),t[n]=e[r]})),Cjr=v4&&v4.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&kjr(e,t,r)};Object.defineProperty(v4,"__esModule",{value:!0});Cjr(m0t(),v4)});var T5e=x(kd=>{"use strict";var Tjr=kd&&kd.__createBinding||(Object.create?(function(t,e,r,n){n===void 0&&(n=r);var i=Object.getOwnPropertyDescriptor(e,r);(!i||("get"in i?!e.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,n,i)}):(function(t,e,r,n){n===void 0&&(n=r),t[n]=e[r]})),HH=kd&&kd.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&Tjr(e,t,r)};Object.defineProperty(kd,"__esModule",{value:!0});HH(x5e(),kd);HH(f0t(),kd);HH(G4e(),kd);HH(g0t(),kd)});var JH=Kr(obe(),1);import hh from"path";import WH from"fs";var ddt=Kr(yc(),1);import*as fdt from"path";var ut=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,r){return!!e&&e.toLowerCase().startsWith(this.commandWord)}};var o_e=Kr(yc(),1);function HJ(t,e=80){if(t.length<=e)return t;try{if(t.trim().startsWith("{")||t.trim().startsWith("[")){let r=JSON.parse(t),n=JSON.stringify(r);return n.length<=e?n:n.substring(0,e)+`...(${n.length} chars)`}}catch{}return t.substring(0,e)+"..."}var ba=class{constructor(e,r){this.type=r;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 r=this.timestamp.substring(e+1);if(r.length===5&&/^[a-z0-9]+$/.test(r))return new Date(this.timestamp.substring(0,e))}return new Date(this.timestamp)}},PI=class extends ba{invite;constructor(e,r){super(e,r),this.invite=e.invite}buildAnswer(e){return new mn({answer:e,parentKey:this.timestamp,invite:this.invite})}},V3=class t extends ba{static type="heartbeat";constructor(e){super(e,t.type)}},sa=class t extends PI{defaultValue;static type="invite";constructor(e){super(e,t.type),this.defaultValue=e.defaultValue}},K5="InviteEventDefault",mn=class t extends ba{answer;invite;name;silent;static type="answer";constructor(e){super(e,t.type),this.answer=e.answer??"No answer",this.invite=e.invite,this.name=e.name,this.silent=e.silent}},Ud=class t extends ba{speaker;text;static type="text";constructor(e){super(e,t.type),this.speaker=e.speaker,this.text=e.text}},Yh=class t extends ba{chunk;static type="text_chunk";constructor(e){super(e,t.type),this.chunk=e.chunk,this.length=this.chunk.length}},J5=class t extends ba{warning;static type="warn";constructor(e){super(e,t.type),this.warning=e.warning}},jo=class t extends ba{error;static type="error";constructor(e){super(e,t.type),this.error=e.error}},oa=class t extends PI{options;optionalQuestion;allowFreeText;static type="choice";constructor(e){super(e,t.type),this.options=Array.isArray(e.options)?e.options:[],this.optionalQuestion=e.optionalQuestion,this.allowFreeText=e.allowFreeText??!1}},vi=class t extends ba{toolRequestId;name;args;static type="tool_request";constructor(e){super(e,t.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 Fi({output:e,toolRequestId:this.toolRequestId,parentKey:this.timestamp})}toSingleLineString(e=50){let r=HJ(this.args,e);return`\u{1F527} ${this.name}(${r})`}},Fi=class t extends ba{toolRequestId;output;static type="tool_response";constructor(e){if(super(e,t.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 r=(this.output.width??0)*(this.output.height??0)/750;this.length=(r?r*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 r=this.getTextOutput(),n=HJ(r,e),i=typeof this.output!="string"&&this.output.type==="image"?" [image]":"";return`\u2B91 ${n}${i}`}},G3=class t extends ba{static type="thinking";static debounce=5e3;constructor(e){super(e,t.type)}},io=class t extends ba{summary;static type="summary";constructor(e){super(e,t.type),this.summary=e.summary,this.length=this.summary.length}toSingleLineString(e=80){return`\u{1F4CB} Summary: ${HJ(this.summary,e)}`}},mr=class t extends ba{role;name;content;static type="message";constructor(e){super(e,t.type),this.role=e.role,this.name=e.name,this.content=
|
|
551
|
+
`)),r}function E5e(t){let e=t.logProvider&&t.logProvider();return e&&(t.logger=e),(0,vjr.getLogger)(t)}});var h0t=x(C5e=>{"use strict";Object.defineProperty(C5e,"__esModule",{value:!0});C5e.legacyCreateProxyMiddleware=Sjr;var xjr=x5e(),wjr=dh(),_jr=d0t(),p0t=wjr.Debug.extend("legacy-create-proxy-middleware");function Sjr(t,e){p0t("init");let r=(0,_jr.legacyOptionsAdapter)(t,e),n=(0,xjr.createProxyMiddleware)(r);return p0t("add marker for patching req.url (old behavior)"),n.__LEGACY_HTTP_PROXY_MIDDLEWARE__=!0,n}});var m0t=x(UH=>{"use strict";Object.defineProperty(UH,"__esModule",{value:!0});UH.legacyCreateProxyMiddleware=void 0;var Ejr=h0t();Object.defineProperty(UH,"legacyCreateProxyMiddleware",{enumerable:!0,get:function(){return Ejr.legacyCreateProxyMiddleware}})});var g0t=x(v4=>{"use strict";var kjr=v4&&v4.__createBinding||(Object.create?(function(t,e,r,n){n===void 0&&(n=r);var i=Object.getOwnPropertyDescriptor(e,r);(!i||("get"in i?!e.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,n,i)}):(function(t,e,r,n){n===void 0&&(n=r),t[n]=e[r]})),Cjr=v4&&v4.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&kjr(e,t,r)};Object.defineProperty(v4,"__esModule",{value:!0});Cjr(m0t(),v4)});var T5e=x(kd=>{"use strict";var Tjr=kd&&kd.__createBinding||(Object.create?(function(t,e,r,n){n===void 0&&(n=r);var i=Object.getOwnPropertyDescriptor(e,r);(!i||("get"in i?!e.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,n,i)}):(function(t,e,r,n){n===void 0&&(n=r),t[n]=e[r]})),HH=kd&&kd.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&Tjr(e,t,r)};Object.defineProperty(kd,"__esModule",{value:!0});HH(x5e(),kd);HH(f0t(),kd);HH(G4e(),kd);HH(g0t(),kd)});var JH=Kr(obe(),1);import hh from"path";import WH from"fs";var ddt=Kr(yc(),1);import*as fdt from"path";var ut=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,r){return!!e&&e.toLowerCase().startsWith(this.commandWord)}};var o_e=Kr(yc(),1);function HJ(t,e=80){if(t.length<=e)return t;try{if(t.trim().startsWith("{")||t.trim().startsWith("[")){let r=JSON.parse(t),n=JSON.stringify(r);return n.length<=e?n:n.substring(0,e)+`...(${n.length} chars)`}}catch{}return t.substring(0,e)+"..."}var ba=class{constructor(e,r){this.type=r;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 r=this.timestamp.substring(e+1);if(r.length===5&&/^[a-z0-9]+$/.test(r))return new Date(this.timestamp.substring(0,e))}return new Date(this.timestamp)}},PI=class extends ba{invite;constructor(e,r){super(e,r),this.invite=e.invite}buildAnswer(e){return new mn({answer:e,parentKey:this.timestamp,invite:this.invite})}},V3=class t extends ba{static type="heartbeat";constructor(e){super(e,t.type)}},sa=class t extends PI{defaultValue;static type="invite";constructor(e){super(e,t.type),this.defaultValue=e.defaultValue}},K5="InviteEventDefault",mn=class t extends ba{answer;invite;name;silent;static type="answer";constructor(e){super(e,t.type),this.answer=e.answer??"No answer",this.invite=e.invite,this.name=e.name,this.silent=e.silent}},Ud=class t extends ba{speaker;text;static type="text";constructor(e){super(e,t.type),this.speaker=e.speaker,this.text=e.text}},Yh=class t extends ba{chunk;static type="text_chunk";constructor(e){super(e,t.type),this.chunk=e.chunk,this.length=this.chunk.length}},J5=class t extends ba{warning;static type="warn";constructor(e){super(e,t.type),this.warning=e.warning}},jo=class t extends ba{error;static type="error";constructor(e){super(e,t.type),this.error=e.error}},oa=class t extends PI{options;optionalQuestion;allowFreeText;static type="choice";constructor(e){super(e,t.type),this.options=Array.isArray(e.options)?e.options:[],this.optionalQuestion=e.optionalQuestion,this.allowFreeText=e.allowFreeText??!1}},vi=class t extends ba{toolRequestId;name;args;static type="tool_request";constructor(e){super(e,t.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 Fi({output:e,toolRequestId:this.toolRequestId,parentKey:this.timestamp})}toSingleLineString(e=50){let r=HJ(this.args,e);return`\u{1F527} ${this.name}(${r})`}},Fi=class t extends ba{toolRequestId;output;static type="tool_response";constructor(e){if(super(e,t.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 r=(this.output.width??0)*(this.output.height??0)/750;this.length=(r?r*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 r=this.getTextOutput(),n=HJ(r,e),i=typeof this.output!="string"&&this.output.type==="image"?" [image]":"";return`\u2B91 ${n}${i}`}},G3=class t extends ba{static type="thinking";static debounce=5e3;constructor(e){super(e,t.type)}},io=class t extends ba{summary;static type="summary";constructor(e){super(e,t.type),this.summary=e.summary,this.length=this.summary.length}toSingleLineString(e=80){return`\u{1F4CB} Summary: ${HJ(this.summary,e)}`}},mr=class t extends ba{role;name;content;static type="message";constructor(e){super(e,t.type),this.role=e.role,this.name=e.name;let r=e.content;Array.isArray(r)?this.content=r.map(n=>typeof n=="string"?{type:"text",content:n}:n):typeof r=="string"?this.content=[{type:"text",content:r}]:r&&typeof r=="object"&&"type"in r?this.content=[r]:this.content=[],this.length=this.content.map(n=>{if(n.type==="text")return n.content.length;if(n.type==="image"){let i=(n.width||0)*(n.height||0)/750;return i?i*3.5:n.content.length}return n.type==="audio"?n.transcription?.length??100:0}).reduce((n,i)=>n+i,0)}getTextContent(){return this.content.filter(e=>e.type==="text").map(e=>e.content).join(`
|
|
552
552
|
`)}},Fa=class t extends ba{threadId;name;summary;users;static type="thread_update";constructor(e){super(e,t.type),this.threadId=e.threadId,this.name=e.name,this.summary=e.summary,this.users=e.users}},hf=class t extends ba{filename;operation;size;mimeType;static type="file";constructor(e){super(e,t.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",r=this.size?` (${(this.size/1024).toFixed(1)} KB)`:"";return`${e} ${this.operation}: ${this.filename}${r}`}},mf=class t extends ba{authUrl;state;integrationName;static type="oauth_request";constructor(e){super(e,t.type),this.authUrl=e.authUrl,this.state=e.state,this.integrationName=e.integrationName}},bc=class t extends ba{subThreadId;agentName;static type="delegation";constructor(e){super(e,t.type),this.subThreadId=e.subThreadId,this.agentName=e.agentName}},II=class t extends ba{code;state;integrationName;error;errorDescription;static type="oauth_callback";constructor(e){super(e,t.type),this.code=e.code,this.state=e.state,this.integrationName=e.integrationName,this.error=e.error,this.errorDescription=e.errorDescription}},hRt={[mr.type]:mr,[mn.type]:mn,[oa.type]:oa,[bc.type]:bc,[jo.type]:jo,[V3.type]:V3,[sa.type]:sa,[vi.type]:vi,[Fi.type]:Fi,[Ud.type]:Ud,[Yh.type]:Yh,[G3.type]:G3,[J5.type]:J5,[Fa.type]:Fa,[io.type]:io,[hf.type]:hf,[mf.type]:mf,[II.type]:II};function DI(t){let e=hRt[t.type];return e?new e(t):void 0}var RI=class{constructor(e,r,n,i=!1){this.aiClient=r;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,r,n){if(!r)throw new Error(`[Agent:${this.name}] Cannot run: thread context is undefined. Ensure initThread() completed before agent execution.`);let i=e.trim(),a=new mn({answer:i,name:n??r.username});r.addAnswerEvent(a);let s=await this.aiClient.run(this,r),o=new o_e.ReplaySubject;return s.subscribe(o),o.asObservable()}};var $I={name:"Coday",description:"Default fallback agent with neutral character and access to all tools",instructions:`
|
|
553
553
|
You are Coday, an AI assistant designed for interactive usage by users through various chat-like interfaces.
|
|
554
554
|
|
|
@@ -821,7 +821,7 @@ Verify the memory system's overall health:
|
|
|
821
821
|
- List any remaining issues or concerns
|
|
822
822
|
- Provide recommendations for maintaining memory quality
|
|
823
823
|
|
|
824
|
-
This ensures the memory system stays efficient and valuable.`],createdBy:"system",createdAt:new Date("2024-01-01").toISOString(),webhookEnabled:!1,parameterFormat:""}];var Hd=class extends Error{constructor(r,n){super(r);this.cause=n;this.name="ThreadRepositoryError"}},bb={input:0,output:0,cache_read:0,cache_write:0,price:0,iterations:0,priceThreshold:10,iterationsThreshold:100};function Ln(t,e){return t.users.some(r=>r.userId===e)}function c_e(t,e,r=.7){if(!e||!t.length)return{messages:t,overflow:[]};let n=0,i=0,a=e*r;for(let c of t)i+=c.length,n+=i<a?1:0;if(i<e)return{messages:t,overflow:[]};let s=t.slice(0,n),o=t.slice(n);return{messages:s,overflow:o}}var mRt=[mr.type,vi.type,Fi.type,io.type,sa.type,oa.type,mn.type,bc.type],Wd=class t{id;projectId;name;summary;starring=[];username;users=[];createdDate;modifiedDate;runStatus="STOPPED";data={};usage={...bb};price=0;delegationDepth=0;parentThreadId;parentEventId;delegatedAgentName;delegatedTask;worktreeProject;closedByUser=!1;parentThread;messages;get messagesLength(){return this.messages.length}constructor(e){this.id=e.id,this.username=e.username??"",this.projectId=e.projectId??"",this.name=e.name??"",this.summary=e.summary??"",this.starring=e.starring
|
|
824
|
+
This ensures the memory system stays efficient and valuable.`],createdBy:"system",createdAt:new Date("2024-01-01").toISOString(),webhookEnabled:!1,parameterFormat:""}];var Hd=class extends Error{constructor(r,n){super(r);this.cause=n;this.name="ThreadRepositoryError"}},bb={input:0,output:0,cache_read:0,cache_write:0,price:0,iterations:0,priceThreshold:10,iterationsThreshold:100};function Ln(t,e){return t.users.some(r=>r.userId===e)}function c_e(t,e,r=.7){if(!e||!t.length)return{messages:t,overflow:[]};let n=0,i=0,a=e*r;for(let c of t)i+=c.length,n+=i<a?1:0;if(i<e)return{messages:t,overflow:[]};let s=t.slice(0,n),o=t.slice(n);return{messages:s,overflow:o}}var mRt=[mr.type,vi.type,Fi.type,io.type,sa.type,oa.type,mn.type,bc.type],Wd=class t{id;projectId;name;summary;starring=[];username;users=[];createdDate;modifiedDate;runStatus="STOPPED";data={};usage={...bb};price=0;delegationDepth=0;parentThreadId;parentEventId;delegatedAgentName;delegatedTask;worktreeProject;closedByUser=!1;parentThread;messages;get messagesLength(){return this.messages.length}constructor(e){this.id=e.id,this.username=e.username??"",this.projectId=e.projectId??"",this.name=e.name??"",this.summary=e.summary??"",this.starring=Array.isArray(e.starring)?e.starring:[],this.users=Array.isArray(e.users)&&e.users.length>0?e.users:e.username?[{userId:e.username}]:[],this.createdDate=e.createdDate??new Date().toISOString(),this.modifiedDate=e.modifiedDate??this.createdDate,this.price=e.price??0,this.parentThreadId=e.parentThreadId,this.parentEventId=e.parentEventId,this.delegatedAgentName=e.delegatedAgentName,this.delegatedTask=e.delegatedTask,this.worktreeProject=e.worktreeProject,this.closedByUser=e.closedByUser??!1;let r=e.messages??[];Array.isArray(r)?this.messages=r.filter(n=>mRt.includes(n.type)).map(n=>DI(n)).filter(n=>n!==void 0):this.messages=[]}async getMessages(e,r){if((!this.messages||!Array.isArray(this.messages))&&(this.messages=[]),!e){let f=this.getMessagesUpToFirstSummary();return{messages:this.cleanToolRequestResponseConsistency(f),compacted:!1}}let n=this.getMessagesUpToFirstSummary(),i=Math.floor(e*.5),a=n.map(f=>{if(f instanceof Fi&&f.length>i){let d=Math.floor(e*.15),p=f.getTextOutput(),h=`[... truncated ${f.length-d} chars]
|
|
825
825
|
`+p.slice(-d);return new Fi({...f,output:h})}return f}),{messages:s,overflow:o}=c_e(a.toReversed(),e);if(s=s.toReversed(),o=o.toReversed(),!r||o.length===0)return{messages:this.cleanToolRequestResponseConsistency(s),compacted:o.length>0};let c;try{c=await r(o);let f=o[o.length-1];if(f){let d=this.messages.indexOf(f);d!==-1&&this.messages.splice(d+1,0,c)}}catch(f){return console.error("[AiThread] Compaction failed, keeping recent messages only:",f),{messages:this.cleanToolRequestResponseConsistency(s),compacted:!0}}let u=this.cleanToolRequestResponseConsistency(s);return{messages:[c,...u],compacted:!0}}getAllMessages(){return this.cleanToolRequestResponseConsistency([...this.messages])}getMessagesUpToFirstSummary(){let e=[...this.messages].reverse(),r=[];for(let n of e){if(n instanceof io){r.push(n);break}r.push(n)}return r.reverse()}cleanToolRequestResponseConsistency(e){let r=[],n=new Set,i=new Set;for(let a of e)a instanceof vi&&a.toolRequestId?n.add(a.toolRequestId):a instanceof Fi&&a.toolRequestId&&i.add(a.toolRequestId);for(let a of e){let s=!0;a instanceof vi?a.toolRequestId&&!i.has(a.toolRequestId)&&(console.debug(`[AiThread] Removing orphaned tool request: ${a.name} (ID: ${a.toolRequestId})`),s=!1):a instanceof Fi&&(a.toolRequestId?n.has(a.toolRequestId)||(console.debug(`[AiThread] Removing orphaned tool response for missing request ID: ${a.toolRequestId}`),s=!1):(console.warn(`[AiThread] Removing tool response without tool reference (timestamp: ${a.timestamp})`),s=!1)),s&&r.push(a)}return r}markAsDone(){this.closedByUser=!0}resetUsageForRun(){this.usage={...bb}}addUsage(e){this.price+=e.price??0,this.usage.price+=e.price??0,this.usage.iterations+=1;let r=this.usage;r.input+=e.input??0,r.output+=e.output??0,r.cache_read+=e.cache_read??0,r.cache_write+=e.cache_write??0}add(e){this.messages.push(e)}findToolRequestById(e){return this.messages.find(r=>r instanceof vi&&r.toolRequestId===e)}findSimilarToolRequests(e){return this.messages.filter(r=>r!==e&&r instanceof vi&&r.name===e.name&&r.args===e.args)}findToolResponsesToRequests(e){return this.messages.filter(r=>r instanceof Fi&&e.some(n=>n.toolRequestId===r.toolRequestId))}removeMessages(e){this.messages=this.messages.filter(r=>!e.includes(r))}addUserMessage(e,r){let n=this.messages[this.messages.length-1];n&&n instanceof mr&&n.role==="user"&&n.name===e?n.content.push(r):this.add(new mr({role:"user",content:[r],name:e})),this.modifiedDate=new Date().toISOString()}addAnswerEvent(e){this.add(e),this.modifiedDate=new Date().toISOString()}addInviteEvent(e){this.add(e),this.modifiedDate=new Date().toISOString()}addDelegationEvent(e){this.messages.some(n=>n instanceof bc&&n.subThreadId===e.subThreadId)||this.add(e)}addAgentMessage(e,r){let n=this.messages[this.messages.length-1];n&&n instanceof mr&&n.role==="assistant"&&n.name===e?n.content.push(r):this.add(new mr({role:"assistant",content:[r],name:e})),this.modifiedDate=new Date().toISOString()}fork(e,r,n){let i=new t({id:crypto.randomUUID(),username:this.username,projectId:this.projectId,name:e,summary:"",createdDate:new Date().toISOString(),modifiedDate:new Date().toISOString(),price:0,messages:[],users:this.users.map(a=>({...a})),parentThreadId:this.id,parentEventId:n,delegatedAgentName:e,delegatedTask:r});return i.delegationDepth=this.delegationDepth+1,i.parentThread=this,i.runStatus="RUNNING",i}merge(e){this.price+=e.price,e.price=0}get totalPrice(){return this.price+(this.parentThread?.totalPrice??0)}getLastAgentName(){for(let e=this.messages.length-1;e>=0;e--){let r=this.messages[e];if(r instanceof mr&&r.role==="assistant"&&r.name)return r.name}}getUserMessageCount(){return this.messages.filter(e=>e instanceof mr&&e.role==="user"||e instanceof mn).length}getEventById(e){return this.messages.find(r=>r.timestamp===e)}truncateAtUserMessage(e){let r=this.messages.findIndex(i=>i.timestamp===e);if(r===-1)return!1;let n=this.messages[r];return!(n instanceof mr)||n.role!=="user"||r===0?!1:(this.messages=this.messages.slice(0,r),this.modifiedDate=new Date().toISOString(),!0)}addToolRequests(e,r){r.forEach(n=>{!n.toolRequestId||!n.name||!n.args||this.add(n)})}addToolResponseEvents(e){e.forEach(r=>{if(!r.toolRequestId||!r.output)return;let n=this.findToolRequestById(r.toolRequestId);if(!n)return;let i=this.findSimilarToolRequests(n),a=this.findToolResponsesToRequests(i);this.removeMessages([...i,...a]),this.add(r)})}addToolCalls(e,r){r.forEach(n=>{!n.id||!n.name||!n.args||this.add(new vi({name:n.name,args:n.args,toolRequestId:n.id}))})}addToolResponses(e,r){r.forEach(n=>{if(!n.id||!n.response)return;let i=this.findToolRequestById(n.id);if(!i)return;let a=this.findSimilarToolRequests(i),s=this.findToolResponsesToRequests(a);this.removeMessages([...a,...s]),this.add(new Fi({toolRequestId:n.id,output:n.response}))})}serialize(){return{id:this.id,username:this.username,projectId:this.projectId,name:this.name,summary:this.summary,createdDate:this.createdDate,modifiedDate:this.modifiedDate,price:this.price,starring:this.starring,users:this.users,parentThreadId:this.parentThreadId,parentEventId:this.parentEventId,delegatedAgentName:this.delegatedAgentName,delegatedTask:this.delegatedTask,worktreeProject:this.worktreeProject,closedByUser:this.closedByUser||void 0,messages:this.messages}}};var u_e=Kr(yc(),1);var Y5=class{constructor(e,r){this.aiProviderConfig=e;this.logger=r;this.apiKey=e.apiKey}models=[];apiKey;killed=!1;thinkingInterval=1e3;charsPerToken=3;username;activeThinkingIntervals=new Set;activeDelays=new Set;isShuttingDown=!1;mergeModels(e){let r=new Map(e.map(n=>[n.alias??n.name,n]));this.aiProviderConfig.models?.forEach(n=>{let i=n.alias??n.name,a=r.get(i);a?r.set(i,{...a,...n,price:n.price??a.price}):r.set(i,n)}),this.models=Array.from(r.values())}kill(){this.killed=!0,this.cleanup()}cleanup(){this.isShuttingDown=!0;for(let e of this.activeDelays)clearTimeout(e);this.activeDelays.clear();for(let e of this.activeThinkingIntervals)clearInterval(e);this.activeThinkingIntervals.clear()}async delay(e,r){if(this.isShuttingDown)throw new Error("Client is shutting down");return new Promise((n,i)=>{let a=setTimeout(()=>{this.activeDelays.delete(a),n()},e);this.activeDelays.add(a),this.isShuttingDown&&(clearTimeout(a),this.activeDelays.delete(a),i(new Error(`Delay interrupted by shutdown${r?`: ${r}`:""}`)))})}startThinkingInterval(){let e=setInterval(()=>this.interactor.thinking(),this.thinkingInterval);return this.activeThinkingIntervals.add(e),e}stopThinkingInterval(e){clearInterval(e),this.activeThinkingIntervals.delete(e)}getCompactor(e,r){return async n=>{if(this.interactor.debug(`\u{1F5DC}\uFE0F Starting compaction for ${n.length} messages (budget: ${r} chars)`),r<500)return this.interactor.warn(`\u26A0\uFE0F Budget too small for compaction (${r} chars). Using truncation marker.`),new io({summary:"[Previous conversation truncated due to context window constraints]"});let i=n.filter(h=>h instanceof mr).map(h=>` - ${h.role}: ${h.getTextContent()}`).join(`
|
|
826
826
|
`);this.interactor.debug(`\u{1F4DD} Built transcript from ${n.filter(h=>h instanceof mr).length} messages (${i.length} chars)`);let a=Math.max(100,Math.floor(r/20)),s=150,o=.2,c=Math.max(0,Math.floor((r-s-a)*(1-o)));this.interactor.debug(`\u{1F4CA} Compaction budget: summary=${a} chars, max transcript=${c} chars (overhead=${s}, margin=${Math.round(o*100)}%)`);let u=i,f=!1;i.length>c&&(u="..."+i.slice(-(c-3)),f=!0,this.interactor.debug(`\u2702\uFE0F Transcript truncated: ${i.length} \u2192 ${u.length} chars (removed ${i.length-u.length} chars from beginning)`));let d=`Here is a transcript of a conversation:
|
|
827
827
|
<transcript>${u}</transcript>
|
|
@@ -911,7 +911,7 @@ ${s}`),i}catch(o){return console.error(`Could not format docs: ${o.message}`),""
|
|
|
911
911
|
`)+`
|
|
912
912
|
`;await SX.appendFile(r,n,"utf8")}catch(e){console.warn("Logger: Failed to flush log entries:",e)}}async ensureLogDir(e){let r=j6.dirname(e);try{await SX.mkdir(r,{recursive:!0})}catch(n){if(n.code!=="EEXIST")throw n}}async shutdown(){this.flushInterval&&(clearInterval(this.flushInterval),this.flushInterval=null),await this.flush()}};function N6(t,e){let r=t.version?t:{...t,version:1},n=[...e].filter(i=>i.version>=r.version).sort((i,a)=>i.version-a.version);for(let i of n){let a=i.migrate({...r});a.version=i.version+1,r=a}return r}function TFt(t){let e=Ike(t);if(!e)return!1;let{value:r,unit:n}=e;switch(n){case"min":return r>=1&&r<=59;case"h":return r>=1&&r<=24;case"d":return r>=1&&r<=31;case"M":return r>=1&&r<=12;default:return!1}}function Ike(t){let e=t.match(/^(\d+)(min|h|d|M)$/);if(!e||!e[1]||!e[2])return null;let r=parseInt(e[1],10),n=e[2];return isNaN(r)||r<1?null:{value:r,unit:n}}function AFt(t){return t?!Array.isArray(t)||t.length===0?!1:t.every(e=>Number.isInteger(e)&&e>=0&&e<=6):!0}function Dke(t){try{let e=new Date(t.startTimestamp);if(isNaN(e.getTime()))return{valid:!1,error:"Invalid startTimestamp format"}}catch{return{valid:!1,error:"Invalid startTimestamp format"}}if(!TFt(t.interval))return{valid:!1,error:"Invalid interval. Use 1min-59min, 1h-24h, 1d-31d, or 1M-12M"};if(!AFt(t.daysOfWeek))return{valid:!1,error:"Invalid daysOfWeek. Must be array of integers 0-6"};if(t.endCondition){let{type:e,value:r}=t.endCondition;if(e==="occurrences"){if(typeof r!="number"||r<1||!Number.isInteger(r))return{valid:!1,error:"Occurrences must be a positive integer"}}else if(e==="endTimestamp")try{let n=new Date(r);if(isNaN(n.getTime()))return{valid:!1,error:"Invalid endTimestamp format"};let i=new Date(t.startTimestamp);if(n<=i)return{valid:!1,error:"endTimestamp must be after startTimestamp"}}catch{return{valid:!1,error:"Invalid endTimestamp format"}}else return{valid:!1,error:'endCondition type must be "occurrences" or "endTimestamp"'}}return{valid:!0}}function gx(t,e=new Date,r=0){let n=Ike(t.interval);if(!n)throw new Error(`Invalid interval: ${t.interval}`);let i=new Date(t.startTimestamp),a;if(e<i?a=new Date(i):a=OFt(i,n,e),t.endCondition){if(t.endCondition.type==="occurrences"){let s=t.endCondition.value;if(r>=s)return null}else if(t.endCondition.type==="endTimestamp"){let s=new Date(t.endCondition.value);if(a>s)return null}}if(t.daysOfWeek&&t.daysOfWeek.length>0){let o=0;for(;o<365;){let c=a.getUTCDay();if(t.daysOfWeek.includes(c)){if(t.endCondition?.type==="endTimestamp"){let u=new Date(t.endCondition.value);if(a>u)return null}return a.toISOString()}if(a=Rke(a,n),o++,t.endCondition?.type==="endTimestamp"){let u=new Date(t.endCondition.value);if(a>u)return null}}throw new Error("Could not find next valid day within reasonable timeframe")}return a.toISOString()}function OFt(t,e,r){if(e.unit==="M"){let o=new Date(t);for(;o<=r;)o=Rke(o,e);return o}let n=PFt(e),i=r.getTime()-t.getTime(),a=Math.floor(i/n)+1;return new Date(t.getTime()+a*n)}function PFt(t){switch(t.unit){case"min":return t.value*60*1e3;case"h":return t.value*60*60*1e3;case"d":return t.value*24*60*60*1e3;default:throw new Error(`intervalToMs does not support unit: ${t.unit}`)}}function Rke(t,e){let r=new Date(t);switch(e.unit){case"min":r.setUTCMinutes(r.getUTCMinutes()+e.value);break;case"h":r.setUTCHours(r.getUTCHours()+e.value);break;case"d":r.setUTCDate(r.getUTCDate()+e.value);break;case"M":let n=r.getUTCDate();r.setUTCMonth(r.getUTCMonth()+e.value),r.getUTCDate()!==n&&r.setUTCDate(0);break}return r}function $ke(t,e,r=0){if(!e)return!1;let n=new Date;if(new Date(e)>n)return!1;if(t.endCondition?.type==="occurrences"){let a=t.endCondition.value;if(r>=a)return!1}if(t.endCondition?.type==="endTimestamp"){let a=new Date(t.endCondition.value);if(n>a)return!1}return!0}var vx=(t,e)=>{let{lineLimit:r,charLimit:n}=e,i=DFt(t,n);return IFt(i,r)},IFt=(t,e)=>{let r=t.split(`
|
|
913
913
|
`);return r.length>e?r.slice(-e).join(`
|
|
914
|
-
`):t},DFt=(t,e)=>t.length>e?t.slice(-e):t;var jke=[nR];var SAe=Kr(Tf(),1);import{existsSync as szt,readFileSync as ozt}from"fs";function $s(t){try{if(!szt(t))return;let e=ozt(t,"utf-8");return SAe.parse(e)}catch(e){console.error(`Failed to file at ${t} :`,e);return}}var EAe=[nR];function Jx(t){return t.replace(/[^a-zA-Z0-9]/g,"_")}var kAe=Kr(Tf(),1);import{writeFileSync as czt}from"node:fs";function Xi(t,e){try{let r=kAe.stringify(e,{lineWidth:0});czt(t,r)}catch(r){console.error(`Failed to write file ${t}:`,r)}}var pzt=dzt(fzt),hzt=10*1024*1024,Tc=async({command:t,relPath:e,root:r,requireConfirmation:n,interactor:i,lineLimit:a=1e3,maxBuffer:s=hzt})=>{let o=r,c={lineLimit:a,charLimit:5e4};if(e&&(o=t$.resolve(r,e)),!o.startsWith(t$.resolve(r)))return"Attempt to navigate outside the root folder";try{let u=e?t$.resolve(r,e):r;if(i.debug(`
|
|
914
|
+
`):t},DFt=(t,e)=>t.length>e?t.slice(-e):t;var jke=[nR];var SAe=Kr(Tf(),1);import{existsSync as szt,readFileSync as ozt}from"fs";function $s(t){try{if(!szt(t))return;let e=ozt(t,"utf-8");return SAe.parse(e)}catch(e){console.error(`Failed to file at ${t} :`,e);return}}var EAe=[nR];function Jx(t){return t.replace(/[^a-zA-Z0-9]/g,"_")}var kAe=Kr(Tf(),1);import{writeFileSync as czt}from"node:fs";function Xi(t,e){try{let r=kAe.stringify(e,{lineWidth:0,blockQuote:!1});czt(t,r)}catch(r){console.error(`Failed to write file ${t}:`,r)}}var pzt=dzt(fzt),hzt=10*1024*1024,Tc=async({command:t,relPath:e,root:r,requireConfirmation:n,interactor:i,lineLimit:a=1e3,maxBuffer:s=hzt})=>{let o=r,c={lineLimit:a,charLimit:5e4};if(e&&(o=t$.resolve(r,e)),!o.startsWith(t$.resolve(r)))return"Attempt to navigate outside the root folder";try{let u=e?t$.resolve(r,e):r;if(i.debug(`
|
|
915
915
|
Running command: ${t} in ${u}`),n){let m=await i.chooseOption(["OK","Cancel"],`Confirm execution of: \`${t}\``,void 0,!0);if(m!=="OK")return`Command execution was cancelled by user${m&&m!=="Cancel"?` with reason: ${m}`:""}`}let{stdout:f,stderr:d}=await pzt(t,{cwd:u,maxBuffer:s}),p=vx(f,c),h=vx(d,c);return`Output:
|
|
916
916
|
${p}${h?`
|
|
917
917
|
|
|
@@ -1097,7 +1097,7 @@ Are you sure you want to delete this MCP server configuration?
|
|
|
1097
1097
|
|
|
1098
1098
|
Here are the information collected during previous chats:
|
|
1099
1099
|
`),n.join(`
|
|
1100
|
-
`)):""}loadMemoriesFrom(e){this.memories=[],this.userMemoriesPath=this.readMemories(this.userMemoriesPath)?this.userMemoriesPath:void 0;let r=e?.configPath?pj.join(e.configPath,cte):void 0;this.projectMemoriesPath=this.readMemories(r)?r:void 0,e&&this.checkInit()}readMemories(e){if(!e)return!1;try{if(!KUt(e)){let n=nPe.stringify({memories:[]});XUt(e,n)}let r=$s(e);return r?(this.memories.push(...r.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"),r=this.memories.filter(n=>n.level==="PROJECT");Xi(this.userMemoriesPath,{memories:e}),Xi(this.projectMemoriesPath,{memories:r})}};import*as sPe from"crypto";import*as lo from"node:fs/promises";import*as oPe from"node:fs";import*as Dc from"path";import{exec as aPe}from"child_process";var Bv=class t{constructor(e,r,n){this.repository=e;this.defaultProject=r;this.isForcedMode=n}maskingService=new L2;listProjects(){let e=this.repository.listProjects();return this.isForcedMode&&this.defaultProject?e.filter(r=>r===this.defaultProject).map(r=>{let n=this.repository.getConfig(r);return{name:r,volatile:n?.volatile}}):e.map(r=>{let n=this.repository.getConfig(r);return{name:r,volatile:n?.volatile,projectPath:n?.path}}).filter(({projectPath:r})=>{if(!r)return!0;try{return oPe.existsSync(r)}catch{return!0}}).map(({name:r,volatile:n})=>({name:r,volatile:n}))}getDefaultProject(){return this.defaultProject||null}getForcedMode(){return this.isForcedMode}getProject(e){this.checkAgainstForced(e);let r=this.repository.getConfig(e);if(r)return{name:e,config:r};if(!this.isForcedMode&&this.defaultProject){let n=process.cwd(),i=t.generateProjectId(n),a=Dc.basename(n);if(e===a||e===i||e===this.defaultProject){console.log(`[PROJECT_SERVICE] Creating volatile project for '${e}' at ${n}`);let s=this.getOrCreateVolatileProject(n);if(r=this.repository.getConfig(s),r)return{name:s,config:r}}}return null}exists(e){return this.checkAgainstForced(e),this.repository.exists(e)}createProject(e,r){if(this.checkAgainstForced(e),!e||!r)throw new Error("Project name and path are required");if(!this.repository.createProject(e,r))throw new Error(`Project '${e}' already exists`)}updateProjectConfig(e,r){if(this.checkAgainstForced(e),!this.repository.exists(e))throw new Error(`Project '${e}' does not exist`);this.repository.saveConfig(e,r)}async deleteProject(e,r){if(this.checkAgainstForced(e),e.includes("__"))r?.removeGitWorktree&&await this.removeGitWorktree(e),await this.unregisterWorktreeProject(e);else if(!this.repository.deleteProject(e))throw new Error(`Project '${e}' does not exist`)}async removeGitWorktree(e){let r=e.lastIndexOf("__");if(r===-1)return;let n=e.substring(0,r),i=this.repository.getConfig(n);if(!i?.path){console.warn(`[PROJECT_SERVICE] Cannot remove git worktree: parent project '${n}' config not found`);return}let a=i.path,s=Dc.dirname(a),o=Dc.join(s,e);try{await lo.access(o)}catch{console.warn(`[PROJECT_SERVICE] Worktree path does not exist, skipping git removal: ${o}`);return}aPe(`git worktree remove "${o}" --force`,{cwd:a},c=>{if(c){console.error(`[PROJECT_SERVICE] Failed to remove git worktree: ${c.message}`);return}console.log(`[PROJECT_SERVICE] Removed git worktree: ${o}`),aPe("git worktree prune",{cwd:a},u=>{u&&console.warn(`[PROJECT_SERVICE] git worktree prune failed: ${u.message}`)})})}getProjectConfigForClient(e){this.checkAgainstForced(e);let r=this.repository.getConfig(e);return r?this.maskingService.maskConfig(r):null}updateProjectConfigFromClient(e,r){this.checkAgainstForced(e);let n=this.repository.getConfig(e);if(!n)throw new Error(`Project '${e}' does not exist`);let i=this.maskingService.unmaskConfig(r,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 r=t.generateProjectId(e);if(this.repository.exists(r))return r;this.repository.createProject(r,e);let n=this.repository.getConfig(r);return n&&(n.volatile=!0,n.createdAt=Date.now(),this.repository.saveConfig(r,n)),r}async registerWorktreeProject(e,r,n){let i=this.repository.getConfig(n),a=i?{...i,path:r,volatile:void 0,createdAt:void 0}:{version:1,path:r,integration:{},storage:{type:"file"},agents:[]};this.repository.createProject(e,r),this.repository.saveConfig(e,a);let s=this.repository.getProjectInfo(n);if(s){let o=this.repository.getProjectInfo(e);if(o)for(let c of["agents","prompts","schedulers","memories"]){let u=Dc.join(s.configPath,c),f=Dc.join(o.configPath,c);try{await lo.access(u),await lo.symlink(u,f)}catch{}}}}async unregisterWorktreeProject(e){let r=this.repository.getProjectInfo(e);if(!r)return;let n=e.lastIndexOf("__");if(n!==-1){let i=e.substring(0,n),a=this.repository.getProjectInfo(i);a&&await this.migrateThreadsToParent(r.configPath,a.configPath)}await lo.rm(r.configPath,{recursive:!0,force:!0}),this.repository.deleteProject(e)}async migrateThreadsToParent(e,r){let n=Dc.join(e,"threads"),i=Dc.join(r,"threads");try{await lo.access(n)}catch{return}await lo.mkdir(i,{recursive:!0});let a=await lo.readdir(n);for(let s of a){let o=Dc.join(n,s),c=Dc.join(i,s);try{await lo.access(c)}catch{await lo.rename(o,c)}}}static generateProjectId(e){let r=Dc.basename(e),n=sPe.createHash("sha256").update(e).digest("hex").substring(0,8);return`${r}_${n}`}};var lPe=Kr(yc(),1);import*as zv from"node:path";import*as uPe from"node:os";import{mkdirSync as YUt}from"fs";var QUt="projects",cPe="project.yaml",Uv=class{constructor(e,r,n){this.interactor=e;this.projectService=r;let i=zv.join(uPe.userInfo().homedir,".coday");this.projectsConfigPath=zv.join(n??i,QUt),YUt(this.projectsConfigPath,{recursive:!0}),this.projects=this.projectService.listProjects().map(a=>a.name)}projectsConfigPath;maskingService=new L2;projects;selectedProjectBehaviorSubject=new lPe.BehaviorSubject(null);selectedProject$=this.selectedProjectBehaviorSubject.asObservable();selectProject(e){let r=zv.join(this.projectsConfigPath,e),n=zv.join(r,cPe),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 s={name:e,config:i,configPath:r};console.log(`[PROJECT_STATE_SERVICE] Selected '${e}' \u2192 ${i.path}`),this.updateSelectedProject(s),this.interactor.displayText(`Project local configuration used: ${n}`)}updateSelectedProject(e){this.selectedProjectBehaviorSubject.next(e)}get selectedProject(){return this.selectedProjectBehaviorSubject.value}save(e){let r=this.selectedProjectBehaviorSubject.value;if(!r){this.interactor.error("No current project selected, save not possible");return}let n={...r.config,...e};Xi(zv.join(r.configPath,cPe),n),r.config=n,this.updateSelectedProject(r)}getConfigForClient(){let e=this.selectedProjectBehaviorSubject.value;return e?this.maskingService.maskConfig(e.config):null}updateConfigFromClient(e){let r=this.selectedProjectBehaviorSubject.value;if(!r){this.interactor.error("No current project selected, update not possible");return}let n=this.maskingService.unmaskConfig(e,r.config);this.save(n)}};import*as gp from"node:path";import*as pPe from"node:os";import{randomUUID as tHt}from"node:crypto";import{existsSync as B2,mkdirSync as rHt,readdirSync as dPe,unlinkSync as nHt}from"fs";import*as ute from"node:path";import*as fPe from"node:os";function eHt(t){return t.replace(/[^a-zA-Z0-9]/g,"_")}function Hv(t,e){try{let r=ute.join(fPe.userInfo().homedir,".coday"),n=eHt(t),i=ute.join(e??r,"users",n,"user.yaml"),a=$s(i);return a?a.groups?.includes("CODAY_ADMIN")??!1:!1}catch{return!1}}var hj=class{codayConfigDir;projectService;nativeHandlerStubs=[];constructor(e,r){let n=gp.join(pPe.userInfo().homedir,".coday");this.codayConfigDir=e??n,this.projectService=r}getProjectPath(e){if(this.projectService)return this.projectService.getProject(e)?.config.path}async getOrCreatePromptsDir(e,r){let n;if(r==="local")n=gp.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 u2({text:"coday.yaml",root:i});if(a.length===0)throw new Error(`coday.yaml not found in project path: ${i}`);let s=gp.dirname(a[0]);n=gp.join(i,s,"prompts")}return B2(n)||(rHt(n,{recursive:!0}),console.log(`[PROMPT] Created prompts directory: ${n}`)),n}async getOrCreatePromptFilePath(e,r,n){let i=await this.getOrCreatePromptsDir(e,n);return gp.join(i,`${r}.yml`)}async findPromptSource(e,r){let n=await this.getOrCreatePromptFilePath(e,r,"local");if(B2(n))return"local";if(this.projectService)try{let i=await this.getOrCreatePromptFilePath(e,r,"project");if(B2(i))return"project"}catch{}return null}async findProjectForPrompt(e){let r=gp.join(this.codayConfigDir,"projects");if(!B2(r))return null;let n=dPe(r,{withFileTypes:!0}).filter(i=>i.isDirectory()).map(i=>i.name);for(let i of n){let a=gp.join(this.codayConfigDir,"projects",i,"prompts",`${e}.yml`);if(B2(a))return i;if(this.projectService)try{let s=await this.getOrCreatePromptFilePath(i,e,"project");if(B2(s))return i}catch{}}return null}validatePlaceholders(e){let r=/\{\{(\w+)\}\}/g,n=[],i=/^[A-Za-z][A-Za-z0-9-]*$/;if(e.forEach(a=>{let s;for(;(s=r.exec(a))!==null;){let o=s[1];o&&o!=="PARAMETERS"&&!i.test(o)&&n.push(o)}}),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,r,n="local"){try{this.validatePlaceholders(r.commands);let i=tHt(),a={...r,id:i,source:n,createdAt:new Date().toISOString(),parameterFormat:this.getParameterFormat(r.commands)},s=await this.getOrCreatePromptFilePath(e,i,n);if(B2(s))throw new Error(`Prompt with ID ${i} already exists`);return Xi(s,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,r){try{let n=await this.findPromptSource(e,r);if(!n)return null;let i=await this.getOrCreatePromptFilePath(e,r,n),a=$s(i);return a?(a.source||(a.source=n),a):null}catch(n){return console.error(`Failed to get prompt ${r}:`,n),null}}async getById(e){try{let r=await this.findProjectForPrompt(e);if(!r)return null;let n=await this.get(r,e);return n?{prompt:n,projectName:r}:null}catch(r){return console.error(`Failed to get prompt ${e}:`,r),null}}async update(e,r,n,i){try{let a=await this.get(e,r);if(!a)return null;if(n.webhookEnabled!==void 0&&n.webhookEnabled!==a.webhookEnabled&&!Hv(i,this.codayConfigDir))throw new Error("Only CODAY_ADMIN can enable/disable webhook for prompts");let{id:s,createdAt:o,source:c,...u}=n;n.commands&&this.validatePlaceholders(n.commands);let f={...a,...u,updatedAt:new Date().toISOString()};n.commands&&(f.parameterFormat=this.getParameterFormat(n.commands));let d=await this.getOrCreatePromptFilePath(e,r,a.source);return Xi(d,f),console.log(`[PROMPT] Updated prompt ${r} (${a.source}) by user ${i}`),f}catch(a){throw console.error(`Failed to update prompt ${r}:`,a),a}}async delete(e,r){try{let n=await this.findPromptSource(e,r);if(!n)return!1;let i=await this.getOrCreatePromptFilePath(e,r,n);return nHt(i),console.log(`[PROMPT] Deleted prompt ${r} from ${n}`),!0}catch(n){return console.error(`Failed to delete prompt ${r}:`,n),!1}}getParameterFormat(e){if(e.some(a=>/\{\{PARAMETERS\}\}/.test(a)))return"";let n=/\{\{(\w+)\}\}/g,i=new Set;return e.forEach(a=>{let s;for(;(s=n.exec(a))!==null;){let o=s[1];o&&o!=="PARAMETERS"&&i.add(o)}}),i.size===0?"":Array.from(i).map(a=>`${a}=""`).join(" ")}registerNativeHandler(e){this.nativeHandlerStubs.find(r=>r.id===e.id)||this.nativeHandlerStubs.push(e)}async list(e,r=[]){try{let n=[],i=["local"];this.projectService&&i.push("project");for(let a of i)try{let s=await this.getOrCreatePromptsDir(e,a);if(!B2(s))continue;let c=dPe(s).filter(u=>u.endsWith(".yml"));for(let u of c){let f=u.replace(".yml",""),d=await this.get(e,f);d&&n.push({id:d.id,name:d.name,description:d.description,webhookEnabled:d.webhookEnabled,createdBy:d.createdBy,createdAt:d.createdAt,updatedAt:d.updatedAt,source:d.source||a,parameterFormat:d.parameterFormat})}}catch(s){console.log(`[PROMPT] Could not access ${a} prompts for ${e}:`,s)}return n.push(...X5),n.push(...this.nativeHandlerStubs),n.push(...r),n.sort((a,s)=>new Date(s.createdAt).getTime()-new Date(a.createdAt).getTime())}catch(n){return console.error(`Failed to list prompts for project ${e}:`,n),[]}}async enableWebhook(e,r,n){return this.update(e,r,{webhookEnabled:!0},n)}async disableWebhook(e,r,n){return this.update(e,r,{webhookEnabled:!1},n)}};var mj=class{constructor(e){this.promptService=e}threadCodayManager;threadService;codayOptions;logger;initialize(e,r,n,i){this.threadCodayManager=e,this.threadService=r,this.codayOptions=n,this.logger=i}processCommands(e,r){let n;if(typeof r=="string"){let a=e.some(o=>/\{\{PARAMETERS\}\}/.test(o));if(e.some(o=>/\{\{(?!PARAMETERS\}\})\w+\}\}/.test(o)))throw new Error("Prompt contains structured placeholders ({{key}}). Use an object parameter instead of a string.");a?n=e.map(o=>o.replace(/\{\{PARAMETERS\}\}/g,r)):n=e.map((o,c)=>c===0?`${o} ${r}`.trim():o)}else typeof r=="object"&&r!==null?n=e.map(a=>{let s=a;return Object.entries(r).forEach(([o,c])=>{let u=`{{${o}}}`;s=s.replaceAll(u,String(c))}),s}):n=[...e];let i=new Set;if(n.forEach(a=>{let s=a.match(/\{\{(\w+)\}\}/g);s&&s.forEach(o=>i.add(o))}),i.size>0){let a=Array.from(i).map(s=>s.replace(/[{}]/g,"")).join(", ");throw new Error(`Missing required parameters: ${a}`)}return n}async executeInstruction(e,r,n,i,a){if(!this.threadCodayManager||!this.threadService||!this.codayOptions||!this.logger)throw new Error("PromptExecutionService not initialized. Call initialize() first.");let{title:s,awaitFinalAnswer:o=!1,projectName:c}=a||{};if(!c)throw new Error("projectName is required for executeInstruction");if(!n)throw new Error("Username is required");let u=`@${e} ${r}`.trim(),d=(await this.threadService.createThread(c,n,s)).id;console.log(`[PROMPT_EXEC] Created new thread: ${d} for ${i} instruction execution`);let p={...this.codayOptions,oneshot:!0,project:c,thread:d,prompts:[u]},h=this.threadCodayManager.createWithoutConnection(d,c,n,p);if(this.logger.logWebhook({project:c,title:s??"Untitled",username:n,clientId:d,promptCount:1,awaitFinalAnswer:!!o,promptName:e,promptId:e,executionMode:i,webhookName:e,webhookUuid:e}),console.log(`[PROMPT_EXEC] Starting instruction run for thread: ${d}, agent: ${e}`),o)try{let m=await h.runOneshot({awaitFinalAnswer:!0});return await this.threadCodayManager.cleanup(d),{threadId:d,lastEvent:m}}catch(m){throw await this.threadCodayManager.cleanup(d),m}else return h.runOneshot({awaitFinalAnswer:!1}).catch(m=>console.error("[PROMPT_EXEC] Error during instruction run:",m)).finally(()=>{this.threadCodayManager.cleanup(d).catch(m=>console.error("[PROMPT_EXEC] Error cleaning up instruction thread:",m))}),{threadId:d}}async executePrompt(e,r,n,i,a){if(!this.threadCodayManager||!this.threadService||!this.codayOptions||!this.logger)throw new Error("PromptExecutionService not initialized. Call initialize() first.");let{title:s,awaitFinalAnswer:o=!1,projectName:c}=a||{},u,f;if(c){if(f=c,u=await this.promptService.get(f,e),!u)throw new Error(`Prompt ${e} not found in project ${f}`)}else{let y=await this.promptService.getById(e);if(!y)throw new Error(`Prompt not found: ${e}`);u=y.prompt,f=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 d=this.processCommands(u.commands,r);if(!n)throw new Error("Username is required");let h=(await this.threadService.createThread(f,n,s)).id;console.log(`[PROMPT_EXEC] Created new thread: ${h} for ${i} execution`);let m={...this.codayOptions,oneshot:!0,project:f,thread:h,prompts:d};console.log(`[PROMPT_EXEC] Creating instance for ${i} execution with ${d.length} prompts:`,d);let g=this.threadCodayManager.createWithoutConnection(h,f,n,m),v={project:f,title:s??"Untitled",username:n,clientId:h,promptCount:d.length,awaitFinalAnswer:!!o,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}),o)try{let y=await g.runOneshot({awaitFinalAnswer:!0});return await this.threadCodayManager.cleanup(h),{threadId:h,lastEvent:y}}catch(y){let b=y instanceof Error?y.message:"Unknown error";throw this.logger.logWebhookError({error:`Prompt execution failed: ${b}`,username:n,project:f,clientId:h}),console.error("[PROMPT_EXEC] Error waiting for prompt completion:",y),await this.threadCodayManager.cleanup(h),y}else return g.runOneshot({awaitFinalAnswer:!1}).catch(y=>console.error("[PROMPT_EXEC] Error during prompt Coday run:",y)).finally(()=>{this.threadCodayManager.cleanup(h).catch(y=>{console.error("[PROMPT_EXEC] Error cleaning up prompt thread after run:",y)})}),{threadId:h}}};var Cw=Kr(Tf(),1);import*as ka from"fs";import*as Wv from"path";import{randomUUID as iHt}from"node:crypto";var gj=class{constructor(e,r,n){this.logger=e;this.promptService=r;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=Wv.join(this.codayConfigDir,"projects");if(!ka.existsSync(e))return;let r=ka.readdirSync(e,{withFileTypes:!0}).filter(n=>n.isDirectory()).map(n=>n.name);for(let n of r)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 r=this.getSchedulersDir(e);if(!ka.existsSync(r))return[];let n=ka.readdirSync(r),i=[];for(let a of n)if(a.endsWith(".yml"))try{let s=Wv.join(r,a),o=ka.readFileSync(s,"utf-8"),c=Cw.parse(o),u=this.calculateNextRunSkippingMissed(c),f=u.occurrenceCount!==c.occurrenceCount;c.nextRun=u.nextRun,c.occurrenceCount=u.occurrenceCount,f&&await this.saveScheduler(c,e),i.push(c)}catch(s){console.error(`[SCHEDULER] Failed to load scheduler from ${a}:`,s)}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&&$ke(e.schedule,e.nextRun??null,e.occurrenceCount??0)&&this.executeScheduler(e).catch(r=>{console.error(`[SCHEDULER] Failed to execute scheduler ${e.id}:`,r)})}async executeSchedulerInternal(e,r,n){if(!this.promptExecutionService)throw new Error("PromptExecutionService not initialized");console.log(`[SCHEDULER] Executing scheduler "${e.name}" (${e.id}) [${n}]`);let i=n==="scheduled"?`Scheduled: ${e.name}`:`Manual: ${e.name}`;if(e.agentName&&e.instruction){let o=await this.promptExecutionService.executeInstruction(e.agentName,e.instruction,e.createdBy,"scheduled",{title:i,awaitFinalAnswer:!1,projectName:r});return console.log(`[SCHEDULER] Scheduler "${e.name}" executed successfully. Thread: ${o.threadId}`),o.threadId}if(!e.promptId)throw new Error(`Scheduler "${e.name}" has neither promptId nor agentName+instruction configured`);let a=e.parameters;e.parameters&&typeof e.parameters=="object"&&Object.keys(e.parameters).length===1&&"PARAMETERS"in e.parameters&&(a=String(e.parameters.PARAMETERS));let s=await this.promptExecutionService.executePrompt(e.promptId,a,e.createdBy,"scheduled",{title:i,awaitFinalAnswer:!1,projectName:r});return console.log(`[SCHEDULER] Scheduler "${e.name}" executed successfully. Thread: ${s.threadId}`),s.threadId}async executeScheduler(e){let r=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,s;e.lastRun=r,e.occurrenceCount=(e.occurrenceCount??0)+1,e.nextRun=gx(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(o){i=!1,s=o instanceof Error?o.message:String(o),console.error(`[SCHEDULER] Scheduler "${e.name}" failed:`,o)}this.logger.logTriggerExecution({triggerId:e.id,triggerName:e.name,webhookUuid:e.promptId??e.agentName??e.id,projectName:n,success:i,threadId:a,error:s})}validateSchedule(e){return Dke(e)}calculateNextRunSkippingMissed(e){let r=new Date,n=e.occurrenceCount??0;if(e.nextRun&&new Date(e.nextRun)>=r)return{nextRun:e.nextRun,occurrenceCount:n};let i=gx(e.schedule,r,n);return e.nextRun&&new Date(e.nextRun)<r&&console.log(`[SCHEDULER] Scheduler "${e.name}" (${e.id}) had missed nextRun, recalculated to: ${i}`),{nextRun:i,occurrenceCount:n}}getSchedulersDir(e){return Wv.join(this.codayConfigDir,"projects",e,"schedulers")}getSchedulerFilePath(e,r){return Wv.join(this.getSchedulersDir(e),`${r}.yml`)}findProjectForScheduler(e){let r=Wv.join(this.codayConfigDir,"projects");if(!ka.existsSync(r))return null;let n=ka.readdirSync(r,{withFileTypes:!0}).filter(i=>i.isDirectory()).map(i=>i.name);for(let i of n){let a=this.getSchedulerFilePath(i,e);if(ka.existsSync(a))return i}return null}canAccessScheduler(e,r){return e.createdBy===r?!0:Hv(r,this.codayConfigDir)}async listSchedulers(e,r){return(await this.loadProjectSchedulers(e)).filter(i=>this.canAccessScheduler(i,r)).map(i=>({id:i.id,name:i.name,enabled:i.enabled,promptId:i.promptId,agentName:i.agentName,instruction:i.instruction,schedule:i.schedule,parameters:i.parameters,lastRun:i.lastRun,nextRun:i.nextRun,createdBy:i.createdBy}))}async getScheduler(e,r,n){let i=this.getSchedulerFilePath(e,r);if(!ka.existsSync(i))return null;try{let a=ka.readFileSync(i,"utf-8"),s=Cw.parse(a),o=this.calculateNextRunSkippingMissed(s);return s.nextRun=o.nextRun,s.occurrenceCount=o.occurrenceCount,n&&!this.canAccessScheduler(s,n)?(console.log(`[SCHEDULER] Access denied for user ${n} to scheduler ${r}`),null):s}catch(a){return console.error(`[SCHEDULER] Failed to load scheduler ${r}:`,a),null}}async createScheduler(e,r,n){let i=this.validateSchedule(r.schedule);if(!i.valid)throw new Error(`Invalid schedule: ${i.error}`);if(!r.promptId&&!(r.agentName&&r.instruction))throw new Error("Scheduler must have either a promptId or both agentName and instruction");if(r.promptId&&!await this.promptService.getById(r.promptId))throw new Error(`Prompt not found: ${r.promptId}`);let a={id:iHt(),name:r.name,enabled:r.enabled??!0,promptId:r.promptId,agentName:r.agentName,instruction:r.instruction,schedule:r.schedule,parameters:r.parameters,createdBy:n,createdAt:new Date().toISOString(),nextRun:gx(r.schedule,new Date,0),occurrenceCount:0};return await this.saveScheduler(a,e),this.schedulers.set(a.id,a),console.log(`[SCHEDULER] Created scheduler "${a.name}" (${a.id}) for project ${e}`),a}async updateScheduler(e,r,n,i){let a=await this.getScheduler(e,r,i);if(!a)throw new Error(`Scheduler not found or access denied: ${r}`);if(console.log(`[SCHEDULER] Updating scheduler ${r} 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.agentName!==void 0&&(a.agentName=n.agentName),n.instruction!==void 0&&(a.instruction=n.instruction),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 s=this.validateSchedule(n.schedule);if(!s.valid)throw new Error(`Invalid schedule: ${s.error}`);a.schedule=n.schedule,a.occurrenceCount=0,a.nextRun=gx(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,r,n){if(!await this.getScheduler(e,r,n))return!1;let a=this.getSchedulerFilePath(e,r);return ka.unlinkSync(a),this.schedulers.delete(r),console.log(`[SCHEDULER] Deleted scheduler ${r} by user ${n}`),!0}async enableScheduler(e,r,n){return this.updateScheduler(e,r,{enabled:!0},n)}async disableScheduler(e,r,n){return this.updateScheduler(e,r,{enabled:!1},n)}async runSchedulerNow(e,r,n){let i=await this.getScheduler(e,r,n);if(!i)throw new Error(`Scheduler not found or access denied: ${r}`);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??i.agentName??i.id,projectName:e,success:!0,threadId:a}),a}async saveScheduler(e,r){if(!r&&(r=this.findProjectForScheduler(e.id),!r))throw new Error(`Cannot find project for scheduler ${e.id}`);let n=this.getSchedulersDir(r);ka.mkdirSync(n,{recursive:!0});let i=this.getSchedulerFilePath(r,e.id),a=Cw.stringify(e);ka.writeFileSync(i,a,"utf-8")}};import*as vu from"node:path";import*as mPe from"node:os";import{existsSync as hPe,lstatSync as aHt,mkdirSync as lte,readdirSync as sHt,renameSync as oHt}from"fs";var vj=class t{projectsConfigPath;static PROJECT_FILENAME="project.yaml";constructor(e){let r=vu.join(mPe.userInfo().homedir,".coday");this.projectsConfigPath=vu.join(e??r,"projects"),lte(this.projectsConfigPath,{recursive:!0})}listProjects(){return sHt(this.projectsConfigPath).filter(r=>!r.startsWith(".")&&aHt(vu.join(this.projectsConfigPath,r)).isDirectory())}getProjectInfo(e){let r=vu.join(this.projectsConfigPath,e),n=vu.join(r,t.PROJECT_FILENAME);return hPe(n)?{name:e,configPath:r}:null}exists(e){return this.getProjectInfo(e)!==null}getConfig(e){let r=this.getProjectInfo(e);if(!r)return console.log(`[PROJECT_REPO] No project info found for: '${e}'`),null;let n=vu.join(r.configPath,t.PROJECT_FILENAME),i=$s(n);if(!i)return console.log(`[PROJECT_REPO] Failed to load config for '${e}' from ${n}`),null;let a=N6(i,jke);return a!==i&&(console.log(`[PROJECT_REPO] Config migrated for '${e}', saving...`),Xi(n,a)),a}saveConfig(e,r){let n=this.getProjectInfo(e);if(!n)throw new Error(`Project '${e}' does not exist`);let i=vu.join(n.configPath,t.PROJECT_FILENAME);Xi(i,r)}createProject(e,r){let n=vu.join(this.projectsConfigPath,e),i=vu.join(n,t.PROJECT_FILENAME);return hPe(i)?!1:(console.log(`[PROJECT_REPO] Creating project '${e}' with path: ${r}`),lte(n,{recursive:!0}),Xi(i,{version:1,path:r,integration:{},storage:{type:"file"},agents:[]}),console.log(`[PROJECT_REPO] Project '${e}' created successfully`),!0)}deleteProject(e){let r=this.getProjectInfo(e);if(!r)return!1;let n=vu.join(this.projectsConfigPath,".deleted");lte(n,{recursive:!0});let i=new Date().toISOString().replace(/:/g,"-"),a=vu.join(n,`${e}__${i}`);return oHt(r.configPath,a),!0}};var fte=Kr(Tf(),1);import{promises as vp}from"fs";import Xm from"path";var gPe=async t=>{try{let e=await vp.readFile(t,"utf-8");return fte.default.parse(e)}catch{return null}},yj=class{constructor(e){this.projectsDir=e}getThreadsDir(e){return Xm.join(this.projectsDir,e,"threads")}async ensureThreadsDir(e){let r=this.getThreadsDir(e);try{await vp.mkdir(r,{recursive:!0})}catch(n){throw new Hd(`Failed to initialize threads directory for project ${e}`,n)}}getThreadFileName(e){return`${e.id}.yml`}async findThreadFile(e,r){try{let n=this.getThreadsDir(e),i=`${r}.yml`;try{return await vp.access(Xm.join(n,i)),i}catch{}return(await vp.readdir(n)).find(o=>o.endsWith(`-${r}.yml`))||null}catch(n){throw new Hd(`Error finding thread ${r} in project ${e}`,n)}}async getById(e,r){try{let n=await this.findThreadFile(e,r);if(!n)return null;let i=this.getThreadsDir(e),a=Xm.join(i,n),s=await gPe(a);if(!s)return null;let o=N6(s,_X);return o.projectId||(o.projectId=e),o!==s&&Xi(a,o),new Wd(o)}catch(n){throw new Hd(`Failed to read thread ${r} from project ${e}`,n)}}async save(e,r){await this.ensureThreadsDir(e);try{if(r.id||(r.id=crypto.randomUUID()),r.projectId||(r.projectId=e),r.projectId!==e)throw new Error(`Thread projectId mismatch: expected ${e}, got ${r.projectId}`);let n=this.getThreadsDir(e),i=this.getThreadFileName(r),a=Xm.join(n,i),s=await this.findThreadFile(e,r.id);if(s&&s!==i){let u=Xm.join(n,s);try{await vp.unlink(u),console.log(`[THREAD-REPO] Migrated/renamed thread file: ${s} \u2192 ${i}`)}catch(f){console.warn(`[THREAD-REPO] Could not delete old thread file: ${s}`,f)}}let o={...r.serialize(),version:_X.length+1},c=fte.default.stringify(o);return await vp.writeFile(a,c,"utf-8"),r}catch(n){throw new Hd(`Failed to save thread ${r.id} to project ${e}`,n)}}async listByProject(e){try{let r=this.getThreadsDir(e);try{await vp.access(r)}catch{return[]}let n=await vp.readdir(r);return(await Promise.all(n.filter(a=>a.endsWith(".yml")).map(async a=>{let s=await gPe(Xm.join(r,a));if(!s)return null;let o=s.projectId||e;return{id:s.id,username:s.username,projectId:o,name:s.name??"...",summary:s.summary??"",createdDate:s.createdDate??"",modifiedDate:s.modifiedDate??"",price:s.price??0,starring:s.starring??[],users:Array.isArray(s.users)?s.users.map(c=>typeof c=="string"?{userId:c}:c):s.username?[{userId:s.username}]:[],parentThreadId:s.parentThreadId,parentEventId:s.parentEventId,delegatedAgentName:s.delegatedAgentName,delegatedTask:s.delegatedTask,worktreeProject:s.worktreeProject,closedByUser:s.closedByUser||void 0}}))).filter(a=>!!a).sort((a,s)=>a.modifiedDate>s.modifiedDate?-1:1)}catch(r){throw new Hd(`Failed to list threads for project ${e}`,r)}}async delete(e,r){try{let n=await this.findThreadFile(e,r);if(!n)return!1;let i=this.getThreadsDir(e);return await vp.unlink(Xm.join(i,n)),!0}catch(n){throw new Hd(`Failed to delete thread ${r} from project ${e}`,n)}}};var bj=class{constructor(e,r,n){this.projectRepository=e;this.projectsDir=r;this.threadFileService=n}repositoryCache=new Map;threadListCache=new Map;CACHE_TTL_MS=14400*1e3;loadingPromises=new Map;getThreadRepository(e){let r=this.repositoryCache.get(e);if(r)return r;if(!this.projectRepository.getProjectInfo(e))throw new Error(`Project '${e}' not found`);let i=new yj(this.projectsDir);return this.repositoryCache.set(e,i),i}clearCache(e){e?this.repositoryCache.delete(e):this.repositoryCache.clear()}async listThreads(e,r){let n=this.threadListCache.get(e);if(n&&Date.now()-n.timestamp<this.CACHE_TTL_MS)return n.data.filter(s=>Ln(s,r)).sort((s,o)=>s.modifiedDate>o.modifiedDate?-1:1);let i=this.loadingPromises.get(e);if(i)return await i,this.listThreads(e,r);let a=this.loadThreadListFromDisk(e);this.loadingPromises.set(e,a);try{return(await a).filter(o=>Ln(o,r)).sort((o,c)=>o.modifiedDate>c.modifiedDate?-1:1)}catch(s){throw this.threadListCache.delete(e),s}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,worktreeProject:e.worktreeProject,closedByUser:e.closedByUser||void 0}}updateThreadInCache(e,r){let n=this.threadListCache.get(e);if(!n)return;let i=n.data.findIndex(a=>a.id===r.id);i!==-1?n.data[i]=r:n.data.push(r)}removeThreadFromCache(e,r){let n=this.threadListCache.get(e);n&&(n.data=n.data.filter(i=>i.id!==r))}async getThread(e,r){return await this.getThreadRepository(e).getById(e,r)}async createThread(e,r,n){let i=this.getThreadRepository(e),a=new Wd({id:crypto.randomUUID(),username:r,projectId:e,name:n||"",price:0}),s=await i.save(e,a);return this.updateThreadInCache(e,this.toThreadSummary(s)),s}async updateThread(e,r,n){let i=this.getThreadRepository(e),a=await i.getById(e,r);if(!a){let c=this.threadListCache.get(e)?.data.find(u=>u.id===r);if(c)a=new Wd({id:c.id,username:c.username,projectId:c.projectId,name:c.name,summary:c.summary,price:c.price,starring:c.starring,users:c.users,parentThreadId:c.parentThreadId,parentEventId:c.parentEventId,delegatedAgentName:c.delegatedAgentName,delegatedTask:c.delegatedTask});else throw new Error(`Thread '${r}' 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),n.closedByUser!==void 0&&(a.closedByUser=n.closedByUser);let s=await i.save(e,a);return this.updateThreadInCache(e,this.toThreadSummary(s)),s}async starThread(e,r,n){let i=this.getThreadRepository(e),a=await i.getById(e,r);if(!a)throw new Error(`Thread '${r}' not found in project '${e}'`);a.starring.includes(n)||a.starring.push(n);let s=await i.save(e,a);return this.updateThreadInCache(e,this.toThreadSummary(s)),s}async unstarThread(e,r,n){let i=this.getThreadRepository(e),a=await i.getById(e,r);if(!a)throw new Error(`Thread '${r}' not found in project '${e}'`);a.starring=a.starring.filter(o=>o!==n);let s=await i.save(e,a);return this.updateThreadInCache(e,this.toThreadSummary(s)),s}async deleteThread(e,r){let i=await this.getThreadRepository(e).delete(e,r);return i&&(await this.threadFileService.deleteThreadFiles(e,r),this.removeThreadFromCache(e,r)),i}async saveThread(e,r){let i=await this.getThreadRepository(e).save(e,r);return this.updateThreadInCache(e,this.toThreadSummary(i)),i}async listAllThreads(e){let r=this.threadListCache.get(e);if(r&&Date.now()-r.timestamp<this.CACHE_TTL_MS)return r.data.sort((a,s)=>a.modifiedDate>s.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((s,o)=>s.modifiedDate>o.modifiedDate?-1:1)}catch(a){throw this.threadListCache.delete(e),a}finally{this.loadingPromises.delete(e)}}async exists(e,r){return await this.getThread(e,r)!==null}};var wPe=Kr(Tf(),1);import*as Ho from"fs/promises";import*as Tw from"path";var vPe=5,yPe=24,bPe=100,xPe={SHORT_THREADS:30,LONG_THREADS:90},xj=class{constructor(e,r){this.projectsConfigPath=e;this.logger=r}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()},yPe*60*60*1e3),this.log(`Thread cleanup scheduled every ${yPe} hours`)},vPe*60*1e3),this.log(`Initial cleanup scheduled in ${vPe} 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(),r=0,n=0,i=0;try{this.log("Starting thread cleanup...");let a=await Ho.readdir(this.projectsConfigPath);this.log(`Found ${a.length} projects to scan`);for(let o of a)try{let c=Tw.join(this.projectsConfigPath,o);if(!(await Ho.lstat(c)).isDirectory())continue;let f=Tw.join(c,"threads");try{await Ho.access(f)}catch{continue}let{scanned:d,deleted:p,errors:h}=await this.cleanupProjectThreads(o,f);r+=d,n+=p,i+=h}catch(c){this.logError(`Error processing project ${o}: ${c}`),i++}let s=Date.now()-e;this.log(`Cleanup completed: ${n}/${r} threads deleted across all projects in ${s}ms (${i} errors)`)}catch(a){let s=Date.now()-e;this.logError(`Cleanup failed after ${s}ms: ${a}`)}}async cleanupProjectThreads(e,r){let n=0,i=0,a=0;try{let o=(await Ho.readdir(r)).filter(c=>c.endsWith(".yml"));if(n=o.length,o.length===0)return{scanned:n,deleted:i,errors:a};this.log(`Scanning ${o.length} threads in project ${e}`);for(let c=0;c<o.length;c+=bPe){let u=o.slice(c,c+bPe),f=await this.processBatch(u,r,e);i+=f.deleted,a+=f.errors}i>0&&this.log(`Project ${e}: deleted ${i}/${n} expired threads`)}catch(s){this.logError(`Error scanning project ${e}: ${s}`),a++}return{scanned:n,deleted:i,errors:a}}async processBatch(e,r,n){let i=0,a=0;return await Promise.all(e.map(async s=>{let o=Tw.join(r,s),c;try{let u=await Ho.readFile(o,"utf-8");c=wPe.parse(u)}catch(u){a++,this.logError(`Error processing file ${s} in project ${n}: ${u}`);return}if(!(!c||!c.modifiedDate)&&!(c.starring&&Array.isArray(c.starring)&&c.starring.length>0)&&this.shouldDeleteThread(c)){let u=this.countUserMessages(c.messages||[]),f=this.getDaysSinceModified(c.modifiedDate),d=c.id||s.replace(".yml","");await Ho.unlink(o),await this.deleteThreadFiles(r,d),i++,this.logger.logThreadCleanup(n,s),console.log(`ThreadCleanup: Deleted thread ${d} and its files directory (${u} user messages, ${f} days old)`)}})),{deleted:i,errors:a}}shouldDeleteThread(e){if(!e||!e.modifiedDate)return!1;let n=this.countUserMessages(e.messages||[])<=3?xPe.SHORT_THREADS:xPe.LONG_THREADS;return this.getDaysSinceModified(e.modifiedDate)>n}countUserMessages(e){return e.filter(r=>r&&(r.type==="message"&&r.role==="user"||r.type==="answer")).length}getDaysSinceModified(e){let r=new Date(e),i=new Date().getTime()-r.getTime();return Math.floor(i/(1e3*60*60*24))}async deleteThreadFiles(e,r){try{let n=Tw.join(e,`${r}-files`);try{await Ho.access(n),await Ho.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 ${r}:`,n)}}log(e){let r=new Date().toISOString();console.log(`[${r}] ThreadCleanup: ${e}`)}logError(e){let r=new Date().toISOString();console.error(`[${r}] ThreadCleanup ERROR: ${e}`)}async forceCleanup(){this.log("Manual cleanup triggered"),await this.performCleanup()}};import*as fs from"path";import*as Ym from"fs";import*as fo from"fs/promises";var wj=class{constructor(e){this.projectsDir=e}getThreadFilesDir(e,r){return fs.join(this.projectsDir,e,"threads",`${r}-files`)}async ensureThreadFilesDir(e,r){let n=this.getThreadFilesDir(e,r);Ym.existsSync(n)||await fo.mkdir(n,{recursive:!0})}async listFiles(e,r){await this.ensureThreadFilesDir(e,r);let n=this.getThreadFilesDir(e,r),i=await fo.readdir(n);return await Promise.all(i.map(async s=>{let o=fs.join(n,s),c=await fo.stat(o);return{filename:s,size:c.size,lastModified:c.mtime.toISOString()}}))}async saveFile(e,r,n,i){let a=this.getThreadFilesDir(e,r);await fo.mkdir(a,{recursive:!0});let s=fs.join(a,n);await fo.writeFile(s,i)}async getFile(e,r,n){await this.ensureThreadFilesDir(e,r);let i=this.getThreadFilesDir(e,r),a=fs.join(i,n),s=fs.resolve(a),o=fs.resolve(i);if(!s.startsWith(o))throw new Error("Access denied: invalid file path");if(!Ym.existsSync(a))throw new Error(`File '${n}' not found`);return await fo.readFile(a)}async getFilePath(e,r,n){await this.ensureThreadFilesDir(e,r);let i=this.getThreadFilesDir(e,r),a=fs.join(i,n),s=fs.resolve(a),o=fs.resolve(i);if(!s.startsWith(o))throw new Error("Access denied: invalid file path");if(!Ym.existsSync(a))throw new Error(`File '${n}' not found`);return a}fileExists(e,r,n){let i=this.getThreadFilesDir(e,r),a=fs.join(i,n),s=fs.resolve(a),o=fs.resolve(i);return s.startsWith(o)?Ym.existsSync(a):!1}async deleteFile(e,r,n){await this.ensureThreadFilesDir(e,r);let i=this.getThreadFilesDir(e,r),a=fs.join(i,n),s=fs.resolve(a),o=fs.resolve(i);if(!s.startsWith(o))throw new Error("Access denied: invalid file path");if(!Ym.existsSync(a))throw new Error(`File '${n}' not found`);await fo.unlink(a)}async deleteThreadFiles(e,r){try{let n=this.getThreadFilesDir(e,r);Ym.existsSync(n)&&(await fo.rm(n,{recursive:!0,force:!0}),console.log(`Deleted thread files directory: ${n}`))}catch(n){console.error(`Error deleting thread files for ${r}:`,n)}}};var _Pe=Kr(yc(),1);var _j=class{constructor(e,r,n,i){this.threadRepository=r;this.projectId=n;this.interactor=i;this.username=e.username}activeThread$=new _Pe.BehaviorSubject(null);isKilled=!1;activeThread=this.activeThread$.asObservable();username;async kill(){let e=this.activeThread$.value;if(e&&e.messagesLength>0)try{await this.threadRepository.save(this.projectId,e),console.log(`[THREAD_STATE] Kill-save succeeded for thread ${e.id} (${e.messagesLength} messages)`)}catch(r){console.log("Kill-save failed:",r instanceof Error?r.message:r)}else console.log(`[THREAD_STATE] Kill-save skipped: ${e?`thread ${e.id} has ${e.messagesLength} messages`:"no active thread"}`);this.isKilled=!0,this.activeThread$.complete()}async create(e){let r=new Wd({id:"",username:this.username,name:e??"",price:0});return this.activeThread$.next(r),r}async select(e){let r=await this.threadRepository.getById(this.projectId,e);if(!r)throw new Error(`Thread ${e} not found`);return this.activeThread$.next(r),r}async save(e){let r=this.activeThread$.value;if(!r){console.error(`No thread existing when save attempt with name '${e}'`);return}e&&(r.name=e);let n=await this.threadRepository.save(this.projectId,r);this.activeThread$.next(n)}async autoSave(e){if(this.isKilled){console.warn(`[AUTOSAVE] SKIPPED for project ${this.projectId}: service already killed (thread data may be lost if no prior save succeeded)`);return}let r=this.activeThread$.value;if(!r||r.messagesLength==0){console.warn(`[AUTOSAVE] Skipped: ${r?`thread ${r.id} has 0 messages`:"no active thread"} (project: ${this.projectId}, user: ${this.username})`);return}try{e&&(r.name=e),await this.threadRepository.save(this.projectId,r),console.log(`[AUTOSAVE] Thread ${r.id} saved (${r.messagesLength} messages, project: ${this.projectId})`),this.interactor&&this.interactor.sendEvent(new Fa({threadId:r.id,name:r.name||void 0}))}catch(n){console.log("Autosave failed (service may have been killed):",n instanceof Error?n.message:n)}}async truncateAtUserMessage(e){let r=this.activeThread$.value;if(!r)return console.error("No active thread available for truncation"),!1;let n=r.truncateAtUserMessage(e);return n||this.interactor?.warn("Failed to truncate thread."),n}getCurrentThread(){return this.activeThread$.value}};async function SPe(t,e){let r=e.project.selectedProject,n=e.user.getUserData(r.name),i=await fj(r.config.path,t,n),a=new Q5({...i,root:r.config.path,name:r.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 Sj=class extends ut{constructor(r,n){super({commandWord:"select-project",description:"Select an existing project"});this.interactor=r;this.services=n}async handle(r,n){try{let i=this.getSubCommand(r);return await this.selectProject(i)??n}catch(i){return this.interactor.error(`Invalid project selection because: ${i.toString()}`),n}}async selectProject(r){return this.services.project.selectProject(r),this.services.project.selectedProject?SPe(this.interactor,this.services):null}};var Ej=class extends ut{constructor(r,n,i){super({commandWord:"add",description:"Add a new integration configuration. User level is default, use --project/-p for project level."});this.interactor=r;this.service=n;this.editHandler=i}async handle(r,n){let a=!!or(this.getSubCommand(r),[{key:"project",alias:"p"}]).project,s=a?"project":"user",o=this.service.getMergedIntegrations(),c=Object.keys(o),u=Z3.filter(g=>!c.includes(g));if(u.length===0)return this.interactor.displayText(`All available integrations (${Z3.join(", ")}) are already configured.`),n;let f=await this.interactor.chooseOption(u.sort(),"Select integration to add:",`Available integrations to configure:
|
|
1100
|
+
`)):""}loadMemoriesFrom(e){this.memories=[],this.userMemoriesPath=this.readMemories(this.userMemoriesPath)?this.userMemoriesPath:void 0;let r=e?.configPath?pj.join(e.configPath,cte):void 0;this.projectMemoriesPath=this.readMemories(r)?r:void 0,e&&this.checkInit()}readMemories(e){if(!e)return!1;try{if(!KUt(e)){let n=nPe.stringify({memories:[]});XUt(e,n)}let r=$s(e);return r?(this.memories.push(...r.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"),r=this.memories.filter(n=>n.level==="PROJECT");Xi(this.userMemoriesPath,{memories:e}),Xi(this.projectMemoriesPath,{memories:r})}};import*as sPe from"crypto";import*as lo from"node:fs/promises";import*as oPe from"node:fs";import*as Dc from"path";import{exec as aPe}from"child_process";var Bv=class t{constructor(e,r,n){this.repository=e;this.defaultProject=r;this.isForcedMode=n}maskingService=new L2;listProjects(){let e=this.repository.listProjects();return this.isForcedMode&&this.defaultProject?e.filter(r=>r===this.defaultProject).map(r=>{let n=this.repository.getConfig(r);return{name:r,volatile:n?.volatile}}):e.map(r=>{let n=this.repository.getConfig(r);return{name:r,volatile:n?.volatile,projectPath:n?.path}}).filter(({projectPath:r})=>{if(!r)return!0;try{return oPe.existsSync(r)}catch{return!0}}).map(({name:r,volatile:n})=>({name:r,volatile:n}))}getDefaultProject(){return this.defaultProject||null}getForcedMode(){return this.isForcedMode}getProject(e){this.checkAgainstForced(e);let r=this.repository.getConfig(e);if(r)return{name:e,config:r};if(!this.isForcedMode&&this.defaultProject){let n=process.cwd(),i=t.generateProjectId(n),a=Dc.basename(n);if(e===a||e===i||e===this.defaultProject){console.log(`[PROJECT_SERVICE] Creating volatile project for '${e}' at ${n}`);let s=this.getOrCreateVolatileProject(n);if(r=this.repository.getConfig(s),r)return{name:s,config:r}}}return null}exists(e){return this.checkAgainstForced(e),this.repository.exists(e)}createProject(e,r){if(this.checkAgainstForced(e),!e||!r)throw new Error("Project name and path are required");if(!this.repository.createProject(e,r))throw new Error(`Project '${e}' already exists`)}updateProjectConfig(e,r){if(this.checkAgainstForced(e),!this.repository.exists(e))throw new Error(`Project '${e}' does not exist`);this.repository.saveConfig(e,r)}async deleteProject(e,r){if(this.checkAgainstForced(e),e.includes("__"))r?.removeGitWorktree&&await this.removeGitWorktree(e),await this.unregisterWorktreeProject(e);else if(!this.repository.deleteProject(e))throw new Error(`Project '${e}' does not exist`)}async removeGitWorktree(e){let r=e.lastIndexOf("__");if(r===-1)return;let n=e.substring(0,r),i=this.repository.getConfig(n);if(!i?.path){console.warn(`[PROJECT_SERVICE] Cannot remove git worktree: parent project '${n}' config not found`);return}let a=i.path,s=Dc.dirname(a),o=Dc.join(s,e);try{await lo.access(o)}catch{console.warn(`[PROJECT_SERVICE] Worktree path does not exist, skipping git removal: ${o}`);return}aPe(`git worktree remove "${o}" --force`,{cwd:a},c=>{if(c){console.error(`[PROJECT_SERVICE] Failed to remove git worktree: ${c.message}`);return}console.log(`[PROJECT_SERVICE] Removed git worktree: ${o}`),aPe("git worktree prune",{cwd:a},u=>{u&&console.warn(`[PROJECT_SERVICE] git worktree prune failed: ${u.message}`)})})}getProjectConfigForClient(e){this.checkAgainstForced(e);let r=this.repository.getConfig(e);return r?this.maskingService.maskConfig(r):null}updateProjectConfigFromClient(e,r){this.checkAgainstForced(e);let n=this.repository.getConfig(e);if(!n)throw new Error(`Project '${e}' does not exist`);let i=this.maskingService.unmaskConfig(r,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 r=t.generateProjectId(e);if(this.repository.exists(r))return r;this.repository.createProject(r,e);let n=this.repository.getConfig(r);return n&&(n.volatile=!0,n.createdAt=Date.now(),this.repository.saveConfig(r,n)),r}async registerWorktreeProject(e,r,n){let i=this.repository.getConfig(n),a=i?{...i,path:r,volatile:void 0,createdAt:void 0}:{version:1,path:r,integration:{},storage:{type:"file"},agents:[]};this.repository.createProject(e,r),this.repository.saveConfig(e,a);let s=this.repository.getProjectInfo(n);if(s){let o=this.repository.getProjectInfo(e);if(o)for(let c of["agents","prompts","schedulers","memories"]){let u=Dc.join(s.configPath,c),f=Dc.join(o.configPath,c);try{await lo.access(u),await lo.symlink(u,f)}catch{}}}}async unregisterWorktreeProject(e){let r=this.repository.getProjectInfo(e);if(!r)return;let n=e.lastIndexOf("__");if(n!==-1){let i=e.substring(0,n),a=this.repository.getProjectInfo(i);a&&await this.migrateThreadsToParent(r.configPath,a.configPath)}await lo.rm(r.configPath,{recursive:!0,force:!0}),this.repository.deleteProject(e)}async migrateThreadsToParent(e,r){let n=Dc.join(e,"threads"),i=Dc.join(r,"threads");try{await lo.access(n)}catch{return}await lo.mkdir(i,{recursive:!0});let a=await lo.readdir(n);for(let s of a){let o=Dc.join(n,s),c=Dc.join(i,s);try{await lo.access(c)}catch{await lo.rename(o,c)}}}static generateProjectId(e){let r=Dc.basename(e),n=sPe.createHash("sha256").update(e).digest("hex").substring(0,8);return`${r}_${n}`}};var lPe=Kr(yc(),1);import*as zv from"node:path";import*as uPe from"node:os";import{mkdirSync as YUt}from"fs";var QUt="projects",cPe="project.yaml",Uv=class{constructor(e,r,n){this.interactor=e;this.projectService=r;let i=zv.join(uPe.userInfo().homedir,".coday");this.projectsConfigPath=zv.join(n??i,QUt),YUt(this.projectsConfigPath,{recursive:!0}),this.projects=this.projectService.listProjects().map(a=>a.name)}projectsConfigPath;maskingService=new L2;projects;selectedProjectBehaviorSubject=new lPe.BehaviorSubject(null);selectedProject$=this.selectedProjectBehaviorSubject.asObservable();selectProject(e){let r=zv.join(this.projectsConfigPath,e),n=zv.join(r,cPe),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 s={name:e,config:i,configPath:r};console.log(`[PROJECT_STATE_SERVICE] Selected '${e}' \u2192 ${i.path}`),this.updateSelectedProject(s),this.interactor.displayText(`Project local configuration used: ${n}`)}updateSelectedProject(e){this.selectedProjectBehaviorSubject.next(e)}get selectedProject(){return this.selectedProjectBehaviorSubject.value}save(e){let r=this.selectedProjectBehaviorSubject.value;if(!r){this.interactor.error("No current project selected, save not possible");return}let n={...r.config,...e};Xi(zv.join(r.configPath,cPe),n),r.config=n,this.updateSelectedProject(r)}getConfigForClient(){let e=this.selectedProjectBehaviorSubject.value;return e?this.maskingService.maskConfig(e.config):null}updateConfigFromClient(e){let r=this.selectedProjectBehaviorSubject.value;if(!r){this.interactor.error("No current project selected, update not possible");return}let n=this.maskingService.unmaskConfig(e,r.config);this.save(n)}};import*as gp from"node:path";import*as pPe from"node:os";import{randomUUID as tHt}from"node:crypto";import{existsSync as B2,mkdirSync as rHt,readdirSync as dPe,unlinkSync as nHt}from"fs";import*as ute from"node:path";import*as fPe from"node:os";function eHt(t){return t.replace(/[^a-zA-Z0-9]/g,"_")}function Hv(t,e){try{let r=ute.join(fPe.userInfo().homedir,".coday"),n=eHt(t),i=ute.join(e??r,"users",n,"user.yaml"),a=$s(i);return a?a.groups?.includes("CODAY_ADMIN")??!1:!1}catch{return!1}}var hj=class{codayConfigDir;projectService;nativeHandlerStubs=[];constructor(e,r){let n=gp.join(pPe.userInfo().homedir,".coday");this.codayConfigDir=e??n,this.projectService=r}getProjectPath(e){if(this.projectService)return this.projectService.getProject(e)?.config.path}async getOrCreatePromptsDir(e,r){let n;if(r==="local")n=gp.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 u2({text:"coday.yaml",root:i});if(a.length===0)throw new Error(`coday.yaml not found in project path: ${i}`);let s=gp.dirname(a[0]);n=gp.join(i,s,"prompts")}return B2(n)||(rHt(n,{recursive:!0}),console.log(`[PROMPT] Created prompts directory: ${n}`)),n}async getOrCreatePromptFilePath(e,r,n){let i=await this.getOrCreatePromptsDir(e,n);return gp.join(i,`${r}.yml`)}async findPromptSource(e,r){let n=await this.getOrCreatePromptFilePath(e,r,"local");if(B2(n))return"local";if(this.projectService)try{let i=await this.getOrCreatePromptFilePath(e,r,"project");if(B2(i))return"project"}catch{}return null}async findProjectForPrompt(e){let r=gp.join(this.codayConfigDir,"projects");if(!B2(r))return null;let n=dPe(r,{withFileTypes:!0}).filter(i=>i.isDirectory()).map(i=>i.name);for(let i of n){let a=gp.join(this.codayConfigDir,"projects",i,"prompts",`${e}.yml`);if(B2(a))return i;if(this.projectService)try{let s=await this.getOrCreatePromptFilePath(i,e,"project");if(B2(s))return i}catch{}}return null}validatePlaceholders(e){let r=/\{\{(\w+)\}\}/g,n=[],i=/^[A-Za-z][A-Za-z0-9-]*$/;if(e.forEach(a=>{let s;for(;(s=r.exec(a))!==null;){let o=s[1];o&&o!=="PARAMETERS"&&!i.test(o)&&n.push(o)}}),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,r,n="local"){try{this.validatePlaceholders(r.commands);let i=tHt(),a={...r,id:i,source:n,createdAt:new Date().toISOString(),parameterFormat:this.getParameterFormat(r.commands)},s=await this.getOrCreatePromptFilePath(e,i,n);if(B2(s))throw new Error(`Prompt with ID ${i} already exists`);return Xi(s,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,r){try{let n=await this.findPromptSource(e,r);if(!n)return null;let i=await this.getOrCreatePromptFilePath(e,r,n),a=$s(i);return a?(a.source||(a.source=n),a):null}catch(n){return console.error(`Failed to get prompt ${r}:`,n),null}}async getById(e){try{let r=await this.findProjectForPrompt(e);if(!r)return null;let n=await this.get(r,e);return n?{prompt:n,projectName:r}:null}catch(r){return console.error(`Failed to get prompt ${e}:`,r),null}}async update(e,r,n,i){try{let a=await this.get(e,r);if(!a)return null;if(n.webhookEnabled!==void 0&&n.webhookEnabled!==a.webhookEnabled&&!Hv(i,this.codayConfigDir))throw new Error("Only CODAY_ADMIN can enable/disable webhook for prompts");let{id:s,createdAt:o,source:c,...u}=n;n.commands&&this.validatePlaceholders(n.commands);let f={...a,...u,updatedAt:new Date().toISOString()};n.commands&&(f.parameterFormat=this.getParameterFormat(n.commands));let d=await this.getOrCreatePromptFilePath(e,r,a.source);return Xi(d,f),console.log(`[PROMPT] Updated prompt ${r} (${a.source}) by user ${i}`),f}catch(a){throw console.error(`Failed to update prompt ${r}:`,a),a}}async delete(e,r){try{let n=await this.findPromptSource(e,r);if(!n)return!1;let i=await this.getOrCreatePromptFilePath(e,r,n);return nHt(i),console.log(`[PROMPT] Deleted prompt ${r} from ${n}`),!0}catch(n){return console.error(`Failed to delete prompt ${r}:`,n),!1}}getParameterFormat(e){if(e.some(a=>/\{\{PARAMETERS\}\}/.test(a)))return"";let n=/\{\{(\w+)\}\}/g,i=new Set;return e.forEach(a=>{let s;for(;(s=n.exec(a))!==null;){let o=s[1];o&&o!=="PARAMETERS"&&i.add(o)}}),i.size===0?"":Array.from(i).map(a=>`${a}=""`).join(" ")}registerNativeHandler(e){this.nativeHandlerStubs.find(r=>r.id===e.id)||this.nativeHandlerStubs.push(e)}async list(e,r=[]){try{let n=[],i=["local"];this.projectService&&i.push("project");for(let a of i)try{let s=await this.getOrCreatePromptsDir(e,a);if(!B2(s))continue;let c=dPe(s).filter(u=>u.endsWith(".yml"));for(let u of c){let f=u.replace(".yml",""),d=await this.get(e,f);d&&n.push({id:d.id,name:d.name,description:d.description,webhookEnabled:d.webhookEnabled,createdBy:d.createdBy,createdAt:d.createdAt,updatedAt:d.updatedAt,source:d.source||a,parameterFormat:d.parameterFormat})}}catch(s){console.log(`[PROMPT] Could not access ${a} prompts for ${e}:`,s)}return n.push(...X5),n.push(...this.nativeHandlerStubs),n.push(...r),n.sort((a,s)=>new Date(s.createdAt).getTime()-new Date(a.createdAt).getTime())}catch(n){return console.error(`Failed to list prompts for project ${e}:`,n),[]}}async enableWebhook(e,r,n){return this.update(e,r,{webhookEnabled:!0},n)}async disableWebhook(e,r,n){return this.update(e,r,{webhookEnabled:!1},n)}};var mj=class{constructor(e){this.promptService=e}threadCodayManager;threadService;codayOptions;logger;initialize(e,r,n,i){this.threadCodayManager=e,this.threadService=r,this.codayOptions=n,this.logger=i}processCommands(e,r){let n;if(typeof r=="string"){let a=e.some(o=>/\{\{PARAMETERS\}\}/.test(o));if(e.some(o=>/\{\{(?!PARAMETERS\}\})\w+\}\}/.test(o)))throw new Error("Prompt contains structured placeholders ({{key}}). Use an object parameter instead of a string.");a?n=e.map(o=>o.replace(/\{\{PARAMETERS\}\}/g,r)):n=e.map((o,c)=>c===0?`${o} ${r}`.trim():o)}else typeof r=="object"&&r!==null?n=e.map(a=>{let s=a;return Object.entries(r).forEach(([o,c])=>{let u=`{{${o}}}`;s=s.replaceAll(u,String(c))}),s}):n=[...e];let i=new Set;if(n.forEach(a=>{let s=a.match(/\{\{(\w+)\}\}/g);s&&s.forEach(o=>i.add(o))}),i.size>0){let a=Array.from(i).map(s=>s.replace(/[{}]/g,"")).join(", ");throw new Error(`Missing required parameters: ${a}`)}return n}async executeInstruction(e,r,n,i,a){if(!this.threadCodayManager||!this.threadService||!this.codayOptions||!this.logger)throw new Error("PromptExecutionService not initialized. Call initialize() first.");let{title:s,awaitFinalAnswer:o=!1,projectName:c}=a||{};if(!c)throw new Error("projectName is required for executeInstruction");if(!n)throw new Error("Username is required");let u=`@${e} ${r}`.trim(),d=(await this.threadService.createThread(c,n,s)).id;console.log(`[PROMPT_EXEC] Created new thread: ${d} for ${i} instruction execution`);let p={...this.codayOptions,oneshot:!0,project:c,thread:d,prompts:[u]},h=this.threadCodayManager.createWithoutConnection(d,c,n,p);if(this.logger.logWebhook({project:c,title:s??"Untitled",username:n,clientId:d,promptCount:1,awaitFinalAnswer:!!o,promptName:e,promptId:e,executionMode:i,webhookName:e,webhookUuid:e}),console.log(`[PROMPT_EXEC] Starting instruction run for thread: ${d}, agent: ${e}`),o)try{let m=await h.runOneshot({awaitFinalAnswer:!0});return await this.threadCodayManager.cleanup(d),{threadId:d,lastEvent:m}}catch(m){throw await this.threadCodayManager.cleanup(d),m}else return h.runOneshot({awaitFinalAnswer:!1}).catch(m=>console.error("[PROMPT_EXEC] Error during instruction run:",m)).finally(()=>{this.threadCodayManager.cleanup(d).catch(m=>console.error("[PROMPT_EXEC] Error cleaning up instruction thread:",m))}),{threadId:d}}async executePrompt(e,r,n,i,a){if(!this.threadCodayManager||!this.threadService||!this.codayOptions||!this.logger)throw new Error("PromptExecutionService not initialized. Call initialize() first.");let{title:s,awaitFinalAnswer:o=!1,projectName:c}=a||{},u,f;if(c){if(f=c,u=await this.promptService.get(f,e),!u)throw new Error(`Prompt ${e} not found in project ${f}`)}else{let y=await this.promptService.getById(e);if(!y)throw new Error(`Prompt not found: ${e}`);u=y.prompt,f=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 d=this.processCommands(u.commands,r);if(!n)throw new Error("Username is required");let h=(await this.threadService.createThread(f,n,s)).id;console.log(`[PROMPT_EXEC] Created new thread: ${h} for ${i} execution`);let m={...this.codayOptions,oneshot:!0,project:f,thread:h,prompts:d};console.log(`[PROMPT_EXEC] Creating instance for ${i} execution with ${d.length} prompts:`,d);let g=this.threadCodayManager.createWithoutConnection(h,f,n,m),v={project:f,title:s??"Untitled",username:n,clientId:h,promptCount:d.length,awaitFinalAnswer:!!o,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}),o)try{let y=await g.runOneshot({awaitFinalAnswer:!0});return await this.threadCodayManager.cleanup(h),{threadId:h,lastEvent:y}}catch(y){let b=y instanceof Error?y.message:"Unknown error";throw this.logger.logWebhookError({error:`Prompt execution failed: ${b}`,username:n,project:f,clientId:h}),console.error("[PROMPT_EXEC] Error waiting for prompt completion:",y),await this.threadCodayManager.cleanup(h),y}else return g.runOneshot({awaitFinalAnswer:!1}).catch(y=>console.error("[PROMPT_EXEC] Error during prompt Coday run:",y)).finally(()=>{this.threadCodayManager.cleanup(h).catch(y=>{console.error("[PROMPT_EXEC] Error cleaning up prompt thread after run:",y)})}),{threadId:h}}};var Cw=Kr(Tf(),1);import*as ka from"fs";import*as Wv from"path";import{randomUUID as iHt}from"node:crypto";var gj=class{constructor(e,r,n){this.logger=e;this.promptService=r;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=Wv.join(this.codayConfigDir,"projects");if(!ka.existsSync(e))return;let r=ka.readdirSync(e,{withFileTypes:!0}).filter(n=>n.isDirectory()).map(n=>n.name);for(let n of r)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 r=this.getSchedulersDir(e);if(!ka.existsSync(r))return[];let n=ka.readdirSync(r),i=[];for(let a of n)if(a.endsWith(".yml"))try{let s=Wv.join(r,a),o=ka.readFileSync(s,"utf-8"),c=Cw.parse(o),u=this.calculateNextRunSkippingMissed(c),f=u.occurrenceCount!==c.occurrenceCount;c.nextRun=u.nextRun,c.occurrenceCount=u.occurrenceCount,f&&await this.saveScheduler(c,e),i.push(c)}catch(s){console.error(`[SCHEDULER] Failed to load scheduler from ${a}:`,s)}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&&$ke(e.schedule,e.nextRun??null,e.occurrenceCount??0)&&this.executeScheduler(e).catch(r=>{console.error(`[SCHEDULER] Failed to execute scheduler ${e.id}:`,r)})}async executeSchedulerInternal(e,r,n){if(!this.promptExecutionService)throw new Error("PromptExecutionService not initialized");console.log(`[SCHEDULER] Executing scheduler "${e.name}" (${e.id}) [${n}]`);let i=n==="scheduled"?`Scheduled: ${e.name}`:`Manual: ${e.name}`;if(e.agentName&&e.instruction){let o=await this.promptExecutionService.executeInstruction(e.agentName,e.instruction,e.createdBy,"scheduled",{title:i,awaitFinalAnswer:!1,projectName:r});return console.log(`[SCHEDULER] Scheduler "${e.name}" executed successfully. Thread: ${o.threadId}`),o.threadId}if(!e.promptId)throw new Error(`Scheduler "${e.name}" has neither promptId nor agentName+instruction configured`);let a=e.parameters;e.parameters&&typeof e.parameters=="object"&&Object.keys(e.parameters).length===1&&"PARAMETERS"in e.parameters&&(a=String(e.parameters.PARAMETERS));let s=await this.promptExecutionService.executePrompt(e.promptId,a,e.createdBy,"scheduled",{title:i,awaitFinalAnswer:!1,projectName:r});return console.log(`[SCHEDULER] Scheduler "${e.name}" executed successfully. Thread: ${s.threadId}`),s.threadId}async executeScheduler(e){let r=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,s;e.lastRun=r,e.occurrenceCount=(e.occurrenceCount??0)+1,e.nextRun=gx(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(o){i=!1,s=o instanceof Error?o.message:String(o),console.error(`[SCHEDULER] Scheduler "${e.name}" failed:`,o)}this.logger.logTriggerExecution({triggerId:e.id,triggerName:e.name,webhookUuid:e.promptId??e.agentName??e.id,projectName:n,success:i,threadId:a,error:s})}validateSchedule(e){return Dke(e)}calculateNextRunSkippingMissed(e){let r=new Date,n=e.occurrenceCount??0;if(e.nextRun&&new Date(e.nextRun)>=r)return{nextRun:e.nextRun,occurrenceCount:n};let i=gx(e.schedule,r,n);return e.nextRun&&new Date(e.nextRun)<r&&console.log(`[SCHEDULER] Scheduler "${e.name}" (${e.id}) had missed nextRun, recalculated to: ${i}`),{nextRun:i,occurrenceCount:n}}getSchedulersDir(e){return Wv.join(this.codayConfigDir,"projects",e,"schedulers")}getSchedulerFilePath(e,r){return Wv.join(this.getSchedulersDir(e),`${r}.yml`)}findProjectForScheduler(e){let r=Wv.join(this.codayConfigDir,"projects");if(!ka.existsSync(r))return null;let n=ka.readdirSync(r,{withFileTypes:!0}).filter(i=>i.isDirectory()).map(i=>i.name);for(let i of n){let a=this.getSchedulerFilePath(i,e);if(ka.existsSync(a))return i}return null}canAccessScheduler(e,r){return e.createdBy===r?!0:Hv(r,this.codayConfigDir)}async listSchedulers(e,r){return(await this.loadProjectSchedulers(e)).filter(i=>this.canAccessScheduler(i,r)).map(i=>({id:i.id,name:i.name,enabled:i.enabled,promptId:i.promptId,agentName:i.agentName,instruction:i.instruction,schedule:i.schedule,parameters:i.parameters,lastRun:i.lastRun,nextRun:i.nextRun,createdBy:i.createdBy}))}async getScheduler(e,r,n){let i=this.getSchedulerFilePath(e,r);if(!ka.existsSync(i))return null;try{let a=ka.readFileSync(i,"utf-8"),s=Cw.parse(a),o=this.calculateNextRunSkippingMissed(s);return s.nextRun=o.nextRun,s.occurrenceCount=o.occurrenceCount,n&&!this.canAccessScheduler(s,n)?(console.log(`[SCHEDULER] Access denied for user ${n} to scheduler ${r}`),null):s}catch(a){return console.error(`[SCHEDULER] Failed to load scheduler ${r}:`,a),null}}async createScheduler(e,r,n){let i=this.validateSchedule(r.schedule);if(!i.valid)throw new Error(`Invalid schedule: ${i.error}`);if(!r.promptId&&!(r.agentName&&r.instruction))throw new Error("Scheduler must have either a promptId or both agentName and instruction");if(r.promptId&&!await this.promptService.getById(r.promptId))throw new Error(`Prompt not found: ${r.promptId}`);let a={id:iHt(),name:r.name,enabled:r.enabled??!0,promptId:r.promptId,agentName:r.agentName,instruction:r.instruction,schedule:r.schedule,parameters:r.parameters,createdBy:n,createdAt:new Date().toISOString(),nextRun:gx(r.schedule,new Date,0),occurrenceCount:0};return await this.saveScheduler(a,e),this.schedulers.set(a.id,a),console.log(`[SCHEDULER] Created scheduler "${a.name}" (${a.id}) for project ${e}`),a}async updateScheduler(e,r,n,i){let a=await this.getScheduler(e,r,i);if(!a)throw new Error(`Scheduler not found or access denied: ${r}`);if(console.log(`[SCHEDULER] Updating scheduler ${r} 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.agentName!==void 0&&(a.agentName=n.agentName),n.instruction!==void 0&&(a.instruction=n.instruction),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 s=this.validateSchedule(n.schedule);if(!s.valid)throw new Error(`Invalid schedule: ${s.error}`);a.schedule=n.schedule,a.occurrenceCount=0,a.nextRun=gx(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,r,n){if(!await this.getScheduler(e,r,n))return!1;let a=this.getSchedulerFilePath(e,r);return ka.unlinkSync(a),this.schedulers.delete(r),console.log(`[SCHEDULER] Deleted scheduler ${r} by user ${n}`),!0}async enableScheduler(e,r,n){return this.updateScheduler(e,r,{enabled:!0},n)}async disableScheduler(e,r,n){return this.updateScheduler(e,r,{enabled:!1},n)}async runSchedulerNow(e,r,n){let i=await this.getScheduler(e,r,n);if(!i)throw new Error(`Scheduler not found or access denied: ${r}`);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??i.agentName??i.id,projectName:e,success:!0,threadId:a}),a}async saveScheduler(e,r){if(!r&&(r=this.findProjectForScheduler(e.id),!r))throw new Error(`Cannot find project for scheduler ${e.id}`);let n=this.getSchedulersDir(r);ka.mkdirSync(n,{recursive:!0});let i=this.getSchedulerFilePath(r,e.id),a=Cw.stringify(e);ka.writeFileSync(i,a,"utf-8")}};import*as vu from"node:path";import*as mPe from"node:os";import{existsSync as hPe,lstatSync as aHt,mkdirSync as lte,readdirSync as sHt,renameSync as oHt}from"fs";var vj=class t{projectsConfigPath;static PROJECT_FILENAME="project.yaml";constructor(e){let r=vu.join(mPe.userInfo().homedir,".coday");this.projectsConfigPath=vu.join(e??r,"projects"),lte(this.projectsConfigPath,{recursive:!0})}listProjects(){return sHt(this.projectsConfigPath).filter(r=>!r.startsWith(".")&&aHt(vu.join(this.projectsConfigPath,r)).isDirectory())}getProjectInfo(e){let r=vu.join(this.projectsConfigPath,e),n=vu.join(r,t.PROJECT_FILENAME);return hPe(n)?{name:e,configPath:r}:null}exists(e){return this.getProjectInfo(e)!==null}getConfig(e){let r=this.getProjectInfo(e);if(!r)return console.log(`[PROJECT_REPO] No project info found for: '${e}'`),null;let n=vu.join(r.configPath,t.PROJECT_FILENAME),i=$s(n);if(!i)return console.log(`[PROJECT_REPO] Failed to load config for '${e}' from ${n}`),null;let a=N6(i,jke);return a!==i&&(console.log(`[PROJECT_REPO] Config migrated for '${e}', saving...`),Xi(n,a)),a}saveConfig(e,r){let n=this.getProjectInfo(e);if(!n)throw new Error(`Project '${e}' does not exist`);let i=vu.join(n.configPath,t.PROJECT_FILENAME);Xi(i,r)}createProject(e,r){let n=vu.join(this.projectsConfigPath,e),i=vu.join(n,t.PROJECT_FILENAME);return hPe(i)?!1:(console.log(`[PROJECT_REPO] Creating project '${e}' with path: ${r}`),lte(n,{recursive:!0}),Xi(i,{version:1,path:r,integration:{},storage:{type:"file"},agents:[]}),console.log(`[PROJECT_REPO] Project '${e}' created successfully`),!0)}deleteProject(e){let r=this.getProjectInfo(e);if(!r)return!1;let n=vu.join(this.projectsConfigPath,".deleted");lte(n,{recursive:!0});let i=new Date().toISOString().replace(/:/g,"-"),a=vu.join(n,`${e}__${i}`);return oHt(r.configPath,a),!0}};var fte=Kr(Tf(),1);import{promises as vp}from"fs";import Xm from"path";var gPe=async t=>{try{let e=await vp.readFile(t,"utf-8");return fte.default.parse(e)}catch{return null}},yj=class{constructor(e){this.projectsDir=e}getThreadsDir(e){return Xm.join(this.projectsDir,e,"threads")}async ensureThreadsDir(e){let r=this.getThreadsDir(e);try{await vp.mkdir(r,{recursive:!0})}catch(n){throw new Hd(`Failed to initialize threads directory for project ${e}`,n)}}getThreadFileName(e){return`${e.id}.yml`}async findThreadFile(e,r){try{let n=this.getThreadsDir(e),i=`${r}.yml`;try{return await vp.access(Xm.join(n,i)),i}catch{}return(await vp.readdir(n)).find(o=>o.endsWith(`-${r}.yml`))||null}catch(n){throw new Hd(`Error finding thread ${r} in project ${e}`,n)}}async getById(e,r){try{let n=await this.findThreadFile(e,r);if(!n)return null;let i=this.getThreadsDir(e),a=Xm.join(i,n),s=await gPe(a);if(!s)return null;let o=N6(s,_X);return o.projectId||(o.projectId=e),o!==s&&Xi(a,o),new Wd(o)}catch(n){throw new Hd(`Failed to read thread ${r} from project ${e}`,n)}}async save(e,r){await this.ensureThreadsDir(e);try{if(r.id||(r.id=crypto.randomUUID()),r.projectId||(r.projectId=e),r.projectId!==e)throw new Error(`Thread projectId mismatch: expected ${e}, got ${r.projectId}`);let n=this.getThreadsDir(e),i=this.getThreadFileName(r),a=Xm.join(n,i),s=await this.findThreadFile(e,r.id);if(s&&s!==i){let u=Xm.join(n,s);try{await vp.unlink(u),console.log(`[THREAD-REPO] Migrated/renamed thread file: ${s} \u2192 ${i}`)}catch(f){console.warn(`[THREAD-REPO] Could not delete old thread file: ${s}`,f)}}let o={...r.serialize(),version:_X.length+1},c=fte.default.stringify(o,{lineWidth:0,blockQuote:!1});return await vp.writeFile(a,c,"utf-8"),r}catch(n){throw new Hd(`Failed to save thread ${r.id} to project ${e}`,n)}}async listByProject(e){try{let r=this.getThreadsDir(e);try{await vp.access(r)}catch{return[]}let n=await vp.readdir(r);return(await Promise.all(n.filter(a=>a.endsWith(".yml")).map(async a=>{let s=await gPe(Xm.join(r,a));if(!s)return null;let o=s.projectId||e;return{id:s.id,username:s.username,projectId:o,name:s.name??"...",summary:s.summary??"",createdDate:s.createdDate??"",modifiedDate:s.modifiedDate??"",price:s.price??0,starring:s.starring??[],users:Array.isArray(s.users)?s.users.map(c=>typeof c=="string"?{userId:c}:c):s.username?[{userId:s.username}]:[],parentThreadId:s.parentThreadId,parentEventId:s.parentEventId,delegatedAgentName:s.delegatedAgentName,delegatedTask:s.delegatedTask,worktreeProject:s.worktreeProject,closedByUser:s.closedByUser||void 0}}))).filter(a=>!!a).sort((a,s)=>a.modifiedDate>s.modifiedDate?-1:1)}catch(r){throw new Hd(`Failed to list threads for project ${e}`,r)}}async delete(e,r){try{let n=await this.findThreadFile(e,r);if(!n)return!1;let i=this.getThreadsDir(e);return await vp.unlink(Xm.join(i,n)),!0}catch(n){throw new Hd(`Failed to delete thread ${r} from project ${e}`,n)}}};var bj=class{constructor(e,r,n){this.projectRepository=e;this.projectsDir=r;this.threadFileService=n}repositoryCache=new Map;threadListCache=new Map;CACHE_TTL_MS=14400*1e3;loadingPromises=new Map;getThreadRepository(e){let r=this.repositoryCache.get(e);if(r)return r;if(!this.projectRepository.getProjectInfo(e))throw new Error(`Project '${e}' not found`);let i=new yj(this.projectsDir);return this.repositoryCache.set(e,i),i}clearCache(e){e?this.repositoryCache.delete(e):this.repositoryCache.clear()}async listThreads(e,r){let n=this.threadListCache.get(e);if(n&&Date.now()-n.timestamp<this.CACHE_TTL_MS)return n.data.filter(s=>Ln(s,r)).sort((s,o)=>s.modifiedDate>o.modifiedDate?-1:1);let i=this.loadingPromises.get(e);if(i)return await i,this.listThreads(e,r);let a=this.loadThreadListFromDisk(e);this.loadingPromises.set(e,a);try{return(await a).filter(o=>Ln(o,r)).sort((o,c)=>o.modifiedDate>c.modifiedDate?-1:1)}catch(s){throw this.threadListCache.delete(e),s}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,worktreeProject:e.worktreeProject,closedByUser:e.closedByUser||void 0}}updateThreadInCache(e,r){let n=this.threadListCache.get(e);if(!n)return;let i=n.data.findIndex(a=>a.id===r.id);i!==-1?n.data[i]=r:n.data.push(r)}removeThreadFromCache(e,r){let n=this.threadListCache.get(e);n&&(n.data=n.data.filter(i=>i.id!==r))}async getThread(e,r){return await this.getThreadRepository(e).getById(e,r)}async createThread(e,r,n){let i=this.getThreadRepository(e),a=new Wd({id:crypto.randomUUID(),username:r,projectId:e,name:n||"",price:0}),s=await i.save(e,a);return this.updateThreadInCache(e,this.toThreadSummary(s)),s}async updateThread(e,r,n){let i=this.getThreadRepository(e),a=await i.getById(e,r);if(!a){let c=this.threadListCache.get(e)?.data.find(u=>u.id===r);if(c)a=new Wd({id:c.id,username:c.username,projectId:c.projectId,name:c.name,summary:c.summary,price:c.price,starring:c.starring,users:c.users,parentThreadId:c.parentThreadId,parentEventId:c.parentEventId,delegatedAgentName:c.delegatedAgentName,delegatedTask:c.delegatedTask});else throw new Error(`Thread '${r}' 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),n.closedByUser!==void 0&&(a.closedByUser=n.closedByUser);let s=await i.save(e,a);return this.updateThreadInCache(e,this.toThreadSummary(s)),s}async starThread(e,r,n){let i=this.getThreadRepository(e),a=await i.getById(e,r);if(!a)throw new Error(`Thread '${r}' not found in project '${e}'`);a.starring.includes(n)||a.starring.push(n);let s=await i.save(e,a);return this.updateThreadInCache(e,this.toThreadSummary(s)),s}async unstarThread(e,r,n){let i=this.getThreadRepository(e),a=await i.getById(e,r);if(!a)throw new Error(`Thread '${r}' not found in project '${e}'`);a.starring=a.starring.filter(o=>o!==n);let s=await i.save(e,a);return this.updateThreadInCache(e,this.toThreadSummary(s)),s}async deleteThread(e,r){let i=await this.getThreadRepository(e).delete(e,r);return i&&(await this.threadFileService.deleteThreadFiles(e,r),this.removeThreadFromCache(e,r)),i}async saveThread(e,r){let i=await this.getThreadRepository(e).save(e,r);return this.updateThreadInCache(e,this.toThreadSummary(i)),i}async listAllThreads(e){let r=this.threadListCache.get(e);if(r&&Date.now()-r.timestamp<this.CACHE_TTL_MS)return r.data.sort((a,s)=>a.modifiedDate>s.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((s,o)=>s.modifiedDate>o.modifiedDate?-1:1)}catch(a){throw this.threadListCache.delete(e),a}finally{this.loadingPromises.delete(e)}}async exists(e,r){return await this.getThread(e,r)!==null}};var wPe=Kr(Tf(),1);import*as Ho from"fs/promises";import*as Tw from"path";var vPe=5,yPe=24,bPe=100,xPe={SHORT_THREADS:30,LONG_THREADS:90},xj=class{constructor(e,r){this.projectsConfigPath=e;this.logger=r}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()},yPe*60*60*1e3),this.log(`Thread cleanup scheduled every ${yPe} hours`)},vPe*60*1e3),this.log(`Initial cleanup scheduled in ${vPe} 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(),r=0,n=0,i=0;try{this.log("Starting thread cleanup...");let a=await Ho.readdir(this.projectsConfigPath);this.log(`Found ${a.length} projects to scan`);for(let o of a)try{let c=Tw.join(this.projectsConfigPath,o);if(!(await Ho.lstat(c)).isDirectory())continue;let f=Tw.join(c,"threads");try{await Ho.access(f)}catch{continue}let{scanned:d,deleted:p,errors:h}=await this.cleanupProjectThreads(o,f);r+=d,n+=p,i+=h}catch(c){this.logError(`Error processing project ${o}: ${c}`),i++}let s=Date.now()-e;this.log(`Cleanup completed: ${n}/${r} threads deleted across all projects in ${s}ms (${i} errors)`)}catch(a){let s=Date.now()-e;this.logError(`Cleanup failed after ${s}ms: ${a}`)}}async cleanupProjectThreads(e,r){let n=0,i=0,a=0;try{let o=(await Ho.readdir(r)).filter(c=>c.endsWith(".yml"));if(n=o.length,o.length===0)return{scanned:n,deleted:i,errors:a};this.log(`Scanning ${o.length} threads in project ${e}`);for(let c=0;c<o.length;c+=bPe){let u=o.slice(c,c+bPe),f=await this.processBatch(u,r,e);i+=f.deleted,a+=f.errors}i>0&&this.log(`Project ${e}: deleted ${i}/${n} expired threads`)}catch(s){this.logError(`Error scanning project ${e}: ${s}`),a++}return{scanned:n,deleted:i,errors:a}}async processBatch(e,r,n){let i=0,a=0;return await Promise.all(e.map(async s=>{let o=Tw.join(r,s),c;try{let u=await Ho.readFile(o,"utf-8");c=wPe.parse(u)}catch(u){a++,this.logError(`Error processing file ${s} in project ${n}: ${u}`);return}if(!(!c||!c.modifiedDate)&&!(c.starring&&Array.isArray(c.starring)&&c.starring.length>0)&&this.shouldDeleteThread(c)){let u=this.countUserMessages(c.messages||[]),f=this.getDaysSinceModified(c.modifiedDate),d=c.id||s.replace(".yml","");await Ho.unlink(o),await this.deleteThreadFiles(r,d),i++,this.logger.logThreadCleanup(n,s),console.log(`ThreadCleanup: Deleted thread ${d} and its files directory (${u} user messages, ${f} days old)`)}})),{deleted:i,errors:a}}shouldDeleteThread(e){if(!e||!e.modifiedDate)return!1;let n=this.countUserMessages(e.messages||[])<=3?xPe.SHORT_THREADS:xPe.LONG_THREADS;return this.getDaysSinceModified(e.modifiedDate)>n}countUserMessages(e){return e.filter(r=>r&&(r.type==="message"&&r.role==="user"||r.type==="answer")).length}getDaysSinceModified(e){let r=new Date(e),i=new Date().getTime()-r.getTime();return Math.floor(i/(1e3*60*60*24))}async deleteThreadFiles(e,r){try{let n=Tw.join(e,`${r}-files`);try{await Ho.access(n),await Ho.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 ${r}:`,n)}}log(e){let r=new Date().toISOString();console.log(`[${r}] ThreadCleanup: ${e}`)}logError(e){let r=new Date().toISOString();console.error(`[${r}] ThreadCleanup ERROR: ${e}`)}async forceCleanup(){this.log("Manual cleanup triggered"),await this.performCleanup()}};import*as fs from"path";import*as Ym from"fs";import*as fo from"fs/promises";var wj=class{constructor(e){this.projectsDir=e}getThreadFilesDir(e,r){return fs.join(this.projectsDir,e,"threads",`${r}-files`)}async ensureThreadFilesDir(e,r){let n=this.getThreadFilesDir(e,r);Ym.existsSync(n)||await fo.mkdir(n,{recursive:!0})}async listFiles(e,r){await this.ensureThreadFilesDir(e,r);let n=this.getThreadFilesDir(e,r),i=await fo.readdir(n);return await Promise.all(i.map(async s=>{let o=fs.join(n,s),c=await fo.stat(o);return{filename:s,size:c.size,lastModified:c.mtime.toISOString()}}))}async saveFile(e,r,n,i){let a=this.getThreadFilesDir(e,r);await fo.mkdir(a,{recursive:!0});let s=fs.join(a,n);await fo.writeFile(s,i)}async getFile(e,r,n){await this.ensureThreadFilesDir(e,r);let i=this.getThreadFilesDir(e,r),a=fs.join(i,n),s=fs.resolve(a),o=fs.resolve(i);if(!s.startsWith(o))throw new Error("Access denied: invalid file path");if(!Ym.existsSync(a))throw new Error(`File '${n}' not found`);return await fo.readFile(a)}async getFilePath(e,r,n){await this.ensureThreadFilesDir(e,r);let i=this.getThreadFilesDir(e,r),a=fs.join(i,n),s=fs.resolve(a),o=fs.resolve(i);if(!s.startsWith(o))throw new Error("Access denied: invalid file path");if(!Ym.existsSync(a))throw new Error(`File '${n}' not found`);return a}fileExists(e,r,n){let i=this.getThreadFilesDir(e,r),a=fs.join(i,n),s=fs.resolve(a),o=fs.resolve(i);return s.startsWith(o)?Ym.existsSync(a):!1}async deleteFile(e,r,n){await this.ensureThreadFilesDir(e,r);let i=this.getThreadFilesDir(e,r),a=fs.join(i,n),s=fs.resolve(a),o=fs.resolve(i);if(!s.startsWith(o))throw new Error("Access denied: invalid file path");if(!Ym.existsSync(a))throw new Error(`File '${n}' not found`);await fo.unlink(a)}async deleteThreadFiles(e,r){try{let n=this.getThreadFilesDir(e,r);Ym.existsSync(n)&&(await fo.rm(n,{recursive:!0,force:!0}),console.log(`Deleted thread files directory: ${n}`))}catch(n){console.error(`Error deleting thread files for ${r}:`,n)}}};var _Pe=Kr(yc(),1);var _j=class{constructor(e,r,n,i){this.threadRepository=r;this.projectId=n;this.interactor=i;this.username=e.username}activeThread$=new _Pe.BehaviorSubject(null);isKilled=!1;activeThread=this.activeThread$.asObservable();username;async kill(){let e=this.activeThread$.value;if(e&&e.messagesLength>0)try{await this.threadRepository.save(this.projectId,e),console.log(`[THREAD_STATE] Kill-save succeeded for thread ${e.id} (${e.messagesLength} messages)`)}catch(r){console.log("Kill-save failed:",r instanceof Error?r.message:r)}else console.log(`[THREAD_STATE] Kill-save skipped: ${e?`thread ${e.id} has ${e.messagesLength} messages`:"no active thread"}`);this.isKilled=!0,this.activeThread$.complete()}async create(e){let r=new Wd({id:"",username:this.username,name:e??"",price:0});return this.activeThread$.next(r),r}async select(e){let r=await this.threadRepository.getById(this.projectId,e);if(!r)throw new Error(`Thread ${e} not found`);return this.activeThread$.next(r),r}async save(e){let r=this.activeThread$.value;if(!r){console.error(`No thread existing when save attempt with name '${e}'`);return}e&&(r.name=e);let n=await this.threadRepository.save(this.projectId,r);this.activeThread$.next(n)}async autoSave(e){if(this.isKilled){console.warn(`[AUTOSAVE] SKIPPED for project ${this.projectId}: service already killed (thread data may be lost if no prior save succeeded)`);return}let r=this.activeThread$.value;if(!r||r.messagesLength==0){console.warn(`[AUTOSAVE] Skipped: ${r?`thread ${r.id} has 0 messages`:"no active thread"} (project: ${this.projectId}, user: ${this.username})`);return}try{e&&(r.name=e),await this.threadRepository.save(this.projectId,r),console.log(`[AUTOSAVE] Thread ${r.id} saved (${r.messagesLength} messages, project: ${this.projectId})`),this.interactor&&this.interactor.sendEvent(new Fa({threadId:r.id,name:r.name||void 0}))}catch(n){console.log("Autosave failed (service may have been killed):",n instanceof Error?n.message:n)}}async truncateAtUserMessage(e){let r=this.activeThread$.value;if(!r)return console.error("No active thread available for truncation"),!1;let n=r.truncateAtUserMessage(e);return n||this.interactor?.warn("Failed to truncate thread."),n}getCurrentThread(){return this.activeThread$.value}};async function SPe(t,e){let r=e.project.selectedProject,n=e.user.getUserData(r.name),i=await fj(r.config.path,t,n),a=new Q5({...i,root:r.config.path,name:r.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 Sj=class extends ut{constructor(r,n){super({commandWord:"select-project",description:"Select an existing project"});this.interactor=r;this.services=n}async handle(r,n){try{let i=this.getSubCommand(r);return await this.selectProject(i)??n}catch(i){return this.interactor.error(`Invalid project selection because: ${i.toString()}`),n}}async selectProject(r){return this.services.project.selectProject(r),this.services.project.selectedProject?SPe(this.interactor,this.services):null}};var Ej=class extends ut{constructor(r,n,i){super({commandWord:"add",description:"Add a new integration configuration. User level is default, use --project/-p for project level."});this.interactor=r;this.service=n;this.editHandler=i}async handle(r,n){let a=!!or(this.getSubCommand(r),[{key:"project",alias:"p"}]).project,s=a?"project":"user",o=this.service.getMergedIntegrations(),c=Object.keys(o),u=Z3.filter(g=>!c.includes(g));if(u.length===0)return this.interactor.displayText(`All available integrations (${Z3.join(", ")}) are already configured.`),n;let f=await this.interactor.chooseOption(u.sort(),"Select integration to add:",`Available integrations to configure:
|
|
1101
1101
|
|
|
1102
1102
|
${u.map(g=>`- **${g}**`).join(`
|
|
1103
1103
|
`)}
|
|
@@ -1649,12 +1649,12 @@ Transcript:
|
|
|
1649
1649
|
${a.join(`
|
|
1650
1650
|
`)}
|
|
1651
1651
|
|
|
1652
|
-
JSON:`,c,u;try{let p=(await this.aiClient.complete(o,{maxTokens:300})).replace(/^```(?:json)?\s*/i,"").replace(/\s*```$/,"").trim(),h=JSON.parse(p);c=typeof h.name=="string"?h.name.trim().slice(0,60):void 0,u=typeof h.summary=="string"?h.summary.trim():void 0}catch(d){_e("POST_PROCESSOR",`Failed to parse AI response for thread ${e.id}:`,d);return}if(!c&&!u){_e("POST_PROCESSOR",`Nothing to update for thread ${e.id}`);return}let f={};u&&(f.summary=u),c&&!e.name&&(f.name=c);try{await this.threadService.updateThread(r,e.id,f),_e("POST_PROCESSOR",`Thread ${e.id} updated \u2014 name: ${f.name??"(kept)"}, summary: ${!!f.summary}`)}catch(d){_e("POST_PROCESSOR",`Failed to persist updates for thread ${e.id}:`,d)}}};var ZU=class t{constructor(e,r,n,i,a,s,o,c,u,f,d,p,h){this.threadId=e;this.projectName=r;this.username=n;this.options=i;this.logger=a;this.projectService=s;this.threadService=o;this.promptService=c;this.mcpPool=u;this.onTimeout=f;this.projectEventManager=d;this.setPendingInviteCb=p;this.hasPendingInviteCb=h;this.resetInactivityTimeout()}connections=new Set;lastActivity=Date.now();inactivityTimeout;isOneshot=!1;isReplaying=!1;coday;static INTERACTIVE_TIMEOUT=480*60*1e3;static ONESHOT_TIMEOUT=1800*1e3;addConnection(e){this.connections.has(e)||(this.connections.add(e),this.updateActivity(),this.isOneshot=!1,_e("THREAD_CODAY",`Added SSE connection to thread ${this.threadId} (total: ${this.connections.size})`),_e("THREAD_CODAY",`Replaying thread history for new connection to ${this.threadId}`),this.replayThreadHistory(e))}async replayThreadHistory(e){try{let r;if(this.coday?.context?.aiThread)r=(await this.coday.context.aiThread.getMessages(void 0,void 0)).messages;else{let i=await this.threadService.getThread(this.projectName,this.threadId);if(!i){_e("THREAD_CODAY",`No thread found on disk for replay in ${this.threadId}`);return}r=i.getAllMessages()}_e("THREAD_CODAY",`Replaying ${r.length} messages for thread ${this.threadId}`);for(let i of r){if(i.type==="invite"||i.type==="choice")continue;let a=`data: ${JSON.stringify(i)}
|
|
1652
|
+
JSON:`,c,u;try{let p=(await this.aiClient.complete(o,{maxTokens:300})).replace(/^```(?:json)?\s*/i,"").replace(/\s*```$/,"").trim(),h=JSON.parse(p);c=typeof h.name=="string"?h.name.trim().slice(0,60):void 0,u=typeof h.summary=="string"?h.summary.trim():void 0}catch(d){_e("POST_PROCESSOR",`Failed to parse AI response for thread ${e.id}:`,d);return}if(!c&&!u){_e("POST_PROCESSOR",`Nothing to update for thread ${e.id}`);return}let f={};u&&(f.summary=u),c&&!e.name&&(f.name=c);try{await this.threadService.updateThread(r,e.id,f),_e("POST_PROCESSOR",`Thread ${e.id} updated \u2014 name: ${f.name??"(kept)"}, summary: ${!!f.summary}`)}catch(d){_e("POST_PROCESSOR",`Failed to persist updates for thread ${e.id}:`,d)}}};var ZU=class t{constructor(e,r,n,i,a,s,o,c,u,f,d,p,h){this.threadId=e;this.projectName=r;this.username=n;this.options=i;this.logger=a;this.projectService=s;this.threadService=o;this.promptService=c;this.mcpPool=u;this.onTimeout=f;this.projectEventManager=d;this.setPendingInviteCb=p;this.hasPendingInviteCb=h;this.resetInactivityTimeout()}connections=new Set;lastActivity=Date.now();inactivityTimeout;isOneshot=!1;isReplaying=!1;isCleaningUp=!1;coday;static INTERACTIVE_TIMEOUT=480*60*1e3;static ONESHOT_TIMEOUT=1800*1e3;addConnection(e){this.connections.has(e)||(this.connections.add(e),this.updateActivity(),this.isOneshot=!1,_e("THREAD_CODAY",`Added SSE connection to thread ${this.threadId} (total: ${this.connections.size})`),_e("THREAD_CODAY",`Replaying thread history for new connection to ${this.threadId}`),this.replayThreadHistory(e))}async replayThreadHistory(e){try{let r;if(this.coday?.context?.aiThread)r=(await this.coday.context.aiThread.getMessages(void 0,void 0)).messages;else{let i=await this.threadService.getThread(this.projectName,this.threadId);if(!i){_e("THREAD_CODAY",`No thread found on disk for replay in ${this.threadId}`);return}r=i.getAllMessages()}_e("THREAD_CODAY",`Replaying ${r.length} messages for thread ${this.threadId}`);for(let i of r){if(i.type==="invite"||i.type==="choice")continue;let a=`data: ${JSON.stringify(i)}
|
|
1653
1653
|
|
|
1654
1654
|
`;e.writableEnded||e.write(a)}if(this.hasPendingInviteCb(this.threadId)){this.isReplaying=!0;try{this.coday?.interactor.replayLastQuestion()}finally{this.isReplaying=!1}}}catch(r){_e("THREAD_CODAY","Error replaying thread history:",r)}}removeConnection(e){this.connections.delete(e),_e("THREAD_CODAY",`Removed SSE connection from thread ${this.threadId} (remaining: ${this.connections.size})`)}get connectionCount(){return this.connections.size}updateActivity(){this.lastActivity=Date.now(),this.resetInactivityTimeout()}resetInactivityTimeout(){this.inactivityTimeout&&clearTimeout(this.inactivityTimeout);let e=this.isOneshot?t.ONESHOT_TIMEOUT:t.INTERACTIVE_TIMEOUT;this.inactivityTimeout=setTimeout(()=>{let r=Date.now()-this.lastActivity;_e("THREAD_CODAY",`Inactivity timeout reached for thread ${this.threadId} after ${Math.round(r/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 _e("THREAD_CODAY",`Coday already running for thread ${this.threadId}`),!1;_e("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 gf(this.threadId),r=new q2(this.options.configDir,this.username,e),n=new Uv(e,this.projectService,this.options.configDir),i=new Nv(n,r),a=new jv(r,n,e),s=new Lv(n,r),o=new Mv(r,n,e);return e.events.subscribe(c=>{this.broadcastEvent(c)}),this.coday=new WU(e,this.options,{user:r,project:n,projectService:this.projectService,integration:i,integrationConfig:a,memory:s,mcp:o,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}async runOneshot(e){if(this.prepareCoday(),!this.coday)throw new Error(`prepareCoday() failed for thread ${this.threadId} \u2014 coday instance is undefined`);if(this.projectEventManager?.broadcast(this.projectName,new Fa({threadId:this.threadId})),e?.awaitFinalAnswer){let r=[],n=this.coday.interactor.events.pipe((0,ddt.filter)(i=>i instanceof mr&&i.role==="assistant"&&!!i.name)).subscribe(i=>r.push(i));try{return await this.coday.run(),n.unsubscribe(),r[r.length-1]}catch(i){throw n.unsubscribe(),i}}else{this.coday.run().catch(r=>{_e("THREAD_CODAY",`Error during oneshot run for thread ${this.threadId}:`,r),console.error(`Oneshot run failed for thread ${this.threadId}:`,r)});return}}startCoday(){this.updateActivity();let e=this.prepareCoday();return this.coday?e?(this.coday.run().catch(r=>{_e("THREAD_CODAY",`Error during Coday run for thread ${this.threadId}:`,r),console.error(`Coday run failed for thread ${this.threadId}:`,r)}).finally(()=>{_e("THREAD_CODAY",`Coday run finished for thread ${this.threadId}`)}),e):(_e("THREAD_CODAY",`Instance already running for thread ${this.threadId}, skipping run()`),!1):!1}sendHeartbeat(){if(this.connections.size!==0)try{let e=new V3({});this.broadcastEvent(e)}catch(e){_e("THREAD_CODAY",`Error sending heartbeat for thread ${this.threadId}:`,e)}}broadcastEvent(e){if(!this.isReplaying&&(e instanceof sa&&e.invite!==K5||e instanceof oa)&&(this.setPendingInviteCb(this.threadId),this.projectEventManager?.broadcast(this.projectName,new Fa({threadId:this.threadId}))),!this.isReplaying&&e instanceof mr&&e.role==="assistant"){let n=e.getTextContent().trim();if(n){let i=n.split(`
|
|
1655
|
-
`).map(s=>s.trim()).filter(Boolean);(i[i.length-1]??"").includes("?")&&(this.setPendingInviteCb(this.threadId),this.projectEventManager?.broadcast(this.projectName,new Fa({threadId:this.threadId})))}}if(e instanceof Fa&&(e.name||e.summary)&&(_e("THREAD_CODAY",`Updating thread cache for ${this.threadId} name/summary`),(async()=>{try{let n=await this.threadService.getThread(this.projectName,this.threadId);if(!n)return;e.name&&(n.name=e.name),e.summary&&(n.summary=e.summary),n.messagesLength>0&&await this.threadService.updateThread(this.projectName,this.threadId,{name:e.name,summary:e.summary})}catch(n){_e("THREAD_CODAY","Error updating thread cache:",n)}})(),this.projectEventManager?.broadcast(this.projectName,e)),e instanceof sa&&e.invite!==K5||e instanceof oa){let n={...e,threadId:this.threadId};this.projectEventManager?.broadcast(this.projectName,n)}let r=`data: ${JSON.stringify(e)}
|
|
1655
|
+
`).map(s=>s.trim()).filter(Boolean);(i[i.length-1]??"").includes("?")&&(this.setPendingInviteCb(this.threadId),this.projectEventManager?.broadcast(this.projectName,new Fa({threadId:this.threadId})))}}if(e instanceof Fa&&(e.name||e.summary)&&!this.isCleaningUp&&(_e("THREAD_CODAY",`Updating thread cache for ${this.threadId} name/summary`),(async()=>{try{let n=await this.threadService.getThread(this.projectName,this.threadId);if(!n)return;e.name&&(n.name=e.name),e.summary&&(n.summary=e.summary),n.messagesLength>0&&await this.threadService.updateThread(this.projectName,this.threadId,{name:e.name,summary:e.summary})}catch(n){_e("THREAD_CODAY","Error updating thread cache:",n)}})(),this.projectEventManager?.broadcast(this.projectName,e)),e instanceof sa&&e.invite!==K5||e instanceof oa){let n={...e,threadId:this.threadId};this.projectEventManager?.broadcast(this.projectName,n)}let r=`data: ${JSON.stringify(e)}
|
|
1656
1656
|
|
|
1657
|
-
`;for(let n of this.connections)try{n.writableEnded?this.connections.delete(n):n.write(r)}catch(i){_e("THREAD_CODAY","Error broadcasting to connection:",i),this.connections.delete(n)}}stop(){this.coday?.stop()}async handleOAuthCallback(e){if(!this.coday){_e("THREAD_CODAY",`Cannot handle OAuth callback: Coday not initialized for thread ${this.threadId}`);return}if(!this.coday.services.agent){_e("THREAD_CODAY","Cannot handle OAuth callback: Agent service not initialized");return}let n=this.coday.services.agent?.toolbox;if(!n){_e("THREAD_CODAY","Cannot handle OAuth callback: Toolbox not initialized");return}_e("THREAD_CODAY",`Routing OAuth callback for ${e.integrationName}`),await n.handleOAuthCallback(e)}async cleanup(){_e("THREAD_CODAY",`Cleaning up thread ${this.threadId}`),this.inactivityTimeout&&(clearTimeout(this.inactivityTimeout),this.inactivityTimeout=void 0);for(let n of this.connections)try{n.end()}catch(i){_e("THREAD_CODAY","Error closing connection:",i)}this.connections.clear();let e,r;if(this.coday){let n=this.coday.aiThreadService;e=this.coday.context?.aiThread??n?.getCurrentThread();let i=this.coday.aiClientProvider;r=i?.getClient(void 0,"SMALL")??i?.getClient(void 0),_e("THREAD_CODAY",`Pre-kill snapshot for ${this.threadId}: thread=${!!e} (${e?.messagesLength??0} msgs), aiClient=${!!r}`)}if(this.coday){try{await this.coday.kill()}catch(n){_e("THREAD_CODAY","Error during Coday kill:",n)}this.coday=void 0}if(e&&r){let n=new GU(r,this.threadService);try{let i=Date.now();await Promise.race([n.process(e,this.projectName).then(()=>"completed"),new Promise(s=>setTimeout(()=>s("timeout"),1e4))])==="timeout"?_e("THREAD_CODAY",`Post-processing TIMED OUT for thread ${this.threadId} after 10s (thread data is safe, only name/summary may be missing)`):_e("THREAD_CODAY",`Post-processing completed for thread ${this.threadId} in ${Date.now()-i}ms`)}catch(i){_e("THREAD_CODAY",`Post-processing error for thread ${this.threadId}:`,i)}}else _e("THREAD_CODAY",`Skipping post-processing for thread ${this.threadId}: no thread or AI client`)}},JU=class t{constructor(e,r,n,i,a){this.logger=e;this.projectService=r;this.threadService=n;this.promptService=i;this.mcpPool=a;this.heartbeatInterval=setInterval(()=>this.sendHeartbeats(),t.HEARTBEAT_INTERVAL),_e("THREAD_CODAY_MANAGER","Heartbeat mechanism started"),this.projectEventManager.onNewConnection=(s,o)=>{this.replayActiveStatusForProject(s,o)},this.projectEventManager.onNewGlobalConnection=s=>{for(let o of this.instances.values()){if(!this.pendingInvites.has(o.threadId))continue;let c=o.coday?.interactor?.getLastQuestionEvent();if(c){let u={...c,threadId:o.threadId,projectName:o.projectName},f=`data: ${JSON.stringify(u)}
|
|
1657
|
+
`;for(let n of this.connections)try{n.writableEnded?this.connections.delete(n):n.write(r)}catch(i){_e("THREAD_CODAY","Error broadcasting to connection:",i),this.connections.delete(n)}}stop(){this.coday?.stop()}async handleOAuthCallback(e){if(!this.coday){_e("THREAD_CODAY",`Cannot handle OAuth callback: Coday not initialized for thread ${this.threadId}`);return}if(!this.coday.services.agent){_e("THREAD_CODAY","Cannot handle OAuth callback: Agent service not initialized");return}let n=this.coday.services.agent?.toolbox;if(!n){_e("THREAD_CODAY","Cannot handle OAuth callback: Toolbox not initialized");return}_e("THREAD_CODAY",`Routing OAuth callback for ${e.integrationName}`),await n.handleOAuthCallback(e)}async cleanup(){this.isCleaningUp=!0,_e("THREAD_CODAY",`Cleaning up thread ${this.threadId}`),this.inactivityTimeout&&(clearTimeout(this.inactivityTimeout),this.inactivityTimeout=void 0);for(let n of this.connections)try{n.end()}catch(i){_e("THREAD_CODAY","Error closing connection:",i)}this.connections.clear();let e,r;if(this.coday){let n=this.coday.aiThreadService;e=this.coday.context?.aiThread??n?.getCurrentThread();let i=this.coday.aiClientProvider;r=i?.getClient(void 0,"SMALL")??i?.getClient(void 0),_e("THREAD_CODAY",`Pre-kill snapshot for ${this.threadId}: thread=${!!e} (${e?.messagesLength??0} msgs), aiClient=${!!r}`)}if(this.coday){try{await this.coday.kill()}catch(n){_e("THREAD_CODAY","Error during Coday kill:",n)}this.coday=void 0}if(e&&r){let n=new GU(r,this.threadService);try{let i=Date.now();await Promise.race([n.process(e,this.projectName).then(()=>"completed"),new Promise(s=>setTimeout(()=>s("timeout"),1e4))])==="timeout"?_e("THREAD_CODAY",`Post-processing TIMED OUT for thread ${this.threadId} after 10s (thread data is safe, only name/summary may be missing)`):_e("THREAD_CODAY",`Post-processing completed for thread ${this.threadId} in ${Date.now()-i}ms`)}catch(i){_e("THREAD_CODAY",`Post-processing error for thread ${this.threadId}:`,i)}}else _e("THREAD_CODAY",`Skipping post-processing for thread ${this.threadId}: no thread or AI client`)}},JU=class t{constructor(e,r,n,i,a){this.logger=e;this.projectService=r;this.threadService=n;this.promptService=i;this.mcpPool=a;this.heartbeatInterval=setInterval(()=>this.sendHeartbeats(),t.HEARTBEAT_INTERVAL),_e("THREAD_CODAY_MANAGER","Heartbeat mechanism started"),this.projectEventManager.onNewConnection=(s,o)=>{this.replayActiveStatusForProject(s,o)},this.projectEventManager.onNewGlobalConnection=s=>{for(let o of this.instances.values()){if(!this.pendingInvites.has(o.threadId))continue;let c=o.coday?.interactor?.getLastQuestionEvent();if(c){let u={...c,threadId:o.threadId,projectName:o.projectName},f=`data: ${JSON.stringify(u)}
|
|
1658
1658
|
|
|
1659
1659
|
`;try{s.writableEnded||s.write(f)}catch{}}}}}instances=new Map;heartbeatInterval;projectEventManager=new VU;pendingInvites=new Set;static HEARTBEAT_INTERVAL=3e4;setPendingInvite(e){this.pendingInvites.add(e)}clearPendingInvite(e){this.pendingInvites.delete(e)}hasPendingInvite(e){return this.pendingInvites.has(e)}replayActiveStatusForProject(e,r){for(let n of this.instances.values()){if(n.projectName!==e||!this.pendingInvites.has(n.threadId))continue;let i=n.coday?.interactor?.getLastQuestionEvent();if(i){let a={...i,threadId:n.threadId},s=`data: ${JSON.stringify(a)}
|
|
1660
1660
|
|