@kelceyp/caw-server 1.0.170 → 1.0.171

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -1122,4 +1122,4 @@ Populated:
1122
1122
  Errors:
1123
1123
  `;for(let G of X.slice(0,10))P+=` - Version PK ${G.versionPk}: ${G.error}
1124
1124
  `;if(X.length>10)P+=` ... and ${X.length-10} more errors
1125
- `}return{content:[{type:"text",text:P}]}}catch(W){return i1(W)}},XT8={name:"backfill_content_refs",title:"Backfill Content Refs",description:"Backfill content reference fields (attachments, includes, hyperlinks) on existing version entities. If confirm=false, returns preview. If confirm=true, performs backfill.",schema:Dq4,execute:Rq4};var wT8=[XT8];c8();var Cq4=f.object({store:f.string().optional().describe('Store code (default: "A")'),limit:f.coerce.number().optional().describe("Maximum number of events to return (default: 50)"),offset:f.coerce.number().optional().describe("Pagination offset (default: 0)")}),Eq4=async({core:$,projectId:K},{store:q,limit:Y,offset:z})=>{try{let J=await $.listDeletedEvents(K,{store:q??"A",limit:Y??50,offset:z??0});return{content:[{type:"text",text:JSON.stringify(J,null,2)}]}}catch(J){return i1(J)}},GT8={name:"list_deleted_events",title:"List Deletion Events",description:"List deletion events grouped by timestamp. Each event represents a single delete action (e.g. deleting a folder and all its contents). Returns events with deletedAt timestamp, root entity info, item count, and days until purge.",schema:Cq4,execute:Eq4};c8();var Lq4=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/,Sq4=f.object({deleted_at:f.string().describe('Deletion event timestamp (ISO 8601, e.g. "2026-03-15T10:23:45.678Z")'),store:f.string().optional().describe('Store code (default: "A")'),limit:f.coerce.number().optional().describe("Maximum number of items to return (default: 50)"),offset:f.coerce.number().optional().describe("Pagination offset (default: 0)")}),hq4=async({core:$,projectId:K},{deleted_at:q,store:Y,limit:z,offset:J})=>{try{if(!Lq4.test(q))return{content:[{type:"text",text:JSON.stringify({error:`Invalid deleted_at timestamp: ${q}`,code:"INVALID_PARAMETER"},null,2)}],isError:!0};let W=await $.getDeletedEvent(K,{deletedAt:q,store:Y??"A",limit:z??50,offset:J??0});return{content:[{type:"text",text:JSON.stringify(W,null,2)}]}}catch(W){return i1(W)}},PT8={name:"get_deleted_event",title:"Get Deletion Event",description:"Get the items in a specific deletion event identified by its timestamp. Returns root entity info and a paginated list of all entities deleted in that event.",schema:Sq4,execute:hq4};c8();var Iq4=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/,xq4=f.object({deleted_at:f.string().describe('Deletion event timestamp (ISO 8601, e.g. "2026-03-15T10:23:45.678Z")'),store:f.string().optional().describe('Store code (default: "A")')}),gq4=async({core:$,projectId:K},{deleted_at:q,store:Y})=>{try{if(!Iq4.test(q))return{content:[{type:"text",text:JSON.stringify({error:`Invalid deleted_at timestamp: ${q}`,code:"INVALID_PARAMETER"},null,2)}],isError:!0};let z=await $.restoreDeletedEvent(K,{deletedAt:q,store:Y??"A"});return{content:[{type:"text",text:JSON.stringify(z,null,2)}]}}catch(z){return i1(z)}},TT8={name:"restore_deleted_event",title:"Restore Deletion Event",description:'Restore all entities in a deletion event (identified by its timestamp). All entities deleted in the same action are restored together. If the root entity has a name collision, it is renamed with a "-restored" suffix.',schema:xq4,execute:gq4};var vT8=[GT8,PT8,TT8];c8();var uq4=f.object({}),yq4=async({core:$,projectId:K})=>{try{let q=await $.getSystemSettings(K);return{content:[{type:"text",text:JSON.stringify(q,null,2)}]}}catch(q){return i1(q)}},AT8={name:"get_system_settings",title:"Get System Settings",description:"Returns all system settings for the project (autoArchiveDelayDays, maxConcurrentJobs, trashRetentionDays, maxResumeAttempts, defaultResumePromptRef, scratchDocDelayDays, jobDelayDays)",schema:uq4,execute:yq4};c8();var bq4=f.object({settings:Qq(f.object({autoArchiveDelayDays:f.number().int().optional(),maxConcurrentJobs:f.number().int().optional(),trashRetentionDays:f.number().int().optional(),maxResumeAttempts:f.number().int().optional(),defaultResumePromptRef:f.string().nullable().optional(),scratchDocDelayDays:f.number().int().optional(),jobDelayDays:f.number().int().optional()})).describe("Partial settings object. Only provided keys are updated.")}),Bq4=async({core:$,projectId:K},{settings:q})=>{try{let Y=await $.updateSystemSettings(K,{settings:q});return{content:[{type:"text",text:JSON.stringify(Y,null,2)}]}}catch(Y){return i1(Y)}},MT8={name:"update_system_settings",title:"Update System Settings",description:"Update system settings for the project. Accepts partial updates — only provided keys are changed. Settings: autoArchiveDelayDays, maxConcurrentJobs, trashRetentionDays, maxResumeAttempts, defaultResumePromptRef, scratchDocDelayDays, jobDelayDays. Validates values: integer fields must be positive integers; defaultResumePromptRef must be a template ID string or null (to clear).",schema:bq4,execute:Bq4};var VT8=[AT8,MT8];var mq4=jT8.default("caw:mcp"),Uq4=({core:$,projectId:K})=>{let q=new i61({name:"caw-server",version:"1.0.169"},{capabilities:{tools:{}}}),Y=[..._P8,...JP8,...TP8,...SP8,...uP8,...lP8,...rP8,...tP8,...WT8,...HT8,...wT8,...vT8,...VT8];for(let z of Y)q.registerTool(z.name,{title:z.title,description:z.description,inputSchema:z.schema},async(J,W)=>{try{let Z=W?.sessionId||W?.requestInfo?.headers?.["mcp-session-id"];return await z.execute({core:$,projectId:K,sessionId:Z,extra:W},J)}catch(Z){if(Z.isDomainError)mq4("Tool %s domain error: %o",z.name,Z);else console.error(`Tool ${z.name} failed:`,Z);return i1(Z)}});return q},NT8=Object.freeze({createMcpServer:Uq4});var Fq4=d61.default("caw:mcp"),HK=d61.default("caw:mcp:session"),pq4=({core:$})=>{let K=new Map;return Object.freeze({handleRequest:async(W,Z,{projectId:O})=>{let H=W.headers["mcp-session-id"];if(H){let T=K.get(H);if(!T)return HK("Session not found: %s",H),Z.status(404).json({jsonrpc:"2.0",error:{code:-32001,message:"Session not found. Server may have been restarted. If so, ask user to reconnect"},id:null});if(T.projectId!==O)return HK("Session %s belongs to project %s, not %s",H,T.projectId,O),Z.status(404).json({jsonrpc:"2.0",error:{code:-32001,message:"Session not found. Server may have been restarted. If so, ask user to reconnect"},id:null});HK("Routing request to existing session: %s",H),T.lastActivity=Date.now();try{return await T.transport.handleRequest(W,Z,W.body)}catch(v){console.error("MCP transport request failed:",v)}}HK("Creating new MCP session for project: %s",O);let X=null,w=new I81({sessionIdGenerator:()=>{return X=cq4(),HK("Generated session ID: %s",X),X},onsessioninitialized:(T)=>{HK("Session initialized: %s",T),Z.setHeader("Mcp-Session-Id",T),G.sessionId=T,K.set(T,G),HK("Session stored: %s",T)}});HK("Creating new server for session");let P=NT8.createMcpServer({core:$,projectId:O});try{await P.connect(w)}catch(T){return console.error("MCP server connect failed:",T),w.close?.(),P.close?.(),Z.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:"Internal server error"},id:null})}let G={sessionId:null,transport:w,server:P,projectId:O,createdAt:Date.now(),lastActivity:Date.now()};Z.on("finish",()=>{if(Z.statusCode!==200&&X&&K.has(X))HK("Request failed (status %d), cleaning up session: %s",Z.statusCode,X),K.delete(X),w.close?.(),P.close?.()});try{await w.handleRequest(W,Z,W.body)}catch(T){console.error("MCP transport request failed:",T)}},getSession:(W)=>{return K.get(W)},closeSession:(W)=>{let Z=K.get(W);if(!Z){HK("Cannot close session - not found: %s",W);return}HK("Closing session: %s",W),Z.transport.close?.(),Z.server.close?.(),K.delete(W)},cleanupIdle:(W)=>{let Z=Date.now(),O=0;for(let[H,X]of K.entries())if(Z-X.lastActivity>W)HK("Cleaning up idle session: %s (idle for %dms)",H,Z-X.lastActivity),X.transport.close?.(),X.server.close?.(),K.delete(H),O++;if(O>0)Fq4("Cleaned up %d idle sessions",O)}})},fT8=Object.freeze({create:pq4});var Qq4=86400000,lq4=300000,iq4=({mcpSessionManager:$})=>{let{jobFns:K,controlFns:q}=l7.create({name:"cleanup-idle-mcp-sessions",interval:lq4,execute:async()=>{$.cleanupIdle(Qq4)}});return{job:Object.freeze(K),control:q}},kT8=Object.freeze({create:iq4});var vu=Wv8.default("caw:server"),E04=async({port:$,envDir:K,databaseFilepath:q,assetsDir:Y,lazilyCreateDb:z,enableRest:J,enableSse:W,enableStatic:Z,enableCrons:O,enableMcp:H=!0,enableCli:X=!0,staticPath:w,kyselyFactory:P})=>{let G=await f08.create({envDir:K,databaseFilepath:q,assetsDir:Y,lazilyCreateDb:z,kyselyFactory:P}),T=O41.default();if(T.use(O41.default.json({limit:"5mb"})),T.get("/health",(N,E)=>{E.json({status:"ok"})}),T.get("/api/info",(N,E)=>{E.json({version:"1.0.169",hookFailureCount:CU1()})}),J)T.use("/api",SJ8),C08.create(T,{core:G}),S08.create(T,{core:G}),h08.create(T,{core:G}),x08.create(T,{core:G}),y08.create(T,{core:G}),m08.create(T,{core:G}),c08.create(T,{core:G}),p08.create(T,{core:G}),l08.create(T,{core:G}),TJ8.create(T,{core:G}),AJ8.create(T,{core:G}),VJ8.create(T,{core:G}),NJ8.create(T,{core:G}),DJ8.create(T,{core:G});if(W)CJ8.create(T,{core:G}),LJ8.create(T,{core:G});if(Z&&w)D08.create(T,{staticPath:w});if(H){vu("Initializing MCP subsystem...");let N=fT8.create({core:G});G.registerCronJob(kT8,{mcpSessionManager:N}),IJ8.create(T,{core:G,mcpSessionManager:N}),vu("MCP subsystem initialized")}if(X){vu("Initializing CLI Adapter subsystem...");let N=(await Promise.resolve().then(() => (dT8(),nT8))).default,E=(await Promise.resolve().then(() => (sT8(),rT8))).default,x=(await Promise.resolve().then(() => (qv8(),_v8))).default,b=(await Promise.resolve().then(() => (Jv8(),zv8))).default,S=x.create({mcpClientFactory:N.create(),aliasGenerator:E.create(),core:G});await S.init(),G.subscribeServerEvents({onProjectCreated:(I)=>S.addProject({objectId:I.id,name:I.name,path:I.path})}),b.create(T,{cliSessionManager:S}),vu("CLI Adapter subsystem initialized")}if(O)G.startAllCrons();T.use((N,E,x,b)=>{x.status(N.status||N.statusCode||500).json({error:N.message,type:N.type})});let v=null,M=new Set;return Object.freeze({app:T,core:G,start:async()=>{return new Promise((N)=>{v=T.listen($,()=>{let E=v.address().port;N(E)}),v.on("connection",(E)=>{M.add(E),E.on("close",()=>{M.delete(E)})})})},stop:async()=>{if(G.stopAllCrons(),v){for(let N of M)N.destroy();return M.clear(),new Promise((N)=>{v.close(()=>{N()})})}}})},Zv8=Object.freeze({create:E04});var S04=3131,h04=Au.join(Au.dirname(L04(import.meta.url)),"public_html"),I04=!0,x04=!0,g04=!0,u04=!0,y04=!1,b04=!0,B04=!0,m04=!0,fJ=($,K)=>$!==void 0?$==="true":K,U04=()=>{let $=process.env.CAW_ENV_DIR;if(!$)console.error("ERROR: CAW_ENV_DIR environment variable is required"),console.error("Set it to the path of your environment folder, e.g.:"),console.error(' export CAW_ENV_DIR="$HOME/.caw/dev"'),process.exit(1);return{envDir:$,databaseFilepath:Au.join($,"caw.db"),assetsDir:Au.join($,"assets")}},c04=async($)=>{let K=await Zv8.create($),q=await K.start();console.log(`Server listening on port ${q}`),process.on("SIGINT",()=>K.stop("SIGINT")),process.on("SIGTERM",()=>K.stop("SIGTERM"))},F04=()=>{let{envDir:$,databaseFilepath:K,assetsDir:q}=U04(),Y=process.env.CAW_PORT?Number(process.env.CAW_PORT):S04,z=process.env.STATIC_PATH||h04,J=fJ(process.env.LAZY_CREATE_DB,I04),W=fJ(process.env.ENABLE_REST,x04),Z=fJ(process.env.ENABLE_MCP,g04),O=fJ(process.env.ENABLE_CLI,u04),H=fJ(process.env.ENABLE_WEBLLM_WSS,y04),X=fJ(process.env.ENABLE_SSE,b04),w=fJ(process.env.ENABLE_STATIC,B04),P=fJ(process.env.ENABLE_CRONS,m04);return Object.freeze({port:Y,staticPath:z,envDir:$,databaseFilepath:K,assetsDir:q,lazilyCreateDb:J,enableRest:W,enableMcp:Z,enableCli:O,enableWebllmWss:H,enableSse:X,enableStatic:w,enableCrons:P})};await c04(F04()).catch(($)=>{console.error("ERROR: Failed to start server:",$),process.exit(1)});
1125
+ `}return{content:[{type:"text",text:P}]}}catch(W){return i1(W)}},XT8={name:"backfill_content_refs",title:"Backfill Content Refs",description:"Backfill content reference fields (attachments, includes, hyperlinks) on existing version entities. If confirm=false, returns preview. If confirm=true, performs backfill.",schema:Dq4,execute:Rq4};var wT8=[XT8];c8();var Cq4=f.object({store:f.string().optional().describe('Store code (default: "A")'),limit:f.coerce.number().optional().describe("Maximum number of events to return (default: 50)"),offset:f.coerce.number().optional().describe("Pagination offset (default: 0)")}),Eq4=async({core:$,projectId:K},{store:q,limit:Y,offset:z})=>{try{let J=await $.listDeletedEvents(K,{store:q??"A",limit:Y??50,offset:z??0});return{content:[{type:"text",text:JSON.stringify(J,null,2)}]}}catch(J){return i1(J)}},GT8={name:"list_deleted_events",title:"List Deletion Events",description:"List deletion events grouped by timestamp. Each event represents a single delete action (e.g. deleting a folder and all its contents). Returns events with deletedAt timestamp, root entity info, item count, and days until purge.",schema:Cq4,execute:Eq4};c8();var Lq4=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/,Sq4=f.object({deleted_at:f.string().describe('Deletion event timestamp (ISO 8601, e.g. "2026-03-15T10:23:45.678Z")'),store:f.string().optional().describe('Store code (default: "A")'),limit:f.coerce.number().optional().describe("Maximum number of items to return (default: 50)"),offset:f.coerce.number().optional().describe("Pagination offset (default: 0)")}),hq4=async({core:$,projectId:K},{deleted_at:q,store:Y,limit:z,offset:J})=>{try{if(!Lq4.test(q))return{content:[{type:"text",text:JSON.stringify({error:`Invalid deleted_at timestamp: ${q}`,code:"INVALID_PARAMETER"},null,2)}],isError:!0};let W=await $.getDeletedEvent(K,{deletedAt:q,store:Y??"A",limit:z??50,offset:J??0});return{content:[{type:"text",text:JSON.stringify(W,null,2)}]}}catch(W){return i1(W)}},PT8={name:"get_deleted_event",title:"Get Deletion Event",description:"Get the items in a specific deletion event identified by its timestamp. Returns root entity info and a paginated list of all entities deleted in that event.",schema:Sq4,execute:hq4};c8();var Iq4=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/,xq4=f.object({deleted_at:f.string().describe('Deletion event timestamp (ISO 8601, e.g. "2026-03-15T10:23:45.678Z")'),store:f.string().optional().describe('Store code (default: "A")')}),gq4=async({core:$,projectId:K},{deleted_at:q,store:Y})=>{try{if(!Iq4.test(q))return{content:[{type:"text",text:JSON.stringify({error:`Invalid deleted_at timestamp: ${q}`,code:"INVALID_PARAMETER"},null,2)}],isError:!0};let z=await $.restoreDeletedEvent(K,{deletedAt:q,store:Y??"A"});return{content:[{type:"text",text:JSON.stringify(z,null,2)}]}}catch(z){return i1(z)}},TT8={name:"restore_deleted_event",title:"Restore Deletion Event",description:'Restore all entities in a deletion event (identified by its timestamp). All entities deleted in the same action are restored together. If the root entity has a name collision, it is renamed with a "-restored" suffix.',schema:xq4,execute:gq4};var vT8=[GT8,PT8,TT8];c8();var uq4=f.object({}),yq4=async({core:$,projectId:K})=>{try{let q=await $.getSystemSettings(K);return{content:[{type:"text",text:JSON.stringify(q,null,2)}]}}catch(q){return i1(q)}},AT8={name:"get_system_settings",title:"Get System Settings",description:"Returns all system settings for the project (autoArchiveDelayDays, maxConcurrentJobs, trashRetentionDays, maxResumeAttempts, defaultResumePromptRef, scratchDocDelayDays, jobDelayDays)",schema:uq4,execute:yq4};c8();var bq4=f.object({settings:Qq(f.object({autoArchiveDelayDays:f.number().int().optional(),maxConcurrentJobs:f.number().int().optional(),trashRetentionDays:f.number().int().optional(),maxResumeAttempts:f.number().int().optional(),defaultResumePromptRef:f.string().nullable().optional(),scratchDocDelayDays:f.number().int().optional(),jobDelayDays:f.number().int().optional()})).describe("Partial settings object. Only provided keys are updated.")}),Bq4=async({core:$,projectId:K},{settings:q})=>{try{let Y=await $.updateSystemSettings(K,{settings:q});return{content:[{type:"text",text:JSON.stringify(Y,null,2)}]}}catch(Y){return i1(Y)}},MT8={name:"update_system_settings",title:"Update System Settings",description:"Update system settings for the project. Accepts partial updates — only provided keys are changed. Settings: autoArchiveDelayDays, maxConcurrentJobs, trashRetentionDays, maxResumeAttempts, defaultResumePromptRef, scratchDocDelayDays, jobDelayDays. Validates values: integer fields must be positive integers; defaultResumePromptRef must be a template ID string or null (to clear).",schema:bq4,execute:Bq4};var VT8=[AT8,MT8];var mq4=jT8.default("caw:mcp"),Uq4=({core:$,projectId:K})=>{let q=new i61({name:"caw-server",version:"1.0.171"},{capabilities:{tools:{}}}),Y=[..._P8,...JP8,...TP8,...SP8,...uP8,...lP8,...rP8,...tP8,...WT8,...HT8,...wT8,...vT8,...VT8];for(let z of Y)q.registerTool(z.name,{title:z.title,description:z.description,inputSchema:z.schema},async(J,W)=>{try{let Z=W?.sessionId||W?.requestInfo?.headers?.["mcp-session-id"];return await z.execute({core:$,projectId:K,sessionId:Z,extra:W},J)}catch(Z){if(Z.isDomainError)mq4("Tool %s domain error: %o",z.name,Z);else console.error(`Tool ${z.name} failed:`,Z);return i1(Z)}});return q},NT8=Object.freeze({createMcpServer:Uq4});var Fq4=d61.default("caw:mcp"),HK=d61.default("caw:mcp:session"),pq4=({core:$})=>{let K=new Map;return Object.freeze({handleRequest:async(W,Z,{projectId:O})=>{let H=W.headers["mcp-session-id"];if(H){let T=K.get(H);if(!T)return HK("Session not found: %s",H),Z.status(404).json({jsonrpc:"2.0",error:{code:-32001,message:"Session not found. Server may have been restarted. If so, ask user to reconnect"},id:null});if(T.projectId!==O)return HK("Session %s belongs to project %s, not %s",H,T.projectId,O),Z.status(404).json({jsonrpc:"2.0",error:{code:-32001,message:"Session not found. Server may have been restarted. If so, ask user to reconnect"},id:null});HK("Routing request to existing session: %s",H),T.lastActivity=Date.now();try{return await T.transport.handleRequest(W,Z,W.body)}catch(v){console.error("MCP transport request failed:",v)}}HK("Creating new MCP session for project: %s",O);let X=null,w=new I81({sessionIdGenerator:()=>{return X=cq4(),HK("Generated session ID: %s",X),X},onsessioninitialized:(T)=>{HK("Session initialized: %s",T),Z.setHeader("Mcp-Session-Id",T),G.sessionId=T,K.set(T,G),HK("Session stored: %s",T)}});HK("Creating new server for session");let P=NT8.createMcpServer({core:$,projectId:O});try{await P.connect(w)}catch(T){return console.error("MCP server connect failed:",T),w.close?.(),P.close?.(),Z.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:"Internal server error"},id:null})}let G={sessionId:null,transport:w,server:P,projectId:O,createdAt:Date.now(),lastActivity:Date.now()};Z.on("finish",()=>{if(Z.statusCode!==200&&X&&K.has(X))HK("Request failed (status %d), cleaning up session: %s",Z.statusCode,X),K.delete(X),w.close?.(),P.close?.()});try{await w.handleRequest(W,Z,W.body)}catch(T){console.error("MCP transport request failed:",T)}},getSession:(W)=>{return K.get(W)},closeSession:(W)=>{let Z=K.get(W);if(!Z){HK("Cannot close session - not found: %s",W);return}HK("Closing session: %s",W),Z.transport.close?.(),Z.server.close?.(),K.delete(W)},cleanupIdle:(W)=>{let Z=Date.now(),O=0;for(let[H,X]of K.entries())if(Z-X.lastActivity>W)HK("Cleaning up idle session: %s (idle for %dms)",H,Z-X.lastActivity),X.transport.close?.(),X.server.close?.(),K.delete(H),O++;if(O>0)Fq4("Cleaned up %d idle sessions",O)}})},fT8=Object.freeze({create:pq4});var Qq4=86400000,lq4=300000,iq4=({mcpSessionManager:$})=>{let{jobFns:K,controlFns:q}=l7.create({name:"cleanup-idle-mcp-sessions",interval:lq4,execute:async()=>{$.cleanupIdle(Qq4)}});return{job:Object.freeze(K),control:q}},kT8=Object.freeze({create:iq4});var vu=Wv8.default("caw:server"),E04=async({port:$,envDir:K,databaseFilepath:q,assetsDir:Y,lazilyCreateDb:z,enableRest:J,enableSse:W,enableStatic:Z,enableCrons:O,enableMcp:H=!0,enableCli:X=!0,staticPath:w,kyselyFactory:P})=>{let G=await f08.create({envDir:K,databaseFilepath:q,assetsDir:Y,lazilyCreateDb:z,kyselyFactory:P}),T=O41.default();if(T.use(O41.default.json({limit:"5mb"})),T.get("/health",(N,E)=>{E.json({status:"ok"})}),T.get("/api/info",(N,E)=>{E.json({version:"1.0.171",hookFailureCount:CU1()})}),J)T.use("/api",SJ8),C08.create(T,{core:G}),S08.create(T,{core:G}),h08.create(T,{core:G}),x08.create(T,{core:G}),y08.create(T,{core:G}),m08.create(T,{core:G}),c08.create(T,{core:G}),p08.create(T,{core:G}),l08.create(T,{core:G}),TJ8.create(T,{core:G}),AJ8.create(T,{core:G}),VJ8.create(T,{core:G}),NJ8.create(T,{core:G}),DJ8.create(T,{core:G});if(W)CJ8.create(T,{core:G}),LJ8.create(T,{core:G});if(Z&&w)D08.create(T,{staticPath:w});if(H){vu("Initializing MCP subsystem...");let N=fT8.create({core:G});G.registerCronJob(kT8,{mcpSessionManager:N}),IJ8.create(T,{core:G,mcpSessionManager:N}),vu("MCP subsystem initialized")}if(X){vu("Initializing CLI Adapter subsystem...");let N=(await Promise.resolve().then(() => (dT8(),nT8))).default,E=(await Promise.resolve().then(() => (sT8(),rT8))).default,x=(await Promise.resolve().then(() => (qv8(),_v8))).default,b=(await Promise.resolve().then(() => (Jv8(),zv8))).default,S=x.create({mcpClientFactory:N.create(),aliasGenerator:E.create(),core:G});await S.init(),G.subscribeServerEvents({onProjectCreated:(I)=>S.addProject({objectId:I.id,name:I.name,path:I.path})}),b.create(T,{cliSessionManager:S}),vu("CLI Adapter subsystem initialized")}if(O)G.startAllCrons();T.use((N,E,x,b)=>{x.status(N.status||N.statusCode||500).json({error:N.message,type:N.type})});let v=null,M=new Set;return Object.freeze({app:T,core:G,start:async()=>{return new Promise((N)=>{v=T.listen($,()=>{let E=v.address().port;N(E)}),v.on("connection",(E)=>{M.add(E),E.on("close",()=>{M.delete(E)})})})},stop:async()=>{if(G.stopAllCrons(),v){for(let N of M)N.destroy();return M.clear(),new Promise((N)=>{v.close(()=>{N()})})}}})},Zv8=Object.freeze({create:E04});var S04=3131,h04=Au.join(Au.dirname(L04(import.meta.url)),"public_html"),I04=!0,x04=!0,g04=!0,u04=!0,y04=!1,b04=!0,B04=!0,m04=!0,fJ=($,K)=>$!==void 0?$==="true":K,U04=()=>{let $=process.env.CAW_ENV_DIR;if(!$)console.error("ERROR: CAW_ENV_DIR environment variable is required"),console.error("Set it to the path of your environment folder, e.g.:"),console.error(' export CAW_ENV_DIR="$HOME/.caw/dev"'),process.exit(1);return{envDir:$,databaseFilepath:Au.join($,"caw.db"),assetsDir:Au.join($,"assets")}},c04=async($)=>{let K=await Zv8.create($),q=await K.start();console.log(`Server listening on port ${q}`),process.on("SIGINT",()=>K.stop("SIGINT")),process.on("SIGTERM",()=>K.stop("SIGTERM"))},F04=()=>{let{envDir:$,databaseFilepath:K,assetsDir:q}=U04(),Y=process.env.CAW_PORT?Number(process.env.CAW_PORT):S04,z=process.env.STATIC_PATH||h04,J=fJ(process.env.LAZY_CREATE_DB,I04),W=fJ(process.env.ENABLE_REST,x04),Z=fJ(process.env.ENABLE_MCP,g04),O=fJ(process.env.ENABLE_CLI,u04),H=fJ(process.env.ENABLE_WEBLLM_WSS,y04),X=fJ(process.env.ENABLE_SSE,b04),w=fJ(process.env.ENABLE_STATIC,B04),P=fJ(process.env.ENABLE_CRONS,m04);return Object.freeze({port:Y,staticPath:z,envDir:$,databaseFilepath:K,assetsDir:q,lazilyCreateDb:J,enableRest:W,enableMcp:Z,enableCli:O,enableWebllmWss:H,enableSse:X,enableStatic:w,enableCrons:P})};await c04(F04()).catch(($)=>{console.error("ERROR: Failed to start server:",$),process.exit(1)});