alchemylab 3.0.4 → 3.0.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/index.js CHANGED
@@ -1472,24 +1472,26 @@ for(const t of e.guidanceNow??[])g.push(` Guidance ${t}`)}}if(m.length>0){g.pus
1472
1472
  for(const e of m){const t=e.createdByAgent?`agent ${e.createdByAgent}`:"user",r=(e.createdAt??"").slice(0,10),n=e.anchor?.selectedText?` on "${o(e.anchor.selectedText,80)}"`:""
1473
1473
  g.push(`- ${e.artifactRef?`[${e.artifactRef}]`:"Not anchored"} (${e.status}) by ${t}${r?` on ${r}`:""}${n}: ${o(e.body,240)} (annotation ${e.id})`)}}return g.push("","When you answer, cite the bracketed refs verbatim (req\u2026, document:\u2026, file:\u2026): they render as clickable links for the user."),{content:[{type:"text",text:g.join("\n")}]}}throw new r.ValidationError(`Unknown operation: ${u}. Use "set", "list" or "search-decisions".`)}catch(e){return d({operation:u,success:!1}),l.error("Directive operation failed",{operation:u,error:(0,n.getErrorMessage)(e)}),{content:[{type:"text",text:`Error (${u}): ${(0,n.getErrorMessage)(e)}`}],isError:!0}}}
