@kelceyp/caw-server 1.0.92 → 1.0.93
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/cli.js +5 -3
- package/dist/main.js +2 -2
- package/dist/public_html/main.js +413 -409
- package/dist/public_html/styles.css +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -9872,8 +9872,8 @@ var create_default5 = Object.freeze({ create: create61 });
|
|
|
9872
9872
|
|
|
9873
9873
|
// src/commands/template/render.js
|
|
9874
9874
|
var create62 = ({ httpClient }) => {
|
|
9875
|
-
return createCommand("render").summary("Render a template").param((p) => p.name("sid").type("string").flag("sid", "s").required()).param((p) => p.name("id").type("string").flag("id").required()).param((p) => p.name("params").type("string").flag("params")).param((p) => p.name("target").type("string").flag("target")).param((p) => p.name("path").type("string").flag("path")).param((p) => p.name("publish").type("boolean").flag("publish")).run(async (ctx) => {
|
|
9876
|
-
const { sid, id, params, target, path, publish } = ctx.params;
|
|
9875
|
+
return createCommand("render").summary("Render a template").param((p) => p.name("sid").type("string").flag("sid", "s").required()).param((p) => p.name("id").type("string").flag("id").required()).param((p) => p.name("params").type("string").flag("params")).param((p) => p.name("target").type("string").flag("target")).param((p) => p.name("path").type("string").flag("path")).param((p) => p.name("publish").type("boolean").flag("publish")).param((p) => p.name("store").type("string").flag("store")).run(async (ctx) => {
|
|
9876
|
+
const { sid, id, params, target, path, publish, store } = ctx.params;
|
|
9877
9877
|
const args = { id };
|
|
9878
9878
|
if (params !== undefined) {
|
|
9879
9879
|
try {
|
|
@@ -9884,12 +9884,14 @@ var create62 = ({ httpClient }) => {
|
|
|
9884
9884
|
}
|
|
9885
9885
|
if (target !== undefined)
|
|
9886
9886
|
args.target = target;
|
|
9887
|
-
if (path !== undefined || publish !== undefined) {
|
|
9887
|
+
if (path !== undefined || publish !== undefined || store !== undefined) {
|
|
9888
9888
|
args.targetOptions = {};
|
|
9889
9889
|
if (path !== undefined)
|
|
9890
9890
|
args.targetOptions.path = path;
|
|
9891
9891
|
if (publish !== undefined)
|
|
9892
9892
|
args.targetOptions.publish = publish;
|
|
9893
|
+
if (store !== undefined)
|
|
9894
|
+
args.targetOptions.store = store;
|
|
9893
9895
|
}
|
|
9894
9896
|
const result = await httpClient.post(`/cli/mcp-client/${sid}/dispatch`, {
|
|
9895
9897
|
cwd: process.cwd(),
|
package/dist/main.js
CHANGED
|
@@ -611,7 +611,7 @@ try {
|
|
|
611
611
|
Write-Error "Failed to get clipboard: $($_.Exception.Message)"
|
|
612
612
|
exit 1
|
|
613
613
|
}
|
|
614
|
-
`.trim(),ai8=async($,K)=>{try{return await $()}catch{return K()}},oi8=($,K)=>{try{return $()}catch{return K()}},i01={copy:async($)=>ai8(async()=>j3(ch,lh(di8),$),async()=>j3(ph,["--copy"],$)),async paste($){let{stdout:K}=await ai8(async()=>j3(ch,lh(ni8),$),async()=>j3(ph,["--paste"],$));return K},copySync:($)=>oi8(()=>v3(ch,lh(di8),$),()=>v3(ph,["--copy"],$)),pasteSync:($)=>oi8(()=>v3(ch,lh(ni8),$),()=>v3(ph,["--paste"],$)).stdout},ln=i01;var ih=(()=>{switch(si8.platform){case"darwin":return ci8;case"win32":return ln;case"android":{if(si8.env.TERMUX_VERSION===void 0)throw Error("You need to install Termux for this module to work on Android: https://termux.com");return Si8}default:{if(_F8)return ln;if(jd())return pi8;return iZ}}})(),d01={async write($){if(typeof $!=="string")throw TypeError(`Expected a string, got ${typeof $}`);await ih.copy({input:$})},async read(){return ih.paste({stripFinalNewline:!1})},writeSync($){if(typeof $!=="string")throw TypeError(`Expected a string, got ${typeof $}`);ih.copySync({input:$})},readSync(){return ih.pasteSync({stripFinalNewline:!1})}},ti8=d01;var n01=()=>{return Object.freeze({copyToClipboard:async(K)=>{try{await ti8.write(K)}catch(Y){throw Error(`Failed to copy to clipboard: ${Y.message}`)}}})},ei8=Object.freeze({create:n01});e6();var $d8=/[/\\:*?"<>|]/,a01=({store:$,fieldService:K,workflowService:Y})=>{let q=["STORY_STATE_CHANGED","STORY_CREATED"],{notify:J,subscribe:z,subscribeAll:W}=PJ.create(q),Z=({entityType:N,entityId:V,fieldName:f,oldValue:C,newValue:I,storeCode:D})=>{if(N!=="s"||f!=="state")return;J("STORY_STATE_CHANGED",{id:V,oldState:C,newState:I})};$.subscribe(v6.FIELD_VALUE_CHANGED,Z);let H=async(N,V,{store:f,workflowName:C},I)=>{let D=C||"Default",x;if(D==="Default")x=await Y.getOrCreateDefaultWorkflow(N,V,f,I);else x=await Y.getWorkflowByName(N,V,{store:f,name:D}),b.factory(!x,E.validation,`Workflow not found: ${D}`,"WORKFLOW_NOT_FOUND");let h=x.fields?.states||[];return b.factory(!h||h.length===0,E.validation,`Workflow "${D}" has no states configured`,"EMPTY_WORKFLOW_STATES"),{statesArray:h,validStates:new Set(h)}},X=async(N,V,f,C)=>{let I=await $.readStory(N,V,{id:f});b.factory(!I,E.notFound,`Story not found: ${f}`,"STORY_NOT_FOUND");let x=I.getFields?.()?.workflow?.getValue?.()||"Default",h=$1.extractStoreCode(f);return await H(N,V,{store:h,workflowName:x},C)};return Object.freeze({createStory:async(N,V,{store:f,name:C,state:I,workflow:D},x)=>{b.factory(!f,E.validation,"Store is required","MISSING_STORE_CODE"),b.factory(!C||!C.trim(),E.validation,"Story name is required","MISSING_NAME"),b.factory($d8.test(C),E.validation,'Story name contains invalid characters: /\\:*?"<>|',"INVALID_CHARS");let h=D||"Default",{statesArray:R,validStates:L}=await H(N,V,{store:f,workflowName:h},x),m=I||R[0];b.factory(!L.has(m),E.validation,`Invalid state '${m}' for workflow '${h}'`,"INVALID_STATE");let l=await $.readStoryRootFolder(N,V,{storeCode:f});b.factory(!l,E.notFound,"Story root folder not found","STORY_ROOT_NOT_FOUND");let r=await $.isDuplicateNameInParent(N,V,l.getObjectId(),C.trim());b.factory(r,E.conflict,`Story "${C.trim()}" already exists`,"DUPLICATE_NAME");let W8=await $.createStory(N,V,{storeCode:f,parentId:l.getObjectId(),name:C.trim(),state:m},x);await K.setFieldValue(N,V,{entityId:W8.getObjectId(),fieldName:"state",value:m},x),await K.setFieldValue(N,V,{entityId:W8.getObjectId(),fieldName:"workflow",value:h},x);let $8=await $.createFolder(N,V,{storeCode:f,parentId:W8.getObjectId(),name:"tasks",subtype:"tasks"},x),B8=(await K.getFieldDefinitionsForType(N,V,{store:f,code:"f",subtype:"tasks"})).find((x8)=>x8.entity.getName()==="states")?.entity;b.factory(!B8,E.notFound,"states field definition not found for f/tasks","FIELD_DEFINITION_NOT_FOUND"),await K.setFieldValue(N,V,{entityId:$8.getObjectId(),fieldDefinitionId:B8.getObjectId(),values:[...lz]},x),x(()=>{J("STORY_CREATED",{id:W8.getObjectId(),name:C.trim(),state:m,workflow:h,storeCode:f})});let S8=W8.toJSON();S8.fields={...S8.fields,state:m,workflow:h};let g8={...S8,storeCode:f},C8=$8.toJSON();return C8.fields={states:[...lz]},g8.tasksFolder=C8,g8},listStories:async(N,V,{store:f})=>{b.factory(!f,E.validation,"Store is required","MISSING_STORE_CODE");let C=await $.listStories(N,V,{storeCode:f}),I=[];for(let D of C){let h=D.getFields().state;b.factory(!h,E.validation,`Story ${D.getObjectId()} missing required state field`,"MISSING_STATE_FIELD"),I.push({...D.toJSON(),storeCode:f})}return I},getStory:async(N,V,{id:f})=>{b.factory(!f,E.validation,"ID is required","MISSING_ID");let C=$1.extractStoreCode(f),I=await $.readStory(N,V,{id:f});b.factory(!I,E.notFound,`Story not found: ${f}`,"STORY_NOT_FOUND");let x=I.getFields().state;return b.factory(!x,E.validation,`Story ${f} missing required state field`,"MISSING_STATE_FIELD"),{...I.toJSON(),storeCode:C}},renameStory:async(N,V,{id:f,name:C},I)=>{b.factory(!f,E.validation,"ID is required","MISSING_ID"),b.factory(!C||!C.trim(),E.validation,"Name is required","MISSING_NAME"),b.factory($d8.test(C),E.validation,'Story name contains invalid characters: /\\:*?"<>|',"INVALID_CHARS");let D=$1.extractStoreCode(f),x=C.trim(),h=await $.readStory(N,V,{id:f});b.factory(!h,E.notFound,`Story not found: ${f}`,"STORY_NOT_FOUND");let R=await $.isDuplicateNameInParent(N,V,h.getParentId(),x,f);b.factory(R,E.conflict,`Story "${x}" already exists`,"DUPLICATE_NAME");let{entity:L}=await $.renameStory(N,V,{id:f,name:x},I);return{...L.toJSON(),storeCode:D}},updateStoryState:async(N,V,{id:f,state:C},I)=>{b.factory(!f,E.validation,"ID is required","MISSING_ID"),b.factory(!C,E.validation,"State is required","MISSING_STATE");let D=$1.extractStoreCode(f),{validStates:x}=await X(N,V,f,I);b.factory(!x.has(C),E.validation,`Invalid state: ${C}`,"INVALID_STATE");let h=await $.readStory(N,V,{id:f});b.factory(!h,E.notFound,`Story not found: ${f}`,"STORY_NOT_FOUND");let L=h.getFields().state;b.factory(!L,E.validation,`Story ${f} missing required state field`,"MISSING_STATE_FIELD");let m=L.getValue(),l=C==="done"&&m!=="done",r=C!=="done"&&m==="done";if(await K.setFieldValue(N,V,{entityId:f,fieldName:"state",value:C},I),l)await K.setFieldValue(N,V,{entityId:f,fieldName:"dateCompleted",value:_6(),bypassEditableCheck:!0},I);else if(r)await K.deleteFieldValue(N,V,{entityId:f,fieldName:"dateCompleted"},I);let W8=h.toJSON();return W8.fields={...W8.fields,state:C},{...W8,storeCode:D}},deleteStory:async(N,V,{id:f},C)=>{b.factory(!f,E.validation,"ID is required","MISSING_ID");let I=$1.extractStoreCode(f),D=await $.readStory(N,V,{id:f});return b.factory(!D,E.notFound,`Story not found: ${f}`,"STORY_NOT_FOUND"),{...await $.deleteStory(N,V,{id:f},C),storeCode:I}},incrementActiveJobCount:async(N,V,{id:f},C)=>{b.factory(!f,E.validation,"ID is required","MISSING_ID");let I=$1.extractStoreCode(f),D=await $.readStory(N,V,{id:f});if(!D)return null;let h=parseInt(D.getFields().activeJobCount?.getValue()||"0",10)+1;await K.setFieldValue(N,V,{entityId:f,fieldName:"activeJobCount",value:String(h),bypassEditableCheck:!0},C);let R=D.toJSON();return R.fields={...R.fields,activeJobCount:String(h)},{...R,storeCode:I}},decrementActiveJobCount:async(N,V,{id:f},C)=>{b.factory(!f,E.validation,"ID is required","MISSING_ID");let I=$1.extractStoreCode(f),D=await $.readStory(N,V,{id:f});if(!D)return null;let x=parseInt(D.getFields().activeJobCount?.getValue()||"0",10);if(x<=0)return{...D.toJSON(),storeCode:I};let h=x-1;await K.setFieldValue(N,V,{entityId:f,fieldName:"activeJobCount",value:String(h),bypassEditableCheck:!0},C);let R=D.toJSON();return R.fields={...R.fields,activeJobCount:String(h)},{...R,storeCode:I}},subscribe:z,subscribeAll:W})},dn=Object.freeze({create:a01});e6();var jV="Workflows",Kd8="Default",o01=({store:$,documentService:K,fieldService:Y,folderService:q})=>{let J=async(P,w,G,j)=>{let T=await $.readSettingsRootFolder(P,w,{storeCode:G});b.factory(!T,E.notFound,"Settings root folder not found","SETTINGS_ROOT_NOT_FOUND");let v=await $.findFolderByName(P,w,T.getObjectId(),jV);if(v)return v;return await $.createFolder(P,w,{storeCode:G,parentId:T.getObjectId(),name:jV},j)},z=async(P,w,G,j)=>{let T=await H(P,w,{store:G,name:Kd8});if(T)return T;return await W(P,w,{store:G,name:Kd8,states:[...EX]},j)},W=async(P,w,{store:G,name:j,states:T},v)=>{b.factory(!G,E.validation,"Store is required","MISSING_STORE_CODE"),b.factory(!j||!j.trim(),E.validation,"Workflow name is required","MISSING_NAME"),b.factory(!T||T.length===0,E.validation,"Workflow must have at least one state","EMPTY_STATES");let k=new Set(T);b.factory(k.size!==T.length,E.validation,"Workflow states must be unique","DUPLICATE_STATES");let N=j.trim(),V=await J(P,w,G,v),f=await $.isDuplicateNameInParent(P,w,V.getObjectId(),N);b.factory(f,E.conflict,`Workflow "${N}" already exists`,"DUPLICATE_WORKFLOW_NAME");let C=await K.createDocument(P,w,{mode:"parentName",store:G,parentId:V.getObjectId(),name:N,subtype:"workflow",fields:{states:T}},v);return{...C,fields:{...C.fields,states:T}}},Z=async(P,w,{store:G})=>{b.factory(!G,E.validation,"Store is required","MISSING_STORE_CODE");let j=await $.readSettingsRootFolder(P,w,{storeCode:G});if(!j)return[];let T=await $.findFolderByName(P,w,j.getObjectId(),jV);if(!T)return[];let v=await $.listContent(P,w,{parentId:T.getObjectId(),type:"d"}),k=[];for(let N of v){let V=N.toJSON(),C=N.getFields?.()?.states?.getValues?.()||[];k.push({...V,storeCode:G,fields:{...V.fields,states:C}})}return k},H=async(P,w,{store:G,name:j})=>{b.factory(!G,E.validation,"Store is required","MISSING_STORE_CODE"),b.factory(!j,E.validation,"Name is required","MISSING_NAME");let T=await $.readSettingsRootFolder(P,w,{storeCode:G});if(!T)return null;let v=await $.findFolderByName(P,w,T.getObjectId(),jV);if(!v)return null;let k=await $.findContentByName(P,w,v.getObjectId(),j.trim(),"d");if(!k)return null;let N=k.toJSON(),f=k.getFields?.()?.states?.getValues?.()||[];return{...N,storeCode:G,fields:{...N.fields,states:f}}};return Object.freeze({createWorkflow:W,listWorkflows:Z,getWorkflowByName:H,getOrCreateDefaultWorkflow:z,updateWorkflow:async(P,w,{id:G,name:j,states:T},v)=>{b.factory(!G,E.validation,"ID is required","MISSING_ID"),b.factory(!j&&!T,E.validation,"At least one of name or states is required","MISSING_UPDATE_DATA");let k=$1.extractStoreCode(G),N=await $.readContent(P,w,{id:G});b.factory(!N,E.notFound,`Workflow not found: ${G}`,"WORKFLOW_NOT_FOUND");let V=N.getName(),C=N.getFields?.()?.states?.getValues?.()||[];if(T){b.factory(T.length===0,E.validation,"Workflow must have at least one state","EMPTY_STATES");let R=new Set(T);b.factory(R.size!==T.length,E.validation,"Workflow states must be unique","DUPLICATE_STATES");let L=C.filter((m)=>!T.includes(m));if(L.length>0){let l=(await $.listStories(P,w,{storeCode:k})).filter((r)=>{return r.getFields?.()?.workflow?.getValue?.()===V});for(let r of L){let W8=l.filter(($8)=>{return $8.getFields?.()?.state?.getValue?.()===r});b.factory(W8.length>0,E.conflict,`Cannot remove state "${r}" - ${W8.length} ${W8.length===1?"story exists":"stories exist"} in this state`,"STATE_IN_USE")}}await Y.setFieldValue(P,w,{entityId:G,fieldName:"states",values:T},v)}let I=V;if(j&&j.trim()!==V){let R=j.trim(),L=await J(P,w,k,v),m=await $.isDuplicateNameInParent(P,w,L.getObjectId(),R,G);b.factory(m,E.conflict,`Workflow "${R}" already exists`,"DUPLICATE_WORKFLOW_NAME");let l=`${jV}/${R}`;await K.updateDocumentPath(P,w,{id:G,path:l,type:"d"},v),I=R;let r=await $.listStories(P,w,{storeCode:k});for(let W8 of r)if(W8.getFields?.()?.workflow?.getValue?.()===V)await Y.setFieldValue(P,w,{entityId:W8.getObjectId(),fieldName:"workflow",value:I},v)}let D=T||C,h=(await $.readContent(P,w,{id:G})).toJSON();return{...h,storeCode:k,fields:{...h.fields,states:D}}},deleteWorkflow:async(P,w,{id:G},j)=>{b.factory(!G,E.validation,"ID is required","MISSING_ID");let T=$1.extractStoreCode(G),v=await $.readContent(P,w,{id:G});b.factory(!v,E.notFound,`Workflow not found: ${G}`,"WORKFLOW_NOT_FOUND");let k=v.getName(),V=(await $.listStories(P,w,{storeCode:T})).filter((C)=>{return C.getFields?.()?.workflow?.getValue?.()===k});return b.factory(V.length>0,E.conflict,`Cannot delete workflow "${k}" - ${V.length} ${V.length===1?"story is":"stories are"} assigned to it`,"WORKFLOW_IN_USE"),{...await K.deleteDocument(P,w,{id:G},j),storeCode:T}},getOrCreateWorkflowsFolder:J})},nn=Object.freeze({create:o01});e6();import{createHash as r01}from"crypto";import{promises as vw}from"fs";import Yd8 from"path";var s01=10485760,qd8=Object.freeze(["image/png","image/jpeg","image/gif","image/webp"]),t01=({assetsDir:$})=>{let K=(H)=>{return r01("sha256").update(H).digest("hex")},Y=(H)=>{let X=H.substring(0,2);return Yd8.join($,X,H)};return Object.freeze({computeHash:K,getAssetPath:Y,exists:async(H)=>{try{return await vw.access(Y(H)),!0}catch{return!1}},write:async(H,X)=>{let O=Y(H),P=Yd8.dirname(O),w=O+".tmp";await vw.mkdir(P,{recursive:!0}),await vw.writeFile(w,X),await vw.rename(w,O)},read:async(H)=>{let X=Y(H);return vw.readFile(X)},remove:async(H)=>{let X=Y(H);try{await vw.unlink(X)}catch(O){if(O.code!=="ENOENT")throw O}},isAllowedMimeType:(H)=>{return qd8.includes(H)},MAX_SIZE_BYTES:s01,ALLOWED_MIME_TYPES:qd8,assetsDir:$})},Jd8=Object.freeze({create:t01});var e01=({store:$,assetsDir:K})=>{let Y=Jd8.create({assetsDir:K});return Object.freeze({createAsset:async(H,X,{store:O,buffer:P,mimeType:w,originalFilename:G,widthPx:j,heightPx:T,displayWidth:v,displayHeight:k},N)=>{b.factory(!O,E.validation,"Store is required","MISSING_STORE_CODE"),b.factory(!P,E.validation,"Binary data is required","MISSING_DATA"),b.factory(!w,E.validation,"MIME type is required","MISSING_MIME_TYPE"),b.factory(!Y.isAllowedMimeType(w),E.validation,`Unsupported MIME type: ${w}. Allowed: ${Y.ALLOWED_MIME_TYPES.join(", ")}`,"UNSUPPORTED_MIME_TYPE");let V=P.length;b.factory(V>Y.MAX_SIZE_BYTES,E.validation,`File too large: ${V} bytes. Maximum: ${Y.MAX_SIZE_BYTES} bytes (10MB)`,"FILE_TOO_LARGE");let f=Y.computeHash(P);if(!await Y.exists(f))await Y.write(f,P);return{...(await $.createAsset(H,X,{storeCode:O,hash:f,mimeType:w,sizeBytes:V,originalFilename:G,widthPx:j,heightPx:T,displayWidth:v,displayHeight:k},N)).toJSON(),storeCode:O}},readAsset:async(H,X,{id:O})=>{b.factory(!O,E.validation,"ID is required","MISSING_ID");let P=await $.readAsset(H,X,{id:O});b.factory(!P,E.notFound,`Asset not found: ${O}`,"ASSET_NOT_FOUND");let w=$1.extractStoreCode(O);return{...P.toJSON(),storeCode:w}},readAssetBinary:async(H,X,{id:O})=>{b.factory(!O,E.validation,"ID is required","MISSING_ID");let P=await $.readAsset(H,X,{id:O});b.factory(!P,E.notFound,`Asset not found: ${O}`,"ASSET_NOT_FOUND");let w=P.getHash(),G;try{G=await Y.read(w)}catch(j){if(j.code==="ENOENT")throw E.notFound(`Blob file not found for asset: ${O}`,"BLOB_NOT_FOUND");throw j}return{buffer:G,mimeType:P.getMimeType(),sizeBytes:P.getSizeBytes(),hash:w,originalFilename:P.getOriginalFilename()}},listAssets:async(H,X,{store:O})=>{return b.factory(!O,E.validation,"Store is required","MISSING_STORE_CODE"),(await $.listAssets(H,X,{storeCode:O})).map((w)=>({...w.toJSON(),storeCode:O}))},deleteAsset:async(H,X,{id:O},P)=>{b.factory(!O,E.validation,"ID is required","MISSING_ID");let w=await $.readAsset(H,X,{id:O});b.factory(!w,E.notFound,`Asset not found: ${O}`,"ASSET_NOT_FOUND");let G=$1.extractStoreCode(O);return{...await $.deleteAsset(H,X,{id:O},P),storeCode:G}}})},an=Object.freeze({create:e01});e6();import{randomUUID as $j1}from"crypto";import{execSync as zd8}from"child_process";var Xd8=["claude","codex"],rn=["pending","running","completed","error","stopped"],Kj1=5000,Wd8="job-service-system",K1={AGENT:"agent",MODEL:"model",STATUS:"status",STARTED_AT:"startedAt",COMPLETED_AT:"completedAt",TOKENS_USED:"tokensUsed",EXIT_CODE:"exitCode",ERROR_MESSAGE:"errorMessage",DURATION_MS:"durationMs",TOTAL_COST_USD:"totalCostUsd",NUM_TURNS:"numTurns",SESSION_ID:"sessionId",WORKING_DIRECTORY:"workingDirectory",PID:"pid",OBJECT_ID:"objectId",STREAMING:"streaming",PARENT_JOB_ID:"parentJobId",BLOCKING:"blocking",DOCKER_IMAGE:"dockerImage",CLEAR_STORY_FLAG:"clearStoryFlag",CLEAR_STATUS_MESSAGE:"clearStatusMessage",SKIP_PERMISSIONS:"skipPermissions"},Yj1=($)=>Xd8.includes($),Zd8=($)=>rn.includes($),qj1=($)=>{let K=new Date,Y=K.toISOString().slice(0,10),q=K.toISOString().slice(11,19).replace(/:/g,"");return`${$}-${Y}-${q}`},Hd8=($)=>{return{R:"running",S:"sleeping",D:"disk_sleep",Z:"zombie",T:"stopped",t:"tracing_stop",X:"dead",I:"idle"}[$]||$},on=($)=>{try{process.kill($,0)}catch(K){if(K.code==="ESRCH")return{exists:!1};if(K.code==="EPERM")return{exists:!0,state:"permission_denied"};return{exists:!1,error:K.message}}try{if(process.platform==="darwin"){let K=zd8(`ps -o state=,comm= -p ${$}`,{encoding:"utf8"}).trim(),[Y,...q]=K.split(/\s+/),J=Y?Y[0]:"unknown";return{exists:!0,state:Hd8(J),command:q.join(" ")}}else{let K=zd8(`cat /proc/${$}/status 2>/dev/null | grep -E '^(State|Name):'`,{encoding:"utf8"}),Y=K.match(/State:\s*(\w)/),q=K.match(/Name:\s*(\S+)/);return{exists:!0,state:Y?Hd8(Y[1]):"unknown",command:q?q[1]:void 0}}}catch{return{exists:!0,state:"unknown"}}},Jj1=({store:$,fieldService:K})=>{let Y=["JOB_STATUS_CHANGED","JOB_STARTED","JOB_COMPLETED","JOB_OUTPUT_CHUNK"],{notify:q,subscribe:J,subscribeAll:z}=PJ.create(Y),W=({entityType:h,entityId:R,fieldName:L,oldValue:m,newValue:l,storeCode:r})=>{if(h!=="j"||L!=="status")return;if(q("JOB_STATUS_CHANGED",{id:R,oldStatus:m,newStatus:l}),l==="running")q("JOB_STARTED",{id:R});if(l==="completed"||l==="error"||l==="stopped")q("JOB_COMPLETED",{id:R,status:l})};$.subscribe(v6.FIELD_VALUE_CHANGED,W);let Z=(h,R,L={})=>{let m=h.toJSON();if(Object.keys(L).length>0)m.fields={...m.fields,...L};return{...m,storeCode:R}},H=async(h,R,L)=>{return await $.findContentByName(h,R,L,"prompt.md","d")!==null},X=async(h,R,L)=>{let m=await $.listContent(h,R,{parentId:L,type:"d"}),l=/^prompt-(\d+)\.md$/,r=m.filter(($8)=>l.test($8.getName()));if(r.length===0)return 0;let W8=r.map(($8)=>{let f8=$8.getName().match(l);return f8?parseInt(f8[1],10):0});return Math.max(...W8)};return Object.freeze({createJob:async(h,R,{store:L,name:m,agent:l,model:r,prompt:W8,workingDirectory:$8,objectId:f8,streaming:B8,parentJobId:S8,blocking:g8,dockerImage:C8,skipPermissions:x8,clearStoryFlag:Y6,clearStatusMessage:M6},M8)=>{b.factory(!L,E.validation,"Store is required","MISSING_STORE_CODE"),b.factory(!l,E.validation,"Agent is required","MISSING_AGENT"),b.factory(!Yj1(l),E.validation,`Invalid agent: ${l}. Must be one of: ${Xd8.join(", ")}`,"INVALID_AGENT"),b.factory(!W8,E.validation,"Prompt is required","MISSING_PROMPT");let u8=$j1(),Q8=m?.trim()||qj1(l),Y8=await $.readJobRootFolder(h,R,{storeCode:L});b.factory(!Y8,E.notFound,"Job root folder not found","JOB_ROOT_NOT_FOUND");let K8=await $.isDuplicateNameInParent(h,R,Y8.getObjectId(),Q8);b.factory(K8,E.conflict,`Job "${Q8}" already exists`,"DUPLICATE_NAME");let N8=(await $.createJob(h,R,{storeCode:L,parentId:Y8.getObjectId(),name:Q8,status:"pending"},M8)).getObjectId(),I8=new Date().toISOString();if(await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.AGENT,value:l,bypassEditableCheck:!0},M8),await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.STATUS,value:"pending",bypassEditableCheck:!0},M8),await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.STARTED_AT,value:I8,bypassEditableCheck:!0},M8),await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.SESSION_ID,value:u8,bypassEditableCheck:!0},M8),r?.trim())await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.MODEL,value:r.trim(),bypassEditableCheck:!0},M8);if($8?.trim())await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.WORKING_DIRECTORY,value:$8.trim(),bypassEditableCheck:!0},M8);if(f8?.trim())await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.OBJECT_ID,value:f8.trim(),bypassEditableCheck:!0},M8);if(B8)await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.STREAMING,value:"true",bypassEditableCheck:!0},M8);if(S8?.trim())await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.PARENT_JOB_ID,value:S8.trim(),bypassEditableCheck:!0},M8);if(g8)await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.BLOCKING,value:"true",bypassEditableCheck:!0},M8);if(C8?.trim())await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.DOCKER_IMAGE,value:C8.trim(),bypassEditableCheck:!0},M8);if(Y6!==void 0&&Y6!==null)await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.CLEAR_STORY_FLAG,value:String(Y6),bypassEditableCheck:!0},M8);if(M6!==void 0&&M6!==null)await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.CLEAR_STATUS_MESSAGE,value:String(M6),bypassEditableCheck:!0},M8);if(x8!==void 0&&x8!==null)await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.SKIP_PERMISSIONS,value:String(x8),bypassEditableCheck:!0},M8);return await $.createContent(h,R,{storeCode:L,type:"d",parentId:N8,name:"prompt-1.md",initialContent:W8},M8),await $.createContent(h,R,{storeCode:L,type:"d",parentId:N8,name:"output-1.md",initialContent:""},M8),{...(await $.readJob(h,R,{id:N8})).toJSON(),storeCode:L}},listJobs:async(h,R,{store:L,status:m})=>{if(b.factory(!L,E.validation,"Store is required","MISSING_STORE_CODE"),m)b.factory(!Zd8(m),E.validation,`Invalid status: ${m}. Must be one of: ${rn.join(", ")}`,"INVALID_STATUS");let l=await $.listJobs(h,R,{storeCode:L}),r=[];for(let W8 of l){if(m){let f8=W8.getFields()[K1.STATUS];if((f8?f8.getValue():null)!==m)continue}r.push({...W8.toJSON(),storeCode:L})}return r},getJob:async(h,R,{id:L})=>{b.factory(!L,E.validation,"ID is required","MISSING_ID");let m=$1.extractStoreCode(L),l=await $.readJob(h,R,{id:L});return b.factory(!l,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND"),{...l.toJSON(),storeCode:m}},updateJobStatus:async(h,R,{id:L,status:m,exitCode:l,errorMessage:r},W8)=>{b.factory(!L,E.validation,"ID is required","MISSING_ID"),b.factory(!m,E.validation,"Status is required","MISSING_STATUS"),b.factory(!Zd8(m),E.validation,`Invalid status: ${m}. Must be one of: ${rn.join(", ")}`,"INVALID_STATUS");let $8=$1.extractStoreCode(L),f8=await $.readJob(h,R,{id:L});b.factory(!f8,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND");let S8=f8.getFields()[K1.STATUS],g8=S8?S8.getValue():null;if(["completed","error","stopped"].includes(g8))return Z(f8,$8,{});if(await K.setFieldValue(h,R,{entityId:L,fieldName:K1.STATUS,value:m,bypassEditableCheck:!0},W8),m==="completed"||m==="error"||m==="stopped"){let Y6=new Date().toISOString();await K.setFieldValue(h,R,{entityId:L,fieldName:K1.COMPLETED_AT,value:Y6,bypassEditableCheck:!0},W8)}if(l!==void 0&&l!==null)await K.setFieldValue(h,R,{entityId:L,fieldName:K1.EXIT_CODE,value:String(l),bypassEditableCheck:!0},W8);if(r)await K.setFieldValue(h,R,{entityId:L,fieldName:K1.ERROR_MESSAGE,value:r,bypassEditableCheck:!0},W8);let x8={status:m};if(m==="completed"||m==="error"||m==="stopped")x8.completedAt=new Date().toISOString();if(l!==void 0&&l!==null)x8.exitCode=String(l);if(r)x8.errorMessage=r;return Z(f8,$8,x8)},updateJobOutput:async(h,R,{id:L,output:m},l)=>{b.factory(!L,E.validation,"ID is required","MISSING_ID"),b.factory(m===void 0||m===null,E.validation,"Output is required","MISSING_OUTPUT");let r=$1.extractStoreCode(L),W8=await $.readJob(h,R,{id:L});b.factory(!W8,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND");let $8;if(await H(h,R,L))$8=await $.findContentByName(h,R,L,"output.md","d");else{let g8=await X(h,R,L),C8=g8>0?`output-${g8}.md`:"output-1.md";$8=await $.findContentByName(h,R,L,C8,"d")}b.factory(!$8,E.notFound,"Output document not found","OUTPUT_DOC_NOT_FOUND");let B8=$8.getObjectId();return await $.saveDraft(h,R,{id:B8,content:m,sessionId:Wd8},l),await $.publishContent(h,R,{id:B8},l),{...(await $.readJob(h,R,{id:L})).toJSON(),storeCode:r}},updateJobTokens:async(h,R,{id:L,tokensUsed:m},l)=>{b.factory(!L,E.validation,"ID is required","MISSING_ID"),b.factory(m===void 0||m===null,E.validation,"tokensUsed is required","MISSING_TOKENS");let r=$1.extractStoreCode(L),W8=await $.readJob(h,R,{id:L});return b.factory(!W8,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND"),await K.setFieldValue(h,R,{entityId:L,fieldName:K1.TOKENS_USED,value:String(m),bypassEditableCheck:!0},l),Z(W8,r,{tokensUsed:String(m)})},updateJobMetadata:async(h,R,{id:L,durationMs:m,totalCostUsd:l,numTurns:r,sessionId:W8},$8)=>{b.factory(!L,E.validation,"ID is required","MISSING_ID");let f8=$1.extractStoreCode(L),B8=await $.readJob(h,R,{id:L});if(b.factory(!B8,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND"),m!==void 0&&m!==null)await K.setFieldValue(h,R,{entityId:L,fieldName:K1.DURATION_MS,value:String(m),bypassEditableCheck:!0},$8);if(l!==void 0&&l!==null)await K.setFieldValue(h,R,{entityId:L,fieldName:K1.TOTAL_COST_USD,value:String(l),bypassEditableCheck:!0},$8);if(r!==void 0&&r!==null)await K.setFieldValue(h,R,{entityId:L,fieldName:K1.NUM_TURNS,value:String(r),bypassEditableCheck:!0},$8);if(W8!==void 0&&W8!==null)await K.setFieldValue(h,R,{entityId:L,fieldName:K1.SESSION_ID,value:W8,bypassEditableCheck:!0},$8);let S8={};if(m!==void 0&&m!==null)S8.durationMs=String(m);if(l!==void 0&&l!==null)S8.totalCostUsd=String(l);if(r!==void 0&&r!==null)S8.numTurns=String(r);if(W8!==void 0&&W8!==null)S8.sessionId=W8;return Z(B8,f8,S8)},setJobPid:async(h,R,{id:L,pid:m},l)=>{b.factory(!L,E.validation,"ID is required","MISSING_ID"),b.factory(!m,E.validation,"PID is required","MISSING_PID");let r=await $.readJob(h,R,{id:L});b.factory(!r,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND"),await K.setFieldValue(h,R,{entityId:L,fieldName:K1.PID,value:String(m),bypassEditableCheck:!0},l)},clearJobPid:async(h,R,{id:L},m)=>{b.factory(!L,E.validation,"ID is required","MISSING_ID");let l=await $.readJob(h,R,{id:L});b.factory(!l,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND"),await K.deleteFieldValue(h,R,{entityId:L,fieldName:K1.PID,bypassEditableCheck:!0},m)},getProcessStatus:async(h,R,{id:L})=>{b.factory(!L,E.validation,"ID is required","MISSING_ID");let m=await $.readJob(h,R,{id:L});b.factory(!m,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND");let r=m.getFields()[K1.PID],W8=r?parseInt(r.getValue(),10):null;if(!W8||isNaN(W8))return{exists:!1,error:"No PID recorded for this job"};return on(W8)},deleteJob:async(h,R,{id:L},m)=>{b.factory(!L,E.validation,"ID is required","MISSING_ID");let l=$1.extractStoreCode(L),r=await $.readJob(h,R,{id:L});return b.factory(!r,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND"),{...await $.deleteJob(h,R,{id:L},m),storeCode:l}},continueJob:async(h,R,{id:L,prompt:m,model:l,streaming:r,workingDirectory:W8,dockerImage:$8,skipPermissions:f8},B8)=>{b.factory(!L,E.validation,"ID is required","MISSING_ID"),b.factory(!m,E.validation,"Prompt is required","MISSING_PROMPT");let S8=$1.extractStoreCode(L),g8=await $.readJob(h,R,{id:L});b.factory(!g8,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND");let C8=g8.getFields(),x8=C8[K1.STATUS]?.getValue();b.factory(x8!=="completed"&&x8!=="error"&&x8!=="stopped",E.validation,"Can only continue completed, error, or stopped jobs","INVALID_STATUS_FOR_CONTINUE");let Y6=C8[K1.SESSION_ID]?.getValue();b.factory(!Y6,E.validation,"Job has no session ID","MISSING_SESSION_ID");let M6=await H(h,R,L),M8;if(M6){let K8=await $.findContentByName(h,R,L,"prompt.md","d");b.factory(!K8,E.notFound,"Prompt document not found","PROMPT_NOT_FOUND");let A8=K8.getPublishedContent()||K8.getDraftContent()||"",N8=A8.match(/---\n## Turn \d+\n/g);M8=(N8?N8.length+1:1)+1;let y8=`
|
|
614
|
+
`.trim(),ai8=async($,K)=>{try{return await $()}catch{return K()}},oi8=($,K)=>{try{return $()}catch{return K()}},i01={copy:async($)=>ai8(async()=>j3(ch,lh(di8),$),async()=>j3(ph,["--copy"],$)),async paste($){let{stdout:K}=await ai8(async()=>j3(ch,lh(ni8),$),async()=>j3(ph,["--paste"],$));return K},copySync:($)=>oi8(()=>v3(ch,lh(di8),$),()=>v3(ph,["--copy"],$)),pasteSync:($)=>oi8(()=>v3(ch,lh(ni8),$),()=>v3(ph,["--paste"],$)).stdout},ln=i01;var ih=(()=>{switch(si8.platform){case"darwin":return ci8;case"win32":return ln;case"android":{if(si8.env.TERMUX_VERSION===void 0)throw Error("You need to install Termux for this module to work on Android: https://termux.com");return Si8}default:{if(_F8)return ln;if(jd())return pi8;return iZ}}})(),d01={async write($){if(typeof $!=="string")throw TypeError(`Expected a string, got ${typeof $}`);await ih.copy({input:$})},async read(){return ih.paste({stripFinalNewline:!1})},writeSync($){if(typeof $!=="string")throw TypeError(`Expected a string, got ${typeof $}`);ih.copySync({input:$})},readSync(){return ih.pasteSync({stripFinalNewline:!1})}},ti8=d01;var n01=()=>{return Object.freeze({copyToClipboard:async(K)=>{try{await ti8.write(K)}catch(Y){throw Error(`Failed to copy to clipboard: ${Y.message}`)}}})},ei8=Object.freeze({create:n01});e6();var $d8=/[/\\:*?"<>|]/,a01=({store:$,fieldService:K,workflowService:Y})=>{let q=["STORY_STATE_CHANGED","STORY_CREATED"],{notify:J,subscribe:z,subscribeAll:W}=PJ.create(q),Z=({entityType:N,entityId:V,fieldName:f,oldValue:C,newValue:I,storeCode:D})=>{if(N!=="s"||f!=="state")return;J("STORY_STATE_CHANGED",{id:V,oldState:C,newState:I})};$.subscribe(v6.FIELD_VALUE_CHANGED,Z);let H=async(N,V,{store:f,workflowName:C},I)=>{let D=C||"Default",x;if(D==="Default")x=await Y.getOrCreateDefaultWorkflow(N,V,f,I);else x=await Y.getWorkflowByName(N,V,{store:f,name:D}),b.factory(!x,E.validation,`Workflow not found: ${D}`,"WORKFLOW_NOT_FOUND");let h=x.fields?.states||[];return b.factory(!h||h.length===0,E.validation,`Workflow "${D}" has no states configured`,"EMPTY_WORKFLOW_STATES"),{statesArray:h,validStates:new Set(h)}},X=async(N,V,f,C)=>{let I=await $.readStory(N,V,{id:f});b.factory(!I,E.notFound,`Story not found: ${f}`,"STORY_NOT_FOUND");let x=I.getFields?.()?.workflow?.getValue?.()||"Default",h=$1.extractStoreCode(f);return await H(N,V,{store:h,workflowName:x},C)};return Object.freeze({createStory:async(N,V,{store:f,name:C,state:I,workflow:D},x)=>{b.factory(!f,E.validation,"Store is required","MISSING_STORE_CODE"),b.factory(f!=="A",E.validation,"Stories can only be created in Project store (A)","SHARED_STORE_NOT_SUPPORTED"),b.factory(!C||!C.trim(),E.validation,"Story name is required","MISSING_NAME"),b.factory($d8.test(C),E.validation,'Story name contains invalid characters: /\\:*?"<>|',"INVALID_CHARS");let h=D||"Default",{statesArray:R,validStates:L}=await H(N,V,{store:f,workflowName:h},x),m=I||R[0];b.factory(!L.has(m),E.validation,`Invalid state '${m}' for workflow '${h}'`,"INVALID_STATE");let l=await $.readStoryRootFolder(N,V,{storeCode:f});b.factory(!l,E.notFound,"Story root folder not found","STORY_ROOT_NOT_FOUND");let r=await $.isDuplicateNameInParent(N,V,l.getObjectId(),C.trim());b.factory(r,E.conflict,`Story "${C.trim()}" already exists`,"DUPLICATE_NAME");let W8=await $.createStory(N,V,{storeCode:f,parentId:l.getObjectId(),name:C.trim(),state:m},x);await K.setFieldValue(N,V,{entityId:W8.getObjectId(),fieldName:"state",value:m},x),await K.setFieldValue(N,V,{entityId:W8.getObjectId(),fieldName:"workflow",value:h},x);let $8=await $.createFolder(N,V,{storeCode:f,parentId:W8.getObjectId(),name:"tasks",subtype:"tasks"},x),B8=(await K.getFieldDefinitionsForType(N,V,{store:f,code:"f",subtype:"tasks"})).find((x8)=>x8.entity.getName()==="states")?.entity;b.factory(!B8,E.notFound,"states field definition not found for f/tasks","FIELD_DEFINITION_NOT_FOUND"),await K.setFieldValue(N,V,{entityId:$8.getObjectId(),fieldDefinitionId:B8.getObjectId(),values:[...lz]},x),x(()=>{J("STORY_CREATED",{id:W8.getObjectId(),name:C.trim(),state:m,workflow:h,storeCode:f})});let S8=W8.toJSON();S8.fields={...S8.fields,state:m,workflow:h};let g8={...S8,storeCode:f},C8=$8.toJSON();return C8.fields={states:[...lz]},g8.tasksFolder=C8,g8},listStories:async(N,V,{store:f})=>{b.factory(!f,E.validation,"Store is required","MISSING_STORE_CODE");let C=await $.listStories(N,V,{storeCode:f}),I=[];for(let D of C){let h=D.getFields().state;b.factory(!h,E.validation,`Story ${D.getObjectId()} missing required state field`,"MISSING_STATE_FIELD"),I.push({...D.toJSON(),storeCode:f})}return I},getStory:async(N,V,{id:f})=>{b.factory(!f,E.validation,"ID is required","MISSING_ID");let C=$1.extractStoreCode(f),I=await $.readStory(N,V,{id:f});b.factory(!I,E.notFound,`Story not found: ${f}`,"STORY_NOT_FOUND");let x=I.getFields().state;return b.factory(!x,E.validation,`Story ${f} missing required state field`,"MISSING_STATE_FIELD"),{...I.toJSON(),storeCode:C}},renameStory:async(N,V,{id:f,name:C},I)=>{b.factory(!f,E.validation,"ID is required","MISSING_ID"),b.factory(!C||!C.trim(),E.validation,"Name is required","MISSING_NAME"),b.factory($d8.test(C),E.validation,'Story name contains invalid characters: /\\:*?"<>|',"INVALID_CHARS");let D=$1.extractStoreCode(f),x=C.trim(),h=await $.readStory(N,V,{id:f});b.factory(!h,E.notFound,`Story not found: ${f}`,"STORY_NOT_FOUND");let R=await $.isDuplicateNameInParent(N,V,h.getParentId(),x,f);b.factory(R,E.conflict,`Story "${x}" already exists`,"DUPLICATE_NAME");let{entity:L}=await $.renameStory(N,V,{id:f,name:x},I);return{...L.toJSON(),storeCode:D}},updateStoryState:async(N,V,{id:f,state:C},I)=>{b.factory(!f,E.validation,"ID is required","MISSING_ID"),b.factory(!C,E.validation,"State is required","MISSING_STATE");let D=$1.extractStoreCode(f),{validStates:x}=await X(N,V,f,I);b.factory(!x.has(C),E.validation,`Invalid state: ${C}`,"INVALID_STATE");let h=await $.readStory(N,V,{id:f});b.factory(!h,E.notFound,`Story not found: ${f}`,"STORY_NOT_FOUND");let L=h.getFields().state;b.factory(!L,E.validation,`Story ${f} missing required state field`,"MISSING_STATE_FIELD");let m=L.getValue(),l=C==="done"&&m!=="done",r=C!=="done"&&m==="done";if(await K.setFieldValue(N,V,{entityId:f,fieldName:"state",value:C},I),l)await K.setFieldValue(N,V,{entityId:f,fieldName:"dateCompleted",value:_6(),bypassEditableCheck:!0},I);else if(r)await K.deleteFieldValue(N,V,{entityId:f,fieldName:"dateCompleted"},I);let W8=h.toJSON();return W8.fields={...W8.fields,state:C},{...W8,storeCode:D}},deleteStory:async(N,V,{id:f},C)=>{b.factory(!f,E.validation,"ID is required","MISSING_ID");let I=$1.extractStoreCode(f),D=await $.readStory(N,V,{id:f});return b.factory(!D,E.notFound,`Story not found: ${f}`,"STORY_NOT_FOUND"),{...await $.deleteStory(N,V,{id:f},C),storeCode:I}},incrementActiveJobCount:async(N,V,{id:f},C)=>{b.factory(!f,E.validation,"ID is required","MISSING_ID");let I=$1.extractStoreCode(f),D=await $.readStory(N,V,{id:f});if(!D)return null;let h=parseInt(D.getFields().activeJobCount?.getValue()||"0",10)+1;await K.setFieldValue(N,V,{entityId:f,fieldName:"activeJobCount",value:String(h),bypassEditableCheck:!0},C);let R=D.toJSON();return R.fields={...R.fields,activeJobCount:String(h)},{...R,storeCode:I}},decrementActiveJobCount:async(N,V,{id:f},C)=>{b.factory(!f,E.validation,"ID is required","MISSING_ID");let I=$1.extractStoreCode(f),D=await $.readStory(N,V,{id:f});if(!D)return null;let x=parseInt(D.getFields().activeJobCount?.getValue()||"0",10);if(x<=0)return{...D.toJSON(),storeCode:I};let h=x-1;await K.setFieldValue(N,V,{entityId:f,fieldName:"activeJobCount",value:String(h),bypassEditableCheck:!0},C);let R=D.toJSON();return R.fields={...R.fields,activeJobCount:String(h)},{...R,storeCode:I}},subscribe:z,subscribeAll:W})},dn=Object.freeze({create:a01});e6();var jV="Workflows",Kd8="Default",o01=({store:$,documentService:K,fieldService:Y,folderService:q})=>{let J=async(P,w,G,j)=>{let T=await $.readSettingsRootFolder(P,w,{storeCode:G});b.factory(!T,E.notFound,"Settings root folder not found","SETTINGS_ROOT_NOT_FOUND");let v=await $.findFolderByName(P,w,T.getObjectId(),jV);if(v)return v;return await $.createFolder(P,w,{storeCode:G,parentId:T.getObjectId(),name:jV},j)},z=async(P,w,G,j)=>{let T=await H(P,w,{store:G,name:Kd8});if(T)return T;return await W(P,w,{store:G,name:Kd8,states:[...EX]},j)},W=async(P,w,{store:G,name:j,states:T},v)=>{b.factory(!G,E.validation,"Store is required","MISSING_STORE_CODE"),b.factory(!j||!j.trim(),E.validation,"Workflow name is required","MISSING_NAME"),b.factory(!T||T.length===0,E.validation,"Workflow must have at least one state","EMPTY_STATES");let k=new Set(T);b.factory(k.size!==T.length,E.validation,"Workflow states must be unique","DUPLICATE_STATES");let N=j.trim(),V=await J(P,w,G,v),f=await $.isDuplicateNameInParent(P,w,V.getObjectId(),N);b.factory(f,E.conflict,`Workflow "${N}" already exists`,"DUPLICATE_WORKFLOW_NAME");let C=await K.createDocument(P,w,{mode:"parentName",store:G,parentId:V.getObjectId(),name:N,subtype:"workflow",fields:{states:T}},v);return{...C,fields:{...C.fields,states:T}}},Z=async(P,w,{store:G})=>{b.factory(!G,E.validation,"Store is required","MISSING_STORE_CODE");let j=await $.readSettingsRootFolder(P,w,{storeCode:G});if(!j)return[];let T=await $.findFolderByName(P,w,j.getObjectId(),jV);if(!T)return[];let v=await $.listContent(P,w,{parentId:T.getObjectId(),type:"d"}),k=[];for(let N of v){let V=N.toJSON(),C=N.getFields?.()?.states?.getValues?.()||[];k.push({...V,storeCode:G,fields:{...V.fields,states:C}})}return k},H=async(P,w,{store:G,name:j})=>{b.factory(!G,E.validation,"Store is required","MISSING_STORE_CODE"),b.factory(!j,E.validation,"Name is required","MISSING_NAME");let T=await $.readSettingsRootFolder(P,w,{storeCode:G});if(!T)return null;let v=await $.findFolderByName(P,w,T.getObjectId(),jV);if(!v)return null;let k=await $.findContentByName(P,w,v.getObjectId(),j.trim(),"d");if(!k)return null;let N=k.toJSON(),f=k.getFields?.()?.states?.getValues?.()||[];return{...N,storeCode:G,fields:{...N.fields,states:f}}};return Object.freeze({createWorkflow:W,listWorkflows:Z,getWorkflowByName:H,getOrCreateDefaultWorkflow:z,updateWorkflow:async(P,w,{id:G,name:j,states:T},v)=>{b.factory(!G,E.validation,"ID is required","MISSING_ID"),b.factory(!j&&!T,E.validation,"At least one of name or states is required","MISSING_UPDATE_DATA");let k=$1.extractStoreCode(G),N=await $.readContent(P,w,{id:G});b.factory(!N,E.notFound,`Workflow not found: ${G}`,"WORKFLOW_NOT_FOUND");let V=N.getName(),C=N.getFields?.()?.states?.getValues?.()||[];if(T){b.factory(T.length===0,E.validation,"Workflow must have at least one state","EMPTY_STATES");let R=new Set(T);b.factory(R.size!==T.length,E.validation,"Workflow states must be unique","DUPLICATE_STATES");let L=C.filter((m)=>!T.includes(m));if(L.length>0){let l=(await $.listStories(P,w,{storeCode:k})).filter((r)=>{return r.getFields?.()?.workflow?.getValue?.()===V});for(let r of L){let W8=l.filter(($8)=>{return $8.getFields?.()?.state?.getValue?.()===r});b.factory(W8.length>0,E.conflict,`Cannot remove state "${r}" - ${W8.length} ${W8.length===1?"story exists":"stories exist"} in this state`,"STATE_IN_USE")}}await Y.setFieldValue(P,w,{entityId:G,fieldName:"states",values:T},v)}let I=V;if(j&&j.trim()!==V){let R=j.trim(),L=await J(P,w,k,v),m=await $.isDuplicateNameInParent(P,w,L.getObjectId(),R,G);b.factory(m,E.conflict,`Workflow "${R}" already exists`,"DUPLICATE_WORKFLOW_NAME");let l=`${jV}/${R}`;await K.updateDocumentPath(P,w,{id:G,path:l,type:"d"},v),I=R;let r=await $.listStories(P,w,{storeCode:k});for(let W8 of r)if(W8.getFields?.()?.workflow?.getValue?.()===V)await Y.setFieldValue(P,w,{entityId:W8.getObjectId(),fieldName:"workflow",value:I},v)}let D=T||C,h=(await $.readContent(P,w,{id:G})).toJSON();return{...h,storeCode:k,fields:{...h.fields,states:D}}},deleteWorkflow:async(P,w,{id:G},j)=>{b.factory(!G,E.validation,"ID is required","MISSING_ID");let T=$1.extractStoreCode(G),v=await $.readContent(P,w,{id:G});b.factory(!v,E.notFound,`Workflow not found: ${G}`,"WORKFLOW_NOT_FOUND");let k=v.getName(),V=(await $.listStories(P,w,{storeCode:T})).filter((C)=>{return C.getFields?.()?.workflow?.getValue?.()===k});return b.factory(V.length>0,E.conflict,`Cannot delete workflow "${k}" - ${V.length} ${V.length===1?"story is":"stories are"} assigned to it`,"WORKFLOW_IN_USE"),{...await K.deleteDocument(P,w,{id:G},j),storeCode:T}},getOrCreateWorkflowsFolder:J})},nn=Object.freeze({create:o01});e6();import{createHash as r01}from"crypto";import{promises as vw}from"fs";import Yd8 from"path";var s01=10485760,qd8=Object.freeze(["image/png","image/jpeg","image/gif","image/webp"]),t01=({assetsDir:$})=>{let K=(H)=>{return r01("sha256").update(H).digest("hex")},Y=(H)=>{let X=H.substring(0,2);return Yd8.join($,X,H)};return Object.freeze({computeHash:K,getAssetPath:Y,exists:async(H)=>{try{return await vw.access(Y(H)),!0}catch{return!1}},write:async(H,X)=>{let O=Y(H),P=Yd8.dirname(O),w=O+".tmp";await vw.mkdir(P,{recursive:!0}),await vw.writeFile(w,X),await vw.rename(w,O)},read:async(H)=>{let X=Y(H);return vw.readFile(X)},remove:async(H)=>{let X=Y(H);try{await vw.unlink(X)}catch(O){if(O.code!=="ENOENT")throw O}},isAllowedMimeType:(H)=>{return qd8.includes(H)},MAX_SIZE_BYTES:s01,ALLOWED_MIME_TYPES:qd8,assetsDir:$})},Jd8=Object.freeze({create:t01});var e01=({store:$,assetsDir:K})=>{let Y=Jd8.create({assetsDir:K});return Object.freeze({createAsset:async(H,X,{store:O,buffer:P,mimeType:w,originalFilename:G,widthPx:j,heightPx:T,displayWidth:v,displayHeight:k},N)=>{b.factory(!O,E.validation,"Store is required","MISSING_STORE_CODE"),b.factory(!P,E.validation,"Binary data is required","MISSING_DATA"),b.factory(!w,E.validation,"MIME type is required","MISSING_MIME_TYPE"),b.factory(!Y.isAllowedMimeType(w),E.validation,`Unsupported MIME type: ${w}. Allowed: ${Y.ALLOWED_MIME_TYPES.join(", ")}`,"UNSUPPORTED_MIME_TYPE");let V=P.length;b.factory(V>Y.MAX_SIZE_BYTES,E.validation,`File too large: ${V} bytes. Maximum: ${Y.MAX_SIZE_BYTES} bytes (10MB)`,"FILE_TOO_LARGE");let f=Y.computeHash(P);if(!await Y.exists(f))await Y.write(f,P);return{...(await $.createAsset(H,X,{storeCode:O,hash:f,mimeType:w,sizeBytes:V,originalFilename:G,widthPx:j,heightPx:T,displayWidth:v,displayHeight:k},N)).toJSON(),storeCode:O}},readAsset:async(H,X,{id:O})=>{b.factory(!O,E.validation,"ID is required","MISSING_ID");let P=await $.readAsset(H,X,{id:O});b.factory(!P,E.notFound,`Asset not found: ${O}`,"ASSET_NOT_FOUND");let w=$1.extractStoreCode(O);return{...P.toJSON(),storeCode:w}},readAssetBinary:async(H,X,{id:O})=>{b.factory(!O,E.validation,"ID is required","MISSING_ID");let P=await $.readAsset(H,X,{id:O});b.factory(!P,E.notFound,`Asset not found: ${O}`,"ASSET_NOT_FOUND");let w=P.getHash(),G;try{G=await Y.read(w)}catch(j){if(j.code==="ENOENT")throw E.notFound(`Blob file not found for asset: ${O}`,"BLOB_NOT_FOUND");throw j}return{buffer:G,mimeType:P.getMimeType(),sizeBytes:P.getSizeBytes(),hash:w,originalFilename:P.getOriginalFilename()}},listAssets:async(H,X,{store:O})=>{return b.factory(!O,E.validation,"Store is required","MISSING_STORE_CODE"),(await $.listAssets(H,X,{storeCode:O})).map((w)=>({...w.toJSON(),storeCode:O}))},deleteAsset:async(H,X,{id:O},P)=>{b.factory(!O,E.validation,"ID is required","MISSING_ID");let w=await $.readAsset(H,X,{id:O});b.factory(!w,E.notFound,`Asset not found: ${O}`,"ASSET_NOT_FOUND");let G=$1.extractStoreCode(O);return{...await $.deleteAsset(H,X,{id:O},P),storeCode:G}}})},an=Object.freeze({create:e01});e6();import{randomUUID as $j1}from"crypto";import{execSync as zd8}from"child_process";var Xd8=["claude","codex"],rn=["pending","running","completed","error","stopped"],Kj1=5000,Wd8="job-service-system",K1={AGENT:"agent",MODEL:"model",STATUS:"status",STARTED_AT:"startedAt",COMPLETED_AT:"completedAt",TOKENS_USED:"tokensUsed",EXIT_CODE:"exitCode",ERROR_MESSAGE:"errorMessage",DURATION_MS:"durationMs",TOTAL_COST_USD:"totalCostUsd",NUM_TURNS:"numTurns",SESSION_ID:"sessionId",WORKING_DIRECTORY:"workingDirectory",PID:"pid",OBJECT_ID:"objectId",STREAMING:"streaming",PARENT_JOB_ID:"parentJobId",BLOCKING:"blocking",DOCKER_IMAGE:"dockerImage",CLEAR_STORY_FLAG:"clearStoryFlag",CLEAR_STATUS_MESSAGE:"clearStatusMessage",SKIP_PERMISSIONS:"skipPermissions"},Yj1=($)=>Xd8.includes($),Zd8=($)=>rn.includes($),qj1=($)=>{let K=new Date,Y=K.toISOString().slice(0,10),q=K.toISOString().slice(11,19).replace(/:/g,"");return`${$}-${Y}-${q}`},Hd8=($)=>{return{R:"running",S:"sleeping",D:"disk_sleep",Z:"zombie",T:"stopped",t:"tracing_stop",X:"dead",I:"idle"}[$]||$},on=($)=>{try{process.kill($,0)}catch(K){if(K.code==="ESRCH")return{exists:!1};if(K.code==="EPERM")return{exists:!0,state:"permission_denied"};return{exists:!1,error:K.message}}try{if(process.platform==="darwin"){let K=zd8(`ps -o state=,comm= -p ${$}`,{encoding:"utf8"}).trim(),[Y,...q]=K.split(/\s+/),J=Y?Y[0]:"unknown";return{exists:!0,state:Hd8(J),command:q.join(" ")}}else{let K=zd8(`cat /proc/${$}/status 2>/dev/null | grep -E '^(State|Name):'`,{encoding:"utf8"}),Y=K.match(/State:\s*(\w)/),q=K.match(/Name:\s*(\S+)/);return{exists:!0,state:Y?Hd8(Y[1]):"unknown",command:q?q[1]:void 0}}}catch{return{exists:!0,state:"unknown"}}},Jj1=({store:$,fieldService:K})=>{let Y=["JOB_STATUS_CHANGED","JOB_STARTED","JOB_COMPLETED","JOB_OUTPUT_CHUNK"],{notify:q,subscribe:J,subscribeAll:z}=PJ.create(Y),W=({entityType:h,entityId:R,fieldName:L,oldValue:m,newValue:l,storeCode:r})=>{if(h!=="j"||L!=="status")return;if(q("JOB_STATUS_CHANGED",{id:R,oldStatus:m,newStatus:l}),l==="running")q("JOB_STARTED",{id:R});if(l==="completed"||l==="error"||l==="stopped")q("JOB_COMPLETED",{id:R,status:l})};$.subscribe(v6.FIELD_VALUE_CHANGED,W);let Z=(h,R,L={})=>{let m=h.toJSON();if(Object.keys(L).length>0)m.fields={...m.fields,...L};return{...m,storeCode:R}},H=async(h,R,L)=>{return await $.findContentByName(h,R,L,"prompt.md","d")!==null},X=async(h,R,L)=>{let m=await $.listContent(h,R,{parentId:L,type:"d"}),l=/^prompt-(\d+)\.md$/,r=m.filter(($8)=>l.test($8.getName()));if(r.length===0)return 0;let W8=r.map(($8)=>{let f8=$8.getName().match(l);return f8?parseInt(f8[1],10):0});return Math.max(...W8)};return Object.freeze({createJob:async(h,R,{store:L,name:m,agent:l,model:r,prompt:W8,workingDirectory:$8,objectId:f8,streaming:B8,parentJobId:S8,blocking:g8,dockerImage:C8,skipPermissions:x8,clearStoryFlag:Y6,clearStatusMessage:M6},M8)=>{b.factory(!L,E.validation,"Store is required","MISSING_STORE_CODE"),b.factory(L!=="A",E.validation,"Jobs can only be created in Project store (A)","SHARED_STORE_NOT_SUPPORTED"),b.factory(!l,E.validation,"Agent is required","MISSING_AGENT"),b.factory(!Yj1(l),E.validation,`Invalid agent: ${l}. Must be one of: ${Xd8.join(", ")}`,"INVALID_AGENT"),b.factory(!W8,E.validation,"Prompt is required","MISSING_PROMPT");let u8=$j1(),Q8=m?.trim()||qj1(l),Y8=await $.readJobRootFolder(h,R,{storeCode:L});b.factory(!Y8,E.notFound,"Job root folder not found","JOB_ROOT_NOT_FOUND");let K8=await $.isDuplicateNameInParent(h,R,Y8.getObjectId(),Q8);b.factory(K8,E.conflict,`Job "${Q8}" already exists`,"DUPLICATE_NAME");let N8=(await $.createJob(h,R,{storeCode:L,parentId:Y8.getObjectId(),name:Q8,status:"pending"},M8)).getObjectId(),I8=new Date().toISOString();if(await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.AGENT,value:l,bypassEditableCheck:!0},M8),await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.STATUS,value:"pending",bypassEditableCheck:!0},M8),await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.STARTED_AT,value:I8,bypassEditableCheck:!0},M8),await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.SESSION_ID,value:u8,bypassEditableCheck:!0},M8),r?.trim())await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.MODEL,value:r.trim(),bypassEditableCheck:!0},M8);if($8?.trim())await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.WORKING_DIRECTORY,value:$8.trim(),bypassEditableCheck:!0},M8);if(f8?.trim())await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.OBJECT_ID,value:f8.trim(),bypassEditableCheck:!0},M8);if(B8)await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.STREAMING,value:"true",bypassEditableCheck:!0},M8);if(S8?.trim())await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.PARENT_JOB_ID,value:S8.trim(),bypassEditableCheck:!0},M8);if(g8)await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.BLOCKING,value:"true",bypassEditableCheck:!0},M8);if(C8?.trim())await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.DOCKER_IMAGE,value:C8.trim(),bypassEditableCheck:!0},M8);if(Y6!==void 0&&Y6!==null)await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.CLEAR_STORY_FLAG,value:String(Y6),bypassEditableCheck:!0},M8);if(M6!==void 0&&M6!==null)await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.CLEAR_STATUS_MESSAGE,value:String(M6),bypassEditableCheck:!0},M8);if(x8!==void 0&&x8!==null)await K.setFieldValue(h,R,{entityId:N8,fieldName:K1.SKIP_PERMISSIONS,value:String(x8),bypassEditableCheck:!0},M8);return await $.createContent(h,R,{storeCode:L,type:"d",parentId:N8,name:"prompt-1.md",initialContent:W8},M8),await $.createContent(h,R,{storeCode:L,type:"d",parentId:N8,name:"output-1.md",initialContent:""},M8),{...(await $.readJob(h,R,{id:N8})).toJSON(),storeCode:L}},listJobs:async(h,R,{store:L,status:m})=>{if(b.factory(!L,E.validation,"Store is required","MISSING_STORE_CODE"),m)b.factory(!Zd8(m),E.validation,`Invalid status: ${m}. Must be one of: ${rn.join(", ")}`,"INVALID_STATUS");let l=await $.listJobs(h,R,{storeCode:L}),r=[];for(let W8 of l){if(m){let f8=W8.getFields()[K1.STATUS];if((f8?f8.getValue():null)!==m)continue}r.push({...W8.toJSON(),storeCode:L})}return r},getJob:async(h,R,{id:L})=>{b.factory(!L,E.validation,"ID is required","MISSING_ID");let m=$1.extractStoreCode(L),l=await $.readJob(h,R,{id:L});return b.factory(!l,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND"),{...l.toJSON(),storeCode:m}},updateJobStatus:async(h,R,{id:L,status:m,exitCode:l,errorMessage:r},W8)=>{b.factory(!L,E.validation,"ID is required","MISSING_ID"),b.factory(!m,E.validation,"Status is required","MISSING_STATUS"),b.factory(!Zd8(m),E.validation,`Invalid status: ${m}. Must be one of: ${rn.join(", ")}`,"INVALID_STATUS");let $8=$1.extractStoreCode(L),f8=await $.readJob(h,R,{id:L});b.factory(!f8,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND");let S8=f8.getFields()[K1.STATUS],g8=S8?S8.getValue():null;if(["completed","error","stopped"].includes(g8))return Z(f8,$8,{});if(await K.setFieldValue(h,R,{entityId:L,fieldName:K1.STATUS,value:m,bypassEditableCheck:!0},W8),m==="completed"||m==="error"||m==="stopped"){let Y6=new Date().toISOString();await K.setFieldValue(h,R,{entityId:L,fieldName:K1.COMPLETED_AT,value:Y6,bypassEditableCheck:!0},W8)}if(l!==void 0&&l!==null)await K.setFieldValue(h,R,{entityId:L,fieldName:K1.EXIT_CODE,value:String(l),bypassEditableCheck:!0},W8);if(r)await K.setFieldValue(h,R,{entityId:L,fieldName:K1.ERROR_MESSAGE,value:r,bypassEditableCheck:!0},W8);let x8={status:m};if(m==="completed"||m==="error"||m==="stopped")x8.completedAt=new Date().toISOString();if(l!==void 0&&l!==null)x8.exitCode=String(l);if(r)x8.errorMessage=r;return Z(f8,$8,x8)},updateJobOutput:async(h,R,{id:L,output:m},l)=>{b.factory(!L,E.validation,"ID is required","MISSING_ID"),b.factory(m===void 0||m===null,E.validation,"Output is required","MISSING_OUTPUT");let r=$1.extractStoreCode(L),W8=await $.readJob(h,R,{id:L});b.factory(!W8,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND");let $8;if(await H(h,R,L))$8=await $.findContentByName(h,R,L,"output.md","d");else{let g8=await X(h,R,L),C8=g8>0?`output-${g8}.md`:"output-1.md";$8=await $.findContentByName(h,R,L,C8,"d")}b.factory(!$8,E.notFound,"Output document not found","OUTPUT_DOC_NOT_FOUND");let B8=$8.getObjectId();return await $.saveDraft(h,R,{id:B8,content:m,sessionId:Wd8},l),await $.publishContent(h,R,{id:B8},l),{...(await $.readJob(h,R,{id:L})).toJSON(),storeCode:r}},updateJobTokens:async(h,R,{id:L,tokensUsed:m},l)=>{b.factory(!L,E.validation,"ID is required","MISSING_ID"),b.factory(m===void 0||m===null,E.validation,"tokensUsed is required","MISSING_TOKENS");let r=$1.extractStoreCode(L),W8=await $.readJob(h,R,{id:L});return b.factory(!W8,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND"),await K.setFieldValue(h,R,{entityId:L,fieldName:K1.TOKENS_USED,value:String(m),bypassEditableCheck:!0},l),Z(W8,r,{tokensUsed:String(m)})},updateJobMetadata:async(h,R,{id:L,durationMs:m,totalCostUsd:l,numTurns:r,sessionId:W8},$8)=>{b.factory(!L,E.validation,"ID is required","MISSING_ID");let f8=$1.extractStoreCode(L),B8=await $.readJob(h,R,{id:L});if(b.factory(!B8,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND"),m!==void 0&&m!==null)await K.setFieldValue(h,R,{entityId:L,fieldName:K1.DURATION_MS,value:String(m),bypassEditableCheck:!0},$8);if(l!==void 0&&l!==null)await K.setFieldValue(h,R,{entityId:L,fieldName:K1.TOTAL_COST_USD,value:String(l),bypassEditableCheck:!0},$8);if(r!==void 0&&r!==null)await K.setFieldValue(h,R,{entityId:L,fieldName:K1.NUM_TURNS,value:String(r),bypassEditableCheck:!0},$8);if(W8!==void 0&&W8!==null)await K.setFieldValue(h,R,{entityId:L,fieldName:K1.SESSION_ID,value:W8,bypassEditableCheck:!0},$8);let S8={};if(m!==void 0&&m!==null)S8.durationMs=String(m);if(l!==void 0&&l!==null)S8.totalCostUsd=String(l);if(r!==void 0&&r!==null)S8.numTurns=String(r);if(W8!==void 0&&W8!==null)S8.sessionId=W8;return Z(B8,f8,S8)},setJobPid:async(h,R,{id:L,pid:m},l)=>{b.factory(!L,E.validation,"ID is required","MISSING_ID"),b.factory(!m,E.validation,"PID is required","MISSING_PID");let r=await $.readJob(h,R,{id:L});b.factory(!r,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND"),await K.setFieldValue(h,R,{entityId:L,fieldName:K1.PID,value:String(m),bypassEditableCheck:!0},l)},clearJobPid:async(h,R,{id:L},m)=>{b.factory(!L,E.validation,"ID is required","MISSING_ID");let l=await $.readJob(h,R,{id:L});b.factory(!l,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND"),await K.deleteFieldValue(h,R,{entityId:L,fieldName:K1.PID,bypassEditableCheck:!0},m)},getProcessStatus:async(h,R,{id:L})=>{b.factory(!L,E.validation,"ID is required","MISSING_ID");let m=await $.readJob(h,R,{id:L});b.factory(!m,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND");let r=m.getFields()[K1.PID],W8=r?parseInt(r.getValue(),10):null;if(!W8||isNaN(W8))return{exists:!1,error:"No PID recorded for this job"};return on(W8)},deleteJob:async(h,R,{id:L},m)=>{b.factory(!L,E.validation,"ID is required","MISSING_ID");let l=$1.extractStoreCode(L),r=await $.readJob(h,R,{id:L});return b.factory(!r,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND"),{...await $.deleteJob(h,R,{id:L},m),storeCode:l}},continueJob:async(h,R,{id:L,prompt:m,model:l,streaming:r,workingDirectory:W8,dockerImage:$8,skipPermissions:f8},B8)=>{b.factory(!L,E.validation,"ID is required","MISSING_ID"),b.factory(!m,E.validation,"Prompt is required","MISSING_PROMPT");let S8=$1.extractStoreCode(L),g8=await $.readJob(h,R,{id:L});b.factory(!g8,E.notFound,`Job not found: ${L}`,"JOB_NOT_FOUND");let C8=g8.getFields(),x8=C8[K1.STATUS]?.getValue();b.factory(x8!=="completed"&&x8!=="error"&&x8!=="stopped",E.validation,"Can only continue completed, error, or stopped jobs","INVALID_STATUS_FOR_CONTINUE");let Y6=C8[K1.SESSION_ID]?.getValue();b.factory(!Y6,E.validation,"Job has no session ID","MISSING_SESSION_ID");let M6=await H(h,R,L),M8;if(M6){let K8=await $.findContentByName(h,R,L,"prompt.md","d");b.factory(!K8,E.notFound,"Prompt document not found","PROMPT_NOT_FOUND");let A8=K8.getPublishedContent()||K8.getDraftContent()||"",N8=A8.match(/---\n## Turn \d+\n/g);M8=(N8?N8.length+1:1)+1;let y8=`
|
|
615
615
|
|
|
616
616
|
---
|
|
617
617
|
## Turn ${M8}
|
|
@@ -762,4 +762,4 @@ ID Remapping (${W} IDs):
|
|
|
762
762
|
`}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:cg1,execute:lg1};var b46=[I46,x46,g46,y46];P6();var ig1=A.object({name:A.string().describe("Story name"),store:A.string().optional().describe('Store code (default: "A")'),state:A.string().optional().describe("Initial state (default: first state in workflow)"),workflow:A.string().optional().describe('Workflow name (default: "Default")')}),dg1=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:ig1,execute:dg1};P6();var ng1=A.object({store:A.string().optional().describe('Store code (default: "A")')}),ag1=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:ng1,execute:ag1};P6();var og1=A.object({id:A.string().describe('Story ID (e.g., "As1")')}),rg1=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:og1,execute:rg1};P6();var sg1=A.object({id:A.string().describe('Story ID (e.g., "As1")'),state:A.string().describe("New state value")}),tg1=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:sg1,execute:tg1};P6();var eg1=A.object({id:A.string().describe('Story ID (e.g., "As1")'),confirm:A.boolean().optional().describe("Set to true to confirm deletion. If false or omitted, returns impact preview.")}),$y1=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})
|
|
763
763
|
State: ${z.fields.state}
|
|
764
764
|
|
|
765
|
-
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:eg1,execute:$y1};P6();var Ky1=A.object({id:A.string().describe('Story ID (e.g., "As1")')}),Yy1=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:Ky1,execute:Yy1};P6();var qy1=A.object({id:A.string().describe('Story ID (e.g., "As1")')}),Jy1=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:qy1,execute:Jy1};var c46=[u46,m46,B46,U46,F46,Q46,p46];P6();var zy1=A.object({name:A.string().describe("Workflow name (must be unique in store)"),states:A.array(A.string()).min(1).describe("Ordered list of state names"),store:A.string().optional().describe('Store code (default: "A")')}),Wy1=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:zy1,execute:Wy1};P6();var Zy1=A.object({store:A.string().optional().describe('Store code (default: "A")')}),Hy1=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:Zy1,execute:Hy1};P6();var Xy1=A.object({name:A.string().optional().describe("Workflow name"),id:A.string().optional().describe('Workflow ID (e.g., "Ad123")'),store:A.string().optional().describe('Store code (default: "A", required if using name)')}).refine(($)=>$.name||$.id,{message:"Either name or id is required"}),Oy1=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:Xy1,execute:Oy1};P6();var Py1=A.object({id:A.string().describe('Workflow ID (e.g., "Ad123")'),name:A.string().optional().describe("New workflow name"),states:A.array(A.string()).min(1).optional().describe("New ordered list of state names")}).refine(($)=>$.name||$.states,{message:"At least one of name or states is required"}),wy1=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:Py1,execute:wy1};P6();var Gy1=A.object({id:A.string().describe('Workflow ID (e.g., "Ad123")')}),Ty1=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:Gy1,execute:Ty1};var o46=[l46,i46,d46,n46,a46];P6();var jy1=A.object({id:A.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:jy1,execute:vy1};var s46=[r46];P6();var Vy1=A.object({store:A.string().optional().describe('Store code (default: "A")'),status:A.string().optional().describe("Filter by status (pending, running, completed, error, stopped)")}),Ay1=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:Vy1,execute:Ay1};P6();var My1=A.object({id:A.string().describe('Job ID (e.g., "Aj1")')}),_y1=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:My1,execute:_y1};P6();var ky1=A.object({id:A.string().describe('Job ID (e.g., "Aj1")')}),Ny1=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:ky1,execute:Ny1};P6();var fy1=A.object({id:A.string().describe('Job ID (e.g., "Aj1")')}),Ry1=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:fy1,execute:Ry1};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 Cy1=A.object({agent:A.enum(["claude","codex"]).describe("Agent type (claude or codex)"),prompt:A.string().describe("Prompt content"),name:A.string().optional().describe("Job name (auto-generated if omitted)"),model:A.string().optional().describe("Model for Claude agent"),workingDirectory:A.string().optional().describe("Working directory"),objectId:A.string().optional().describe("ID of entity to associate with"),streaming:A.boolean().optional().describe("Enable streaming output"),skipPermissions:A.boolean().optional().describe("Skip permission prompts (default: true). Set to false to enable permission prompts."),parentJobId:A.string().optional().describe("Parent job ID for hierarchy tracking"),blocking:A.boolean().optional().describe("Wait for job completion with 60-minute timeout (default: true). Set to false for asynchronous operation."),dockerImage:A.string().optional().describe("Docker image for containerized execution"),store:A.string().optional().describe('Store code (default: "A")')}),Dy1=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:Cy1,execute:Dy1};P6();var hy1=A.object({id:A.string().describe('Job ID to continue (e.g., "Aj1")'),prompt:A.string().describe("Follow-up prompt"),model:A.string().optional().describe("Model (allows changing between turns)"),dockerImage:A.string().optional().describe("Docker image for containerized execution"),skipPermissions:A.boolean().optional().describe("Skip permission prompts (Claude agent only)"),blocking:A.boolean().optional().describe("Wait for job completion with 60-minute timeout (default: true). Set to false for asynchronous operation.")}),Ly1=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:hy1,execute:Ly1};var z$6=[t46,e46,$$6,K$6,q$6,J$6];P6();e6();var Ey1=A.object({query:A.string().describe("FTS5 search query"),field_name:A.string().optional().describe("Filter by field definition name"),store:A.string().optional().describe('Store code (default: "A")')}),Sy1=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:Ey1,execute:Sy1};P6();e6();var Iy1=A.object({query:A.string().describe("FTS5 search query"),store:A.string().optional().describe('Store code (default: "A")'),limit:A.number().int().positive().optional().describe("Maximum results (default: 20)"),offset:A.number().int().min(0).optional().describe("Pagination offset (default: 0)"),start_marker:A.string().optional().describe('Snippet highlight start marker (default: "<mark>")'),end_marker:A.string().optional().describe('Snippet highlight end marker (default: "</mark>")')}),xy1=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:Iy1,execute:xy1};var H$6=[W$6,Z$6];var gy1=({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:gy1});var by1=Zs.default("caw:mcp"),b5=Zs.default("caw:mcp:session"),uy1=({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=yy1(),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)by1("Cleaned up %d idle sessions",H)}})},O$6=Object.freeze({create:uy1});var my1=86400000,By1=300000,Uy1=({mcpSessionManager:$})=>{let{jobFns:K,controlFns:Y}=hD.create({name:"cleanup-idle-mcp-sessions",interval:By1,execute:async()=>{$.cleanupIdle(my1)}});return{job:Object.freeze(K),control:Y}},P$6=Object.freeze({create:Uy1});var zS=o$6.default("caw:server"),kb1=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",(V,f)=>{f.json({status:"ok"})}),j.get("/api/info",(V,f)=>{f.json({version:"1.0.92"})}),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 V=O$6.create({core:G});G.registerCronJob(P$6,{mcpSessionManager:V}),bo8.create(j,{core:G,mcpSessionManager:V}),zS("MCP subsystem initialized")}if(O){zS("Initializing CLI Adapter subsystem...");let V=(await Promise.resolve().then(() => (b$6(),y$6))).default,f=(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:V.create(),aliasGenerator:f.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((V)=>{T=j.listen($,()=>{let f=T.address().port;V(f)}),T.on("connection",(f)=>{v.add(f),f.on("close",()=>{v.delete(f)})})})},stop:async()=>{if(G.stopAllCrons(),T){for(let V of v)V.destroy();return v.clear(),new Promise((V)=>{T.close(()=>{V()})})}}})},r$6=Object.freeze({create:kb1});var fb1=3131,Rb1=WS.join(WS.dirname(Nb1(import.meta.url)),"public_html"),Cb1=!0,Db1=!0,hb1=!0,Lb1=!0,Eb1=!1,Sb1=!0,Ib1=!0,xb1=!0,Pz=($,K)=>$!==void 0?$==="true":K,gb1=()=>{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")}},yb1=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"))},bb1=()=>{let{envDir:$,databaseFilepath:K,assetsDir:Y}=gb1(),q=process.env.CAW_PORT?Number(process.env.CAW_PORT):fb1,J=process.env.STATIC_PATH||Rb1,z=Pz(process.env.LAZY_CREATE_DB,Cb1),W=Pz(process.env.ENABLE_REST,Db1),Z=Pz(process.env.ENABLE_MCP,hb1),H=Pz(process.env.ENABLE_CLI,Lb1),X=Pz(process.env.ENABLE_WEBLLM_WSS,Eb1),O=Pz(process.env.ENABLE_SSE,Sb1),P=Pz(process.env.ENABLE_STATIC,Ib1),w=Pz(process.env.ENABLE_CRONS,xb1);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 yb1(bb1()).catch(($)=>{console.error("ERROR: Failed to start server:",$),process.exit(1)});
|
|
765
|
+
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:eg1,execute:$y1};P6();var Ky1=A.object({id:A.string().describe('Story ID (e.g., "As1")')}),Yy1=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:Ky1,execute:Yy1};P6();var qy1=A.object({id:A.string().describe('Story ID (e.g., "As1")')}),Jy1=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:qy1,execute:Jy1};var c46=[u46,m46,B46,U46,F46,Q46,p46];P6();var zy1=A.object({name:A.string().describe("Workflow name (must be unique in store)"),states:A.array(A.string()).min(1).describe("Ordered list of state names"),store:A.string().optional().describe('Store code (default: "A")')}),Wy1=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:zy1,execute:Wy1};P6();var Zy1=A.object({store:A.string().optional().describe('Store code (default: "A")')}),Hy1=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:Zy1,execute:Hy1};P6();var Xy1=A.object({name:A.string().optional().describe("Workflow name"),id:A.string().optional().describe('Workflow ID (e.g., "Ad123")'),store:A.string().optional().describe('Store code (default: "A", required if using name)')}).refine(($)=>$.name||$.id,{message:"Either name or id is required"}),Oy1=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:Xy1,execute:Oy1};P6();var Py1=A.object({id:A.string().describe('Workflow ID (e.g., "Ad123")'),name:A.string().optional().describe("New workflow name"),states:A.array(A.string()).min(1).optional().describe("New ordered list of state names")}).refine(($)=>$.name||$.states,{message:"At least one of name or states is required"}),wy1=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:Py1,execute:wy1};P6();var Gy1=A.object({id:A.string().describe('Workflow ID (e.g., "Ad123")')}),Ty1=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:Gy1,execute:Ty1};var o46=[l46,i46,d46,n46,a46];P6();var jy1=A.object({id:A.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:jy1,execute:vy1};var s46=[r46];P6();var Vy1=A.object({store:A.string().optional().describe('Store code (default: "A")'),status:A.string().optional().describe("Filter by status (pending, running, completed, error, stopped)")}),Ay1=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:Vy1,execute:Ay1};P6();var My1=A.object({id:A.string().describe('Job ID (e.g., "Aj1")')}),_y1=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:My1,execute:_y1};P6();var ky1=A.object({id:A.string().describe('Job ID (e.g., "Aj1")')}),Ny1=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:ky1,execute:Ny1};P6();var fy1=A.object({id:A.string().describe('Job ID (e.g., "Aj1")')}),Ry1=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:fy1,execute:Ry1};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 Cy1=A.object({agent:A.enum(["claude","codex"]).describe("Agent type (claude or codex)"),prompt:A.string().describe("Prompt content"),name:A.string().optional().describe("Job name (auto-generated if omitted)"),model:A.string().optional().describe("Model for Claude agent"),workingDirectory:A.string().optional().describe("Working directory"),objectId:A.string().optional().describe("ID of entity to associate with"),streaming:A.boolean().optional().describe("Enable streaming output"),skipPermissions:A.boolean().optional().describe("Skip permission prompts (default: true). Set to false to enable permission prompts."),parentJobId:A.string().optional().describe("Parent job ID for hierarchy tracking"),blocking:A.boolean().optional().describe("Wait for job completion with 60-minute timeout (default: true). Set to false for asynchronous operation."),dockerImage:A.string().optional().describe("Docker image for containerized execution"),store:A.string().optional().describe('Store code (default: "A")')}),Dy1=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:Cy1,execute:Dy1};P6();var hy1=A.object({id:A.string().describe('Job ID to continue (e.g., "Aj1")'),prompt:A.string().describe("Follow-up prompt"),model:A.string().optional().describe("Model (allows changing between turns)"),dockerImage:A.string().optional().describe("Docker image for containerized execution"),skipPermissions:A.boolean().optional().describe("Skip permission prompts (Claude agent only)"),blocking:A.boolean().optional().describe("Wait for job completion with 60-minute timeout (default: true). Set to false for asynchronous operation.")}),Ly1=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:hy1,execute:Ly1};var z$6=[t46,e46,$$6,K$6,q$6,J$6];P6();e6();var Ey1=A.object({query:A.string().describe("FTS5 search query"),field_name:A.string().optional().describe("Filter by field definition name"),store:A.string().optional().describe('Store code (default: "A")')}),Sy1=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:Ey1,execute:Sy1};P6();e6();var Iy1=A.object({query:A.string().describe("FTS5 search query"),store:A.string().optional().describe('Store code (default: "A")'),limit:A.number().int().positive().optional().describe("Maximum results (default: 20)"),offset:A.number().int().min(0).optional().describe("Pagination offset (default: 0)"),start_marker:A.string().optional().describe('Snippet highlight start marker (default: "<mark>")'),end_marker:A.string().optional().describe('Snippet highlight end marker (default: "</mark>")')}),xy1=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:Iy1,execute:xy1};var H$6=[W$6,Z$6];var gy1=({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:gy1});var by1=Zs.default("caw:mcp"),b5=Zs.default("caw:mcp:session"),uy1=({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=yy1(),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)by1("Cleaned up %d idle sessions",H)}})},O$6=Object.freeze({create:uy1});var my1=86400000,By1=300000,Uy1=({mcpSessionManager:$})=>{let{jobFns:K,controlFns:Y}=hD.create({name:"cleanup-idle-mcp-sessions",interval:By1,execute:async()=>{$.cleanupIdle(my1)}});return{job:Object.freeze(K),control:Y}},P$6=Object.freeze({create:Uy1});var zS=o$6.default("caw:server"),kb1=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",(V,f)=>{f.json({status:"ok"})}),j.get("/api/info",(V,f)=>{f.json({version:"1.0.93"})}),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 V=O$6.create({core:G});G.registerCronJob(P$6,{mcpSessionManager:V}),bo8.create(j,{core:G,mcpSessionManager:V}),zS("MCP subsystem initialized")}if(O){zS("Initializing CLI Adapter subsystem...");let V=(await Promise.resolve().then(() => (b$6(),y$6))).default,f=(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:V.create(),aliasGenerator:f.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((V)=>{T=j.listen($,()=>{let f=T.address().port;V(f)}),T.on("connection",(f)=>{v.add(f),f.on("close",()=>{v.delete(f)})})})},stop:async()=>{if(G.stopAllCrons(),T){for(let V of v)V.destroy();return v.clear(),new Promise((V)=>{T.close(()=>{V()})})}}})},r$6=Object.freeze({create:kb1});var fb1=3131,Rb1=WS.join(WS.dirname(Nb1(import.meta.url)),"public_html"),Cb1=!0,Db1=!0,hb1=!0,Lb1=!0,Eb1=!1,Sb1=!0,Ib1=!0,xb1=!0,Pz=($,K)=>$!==void 0?$==="true":K,gb1=()=>{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")}},yb1=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"))},bb1=()=>{let{envDir:$,databaseFilepath:K,assetsDir:Y}=gb1(),q=process.env.CAW_PORT?Number(process.env.CAW_PORT):fb1,J=process.env.STATIC_PATH||Rb1,z=Pz(process.env.LAZY_CREATE_DB,Cb1),W=Pz(process.env.ENABLE_REST,Db1),Z=Pz(process.env.ENABLE_MCP,hb1),H=Pz(process.env.ENABLE_CLI,Lb1),X=Pz(process.env.ENABLE_WEBLLM_WSS,Eb1),O=Pz(process.env.ENABLE_SSE,Sb1),P=Pz(process.env.ENABLE_STATIC,Ib1),w=Pz(process.env.ENABLE_CRONS,xb1);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 yb1(bb1()).catch(($)=>{console.error("ERROR: Failed to start server:",$),process.exit(1)});
|