@kelceyp/caw-server 1.0.88 → 1.0.89
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 +1 -1
- package/dist/public_html/main.js +396 -396
- package/dist/public_html/styles.css +1 -1
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -760,4 +760,4 @@ ID Remapping (${W} IDs):
|
|
|
760
760
|
`}return{content:[{type:"text",text:z}]}}catch(J){return{content:[{type:"text",text:`Error: ${J.message}`}],isError:!0}}},y46={name:"import_documents",title:"Import Documents",description:"Import documents and templates from .caw-exports/. Store must be empty.",schema:lg1,execute:ig1};var b46=[I46,x46,g46,y46];P6();var dg1=V.object({name:V.string().describe("Story name"),store:V.string().optional().describe('Store code (default: "A")'),state:V.string().optional().describe("Initial state (default: first state in workflow)"),workflow:V.string().optional().describe('Workflow name (default: "Default")')}),ng1=async({core:$,projectId:K},{name:Y,store:q,state:J,workflow:z})=>{try{let W=await $.createStory(K,{name:Y,store:q||"A",state:J,workflow:z});return{content:[{type:"text",text:`Created story: ${W.id} (name: ${W.name}, state: ${W.fields.state}, workflow: ${W.fields.workflow})`}]}}catch(W){return{content:[{type:"text",text:`Error: ${W.message}`}],isError:!0}}},u46={name:"create_story",title:"Create Story",description:"Create a new story",schema:dg1,execute:ng1};P6();var ag1=V.object({store:V.string().optional().describe('Store code (default: "A")')}),og1=async({core:$,projectId:K},{store:Y})=>{try{let q=await $.listStories(K,{store:Y||"A"});return{content:[{type:"text",text:JSON.stringify(q,null,2)}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},m46={name:"list_stories",title:"List Stories",description:"List all stories",schema:ag1,execute:og1};P6();var rg1=V.object({id:V.string().describe('Story ID (e.g., "As1")')}),sg1=async({core:$,projectId:K},{id:Y})=>{try{let q=await $.getStory(K,{id:Y});return{content:[{type:"text",text:JSON.stringify(q,null,2)}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},B46={name:"get_story",title:"Get Story",description:"Get story details",schema:rg1,execute:sg1};P6();var tg1=V.object({id:V.string().describe('Story ID (e.g., "As1")'),state:V.string().describe("New state value")}),eg1=async({core:$,projectId:K},{id:Y,state:q})=>{try{let J=await $.updateStoryState(K,{id:Y,state:q});return{content:[{type:"text",text:`Updated story ${J.id} state to: ${J.fields.state}`}]}}catch(J){return{content:[{type:"text",text:`Error: ${J.message}`}],isError:!0}}},U46={name:"update_story_state",title:"Update Story State",description:"Update story state",schema:tg1,execute:eg1};P6();var $y1=V.object({id:V.string().describe('Story ID (e.g., "As1")'),confirm:V.boolean().optional().describe("Set to true to confirm deletion. If false or omitted, returns impact preview.")}),Ky1=async({core:$,projectId:K},{id:Y,confirm:q})=>{try{if(!q){let z=await $.getStory(K,{id:Y});return{content:[{type:"text",text:`This will delete story: ${z.id} (${z.name})
|
|
761
761
|
State: ${z.fields.state}
|
|
762
762
|
|
|
763
|
-
To confirm, call delete_story with confirm=true`}]}}let J=await $.deleteStory(K,{id:Y});return{content:[{type:"text",text:`Deleted story: ${J.id} (${J.descendantCount} descendants also deleted)`}]}}catch(J){return{content:[{type:"text",text:`Error: ${J.message}`}],isError:!0}}},F46={name:"delete_story",title:"Delete Story",description:"Soft delete a story (can be restored later). If confirm is false or omitted, returns impact preview.",schema:$y1,execute:Ky1};P6();var Yy1=V.object({id:V.string().describe('Story ID (e.g., "As1")')}),qy1=async({core:$,projectId:K},{id:Y})=>{try{let q=await $.incrementStoryJobCount(K,{id:Y});if(!q)return{content:[{type:"text",text:`Story ${Y} not found`}],isError:!0};return{content:[{type:"text",text:`Incremented activeJobCount for story ${q.id} to: ${q.fields.activeJobCount}`}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},Q46={name:"increment_story_job_count",title:"Increment Story Job Count",description:"Increment a story's activeJobCount field (for manual tracking of agent activity)",schema:Yy1,execute:qy1};P6();var Jy1=V.object({id:V.string().describe('Story ID (e.g., "As1")')}),zy1=async({core:$,projectId:K},{id:Y})=>{try{let q=await $.decrementStoryJobCount(K,{id:Y});if(!q)return{content:[{type:"text",text:`Story ${Y} not found`}],isError:!0};return{content:[{type:"text",text:`Decremented activeJobCount for story ${q.id} to: ${q.fields.activeJobCount}`}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},p46={name:"decrement_story_job_count",title:"Decrement Story Job Count",description:"Decrement a story's activeJobCount field (for manual tracking of agent activity). Guards against going below zero.",schema:Jy1,execute:zy1};var c46=[u46,m46,B46,U46,F46,Q46,p46];P6();var Wy1=V.object({name:V.string().describe("Workflow name (must be unique in store)"),states:V.array(V.string()).min(1).describe("Ordered list of state names"),store:V.string().optional().describe('Store code (default: "A")')}),Zy1=async({core:$,projectId:K},{name:Y,states:q,store:J})=>{try{let z=await $.createWorkflow(K,{name:Y,states:q,store:J||"A"});return{content:[{type:"text",text:`Created workflow: ${z.id} (name: ${z.name}, states: [${z.fields.states.join(", ")}])`}]}}catch(z){return{content:[{type:"text",text:`Error: ${z.message}`}],isError:!0}}},l46={name:"create_workflow",title:"Create Workflow",description:"Create a new workflow with name and states array",schema:Wy1,execute:Zy1};P6();var Hy1=V.object({store:V.string().optional().describe('Store code (default: "A")')}),Xy1=async({core:$,projectId:K},{store:Y})=>{try{let q=await $.listWorkflows(K,{store:Y||"A"});return{content:[{type:"text",text:JSON.stringify(q,null,2)}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},i46={name:"list_workflows",title:"List Workflows",description:"List all workflows in a store",schema:Hy1,execute:Xy1};P6();var Oy1=V.object({name:V.string().optional().describe("Workflow name"),id:V.string().optional().describe('Workflow ID (e.g., "Ad123")'),store:V.string().optional().describe('Store code (default: "A", required if using name)')}).refine(($)=>$.name||$.id,{message:"Either name or id is required"}),Py1=async({core:$,projectId:K},{name:Y,id:q,store:J})=>{try{let z=await $.getWorkflow(K,{name:Y,id:q,store:J||"A"});if(!z)return{content:[{type:"text",text:"Workflow not found"}],isError:!0};return{content:[{type:"text",text:JSON.stringify(z,null,2)}]}}catch(z){return{content:[{type:"text",text:`Error: ${z.message}`}],isError:!0}}},d46={name:"get_workflow",title:"Get Workflow",description:"Get workflow by name or ID",schema:Oy1,execute:Py1};P6();var wy1=V.object({id:V.string().describe('Workflow ID (e.g., "Ad123")'),name:V.string().optional().describe("New workflow name"),states:V.array(V.string()).min(1).optional().describe("New ordered list of state names")}).refine(($)=>$.name||$.states,{message:"At least one of name or states is required"}),Gy1=async({core:$,projectId:K},{id:Y,name:q,states:J})=>{try{let z=await $.updateWorkflow(K,{id:Y,name:q,states:J});return{content:[{type:"text",text:`Updated workflow: ${z.id} (name: ${z.name}, states: [${z.fields.states.join(", ")}])`}]}}catch(z){return{content:[{type:"text",text:`Error: ${z.message}`}],isError:!0}}},n46={name:"update_workflow",title:"Update Workflow",description:"Update workflow name and/or states",schema:wy1,execute:Gy1};P6();var Ty1=V.object({id:V.string().describe('Workflow ID (e.g., "Ad123")')}),jy1=async({core:$,projectId:K},{id:Y})=>{try{return{content:[{type:"text",text:`Deleted workflow: ${(await $.deleteWorkflow(K,{id:Y})).id}`}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},a46={name:"delete_workflow",title:"Delete Workflow",description:"Delete a workflow (fails if stories are assigned to it)",schema:Ty1,execute:jy1};var o46=[l46,i46,d46,n46,a46];P6();var vy1=V.object({id:V.string().describe('Asset ID (e.g., "Aa1")')}),Vy1=async({core:$,projectId:K},{id:Y})=>{try{let{buffer:q,mimeType:J,sizeBytes:z,hash:W,originalFilename:Z}=await $.readAssetBinary(K,{id:Y});return{content:[{type:"image",data:q.toString("base64"),mimeType:J},{type:"text",text:JSON.stringify({id:Y,originalFilename:Z,sizeBytes:z,hash:W},null,2)}]}}catch(q){return{content:[{type:"text",text:q.code==="ASSET_NOT_FOUND"||q.code==="BLOB_NOT_FOUND"?q.message:`Error: ${q.message}`}],isError:!0}}},r46={name:"read_asset",title:"Read Asset",description:"Read an asset image by ID. Returns the image as base64-encoded data that Claude can view. Supported formats: PNG, JPEG, GIF, WebP. Maximum size: 10MB.",schema:vy1,execute:Vy1};var s46=[r46];P6();var Ay1=V.object({store:V.string().optional().describe('Store code (default: "A")'),status:V.string().optional().describe("Filter by status (pending, running, completed, error, stopped)")}),My1=async({core:$,projectId:K},{store:Y,status:q})=>{try{let J=await $.listJobs(K,{store:Y||"A",status:q});return{content:[{type:"text",text:JSON.stringify(J,null,2)}]}}catch(J){return{content:[{type:"text",text:`Error: ${J.message}`}],isError:!0}}},t46={name:"list_jobs",title:"List Jobs",description:"List all jobs",schema:Ay1,execute:My1};P6();var _y1=V.object({id:V.string().describe('Job ID (e.g., "Aj1")')}),ky1=async({core:$,projectId:K},{id:Y})=>{try{let q=await $.getJob(K,{id:Y});return{content:[{type:"text",text:JSON.stringify(q,null,2)}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},e46={name:"read_job",title:"Read Job",description:"Get job details",schema:_y1,execute:ky1};P6();var Ny1=V.object({id:V.string().describe('Job ID (e.g., "Aj1")')}),fy1=async({core:$,projectId:K},{id:Y})=>{try{return{content:[{type:"text",text:await $.readJobOutput(K,{id:Y})}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},$$6={name:"read_job_output",title:"Read Job Output",description:"Read the output content from a job",schema:Ny1,execute:fy1};P6();var Ry1=V.object({id:V.string().describe('Job ID (e.g., "Aj1")')}),Cy1=async({core:$,projectId:K},{id:Y})=>{try{return{content:[{type:"text",text:await $.readJobPrompt(K,{id:Y})}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},K$6={name:"read_job_prompt",title:"Read Job Prompt",description:"Read the prompt content from a job",schema:Ry1,execute:Cy1};P6();var Ws=4,QE=2000,pE=3600000;async function Y$6($,K){let Y=0,q=K;q=(await $.core.getJob($.projectId,{id:q})).fields?.parentJobId;while(q)Y++,q=(await $.core.getJob($.projectId,{id:q})).fields?.parentJobId;return Y}async function cE($,K,{intervalMs:Y,timeoutMs:q}){let J=Date.now(),z=["completed","error","stopped"];while(!0){let W=await $.core.getJob($.projectId,{id:K});if(z.includes(W.fields?.status))return W;if(Date.now()-J>q)throw Error(`Job ${K} did not complete within timeout (${q/60000} minutes)`);await new Promise((Z)=>setTimeout(Z,Y))}}var Dy1=V.object({agent:V.enum(["claude","codex"]).describe("Agent type (claude or codex)"),prompt:V.string().describe("Prompt content"),name:V.string().optional().describe("Job name (auto-generated if omitted)"),model:V.string().optional().describe("Model for Claude agent"),workingDirectory:V.string().optional().describe("Working directory"),objectId:V.string().optional().describe("ID of entity to associate with"),streaming:V.boolean().optional().describe("Enable streaming output"),skipPermissions:V.boolean().optional().describe("Skip permission prompts (default: true). Set to false to enable permission prompts."),parentJobId:V.string().optional().describe("Parent job ID for hierarchy tracking"),blocking:V.boolean().optional().describe("Wait for job completion with 60-minute timeout (default: true). Set to false for asynchronous operation."),dockerImage:V.string().optional().describe("Docker image for containerized execution"),store:V.string().optional().describe('Store code (default: "A")')}),hy1=async({core:$,projectId:K},Y)=>{try{let{blocking:q,parentJobId:J,store:z="A",...W}=Y;if(J){let P=await Y$6({core:$,projectId:K},J);if(P>=Ws)throw Error(`Job depth limit exceeded (max ${Ws}, parent depth: ${P})`)}let Z=await $.createJob(K,{...W,store:z,parentJobId:J,blocking:q??!0});if(q===!1)return{content:[{type:"text",text:JSON.stringify(Z,null,2)}]};let H=await cE({core:$,projectId:K},Z.id,{intervalMs:QE,timeoutMs:pE}),X=await $.readJobOutput(K,{id:Z.id}),O={...H,output:X};return{content:[{type:"text",text:JSON.stringify(O,null,2)}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},q$6={name:"create_job",title:"Create Job",description:"Create and execute a job. Set blocking=true to wait for completion and return output directly (60-minute timeout). When parentJobId is provided, depth validation ensures jobs do not exceed depth limit of 4.",schema:Dy1,execute:hy1};P6();var Ly1=V.object({id:V.string().describe('Job ID to continue (e.g., "Aj1")'),prompt:V.string().describe("Follow-up prompt"),model:V.string().optional().describe("Model (allows changing between turns)"),dockerImage:V.string().optional().describe("Docker image for containerized execution"),skipPermissions:V.boolean().optional().describe("Skip permission prompts (Claude agent only)"),blocking:V.boolean().optional().describe("Wait for job completion with 60-minute timeout (default: true). Set to false for asynchronous operation.")}),Ey1=async({core:$,projectId:K},Y)=>{try{let{id:q,prompt:J,model:z,dockerImage:W,skipPermissions:Z,blocking:H}=Y,X=await $.continueJob(K,{id:q,prompt:J,model:z,dockerImage:W,skipPermissions:Z});if(H===!1)return{content:[{type:"text",text:JSON.stringify(X,null,2)}]};let O=await cE({core:$,projectId:K},X.id,{intervalMs:QE,timeoutMs:pE}),P=await $.readJobOutput(K,{id:X.id}),w={...O,output:P};return{content:[{type:"text",text:JSON.stringify(w,null,2)}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},J$6={name:"continue_job",title:"Continue Job",description:"Continue a completed or errored job with a follow-up prompt. Set blocking=true to wait for completion and return output directly (60-minute timeout).",schema:Ly1,execute:Ey1};var z$6=[t46,e46,$$6,K$6,q$6,J$6];P6();t6();var Sy1=V.object({query:V.string().describe("FTS5 search query"),field_name:V.string().optional().describe("Filter by field definition name"),store:V.string().optional().describe('Store code (default: "A")')}),Iy1=async({core:$,projectId:K},{query:Y,field_name:q,store:J})=>{try{let z=await $.searchTextFields(K,{query:Y,fieldName:q,store:J||"A"});return{content:[{type:"text",text:JSON.stringify(z,null,2)}]}}catch(z){if(z.message?.includes("fts5: syntax error"))return{content:[{type:"text",text:`Error: ${E.validation('Invalid FTS5 query syntax. Valid syntax includes: simple terms (hello world), phrases ("hello world"), boolean (hello OR world), prefix (hel*), negation (hello NOT world)',"INVALID_FTS5_QUERY").message}`}],isError:!0};return{content:[{type:"text",text:`Error: ${z.message}`}],isError:!0}}},W$6={name:"search_text_fields",title:"Search Text Fields",description:"Search text field content using FTS5 full-text search. Returns matching entity IDs, field names, and BM25 relevance ranking. Supports store:X filter to override store parameter.",schema:Sy1,execute:Iy1};P6();t6();var xy1=V.object({query:V.string().describe("FTS5 search query"),store:V.string().optional().describe('Store code (default: "A")'),limit:V.number().int().positive().optional().describe("Maximum results (default: 20)"),offset:V.number().int().min(0).optional().describe("Pagination offset (default: 0)"),start_marker:V.string().optional().describe('Snippet highlight start marker (default: "<mark>")'),end_marker:V.string().optional().describe('Snippet highlight end marker (default: "</mark>")')}),gy1=async({core:$,projectId:K},{query:Y,store:q,limit:J,offset:z,start_marker:W,end_marker:Z})=>{try{let H=await $.searchContent(K,{query:Y,store:q||"A",limit:J??20,offset:z??0,startMarker:W??"<mark>",endMarker:Z??"</mark>"});return{content:[{type:"text",text:JSON.stringify(H,null,2)}]}}catch(H){if(H.message?.includes("fts5: syntax error"))return{content:[{type:"text",text:`Error: ${E.validation('Invalid FTS5 query syntax. Valid syntax includes: simple terms (hello world), phrases ("hello world"), boolean (hello OR world), prefix (hel*), negation (hello NOT world)',"INVALID_FTS5_QUERY").message}`}],isError:!0};return{content:[{type:"text",text:`Error: ${H.message}`}],isError:!0}}},Z$6={name:"search",title:"Search Document Content",description:'Search document content using FTS5 full-text search. Returns matching documents with entity IDs, paths, names, BM25 relevance scores, and content snippets. Response includes debug.strategy field indicating execution path: "fts-first" (FTS query with optional filters) or "filters-only" (no FTS, filters applied directly). Query syntax: simple terms (hello), phrases ("hello world"), boolean (hello OR world), prefix (auth*), negation (hello NOT world). Filters: type:document, type:template, type:d/task, store:X (overrides store parameter), fieldName:value (string field equality). For multi-value fields, matches if ANY value equals the filter (contains semantics).',schema:xy1,execute:gy1};var H$6=[W$6,Z$6];var yy1=({core:$,projectId:K})=>{let Y=new zs({name:"caw-server",version:"0.0.1"},{capabilities:{tools:{}}}),q=[...Z46,...P46,...M46,...S46,...b46,...c46,...o46,...s46,...z$6,...H$6];for(let J of q)Y.registerTool(J.name,{title:J.title,description:J.description,inputSchema:J.schema},async(z,W)=>{try{let Z=W?.sessionId||W?.requestInfo?.headers?.["mcp-session-id"];return await J.execute({core:$,projectId:K,sessionId:Z},z)}catch(Z){return console.error(`Tool ${J.name} failed:`,Z),{content:[{type:"text",text:`Tool execution failed: ${Z.message}`}],isError:!0}}});return Y},X$6=Object.freeze({createMcpServer:yy1});var uy1=Zs.default("caw:mcp"),b5=Zs.default("caw:mcp:session"),my1=({core:$})=>{let K=new Map;return Object.freeze({handleRequest:async(W,Z,{projectId:H})=>{let X=W.headers["mcp-session-id"];if(X){let j=K.get(X);if(!j)return b5("Session not found: %s",X),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(j.projectId!==H)return b5("Session %s belongs to project %s, not %s",X,j.projectId,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});b5("Routing request to existing session: %s",X),j.lastActivity=Date.now();try{return await j.transport.handleRequest(W,Z,W.body)}catch(T){console.error("MCP transport request failed:",T)}}b5("Creating new MCP session for project: %s",H);let O=null,P=new lo({sessionIdGenerator:()=>{return O=by1(),b5("Generated session ID: %s",O),O},onsessioninitialized:(j)=>{b5("Session initialized: %s",j),Z.setHeader("Mcp-Session-Id",j),G.sessionId=j,K.set(j,G),b5("Session stored: %s",j)}});b5("Creating new server for session");let w=X$6.createMcpServer({core:$,projectId:H});try{await w.connect(P)}catch(j){return console.error("MCP server connect failed:",j),P.close?.(),w.close?.(),Z.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:"Internal server error"},id:null})}let G={sessionId:null,transport:P,server:w,projectId:H,createdAt:Date.now(),lastActivity:Date.now()};Z.on("finish",()=>{if(Z.statusCode!==200&&O&&K.has(O))b5("Request failed (status %d), cleaning up session: %s",Z.statusCode,O),K.delete(O),P.close?.(),w.close?.()});try{await P.handleRequest(W,Z,W.body)}catch(j){console.error("MCP transport request failed:",j)}},getSession:(W)=>{return K.get(W)},closeSession:(W)=>{let Z=K.get(W);if(!Z){b5("Cannot close session - not found: %s",W);return}b5("Closing session: %s",W),Z.transport.close?.(),Z.server.close?.(),K.delete(W)},cleanupIdle:(W)=>{let Z=Date.now(),H=0;for(let[X,O]of K.entries())if(Z-O.lastActivity>W)b5("Cleaning up idle session: %s (idle for %dms)",X,Z-O.lastActivity),O.transport.close?.(),O.server.close?.(),K.delete(X),H++;if(H>0)uy1("Cleaned up %d idle sessions",H)}})},O$6=Object.freeze({create:my1});var By1=86400000,Uy1=300000,Fy1=({mcpSessionManager:$})=>{let{jobFns:K,controlFns:Y}=hD.create({name:"cleanup-idle-mcp-sessions",interval:Uy1,execute:async()=>{$.cleanupIdle(By1)}});return{job:Object.freeze(K),control:Y}},P$6=Object.freeze({create:Fy1});var zS=o$6.default("caw:server"),Nb1=async({port:$,envDir:K,databaseFilepath:Y,assetsDir:q,lazilyCreateDb:J,enableRest:z,enableSse:W,enableStatic:Z,enableCrons:H,enableMcp:X=!0,enableCli:O=!0,staticPath:P,kyselyFactory:w})=>{let G=await gd8.create({envDir:K,databaseFilepath:Y,assetsDir:q,lazilyCreateDb:J,kyselyFactory:w}),j=fs.default();if(j.use(fs.default.json()),j.get("/health",(A,N)=>{N.json({status:"ok"})}),j.get("/api/info",(A,N)=>{N.json({version:"1.0.88"})}),z)j.use("/api",go8),md8.create(j,{core:G}),Fd8.create(j,{core:G}),Qd8.create(j,{core:G}),cd8.create(j,{core:G}),id8.create(j,{core:G}),nd8.create(j,{core:G}),od8.create(j,{core:G}),sd8.create(j,{core:G}),No8.create(j,{core:G}),Ro8.create(j,{core:G}),Do8.create(j,{core:G}),Lo8.create(j,{core:G});if(W)So8.create(j,{core:G}),xo8.create(j,{core:G});if(Z&&P)bd8.create(j,{staticPath:P});if(X){zS("Initializing MCP subsystem...");let A=O$6.create({core:G});G.registerCronJob(P$6,{mcpSessionManager:A}),bo8.create(j,{core:G,mcpSessionManager:A}),zS("MCP subsystem initialized")}if(O){zS("Initializing CLI Adapter subsystem...");let A=(await Promise.resolve().then(() => (b$6(),y$6))).default,N=(await Promise.resolve().then(() => (U$6(),B$6))).default,C=(await Promise.resolve().then(() => (i$6(),l$6))).default,I=(await Promise.resolve().then(() => (a$6(),n$6))).default,D=C.create({mcpClientFactory:A.create(),aliasGenerator:N.create(),core:G});await D.init(),G.subscribeServerEvents({onProjectCreated:(x)=>D.addProject({objectId:x.id,name:x.name,path:x.path})}),I.create(j,{cliSessionManager:D}),zS("CLI Adapter subsystem initialized")}if(H)G.startAllCrons();let T=null,v=new Set;return Object.freeze({app:j,core:G,start:async()=>{return new Promise((A)=>{T=j.listen($,()=>{let N=T.address().port;A(N)}),T.on("connection",(N)=>{v.add(N),N.on("close",()=>{v.delete(N)})})})},stop:async()=>{if(G.stopAllCrons(),T){for(let A of v)A.destroy();return v.clear(),new Promise((A)=>{T.close(()=>{A()})})}}})},r$6=Object.freeze({create:Nb1});var Rb1=3131,Cb1=WS.join(WS.dirname(fb1(import.meta.url)),"public_html"),Db1=!0,hb1=!0,Lb1=!0,Eb1=!0,Sb1=!1,Ib1=!0,xb1=!0,gb1=!0,wz=($,K)=>$!==void 0?$==="true":K,yb1=()=>{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:WS.join($,"caw.db"),assetsDir:WS.join($,"assets")}},bb1=async($)=>{let K=await r$6.create($),Y=await K.start();console.log(`Server listening on port ${Y}`),process.on("SIGINT",()=>K.stop("SIGINT")),process.on("SIGTERM",()=>K.stop("SIGTERM"))},ub1=()=>{let{envDir:$,databaseFilepath:K,assetsDir:Y}=yb1(),q=process.env.CAW_PORT?Number(process.env.CAW_PORT):Rb1,J=process.env.STATIC_PATH||Cb1,z=wz(process.env.LAZY_CREATE_DB,Db1),W=wz(process.env.ENABLE_REST,hb1),Z=wz(process.env.ENABLE_MCP,Lb1),H=wz(process.env.ENABLE_CLI,Eb1),X=wz(process.env.ENABLE_WEBLLM_WSS,Sb1),O=wz(process.env.ENABLE_SSE,Ib1),P=wz(process.env.ENABLE_STATIC,xb1),w=wz(process.env.ENABLE_CRONS,gb1);return Object.freeze({port:q,staticPath:J,envDir:$,databaseFilepath:K,assetsDir:Y,lazilyCreateDb:z,enableRest:W,enableMcp:Z,enableCli:H,enableWebllmWss:X,enableSse:O,enableStatic:P,enableCrons:w})};await bb1(ub1()).catch(($)=>{console.error("ERROR: Failed to start server:",$),process.exit(1)});
|
|
763
|
+
To confirm, call delete_story with confirm=true`}]}}let J=await $.deleteStory(K,{id:Y});return{content:[{type:"text",text:`Deleted story: ${J.id} (${J.descendantCount} descendants also deleted)`}]}}catch(J){return{content:[{type:"text",text:`Error: ${J.message}`}],isError:!0}}},F46={name:"delete_story",title:"Delete Story",description:"Soft delete a story (can be restored later). If confirm is false or omitted, returns impact preview.",schema:$y1,execute:Ky1};P6();var Yy1=V.object({id:V.string().describe('Story ID (e.g., "As1")')}),qy1=async({core:$,projectId:K},{id:Y})=>{try{let q=await $.incrementStoryJobCount(K,{id:Y});if(!q)return{content:[{type:"text",text:`Story ${Y} not found`}],isError:!0};return{content:[{type:"text",text:`Incremented activeJobCount for story ${q.id} to: ${q.fields.activeJobCount}`}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},Q46={name:"increment_story_job_count",title:"Increment Story Job Count",description:"Increment a story's activeJobCount field (for manual tracking of agent activity)",schema:Yy1,execute:qy1};P6();var Jy1=V.object({id:V.string().describe('Story ID (e.g., "As1")')}),zy1=async({core:$,projectId:K},{id:Y})=>{try{let q=await $.decrementStoryJobCount(K,{id:Y});if(!q)return{content:[{type:"text",text:`Story ${Y} not found`}],isError:!0};return{content:[{type:"text",text:`Decremented activeJobCount for story ${q.id} to: ${q.fields.activeJobCount}`}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},p46={name:"decrement_story_job_count",title:"Decrement Story Job Count",description:"Decrement a story's activeJobCount field (for manual tracking of agent activity). Guards against going below zero.",schema:Jy1,execute:zy1};var c46=[u46,m46,B46,U46,F46,Q46,p46];P6();var Wy1=V.object({name:V.string().describe("Workflow name (must be unique in store)"),states:V.array(V.string()).min(1).describe("Ordered list of state names"),store:V.string().optional().describe('Store code (default: "A")')}),Zy1=async({core:$,projectId:K},{name:Y,states:q,store:J})=>{try{let z=await $.createWorkflow(K,{name:Y,states:q,store:J||"A"});return{content:[{type:"text",text:`Created workflow: ${z.id} (name: ${z.name}, states: [${z.fields.states.join(", ")}])`}]}}catch(z){return{content:[{type:"text",text:`Error: ${z.message}`}],isError:!0}}},l46={name:"create_workflow",title:"Create Workflow",description:"Create a new workflow with name and states array",schema:Wy1,execute:Zy1};P6();var Hy1=V.object({store:V.string().optional().describe('Store code (default: "A")')}),Xy1=async({core:$,projectId:K},{store:Y})=>{try{let q=await $.listWorkflows(K,{store:Y||"A"});return{content:[{type:"text",text:JSON.stringify(q,null,2)}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},i46={name:"list_workflows",title:"List Workflows",description:"List all workflows in a store",schema:Hy1,execute:Xy1};P6();var Oy1=V.object({name:V.string().optional().describe("Workflow name"),id:V.string().optional().describe('Workflow ID (e.g., "Ad123")'),store:V.string().optional().describe('Store code (default: "A", required if using name)')}).refine(($)=>$.name||$.id,{message:"Either name or id is required"}),Py1=async({core:$,projectId:K},{name:Y,id:q,store:J})=>{try{let z=await $.getWorkflow(K,{name:Y,id:q,store:J||"A"});if(!z)return{content:[{type:"text",text:"Workflow not found"}],isError:!0};return{content:[{type:"text",text:JSON.stringify(z,null,2)}]}}catch(z){return{content:[{type:"text",text:`Error: ${z.message}`}],isError:!0}}},d46={name:"get_workflow",title:"Get Workflow",description:"Get workflow by name or ID",schema:Oy1,execute:Py1};P6();var wy1=V.object({id:V.string().describe('Workflow ID (e.g., "Ad123")'),name:V.string().optional().describe("New workflow name"),states:V.array(V.string()).min(1).optional().describe("New ordered list of state names")}).refine(($)=>$.name||$.states,{message:"At least one of name or states is required"}),Gy1=async({core:$,projectId:K},{id:Y,name:q,states:J})=>{try{let z=await $.updateWorkflow(K,{id:Y,name:q,states:J});return{content:[{type:"text",text:`Updated workflow: ${z.id} (name: ${z.name}, states: [${z.fields.states.join(", ")}])`}]}}catch(z){return{content:[{type:"text",text:`Error: ${z.message}`}],isError:!0}}},n46={name:"update_workflow",title:"Update Workflow",description:"Update workflow name and/or states",schema:wy1,execute:Gy1};P6();var Ty1=V.object({id:V.string().describe('Workflow ID (e.g., "Ad123")')}),jy1=async({core:$,projectId:K},{id:Y})=>{try{return{content:[{type:"text",text:`Deleted workflow: ${(await $.deleteWorkflow(K,{id:Y})).id}`}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},a46={name:"delete_workflow",title:"Delete Workflow",description:"Delete a workflow (fails if stories are assigned to it)",schema:Ty1,execute:jy1};var o46=[l46,i46,d46,n46,a46];P6();var vy1=V.object({id:V.string().describe('Asset ID (e.g., "Aa1")')}),Vy1=async({core:$,projectId:K},{id:Y})=>{try{let{buffer:q,mimeType:J,sizeBytes:z,hash:W,originalFilename:Z}=await $.readAssetBinary(K,{id:Y});return{content:[{type:"image",data:q.toString("base64"),mimeType:J},{type:"text",text:JSON.stringify({id:Y,originalFilename:Z,sizeBytes:z,hash:W},null,2)}]}}catch(q){return{content:[{type:"text",text:q.code==="ASSET_NOT_FOUND"||q.code==="BLOB_NOT_FOUND"?q.message:`Error: ${q.message}`}],isError:!0}}},r46={name:"read_asset",title:"Read Asset",description:"Read an asset image by ID. Returns the image as base64-encoded data that Claude can view. Supported formats: PNG, JPEG, GIF, WebP. Maximum size: 10MB.",schema:vy1,execute:Vy1};var s46=[r46];P6();var Ay1=V.object({store:V.string().optional().describe('Store code (default: "A")'),status:V.string().optional().describe("Filter by status (pending, running, completed, error, stopped)")}),My1=async({core:$,projectId:K},{store:Y,status:q})=>{try{let J=await $.listJobs(K,{store:Y||"A",status:q});return{content:[{type:"text",text:JSON.stringify(J,null,2)}]}}catch(J){return{content:[{type:"text",text:`Error: ${J.message}`}],isError:!0}}},t46={name:"list_jobs",title:"List Jobs",description:"List all jobs",schema:Ay1,execute:My1};P6();var _y1=V.object({id:V.string().describe('Job ID (e.g., "Aj1")')}),ky1=async({core:$,projectId:K},{id:Y})=>{try{let q=await $.getJob(K,{id:Y});return{content:[{type:"text",text:JSON.stringify(q,null,2)}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},e46={name:"read_job",title:"Read Job",description:"Get job details",schema:_y1,execute:ky1};P6();var Ny1=V.object({id:V.string().describe('Job ID (e.g., "Aj1")')}),fy1=async({core:$,projectId:K},{id:Y})=>{try{return{content:[{type:"text",text:await $.readJobOutput(K,{id:Y})}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},$$6={name:"read_job_output",title:"Read Job Output",description:"Read the output content from a job",schema:Ny1,execute:fy1};P6();var Ry1=V.object({id:V.string().describe('Job ID (e.g., "Aj1")')}),Cy1=async({core:$,projectId:K},{id:Y})=>{try{return{content:[{type:"text",text:await $.readJobPrompt(K,{id:Y})}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},K$6={name:"read_job_prompt",title:"Read Job Prompt",description:"Read the prompt content from a job",schema:Ry1,execute:Cy1};P6();var Ws=4,QE=2000,pE=3600000;async function Y$6($,K){let Y=0,q=K;q=(await $.core.getJob($.projectId,{id:q})).fields?.parentJobId;while(q)Y++,q=(await $.core.getJob($.projectId,{id:q})).fields?.parentJobId;return Y}async function cE($,K,{intervalMs:Y,timeoutMs:q}){let J=Date.now(),z=["completed","error","stopped"];while(!0){let W=await $.core.getJob($.projectId,{id:K});if(z.includes(W.fields?.status))return W;if(Date.now()-J>q)throw Error(`Job ${K} did not complete within timeout (${q/60000} minutes)`);await new Promise((Z)=>setTimeout(Z,Y))}}var Dy1=V.object({agent:V.enum(["claude","codex"]).describe("Agent type (claude or codex)"),prompt:V.string().describe("Prompt content"),name:V.string().optional().describe("Job name (auto-generated if omitted)"),model:V.string().optional().describe("Model for Claude agent"),workingDirectory:V.string().optional().describe("Working directory"),objectId:V.string().optional().describe("ID of entity to associate with"),streaming:V.boolean().optional().describe("Enable streaming output"),skipPermissions:V.boolean().optional().describe("Skip permission prompts (default: true). Set to false to enable permission prompts."),parentJobId:V.string().optional().describe("Parent job ID for hierarchy tracking"),blocking:V.boolean().optional().describe("Wait for job completion with 60-minute timeout (default: true). Set to false for asynchronous operation."),dockerImage:V.string().optional().describe("Docker image for containerized execution"),store:V.string().optional().describe('Store code (default: "A")')}),hy1=async({core:$,projectId:K},Y)=>{try{let{blocking:q,parentJobId:J,store:z="A",...W}=Y;if(J){let P=await Y$6({core:$,projectId:K},J);if(P>=Ws)throw Error(`Job depth limit exceeded (max ${Ws}, parent depth: ${P})`)}let Z=await $.createJob(K,{...W,store:z,parentJobId:J,blocking:q??!0});if(q===!1)return{content:[{type:"text",text:JSON.stringify(Z,null,2)}]};let H=await cE({core:$,projectId:K},Z.id,{intervalMs:QE,timeoutMs:pE}),X=await $.readJobOutput(K,{id:Z.id}),O={...H,output:X};return{content:[{type:"text",text:JSON.stringify(O,null,2)}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},q$6={name:"create_job",title:"Create Job",description:"Create and execute a job. Set blocking=true to wait for completion and return output directly (60-minute timeout). When parentJobId is provided, depth validation ensures jobs do not exceed depth limit of 4.",schema:Dy1,execute:hy1};P6();var Ly1=V.object({id:V.string().describe('Job ID to continue (e.g., "Aj1")'),prompt:V.string().describe("Follow-up prompt"),model:V.string().optional().describe("Model (allows changing between turns)"),dockerImage:V.string().optional().describe("Docker image for containerized execution"),skipPermissions:V.boolean().optional().describe("Skip permission prompts (Claude agent only)"),blocking:V.boolean().optional().describe("Wait for job completion with 60-minute timeout (default: true). Set to false for asynchronous operation.")}),Ey1=async({core:$,projectId:K},Y)=>{try{let{id:q,prompt:J,model:z,dockerImage:W,skipPermissions:Z,blocking:H}=Y,X=await $.continueJob(K,{id:q,prompt:J,model:z,dockerImage:W,skipPermissions:Z});if(H===!1)return{content:[{type:"text",text:JSON.stringify(X,null,2)}]};let O=await cE({core:$,projectId:K},X.id,{intervalMs:QE,timeoutMs:pE}),P=await $.readJobOutput(K,{id:X.id}),w={...O,output:P};return{content:[{type:"text",text:JSON.stringify(w,null,2)}]}}catch(q){return{content:[{type:"text",text:`Error: ${q.message}`}],isError:!0}}},J$6={name:"continue_job",title:"Continue Job",description:"Continue a completed or errored job with a follow-up prompt. Set blocking=true to wait for completion and return output directly (60-minute timeout).",schema:Ly1,execute:Ey1};var z$6=[t46,e46,$$6,K$6,q$6,J$6];P6();t6();var Sy1=V.object({query:V.string().describe("FTS5 search query"),field_name:V.string().optional().describe("Filter by field definition name"),store:V.string().optional().describe('Store code (default: "A")')}),Iy1=async({core:$,projectId:K},{query:Y,field_name:q,store:J})=>{try{let z=await $.searchTextFields(K,{query:Y,fieldName:q,store:J||"A"});return{content:[{type:"text",text:JSON.stringify(z,null,2)}]}}catch(z){if(z.message?.includes("fts5: syntax error"))return{content:[{type:"text",text:`Error: ${E.validation('Invalid FTS5 query syntax. Valid syntax includes: simple terms (hello world), phrases ("hello world"), boolean (hello OR world), prefix (hel*), negation (hello NOT world)',"INVALID_FTS5_QUERY").message}`}],isError:!0};return{content:[{type:"text",text:`Error: ${z.message}`}],isError:!0}}},W$6={name:"search_text_fields",title:"Search Text Fields",description:"Search text field content using FTS5 full-text search. Returns matching entity IDs, field names, and BM25 relevance ranking. Supports store:X filter to override store parameter.",schema:Sy1,execute:Iy1};P6();t6();var xy1=V.object({query:V.string().describe("FTS5 search query"),store:V.string().optional().describe('Store code (default: "A")'),limit:V.number().int().positive().optional().describe("Maximum results (default: 20)"),offset:V.number().int().min(0).optional().describe("Pagination offset (default: 0)"),start_marker:V.string().optional().describe('Snippet highlight start marker (default: "<mark>")'),end_marker:V.string().optional().describe('Snippet highlight end marker (default: "</mark>")')}),gy1=async({core:$,projectId:K},{query:Y,store:q,limit:J,offset:z,start_marker:W,end_marker:Z})=>{try{let H=await $.searchContent(K,{query:Y,store:q||"A",limit:J??20,offset:z??0,startMarker:W??"<mark>",endMarker:Z??"</mark>"});return{content:[{type:"text",text:JSON.stringify(H,null,2)}]}}catch(H){if(H.message?.includes("fts5: syntax error"))return{content:[{type:"text",text:`Error: ${E.validation('Invalid FTS5 query syntax. Valid syntax includes: simple terms (hello world), phrases ("hello world"), boolean (hello OR world), prefix (hel*), negation (hello NOT world)',"INVALID_FTS5_QUERY").message}`}],isError:!0};return{content:[{type:"text",text:`Error: ${H.message}`}],isError:!0}}},Z$6={name:"search",title:"Search Document Content",description:'Search document content using FTS5 full-text search. Returns matching documents with entity IDs, paths, names, BM25 relevance scores, and content snippets. Response includes debug.strategy field indicating execution path: "fts-first" (FTS query with optional filters) or "filters-only" (no FTS, filters applied directly). Query syntax: simple terms (hello), phrases ("hello world"), boolean (hello OR world), prefix (auth*), negation (hello NOT world). Filters: type:document, type:template, type:d/task, store:X (overrides store parameter), fieldName:value (string field equality). For multi-value fields, matches if ANY value equals the filter (contains semantics).',schema:xy1,execute:gy1};var H$6=[W$6,Z$6];var yy1=({core:$,projectId:K})=>{let Y=new zs({name:"caw-server",version:"0.0.1"},{capabilities:{tools:{}}}),q=[...Z46,...P46,...M46,...S46,...b46,...c46,...o46,...s46,...z$6,...H$6];for(let J of q)Y.registerTool(J.name,{title:J.title,description:J.description,inputSchema:J.schema},async(z,W)=>{try{let Z=W?.sessionId||W?.requestInfo?.headers?.["mcp-session-id"];return await J.execute({core:$,projectId:K,sessionId:Z},z)}catch(Z){return console.error(`Tool ${J.name} failed:`,Z),{content:[{type:"text",text:`Tool execution failed: ${Z.message}`}],isError:!0}}});return Y},X$6=Object.freeze({createMcpServer:yy1});var uy1=Zs.default("caw:mcp"),b5=Zs.default("caw:mcp:session"),my1=({core:$})=>{let K=new Map;return Object.freeze({handleRequest:async(W,Z,{projectId:H})=>{let X=W.headers["mcp-session-id"];if(X){let j=K.get(X);if(!j)return b5("Session not found: %s",X),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(j.projectId!==H)return b5("Session %s belongs to project %s, not %s",X,j.projectId,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});b5("Routing request to existing session: %s",X),j.lastActivity=Date.now();try{return await j.transport.handleRequest(W,Z,W.body)}catch(T){console.error("MCP transport request failed:",T)}}b5("Creating new MCP session for project: %s",H);let O=null,P=new lo({sessionIdGenerator:()=>{return O=by1(),b5("Generated session ID: %s",O),O},onsessioninitialized:(j)=>{b5("Session initialized: %s",j),Z.setHeader("Mcp-Session-Id",j),G.sessionId=j,K.set(j,G),b5("Session stored: %s",j)}});b5("Creating new server for session");let w=X$6.createMcpServer({core:$,projectId:H});try{await w.connect(P)}catch(j){return console.error("MCP server connect failed:",j),P.close?.(),w.close?.(),Z.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:"Internal server error"},id:null})}let G={sessionId:null,transport:P,server:w,projectId:H,createdAt:Date.now(),lastActivity:Date.now()};Z.on("finish",()=>{if(Z.statusCode!==200&&O&&K.has(O))b5("Request failed (status %d), cleaning up session: %s",Z.statusCode,O),K.delete(O),P.close?.(),w.close?.()});try{await P.handleRequest(W,Z,W.body)}catch(j){console.error("MCP transport request failed:",j)}},getSession:(W)=>{return K.get(W)},closeSession:(W)=>{let Z=K.get(W);if(!Z){b5("Cannot close session - not found: %s",W);return}b5("Closing session: %s",W),Z.transport.close?.(),Z.server.close?.(),K.delete(W)},cleanupIdle:(W)=>{let Z=Date.now(),H=0;for(let[X,O]of K.entries())if(Z-O.lastActivity>W)b5("Cleaning up idle session: %s (idle for %dms)",X,Z-O.lastActivity),O.transport.close?.(),O.server.close?.(),K.delete(X),H++;if(H>0)uy1("Cleaned up %d idle sessions",H)}})},O$6=Object.freeze({create:my1});var By1=86400000,Uy1=300000,Fy1=({mcpSessionManager:$})=>{let{jobFns:K,controlFns:Y}=hD.create({name:"cleanup-idle-mcp-sessions",interval:Uy1,execute:async()=>{$.cleanupIdle(By1)}});return{job:Object.freeze(K),control:Y}},P$6=Object.freeze({create:Fy1});var zS=o$6.default("caw:server"),Nb1=async({port:$,envDir:K,databaseFilepath:Y,assetsDir:q,lazilyCreateDb:J,enableRest:z,enableSse:W,enableStatic:Z,enableCrons:H,enableMcp:X=!0,enableCli:O=!0,staticPath:P,kyselyFactory:w})=>{let G=await gd8.create({envDir:K,databaseFilepath:Y,assetsDir:q,lazilyCreateDb:J,kyselyFactory:w}),j=fs.default();if(j.use(fs.default.json()),j.get("/health",(A,N)=>{N.json({status:"ok"})}),j.get("/api/info",(A,N)=>{N.json({version:"1.0.89"})}),z)j.use("/api",go8),md8.create(j,{core:G}),Fd8.create(j,{core:G}),Qd8.create(j,{core:G}),cd8.create(j,{core:G}),id8.create(j,{core:G}),nd8.create(j,{core:G}),od8.create(j,{core:G}),sd8.create(j,{core:G}),No8.create(j,{core:G}),Ro8.create(j,{core:G}),Do8.create(j,{core:G}),Lo8.create(j,{core:G});if(W)So8.create(j,{core:G}),xo8.create(j,{core:G});if(Z&&P)bd8.create(j,{staticPath:P});if(X){zS("Initializing MCP subsystem...");let A=O$6.create({core:G});G.registerCronJob(P$6,{mcpSessionManager:A}),bo8.create(j,{core:G,mcpSessionManager:A}),zS("MCP subsystem initialized")}if(O){zS("Initializing CLI Adapter subsystem...");let A=(await Promise.resolve().then(() => (b$6(),y$6))).default,N=(await Promise.resolve().then(() => (U$6(),B$6))).default,C=(await Promise.resolve().then(() => (i$6(),l$6))).default,I=(await Promise.resolve().then(() => (a$6(),n$6))).default,D=C.create({mcpClientFactory:A.create(),aliasGenerator:N.create(),core:G});await D.init(),G.subscribeServerEvents({onProjectCreated:(x)=>D.addProject({objectId:x.id,name:x.name,path:x.path})}),I.create(j,{cliSessionManager:D}),zS("CLI Adapter subsystem initialized")}if(H)G.startAllCrons();let T=null,v=new Set;return Object.freeze({app:j,core:G,start:async()=>{return new Promise((A)=>{T=j.listen($,()=>{let N=T.address().port;A(N)}),T.on("connection",(N)=>{v.add(N),N.on("close",()=>{v.delete(N)})})})},stop:async()=>{if(G.stopAllCrons(),T){for(let A of v)A.destroy();return v.clear(),new Promise((A)=>{T.close(()=>{A()})})}}})},r$6=Object.freeze({create:Nb1});var Rb1=3131,Cb1=WS.join(WS.dirname(fb1(import.meta.url)),"public_html"),Db1=!0,hb1=!0,Lb1=!0,Eb1=!0,Sb1=!1,Ib1=!0,xb1=!0,gb1=!0,wz=($,K)=>$!==void 0?$==="true":K,yb1=()=>{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:WS.join($,"caw.db"),assetsDir:WS.join($,"assets")}},bb1=async($)=>{let K=await r$6.create($),Y=await K.start();console.log(`Server listening on port ${Y}`),process.on("SIGINT",()=>K.stop("SIGINT")),process.on("SIGTERM",()=>K.stop("SIGTERM"))},ub1=()=>{let{envDir:$,databaseFilepath:K,assetsDir:Y}=yb1(),q=process.env.CAW_PORT?Number(process.env.CAW_PORT):Rb1,J=process.env.STATIC_PATH||Cb1,z=wz(process.env.LAZY_CREATE_DB,Db1),W=wz(process.env.ENABLE_REST,hb1),Z=wz(process.env.ENABLE_MCP,Lb1),H=wz(process.env.ENABLE_CLI,Eb1),X=wz(process.env.ENABLE_WEBLLM_WSS,Sb1),O=wz(process.env.ENABLE_SSE,Ib1),P=wz(process.env.ENABLE_STATIC,xb1),w=wz(process.env.ENABLE_CRONS,gb1);return Object.freeze({port:q,staticPath:J,envDir:$,databaseFilepath:K,assetsDir:Y,lazilyCreateDb:z,enableRest:W,enableMcp:Z,enableCli:H,enableWebllmWss:X,enableSse:O,enableStatic:P,enableCrons:w})};await bb1(ub1()).catch(($)=>{console.error("ERROR: Failed to start server:",$),process.exit(1)});
|