alchemylab 1.4.4 → 1.4.6
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 +148 -130
- package/dist/http-server.js +207 -180
- package/dist/index.js +207 -180
- package/dist/mcp-direct.js +207 -180
- package/package.json +2 -2
package/dist/mcp-direct.js
CHANGED
|
@@ -529,42 +529,55 @@ for(const s of t.lineRanges){const a=await o(e,t.path,s.start,s.end,i)
|
|
|
529
529
|
a&&(n(a.message)||r.push({range:`${s.start}-${s.end}`,commit:a}))}if(r.length>0){const e=r.map((e=>`Lines ${e.range}: ${e.commit.hash.substring(0,8)} - ${e.commit.message}`)).join("; "),n=[`\u26a0\ufe0f Warning: Lines ${m} were last modified by external commits (not alchemy).`,"","Commit details: "+e,"\nThese changes may have been made manually or by another tool.\nReview recent commits before proceeding."].join("\n")
|
|
530
530
|
return{hasExternalEdits:!0,conflictingLines:t.lineRanges.flatMap((e=>Array.from({length:e.end-e.start+1},((t,r)=>e.start+r)))),message:n,debugInfo:{detectionRan:!0,affectedRegion:m,uncommittedChanges:"none",lastCommit:r[0].commit.message,wasLastCommitAlchemy:!1,diffPreview:e,overlapDetected:!0}}}return{hasExternalEdits:!1,conflictingLines:[],debugInfo:{detectionRan:!0,affectedRegion:m,uncommittedChanges:"none",lastCommit:h,wasLastCommitAlchemy:p,diffPreview:"no uncommitted changes, last commits from alchemy",overlapDetected:!1}}}const y={path:t.path,lineRanges:d,totalLines:d.reduce(((e,t)=>e+(t.end-t.start+1)),0),operationType:"modification"},w=(0,a.getOverlappingLines)(t,y)
|
|
531
531
|
return 0===w.length?{hasExternalEdits:!1,conflictingLines:[],message:"File has uncommitted changes, but they do not conflict with this operation.",debugInfo:{detectionRan:!0,affectedRegion:m,uncommittedChanges:g,lastCommit:h,wasLastCommitAlchemy:p,diffPreview:f,overlapDetected:!1}}:{hasExternalEdits:!0,conflictingLines:w,message:["\u26a0\ufe0f Warning: File has uncommitted changes in lines you're about to modify.\n","Affected lines: "+m,"Conflicting lines: "+s(w),"",p?"Last commit was by alchemy, but file has been edited since.":"Last commit was NOT from alchemy - these may be manual edits.","\nReview the changes before proceeding."].join("\n"),details:{totalExternalChanges:y.totalLines,overlappingChanges:w.length,changedLineRanges:d},debugInfo:{detectionRan:!0,affectedRegion:m,uncommittedChanges:g,lastCommit:h,wasLastCommitAlchemy:p,diffPreview:f,overlapDetected:!0}}}catch(e){return i.error("Failed to detect external edits",{path:t.path,error:(0,l.getErrorMessage)(e)}),{hasExternalEdits:!1,conflictingLines:[],message:"Unable to check for external edits (Git error). Proceeding with caution."}}},exports.hasUncommittedChanges=async function(e,t){try{return(await e.status([t])).files.some((e=>e.path===t))}catch(e){return!1}}
|
|
532
|
-
const a=t(9947),c=i(t(6928)),l=t(8824)},
|
|
532
|
+
const a=t(9947),c=i(t(6928)),l=t(8824)},1375(e,exports,t){"use strict"
|
|
533
|
+
async function r(e,t){const{progressToken:r,sendNotification:n}=e,o=e.intervalMs??1e4
|
|
534
|
+
if(null==r||!n)return t()
|
|
535
|
+
let s=0
|
|
536
|
+
const i=setInterval((()=>{s+=1
|
|
537
|
+
const t=e.message?.()
|
|
538
|
+
n({method:"notifications/progress",params:{progressToken:r,progress:s,...t?{message:t}:{}}}).catch((()=>{}))}),o)
|
|
539
|
+
try{return await t()}finally{clearInterval(i)}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.withHeartbeat=r,exports.runTrackedShellWithHeartbeat=function(e,t,o,s){return r({progressToken:s?.progressToken,sendNotification:s?.sendNotification,message(){return"running "+o.name}},(()=>(0,n.runTrackedShellCommand)(e,t,o)))}
|
|
540
|
+
const n=t(4600)},1387(e,exports,t){"use strict"
|
|
533
541
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.WorkspaceRequestProcessor=void 0
|
|
534
|
-
const r=t(
|
|
535
|
-
exports.WorkspaceRequestProcessor=class{constructor(e,t,r,n,o){this.gitAdapter=e,this.conflictDetector=t,this.safetyAnalyzer=r,this.conflictResolver=n,this.logger=o}async completeRequest(e,t,
|
|
536
|
-
if(!
|
|
537
|
-
throw
|
|
538
|
-
|
|
539
|
-
try{const
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
542
|
+
const r=t(3807),n=t(7075),o=t(5964),s=t(8824)
|
|
543
|
+
exports.WorkspaceRequestProcessor=class{constructor(e,t,r,n,o){this.gitAdapter=e,this.conflictDetector=t,this.safetyAnalyzer=r,this.conflictResolver=n,this.logger=o}async completeRequest(e,t,i){const a=n.WorkspaceValidation.validateRequestId(e)
|
|
544
|
+
if(!a.isValid){const t="Invalid request ID: "+a.errors.join(", ")
|
|
545
|
+
throw n.WorkspaceLogging.logOperation(this.logger,"error",t,e,this.gitAdapter.mode,"completeRequest"),Error(t)}const c=a.sanitized,l="requests/"+c,d=i?.skipConflictDetection||!1
|
|
546
|
+
n.WorkspaceLogging.logOperation(this.logger,"info","Starting request completion",e,this.gitAdapter.mode,"completeRequest",{requestTitle:t,branchName:l,skipConflictDetection:d})
|
|
547
|
+
try{const n=await this.gitAdapter.setupWorkspace(c)
|
|
548
|
+
this.logger.info(`Starting ${this.gitAdapter.mode} request completion`,{requestId:e,branchName:l,workingDirectory:n.workingDirectory,skipConflictDetection:d,preMergeCommitEnabled:!0})
|
|
549
|
+
try{const e=(0,r.simpleGit)(n.workingDirectory),t=await e.raw(["rev-list","--count","main..HEAD"]),o=parseInt(t.trim(),10)
|
|
550
|
+
if(Number.isFinite(o)&&0===o){let t="\n\nNo uncommitted changes either \u2014 the request branch is identical to main. The work either never started, or was discarded before completion."
|
|
551
|
+
try{const r=(await e.raw(["status","--porcelain"])).trim()
|
|
552
|
+
r&&(t=`\n\nUncommitted changes detected in the worktree:\n${r}\n\nThese were never committed \u2014 they were likely created by a raw shell command (touch / echo / cat >) that bypassed alchemy's auto-commit hook. Use write_file / replace_in_files / quick_edit for file changes, or stage and commit manually before completing.`)}catch{}throw Error(`Branch \`${l}\` has no commits ahead of main \u2014 there is nothing to merge.${t}`)}}catch(t){if(t instanceof Error&&t.message.includes("has no commits ahead of main"))throw t
|
|
553
|
+
this.logger.warn("Pre-merge empty-branch check failed; proceeding",{requestId:e,error:t instanceof Error?t.message:t+""})}if(d)return this.logger.info("Skipping conflict detection (already conflicted request)",{requestId:e,reason:"skipConflictDetection flag set"}),await this.executeDirectMerge(n,t)
|
|
554
|
+
this.logger.info("Starting conflict detection",{requestId:e,branchName:l,mode:this.gitAdapter.mode})
|
|
555
|
+
const s=await this.gitAdapter.detectConflicts(n,{sourceBranch:l,targetBranch:"main",requestId:e})
|
|
556
|
+
if(this.logger.info("Conflict detection completed",{requestId:e,hasConflicts:s.hasConflicts,conflictedFiles:s.conflictedFiles.length,summary:s.summary,detectionMethod:s.detectionMethod}),s.hasConflicts){this.logger.warn("Conflicts detected, manual resolution or AI assistance required",{requestId:e,conflictedFiles:s.conflictedFiles.length,files:s.conflictedFiles.map((e=>e.path))})
|
|
557
|
+
const t={requestId:e,conflictedFiles:s.conflictedFiles,summary:s.summary,resolutionInstructions:s.resolutionInstructions,detectionMethod:s.detectionMethod,mode:this.gitAdapter.mode,workingDirectory:n.workingDirectory,rawConflictContent:s.rawConflictContent}
|
|
558
|
+
throw(0,o.createConflictDetectionError)(s.resolutionInstructions,t)}return this.logger.info("No conflicts detected, proceeding with clean merge",{requestId:e,branchName:l,mode:this.gitAdapter.mode}),await this.executeCleanMerge(n,t)}catch(t){if(this.logger.error(`Request completion failed in ${this.gitAdapter.mode} mode`,{requestId:e,error:(0,s.getErrorMessage)(t)}),o.ConflictDetectionError.isConflictDetectionError(t))this.logger.info("Preserving worktree for conflict resolution",{requestId:c,reason:"conflict-detection-requires-worktree-preservation",mode:this.gitAdapter.mode})
|
|
559
|
+
else if("multi-agent"===this.gitAdapter.mode)try{const e=await this.gitAdapter.setupWorkspace(c),t=await this.gitAdapter.cleanup(e)
|
|
560
|
+
t.success?this.logger.info("Successfully cleaned up worktree after actual failure",{requestId:c,reason:"failsafe-cleanup-non-conflict-failure"}):this.logger.warn("Failsafe cleanup also failed",{requestId:c,cleanupMessage:t.message})}catch(e){this.logger.warn("Exception during failsafe cleanup",{requestId:c,cleanupError:e instanceof Error?e.message:e+""})}throw t}}async executeDirectMerge(e,t){this.logger.info("Executing direct merge for resolved conflicts",{requestId:e.requestId,branchName:e.branchName,mode:e.mode})
|
|
548
561
|
try{await this.gitAdapter.stageAndCommitChanges(e)
|
|
549
562
|
const r=t?`Merge ${e.branchName}-${t} (resolved conflicts)`:`Merge ${e.branchName} (resolved conflicts)`,n=await this.gitAdapter.executeMerge(e,{strategy:"direct",mergeMessage:r,skipConflictDetection:!0,gitStrategy:"theirs"})
|
|
550
563
|
this.logger.info("Direct merge completed successfully",{requestId:e.requestId,mergeCommitHash:n.mergeCommitHash.substring(0,8),strategy:n.strategy})
|
|
551
564
|
const o=await this.gitAdapter.cleanup(e)
|
|
552
|
-
return this.gitAdapter.updateState(e,!0),{mergeCommitHash:n.mergeCommitHash,mergedFiles:n.mergedFiles,cleanedUp:o.success,autoMergeInfo:{wasAutoMerged:!0,strategy:"direct-merge-theirs",safetyReason:"conflicts-already-resolved",userMessage:"Successfully merged resolved conflicts using request branch version",technicalDetails:"Direct merge executed with -X theirs strategy to preserve user resolution"}}}catch(t){if(this.logger.error("Direct merge failed",{requestId:e.requestId,error:(0,
|
|
565
|
+
return this.gitAdapter.updateState(e,!0),{mergeCommitHash:n.mergeCommitHash,mergedFiles:n.mergedFiles,cleanedUp:o.success,autoMergeInfo:{wasAutoMerged:!0,strategy:"direct-merge-theirs",safetyReason:"conflicts-already-resolved",userMessage:"Successfully merged resolved conflicts using request branch version",technicalDetails:"Direct merge executed with -X theirs strategy to preserve user resolution"}}}catch(t){if(this.logger.error("Direct merge failed",{requestId:e.requestId,error:(0,s.getErrorMessage)(t)}),o.ConflictDetectionError.shouldPreserveWorktree(t)||t instanceof Error&&(t.message.toLowerCase().includes("conflict")||t.message.toLowerCase().includes("merge")))this.logger.info("Preserving worktree for conflict-related merge failure",{requestId:e.requestId,reason:"conflict-related-merge-failure-preserve-worktree"})
|
|
553
566
|
else try{const t=await this.gitAdapter.cleanup(e)
|
|
554
|
-
t.success?this.logger.info("Successfully cleaned up worktree after non-conflict merge failure",{requestId:e.requestId,reason:"direct-merge-failure-cleanup"}):this.logger.warn("Cleanup after merge failure also failed",{requestId:e.requestId,cleanupMessage:t.message})}catch(t){this.logger.warn("Exception during cleanup after merge failure",{requestId:e.requestId,cleanupError:t instanceof Error?t.message:t+""})}const r=(0,
|
|
567
|
+
t.success?this.logger.info("Successfully cleaned up worktree after non-conflict merge failure",{requestId:e.requestId,reason:"direct-merge-failure-cleanup"}):this.logger.warn("Cleanup after merge failure also failed",{requestId:e.requestId,cleanupMessage:t.message})}catch(t){this.logger.warn("Exception during cleanup after merge failure",{requestId:e.requestId,cleanupError:t instanceof Error?t.message:t+""})}const r=(0,s.getErrorMessage)(t)
|
|
555
568
|
throw r.toLowerCase().includes("conflict")||r.toLowerCase().includes("merge")?Error(`Merge failed due to unresolved conflicts in ${e.branchName}. The conflict resolution validation may have missed some conflict markers. Please verify all conflicts are resolved and try again.`):t}}async executeCleanMerge(e,t){this.logger.info("Executing clean merge (no conflicts)",{requestId:e.requestId,branchName:e.branchName,mode:e.mode})
|
|
556
569
|
try{const r=t?`Merge ${e.branchName}-${t}`:"Merge "+e.branchName,n=await this.gitAdapter.executeMerge(e,{strategy:"auto-merge",mergeMessage:r,skipConflictDetection:!1})
|
|
557
570
|
this.logger.info("Clean merge completed successfully",{requestId:e.requestId,mergeCommitHash:n.mergeCommitHash.substring(0,8)})
|
|
558
571
|
const o=await this.gitAdapter.cleanup(e)
|
|
559
|
-
return this.gitAdapter.updateState(e,!0),{mergeCommitHash:n.mergeCommitHash,mergedFiles:n.mergedFiles,cleanedUp:o.success,autoMergeInfo:{wasAutoMerged:!1,strategy:"clean-merge",safetyReason:"no-conflicts-detected",userMessage:"Successfully merged without conflicts",technicalDetails:"Standard Git merge executed without conflict resolution"}}}catch(t){const r=(0,
|
|
572
|
+
return this.gitAdapter.updateState(e,!0),{mergeCommitHash:n.mergeCommitHash,mergedFiles:n.mergedFiles,cleanedUp:o.success,autoMergeInfo:{wasAutoMerged:!1,strategy:"clean-merge",safetyReason:"no-conflicts-detected",userMessage:"Successfully merged without conflicts",technicalDetails:"Standard Git merge executed without conflict resolution"}}}catch(t){const r=(0,s.getErrorMessage)(t)
|
|
560
573
|
this.logger.error("Clean merge failed",{requestId:e.requestId,error:r})
|
|
561
|
-
const
|
|
562
|
-
if(
|
|
574
|
+
const n=r.includes("CONFLICTS:")||r.includes("Merge conflict")||r.includes("merge conflict")||r.toLowerCase().includes("conflict")
|
|
575
|
+
if(n){this.logger.warn("Merge failed with conflicts that were not detected by merge-tree",{requestId:e.requestId,errorMessage:r,reason:"merge-tree-false-negative"}),this.logger.info("Re-running conflict detection after merge failure",{requestId:e.requestId})
|
|
563
576
|
try{const t=await this.gitAdapter.detectConflicts(e,{sourceBranch:e.branchName,targetBranch:e.branchInfo?.mainBranch||"main",requestId:e.requestId})
|
|
564
577
|
if(t.hasConflicts){this.logger.info("Re-detection confirmed conflicts",{requestId:e.requestId,conflictedFiles:t.conflictedFiles.length})
|
|
565
578
|
const r={requestId:e.requestId,conflictedFiles:t.conflictedFiles,summary:t.summary,resolutionInstructions:t.resolutionInstructions,detectionMethod:t.detectionMethod+" (post-merge-failure)",mode:this.gitAdapter.mode,workingDirectory:e.workingDirectory,rawConflictContent:t.rawConflictContent}
|
|
566
|
-
throw(0,
|
|
567
|
-
this.logger.warn("Re-detection failed",{requestId:e.requestId,error:t instanceof Error?t.message:t+""})}}if(
|
|
579
|
+
throw(0,o.createConflictDetectionError)(t.resolutionInstructions,r)}this.logger.warn("Re-detection did not find conflicts - merge failure for other reason",{requestId:e.requestId})}catch(t){if(o.ConflictDetectionError.isConflictDetectionError(t))throw t
|
|
580
|
+
this.logger.warn("Re-detection failed",{requestId:e.requestId,error:t instanceof Error?t.message:t+""})}}if(o.ConflictDetectionError.shouldPreserveWorktree(t)||n)this.logger.info("Preserving worktree for conflict-related clean merge failure",{requestId:e.requestId,reason:"conflict-related-clean-merge-failure-preserve-worktree"})
|
|
568
581
|
else try{const t=await this.gitAdapter.cleanup(e)
|
|
569
582
|
t.success?this.logger.info("Successfully cleaned up worktree after non-conflict clean merge failure",{requestId:e.requestId,reason:"clean-merge-failure-cleanup"}):this.logger.warn("Cleanup after clean merge failure also failed",{requestId:e.requestId,cleanupMessage:t.message})}catch(t){this.logger.warn("Exception during cleanup after clean merge failure",{requestId:e.requestId,cleanupError:t instanceof Error?t.message:t+""})}throw t}}}},1391(e,exports,t){"use strict"
|
|
570
583
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
@@ -594,31 +607,31 @@ k.info(`Generating tools list with testsRequired=${e}, authenticated=${t}`)
|
|
|
594
607
|
const r={testsRequired:e,authenticated:t}
|
|
595
608
|
return(0,f.generateVisibleToolsList)(r)}
|
|
596
609
|
let S=E(),q=[]
|
|
597
|
-
S.then((e=>{q=e})).catch((e=>{k.error("Error generating initial tools list",{error:(0,d.getErrorMessage)(e)}),q=[]})),e.setRequestHandler(c.ListToolsRequestSchema,(async()=>{try{return q=await E(),{tools:q}}catch(e){return k.error("Error generating tools list",{error:(0,d.getErrorMessage)(e)}),{tools:[]}}})),e.setRequestHandler(c.CallToolRequestSchema,(async
|
|
598
|
-
try{const{name:n,arguments:b={},_meta:
|
|
599
|
-
const
|
|
610
|
+
S.then((e=>{q=e})).catch((e=>{k.error("Error generating initial tools list",{error:(0,d.getErrorMessage)(e)}),q=[]})),e.setRequestHandler(c.ListToolsRequestSchema,(async()=>{try{return q=await E(),{tools:q}}catch(e){return k.error("Error generating tools list",{error:(0,d.getErrorMessage)(e)}),{tools:[]}}})),e.setRequestHandler(c.CallToolRequestSchema,(async(e,c)=>{let l
|
|
611
|
+
try{const{name:n,arguments:b={},_meta:S}=e.params;(0,g.logSessionIdentity)(n,"_meta-debug",{has_meta:!!S,sessionId:S?.sessionId||null,messageId:S?.messageId||null,paramKeys:Object.keys(e.params)}),k.info("Tool call received: "+n,{tool:n}),a.incrementCounter("tool_calls_total",1,{tool:n})
|
|
612
|
+
const q=a.startTimer("tool_execution_time")
|
|
600
613
|
Date.now()
|
|
601
|
-
let
|
|
602
|
-
if(
|
|
603
|
-
if(Date.now(),!e)return k.warn("Unauthenticated tool call attempt",{tool:n}),{content:[{type:"text",text:"Authentication required. Please run 'alchemylab setup' to authenticate and configure your project."}],isError:!0}}const
|
|
604
|
-
let
|
|
605
|
-
if(
|
|
614
|
+
let T=Date.now()
|
|
615
|
+
if(l=r(b),Date.now(),T=Date.now(),C){const e=await _()
|
|
616
|
+
if(Date.now(),!e)return k.warn("Unauthenticated tool call attempt",{tool:n}),{content:[{type:"text",text:"Authentication required. Please run 'alchemylab setup' to authenticate and configure your project."}],isError:!0}}const x=(0,f.getToolByName)(n)
|
|
617
|
+
let P
|
|
618
|
+
if(T=Date.now(),s?(s.setOptions({createRecords:x?.createsRecords??!1}),k.info(`Setting record creation for tool ${n}: ${x?.createsRecords??!1}`)):k.debug(`No API client available for tool ${n} (minimal mode)`),Date.now(),Date.now(),T=Date.now(),S?.sessionId){const e=S.sessionId,t=S.messageId,r=h.sessionIdentity.getIdentity()
|
|
606
619
|
if(r)r.sessionId!==e&&((0,g.logSessionIdentity)(n,"_meta-session-switch",{prevSessionId:r.sessionId,prevAgentType:r.agentType,newSessionId:e}),h.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:r.serverUrl}),o?.workspaceManager?.resetCurrentContext?.(e))
|
|
607
620
|
else{const t=await(0,u.getServerUrl)(o,k)
|
|
608
|
-
h.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:t||""})}
|
|
609
|
-
h.sessionIdentity.setCurrentCallOrigin(
|
|
610
|
-
const P
|
|
611
|
-
if(o?.workspaceManager){
|
|
621
|
+
h.sessionIdentity.setIdentity({providerId:"opencode",sessionId:e,serverUrl:t||""})}P={providerId:"opencode",sessionId:e,messageId:t,createdAt:(new Date).toISOString()},(0,g.logSessionIdentity)(n,"_meta",{sessionId:e,messageId:t})}else if(m=n,E=S,v||(v=!0,k.warn("No _meta.sessionId on tool call \u2014 caller not on alchemylab-opencode fork.",{tool:m,metaKeys:E?Object.keys(E):null})),!1!==x?.requiresSession)throw(0,p.createMcpProtocolError)(`_meta.sessionId required for tool '${n}'`,{tool:n})
|
|
622
|
+
h.sessionIdentity.setCurrentCallOrigin(P)
|
|
623
|
+
const R=P?.sessionId||S?.sessionId
|
|
624
|
+
if(o?.workspaceManager){T=Date.now()
|
|
612
625
|
try{const e=await(0,u.getServerUrl)(o,k)
|
|
613
|
-
e&&s&&await o.workspaceManager.ensureReadonlyBranchIfNeeded(e,n,s,
|
|
614
|
-
fetch(r()+"/api/mcp/tool-call-event",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:e,callId
|
|
615
|
-
let
|
|
616
|
-
|
|
617
|
-
try{if(
|
|
618
|
-
const e={context:
|
|
619
|
-
|
|
626
|
+
e&&s&&await o.workspaceManager.ensureReadonlyBranchIfNeeded(e,n,s,R)}catch(e){k.debug("Error during workspace check",{error:(0,d.getErrorMessage)(e)})}Date.now()}const M=o?{...o,currentSessionId:R??"__server__"}:null,$=`${Date.now()}-${Math.random().toString(36).slice(2,10)}`,j=e=>{const{getActionServerBaseUrl:r}=t(9414)
|
|
627
|
+
fetch(r()+"/api/mcp/tool-call-event",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:e,callId:$}),signal:AbortSignal.timeout(500)}).catch((()=>{}))}
|
|
628
|
+
let O
|
|
629
|
+
j("start")
|
|
630
|
+
try{if(x){(0,y.preNormalize)(n,l),await(0,w.expandTaskRefsInArgs)(l,s,P?.sessionId,k),l=(0,f.resolveSchema)(x).parse(l)
|
|
631
|
+
const t=e.params?._meta?.progressToken,r=c?.sendNotification,o={context:M,apiClient:s,logger:i,metrics:a,mcpServer:I,cliOrigin:P,progressToken:t,sendNotification:r}
|
|
632
|
+
O=await x.handler(l,o)}else k.info(`Tool ${n} not found, returning negative response`),O={content:[{type:"text",text:`The tool '${n}' does not exist.`}]}}finally{j("end")}return Date.now(),Date.now(),q({tool:n,success:!0}),O}catch(t){k.error("Error executing tool:",{error:t instanceof Error?t.stack:t+"",tool:e.params.name}),a.incrementCounter("tool_errors_total",1,{tool:e.params.name,error:t instanceof Error?t.name:"unknown"})
|
|
620
633
|
let r="Unknown error"
|
|
621
|
-
return r=t instanceof b.ZodError?function(e,t){return 1===e.issues.length?n(e.issues[0],t):e.issues.map((e=>n(e,t))).join("; ")}(t,
|
|
634
|
+
return r=t instanceof b.ZodError?function(e,t){return 1===e.issues.length?n(e.issues[0],t):e.issues.map((e=>n(e,t))).join("; ")}(t,l):(0,d.getStructuredErrorMessage)(t),{content:[{type:"text",text:"Error: "+r}],isError:!0}}var m,E})),k.info("Tools registration complete")}
|
|
622
635
|
const c=t(9150),l=t(2478),d=t(8824),u=t(7617),h=t(6688),p=t(9860)
|
|
623
636
|
a(t(9896)),a(t(6928))
|
|
624
637
|
var m=t(7280)
|
|
@@ -1202,7 +1215,28 @@ let n=t
|
|
|
1202
1215
|
if(r){const e=t.includes("?")?"&":"?"
|
|
1203
1216
|
n=`${t}${e}projectId=${encodeURIComponent(r)}`}this.logger.info("Executing DELETE request",{originalPath:e,finalPath:n,hasProjectId:!!r})
|
|
1204
1217
|
const o=await this.requestWithRetry("DELETE",n,void 0)
|
|
1205
|
-
return(0,s.safeGetResponseData)(o,null)}catch(t){throw this.logger.error("Error in proxyDelete request:",{path:e,error:t instanceof Error?t.stack:t+"",statusCode:t.status||"unknown",projectId:this.projectClient.getProjectId(),errorDetails:t.details||"none"}),t}}))}}exports.ProxyClient=a},
|
|
1218
|
+
return(0,s.safeGetResponseData)(o,null)}catch(t){throw this.logger.error("Error in proxyDelete request:",{path:e,error:t instanceof Error?t.stack:t+"",statusCode:t.status||"unknown",projectId:this.projectClient.getProjectId(),errorDetails:t.details||"none"}),t}}))}}exports.ProxyClient=a},1925(e,exports,t){"use strict"
|
|
1219
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMergeRequest=async function(e,t,a,c,l){const d=c.child({tool:"merge_request"}),u=l.startTimer("tool_execution_time"),{requestId:h,verifications:p}=e
|
|
1220
|
+
try{if(!h)throw(0,n.createValidationError)("requestId is required")
|
|
1221
|
+
d.info("Starting merge request",{requestId:h,verificationCount:p.length})
|
|
1222
|
+
const e=a.getRequestClient(),s=await e.getRequest(h)
|
|
1223
|
+
if("ready_for_review"===s?.status)return u({success:!1,reason:"testing_in_progress"}),{content:[{type:"text",text:`STOP: Cannot merge request ${h} \u2014 testing is in progress. Wait for tests to complete. The request will be moved to ready_for_merge when tests pass.`}],isError:!0}
|
|
1224
|
+
if(p.length>0)try{await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/verify-criteria`,{verifications:p}),d.info("Criteria verified",{requestId:h,count:p.length})}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
1225
|
+
d.warn("Criteria verification failed, continuing with merge",{requestId:h,error:t})}let c,l,m
|
|
1226
|
+
try{const e=await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/validate-completion`,{})
|
|
1227
|
+
c=e?.data||e}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
1228
|
+
return u({success:!1,error:"validation_failed"}),{content:[{type:"text",text:"Failed to validate merge: "+t}],isError:!0}}if(!c.canComplete){let e=`Cannot merge request ${h}: ${c.reason}\n`
|
|
1229
|
+
return c.blockedByTasks?.length&&(e+="\n**Tasks that must be completed first:**\n",c.blockedByTasks.forEach(((t,r)=>{e+=`${r+1}. **${t.taskId}** - ${t.title} (${t.status})\n`}))),u({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}if(!t.workspaceManager)throw Error("WorkspaceManager not available")
|
|
1230
|
+
try{const e=t.workspaceManager.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,n=t.git??(0,r.simpleGit)({baseDir:e,binary:t.gitBinary}),o=await async function(e){for(const t of["main","master"])try{return await e.raw(["rev-parse","--verify",t]),t}catch{}return"main"}(n)
|
|
1231
|
+
l=(await n.raw(["merge-base",o,"requests/"+h])).trim()||void 0}catch(e){d.warn("Could not compute merge-base; mergeBaseSha will not be recorded",{requestId:h,error:(0,i.getErrorMessage)(e)})}let g="workspace-manager"
|
|
1232
|
+
const f=await e.getRequest(h),y=f?.title||"Request "+h,w="resolving_conflicts"===f?.status
|
|
1233
|
+
try{w?(d.info("Merge retry (resolving_conflicts) \u2014 using -X theirs",{requestId:h}),m=await t.workspaceManager.completeRequest(h,y,{skipConflictDetection:!0}),g="retry-theirs"):(m=await t.workspaceManager.completeRequest(h,y),g=m.autoMergeInfo?.strategy||"workspace-manager"),d.info("Merge completed",{requestId:h,mergeCommitHash:m.mergeCommitHash,mergeMethod:g})}catch(r){if(r.conflictInfo){const n=r.conflictInfo,s=n.workingDirectory||t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||process.cwd(),c=(0,o.createConflictResolutionManager)(d,a,s,t.git),l=await c.handleConflicts(n)
|
|
1234
|
+
try{await e.updateRequest(h,{status:"resolving_conflicts"}),d.info("Set status to resolving_conflicts",{requestId:h})}catch(e){d.error("Failed to set resolving_conflicts status",{requestId:h,error:(0,i.getErrorMessage)(e)})}return u({success:!1,reason:"merge_conflicts"}),{content:[{type:"text",text:l.userMessage}],isError:!1}}const n=(0,i.getErrorMessage)(r)
|
|
1235
|
+
return u({success:!1,error:"merge_failure"}),{content:[{type:"text",text:"Merge failed: "+n}],isError:!0}}try{await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/finalize-completion`,{summary:f?.completionSummary||"Merged request "+h,acceptanceEvidence:p.map((e=>({evidence:e.evidence}))),mergeResult:{mergeCommitHash:m.mergeCommitHash,mergeBaseSha:l,mergedFiles:m.mergedFiles,cleanedUp:m.cleanedUp,method:g}})}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
1236
|
+
return d.error("CRITICAL: Merge succeeded but server finalization failed",{requestId:h,mergeCommitHash:m.mergeCommitHash,error:t}),u({success:!1,error:"api_update_failed"}),{content:[{type:"text",text:`CRITICAL: Code was merged (commit: ${m.mergeCommitHash.substring(0,8)}) but failed to update server: ${t}`}],isError:!0}}return u({success:!0}),{content:[{type:"text",text:`Request ${h} merged successfully.\nCommit: ${m.mergeCommitHash.substring(0,8)}`}]}}catch(e){const r=(0,i.getErrorMessage)(e)
|
|
1237
|
+
d.error("Merge request failed",{error:r})
|
|
1238
|
+
try{await(0,s.createFailureToolRecord)("merge-request",e,{error:r,requestId:h},a.getToolRecordClient(),d,l,{requestId:h,projectId:t.projectId,note:"Failed to merge request"})}catch{}return u({success:!1,error:e instanceof Error?e.name:"unknown"}),{content:[{type:"text",text:"Error: "+r}],isError:!0}}}
|
|
1239
|
+
const r=t(3807),n=t(9860),o=t(1651),s=t(8616),i=t(8824)},1943(module){"use strict"
|
|
1206
1240
|
module.exports=require("fs/promises")},2040(e,exports,t){"use strict"
|
|
1207
1241
|
var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
|
|
1208
1242
|
var o=Object.getOwnPropertyDescriptor(t,r)
|
|
@@ -1237,65 +1271,70 @@ return i({success:!0}),{content:[{type:"text",text:`\u2705 Created test process
|
|
|
1237
1271
|
try{const r={}
|
|
1238
1272
|
if(void 0!==e.name&&(r.name=e.name),void 0!==e.description&&(r.description=e.description),void 0!==e.scope&&(r.scope=e.scope),void 0!==e.isActive&&(r.isActive=e.isActive),void 0!==e.commands||void 0!==e.setup||void 0!==e.fingerprint||void 0!==e.poolSize){const o=await n.proxyGet(`/api/projects/${t.projectId}/test-processes/${e.processId}`),s=o?.data||o,i=s?.config||{},a={setup:e.setup??i.setup??[],commands:e.commands?e.commands.map((e=>({name:e.name,command:e.command,required:!1!==e.required,timeout:e.timeout||300}))):i.commands??[]}
|
|
1239
1273
|
void 0!==e.fingerprint?a.fingerprint=e.fingerprint:void 0!==i.fingerprint&&(a.fingerprint=i.fingerprint),void 0!==e.poolSize?a.poolSize=e.poolSize:void 0!==i.poolSize&&(a.poolSize=i.poolSize),void 0!==i.verifyAcceptanceCriteria&&(a.verifyAcceptanceCriteria=i.verifyAcceptanceCriteria),r.config=a}const o=await n.proxyPatch(`/api/projects/${t.projectId}/test-processes/${e.processId}`,r),process=o?.data||o
|
|
1240
|
-
return i({success:!0}),{content:[{type:"text",text:`\u2705 Updated test process **${process.name}** (${process.id}).`}]}}catch(e){return i({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to update test process: "+(0,r.getErrorMessage)(e)}],isError:!0}}},exports.handleExecuteTestCommand=async function(e,n,o,s,
|
|
1241
|
-
try{const
|
|
1242
|
-
if(!process?.config)return
|
|
1243
|
-
let
|
|
1274
|
+
return i({success:!0}),{content:[{type:"text",text:`\u2705 Updated test process **${process.name}** (${process.id}).`}]}}catch(e){return i({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to update test process: "+(0,r.getErrorMessage)(e)}],isError:!0}}},exports.handleExecuteTestCommand=async function(e,n,o,s,a,c,l){const d=a.startTimer("tool_execution_time"),u=s.child({tool:"execute_test_command"})
|
|
1275
|
+
try{const a=await o.proxyGet(`/api/projects/${n.projectId}/test-processes/${e.processId}`),process=a?.data||a
|
|
1276
|
+
if(!process?.config)return d({success:!1,error:"not_found"}),{content:[{type:"text",text:`Test process ${e.processId} not found or has no config.`}],isError:!0}
|
|
1277
|
+
let c
|
|
1244
1278
|
if("setup"===e.commandName){const e=process.config.setup||[]
|
|
1245
|
-
if(0===e.length)return
|
|
1246
|
-
|
|
1279
|
+
if(0===e.length)return d({success:!0}),{content:[{type:"text",text:"No setup commands configured for this test process."}]}
|
|
1280
|
+
c=e.map(((e,t)=>({name:"setup-"+(t+1),command:e,timeout:120})))}else{const t=process.config.commands||[],r=t.find((t=>t.name===e.commandName))
|
|
1247
1281
|
if(!r){const r=t.map((e=>e.name)).join(", ")
|
|
1248
|
-
return
|
|
1249
|
-
let
|
|
1250
|
-
const
|
|
1282
|
+
return d({success:!1,error:"command_not_found"}),{content:[{type:"text",text:`Command "${e.commandName}" not found in test process "${process.name}".\nAvailable commands: ${r}\nUse "setup" to run setup commands.`}],isError:!0}}c=[{name:r.name,command:r.command,timeout:r.timeout||300}]}const{runShellCommand:h}=await Promise.resolve().then(t.bind(t,4600)),p=globalThis.process
|
|
1283
|
+
let m=null
|
|
1284
|
+
const g=[]
|
|
1251
1285
|
try{const{sessionIdentity:e}=await Promise.resolve().then(t.bind(t,6688)),r=e.getIdentity()
|
|
1252
|
-
if(
|
|
1253
|
-
if(
|
|
1254
|
-
|
|
1255
|
-
const
|
|
1256
|
-
try{
|
|
1257
|
-
for(const t of
|
|
1258
|
-
const r=`${t.name.replace(/[^a-zA-Z0-9._-]/g,"_")}-${Date.now()}`,n=
|
|
1286
|
+
if(g.push("session: "+(r?.sessionId||"NONE")),r?.sessionId){const t=await e.getSessionRequestId(o,s)
|
|
1287
|
+
if(g.push("reqId: "+(t||"NONE")),t){const e=await o.proxyGet(`/api/projects/${n.projectId}/requests/${t}/test-runs`),r=e?.data||e||[],s=Array.isArray(r)?r.find((e=>e.worktreePath||e.worktree_path)):null
|
|
1288
|
+
g.push(`runs: ${Array.isArray(r)?r.length:0}, withWorktree: ${s?.id||"NONE"}, path: ${s?.worktreePath||s?.worktree_path||"NONE"}`),s&&(m=s.worktreePath||s.worktree_path,u.info("Using test worktree from request test run",{worktreePath:m,reqId:t}))}}}catch(e){u.warn("Failed to resolve test worktree",{error:(0,r.getErrorMessage)(e)})}if(!m)return d({success:!1,error:"no_worktree"}),{content:[{type:"text",text:`No test worktree found.\n\nDiagnostics:\n${g.length>0?g.map((e=>"\u2022 "+e)).join("\n"):"\u2022 No session identity found"}\n\nEnsure this session is linked to a test process and a test run has been created.`}],isError:!0}
|
|
1289
|
+
const f=[],{default:y}=await Promise.resolve().then(t.t.bind(t,6928,23)),{default:w}=await Promise.resolve().then(t.t.bind(t,9896,23)),{ALCHEMY_DIR_NAME:b}=await Promise.resolve().then(t.bind(t,4139)),I=y.join(m,b,"command-logs")
|
|
1290
|
+
try{w.mkdirSync(I,{recursive:!0})}catch{}const{runTrackedShellCommand:k}=await Promise.resolve().then(t.bind(t,4600)),{formatCombinedOutput:v}=await Promise.resolve().then(t.bind(t,1816)),{sessionIdentity:C}=await Promise.resolve().then(t.bind(t,6688)),_=C.getIdentity()?.sessionId
|
|
1291
|
+
for(const t of c){u.info("Executing test command",{name:t.name,command:t.command,timeout:t.timeout,cwd:m})
|
|
1292
|
+
const r=`${t.name.replace(/[^a-zA-Z0-9._-]/g,"_")}-${Date.now()}`,n=y.join(I,r+".log")
|
|
1259
1293
|
let o=null
|
|
1260
|
-
try{o=
|
|
1294
|
+
try{o=w.createWriteStream(n,{flags:"w"}),o.write(`# ${(new Date).toISOString()} starting: ${t.command}\n# cwd: ${m}\n# timeout: ${t.timeout}s\n\n`)}catch(e){u.warn("Failed to open command log file",{logPath:n,error:e+""})}const s=await(0,i.runTrackedShellWithHeartbeat)(t.command,{cwd:m,timeoutMs:1e3*t.timeout,env:{...p.env,FORCE_COLOR:"0"},onChunk:o?(e,t)=>{o?.write(t)}:void 0},{id:r,name:t.name,sessionId:_,logPath:n},l)
|
|
1261
1295
|
o&&(o.write(`\n# exit: ${s.exitCode}${s.timedOut?" (timed out)":""}\n`),o.end())
|
|
1262
|
-
const
|
|
1263
|
-
if(
|
|
1296
|
+
const a=(s.stdout+(s.stderr?"\n"+s.stderr:"")).trim(),{output:c,truncatedNote:d,logFooter:h}=v(a,{invocationId:r})
|
|
1297
|
+
if(f.push({name:t.name,command:t.command,exitCode:s.exitCode,output:c,timedOut:s.timedOut,invocationId:r,truncatedNote:d,logFooter:h}),"setup"===e.commandName&&0!==s.exitCode)break}const E=f.every((e=>0===e.exitCode)),S=f.map((e=>{const t=e.timedOut?"\u23f1 TIMEOUT":0===e.exitCode?"\u2705 PASS":`\u274c FAIL (exit ${e.exitCode})`
|
|
1264
1298
|
return`### ${e.name}: ${t}\n\`\`\`\n$ ${e.command}\n${e.output}\n\`\`\`${e.truncatedNote}\n${e.logFooter}`})).join("\n\n")
|
|
1265
|
-
return
|
|
1266
|
-
try{const{
|
|
1267
|
-
if(!h)return d({success:!1,error:"no_request_association"}),
|
|
1268
|
-
const p=await i.proxyGet(`/api/projects/${s.projectId}/requests/${
|
|
1269
|
-
if(!
|
|
1270
|
-
const y
|
|
1271
|
-
await i.proxyPatch(`/api/projects/${s.projectId}/test-runs/${
|
|
1272
|
-
const
|
|
1299
|
+
return d({success:!0}),{content:[{type:"text",text:`## ${"setup"===e.commandName?"Setup":e.commandName} \u2014 ${E?"PASSED":"FAILED"}\n\n${S}`}]}}catch(e){return d({success:!1,error:"execution_error"}),{content:[{type:"text",text:"Failed to execute test command: "+(0,r.getErrorMessage)(e)}],isError:!0}}},exports.handleReportTestResults=async function(e,s,i,a,c,l){const d=c.startTimer("tool_execution_time")
|
|
1300
|
+
try{const{resolveRequestIdOrError:u}=await Promise.resolve().then(t.bind(t,9032)),h=await u(i,a,l?.sessionId,"Cannot report test results: this session is not associated with a request.")
|
|
1301
|
+
if(!h.ok)return d({success:!1,error:"no_request_association"}),h.errorResult
|
|
1302
|
+
const p=h.requestId,m=await i.proxyGet(`/api/projects/${s.projectId}/requests/${p}/test-runs`),g=m?.data||m||[],f=Array.isArray(g)?g:[],y=f.find((e=>"pending"===e.status||"running"===e.status))||f[0]
|
|
1303
|
+
if(!y)return d({success:!1,error:"no_test_run"}),{content:[{type:"text",text:`No test run found for request ${p}.`}],isError:!0}
|
|
1304
|
+
const w=y.id
|
|
1305
|
+
await i.proxyPatch(`/api/projects/${s.projectId}/test-runs/${w}`,{status:e.status,results:e.results}),y.worktreePath&&fetch((0,o.getActionServerBaseUrl)()+"/api/release-pool-slot",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({worktreePath:y.worktreePath}),signal:AbortSignal.timeout(5e3)}).catch((e=>a.debug("release-pool-slot fire-and-forget failed (non-fatal)",{error:(0,r.getErrorMessage)(e)})))
|
|
1306
|
+
const b="passed"===e.status?"\u2705":"failed"===e.status?"\u274c":"\u26a0\ufe0f"
|
|
1273
1307
|
try{const t=i.getRequestClient()
|
|
1274
|
-
"passed"===e.status?(await t.updateRequest(
|
|
1275
|
-
try{const t=await(0,n.handleSessionMessageOperations)({operation:"send",type:"report",status:"passed"===e.status?"success":"failure",summary:
|
|
1276
|
-
return d({success:!0}),{content:[{type:"text",text:`Test run for request ${
|
|
1308
|
+
"passed"===e.status?(await t.updateRequest(p,{status:"ready_for_merge"}),a.info("Tests passed, set request to ready_for_merge",{requestId:p})):(await t.updateRequest(p,{status:"in_progress"}),a.info("Tests failed, set request back to in_progress",{requestId:p}))}catch(e){a.warn("Failed to update request status after test results",{requestId:p,error:(0,r.getErrorMessage)(e)})}const I="passed"===e.status?"\n\nAll tests passed \u2014 the coder can now call `merge` to merge this request.":"\n\nTests failed \u2014 the coder should fix the issues and call `complete` again.",k=`${b} Test run ${e.status} for request ${p}\n\n${e.results.summary}${I}`
|
|
1309
|
+
try{const t=await(0,n.handleSessionMessageOperations)({operation:"send",type:"report",status:"passed"===e.status?"success":"failure",summary:k,details:e.results.commands?.map((e=>`${"passed"===e.status?"\u2705":"\u274c"} ${e.name}: ${e.status}${e.diagnosis?" - "+e.diagnosis:""}`)).join("\n"),finish:!0},s,a,c,i,l),r=t?.content?.[0]?.text||"unknown",o=t?.isError
|
|
1310
|
+
return d({success:!0}),{content:[{type:"text",text:`Test run for request ${p} reported as **${e.status}**.${o?" Parent notification FAILED: "+r:" Parent session notified."}\n\n${e.results.summary}`}]}}catch(t){return d({success:!0}),{content:[{type:"text",text:`Test run for request ${p} reported as **${e.status}** but failed to notify parent: ${(0,r.getErrorMessage)(t)}\n\n${e.results.summary}`}]}}}catch(e){return d({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to report test results: "+(0,r.getErrorMessage)(e)}],isError:!0}}},exports.handleTestingReference=async function(e,t,r,n,o){return o.startTimer("tool_execution_time")({success:!0}),{content:[{type:"text",text:'# Test Process Design Guide\n\n## Overview\n\nA test process defines how to verify code changes for a project. It consists of:\n- **Setup**: Commands to prepare the environment (install deps, link node_modules, etc.) \u2014 runs once per worktree\n- **Commands**: The actual test commands (build, lint, test, etc.) \u2014 the verification steps\n\n## Command Properties\n\n- **name**: Human-readable name (e.g., "Build", "Unit Tests")\n- **command**: Shell command to run (e.g., `npm test`)\n- **required** (default: true): If a required command fails, the request won\'t be merged\n- **timeout** (default: 300s): Maximum execution time. Exit code 0 = pass, non-zero = fail.\n\n## Scope (Monorepo Support)\n\nSet `scope` to a path prefix to limit when a process runs:\n- `scope: "packages/api/"` \u2192 only runs when files under packages/api/ change\n- omit `scope` \u2192 runs for all changes (global process)\n\nMultiple active processes per project are supported.\n\n## Common Patterns\n\n### Node.js / TypeScript\n```json\n{\n "setup": ["ln -s ../../node_modules node_modules"],\n "commands": [\n { "name": "Build", "command": "npm run build" },\n { "name": "Lint", "command": "npm run lint", "required": false },\n { "name": "Unit Tests", "command": "npm test" }\n ]\n}\n```\n\n### Python\n```json\n{\n "setup": ["pip install -e \'.[dev]\'"],\n "commands": [\n { "name": "Type Check", "command": "mypy src/" },\n { "name": "Lint", "command": "ruff check .", "required": false },\n { "name": "Tests", "command": "pytest" }\n ]\n}\n```\n\n### Go\n```json\n{\n "setup": ["go mod download"],\n "commands": [\n { "name": "Build", "command": "go build ./..." },\n { "name": "Vet", "command": "go vet ./...", "required": false },\n { "name": "Tests", "command": "go test ./..." }\n ]\n}\n```\n\n### Rust\n```json\n{\n "setup": ["cargo fetch"],\n "commands": [\n { "name": "Build", "command": "cargo build" },\n { "name": "Clippy", "command": "cargo clippy -- -D warnings", "required": false },\n { "name": "Tests", "command": "cargo test" }\n ]\n}\n```\n\n## Project Analysis Checklist\n\nWhen setting up testing for a new project, check for:\n1. **package.json** \u2192 Node.js/TypeScript (check "scripts" for test/build/lint commands)\n2. **Cargo.toml** \u2192 Rust\n3. **go.mod** \u2192 Go\n4. **pyproject.toml** / **requirements.txt** \u2192 Python\n5. **Makefile** \u2192 Custom build system (check for test/build targets)\n6. **.github/workflows/** \u2192 Existing CI configuration (great source of test commands)\n7. **.gitlab-ci.yml** \u2192 GitLab CI\n8. **tsconfig.json** \u2192 TypeScript type checking\n9. **.eslintrc** / **biome.json** \u2192 Linting configuration\n10. **vitest.config.ts** / **jest.config.ts** / **pytest.ini** \u2192 Test framework configuration'}]}},exports.handleTestingProcessDelete=async function(e,t,n,o,s){const i=s.startTimer("tool_execution_time")
|
|
1277
1311
|
try{return await n.proxyDelete(`/api/projects/${t.projectId}/test-processes/${e.processId}`),o.info("Deleted test process",{processId:e.processId}),i({success:!0}),{content:[{type:"text",text:`Deleted test process ${e.processId}.`}]}}catch(e){return i({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to delete test process: "+(0,r.getErrorMessage)(e)}],isError:!0}}},exports.handleTests=async function(e,n,i,a,c,l){const d=c.startTimer("tool_execution_time")
|
|
1278
1312
|
try{if("list"===e.operation){const e=await i.proxyGet(`/api/projects/${n.projectId}/test-processes`),t=e?.data||e||[],r=Array.isArray(t)?t:[]
|
|
1279
1313
|
if(0===r.length)return d({success:!0}),{content:[{type:"text",text:'No test processes registered for this project. Use `tests` with `operation: "setup"` to spawn an interactive setup session that helps configure one.'}]}
|
|
1280
1314
|
const o=r.map((e=>`**${e.name}** (${e.id})${e.scope?` [scope: ${e.scope}]`:""}\n ${e.isActive?"\u2705 Active":"\u23f8 Inactive"} \u2014 ${e.config?.commands?.length||0} commands${e.description?"\n "+e.description:""}`)).join("\n\n")
|
|
1281
|
-
return d({success:!0}),{content:[{type:"text",text:`## Test Processes (${r.length})\n\n${o}`}]}}if("run"===e.operation){let c=
|
|
1315
|
+
return d({success:!0}),{content:[{type:"text",text:`## Test Processes (${r.length})\n\n${o}`}]}}if("run"===e.operation){let c,u=[]
|
|
1282
1316
|
try{const e=await i.proxyGet(`/api/projects/${n.projectId}/test-processes`),t=e?.data||e||[]
|
|
1283
|
-
|
|
1284
|
-
const
|
|
1285
|
-
if(
|
|
1286
|
-
const
|
|
1287
|
-
|
|
1317
|
+
u=Array.isArray(t)?t:[]}catch(e){a.warn("tests run: existence check failed; proceeding optimistically",{error:(0,r.getErrorMessage)(e)})}if(0===u.length)return d({success:!1,error:"no_process"}),{content:[{type:"text",text:'No test process registered for this project. Run `tests` with `operation: "setup"` first to bootstrap one.'}],isError:!0}
|
|
1318
|
+
const h=e.process
|
|
1319
|
+
if(h){const e=h.toLowerCase(),t=u.find((t=>t.id===h||"string"==typeof t.name&&t.name.toLowerCase()===e))
|
|
1320
|
+
if(!t){const e=u.map((e=>`- ${e.name} (${e.id})`)).join("\n")
|
|
1321
|
+
return d({success:!1,error:"process_not_found"}),{content:[{type:"text",text:`No test process matched "${h}". Available:\n${e}`}],isError:!0}}c=[t.id]}const p=l?.sessionId,{resolveRequestIdOrError:m}=await Promise.resolve().then(t.bind(t,9032)),g=await m(i,a,p,"tests run requires an associated request \u2014 your session is not currently linked to one. Open or create a request, then try again.")
|
|
1322
|
+
if(!g.ok)return d({success:!1,error:"no_request"}),g.errorResult
|
|
1323
|
+
const f=g.requestId,y=e.name?[e.name]:void 0
|
|
1324
|
+
try{const e=await fetch((0,o.getActionServerBaseUrl)()+"/api/run-tests-now",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({requestId:f,parentSessionId:p,testProcessIds:c,commandNames:y}),signal:AbortSignal.timeout(15e3)})
|
|
1288
1325
|
if(!e.ok){const t=await e.text().catch((()=>""))
|
|
1289
1326
|
return d({success:!1,error:"run_failed"}),{content:[{type:"text",text:`tests run failed: action server returned ${e.status}: ${t.slice(0,300)}`}],isError:!0}}const t=await e.json()
|
|
1290
1327
|
if(!t.success||!t.data)return d({success:!1,error:"run_failed"}),{content:[{type:"text",text:"tests run failed: "+(t.error||"unknown error")}],isError:!0}
|
|
1291
|
-
const r=t.data.spawnedSessionIds?.[0],n=
|
|
1292
|
-
return d({success:!0}),{content:[{type:"text",text:`Test run started${n}.\nSpawned ${t.data.agentsSpawned} runner(s) for ${t.data.processCount} process(es). Test runs: ${t.data.testRunIds.join(", ")}.\n\nThe auto-tester is executing the registered commands. You will receive a notification on your next turn when results are reported \u2014 continue with other work in the meantime.`}],...(0,s.alchemyMeta)({kind:"spawn-subagent",spawnedSessionId:r,agentType:"auto-tester",requestId:
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1328
|
+
const r=t.data.spawnedSessionIds?.[0],n=y?` (filtered to: ${y.join(", ")})`:""
|
|
1329
|
+
return d({success:!0}),{content:[{type:"text",text:`Test run started${n}.\nSpawned ${t.data.agentsSpawned} runner(s) for ${t.data.processCount} process(es). Test runs: ${t.data.testRunIds.join(", ")}.\n\nThe auto-tester is executing the registered commands. You will receive a notification on your next turn when results are reported \u2014 continue with other work in the meantime.`}],...(0,s.alchemyMeta)({kind:"spawn-subagent",spawnedSessionId:r,agentType:"auto-tester",requestId:f,description:y?"Test run: "+y.join(", "):"Test run"})}}catch(e){return d({success:!1,error:"fetch_error"}),{content:[{type:"text",text:"tests run failed: could not reach action server: "+(0,r.getErrorMessage)(e)}],isError:!0}}}if("setup"===e.operation){let e
|
|
1330
|
+
try{const t=await i.proxyGet(`/api/projects/${n.projectId}/test-processes`),r=t?.data||t||[],o=Array.isArray(r)?r:[]
|
|
1331
|
+
if(o.length>0){const t=o.map((e=>`- ${e.name}${e.scope?` (scope: ${e.scope})`:""} \u2014 ${e.config?.commands?.length||0} command(s), ${e.isActive?"active":"inactive"}`)).join("\n")
|
|
1332
|
+
e=`${o.length} test process(es) already registered for this project:\n${t}\n\nPick a distinct name AND a non-overlapping scope for the new process. Confirm with the user what they want this new process to cover before registering.`}}catch(e){a.warn("tests setup: existing-processes lookup failed; proceeding without hint",{error:(0,r.getErrorMessage)(e)})}const{sessionIdentity:c}=await Promise.resolve().then(t.bind(t,6688)),u=l?.sessionId,h=u?await c.getSessionRequestId(i,a,u):void 0
|
|
1333
|
+
try{const t=await fetch((0,o.getActionServerBaseUrl)()+"/api/setup-tests",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({requestId:h,parentSessionId:u,context:e}),signal:AbortSignal.timeout(15e3)})
|
|
1334
|
+
if(!t.ok){const e=await t.text().catch((()=>""))
|
|
1335
|
+
return d({success:!1,error:"spawn_failed"}),{content:[{type:"text",text:`tests setup failed: action server returned ${t.status}: ${e.slice(0,300)}`}],isError:!0}}const r=await t.json()
|
|
1336
|
+
return r.success&&r.data?(d({success:!0}),{content:[{type:"text",text:`Test setup session started.\nWorktree: ${r.data.worktreePath} (branch: ${r.data.branch})\n\nThe test-architect agent is now interviewing the user. You will receive a notification on your next turn when configuration completes \u2014 continue with other work in the meantime.`}],...(0,s.alchemyMeta)({kind:"spawn-subagent",spawnedSessionId:r.data.sessionId,agentType:"test-architect",requestId:h??void 0,description:"Test setup"})}):(d({success:!1,error:"spawn_failed"}),{content:[{type:"text",text:"tests setup failed: "+(r.error||"unknown error")}],isError:!0})}catch(e){return d({success:!1,error:"fetch_error"}),{content:[{type:"text",text:"tests setup failed: could not reach action server: "+(0,r.getErrorMessage)(e)}],isError:!0}}}return d({success:!1,error:"unknown_operation"}),{content:[{type:"text",text:"Unknown operation: "+e.operation}],isError:!0}}catch(e){return d({success:!1,error:"api_error"}),{content:[{type:"text",text:"tests failed: "+(0,r.getErrorMessage)(e)}],isError:!0}}}
|
|
1337
|
+
const r=t(8824),n=t(9072),o=t(9414),s=t(2272),i=t(1375)},2085(e,exports,t){"use strict"
|
|
1299
1338
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.getRequestTimelineForFile=async function(e,t,s,i){let a=`# File History: ${t}\n\n`
|
|
1300
1339
|
a+="**Context**: Main branch (request-level view)\n\n"
|
|
1301
1340
|
try{const o=await e.log({file:t,n:100})
|
|
@@ -1474,7 +1513,7 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.buildTaskEndpoint
|
|
|
1474
1513
|
return`/api/projects/${e}/tasks/${encodeURIComponent(t)}${n}`}},2462(e,exports,t){"use strict"
|
|
1475
1514
|
Object.defineProperty(exports,"__esModule",{value:!0})
|
|
1476
1515
|
const r=t(2245),n=t(9080),o=t(5692),s=t(9030),i=t(2903),a=t(4607),c=t(9499),l=t(6770),d=t(8045),u=t(9697),h=t(9196),p=t(5459),m=t(4805),g=t(260),f=t(2283),y=t(4165),w=t(7834),b=t(9373),I=t(6111),k=t(700),v=t(1535),C=t(7257),_=t(9230),E=t(4150),S=t(6473),q=t(6309),T=t(4921),x=t(8850),P=t(3556),R=t(1391),M=t(6315),$=t(7713),j=t(6252),O=t(213),D=t(7250),A=t(2425),F=t(1540),N=t(5767),z=t(4973),L=t(509),H=t(7613),B=t(8456),U=t(3322),G=t(5247),W=t(8849),V=t(542);(0,r.registerTool)(n.def),(0,r.registerTool)(o.def),(0,r.registerTool)(s.def),(0,r.registerTool)(i.def),(0,r.registerTool)(a.def),(0,r.registerTool)(c.def),(0,r.registerTool)(l.def),(0,r.registerTool)(d.def),(0,r.registerTool)(u.def),(0,r.registerTool)(h.def),(0,r.registerTool)(p.def),(0,r.registerTool)(m.def),(0,r.registerTool)(g.def),(0,r.registerTool)(f.def),(0,r.registerTool)(y.def),(0,r.registerTool)(w.def),(0,r.registerTool)(b.def),(0,r.registerTool)(I.def),(0,r.registerTool)(k.def),(0,r.registerTool)(v.def),(0,r.registerTool)(E.def),(0,r.registerTool)(C.def),(0,r.registerTool)(_.def),(0,r.registerTool)(S.def),(0,r.registerTool)(q.def),(0,r.registerTool)(T.def),(0,r.registerTool)(x.def),(0,r.registerTool)(P.def),(0,r.registerTool)(R.def),(0,r.registerTool)(M.def),(0,r.registerTool)($.def),(0,r.registerTool)(j.def),(0,r.registerTool)(O.def),(0,r.registerTool)(D.def),(0,r.registerTool)(A.def),(0,r.registerTool)(F.def),(0,r.registerTool)(N.def),(0,r.registerTool)(z.def),(0,r.registerTool)(L.def),(0,r.registerTool)(H.def),(0,r.registerTool)(B.def),(0,r.registerTools)(U.metaDefs),(0,r.registerTools)(G.testingDefs),(0,r.registerTools)(W.checkingDefs),(0,r.registerTools)(V.debugDefs),(0,t(2245).freezeRegistry)()},2478(e,exports){"use strict"
|
|
1477
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.requestConfig=void 0,exports.areTestsRequiredForCompletion=function(){return exports.requestConfig.requireTestsForCompletion},exports.setTestsRequiredForCompletion=function(e){exports.requestConfig.requireTestsForCompletion=e},exports.getCompletionMode=function(e){return e&&["auto-merge","
|
|
1516
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.requestConfig=void 0,exports.areTestsRequiredForCompletion=function(){return exports.requestConfig.requireTestsForCompletion},exports.setTestsRequiredForCompletion=function(e){exports.requestConfig.requireTestsForCompletion=e},exports.getCompletionMode=function(e){return e&&["auto-merge","ask-me","test-by-default","always-test"].includes(e)?e:"test-by-default"},exports.getReviewMode=function(e){return e&&["auto-finalize","manual-review"].includes(e)?e:"auto-finalize"},exports.getApprovalMode=function(e){return e&&["none","require-approval"].includes(e)?e:"none"},exports.requestConfig={requireTestsForCompletion:!1}},2537(e,exports,t){"use strict"
|
|
1478
1517
|
async function r(e,t,r){if(v.has(r)&&C>=t){if(0===t)return 0
|
|
1479
1518
|
try{return(await y.default.readFile(e,"utf-8")).split("\n").length}catch{return}}}function n(e,t,r){const n="depth"in e,o=n?e:r,s=n?e.isDirectory:e.isDirectory(),a=e.name,c=s?"[\u{1f4c1} DIR]":"[\u{1f4c4} FILE]"
|
|
1480
1519
|
let l=""
|
|
@@ -2040,7 +2079,7 @@ var g=t(6539)
|
|
|
2040
2079
|
Object.defineProperty(exports,"ClientFactory",{enumerable:!0,get(){return g.ClientFactory}})
|
|
2041
2080
|
const f=t(6539)
|
|
2042
2081
|
exports.default={ClientFactory:f.ClientFactory}},3416(e,exports){"use strict"
|
|
2043
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.KIND_META=exports.QUEST_STATUS_CLOSED=exports.QUEST_STATUS_OPEN=exports.QUEST_DEFAULTS=exports.PLAN_KINDS=void 0,exports.PLAN_KINDS=["plan","quest"],exports.QUEST_DEFAULTS={tickIntervalSeconds:1800,maxInFlight:1,maxPerDay:24,minIterations:3},exports.QUEST_STATUS_OPEN="open",exports.QUEST_STATUS_CLOSED="closed",exports.KIND_META={plan:{docType:"Plan",filenamePrefix:"PLAN-",label:"plan",idLabel:"Plan ID",headingCreated:"Plan Created",errorVerb:"create plan",alchemyKind:"plan-create",canBeActivePlan:!0},quest:{docType:"Quest",filenamePrefix:"QUEST-",label:"quest",idLabel:"Quest ID",headingCreated:"Quest Created",errorVerb:"create quest",alchemyKind:"quest-create",canBeActivePlan:!1}}},3420(e,exports,t){"use strict"
|
|
2082
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.KIND_META=exports.QUEST_STATUS_DRAFT=exports.QUEST_STATUS_CLOSED=exports.QUEST_STATUS_OPEN=exports.QUEST_DEFAULTS=exports.PLAN_KINDS=void 0,exports.PLAN_KINDS=["plan","quest"],exports.QUEST_DEFAULTS={tickIntervalSeconds:1800,maxInFlight:1,maxPerDay:24,minIterations:3},exports.QUEST_STATUS_OPEN="open",exports.QUEST_STATUS_CLOSED="closed",exports.QUEST_STATUS_DRAFT="draft",exports.KIND_META={plan:{docType:"Plan",filenamePrefix:"PLAN-",label:"plan",idLabel:"Plan ID",headingCreated:"Plan Created",errorVerb:"create plan",alchemyKind:"plan-create",canBeActivePlan:!0},quest:{docType:"Quest",filenamePrefix:"QUEST-",label:"quest",idLabel:"Quest ID",headingCreated:"Quest Created",errorVerb:"create quest",alchemyKind:"quest-create",canBeActivePlan:!1}}},3420(e,exports,t){"use strict"
|
|
2044
2083
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleGetTaskInformation=async function(e,t,i,a,c){const l=a.child({tool:"get_task_information"})
|
|
2045
2084
|
l.info("Getting task information",{args:e})
|
|
2046
2085
|
const d=c.startTimer("tool_handler_duration")
|
|
@@ -2424,28 +2463,7 @@ if("svg"===u)return{content:[{type:"text",text:`**Asset: ${r}**\n\n\`\`\`svg\n${
|
|
|
2424
2463
|
const p=await i.readFile(c),m=p.toString("base64")
|
|
2425
2464
|
return o.info("Asset viewed",{filename:r,size:p.length}),{content:[{type:"text",text:`**Asset: ${r}** (${(p.length/1024).toFixed(1)} KB)`},{type:"image",data:m,mimeType:h}]}}catch(e){return o.error("Failed to view asset",{error:(0,c.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c **Failed to view asset:** "+(0,c.getErrorMessage)(e)}],isError:!0}}}
|
|
2426
2465
|
const i=s(t(1943)),a=s(t(6928)),c=t(8824),l=t(4139),d={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml"}},4245(module){function e(e){var t=Error("Cannot find module '"+e+"'")
|
|
2427
|
-
throw t.code="MODULE_NOT_FOUND",t}e.keys=()=>[],e.resolve=e,e.id=4245,module.exports=e},
|
|
2428
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleMergeRequest=async function(e,t,a,c,l){const d=c.child({tool:"merge_request"}),u=l.startTimer("tool_execution_time"),{requestId:h,verifications:p}=e
|
|
2429
|
-
try{if(!h)throw(0,n.createValidationError)("requestId is required")
|
|
2430
|
-
d.info("Starting merge request",{requestId:h,verificationCount:p.length})
|
|
2431
|
-
const e=a.getRequestClient(),s=await e.getRequest(h)
|
|
2432
|
-
if("ready_for_review"===s?.status)return u({success:!1,reason:"testing_in_progress"}),{content:[{type:"text",text:`STOP: Cannot merge request ${h} \u2014 testing is in progress. Wait for tests to complete. The request will be moved to ready_for_merge when tests pass.`}],isError:!0}
|
|
2433
|
-
if(p.length>0)try{await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/verify-criteria`,{verifications:p}),d.info("Criteria verified",{requestId:h,count:p.length})}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
2434
|
-
d.warn("Criteria verification failed, continuing with merge",{requestId:h,error:t})}let c,l,m
|
|
2435
|
-
try{const e=await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/validate-completion`,{})
|
|
2436
|
-
c=e?.data||e}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
2437
|
-
return u({success:!1,error:"validation_failed"}),{content:[{type:"text",text:"Failed to validate merge: "+t}],isError:!0}}if(!c.canComplete){let e=`Cannot merge request ${h}: ${c.reason}\n`
|
|
2438
|
-
return c.blockedByTasks?.length&&(e+="\n**Tasks that must be completed first:**\n",c.blockedByTasks.forEach(((t,r)=>{e+=`${r+1}. **${t.taskId}** - ${t.title} (${t.status})\n`}))),u({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}if(!t.workspaceManager)throw Error("WorkspaceManager not available")
|
|
2439
|
-
try{const e=t.workspaceManager.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,n=t.git??(0,r.simpleGit)({baseDir:e,binary:t.gitBinary}),o=await async function(e){for(const t of["main","master"])try{return await e.raw(["rev-parse","--verify",t]),t}catch{}return"main"}(n)
|
|
2440
|
-
l=(await n.raw(["merge-base",o,"requests/"+h])).trim()||void 0}catch(e){d.warn("Could not compute merge-base; mergeBaseSha will not be recorded",{requestId:h,error:(0,i.getErrorMessage)(e)})}let g="workspace-manager"
|
|
2441
|
-
const f=await e.getRequest(h),y=f?.title||"Request "+h,w="resolving_conflicts"===f?.status
|
|
2442
|
-
try{w?(d.info("Merge retry (resolving_conflicts) \u2014 using -X theirs",{requestId:h}),m=await t.workspaceManager.completeRequest(h,y,{skipConflictDetection:!0}),g="retry-theirs"):(m=await t.workspaceManager.completeRequest(h,y),g=m.autoMergeInfo?.strategy||"workspace-manager"),d.info("Merge completed",{requestId:h,mergeCommitHash:m.mergeCommitHash,mergeMethod:g})}catch(r){if(r.conflictInfo){const n=r.conflictInfo,s=n.workingDirectory||t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||process.cwd(),c=(0,o.createConflictResolutionManager)(d,a,s,t.git),l=await c.handleConflicts(n)
|
|
2443
|
-
try{await e.updateRequest(h,{status:"resolving_conflicts"}),d.info("Set status to resolving_conflicts",{requestId:h})}catch(e){d.error("Failed to set resolving_conflicts status",{requestId:h,error:(0,i.getErrorMessage)(e)})}return u({success:!1,reason:"merge_conflicts"}),{content:[{type:"text",text:l.userMessage}],isError:!1}}const n=(0,i.getErrorMessage)(r)
|
|
2444
|
-
return u({success:!1,error:"merge_failure"}),{content:[{type:"text",text:"Merge failed: "+n}],isError:!0}}try{await a.proxyPost(`/api/projects/${t.projectId}/requests/${h}/finalize-completion`,{summary:f?.completionSummary||"Merged request "+h,acceptanceEvidence:p.map((e=>({evidence:e.evidence}))),mergeResult:{mergeCommitHash:m.mergeCommitHash,mergeBaseSha:l,mergedFiles:m.mergedFiles,cleanedUp:m.cleanedUp,method:g}})}catch(e){const t=(0,i.getErrorMessage)(e)
|
|
2445
|
-
return d.error("CRITICAL: Merge succeeded but server finalization failed",{requestId:h,mergeCommitHash:m.mergeCommitHash,error:t}),u({success:!1,error:"api_update_failed"}),{content:[{type:"text",text:`CRITICAL: Code was merged (commit: ${m.mergeCommitHash.substring(0,8)}) but failed to update server: ${t}`}],isError:!0}}return u({success:!0}),{content:[{type:"text",text:`Request ${h} merged successfully.\nCommit: ${m.mergeCommitHash.substring(0,8)}`}]}}catch(e){const r=(0,i.getErrorMessage)(e)
|
|
2446
|
-
d.error("Merge request failed",{error:r})
|
|
2447
|
-
try{await(0,s.createFailureToolRecord)("merge-request",e,{error:r,requestId:h},a.getToolRecordClient(),d,l,{requestId:h,projectId:t.projectId,note:"Failed to merge request"})}catch{}return u({success:!1,error:e instanceof Error?e.name:"unknown"}),{content:[{type:"text",text:"Error: "+r}],isError:!0}}}
|
|
2448
|
-
const r=t(3807),n=t(9860),o=t(1651),s=t(8616),i=t(8824)},4394(e,exports,t){"use strict"
|
|
2466
|
+
throw t.code="MODULE_NOT_FOUND",t}e.keys=()=>[],e.resolve=e,e.id=4245,module.exports=e},4394(e,exports,t){"use strict"
|
|
2449
2467
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.getOrCreateHealthCheckManager=function(e,t,o,s={}){const i=e.endsWith("/")?e.slice(0,-1):e,a=n.get(i)
|
|
2450
2468
|
if(a)return t.debug("Reusing existing HealthCheckManager instance",{baseUrl:i,totalInstances:n.size}),a
|
|
2451
2469
|
t.info("Creating new HealthCheckManager instance",{baseUrl:i,totalInstancesBefore:n.size})
|
|
@@ -2462,18 +2480,18 @@ const a=await r.updateDocument(e.planId,i),c=a.localId||a.id
|
|
|
2462
2480
|
return o.info("Plan appended",{planId:c,appendedLength:e.content.length}),{content:[{type:"text",text:`\u2705 **Plan Appended**\n\n**Plan ID:** ${c}\n**Appended:** ${e.content.length} characters\n**Total Length:** ${s.length} characters`}]}}catch(e){return o.error("Failed to append to plan",{error:(0,r.getErrorMessage)(e)}),{content:[{type:"text",text:"\u274c **Failed to append to plan:** "+(0,r.getErrorMessage)(e)}],isError:!0}}}
|
|
2463
2481
|
const r=t(8824)},4425(e,exports,t){"use strict"
|
|
2464
2482
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2465
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCommands=async function(e,t,r,h,p,m,g){const
|
|
2466
|
-
try{const p=await r.proxyGet(`/api/projects/${t.projectId}/check-commands`),
|
|
2467
|
-
if("list"===
|
|
2483
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCommands=async function(e,t,r,h,p,m,g,f){const y=p.startTimer("tool_execution_time"),w=e.operation||"run"
|
|
2484
|
+
try{const p=await r.proxyGet(`/api/projects/${t.projectId}/check-commands`),b=p?.data||p||[],I=b.filter((e=>e.isActive)),k=b.filter((e=>!e.isActive))
|
|
2485
|
+
if("list"===w){if(0===b.length)return y({success:!0}),{content:[{type:"text",text:'No commands configured for this project yet.\n\nUse `commands({ operation: "register", commands: [{ name: "typecheck", command: "tsc --noEmit", description: "..." }] })` to add one, or `commands({ operation: "setup" })` to spawn the architect for an interview.'}],...(0,c.alchemyMeta)({kind:"list-commands"})}
|
|
2468
2486
|
const e=[]
|
|
2469
|
-
return
|
|
2487
|
+
return I.length>0&&(e.push(`## Available Commands (${I.length})\n`),e.push(...I.map((e=>`- **${e.name}**: \`${e.command}\`${e.cwd?` (in \`${e.cwd}\`)`:""}${e.description?" \u2014 "+e.description:""}`)))),k.length>0&&(e.push(`\n## Pending Approval (${k.length})\n`),e.push(...k.map((e=>`- **${e.name}**: \`${e.command}\`${e.cwd?` (in \`${e.cwd}\`)`:""} \u2014 \u23f3 waiting for user approval`)))),e.push('\nRun: `commands({ name: "name" })`\nRegister: `commands({ operation: "register", commands: [{ name, command, description, cwd? }, ...] })` \u2014 submits 1+ commands for approval. Single-item arrays work for one command; multiples bundle into one batch notification.\nRemove: `commands({ operation: "remove", name: "..." })`\nSetup (interactive): `commands({ operation: "setup" })` \u2014 spawns the command-architect for guided setup'),y({success:!0}),{content:[{type:"text",text:e.join("\n")}],...(0,c.alchemyMeta)({kind:"list-commands"})}}if("setup"===w){const t=g?.sessionId,n=t?await d.sessionIdentity.getSessionRequestId(r,h,t):void 0
|
|
2470
2488
|
try{const r=await fetch((0,u.getActionServerBaseUrl)()+"/api/setup-commands",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({requestId:n,parentSessionId:t,context:e.context}),signal:AbortSignal.timeout(15e3)})
|
|
2471
2489
|
if(!r.ok){const e=await r.text().catch((()=>""))
|
|
2472
|
-
return
|
|
2473
|
-
return o.success&&o.data?(
|
|
2490
|
+
return y({success:!1,error:"spawn_failed"}),{content:[{type:"text",text:`commands setup failed: action server returned ${r.status}: ${e.slice(0,300)}`}],isError:!0}}const o=await r.json()
|
|
2491
|
+
return o.success&&o.data?(y({success:!0}),{content:[{type:"text",text:`Commands setup session started.\nWorktree: ${o.data.worktreePath} (branch: ${o.data.branch})\n\nThe command-architect agent is now interviewing the user. You will receive a notification on your next turn when configuration completes \u2014 continue with other work in the meantime.`}],...(0,c.alchemyMeta)({kind:"spawn-subagent",spawnedSessionId:o.data.sessionId,agentType:"command-architect",description:"Commands setup"})}):(y({success:!1,error:"spawn_failed"}),{content:[{type:"text",text:"commands setup failed: "+(o.error||"unknown error")}],isError:!0})}catch(e){return y({success:!1,error:"spawn_failed"}),{content:[{type:"text",text:"commands setup failed: "+(0,l.getErrorMessage)(e)}],isError:!0}}}if("register"===w){if(!Array.isArray(e.commands)||0===e.commands.length)return y({success:!1,error:"missing_commands"}),{content:[{type:"text",text:"Error: `commands` array is required and must be non-empty for the register operation."}],isError:!0}
|
|
2474
2492
|
const n=function(e){return e?.sessionId||d.sessionIdentity.getIdentity()?.sessionId||null}(g)
|
|
2475
|
-
if(!n)return
|
|
2476
|
-
const o=new Set(
|
|
2493
|
+
if(!n)return y({success:!1,error:"no_session"}),{content:[{type:"text",text:"Error: no session context available to attribute approval notifications."}],isError:!0}
|
|
2494
|
+
const o=new Set(b.map((e=>e.name.toLowerCase()))),s=[],i=[]
|
|
2477
2495
|
for(const t of e.commands){const e=t.name?.trim(),r=t.command?.trim(),n=t.description?.trim()
|
|
2478
2496
|
e&&r&&n?o.has(e.toLowerCase())?i.push({name:e,reason:"already exists"}):(o.add(e.toLowerCase()),s.push({name:e,command:r,description:n,cwd:t.cwd?.trim(),timeout:t.timeout})):i.push({name:e||"(unnamed)",reason:"missing required fields (name, command, description)"})}const a=await Promise.all(s.map((async e=>{try{const n=await r.proxyPost(`/api/projects/${t.projectId}/check-commands`,{name:e.name,command:e.command,description:e.description,timeout:e.timeout||60,cwd:e.cwd||void 0,addedBySessionId:g?.sessionId,isActive:!1}),o=n?.data?.id||n?.id
|
|
2479
2497
|
if(!o)throw Error("command create returned no id")
|
|
@@ -2484,26 +2502,26 @@ if(u.length>0)try{const e=r.getSessionMessageClient()
|
|
|
2484
2502
|
if(!e)throw Error("session message client unavailable")
|
|
2485
2503
|
await e.createQuestion({fromSessionId:n,questionType:"alternatives",question:`Command batch approval: ${u.length} command${1===u.length?"":"s"}`,options:[{id:"approve-all",label:"Approve all",description:`Activate all ${u.length} commands`},{id:"deny-all",label:"Deny all",description:"Delete all proposed commands"},{id:"select",label:"Select\u2026",description:"Pick which to approve individually"}],context:JSON.stringify({type:"command-approval-batch",commands:u.map((e=>({commandId:e.commandId,name:e.proposal.name,command:e.proposal.command,description:e.proposal.description,cwd:e.proposal.cwd})))}),category:"action-required",priority:"high"})
|
|
2486
2504
|
for(const e of u)p.push(e.proposal.name)}catch(e){await Promise.allSettled(u.map((e=>r.proxyDelete(`/api/projects/${t.projectId}/check-commands/${e.commandId}`).catch((t=>h.warn("Rollback delete after batch question failure",{commandId:e.commandId,error:(0,l.getErrorMessage)(t)}))))))
|
|
2487
|
-
for(const t of u)i.push({name:t.proposal.name,reason:(0,l.getErrorMessage)(e)})}h.info("Register submitted commands for approval",{total:e.commands.length,submitted:p.length,skipped:i.length}),
|
|
2505
|
+
for(const t of u)i.push({name:t.proposal.name,reason:(0,l.getErrorMessage)(e)})}h.info("Register submitted commands for approval",{total:e.commands.length,submitted:p.length,skipped:i.length}),y({success:!0})
|
|
2488
2506
|
const m=[`## Submitted ${p.length} command${1===p.length?"":"s"} for approval${i.length?`, ${i.length} skipped`:""}`]
|
|
2489
|
-
return p.length>0&&(m.push("","### Pending approval"),m.push(...p.map((e=>`- **${e}**`))),m.push("","The user will see one approval notification per command. Approved commands become runnable; denied ones are removed.")),i.length>0&&(m.push("",`### Skipped (${i.length})`),m.push(...i.map((e=>`- **${e.name}** \u2014 ${e.reason}`)))),m.push("",'Use `commands({ operation: "list" })` to see status.'),{content:[{type:"text",text:m.join("\n")}],...(0,c.alchemyMeta)({kind:"register-commands"})}}if("remove"===
|
|
2490
|
-
const n=
|
|
2491
|
-
if(!n)return
|
|
2492
|
-
try{return await r.proxyDelete(`/api/projects/${t.projectId}/check-commands/${n.id}`),h.info("Removed command",{name:n.name,id:n.id}),
|
|
2493
|
-
return
|
|
2494
|
-
if(!
|
|
2495
|
-
return
|
|
2496
|
-
e.grep&&(
|
|
2497
|
-
const
|
|
2498
|
-
let
|
|
2499
|
-
try{i.default.mkdirSync(
|
|
2500
|
-
const
|
|
2501
|
-
|
|
2502
|
-
const{stdout:
|
|
2503
|
-
let
|
|
2504
|
-
if(m)try{const e=await m.createToolRecord({projectId:t.projectId,type:"run-command",metadata:{name:
|
|
2505
|
-
|
|
2506
|
-
const n=t(
|
|
2507
|
+
return p.length>0&&(m.push("","### Pending approval"),m.push(...p.map((e=>`- **${e}**`))),m.push("","The user will see one approval notification per command. Approved commands become runnable; denied ones are removed.")),i.length>0&&(m.push("",`### Skipped (${i.length})`),m.push(...i.map((e=>`- **${e.name}** \u2014 ${e.reason}`)))),m.push("",'Use `commands({ operation: "list" })` to see status.'),{content:[{type:"text",text:m.join("\n")}],...(0,c.alchemyMeta)({kind:"register-commands"})}}if("remove"===w){if(!e.name?.trim())return y({success:!1,error:"missing_name"}),{content:[{type:"text",text:"Error: `name` is required when removing a command."}],isError:!0}
|
|
2508
|
+
const n=b.find((t=>t.name.toLowerCase()===e.name.toLowerCase()))
|
|
2509
|
+
if(!n)return y({success:!1,error:"not_found"}),{content:[{type:"text",text:`Command "${e.name}" not found.`}],isError:!0}
|
|
2510
|
+
try{return await r.proxyDelete(`/api/projects/${t.projectId}/check-commands/${n.id}`),h.info("Removed command",{name:n.name,id:n.id}),y({success:!0}),{content:[{type:"text",text:`Removed command **${n.name}**.`}]}}catch(e){return y({success:!1,error:"remove_failed"}),{content:[{type:"text",text:"Failed to remove command: "+(0,l.getErrorMessage)(e)}],isError:!0}}}if(!e.name){const e=I.map((e=>e.name)).join(", ")
|
|
2511
|
+
return y({success:!1,error:"missing_name"}),{content:[{type:"text",text:"Error: `name` is required when running a command.\n\nAvailable commands: "+(e||"(none configured)")}],isError:!0}}const v=I.find((t=>t.name.toLowerCase()===e.name.toLowerCase()))
|
|
2512
|
+
if(!v){const t=I.map((e=>e.name)).join(", ")
|
|
2513
|
+
return y({success:!1,error:"not_found"}),{content:[{type:"text",text:`Command "${e.name}" not found.\n\nAvailable commands: ${t||"(none configured)"}`}],isError:!0}}let C=e.args?`${v.command} ${e.args}`:v.command
|
|
2514
|
+
e.grep&&(C=`${C} 2>&1 | grep -i ${JSON.stringify(e.grep)}`)
|
|
2515
|
+
const _=t.workspaceManager?.getCurrentContext(t.currentSessionId)?.basePath||t.basePath,E=v.cwd?s.default.resolve(_,v.cwd):_,S=s.default.join(_,a.ALCHEMY_DIR_NAME,"command-logs"),q=`${v.name.replace(/[^a-zA-Z0-9._-]/g,"_")}-${Date.now()}`,T=s.default.join(S,q+".log")
|
|
2516
|
+
let x=null
|
|
2517
|
+
try{i.default.mkdirSync(S,{recursive:!0}),x=i.default.createWriteStream(T,{flags:"w"}),x.write(`# ${(new Date).toISOString()} starting: ${C}\n# cwd: ${E}\n# timeout: ${v.timeout||60}s\n\n`)}catch(e){h.warn("Failed to open command log file",{logPath:T,error:(0,l.getErrorMessage)(e)})}h.info("Running command",{name:v.name,command:C,cwd:E,configuredCwd:v.cwd,logPath:T})
|
|
2518
|
+
const P=await(0,n.runTrackedShellWithHeartbeat)(C,{cwd:E,timeoutMs:1e3*(v.timeout||60),env:{...process.env,FORCE_COLOR:"0"},onChunk:x?(e,t)=>{x?.write(t)}:void 0},{id:q,name:v.name,sessionId:g?.sessionId,logPath:T},f)
|
|
2519
|
+
x&&(x.write(`\n# exit: ${P.exitCode}${P.timedOut?" (timed out)":""}\n`),x.end())
|
|
2520
|
+
const{stdout:R,stderr:M,exitCode:$,timedOut:j}=P,{output:O,truncatedNote:D,logFooter:A}=(0,o.formatCommandOutput)(R,M,{invocationId:q}),F=j?"TIMEOUT":null
|
|
2521
|
+
let N
|
|
2522
|
+
if(m)try{const e=await m.createToolRecord({projectId:t.projectId,type:"run-command",metadata:{name:v.name,command:C,exitCode:$,timedOut:j,status:j?"timeout":0===$?"success":"failed",timestamp:(new Date).toISOString()}})
|
|
2523
|
+
N=e?.id}catch(e){h.debug("Failed to create tool record for command run",{error:(0,l.getErrorMessage)(e)})}return y({success:!0}),{content:[{type:"text",text:`## ${v.name}${F?` \u2014 ${F} (killed after ${v.timeout}s)`:""}\n\`\`\`\n$ ${C}\n${O}\n\`\`\`${D}\n\nExit code: ${$}\n${A} (pass to read_files or search)`}],...(0,c.alchemyMeta)({kind:"run-command",toolRecordId:N})}}catch(e){return y({success:!1,error:"api_error"}),{content:[{type:"text",text:"Failed to run command: "+(0,l.getErrorMessage)(e)}],isError:!0}}}
|
|
2524
|
+
const n=t(1375),o=t(1816),s=r(t(6928)),i=r(t(9896)),a=t(4139),c=t(2272),l=t(8824),d=t(6688),u=t(9414)},4466(e,exports,t){"use strict"
|
|
2507
2525
|
function r(e,t){return`${e}#${t.toString().padStart(2,"0")}`}async function n(e,t,n,s){if(exports.TASK_REF_PATTERN.test(e))return e
|
|
2508
2526
|
const i=e.match(exports.TASK_REF_SHORT_PATTERN)
|
|
2509
2527
|
if(!i)return e
|
|
@@ -2602,29 +2620,30 @@ let q=`\u2705 **File ${S.charAt(0).toUpperCase()+S.slice(1)} Successfully**\n\n`
|
|
|
2602
2620
|
return q+=`**File:** ${y}\n`,q+=`**Recovered from:** ${r.substring(0,8)}\n`,q+=`**Content length:** ${_.length} characters\n`,n&&v&&k&&(q+=`**Backup created:** ${i.basename(k)}\n`),q+="**Git status:** Recovery committed\n",q+="\u{1f4a1} **Tip:** The file has been restored to its state at the specified commit.",h.info("File recovery completed successfully",{path:y,commitHash:r,duration:Date.now()-m}),p.incrementCounter("file_recover_total",1,{success:!0,type:"file"}),{content:[{type:"text",text:q}]}}catch(e){throw e}}(I,f,y,w,r,n,o,p,u,g,h)}catch(e){const t=Date.now()-g
|
|
2603
2621
|
return p.error("Recovery operation failed",{error:e instanceof Error?e.stack:e+"",duration:t}),m({tool:"file_recover",success:!1}),u.incrementCounter("file_recover_errors",1),{content:[{type:"text",text:"\u274c **Recovery Failed:** "+(0,d.getErrorMessage)(e)}],isError:!0}}}
|
|
2604
2622
|
const i=s(t(6928)),a=s(t(1943)),c=s(t(5967)),l=t(3922),d=t(8824)},4648(e,exports,t){"use strict"
|
|
2605
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestOperations=async function(e,
|
|
2623
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleRequestOperations=async function(e,t,p,m,g,f){const y=m.child({tool:"request_operations"})
|
|
2606
2624
|
try{const w=e
|
|
2607
2625
|
let{requestId:b}=w
|
|
2608
2626
|
const{operation:I}=w
|
|
2609
|
-
if("list"!==I&&"search"!==I&&!b){const
|
|
2610
|
-
if(
|
|
2611
|
-
|
|
2612
|
-
|
|
2627
|
+
if("list"!==I&&"search"!==I&&!b){const e=await(0,a.resolveRequestIdOrError)(p,y,t.currentSessionId,`Error: requestId is required for '${I}' and could not be resolved from session`)
|
|
2628
|
+
if(!e.ok)return e.errorResult
|
|
2629
|
+
b=e.requestId}switch(y.info("Processing request operation",{requestId:b,operation:I}),I){case"complete":{y.info("Routing to complete-request handler")
|
|
2630
|
+
const e={requestId:b,summary:w.complete.summary,skipTestsReason:w.complete.skipTestsReason,skipTests:w.complete.skipTests}
|
|
2631
|
+
return(0,u.withAlchemyKind)(await(0,r.handleCompleteRequest)(e,t,p,m,g,f),h.complete)}case"merge":return y.info("Routing to merge handler"),(0,u.withAlchemyKind)(await(0,l.handleMergeRequest)({requestId:b,verifications:w.merge?.verifications||[]},t,p,m,g,f),h.merge)
|
|
2613
2632
|
case"approve":{y.info("Routing to approve-request handler")
|
|
2614
2633
|
const e={requestId:b}
|
|
2615
|
-
return(0,
|
|
2634
|
+
return(0,u.withAlchemyKind)(await(0,c.handleApproveRequest)(e,t,p,m,g,f),h.approve)}case"revert":{y.info("Routing to revert-request handler")
|
|
2616
2635
|
const e={requestId:b,reason:w.revert.reason,confirmDestructive:w.revert.confirmDestructive}
|
|
2617
|
-
return(0,
|
|
2636
|
+
return(0,u.withAlchemyKind)(await(0,n.handleRevertRequest)(e,t,p,m,g),h.revert)}case"get-info":{y.info("Routing to get-request-information handler")
|
|
2618
2637
|
const e={requestId:b}
|
|
2619
|
-
return(0,
|
|
2638
|
+
return(0,u.withAlchemyKind)(await(0,o.handleGetRequestInformation)(e,t,p,m,g),h["get-info"])}case"list":{y.info("Routing to list-requests handler")
|
|
2620
2639
|
const e={filters:w.list?.filters}
|
|
2621
|
-
return(0,
|
|
2640
|
+
return(0,u.withAlchemyKind)(await(0,s.handleListRequests)(e,t,p,m,g),h.list)}case"search":{y.info("Routing to search-requests handler")
|
|
2622
2641
|
const e={search:w.search}
|
|
2623
|
-
return(0,
|
|
2624
|
-
try{const e=p.getProxyClient(),
|
|
2625
|
-
return(Array.isArray(
|
|
2626
|
-
return y.error(e),{content:[{type:"text",text:"\u274c **Request Operations Failed:** "+e}],isError:!0}}}}catch(e){return y.error("Request operations failed",{error:e instanceof Error?e.stack:e+""}),g.incrementCounter("request_operations_errors",1),{content:[{type:"text",text:"\u274c **Request Operations Failed:** "+(0,
|
|
2627
|
-
const r=t(5715),n=t(6416),o=t(5434),s=t(8037),i=t(233),a=t(
|
|
2642
|
+
return(0,u.withAlchemyKind)(await(0,i.handleSearchRequests)(e,t,p,m,g),h.search)}case"delete-empty":if(y.info("Routing to delete-empty handler"),!b)return{content:[{type:"text",text:"\u274c **Request Operations Failed:** requestId is required for delete-empty"}],isError:!0}
|
|
2643
|
+
try{const e=p.getProxyClient(),r=await e.proxyGet(`/api/projects/${t.projectId}/tasks`,{requestLocalId:b,limit:1}),n=r?.data||r||[]
|
|
2644
|
+
return(Array.isArray(n)?n.length:0)>0?{content:[{type:"text",text:`\u274c Cannot delete ${b}: it has tasks. Only empty requests (no tasks created) can be deleted.`}],isError:!0}:(await e.proxyDelete(`/api/projects/${t.projectId}/requests/${b}`),y.info("Empty request deleted",{requestId:b}),(0,u.withAlchemyKind)({content:[{type:"text",text:`\u2705 Request ${b} deleted (had no tasks).`}]},h["delete-empty"]))}catch(e){return{content:[{type:"text",text:"\u274c **Failed to delete request:** "+(0,d.getErrorMessage)(e)}],isError:!0}}default:{const e="Unknown operation type: "+I
|
|
2645
|
+
return y.error(e),{content:[{type:"text",text:"\u274c **Request Operations Failed:** "+e}],isError:!0}}}}catch(e){return y.error("Request operations failed",{error:e instanceof Error?e.stack:e+""}),g.incrementCounter("request_operations_errors",1),{content:[{type:"text",text:"\u274c **Request Operations Failed:** "+(0,d.getErrorMessage)(e)}],isError:!0}}}
|
|
2646
|
+
const r=t(5715),n=t(6416),o=t(5434),s=t(8037),i=t(233),a=t(9032),c=t(1537),l=t(1925),d=t(8824),u=t(2272),h={complete:"complete-request",merge:"finalize-request",approve:"approve-request",revert:"revert-request","get-info":"get-request-info",list:"list-requests",search:"search-requests","delete-empty":"delete-empty-request"}},4710(e,exports,t){"use strict"
|
|
2628
2647
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2629
2648
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProjectClient=void 0
|
|
2630
2649
|
const n=r(t(9896)),o=r(t(6928)),s=t(7645),i=t(2161),a=t(1058),c=t(8824)
|
|
@@ -2883,7 +2902,7 @@ var t={}
|
|
|
2883
2902
|
if(null!=e)for(var s=r(e),i=0;i<s.length;i++)"default"!==s[i]&&n(t,e,s[i])
|
|
2884
2903
|
return o(t,e),t})
|
|
2885
2904
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.testingDefs=void 0
|
|
2886
|
-
const i=s(t(6183)),a=t(2052),c=e=>(t,r)=>e(t,r.context,r.apiClient,r.logger,r.metrics,r.cliOrigin)
|
|
2905
|
+
const i=s(t(6183)),a=t(2052),c=e=>(t,r)=>e(t,r.context,r.apiClient,r.logger,r.metrics,r.cliOrigin,{progressToken:r.progressToken,sendNotification:r.sendNotification})
|
|
2887
2906
|
exports.testingDefs=[{name:"testing_process_list",description:"List all test processes for this project. Shows active/inactive status, command count, and scope.",schema:i.TestingProcessListSchema,annotations:{title:"List Test Processes",readOnlyHint:!0},readOnly:!0,handler:c(a.handleTestingProcessList)},{name:"testing_process_get",description:"Get detailed configuration of a test process including setup and test commands.",schema:i.TestingProcessGetSchema,annotations:{title:"Get Test Process",readOnlyHint:!0},readOnly:!0,handler:c(a.handleTestingProcessGet)},{name:"testing_process_create",description:"Create a new test process with optional setup commands and one or more test commands. Each command has a name, shell command, required flag, and timeout.",schema:i.TestingProcessCreateSchema,annotations:{title:"Create Test Process",readOnlyHint:!1},handler:c(a.handleTestingProcessCreate)},{name:"testing_process_update",description:"Update an existing test process. Can modify name, description, scope, active status, and test configuration.",schema:i.TestingProcessUpdateSchema,annotations:{title:"Update Test Process",readOnlyHint:!1},handler:c(a.handleTestingProcessUpdate)},{name:"testing_process_delete",description:"Delete a test process. Removes the registered process from the project; existing test runs against it stay in the database. Use when you want to fully reset bootstrapping (e.g. before re-running `tests setup`) rather than toggling active state.",schema:i.TestingProcessDeleteSchema,annotations:{title:"Delete Test Process",readOnlyHint:!1,destructiveHint:!0},handler:c(a.handleTestingProcessDelete)},{name:"testing_reference",description:"Get the test process design guide with patterns for Node.js, Python, Go, Rust, and monorepo setups.",schema:i.TestingReferenceSchema,annotations:{title:"Testing Reference",readOnlyHint:!0},readOnly:!0,handler:c(a.handleTestingReference)},{name:"execute_test_command",description:'Execute a specific command from a configured test process. Use commandName="setup" to run all setup commands, or specify a test command name to run it. Only commands defined in the test process can be executed.',schema:i.ExecuteTestCommandSchema,annotations:{title:"Execute Test Command",readOnlyHint:!1},handler:c(a.handleExecuteTestCommand)},{name:"report_test_results",description:"Report the results of a test run. Call this after running all test commands to record pass/fail status and per-command results. The test run is auto-discovered from the current request context.",schema:i.ReportTestResultsSchema,annotations:{title:"Report Test Results",readOnlyHint:!1},handler:c(a.handleReportTestResults)},{name:"tests",description:'Manage testing for this project. Operation "list" returns the registered test processes (use this before doing test-related work to see what is available). Operation "setup" spawns an interactive test-architect session that helps the user configure a test process from scratch; you do not block waiting for it to finish \u2014 continue other work and you will receive a report when the session completes.',schema:i.TestsSchema,annotations:{title:"Tests",readOnlyHint:!1},handler:c(a.handleTests)}]},5278(e,exports,t){"use strict"
|
|
2888
2907
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
2889
2908
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.DocumentFileManager=void 0
|
|
@@ -3030,28 +3049,33 @@ Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
|
3030
3049
|
const r=t(6183),n=t(2965)
|
|
3031
3050
|
exports.def={name:"read_files",description:'Read the contents of multiple files and documents with flexible line selection.\n\nLINE SELECTION (string format):\n- Single line: "lines": "5"\n- Multiple lines: "lines": "1,3,7,10"\n- Range: "lines": "5-15"\n- Entire file: omit "lines" parameter\n\nEXAMPLES:\n- Read first 10 lines: {"path": "file.txt", "lines": "1-10"}\n- Read specific lines: {"path": "file.txt", "lines": "1,5,25"}\n- Read line 42 only: {"path": "file.txt", "lines": "42"}\n- Read entire file: {"path": "file.txt"}\n\nSupports both filesystem files (using \'path\') and tracked documents (using \'documentId\'). More efficient than reading files one by one. Failed reads won\'t stop the entire operation.',schema:r.ReadFilesSchema,annotations:{title:"Read Files/Documents",readOnlyHint:!0},readOnly:!0,handler(e,t){return(0,n.handleReadFiles)(e,t.context,t.logger,t.metrics)}}},5715(e,exports,t){"use strict"
|
|
3032
3051
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleCompleteRequest=async function(e,t,c,l,d,u,h){const p=l.child({tool:"complete_request"}),m=d.startTimer("tool_execution_time")
|
|
3033
|
-
try{const{requestId:n,summary:o}=e
|
|
3052
|
+
try{const{requestId:n,summary:o,skipTestsReason:l,skipTests:d}=e
|
|
3034
3053
|
if(!n)throw(0,r.createValidationError)("Request ID is required")
|
|
3035
3054
|
if(!o)throw(0,r.createValidationError)("Summary is required")
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
return
|
|
3043
|
-
|
|
3044
|
-
|
|
3055
|
+
if(l&&d&&d.length>0)throw(0,r.createValidationError)("Provide either skipTestsReason (skip all) or skipTests (per-command), not both.")
|
|
3056
|
+
p.info("Starting request completion",{requestId:n,skipAllRequested:!!l,perCommandSkipCount:d?.length||0})
|
|
3057
|
+
const u=h?.sessionId
|
|
3058
|
+
let g
|
|
3059
|
+
try{const e=await c.proxyPost(`/api/projects/${t.projectId}/requests/${n}/validate-completion`,{sessionId:u,skipTestsReason:l,skipTests:d})
|
|
3060
|
+
g=e?.data||e}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3061
|
+
return p.error("Server validation failed",{requestId:n,error:t}),m({success:!1,error:"validation_request_failed"}),{content:[{type:"text",text:"Failed to validate completion: "+t}],isError:!0}}if(!g.canComplete){let e=`Cannot complete request ${n}: ${g.reason}\n`
|
|
3062
|
+
return g.blockedByTasks&&g.blockedByTasks.length>0&&(e+="\n**Tasks that must be completed or canceled first:**\n",g.blockedByTasks.forEach(((t,r)=>{e+=`${r+1}. **${t.taskId}** - ${t.title} (Status: ${t.status})\n`}))),g.lifoViolation&&(e+="\n**Requests that must be re-completed first (LIFO order):**\n",g.lifoViolation.blockingRequests.forEach(((t,r)=>{e+=`${r+1}. **${t.requestId}** - ${t.title} (Status: ${t.status})\n`}))),m({success:!1,reason:"server_blocked"}),{content:[{type:"text",text:e}],isError:!0}}if(g.testsSkipped&&(l||d&&d.length>0))try{const e=c.getToolRecordClient()
|
|
3063
|
+
e&&await e.createToolRecord({projectId:t.projectId,requestId:n,type:"tests-skipped",metadata:{...l?{reason:l}:{},...d&&d.length>0?{skipTests:d}:{},completionMode:g.completionMode,timestamp:(new Date).toISOString()}})}catch(e){p.warn("Failed to persist tests-skipped tool_record",{error:(0,s.getErrorMessage)(e)})}const f=c.getRequestClient()
|
|
3064
|
+
let y="auto-merge"!==g.completionMode&&!g.testsSkipped
|
|
3065
|
+
const w="manual-review"===g.reviewMode
|
|
3066
|
+
let b,I=null
|
|
3067
|
+
if(y)try{const[e,r]=await Promise.all([c.proxyGet(`/api/projects/${t.projectId}/requests/${n}/test-runs`),fetch(`${(0,a.getActionServerBaseUrl)()}/api/branch-head?requestId=${encodeURIComponent(n)}`,{signal:AbortSignal.timeout(5e3)}).catch((e=>(p.debug("branch-head fetch failed; proceeding with ready_for_review",{error:(0,s.getErrorMessage)(e)}),null)))]),o=e?.data||e||[],i=Array.isArray(o)&&o.length>0?o[0]:null
|
|
3045
3068
|
if(i&&"passed"===i.status&&i.commitSha){let e=null
|
|
3046
3069
|
if(r&&r.ok){const t=await r.json()
|
|
3047
|
-
e=t?.data?.sha??null}e&&e===i.commitSha&&(
|
|
3048
|
-
try{await
|
|
3049
|
-
return m({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let
|
|
3050
|
-
try{
|
|
3051
|
-
return m({success:!1,error:"fetch_request_failed"}),{content:[{type:"text",text:"Failed to fetch request criteria: "+t}],isError:!0}}const
|
|
3052
|
-
if(m({success:!0}),
|
|
3053
|
-
|
|
3054
|
-
|
|
3070
|
+
e=t?.data?.sha??null}e&&e===i.commitSha&&(y=!1,I=`latest test run ${i.id} passed against current branch HEAD ${e.slice(0,7)}`,b=i.id,p.info("Skip-if-fresh: SHA match, bypassing ready_for_review",{requestId:n,runId:i.id,sha:e}))}}catch(e){p.debug("Skip-if-fresh lookup failed; proceeding with ready_for_review",{error:(0,s.getErrorMessage)(e)})}const k=y||w?"ready_for_review":"ready_for_merge"
|
|
3071
|
+
try{await f.updateRequest(n,{status:k,completionSummary:o,...b?{skippedTestRunId:b}:{}})}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3072
|
+
return m({success:!1,error:"status_transition_failed"}),{content:[{type:"text",text:"Failed to transition request: "+t}],isError:!0}}let v
|
|
3073
|
+
try{v=await f.getRequest(n)}catch(e){const t=(0,s.getErrorMessage)(e)
|
|
3074
|
+
return m({success:!1,error:"fetch_request_failed"}),{content:[{type:"text",text:"Failed to fetch request criteria: "+t}],isError:!0}}const C=v?.acceptanceCriteria||[]
|
|
3075
|
+
if(m({success:!0}),y)return{content:[{type:"text",text:`Request ${n} moved to ready_for_review. Testing is active \u2014 a notification has been created for the user to choose testing mode. Do NOT call merge or any other tool. Your work is done. Stop here and wait.`}]}
|
|
3076
|
+
if(w)return{content:[{type:"text",text:`Request ${n} submitted for human review.${g.testsSkipped&&l?`\n\n_Tests skipped: ${l}_`:""}\n\nThe project is set to manual-review \u2014 a person will approve and merge from the UI. Do NOT call merge yourself.`}]}
|
|
3077
|
+
const _=I?`\n\n_Skipped re-running tests: ${I}._\n`:""
|
|
3078
|
+
return 0===C.length?{content:[{type:"text",text:`Request ${n} is ready. ${_}No acceptance criteria defined \u2014 call merge directly.`}]}:{content:[{type:"text",text:`Request ${n} completion started (${k}).${_}\n\n## Next Step: Verify & Merge\n\n${(0,i.formatVerifyInstructions)(C)}\n\nUse the merge operation with your verification evidence to merge to main.`}]}}catch(r){let s="An unexpected error occurred",i=""
|
|
3055
3079
|
r instanceof n.ZodError?(s="Validation error",i=r.errors.map((e=>`${e.path.join(".")}: ${e.message}`)).join(", ")):r instanceof Error?(s=r.message,i=r.stack||""):i=r+"",p.error("Complete request failed",{error:s,details:i})
|
|
3056
3080
|
try{await(0,o.createFailureToolRecord)("complete-request",r,{error:s,details:i,requestId:e?.requestId},c.getToolRecordClient(),p,d,{requestId:e?.requestId,projectId:t.projectId,note:"Failed to complete request"})}catch{}return d.startTimer("tool_execution_time")({success:!1,error:r instanceof Error?r.name:"unknown"}),{content:[{type:"text",text:"Error: "+s}],isError:!0}}}
|
|
3057
3081
|
const r=t(9860),n=t(1569),o=t(8616),s=t(8824),i=t(5454),a=t(9414)},5767(e,exports,t){"use strict"
|
|
@@ -3061,7 +3085,7 @@ exports.def={name:"specialist_ops",description:"Manage your pool of up to 10 spe
|
|
|
3061
3085
|
module.exports=require("@modelcontextprotocol/sdk/server/stdio.js")},5806(e,exports,t){"use strict"
|
|
3062
3086
|
function r(){const e=(0,o.areTestsRequiredForCompletion)(),t=e?s:i
|
|
3063
3087
|
if(t)return t
|
|
3064
|
-
const r=n.z.object({requestId:n.z.string(),summary:n.z.string(),acceptanceEvidence:n.z.array(n.z.object({evidence:n.z.string()}))}),a=n.z.object({testRecords:n.z.array(n.z.string()),coverage:n.z.object({criteriaTestedCount:n.z.number(),totalTestCases:n.z.number()}),criterionCoverage:n.z.array(n.z.object({coverage:n.z.enum(["none","partial","full"]),testRecords:n.z.array(n.z.string())}))}),c=e?r.extend({testVerification:a}):r
|
|
3088
|
+
const r=n.z.object({requestId:n.z.string(),summary:n.z.string(),skipTestsReason:n.z.string().min(20).optional(),skipTests:n.z.array(n.z.object({commandName:n.z.string().min(1),reason:n.z.string().min(20)})).optional(),acceptanceEvidence:n.z.array(n.z.object({evidence:n.z.string()}))}),a=n.z.object({testRecords:n.z.array(n.z.string()),coverage:n.z.object({criteriaTestedCount:n.z.number(),totalTestCases:n.z.number()}),criterionCoverage:n.z.array(n.z.object({coverage:n.z.enum(["none","partial","full"]),testRecords:n.z.array(n.z.string())}))}),c=e?r.extend({testVerification:a}):r
|
|
3065
3089
|
return e?s=c:i=c,c}Object.defineProperty(exports,"__esModule",{value:!0}),exports.DynamicCompleteRequestSchema=void 0,exports.getDynamicCompleteRequestSchema=r
|
|
3066
3090
|
const n=t(1569),o=t(2478)
|
|
3067
3091
|
let s=null,i=null
|
|
@@ -3202,19 +3226,19 @@ const n=await this.requestWithRetry("POST","/api/files/recover",t)
|
|
|
3202
3226
|
if(!(0,i.safeGetResponseData)(n,null))throw new r.ServiceError("Empty response when recovering file")
|
|
3203
3227
|
const o=(0,i.safeGetResponseData)(n,{success:!0,path:e.path,commitHash:e.commitHash,backupPath:void 0})
|
|
3204
3228
|
return this.logger.info("Successfully recovered file "+e.path,{path:o.path,commitHash:o.commitHash,backupPath:o.backupPath}),o}catch(t){throw this.logger.error("Failed to recover file "+e.path,{path:e.path,commitHash:e.commitHash,error:t instanceof Error?t.stack:t+""}),t}}}exports.FileOperationsClient=a},6183(e,exports,t){"use strict"
|
|
3205
|
-
Object.defineProperty(exports,"__esModule",{value:!0}),exports.
|
|
3229
|
+
Object.defineProperty(exports,"__esModule",{value:!0}),exports.DocumentOperationsSchema=exports.SearchDocumentsSchema=exports.CreateDocumentSchema=exports.ReplaceLinesSchema=exports.InsertLinesSchema=exports.SwitchToRequestBranchSchema=exports.PlannerOpsSchema=exports.SpecialistOpsSchema=exports.SubagentOperationsSchema=exports.TaskInspectSchema=exports.CompleteTaskSchema=exports.GetTaskInformationSchema=exports.GetRequestInformationSchema=exports.ListRequestsSchema=exports.ListTasksSchema=exports.SearchSchema=exports.QueryHistorySchema=exports.RequestDiffSchema=exports.FileRecoverSchema=exports.FileHistorySchema=exports.DeleteFilesSchema=exports.DeleteFileSchema=exports.ReplaceInFilesSchema=exports.ReplaceStringsSchema=exports.ReplaceStringSchema=exports.MoveFilesSchema=exports.CreateDirectorySchema=exports.GetFileInfoSchema=exports.ListDirectorySchema=exports.ReadFilesSchema=exports.ViewAssetSchema=exports.WriteFileSchema=exports.UpdateTaskStatusSchema=exports.CreateTaskSchema=exports.CreateRequestSchema=exports.CompleteRequestSchema=exports.skipTestsSchema=exports.skipTestsReasonSchema=exports.ExecutedTestSchema=exports.TestVerificationSchema=exports.TestDefinitionSchema=exports.AcceptanceCriterionSchema=exports.RecordTypeEnum=exports.EvidenceTypeEnum=exports.CriterionStatusEnum=exports.RequestStatusEnum=exports.TaskStatusEnum=exports.RequestTypeEnum=exports.TestCoverageTypeEnum=exports.CompletionStatusEnum=void 0,exports.CommitToViewedSessionSchema=exports.UpdateSpecializationSchema=exports.SessionMessageOperationsSchema=exports.ReportTestResultsSchema=exports.CommandsSchema=exports.ExecuteTestCommandSchema=exports.TestsSchema=exports.TestingReferenceSchema=exports.TestingProcessUpdateSchema=exports.TestingProcessDeleteSchema=exports.TestingProcessCreateSchema=exports.TestingProcessGetSchema=exports.TestingProcessListSchema=exports.MetaReferenceSchema=exports.MetaAgentListSchema=exports.MetaWorkflowRemoveRecipeSchema=exports.MetaWorkflowAddRecipeSchema=exports.MetaHookCreateSchema=exports.MetaHookListSchema=exports.MetaRecipeRemoveHookSchema=exports.MetaRecipeAddHookSchema=exports.MetaRecipeCreateSchema=exports.MetaRecipeGetSchema=exports.MetaRecipeListSchema=exports.MetaWorkflowUpdateSchema=exports.MetaWorkflowCreateSchema=exports.MetaWorkflowGetSchema=exports.MetaWorkflowListSchema=exports.GenerateRequestJournalSchema=exports.QuickManageSchema=exports.QuickReplaceSchema=exports.QuickWriteSchema=exports.RequestOperationsSchema=exports.ManageFilesSchema=exports.ModifyFileSchema=exports.RevertRequestSchema=exports.SwitchToBranchSchema=exports.SwitchToMainBranchSchema=exports.PlanWriteSchema=exports.PlanReadSchema=void 0
|
|
3206
3230
|
const r=t(1569),n=t(8955),o=t(4466),s=(e,t,n={})=>r.z.string().refine((t=>!(!n.allowEmpty||""!==t)||!!t&&e.some((e=>e.test(t)))),{message:t}),i=s([o.TASK_REF_PATTERN,o.TASK_REF_SHORT_PATTERN],"Task ID must be req######+#NN (e.g. req000005#03) or a short form like #01, 01, or 1 (resolved against the active request)."),a=s([/^req\d{6}$/],"Request ID must match format: req###### (e.g. req000001)"),c=s([/^doc_[0-9A-Z]{26}$/i,/^(doc|plan|quest|jour)\d{6}$/],"Document ID must match format: doc_[26 alphanumeric] (ULID) or doc######/plan######/quest######/jour###### (local ID)",{allowEmpty:!0}),l=e=>e.path&&e.documentId?{...e,documentId:void 0}:e,d=e=>!!e.path||!!e.documentId
|
|
3207
|
-
exports.CompletionStatusEnum=r.z.enum(["complete","incomplete","partial"]),exports.TestCoverageTypeEnum=r.z.enum(["unit","e2e","integration","manual"]),exports.RequestTypeEnum=r.z.enum(["feature","bugfix","quick-edit"]),exports.TaskStatusEnum=r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]),exports.RequestStatusEnum=r.z.enum(["open","in_progress","ready_for_review","ready_for_merge","completed","canceled","reverted","conflicted"]),exports.CriterionStatusEnum=r.z.enum(["unverified","verified"]),exports.EvidenceTypeEnum=r.z.enum(["test","manual","other"]),exports.RecordTypeEnum=r.z.enum(["write","modify","blocker","resolution","discovery","test","delete"]),exports.AcceptanceCriterionSchema=r.z.object({description:r.z.string(),status:r.z.enum(["unverified","verified"]).default("unverified"),evidence:r.z.string().optional(),evidenceType:r.z.enum(["test","manual","other"]).optional(),createdAt:r.z.string().optional(),updatedAt:r.z.string().optional()}),exports.TestDefinitionSchema=r.z.object({id:r.z.string(),description:r.z.string(),status:exports.CompletionStatusEnum,coverageType:exports.TestCoverageTypeEnum,accepts:r.z.array(r.z.string())}),exports.TestVerificationSchema=r.z.object({criteria:r.z.array(r.z.string()),tests:r.z.array(r.z.string()),coverageType:exports.TestCoverageTypeEnum,coverageRatio:r.z.number(),createdAt:r.z.string().optional(),updatedAt:r.z.string().optional()}),exports.ExecutedTestSchema=r.z.object({id:r.z.string(),testId:r.z.string(),status:exports.CompletionStatusEnum,results:r.z.string(),coverage:r.z.array(r.z.string()),executedAt:r.z.string()}),exports.CompleteRequestSchema=r.z.object({status:exports.RequestStatusEnum,acceptanceCriteria:r.z.array(exports.AcceptanceCriterionSchema),testVerification:exports.TestVerificationSchema.optional(),completionSummary:r.z.string().optional()}),exports.CreateRequestSchema=r.z.object({title:r.z.string(),type:r.z.enum(["feature","bugfix"]),description:r.z.string(),acceptanceCriteria:r.z.array(r.z.string()),planDocumentId:r.z.string().optional(),questDocumentId:r.z.string().optional()}),exports.CreateTaskSchema=r.z.object({requestId:a,title:r.z.string(),description:r.z.string()}),exports.UpdateTaskStatusSchema=r.z.object({taskId:i,status:exports.TaskStatusEnum,note:r.z.string()}),exports.WriteFileSchema=r.z.object({path:r.z.string().optional(),documentId:c.optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())]),format:r.z.enum(["text","json"]).optional(),append:r.z.boolean().optional(),comment:r.z.string()}).transform(l).refine(d,{message:"path or documentId required"}),exports.ViewAssetSchema=r.z.object({filename:r.z.string().describe("The asset filename (e.g., 01JMXYZ.png)")}),exports.ReadFilesSchema=r.z.object({paths:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),lines:r.z.string().optional()}).transform(l).refine(d,{message:"path or documentId required"})),encoding:r.z.enum(["utf8","utf-8","ascii","binary"]).optional()}),exports.ListDirectorySchema=r.z.object({path:r.z.string(),levels:r.z.number().min(1).max(4).optional(),sortBy:r.z.enum(["name","modified","size","type"]).optional()}),exports.GetFileInfoSchema=r.z.object({path:r.z.string()}),exports.CreateDirectorySchema=r.z.object({path:r.z.string(),comment:r.z.string().optional()}),exports.MoveFilesSchema=r.z.object({operations:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()})),comment:r.z.string()}),exports.ReplaceStringSchema=r.z.object({path:r.z.string(),replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional(),comment:r.z.string()}),exports.ReplaceStringsSchema=r.z.object({operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional()}).transform(l).refine(d,{message:"path or documentId required"})),comment:r.z.string()}),exports.ReplaceInFilesSchema=r.z.object({operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),replacements:r.z.array(r.z.object({old:r.z.string().min(1,"old string cannot be empty"),new:r.z.string(),match_mode:r.z.enum(["unique","all"]).optional()})).min(1,"At least one replacement required"),fuzzy_match:r.z.boolean().optional()}).transform(l).refine(d,{message:"path or documentId required"})).min(1,"At least one operation required"),fuzzy_match:r.z.boolean().optional().default(!0),comment:r.z.string()}),exports.DeleteFileSchema=r.z.object({path:r.z.string(),comment:r.z.string()}),exports.DeleteFilesSchema=r.z.object({paths:r.z.array(r.z.string()).optional(),operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional()}).transform(l).refine(d,{message:"path or documentId required"})).optional(),comment:r.z.string()}).refine((e=>e.paths&&!e.operations||!e.paths&&e.operations),{message:"paths or operations required"}).refine((e=>e.paths?.length||e.operations?.length),{message:"path/operation required"}),exports.FileHistorySchema=r.z.object({path:r.z.string(),limit:r.z.number().min(1).max(100).default(10),showDiff:r.z.boolean().default(!1),showTraceability:r.z.boolean().default(!0),branch:r.z.string().optional(),commit:r.z.string().optional(),since:r.z.string().optional()}),exports.FileRecoverSchema=r.z.object({path:r.z.string(),commitHash:r.z.string(),createBackup:r.z.boolean().default(!0)}),exports.RequestDiffSchema=r.z.object({requestId:a,format:r.z.enum(["summary","unified"]).default("summary"),path:r.z.string().optional()}),exports.QueryHistorySchema=r.z.object({queryType:r.z.enum(["file-history","request-file-history","recover","blame"],{errorMap(){return{message:"Invalid queryType. Valid options: file-history, request-file-history, recover, blame"}}}),fileHistory:r.z.object({path:r.z.string(),limit:r.z.number().min(1).max(100).default(10),showDiff:r.z.boolean().default(!1),showTraceability:r.z.boolean().default(!0),branch:r.z.string().optional(),commit:r.z.string().optional(),since:r.z.string().optional()}).optional(),requestHistory:r.z.object({requestId:a,detailLevel:r.z.enum(["summary","detailed"]).default("summary"),taskId:i.optional(),showDiff:r.z.boolean().optional(),fileFilter:r.z.string().optional()}).optional(),recover:r.z.object({path:r.z.string(),commitHash:r.z.string().optional(),createBackup:r.z.boolean().default(!0)}).optional(),blame:r.z.object({path:r.z.string(),lines:r.z.string().optional(),branch:r.z.string().optional()}).optional()}).refine((e=>"file-history"===e.queryType?e.fileHistory&&!e.requestHistory&&!e.recover:"request-file-history"===e.queryType?e.requestHistory&&!e.fileHistory&&!e.recover:"recover"===e.queryType?e.recover&&!e.fileHistory&&!e.requestHistory&&!e.blame:"blame"===e.queryType&&e.blame&&!e.fileHistory&&!e.requestHistory&&!e.recover),{message:"Invalid query data"}),exports.SearchSchema=r.z.object({needle:r.z.string().optional(),directory:r.z.string().optional(),options:r.z.object({caseSensitive:r.z.boolean().optional(),fileExtension:r.z.string().optional(),maxResults:r.z.number().optional(),useRegex:r.z.boolean().optional(),searchIn:r.z.enum(["content","filename","both"]).default("content").optional(),contextLines:r.z.number().min(0).max(10).optional(),levels:r.z.number().min(1).max(4).optional(),sortBy:r.z.enum(["name","modified","size","type"]).optional()}).optional()}),exports.ListTasksSchema=r.z.object({requestId:a,filters:r.z.object({status:r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}),exports.ListRequestsSchema=r.z.object({filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["open","in_progress","ready_for_review","completed","canceled"]).optional(),planDocumentId:r.z.string().optional(),questDocumentId:r.z.string().optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}),exports.GetRequestInformationSchema=r.z.object({requestId:a}),exports.GetTaskInformationSchema=r.z.object({taskId:i}),exports.CompleteTaskSchema=r.z.object({taskId:i,summary:r.z.string()}),exports.TaskInspectSchema=r.z.object({operation:r.z.enum(["get-info","list"]),taskId:i.optional(),requestId:a.optional(),status:r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).superRefine(((e,t)=>{"get-info"!==e.operation||e.taskId||t.addIssue({code:"custom",message:'taskId is required for get-info. Example: { "operation": "get-info", "taskId": "req000001#01" }'}),"list"!==e.operation||e.requestId||t.addIssue({code:"custom",message:'requestId is required for list. Example: { "operation": "list", "requestId": "req000001" }'})}))
|
|
3231
|
+
exports.CompletionStatusEnum=r.z.enum(["complete","incomplete","partial"]),exports.TestCoverageTypeEnum=r.z.enum(["unit","e2e","integration","manual"]),exports.RequestTypeEnum=r.z.enum(["feature","bugfix","quick-edit"]),exports.TaskStatusEnum=r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]),exports.RequestStatusEnum=r.z.enum(["open","in_progress","ready_for_review","ready_for_merge","completed","canceled","reverted","conflicted"]),exports.CriterionStatusEnum=r.z.enum(["unverified","verified"]),exports.EvidenceTypeEnum=r.z.enum(["test","manual","other"]),exports.RecordTypeEnum=r.z.enum(["write","modify","blocker","resolution","discovery","test","delete"]),exports.AcceptanceCriterionSchema=r.z.object({description:r.z.string(),status:r.z.enum(["unverified","verified"]).default("unverified"),evidence:r.z.string().optional(),evidenceType:r.z.enum(["test","manual","other"]).optional(),createdAt:r.z.string().optional(),updatedAt:r.z.string().optional()}),exports.TestDefinitionSchema=r.z.object({id:r.z.string(),description:r.z.string(),status:exports.CompletionStatusEnum,coverageType:exports.TestCoverageTypeEnum,accepts:r.z.array(r.z.string())}),exports.TestVerificationSchema=r.z.object({criteria:r.z.array(r.z.string()),tests:r.z.array(r.z.string()),coverageType:exports.TestCoverageTypeEnum,coverageRatio:r.z.number(),createdAt:r.z.string().optional(),updatedAt:r.z.string().optional()}),exports.ExecutedTestSchema=r.z.object({id:r.z.string(),testId:r.z.string(),status:exports.CompletionStatusEnum,results:r.z.string(),coverage:r.z.array(r.z.string()),executedAt:r.z.string()}),exports.skipTestsReasonSchema=r.z.string().min(20).optional().describe("Optional: opt out of ALL tests for this completion. Provide >=20 chars explaining why. Rejected in always-test projects. For per-test opt-out use `skipTests` instead."),exports.skipTestsSchema=r.z.array(r.z.object({commandName:r.z.string().min(1).describe("Name of the test command to skip (must match a command registered in an active test_process)."),reason:r.z.string().min(20).describe("Why this specific command is irrelevant to the change (>=20 chars).")})).optional().describe("Optional: skip individual test commands by name. Mutually exclusive with skipTestsReason. Rejected in always-test projects."),exports.CompleteRequestSchema=r.z.object({status:exports.RequestStatusEnum,acceptanceCriteria:r.z.array(exports.AcceptanceCriterionSchema),testVerification:exports.TestVerificationSchema.optional(),completionSummary:r.z.string().optional()}),exports.CreateRequestSchema=r.z.object({title:r.z.string(),type:r.z.enum(["feature","bugfix"]),description:r.z.string(),acceptanceCriteria:r.z.array(r.z.string()),planDocumentId:r.z.string().optional(),questDocumentId:r.z.string().optional()}),exports.CreateTaskSchema=r.z.object({requestId:a,title:r.z.string(),description:r.z.string()}),exports.UpdateTaskStatusSchema=r.z.object({taskId:i,status:exports.TaskStatusEnum,note:r.z.string()}),exports.WriteFileSchema=r.z.object({path:r.z.string().optional(),documentId:c.optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())]),format:r.z.enum(["text","json"]).optional(),append:r.z.boolean().optional(),comment:r.z.string()}).transform(l).refine(d,{message:"path or documentId required"}),exports.ViewAssetSchema=r.z.object({filename:r.z.string().describe("The asset filename (e.g., 01JMXYZ.png)")}),exports.ReadFilesSchema=r.z.object({paths:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),lines:r.z.string().optional()}).transform(l).refine(d,{message:"path or documentId required"})),encoding:r.z.enum(["utf8","utf-8","ascii","binary"]).optional()}),exports.ListDirectorySchema=r.z.object({path:r.z.string(),levels:r.z.number().min(1).max(4).optional(),sortBy:r.z.enum(["name","modified","size","type"]).optional()}),exports.GetFileInfoSchema=r.z.object({path:r.z.string()}),exports.CreateDirectorySchema=r.z.object({path:r.z.string(),comment:r.z.string().optional()}),exports.MoveFilesSchema=r.z.object({operations:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()})),comment:r.z.string()}),exports.ReplaceStringSchema=r.z.object({path:r.z.string(),replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional(),comment:r.z.string()}),exports.ReplaceStringsSchema=r.z.object({operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional()}).transform(l).refine(d,{message:"path or documentId required"})),comment:r.z.string()}),exports.ReplaceInFilesSchema=r.z.object({operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),replacements:r.z.array(r.z.object({old:r.z.string().min(1,"old string cannot be empty"),new:r.z.string(),match_mode:r.z.enum(["unique","all"]).optional()})).min(1,"At least one replacement required"),fuzzy_match:r.z.boolean().optional()}).transform(l).refine(d,{message:"path or documentId required"})).min(1,"At least one operation required"),fuzzy_match:r.z.boolean().optional().default(!0),comment:r.z.string()}),exports.DeleteFileSchema=r.z.object({path:r.z.string(),comment:r.z.string()}),exports.DeleteFilesSchema=r.z.object({paths:r.z.array(r.z.string()).optional(),operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional()}).transform(l).refine(d,{message:"path or documentId required"})).optional(),comment:r.z.string()}).refine((e=>e.paths&&!e.operations||!e.paths&&e.operations),{message:"paths or operations required"}).refine((e=>e.paths?.length||e.operations?.length),{message:"path/operation required"}),exports.FileHistorySchema=r.z.object({path:r.z.string(),limit:r.z.number().min(1).max(100).default(10),showDiff:r.z.boolean().default(!1),showTraceability:r.z.boolean().default(!0),branch:r.z.string().optional(),commit:r.z.string().optional(),since:r.z.string().optional()}),exports.FileRecoverSchema=r.z.object({path:r.z.string(),commitHash:r.z.string(),createBackup:r.z.boolean().default(!0)}),exports.RequestDiffSchema=r.z.object({requestId:a,format:r.z.enum(["summary","unified"]).default("summary"),path:r.z.string().optional()}),exports.QueryHistorySchema=r.z.object({queryType:r.z.enum(["file-history","request-file-history","recover","blame"],{errorMap(){return{message:"Invalid queryType. Valid options: file-history, request-file-history, recover, blame"}}}),fileHistory:r.z.object({path:r.z.string(),limit:r.z.number().min(1).max(100).default(10),showDiff:r.z.boolean().default(!1),showTraceability:r.z.boolean().default(!0),branch:r.z.string().optional(),commit:r.z.string().optional(),since:r.z.string().optional()}).optional(),requestHistory:r.z.object({requestId:a,detailLevel:r.z.enum(["summary","detailed"]).default("summary"),taskId:i.optional(),showDiff:r.z.boolean().optional(),fileFilter:r.z.string().optional()}).optional(),recover:r.z.object({path:r.z.string(),commitHash:r.z.string().optional(),createBackup:r.z.boolean().default(!0)}).optional(),blame:r.z.object({path:r.z.string(),lines:r.z.string().optional(),branch:r.z.string().optional()}).optional()}).refine((e=>"file-history"===e.queryType?e.fileHistory&&!e.requestHistory&&!e.recover:"request-file-history"===e.queryType?e.requestHistory&&!e.fileHistory&&!e.recover:"recover"===e.queryType?e.recover&&!e.fileHistory&&!e.requestHistory&&!e.blame:"blame"===e.queryType&&e.blame&&!e.fileHistory&&!e.requestHistory&&!e.recover),{message:"Invalid query data"}),exports.SearchSchema=r.z.object({needle:r.z.string().optional(),directory:r.z.string().optional(),options:r.z.object({caseSensitive:r.z.boolean().optional(),fileExtension:r.z.string().optional(),maxResults:r.z.number().optional(),useRegex:r.z.boolean().optional(),searchIn:r.z.enum(["content","filename","both"]).default("content").optional(),contextLines:r.z.number().min(0).max(10).optional(),levels:r.z.number().min(1).max(4).optional(),sortBy:r.z.enum(["name","modified","size","type"]).optional()}).optional()}),exports.ListTasksSchema=r.z.object({requestId:a,filters:r.z.object({status:r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}),exports.ListRequestsSchema=r.z.object({filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["open","in_progress","ready_for_review","completed","canceled"]).optional(),planDocumentId:r.z.string().optional(),questDocumentId:r.z.string().optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}),exports.GetRequestInformationSchema=r.z.object({requestId:a}),exports.GetTaskInformationSchema=r.z.object({taskId:i}),exports.CompleteTaskSchema=r.z.object({taskId:i,summary:r.z.string()}),exports.TaskInspectSchema=r.z.object({operation:r.z.enum(["get-info","list"]),taskId:i.optional(),requestId:a.optional(),status:r.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).superRefine(((e,t)=>{"get-info"!==e.operation||e.taskId||t.addIssue({code:"custom",message:'taskId is required for get-info. Example: { "operation": "get-info", "taskId": "req000001#01" }'}),"list"!==e.operation||e.requestId||t.addIssue({code:"custom",message:'requestId is required for list. Example: { "operation": "list", "requestId": "req000001" }'})}))
|
|
3208
3232
|
const u=r.z.string().min(1).describe("OpenCode session ID")
|
|
3209
3233
|
exports.SubagentOperationsSchema=r.z.object({sessionId:u.optional(),operation:r.z.enum(["spawn","continue","check-status","abort","read-messages","list-sessions"]),prompt:r.z.string().min(1).describe("Instructions for the subagent (required for spawn and continue)").optional(),agent:r.z.string().default("work").refine((e=>(0,n.isValidAgent)(e)),{message:"Invalid agent. Check tool description for available agents."}).describe("The subagent type to spawn (see tool description for available agents)").optional(),description:r.z.string().max(60).describe("Brief label for the UI (max 60 chars, spawn only)").optional(),requestId:r.z.string().describe("Request ID \u2014 associates work (spawn) or filters results (list-sessions)").optional(),allowParallel:r.z.boolean().describe("Allow spawning even if request already has active workers (spawn only)").optional(),useExistingSession:r.z.string().describe("Existing session ID to send prompt to instead of creating new session (spawn only)").optional(),limit:r.z.number().min(1).max(100).describe("Max items to return (read-messages: max 50, list-sessions: max 100)").optional(),activeOnly:r.z.boolean().describe("Only show sessions that are currently active/busy (list-sessions only)").optional(),minTokens:r.z.number().min(0).describe("Only show sessions with at least this many tokens (list-sessions only)").optional(),maxTokens:r.z.number().min(0).describe("Only show sessions with at most this many tokens (list-sessions only)").optional(),maxAgeHours:r.z.number().min(0).describe("Only show sessions newer than X hours (list-sessions only)").optional()}).refine((e=>"spawn"===e.operation?!!e.prompt:"continue"===e.operation?!!e.prompt&&!!e.sessionId:"check-status"===e.operation||"abort"===e.operation||"read-messages"===e.operation?!!e.sessionId:"list-sessions"===e.operation),{message:"spawn requires prompt; continue requires prompt+sessionId; check-status/abort/read-messages require sessionId"}),exports.SpecialistOpsSchema=r.z.object({operation:r.z.enum(["delegate","follow-up","check-status","list","abort"]),sessionId:u.optional(),prompt:r.z.string().min(1).describe("Instructions for the specialist (required for delegate and follow-up)").optional(),description:r.z.string().max(60).describe("Brief label for the UI (max 60 chars, delegate only)").optional(),specialization:r.z.string().max(500).describe('Domain description (e.g. "Frontend UI components"). Required for delegate').optional(),specializationHeadline:r.z.string().max(80).describe("Optional short tagline (\u226480 chars) shown next to the specialist\u2019s name in the UI directory. The specialist can refine it later via update_specialization.").optional(),requestId:r.z.string().describe("Request ID \u2014 associates work (delegate) or filters results (list)").optional(),activeOnly:r.z.boolean().describe("Only show active/busy specialists (list only)").optional(),limit:r.z.number().min(1).max(100).describe("Max sessions to return (list only)").optional()}).refine((e=>"delegate"===e.operation?!!e.prompt&&!!e.specialization&&!e.sessionId:"follow-up"===e.operation?!!e.prompt&&!!e.sessionId:"check-status"===e.operation||"abort"===e.operation?!!e.sessionId:"list"===e.operation),{message:"delegate requires prompt+specialization; follow-up requires prompt+sessionId; check-status/abort require sessionId"}),exports.PlannerOpsSchema=r.z.object({operation:r.z.enum(["request","check-status","list"]),sessionId:u.optional(),prompt:r.z.string().min(1).describe("What to plan \u2014 feature description, architecture question, etc. (required for request)").optional(),description:r.z.string().max(60).describe("Brief label for the UI (max 60 chars, request only)").optional(),activeOnly:r.z.boolean().describe("Only show active/busy planning sessions (list only)").optional(),limit:r.z.number().min(1).max(100).describe("Max sessions to return (list only)").optional()}).refine((e=>"request"===e.operation?!!e.prompt:"check-status"===e.operation?!!e.sessionId:"list"===e.operation),{message:"request requires prompt; check-status requires sessionId"}),exports.SwitchToRequestBranchSchema=r.z.object({requestId:a}),exports.InsertLinesSchema=r.z.object({operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),insertions:r.z.array(r.z.object({type:r.z.enum(["before","after","between"]),line:r.z.number().optional(),afterLine:r.z.number().optional(),beforeLine:r.z.number().optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}).refine((e=>"between"===e.type?void 0!==e.afterLine&&void 0!==e.beforeLine&&void 0===e.line:void 0!==e.line&&void 0===e.afterLine&&void 0===e.beforeLine),{message:"Invalid line parameters"}))}).transform(l).refine(d,{message:"path or documentId required"})),comment:r.z.string()}),exports.ReplaceLinesSchema=r.z.object({operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),replacements:r.z.array(r.z.object({lines:r.z.string(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}))}).transform(l).refine(d,{message:"path or documentId required"})),comment:r.z.string()}),exports.CreateDocumentSchema=r.z.object({requestId:a.optional(),filename:r.z.string().refine((e=>e.toLowerCase().endsWith(".md")),{message:"Filename must end with .md extension"}),content:r.z.string(),type:r.z.enum(["Report","Documentation","Plan","Other"],{errorMap(){return{message:"Document type must be one of: Report, Documentation, Plan, Other"}}}),comment:r.z.string()}),exports.SearchDocumentsSchema=r.z.object({query:r.z.string(),type:r.z.enum(["Report","Documentation","Plan","Other"]).optional(),requestId:a.optional(),includeArchived:r.z.boolean().default(!1),maxResults:r.z.number().min(1).max(100).default(20),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),searchIn:r.z.enum(["content","filename","both"]).default("both")}),exports.DocumentOperationsSchema=r.z.object({operation:r.z.enum(["create","search","create-snapshot","get-history","get-version","restore-version","list-annotations","create-annotation","reply-to-annotation","resolve-annotation"]),documentId:c.optional(),requestId:a.optional(),filename:r.z.string().optional(),content:r.z.string().optional(),type:r.z.enum(["Report","Documentation","Plan","Other"]).optional(),comment:r.z.string().optional(),query:r.z.string().optional(),includeArchived:r.z.boolean().default(!1),maxResults:r.z.number().min(1).max(100).default(20),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),searchIn:r.z.enum(["content","filename","both"]).default("both"),versionLabel:r.z.string().optional(),changeSummary:r.z.string().optional(),versionNumber:r.z.number().int().min(1).optional(),selectedText:r.z.string().optional(),prefixContext:r.z.string().optional(),suffixContext:r.z.string().optional(),lineHint:r.z.number().int().optional(),body:r.z.string().optional(),annotationId:r.z.string().optional()}).superRefine(((e,t)=>{const r=e.operation;["create-snapshot","get-history","get-version","restore-version","list-annotations","create-annotation","reply-to-annotation","resolve-annotation"].includes(r)&&!e.documentId&&t.addIssue({code:"custom",message:`documentId is required for '${r}'. Example: { "operation": "${r}", "documentId": "doc000001" }`}),"create"===r&&(e.filename?e.filename.toLowerCase().endsWith(".md")||t.addIssue({code:"custom",message:"Filename must end with .md extension"}):t.addIssue({code:"custom",message:"filename is required for create (must end with .md)"}),e.content||t.addIssue({code:"custom",message:"content is required for create"}),e.type||t.addIssue({code:"custom",message:"type is required for create (Report, Documentation, Plan, or Other)"}),e.comment||t.addIssue({code:"custom",message:"comment is required for create"})),"search"!==r||e.query||t.addIssue({code:"custom",message:'query is required for search. Example: { "operation": "search", "query": "search term" }'}),"get-version"!==r&&"restore-version"!==r||e.versionNumber||t.addIssue({code:"custom",message:`versionNumber is required for '${r}'`}),"create-annotation"===r&&(e.selectedText||t.addIssue({code:"custom",message:"selectedText is required for create-annotation"}),e.body||t.addIssue({code:"custom",message:"body is required for create-annotation"})),"reply-to-annotation"===r&&(e.annotationId||t.addIssue({code:"custom",message:"annotationId is required for reply-to-annotation"}),e.body||t.addIssue({code:"custom",message:"body is required for reply-to-annotation"})),"resolve-annotation"!==r||e.annotationId||t.addIssue({code:"custom",message:"annotationId is required for resolve-annotation"})}))
|
|
3210
3234
|
const h=s([/^doc_[0-9A-Z]{26}$/i,/^(plan|quest)\d{6}$/],"Plan ID must match format: doc_[26 alphanumeric] (ULID) or plan######/quest###### (local ID)")
|
|
3211
3235
|
exports.PlanReadSchema=r.z.object({operation:r.z.enum(["get","get-active","list","get-history","get-requests"]),planId:h.optional(),searchQuery:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["createdAt","updatedAt","filename"]).default("updatedAt"),sortDirection:r.z.enum(["ASC","DESC"]).default("DESC")}).superRefine(((e,t)=>{["get","get-history","get-requests"].includes(e.operation)&&!e.planId&&t.addIssue({code:"custom",message:`planId is required for '${e.operation}'. Example: { "operation": "${e.operation}", "planId": "plan000001" }`})})),exports.PlanWriteSchema=r.z.object({operation:r.z.enum(["create","update","append","replace","create-snapshot","restore","set-active"]),planId:h.optional(),kind:r.z.enum(["plan","quest"]).default("plan").describe("Document kind to create. Defaults to plan; quest writes type=Quest with quest metadata."),criteria:r.z.string().optional().describe("Quest acceptance criteria. Free text. Settable on create or update (when planId is a Quest)."),tickIntervalSeconds:r.z.number().int().min(300).optional().describe("Quest evaluation interval (seconds). Default 1800 (30 min) at create time. Minimum 300 (5 min). Provide on update to change."),maxInFlight:r.z.number().int().min(1).optional().describe("Quest concurrent in-flight request cap. Default 1 at create time."),maxPerDay:r.z.number().int().min(1).optional().describe("Quest daily spawn cap. Default 24 at create time."),minIterations:r.z.number().int().min(1).optional().describe("Quest minimum tick count. Runner fires at least this many ticks. Default 3 at create time."),status:r.z.enum(["open","closed"]).optional().describe('Quest lifecycle status. Set to "closed" to pause the runner; "open" to resume.'),content:r.z.string().optional(),name:r.z.string().optional().describe("Plan/quest name (used in filename for create; optional new name for update)."),old:r.z.string().optional().describe("Text to find in the plan (for replace)"),new:r.z.string().optional().describe("Replacement text (for replace)"),versionLabel:r.z.string().optional(),changeSummary:r.z.string().optional(),versionNumber:r.z.number().int().min(1).optional()}).superRefine(((e,t)=>{const r=e.operation
|
|
3212
3236
|
if("create"===r?(e.name||t.addIssue({code:"custom",message:"name is required for 'create'. Letters, numbers, hyphens, underscores only."}),void 0===e.content&&t.addIssue({code:"custom",message:"content is required for 'create' (use empty string for an empty body)."}),"quest"!==e.kind||e.criteria||t.addIssue({code:"custom",message:"criteria is required when kind='quest'."})):e.planId||t.addIssue({code:"custom",message:`planId is required for '${r}'.`}),"append"!==r||e.content||t.addIssue({code:"custom",message:'content is required for \'append\'. Example: { "operation": "append", "planId": "plan000001", "content": "..." }'}),"update"===r){const r=void 0!==e.content,n=void 0!==e.criteria||void 0!==e.tickIntervalSeconds||void 0!==e.maxInFlight||void 0!==e.maxPerDay||void 0!==e.minIterations||void 0!==e.status
|
|
3213
|
-
r||n||t.addIssue({code:"custom",message:"update requires either 'content' (plan or quest body) or at least one metadata field (criteria, tickIntervalSeconds, maxInFlight, maxPerDay, minIterations, status \u2014 quest only)."})}"replace"===r&&(e.old||t.addIssue({code:"custom",message:'old is required for replace. Example: { "operation": "replace", "planId": "plan000001", "old": "find this", "new": "replace with" }'}),void 0===e.new&&t.addIssue({code:"custom",message:"new is required for replace"})),"restore"!==r||e.versionNumber||t.addIssue({code:"custom",message:'versionNumber is required for restore. Example: { "operation": "restore", "planId": "plan000001", "versionNumber": 1 }'})})),exports.SwitchToMainBranchSchema=r.z.object({}),exports.SwitchToBranchSchema=r.z.object({branch:r.z.string().optional()}),exports.RevertRequestSchema=r.z.object({requestId:a,reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}),exports.ModifyFileSchema=r.z.object({operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),operationType:r.z.enum(["replace-string","insert-lines","replace-lines","delete-string","delete-lines"]),replaceString:r.z.object({replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional()}).optional(),insertLines:r.z.object({insertions:r.z.array(r.z.object({type:r.z.enum(["before","after","between"]),line:r.z.number().optional(),afterLine:r.z.number().optional(),beforeLine:r.z.number().optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}).refine((e=>"between"===e.type?void 0!==e.afterLine&&void 0!==e.beforeLine&&void 0===e.line:void 0!==e.line&&void 0===e.afterLine&&void 0===e.beforeLine),{message:"Invalid line parameters"}))}).optional(),replaceLines:r.z.object({replacements:r.z.array(r.z.object({lines:r.z.string(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}))}).optional(),deleteString:r.z.object({patterns:r.z.array(r.z.string()),mode:r.z.enum(["all","unique"]).optional()}).optional(),deleteLines:r.z.object({lines:r.z.string()}).optional()}).transform(l).refine(d,{message:"path or documentId required"}).refine((e=>"replace-string"===e.operationType?e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"insert-lines"===e.operationType?e.insertLines&&!e.replaceString&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"replace-lines"===e.operationType?e.replaceLines&&!e.replaceString&&!e.insertLines&&!e.deleteString&&!e.deleteLines:"delete-string"===e.operationType?e.deleteString&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteLines:"delete-lines"===e.operationType&&e.deleteLines&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString),{message:"Invalid operation data"})),comment:r.z.string()}),exports.ManageFilesSchema=r.z.object({operations:r.z.array(r.z.object({operationType:r.z.enum(["create-directory","move-files","delete-files","get-file-info"]),createDirectory:r.z.object({path:r.z.string()}).optional(),moveFiles:r.z.object({moves:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()}))}).optional(),deleteFiles:r.z.object({targets:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional()}).transform(l).refine(d,{message:"path or documentId required"}))}).optional(),getFileInfo:r.z.object({path:r.z.string()}).optional()}).refine((e=>"create-directory"===e.operationType?e.createDirectory&&!e.moveFiles&&!e.deleteFiles&&!e.getFileInfo:"move-files"===e.operationType?e.moveFiles&&!e.createDirectory&&!e.deleteFiles&&!e.getFileInfo:"delete-files"===e.operationType?e.deleteFiles&&!e.createDirectory&&!e.moveFiles&&!e.getFileInfo:"get-file-info"===e.operationType&&e.getFileInfo&&!e.createDirectory&&!e.moveFiles&&!e.deleteFiles),{message:"Invalid operation data"})),comment:r.z.string()}),exports.RequestOperationsSchema=r.z.object({requestId:a.optional(),operation:r.z.enum(["complete","merge","approve","revert","get-info","list","search","delete-empty"]),complete:r.z.preprocess((e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e),r.z.object({summary:r.z.string()})).optional(),merge:r.z.preprocess((e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e),r.z.object({verifications:r.z.array(r.z.object({key:r.z.string().min(2).max(4),evidence:r.z.string().min(1)})).min(1)})).optional(),revert:r.z.object({reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}).optional(),list:r.z.object({filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","ready_for_merge","resolving_conflicts","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}).optional(),search:r.z.object({query:r.z.string().min(1),searchIn:r.z.enum(["title","description","criteria","all"]).default("all"),filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","ready_for_merge","resolving_conflicts","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0)}).optional()}).optional(),approve:r.z.object({}).optional()}).superRefine(((e,t)=>{e.requestId
|
|
3237
|
+
r||n||t.addIssue({code:"custom",message:"update requires either 'content' (plan or quest body) or at least one metadata field (criteria, tickIntervalSeconds, maxInFlight, maxPerDay, minIterations, status \u2014 quest only)."})}"replace"===r&&(e.old||t.addIssue({code:"custom",message:'old is required for replace. Example: { "operation": "replace", "planId": "plan000001", "old": "find this", "new": "replace with" }'}),void 0===e.new&&t.addIssue({code:"custom",message:"new is required for replace"})),"restore"!==r||e.versionNumber||t.addIssue({code:"custom",message:'versionNumber is required for restore. Example: { "operation": "restore", "planId": "plan000001", "versionNumber": 1 }'})})),exports.SwitchToMainBranchSchema=r.z.object({}),exports.SwitchToBranchSchema=r.z.object({branch:r.z.string().optional()}),exports.RevertRequestSchema=r.z.object({requestId:a,reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}),exports.ModifyFileSchema=r.z.object({operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),operationType:r.z.enum(["replace-string","insert-lines","replace-lines","delete-string","delete-lines"]),replaceString:r.z.object({replacements:r.z.array(r.z.object({old_str:r.z.string(),new_str:r.z.string()})),mode:r.z.enum(["unique","all"]).optional()}).optional(),insertLines:r.z.object({insertions:r.z.array(r.z.object({type:r.z.enum(["before","after","between"]),line:r.z.number().optional(),afterLine:r.z.number().optional(),beforeLine:r.z.number().optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}).refine((e=>"between"===e.type?void 0!==e.afterLine&&void 0!==e.beforeLine&&void 0===e.line:void 0!==e.line&&void 0===e.afterLine&&void 0===e.beforeLine),{message:"Invalid line parameters"}))}).optional(),replaceLines:r.z.object({replacements:r.z.array(r.z.object({lines:r.z.string(),content:r.z.union([r.z.string(),r.z.array(r.z.string())])}))}).optional(),deleteString:r.z.object({patterns:r.z.array(r.z.string()),mode:r.z.enum(["all","unique"]).optional()}).optional(),deleteLines:r.z.object({lines:r.z.string()}).optional()}).transform(l).refine(d,{message:"path or documentId required"}).refine((e=>"replace-string"===e.operationType?e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"insert-lines"===e.operationType?e.insertLines&&!e.replaceString&&!e.replaceLines&&!e.deleteString&&!e.deleteLines:"replace-lines"===e.operationType?e.replaceLines&&!e.replaceString&&!e.insertLines&&!e.deleteString&&!e.deleteLines:"delete-string"===e.operationType?e.deleteString&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteLines:"delete-lines"===e.operationType&&e.deleteLines&&!e.replaceString&&!e.insertLines&&!e.replaceLines&&!e.deleteString),{message:"Invalid operation data"})),comment:r.z.string()}),exports.ManageFilesSchema=r.z.object({operations:r.z.array(r.z.object({operationType:r.z.enum(["create-directory","move-files","delete-files","get-file-info"]),createDirectory:r.z.object({path:r.z.string()}).optional(),moveFiles:r.z.object({moves:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()}))}).optional(),deleteFiles:r.z.object({targets:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional()}).transform(l).refine(d,{message:"path or documentId required"}))}).optional(),getFileInfo:r.z.object({path:r.z.string()}).optional()}).refine((e=>"create-directory"===e.operationType?e.createDirectory&&!e.moveFiles&&!e.deleteFiles&&!e.getFileInfo:"move-files"===e.operationType?e.moveFiles&&!e.createDirectory&&!e.deleteFiles&&!e.getFileInfo:"delete-files"===e.operationType?e.deleteFiles&&!e.createDirectory&&!e.moveFiles&&!e.getFileInfo:"get-file-info"===e.operationType&&e.getFileInfo&&!e.createDirectory&&!e.moveFiles&&!e.deleteFiles),{message:"Invalid operation data"})),comment:r.z.string()}),exports.RequestOperationsSchema=r.z.object({requestId:a.optional(),operation:r.z.enum(["complete","merge","approve","revert","get-info","list","search","delete-empty"]),complete:r.z.preprocess((e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e),r.z.object({summary:r.z.string(),skipTestsReason:exports.skipTestsReasonSchema,skipTests:exports.skipTestsSchema})).optional(),merge:r.z.preprocess((e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e),r.z.object({verifications:r.z.array(r.z.object({key:r.z.string().min(2).max(4),evidence:r.z.string().min(1)})).min(1)})).optional(),revert:r.z.object({reason:r.z.string(),confirmDestructive:r.z.boolean().optional()}).optional(),list:r.z.object({filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","ready_for_merge","resolving_conflicts","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0),sortBy:r.z.enum(["created","updated"]).default("updated"),sortDirection:r.z.enum(["asc","desc"]).default("desc")}).optional()}).optional(),search:r.z.object({query:r.z.string().min(1),searchIn:r.z.enum(["title","description","criteria","all"]).default("all"),filters:r.z.object({type:r.z.enum(["feature","bugfix"]).optional(),status:r.z.enum(["pending_approval","open","in_progress","ready_for_review","ready_for_merge","resolving_conflicts","completed","canceled"]).optional(),dateFrom:r.z.string().optional(),dateTo:r.z.string().optional(),limit:r.z.number().min(1).max(100).default(20),offset:r.z.number().min(0).default(0)}).optional()}).optional(),approve:r.z.object({}).optional()}).superRefine(((e,t)=>{e.requestId
|
|
3214
3238
|
const r=e.operation,n={complete:{field:"complete",hint:'Provide: { complete: { summary: "..." } }'},merge:{field:"merge",hint:'Provide: { merge: { verifications: [{key: "1a", evidence: "..."}] } }'},revert:{field:"revert",hint:'Provide: { revert: { reason: "..." } }'},search:{field:"search",hint:'Provide: { search: { query: "..." } }'}}[r]
|
|
3215
|
-
n&&!e[n.field]&&t.addIssue({code:"custom",message:`'${r}' operation requires '${n.field}' data. ${n.hint}`})})),exports.QuickWriteSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),path:r.z.string().optional(),documentId:c.optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())]),format:r.z.enum(["text","json"]).optional(),append:r.z.boolean().optional()}).transform(l).refine(d,{message:"path or documentId required"}),exports.QuickReplaceSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),replacements:r.z.array(r.z.object({old:r.z.string().min(1),new:r.z.string(),match_mode:r.z.enum(["unique","all"]).optional()})).min(1),fuzzy_match:r.z.boolean().optional()}).transform(l).refine(d,{message:"path or documentId required"})).min(1),fuzzy_match:r.z.boolean().optional(),comment:r.z.string().min(1,"Comment describing the change is required")}),exports.QuickManageSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),operations:r.z.array(r.z.object({operationType:r.z.enum(["create-directory","move-files","delete-files"]),createDirectory:r.z.object({path:r.z.string()}).optional(),moveFiles:r.z.object({moves:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()}))}).optional(),deleteFiles:r.z.object({targets:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional()}).transform(l).refine(d,{message:"path or documentId required"}))}).optional()})).min(1)}),exports.GenerateRequestJournalSchema=r.z.object({requestId:r.z.string().regex(/^req[_\d].+$/,"Invalid request ID format. Expected format: req_[26 chars] or req######")}),exports.MetaWorkflowListSchema=r.z.object({}),exports.MetaWorkflowGetSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to retrieve")}),exports.MetaWorkflowCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the workflow"),shortName:r.z.string().min(1).max(10).describe("Short display name (required, max 10 chars)"),description:r.z.string().optional().describe("Description of what the workflow does"),documentation:r.z.string().optional().describe("Detailed documentation"),defaultAgent:r.z.string().optional().describe("Default agent template to use"),completionMode:r.z.enum(["auto-merge","
|
|
3239
|
+
n&&!e[n.field]&&t.addIssue({code:"custom",message:`'${r}' operation requires '${n.field}' data. ${n.hint}`})})),exports.QuickWriteSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),path:r.z.string().optional(),documentId:c.optional(),content:r.z.union([r.z.string(),r.z.array(r.z.string())]),format:r.z.enum(["text","json"]).optional(),append:r.z.boolean().optional()}).transform(l).refine(d,{message:"path or documentId required"}),exports.QuickReplaceSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),operations:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional(),replacements:r.z.array(r.z.object({old:r.z.string().min(1),new:r.z.string(),match_mode:r.z.enum(["unique","all"]).optional()})).min(1),fuzzy_match:r.z.boolean().optional()}).transform(l).refine(d,{message:"path or documentId required"})).min(1),fuzzy_match:r.z.boolean().optional(),comment:r.z.string().min(1,"Comment describing the change is required")}),exports.QuickManageSchema=r.z.object({title:r.z.string().min(1,"Title is required"),description:r.z.string().min(1,"Description is required"),operations:r.z.array(r.z.object({operationType:r.z.enum(["create-directory","move-files","delete-files"]),createDirectory:r.z.object({path:r.z.string()}).optional(),moveFiles:r.z.object({moves:r.z.array(r.z.object({source:r.z.string(),destination:r.z.string()}))}).optional(),deleteFiles:r.z.object({targets:r.z.array(r.z.object({path:r.z.string().optional(),documentId:c.optional()}).transform(l).refine(d,{message:"path or documentId required"}))}).optional()})).min(1)}),exports.GenerateRequestJournalSchema=r.z.object({requestId:r.z.string().regex(/^req[_\d].+$/,"Invalid request ID format. Expected format: req_[26 chars] or req######")}),exports.MetaWorkflowListSchema=r.z.object({}),exports.MetaWorkflowGetSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to retrieve")}),exports.MetaWorkflowCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the workflow"),shortName:r.z.string().min(1).max(10).describe("Short display name (required, max 10 chars)"),description:r.z.string().optional().describe("Description of what the workflow does"),documentation:r.z.string().optional().describe("Detailed documentation"),defaultAgent:r.z.string().optional().describe("Default agent template to use"),completionMode:r.z.enum(["auto-merge","ask-me","test-by-default","always-test"]).optional().describe("Testing axis: auto-merge (skip tests), ask-me (notify human on completion), test-by-default (tests run; opt-out allowed), always-test (tests required)"),reviewMode:r.z.enum(["auto-finalize","manual-review"]).optional().describe("Review axis: auto-finalize (server merges on pass/skip) or manual-review (human approves via UI)"),approvalMode:r.z.enum(["none","require-approval"]).optional().describe("Pre-work approval: none (default) or require-approval")}),exports.MetaWorkflowUpdateSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to update"),name:r.z.string().min(1).optional().describe("New name"),shortName:r.z.string().max(10).optional().describe("New short name (max 10 chars)"),description:r.z.string().optional().describe("New description"),documentation:r.z.string().optional().describe("New documentation"),defaultAgent:r.z.string().optional().describe("New default agent"),completionMode:r.z.enum(["auto-merge","ask-me","test-by-default","always-test"]).optional().describe("Testing axis"),reviewMode:r.z.enum(["auto-finalize","manual-review"]).optional().describe("Review axis"),approvalMode:r.z.enum(["none","require-approval"]).optional().describe("Pre-work approval: none (default) or require-approval")}),exports.MetaRecipeListSchema=r.z.object({}),exports.MetaRecipeGetSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to retrieve")}),exports.MetaRecipeCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the recipe"),description:r.z.string().optional().describe("Description of what the recipe does"),documentation:r.z.string().optional().describe("Detailed documentation")}),exports.MetaRecipeAddHookSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to add the hook to"),hookId:r.z.string().describe("Hook template ID to add"),position:r.z.number().int().min(0).optional().describe("Position in the recipe (0-based, appended if omitted)")}),exports.MetaRecipeRemoveHookSchema=r.z.object({recipeId:r.z.string().describe("Recipe ID to remove the hook from"),hookId:r.z.string().describe("Hook template ID to remove")}),exports.MetaHookListSchema=r.z.object({}),exports.MetaHookCreateSchema=r.z.object({name:r.z.string().min(1).describe("Unique name for the hook"),description:r.z.string().optional().describe("Description of what the hook does"),eventType:r.z.string().describe("Event type that triggers this hook (e.g., session_idle, request_completed, custom:plan_ready)"),category:r.z.enum(["alchemy","session","message","editing","reading","file_management","documents","history","tool"]).default("session").describe("Hook category"),agent:r.z.string().describe("Agent template to execute when hook fires"),promptTemplate:r.z.string().describe("Prompt template with {{variable}} substitution"),condition:r.z.record(r.z.any()).optional().describe("Condition object for filtering when hook fires"),executionMode:r.z.enum(["same_session","sub_agent","background","notification","direct_report"]).default("background").describe("How to execute the hook"),timing:r.z.enum(["before","after"]).default("after").describe("When to fire relative to the event"),maxIterations:r.z.number().int().min(1).optional().describe("Maximum times to fire per session"),emitEvent:r.z.string().optional().describe("Custom event to emit on completion"),emitEventOnCondition:r.z.union([r.z.object({condition:r.z.object({field:r.z.string(),operator:r.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:r.z.string()}),event:r.z.string()}),r.z.array(r.z.object({condition:r.z.object({field:r.z.string(),operator:r.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:r.z.string()}),event:r.z.string()}))]).optional().describe("Conditional event emission based on output")}),exports.MetaWorkflowAddRecipeSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to add the recipe to"),recipeId:r.z.string().describe("Recipe ID to add"),position:r.z.number().int().min(0).optional().describe("Position in the workflow (0-based, appended if omitted)")}),exports.MetaWorkflowRemoveRecipeSchema=r.z.object({workflowId:r.z.string().describe("Workflow ID to remove the recipe from"),recipeId:r.z.string().describe("Recipe ID to remove")}),exports.MetaAgentListSchema=r.z.object({}),exports.MetaReferenceSchema=r.z.object({}),exports.TestingProcessListSchema=r.z.object({}),exports.TestingProcessGetSchema=r.z.object({processId:r.z.string().describe("Test process ID to retrieve")})
|
|
3216
3240
|
const p=r.z.object({name:r.z.string().min(1).describe('Command name (e.g., "Build", "Unit Tests")'),command:r.z.string().min(1).describe('Shell command to run (e.g., "npm test")'),required:r.z.boolean().default(!0).describe("If true, failure blocks the request (default: true)"),timeout:r.z.number().int().min(10).max(3600).default(300).describe("Max execution time in seconds (default: 300)")})
|
|
3217
|
-
exports.TestingProcessCreateSchema=r.z.object({name:r.z.string().min(1).describe("Name for the test process"),description:r.z.string().optional().describe("Description of what this process verifies"),scope:r.z.string().optional().describe('Path prefix for monorepo scoping (e.g., "packages/api/"). Omit for global.'),setup:r.z.array(r.z.string()).optional().describe('Commands to prepare the environment (e.g., ["ln -s ../../node_modules node_modules"])'),commands:r.z.array(p).min(1).describe("Test commands to execute in order"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands"),fingerprint:r.z.array(r.z.string()).optional().describe('Files whose content invalidates setup. Setup commands re-run only when these files change between runs (e.g. ["package-lock.json"], ["Cargo.lock"], ["uv.lock", "poetry.lock"]). Polyglot repos list multiple. Omit / empty list = always re-run setup (existing behavior).'),poolSize:r.z.number().int().min(1).max(8).optional().describe("Number of warm test worktrees in the pool. Default 2. Set to 1 for languages with very large build artifacts (Rust target/, C++ build/). Higher values allow more parallel test runs at the cost of disk.")}),exports.TestingProcessDeleteSchema=r.z.object({processId:r.z.string().describe("Test process ID to delete")}),exports.TestingProcessUpdateSchema=r.z.object({processId:r.z.string().describe("Test process ID to update"),name:r.z.string().min(1).optional().describe("New name"),description:r.z.string().optional().describe("New description"),scope:r.z.string().optional().describe('New scope to limit when this process runs (e.g., "packages/api/"). Omit to leave unchanged.'),isActive:r.z.boolean().optional().describe("Enable or disable the process"),setup:r.z.array(r.z.string()).optional().describe("New setup commands (replaces existing)"),commands:r.z.array(p).optional().describe("New test commands (replaces existing)"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands"),fingerprint:r.z.array(r.z.string()).optional().describe("Files whose content invalidates setup (replaces existing list)."),poolSize:r.z.number().int().min(1).max(8).optional().describe("Number of warm test worktrees in the pool (replaces existing).")}),exports.TestingReferenceSchema=r.z.object({}),exports.TestsSchema=r.z.object({operation:r.z.enum(["list","setup","run"]).describe('"list" to see registered test processes for this project. "setup" to spawn an interactive test-architect session that helps configure a process. "run" to fire an async test run against the active process for your current request \u2014 optional `name` filters to one registered command. The call returns immediately and you receive a report on your next turn.'),name:r.z.string().optional().describe("Only used by `run`. Filters execution to a single test command by name (matches a command name registered in the test process). Omit to run all required commands.")}),exports.ExecuteTestCommandSchema=r.z.object({processId:r.z.string().describe("Test process ID containing the command"),commandName:r.z.string().describe('Name of the test command to run, or "setup" to run all setup commands in sequence')}),exports.CommandsSchema=r.z.object({operation:r.z.enum(["run","list","remove","register","setup"]).default("run").describe('"run" to execute a command, "list" to see available commands, "register" to submit one or more commands for user approval (a single-item array works for one command; multiple items get bundled into a single batch approval notification), "remove" to delete one, "setup" to spawn the command-architect for an interactive setup interview (mirrors tests.setup)'),name:r.z.string().optional().describe('Command name (required for "run", "add", and "remove")'),args:r.z.string().optional().describe('Additional arguments appended to the base command (optional, for "run")'),grep:r.z.string().optional().describe('Filter output through grep (optional, for "run"). Pipes command output through grep -i with this pattern.'),command:r.z.string().optional().describe('Shell command to register (required for "add", e.g. "tsc --noEmit")'),description:r.z.string().optional().describe('What this command verifies. REQUIRED when operation is "add" \u2014 must articulate the command\'s purpose so the audit trail (added_by_session_id + description) is meaningful in the project commands UI.'),timeout:r.z.number().optional().describe('Timeout in seconds (optional, for "add", default 60)'),cwd:r.z.string().optional().describe('Working directory relative to project root (optional, for "add", e.g. "apps/web"). Omit to run at project root \u2014 use this for monorepos where the command lives in a subdir.'),context:r.z.string().optional().describe('Optional caller hint for the "setup" operation \u2014 short note about what the calling agent thinks the user needs (e.g. "specialist asked for npm run build with strict TS"). The architect treats this as a hint but still does its own discovery + user confirmation.'),commands:r.z.array(r.z.object({name:r.z.string().min(1).describe('Command name (e.g. "test:web")'),command:r.z.string().min(1).describe("Shell command to execute"),description:r.z.string().min(1).describe("What this command verifies"),cwd:r.z.string().optional().describe("Working directory relative to project root (omit for root)"),timeout:r.z.number().optional().describe("Timeout in seconds (default 60)")})).optional().describe('Batch of commands to register (required for "register", ignored otherwise). Each item must have name, command, and description. cwd is optional and supports monorepo subdirs.')}),exports.ReportTestResultsSchema=r.z.object({status:r.z.enum(["passed","failed","error"]).describe("Overall result"),results:r.z.object({commands:r.z.array(r.z.object({name:r.z.string().describe("Command name"),status:r.z.enum(["passed","failed","skipped","error"]).describe("Command result"),output:r.z.string().optional().describe("Relevant output snippet"),diagnosis:r.z.string().optional().describe("Why it failed, if applicable")})).describe("Per-command results"),summary:r.z.string().describe("Brief overall summary"),acceptanceCriteria:r.z.array(r.z.object({criterion:r.z.string().describe("The acceptance criterion text"),status:r.z.enum(["verified","unverified","unclear"]),evidence:r.z.string().describe("How verified, or why not")})).optional().describe("AC verification results, if applicable")}).describe("Structured test results")}),exports.SessionMessageOperationsSchema=r.z.object({operation:r.z.enum(["send","reply","list","get","offer-handoff"]),type:r.z.enum(["question","report"]).optional().describe("Message type to send (required for send)"),toSessionId:r.z.string().optional().describe('Target session ID, or "parent" to auto-resolve to parent session (omit for broadcast questions)'),questionType:r.z.enum(["free-form","alternatives"]).optional().describe('Type of question (required for send type="question")'),questionContent:r.z.object({question:r.z.string().min(1).describe("The question text"),context:r.z.string().optional().describe("Additional context"),options:r.z.array(r.z.object({id:r.z.string(),label:r.z.string(),description:r.z.string().optional()})).optional().describe("Options for alternatives questions"),allowMultiple:r.z.boolean().optional().describe("Allow selecting multiple options")}).optional().describe('Question content (required for send type="question")'),priority:r.z.enum(["low","normal","high"]).optional().describe("Question priority"),expiresInHours:r.z.number().optional().describe("Question expiry in hours"),status:r.z.enum(["success","partial","failure","blocked"]).optional().describe('Report status (required for send type="report")'),summary:r.z.string().optional().describe('Report summary (required for send type="report")'),details:r.z.string().optional().describe("Report details"),finish:r.z.boolean().optional().describe("Release request associations after report"),relatesTo:r.z.string().regex(/^I-[A-Za-z0-9]+-\d+$/,'relatesTo must be an instruction code like "I-abc12345-001"').optional().describe("Optional instruction code (I-...) this question or report relates to"),messageCode:r.z.string().optional().describe("Message code (required for reply and get operations)"),respondedBySessionId:r.z.string().optional().describe("Session ID answering the question. Optional \u2014 auto-filled from the caller's session (_meta.sessionId) when omitted; only pass explicitly to answer on behalf of a different session (e.g. UI passing 'user')."),text:r.z.string().optional().describe("Text answer for free-form questions"),selectedOptions:r.z.array(r.z.string()).optional().describe("Selected option IDs for alternatives"),notes:r.z.string().optional().describe("Additional notes"),list:r.z.object({sessionId:r.z.string().optional().describe("Filter by session ID (auto-discovered if omitted)"),messageType:r.z.enum(["question","report","instruction","all"]).default("all").describe("Filter by message type"),direction:r.z.enum(["incoming","outgoing","all"]).default("all"),status:r.z.enum(["pending","answered","expired","success","partial","failure","blocked","all"]).default("all").describe("Filter by status"),readStatus:r.z.enum(["unread","read","acknowledged","all"]).default("all").describe("Filter by read status (reports only)"),limit:r.z.number().min(1).max(100).default(50),offset:r.z.number().min(0).default(0)}).optional().describe('List filters (operation: "list" only)'),offerHandoff:r.z.object({summary:r.z.string().describe("Summary of what was planned/created"),requestIds:r.z.array(r.z.string()).describe("Request IDs that were created from the plan")}).optional().describe('Handoff offer details (operation: "offer-handoff" only)')}).refine((e=>"send"===e.operation?!!e.type:"reply"===e.operation?!!e.messageCode:"list"===e.operation||("get"===e.operation?!!e.messageCode:"offer-handoff"===e.operation)),{message:"Invalid operation data: send requires type, reply requires messageCode, get requires messageCode"}),exports.UpdateSpecializationSchema=r.z.object({specialization:r.z.string().min(1).max(500).describe("Your updated specialization summary \u2014 a concise description of your accumulated domain expertise"),specializationHeadline:r.z.string().min(1).max(80).optional().describe("Short tagline (\u226480 chars) summarising your domain at a glance \u2014 shown next to your name in the alchemist\u2019s specialist directory. Keep it current alongside the longer specialization.")}),exports.CommitToViewedSessionSchema=r.z.object({message:r.z.coerce.string().min(1).describe("The cleaned-up user message to post to the viewed session. Fix obvious dictation errors, add punctuation, but preserve the user's intent exactly.")})},6252(e,exports,t){"use strict"
|
|
3241
|
+
exports.TestingProcessCreateSchema=r.z.object({name:r.z.string().min(1).describe("Name for the test process"),description:r.z.string().optional().describe("Description of what this process verifies"),scope:r.z.string().optional().describe('Path prefix for monorepo scoping (e.g., "packages/api/"). Omit for global.'),setup:r.z.array(r.z.string()).optional().describe('Commands to prepare the environment (e.g., ["ln -s ../../node_modules node_modules"])'),commands:r.z.array(p).min(1).describe("Test commands to execute in order"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands"),fingerprint:r.z.array(r.z.string()).optional().describe('Files whose content invalidates setup. Setup commands re-run only when these files change between runs (e.g. ["package-lock.json"], ["Cargo.lock"], ["uv.lock", "poetry.lock"]). Polyglot repos list multiple. Omit / empty list = always re-run setup (existing behavior).'),poolSize:r.z.number().int().min(1).max(8).optional().describe("Number of warm test worktrees in the pool. Default 2. Set to 1 for languages with very large build artifacts (Rust target/, C++ build/). Higher values allow more parallel test runs at the cost of disk.")}),exports.TestingProcessDeleteSchema=r.z.object({processId:r.z.string().describe("Test process ID to delete")}),exports.TestingProcessUpdateSchema=r.z.object({processId:r.z.string().describe("Test process ID to update"),name:r.z.string().min(1).optional().describe("New name"),description:r.z.string().optional().describe("New description"),scope:r.z.string().optional().describe('New scope to limit when this process runs (e.g., "packages/api/"). Omit to leave unchanged.'),isActive:r.z.boolean().optional().describe("Enable or disable the process"),setup:r.z.array(r.z.string()).optional().describe("New setup commands (replaces existing)"),commands:r.z.array(p).optional().describe("New test commands (replaces existing)"),verifyAcceptanceCriteria:r.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands"),fingerprint:r.z.array(r.z.string()).optional().describe("Files whose content invalidates setup (replaces existing list)."),poolSize:r.z.number().int().min(1).max(8).optional().describe("Number of warm test worktrees in the pool (replaces existing).")}),exports.TestingReferenceSchema=r.z.object({}),exports.TestsSchema=r.z.object({operation:r.z.enum(["list","setup","run"]).describe('"list" to see registered test processes for this project. "setup" to spawn an interactive test-architect session that helps configure a process. "run" to fire an async test run for your current request \u2014 optional `process` picks one configured process (by name or id), optional `name` filters to one registered command. The call returns immediately and you receive a report on your next turn.'),process:r.z.string().optional().describe('Only used by `run`. Picks a single test process by name (case-insensitive) or id. Omit to run every active test process for this project. Use `operation: "list"` to see available process names.'),name:r.z.string().optional().describe("Only used by `run`. Filters execution to a single test command by name (matches a command name registered in the test process). Omit to run all required commands.")}),exports.ExecuteTestCommandSchema=r.z.object({processId:r.z.string().describe("Test process ID containing the command"),commandName:r.z.string().describe('Name of the test command to run, or "setup" to run all setup commands in sequence')}),exports.CommandsSchema=r.z.object({operation:r.z.enum(["run","list","remove","register","setup"]).default("run").describe('"run" to execute a command, "list" to see available commands, "register" to submit one or more commands for user approval (a single-item array works for one command; multiple items get bundled into a single batch approval notification), "remove" to delete one, "setup" to spawn the command-architect for an interactive setup interview (mirrors tests.setup)'),name:r.z.string().optional().describe('Command name (required for "run", "add", and "remove")'),args:r.z.string().optional().describe('Additional arguments appended to the base command (optional, for "run")'),grep:r.z.string().optional().describe('Filter output through grep (optional, for "run"). Pipes command output through grep -i with this pattern.'),command:r.z.string().optional().describe('Shell command to register (required for "add", e.g. "tsc --noEmit")'),description:r.z.string().optional().describe('What this command verifies. REQUIRED when operation is "add" \u2014 must articulate the command\'s purpose so the audit trail (added_by_session_id + description) is meaningful in the project commands UI.'),timeout:r.z.number().optional().describe('Timeout in seconds (optional, for "add", default 60)'),cwd:r.z.string().optional().describe('Working directory relative to project root (optional, for "add", e.g. "apps/web"). Omit to run at project root \u2014 use this for monorepos where the command lives in a subdir.'),context:r.z.string().optional().describe('Optional caller hint for the "setup" operation \u2014 short note about what the calling agent thinks the user needs (e.g. "specialist asked for npm run build with strict TS"). The architect treats this as a hint but still does its own discovery + user confirmation.'),commands:r.z.array(r.z.object({name:r.z.string().min(1).describe('Command name (e.g. "test:web")'),command:r.z.string().min(1).describe("Shell command to execute"),description:r.z.string().min(1).describe("What this command verifies"),cwd:r.z.string().optional().describe("Working directory relative to project root (omit for root)"),timeout:r.z.number().optional().describe("Timeout in seconds (default 60)")})).optional().describe('Batch of commands to register (required for "register", ignored otherwise). Each item must have name, command, and description. cwd is optional and supports monorepo subdirs.')}),exports.ReportTestResultsSchema=r.z.object({status:r.z.enum(["passed","failed","error"]).describe("Overall result"),results:r.z.object({commands:r.z.array(r.z.object({name:r.z.string().describe("Command name"),status:r.z.enum(["passed","failed","skipped","error"]).describe("Command result"),output:r.z.string().optional().describe("Relevant output snippet"),diagnosis:r.z.string().optional().describe("Why it failed, if applicable")})).describe("Per-command results"),summary:r.z.string().describe("Brief overall summary"),acceptanceCriteria:r.z.array(r.z.object({criterion:r.z.string().describe("The acceptance criterion text"),status:r.z.enum(["verified","unverified","unclear"]),evidence:r.z.string().describe("How verified, or why not")})).optional().describe("AC verification results, if applicable")}).describe("Structured test results")}),exports.SessionMessageOperationsSchema=r.z.object({operation:r.z.enum(["send","reply","list","get","offer-handoff"]),type:r.z.enum(["question","report"]).optional().describe("Message type to send (required for send)"),toSessionId:r.z.string().optional().describe('Target session ID, or "parent" to auto-resolve to parent session (omit for broadcast questions)'),questionType:r.z.enum(["free-form","alternatives"]).optional().describe('Type of question (required for send type="question")'),questionContent:r.z.object({question:r.z.string().min(1).describe("The question text"),context:r.z.string().optional().describe("Additional context"),options:r.z.array(r.z.object({id:r.z.string(),label:r.z.string(),description:r.z.string().optional()})).optional().describe("Options for alternatives questions"),allowMultiple:r.z.boolean().optional().describe("Allow selecting multiple options")}).optional().describe('Question content (required for send type="question")'),priority:r.z.enum(["low","normal","high"]).optional().describe("Question priority"),expiresInHours:r.z.number().optional().describe("Question expiry in hours"),status:r.z.enum(["success","partial","failure","blocked"]).optional().describe('Report status (required for send type="report")'),summary:r.z.string().optional().describe('Report summary (required for send type="report")'),details:r.z.string().optional().describe("Report details"),finish:r.z.boolean().optional().describe("Release request associations after report"),relatesTo:r.z.string().regex(/^I-[A-Za-z0-9]+-\d+$/,'relatesTo must be an instruction code like "I-abc12345-001"').optional().describe("Optional instruction code (I-...) this question or report relates to"),messageCode:r.z.string().optional().describe("Message code (required for reply and get operations)"),respondedBySessionId:r.z.string().optional().describe("Session ID answering the question. Optional \u2014 auto-filled from the caller's session (_meta.sessionId) when omitted; only pass explicitly to answer on behalf of a different session (e.g. UI passing 'user')."),text:r.z.string().optional().describe("Text answer for free-form questions"),selectedOptions:r.z.array(r.z.string()).optional().describe("Selected option IDs for alternatives"),notes:r.z.string().optional().describe("Additional notes"),list:r.z.object({sessionId:r.z.string().optional().describe("Filter by session ID (auto-discovered if omitted)"),messageType:r.z.enum(["question","report","instruction","all"]).default("all").describe("Filter by message type"),direction:r.z.enum(["incoming","outgoing","all"]).default("all"),status:r.z.enum(["pending","answered","expired","success","partial","failure","blocked","all"]).default("all").describe("Filter by status"),readStatus:r.z.enum(["unread","read","acknowledged","all"]).default("all").describe("Filter by read status (reports only)"),limit:r.z.number().min(1).max(100).default(50),offset:r.z.number().min(0).default(0)}).optional().describe('List filters (operation: "list" only)'),offerHandoff:r.z.object({summary:r.z.string().describe("Summary of what was planned/created"),requestIds:r.z.array(r.z.string()).describe("Request IDs that were created from the plan")}).optional().describe('Handoff offer details (operation: "offer-handoff" only)')}).refine((e=>"send"===e.operation?!!e.type:"reply"===e.operation?!!e.messageCode:"list"===e.operation||("get"===e.operation?!!e.messageCode:"offer-handoff"===e.operation)),{message:"Invalid operation data: send requires type, reply requires messageCode, get requires messageCode"}),exports.UpdateSpecializationSchema=r.z.object({specialization:r.z.string().min(1).max(500).describe("Your updated specialization summary \u2014 a concise description of your accumulated domain expertise"),specializationHeadline:r.z.string().min(1).max(80).optional().describe("Short tagline (\u226480 chars) summarising your domain at a glance \u2014 shown next to your name in the alchemist\u2019s specialist directory. Keep it current alongside the longer specialization.")}),exports.CommitToViewedSessionSchema=r.z.object({message:r.z.coerce.string().min(1).describe("The cleaned-up user message to post to the viewed session. Fix obvious dictation errors, add punctuation, but preserve the user's intent exactly.")})},6252(e,exports,t){"use strict"
|
|
3218
3242
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
3219
3243
|
const r=t(6183),n=t(405)
|
|
3220
3244
|
exports.def={name:"plan_write",description:"Create and modify project plans (and quests).\n\nOperations:\n\u2022 create - Create a new plan or quest. Pass kind='quest' with criteria/tickIntervalSeconds/maxInFlight/maxPerDay to create a quest.\n\u2022 update - Update plan/quest content. For quests, also accepts criteria / tickIntervalSeconds / maxInFlight / maxPerDay / minIterations / status (open|closed). Provide at least content or one metadata field.\n\u2022 append - Append content to an existing plan\n\u2022 replace - Find and replace text within a plan\n\u2022 create-snapshot - Create a version snapshot\n\u2022 restore - Restore to a previous version\n\u2022 set-active - Set a plan as the project's active plan",schema:r.PlanWriteSchema,annotations:{title:"Plan Write",readOnlyHint:!1,destructiveHint:!1},handler(e,t){return(0,n.handlePlanWrite)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer,t.cliOrigin)}}},6261(module){"use strict"
|
|
@@ -4775,7 +4799,7 @@ return o(t,e),t})
|
|
|
4775
4799
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.checkingDefs=void 0
|
|
4776
4800
|
const i=s(t(6183)),a=t(4425)
|
|
4777
4801
|
var c
|
|
4778
|
-
exports.checkingDefs=[{name:"commands",description:'Manage and run project commands (typecheck, lint, build, etc.) to verify your work. Operations: "list" to see available commands, "run" to execute one by name, "add" to register a new command for this project.',schema:i.CommandsSchema,annotations:{title:"Commands",readOnlyHint:!1},createsRecords:!0,handler:(c=a.handleCommands,(e,t)=>c(e,t.context,t.apiClient,t.logger,t.metrics,t.apiClient?.getToolRecordClient?.(),t.cliOrigin))}]},8850(e,exports,t){"use strict"
|
|
4802
|
+
exports.checkingDefs=[{name:"commands",description:'Manage and run project commands (typecheck, lint, build, etc.) to verify your work. Operations: "list" to see available commands, "run" to execute one by name, "add" to register a new command for this project.',schema:i.CommandsSchema,annotations:{title:"Commands",readOnlyHint:!1},createsRecords:!0,handler:(c=a.handleCommands,(e,t)=>c(e,t.context,t.apiClient,t.logger,t.metrics,t.apiClient?.getToolRecordClient?.(),t.cliOrigin,{progressToken:t.progressToken,sendNotification:t.sendNotification}))}]},8850(e,exports,t){"use strict"
|
|
4779
4803
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4780
4804
|
const r=t(6183),n=t(6891)
|
|
4781
4805
|
exports.def={name:"task_file_history",description:"See all file changes made during a task. Use query_history tool instead.",schema:r.QueryHistorySchema,annotations:{title:"Task File History",readOnlyHint:!0},hidden:!0,readOnly:!0,handler(e,t){return(0,n.handleTaskFileHistory)(e,t.context,t.apiClient,t.logger,t.metrics)}}},8851(e,exports,t){"use strict"
|
|
@@ -4808,7 +4832,10 @@ const n=[{id:"coder",name:"coder",description:"Development and implementation ag
|
|
|
4808
4832
|
let s=null,i=!1,a=null},9030(e,exports,t){"use strict"
|
|
4809
4833
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.def=void 0
|
|
4810
4834
|
const r=t(6183),n=t(4079)
|
|
4811
|
-
exports.def={name:"write_file",description:"Write content to files or documents. Supports both filesystem files (using 'path') and tracked documents (using 'documentId'). For files: requires a comment, creates/overwrites files, and commits to git under the active task (resolved automatically from your session). For documents: writes to cached document and syncs back to tracking system. Set append:true to add content to existing content. Handles both text and JSON content.\n\n`content` accepts a single string OR an array of lines (joined with \\n). PREFER the array form for any file containing brackets, quotes, or code-like syntax (TOML, JSON, Python, YAML, etc.) \u2014 it sidesteps the most common JSON-escaping foot-gun where multi-line content with `[` or `{` confuses the JSON parser.",schema:r.WriteFileSchema,annotations:{title:"Write File/Document",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},createsRecords:!0,handler(e,t){return(0,n.handleWriteFile)(e,t.context,t.apiClient.getFileClient(),t.apiClient.getTaskClient(),t.apiClient.getToolRecordClient(),t.apiClient.getRequestClient(),t.logger,t.metrics,t.mcpServer)}}},
|
|
4835
|
+
exports.def={name:"write_file",description:"Write content to files or documents. Supports both filesystem files (using 'path') and tracked documents (using 'documentId'). For files: requires a comment, creates/overwrites files, and commits to git under the active task (resolved automatically from your session). For documents: writes to cached document and syncs back to tracking system. Set append:true to add content to existing content. Handles both text and JSON content.\n\n`content` accepts a single string OR an array of lines (joined with \\n). PREFER the array form for any file containing brackets, quotes, or code-like syntax (TOML, JSON, Python, YAML, etc.) \u2014 it sidesteps the most common JSON-escaping foot-gun where multi-line content with `[` or `{` confuses the JSON parser.",schema:r.WriteFileSchema,annotations:{title:"Write File/Document",readOnlyHint:!1,destructiveHint:!0,idempotentHint:!1},createsRecords:!0,handler(e,t){return(0,n.handleWriteFile)(e,t.context,t.apiClient.getFileClient(),t.apiClient.getTaskClient(),t.apiClient.getToolRecordClient(),t.apiClient.getRequestClient(),t.logger,t.metrics,t.mcpServer)}}},9032(e,exports,t){"use strict"
|
|
4836
|
+
function r(e){return{content:[{type:"text",text:e}],isError:!0}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.mcpError=r,exports.resolveRequestIdOrError=async function(e,t,s,i){if(s&&!o.has(s)){const r=await n.sessionIdentity.getSessionRequestId(e,t,s)
|
|
4837
|
+
if(r)return{ok:!0,requestId:r}}return{ok:!1,errorResult:r(i)}}
|
|
4838
|
+
const n=t(6688),o=new Set(["__unknown__","__server__",""])},9060(e,exports,t){"use strict"
|
|
4812
4839
|
var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
|
|
4813
4840
|
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConfigManager=void 0,exports.createConfigManager=function(e){return new d(e)}
|
|
4814
4841
|
const n=r(t(1943)),o=r(t(6928)),s=r(t(857)),i=t(4139),a=t(8824),c={},l={remoteServerUrl:"https://api.alchemylabcode.com",nodePath:"node"}
|
|
@@ -4877,7 +4904,7 @@ if(n(parseInt(e.replace("v","").split(".")[0],10)))return"node"}catch{}const e=p
|
|
|
4877
4904
|
if((0,i.existsSync)(t))try{const e=(0,i.readdirSync)(t).filter((e=>n(parseInt(e.replace("v","").split(".")[0],10)))).sort(((e,t)=>{const r=parseInt(e.replace("v","").split(".")[0],10)
|
|
4878
4905
|
return parseInt(t.replace("v","").split(".")[0],10)-r}))
|
|
4879
4906
|
if(e.length>0){const r=(0,s.join)(t,e[0],"bin","node")
|
|
4880
|
-
if((0,i.existsSync)(r))return r}}catch{}throw Error(`AlchemyLab requires Node.js 22 or 24+ to run the OpenCode server (Node 23 is not supported).\nYour current version: ${process.version}\nInstall a compatible version: nvm install 22 (or download from https://nodejs.org)`)}(),prependArgs:["--no-warnings",(0,s.join)(e,t)]}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.resolveServeCommand=function(){const e=r()
|
|
4907
|
+
if((0,i.existsSync)(r))return r}}catch{}throw Error(`AlchemyLab requires Node.js 22 or 24+ to run the OpenCode server (Node 23 is not supported).\nYour current version: ${process.version}\nInstall a compatible version: nvm install 22 (or download from https://nodejs.org)`)}(),prependArgs:["--no-warnings",(0,s.join)(e,t)]}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.findOpencodeDir=r,exports.resolveServeCommand=function(){const e=r()
|
|
4881
4908
|
return e?o((0,s.join)(e,"dist"),"serve.js"):{command:"opencode",prependArgs:["serve"]}},exports.resolveRunCommand=function(){const e=r()
|
|
4882
4909
|
return e?o((0,s.join)(e,"dist"),"run.js"):{command:"opencode",prependArgs:[]}}
|
|
4883
4910
|
const s=t(6928),i=t(9896),a=t(5317)},9072(e,exports,t){"use strict"
|