1474
1474
  const r=t(59860),n=t(58824),o=(e,t)=>{const r=(e??"").replace(/\s+/g," ").trim()
1475
- return r.length>t?`${r.slice(0,t-1)}\u2026`:r}},31572(e,exports,t){exports.handleCreateDocument=async function(e,t,a,c,l,d,u){const h=c.child({tool:"create_document"}),p=l.startTimer("tool_execution_time")
1476
- try{const c=e,{requestId:l,filename:d,content:p}=c,f="string"==typeof c.comment&&c.comment.trim()?c.comment:`Created ${d}`
1477
- h.info("Creating new document",{requestId:l||"standalone",filename:d,contentLength:p.length,comment:f})
1478
- const m=t.projectId
1479
- if(!m){const e="Project ID is required. Make sure you are in a project context."
1480
- return h.warn("No project context"),{content:[{type:"text",text:`\u274c ${e}`}],isError:!0}}if(!/\.(md|html?)$/i.test(d)){const e=`Filename must end in .md (prose) or .html (a rendered page): ${d}`
1481
- return h.warn("Invalid filename extension",{filename:d}),{content:[{type:"text",text:`\u274c ${e}`}],isError:!0}}if((0,n.isProjectMapPath)(d)&&u?.sessionId){const e=await(0,r.holdNewProjectMap)((0,r.heldDocumentDepsFrom)(a,h),u.sessionId,p).catch(()=>null)
1482
- if(e)return{content:[{type:"text",text:`\u2705 ${d} started. ${(0,r.heldDocumentNote)(e)}`}]}}try{a.setProjectId(m)
1483
- const e=a.getDocumentClient()
1484
- let t,r=[]
1485
- if((0,s.hasScheduleArgs)(c)){const e=(0,s.applyScheduleArgs)(c,null)
1475
+ return r.length>t?`${r.slice(0,t-1)}\u2026`:r}},31572(e,exports,t){exports.handleCreateDocument=async function(e,a,c,l,d,u,h){const p=l.child({tool:"create_document"}),f=d.startTimer("tool_execution_time")
1476
+ try{const l=e,{requestId:d,filename:u,content:f}=l,m="string"==typeof l.comment&&l.comment.trim()?l.comment:`Created ${u}`
1477
+ p.info("Creating new document",{requestId:d||"standalone",filename:u,contentLength:f.length,comment:m})
1478
+ const g=a.projectId
1479
+ if(!g){const e="Project ID is required. Make sure you are in a project context."
1480
+ return p.warn("No project context"),{content:[{type:"text",text:`\u274c ${e}`}],isError:!0}}if(!/\.(md|html?)$/i.test(u)){const e=`Filename must end in .md (prose) or .html (a rendered page): ${u}`
1481
+ return p.warn("Invalid filename extension",{filename:u}),{content:[{type:"text",text:`\u274c ${e}`}],isError:!0}}if((0,n.isProjectMapPath)(u)&&h?.sessionId){const e=await(0,r.holdNewProjectMap)((0,r.heldDocumentDepsFrom)(c,p),h.sessionId,f).catch(()=>null)
1482
+ if(e)return{content:[{type:"text",text:`\u2705 ${u} started. ${(0,r.heldDocumentNote)(e)}`}]}}try{c.setProjectId(g)
1483
+ const e=c.getDocumentClient()
1484
+ let r,n=[]
1485
+ if((0,s.hasScheduleArgs)(l)){const e=(0,s.applyScheduleArgs)(l,null)
1486
1486
  if("problem"in e)return{content:[{type:"text",text:`\u274c ${e.problem}`}],isError:!0}
1487
- t={schedule:e.schedule},r=e.changed}const n=await e.createDocument(l,{filename:d,content:p,...u&&{cliOrigin:u},...t&&{metadata:t},..."number"==typeof c.scheduleBudgetUsd&&{budget:c.scheduleBudgetUsd,budgetSaid:"string"==typeof c.userSaid?c.userSaid:""},...void 0!==c.target&&{target:c.target,..."string"==typeof c.userSaid?{targetSaid:c.userSaid}:{}}})
1488
- h.info("Document created successfully",{documentId:n.id,filename:n.filename,requestId:l||"standalone"})
1489
- try{const e=a.getToolRecordClient()
1490
- await e.createToolRecord({type:"create-document",projectId:m,metadata:{documentId:n.id,filename:n.filename,contentLength:p.length,requestId:l,projectId:m},note:f})}catch(e){h.warn("Failed to create tool record",{recordError:e})}const o=(l?`**Request:** ${l}\n`:"**Standalone:** Yes (not tied to a request)\n")+(t?`**Schedule:** ACTIVE -- ${r.join("; ")} (${t.schedule.maxPerDay?`at most ${t.schedule.maxPerDay} request${1===t.schedule.maxPerDay?"":"s"} a day, `:""}maxInFlight ${t.schedule.maxInFlight}). The runner will periodically create ONE linked request through normal intake${c.target?.length?", only while its target is missed":""}; the user disables it by editing or deleting this document.\n`+(c.target?.length?"":"**No target:** every firing wakes you to judge the goal. If its state shows in numbers (a count, a share, an age), give it a target so it fires only while missed: a saved command that prints them (`commands` setup asks for one), then `update` this document with target.\n"):"")+("string"==typeof n.budgetNote?`**Budget:** ${n.budgetNote}\n`:"")+("string"==typeof n.targetNote?`**Target:** ${n.targetNote}\n`:"")
1491
- return{content:[{type:"text",text:`\u2705 Document created successfully!\n\n**Document ID:** ${n.id}\n**Filename:** ${n.filename}\n**Size:** ${p.length} characters\n`+o+`**Created:** ${n.createdAt}\n\n`+`The document is now stored in the tracking system and can be edited using standard file modification tools by referencing its document ID (${n.id}) instead of a file path.\n\n**Examples:**\n`+`- \`replace_string\` with \`documentId: "${n.id}"\`\n`+`- \`write_file\` with \`documentId: "${n.id}"\`\n`+`- \`file_history\` with \`documentId: "${n.id}"\``}],...t?(0,i.alchemyMeta)({threadRef:`plan:${n.id}`}):{}}}catch(e){const t=`Failed to create document: ${(0,o.getErrorMessage)(e)}`
1492
- return h.error("Failed to create document",{error:e}),{content:[{type:"text",text:`\u274c ${t}`}],isError:!0}}}catch(e){return h.error("Unexpected error in create document",{error:e}),{content:[{type:"text",text:`\u274c Unexpected error: ${(0,o.getErrorMessage)(e)}`}],isError:!0}}finally{p({tool:"create_document"})}}
1487
+ r={schedule:e.schedule},n=e.changed}const o=await e.createDocument(d,{filename:u,content:f,...h&&{cliOrigin:h},...r&&{metadata:r},..."number"==typeof l.scheduleBudgetUsd&&{budget:l.scheduleBudgetUsd,budgetSaid:"string"==typeof l.userSaid?l.userSaid:""},...void 0!==l.target&&{target:l.target,..."string"==typeof l.userSaid?{targetSaid:l.userSaid}:{}}})
1488
+ p.info("Document created successfully",{documentId:o.id,filename:o.filename,requestId:d||"standalone"})
1489
+ try{const e=c.getToolRecordClient()
1490
+ let r=d||void 0
1491
+ if(!r&&h?.sessionId)try{const{resolveRequestIdOrError:e}=await Promise.resolve().then(()=>t(36651)),n=await e(c,p,h.sessionId,"no active request")
1492
+ n?.ok&&(r=n.requestId)}catch{}await e.createToolRecord({type:"create-document",projectId:g,...r?{requestId:r}:{},metadata:{documentId:o.id,filename:o.filename,contentLength:f.length,requestId:r??d,projectId:g},note:m})}catch(e){p.warn("Failed to create tool record",{recordError:e})}const a=(d?`**Request:** ${d}\n`:"**Standalone:** Yes (not tied to a request)\n")+(r?`**Schedule:** ACTIVE -- ${n.join("; ")} (${r.schedule.maxPerDay?`at most ${r.schedule.maxPerDay} request${1===r.schedule.maxPerDay?"":"s"} a day, `:""}maxInFlight ${r.schedule.maxInFlight}). The runner will periodically create ONE linked request through normal intake${l.target?.length?", only while its target is missed":""}; the user disables it by editing or deleting this document.\n`+(l.target?.length?"":"**No target:** every firing wakes you to judge the goal. If its state shows in numbers (a count, a share, an age), give it a target so it fires only while missed: a saved command that prints them (`commands` setup asks for one), then `update` this document with target.\n"):"")+("string"==typeof o.budgetNote?`**Budget:** ${o.budgetNote}\n`:"")+("string"==typeof o.targetNote?`**Target:** ${o.targetNote}\n`:"")
1493
+ return{content:[{type:"text",text:`\u2705 Document created successfully!\n\n**Document ID:** ${o.id}\n**Filename:** ${o.filename}\n**Size:** ${f.length} characters\n`+a+`**Created:** ${o.createdAt}\n\n`+`The document is now stored in the tracking system and can be edited using standard file modification tools by referencing its document ID (${o.id}) instead of a file path.\n\n**Examples:**\n`+`- \`replace_string\` with \`documentId: "${o.id}"\`\n`+`- \`write_file\` with \`documentId: "${o.id}"\`\n`+`- \`file_history\` with \`documentId: "${o.id}"\``}],...r?(0,i.alchemyMeta)({threadRef:`plan:${o.id}`}):{}}}catch(e){const t=`Failed to create document: ${(0,o.getErrorMessage)(e)}`
1494
+ return p.error("Failed to create document",{error:e}),{content:[{type:"text",text:`\u274c ${t}`}],isError:!0}}}catch(e){return p.error("Unexpected error in create document",{error:e}),{content:[{type:"text",text:`\u274c Unexpected error: ${(0,o.getErrorMessage)(e)}`}],isError:!0}}finally{f({tool:"create_document"})}}
1493
1495
  const r=t(95040),n=t(2503),o=t(58824),s=t(72076),i=t(82272)},61391(e,exports,t){exports.def=void 0
1494
1496
  const r=t(76183),n=t(5626)
1495
1497
  exports.def={name:"document_operations",description:"Project documents, optionally linked to a request.\n\n\u2022 create - A document with content. A name ending in `.html` renders as a page in a sealed frame (no network, no other files: everything inline; no annotations); markdown is the default. scheduleAtTimes ('09:00,17:00', with scheduleOnDays 'weekdays' | 'weekends' | 'mon,thu') or scheduleIntervalSeconds makes it a SCHEDULE: a standing goal that files one linked request per firing through intake (schedulePrompt, scheduleMaxPerDay, scheduleMaxInFlight). A target makes it fire only while the target is missed. scheduleBudgetUsd: a budget the user named for the goal, their words in userSaid. On update the same params change a schedule; scheduleEnabled false (with scheduleReason) pauses it.\n\u2022 update - Edit in place (documentId, or filename such as PROJECT-MAP.md; replacements[{old_str,new_str}], mode unique|all). Keep one living deliverable current rather than a parallel one; create-snapshot before a major revision.\n\u2022 search - By content or name, project-wide; requestId narrows to that request's documents only.\n\u2022 create-snapshot / get-history / get-version / restore-version - Versions.\n\u2022 list-annotations / create-annotation / reply-to-annotation / resolve-annotation - Comments on a document.\n\u2022 create-artifact-annotation - Pin a comment to a repo file line (ref \"file:<path>\", file, line, selectedText).\n\nMarkdown: syntax highlighting, Mermaid, GFM tables, entity links ([DOC:doc######], [REQUEST:req######], [TASK:tas######]).",schema:r.DocumentOperationsSchema,fieldTags:{standardRules:["propose-standard"],filename:["create","update"],content:["create","update"],scheduleIntervalSeconds:["schedule"],scheduleAtTimes:["schedule"],scheduleOnDays:["schedule"],schedulePrompt:["schedule"],scheduleMaxPerDay:["schedule"],scheduleMaxInFlight:["schedule"],target:["schedule"],scheduleEnabled:["schedule"],scheduleBudgetUsd:["schedule"],userSaid:["schedule"],scheduleReason:["schedule"],query:["search"],includeArchived:["search"],maxResults:["search"],dateFrom:["search"],dateTo:["search"],searchIn:["search"],replacements:["update"],mode:["update"],versionNumber:["get-version","restore-version"],selectedText:["create-annotation","create-artifact-annotation"],prefixContext:["create-annotation"],suffixContext:["create-annotation"],lineHint:["create-annotation"],annotationId:["reply-to-annotation","resolve-annotation"],ref:["create-artifact-annotation"],file:["create-artifact-annotation"],line:["create-artifact-annotation"]},annotations:{title:"Document Operations",readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1},handler:(e,t)=>(0,n.handleDocumentOperations)(e,t.context,t.apiClient,t.logger,t.metrics,t.mcpServer,t.cliOrigin)}},5626(e,exports,t){exports.handleDocumentOperations=async function(e,u,h,p,f,m,g){const y=p.child({tool:"document_operations"})
@@ -3160,28 +3162,39 @@ const y=t(87280)
3160
3162
  t(52462)
3161
3163
  const w=t(82245),b=t(75632),v=t(58185),k=t(58622),I=t(79236),$=t(94466),x=(i(t(70857)),t(11569)),S=t(97896),E=t(98537),_="true"===process.env.ALCHEMY_DEBUG_LOGS,C=new Set,T=new Map,q=new Map},65948(e,exports,t){exports.mcpConnectionDefs=void 0
3162
3164
  const r=t(76183),n=t(57034)
3163
- exports.mcpConnectionDefs=[{name:"mcp_connections",description:'The project\'s MCP connections: external tool servers the fleet may reach (Runtime > MCP Servers in the product). list = what is registered and whether it is on; propose = register one, switched off, for the user to switch on and grant to agents. Use propose when your work is or needs an MCP server: a server you built in this repository is proposed as transport "repo" with its Dockerfile; a published npm server as "boxed" with a pinned version; a hosted one as "remote" with its url. Never point the user at a config file: the product has no config file for this, and the generated ones are not theirs to edit.',schema:r.McpConnectionsSchema,annotations:{title:"MCP connections",readOnlyHint:!1},createsRecords:!0,handler:(e,t)=>(0,n.handleMcpConnections)(e,t.context,t.apiClient,t.logger,t.metrics)}]},57034(e,exports,t){exports.G=void 0,exports.handleMcpConnections=async function(e,t,i,a,c){const l=c.startTimer("tool_execution_time")
3164
- try{if("list"===e.operation){const e=await i.proxyGet(`/api/projects/${t.projectId}/mcp-servers`),r=Array.isArray(e)?e:e?.data??[]
3165
- if(l({success:!0}),0===r.length)return o('This project has no MCP connections registered. Propose one with operation "propose".')
3165
+ exports.mcpConnectionDefs=[{name:"mcp_connections",description:'The project\'s MCP connections: external tool servers the fleet may reach (Runtime > MCP Servers in the product). list = what is registered and whether it is on; propose = register one, switched off, for the user to switch on and grant to agents; update = correct one by name, passing only what was wrong (if it was on it goes off until the user switches it on again); remove = take back one that is switched off. Use propose when your work is or needs an MCP server: a server you built in this repository is proposed as transport "repo" with its Dockerfile; a published npm server as "boxed" with a pinned version; a hosted one as "remote" with its url. Never point the user at a config file: the product has no config file for this, and the generated ones are not theirs to edit.',schema:r.McpConnectionsSchema,annotations:{title:"MCP connections",readOnlyHint:!1},createsRecords:!0,handler:(e,t)=>(0,n.handleMcpConnections)(e,t.context,t.apiClient,t.logger,t.metrics)}]},57034(e,exports,t){function r(e,t,r={}){if("repo"===t){const t={dockerfile:String(e.dockerfile??r.dockerfile??"").trim(),...e.context??r.context?{context:String(e.context??r.context).trim()}:{},...e.environment??r.environment?{environment:e.environment??r.environment}:{}},n=(0,o.validateRepoConfig)(t)
3166
+ return n?{problem:n}:{config:t}}if("boxed"===t){const t=String(e.package??r.package??"").trim()
3167
+ if(!t||!(0,o.isPinnedPackage)(t))return{problem:"A boxed connection needs an npm package with an exact version, for example @scope/server@1.2.3, and the bin it runs."}
3168
+ const n=String(e.bin??r.bin??"").trim()
3169
+ return n?{config:{package:t,bin:n,...e.environment??r.environment?{environment:e.environment??r.environment}:{}}}:{problem:"A boxed connection needs the bin to run, the name under node_modules/.bin."}}if("remote"===t){const t=String(e.url??r.url??"").trim()
3170
+ return/^https?:\/\//.test(t)?{config:{url:t,...e.environment??r.headers?{headers:e.environment??r.headers}:{}}}:{problem:"A remote connection needs an http(s) url."}}return{problem:'transport must be "repo" (a Dockerfile in this repository), "boxed" (a pinned npm package) or "remote" (a url). A command that runs unconfined on the user\'s machine can only be registered by the user.'}}exports.G=void 0,exports.handleMcpConnections=async function(e,t,a,c,l){const d=l.startTimer("tool_execution_time")
3171
+ try{if("list"===e.operation){const e=await a.proxyGet(`/api/projects/${t.projectId}/mcp-servers`),r=Array.isArray(e)?e:e?.data??[]
3172
+ if(d({success:!0}),0===r.length)return s('This project has no MCP connections registered. Propose one with operation "propose".')
3166
3173
  const n=r.map(e=>{const t=Array.isArray(e.toolManifest)?`${e.toolManifest.length} tools`:"not probed yet",r="repo"===e.transport?`built from ${e.config?.dockerfile}`:"boxed"===e.transport?`package ${e.config?.package}`:"remote"===e.transport?e.config?.url:"a command on the host"
3167
3174
  return`- ${e.name}: ${e.enabled?e.status:"switched off"} (${e.transport}, ${r}, ${t})`})
3168
- return o(["MCP connections registered for this project:",...n,"","Which agents may use each one is set on the workflow's Agents tab."].join("\n"))}if("propose"!==e.operation)return s('operation must be "list" or "propose"')
3169
- const r=String(e.name??"").trim(),a=(0,n.validateServerName)(r)
3170
- if(a)return l({success:!1,error:"bad_name"}),s(a)
3171
- const c=e.transport
3172
- let d
3173
- if("repo"===c){d={dockerfile:String(e.dockerfile??"").trim(),...e.context?{context:String(e.context).trim()}:{},...e.environment?{environment:e.environment}:{}}
3174
- const t=(0,n.validateRepoConfig)(d)
3175
- if(t)return l({success:!1,error:"bad_config"}),s(t)}else if("boxed"===c){const t=String(e.package??"").trim()
3176
- if(!t||!(0,n.isPinnedPackage)(t))return l({success:!1,error:"bad_config"}),s("A boxed connection needs an npm package with an exact version, for example @scope/server@1.2.3, and the bin it runs.")
3177
- if(!String(e.bin??"").trim())return l({success:!1,error:"bad_config"}),s("A boxed connection needs the bin to run, the name under node_modules/.bin.")
3178
- d={package:t,bin:String(e.bin).trim(),...e.environment?{environment:e.environment}:{}}}else{if("remote"!==c)return l({success:!1,error:"bad_transport"}),s('transport must be "repo" (a Dockerfile in this repository), "boxed" (a pinned npm package) or "remote" (a url). A command that runs unconfined on the user\'s machine can only be registered by the user.')
3179
- if(!/^https?:\/\//.test(String(e.url??"")))return l({success:!1,error:"bad_config"}),s("A remote connection needs an http(s) url.")
3180
- d={url:String(e.url).trim(),...e.environment?{headers:e.environment}:{}}}const u=await i.proxyPost(`/api/projects/${t.projectId}/mcp-servers`,{name:r,transport:c,config:d,secretKeys:Array.isArray(e.secretKeys)?e.secretKeys:[],addedBySessionId:t.currentSessionId}),h=u?.data??u
3181
- l({success:!0})
3182
- const p="repo"===c?" The product builds its image from the Dockerfile when it is switched on, and rebuilds it whenever the files it is built from change on main; the repository is mounted read-only at /work, /scratch is writable memory, and the image's ENTRYPOINT is what runs.":""
3183
- return o(`Proposed MCP connection **${h?.name??r}** (${c}).${p} ${exports.G}`)}catch(e){return l({success:!1,error:"exception"}),a.warn("mcp_connections failed",{error:(0,r.getErrorMessage)(e)}),s(`Could not do that: ${(0,r.getErrorMessage)(e)}`)}}
3184
- const r=t(58824),n=t(49779),o=e=>({content:[{type:"text",text:e}]}),s=e=>({content:[{type:"text",text:e}],isError:!0})
3175
+ return s(["MCP connections registered for this project:",...n,"","Which agents may use each one is set on the workflow's Agents tab."].join("\n"))}if("update"===e.operation||"remove"===e.operation)return await async function(e,t,n,o){const a=String(e.name??"").trim()
3176
+ if(!a)return o({success:!1,error:"bad_name"}),i('Name the connection to change (operation "list" shows them).')
3177
+ const c=await n.proxyGet(`/api/projects/${t.projectId}/mcp-servers`),l=Array.isArray(c)?c:c?.data??[],d=l.find(e=>e.name===a)
3178
+ if(!d)return o({success:!1,error:"not_found"}),i(`No MCP connection named ${a}. These are registered: ${l.map(e=>e.name).join(", ")||"none"}.`)
3179
+ if("remove"===e.operation)return d.enabled?(o({success:!1,error:"enabled"}),i(`${a} is switched on; only the user can remove it. Change it with update instead, or ask the user.`)):(await n.proxyDelete(`/api/projects/${t.projectId}/mcp-servers/${encodeURIComponent(d.id)}`),o({success:!0}),s(`Removed the MCP connection **${a}**.`))
3180
+ const u=e.transport??d.transport,h={}
3181
+ if(void 0!==e.transport||["dockerfile","context","package","bin","url","environment"].some(t=>void 0!==e[t])){const t=r(e,u,e.transport&&e.transport!==d.transport?{}:d.config??{})
3182
+ if("problem"in t)return o({success:!1,error:"bad_config"}),i(t.problem)
3183
+ h.config=t.config,e.transport&&e.transport!==d.transport&&(h.transport=e.transport)}if(Array.isArray(e.secretKeys)&&(h.secretKeys=e.secretKeys),0===Object.keys(h).length)return o({success:!1,error:"nothing"}),i("Nothing to change: pass the fields that are wrong (url, package, bin, dockerfile, context, environment, secretKeys or transport).")
3184
+ const p=await n.proxyPatch(`/api/projects/${t.projectId}/mcp-servers/${encodeURIComponent(d.id)}`,h),f=p?.data??p
3185
+ o({success:!0})
3186
+ const m=d.enabled&&f&&!1===f.enabled
3187
+ return s(`Changed the MCP connection **${a}** (${f?.transport??u}).`+(m?" It was switched on, so it is now switched OFF until the user switches it on again under Runtime > MCP Servers.":d.enabled?"":` ${exports.G}`))}(e,t,a,d)
3188
+ if("propose"!==e.operation)return i('operation must be "list", "propose", "update" or "remove"')
3189
+ const n=String(e.name??"").trim(),c=(0,o.validateServerName)(n)
3190
+ if(c)return d({success:!1,error:"bad_name"}),i(c)
3191
+ const l=e.transport,u=r(e,l)
3192
+ if("problem"in u)return d({success:!1,error:"bad_config"}),i(u.problem)
3193
+ const h=u.config,p=await a.proxyPost(`/api/projects/${t.projectId}/mcp-servers`,{name:n,transport:l,config:h,secretKeys:Array.isArray(e.secretKeys)?e.secretKeys:[],addedBySessionId:t.currentSessionId}),f=p?.data??p
3194
+ d({success:!0})
3195
+ const m="repo"===l?" The product builds its image from the Dockerfile when it is switched on, and rebuilds it whenever the files it is built from change on main; the repository is mounted read-only at /work, /scratch is writable memory, and the image's ENTRYPOINT is what runs.":""
3196
+ return s(`Proposed MCP connection **${f?.name??n}** (${l}).${m} ${exports.G}`)}catch(e){return d({success:!1,error:"exception"}),c.warn("mcp_connections failed",{error:(0,n.getErrorMessage)(e)}),i(`Could not do that: ${(0,n.getErrorMessage)(e)}`)}}
3197
+ const n=t(58824),o=t(49779),s=e=>({content:[{type:"text",text:e}]}),i=e=>({content:[{type:"text",text:e}],isError:!0})
3185
3198
  exports.G="It is registered switched OFF. The user switches it on under Runtime > MCP Servers and names the agents that may use it on the workflow's Agents tab; nothing reaches it until both are done. Say this in your handover instead of pointing at any config file."},23322(e,exports,t){var r,n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
3186
3199
  var o=Object.getOwnPropertyDescriptor(t,r)
3187
3200
  o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),s=this&&this.__importStar||(r=function(e){return r=Object.getOwnPropertyNames||function(e){var t=[]
@@ -3653,8 +3666,8 @@ if(P.info("Recording coder criteria comments",{requestId:s,comments:F.length,cri
3653
3666
  for(const t of F){const r=e.get(t.key),s=Array.isArray(t.verify)?t.verify.filter(e=>"string"==typeof e&&e.trim()):[]
3654
3667
  if(r&&s.length>0&&"subjective"===r.kind){n.push({criterionId:r.id,evidence:`${t.comment}\n\nWhat I ran (a judgment decides this criterion, not these): ${s.join(" ; ")}`})
3655
3668
  continue}const i=s.length&&Array.isArray(t.testFiles)?t.testFiles.filter(e=>"string"==typeof e&&e.trim()).map(e=>e.trim().replace(/^\.\//,"")):[]
3656
- r?n.push({criterionId:r.id,evidence:t.comment,...s.length?{verify:s}:{},...i.length?{testFiles:i}:{}}):o.push(t.key)}if(o.length>0){const e=(0,p.formatCriteriaWithKeys)(r)
3657
- return P.warn("criteriaComments keys did not match any criterion",{requestId:s,unmatched:o}),{content:[{type:"text",text:`Completion NOT recorded: ${o.length} criteriaComments key(s) match no criterion on ${s}: ${o.join(", ")}.\n\nThe key's letter is a checksum over the criterion's id, so a wrong letter is refused rather than guessed at -- otherwise your evidence would attach to the wrong criterion. Copy the keys exactly as listed:\n\n${e}\n\nRe-run complete with the exact keys. Nothing was recorded, so no verdict was attached to the wrong criterion.`}],isError:!0}}const i=[]
3669
+ r?n.push({criterionId:r.id,evidence:t.comment,...s.length?{verify:s}:{},...i.length?{testFiles:i}:{}}):o.push(t.key)}if(o.length>0)return P.warn("criteriaComments keys did not match any criterion",{requestId:s,unmatched:o}),{content:[{type:"text",text:`Completion NOT recorded: ${o.length} criteriaComments key(s) match no criterion on ${s}: ${o.map(e=>JSON.stringify(String(e).slice(0,60))).join(", ")}.\n\nA key is the short code before each criterion, such as "1p": just those characters. The keys on ${s}:\n${(0,p.criteriaKeyChoices)(r)}\n\nRun complete again with these keys. Nothing was recorded.`}],isError:!0}
3670
+ const i=[]
3658
3671
  for(const e of n.flatMap(e=>e.verify??[])){const t=(0,m.gitVerifyProblem)(e)??(_.git?await(0,m.nodeCheckProblem)(_.git,`requests/${s}`,e):null)
3659
3672
  t&&i.push(` ${e}\n -> ${t}`)}if(_.git)for(const e of[...new Set(n.flatMap(e=>e.testFiles??[]))])await _.git.raw(["cat-file","-e",`requests/${s}:${e}`]).then(()=>!0,()=>!1)||i.push(` testFiles: ${e}\n -> no such file on ${s}'s branch; name the test files your verify commands run, as repo paths`)
3660
3673
  if(i.length>0)return P.warn("verify commands that cannot prove anything; completion refused",{requestId:s,count:i.length}),{content:[{type:"text",text:`Completion NOT recorded: ${i.length} verify command(s) or test file(s) can never prove their criterion.\n\n${i.join("\n")}\n\nReplace them and complete again. Nothing was recorded.`}],isError:!0}
@@ -3848,7 +3861,9 @@ if(!r)return""
3848
3861
  const n=t.at&&!Number.isNaN(Date.parse(t.at))?`${new Date(t.at).toLocaleString()} `:""
3849
3862
  return`${t.discarded?"Discarded":"Canceled"}: ${n}by ${r}${t.via?`, with ${t.via}`:""}`}(I.canceledBy):""
3850
3863
  let N=`# ${P} Request: ${C} (${s})\nStatus: ${q}${I.endedWithout?`, ended without ${I.endedWithout}`:""}\n${A}${O}Created: ${R}${M?`\n${M}`:""}${D?`\n${D}`:""}\nUpdated: ${j}\n\n## Description\n${I.description||"_No description provided._"}\n\n## Progress Summary\n- Tasks: ${x.completed}/${x.total} completed (${Math.round(x.completed/x.total*100)||0}%)\n- Acceptance Criteria: ${E}/${S.length} proven (${Math.round(E/S.length*100)||0}%)\n`
3851
- N+=`\n## Task Status\n- Pending: ${x.pending}\n- In Progress: ${x.in_progress}\n- Blocked: ${x.blocked}\n- Ready for Review: ${x.ready_for_review}\n- Completed: ${x.completed}\n- Reverted: ${x.reverted}\n`,N+="\n## Tasks\n",0===$.length?N+="No tasks found for this request.\n":$.forEach(e=>{N+=`**[${e.id}]** ${e.title} (Status: ${e.status})\n`}),y.info(`Added task listing with ${$.length} tasks`),N+="\n## Acceptance Criteria\n",N+=(0,c.formatCriteriaWithHashes)(S)+"\n","ready_for_review"===I.status&&S.some(e=>!(0,c.criterionProven)(e))&&(N+="\n> **Status: ready_for_review**: Use the merge operation to verify criteria and merge to main.\n")
3864
+ N+=`\n## Task Status\n- Pending: ${x.pending}\n- In Progress: ${x.in_progress}\n- Blocked: ${x.blocked}\n- Ready for Review: ${x.ready_for_review}\n- Completed: ${x.completed}\n- Reverted: ${x.reverted}\n`,N+="\n## Tasks\n",0===$.length?N+="No tasks found for this request.\n":$.forEach(e=>{N+=`**[${e.id}]** ${e.title} (Status: ${e.status})\n`}),y.info(`Added task listing with ${$.length} tasks`)
3865
+ const F="string"==typeof I.roundOf&&I.roundOf?I.roundOf:null
3866
+ N+=F&&"completed"!==I.status?`\n## ${F}'s criteria (met when it completed)\nAn answer needs nothing more. If you change the project, your completion accounts for these again, on your change.\n`:"\n## Acceptance Criteria\n",N+=(F&&"completed"!==I.status?(0,c.formatCriteriaWithHashes)(S).replace(/\[UNPROVEN\] /g,""):(0,c.formatCriteriaWithHashes)(S))+"\n","ready_for_review"===I.status&&S.some(e=>!(0,c.criterionProven)(e))&&(N+="\n> **Status: ready_for_review**: Use the merge operation to verify criteria and merge to main.\n")
3852
3867
  try{const e=await f.proxyGet(`/api/projects/${t.projectId}/requests/${s}/record-for-agents`),r=String((e?.data??e)?.text??"").trim()
3853
3868
  r&&(N+=`\n${r}\n`)}catch(e){y.debug("record for agents unavailable",{error:(0,a.getErrorMessage)(e)})}if(_&&(N+=`\n## Test Coverage\n- Test Cases: ${_.totalTestCases||0}\n- Criteria Tested: ${_.criteriaTestedCount||0}/${S.length}\n`,_.criterionCoverage&&Array.isArray(_.criterionCoverage)&&(N+="\n### Detailed Test Coverage:\n",_.criterionCoverage.forEach(e=>{N+=`- Criterion ${e.criterionId}: ${e.coverage} coverage\n`}))),!["completed","reverted","canceled","cancelled","draft"].includes(String(q)))try{const e=await f.proxyGet(`/api/projects/${t.projectId}/requests/${s}/sessions`),r=Array.isArray(e)?e:e?.data??[]
3854
3869
  if(r.length>0){const e=await(0,d.getServerUrl)(t,y).catch(()=>null),n=await(0,l.readLiveWorker)(e??null,r)
@@ -5662,7 +5677,7 @@ return`${e.ok?"ok ":"FAIL"} ${t}${e.ok?"":`: ${e.error||"no reason given"}`}${e
5662
5677
  try{if(i&&s?.projectId){const{resolveRequestIdOrError:e}=await Promise.resolve().then(()=>t(36651))
5663
5678
  let r
5664
5679
  try{const t=a?.sessionId||s?.currentSessionId,o=await e(i,n,t,"no active request")
5665
- o?.ok&&(r=o.requestId)}catch{}await i.getToolRecordClient().createToolRecord({type:"drive-site",projectId:s.projectId,...r?{requestId:r}:{},metadata:{url:o,finalUrl:f.finalUrl,title:f.title??null,steps:(f.steps||[]).length,failed:(f.steps||[]).filter(e=>!e.ok).length,consoleErrors:(f.consoleErrors||[]).length,shot:f.finalShot??null},note:`Drove ${f.finalUrl||o} (${(f.steps||[]).length} steps)`})}}catch(e){n.warn("drive_site: tool record failed (drive unaffected)",{error:e instanceof Error?e.message:String(e)})}c({success:!0})
5680
+ o?.ok&&(r=o.requestId)}catch{}await i.getToolRecordClient().createToolRecord({type:"drive-site",projectId:s.projectId,...r?{requestId:r}:{},metadata:{url:o,finalUrl:f.finalUrl,title:f.title??null,steps:(f.steps||[]).length,failed:(f.steps||[]).filter(e=>!e.ok).length,consoleErrors:(f.consoleErrors||[]).length,shot:f.finalShot??null,shots:[...(f.steps||[]).map(e=>e?.shot).filter(e=>"string"==typeof e),...f.finalShot?[f.finalShot]:[]]},note:`Drove ${f.finalUrl||o} (${(f.steps||[]).length} steps)`})}}catch(e){n.warn("drive_site: tool record failed (drive unaffected)",{error:e instanceof Error?e.message:String(e)})}c({success:!0})
5666
5681
  const y=/^data:(image\/[a-z+.-]+);base64,(.+)$/.exec(String(f.finalShotDataUrl||""))
5667
5682
  return{content:[...y?[{type:"image",data:y[2],mimeType:y[1]}]:[],{type:"text",text:g}]}}catch(e){return n.error("drive_site failed",{error:e}),c({success:!1,error:"exception"}),{content:[{type:"text",text:`drive_site failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}}
5668
5683
  const r=t(70901)},75010(e,exports,t){exports.handleFetchAsset=async function(e,t,i,a){const c=a.startTimer("tool_execution_time"),l=e=>(c({success:!1,error:"bad"}),{content:[{type:"text",text:e}],isError:!0})
@@ -5755,27 +5770,36 @@ var o=Object.getOwnPropertyDescriptor(t,r)
5755
5770
  o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),n=this&&this.__exportStar||function(e,exports){for(var t in e)"default"===t||Object.prototype.hasOwnProperty.call(exports,t)||r(exports,e,t)}
5756
5771
  Object.defineProperty(exports,"__esModule",{value:!0}),n(t(70441),exports),n(t(70270),exports)},70270(e,exports){Object.defineProperty(exports,"__esModule",{value:!0})},26540(e,exports){var t
5757
5772
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.LogLevel=void 0,function(e){e.ERROR="error",e.WARN="warn",e.INFO="info",e.DEBUG="debug"}(t||(exports.LogLevel=t={}))},76183(e,exports,t){function r(e){const t={...e._def,description:void 0}
5758
- if(e instanceof n.z.ZodObject){const n=Object.fromEntries(Object.entries(e.shape).map(([e,t])=>[e,r(t)]))
5759
- t.shape=()=>n}else e instanceof n.z.ZodOptional||e instanceof n.z.ZodNullable||e instanceof n.z.ZodDefault?t.innerType=r(t.innerType):e instanceof n.z.ZodArray?t.type=r(t.type):e instanceof n.z.ZodRecord&&(t.valueType=r(t.valueType))
5760
- return new e.constructor(t)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.ReplaceLinesSchema=exports.InsertLinesSchema=exports.PlannerOpsSchema=exports.ResearchFanoutSchema=exports.SubagentOperationsSchema=exports.TaskInspectSchema=exports.CompleteTaskSchema=exports.GetTaskInformationSchema=exports.GetRequestInformationSchema=exports.ListRequestsSchema=exports.ListTasksSchema=exports.SearchSchema=exports.QueryHistorySchema=exports.RequestDiffSchema=exports.MergePreviewSchema=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.TargetConditionsSchema=exports.TargetConditionSchema=exports.CompleteRequestSchema=exports.BaselineSchema=exports.skipTestsSchema=exports.skipTestsReasonSchema=exports.ExecutedTestSchema=exports.TestVerificationSchema=exports.TestDefinitionSchema=exports.AcceptanceCriterionSchema=exports.RecordTypeEnum=exports.RequestStatusEnum=exports.TaskStatusEnum=exports.RequestStatusFilterEnum=exports.SettableRequestTypeEnum=exports.RequestTypeEnum=exports.TestCoverageTypeEnum=exports.CompletionStatusEnum=void 0,exports.EnvironmentUpdateSchema=exports.EnvironmentCreateSchema=exports.EnvironmentVerifyStackSchema=exports.EnvironmentStatusSchema=exports.EnvironmentTeardownSchema=exports.EnvironmentProvisionSchema=exports.EnvironmentGetSchema=exports.AskUserVisualSchema=exports.RequestVisualFeedbackSchema=exports.FetchAssetSchema=exports.PreviewSiteSchema=exports.CaptureSiteSchema=exports.DriveSiteSchema=exports.ReadSiteSchema=exports.ExperimentListSchema=exports.ExperimentStopSchema=exports.ExperimentStartSchema=exports.ResultInspectSchema=exports.ResultsSchema=exports.EnvironmentListSchema=exports.TestingProcessDeleteSchema=exports.TestingProcessCreateSchema=exports.TestingProcessGetSchema=exports.TestingProcessListSchema=exports.MetaOperationsSchema=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.QuickReplaceSchema=exports.QuickWriteSchema=exports.RequestOperationsSchema=exports.ManageFilesSchema=exports.ModifyFileSchema=exports.RevertRequestSchema=exports.PlanWriteSchema=exports.PlanReadSchema=exports.DocumentOperationsSchema=exports.SearchDocumentsSchema=exports.CreateDocumentSchema=void 0,exports.AnswerQuestionSchema=exports.McpConnectionsSchema=exports.DirectiveOperationsSchema=exports.CommitToViewedSessionSchema=exports.SessionMessageOperationsSchema=exports.OpeningBriefSectionSchema=exports.ReportTestResultsSchema=exports.CommandsSchema=exports.RunSchema=exports.ExecuteTestCommandSchema=exports.TestsSchema=exports.TestingProcessUpdateSchema=exports.SetupFinishSchema=exports.EnvironmentSetupSchema=exports.EnvironmentVerifySchema=exports.EnvironmentDeleteSchema=void 0
5761
- const n=t(11569),o=t(8955),s=t(94466),i=e=>"string"!=typeof e||e.trim()?e:void 0,a=(e,t,r={})=>n.z.string().refine(t=>!(!r.allowEmpty||""!==t)||!!t&&e.some(e=>e.test(t)),{message:t}),c=a([s.TASK_REF_PATTERN,s.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)."),l=a([/^req\d{6}$/],"Request ID must match format: req###### (e.g. req000001)"),d=a([/^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}),u=e=>e.path&&e.documentId?{...e,documentId:void 0}:e,h=e=>Boolean(e.path)||Boolean(e.documentId)
5762
- exports.CompletionStatusEnum=n.z.enum(["complete","incomplete","partial"]),exports.TestCoverageTypeEnum=n.z.enum(["unit","e2e","integration","manual"]),exports.RequestTypeEnum=n.z.enum(["code","quick-edit","drive","writing","engineering","setup"]),exports.SettableRequestTypeEnum=n.z.enum(["code","drive","writing","engineering"]),exports.RequestStatusFilterEnum=n.z.enum(["draft","open","in_progress","ready_for_review","completing","resolving_conflicts","conflicted","completed","canceled","reverted","in_flight"]).describe("A status, or in_flight: every request under way."),exports.TaskStatusEnum=n.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]),exports.RequestStatusEnum=n.z.enum(["open","in_progress","ready_for_review","completing","completed","canceled","reverted","conflicted"]),exports.RecordTypeEnum=n.z.enum(["write","modify","blocker","resolution","discovery","test","delete"]),exports.AcceptanceCriterionSchema=n.z.object({description:n.z.string(),createdAt:n.z.string().optional(),updatedAt:n.z.string().optional()}),exports.TestDefinitionSchema=n.z.object({id:n.z.string(),description:n.z.string(),status:exports.CompletionStatusEnum,coverageType:exports.TestCoverageTypeEnum,accepts:n.z.array(n.z.string())}),exports.TestVerificationSchema=n.z.object({criteria:n.z.array(n.z.string()),tests:n.z.array(n.z.string()),coverageType:exports.TestCoverageTypeEnum,coverageRatio:n.z.number(),createdAt:n.z.string().optional(),updatedAt:n.z.string().optional()}),exports.ExecutedTestSchema=n.z.object({id:n.z.string(),testId:n.z.string(),status:exports.CompletionStatusEnum,results:n.z.string(),coverage:n.z.array(n.z.string()),executedAt:n.z.string()}),exports.skipTestsReasonSchema=n.z.string().min(20).optional().describe("Opt out of all tests (20+ characters); refused when any is blocking."),exports.skipTestsSchema=n.z.array(n.z.object({commandName:n.z.string().min(1),reason:n.z.string().min(20)})).optional().describe("Skip some advisory test commands, each with why (20+ characters)."),exports.BaselineSchema=n.z.object({metric:n.z.string().regex(/^[A-Za-z_][A-Za-z0-9_.-]{0,59}$/).describe('"time" (the command\'s running time, seconds) or the name of a number it prints ("items_per_s: 812").'),better:n.z.enum(["lower","higher"]),tolerancePct:n.z.number().min(0).max(1e3).optional().describe("Percent worse still counted as no worse; default 10, or the user's number."),atLeast:n.z.number().min(0).optional().describe("Minimum absolute worsening that counts (default 0.1 for time, else 0)."),repeats:n.z.number().int().min(1).max(9).optional().describe("Runs per side, default 3; 1 for a number that never varies."),measures:n.z.enum(["time","size","count","rate","other"]).optional().describe('"time" for any duration ("solver_ms=12"), "size", "count", "rate" (per second), else "other".')}).describe("Only when the user asks that a measured number must not get worse (a time, a test count, a size); needs `command`, kind objective. Measured side by side before and after in the project's box; a regression waits for the user's sign-off."),exports.CompleteRequestSchema=n.z.object({status:exports.RequestStatusEnum,acceptanceCriteria:n.z.array(exports.AcceptanceCriterionSchema),testVerification:exports.TestVerificationSchema.optional(),completionSummary:n.z.string().optional()}),exports.TargetConditionSchema=n.z.object({id:n.z.string().optional().describe("Kept on an edit."),words:n.z.string().min(1).max(200).describe("What must hold, in the user's words."),command:n.z.string().optional().describe("The saved command that prints it, by name (SAVED COMMANDS in your context); omit until one exists."),metric:n.z.string().optional().describe("The name before its number (`name: 1.9`); omit for a lone number."),min:n.z.number().optional().describe('The user\'s lower bound ("at least 3": 3 meets it), set even before a command exists.'),max:n.z.number().optional().describe('The user\'s upper bound ("under 55" or "at most 55": 55 meets it), set even before a command exists.'),unit:n.z.string().max(12).optional().describe('The unit the user stated for the number ("ms", "kB", "%"); omit when they stated none.')}),exports.TargetConditionsSchema=n.z.array(exports.TargetConditionSchema).max(8).nullable().describe("The thread's target: met when every condition holds on main, a bound counting its own number as met. [] or null clears it."),exports.CreateRequestSchema=n.z.object({title:n.z.string().optional(),process:n.z.string().optional().describe("The workflow process it follows, by name, when it clearly is that kind of work: sets the kind and adds its guidance as criteria."),userSaid:n.z.string().min(8).max(600).optional().describe("The phrase of the user's that asks for this, copied exactly (an excerpt is matched). Pass it whenever the request comes from what they wrote; required for a 'gate' criterion, whose words must ask for a lasting check."),type:exports.SettableRequestTypeEnum.describe("'code': builds or fixes behaviour. 'writing': prose in the repo (docs, page copy). 'drive': the driver exercises the product as its user would against the criteria as claims; no branch, no merge, an unmet claim waits for the user. 'engineering': a model, simulation or analysis whose numbers are the product, reviewed on assumptions and evidence; prefer it over 'code' when the deliverable is a result."),description:n.z.string().optional().describe('What to build or find out and why: the record, not a reply (guidance on how you talk to the user does not apply). Call the user "you".'),quotesMessage:n.z.boolean().optional().describe("true when the user's message is the specification: it is copied in word for word, and your description is only what you add. Do not write their message out yourself. userSaid picks which message."),acceptanceCriteria:n.z.array(n.z.union([n.z.string(),n.z.object({description:n.z.string().min(1),beforeMerge:n.z.boolean().optional().describe("[user-input] only: the user asked to check it before it merges; the merge then waits for them at every Autonomy."),command:n.z.string().min(1).max(500).optional().describe("The command that decides it, if one does, as it runs in the project's box (not in the text). Written before the work exists: check what the result does, not how it is worded."),environment:n.z.string().min(1).max(120).optional().describe("The registered environment that runs its command when the check's box cannot (a browser suite in a Playwright environment); an unknown or unfinished one is asked for or waited on."),kind:n.z.enum(["objective","subjective","gate"]).describe("objective: provable by running something (output, files, exit codes), even with no tests yet. subjective: needs judgment. gate: a check on every merge from now on, met by a test process registered for this request."),baseline:exports.BaselineSchema.optional()})])).optional().describe('Done-conditions other than the bars in `target`: a string, or { description, kind }; split a mixed claim. What must be true of the result, never that a check ran. What must come from the user is its own criterion marked [user-input] (the end card asks for it). Address the user as "you".'),draft:n.z.boolean().optional().describe("A draft: nothing runs until the user starts it (a title alone is fine). How a worker files work nobody asked for (follows: its request)."),delegate:n.z.boolean().optional(),follows:n.z.string({required_error:"Required. Every request either follows earlier work or starts fresh: pass the origin request id (req######) or the word 'new'."}).refine(e=>"new"===e||/^(round:|new:)?req\d{6}$/.test(e),{message:"Pass a request id like req000031, 'round:req000031' for another round of work that has landed, 'new:req000031' for new work that grew out of it, or 'new' for genuinely new work."}).describe("The only link between requests. 'round:req######': another pass at what that completed request built (bigger, the wording back), shown as one item; pass only follows and type, it keeps the request's title and criteria and takes the user's message as its change. 'req######': a follow-up or fix of it, only when the user pointed at it or you are working it. 'new': fresh work, anything asked on its own, even touching earlier work; 'new:req######' when it grew out of that one (own thread and budget). Never the project's founding request."),planDocumentId:n.z.string().optional().describe("The plan that decomposes this work (plan######)."),scheduleDocumentId:n.z.string().optional().describe("Only when a schedule told you to create it: the id it gave."),questDocumentId:n.z.string().optional(),waitsOn:n.z.array(n.z.string().regex(/^req\d{6}$/)).max(5).optional().describe("Requests it waits for: it starts once all have landed (a canceled one never does: move or clear the wait). Declare it here; work is dispatched at registration. Growing out of an unlanded request: this or startsNow."),waitReason:n.z.string().optional().describe("With waitsOn (required): what it needs from the one it waits for, as the user reads it. Needing nothing means no wait."),startsNow:n.z.boolean().optional().describe("The other answer to waitsOn: start now beside the unlanded request. The user's words decide; silent on order, wait only when it builds on what that one adds."),asked:n.z.array(n.z.string().regex(/^Q-[A-Z0-9]+-\d+$/)).max(5).optional().describe("Your open questions (Q-codes) whose answer this builds on; the worker gets the answer and does not re-ask."),userChoices:n.z.array(n.z.string().regex(/^Q-[A-Za-z0-9]+-\d+$/)).max(10).optional().describe("Cards the user answered (or still may) that this builds on; their picks count as sources in review, so carry the picked words into the description. Cards closed by an agent, default or withdrawal are refused."),replaces:n.z.string().regex(/^req\d{6}$/).optional().describe("The canceled request this refiles; its waiters move here."),areas:n.z.array(n.z.string()).max(3).optional().describe("1-3 work areas, required unless draft: lowercase kebab paths ('graphics/opengl'). Pick from the project's areas (WORK AREAS when your context lists them, else list-areas); a new name only when nothing fits, under an existing parent."),budget:n.z.number().positive().max(1e5).optional().describe('A budget the user named ("up to $3"), dollars at list price, their words in userSaid: the thread\'s; at it, nothing new starts until they allow more.'),target:n.z.array(exports.TargetConditionSchema,{required_error:'Required. The bars the user set on a number, each { words, max or min } ("under 200 kB": max 200); [] when they set none.'}).max(8).describe('Every bar the user set on a number ("under 200 kB": max 200), in their words; [] when they set none. Each is shown as a criterion with its reading and is the thread\'s target, read on main: write no other criterion for it.'),estimate:n.z.number().positive().max(1e5).optional().describe("Expected cost in dollars at list price, judged from recent requests.")}),exports.CreateTaskSchema=n.z.object({requestId:l,title:n.z.string(),description:n.z.string()}),exports.UpdateTaskStatusSchema=n.z.object({taskId:c,status:exports.TaskStatusEnum,note:n.z.string()}),exports.WriteFileSchema=n.z.object({path:n.z.string().optional(),documentId:d.optional(),content:n.z.union([n.z.string(),n.z.array(n.z.string())]).optional(),fromResult:n.z.string().optional().describe('Instead of content: a recorded result (its address, or a unique prefix) whose bytes become this file, unchanged. For a file made somewhere you cannot write the worktree from, e.g. a .docx made in a sealed box and recorded with results({ operation: "record", box }). Files only (with path), up to 20 MB; bulk stays in the store (results pin).'),format:n.z.enum(["text","json"]).optional(),append:n.z.boolean().optional(),comment:n.z.string()}).transform(u).refine(h,{message:"path or documentId required"}).refine(e=>void 0!==e.content!==Boolean(e.fromResult),{message:"pass content or fromResult (exactly one)"}),exports.ViewAssetSchema=n.z.object({filename:n.z.string().optional().describe("An image in .alchemy_lab/assets/, as an asset:<filename> ref names it."),path:n.z.string().optional().describe("An image, PDF or office file (Word, Excel, PowerPoint, OpenDocument, .doc/.xls/.ppt/.rtf) in the working tree."),result:n.z.string().optional().describe("A recorded result: its address or a unique prefix."),pages:n.z.string().optional().describe('e.g. "3", "12-18" or "1,4,7-9"; at most 20 per view, required for documents over 20 pages.'),revision:n.z.string().optional().describe('With path: the file as committed at this commit, branch or tag; "base" is the version before this branch changed it.')}),exports.ReadFilesSchema=n.z.object({paths:n.z.array(n.z.object({path:n.z.string().optional(),documentId:d.optional(),lines:n.z.string().optional(),symbol:n.z.string().max(200).optional()}).transform(u).refine(h,{message:"path or documentId required"})),encoding:n.z.enum(["utf8","utf-8","ascii","binary"]).optional()}),exports.ListDirectorySchema=n.z.object({path:n.z.string(),levels:n.z.number().min(1).max(4).optional(),sortBy:n.z.enum(["name","modified","size","type"]).optional()}),exports.GetFileInfoSchema=n.z.object({path:n.z.string()}),exports.CreateDirectorySchema=n.z.object({path:n.z.string(),comment:n.z.string().optional()}),exports.MoveFilesSchema=n.z.object({operations:n.z.array(n.z.object({source:n.z.string(),destination:n.z.string()})),comment:n.z.string()}),exports.ReplaceStringSchema=n.z.object({path:n.z.string(),replacements:n.z.array(n.z.object({old_str:n.z.string(),new_str:n.z.string()})),mode:n.z.enum(["unique","all"]).optional(),comment:n.z.string()}),exports.ReplaceStringsSchema=n.z.object({operations:n.z.array(n.z.object({path:n.z.string().optional(),documentId:d.optional(),replacements:n.z.array(n.z.object({old_str:n.z.string(),new_str:n.z.string()})),mode:n.z.enum(["unique","all"]).optional()}).transform(u).refine(h,{message:"path or documentId required"})),comment:n.z.string()}),exports.ReplaceInFilesSchema=n.z.object({operations:n.z.array(n.z.object({path:n.z.string().optional(),documentId:d.optional(),replacements:n.z.array(n.z.object({old_str:n.z.string().min(1,"old_str cannot be empty"),new_str:n.z.string(),match_mode:n.z.enum(["unique","all"]).optional()})).min(1,"At least one replacement required"),fuzzy_match:n.z.boolean().optional()}).transform(u).refine(h,{message:"path or documentId required"})).min(1,"At least one operation required"),fuzzy_match:n.z.boolean().optional().default(!0),comment:n.z.string()}),exports.DeleteFileSchema=n.z.object({path:n.z.string(),comment:n.z.string()}),exports.DeleteFilesSchema=n.z.object({paths:n.z.array(n.z.string()).optional(),operations:n.z.array(n.z.object({path:n.z.string().optional(),documentId:d.optional()}).transform(u).refine(h,{message:"path or documentId required"})).optional(),comment:n.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=n.z.object({path:n.z.string(),limit:n.z.number().min(1).max(100).default(10),showDiff:n.z.boolean().default(!1),showTraceability:n.z.boolean().default(!0),branch:n.z.string().optional(),commit:n.z.string().optional(),since:n.z.string().optional()}),exports.FileRecoverSchema=n.z.object({path:n.z.string(),commitHash:n.z.string(),createBackup:n.z.boolean().default(!0)}),exports.MergePreviewSchema=n.z.object({requestId:l,format:n.z.enum(["summary","unified"]).default("summary").describe("summary = per-file counts; unified = the diff the merge would add to your branch"),path:n.z.string().optional().describe('Optional git pathspec to scope the preview (e.g. "src/hud.css", "src/", "**/*.ts")')}),exports.RequestDiffSchema=n.z.object({requestId:l,format:n.z.enum(["summary","unified"]).default("summary"),path:n.z.string().optional()}),exports.QueryHistorySchema=n.z.object({queryType:n.z.enum(["file-history","task-file-history","request-file-history","recover","blame"],{errorMap:()=>({message:"Invalid queryType. Valid options: file-history, task-file-history, request-file-history, recover, blame"})}),fileHistory:n.z.object({path:n.z.string(),limit:n.z.number().min(1).max(100).default(10),showDiff:n.z.boolean().default(!1),showTraceability:n.z.boolean().default(!0),branch:n.z.string().optional(),commit:n.z.string().optional(),since:n.z.string().optional()}).optional(),taskHistory:n.z.object({taskId:c,showDiff:n.z.boolean().optional()}).optional(),requestHistory:n.z.object({requestId:l,detailLevel:n.z.enum(["summary","detailed"]).default("summary"),taskId:c.optional(),showDiff:n.z.boolean().optional(),fileFilter:n.z.string().optional()}).optional(),recover:n.z.object({path:n.z.string(),commitHash:n.z.string().optional(),createBackup:n.z.boolean().default(!0)}).optional(),blame:n.z.object({path:n.z.string(),lines:n.z.string().optional(),branch:n.z.string().optional()}).optional()}).refine(e=>"file-history"===e.queryType?e.fileHistory&&!e.requestHistory&&!e.recover:"task-file-history"===e.queryType?e.taskHistory&&!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=n.z.object({needle:n.z.string().optional(),directory:n.z.string().optional(),directories:n.z.array(n.z.string()).max(8).optional(),options:n.z.object({caseSensitive:n.z.boolean().optional(),fileExtension:n.z.string().optional(),maxResults:n.z.number().optional(),useRegex:n.z.boolean().optional(),searchIn:n.z.enum(["content","filename","both"]).default("content").optional(),contextLines:n.z.number().min(0).optional(),levels:n.z.number().min(1).max(4).optional(),sortBy:n.z.enum(["name","modified","size","type"]).optional()}).optional()}),exports.ListTasksSchema=n.z.object({requestId:l,filters:n.z.object({status:n.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).optional(),limit:n.z.number().min(1).max(100).default(20),offset:n.z.number().min(0).default(0),sortBy:n.z.enum(["created","updated"]).default("updated"),sortDirection:n.z.enum(["asc","desc"]).default("desc")}).optional()}),exports.ListRequestsSchema=n.z.object({filters:n.z.object({type:exports.RequestTypeEnum.optional(),status:exports.RequestStatusFilterEnum.optional(),planDocumentId:n.z.string().optional(),scheduleDocumentId:n.z.string().optional().describe("Requests a schedule fired: that schedule document."),questDocumentId:n.z.string().optional().describe("Legacy name of scheduleDocumentId."),dateFrom:n.z.string().optional().describe("Only requests with activity from this date on (YYYY-MM-DD means that whole day in the user's clock, or an ISO timestamp)."),dateTo:n.z.string().optional().describe("Only requests with activity up to this date (YYYY-MM-DD includes the whole day)."),limit:n.z.number().min(1).max(100).default(20),offset:n.z.number().min(0).default(0),sortBy:n.z.enum(["created","updated"]).default("updated"),sortDirection:n.z.enum(["asc","desc"]).default("desc")}).optional()}),exports.GetRequestInformationSchema=n.z.object({requestId:l}),exports.GetTaskInformationSchema=n.z.object({taskId:c}),exports.CompleteTaskSchema=n.z.object({taskId:c,summary:n.z.string()}),exports.TaskInspectSchema=n.z.object({operation:n.z.enum(["get-info","list"]),taskId:c.optional(),requestId:l.optional(),status:n.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).optional(),limit:n.z.number().min(1).max(100).default(20),offset:n.z.number().min(0).default(0),sortBy:n.z.enum(["created","updated"]).default("updated"),sortDirection:n.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" }'})})
5763
- const p=n.z.string().min(1).describe("OpenCode session ID")
5764
- exports.SubagentOperationsSchema=n.z.object({sessionId:p.optional(),operation:n.z.enum(["spawn","continue","check-status","abort","read-messages","list-sessions"]),prompt:n.z.string().min(1).describe("Instructions for the subagent (required for spawn and continue)").optional(),agent:n.z.string().default("work").refine(e=>(0,o.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:n.z.string().max(60).describe("Brief label for the UI (max 60 chars, spawn only)").optional(),requestId:n.z.string().describe("Request ID: associates work (spawn) or filters results (list-sessions)").optional(),allowParallel:n.z.boolean().describe("Allow spawning even if request already has active workers (spawn only)").optional(),useExistingSession:n.z.string().describe("Existing session ID to send prompt to instead of creating new session (spawn only)").optional(),limit:n.z.number().min(1).max(100).describe("Max items to return (read-messages: max 50, list-sessions: max 100)").optional(),compact:n.z.boolean().describe("read-messages: return a one-line index of EACH message with tool-call markers (the subagent`s trajectory at a glance: which tools ran, in what order, which failed), instead of full text. Use to see what a subagent actually DID, then `select` one for detail.").optional(),select:n.z.number().min(1).describe("read-messages: return ONLY this message number (from the compact list) in full structured detail: each tool call as {tool, input, status, output}, plus its text. The objective record of one step.").optional(),activeOnly:n.z.boolean().describe("Only show sessions that are currently active/busy (list-sessions only)").optional(),minTokens:n.z.number().min(0).describe("Only show sessions with at least this many tokens (list-sessions only)").optional(),maxTokens:n.z.number().min(0).describe("Only show sessions with at most this many tokens (list-sessions only)").optional(),maxAgeHours:n.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.ResearchFanoutSchema=n.z.object({goal:n.z.string().min(1).optional().describe("What to research; passed to every angle. Required to START a run."),angles:n.z.array(n.z.string()).optional().describe("Research angles to fan out over. Omit to use the default set (data-model, call-sites, prior-art/history, external/web, test-surface)."),planId:n.z.string().optional().describe("Plan document to reference the research report from when the run completes."),checkRunId:n.z.string().optional().describe("Pass a runId from a previous start to CHECK that run live progress instead of starting a new one.")}).refine(e=>!(!e.goal||!e.goal.trim())||!!e.checkRunId,{message:"Provide goal to start a run, or checkRunId to check one."}),exports.PlannerOpsSchema=n.z.object({operation:n.z.enum(["request","check-status","list","end"]),sessionId:p.optional(),prompt:n.z.string().min(1).describe("request (required): what to plan").optional(),description:n.z.string().max(60).describe("request: a short label").optional(),userRequested:n.z.boolean().describe("request: true only when the user asked for this plan themselves").optional(),userStarts:n.z.boolean().describe("request: the user said they will start the plan themselves").optional(),documentId:n.z.string().describe("request: an existing plan to evolve in place; end: the plan whose planner to end").optional(),activeOnly:n.z.boolean().optional(),limit:n.z.number().min(1).max(100).optional()}).refine(e=>"request"===e.operation?!!e.prompt:"check-status"===e.operation?!!e.sessionId:"list"===e.operation||"end"===e.operation&&(!!e.sessionId||!!e.documentId),{message:"request requires prompt; check-status requires sessionId; end requires sessionId or documentId"}),exports.InsertLinesSchema=n.z.object({operations:n.z.array(n.z.object({path:n.z.string().optional(),documentId:d.optional(),insertions:n.z.array(n.z.object({type:n.z.enum(["before","after","between"]),line:n.z.number().optional(),afterLine:n.z.number().optional(),beforeLine:n.z.number().optional(),content:n.z.union([n.z.string(),n.z.array(n.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(u).refine(h,{message:"path or documentId required"})),comment:n.z.string()}),exports.ReplaceLinesSchema=n.z.object({operations:n.z.array(n.z.object({path:n.z.string().optional(),documentId:d.optional(),replacements:n.z.array(n.z.object({lines:n.z.string(),content:n.z.union([n.z.string(),n.z.array(n.z.string())])}))}).transform(u).refine(h,{message:"path or documentId required"})),comment:n.z.string()}),exports.CreateDocumentSchema=n.z.object({requestId:l.optional(),filename:n.z.string().refine(e=>/\.(md|html?)$/i.test(e),{message:"Filename must end in .md (prose) or .html (a rendered page)"}),content:n.z.string(),comment:n.z.string(),scheduleIntervalSeconds:n.z.number().int().min(300).describe("Fire interval in seconds (min 300). Setting this makes the document a SCHEDULE: the runner periodically asks the alchemist to read it and create one linked request. 86400 = daily. Prefer scheduleAtTimes when the goal wants a time of day.").optional(),scheduleAtTimes:n.z.string().describe("Local time(s) of day to fire, e.g. '09:00' or '09:00,17:00'. Setting this makes the document a SCHEDULE that runs at that clock time instead of on an interval, and it starts at the next such time (never the moment it is created).").optional(),scheduleOnDays:n.z.string().describe("Which days scheduleAtTimes applies to: 'weekdays', 'weekends', or names like 'mon,thu'. Omit for every day.").optional(),schedulePrompt:n.z.string().describe('What each firing should do -- the instruction the alchemist receives per tick (e.g. "validate quotes.ndjson and file a short report; flag the user only on real breakage").').optional(),scheduleMaxPerDay:n.z.number().int().min(1).describe("Cap on requests it files per day (structural guard); only when the user named one. A goal with a target keeps reading it past the cap.").optional(),scheduleMaxInFlight:n.z.number().int().min(1).describe("Cap on live linked requests before firings pause (structural guard). Default 1.").optional(),target:exports.TargetConditionsSchema.optional(),scheduleBudgetUsd:n.z.number().positive().max(1e5).optional(),userSaid:n.z.string().max(600).optional()}),exports.SearchDocumentsSchema=n.z.object({query:n.z.string(),requestId:l.optional(),includeArchived:n.z.boolean().default(!1),maxResults:n.z.number().min(1).max(100).default(20),dateFrom:n.z.string().optional(),dateTo:n.z.string().optional(),searchIn:n.z.enum(["content","filename","both"]).default("both")}),exports.DocumentOperationsSchema=n.z.object({operation:n.z.enum(["create","update","search","create-snapshot","get-history","get-version","restore-version","archive","unarchive","list-annotations","create-annotation","reply-to-annotation","resolve-annotation","create-artifact-annotation","propose-standard"]),standardRules:n.z.array(n.z.object({text:n.z.string().min(1).max(600),section:n.z.string().min(1).max(120),checked:n.z.boolean(),kinds:n.z.array(n.z.enum(["code","engineering","writing","drive"])).max(4).optional()})).min(1).max(12).optional(),documentId:d.optional(),requestId:l.optional(),filename:n.z.string().optional(),content:n.z.string().optional(),comment:n.z.string().optional(),scheduleIntervalSeconds:n.z.number().int().min(300).optional(),scheduleAtTimes:n.z.string().optional(),scheduleOnDays:n.z.string().optional(),schedulePrompt:n.z.string().optional(),scheduleMaxPerDay:n.z.number().int().min(1).optional(),scheduleMaxInFlight:n.z.number().int().min(1).optional(),target:exports.TargetConditionsSchema.optional(),scheduleEnabled:n.z.boolean().optional().describe("update: false pauses, true resumes (with scheduleReason); archive only a finished goal."),scheduleBudgetUsd:n.z.number().positive().max(1e5).nullable().optional().describe("Dollars at list price for the whole goal (its requests and your turns on it); at it, the goal stops until the user allows more. null removes it."),userSaid:n.z.string().min(8).max(600).optional().describe("With scheduleBudgetUsd or target: the user's words, exact."),scheduleReason:n.z.string().optional().describe("Why paused or resumed; the user reads it."),query:n.z.string().optional(),includeArchived:n.z.boolean().default(!1),maxResults:n.z.number().min(1).max(100).default(20),dateFrom:n.z.string().optional(),dateTo:n.z.string().optional(),searchIn:n.z.enum(["content","filename","both"]).default("both"),replacements:n.z.array(n.z.object({old_str:n.z.string(),new_str:n.z.string()})).optional(),mode:n.z.enum(["unique","all"]).optional(),versionLabel:n.z.string().optional(),changeSummary:n.z.string().optional(),versionNumber:n.z.number().int().min(1).optional(),selectedText:n.z.string().optional(),prefixContext:n.z.string().optional(),suffixContext:n.z.string().optional(),lineHint:n.z.number().int().optional(),body:n.z.string().optional(),annotationId:n.z.string().optional(),ref:n.z.string().optional(),file:n.z.string().optional(),line:n.z.union([n.z.number().int(),n.z.string()]).optional()}).superRefine((e,t)=>{const r=e.operation
5773
+ if(e instanceof o.z.ZodObject){const n=Object.fromEntries(Object.entries(e.shape).map(([e,t])=>[e,r(t)]))
5774
+ t.shape=()=>n}else e instanceof o.z.ZodOptional||e instanceof o.z.ZodNullable||e instanceof o.z.ZodDefault?t.innerType=r(t.innerType):e instanceof o.z.ZodArray?t.type=r(t.type):e instanceof o.z.ZodRecord&&(t.valueType=r(t.valueType))
5775
+ return new e.constructor(t)}function n(e){switch(e.operation){case"send":return e.type?null:'send needs "type": use "report" for a summary, a verdict or an update, or "question" to ask someone.'
5776
+ case"note":return"string"==typeof e.text&&e.text.trim()?null:'note needs "text": the note itself.'
5777
+ case"reply":return e.messageCode?null:'reply needs "messageCode": the code of the message you answer.'
5778
+ case"get":return e.messageCode?null:'get needs "messageCode": the code of the message to read.'
5779
+ case"withdraw":return e.messageCode?null:'withdraw needs "messageCode": the code of the message to withdraw.'
5780
+ case"record-decision":return e.decision?null:'record-decision needs "decision".'
5781
+ case"brief":return e.requestId&&Array.isArray(e.sections)&&e.sections.length>0?null:'brief needs "requestId" and a non-empty "sections" array.'
5782
+ case"list":case"offer-handoff":return null
5783
+ default:return'"operation" must be one of: send, note, reply, list, get, withdraw, record-decision, brief, offer-handoff.'}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.ReplaceLinesSchema=exports.InsertLinesSchema=exports.PlannerOpsSchema=exports.ResearchFanoutSchema=exports.SubagentOperationsSchema=exports.TaskInspectSchema=exports.CompleteTaskSchema=exports.GetTaskInformationSchema=exports.GetRequestInformationSchema=exports.ListRequestsSchema=exports.ListTasksSchema=exports.SearchSchema=exports.QueryHistorySchema=exports.RequestDiffSchema=exports.MergePreviewSchema=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.TargetConditionsSchema=exports.TargetConditionSchema=exports.CompleteRequestSchema=exports.BaselineSchema=exports.skipTestsSchema=exports.skipTestsReasonSchema=exports.ExecutedTestSchema=exports.TestVerificationSchema=exports.TestDefinitionSchema=exports.AcceptanceCriterionSchema=exports.RecordTypeEnum=exports.RequestStatusEnum=exports.TaskStatusEnum=exports.RequestStatusFilterEnum=exports.SettableRequestTypeEnum=exports.RequestTypeEnum=exports.TestCoverageTypeEnum=exports.CompletionStatusEnum=void 0,exports.EnvironmentUpdateSchema=exports.EnvironmentCreateSchema=exports.EnvironmentVerifyStackSchema=exports.EnvironmentStatusSchema=exports.EnvironmentTeardownSchema=exports.EnvironmentProvisionSchema=exports.EnvironmentGetSchema=exports.AskUserVisualSchema=exports.RequestVisualFeedbackSchema=exports.FetchAssetSchema=exports.PreviewSiteSchema=exports.CaptureSiteSchema=exports.DriveSiteSchema=exports.ReadSiteSchema=exports.ExperimentListSchema=exports.ExperimentStopSchema=exports.ExperimentStartSchema=exports.ResultInspectSchema=exports.ResultsSchema=exports.EnvironmentListSchema=exports.TestingProcessDeleteSchema=exports.TestingProcessCreateSchema=exports.TestingProcessGetSchema=exports.TestingProcessListSchema=exports.MetaOperationsSchema=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.QuickReplaceSchema=exports.QuickWriteSchema=exports.RequestOperationsSchema=exports.ManageFilesSchema=exports.ModifyFileSchema=exports.RevertRequestSchema=exports.PlanWriteSchema=exports.PlanReadSchema=exports.DocumentOperationsSchema=exports.SearchDocumentsSchema=exports.CreateDocumentSchema=void 0,exports.AnswerQuestionSchema=exports.McpConnectionsSchema=exports.DirectiveOperationsSchema=exports.CommitToViewedSessionSchema=exports.SessionMessageOperationsSchema=exports.OpeningBriefSectionSchema=exports.ReportTestResultsSchema=exports.CommandsSchema=exports.RunSchema=exports.ExecuteTestCommandSchema=exports.TestsSchema=exports.TestingProcessUpdateSchema=exports.SetupFinishSchema=exports.EnvironmentSetupSchema=exports.EnvironmentVerifySchema=exports.EnvironmentDeleteSchema=void 0,exports.sessionMessageMissing=n
5784
+ const o=t(11569),s=t(8955),i=t(94466),a=e=>"string"!=typeof e||e.trim()?e:void 0,c=(e,t,r={})=>o.z.string().refine(t=>!(!r.allowEmpty||""!==t)||!!t&&e.some(e=>e.test(t)),{message:t}),l=c([i.TASK_REF_PATTERN,i.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)."),d=c([/^req\d{6}$/],"Request ID must match format: req###### (e.g. req000001)"),u=c([/^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}),h=e=>e.path&&e.documentId?{...e,documentId:void 0}:e,p=e=>Boolean(e.path)||Boolean(e.documentId)
5785
+ exports.CompletionStatusEnum=o.z.enum(["complete","incomplete","partial"]),exports.TestCoverageTypeEnum=o.z.enum(["unit","e2e","integration","manual"]),exports.RequestTypeEnum=o.z.enum(["code","quick-edit","drive","writing","engineering","setup"]),exports.SettableRequestTypeEnum=o.z.enum(["code","drive","writing","engineering"]),exports.RequestStatusFilterEnum=o.z.enum(["draft","open","in_progress","ready_for_review","completing","resolving_conflicts","conflicted","completed","canceled","reverted","in_flight"]).describe("A status, or in_flight: every request under way."),exports.TaskStatusEnum=o.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]),exports.RequestStatusEnum=o.z.enum(["open","in_progress","ready_for_review","completing","completed","canceled","reverted","conflicted"]),exports.RecordTypeEnum=o.z.enum(["write","modify","blocker","resolution","discovery","test","delete"]),exports.AcceptanceCriterionSchema=o.z.object({description:o.z.string(),createdAt:o.z.string().optional(),updatedAt:o.z.string().optional()}),exports.TestDefinitionSchema=o.z.object({id:o.z.string(),description:o.z.string(),status:exports.CompletionStatusEnum,coverageType:exports.TestCoverageTypeEnum,accepts:o.z.array(o.z.string())}),exports.TestVerificationSchema=o.z.object({criteria:o.z.array(o.z.string()),tests:o.z.array(o.z.string()),coverageType:exports.TestCoverageTypeEnum,coverageRatio:o.z.number(),createdAt:o.z.string().optional(),updatedAt:o.z.string().optional()}),exports.ExecutedTestSchema=o.z.object({id:o.z.string(),testId:o.z.string(),status:exports.CompletionStatusEnum,results:o.z.string(),coverage:o.z.array(o.z.string()),executedAt:o.z.string()}),exports.skipTestsReasonSchema=o.z.string().min(20).optional().describe("Opt out of all tests (20+ characters); refused when any is blocking."),exports.skipTestsSchema=o.z.array(o.z.object({commandName:o.z.string().min(1),reason:o.z.string().min(20)})).optional().describe("Skip some advisory test commands, each with why (20+ characters)."),exports.BaselineSchema=o.z.object({metric:o.z.string().regex(/^[A-Za-z_][A-Za-z0-9_.-]{0,59}$/).describe('"time" (the command\'s running time, seconds) or the name of a number it prints ("items_per_s: 812").'),better:o.z.enum(["lower","higher"]),tolerancePct:o.z.number().min(0).max(1e3).optional().describe("Percent worse still counted as no worse; default 10, or the user's number."),atLeast:o.z.number().min(0).optional().describe("Minimum absolute worsening that counts (default 0.1 for time, else 0)."),repeats:o.z.number().int().min(1).max(9).optional().describe("Runs per side, default 3; 1 for a number that never varies."),measures:o.z.enum(["time","size","count","rate","other"]).optional().describe('"time" for any duration ("solver_ms=12"), "size", "count", "rate" (per second), else "other".')}).describe("Only when the user asks that a measured number must not get worse (a time, a test count, a size); needs `command`, kind objective. Measured side by side before and after in the project's box; a regression waits for the user's sign-off."),exports.CompleteRequestSchema=o.z.object({status:exports.RequestStatusEnum,acceptanceCriteria:o.z.array(exports.AcceptanceCriterionSchema),testVerification:exports.TestVerificationSchema.optional(),completionSummary:o.z.string().optional()}),exports.TargetConditionSchema=o.z.object({id:o.z.string().optional().describe("Kept on an edit."),words:o.z.string().min(1).max(200).describe("What must hold, in the user's words."),command:o.z.string().optional().describe("The saved command that prints it, by name (SAVED COMMANDS in your context); omit until one exists."),metric:o.z.string().optional().describe("The name before its number (`name: 1.9`); omit for a lone number."),min:o.z.number().optional().describe('The user\'s lower bound ("at least 3": 3 meets it), set even before a command exists.'),max:o.z.number().optional().describe('The user\'s upper bound ("under 55" or "at most 55": 55 meets it), set even before a command exists.'),unit:o.z.string().max(12).optional().describe('The unit the user stated for the number ("ms", "kB", "%"); omit when they stated none.')}),exports.TargetConditionsSchema=o.z.array(exports.TargetConditionSchema).max(8).nullable().describe("The thread's target: met when every condition holds on main, a bound counting its own number as met. [] or null clears it."),exports.CreateRequestSchema=o.z.object({title:o.z.string().optional(),process:o.z.string().optional().describe("The workflow process it follows, by name, when it clearly is that kind of work: sets the kind and adds its guidance as criteria."),userSaid:o.z.string().min(8).max(600).optional().describe("The phrase of the user's that asks for this, copied exactly (an excerpt is matched). Pass it whenever the request comes from what they wrote; required for a 'gate' criterion, whose words must ask for a lasting check."),type:exports.SettableRequestTypeEnum.describe("'code': builds or fixes behaviour. 'writing': prose in the repo (docs, page copy). 'drive': the driver exercises the product as its user would against the criteria as claims; no branch, no merge, an unmet claim waits for the user. 'engineering': a model, simulation or analysis whose numbers are the product, reviewed on assumptions and evidence; prefer it over 'code' when the deliverable is a result."),description:o.z.string().optional().describe('What to build or find out and why: the record, not a reply (guidance on how you talk to the user does not apply). Call the user "you".'),quotesMessage:o.z.boolean().optional().describe("true when the user's message is the specification: it is copied in word for word, and your description is only what you add. Do not write their message out yourself. userSaid picks which message."),acceptanceCriteria:o.z.array(o.z.union([o.z.string(),o.z.object({description:o.z.string().min(1),beforeMerge:o.z.boolean().optional().describe("[user-input] only: the user asked to check it before it merges; the merge then waits for them at every Autonomy."),command:o.z.string().min(1).max(500).optional().describe("The command that decides it, if one does, as it runs in the project's box (not in the text). Written before the work exists: check what the result does, not how it is worded."),environment:o.z.string().min(1).max(120).optional().describe("The registered environment that runs its command when the check's box cannot (a browser suite in a Playwright environment); an unknown or unfinished one is asked for or waited on."),kind:o.z.enum(["objective","subjective","gate"]).describe("objective: provable by running something (output, files, exit codes), even with no tests yet. subjective: needs judgment. gate: a check on every merge from now on, met by a test process registered for this request."),baseline:exports.BaselineSchema.optional()})])).optional().describe('Done-conditions other than the bars in `target`: a string, or { description, kind }; split a mixed claim. What must be true of the result, never that a check ran. What must come from the user is its own criterion marked [user-input] (the end card asks for it). Address the user as "you".'),draft:o.z.boolean().optional().describe("A draft: nothing runs until the user starts it (a title alone is fine). How a worker files work nobody asked for (follows: its request)."),delegate:o.z.boolean().optional(),follows:o.z.string({required_error:"Required. Every request either follows earlier work or starts fresh: pass the origin request id (req######) or the word 'new'."}).refine(e=>"new"===e||/^(round:|new:)?req\d{6}$/.test(e),{message:"Pass a request id like req000031, 'round:req000031' for another round of work that has landed, 'new:req000031' for new work that grew out of it, or 'new' for genuinely new work."}).describe("The only link between requests. 'round:req######': another pass at what that completed request built (bigger, the wording back), shown as one item; pass only follows and type, it keeps the request's title and criteria and takes the user's message as its change. 'req######': a follow-up or fix of it, only when the user pointed at it or you are working it. 'new': fresh work, anything asked on its own, even touching earlier work; 'new:req######' when it grew out of that one (own thread and budget). Never the project's founding request."),planDocumentId:o.z.string().optional().describe("The plan that decomposes this work (plan######)."),scheduleDocumentId:o.z.string().optional().describe("Only when a schedule told you to create it: the id it gave."),questDocumentId:o.z.string().optional(),waitsOn:o.z.array(o.z.string().regex(/^req\d{6}$/)).max(5).optional().describe("Requests it waits for: it starts once all have landed (a canceled one never does: move or clear the wait). Declare it here; work is dispatched at registration. Growing out of an unlanded request: this or startsNow."),waitReason:o.z.string().optional().describe("With waitsOn (required): what it needs from the one it waits for, as the user reads it. Needing nothing means no wait."),startsNow:o.z.boolean().optional().describe("The other answer to waitsOn: start now beside the unlanded request. The user's words decide; silent on order, wait only when it builds on what that one adds."),asked:o.z.array(o.z.string().regex(/^Q-[A-Z0-9]+-\d+$/)).max(5).optional().describe("Your open questions (Q-codes) whose answer this builds on; the worker gets the answer and does not re-ask."),userChoices:o.z.array(o.z.string().regex(/^Q-[A-Za-z0-9]+-\d+$/)).max(10).optional().describe("Cards the user answered (or still may) that this builds on; their picks count as sources in review, so carry the picked words into the description. Cards closed by an agent, default or withdrawal are refused."),replaces:o.z.string().regex(/^req\d{6}$/).optional().describe("The canceled request this refiles; its waiters move here."),areas:o.z.array(o.z.string()).max(3).optional().describe("1-3 work areas, required unless draft: lowercase kebab paths ('graphics/opengl'). Pick from the project's areas (WORK AREAS when your context lists them, else list-areas); a new name only when nothing fits, under an existing parent."),budget:o.z.number().positive().max(1e5).optional().describe('A budget the user named ("up to $3"), dollars at list price, their words in userSaid: the thread\'s; at it, nothing new starts until they allow more.'),target:o.z.array(exports.TargetConditionSchema,{required_error:'Required. The bars the user set on a number, each { words, max or min } ("under 200 kB": max 200); [] when they set none.'}).max(8).describe('Every bar the user set on a number ("under 200 kB": max 200), in their words; [] when they set none. Each is shown as a criterion with its reading and is the thread\'s target, read on main: write no other criterion for it.'),estimate:o.z.number().positive().max(1e5).optional().describe("Expected cost in dollars at list price, judged from recent requests.")}),exports.CreateTaskSchema=o.z.object({requestId:d,title:o.z.string(),description:o.z.string()}),exports.UpdateTaskStatusSchema=o.z.object({taskId:l,status:exports.TaskStatusEnum,note:o.z.string()}),exports.WriteFileSchema=o.z.object({path:o.z.string().optional(),documentId:u.optional(),content:o.z.union([o.z.string(),o.z.array(o.z.string())]).optional(),fromResult:o.z.string().optional().describe('Instead of content: a recorded result (its address, or a unique prefix) whose bytes become this file, unchanged. For a file made somewhere you cannot write the worktree from, e.g. a .docx made in a sealed box and recorded with results({ operation: "record", box }). Files only (with path), up to 20 MB; bulk stays in the store (results pin).'),format:o.z.enum(["text","json"]).optional(),append:o.z.boolean().optional(),comment:o.z.string()}).transform(h).refine(p,{message:"path or documentId required"}).refine(e=>void 0!==e.content!==Boolean(e.fromResult),{message:"pass content or fromResult (exactly one)"}),exports.ViewAssetSchema=o.z.object({filename:o.z.string().optional().describe("An image in .alchemy_lab/assets/, as an asset:<filename> ref names it."),path:o.z.string().optional().describe("An image, PDF or office file (Word, Excel, PowerPoint, OpenDocument, .doc/.xls/.ppt/.rtf) in the working tree."),result:o.z.string().optional().describe("A recorded result: its address or a unique prefix."),pages:o.z.string().optional().describe('e.g. "3", "12-18" or "1,4,7-9"; at most 20 per view, required for documents over 20 pages.'),revision:o.z.string().optional().describe('With path: the file as committed at this commit, branch or tag; "base" is the version before this branch changed it.')}),exports.ReadFilesSchema=o.z.object({paths:o.z.array(o.z.object({path:o.z.string().optional(),documentId:u.optional(),lines:o.z.string().optional(),symbol:o.z.string().max(200).optional()}).transform(h).refine(p,{message:"path or documentId required"})),encoding:o.z.enum(["utf8","utf-8","ascii","binary"]).optional()}),exports.ListDirectorySchema=o.z.object({path:o.z.string(),levels:o.z.number().min(1).max(4).optional(),sortBy:o.z.enum(["name","modified","size","type"]).optional()}),exports.GetFileInfoSchema=o.z.object({path:o.z.string()}),exports.CreateDirectorySchema=o.z.object({path:o.z.string(),comment:o.z.string().optional()}),exports.MoveFilesSchema=o.z.object({operations:o.z.array(o.z.object({source:o.z.string(),destination:o.z.string()})),comment:o.z.string()}),exports.ReplaceStringSchema=o.z.object({path:o.z.string(),replacements:o.z.array(o.z.object({old_str:o.z.string(),new_str:o.z.string()})),mode:o.z.enum(["unique","all"]).optional(),comment:o.z.string()}),exports.ReplaceStringsSchema=o.z.object({operations:o.z.array(o.z.object({path:o.z.string().optional(),documentId:u.optional(),replacements:o.z.array(o.z.object({old_str:o.z.string(),new_str:o.z.string()})),mode:o.z.enum(["unique","all"]).optional()}).transform(h).refine(p,{message:"path or documentId required"})),comment:o.z.string()}),exports.ReplaceInFilesSchema=o.z.object({operations:o.z.array(o.z.object({path:o.z.string().optional(),documentId:u.optional(),replacements:o.z.array(o.z.object({old_str:o.z.string().min(1,"old_str cannot be empty"),new_str:o.z.string(),match_mode:o.z.enum(["unique","all"]).optional()})).min(1,"At least one replacement required"),fuzzy_match:o.z.boolean().optional()}).transform(h).refine(p,{message:"path or documentId required"})).min(1,"At least one operation required"),fuzzy_match:o.z.boolean().optional().default(!0),comment:o.z.string()}),exports.DeleteFileSchema=o.z.object({path:o.z.string(),comment:o.z.string()}),exports.DeleteFilesSchema=o.z.object({paths:o.z.array(o.z.string()).optional(),operations:o.z.array(o.z.object({path:o.z.string().optional(),documentId:u.optional()}).transform(h).refine(p,{message:"path or documentId required"})).optional(),comment:o.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=o.z.object({path:o.z.string(),limit:o.z.number().min(1).max(100).default(10),showDiff:o.z.boolean().default(!1),showTraceability:o.z.boolean().default(!0),branch:o.z.string().optional(),commit:o.z.string().optional(),since:o.z.string().optional()}),exports.FileRecoverSchema=o.z.object({path:o.z.string(),commitHash:o.z.string(),createBackup:o.z.boolean().default(!0)}),exports.MergePreviewSchema=o.z.object({requestId:d,format:o.z.enum(["summary","unified"]).default("summary").describe("summary = per-file counts; unified = the diff the merge would add to your branch"),path:o.z.string().optional().describe('Optional git pathspec to scope the preview (e.g. "src/hud.css", "src/", "**/*.ts")')}),exports.RequestDiffSchema=o.z.object({requestId:d,format:o.z.enum(["summary","unified"]).default("summary"),path:o.z.string().optional()}),exports.QueryHistorySchema=o.z.object({queryType:o.z.enum(["file-history","task-file-history","request-file-history","recover","blame"],{errorMap:()=>({message:"Invalid queryType. Valid options: file-history, task-file-history, request-file-history, recover, blame"})}),fileHistory:o.z.object({path:o.z.string(),limit:o.z.number().min(1).max(100).default(10),showDiff:o.z.boolean().default(!1),showTraceability:o.z.boolean().default(!0),branch:o.z.string().optional(),commit:o.z.string().optional(),since:o.z.string().optional()}).optional(),taskHistory:o.z.object({taskId:l,showDiff:o.z.boolean().optional()}).optional(),requestHistory:o.z.object({requestId:d,detailLevel:o.z.enum(["summary","detailed"]).default("summary"),taskId:l.optional(),showDiff:o.z.boolean().optional(),fileFilter:o.z.string().optional()}).optional(),recover:o.z.object({path:o.z.string(),commitHash:o.z.string().optional(),createBackup:o.z.boolean().default(!0)}).optional(),blame:o.z.object({path:o.z.string(),lines:o.z.string().optional(),branch:o.z.string().optional()}).optional()}).refine(e=>"file-history"===e.queryType?e.fileHistory&&!e.requestHistory&&!e.recover:"task-file-history"===e.queryType?e.taskHistory&&!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=o.z.object({needle:o.z.string().optional(),directory:o.z.string().optional(),directories:o.z.array(o.z.string()).max(8).optional(),options:o.z.object({caseSensitive:o.z.boolean().optional(),fileExtension:o.z.string().optional(),maxResults:o.z.number().optional(),useRegex:o.z.boolean().optional(),searchIn:o.z.enum(["content","filename","both"]).default("content").optional(),contextLines:o.z.number().min(0).optional(),levels:o.z.number().min(1).max(4).optional(),sortBy:o.z.enum(["name","modified","size","type"]).optional()}).optional()}),exports.ListTasksSchema=o.z.object({requestId:d,filters:o.z.object({status:o.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).optional(),limit:o.z.number().min(1).max(100).default(20),offset:o.z.number().min(0).default(0),sortBy:o.z.enum(["created","updated"]).default("updated"),sortDirection:o.z.enum(["asc","desc"]).default("desc")}).optional()}),exports.ListRequestsSchema=o.z.object({filters:o.z.object({type:exports.RequestTypeEnum.optional(),status:exports.RequestStatusFilterEnum.optional(),planDocumentId:o.z.string().optional(),scheduleDocumentId:o.z.string().optional().describe("Requests a schedule fired: that schedule document."),questDocumentId:o.z.string().optional().describe("Legacy name of scheduleDocumentId."),dateFrom:o.z.string().optional().describe("Only requests with activity from this date on (YYYY-MM-DD means that whole day in the user's clock, or an ISO timestamp)."),dateTo:o.z.string().optional().describe("Only requests with activity up to this date (YYYY-MM-DD includes the whole day)."),limit:o.z.number().min(1).max(100).default(20),offset:o.z.number().min(0).default(0),sortBy:o.z.enum(["created","updated"]).default("updated"),sortDirection:o.z.enum(["asc","desc"]).default("desc")}).optional()}),exports.GetRequestInformationSchema=o.z.object({requestId:d}),exports.GetTaskInformationSchema=o.z.object({taskId:l}),exports.CompleteTaskSchema=o.z.object({taskId:l,summary:o.z.string()}),exports.TaskInspectSchema=o.z.object({operation:o.z.enum(["get-info","list"]),taskId:l.optional(),requestId:d.optional(),status:o.z.enum(["pending","in_progress","ready_for_review","completed","canceled","reverted"]).optional(),limit:o.z.number().min(1).max(100).default(20),offset:o.z.number().min(0).default(0),sortBy:o.z.enum(["created","updated"]).default("updated"),sortDirection:o.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" }'})})
5786
+ const f=o.z.string().min(1).describe("OpenCode session ID")
5787
+ exports.SubagentOperationsSchema=o.z.object({sessionId:f.optional(),operation:o.z.enum(["spawn","continue","check-status","abort","read-messages","list-sessions"]),prompt:o.z.string().min(1).describe("Instructions for the subagent (required for spawn and continue)").optional(),agent:o.z.string().default("work").refine(e=>(0,s.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:o.z.string().max(60).describe("Brief label for the UI (max 60 chars, spawn only)").optional(),requestId:o.z.string().describe("Request ID: associates work (spawn) or filters results (list-sessions)").optional(),allowParallel:o.z.boolean().describe("Allow spawning even if request already has active workers (spawn only)").optional(),useExistingSession:o.z.string().describe("Existing session ID to send prompt to instead of creating new session (spawn only)").optional(),limit:o.z.number().min(1).max(100).describe("Max items to return (read-messages: max 50, list-sessions: max 100)").optional(),compact:o.z.boolean().describe("read-messages: return a one-line index of EACH message with tool-call markers (the subagent`s trajectory at a glance: which tools ran, in what order, which failed), instead of full text. Use to see what a subagent actually DID, then `select` one for detail.").optional(),select:o.z.number().min(1).describe("read-messages: return ONLY this message number (from the compact list) in full structured detail: each tool call as {tool, input, status, output}, plus its text. The objective record of one step.").optional(),activeOnly:o.z.boolean().describe("Only show sessions that are currently active/busy (list-sessions only)").optional(),minTokens:o.z.number().min(0).describe("Only show sessions with at least this many tokens (list-sessions only)").optional(),maxTokens:o.z.number().min(0).describe("Only show sessions with at most this many tokens (list-sessions only)").optional(),maxAgeHours:o.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.ResearchFanoutSchema=o.z.object({goal:o.z.string().min(1).optional().describe("What to research; passed to every angle. Required to START a run."),angles:o.z.array(o.z.string()).optional().describe("Research angles to fan out over. Omit to use the default set (data-model, call-sites, prior-art/history, external/web, test-surface)."),planId:o.z.string().optional().describe("Plan document to reference the research report from when the run completes."),checkRunId:o.z.string().optional().describe("Pass a runId from a previous start to CHECK that run live progress instead of starting a new one.")}).refine(e=>!(!e.goal||!e.goal.trim())||!!e.checkRunId,{message:"Provide goal to start a run, or checkRunId to check one."}),exports.PlannerOpsSchema=o.z.object({operation:o.z.enum(["request","check-status","list","end"]),sessionId:f.optional(),prompt:o.z.string().min(1).describe("request (required): what to plan").optional(),description:o.z.string().max(60).describe("request: a short label").optional(),userRequested:o.z.boolean().describe("request: true only when the user asked for this plan themselves").optional(),userStarts:o.z.boolean().describe("request: the user said they will start the plan themselves").optional(),documentId:o.z.string().describe("request: an existing plan to evolve in place; end: the plan whose planner to end").optional(),activeOnly:o.z.boolean().optional(),limit:o.z.number().min(1).max(100).optional()}).refine(e=>"request"===e.operation?!!e.prompt:"check-status"===e.operation?!!e.sessionId:"list"===e.operation||"end"===e.operation&&(!!e.sessionId||!!e.documentId),{message:"request requires prompt; check-status requires sessionId; end requires sessionId or documentId"}),exports.InsertLinesSchema=o.z.object({operations:o.z.array(o.z.object({path:o.z.string().optional(),documentId:u.optional(),insertions:o.z.array(o.z.object({type:o.z.enum(["before","after","between"]),line:o.z.number().optional(),afterLine:o.z.number().optional(),beforeLine:o.z.number().optional(),content:o.z.union([o.z.string(),o.z.array(o.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(h).refine(p,{message:"path or documentId required"})),comment:o.z.string()}),exports.ReplaceLinesSchema=o.z.object({operations:o.z.array(o.z.object({path:o.z.string().optional(),documentId:u.optional(),replacements:o.z.array(o.z.object({lines:o.z.string(),content:o.z.union([o.z.string(),o.z.array(o.z.string())])}))}).transform(h).refine(p,{message:"path or documentId required"})),comment:o.z.string()}),exports.CreateDocumentSchema=o.z.object({requestId:d.optional(),filename:o.z.string().refine(e=>/\.(md|html?)$/i.test(e),{message:"Filename must end in .md (prose) or .html (a rendered page)"}),content:o.z.string(),comment:o.z.string(),scheduleIntervalSeconds:o.z.number().int().min(300).describe("Fire interval in seconds (min 300). Setting this makes the document a SCHEDULE: the runner periodically asks the alchemist to read it and create one linked request. 86400 = daily. Prefer scheduleAtTimes when the goal wants a time of day.").optional(),scheduleAtTimes:o.z.string().describe("Local time(s) of day to fire, e.g. '09:00' or '09:00,17:00'. Setting this makes the document a SCHEDULE that runs at that clock time instead of on an interval, and it starts at the next such time (never the moment it is created).").optional(),scheduleOnDays:o.z.string().describe("Which days scheduleAtTimes applies to: 'weekdays', 'weekends', or names like 'mon,thu'. Omit for every day.").optional(),schedulePrompt:o.z.string().describe('What each firing should do -- the instruction the alchemist receives per tick (e.g. "validate quotes.ndjson and file a short report; flag the user only on real breakage").').optional(),scheduleMaxPerDay:o.z.number().int().min(1).describe("Cap on requests it files per day (structural guard); only when the user named one. A goal with a target keeps reading it past the cap.").optional(),scheduleMaxInFlight:o.z.number().int().min(1).describe("Cap on live linked requests before firings pause (structural guard). Default 1.").optional(),target:exports.TargetConditionsSchema.optional(),scheduleBudgetUsd:o.z.number().positive().max(1e5).optional(),userSaid:o.z.string().max(600).optional()}),exports.SearchDocumentsSchema=o.z.object({query:o.z.string(),requestId:d.optional(),includeArchived:o.z.boolean().default(!1),maxResults:o.z.number().min(1).max(100).default(20),dateFrom:o.z.string().optional(),dateTo:o.z.string().optional(),searchIn:o.z.enum(["content","filename","both"]).default("both")}),exports.DocumentOperationsSchema=o.z.object({operation:o.z.enum(["create","update","search","create-snapshot","get-history","get-version","restore-version","archive","unarchive","list-annotations","create-annotation","reply-to-annotation","resolve-annotation","create-artifact-annotation","propose-standard"]),standardRules:o.z.array(o.z.object({text:o.z.string().min(1).max(600),section:o.z.string().min(1).max(120),checked:o.z.boolean(),kinds:o.z.array(o.z.enum(["code","engineering","writing","drive"])).max(4).optional()})).min(1).max(12).optional(),documentId:u.optional(),requestId:d.optional(),filename:o.z.string().optional(),content:o.z.string().optional(),comment:o.z.string().optional(),scheduleIntervalSeconds:o.z.number().int().min(300).optional(),scheduleAtTimes:o.z.string().optional(),scheduleOnDays:o.z.string().optional(),schedulePrompt:o.z.string().optional(),scheduleMaxPerDay:o.z.number().int().min(1).optional(),scheduleMaxInFlight:o.z.number().int().min(1).optional(),target:exports.TargetConditionsSchema.optional(),scheduleEnabled:o.z.boolean().optional().describe("update: false pauses, true resumes (with scheduleReason); archive only a finished goal."),scheduleBudgetUsd:o.z.number().positive().max(1e5).nullable().optional().describe("Dollars at list price for the whole goal (its requests and your turns on it); at it, the goal stops until the user allows more. null removes it."),userSaid:o.z.string().min(8).max(600).optional().describe("With scheduleBudgetUsd or target: the user's words, exact."),scheduleReason:o.z.string().optional().describe("Why paused or resumed; the user reads it."),query:o.z.string().optional(),includeArchived:o.z.boolean().default(!1),maxResults:o.z.number().min(1).max(100).default(20),dateFrom:o.z.string().optional(),dateTo:o.z.string().optional(),searchIn:o.z.enum(["content","filename","both"]).default("both"),replacements:o.z.array(o.z.object({old_str:o.z.string(),new_str:o.z.string()})).optional(),mode:o.z.enum(["unique","all"]).optional(),versionLabel:o.z.string().optional(),changeSummary:o.z.string().optional(),versionNumber:o.z.number().int().min(1).optional(),selectedText:o.z.string().optional(),prefixContext:o.z.string().optional(),suffixContext:o.z.string().optional(),lineHint:o.z.number().int().optional(),body:o.z.string().optional(),annotationId:o.z.string().optional(),ref:o.z.string().optional(),file:o.z.string().optional(),line:o.z.union([o.z.number().int(),o.z.string()]).optional()}).superRefine((e,t)=>{const r=e.operation
5765
5788
  "propose-standard"!==r||e.standardRules&&e.standardRules.length||t.addIssue({code:"custom",message:"standardRules is required for propose-standard: [{ text, section, checked, kinds? }]"}),["create-snapshot","get-history","get-version","restore-version","list-annotations","create-annotation","propose-standard"].includes(r)&&!e.documentId&&t.addIssue({code:"custom",message:`documentId is required for '${r}'. Example: { "operation": "${r}", "documentId": "doc000001" }`}),"create"===r&&(e.filename?/\.(md|html?)$/i.test(e.filename)||t.addIssue({code:"custom",message:"Filename must end in .md (prose) or .html (a rendered page)"}):t.addIssue({code:"custom",message:"filename is required for create (must end in .md or .html)"}),e.content||t.addIssue({code:"custom",message:"content 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"}),"create-artifact-annotation"===r&&(e.ref||t.addIssue({code:"custom",message:'ref is required for create-artifact-annotation. Example: { "operation": "create-artifact-annotation", "ref": "file:src/main.cpp", "line": 42, "body": "..." }'}),e.body||t.addIssue({code:"custom",message:"body is required for create-artifact-annotation"}))})
5766
- const f=d
5767
- exports.PlanReadSchema=n.z.object({operation:n.z.enum(["get","get-active","list","get-history","get-requests"]),planId:f.optional(),searchQuery:n.z.string().optional(),limit:n.z.number().min(1).max(100).default(20),offset:n.z.number().min(0).default(0),sortBy:n.z.enum(["createdAt","updatedAt","filename"]).default("updatedAt"),sortDirection:n.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=n.z.object({operation:n.z.enum(["create","update","append","replace","create-snapshot","restore"]),planId:f.optional(),kind:n.z.enum(["plan"]).default("plan").describe("Document kind to create. Plans only."),content:n.z.string().optional(),name:n.z.string().optional().describe("Plan name (used in filename for create; optional new name for update)."),old_str:n.z.string().optional().describe("Text to find in the plan (for replace)"),new_str:n.z.string().optional().describe("Replacement text (for replace)"),versionLabel:n.z.string().optional(),changeSummary:n.z.string().optional(),versionNumber:n.z.number().int().min(1).optional()}).superRefine((e,t)=>{const r=e.operation
5768
- "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)."})):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&&(void 0!==e.content||e.name||t.addIssue({code:"custom",message:"update requires 'content' and/or 'name'."})),"replace"===r&&(e.old_str||t.addIssue({code:"custom",message:'old_str is required for replace. Example: { "operation": "replace", "planId": "plan000001", "old_str": "find this", "new_str": "replace with" }'}),void 0===e.new_str&&t.addIssue({code:"custom",message:"new_str 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.RevertRequestSchema=n.z.object({requestId:l,reason:n.z.string(),confirmDestructive:n.z.boolean().optional()}),exports.ModifyFileSchema=n.z.object({operations:n.z.array(n.z.object({path:n.z.string().optional(),documentId:d.optional(),operationType:n.z.enum(["replace-string","insert-lines","replace-lines","delete-string","delete-lines"]),replaceString:n.z.object({replacements:n.z.array(n.z.object({old_str:n.z.string(),new_str:n.z.string()})),mode:n.z.enum(["unique","all"]).optional()}).optional(),insertLines:n.z.object({insertions:n.z.array(n.z.object({type:n.z.enum(["before","after","between"]),line:n.z.number().optional(),afterLine:n.z.number().optional(),beforeLine:n.z.number().optional(),content:n.z.union([n.z.string(),n.z.array(n.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:n.z.object({replacements:n.z.array(n.z.object({lines:n.z.string(),content:n.z.union([n.z.string(),n.z.array(n.z.string())])}))}).optional(),deleteString:n.z.object({patterns:n.z.array(n.z.string()),mode:n.z.enum(["all","unique"]).optional()}).optional(),deleteLines:n.z.object({lines:n.z.string()}).optional()}).transform(u).refine(h,{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:n.z.string()}),exports.ManageFilesSchema=n.z.object({operations:n.z.array(n.z.object({operationType:n.z.enum(["create-directory","move-files","delete-files","get-file-info"]),createDirectory:n.z.object({path:n.z.string()}).optional(),moveFiles:n.z.object({moves:n.z.array(n.z.object({source:n.z.string(),destination:n.z.string()}))}).optional(),deleteFiles:n.z.object({targets:n.z.array(n.z.object({path:n.z.string().optional(),documentId:d.optional()}).transform(u).refine(h,{message:"path or documentId required"}))}).optional(),getFileInfo:n.z.object({path:n.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:n.z.string()}),exports.RequestOperationsSchema=n.z.object({requestId:l.optional(),operation:n.z.enum(["update","activate","complete","merge","revert","reopen","get-info","list","search","status","cancel","hold","delete-empty","list-areas","update-areas","wait-on","clear-wait","premise-block","dispute-criterion","hand-over","bring-main-in","check-target","round-piece"]),planId:n.z.string().max(64).optional().describe("status / check-target: a plan's thread."),criterion:n.z.string().optional(),reason:n.z.string().optional().describe('cancel, revert, reopen, wait-on: why, to the user ("you"), in their language (a replacing request named). premise-block (required): what the request builds on that the project lacks; not what it adds, not unclear wording (ask instead).'),userSaid:n.z.string().min(8).max(600).optional().describe("The user's words asking for this, exact (checked). Required for activate, cancel of finished work waiting on them, and reopen with a question pending on them."),waitsOn:n.z.string().optional(),update:n.z.preprocess(e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e,n.z.object({userSaid:n.z.string().min(8).max(600).optional().describe("The user's words asking for this change, exact; a worker narrows or rewords its own request only with them."),budget:n.z.number().positive().max(1e5).nullable().optional().describe("The budget the user named for this request's thread (or plan), dollars at list price, their words in userSaid; null removes it."),target:exports.TargetConditionsSchema.optional(),estimate:n.z.number().positive().max(1e5).optional().describe("Expected cost, dollars at list price."),removesCriteria:n.z.boolean().optional().describe("true to delete the criteria your list leaves out; otherwise a shorter list is refused."),arcName:n.z.string().min(2).max(120).optional().describe("The thread's name, two to five plain words (\"Weekly menu app\"); set once, never over the user's."),title:n.z.string().optional(),description:n.z.string().optional(),process:n.z.string().nullable().optional().describe("A workflow process by name, or null; drafts only."),type:exports.SettableRequestTypeEnum.optional(),acceptanceCriteria:n.z.array(n.z.union([n.z.string(),n.z.object({description:n.z.string().min(1),beforeMerge:n.z.boolean().optional(),command:n.z.string().min(1).max(500).optional().describe("With the criterion's key: replaces its command, and the old line is kept on the record beside it. A worker replaces one that cannot pass where it runs with a line that checks the same thing, never less; the user's own command only with their answer in userSaid."),environment:n.z.string().min(1).max(120).optional().describe("As on create_request; set it instead of dropping a command the box cannot run."),kind:n.z.enum(["objective","subjective","gate"]),baseline:r(exports.BaselineSchema).optional(),key:n.z.string().optional().describe("The key of a criterion you reword (it keeps its verdicts); omit for a new one.")})])).optional().describe("Replaces the whole list; items as on create_request.")})).optional(),areas:n.z.array(n.z.string()).max(3).optional().describe("update-areas: up to 3 replacing the current ones; [] clears."),complete:n.z.preprocess(e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e,n.z.object({change:n.z.preprocess(i,n.z.string().min(3).max(200).optional()).describe('On a round (its description opens "Round N of req######"), instead of summary while the round is open: what this one change did, in one line. The user reads it under the message that asked for it.'),summary:n.z.preprocess(i,n.z.string().optional()).describe('Markdown the user reads when it lands. First line: one sentence with the answer (if the request asked a question) or what changed. Then, only if there is more, one short "- " line per thing; no paragraphs. Never "tested" or "verified" when that failed. It replaces earlier summaries (after rework it covers the whole request) and stays after sign-off, so it says what was delivered, not what waits for the user. On a round it is written once, when you are told the round is being completed; until then pass change.'),replacesSummary:n.z.boolean().optional().describe("Required on a re-completion: the summary covers everything, fixes included."),notChecked:n.z.preprocess(i,n.z.string().min(3).max(160).optional()).describe('What you did not check that the user could assume you did ("the page on a phone"); the card leads with it. Not what registered checks run or say they leave out (the card shows those).'),show:n.z.preprocess(e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e,n.z.object({commands:n.z.array(n.z.string().min(1).max(400)).max(5).optional().describe("Command lines that show the result working. AlchemyLab runs each in a box on the work as it was and on the completed work; the user sees both."),artifact:n.z.string().min(1).max(200).optional().describe("A picture, page or document on the record: a result's address, a document id (doc000012) or asset:<file>.")}).optional()).describe("Optional: something more to show with the finished result. What the request already delivered is shown by itself."),worthKnowing:n.z.array(n.z.string().min(10)).max(5).optional().describe("What the user would regret not knowing, one per entry (a discovery, caveat, side effect, follow-up); always one when what was asked was already true or turned out different. Not the summary again; subject first."),guidance:n.z.array(n.z.object({body:n.z.string().min(10).max(800).describe('One fact or instruction for the next agent ("calc.py is generated from ops.json: edit ops.json and regenerate.")'),files:n.z.array(n.z.string().min(1)).min(1).max(8).optional().describe("Files or folders (globs) it is pinned to; without them (userSaid only) the whole project."),evidence:n.z.string().min(1).max(1500).optional().describe("What shows it (command and output, file); not with userSaid."),userSaid:n.z.string().min(8).max(600).optional().describe("A correction of the user's that should hold later: their words, exact.")}).refine(e=>!!e.userSaid||!!e.files?.length&&!!e.evidence,{message:"a trap needs files and evidence; a correction of the user's needs userSaid"})).max(2).optional().describe("A trap the next agent in these files would hit too, or a user correction, proposed as guidance. Not taste, not request-specific, not already guidance. Usually none."),skipTestsReason:exports.skipTestsReasonSchema,skipTests:exports.skipTestsSchema,criteriaComments:n.z.array(n.z.object({key:n.z.string().min(1),comment:n.z.string().min(1),verify:n.z.array(n.z.string().min(1)).max(4).optional().describe("Commands that prove it in the sealed acceptance box (a grep, a targeted test, a screenshot into .visual-check/), judged on their output. Clean checkout of your commit, dependencies installed, nothing built: a check needing a build runs it in the same command. No git, no network, no branching on whether a tool exists. A proof you saw pass on this commit, written exactly as you ran it, is reused."),testFiles:n.z.array(n.z.string().min(1)).max(10).optional().describe("With verify, when it runs just these tests (not the whole suite): their repo paths. Only the user changes a test a promise names.")})).optional().describe("One entry per criterion, keyed as your pickup lists it: what you did and how you saw it hold."),afterRun:n.z.boolean().optional().describe("Call `run` with your final check, then this complete in the SAME response: it completes only if that run passes."),couldNotCheck:n.z.array(n.z.string().min(1)).max(20).optional().describe("Drives only: keys of claims you could not check (reason in criteriaComments); they read as unchecked. Stamp the rest with record_criteria_verification.")})).optional(),merge:n.z.preprocess(e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e,n.z.object({verifications:n.z.array(n.z.object({key:n.z.string().min(2).max(4),evidence:n.z.string().min(1)})).min(1)})).optional(),revert:n.z.object({reason:n.z.string(),confirmDestructive:n.z.boolean().optional()}).optional(),list:n.z.object({filters:n.z.object({type:exports.RequestTypeEnum.optional(),status:exports.RequestStatusFilterEnum.optional(),planDocumentId:n.z.string().optional(),scheduleDocumentId:n.z.string().optional(),questDocumentId:n.z.string().optional(),dateFrom:n.z.string().optional(),dateTo:n.z.string().optional(),limit:n.z.number().min(1).max(100).default(20),offset:n.z.number().min(0).default(0),sortBy:n.z.enum(["created","updated"]).default("updated"),sortDirection:n.z.enum(["asc","desc"]).default("desc")}).optional()}).optional(),search:n.z.object({query:n.z.string().min(1),searchIn:n.z.enum(["title","description","criteria","all"]).default("all"),filters:n.z.object({type:exports.RequestTypeEnum.optional(),status:exports.RequestStatusFilterEnum.optional(),planDocumentId:n.z.string().optional(),scheduleDocumentId:n.z.string().optional(),questDocumentId:n.z.string().optional(),dateFrom:n.z.string().optional(),dateTo:n.z.string().optional(),limit:n.z.number().min(1).max(100).default(20),offset:n.z.number().min(0).default(0)}).optional()}).optional()}).superRefine((e,t)=>{e.requestId
5789
+ const m=u
5790
+ exports.PlanReadSchema=o.z.object({operation:o.z.enum(["get","get-active","list","get-history","get-requests"]),planId:m.optional(),searchQuery:o.z.string().optional(),limit:o.z.number().min(1).max(100).default(20),offset:o.z.number().min(0).default(0),sortBy:o.z.enum(["createdAt","updatedAt","filename"]).default("updatedAt"),sortDirection:o.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=o.z.object({operation:o.z.enum(["create","update","append","replace","create-snapshot","restore"]),planId:m.optional(),kind:o.z.enum(["plan"]).default("plan").describe("Document kind to create. Plans only."),content:o.z.string().optional(),name:o.z.string().optional().describe("Plan name (used in filename for create; optional new name for update)."),old_str:o.z.string().optional().describe("Text to find in the plan (for replace)"),new_str:o.z.string().optional().describe("Replacement text (for replace)"),versionLabel:o.z.string().optional(),changeSummary:o.z.string().optional(),versionNumber:o.z.number().int().min(1).optional()}).superRefine((e,t)=>{const r=e.operation
5791
+ "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)."})):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&&(void 0!==e.content||e.name||t.addIssue({code:"custom",message:"update requires 'content' and/or 'name'."})),"replace"===r&&(e.old_str||t.addIssue({code:"custom",message:'old_str is required for replace. Example: { "operation": "replace", "planId": "plan000001", "old_str": "find this", "new_str": "replace with" }'}),void 0===e.new_str&&t.addIssue({code:"custom",message:"new_str 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.RevertRequestSchema=o.z.object({requestId:d,reason:o.z.string(),confirmDestructive:o.z.boolean().optional()}),exports.ModifyFileSchema=o.z.object({operations:o.z.array(o.z.object({path:o.z.string().optional(),documentId:u.optional(),operationType:o.z.enum(["replace-string","insert-lines","replace-lines","delete-string","delete-lines"]),replaceString:o.z.object({replacements:o.z.array(o.z.object({old_str:o.z.string(),new_str:o.z.string()})),mode:o.z.enum(["unique","all"]).optional()}).optional(),insertLines:o.z.object({insertions:o.z.array(o.z.object({type:o.z.enum(["before","after","between"]),line:o.z.number().optional(),afterLine:o.z.number().optional(),beforeLine:o.z.number().optional(),content:o.z.union([o.z.string(),o.z.array(o.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:o.z.object({replacements:o.z.array(o.z.object({lines:o.z.string(),content:o.z.union([o.z.string(),o.z.array(o.z.string())])}))}).optional(),deleteString:o.z.object({patterns:o.z.array(o.z.string()),mode:o.z.enum(["all","unique"]).optional()}).optional(),deleteLines:o.z.object({lines:o.z.string()}).optional()}).transform(h).refine(p,{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:o.z.string()}),exports.ManageFilesSchema=o.z.object({operations:o.z.array(o.z.object({operationType:o.z.enum(["create-directory","move-files","delete-files","get-file-info"]),createDirectory:o.z.object({path:o.z.string()}).optional(),moveFiles:o.z.object({moves:o.z.array(o.z.object({source:o.z.string(),destination:o.z.string()}))}).optional(),deleteFiles:o.z.object({targets:o.z.array(o.z.object({path:o.z.string().optional(),documentId:u.optional()}).transform(h).refine(p,{message:"path or documentId required"}))}).optional(),getFileInfo:o.z.object({path:o.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:o.z.string()}),exports.RequestOperationsSchema=o.z.object({requestId:d.optional(),operation:o.z.enum(["update","activate","complete","merge","revert","reopen","get-info","list","search","status","cancel","hold","delete-empty","list-areas","update-areas","wait-on","clear-wait","premise-block","dispute-criterion","hand-over","bring-main-in","check-target","round-piece"]),planId:o.z.string().max(64).optional().describe("status / check-target: a plan's thread."),criterion:o.z.string().optional(),reason:o.z.string().optional().describe('cancel, revert, reopen, wait-on: why, to the user ("you"), in their language (a replacing request named). premise-block (required): what the request builds on that the project lacks; not what it adds, not unclear wording (ask instead).'),userSaid:o.z.string().min(8).max(600).optional().describe("The user's words asking for this, exact (checked). Required for activate, cancel of finished work waiting on them, and reopen with a question pending on them."),waitsOn:o.z.string().optional(),update:o.z.preprocess(e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e,o.z.object({userSaid:o.z.string().min(8).max(600).optional().describe("The user's words asking for this change, exact; a worker narrows or rewords its own request only with them."),budget:o.z.number().positive().max(1e5).nullable().optional().describe("The budget the user named for this request's thread (or plan), dollars at list price, their words in userSaid; null removes it."),target:exports.TargetConditionsSchema.optional(),estimate:o.z.number().positive().max(1e5).optional().describe("Expected cost, dollars at list price."),removesCriteria:o.z.boolean().optional().describe("true to delete the criteria your list leaves out; otherwise a shorter list is refused."),arcName:o.z.string().min(2).max(120).optional().describe("The thread's name, two to five plain words (\"Weekly menu app\"); set once, never over the user's."),title:o.z.string().optional(),description:o.z.string().optional(),process:o.z.string().nullable().optional().describe("A workflow process by name, or null; drafts only."),type:exports.SettableRequestTypeEnum.optional(),acceptanceCriteria:o.z.array(o.z.union([o.z.string(),o.z.object({description:o.z.string().min(1),beforeMerge:o.z.boolean().optional(),command:o.z.string().min(1).max(500).optional().describe("With the criterion's key: replaces its command, and the old line is kept on the record beside it. A worker replaces one that cannot pass where it runs with a line that checks the same thing, never less; the user's own command only with their answer in userSaid."),environment:o.z.string().min(1).max(120).optional().describe("As on create_request; set it instead of dropping a command the box cannot run."),kind:o.z.enum(["objective","subjective","gate"]),baseline:r(exports.BaselineSchema).optional(),key:o.z.string().optional().describe("The key of a criterion you reword (it keeps its verdicts); omit for a new one.")})])).optional().describe("Replaces the whole list; items as on create_request.")})).optional(),areas:o.z.array(o.z.string()).max(3).optional().describe("update-areas: up to 3 replacing the current ones; [] clears."),complete:o.z.preprocess(e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e,o.z.object({change:o.z.preprocess(a,o.z.string().min(3).max(200).optional()).describe('On a round (its description opens "Round N of req######"), instead of summary while the round is open: what this one change did, in one line. The user reads it under the message that asked for it.'),summary:o.z.preprocess(a,o.z.string().optional()).describe('Markdown the user reads when it lands. First line: one sentence with the answer (if the request asked a question) or what changed. Then, only if there is more, one short "- " line per thing; no paragraphs. Never "tested" or "verified" when that failed. It replaces earlier summaries (after rework it covers the whole request) and stays after sign-off, so it says what was delivered, not what waits for the user. On a round it is written once, when you are told the round is being completed; until then pass change.'),replacesSummary:o.z.boolean().optional().describe("Required on a re-completion: the summary covers everything, fixes included."),notChecked:o.z.preprocess(a,o.z.string().min(3).max(160).optional()).describe('What you did not check that the user could assume you did ("the page on a phone"); the card leads with it. Not what registered checks run or say they leave out (the card shows those).'),show:o.z.preprocess(e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e,o.z.object({commands:o.z.array(o.z.string().min(1).max(400)).max(5).optional().describe("Command lines that show the result working. AlchemyLab runs each in a box on the work as it was and on the completed work; the user sees both."),artifact:o.z.string().min(1).max(200).optional().describe("A picture, page or document on the record: a result's address, a document id (doc000012) or asset:<file>.")}).optional()).describe("Optional: something more to show with the finished result. What the request already delivered is shown by itself."),worthKnowing:o.z.array(o.z.string().min(10)).max(5).optional().describe("What the user would regret not knowing, one per entry (a discovery, caveat, side effect, follow-up); always one when what was asked was already true or turned out different. Not the summary again; subject first."),guidance:o.z.array(o.z.object({body:o.z.string().min(10).max(800).describe('One fact or instruction for the next agent ("calc.py is generated from ops.json: edit ops.json and regenerate.")'),files:o.z.array(o.z.string().min(1)).min(1).max(8).optional().describe("Files or folders (globs) it is pinned to; without them (userSaid only) the whole project."),evidence:o.z.string().min(1).max(1500).optional().describe("What shows it (command and output, file); not with userSaid."),userSaid:o.z.string().min(8).max(600).optional().describe("A correction of the user's that should hold later: their words, exact.")}).refine(e=>!!e.userSaid||!!e.files?.length&&!!e.evidence,{message:"a trap needs files and evidence; a correction of the user's needs userSaid"})).max(2).optional().describe("A trap the next agent in these files would hit too, or a user correction, proposed as guidance. Not taste, not request-specific, not already guidance. Usually none."),skipTestsReason:exports.skipTestsReasonSchema,skipTests:exports.skipTestsSchema,criteriaComments:o.z.array(o.z.object({key:o.z.string().min(1),comment:o.z.string().min(1),verify:o.z.array(o.z.string().min(1)).max(4).optional().describe("Commands that prove it in the sealed acceptance box (a grep, a targeted test, a screenshot into .visual-check/), judged on their output. Clean checkout of your commit, dependencies installed, nothing built: a check needing a build runs it in the same command. No git, no network, no branching on whether a tool exists. A proof you saw pass on this commit, written exactly as you ran it, is reused."),testFiles:o.z.array(o.z.string().min(1)).max(10).optional().describe("With verify, when it runs just these tests (not the whole suite): their repo paths. Only the user changes a test a promise names.")})).optional().describe("One entry per criterion, keyed as your pickup lists it: what you did and how you saw it hold."),afterRun:o.z.boolean().optional().describe("Call `run` with your final check, then this complete in the SAME response: it completes only if that run passes."),couldNotCheck:o.z.array(o.z.string().min(1)).max(20).optional().describe("Drives only: keys of claims you could not check (reason in criteriaComments); they read as unchecked. Stamp the rest with record_criteria_verification.")})).optional(),merge:o.z.preprocess(e=>"string"==typeof e?(()=>{try{return JSON.parse(e)}catch{return e}})():e,o.z.object({verifications:o.z.array(o.z.object({key:o.z.string().min(2).max(4),evidence:o.z.string().min(1)})).min(1)})).optional(),revert:o.z.object({reason:o.z.string(),confirmDestructive:o.z.boolean().optional()}).optional(),list:o.z.object({filters:o.z.object({type:exports.RequestTypeEnum.optional(),status:exports.RequestStatusFilterEnum.optional(),planDocumentId:o.z.string().optional(),scheduleDocumentId:o.z.string().optional(),questDocumentId:o.z.string().optional(),dateFrom:o.z.string().optional(),dateTo:o.z.string().optional(),limit:o.z.number().min(1).max(100).default(20),offset:o.z.number().min(0).default(0),sortBy:o.z.enum(["created","updated"]).default("updated"),sortDirection:o.z.enum(["asc","desc"]).default("desc")}).optional()}).optional(),search:o.z.object({query:o.z.string().min(1),searchIn:o.z.enum(["title","description","criteria","all"]).default("all"),filters:o.z.object({type:exports.RequestTypeEnum.optional(),status:exports.RequestStatusFilterEnum.optional(),planDocumentId:o.z.string().optional(),scheduleDocumentId:o.z.string().optional(),questDocumentId:o.z.string().optional(),dateFrom:o.z.string().optional(),dateTo:o.z.string().optional(),limit:o.z.number().min(1).max(100).default(20),offset:o.z.number().min(0).default(0)}).optional()}).optional()}).superRefine((e,t)=>{e.requestId
5769
5792
  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]
5770
5793
  n&&!e[n.field]&&t.addIssue({code:"custom",message:`'${r}' operation requires '${n.field}' data. ${n.hint}`})})
5771
- const m=n.z.string({required_error:"Required. A quick edit either touches up an earlier request's result or stands on its own: pass that request id (req######) or the word 'new'."}).refine(e=>"new"===e||/^req\d{6}$/.test(e),{message:"Pass a request id like req000031, or 'new'."}).describe("The request whose result this edit adjusts (the user pointed at it), or 'new': the same rule as create_request's follows.")
5772
- exports.QuickWriteSchema=n.z.object({title:n.z.string().min(1,"Title is required"),description:n.z.string().min(1,"Description is required"),follows:m,path:n.z.string().optional(),documentId:d.optional(),content:n.z.union([n.z.string(),n.z.array(n.z.string())]),format:n.z.enum(["text","json"]).optional(),append:n.z.boolean().optional()}).transform(u).refine(h,{message:"path or documentId required"}),exports.QuickReplaceSchema=n.z.object({title:n.z.string().min(1,"Title is required"),description:n.z.string().min(1,"Description is required"),follows:m,operations:n.z.array(n.z.object({path:n.z.string().optional(),documentId:d.optional(),replacements:n.z.array(n.z.object({old_str:n.z.string().min(1),new_str:n.z.string(),match_mode:n.z.enum(["unique","all"]).optional()})).min(1),fuzzy_match:n.z.boolean().optional()}).transform(u).refine(h,{message:"path or documentId required"})).min(1),fuzzy_match:n.z.boolean().optional(),comment:n.z.string().min(1,"Comment describing the change is required")}),exports.MetaWorkflowListSchema=n.z.object({}),exports.MetaWorkflowGetSchema=n.z.object({workflowId:n.z.string().describe("Workflow ID to retrieve")}),exports.MetaWorkflowCreateSchema=n.z.object({name:n.z.string().min(1).describe("Unique name for the workflow"),shortName:n.z.string().min(1).max(10).describe("Short display name (required, max 10 chars)"),description:n.z.string().optional().describe("Description of what the workflow does"),testGate:n.z.enum(["off","auto","ask"]).optional().describe("Test gate: off (no test gate), auto (checks run automatically; a blocking command must pass, an advisory one may be skipped with a reason), ask (the user picks auto/interactive/skip at each completion)"),reviewGate:n.z.enum(["off","on"]).optional().describe("Review gate: off, or on (one reviewer checks each acceptance criterion, with the reviewers the kind assigns: guidance, model on engineering, any the workflow added)"),signoffGate:n.z.enum(["off","agent","you"]).optional().describe('Sign-off gate, as the workflow page names it: off; agent ("Delivery review": an agent asks whether the delivery is what was asked for, then merges or brings it to the user); you ("You sign off": the user approves before merge)'),approvalMode:n.z.enum(["none","require-approval","agent-check"]).optional().describe("Pre-work approval: none (default), require-approval (the user approves each request), or agent-check (an independent intake reviewer rules on agent-created requests before work starts)"),interactionPosture:n.z.enum(["autonomous","balanced","collaborative"]).optional().describe("Interaction posture (question-gate dial): autonomous (defaulted questions are self-answered -- proceed + FYI report), balanced (default; questions post normally, non-blocking when defaulted), collaborative (always ask the human)")}),exports.MetaWorkflowUpdateSchema=n.z.object({workflowId:n.z.string().describe("Workflow ID to update"),name:n.z.string().min(1).optional().describe("New name"),shortName:n.z.string().max(10).optional().describe("New short name (max 10 chars)"),description:n.z.string().optional().describe("New description"),testGate:n.z.enum(["off","auto","ask"]).optional().describe("Test gate: off (no test gate), auto (checks run automatically; a blocking command must pass, an advisory one may be skipped with a reason), ask (the user picks auto/interactive/skip at each completion)"),reviewGate:n.z.enum(["off","on"]).optional().describe("Review gate: off, or on (one reviewer checks each acceptance criterion, with the reviewers the kind assigns: guidance, model on engineering, any the workflow added)"),signoffGate:n.z.enum(["off","agent","you"]).optional().describe('Sign-off gate, as the workflow page names it: off; agent ("Delivery review": an agent asks whether the delivery is what was asked for, then merges or brings it to the user); you ("You sign off": the user approves before merge)'),approvalMode:n.z.enum(["none","require-approval","agent-check"]).optional().describe("Pre-work approval: none (default), require-approval (the user approves each request), or agent-check (an independent intake reviewer rules on agent-created requests before work starts)"),interactionPosture:n.z.enum(["autonomous","balanced","collaborative"]).optional().describe("Interaction posture (question-gate dial): autonomous (defaulted questions are self-answered -- proceed + FYI report), balanced (default; questions post normally, non-blocking when defaulted), collaborative (always ask the human)")}),exports.MetaRecipeListSchema=n.z.object({}),exports.MetaRecipeGetSchema=n.z.object({recipeId:n.z.string().describe("Recipe ID to retrieve")}),exports.MetaRecipeCreateSchema=n.z.object({name:n.z.string().min(1).describe("Unique name for the recipe"),description:n.z.string().optional().describe("Description of what the recipe does"),documentation:n.z.string().optional().describe("Detailed documentation")}),exports.MetaRecipeAddHookSchema=n.z.object({recipeId:n.z.string().describe("Recipe ID to add the hook to"),hookId:n.z.string().describe("Hook template ID to add"),position:n.z.number().int().min(0).optional().describe("Position in the recipe (0-based, appended if omitted)")}),exports.MetaRecipeRemoveHookSchema=n.z.object({recipeId:n.z.string().describe("Recipe ID to remove the hook from"),hookId:n.z.string().describe("Hook template ID to remove")}),exports.MetaHookListSchema=n.z.object({}),exports.MetaHookCreateSchema=n.z.object({name:n.z.string().min(1).describe("Unique name for the hook"),description:n.z.string().optional().describe("Description of what the hook does"),eventType:n.z.string().describe("Event type that triggers this hook (e.g., session_idle, request_completed, custom:plan_ready)"),category:n.z.enum(["alchemy","session","message","editing","reading","file_management","documents","history","tool"]).default("session").describe("Hook category"),agent:n.z.string().describe("Agent template to execute when hook fires"),promptTemplate:n.z.string().describe("Prompt template with {{variable}} substitution"),condition:n.z.record(n.z.any()).optional().describe("Condition object for filtering when hook fires"),timing:n.z.enum(["before","after"]).default("after").describe("When to fire relative to the event"),action:n.z.enum(["spawn_agent","inject_prompt"]).optional().describe("What the hook does: spawn_agent (default) starts a new session of `agent` with the prompt; inject_prompt sends the prompt into an existing session"),target:n.z.enum(["independent_session","child_session","same_session","parent_session","ancestor_chain"]).optional().describe("Where the prompt goes. With spawn_agent: independent_session (default, no parent) or child_session (under the session that fired the event). With inject_prompt: same_session (default, the session that fired the event), parent_session, or ancestor_chain"),maxIterations:n.z.number().int().min(1).optional().describe("Maximum times the hook fires for one session, counted from its firing record. Set it on every session_idle hook that sends into the same session. A session a hook started never triggers that hook again, whatever this says"),emitEvent:n.z.string().optional().describe("Custom event to emit on completion"),emitEventOnCondition:n.z.union([n.z.object({condition:n.z.object({field:n.z.string(),operator:n.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:n.z.string()}),event:n.z.string()}),n.z.array(n.z.object({condition:n.z.object({field:n.z.string(),operator:n.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:n.z.string()}),event:n.z.string()}))]).optional().describe("Conditional event emission based on output")}),exports.MetaWorkflowAddRecipeSchema=n.z.object({workflowId:n.z.string().describe("Workflow ID to add the recipe to"),recipeId:n.z.string().describe("Recipe ID to add"),position:n.z.number().int().min(0).optional().describe("Position in the workflow (0-based, appended if omitted)")}),exports.MetaWorkflowRemoveRecipeSchema=n.z.object({workflowId:n.z.string().describe("Workflow ID to remove the recipe from"),recipeId:n.z.string().describe("Recipe ID to remove")}),exports.MetaAgentListSchema=n.z.object({}),exports.MetaOperationsSchema=n.z.object({operation:n.z.enum(["workflow-list","workflow-get","workflow-create","workflow-update","recipe-list","recipe-get","recipe-create","recipe-add-hook","recipe-remove-hook","hook-list","hook-create","workflow-add-recipe","workflow-remove-recipe","agent-list"]).describe("Which meta operation to perform; the other params apply per operation (see tool description)"),...exports.MetaWorkflowGetSchema.partial().shape,...exports.MetaWorkflowCreateSchema.partial().shape,...exports.MetaWorkflowUpdateSchema.partial().shape,...exports.MetaRecipeGetSchema.partial().shape,...exports.MetaRecipeCreateSchema.partial().shape,...exports.MetaRecipeAddHookSchema.partial().shape,...exports.MetaRecipeRemoveHookSchema.partial().shape,...exports.MetaHookCreateSchema.partial().shape,...exports.MetaWorkflowAddRecipeSchema.partial().shape,...exports.MetaWorkflowRemoveRecipeSchema.partial().shape}),exports.TestingProcessListSchema=n.z.object({}),exports.TestingProcessGetSchema=n.z.object({processId:n.z.string().describe("Test process ID to retrieve")})
5773
- const g=n.z.object({name:n.z.string().min(1).describe('Command name (e.g., "Build", "Unit Tests")'),command:n.z.string().min(1).describe('Shell command to run (e.g., "npm test")'),required:n.z.boolean().default(!0).describe("If true, failure blocks the request (default: true)"),timeout:n.z.number().int().min(10).max(3600).default(300).describe("Max execution time in seconds (default: 300)")})
5774
- exports.TestingProcessCreateSchema=n.z.object({name:n.z.string().min(1).describe("Name for the test process"),environmentId:n.z.string().optional().describe("ID of the environment (confined runtime) this process runs in. Get it from environment_list or environment_setup."),description:n.z.string().optional().describe("Description of what this process verifies"),scope:n.z.string().optional().describe('LABEL ONLY -- a monorepo path prefix recorded for display (e.g. "packages/api/"). It does NOT affect when the process runs; use pathGlobs for that.'),pathGlobs:n.z.array(n.z.string()).optional().describe('Which changes this process runs on: glob patterns matched against the changed files (e.g. ["sites/**"], ["src/**", "*.md"]). THIS is what limits when the process runs. Omit it and the process runs on EVERY change, which is the right choice only for a check that is cheap and universal.'),areas:n.z.array(n.z.string()).optional().describe('Work-area labels this process covers (e.g. ["graphics/opengl"]). An alternative to pathGlobs for work that is not file-shaped; a process applies if EITHER dimension matches.'),setup:n.z.array(n.z.string()).optional().describe("Commands that prepare the tree for the tests (install the package itself, generate files the tests import), e.g. [\"python -m pip install --no-deps -e .\"]. They run in its box before its commands on every run, and also before a request's criteria checks, which run in a clean checkout of the commit where `commands` do not run: a preparation step put in `commands` is missing there and those checks fail. If one fails, the run fails as the environment's fault and the commands do not run."),commands:n.z.array(g).min(1).describe("Test commands to execute in order"),verifyAcceptanceCriteria:n.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands"),fingerprint:n.z.array(n.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:n.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."),runtimeKept:n.z.string().optional().describe('Only when the user chose to run the check on a runtime other than the lowest one the project declares: that runtime and version, e.g. "python 3.12". Without it, a check whose environment runs another version than the declared minimum is not registered.'),leavesOut:n.z.array(n.z.object({what:n.z.string().describe('The left-out part in plain words, e.g. "the Valkey backend tests"'),paths:n.z.array(n.z.string()).min(1).describe('Globs for the code that part checks, so a change there goes unchecked by this check: for a backend\'s tests, that backend (e.g. ["aiocache/backends/valkey.py"]); for browser or end-to-end tests, the app source they drive (e.g. ["src/**"]). Not only the left-out test files.'),command:n.z.string().min(1).max(300).optional().describe('The command that runs that part, e.g. "pnpm test:e2e": a request whose criterion runs it is not told this part was left out.')})).optional().describe('What this check deliberately does not run and no other check runs (the suites the card lists as "not run on every change"), each with the code it checks. A change to that code is reported to the user as not checked by this check, unless the request ran that part itself.')}),exports.TestingProcessDeleteSchema=n.z.object({processId:n.z.string().describe("Test process ID to delete")}),exports.EnvironmentListSchema=n.z.object({}),exports.ResultsSchema=n.z.object({operation:n.z.enum(["record","fetch","pin","list","read"]),path:n.z.string().optional().describe("record: the file, inside the project (not /tmp); your worktree first, then the main project. Bulk that must not reach a commit can be written by a command under `.alchemy_lab/scratch/` (gitignored)."),name:n.z.string().optional().describe("record: the name a person uses for it (defaults to the filename). list: show every version recorded under this name, newest first."),summary:n.z.record(n.z.any()).optional().describe('record (required): the small facts a reader wants instead of the bytes, e.g. {maxStress: 412, unit: "MPa", converged: true}.'),box:n.z.string().optional().describe("An experiment handle (exp_...). fetch: put the bytes inside that sealed box under its /scratch (a box cannot see the host scratch; omit for host work, which is faster). record: the result lives inside that box and is streamed out and stored in one step (a box cannot write your worktree)."),mediaType:n.z.string().optional().describe("record: MIME type, when you know it."),inputs:n.z.array(n.z.string()).optional().describe("record: addresses of the results this one was made from (provenance)."),note:n.z.string().optional().describe("record: one line on how it was produced."),address:n.z.string().optional().describe("pin / read / fetch: the full 64-character address the record returned (a unique prefix works too)."),at:n.z.string().optional().describe("pin: the pointer path in your worktree (.result.json is added). fetch: where the bytes land, under AlchemyLab's scratch folder for the project on the host (the answer gives the full path) or the box's `/scratch`. Defaults to results/<name>."),comment:n.z.string().optional().describe("pin: the commit comment for the pointer file."),offset:n.z.number().optional().describe("read: line to start at (default 0)."),limit:n.z.number().optional().describe("read: how many lines (default 200). list: how many results (default 25)."),find:n.z.string().optional().describe("read: return only lines containing this text, instead of a range.")}),exports.ResultInspectSchema=n.z.object({operation:n.z.enum(["list","read"]),name:n.z.string().optional().describe("list: show every version recorded under this name, newest first."),address:n.z.string().optional().describe("read: the full 64-character address of the result, a check run's id (tr_...) or a command run's record id (trec...), to read what its commands printed."),offset:n.z.number().optional().describe("read: line to start at (default 0)."),limit:n.z.number().optional().describe("read: how many lines (default 200). list: how many results (default 25)."),find:n.z.string().optional().describe("read: return only lines containing this text, instead of a range.")}),exports.ExperimentStartSchema=n.z.object({env:n.z.string().optional().describe("Environment by name (from environment_list), one whose image has the toolchain you need."),environmentId:n.z.string().optional().describe("Environment by id (alternative to `env`). The primary env is used if neither is given."),size:n.z.enum(["light","standard","heavy"]).optional().describe("light: 2 cores (lint, a typecheck, one test file). standard (default): a share of the free cores (a suite, a build). heavy: every free core but 2 and 6 GB of memory (2 GB otherwise, unless the environment sets its own), for work that uses them (a CFD solve, meshing, a large parallel build, a model that runs out of memory). A size you do not hold opens another box."),confirmWorkspace:n.z.boolean().optional().describe('Required for env "workspace" (the live host): the task genuinely needs the real machine. Building or trying out the app does not.')}),exports.ExperimentStopSchema=n.z.object({handle:n.z.string().describe("The experiment handle to tear down.")}),exports.ExperimentListSchema=n.z.object({}),exports.ReadSiteSchema=n.z.object({url:n.z.string()}),exports.DriveSiteSchema=n.z.object({url:n.z.string().describe("The running product, e.g. the environment's published URL or http://localhost:5173."),steps:n.z.array(n.z.object({action:n.z.enum(["click","clickat","type","press","move","scroll","wait","media"]).describe('click (selector) \xb7 clickat (x,y) \xb7 type (selector + text) \xb7 press (key) \xb7 move (x,y) \xb7 scroll (dy) \xb7 wait (ms, max 5000) \xb7 media ("print" shows the printout, "screen" switches back)'),selector:n.z.string().optional().describe('Playwright selector, e.g. "text=Build" or "#start".'),text:n.z.string().optional(),key:n.z.string().optional().describe('e.g. "Enter"'),x:n.z.number().optional(),y:n.z.number().optional(),dy:n.z.number().optional(),ms:n.z.number().optional(),media:n.z.enum(["print","screen"]).optional()})).min(1).max(20),shots:n.z.enum(["each","final"]).optional().describe('"each" screenshots every step; default the final state only.'),session:n.z.string().optional().describe("Keeps the page open: the next call with this name continues where this one stopped. Idle sessions close after 10 minutes."),close:n.z.boolean().optional().describe("Close the named session after this call."),width:n.z.number().optional().describe("Viewport width for a new session (default 1280; 390 is a phone).")}),exports.CaptureSiteSchema=n.z.object({url:n.z.string(),fullPage:n.z.boolean().optional().describe("The whole scrollable page instead of the viewport."),width:n.z.number().optional().describe("Viewport width (default 1280; 390 is a phone).")}),exports.PreviewSiteSchema=n.z.object({dir:n.z.string().optional().describe('Repo-relative, e.g. "dist" or "." for the top of the repository. Not needed with stop.'),requestId:n.z.string().regex(/^req\d{6}$/).optional().describe("Serve from this unmerged request's working copy instead of main."),name:n.z.string().optional().describe("Preview handle (default: a slug of dir); reusing one replaces that preview. With stop: the preview to stop."),stop:n.z.boolean().optional().describe("Stop a running preview instead of serving one: the one named, or the only one running."),label:n.z.string().optional()}),exports.FetchAssetSchema=n.z.object({url:n.z.string().describe("The http(s) URL of the image or font to download."),destPath:n.z.string().describe('Where to write it, repo-relative (e.g. "sites/acme/assets/hero.jpg"). Must stay inside the working tree; parent directories are created.')}),exports.RequestVisualFeedbackSchema=n.z.object({box:n.z.string().optional().describe("The experiment handle (from experiment_start, on a screenshot-capable env) to render in / read from. The box must stay held until this returns."),route:n.z.string().optional().describe('With `box`: the route I render + screenshot FOR YOU (e.g. "/" or "/settings"). I serve `serveDir` and screenshot it -- you do NOT hand-roll serve/screenshot. This is the easiest path.'),script:n.z.string().optional().describe('With `box`, for FULL control: a Playwright snippet (the body of `async (page, baseUrl) => { ... }`). I serve the app, launch headless Chromium, and run your script -- navigate (page.goto(baseUrl + "/x")), click, fill, scroll, waitForSelector, etc. -- then screenshot the final page state. Reliable: you write only the interaction, no serve/launch/flags. Use this to reach a state that needs interaction (open a menu, log in, submit a form).'),fullPage:n.z.boolean().optional().describe("Capture the entire scrollable page instead of just the viewport."),serveDir:n.z.string().optional().describe("With `box`+`route`: the static dir to serve (default /work). For a built app, build first via run(), then point this at the build output (e.g. /work/dist)."),path:n.z.string().optional().describe("Alternative to route: a screenshot you ALREADY wrote inside the box (e.g. /tmp/shot.png); I read it out."),assetFilename:n.z.string().optional().describe("Alternative to box: the filename of an already-uploaded screenshot asset to annotate."),prompt:n.z.string().optional().describe("What you want the human to look at or mark up (shown with the request)."),timeoutMs:n.z.number().optional().describe("How long to wait for the human, in ms (default ~10 min).")}),exports.AskUserVisualSchema=n.z.object({question:n.z.string().describe('The question for the USER about the marked region (e.g. "Should this button use the primary color?").'),imagePath:n.z.string().optional().describe("Repo-relative path to an image you already produced (png/jpg/gif/webp), e.g. a screenshot you wrote. Provide this OR previewName."),previewName:n.z.string().optional().describe("Name of a registered live preview (a `live:` ref); I freeze it into a snapshot image for you. Provide this OR imagePath."),box:n.z.string().optional().describe('The region the question is about: "x,y,w,h" in normalized 0..1 image coordinates, origin top-left (e.g. "0.62,0.08,0.3,0.12"). Omit to ask about the whole image.'),options:n.z.array(n.z.string()).optional().describe("Optional answer choices (labels). Omit for a free-text answer."),context:n.z.string().optional().describe("Extra context shown with the question in the inbox (why you are asking, what you will do with the answer)."),priority:n.z.enum(["low","normal","high"]).optional().describe('Question priority; "high" always reaches the user regardless of autonomy dial.')}),exports.EnvironmentGetSchema=n.z.object({environmentId:n.z.string().describe("Environment ID to retrieve")}),exports.EnvironmentProvisionSchema=n.z.object({environmentId:n.z.string(),why:n.z.string().optional().describe("Why provision now (shown on the approval).")}),exports.EnvironmentTeardownSchema=n.z.object({environmentId:n.z.string()}),exports.EnvironmentStatusSchema=n.z.object({environmentId:n.z.string()}),exports.EnvironmentVerifyStackSchema=n.z.object({environmentId:n.z.string()})
5775
- const y=n.z.object({image:n.z.string().optional().describe("Container image carrying the project toolchain/deps, e.g. node:20-alpine, python:3.12-slim, golang:1.22, ruby:3.3"),install:n.z.string().optional().describe("Deps install command -- Node-only sugar that populates a /work/node_modules cache volume, run with registry egress before the confined gate, e.g. npm ci. Non-Node runtimes use `artifacts` instead (a cache volume + prepare command: .venv/uv sync, cargo, go, vendor/bundle). Omit if the project has no deps."),composeFile:n.z.string().optional().describe("Path to the project docker-compose file for its services. Omit if no services."),shellInit:n.z.string().optional().describe("Shell preamble run before EVERY command in the box, e.g. '. /usr/lib/openfoam/openfoam2312/etc/bashrc'. REQUIRED for a toolchain that publishes itself through a script rather than the image PATH (OpenFOAM etc/bashrc, oneAPI setvars.sh, conda activate, ROS setup.bash): `docker exec` runs no ENTRYPOINT and reads no login profile, so without this every command gets a bare PATH. Put the preamble HERE, never inside the smoke command -- a smoke command carrying its own preamble proves the preamble and not the environment, and the next agent gets nothing."),connEnv:n.z.record(n.z.string()).optional().describe("Connection env injected into the gate (e.g. DATABASE_URL) using SERVICE NAMES + internal ports, never localhost/host ports."),seed:n.z.array(n.z.string()).optional().describe("Optional commands run after services are up (e.g. migrations)."),artifacts:n.z.array(n.z.object({path:n.z.string().describe("Mount target for the writable, populated volume: relative to /work for a dependency folder the project's toolchain looks for there (node_modules, .venv, vendor/bundle), or absolute (e.g. /cache/cargo). Tools you install (apt/apk packages, binaries) go at an absolute path outside /work, such as /tools: /work is the project's folder, and its test runners see anything in it."),prepare:n.z.string().optional().describe("Command that populates it -- the one phase with registry egress (e.g. npm ci, uv sync, cargo fetch). Omit for a writable empty volume."),manifests:n.z.array(n.z.string()).optional().describe("Lockfiles (relative to /work) whose content hash keys the cache; list them so the volume is reused across runs and only rebuilt when deps change (e.g. uv.lock, Cargo.lock). Omit => rebuilt every run."),env:n.z.record(n.z.string()).optional().describe('Env applied during prepare AND every run, e.g. { CARGO_HOME: "/cache/cargo" } for caches outside /work.')})).optional().describe("Per-runtime build/dependency artifacts: writable volumes populated by a prepare command, generalizing `install` beyond node_modules. Use for Python (.venv), Rust (target + $CARGO_HOME), Go, Ruby (vendor/bundle), etc. `install` is sugar for a single node_modules artifact; for any non-Node runtime use artifacts (install would write to node_modules, the wrong place)."),confinement:n.z.enum(["confined","egress-allowlist","privileged","unsafe","host","pure-host"]).optional().describe("Confinement level. Default 'confined' (fully sealed Docker; add egressAllowlist hosts to open exactly those -- stored as 'egress-allowlist'). privileged/unsafe relax the container. 'host' runs on the host machine (no Docker) inside an OS sandbox (Seatbelt/bubblewrap) for toolchains Docker can't run. 'pure-host' is the built-in workspace env (the live worktree) -- do not create new envs with it. Merge gating is independent (the Sign-off setting)."),commandGate:n.z.array(n.z.enum(["policy","agent","human"])).optional().describe("Gates an experiment command passes before it runs, in escalation order policy -> agent -> human. Empty = run freely; escalating past the last gate blocks (fail closed). policy = deterministic allowlist/deny-floor; agent = isolated LLM judge (allow or escalate only); human = ask. Registered commands are pre-approved. Defaults by level ([] for confined/egress-allowlist, ['human'] for privileged/unsafe)."),worktreeTarget:n.z.enum(["ephemeral","live"]).optional().describe("Worktree the env runs against: 'ephemeral' (a disposable copy at HEAD, default) or 'live' (the project's live working dir, read-write). The built-in workspace env is 'live'."),egressAllowlist:n.z.array(n.z.string()).optional().describe("Hosts the box may reach at the 'egress-allowlist' level (exact name or subdomain, e.g. registry.npmjs.org). Ignored at other levels."),addCaps:n.z.array(n.z.string()).optional().describe("Linux capabilities to add at the 'privileged' level (on top of cap-drop ALL), e.g. SYS_PTRACE for debuggers, IPC_LOCK for memlock. Ignored at other levels."),sysctls:n.z.record(n.z.string()).optional().describe("Namespaced sysctls to set at the 'privileged' level, e.g. net.ipv4.ip_local_port_range. Host-wide sysctls (vm.max_map_count) are NOT settable per-container."),runAsRoot:n.z.boolean().optional().describe("Run the box as root (privileged / unsafe levels). Needed for some caps + the docker socket."),dockerSocket:n.z.boolean().optional().describe("Mount the host docker socket for testcontainers-style tests. WARNING: full host control over the docker daemon. Only honored at the 'unsafe' level."),persistentVolumes:n.z.array(n.z.object({name:n.z.string(),target:n.z.string(),service:n.z.string().optional()})).optional().describe("Data volumes that survive between runs (keyed to this environment; off by default since experiments are ephemeral). Set service to mount into a compose service (e.g. a DB data dir), or omit it to mount into the box (e.g. a SQLite dir)."),resources:n.z.object({memory:n.z.string().optional().describe("Memory cap for this environment's boxes and its checks' boxes, e.g. '4g' (default 2g; 6g at size heavy). Set it when the test suite or build needs more."),cpus:n.z.number().optional().describe("A fixed CPU count. Usually leave it unset and set size instead."),size:n.z.enum(["light","standard","heavy"]).optional().describe("What this environment's boxes and checks are for, which sets their cores from what is free: light (2 cores: lint, small checks), standard (the default: a share of the free cores, for test suites and builds), heavy (every free core but 2: CFD or FEM solves, meshing, large parallel builds). An agent can ask for another size per box."),pidsLimit:n.z.number().optional().describe("Max processes (default 512)."),scratchMb:n.z.number().optional().describe("Size in MB of an in-memory /scratch, used only when the image cannot take the disk-backed one (default 512). /scratch is normally on disk and needs no size."),shmMb:n.z.number().optional().describe("/dev/shm size in MB -- bump for headless browsers (Chrome crashes on the 64m default).")}).optional().describe("Per-environment resource caps that override the confined defaults.")}),w=r(y),b='Start from a built-in preset; anything in config overrides it. "office": python-docx, openpyxl, python-pptx, pandoc, LibreOffice and segno/zbarimg (QR codes) in a sealed box, with `render-pdf FILE` to turn Word, Excel, PowerPoint, Markdown or HTML into PDF. Its image is built locally on first use (a few minutes). Pass the same preset (and config) to environment_verify and environment_create.',v="Save without a passing environment_verify, only for a config that cannot be verified from here (it needs credentials, external services or hardware the confined verifier lacks). Requires skipVerifyReason; the skip is logged."
5776
- exports.EnvironmentCreateSchema=n.z.object({name:n.z.string().min(1).describe("Name for the environment, e.g. node + postgres"),description:n.z.string().optional().describe("What this environment provides"),scope:n.z.string().optional().describe("Subproject path prefix for monorepos (e.g. packages/api/). Omit for the whole repo."),preset:n.z.enum(["office"]).optional().describe(b),config:w.optional().describe("The exact config (after the preset) that passed environment_verify in this session, unless skipVerify; its fields are described on environment_verify. Optional with a preset."),isPrimary:n.z.boolean().optional().describe("Make this the project primary environment (default for new test processes). The first environment is primary automatically."),skipVerify:n.z.boolean().optional().describe(v),skipVerifyReason:n.z.string().optional().describe("Why this config cannot be verified (required with skipVerify: true; recorded in the log).")}),exports.EnvironmentUpdateSchema=n.z.object({environmentId:n.z.string(),name:n.z.string().min(1).optional(),description:n.z.string().optional(),scope:n.z.string().optional(),config:w.optional().describe("Replaces the config wholesale: the exact config that passed environment_verify in this session, unless skipVerify (fields described on environment_verify). Metadata-only updates need no verify."),isPrimary:n.z.boolean().optional().describe("Make this the project primary environment"),skipVerify:n.z.boolean().optional().describe(v),skipVerifyReason:n.z.string().optional().describe("Why this config cannot be verified (required with skipVerify: true; recorded in the log).")}),exports.EnvironmentDeleteSchema=n.z.object({environmentId:n.z.string().describe("Environment ID to delete")}),exports.EnvironmentVerifySchema=n.z.object({preset:n.z.enum(["office"]).optional().describe(b),config:y.optional().describe("The proposed environment config to verify (image, install, services, connection). Optional with a preset."),smoke:n.z.string().optional().describe("Optional smoke command run confined after the environment is up (default: true). Use a connection probe to confirm services are reachable.")}),exports.EnvironmentSetupSchema=n.z.object({name:n.z.string().max(60).optional().describe("A few words naming what you need (e.g. 'Node 20 for syntax checks')."),context:n.z.string().optional().describe("What you need and why, for the setup architect (e.g. 'Node 20 to run node --check on standalone .js files; no deps').")}),exports.SetupFinishSchema=n.z.object({outcome:n.z.enum(["ready","declined","could_not_finish","no_code","not_yet"]).describe("How the run ended. 'ready' needs something saved in this run."),summary:n.z.string().min(1).describe("What was set up (names and ids), and an answer to every ask the run carries: done, or not done and why. Plain words; it reaches the waiting workers and the user."),startsAfter:n.z.string().regex(/^req\d{6}$/).optional().describe("With 'not_yet': the request still writing what this setup registers.")}),exports.TestingProcessUpdateSchema=n.z.object({processId:n.z.string(),environmentId:n.z.string().optional(),name:n.z.string().min(1).optional(),description:n.z.string().optional(),scope:n.z.string().optional().describe("A display label only; pathGlobs decides when the process runs."),pathGlobs:n.z.array(n.z.string()).optional().describe('Globs matched against changed files (e.g. ["src/**", "*.md"]): the changes this process runs on. Replaces the list; [] means every change.'),areas:n.z.array(n.z.string()).optional().describe("Work-area labels this process covers; it applies when pathGlobs or areas match."),isActive:n.z.boolean().optional(),setup:n.z.array(n.z.string()).optional().describe("Replaces the setup commands (run in the check's box before its commands, and before the criteria checks in their clean checkout)."),commands:n.z.array(g).optional().describe("Replaces the test commands."),verifyAcceptanceCriteria:n.z.boolean().optional().describe("The auto-tester also verifies the request's acceptance criteria."),fingerprint:n.z.array(n.z.string()).optional().describe("Files whose content invalidates setup."),leavesOut:n.z.array(n.z.object({what:n.z.string().describe('The left-out part in plain words, e.g. "the Valkey backend tests"'),paths:n.z.array(n.z.string()).min(1).describe("Globs for the code that part checks (for end-to-end tests, the app source they drive), not only its test files."),command:n.z.string().min(1).max(300).optional().describe('The command that runs that part, e.g. "pnpm test:e2e".')})).optional().describe("Replaces what this check deliberately does not run, with the code each part checks; [] clears it."),poolSize:n.z.number().int().min(1).max(8).optional().describe("Warm test worktrees in the pool."),runtimeKept:n.z.string().optional().describe('With environmentId: only when the user chose a runtime other than the lowest one the project declares, e.g. "python 3.12".')}),exports.TestsSchema=n.z.object({operation:n.z.enum(["list","setup","run","switch-off","switch-on"]),process:n.z.string().optional().describe("run, switch-off, switch-on: one test process by name or id (run: omit for all active ones)."),userSaid:n.z.string().max(600).optional().describe("switch-off / switch-on: the user's words asking for it, copied exactly."),name:n.z.string().optional().describe("run: one test command by name; omit for all required commands."),ask:n.z.string().max(1500).optional().describe("setup, required outside a request: what the user asked the check to run, in their words; the setup architect registers exactly that.")}),exports.ExecuteTestCommandSchema=n.z.object({processId:n.z.string().describe("Test process ID containing the command"),commandName:n.z.string().describe('Name of the test command to run, or "setup" to run all setup commands in sequence')}),exports.RunSchema=n.z.object({command:n.z.string().optional().describe("A shell command, run in the box (pass box or env)."),name:n.z.string().optional().describe("A saved command by name, instead of command."),box:n.z.string().optional().describe("An experiment handle from experiment_start."),env:n.z.string().optional().describe("Instead of box: an environment by name; its box is started (or your open one reused) and the result gives the handle."),size:n.z.enum(["light","standard","heavy"]).optional().describe("With env: the box size (see experiment_start)."),args:n.z.string().optional(),grep:n.z.string().optional().describe("Filter output through grep -i with this pattern."),timeout:n.z.number().optional().describe("Seconds."),why:n.z.string().optional().describe("One short sentence, shown on the approval card when the command needs the user's approval."),cwd:n.z.string().optional().describe('A subdirectory for an ad-hoc command (e.g. "apps/web"); a command starting with `cd` is refused in favour of this.')}),exports.CommandsSchema=n.z.object({operation:n.z.enum(["run","list","remove","register","setup"]).default("run").describe('list, setup, register or remove ("run" is the run tool\'s job).'),name:n.z.string().optional().describe("remove: the command name."),args:n.z.string().optional(),grep:n.z.string().optional(),command:n.z.string().optional(),timeout:n.z.number().optional(),cwd:n.z.string().optional(),context:n.z.string().optional().describe("setup: the command wanted, where it runs and what it is for."),commands:n.z.array(n.z.object({name:n.z.string().min(1).describe('e.g. "test:web"'),command:n.z.string().min(1),description:n.z.string().min(1).describe("What this command verifies."),cwd:n.z.string().optional().describe("Relative to the project root (monorepo subdirs); omit for the root."),timeout:n.z.number().optional().describe("Seconds (default 60)."),environment:n.z.string().optional().describe('The environment it runs in, by name (environment_list). Omitted, it goes where you ran it (a bare box with no saved environment is refused, so name one). Name "Workspace" only when it truly needs the host.'),target:n.z.string().optional().describe("The id your setup instructions give for a target this command prints the number for.")})).optional().describe("register: the commands to register.")}),exports.ReportTestResultsSchema=n.z.object({status:n.z.enum(["passed","failed","error"]).describe("Overall result"),testRunId:n.z.string().optional().describe("The test run this verdict belongs to (given in your instructions). Strongly preferred: without it the latest run is guessed, which misattributes results when several testers run concurrently."),results:n.z.object({commands:n.z.array(n.z.object({name:n.z.string().describe("Command name"),status:n.z.enum(["passed","failed","skipped","error"]).describe("Command result"),output:n.z.string().optional().describe("Relevant output snippet"),diagnosis:n.z.string().optional().describe("Why it failed, if applicable")})).describe("Per-command results"),summary:n.z.string().describe("Brief overall summary"),acceptanceCriteria:n.z.array(n.z.object({criterion:n.z.string().describe("The acceptance criterion text"),status:n.z.enum(["verified","unverified","unclear"]),evidence:n.z.string().describe("How verified, or why not")})).optional().describe("AC verification results, if applicable"),faultClass:n.z.enum(["fail_code","fail_evidence","fail_environment","fail_process"]).optional().describe("On a FAILED verdict, WHY it failed so the gate routes to the right actor: 'fail_code' (the change is wrong), 'fail_evidence' (the run did not prove a criterion the coder could have proven: attach/adjust verify commands), or 'fail_environment' (a required tool/runtime is MISSING from the confined box, e.g. 'node: not found': the coder cannot fix this; the environment must be extended). Use 'fail_environment' ONLY when the evidence shows a command/runtime absent from the box, never for a genuine defect or a fixable evidence gap. 'fail_process' is for a test process whose OWN command names a file the repository does not have (a deleted script): nobody's code is wrong and extending the box cannot help; the process itself must be fixed or turned off."),missingCapabilities:n.z.array(n.z.string()).optional().describe("With faultClass 'fail_environment', the binaries/runtimes the box lacks (e.g. ['node']) so the environment can be extended to provide them.")}).describe("Structured test results")}).superRefine((e,t)=>{"fail_environment"!==e.results?.faultClass||e.results.missingCapabilities&&e.results.missingCapabilities.length>0||t.addIssue({code:n.z.ZodIssueCode.custom,path:["results","missingCapabilities"],message:"faultClass 'fail_environment' requires results.missingCapabilities: name the absent binaries/runtimes (the deterministic capability probe in your evidence lists them, e.g. ABSENT from the box: node). Without the names, the environment cannot be extended and the request strands."})})
5777
- const k=n.z.string().min(1,"every option needs its consequence (description)").max(200,"an option's description is its consequence in one line: 200 characters at most").describe("Its consequence in one line: what it gets and costs."),I=n.z.string().min(1).max(120,"because is one clause: 120 characters at most")
5778
- exports.OpeningBriefSectionSchema=n.z.object({id:n.z.string().min(1).describe('Unique within the brief ("date-format").'),question:n.z.string().min(1).describe("The choice, one plain question answerable without your session."),context:n.z.string().min(1).describe("What it shapes, citing the request and its sources as stated; where they answer it, recommend their answer."),options:n.z.array(n.z.object({id:n.z.string().min(1),label:n.z.string().min(1),description:k})).min(2).describe("At least two genuine alternatives."),default:n.z.string().min(1).describe("The option you proceed on now (shown recommended)."),because:I.describe("Why, in one clause."),criteria:n.z.array(n.z.string().min(1)).optional().describe("Keys of criteria whose wording this choice decides (worded for your default); another pick marks them for rewording.")}).superRefine((e,t)=>{e.options.some(t=>t.id===e.default)||t.addIssue({code:n.z.ZodIssueCode.custom,path:["default"],message:`default '${e.default}' names no option in this section (option ids: ${e.options.map(e=>e.id).join(", ")})`}),"testing-mode"===e.id&&t.addIssue({code:n.z.ZodIssueCode.custom,path:["id"],message:"section id 'testing-mode' is reserved: the server composes the testing section when the project's gate needs it -- remove it from your sections"})}),exports.SessionMessageOperationsSchema=n.z.object({operation:n.z.enum(["send","note","reply","list","get","offer-handoff","record-decision","brief","withdraw"]),milestone:n.z.boolean().optional().describe("note: a real boundary (it works, the approach changed, the goal is met); one quiet line in the user's stream, a few per request at most."),percent:n.z.number().min(0).max(100).optional().describe("note: how far along your work on this request is; it may go down."),withdrawReason:n.z.string().optional().describe("withdraw: why the answer is no longer needed."),type:n.z.enum(["question","report"]).optional().describe("Required for send."),toSessionId:n.z.string().optional().describe('A session id, or "parent". Omit for the user (a broadcast).'),questionType:n.z.enum(["free-form","alternatives"]).optional().describe("Required for a question."),questionContent:n.z.object({question:n.z.string().min(1).describe("As the user reads it; a criterion by its words, never its key."),context:n.z.preprocess(e=>null!==e&&"object"==typeof e?JSON.stringify(e):e,n.z.string().optional()).optional().describe("What the user needs to answer without your session: what you found and why it matters. No paths or identifiers; output they should judge goes in a fenced block, as printed."),options:n.z.array(n.z.object({id:n.z.string(),label:n.z.string(),description:k,recommended:n.z.boolean().optional().describe("Your advice, highlighted (what happens unanswered is defaultOption). Not with criteria. Never on an option that makes up what the user has not given (estimates, sample values, invented names): leave it visibly empty or marked unknown."),because:n.z.preprocess(i,I.optional()).describe("With recommended (required there): why, in one clause."),notePrompt:n.z.string().min(3).max(120).optional().describe('For an option only useful with the user\'s words ("I want changes"): the question its text field asks ("What should change?"); the pick arrives with what they typed.'),effect:n.z.enum(["choose","send-back","not-yet"]).optional().describe('"choose" (default): records the pick. "send-back": asks for a change; on a request awaiting sign-off the pick itself sends it back (no reopen). "not-yet": [user-input] criteria only; they stay owed.')})).optional().describe("Genuine alternatives, each complete in one tap; recommended first. When the user's way cannot work, include one reaching their goal another way."),allowMultiple:n.z.boolean().optional(),fields:n.z.array(n.z.object({id:n.z.string().min(1),label:n.z.string().min(1),placeholder:n.z.string().optional()})).min(1).optional().describe('free-form: one labelled input per value; answers arrive as "Label: value" lines. Never ask for passwords or keys: answers are on the record.'),defaultOption:n.z.string().optional().describe("What happens if nobody answers before expiry (option id, or text for free-form); the asker resumes. It happens without the user, so it is the SAFE option when options differ in risk (silent value changes, data loss, made-up data, anything hard to undo), even if you recommend another; the context says so."),onExpiry:n.z.enum(["assume-default","escalate"]).optional().describe('"assume-default" (default with a defaultOption) or "escalate": stays pending for the user (on Self-driving only priority "high" reaches them).'),steer:n.z.enum(["what","how"]).optional().describe('"what" shapes the product (spec, wording, UX, scope); "how" the process (testing, sequencing), mostly yours to decide, not ask.'),changeableLater:n.z.boolean().optional().describe("true when the answer can change later without loss (nothing sent, deleted or published on it).")}).superRefine((e,t)=>{(e.options??[]).forEach((e,r)=>{!0!==e.recommended||e.because||t.addIssue({code:n.z.ZodIssueCode.custom,path:["options",r,"because"],message:`option '${e.id}' is recommended: say why in one clause (because)`})})}).optional().describe("Required for a question. Before asking the user: when context answers it and a wrong guess is cheap to fix, proceed. Otherwise ask with a defaultOption unless only the user can answer. Under 'autonomous' the default returns at once; 'balanced' holds up to ten minutes, then continues; 'collaborative' holds briefly, then ends your turn to wait. One decision per question, related uncertainties bundled; several candidate next steps are one alternatives question. A question the user already decided returns their decision: proceed on it."),priority:n.z.enum(["low","normal","high"]).optional().describe('"high": blocked with real stakes; reaches the user at once. "low" with a defaultOption: under \'balanced\', batched to the next checkpoint without holding.'),expiresInHours:n.z.number().optional(),userSaid:n.z.string().min(8).max(600).optional().describe('question: when the user asked to be asked ("ask me first"), their words exactly (checked); it then reaches them at any Autonomy.'),replaces:n.z.array(n.z.string().regex(/^Q-[A-Za-z0-9]+-\d+$/)).max(10).optional().describe("question: your open questions on the request this supersedes (they close). With one open, pass this or keepsOpen."),keepsOpen:n.z.boolean().optional().describe("question: it asks something else; your open ones stay open."),forceAsk:n.z.boolean().optional().describe("question: re-ask what the decision record answers, only because circumstances changed (say what in context)."),status:n.z.enum(["success","partial","failure","blocked"]).optional().describe("report: how it ended. Omitted reads success, or blocked with blockedOn."),blockedOn:n.z.string().optional().describe('Required with status "blocked" on your request: "decision" (the user\'s open card on it, else a question to your parent), a card code ("Q-AB12CD34-001"), or a request id (a wait; you are told when it settles).'),criteria:n.z.array(n.z.string().min(1)).max(10).optional().describe('question: keys of the [user-input] criteria you ask for; only this counts as asking them. No default, no recommended option; the answer is their proof unless it is "not-yet". With a "not-yet" option you build on a placeholder meanwhile (Self-driving answers it at once); without one you wait at every Autonomy. Their check of finished work is asked on the end card, not here.'),attention:n.z.enum(["fyi","glance","act"]).optional().describe("'fyi' (no badge), 'glance', 'act'. Default from status: failure/blocked act, partial glance, success fyi."),reportKind:n.z.enum(["milestone","reply"]).optional().describe("'reply': answers the user's inbox message."),summary:n.z.string().optional().describe("Required for a report: outcome first, subject named first (it shows alone, often hours later), paths in details."),details:n.z.string().optional().describe("With blockedOn \"decision\", the question's context (maybe the user's card): plain words, no tool names; explain a refusal, never paste it."),ruleVerdicts:n.z.array(n.z.object({rule:n.z.string().min(1).max(80).describe("The guidance id, no brackets."),verdict:n.z.enum(["held","broken","not_applicable"]),note:n.z.string().max(300).optional().describe("broken: what and where (file:line).")})).max(40).optional().describe("report, Guidance reviewer: a verdict on every item you were given."),silent:n.z.boolean().optional().describe("Record without waking the coordinator (fan-out research)."),relatesTo:n.z.string().regex(/^[IQ]-[A-Za-z0-9]+-\d+$/,"relatesTo must be an instruction code (I-...) or question code (Q-...)").optional().describe("An instruction code (I-...); for record-decision, the question (Q-...) it resolves."),decision:n.z.string().optional().describe("record-decision (required): the one-line call."),why:n.z.string().optional().describe("record-decision: the reasoning."),context:n.z.string().optional().describe("record-decision: what the choice was about."),requestId:n.z.string().optional().describe("The request it is about, so it shows there (note: defaults to yours; brief: required); without it a report or decision is filed at the project."),area:n.z.string().optional().describe("record-decision: a work area the call is about (without requestId)."),sections:n.z.array(exports.OpeningBriefSectionSchema).min(1).optional().describe("brief (required): your real design choices."),messageCode:n.z.string().optional().describe("Required for reply, get and withdraw."),amount:n.z.number().positive().max(1e5).optional().describe("Dollars the user named, their words in quote: 'build' on a Plan ready card sets the plan's budget; 'allow' on a budget card allows that much more."),sectionAnswers:n.z.record(n.z.string(),n.z.string().nullable()).optional().describe("reply to an opening brief: { sectionId: optionId } for sections the user answered, changed or confirmed, with quote; null when one no longer applies; 'your-words' when no option says what they asked. Unnamed sections stay open; a change sends finished work back to rework."),quote:n.z.string().optional().describe("reply: the user's words this answer records, exactly (refused if they never wrote them); omit for your own decision. Options that are the user's own statement (\"I checked, it works\") only they can pick."),text:n.z.string().optional().describe("reply: a free-form answer. note (required): the note."),selectedOptions:n.z.array(n.z.string()).optional().describe("reply: the picked option ids."),notes:n.z.string().optional(),escalate:n.z.boolean().optional().describe("reply to a question to you that needs the user: a copy reaches them with your recommendation (notes); the asker gets their answer. Not for broadcasts."),list:n.z.object({sessionId:n.z.string().optional().describe("Defaults to your session."),messageType:n.z.enum(["question","report","instruction","all"]).default("all"),direction:n.z.enum(["incoming","outgoing","all"]).default("all"),status:n.z.enum(["pending","answered","expired","success","partial","failure","blocked","all"]).default("all"),readStatus:n.z.enum(["unread","read","acknowledged","all"]).default("all"),requestId:n.z.string().optional().describe("Only messages about this request."),limit:n.z.number().min(1).max(100).default(50),offset:n.z.number().min(0).default(0)}).optional(),offerHandoff:n.z.object({summary:n.z.string().describe("One sentence: what the plan builds."),requestIds:n.z.array(n.z.string()).describe("Requests created from the plan.")}).optional()}).refine(e=>"send"===e.operation?!!e.type:"note"===e.operation?"string"==typeof e.text&&e.text.trim().length>0:"reply"===e.operation?!!e.messageCode:"list"===e.operation||("get"===e.operation?!!e.messageCode:"offer-handoff"===e.operation||("record-decision"===e.operation?!!e.decision:"brief"===e.operation?!!e.requestId&&Array.isArray(e.sections)&&e.sections.length>0:"withdraw"===e.operation&&!!e.messageCode)),{message:"Invalid operation data: send requires type, note requires text, reply requires messageCode, get requires messageCode, record-decision requires decision, brief requires requestId and a non-empty sections array, withdraw requires messageCode"}),exports.CommitToViewedSessionSchema=n.z.object({message:n.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.")}),exports.DirectiveOperationsSchema=n.z.object({operation:n.z.enum(["set","list","search-decisions"]).describe("search-decisions = free-text search the project's decision + annotation record"),targetType:n.z.enum(["project","area","request","you"]).optional(),targetId:n.z.string().optional(),body:n.z.string().max(2e3).optional(),note:n.z.string().optional(),userSaid:n.z.string().optional(),revises:n.z.string().max(160).optional(),status:n.z.string().optional(),query:n.z.string().max(200).optional().describe("search-decisions: the search text, matched against recorded decisions (question + answer) and annotations (comment body + quoted text). Required for search-decisions."),limit:n.z.number().int().min(1).max(50).optional().describe("search-decisions: max matches per record type (default 10).")}),exports.McpConnectionsSchema=n.z.object({operation:n.z.enum(["list","propose"]).describe("list = the connections this project has; propose = register one, switched off, for the user to switch on."),name:n.z.string().optional().describe("propose: the connection name, lower case letters, digits and dashes. It becomes the tool prefix (name_tool)."),transport:n.z.enum(["repo","boxed","remote"]).optional().describe("propose: repo = a server in THIS repository, built from its Dockerfile and run in a confined box (the repository is mounted read-only at /work, /scratch is writable memory, the image ENTRYPOINT is what runs, rebuilt when its files change on main); boxed = a published npm package at an exact version, installed once and run in a box; remote = a hosted server reached by url."),dockerfile:n.z.string().optional().describe("propose repo: path of the Dockerfile inside the repository, e.g. mcp/server.Dockerfile."),context:n.z.string().optional().describe("propose repo: the docker build context directory inside the repository (default: the repository root)."),package:n.z.string().optional().describe("propose boxed: npm package with an exact version, e.g. @scope/server@1.2.3."),bin:n.z.string().optional().describe("propose boxed: the bin to run, the name under node_modules/.bin."),url:n.z.string().optional().describe("propose remote: the http(s) url."),environment:n.z.record(n.z.string()).optional().describe("propose: plain KEY=value configuration (headers for remote). Never put a secret here; name it in secretKeys instead."),secretKeys:n.z.array(n.z.string()).optional().describe("propose: names of environment variables (or headers) whose VALUES are secret. The user sets the values on the machine that runs the work; they never reach the database.")}),exports.AnswerQuestionSchema=n.z.object({messageCode:n.z.string().min(1).describe("The code in square brackets from <waiting_on_you>, e.g. Q-51209THD-005."),optionId:n.z.string().optional().describe("The id of the option the user picked, when the question has options."),text:n.z.string().optional().describe("The user's answer in their own words, cleaned up, when the question has no options or they said something the options do not cover.")})},19567(e,exports,t){exports.Server=exports.SSEServerTransport=exports.StdioServerTransport=void 0
5794
+ const g=o.z.string({required_error:"Required. A quick edit either touches up an earlier request's result or stands on its own: pass that request id (req######) or the word 'new'."}).refine(e=>"new"===e||/^req\d{6}$/.test(e),{message:"Pass a request id like req000031, or 'new'."}).describe("The request whose result this edit adjusts (the user pointed at it), or 'new': the same rule as create_request's follows.")
5795
+ exports.QuickWriteSchema=o.z.object({title:o.z.string().min(1,"Title is required"),description:o.z.string().min(1,"Description is required"),follows:g,path:o.z.string().optional(),documentId:u.optional(),content:o.z.union([o.z.string(),o.z.array(o.z.string())]),format:o.z.enum(["text","json"]).optional(),append:o.z.boolean().optional()}).transform(h).refine(p,{message:"path or documentId required"}),exports.QuickReplaceSchema=o.z.object({title:o.z.string().min(1,"Title is required"),description:o.z.string().min(1,"Description is required"),follows:g,operations:o.z.array(o.z.object({path:o.z.string().optional(),documentId:u.optional(),replacements:o.z.array(o.z.object({old_str:o.z.string().min(1),new_str:o.z.string(),match_mode:o.z.enum(["unique","all"]).optional()})).min(1),fuzzy_match:o.z.boolean().optional()}).transform(h).refine(p,{message:"path or documentId required"})).min(1),fuzzy_match:o.z.boolean().optional(),comment:o.z.string().min(1,"Comment describing the change is required")}),exports.MetaWorkflowListSchema=o.z.object({}),exports.MetaWorkflowGetSchema=o.z.object({workflowId:o.z.string().describe("Workflow ID to retrieve")}),exports.MetaWorkflowCreateSchema=o.z.object({name:o.z.string().min(1).describe("Unique name for the workflow"),shortName:o.z.string().min(1).max(10).describe("Short display name (required, max 10 chars)"),description:o.z.string().optional().describe("Description of what the workflow does"),testGate:o.z.enum(["off","auto","ask"]).optional().describe("Test gate: off (no test gate), auto (checks run automatically; a blocking command must pass, an advisory one may be skipped with a reason), ask (the user picks auto/interactive/skip at each completion)"),reviewGate:o.z.enum(["off","on"]).optional().describe("Review gate: off, or on (one reviewer checks each acceptance criterion, with the reviewers the kind assigns: guidance, model on engineering, any the workflow added)"),signoffGate:o.z.enum(["off","agent","you"]).optional().describe('Sign-off gate, as the workflow page names it: off; agent ("Delivery review": an agent asks whether the delivery is what was asked for, then merges or brings it to the user); you ("You sign off": the user approves before merge)'),approvalMode:o.z.enum(["none","require-approval","agent-check"]).optional().describe("Pre-work approval: none (default), require-approval (the user approves each request), or agent-check (an independent intake reviewer rules on agent-created requests before work starts)"),interactionPosture:o.z.enum(["autonomous","balanced","collaborative"]).optional().describe("Interaction posture (question-gate dial): autonomous (defaulted questions are self-answered -- proceed + FYI report), balanced (default; questions post normally, non-blocking when defaulted), collaborative (always ask the human)")}),exports.MetaWorkflowUpdateSchema=o.z.object({workflowId:o.z.string().describe("Workflow ID to update"),name:o.z.string().min(1).optional().describe("New name"),shortName:o.z.string().max(10).optional().describe("New short name (max 10 chars)"),description:o.z.string().optional().describe("New description"),testGate:o.z.enum(["off","auto","ask"]).optional().describe("Test gate: off (no test gate), auto (checks run automatically; a blocking command must pass, an advisory one may be skipped with a reason), ask (the user picks auto/interactive/skip at each completion)"),reviewGate:o.z.enum(["off","on"]).optional().describe("Review gate: off, or on (one reviewer checks each acceptance criterion, with the reviewers the kind assigns: guidance, model on engineering, any the workflow added)"),signoffGate:o.z.enum(["off","agent","you"]).optional().describe('Sign-off gate, as the workflow page names it: off; agent ("Delivery review": an agent asks whether the delivery is what was asked for, then merges or brings it to the user); you ("You sign off": the user approves before merge)'),approvalMode:o.z.enum(["none","require-approval","agent-check"]).optional().describe("Pre-work approval: none (default), require-approval (the user approves each request), or agent-check (an independent intake reviewer rules on agent-created requests before work starts)"),interactionPosture:o.z.enum(["autonomous","balanced","collaborative"]).optional().describe("Interaction posture (question-gate dial): autonomous (defaulted questions are self-answered -- proceed + FYI report), balanced (default; questions post normally, non-blocking when defaulted), collaborative (always ask the human)")}),exports.MetaRecipeListSchema=o.z.object({}),exports.MetaRecipeGetSchema=o.z.object({recipeId:o.z.string().describe("Recipe ID to retrieve")}),exports.MetaRecipeCreateSchema=o.z.object({name:o.z.string().min(1).describe("Unique name for the recipe"),description:o.z.string().optional().describe("Description of what the recipe does"),documentation:o.z.string().optional().describe("Detailed documentation")}),exports.MetaRecipeAddHookSchema=o.z.object({recipeId:o.z.string().describe("Recipe ID to add the hook to"),hookId:o.z.string().describe("Hook template ID to add"),position:o.z.number().int().min(0).optional().describe("Position in the recipe (0-based, appended if omitted)")}),exports.MetaRecipeRemoveHookSchema=o.z.object({recipeId:o.z.string().describe("Recipe ID to remove the hook from"),hookId:o.z.string().describe("Hook template ID to remove")}),exports.MetaHookListSchema=o.z.object({}),exports.MetaHookCreateSchema=o.z.object({name:o.z.string().min(1).describe("Unique name for the hook"),description:o.z.string().optional().describe("Description of what the hook does"),eventType:o.z.string().describe("Event type that triggers this hook (e.g., session_idle, request_completed, custom:plan_ready)"),category:o.z.enum(["alchemy","session","message","editing","reading","file_management","documents","history","tool"]).default("session").describe("Hook category"),agent:o.z.string().describe("Agent template to execute when hook fires"),promptTemplate:o.z.string().describe("Prompt template with {{variable}} substitution"),condition:o.z.record(o.z.any()).optional().describe("Condition object for filtering when hook fires"),timing:o.z.enum(["before","after"]).default("after").describe("When to fire relative to the event"),action:o.z.enum(["spawn_agent","inject_prompt"]).optional().describe("What the hook does: spawn_agent (default) starts a new session of `agent` with the prompt; inject_prompt sends the prompt into an existing session"),target:o.z.enum(["independent_session","child_session","same_session","parent_session","ancestor_chain"]).optional().describe("Where the prompt goes. With spawn_agent: independent_session (default, no parent) or child_session (under the session that fired the event). With inject_prompt: same_session (default, the session that fired the event), parent_session, or ancestor_chain"),maxIterations:o.z.number().int().min(1).optional().describe("Maximum times the hook fires for one session, counted from its firing record. Set it on every session_idle hook that sends into the same session. A session a hook started never triggers that hook again, whatever this says"),emitEvent:o.z.string().optional().describe("Custom event to emit on completion"),emitEventOnCondition:o.z.union([o.z.object({condition:o.z.object({field:o.z.string(),operator:o.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:o.z.string()}),event:o.z.string()}),o.z.array(o.z.object({condition:o.z.object({field:o.z.string(),operator:o.z.enum(["contains","not_contains","equals","not_equals","matches","not_matches"]),value:o.z.string()}),event:o.z.string()}))]).optional().describe("Conditional event emission based on output")}),exports.MetaWorkflowAddRecipeSchema=o.z.object({workflowId:o.z.string().describe("Workflow ID to add the recipe to"),recipeId:o.z.string().describe("Recipe ID to add"),position:o.z.number().int().min(0).optional().describe("Position in the workflow (0-based, appended if omitted)")}),exports.MetaWorkflowRemoveRecipeSchema=o.z.object({workflowId:o.z.string().describe("Workflow ID to remove the recipe from"),recipeId:o.z.string().describe("Recipe ID to remove")}),exports.MetaAgentListSchema=o.z.object({}),exports.MetaOperationsSchema=o.z.object({operation:o.z.enum(["workflow-list","workflow-get","workflow-create","workflow-update","recipe-list","recipe-get","recipe-create","recipe-add-hook","recipe-remove-hook","hook-list","hook-create","workflow-add-recipe","workflow-remove-recipe","agent-list"]).describe("Which meta operation to perform; the other params apply per operation (see tool description)"),...exports.MetaWorkflowGetSchema.partial().shape,...exports.MetaWorkflowCreateSchema.partial().shape,...exports.MetaWorkflowUpdateSchema.partial().shape,...exports.MetaRecipeGetSchema.partial().shape,...exports.MetaRecipeCreateSchema.partial().shape,...exports.MetaRecipeAddHookSchema.partial().shape,...exports.MetaRecipeRemoveHookSchema.partial().shape,...exports.MetaHookCreateSchema.partial().shape,...exports.MetaWorkflowAddRecipeSchema.partial().shape,...exports.MetaWorkflowRemoveRecipeSchema.partial().shape}),exports.TestingProcessListSchema=o.z.object({}),exports.TestingProcessGetSchema=o.z.object({processId:o.z.string().describe("Test process ID to retrieve")})
5796
+ const y=o.z.object({name:o.z.string().min(1).describe('Command name (e.g., "Build", "Unit Tests")'),command:o.z.string().min(1).describe('Shell command to run (e.g., "npm test")'),required:o.z.boolean().default(!0).describe("If true, failure blocks the request (default: true)"),timeout:o.z.number().int().min(10).max(3600).default(300).describe("Max execution time in seconds (default: 300)")})
5797
+ exports.TestingProcessCreateSchema=o.z.object({name:o.z.string().min(1).describe("Name for the test process"),environmentId:o.z.string().optional().describe("ID of the environment (confined runtime) this process runs in. Get it from environment_list or environment_setup."),description:o.z.string().optional().describe("Description of what this process verifies"),scope:o.z.string().optional().describe('LABEL ONLY -- a monorepo path prefix recorded for display (e.g. "packages/api/"). It does NOT affect when the process runs; use pathGlobs for that.'),pathGlobs:o.z.array(o.z.string()).optional().describe('Which changes this process runs on: glob patterns matched against the changed files (e.g. ["sites/**"], ["src/**", "*.md"]). THIS is what limits when the process runs. Omit it and the process runs on EVERY change, which is the right choice only for a check that is cheap and universal.'),areas:o.z.array(o.z.string()).optional().describe('Work-area labels this process covers (e.g. ["graphics/opengl"]). An alternative to pathGlobs for work that is not file-shaped; a process applies if EITHER dimension matches.'),setup:o.z.array(o.z.string()).optional().describe("Commands that prepare the tree for the tests (install the package itself, generate files the tests import), e.g. [\"python -m pip install --no-deps -e .\"]. They run in its box before its commands on every run, and also before a request's criteria checks, which run in a clean checkout of the commit where `commands` do not run: a preparation step put in `commands` is missing there and those checks fail. If one fails, the run fails as the environment's fault and the commands do not run."),commands:o.z.array(y).min(1).describe("Test commands to execute in order"),verifyAcceptanceCriteria:o.z.boolean().optional().describe("When true, auto-tester verifies request acceptance criteria after running commands"),fingerprint:o.z.array(o.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:o.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."),runtimeKept:o.z.string().optional().describe('Only when the user chose to run the check on a runtime other than the lowest one the project declares: that runtime and version, e.g. "python 3.12". Without it, a check whose environment runs another version than the declared minimum is not registered.'),leavesOut:o.z.array(o.z.object({what:o.z.string().describe('The left-out part in plain words, e.g. "the Valkey backend tests"'),paths:o.z.array(o.z.string()).min(1).describe('Globs for the code that part checks, so a change there goes unchecked by this check: for a backend\'s tests, that backend (e.g. ["aiocache/backends/valkey.py"]); for browser or end-to-end tests, the app source they drive (e.g. ["src/**"]). Not only the left-out test files.'),command:o.z.string().min(1).max(300).optional().describe('The command that runs that part, e.g. "pnpm test:e2e": a request whose criterion runs it is not told this part was left out.')})).optional().describe('What this check deliberately does not run and no other check runs (the suites the card lists as "not run on every change"), each with the code it checks. A change to that code is reported to the user as not checked by this check, unless the request ran that part itself.')}),exports.TestingProcessDeleteSchema=o.z.object({processId:o.z.string().describe("Test process ID to delete")}),exports.EnvironmentListSchema=o.z.object({}),exports.ResultsSchema=o.z.object({operation:o.z.enum(["record","fetch","pin","list","read"]),path:o.z.string().optional().describe("record: the file, inside the project (not /tmp); your worktree first, then the main project. Bulk that must not reach a commit can be written by a command under `.alchemy_lab/scratch/` (gitignored)."),name:o.z.string().optional().describe("record: the name a person uses for it (defaults to the filename). list: show every version recorded under this name, newest first."),summary:o.z.record(o.z.any()).optional().describe('record (required): the small facts a reader wants instead of the bytes, e.g. {maxStress: 412, unit: "MPa", converged: true}.'),box:o.z.string().optional().describe("An experiment handle (exp_...). fetch: put the bytes inside that sealed box under its /scratch (a box cannot see the host scratch; omit for host work, which is faster). record: the result lives inside that box and is streamed out and stored in one step (a box cannot write your worktree)."),mediaType:o.z.string().optional().describe("record: MIME type, when you know it."),inputs:o.z.array(o.z.string()).optional().describe("record: addresses of the results this one was made from (provenance)."),note:o.z.string().optional().describe("record: one line on how it was produced."),address:o.z.string().optional().describe("pin / read / fetch: the full 64-character address the record returned (a unique prefix works too)."),at:o.z.string().optional().describe("pin: the pointer path in your worktree (.result.json is added). fetch: where the bytes land, under AlchemyLab's scratch folder for the project on the host (the answer gives the full path) or the box's `/scratch`. Defaults to results/<name>."),comment:o.z.string().optional().describe("pin: the commit comment for the pointer file."),offset:o.z.number().optional().describe("read: line to start at (default 0)."),limit:o.z.number().optional().describe("read: how many lines (default 200). list: how many results (default 25)."),find:o.z.string().optional().describe("read: return only lines containing this text, instead of a range.")}),exports.ResultInspectSchema=o.z.object({operation:o.z.enum(["list","read"]),name:o.z.string().optional().describe("list: show every version recorded under this name, newest first."),address:o.z.string().optional().describe("read: the full 64-character address of the result, a check run's id (tr_...) or a command run's record id (trec...), to read what its commands printed."),offset:o.z.number().optional().describe("read: line to start at (default 0)."),limit:o.z.number().optional().describe("read: how many lines (default 200). list: how many results (default 25)."),find:o.z.string().optional().describe("read: return only lines containing this text, instead of a range.")}),exports.ExperimentStartSchema=o.z.object({env:o.z.string().optional().describe("Environment by name (from environment_list), one whose image has the toolchain you need."),environmentId:o.z.string().optional().describe("Environment by id (alternative to `env`). The primary env is used if neither is given."),size:o.z.enum(["light","standard","heavy"]).optional().describe("light: 2 cores (lint, a typecheck, one test file). standard (default): a share of the free cores (a suite, a build). heavy: every free core but 2 and 6 GB of memory (2 GB otherwise, unless the environment sets its own), for work that uses them (a CFD solve, meshing, a large parallel build, a model that runs out of memory). A size you do not hold opens another box."),confirmWorkspace:o.z.boolean().optional().describe('Required for env "workspace" (the live host): the task genuinely needs the real machine. Building or trying out the app does not.')}),exports.ExperimentStopSchema=o.z.object({handle:o.z.string().describe("The experiment handle to tear down.")}),exports.ExperimentListSchema=o.z.object({}),exports.ReadSiteSchema=o.z.object({url:o.z.string()}),exports.DriveSiteSchema=o.z.object({url:o.z.string().describe("The running product, e.g. the environment's published URL or http://localhost:5173."),steps:o.z.array(o.z.object({action:o.z.enum(["click","clickat","type","press","move","scroll","wait","media"]).describe('click (selector) \xb7 clickat (x,y) \xb7 type (selector + text) \xb7 press (key) \xb7 move (x,y) \xb7 scroll (dy) \xb7 wait (ms, max 5000) \xb7 media ("print" shows the printout, "screen" switches back)'),selector:o.z.string().optional().describe('Playwright selector, e.g. "text=Build" or "#start".'),text:o.z.string().optional(),key:o.z.string().optional().describe('e.g. "Enter"'),x:o.z.number().optional(),y:o.z.number().optional(),dy:o.z.number().optional(),ms:o.z.number().optional(),media:o.z.enum(["print","screen"]).optional()})).min(1).max(20),shots:o.z.enum(["each","final"]).optional().describe('"each" screenshots every step; default the final state only.'),session:o.z.string().optional().describe("Keeps the page open: the next call with this name continues where this one stopped. Idle sessions close after 10 minutes."),close:o.z.boolean().optional().describe("Close the named session after this call."),width:o.z.number().optional().describe("Viewport width for a new session (default 1280; 390 is a phone).")}),exports.CaptureSiteSchema=o.z.object({url:o.z.string(),fullPage:o.z.boolean().optional().describe("The whole scrollable page instead of the viewport."),width:o.z.number().optional().describe("Viewport width (default 1280; 390 is a phone).")}),exports.PreviewSiteSchema=o.z.object({dir:o.z.string().optional().describe('Repo-relative, e.g. "dist" or "." for the top of the repository. Not needed with stop.'),requestId:o.z.string().regex(/^req\d{6}$/).optional().describe("Serve from this unmerged request's working copy instead of main."),name:o.z.string().optional().describe("Preview handle (default: a slug of dir); reusing one replaces that preview. With stop: the preview to stop."),stop:o.z.boolean().optional().describe("Stop a running preview instead of serving one: the one named, or the only one running."),label:o.z.string().optional()}),exports.FetchAssetSchema=o.z.object({url:o.z.string().describe("The http(s) URL of the image or font to download."),destPath:o.z.string().describe('Where to write it, repo-relative (e.g. "sites/acme/assets/hero.jpg"). Must stay inside the working tree; parent directories are created.')}),exports.RequestVisualFeedbackSchema=o.z.object({box:o.z.string().optional().describe("The experiment handle (from experiment_start, on a screenshot-capable env) to render in / read from. The box must stay held until this returns."),route:o.z.string().optional().describe('With `box`: the route I render + screenshot FOR YOU (e.g. "/" or "/settings"). I serve `serveDir` and screenshot it -- you do NOT hand-roll serve/screenshot. This is the easiest path.'),script:o.z.string().optional().describe('With `box`, for FULL control: a Playwright snippet (the body of `async (page, baseUrl) => { ... }`). I serve the app, launch headless Chromium, and run your script -- navigate (page.goto(baseUrl + "/x")), click, fill, scroll, waitForSelector, etc. -- then screenshot the final page state. Reliable: you write only the interaction, no serve/launch/flags. Use this to reach a state that needs interaction (open a menu, log in, submit a form).'),fullPage:o.z.boolean().optional().describe("Capture the entire scrollable page instead of just the viewport."),serveDir:o.z.string().optional().describe("With `box`+`route`: the static dir to serve (default /work). For a built app, build first via run(), then point this at the build output (e.g. /work/dist)."),path:o.z.string().optional().describe("Alternative to route: a screenshot you ALREADY wrote inside the box (e.g. /tmp/shot.png); I read it out."),assetFilename:o.z.string().optional().describe("Alternative to box: the filename of an already-uploaded screenshot asset to annotate."),prompt:o.z.string().optional().describe("What you want the human to look at or mark up (shown with the request)."),timeoutMs:o.z.number().optional().describe("How long to wait for the human, in ms (default ~10 min).")}),exports.AskUserVisualSchema=o.z.object({question:o.z.string().describe('The question for the USER about the marked region (e.g. "Should this button use the primary color?").'),imagePath:o.z.string().optional().describe("Repo-relative path to an image you already produced (png/jpg/gif/webp), e.g. a screenshot you wrote. Provide this OR previewName."),previewName:o.z.string().optional().describe("Name of a registered live preview (a `live:` ref); I freeze it into a snapshot image for you. Provide this OR imagePath."),box:o.z.string().optional().describe('The region the question is about: "x,y,w,h" in normalized 0..1 image coordinates, origin top-left (e.g. "0.62,0.08,0.3,0.12"). Omit to ask about the whole image.'),options:o.z.array(o.z.string()).optional().describe("Optional answer choices (labels). Omit for a free-text answer."),context:o.z.string().optional().describe("Extra context shown with the question in the inbox (why you are asking, what you will do with the answer)."),priority:o.z.enum(["low","normal","high"]).optional().describe('Question priority; "high" always reaches the user regardless of autonomy dial.')}),exports.EnvironmentGetSchema=o.z.object({environmentId:o.z.string().describe("Environment ID to retrieve")}),exports.EnvironmentProvisionSchema=o.z.object({environmentId:o.z.string(),why:o.z.string().optional().describe("Why provision now (shown on the approval).")}),exports.EnvironmentTeardownSchema=o.z.object({environmentId:o.z.string()}),exports.EnvironmentStatusSchema=o.z.object({environmentId:o.z.string()}),exports.EnvironmentVerifyStackSchema=o.z.object({environmentId:o.z.string()})
5798
+ const w=o.z.object({image:o.z.string().optional().describe("Container image carrying the project toolchain/deps, e.g. node:20-alpine, python:3.12-slim, golang:1.22, ruby:3.3"),install:o.z.string().optional().describe("Deps install command -- Node-only sugar that populates a /work/node_modules cache volume, run with registry egress before the confined gate, e.g. npm ci. Non-Node runtimes use `artifacts` instead (a cache volume + prepare command: .venv/uv sync, cargo, go, vendor/bundle). Omit if the project has no deps."),composeFile:o.z.string().optional().describe("Path to the project docker-compose file for its services. Omit if no services."),shellInit:o.z.string().optional().describe("Shell preamble run before EVERY command in the box, e.g. '. /usr/lib/openfoam/openfoam2312/etc/bashrc'. REQUIRED for a toolchain that publishes itself through a script rather than the image PATH (OpenFOAM etc/bashrc, oneAPI setvars.sh, conda activate, ROS setup.bash): `docker exec` runs no ENTRYPOINT and reads no login profile, so without this every command gets a bare PATH. Put the preamble HERE, never inside the smoke command -- a smoke command carrying its own preamble proves the preamble and not the environment, and the next agent gets nothing."),connEnv:o.z.record(o.z.string()).optional().describe("Connection env injected into the gate (e.g. DATABASE_URL) using SERVICE NAMES + internal ports, never localhost/host ports."),seed:o.z.array(o.z.string()).optional().describe("Optional commands run after services are up (e.g. migrations)."),artifacts:o.z.array(o.z.object({path:o.z.string().describe("Mount target for the writable, populated volume: relative to /work for a dependency folder the project's toolchain looks for there (node_modules, .venv, vendor/bundle), or absolute (e.g. /cache/cargo). Tools you install (apt/apk packages, binaries) go at an absolute path outside /work, such as /tools: /work is the project's folder, and its test runners see anything in it."),prepare:o.z.string().optional().describe("Command that populates it -- the one phase with registry egress (e.g. npm ci, uv sync, cargo fetch). Omit for a writable empty volume."),manifests:o.z.array(o.z.string()).optional().describe("Lockfiles (relative to /work) whose content hash keys the cache; list them so the volume is reused across runs and only rebuilt when deps change (e.g. uv.lock, Cargo.lock). Omit => rebuilt every run."),env:o.z.record(o.z.string()).optional().describe('Env applied during prepare AND every run, e.g. { CARGO_HOME: "/cache/cargo" } for caches outside /work.')})).optional().describe("Per-runtime build/dependency artifacts: writable volumes populated by a prepare command, generalizing `install` beyond node_modules. Use for Python (.venv), Rust (target + $CARGO_HOME), Go, Ruby (vendor/bundle), etc. `install` is sugar for a single node_modules artifact; for any non-Node runtime use artifacts (install would write to node_modules, the wrong place)."),confinement:o.z.enum(["confined","egress-allowlist","privileged","unsafe","host","pure-host"]).optional().describe("Confinement level. Default 'confined' (fully sealed Docker; add egressAllowlist hosts to open exactly those -- stored as 'egress-allowlist'). privileged/unsafe relax the container. 'host' runs on the host machine (no Docker) inside an OS sandbox (Seatbelt/bubblewrap) for toolchains Docker can't run. 'pure-host' is the built-in workspace env (the live worktree) -- do not create new envs with it. Merge gating is independent (the Sign-off setting)."),commandGate:o.z.array(o.z.enum(["policy","agent","human"])).optional().describe("Gates an experiment command passes before it runs, in escalation order policy -> agent -> human. Empty = run freely; escalating past the last gate blocks (fail closed). policy = deterministic allowlist/deny-floor; agent = isolated LLM judge (allow or escalate only); human = ask. Registered commands are pre-approved. Defaults by level ([] for confined/egress-allowlist, ['human'] for privileged/unsafe)."),worktreeTarget:o.z.enum(["ephemeral","live"]).optional().describe("Worktree the env runs against: 'ephemeral' (a disposable copy at HEAD, default) or 'live' (the project's live working dir, read-write). The built-in workspace env is 'live'."),egressAllowlist:o.z.array(o.z.string()).optional().describe("Hosts the box may reach at the 'egress-allowlist' level (exact name or subdomain, e.g. registry.npmjs.org). Ignored at other levels."),addCaps:o.z.array(o.z.string()).optional().describe("Linux capabilities to add at the 'privileged' level (on top of cap-drop ALL), e.g. SYS_PTRACE for debuggers, IPC_LOCK for memlock. Ignored at other levels."),sysctls:o.z.record(o.z.string()).optional().describe("Namespaced sysctls to set at the 'privileged' level, e.g. net.ipv4.ip_local_port_range. Host-wide sysctls (vm.max_map_count) are NOT settable per-container."),runAsRoot:o.z.boolean().optional().describe("Run the box as root (privileged / unsafe levels). Needed for some caps + the docker socket."),dockerSocket:o.z.boolean().optional().describe("Mount the host docker socket for testcontainers-style tests. WARNING: full host control over the docker daemon. Only honored at the 'unsafe' level."),persistentVolumes:o.z.array(o.z.object({name:o.z.string(),target:o.z.string(),service:o.z.string().optional()})).optional().describe("Data volumes that survive between runs (keyed to this environment; off by default since experiments are ephemeral). Set service to mount into a compose service (e.g. a DB data dir), or omit it to mount into the box (e.g. a SQLite dir)."),resources:o.z.object({memory:o.z.string().optional().describe("Memory cap for this environment's boxes and its checks' boxes, e.g. '4g' (default 2g; 6g at size heavy). Set it when the test suite or build needs more."),cpus:o.z.number().optional().describe("A fixed CPU count. Usually leave it unset and set size instead."),size:o.z.enum(["light","standard","heavy"]).optional().describe("What this environment's boxes and checks are for, which sets their cores from what is free: light (2 cores: lint, small checks), standard (the default: a share of the free cores, for test suites and builds), heavy (every free core but 2: CFD or FEM solves, meshing, large parallel builds). An agent can ask for another size per box."),pidsLimit:o.z.number().optional().describe("Max processes (default 512)."),scratchMb:o.z.number().optional().describe("Size in MB of an in-memory /scratch, used only when the image cannot take the disk-backed one (default 512). /scratch is normally on disk and needs no size."),shmMb:o.z.number().optional().describe("/dev/shm size in MB -- bump for headless browsers (Chrome crashes on the 64m default).")}).optional().describe("Per-environment resource caps that override the confined defaults.")}),b=r(w),v='Start from a built-in preset; anything in config overrides it. "office": python-docx, openpyxl, python-pptx, pandoc, LibreOffice and segno/zbarimg (QR codes) in a sealed box, with `render-pdf FILE` to turn Word, Excel, PowerPoint, Markdown or HTML into PDF. Its image is built locally on first use (a few minutes). Pass the same preset (and config) to environment_verify and environment_create.',k="Save without a passing environment_verify, only for a config that cannot be verified from here (it needs credentials, external services or hardware the confined verifier lacks). Requires skipVerifyReason; the skip is logged."
5799
+ exports.EnvironmentCreateSchema=o.z.object({name:o.z.string().min(1).describe("Name for the environment, e.g. node + postgres"),description:o.z.string().optional().describe("What this environment provides"),scope:o.z.string().optional().describe("Subproject path prefix for monorepos (e.g. packages/api/). Omit for the whole repo."),preset:o.z.enum(["office"]).optional().describe(v),config:b.optional().describe("The exact config (after the preset) that passed environment_verify in this session, unless skipVerify; its fields are described on environment_verify. Optional with a preset."),isPrimary:o.z.boolean().optional().describe("Make this the project primary environment (default for new test processes). The first environment is primary automatically."),skipVerify:o.z.boolean().optional().describe(k),skipVerifyReason:o.z.string().optional().describe("Why this config cannot be verified (required with skipVerify: true; recorded in the log).")}),exports.EnvironmentUpdateSchema=o.z.object({environmentId:o.z.string(),name:o.z.string().min(1).optional(),description:o.z.string().optional(),scope:o.z.string().optional(),config:b.optional().describe("Replaces the config wholesale: the exact config that passed environment_verify in this session, unless skipVerify (fields described on environment_verify). Metadata-only updates need no verify."),isPrimary:o.z.boolean().optional().describe("Make this the project primary environment"),skipVerify:o.z.boolean().optional().describe(k),skipVerifyReason:o.z.string().optional().describe("Why this config cannot be verified (required with skipVerify: true; recorded in the log).")}),exports.EnvironmentDeleteSchema=o.z.object({environmentId:o.z.string().describe("Environment ID to delete")}),exports.EnvironmentVerifySchema=o.z.object({preset:o.z.enum(["office"]).optional().describe(v),config:w.optional().describe("The proposed environment config to verify (image, install, services, connection). Optional with a preset."),smoke:o.z.string().optional().describe("Optional smoke command run confined after the environment is up (default: true). Use a connection probe to confirm services are reachable.")}),exports.EnvironmentSetupSchema=o.z.object({name:o.z.string().max(60).optional().describe("A few words naming what you need (e.g. 'Node 20 for syntax checks')."),context:o.z.string().optional().describe("What you need and why, for the setup architect (e.g. 'Node 20 to run node --check on standalone .js files; no deps').")}),exports.SetupFinishSchema=o.z.object({outcome:o.z.enum(["ready","declined","could_not_finish","no_code","not_yet"]).describe("How the run ended. 'ready' needs something saved in this run."),summary:o.z.string().min(1).describe("What was set up (names and ids), and an answer to every ask the run carries: done, or not done and why. Plain words; it reaches the waiting workers and the user."),startsAfter:o.z.string().regex(/^req\d{6}$/).optional().describe("With 'not_yet': the request still writing what this setup registers.")}),exports.TestingProcessUpdateSchema=o.z.object({processId:o.z.string(),environmentId:o.z.string().optional(),name:o.z.string().min(1).optional(),description:o.z.string().optional(),scope:o.z.string().optional().describe("A display label only; pathGlobs decides when the process runs."),pathGlobs:o.z.array(o.z.string()).optional().describe('Globs matched against changed files (e.g. ["src/**", "*.md"]): the changes this process runs on. Replaces the list; [] means every change.'),areas:o.z.array(o.z.string()).optional().describe("Work-area labels this process covers; it applies when pathGlobs or areas match."),isActive:o.z.boolean().optional(),setup:o.z.array(o.z.string()).optional().describe("Replaces the setup commands (run in the check's box before its commands, and before the criteria checks in their clean checkout)."),commands:o.z.array(y).optional().describe("Replaces the test commands."),verifyAcceptanceCriteria:o.z.boolean().optional().describe("The auto-tester also verifies the request's acceptance criteria."),fingerprint:o.z.array(o.z.string()).optional().describe("Files whose content invalidates setup."),leavesOut:o.z.array(o.z.object({what:o.z.string().describe('The left-out part in plain words, e.g. "the Valkey backend tests"'),paths:o.z.array(o.z.string()).min(1).describe("Globs for the code that part checks (for end-to-end tests, the app source they drive), not only its test files."),command:o.z.string().min(1).max(300).optional().describe('The command that runs that part, e.g. "pnpm test:e2e".')})).optional().describe("Replaces what this check deliberately does not run, with the code each part checks; [] clears it."),poolSize:o.z.number().int().min(1).max(8).optional().describe("Warm test worktrees in the pool."),runtimeKept:o.z.string().optional().describe('With environmentId: only when the user chose a runtime other than the lowest one the project declares, e.g. "python 3.12".')}),exports.TestsSchema=o.z.object({operation:o.z.enum(["list","setup","run","switch-off","switch-on"]),process:o.z.string().optional().describe("run, switch-off, switch-on: one test process by name or id (run: omit for all active ones)."),userSaid:o.z.string().max(600).optional().describe("switch-off / switch-on: the user's words asking for it, copied exactly."),name:o.z.string().optional().describe("run: one test command by name; omit for all required commands."),ask:o.z.string().max(1500).optional().describe("setup, required outside a request: what the user asked the check to run, in their words; the setup architect registers exactly that.")}),exports.ExecuteTestCommandSchema=o.z.object({processId:o.z.string().describe("Test process ID containing the command"),commandName:o.z.string().describe('Name of the test command to run, or "setup" to run all setup commands in sequence')}),exports.RunSchema=o.z.object({command:o.z.string().optional().describe("A shell command, run in the box (pass box or env)."),name:o.z.string().optional().describe("A saved command by name, instead of command."),box:o.z.string().optional().describe("An experiment handle from experiment_start."),env:o.z.string().optional().describe("Instead of box: an environment by name; its box is started (or your open one reused) and the result gives the handle."),size:o.z.enum(["light","standard","heavy"]).optional().describe("With env: the box size (see experiment_start)."),args:o.z.string().optional(),grep:o.z.string().optional().describe("Filter output through grep -i with this pattern."),timeout:o.z.number().optional().describe("Seconds."),why:o.z.string().optional().describe("One short sentence, shown on the approval card when the command needs the user's approval."),cwd:o.z.string().optional().describe('A subdirectory for an ad-hoc command (e.g. "apps/web"); a command starting with `cd` is refused in favour of this.')}),exports.CommandsSchema=o.z.object({operation:o.z.enum(["run","list","remove","register","setup"]).default("run").describe('list, setup, register or remove ("run" is the run tool\'s job).'),name:o.z.string().optional().describe("remove: the command name."),args:o.z.string().optional(),grep:o.z.string().optional(),command:o.z.string().optional(),timeout:o.z.number().optional(),cwd:o.z.string().optional(),context:o.z.string().optional().describe("setup: the command wanted, where it runs and what it is for."),commands:o.z.array(o.z.object({name:o.z.string().min(1).describe('e.g. "test:web"'),command:o.z.string().min(1),description:o.z.string().min(1).describe("What this command verifies."),cwd:o.z.string().optional().describe("Relative to the project root (monorepo subdirs); omit for the root."),timeout:o.z.number().optional().describe("Seconds (default 60)."),environment:o.z.string().optional().describe('The environment it runs in, by name (environment_list). Omitted, it goes where you ran it (a bare box with no saved environment is refused, so name one). Name "Workspace" only when it truly needs the host.'),target:o.z.string().optional().describe("The id your setup instructions give for a target this command prints the number for.")})).optional().describe("register: the commands to register.")}),exports.ReportTestResultsSchema=o.z.object({status:o.z.enum(["passed","failed","error"]).describe("Overall result"),testRunId:o.z.string().optional().describe("The test run this verdict belongs to (given in your instructions). Strongly preferred: without it the latest run is guessed, which misattributes results when several testers run concurrently."),results:o.z.object({commands:o.z.array(o.z.object({name:o.z.string().describe("Command name"),status:o.z.enum(["passed","failed","skipped","error"]).describe("Command result"),output:o.z.string().optional().describe("Relevant output snippet"),diagnosis:o.z.string().optional().describe("Why it failed, if applicable")})).describe("Per-command results"),summary:o.z.string().describe("Brief overall summary"),acceptanceCriteria:o.z.array(o.z.object({criterion:o.z.string().describe("The acceptance criterion text"),status:o.z.enum(["verified","unverified","unclear"]),evidence:o.z.string().describe("How verified, or why not")})).optional().describe("AC verification results, if applicable"),faultClass:o.z.enum(["fail_code","fail_evidence","fail_environment","fail_process"]).optional().describe("On a FAILED verdict, WHY it failed so the gate routes to the right actor: 'fail_code' (the change is wrong), 'fail_evidence' (the run did not prove a criterion the coder could have proven: attach/adjust verify commands), or 'fail_environment' (a required tool/runtime is MISSING from the confined box, e.g. 'node: not found': the coder cannot fix this; the environment must be extended). Use 'fail_environment' ONLY when the evidence shows a command/runtime absent from the box, never for a genuine defect or a fixable evidence gap. 'fail_process' is for a test process whose OWN command names a file the repository does not have (a deleted script): nobody's code is wrong and extending the box cannot help; the process itself must be fixed or turned off."),missingCapabilities:o.z.array(o.z.string()).optional().describe("With faultClass 'fail_environment', the binaries/runtimes the box lacks (e.g. ['node']) so the environment can be extended to provide them.")}).describe("Structured test results")}).superRefine((e,t)=>{"fail_environment"!==e.results?.faultClass||e.results.missingCapabilities&&e.results.missingCapabilities.length>0||t.addIssue({code:o.z.ZodIssueCode.custom,path:["results","missingCapabilities"],message:"faultClass 'fail_environment' requires results.missingCapabilities: name the absent binaries/runtimes (the deterministic capability probe in your evidence lists them, e.g. ABSENT from the box: node). Without the names, the environment cannot be extended and the request strands."})})
5800
+ const I=o.z.string().min(1,"every option needs its consequence (description)").max(200,"an option's description is its consequence in one line: 200 characters at most").describe("Its consequence in one line: what it gets and costs."),$=o.z.string().min(1).max(120,"because is one clause: 120 characters at most")
5801
+ exports.OpeningBriefSectionSchema=o.z.object({id:o.z.string().min(1).describe('Unique within the brief ("date-format").'),question:o.z.string().min(1).describe("The choice, one plain question answerable without your session."),context:o.z.string().min(1).describe("What it shapes, citing the request and its sources as stated; where they answer it, recommend their answer."),options:o.z.array(o.z.object({id:o.z.string().min(1),label:o.z.string().min(1),description:I})).min(2).describe("At least two genuine alternatives."),default:o.z.string().min(1).describe("The option you proceed on now (shown recommended)."),because:$.describe("Why, in one clause."),criteria:o.z.array(o.z.string().min(1)).optional().describe("Keys of criteria whose wording this choice decides (worded for your default); another pick marks them for rewording.")}).superRefine((e,t)=>{e.options.some(t=>t.id===e.default)||t.addIssue({code:o.z.ZodIssueCode.custom,path:["default"],message:`default '${e.default}' names no option in this section (option ids: ${e.options.map(e=>e.id).join(", ")})`}),"testing-mode"===e.id&&t.addIssue({code:o.z.ZodIssueCode.custom,path:["id"],message:"section id 'testing-mode' is reserved: the server composes the testing section when the project's gate needs it -- remove it from your sections"})}),exports.SessionMessageOperationsSchema=o.z.object({operation:o.z.enum(["send","note","reply","list","get","offer-handoff","record-decision","brief","withdraw"]),milestone:o.z.boolean().optional().describe("note: a real boundary (it works, the approach changed, the goal is met); one quiet line in the user's stream, a few per request at most."),percent:o.z.number().min(0).max(100).optional().describe("note: how far along your work on this request is; it may go down."),withdrawReason:o.z.string().optional().describe("withdraw: why the answer is no longer needed."),type:o.z.enum(["question","report"]).optional().describe("Required for send."),toSessionId:o.z.string().optional().describe('A session id, or "parent". Omit for the user (a broadcast).'),questionType:o.z.enum(["free-form","alternatives"]).optional().describe("Required for a question."),questionContent:o.z.object({question:o.z.string().min(1).describe("As the user reads it; a criterion by its words, never its key."),context:o.z.preprocess(e=>null!==e&&"object"==typeof e?JSON.stringify(e):e,o.z.string().optional()).optional().describe("What the user needs to answer without your session: what you found and why it matters. No paths or identifiers; output they should judge goes in a fenced block, as printed."),options:o.z.array(o.z.object({id:o.z.string(),label:o.z.string(),description:I,recommended:o.z.boolean().optional().describe("Your advice, highlighted (what happens unanswered is defaultOption). Not with criteria. Never on an option that makes up what the user has not given (estimates, sample values, invented names): leave it visibly empty or marked unknown."),because:o.z.preprocess(a,$.optional()).describe("With recommended (required there): why, in one clause."),notePrompt:o.z.string().min(3).max(120).optional().describe('For an option only useful with the user\'s words ("I want changes"): the question its text field asks ("What should change?"); the pick arrives with what they typed.'),effect:o.z.enum(["choose","send-back","not-yet"]).optional().describe('"choose" (default): records the pick. "send-back": asks for a change; on a request awaiting sign-off the pick itself sends it back (no reopen). "not-yet": [user-input] criteria only; they stay owed.')})).optional().describe("Genuine alternatives, each complete in one tap; recommended first. When the user's way cannot work, include one reaching their goal another way."),allowMultiple:o.z.boolean().optional(),fields:o.z.array(o.z.object({id:o.z.string().min(1),label:o.z.string().min(1),placeholder:o.z.string().optional()})).min(1).optional().describe('free-form: one labelled input per value; answers arrive as "Label: value" lines. Never ask for passwords or keys: answers are on the record.'),defaultOption:o.z.string().optional().describe("What happens if nobody answers before expiry (option id, or text for free-form); the asker resumes. It happens without the user, so it is the SAFE option when options differ in risk (silent value changes, data loss, made-up data, anything hard to undo), even if you recommend another; the context says so."),onExpiry:o.z.enum(["assume-default","escalate"]).optional().describe('"assume-default" (default with a defaultOption) or "escalate": stays pending for the user (on Self-driving only priority "high" reaches them).'),steer:o.z.enum(["what","how"]).optional().describe('"what" shapes the product (spec, wording, UX, scope); "how" the process (testing, sequencing), mostly yours to decide, not ask.'),changeableLater:o.z.boolean().optional().describe("true when the answer can change later without loss (nothing sent, deleted or published on it).")}).superRefine((e,t)=>{(e.options??[]).forEach((e,r)=>{!0!==e.recommended||e.because||t.addIssue({code:o.z.ZodIssueCode.custom,path:["options",r,"because"],message:`option '${e.id}' is recommended: say why in one clause (because)`})})}).optional().describe("Required for a question. Before asking the user: when context answers it and a wrong guess is cheap to fix, proceed. Otherwise ask with a defaultOption unless only the user can answer. Under 'autonomous' the default returns at once; 'balanced' holds up to ten minutes, then continues; 'collaborative' holds briefly, then ends your turn to wait. One decision per question, related uncertainties bundled; several candidate next steps are one alternatives question. A question the user already decided returns their decision: proceed on it."),priority:o.z.enum(["low","normal","high"]).optional().describe('"high": blocked with real stakes; reaches the user at once. "low" with a defaultOption: under \'balanced\', batched to the next checkpoint without holding.'),expiresInHours:o.z.number().optional(),userSaid:o.z.string().min(8).max(600).optional().describe('question: when the user asked to be asked ("ask me first"), their words exactly (checked); it then reaches them at any Autonomy.'),replaces:o.z.array(o.z.string().regex(/^Q-[A-Za-z0-9]+-\d+$/)).max(10).optional().describe("question: your open questions on the request this supersedes (they close). With one open, pass this or keepsOpen."),keepsOpen:o.z.boolean().optional().describe("question: it asks something else; your open ones stay open."),forceAsk:o.z.boolean().optional().describe("question: re-ask what the decision record answers, only because circumstances changed (say what in context)."),status:o.z.enum(["success","partial","failure","blocked"]).optional().describe("report: how it ended. Omitted reads success, or blocked with blockedOn."),blockedOn:o.z.string().optional().describe('Required with status "blocked" on your request: "decision" (the user\'s open card on it, else a question to your parent), a card code ("Q-AB12CD34-001"), or a request id (a wait; you are told when it settles).'),criteria:o.z.array(o.z.string().min(1)).max(10).optional().describe('question: keys of the [user-input] criteria you ask for; only this counts as asking them. No default, no recommended option; the answer is their proof unless it is "not-yet". With a "not-yet" option you build on a placeholder meanwhile (Self-driving answers it at once); without one you wait at every Autonomy. Their check of finished work is asked on the end card, not here.'),attention:o.z.enum(["fyi","glance","act"]).optional().describe("'fyi' (no badge), 'glance', 'act'. Default from status: failure/blocked act, partial glance, success fyi."),reportKind:o.z.enum(["milestone","reply"]).optional().describe("'reply': answers the user's inbox message."),summary:o.z.string().optional().describe("Required for a report: outcome first, subject named first (it shows alone, often hours later), paths in details."),details:o.z.string().optional().describe("With blockedOn \"decision\", the question's context (maybe the user's card): plain words, no tool names; explain a refusal, never paste it."),ruleVerdicts:o.z.array(o.z.object({rule:o.z.string().min(1).max(80).describe("The guidance id, no brackets."),verdict:o.z.enum(["held","broken","not_applicable"]),note:o.z.string().max(300).optional().describe("broken: what and where (file:line).")})).max(40).optional().describe("report, Guidance reviewer: a verdict on every item you were given."),silent:o.z.boolean().optional().describe("Record without waking the coordinator (fan-out research)."),relatesTo:o.z.string().regex(/^[IQ]-[A-Za-z0-9]+-\d+$/,"relatesTo must be an instruction code (I-...) or question code (Q-...)").optional().describe("An instruction code (I-...); for record-decision, the question (Q-...) it resolves."),decision:o.z.string().optional().describe("record-decision (required): the one-line call."),why:o.z.string().optional().describe("record-decision: the reasoning."),context:o.z.string().optional().describe("record-decision: what the choice was about."),requestId:o.z.string().optional().describe("The request it is about, so it shows there (note: defaults to yours; brief: required); without it a report or decision is filed at the project."),area:o.z.string().optional().describe("record-decision: a work area the call is about (without requestId)."),sections:o.z.array(exports.OpeningBriefSectionSchema).min(1).optional().describe("brief (required): your real design choices."),messageCode:o.z.string().optional().describe("Required for reply, get and withdraw."),amount:o.z.number().positive().max(1e5).optional().describe("Dollars the user named, their words in quote: 'build' on a Plan ready card sets the plan's budget; 'allow' on a budget card allows that much more."),sectionAnswers:o.z.record(o.z.string(),o.z.string().nullable()).optional().describe("reply to an opening brief: { sectionId: optionId } for sections the user answered, changed or confirmed, with quote; null when one no longer applies; 'your-words' when no option says what they asked. Unnamed sections stay open; a change sends finished work back to rework."),quote:o.z.string().optional().describe("reply: the user's words this answer records, exactly (refused if they never wrote them); omit for your own decision. Options that are the user's own statement (\"I checked, it works\") only they can pick."),text:o.z.string().optional().describe("reply: a free-form answer. note (required): the note."),selectedOptions:o.z.array(o.z.string()).optional().describe("reply: the picked option ids."),notes:o.z.string().optional(),escalate:o.z.boolean().optional().describe("reply to a question to you that needs the user: a copy reaches them with your recommendation (notes); the asker gets their answer. Not for broadcasts."),list:o.z.object({sessionId:o.z.string().optional().describe("Defaults to your session."),messageType:o.z.enum(["question","report","instruction","all"]).default("all"),direction:o.z.enum(["incoming","outgoing","all"]).default("all"),status:o.z.enum(["pending","answered","expired","success","partial","failure","blocked","all"]).default("all"),readStatus:o.z.enum(["unread","read","acknowledged","all"]).default("all"),requestId:o.z.string().optional().describe("Only messages about this request."),limit:o.z.number().min(1).max(100).default(50),offset:o.z.number().min(0).default(0)}).optional(),offerHandoff:o.z.object({summary:o.z.string().describe("One sentence: what the plan builds."),requestIds:o.z.array(o.z.string()).describe("Requests created from the plan.")}).optional()}).superRefine((e,t)=>{const r=n(e)
5802
+ r&&t.addIssue({code:o.z.ZodIssueCode.custom,message:r})}),exports.CommitToViewedSessionSchema=o.z.object({message:o.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.")}),exports.DirectiveOperationsSchema=o.z.object({operation:o.z.enum(["set","list","search-decisions"]).describe("search-decisions = free-text search the project's decision + annotation record"),targetType:o.z.enum(["project","area","request","you"]).optional(),targetId:o.z.string().optional(),body:o.z.string().max(2e3).optional(),note:o.z.string().optional(),userSaid:o.z.string().optional(),revises:o.z.string().max(160).optional(),status:o.z.string().optional(),query:o.z.string().max(200).optional().describe("search-decisions: the search text, matched against recorded decisions (question + answer) and annotations (comment body + quoted text). Required for search-decisions."),limit:o.z.number().int().min(1).max(50).optional().describe("search-decisions: max matches per record type (default 10).")}),exports.McpConnectionsSchema=o.z.object({operation:o.z.enum(["list","propose","update","remove"]).describe("list = the connections this project has; propose = register one, switched off, for the user to switch on; update = correct one by name (only the fields you pass change; a connection that was on goes off for the user to switch on again); remove = take back one that is switched off."),name:o.z.string().optional().describe("propose: the connection name, lower case letters, digits and dashes. It becomes the tool prefix (name_tool). update / remove: the name of the connection to change."),transport:o.z.enum(["repo","boxed","remote"]).optional().describe("propose / update: repo = a server in THIS repository, built from its Dockerfile and run in a confined box (the repository is mounted read-only at /work, /scratch is writable memory, the image ENTRYPOINT is what runs, rebuilt when its files change on main); boxed = a published npm package at an exact version, installed once and run in a box; remote = a hosted server reached by url."),dockerfile:o.z.string().optional().describe("propose / update repo: path of the Dockerfile inside the repository, e.g. mcp/server.Dockerfile."),context:o.z.string().optional().describe("propose / update repo: the docker build context directory inside the repository (default: the repository root)."),package:o.z.string().optional().describe("propose / update boxed: npm package with an exact version, e.g. @scope/server@1.2.3."),bin:o.z.string().optional().describe("propose / update boxed: the bin to run, the name under node_modules/.bin."),url:o.z.string().optional().describe("propose / update remote: the http(s) url."),environment:o.z.record(o.z.string()).optional().describe("propose / update: plain KEY=value configuration (headers for remote). Never put a secret here; name it in secretKeys instead."),secretKeys:o.z.array(o.z.string()).optional().describe("propose / update: names of environment variables (or headers) whose VALUES are secret. The user sets the values on the machine that runs the work; they never reach the database.")}),exports.AnswerQuestionSchema=o.z.object({messageCode:o.z.string().min(1).describe("The code in square brackets from <waiting_on_you>, e.g. Q-51209THD-005."),optionId:o.z.string().optional().describe("The id of the option the user picked, when the question has options."),text:o.z.string().optional().describe("The user's answer in their own words, cleaned up, when the question has no options or they said something the options do not cover.")})},19567(e,exports,t){exports.Server=exports.SSEServerTransport=exports.StdioServerTransport=void 0
5779
5803
  const r=t(66865)
5780
5804
  Object.defineProperty(exports,"Server",{enumerable:!0,get:function(){return r.Server}})
5781
5805
  const n=t(25802)
@@ -6722,15 +6746,17 @@ if(!t)return`NOT-MEASURED-YET:it is measured after the work is completed, on the
6722
6746
  const n=String(t.note??"").replace(/\s+/g," ").trim().slice(0,300)
6723
6747
  return`${"met"===t.verdict?"MEASURED-MET":"unmet"===t.verdict?"MEASURED-WORSE":"MEASURED"}:${n||"measured"}; ${r}`}const o=function(e){const t=e?.proof?.checkSetup
6724
6748
  return"string"==typeof t&&t?`its check starts when the request is completed: set up at completion (setup run ${t}). The check runs what this request adds, so it is registered once the request is completed, and its first run on main is the proof, written on the criterion then. Decided by that run only, never by a review: registering the check is not a part of this request left undone. What the check will run is in the diff and is yours to read`:null}(e)
6725
- return o?`CHECK-AT-COMPLETION:${o}`:!0===e?.proven?"reviewer"===t.by?"PROVEN:review":"you"===t.by?"PROVEN:user-hand-check":"driver"===t.by?"PROVEN:drive":"PROVEN:test":"not-checked"===n.driver?.verdict?"NOT-CHECKED:drive":"answer"===t.reword?.from?`REWORD:${String(t.reword.note??"the answer it was written for changed").slice(0,300)}; reword it with request_operations update, its key and userSaid "${t.reword.ref}"`:t.notARealTest?"NOT-A-REAL-TEST":t.checkFails?"met"===n.reviewer?.verdict?"FAILED:test (review met, check fails)":"FAILED:test":t.disputed?`DISPUTED:its check passes, but the reviewer says it does not hold${t.disputed.note?` ("${String(t.disputed.note).slice(0,200)}")`:""}; strengthen the check so it tests what the criterion says, or fix the code`:"could-not-run"===n.instrument?.verdict?"COULD-NOT-RUN:test (its check could not run here; it says nothing either way)":"unmet"===n.reviewer?.verdict?"UNMET:review":!0===n.reviewer?.reword?"REWORD:a reviewer found its words no longer fit what was asked; reword it with the user's words, or ask them":"withdrawn"===n.reviewer?.verdict?"RE-REVIEW:its review was withdrawn (the work changed after it, or a new pass is due)":e?.coder?"ATTESTED":"UNPROVEN"}function o(e){const r=new Map
6749
+ return o?`CHECK-AT-COMPLETION:${o}`:!0===e?.proven?"reviewer"===t.by?"PROVEN:review":"you"===t.by?"PROVEN:user-hand-check":"driver"===t.by?"PROVEN:drive":"PROVEN:test":"not-checked"===n.driver?.verdict?"NOT-CHECKED:drive":"answer"===t.reword?.from?`REWORD:${String(t.reword.note??"the answer it was written for changed").slice(0,300)}; reword it with request_operations update, its key and userSaid "${t.reword.ref}"`:t.notARealTest?"NOT-A-REAL-TEST":t.checkFails?"met"===n.reviewer?.verdict?"FAILED:test (review met, check fails)":"FAILED:test":t.disputed?`DISPUTED:its check passes, but the reviewer says it does not hold${t.disputed.note?` ("${String(t.disputed.note).slice(0,200)}")`:""}; strengthen the check so it tests what the criterion says, or fix the code`:"could-not-run"===n.instrument?.verdict?"COULD-NOT-RUN:test (its check could not run here; it says nothing either way)":"unmet"===n.reviewer?.verdict?"UNMET:review":!0===n.reviewer?.reword?"REWORD:a reviewer found its words no longer fit what was asked; reword it with the user's words, or ask them":"withdrawn"===n.reviewer?.verdict?"RE-REVIEW:its review was withdrawn (the work changed after it, or a new pass is due)":e?.coder?"ATTESTED":"UNPROVEN"}function o(e){const t=String(e??"").trim(),r=/^\[?(\d+[a-z])\](?:\s|$)/i.exec(t)??/^(\d+[a-z])$/i.exec(t)
6750
+ return r?r[1].toLowerCase():t}function s(e){const r=new a
6726
6751
  for(let n=0;n<e.length;n++){const o=t(e[n].id,n)
6727
- r.set(o,e[n])}return r}function s(e){if(0===e.length)return"No acceptance criteria defined."
6728
- const t=o(e),r=[]
6752
+ r.set(o,e[n])}return r}function i(e){if(0===e.length)return"No acceptance criteria defined."
6753
+ const t=s(e),r=[]
6729
6754
  for(const[e,o]of t){const t=n(o),s="objective"===o.kind||"subjective"===o.kind||"gate"===o.kind?` [${o.kind.toUpperCase()}]`:"",i=o.standing?o.waived?" [WAIVED for this request by the user; it no longer binds, do not work on or judge it]":` [FROM THE ${o.standing.processName?`PROCESS "${String(o.standing.processName).slice(0,60)}"`:"WORKFLOW"}: every request that follows it carries it; it cannot be dropped or reworded; if it does not apply, the guidance tool with guidanceId "[guidance:${o.standing.ruleKey?String(o.standing.ruleKey):String(o.standing.id??"")}]": exception when the user said so, else conflict]`:"",a="string"==typeof o.environment&&o.environment.trim()?` [its checks run in the "${o.environment.trim().slice(0,80)}" environment]`:""
6730
6755
  r.push(`[${e}] [${t}]${s}${i}${a} ${o.description}`)}return r.join("\n")}exports.formatCriteriaWithHashes=void 0,exports.criterionShortKey=t,exports.isUserOwnCheck=r,exports.latestRow=function(e,t){const r=e?.ledger
6731
- if(Array.isArray(r))for(let e=r.length-1;e>=0;e--)if(t.includes(r[e]?.source))return r[e]},exports.criterionProven=function(e){return!0===e?.proven},exports.buildCriteriaKeyMap=o,exports.formatCriteriaWithKeys=s,exports.formatVerifyInstructions=function(e){const t=o(e),r=[]
6756
+ if(Array.isArray(r))for(let e=r.length-1;e>=0;e--)if(t.includes(r[e]?.source))return r[e]},exports.criterionProven=function(e){return!0===e?.proven},exports.buildCriteriaKeyMap=s,exports.formatCriteriaWithKeys=i,exports.criteriaKeyChoices=function(e){return[...s(e)].map(([e,t])=>` "${e}": ${String(t.description??"").slice(0,120)}`).join("\n")},exports.formatVerifyInstructions=function(e){const t=s(e),r=[]
6732
6757
  for(const[e,n]of t)r.push(` {"key": "${e}", "evidence": "<your evidence for: ${n.description}>"}`)
6733
- return`Use the merge operation with evidence for each criterion:\n\n${s(e)}\n\nExample call:\n{\n "operation": "merge",\n "requestId": "<requestId>",\n "merge": {\n "verifications": [\n${r.join(",\n")}\n ]\n }\n}`},exports.formatCriteriaWithHashes=s},82960(e,exports){function t(e,t={}){const{logger:r,operationName:n="API operation",throwOnNoData:o=!1,defaultValue:s=null,includeMetadata:i=!1}=t
6758
+ return`Use the merge operation with evidence for each criterion:\n\n${i(e)}\n\nExample call:\n{\n "operation": "merge",\n "requestId": "<requestId>",\n "merge": {\n "verifications": [\n${r.join(",\n")}\n ]\n }\n}`}
6759
+ class a extends Map{get(e){return super.get(e)??super.get(o(e))}has(e){return super.has(e)||super.has(o(e))}}exports.formatCriteriaWithHashes=i},82960(e,exports){function t(e,t={}){const{logger:r,operationName:n="API operation",throwOnNoData:o=!1,defaultValue:s=null,includeMetadata:i=!1}=t
6734
6760
  if(r&&r.debug(`${n} - Response structure analysis`,{type:typeof e,isApiResponse:e&&"object"==typeof e&&"success"in e,isSuccessResponse:e&&"object"==typeof e&&!0===e.success,isErrorResponse:e&&"object"==typeof e&&!1===e.success,hasData:e&&"object"==typeof e&&"data"in e,hasMetadata:e&&"object"==typeof e&&"metadata"in e,properties:e&&"object"==typeof e?Object.keys(e):[],dataPreview:e?JSON.stringify(e).substring(0,200)+"...":"null"}),null==e){if(r&&r.warn(`${n} - Response is null or undefined`),o)throw new Error(`${n}: Response is null or undefined`)
6735
6761
  return i?{data:s,metadata:void 0}:s}if("object"!=typeof e||!("success"in e))return r&&(r.warn(`${n} - Response is not a standard API response (missing success property)`),r.debug(`${n} - Attempting to use response directly as data`)),i?{data:e,metadata:void 0}:e
6736
6762
  if(!1===e.success){const t=e,a=t.error?`${t.error.code}: ${t.error.message}`:"Unknown error"
@@ -7767,13 +7793,15 @@ const i=setInterval(()=>{s+=1
7767
7793
  const t=e.message?.()
7768
7794
  n({method:"notifications/progress",params:{progressToken:r,progress:s,...t?{message:t}:{}}}).catch(()=>{})},o)
7769
7795
  try{return await t()}finally{clearInterval(i)}}exports.withHeartbeat=r,exports.runTrackedShellWithHeartbeat=function(e,t,o,s){return r({progressToken:s?.progressToken,sendNotification:s?.sendNotification,message:()=>`running ${o.name}`},()=>(0,n.runTrackedShellCommand)(e,t,o))}
7770
- const n=t(44600)},49779(e,exports){exports.x4=exports.Tt=void 0,exports.validateServerName=function(e){return exports.x4.test(e)?exports.Tt.includes(e)?`"${e}" is reserved`:null:"Connection name must be 2-39 characters, lower-case letters, digits and dashes, starting with a letter"},exports.validateRepoConfig=function(e){if(void 0!==e.command)return"A repository connection derives its own command from the image; give it a dockerfile instead"
7771
- const t=e=>{const t=e.replace(/\\/g,"/")
7772
- return!t.startsWith("/")&&!/^[a-zA-Z]:/.test(t)&&!t.split("/").includes("..")},r=e.dockerfile
7773
- if("string"!=typeof r||!r.trim())return"A repository connection needs the dockerfile to build, as a path inside the repository, for example mcp/server.Dockerfile"
7774
- if(!t(r.trim()))return`dockerfile must be a path inside the repository, not "${r}"`
7796
+ const n=t(44600)},49779(e,exports){function t(e){return/[\r\n]/.test(e)||e.trim().length>240}exports.x4=exports.Tt=void 0,exports.validateServerName=function(e){return exports.x4.test(e)?exports.Tt.includes(e)?`"${e}" is reserved`:null:"Connection name must be 2-39 characters, lower-case letters, digits and dashes, starting with a letter"},exports.validateRepoConfig=function(e){if(void 0!==e.command)return"A repository connection derives its own command from the image; give it a dockerfile instead"
7797
+ const r=e=>{const t=e.replace(/\\/g,"/")
7798
+ return!t.startsWith("/")&&!/^[a-zA-Z]:/.test(t)&&!t.split("/").includes("..")},n=e.dockerfile
7799
+ if("string"!=typeof n||!n.trim())return"A repository connection needs the dockerfile to build, as a path inside the repository, for example mcp/server.Dockerfile"
7800
+ if(t(n))return"dockerfile is the path of a Dockerfile in this repository, for example mcp/server.Dockerfile, not its contents. To run a published image, the repository needs a Dockerfile that says FROM <the image>: have it written in the repository first, then give its path here."
7801
+ if(!r(n.trim()))return`dockerfile must be a path inside the repository, not "${n}"`
7775
7802
  if(void 0!==e.context){if("string"!=typeof e.context||!e.context.trim())return"context, when given, is a directory inside the repository"
7776
- if(!t(e.context.trim()))return`context must be a directory inside the repository, not "${e.context}"`}return null},exports.isPinnedPackage=function(e){const t=String(e??"").lastIndexOf("@")
7803
+ if(t(e.context))return"context is the path of a directory in this repository (the docker build context), for example mcp/, not a description. Leave it out to build from the repository root."
7804
+ if(!r(e.context.trim()))return`context must be a directory inside the repository, not "${e.context}"`}return null},exports.isPinnedPackage=function(e){const t=String(e??"").lastIndexOf("@")
7777
7805
  return!(t<=0)&&/^\d/.test(e.slice(t+1))},exports.Tt=["alchemy"],exports.x4=/^[a-z][a-z0-9-]{1,38}$/},34803(e,exports,t){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}}
7778
7806
  Object.defineProperty(exports,"__esModule",{value:!0}),exports.mimeFor=function(e){return o[n.default.extname(e).toLowerCase()]??"application/octet-stream"}
7779
7807
  const n=r(t(16928)),o={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".svg":"image/svg+xml",".pdf":"application/pdf",".html":"text/html; charset=utf-8",".htm":"text/html; charset=utf-8",".md":"text/markdown; charset=utf-8",".csv":"text/csv; charset=utf-8",".json":"application/json; charset=utf-8",".txt":"text/plain; charset=utf-8",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".zip":"application/zip",".gz":"application/gzip",".tgz":"application/gzip",".tar":"application/x-tar",".vtu":"application/xml",".vtk":"application/octet-stream",".msh":"text/plain; charset=utf-8"}},35510(e,exports,t){async function r(e,t){try{return{files:(await e.raw(["grep","-l","-e","^<<<<<<< ",t,"--","."])).split("\n").map(e=>e.trim()).filter(Boolean).map(e=>e.startsWith(`${t}:`)?e.slice(t.length+1):e),determined:!0}}catch(e){const t=String(e?.message??"")