alchemylab 3.0.1 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +10 -6
- package/dist/http-server.js +1058 -1050
- package/dist/index.js +202 -194
- package/dist/mcp-direct.js +50 -42
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1316,9 +1316,13 @@ if(!u.ok)return{advanced:!1,clean:!0,why:u.why}
|
|
|
1316
1316
|
try{const r=await e.apiClient.patch(`/api/projects/${e.projectId}/requests/${t.requestId}`,{reviewStatus:"completed",cliOrigin:{sessionId:t.coderSessionId},headSha:i,reviewRound:{...s.reviewed?{reviewed:s.reviewed}:{},clean:!0}})
|
|
1317
1317
|
if(r&&!1===r.success)return{advanced:!1,clean:!0,why:`the finish signal was refused: ${r.error??r.message??"no reason given"}`}}catch(e){return{advanced:!1,clean:!0,why:`the finish signal failed: ${(0,f.getErrorMessage)(e)}`}}return{advanced:!0,clean:!0}}function d(e){const t="DELIVERY: ESCALATE",r=e.map(e=>`${e.content?.summary??""}\n${e.content?.details??""}`).join("\n"),s=/^\(?\s*(none|n\/a|nothing|no items?|nothing to fix)\s*\)?\.?$/i,n=[],o=r.split("\n").map(e=>e.trim())
|
|
1318
1318
|
for(let e=0;e<o.length;e++)if(/^\**must_fix\**:?$/i.test(o[e]))for(let t=e+1;t<o.length&&!/^\**(nice_to_have|out_of_scope)\**:?$/i.test(o[t]);t++){const e=o[t].match(/^[-*]\s+(.+)$/)
|
|
1319
|
-
e&&!s.test(e[1])&&n.push(e[1])}
|
|
1320
|
-
|
|
1321
|
-
|
|
1319
|
+
e&&!s.test(e[1])&&n.push(e[1])}const i=/^[\s:\u2013-]*(?:(?:is|was|would be|are)\s+)?(?:not|never)\b|^[\s:\u2013-]*(?:isn'?t|wasn'?t|unnecessary)\b/i
|
|
1320
|
+
let a=-1
|
|
1321
|
+
for(let e=r.indexOf(t);e>=0;e=r.indexOf(t,e+1)){const t=r.slice(e+18).split("\n")[0]??""
|
|
1322
|
+
if(!i.test(t)){a=e
|
|
1323
|
+
break}}if(a>=0&&0===n.length)return{escalated:!0,rework:!1,reason:r.slice(a+18).replace(/^[\s:\u2013-]+/,"").split("\n").map(e=>e.trim()).find(Boolean)??"The delivery diverges from what was asked; the reviewer could not settle it."}
|
|
1324
|
+
const c=/^\W*Match\W*:\s*no\b[\s,.:;-]*(?:because\s*)?(.*)$/im.exec(r)
|
|
1325
|
+
return e.some(e=>"failure"===String(e.content?.reportStatus??""))||n.length>0||c?{escalated:!1,rework:!0,reason:n[0]??(c?.[1]?.trim()||(e[0]?.content?.summary??"").slice(0,300))}:{escalated:!1,rework:!1,reason:(e[0]?.content?.summary??"").slice(0,800)}}async function u(e,t,r,s,n,o){const i={skipped:r,...s?{reviewed:s}:{}}
|
|
1322
1326
|
let a=!1
|
|
1323
1327
|
if("no-rule"===r)try{const r=await e.apiClient.get(`/api/projects/${e.projectId}/requests/${t.requestId}`)
|
|
1324
1328
|
a=r.success&&"ready_for_review"===r.data?.status}catch{}if("no-rule"!==r||a){try{await e.apiClient.patch(`/api/projects/${e.projectId}/requests/${t.requestId}`,{reviewStatus:"completed",cliOrigin:{sessionId:t.coderSessionId},reviewRound:i})}catch(r){e.logger.error("review-fanout: finish signal failed (gate stays pending -- reconciler surfaces it)",{requestId:t.requestId,error:(0,f.getErrorMessage)(r)})}"nothing"===r&&o&&await(0,A.injectPromptToSession)(e,t.coderSessionId,o)}else await(0,A.injectPromptToSession)(e,t.coderSessionId,o)
|
|
@@ -1891,7 +1895,7 @@ if(!n)return{success:!1,message:"requestId is required",error:"Missing payload"}
|
|
|
1891
1895
|
i.info("Starting start-drive action",{requestId:n,creatorSessionId:o})
|
|
1892
1896
|
try{const e=await a.get(`/api/projects/${c}/requests/${n}`)
|
|
1893
1897
|
if(!e.success||!e.data)return{success:!1,message:`Request ${n} not found`,error:"Request not found"}
|
|
1894
|
-
const r=e.data,u=Array.isArray(r.acceptanceCriteria)&&r.acceptanceCriteria.length>0?r.acceptanceCriteria.map(e=>`- ${e?.description??e}`).join("\n"):"(none authored -- treat the description as the claim list, and say so in the receipt)",h=`Drive ${n}.\n\
|
|
1898
|
+
const r=e.data,u=Array.isArray(r.acceptanceCriteria)&&r.acceptanceCriteria.length>0?r.acceptanceCriteria.map(e=>`- ${e?.description??e}`).join("\n"):"(none authored -- treat the description as the claim list, and say so in the receipt)",h=`Drive ${n}.\n\n${function(e,t){return t?`You own this. It is a message from the user on the page of ${t}, a drive that is completed; its record is there to read (get_request_information). If it asks something that record answers, the answer is the summary you complete with, and nothing is driven. If it asks for another pass, or the record does not answer it, drive what it asks through user doors, per your instructions, and complete with the receipt. Either way end by completing (request_operations complete, requestId: "${e}"). Do not call merge; the server settles the request on your completion.`:`You own this drive request. Its acceptance criteria are CLAIMS to verify against the running system through user doors, per your instructions. Verify each claim with exact evidence, file reports for divergences beyond the criteria, and end by completing the request (request_operations complete, requestId: "${e}") with the claim -> verdict -> one-line-evidence receipt. Do not call merge; the server settles the record after your completion.`}(n,r.roundOf)}\n\n## The request\n\nTitle: ${r.title??"(untitled)"}\n\nDescription:\n${r.description||"(no description)"}\n\nAcceptance criteria (the claims):\n${u}`,p=await(0,s.spawnActionAgent)({agent:"driver",prompt:h,cwd:l,projectPath:l,projectId:c,title:/^(drive|deploy check)\b/i.test(String(r.title??""))?`[${n}] ${r.title}`.trim():`[${n}] Drive: ${r.title??""}`.trim(),requestId:n,parentSessionId:o,allowParallel:!0,skipWorktree:!0,apiClient:a,logger:i,trackChildPid:d,getDefaultModel:()=>t.cachedDefaultModel??void 0})
|
|
1895
1899
|
return p.success?(i.info("Driver spawned",{requestId:n,sessionId:p.sessionId}),{success:!0,message:`Driver spawned for ${n} (session ${p.sessionId})`}):{success:!1,message:`Failed to spawn driver for ${n}`,error:p.error}}catch(e){const t=(0,r.getErrorMessage)(e)
|
|
1896
1900
|
return i.error("start-drive action failed",{requestId:n,error:t}),{success:!1,message:`Drive dispatch failed for ${n}`,error:t}}}
|
|
1897
1901
|
const r=t(58824),s=t(28148)},93503(e,exports,t){"use strict"
|
|
@@ -1983,7 +1987,7 @@ const v=T.get(s.requestId)
|
|
|
1983
1987
|
if(v)return{success:!0,message:`${s.requestId} starts on ${v} when its current turn ends`}
|
|
1984
1988
|
try{const e=async e=>{const t=await o.get(`/api/projects/${i}/requests/${e}`)
|
|
1985
1989
|
return(t?.data??t)?.type}
|
|
1986
|
-
t.projectPath&&await(0,_.defaultBranchHasCode)(t.projectPath,e)&&(await(0,_.reportProjectHasCode)(i,!0,(e,t)=>o.patch(e,t)),await o.post(`/api/projects/${i}/requests/${s.requestId}/test-setup-offer`,{...s.creatorSessionId?{creatorSessionId:s.creatorSessionId}:{}}))}catch(e){d.warn("test-check card could not be asked for (the start goes on)",{requestId:s.requestId,error:(0,S.getErrorMessage)(e)})}const b=await(u.openDuplicates??r)(t,w,s.requestId),k=await(u.requestRecord??n)(t,s.requestId,w),I=function(e,t,r,s){const n=[`Implement ${e.requestId} ("${t?.title??""}") and own its full lifecycle. It was registered via ${e.source??"a registration door"}.`,s?"Its record, as get_request_information shows it now, is at the end of this message: start from it, and read the request again only when you need what changed since. If something it BUILDS ON does not exist in this project, call request_operations premise-block with the reason instead of starting. New content the request introduces is not a missing premise.":"Read it with get_request_information first. If something it BUILDS ON does not exist in this project, call request_operations premise-block with the reason instead of starting. New content the request introduces is not a missing premise."
|
|
1990
|
+
t.projectPath&&await(0,_.defaultBranchHasCode)(t.projectPath,e)&&(await(0,_.reportProjectHasCode)(i,!0,(e,t)=>o.patch(e,t)),await o.post(`/api/projects/${i}/requests/${s.requestId}/test-setup-offer`,{...s.creatorSessionId?{creatorSessionId:s.creatorSessionId}:{}}))}catch(e){d.warn("test-check card could not be asked for (the start goes on)",{requestId:s.requestId,error:(0,S.getErrorMessage)(e)})}const b=await(u.openDuplicates??r)(t,w,s.requestId),k=await(u.requestRecord??n)(t,s.requestId,w),I=function(e,t,r,s){const n=[`Implement ${e.requestId} ("${t?.title??""}") and own its full lifecycle. It was registered via ${e.source??"a registration door"}.`,s?"Its record, as get_request_information shows it now, is at the end of this message: start from it, and read the request again only when you need what changed since. If something it BUILDS ON does not exist in this project, call request_operations premise-block with the reason instead of starting. New content the request introduces is not a missing premise.":"Read it with get_request_information first. If something it BUILDS ON does not exist in this project, call request_operations premise-block with the reason instead of starting. New content the request introduces is not a missing premise.",...t?.roundOf?[]:[`If its acceptance criteria ALREADY hold as the code stands, do no work: complete ${e.requestId} yourself as a verification-only completion, naming exactly which criteria hold and where. Nobody else closes it: a report saying so left req000210 in progress with nobody working it.`,'Otherwise build what it asks (its own choices go in an opening brief when the pickup briefing asks for one), run the relevant validation, and complete the request with evidence. A value the request states is the value: a version number, a label, a default. Do not bump or "improve" it (two coders raised a footer version the user had just set, 2026-09-07).']]
|
|
1987
1991
|
return r.length&&n.push(`Possible duplicates already open with the same title: ${r.join(", ")}. Check before doing the work twice; if one already covers it, cancel ${e.requestId} as superseded.`),e.userNote&&n.push(`From the user: ${e.userNote}`),e.rules?.length&&n.push(function(e){const t=e.filter(e=>"told"===e.enforcement),r=e.filter(e=>"told"!==e.enforcement),s=[...t.map(e=>`- [guidance:${e.id}] ${e.text}`),...r.map(e=>`- [guidance:${e.id}] (reviewed, ${e.severity}) ${e.text}`)]
|
|
1988
1992
|
return`The workflow's guidance for this work (the user's; where an item conflicts with the brief above, the guidance wins).${r.length?" A reviewer checks the reviewed ones by id at the review gate: 'block' ones must hold, 'advise' ones are expected.":""} When the user's own words make an exception to an item for this request, record it with guidance exception (its id as listed, their words, the scope they said); when the request contradicts an item and they have not said, guidance conflict, and follow the guidance until they answer.\n${s.join("\n")}`}(e.rules)),s&&n.push(`\n# ${e.requestId}: ${t?.title??""}\n${s}`),n.join("\n")}(s,w,b,k),j="string"==typeof s.worker&&s.worker.trim()||(0,p.kindProfile)(w?.type).worker||"worker",E=(0,m.spawnToolMask)({kind:w?.type,hasTestProcess:"boolean"==typeof s.hasTestProcess?s.hasTestProcess:void 0});(0,m.hasMask)(E)&&d.info("session routing: narrowing the worker tool surface for this request",{requestId:s.requestId,worker:j,off:Object.keys(E)})
|
|
1989
1993
|
const A={p:s,req:w,worker:j,startPrompt:I,toolMask:E,deps:u}
|
|
@@ -8151,7 +8155,7 @@ if(!s)return{}
|
|
|
8151
8155
|
const n={}
|
|
8152
8156
|
for(const[e,o]of Object.entries(s))!0===r[e]&&(n[`${t}_${e}`]=o)
|
|
8153
8157
|
return n}
|
|
8154
|
-
const t=["run","list","setup","remove"],r={session_message_operations:["send","note","reply","list","get","record-decision","brief","withdraw","question","user-answers","escalate"],request_operations:["update","complete","merge","reopen","get-info","list","search","status","cancel","wait-on","clear-wait","premise-block","
|
|
8158
|
+
const t=["run","list","setup","remove"],r={session_message_operations:["send","note","reply","list","get","record-decision","brief","withdraw","question","user-answers","escalate"],request_operations:["update","complete","merge","reopen","get-info","list","search","status","cancel","wait-on","clear-wait","premise-block","bring-main-in","list-areas","update-areas","check-target","round-piece"],create_request:[],guidance:["propose","exception","conflict","outdated","list"],document_operations:["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"],commands:t}
|
|
8155
8159
|
exports.b={alchemist:{session_message_operations:["send","note","reply","list","get","record-decision","brief","withdraw","question","user-answers","escalate","plan-budget"],request_operations:["update","activate","complete","merge","revert","reopen","get-info","list","search","status","cancel","hold","premise-block","delete-empty","list-areas","update-areas","wait-on","clear-wait","hand-over","check-target","budget","target","arc-name","process","estimate"],create_request:["budget","estimate","schedule","delegate","refile","asked","process"],guidance:["propose","outdated","exception","conflict","list","standard","from-document","process"],document_operations:[...r.document_operations,"schedule"],commands:t},worker:r,coder:r,writer:r,reviewer:{session_message_operations:["send","note","reply","list","get","rule-verdicts"],guidance:["propose","list","standard"],document_operations:["search","get-history","get-version","list-annotations","create-annotation","reply-to-annotation","resolve-annotation","create-artifact-annotation"],record_criteria_verification:[]},driver:{commands:t},"auto-tester":{commands:t}},exports.REGISTER_BY_SETUP_RUN='Commands are saved by a setup run, not here: commands({ operation: "setup", context: "<the command, where it runs, what it is for>" }). Its setup architect tries the command in a box and saves it; you are told when it ends.',exports.REGISTER_BY_SETUP_RUN},82272(e,exports){"use strict"
|
|
8156
8160
|
exports.partMeta=function(e,t){return t?{alchemy:{kind:e,payload:t}}:{alchemy:{kind:e}}},exports.alchemyMeta=function(e){return{_meta:{alchemy:e}}},exports.withAlchemyKind=function(e,t,r){const s=e._meta,n=s?.alchemy??{}
|
|
8157
8161
|
return{...e,_meta:{...s,alchemy:{...n,...r,kind:t}}}}},39844(e,exports,t){"use strict"
|