@linzumi/cli 1.0.95 → 1.0.96
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/README.md +1 -1
- package/dist/index.js +2 -2
- package/dist/mcp-server.mjs +1 -1
- package/package.json +1 -1
- package/scripts/build-config-identity-parity-oracle.mjs +520 -0
package/README.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -987,7 +987,7 @@ query VmGoldenSelectByProject($projectId: ID!, $computeKey: String, $publicId: I
|
|
|
987
987
|
`)+1),fe=AU(Z.split(`
|
|
988
988
|
`)[0]??"");if(!k&&!a&&fe!==void 0){a=!0,d=fe.ok,u=fe.reason,c=fe.turnMs,S=!0,j({markerExit:!0});return}B=void 0}else if(W.startsWith("AGE")){let Z=Number.parseInt(W.slice(3).trim(),10);B=Number.isFinite(Z)&&Z<=y_e?"alive":"miss"}else W.startsWith("NONE")&&(B="miss")}catch{B=void 0}if(!(k||a)){if(B==="miss"){if(P+=1,P>=x_e){S=!0,q(new _t("cloud_turn_guest_vanished: no fresh guest heartbeat and no exit marker for this turn (half-open stream or dead guest); aborting and failing the turn (retryable)"));return}}else B==="alive"&&(P=0);R=setTimeout(()=>{E()},n.livenessPollMs??g_e),R.unref?.()}};R=setTimeout(()=>{E()},n.livenessStartupGraceMs??h_e),R.unref?.()});L.catch(()=>{});let D=()=>{k=!0,R!==void 0&&clearTimeout(R)};try{for(;;){let j=await Promise.race([w.next(),b,L]);if("markerExit"in j){Promise.resolve(w.return?.(void 0)).catch(()=>{});break}if(j.done===!0)break;let q=j.value;switch(q.kind){case"stdout":{l=MU(l+q.data),f+=q.data;let E;for(;(E=f.indexOf(`
|
|
989
989
|
`))>=0;)y(f.slice(0,E)),f=f.slice(E+1);break}case"stderr":p=MU(p+q.data);break;case"exit":m=q.exitCode;break;case"error":throw new _t(`guest exec stream error: ${q.message}`)}}f!==""&&y(f)}catch(j){throw S&&Promise.resolve(w.return?.(void 0)).catch(()=>{}),await EU(e),await DU(e,r),j instanceof _t?j:new _t(`guest exec stream dropped: ${j instanceof Error?j.message:String(j)}`)}finally{D(),v!==void 0&&clearTimeout(v)}if(await EU(e),await DU(e,r),m!==void 0&&m!==0)throw new _t(`guest turn exited non-zero (${m}): ${u}${p===""?"":` | ${p.slice(-300)}`}`);if(!a)throw new _t(`guest turn produced no terminal exit line${l===""?"":` | stdout: ${l.slice(-300)}`}`);if(!d)throw new _t(`guest turn failed: ${u}`);return{ok:!0,turnMs:c}}async function EU(e){await e.exec(wT(),{timeout:ST}).catch(()=>{})}async function DU(e,n){await e.exec(wU(n),{timeout:ST}).catch(()=>{})}function MU(e,n=4e3){return e.length>n?e.slice(e.length-n):e}function AU(e){let n=e.trim();if(n===""||n[0]!=="{")return;let t;try{t=JSON.parse(n)}catch{return}if(typeof t!="object"||t===null||t.phase!==kU)return;let r=t;return{ok:r.ok===!0,reason:typeof r.reason=="string"?r.reason:"",turnMs:typeof r.turnMs=="number"?r.turnMs:0}}var m_e,PU,ST,h_e,g_e,y_e,x_e,__e,b_e,_t,kT=F(()=>{"use strict";cd();vU();CU();m_e=600,PU=30,ST=15,h_e=45e3,g_e=5e3,y_e=30,x_e=2,__e=10,b_e=30*6e4;_t=class extends Error{retryable;constructor(n,t=!0){super(Mc(n)),this.name="CloudTurnError",this.retryable=t}}});import{randomBytes as k_e}from"node:crypto";import{existsSync as CT,mkdirSync as C_e,readFileSync as TT,renameSync as T_e,rmSync as P_e,writeFileSync as I_e}from"node:fs";import{homedir as R_e}from"node:os";import{dirname as E_e,join as D_e}from"node:path";function LU(){return D_e(R_e(),".linzumi","auth.json")}function Ac(e,n=LU()){if(!CT(n))return;let t=PT(TT(n,"utf8")),r=Fn(e),o=t.local_codex_runner?.[r];if(!(o===void 0||o.access_token.trim()==="")&&!(o.expires_at!==void 0&&Date.parse(o.expires_at)<=Date.now()))return{accessToken:o.access_token,kandanBaseUrl:r,issuedAt:o.issued_at,expiresAt:o.expires_at}}function jU(e){if(!CT(e))throw new Error(`missing personal-agent delegation auth file: ${e}`);let t=PT(TT(e,"utf8")).personal_agent_delegation;if(t===void 0||t.access_token.trim()==="")throw new Error("personal-agent delegation auth file is missing access_token");if(t.expires_at!==void 0&&Date.parse(t.expires_at)<=Date.now())throw new Error("personal-agent delegation auth file token is expired");return{accessToken:t.access_token,issuedAt:t.issued_at,expiresAt:t.expires_at}}function so(e){let n=e.authFilePath??LU(),t=CT(n)?PT(TT(n,"utf8")):{version:1},r=Fn(e.kandanUrl),o=new Date,i=e.expiresInSeconds===void 0?void 0:new Date(o.getTime()+e.expiresInSeconds*1e3).toISOString(),s={...t,version:1,local_codex_runner:{...t.local_codex_runner??{},[r]:{access_token:e.accessToken,issued_at:o.toISOString(),expires_at:i}}};C_e(E_e(n),{recursive:!0});let a=`${n}.tmp.${process.pid}.${k_e(6).toString("hex")}`;try{I_e(a,`${JSON.stringify(s,null,2)}
|
|
990
|
-
`,"utf8"),T_e(a,n)}catch(d){try{P_e(a,{force:!0})}catch{}throw d}return{accessToken:e.accessToken,kandanBaseUrl:r,issuedAt:o.toISOString(),expiresAt:i}}function PT(e){let n=JSON.parse(e);if(typeof n!="object"||n===null||Array.isArray(n))throw new Error("Kandan auth cache must contain a JSON object");let t=n,r=t.local_codex_runner,o=t.personal_agent_delegation;if(r!==void 0&&(typeof r!="object"||r===null||Array.isArray(r)))throw new Error("Kandan auth cache local_codex_runner must be an object");if(o!==void 0&&(typeof o!="object"||o===null||Array.isArray(o)))throw new Error("Kandan auth cache personal_agent_delegation must be an object");return{version:1,local_codex_runner:A_e(r),personal_agent_delegation:M_e(o)}}function M_e(e){if(typeof e!="object"||e===null||Array.isArray(e))return;let n=e.access_token,t=e.issued_at,r=e.expires_at;if(!(typeof n!="string"||typeof t!="string"))return{access_token:n,issued_at:t,expires_at:typeof r=="string"?r:void 0}}function A_e(e){if(!(typeof e!="object"||e===null||Array.isArray(e)))return Object.fromEntries(Object.entries(e).flatMap(([n,t])=>{if(typeof t!="object"||t===null||Array.isArray(t))return[];let r=t.access_token,o=t.issued_at,i=t.expires_at;return typeof r!="string"||typeof o!="string"?[]:[[n,{access_token:r,issued_at:o,expires_at:typeof i=="string"?i:void 0}]]}))}var ps=F(()=>{"use strict";wo()});import{randomUUID as O_e}from"node:crypto";import{mkdtempSync as $_e,readFileSync as L_e,rmSync as j_e}from"node:fs";import{tmpdir as F_e}from"node:os";import{join as FU}from"node:path";function z_e(e){let n=$_e(FU(F_e(),"linzumi-cloud-mcp-auth-"));try{let t=FU(n,"auth.json");return so({kandanUrl:e.kandanUrl,accessToken:e.accessToken,authFilePath:t}),L_e(t,"utf8")}finally{j_e(n,{recursive:!0,force:!0})}}function qU(e){let n=e.gateRegistry??q_e,t=e.ensureMachine??$x,r=e.provision??OU,o=e.run??$U,i=e.codexVersion??wc(),s={codexVersion:i,...e.cloudSupervisorBundlePath===void 0?{}:{cloudSupervisorBundlePath:e.cloudSupervisorBundlePath},...e.mcpServerBundlePath===void 0?{}:{mcpServerBundlePath:e.mcpServerBundlePath}};if(e.prewarm===!0&&!IT.has(e.workspaceSlug)){IT.add(e.workspaceSlug);let a=e.workspaceSlug,d=(async()=>{try{let u=await t(e.connection,{kind:"workspace-agent",workspacePublicId:a},e.agentSpec);await r(u.machine,s)}catch{IT.delete(a)}})();Fx.set(a,d),d.finally(()=>{Fx.get(a)===d&&Fx.delete(a)})}return async a=>{let d=a.kandanThreadId??`cloud-${O_e()}`;await n.gateForWorkspace(e.workspaceSlug).runTurn(d,async()=>{let u=Fx.get(e.workspaceSlug);u!==void 0&&await u.catch(()=>{});let c=await t(e.connection,{kind:"workspace-agent",workspacePublicId:e.workspaceSlug},e.agentSpec);await r(c.machine,s);let l=z_e({kandanUrl:e.kandanUrl,accessToken:e.linzumiAgentMcpToken});await o(c.machine,{codexVersion:i,input:a.input,...a.runtimeSettings.model===void 0?{}:{model:a.runtimeSettings.model},...a.runtimeSettings.reasoningEffort===void 0?{}:{reasoningEffort:a.runtimeSettings.reasoningEffort},sandbox:"danger-full-access",approvalPolicy:"never",kandanUrl:e.kandanUrl,...a.kandanThreadId===void 0?{}:{threadId:a.kandanThreadId},sourceSeq:a.sourceSeq,...a.codexThreadId===void 0?{}:{codexThreadId:a.codexThreadId},...e.ownerUsername===void 0?{}:{ownerUsername:e.ownerUsername},...e.turnTimeoutMs===void 0?{}:{turnTimeoutMs:e.turnTimeoutMs},cwd:_r,...e.modelProvider===void 0?{}:{modelProvider:e.modelProvider},mcpAuthFileContents:l,...e.llmProxyToken===void 0?{}:{llmProxyToken:e.llmProxyToken}})})}}function zU(e){return Dc({...e.env===void 0?{}:{env:e.env},config:e.config})}var IT,Fx,q_e,NU=F(()=>{"use strict";zf();cd();io();kT();ps();zf();IT=new Set,Fx=new Map,q_e=new Ox});async function B_e(e){let n=new Set,t=await e.serverLists.listWorkspaceIds(),r=await Promise.all(t.map(i=>e.serverLists.listProjectIds(i))),o=await Promise.all(r.flat().map(i=>e.query({projectId:i,computeKey:e.computeKey,explicitGoldenId:void 0})));for(let i of o){let s=i?.artifactRef;typeof s=="string"&&s.trim()!==""&&n.add(s.trim())}return[...n].sort()}async function J_e(e){let n=e.nowMs??Date.now,t=e.graceMs??U_e,r;try{r=await B_e({computeKey:e.computeKey,serverLists:e.serverLists,query:e.query})}catch(c){return e.log(`linzumi vm: golden GC cycle ABORTED (no goldens reaped) - keep-set fetch failed: ${RT(c)}`),{reaped:[],deleteFailures:[],aborted:!0}}let o=e.listPresent(),i=n()-t,s=o.filter(c=>c.registeredAtMs<=i).map(c=>c.name),a=hN(s,r);if(a.length===0)return{reaped:[],deleteFailures:[],aborted:!1};let d=[],u=[];for(let c of a)try{let l=await e.deleteMachine(c);e.unregister([c]),d.push(c),e.log(l==="deleted"?`linzumi vm: golden GC reaped orphaned golden machine ${c} (present on this compute, no longer in the server keep-set)`:`linzumi vm: golden GC dropped stale marker for ${c} (machine already gone)`)}catch(l){u.push(c),e.log(`linzumi vm: golden GC FAILED to delete orphaned golden machine ${c}: ${RT(l)} (marker kept; will retry next cycle)`)}return{reaped:d,deleteFailures:u,aborted:!1}}function UU(e){let n=e.intervalMs??N_e,t=!1,o=setInterval(()=>{t||(t=!0,J_e(e).catch(i=>{e.log("linzumi vm: golden GC cycle crashed unexpectedly: "+RT(i))}).finally(()=>{t=!1}))},n);return o.unref?.(),()=>clearInterval(o)}function K_e(e){let n=e.fetchImpl??fetch,t=jf(e.kandanUrl),r=async(o,i)=>{let s=await n(t,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.token}`},body:JSON.stringify({query:o,variables:i})});if(!s.ok)throw new Error(`golden GC GraphQL query failed: HTTP ${s.status} `+s.statusText);let a=await s.json();if(Array.isArray(a.errors)&&a.errors.length>0)throw new Error(`golden GC GraphQL query returned errors: ${a.errors.map(d=>d.message??"unknown").join("; ")}`);return a.data};return{listWorkspaceIds:async()=>((await r("query VmGoldenGcViewerWorkspaces { viewerWorkspaces { id } }",{}))?.viewerWorkspaces??[]).map(i=>i?.id).filter(i=>typeof i=="string"&&i!==""),listProjectIds:async o=>((await r(`query VmGoldenGcProjects($workspaceId: ID!) {
|
|
990
|
+
`,{encoding:"utf8",mode:384}),T_e(a,n)}catch(d){try{P_e(a,{force:!0})}catch{}throw d}return{accessToken:e.accessToken,kandanBaseUrl:r,issuedAt:o.toISOString(),expiresAt:i}}function PT(e){let n=JSON.parse(e);if(typeof n!="object"||n===null||Array.isArray(n))throw new Error("Kandan auth cache must contain a JSON object");let t=n,r=t.local_codex_runner,o=t.personal_agent_delegation;if(r!==void 0&&(typeof r!="object"||r===null||Array.isArray(r)))throw new Error("Kandan auth cache local_codex_runner must be an object");if(o!==void 0&&(typeof o!="object"||o===null||Array.isArray(o)))throw new Error("Kandan auth cache personal_agent_delegation must be an object");return{version:1,local_codex_runner:A_e(r),personal_agent_delegation:M_e(o)}}function M_e(e){if(typeof e!="object"||e===null||Array.isArray(e))return;let n=e.access_token,t=e.issued_at,r=e.expires_at;if(!(typeof n!="string"||typeof t!="string"))return{access_token:n,issued_at:t,expires_at:typeof r=="string"?r:void 0}}function A_e(e){if(!(typeof e!="object"||e===null||Array.isArray(e)))return Object.fromEntries(Object.entries(e).flatMap(([n,t])=>{if(typeof t!="object"||t===null||Array.isArray(t))return[];let r=t.access_token,o=t.issued_at,i=t.expires_at;return typeof r!="string"||typeof o!="string"?[]:[[n,{access_token:r,issued_at:o,expires_at:typeof i=="string"?i:void 0}]]}))}var ps=F(()=>{"use strict";wo()});import{randomUUID as O_e}from"node:crypto";import{mkdtempSync as $_e,readFileSync as L_e,rmSync as j_e}from"node:fs";import{tmpdir as F_e}from"node:os";import{join as FU}from"node:path";function z_e(e){let n=$_e(FU(F_e(),"linzumi-cloud-mcp-auth-"));try{let t=FU(n,"auth.json");return so({kandanUrl:e.kandanUrl,accessToken:e.accessToken,authFilePath:t}),L_e(t,"utf8")}finally{j_e(n,{recursive:!0,force:!0})}}function qU(e){let n=e.gateRegistry??q_e,t=e.ensureMachine??$x,r=e.provision??OU,o=e.run??$U,i=e.codexVersion??wc(),s={codexVersion:i,...e.cloudSupervisorBundlePath===void 0?{}:{cloudSupervisorBundlePath:e.cloudSupervisorBundlePath},...e.mcpServerBundlePath===void 0?{}:{mcpServerBundlePath:e.mcpServerBundlePath}};if(e.prewarm===!0&&!IT.has(e.workspaceSlug)){IT.add(e.workspaceSlug);let a=e.workspaceSlug,d=(async()=>{try{let u=await t(e.connection,{kind:"workspace-agent",workspacePublicId:a},e.agentSpec);await r(u.machine,s)}catch{IT.delete(a)}})();Fx.set(a,d),d.finally(()=>{Fx.get(a)===d&&Fx.delete(a)})}return async a=>{let d=a.kandanThreadId??`cloud-${O_e()}`;await n.gateForWorkspace(e.workspaceSlug).runTurn(d,async()=>{let u=Fx.get(e.workspaceSlug);u!==void 0&&await u.catch(()=>{});let c=await t(e.connection,{kind:"workspace-agent",workspacePublicId:e.workspaceSlug},e.agentSpec);await r(c.machine,s);let l=z_e({kandanUrl:e.kandanUrl,accessToken:e.linzumiAgentMcpToken});await o(c.machine,{codexVersion:i,input:a.input,...a.runtimeSettings.model===void 0?{}:{model:a.runtimeSettings.model},...a.runtimeSettings.reasoningEffort===void 0?{}:{reasoningEffort:a.runtimeSettings.reasoningEffort},sandbox:"danger-full-access",approvalPolicy:"never",kandanUrl:e.kandanUrl,...a.kandanThreadId===void 0?{}:{threadId:a.kandanThreadId},sourceSeq:a.sourceSeq,...a.codexThreadId===void 0?{}:{codexThreadId:a.codexThreadId},...e.ownerUsername===void 0?{}:{ownerUsername:e.ownerUsername},...e.turnTimeoutMs===void 0?{}:{turnTimeoutMs:e.turnTimeoutMs},cwd:_r,...e.modelProvider===void 0?{}:{modelProvider:e.modelProvider},mcpAuthFileContents:l,...e.llmProxyToken===void 0?{}:{llmProxyToken:e.llmProxyToken}})})}}function zU(e){return Dc({...e.env===void 0?{}:{env:e.env},config:e.config})}var IT,Fx,q_e,NU=F(()=>{"use strict";zf();cd();io();kT();ps();zf();IT=new Set,Fx=new Map,q_e=new Ox});async function B_e(e){let n=new Set,t=await e.serverLists.listWorkspaceIds(),r=await Promise.all(t.map(i=>e.serverLists.listProjectIds(i))),o=await Promise.all(r.flat().map(i=>e.query({projectId:i,computeKey:e.computeKey,explicitGoldenId:void 0})));for(let i of o){let s=i?.artifactRef;typeof s=="string"&&s.trim()!==""&&n.add(s.trim())}return[...n].sort()}async function J_e(e){let n=e.nowMs??Date.now,t=e.graceMs??U_e,r;try{r=await B_e({computeKey:e.computeKey,serverLists:e.serverLists,query:e.query})}catch(c){return e.log(`linzumi vm: golden GC cycle ABORTED (no goldens reaped) - keep-set fetch failed: ${RT(c)}`),{reaped:[],deleteFailures:[],aborted:!0}}let o=e.listPresent(),i=n()-t,s=o.filter(c=>c.registeredAtMs<=i).map(c=>c.name),a=hN(s,r);if(a.length===0)return{reaped:[],deleteFailures:[],aborted:!1};let d=[],u=[];for(let c of a)try{let l=await e.deleteMachine(c);e.unregister([c]),d.push(c),e.log(l==="deleted"?`linzumi vm: golden GC reaped orphaned golden machine ${c} (present on this compute, no longer in the server keep-set)`:`linzumi vm: golden GC dropped stale marker for ${c} (machine already gone)`)}catch(l){u.push(c),e.log(`linzumi vm: golden GC FAILED to delete orphaned golden machine ${c}: ${RT(l)} (marker kept; will retry next cycle)`)}return{reaped:d,deleteFailures:u,aborted:!1}}function UU(e){let n=e.intervalMs??N_e,t=!1,o=setInterval(()=>{t||(t=!0,J_e(e).catch(i=>{e.log("linzumi vm: golden GC cycle crashed unexpectedly: "+RT(i))}).finally(()=>{t=!1}))},n);return o.unref?.(),()=>clearInterval(o)}function K_e(e){let n=e.fetchImpl??fetch,t=jf(e.kandanUrl),r=async(o,i)=>{let s=await n(t,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.token}`},body:JSON.stringify({query:o,variables:i})});if(!s.ok)throw new Error(`golden GC GraphQL query failed: HTTP ${s.status} `+s.statusText);let a=await s.json();if(Array.isArray(a.errors)&&a.errors.length>0)throw new Error(`golden GC GraphQL query returned errors: ${a.errors.map(d=>d.message??"unknown").join("; ")}`);return a.data};return{listWorkspaceIds:async()=>((await r("query VmGoldenGcViewerWorkspaces { viewerWorkspaces { id } }",{}))?.viewerWorkspaces??[]).map(i=>i?.id).filter(i=>typeof i=="string"&&i!==""),listProjectIds:async o=>((await r(`query VmGoldenGcProjects($workspaceId: ID!) {
|
|
991
991
|
projects(workspaceId: $workspaceId, first: 200) {
|
|
992
992
|
edges { node { id } }
|
|
993
993
|
}
|
|
@@ -1470,7 +1470,7 @@ To kick the agent off:
|
|
|
1470
1470
|
`,L=Buffer.byteLength(P,"utf8");if(L>s)return l("runner_diagnostics.spool_entry_dropped",{reason:"entry_too_large",entry_bytes:L,max_entry_bytes:s}),!1;Qve(n,{recursive:!0}),m(u)+L>i&&f(),_(L);let D=w()?`
|
|
1471
1471
|
`:"";return Hve(u,`${D}${P}`,"utf8"),!0}catch(R){return l("runner_diagnostics.spool_failed",{error:R instanceof Error?R.message:String(R)}),!1}},v=k=>{let R=[],P=Yve(k,"utf8");for(let L of P.split(`
|
|
1472
1472
|
`))if(L.trim()!=="")try{let D=JSON.parse(L);D!==null&&typeof D=="object"&&R.push({parsed:D,raw:L})}catch{}return R};return{append:S,drain:async k=>{if(c)return{uploadedBatches:0,uploadedEntries:0,remainingBatches:p().length,skipped:!0};c=!0;let R=0,P=0;try{f(),_(0);let L=a()-o;for(let D of p()){let j;try{j=v(D)}catch(Z){l("runner_diagnostics.spool_batch_unreadable",{file:D,error:Z instanceof Error?Z.message:String(Z)}),y(D,"unreadable");continue}let q=j.filter(Z=>{let fe=gSe(Z.parsed);return fe===void 0||fe>=L});if(q.length===0){y(D,"empty_or_expired");continue}let E=QT(D,".jsonl"),B=q.map(Z=>Z.raw).join(`
|
|
1473
|
-
`),z=q.map(Z=>Z.parsed.spooled_at).filter(Z=>typeof Z=="string"),W={bundle_name:"runner-diagnostics-spool",exported_at:new Date(a()).toISOString(),idempotency_key:E,diagnostics:{kind:"runner_diagnostic_log",spool_batch:!0,idempotency_key:E,entry_count:q.length,...z.length===0?{}:{first_spooled_at:z[0],last_spooled_at:z[z.length-1]}},telemetry_ndjson:B};try{await k(W)}catch(Z){l("runner_diagnostics.spool_upload_failed",{file:D,remaining_batches:p().length,error:Z instanceof Error?Z.message:String(Z)});break}R+=1,P+=q.length;try{i9(D)}catch(Z){l("runner_diagnostics.spool_delete_failed",{file:D,error:Z instanceof Error?Z.message:String(Z)})}}}catch(L){l("runner_diagnostics.spool_drain_failed",{error:L instanceof Error?L.message:String(L)})}finally{c=!1}return{uploadedBatches:R,uploadedEntries:P,remainingBatches:p().length,skipped:!1}},pendingBatchFiles:p}}var iSe,sSe,aSe,dSe,uSe,s9,lSe,pSe,d9=F(()=>{"use strict";Hy();iSe=32*1024*1024,sSe=10080*60*1e3,aSe=4*1024*1024,dSe=1024*1024,uSe="spool.jsonl",s9=/^batch-(\d{1,16})-[0-9a-f-]+\.jsonl$/;lSe=/\b([A-Z][A-Z0-9_]{1,})=("[^"\n]*"|'[^'\n]*'|[^\s"'`;,)\]}]+)/g,pSe=/(?:\/(?:[A-Za-z0-9._@~+-]|%[0-9A-Fa-f]{2})+){2,}/g});var jt,YT,ea=F(()=>{"use strict";jt="1.0.
|
|
1473
|
+
`),z=q.map(Z=>Z.parsed.spooled_at).filter(Z=>typeof Z=="string"),W={bundle_name:"runner-diagnostics-spool",exported_at:new Date(a()).toISOString(),idempotency_key:E,diagnostics:{kind:"runner_diagnostic_log",spool_batch:!0,idempotency_key:E,entry_count:q.length,...z.length===0?{}:{first_spooled_at:z[0],last_spooled_at:z[z.length-1]}},telemetry_ndjson:B};try{await k(W)}catch(Z){l("runner_diagnostics.spool_upload_failed",{file:D,remaining_batches:p().length,error:Z instanceof Error?Z.message:String(Z)});break}R+=1,P+=q.length;try{i9(D)}catch(Z){l("runner_diagnostics.spool_delete_failed",{file:D,error:Z instanceof Error?Z.message:String(Z)})}}}catch(L){l("runner_diagnostics.spool_drain_failed",{error:L instanceof Error?L.message:String(L)})}finally{c=!1}return{uploadedBatches:R,uploadedEntries:P,remainingBatches:p().length,skipped:!1}},pendingBatchFiles:p}}var iSe,sSe,aSe,dSe,uSe,s9,lSe,pSe,d9=F(()=>{"use strict";Hy();iSe=32*1024*1024,sSe=10080*60*1e3,aSe=4*1024*1024,dSe=1024*1024,uSe="spool.jsonl",s9=/^batch-(\d{1,16})-[0-9a-f-]+\.jsonl$/;lSe=/\b([A-Z][A-Z0-9_]{1,})=("[^"\n]*"|'[^'\n]*'|[^\s"'`;,)\]}]+)/g,pSe=/(?:\/(?:[A-Za-z0-9._@~+-]|%[0-9A-Fa-f]{2})+){2,}/g});var jt,YT,ea=F(()=>{"use strict";jt="1.0.96",YT=`linzumi ${jt}`});import{closeSync as c9,existsSync as nP,mkdirSync as ySe,openSync as l9,readFileSync as p9,renameSync as xSe,unlinkSync as md,writeFileSync as _Se,writeSync as f9}from"node:fs";import{dirname as m9,join as bSe}from"node:path";function tP(e){return e instanceof hs||e instanceof Error&&e.name===g9&&"lockPath"in e&&"heldBy"in e}function rP(e,n=Vn(),t){let r=t===void 0?encodeURIComponent(e):ad(t);return bSe(m9(n),"runners",`${r}.lock`)}function o0(e){let n=rP(e.machineId,e.configPath,e.linzumiUrl),t=e.isPidAlive??S9,r=e.now??(()=>new Date),o=e.killPid??ASe,i=r().toISOString(),s={version:1,machineId:e.machineId,runnerId:e.runnerId,pid:e.pid??process.pid,cwd:e.cwd,workspace:e.workspace,...e.linzumiUrl===void 0?{}:{linzumiUrl:Fn(e.linzumiUrl)},...e.launchSource===void 0?{}:{launchSource:e.launchSource},startedAt:i,heartbeatAt:i,cliVersion:e.cliVersion??jt,...e.gracefulUpdateDrain===!0?{gracefulUpdateDrain:!0}:{}};kSe(e.machineId,e.configPath,e.linzumiUrl,t,r,o,e.onTakeover),CSe(n,s,t,r,o,e.onTakeover,e.beforeReadExistingLock,e.beforeReplaceStaleLock);let a=()=>y9(n,s,r),d=setInterval(a,h9);return d.unref(),{path:n,record:s,heartbeat:a,release:()=>{clearInterval(d),w9(n,s)}}}function y9(e,n,t){try{let r=s0(e);if(r===void 0||r.machineId!==n.machineId||r.runnerId!==n.runnerId||r.pid!==n.pid||r.startedAt!==n.startedAt)return;let o={...r,heartbeatAt:t().toISOString()},i=`${e}.tmp`;_Se(i,`${JSON.stringify(o,null,2)}
|
|
1474
1474
|
`,"utf8"),xSe(i,e)}catch{}}function hd(e,n,t){if(!n(e.pid))return{state:"dead"};let r=e.heartbeatAt??e.startedAt,o=Date.parse(r);return Number.isNaN(o)||t().getTime()-o>wSe?{state:"wedged",reason:e.heartbeatAt===void 0?"missing_heartbeat":"stale_heartbeat"}:{state:"live"}}function x9(e,n,t,r){return t!==i0||e.launchSource!==i0?!1:r.state!=="live"?!0:vSe(n,e.cliVersion)>0}function vSe(e,n){let t=u9(e),r=u9(n);for(let o=0;o<3;o++){let i=t.core[o],s=r.core[o];if(i===void 0||s===void 0)throw new Error(`compareCliVersions: unexpected undefined at core index ${o}`);if(i!==s)return i>s?1:-1}return t.prerelease.length===0&&r.prerelease.length===0?0:t.prerelease.length===0?1:r.prerelease.length===0?-1:SSe(t.prerelease,r.prerelease)}function u9(e){let n=e.trim().replace(/^v/i,"").split("+",1)[0]??"",t=n.indexOf("-"),r=t===-1?n:n.slice(0,t),o=t===-1?"":n.slice(t+1),i=r.split("."),s=[eP(i[0]),eP(i[1]),eP(i[2])],a=o===""?[]:o.split(".").filter(d=>d!=="");return{core:s,prerelease:a}}function eP(e){let n=Number.parseInt(e??"",10);return Number.isInteger(n)&&n>=0?n:0}function SSe(e,n){let t=Math.max(e.length,n.length);for(let r=0;r<t;r++){let o=e[r],i=n[r];if(o===void 0)return-1;if(i===void 0)return 1;let s=Number.parseInt(o,10),a=Number.parseInt(i,10),d=s.toString()===o,u=a.toString()===i;if(d&&u){if(s!==a)return s>a?1:-1}else{if(d!==u)return d?-1:1;if(o!==i)return o>i?1:-1}}return 0}function _9(e,n,t,r,o){try{r(n.pid)}catch(i){let s=i!==null&&typeof i=="object"&&"code"in i?i.code:void 0;if(s!=="ESRCH")throw s==="EPERM"||s==="EACCES"?new Error(`Cannot take over the runner lock at ${e}: its holder process (pid ${n.pid}) is owned by another user and cannot be stopped. Stop that process, or remove the lock file, then retry.`):i}o?.({lockPath:e,holderPid:n.pid,holderRunnerId:n.runnerId,reason:t})}function kSe(e,n,t,r,o,i,s){if(t===void 0||yr(t)!==yr(Bt))return;let a=rP(e,n),d=s0(a);if(d!==void 0){if(hd(d,r,o).state==="live")throw new hs(a,d);b9(a,r,()=>{let u=nP(a)?oP(a):void 0;if(u===void 0)return;let c=hd(u,r,o);if(c.state==="live")throw new hs(a,u);c.state==="wedged"&&_9(a,u,c.reason,i,s),md(a)})}}function CSe(e,n,t,r,o,i,s,a){if(r0(e,n))return;s?.();let d=s0(e);if(d===void 0){if(r0(e,n))return;throw new Error(`another Linzumi runner lock appeared while starting: ${e}`)}if(hd(d,t,r).state==="live")throw new hs(e,d);a?.(),b9(e,t,()=>{let u=nP(e)?oP(e):void 0;if(u!==void 0){let c=hd(u,t,r);if(c.state==="live")throw new hs(e,u);c.state==="wedged"&&_9(e,u,c.reason,o,i),md(e)}if(!r0(e,n))throw new Error(`another Linzumi runner lock appeared while starting: ${e}`)})}function r0(e,n){ySe(m9(e),{recursive:!0});try{let t=l9(e,"wx");try{f9(t,`${JSON.stringify(n,null,2)}
|
|
1475
1475
|
`)}finally{c9(t)}return!0}catch(t){if(zc(t,"EEXIST"))return!1;throw t}}function b9(e,n,t){let r=`${e}.replace`;for(;;)try{let o=l9(r,"wx");try{f9(o,`${process.pid}
|
|
1476
1476
|
`),t()}finally{c9(o),md(r)}return}catch(o){if(zc(o,"EEXIST")){let i=TSe(r);if(i===void 0)continue;if(n(i))throw new Error(["another Linzumi runner is already replacing a stale runner lock",`lock: ${e}`,"Wait for that startup to finish, then retry."].join(`
|
package/dist/mcp-server.mjs
CHANGED
|
@@ -145,7 +145,7 @@ ${o}
|
|
|
145
145
|
</main>
|
|
146
146
|
</body>
|
|
147
147
|
</html>`}function cl(e){return e.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">")}function ST(e){return e.replace(/[&^|<>()%"]/g,t=>`^${t}`)}function $T(e){let t=process.platform==="darwin"?"open":process.platform==="win32"?"cmd":"xdg-open",r=process.platform==="win32"?["/c","start","",ST(e)]:[e];return new Promise(n=>{il("process.spawn",{command:t,args:r,purpose:"oauth.open_browser"});let o=lT(t,r,{stdio:"ignore",detached:!0});il("process.spawned",{command:t,args:r,pid:o.pid,purpose:"oauth.open_browser"}),o.on("error",()=>n()),o.on("spawn",()=>{o.unref(),n()})})}function Fy(){return jT(ET(),".linzumi","auth.json")}function xi(e,t=Fy()){if(!dl(t))return;let r=pl(ll(t,"utf8")),n=Ve(e),o=r.local_codex_runner?.[n];if(!(o===void 0||o.access_token.trim()==="")&&!(o.expires_at!==void 0&&Date.parse(o.expires_at)<=Date.now()))return{accessToken:o.access_token,kandanBaseUrl:n,issuedAt:o.issued_at,expiresAt:o.expires_at}}function Vy(e){if(!dl(e))throw new Error(`missing personal-agent delegation auth file: ${e}`);let r=pl(ll(e,"utf8")).personal_agent_delegation;if(r===void 0||r.access_token.trim()==="")throw new Error("personal-agent delegation auth file is missing access_token");if(r.expires_at!==void 0&&Date.parse(r.expires_at)<=Date.now())throw new Error("personal-agent delegation auth file token is expired");return{accessToken:r.access_token,issuedAt:r.issued_at,expiresAt:r.expires_at}}function By(e){let t=e.authFilePath??Fy(),r=dl(t)?pl(ll(t,"utf8")):{version:1},n=Ve(e.kandanUrl),o=new Date,s=e.expiresInSeconds===void 0?void 0:new Date(o.getTime()+e.expiresInSeconds*1e3).toISOString(),i={...r,version:1,local_codex_runner:{...r.local_codex_runner??{},[n]:{access_token:e.accessToken,issued_at:o.toISOString(),expires_at:s}}};PT(OT(t),{recursive:!0});let a=`${t}.tmp.${process.pid}.${zT(6).toString("hex")}`;try{IT(a,`${JSON.stringify(i,null,2)}
|
|
148
|
-
`,"utf8"),TT(a,t)}catch(c){try{RT(a,{force:!0})}catch{}throw c}return{accessToken:e.accessToken,kandanBaseUrl:n,issuedAt:o.toISOString(),expiresAt:s}}function pl(e){let t=JSON.parse(e);if(typeof t!="object"||t===null||Array.isArray(t))throw new Error("Kandan auth cache must contain a JSON object");let r=t,n=r.local_codex_runner,o=r.personal_agent_delegation;if(n!==void 0&&(typeof n!="object"||n===null||Array.isArray(n)))throw new Error("Kandan auth cache local_codex_runner must be an object");if(o!==void 0&&(typeof o!="object"||o===null||Array.isArray(o)))throw new Error("Kandan auth cache personal_agent_delegation must be an object");return{version:1,local_codex_runner:AT(n),personal_agent_delegation:CT(o)}}function CT(e){if(typeof e!="object"||e===null||Array.isArray(e))return;let t=e.access_token,r=e.issued_at,n=e.expires_at;if(!(typeof t!="string"||typeof r!="string"))return{access_token:t,issued_at:r,expires_at:typeof n=="string"?n:void 0}}function AT(e){if(!(typeof e!="object"||e===null||Array.isArray(e)))return Object.fromEntries(Object.entries(e).flatMap(([t,r])=>{if(typeof r!="object"||r===null||Array.isArray(r))return[];let n=r.access_token,o=r.issued_at,s=r.expires_at;return typeof n!="string"||typeof o!="string"?[]:[[t,{access_token:n,issued_at:o,expires_at:typeof s=="string"?s:void 0}]]}))}var MT=3,NT=3600*1e3,LT=5e3,DT=5e3,ZT=6e4;function UT(e){return e.cycle<=MT?"prompt":e.lastLoudPromptAtMs===void 0||e.nowMs-e.lastLoudPromptAtMs>=NT?"summary":e.isInteractive?"refresh_line":"silent"}function qT(e){switch(e.kind){case"prompt":return`${e.cycle===1?"":`The previous code expired; here is a fresh one (no restart needed - this prompt stays alive).
|
|
148
|
+
`,{encoding:"utf8",mode:384}),TT(a,t)}catch(c){try{RT(a,{force:!0})}catch{}throw c}return{accessToken:e.accessToken,kandanBaseUrl:n,issuedAt:o.toISOString(),expiresAt:s}}function pl(e){let t=JSON.parse(e);if(typeof t!="object"||t===null||Array.isArray(t))throw new Error("Kandan auth cache must contain a JSON object");let r=t,n=r.local_codex_runner,o=r.personal_agent_delegation;if(n!==void 0&&(typeof n!="object"||n===null||Array.isArray(n)))throw new Error("Kandan auth cache local_codex_runner must be an object");if(o!==void 0&&(typeof o!="object"||o===null||Array.isArray(o)))throw new Error("Kandan auth cache personal_agent_delegation must be an object");return{version:1,local_codex_runner:AT(n),personal_agent_delegation:CT(o)}}function CT(e){if(typeof e!="object"||e===null||Array.isArray(e))return;let t=e.access_token,r=e.issued_at,n=e.expires_at;if(!(typeof t!="string"||typeof r!="string"))return{access_token:t,issued_at:r,expires_at:typeof n=="string"?n:void 0}}function AT(e){if(!(typeof e!="object"||e===null||Array.isArray(e)))return Object.fromEntries(Object.entries(e).flatMap(([t,r])=>{if(typeof r!="object"||r===null||Array.isArray(r))return[];let n=r.access_token,o=r.issued_at,s=r.expires_at;return typeof n!="string"||typeof o!="string"?[]:[[t,{access_token:n,issued_at:o,expires_at:typeof s=="string"?s:void 0}]]}))}var MT=3,NT=3600*1e3,LT=5e3,DT=5e3,ZT=6e4;function UT(e){return e.cycle<=MT?"prompt":e.lastLoudPromptAtMs===void 0||e.nowMs-e.lastLoudPromptAtMs>=NT?"summary":e.isInteractive?"refresh_line":"silent"}function qT(e){switch(e.kind){case"prompt":return`${e.cycle===1?"":`The previous code expired; here is a fresh one (no restart needed - this prompt stays alive).
|
|
149
149
|
`}Authorize this computer:
|
|
150
150
|
Code: ${e.userCode}
|
|
151
151
|
Open: ${e.verificationUri}
|
package/package.json
CHANGED
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
// Spec: kandan/plans/2026-07-10-compute-nodes-rescript-commander-zero-ts-program.md
|
|
2
|
+
// (M3 cluster 2, config-identity).
|
|
3
|
+
// Relationship: Builds the TS-side PARITY ORACLE for the config/identity
|
|
4
|
+
// cluster of the ReScript commander port, the sibling of
|
|
5
|
+
// build-protocol-parity-oracle.mjs (cluster 1). The oracle bundles the REAL
|
|
6
|
+
// TS config/identity modules (localConfig.ts, machineFingerprint.ts,
|
|
7
|
+
// machineFingerprintV2.ts, authCache.ts, the cursor-store exports of
|
|
8
|
+
// runner.ts, controlQuarantine.ts's state-file stem, updateNudge.ts's
|
|
9
|
+
// restart-attempt store) behind a one-shot batch driver: a JSON array of
|
|
10
|
+
// cases on stdin, a JSON array of results on stdout. The ReScript package's
|
|
11
|
+
// ConfigIdentityParityConformance drives the SAME inputs through the ported
|
|
12
|
+
// modules in its own scratch directories and asserts
|
|
13
|
+
// accept/reject/normalized-output equivalence AND byte-identical file
|
|
14
|
+
// output - the cross-impl round-trip contract that lets both commanders
|
|
15
|
+
// share ~/.linzumi through M4.
|
|
16
|
+
//
|
|
17
|
+
// Determinism: every source of nondeterminism is pinned per case - id
|
|
18
|
+
// creators are injected constants, timestamps come from a fixed `nowMs`
|
|
19
|
+
// (writeLocalSignupAuth's injectable `now`; a scoped global-Date override
|
|
20
|
+
// for authCache, whose issuedAt is not injectable), and scratch paths are
|
|
21
|
+
// normalized through the "$DIR" placeholder in both directions.
|
|
22
|
+
//
|
|
23
|
+
// SECRETS: the oracle only ever sees the conformance suite's synthetic
|
|
24
|
+
// tokens; nothing here logs case payloads.
|
|
25
|
+
//
|
|
26
|
+
// Like the cluster 1 oracle, the output is a local test artifact
|
|
27
|
+
// (.differential/ is gitignored, never published) and stays unminified for
|
|
28
|
+
// debuggability.
|
|
29
|
+
import { copyFile, mkdir } from 'node:fs/promises';
|
|
30
|
+
import { dirname, join } from 'node:path';
|
|
31
|
+
import { fileURLToPath } from 'node:url';
|
|
32
|
+
import { build } from 'esbuild';
|
|
33
|
+
|
|
34
|
+
const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
35
|
+
|
|
36
|
+
const driverSource = `
|
|
37
|
+
import {
|
|
38
|
+
mkdtempSync,
|
|
39
|
+
mkdirSync,
|
|
40
|
+
readdirSync,
|
|
41
|
+
readFileSync,
|
|
42
|
+
realpathSync,
|
|
43
|
+
statSync,
|
|
44
|
+
writeFileSync,
|
|
45
|
+
} from 'node:fs';
|
|
46
|
+
import { tmpdir } from 'node:os';
|
|
47
|
+
import { join, relative } from 'node:path';
|
|
48
|
+
import {
|
|
49
|
+
addAllowedCwd,
|
|
50
|
+
addAllowedCwdForLinzumiUrl,
|
|
51
|
+
ensureLocalMachineId,
|
|
52
|
+
ensureLocalMachineIdForLinzumiUrl,
|
|
53
|
+
ensureLocalRunnerId,
|
|
54
|
+
ensureLocalRunnerIdForLinzumiUrl,
|
|
55
|
+
localMachineIdSeedPath,
|
|
56
|
+
localRunnerIdSeedPath,
|
|
57
|
+
readConfiguredAllowedCwdDetails,
|
|
58
|
+
readConfiguredAllowedCwdDetailsForLinzumiUrl,
|
|
59
|
+
readLocalConfig,
|
|
60
|
+
readLocalConfigForLinzumiUrl,
|
|
61
|
+
readLocalSignupAuth,
|
|
62
|
+
removeAllowedCwd,
|
|
63
|
+
removeAllowedCwdForLinzumiUrl,
|
|
64
|
+
replaceAllowedCwdsForLinzumiUrl,
|
|
65
|
+
writeLocalConfig,
|
|
66
|
+
writeLocalSignupAuth,
|
|
67
|
+
writeLocalSignupCompletion,
|
|
68
|
+
} from './src/localConfig';
|
|
69
|
+
import {
|
|
70
|
+
rawStableMachineIdentifier,
|
|
71
|
+
stableMachineFingerprint,
|
|
72
|
+
stableMachineId,
|
|
73
|
+
} from './src/machineFingerprint';
|
|
74
|
+
import {
|
|
75
|
+
machineFingerprintV2HelloFields,
|
|
76
|
+
rawOsUsername,
|
|
77
|
+
stableMachineFingerprintV2,
|
|
78
|
+
} from './src/machineFingerprintV2';
|
|
79
|
+
import {
|
|
80
|
+
readCachedLocalRunnerToken,
|
|
81
|
+
readPersonalAgentDelegationToken,
|
|
82
|
+
writeCachedLocalRunnerToken,
|
|
83
|
+
} from './src/authCache';
|
|
84
|
+
import {
|
|
85
|
+
createControlCursorFileStore,
|
|
86
|
+
createRunnerControlEpochStore,
|
|
87
|
+
} from './src/runner';
|
|
88
|
+
import { runnerStateFileStem } from './src/controlQuarantine';
|
|
89
|
+
import { fileRestartAttemptStore } from './src/updateNudge';
|
|
90
|
+
|
|
91
|
+
// --- Placeholder + snapshot plumbing --------------------------------------------
|
|
92
|
+
|
|
93
|
+
const dirPlaceholder = '$DIR';
|
|
94
|
+
|
|
95
|
+
function scratch() {
|
|
96
|
+
// realpath so macOS /var -> /private/var never splits the two impls'
|
|
97
|
+
// placeholder substitution.
|
|
98
|
+
return realpathSync(mkdtempSync(join(tmpdir(), 'linzumi-config-identity-oracle-')));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function substitute(value, from, to) {
|
|
102
|
+
if (typeof value === 'string') {
|
|
103
|
+
return value.split(from).join(to);
|
|
104
|
+
}
|
|
105
|
+
if (Array.isArray(value)) {
|
|
106
|
+
return value.map((entry) => substitute(entry, from, to));
|
|
107
|
+
}
|
|
108
|
+
if (typeof value === 'object' && value !== null) {
|
|
109
|
+
return Object.fromEntries(
|
|
110
|
+
Object.entries(value).map(([key, entry]) => [
|
|
111
|
+
substitute(key, from, to),
|
|
112
|
+
substitute(entry, from, to),
|
|
113
|
+
])
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
return value;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function snapshotFiles(dir) {
|
|
120
|
+
const files = {};
|
|
121
|
+
const walk = (current) => {
|
|
122
|
+
for (const name of readdirSync(current).sort()) {
|
|
123
|
+
const full = join(current, name);
|
|
124
|
+
if (statSync(full).isDirectory()) {
|
|
125
|
+
walk(full);
|
|
126
|
+
} else {
|
|
127
|
+
files[relative(dir, full)] = readFileSync(full, 'utf8');
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
walk(dir);
|
|
132
|
+
return files;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function outcome(run) {
|
|
136
|
+
try {
|
|
137
|
+
const value = run();
|
|
138
|
+
return value === undefined ? { defined: false } : { defined: true, value };
|
|
139
|
+
} catch (error) {
|
|
140
|
+
return {
|
|
141
|
+
threw: true,
|
|
142
|
+
message: error instanceof Error ? error.message : String(error),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const RealDate = Date;
|
|
148
|
+
|
|
149
|
+
function withFixedNow(nowMs, run) {
|
|
150
|
+
if (nowMs === undefined) {
|
|
151
|
+
return run();
|
|
152
|
+
}
|
|
153
|
+
class FixedDate extends RealDate {
|
|
154
|
+
constructor(...args) {
|
|
155
|
+
if (args.length === 0) {
|
|
156
|
+
super(nowMs);
|
|
157
|
+
} else {
|
|
158
|
+
super(...args);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
static now() {
|
|
162
|
+
return nowMs;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
globalThis.Date = FixedDate;
|
|
166
|
+
try {
|
|
167
|
+
return run();
|
|
168
|
+
} finally {
|
|
169
|
+
globalThis.Date = RealDate;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// --- Config lifecycle ------------------------------------------------------------
|
|
174
|
+
|
|
175
|
+
function runConfigAction(action, dir, configPath) {
|
|
176
|
+
switch (action.fn) {
|
|
177
|
+
case 'mkdir':
|
|
178
|
+
// Setup helper (not a ported function): void the created-path return
|
|
179
|
+
// so both impls report the same undefined outcome.
|
|
180
|
+
return outcome(() => {
|
|
181
|
+
mkdirSync(action.path, { recursive: true });
|
|
182
|
+
});
|
|
183
|
+
case 'writeFile':
|
|
184
|
+
return outcome(() => writeFileSync(action.path, action.contents, 'utf8'));
|
|
185
|
+
case 'ensureLocalMachineId':
|
|
186
|
+
return outcome(() =>
|
|
187
|
+
ensureLocalMachineId(configPath, () => action.machineId)
|
|
188
|
+
);
|
|
189
|
+
case 'ensureLocalMachineIdForLinzumiUrl':
|
|
190
|
+
return outcome(() =>
|
|
191
|
+
ensureLocalMachineIdForLinzumiUrl(
|
|
192
|
+
action.linzumiUrl,
|
|
193
|
+
configPath,
|
|
194
|
+
() => action.machineId
|
|
195
|
+
)
|
|
196
|
+
);
|
|
197
|
+
case 'ensureLocalRunnerId':
|
|
198
|
+
return outcome(() =>
|
|
199
|
+
ensureLocalRunnerId(configPath, () => action.runnerId)
|
|
200
|
+
);
|
|
201
|
+
case 'ensureLocalRunnerIdForLinzumiUrl':
|
|
202
|
+
return outcome(() =>
|
|
203
|
+
ensureLocalRunnerIdForLinzumiUrl(
|
|
204
|
+
action.linzumiUrl,
|
|
205
|
+
configPath,
|
|
206
|
+
() => action.runnerId
|
|
207
|
+
)
|
|
208
|
+
);
|
|
209
|
+
case 'machineIdSeedPath':
|
|
210
|
+
return outcome(() => localMachineIdSeedPath(configPath, action.linzumiUrl));
|
|
211
|
+
case 'runnerIdSeedPath':
|
|
212
|
+
return outcome(() => localRunnerIdSeedPath(configPath, action.linzumiUrl));
|
|
213
|
+
case 'writeLocalConfig':
|
|
214
|
+
return outcome(() => writeLocalConfig(action.config, configPath));
|
|
215
|
+
case 'addAllowedCwd':
|
|
216
|
+
return outcome(() => addAllowedCwd(action.pathValue, configPath));
|
|
217
|
+
case 'addAllowedCwdForLinzumiUrl':
|
|
218
|
+
return outcome(() =>
|
|
219
|
+
addAllowedCwdForLinzumiUrl(action.pathValue, action.linzumiUrl, configPath)
|
|
220
|
+
);
|
|
221
|
+
case 'removeAllowedCwd':
|
|
222
|
+
return outcome(() => removeAllowedCwd(action.pathValue, configPath));
|
|
223
|
+
case 'removeAllowedCwdForLinzumiUrl':
|
|
224
|
+
return outcome(() =>
|
|
225
|
+
removeAllowedCwdForLinzumiUrl(action.pathValue, action.linzumiUrl, configPath)
|
|
226
|
+
);
|
|
227
|
+
case 'replaceAllowedCwdsForLinzumiUrl':
|
|
228
|
+
return outcome(() =>
|
|
229
|
+
replaceAllowedCwdsForLinzumiUrl(action.pathValues, action.linzumiUrl, configPath)
|
|
230
|
+
);
|
|
231
|
+
case 'readLocalConfig':
|
|
232
|
+
return outcome(() => readLocalConfig(configPath));
|
|
233
|
+
case 'readLocalConfigForLinzumiUrl':
|
|
234
|
+
return outcome(() => readLocalConfigForLinzumiUrl(action.linzumiUrl, configPath));
|
|
235
|
+
case 'readConfiguredAllowedCwdDetails':
|
|
236
|
+
return outcome(() => readConfiguredAllowedCwdDetails(configPath));
|
|
237
|
+
case 'readConfiguredAllowedCwdDetailsForLinzumiUrl':
|
|
238
|
+
return outcome(() =>
|
|
239
|
+
readConfiguredAllowedCwdDetailsForLinzumiUrl(action.linzumiUrl, configPath)
|
|
240
|
+
);
|
|
241
|
+
case 'readLocalSignupAuth':
|
|
242
|
+
return outcome(() => readLocalSignupAuth(configPath));
|
|
243
|
+
case 'writeLocalSignupAuth':
|
|
244
|
+
return outcome(() =>
|
|
245
|
+
writeLocalSignupAuth(
|
|
246
|
+
{
|
|
247
|
+
...action.auth,
|
|
248
|
+
now: action.auth.nowMs === undefined ? undefined : new RealDate(action.auth.nowMs),
|
|
249
|
+
},
|
|
250
|
+
configPath
|
|
251
|
+
)
|
|
252
|
+
);
|
|
253
|
+
case 'writeLocalSignupCompletion':
|
|
254
|
+
return outcome(() =>
|
|
255
|
+
writeLocalSignupCompletion(
|
|
256
|
+
{
|
|
257
|
+
...action.completion,
|
|
258
|
+
now:
|
|
259
|
+
action.completion.nowMs === undefined
|
|
260
|
+
? undefined
|
|
261
|
+
: new RealDate(action.completion.nowMs),
|
|
262
|
+
},
|
|
263
|
+
configPath
|
|
264
|
+
)
|
|
265
|
+
);
|
|
266
|
+
default:
|
|
267
|
+
return { threw: true, message: 'unknown config action ' + String(action.fn) };
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function handleConfigLifecycle(testCase) {
|
|
272
|
+
const dir = scratch();
|
|
273
|
+
const configPath = join(dir, 'config.json');
|
|
274
|
+
const actions = substitute(testCase.actions, dirPlaceholder, dir);
|
|
275
|
+
const results = actions.map((action) => runConfigAction(action, dir, configPath));
|
|
276
|
+
return substitute({ results, files: snapshotFiles(dir) }, dir, dirPlaceholder);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// --- Auth lifecycle ----------------------------------------------------------------
|
|
280
|
+
|
|
281
|
+
function runAuthAction(action, authFilePath) {
|
|
282
|
+
switch (action.fn) {
|
|
283
|
+
case 'writeFile':
|
|
284
|
+
return outcome(() => writeFileSync(authFilePath, action.contents, 'utf8'));
|
|
285
|
+
case 'writeCachedLocalRunnerToken':
|
|
286
|
+
return outcome(() =>
|
|
287
|
+
writeCachedLocalRunnerToken({
|
|
288
|
+
kandanUrl: action.kandanUrl,
|
|
289
|
+
accessToken: action.accessToken,
|
|
290
|
+
expiresInSeconds: action.expiresInSeconds,
|
|
291
|
+
authFilePath,
|
|
292
|
+
})
|
|
293
|
+
);
|
|
294
|
+
case 'readCachedLocalRunnerToken':
|
|
295
|
+
return outcome(() => readCachedLocalRunnerToken(action.kandanUrl, authFilePath));
|
|
296
|
+
case 'readPersonalAgentDelegationToken':
|
|
297
|
+
return outcome(() => readPersonalAgentDelegationToken(authFilePath));
|
|
298
|
+
default:
|
|
299
|
+
return { threw: true, message: 'unknown auth action ' + String(action.fn) };
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function handleAuthLifecycle(testCase) {
|
|
304
|
+
const dir = scratch();
|
|
305
|
+
const authFilePath = join(dir, 'auth.json');
|
|
306
|
+
const actions = substitute(testCase.actions, dirPlaceholder, dir);
|
|
307
|
+
const results = actions.map((action) =>
|
|
308
|
+
withFixedNow(testCase.nowMs, () => runAuthAction(action, authFilePath))
|
|
309
|
+
);
|
|
310
|
+
return substitute({ results, files: snapshotFiles(dir) }, dir, dirPlaceholder);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// --- Fingerprint probes ---------------------------------------------------------------
|
|
314
|
+
|
|
315
|
+
function handleFingerprint(testCase) {
|
|
316
|
+
const spec = testCase.probes ?? {};
|
|
317
|
+
const probes = {
|
|
318
|
+
...(spec.platform === undefined ? {} : { platform: spec.platform }),
|
|
319
|
+
execFile: () => {
|
|
320
|
+
if (spec.execFileOutput === undefined) {
|
|
321
|
+
throw new Error('execFile probe failed');
|
|
322
|
+
}
|
|
323
|
+
return spec.execFileOutput;
|
|
324
|
+
},
|
|
325
|
+
readFile: (path) => {
|
|
326
|
+
const contents = (spec.readFiles ?? {})[path];
|
|
327
|
+
if (contents === undefined) {
|
|
328
|
+
throw new Error('readFile probe failed: ' + path);
|
|
329
|
+
}
|
|
330
|
+
return contents;
|
|
331
|
+
},
|
|
332
|
+
username: () => {
|
|
333
|
+
if (spec.username === undefined) {
|
|
334
|
+
throw new Error('username probe failed');
|
|
335
|
+
}
|
|
336
|
+
return spec.username;
|
|
337
|
+
},
|
|
338
|
+
};
|
|
339
|
+
return {
|
|
340
|
+
raw: outcome(() => rawStableMachineIdentifier(probes)),
|
|
341
|
+
v1: outcome(() => stableMachineFingerprint(probes)),
|
|
342
|
+
machineId: outcome(() => stableMachineId(probes)),
|
|
343
|
+
rawUsername: outcome(() => rawOsUsername(probes)),
|
|
344
|
+
v2: outcome(() => stableMachineFingerprintV2(probes)),
|
|
345
|
+
helloFields: outcome(() =>
|
|
346
|
+
machineFingerprintV2HelloFields(stableMachineFingerprintV2(probes))
|
|
347
|
+
),
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// --- Cursor store ------------------------------------------------------------------------
|
|
352
|
+
|
|
353
|
+
function collectingLog(events, dir) {
|
|
354
|
+
return (event, payload) => {
|
|
355
|
+
events.push({ event, payload: substitute(payload, dir, dirPlaceholder) });
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function runStoreAction(store, action) {
|
|
360
|
+
switch (action.fn) {
|
|
361
|
+
case 'initial':
|
|
362
|
+
return outcome(() => store.initial(action.topic));
|
|
363
|
+
case 'onAdvance':
|
|
364
|
+
return outcome(() => store.onAdvance(action.topic, action.seq));
|
|
365
|
+
case 'reset':
|
|
366
|
+
return outcome(() => store.reset(action.topic, action.seq));
|
|
367
|
+
case 'adoptEpoch':
|
|
368
|
+
return outcome(() => store.adoptEpoch(action.epoch));
|
|
369
|
+
case 'epoch':
|
|
370
|
+
return outcome(() => store.epoch());
|
|
371
|
+
case 'flush':
|
|
372
|
+
return outcome(() => store.flush());
|
|
373
|
+
default:
|
|
374
|
+
return { threw: true, message: 'unknown store action ' + String(action.fn) };
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function readFileOrNull(path) {
|
|
379
|
+
try {
|
|
380
|
+
return readFileSync(path, 'utf8');
|
|
381
|
+
} catch {
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function handleCursorStore(testCase) {
|
|
387
|
+
const dir = scratch();
|
|
388
|
+
const path = join(dir, 'store.json');
|
|
389
|
+
if (testCase.initialContents !== undefined) {
|
|
390
|
+
writeFileSync(path, testCase.initialContents, 'utf8');
|
|
391
|
+
}
|
|
392
|
+
const events = [];
|
|
393
|
+
const store = createControlCursorFileStore(path, collectingLog(events, dir), {
|
|
394
|
+
...(testCase.discardSeqsOnFirstEpochAdoption === undefined
|
|
395
|
+
? {}
|
|
396
|
+
: { discardSeqsOnFirstEpochAdoption: testCase.discardSeqsOnFirstEpochAdoption }),
|
|
397
|
+
...(testCase.fsyncOnWrite === undefined
|
|
398
|
+
? {}
|
|
399
|
+
: { fsyncOnWrite: testCase.fsyncOnWrite }),
|
|
400
|
+
});
|
|
401
|
+
const results = (testCase.actions ?? []).map((action) => runStoreAction(store, action));
|
|
402
|
+
store.flush();
|
|
403
|
+
return { results, fileBytes: readFileOrNull(path), events };
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function handleEpochStore(testCase) {
|
|
407
|
+
const dir = scratch();
|
|
408
|
+
const cursorPath = join(dir, 'cursor.json');
|
|
409
|
+
const startTurnPath = join(dir, 'start-turn.json');
|
|
410
|
+
if (testCase.cursorContents !== undefined) {
|
|
411
|
+
writeFileSync(cursorPath, testCase.cursorContents, 'utf8');
|
|
412
|
+
}
|
|
413
|
+
if (testCase.startTurnContents !== undefined) {
|
|
414
|
+
writeFileSync(startTurnPath, testCase.startTurnContents, 'utf8');
|
|
415
|
+
}
|
|
416
|
+
const events = [];
|
|
417
|
+
const log = collectingLog(events, dir);
|
|
418
|
+
const cursorStore = createControlCursorFileStore(cursorPath, log);
|
|
419
|
+
const startTurnStore = createControlCursorFileStore(startTurnPath, log, {
|
|
420
|
+
discardSeqsOnFirstEpochAdoption: true,
|
|
421
|
+
});
|
|
422
|
+
const epochStore = createRunnerControlEpochStore(cursorStore, startTurnStore, log, {
|
|
423
|
+
runnerId: testCase.runnerId,
|
|
424
|
+
kandanUrl: testCase.kandanUrl,
|
|
425
|
+
});
|
|
426
|
+
const initialEpoch = outcome(() => epochStore.current());
|
|
427
|
+
const adoptResults = (testCase.adopts ?? []).map((adopt) =>
|
|
428
|
+
outcome(() => epochStore.adopt(adopt.topic, adopt.epoch))
|
|
429
|
+
);
|
|
430
|
+
cursorStore.flush();
|
|
431
|
+
startTurnStore.flush();
|
|
432
|
+
return {
|
|
433
|
+
initialEpoch,
|
|
434
|
+
adoptResults,
|
|
435
|
+
cursorBytes: readFileOrNull(cursorPath),
|
|
436
|
+
startTurnBytes: readFileOrNull(startTurnPath),
|
|
437
|
+
events,
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// --- Restart-attempt store -----------------------------------------------------------------
|
|
442
|
+
|
|
443
|
+
function handleRestartAttemptStore(testCase) {
|
|
444
|
+
const dir = scratch();
|
|
445
|
+
const path = join(dir, 'attempt.json');
|
|
446
|
+
if (testCase.initialContents !== undefined) {
|
|
447
|
+
writeFileSync(path, testCase.initialContents, 'utf8');
|
|
448
|
+
}
|
|
449
|
+
const store = fileRestartAttemptStore(path);
|
|
450
|
+
const loaded = outcome(() => store.load());
|
|
451
|
+
let saved = { defined: false };
|
|
452
|
+
if (testCase.record !== undefined) {
|
|
453
|
+
saved = outcome(() => store.save(testCase.record));
|
|
454
|
+
}
|
|
455
|
+
return { loaded, saved, fileBytes: readFileOrNull(path) };
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// --- Dispatch --------------------------------------------------------------------------------
|
|
459
|
+
|
|
460
|
+
function handle(testCase) {
|
|
461
|
+
switch (testCase.op) {
|
|
462
|
+
case 'configLifecycle':
|
|
463
|
+
return handleConfigLifecycle(testCase);
|
|
464
|
+
case 'authLifecycle':
|
|
465
|
+
return handleAuthLifecycle(testCase);
|
|
466
|
+
case 'fingerprint':
|
|
467
|
+
return handleFingerprint(testCase);
|
|
468
|
+
case 'cursorStore':
|
|
469
|
+
return handleCursorStore(testCase);
|
|
470
|
+
case 'epochStore':
|
|
471
|
+
return handleEpochStore(testCase);
|
|
472
|
+
case 'stateFileStem':
|
|
473
|
+
return outcome(() => runnerStateFileStem(testCase.runnerId));
|
|
474
|
+
case 'restartAttemptStore':
|
|
475
|
+
return handleRestartAttemptStore(testCase);
|
|
476
|
+
default:
|
|
477
|
+
return { threw: true, message: 'unknown op ' + String(testCase.op) };
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
let stdin = '';
|
|
482
|
+
process.stdin.setEncoding('utf8');
|
|
483
|
+
for await (const chunk of process.stdin) {
|
|
484
|
+
stdin += chunk;
|
|
485
|
+
}
|
|
486
|
+
const cases = JSON.parse(stdin);
|
|
487
|
+
process.stdout.write(JSON.stringify(cases.map(handle)));
|
|
488
|
+
`;
|
|
489
|
+
|
|
490
|
+
await mkdir(join(packageRoot, '.differential'), { recursive: true });
|
|
491
|
+
|
|
492
|
+
// runner.ts's graph resolves assets/ relative to the bundle at import time
|
|
493
|
+
// (same requirement as build-differential-entry.mjs).
|
|
494
|
+
await mkdir(join(packageRoot, '.differential/assets'), { recursive: true });
|
|
495
|
+
await copyFile(
|
|
496
|
+
join(packageRoot, 'src/assets/linzumi-logo.svg'),
|
|
497
|
+
join(packageRoot, '.differential/assets/linzumi-logo.svg')
|
|
498
|
+
);
|
|
499
|
+
|
|
500
|
+
await build({
|
|
501
|
+
stdin: {
|
|
502
|
+
contents: driverSource,
|
|
503
|
+
resolveDir: packageRoot,
|
|
504
|
+
sourcefile: 'config-identity-parity-driver.ts',
|
|
505
|
+
loader: 'ts',
|
|
506
|
+
},
|
|
507
|
+
bundle: true,
|
|
508
|
+
platform: 'node',
|
|
509
|
+
target: 'node20',
|
|
510
|
+
format: 'esm',
|
|
511
|
+
outfile: join(packageRoot, '.differential/config-identity-parity-oracle.mjs'),
|
|
512
|
+
minify: false,
|
|
513
|
+
sourcemap: false,
|
|
514
|
+
legalComments: 'none',
|
|
515
|
+
// runner.ts pulls the wider commander graph; the same runtime externals
|
|
516
|
+
// as the differential entry build stay external (they are installed in
|
|
517
|
+
// this package's node_modules, and the oracle only exercises the
|
|
518
|
+
// config/identity exports).
|
|
519
|
+
external: ['ws', 'undici', 'blessed', '@anthropic-ai/claude-agent-sdk'],
|
|
520
|
+
});
|