@leviyuan/lodestar 0.17.3 → 0.17.4
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/lodestar-setup.js +11 -11
- package/dist/lodestar-stop.js +2 -2
- package/dist/lodestar-update.js +7 -7
- package/dist/lodestar-version.js +1 -1
- package/dist/lodestar.js +181 -176
- package/docs/usage.md +24 -0
- package/package.json +1 -1
package/dist/lodestar-setup.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{createRequire as
|
|
3
|
-
${Z}${X}`));else z()})})}async function z0(q,z,J={}){z?.throwIfAborted();let Q=J.platform??process.platform,Z=J.timeoutMs??300000,X=J.terminationTimeoutMs??1e4;return await new Promise((H,B)=>{let Y=(J.spawn??X1.spawn)("npm",["install","--prefix",q,"--include=optional","--no-fund","--no-audit",`--registry=${W8}`],{cwd:q,stdio:["ignore","pipe","pipe"],shell:!1,windowsHide:!0}),V="",
|
|
4
|
-
${V}`),L0=(N)=>{if(
|
|
5
|
-
${V}`))}),Y.once("close",async(N,
|
|
6
|
-
${V}`));else
|
|
7
|
-
`,{mode:384}),await
|
|
8
|
-
`,{mode:384}),await(z.install??z0)(X,z.signal);for(let[_
|
|
2
|
+
import{createRequire as T1}from"node:module";var N1=Object.create;var{getPrototypeOf:k1,defineProperty:K0,getOwnPropertyNames:O1}=Object;var F1=Object.prototype.hasOwnProperty;function x1(q){return this[q]}var _1,P1,U0=(q,z,J)=>{var Q=q!=null&&typeof q==="object";if(Q){var Z=z?_1??=new WeakMap:P1??=new WeakMap,X=Z.get(q);if(X)return X}J=q!=null?N1(k1(q)):{};let H=z||!q||!q.__esModule?K0(J,"default",{value:q,enumerable:!0}):J;for(let B of O1(q))if(!F1.call(H,B))K0(H,B,{get:x1.bind(q,B),enumerable:!0});if(Q)Z.set(q,H);return H};var k=(q,z)=>()=>(z||q((z={exports:{}}).exports,z),z.exports);var P=T1(import.meta.url);var k0=k((C8,N0)=>{N0.exports=M0;M0.sync=R1;var W0=P("fs");function b1(q,z){var J=z.pathExt!==void 0?z.pathExt:process.env.PATHEXT;if(!J)return!0;if(J=J.split(";"),J.indexOf("")!==-1)return!0;for(var Q=0;Q<J.length;Q++){var Z=J[Q].toLowerCase();if(Z&&q.substr(-Z.length).toLowerCase()===Z)return!0}return!1}function G0(q,z,J){if(!q.isSymbolicLink()&&!q.isFile())return!1;return b1(z,J)}function M0(q,z,J){W0.stat(q,function(Q,Z){J(Q,Q?!1:G0(Z,q,z))})}function R1(q,z){return G0(W0.statSync(q),q,z)}});var P0=k((l8,_0)=>{_0.exports=F0;F0.sync=I1;var O0=P("fs");function F0(q,z,J){O0.stat(q,function(Q,Z){J(Q,Q?!1:x0(Z,z))})}function I1(q,z){return x0(O0.statSync(q),z)}function x0(q,z){return q.isFile()&&j1(q,z)}function j1(q,z){var{mode:J,uid:Q,gid:Z}=q,X=z.uid!==void 0?z.uid:process.getuid&&process.getuid(),H=z.gid!==void 0?z.gid:process.getgid&&process.getgid(),B=parseInt("100",8),Y=parseInt("010",8),V=parseInt("001",8),W=B|Y,L=J&V||J&Y&&Z===H||J&B&&Q===X||J&W&&X===0;return L}});var b0=k((p8,T0)=>{var d8=P("fs"),E;if(process.platform==="win32"||global.TESTING_WINDOWS)E=k0();else E=P0();T0.exports=C;C.sync=y1;function C(q,z,J){if(typeof z==="function")J=z,z={};if(!J){if(typeof Promise!=="function")throw TypeError("callback not provided");return new Promise(function(Q,Z){C(q,z||{},function(X,H){if(X)Z(X);else Q(H)})})}E(q,z||{},function(Q,Z){if(Q){if(Q.code==="EACCES"||z&&z.ignoreErrors)Q=null,Z=!1}J(Q,Z)})}function y1(q,z){try{return E.sync(q,z||{})}catch(J){if(z&&z.ignoreErrors||J.code==="EACCES")return!1;else throw J}}});var w0=k((i8,D0)=>{var R=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",R0=P("path"),S1=R?";":":",I0=b0(),j0=(q)=>Object.assign(Error(`not found: ${q}`),{code:"ENOENT"}),y0=(q,z)=>{let J=z.colon||S1,Q=q.match(/\//)||R&&q.match(/\\/)?[""]:[...R?[process.cwd()]:[],...(z.path||process.env.PATH||"").split(J)],Z=R?z.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",X=R?Z.split(J):[""];if(R){if(q.indexOf(".")!==-1&&X[0]!=="")X.unshift("")}return{pathEnv:Q,pathExt:X,pathExtExe:Z}},S0=(q,z,J)=>{if(typeof z==="function")J=z,z={};if(!z)z={};let{pathEnv:Q,pathExt:Z,pathExtExe:X}=y0(q,z),H=[],B=(V)=>new Promise((W,L)=>{if(V===Q.length)return z.all&&H.length?W(H):L(j0(q));let U=Q[V],O=/^".*"$/.test(U)?U.slice(1,-1):U,M=R0.join(O,q),x=!O&&/^\.[\\\/]/.test(q)?q.slice(0,2)+M:M;W(Y(x,V,0))}),Y=(V,W,L)=>new Promise((U,O)=>{if(L===Z.length)return U(B(W+1));let M=Z[L];I0(V+M,{pathExt:X},(x,_)=>{if(!x&&_)if(z.all)H.push(V+M);else return U(V+M);return U(Y(V,W,L+1))})});return J?B(0).then((V)=>J(null,V),J):B(0)},D1=(q,z)=>{z=z||{};let{pathEnv:J,pathExt:Q,pathExtExe:Z}=y0(q,z),X=[];for(let H=0;H<J.length;H++){let B=J[H],Y=/^".*"$/.test(B)?B.slice(1,-1):B,V=R0.join(Y,q),W=!Y&&/^\.[\\\/]/.test(q)?q.slice(0,2)+V:V;for(let L=0;L<Q.length;L++){let U=W+Q[L];try{if(I0.sync(U,{pathExt:Z}))if(z.all)X.push(U);else return U}catch(O){}}}if(z.all&&X.length)return X;if(z.nothrow)return null;throw j0(q)};D0.exports=S0;S0.sync=D1});var f0=k((n8,l)=>{var v0=(q={})=>{let z=q.env||process.env;if((q.platform||process.platform)!=="win32")return"PATH";return Object.keys(z).reverse().find((Q)=>Q.toUpperCase()==="PATH")||"Path"};l.exports=v0;l.exports.default=v0});var h0=k((s8,u0)=>{var E0=P("path"),w1=w0(),v1=f0();function A0(q,z){let J=q.options.env||process.env,Q=process.cwd(),Z=q.options.cwd!=null,X=Z&&process.chdir!==void 0&&!process.chdir.disabled;if(X)try{process.chdir(q.options.cwd)}catch(B){}let H;try{H=w1.sync(q.command,{path:J[v1({env:J})],pathExt:z?E0.delimiter:void 0})}catch(B){}finally{if(X)process.chdir(Q)}if(H)H=E0.resolve(Z?q.options.cwd:"",H);return H}function f1(q){return A0(q)||A0(q,!0)}u0.exports=f1});var c0=k((u1,p)=>{var d=/([()\][%!^"`<>&|;, *?])/g;function E1(q){return q=q.replace(d,"^$1"),q}function A1(q,z){if(q=`${q}`,q=q.replace(/(?=(\\+?)?)\1"/g,"$1$1\\\""),q=q.replace(/(?=(\\+?)?)\1$/,"$1$1"),q=`"${q}"`,q=q.replace(d,"^$1"),z)q=q.replace(d,"^$1");return q}u1.command=E1;u1.argument=A1});var m0=k((a8,g0)=>{g0.exports=/^#!(.*)/});var l0=k((o8,C0)=>{var g1=m0();C0.exports=(q="")=>{let z=q.match(g1);if(!z)return null;let[J,Q]=z[0].replace(/#! ?/,"").split(" "),Z=J.split("/").pop();if(Z==="env")return Q;return Q?`${Z} ${Q}`:Z}});var p0=k((t8,d0)=>{var i=P("fs"),m1=l0();function C1(q){let J=Buffer.alloc(150),Q;try{Q=i.openSync(q,"r"),i.readSync(Q,J,0,150,0),i.closeSync(Q)}catch(Z){}return m1(J.toString())}d0.exports=C1});var a0=k((r8,s0)=>{var l1=P("path"),i0=h0(),n0=c0(),d1=p0(),p1=process.platform==="win32",i1=/\.(?:com|exe)$/i,n1=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function s1(q){q.file=i0(q);let z=q.file&&d1(q.file);if(z)return q.args.unshift(q.file),q.command=z,i0(q);return q.file}function a1(q){if(!p1)return q;let z=s1(q),J=!i1.test(z);if(q.options.forceShell||J){let Q=n1.test(z);q.command=l1.normalize(q.command),q.command=n0.command(q.command),q.args=q.args.map((X)=>n0.argument(X,Q));let Z=[q.command].concat(q.args).join(" ");q.args=["/d","/s","/c",`"${Z}"`],q.command=process.env.comspec||"cmd.exe",q.options.windowsVerbatimArguments=!0}return q}function o1(q,z,J){if(z&&!Array.isArray(z))J=z,z=null;z=z?z.slice(0):[],J=Object.assign({},J);let Q={command:q,args:z,options:J,file:void 0,original:{command:q,args:z}};return J.shell?Q:a1(Q)}s0.exports=o1});var r0=k((e8,t0)=>{var n=process.platform==="win32";function s(q,z){return Object.assign(Error(`${z} ${q.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${z} ${q.command}`,path:q.command,spawnargs:q.args})}function t1(q,z){if(!n)return;let J=q.emit;q.emit=function(Q,Z){if(Q==="exit"){let X=o0(Z,z);if(X)return J.call(q,"error",X)}return J.apply(q,arguments)}}function o0(q,z){if(n&&q===1&&!z.file)return s(z.original,"spawn");return null}function r1(q,z){if(n&&q===1&&!z.file)return s(z.original,"spawnSync");return null}t0.exports={hookChildProcess:t1,verifyENOENT:o0,verifyENOENTSync:r1,notFoundError:s}});var t=k(($$,I)=>{var e0=P("child_process"),a=a0(),o=r0();function $1(q,z,J){let Q=a(q,z,J),Z=e0.spawn(Q.command,Q.args,Q.options);return o.hookChildProcess(Z,Q),Z}function e1(q,z,J){let Q=a(q,z,J),Z=e0.spawnSync(Q.command,Q.args,Q.options);return Z.error=Z.error||o.verifyENOENTSync(Z.status,Q),Z}I.exports=$1;I.exports.spawn=$1;I.exports.sync=e1;I.exports._parse=a;I.exports._enoent=o});var W1=U0(t(),1);import{execFileSync as R8,spawn as g}from"node:child_process";import{existsSync as H0,mkdirSync as G1,readFileSync as I8}from"node:fs";import{createInterface as j8}from"node:readline/promises";import{dirname as y8,join as V0}from"node:path";import{homedir as S8}from"node:os";import{fileURLToPath as D8}from"node:url";import{homedir as $8}from"node:os";import{join as K}from"node:path";var A=$8(),q1=process.platform==="win32";function z1(q,z,J){if(q)return q;if(z)return K(z,"lodestar");return J}function q8(){if(q1)return K(process.env.APPDATA??K(A,"AppData","Roaming"),"Lodestar");return K(A,".config","lodestar")}function z8(){if(q1)return K(process.env.LOCALAPPDATA??K(A,"AppData","Local"),"Lodestar");return K(A,".local","share","lodestar")}var r=z1(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,q8()),G=z1(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,z8()),D=process.env.LODESTAR_CONFIG??K(r,"config.toml"),J$=K(G,"daemon.pid"),Q$=K(G,"daemon.log"),Z$=K(G,"session-chat-map.json"),X$=K(G,"session-resume-map.json"),Y$=K(G,"session-turns-map.json"),H$=K(G,"session-model-map.json"),V$=K(G,"temp-session-leases.json"),L$=K(G,"tasklist-map.json"),B$=K(G,"agent-runs"),K$=K(G,"agent-session-ids.json"),U$=K(G,"managed-claude-plugin"),W$=K(G,"dsh"),G$=K(G,"codex-accounts"),M$=K(G,"codex-accounts.json"),N$=K(G,"codex-quota-blocks.json"),e=K(G,"agent-runtimes"),k$=K(G,"context-window-cache.json"),O$=K(G,"notify-callbacks.json"),F$=K(G,"alive-on-shutdown.json"),x$=K(G,"inbox"),_$=K(G,"debug.sock"),P$=K(G,"debug-context.json");import{chmodSync as J8,closeSync as $0,fsyncSync as J1,mkdirSync as Q8,openSync as Q1,renameSync as Z8,unlinkSync as X8,writeFileSync as Y8}from"node:fs";import{randomUUID as H8}from"node:crypto";import{dirname as Z1}from"node:path";var V8=384;var L8=448;function B8(q){let z=Z1(q);Q8(z,{recursive:!0,mode:L8})}function K8(q,z,J){B8(q);let Q=`${q}.${process.pid}.${H8()}.tmp`,Z=null;try{Z=Q1(Q,"wx",J),Y8(Z,z),J1(Z),$0(Z),Z=null,Z8(Q,q);try{J8(q,J)}catch{}if(process.platform!=="win32"){let X=null;try{X=Q1(Z1(q),"r"),J1(X)}catch{}finally{if(X!==null)try{$0(X)}catch{}}}}catch(X){if(Z!==null)try{$0(Z)}catch{}try{X8(Q)}catch{}throw X}}function q0(q,z){K8(q,z,V8)}import{createHash as M8,randomUUID as N8}from"node:crypto";import{existsSync as J0,readFileSync as H1}from"node:fs";import{mkdir as V1,mkdtemp as k8,readFile as L1,rename as B1,rm as h,writeFile as Q0}from"node:fs/promises";import{join as F,isAbsolute as O8}from"node:path";import{fileURLToPath as F8,pathToFileURL as A$}from"node:url";var X1=U0(t(),1);import{execFile as U8}from"node:child_process";var W8="https://registry.npmjs.org";class u extends Error{}function G8(q){if(!Number.isSafeInteger(q)||q<=0)return Promise.reject(Error(`Invalid npm installer PID: ${q}`));return new Promise((z,J)=>{U8("taskkill",["/PID",String(q),"/T","/F"],{windowsHide:!0,timeout:1e4},(Q,Z,X)=>{if(Q)J(Error(`taskkill npm installer PID ${q} failed: ${Q.message}
|
|
3
|
+
${Z}${X}`));else z()})})}async function z0(q,z,J={}){z?.throwIfAborted();let Q=J.platform??process.platform,Z=J.timeoutMs??300000,X=J.terminationTimeoutMs??1e4;return await new Promise((H,B)=>{let Y=(J.spawn??X1.spawn)("npm",["install","--prefix",q,"--include=optional","--no-fund","--no-audit",`--registry=${W8}`],{cwd:q,stdio:["ignore","pipe","pipe"],shell:!1,windowsHide:!0}),V="",W,L,U=!1,O=!1,M,x=(N)=>{V=(V+N.toString()).slice(-16384)};Y.stdout.on("data",x),Y.stderr.on("data",x);let _=(N)=>{if(U)return;if(U=!0,clearTimeout(B0),M)clearTimeout(M);if(z?.removeEventListener("abort",f),N)B(N);else H()},b=(N)=>new u(`${W?.message??"Agent runtime install failed"}; npm installer PID ${Y.pid??"MISS"} termination unconfirmed: ${N}; partial directory retained: ${q}
|
|
4
|
+
${V}`),L0=(N)=>{if(U||O||L)return;W??=Error(N),M=setTimeout(()=>_(b(`stdio did not close within ${X}ms`)),X),L=Promise.resolve().then(async()=>{if(O)throw Error("installer closed before process-tree termination started");if(!Y.pid)throw Error("installer PID unavailable");if(Q==="win32")await(J.terminateWindows??G8)(Y.pid);else if(!Y.kill("SIGTERM"))throw Error("npm installer rejected SIGTERM")}),L.catch((S)=>_(b(S instanceof Error?S.message:String(S))))},f=()=>L0("Agent runtime install aborted"),B0=setTimeout(()=>L0(`Agent runtime install timed out after ${Z}ms`),Z);if(z?.addEventListener("abort",f,{once:!0}),Y.on("error",(N)=>{if(W??=N,!Y.pid)_(Error(`${N.message}
|
|
5
|
+
${V}`))}),Y.once("close",async(N,S)=>{O=!0,clearTimeout(B0),z?.removeEventListener("abort",f);try{await L}catch(m){_(b(m instanceof Error?m.message:String(m)));return}if(W||N!==0)_(Error(`${W?.message??`npm install exited code=${N} signal=${S}`}
|
|
6
|
+
${V}`));else _()}),z?.aborted)f()})}var x8="https://registry.npmjs.org",w={codex:["@openai/codex"],claude:["@anthropic-ai/claude-code","@anthropic-ai/claude-agent-sdk","@anthropic-ai/sdk"],dsh:["@deepseek-ai/dsh","@deepseek-ai/dsh-llm-pi-ai","@deepseek-ai/dsh-tool-ask-user"]},j=(q)=>q instanceof Error?q.message:String(q);function K1(q,z=e){let J=F(z,q,"current.json");if(!J0(J))return null;let Q=JSON.parse(H1(J,"utf8"));if(!Number.isFinite(Q.checkedAt)||Q.directory!==void 0&&!O8(Q.directory))throw Error(`Invalid ${q} runtime state: ${J}`);return Q}function _8(q){let z=K1(q);if(z?.error)throw Error(`${q} 更新失败: ${z.error}`);if(!z?.directory)throw Error(`${q} runtime 未安装,请运行 lodestar-update --agents-only`);return z.directory}function Z0(q,z){let J=F(_8(q),"node_modules",".bin",`${z}${process.platform==="win32"?".cmd":""}`);if(!J0(J))throw Error(`${q} executable missing: ${J}`);return J}async function P8(q,z,J){let Q=new AbortController,Z=()=>Q.abort(J?.reason);if(J?.addEventListener("abort",Z,{once:!0}),J?.aborted)Z();let X=setTimeout(()=>Q.abort(Error("npm registry request timed out")),30000);try{let H=await fetch(`${x8}/${encodeURIComponent(q)}/${encodeURIComponent(z)}`,{signal:Q.signal});if(!H.ok)throw Error(`${q}@${z}: npm HTTP ${H.status}`);let B=await H.json();if(B.name!==q||typeof B.version!=="string"||!B.version)throw Error(`Invalid npm manifest: ${q}@${z}`);return B}finally{clearTimeout(X),J?.removeEventListener("abort",Z)}}async function T8(q,z){let J={};if(q!=="dsh"){let H=await Promise.all(w[q].map((B)=>z(B,"latest")));for(let B of H)J[B.name]=B.version;return J}let Q=await z("@deepseek-ai/dsh","latest"),Z=new Set(w.dsh),X=new Set;while(Z.size){let H=[...Z].slice(0,12);for(let Y of H)Z.delete(Y),X.add(Y);let B=await Promise.all(H.map((Y)=>Y===Q.name?Q:z(Y,Q.version)));for(let Y of B){if(Y.version!==Q.version)throw Error(`DSH release package mismatch: ${Y.name}@${Y.version}, expected ${Q.version}`);J[Y.name]=Y.version;for(let V of Object.keys({...Y.dependencies,...Y.peerDependencies,...Y.optionalDependencies}))if(V.startsWith("@deepseek-ai/dsh")&&!X.has(V))Z.add(V)}}return J}async function y(q,z=process.platform){for(let J=0;;J++)try{return await q()}catch(Q){let Z=Q.code;if(z!=="win32"||!["EPERM","EACCES","EBUSY","ENOTEMPTY"].includes(Z??"")||J>=5)throw Q;await new Promise((X)=>setTimeout(X,100*(J+1)))}}async function Y1(q,z){let J=F(q,`current-${N8()}.json`),Q;try{await Q0(J,JSON.stringify(z)+`
|
|
7
|
+
`,{mode:384}),await y(()=>B1(J,F(q,"current.json")))}catch(Z){throw Q=Z,Z}finally{try{await y(()=>h(J,{force:!0}))}catch(Z){if(Q)throw AggregateError([Q,Z],`${j(Q)}; state temporary file cleanup failed: ${j(Z)}`);throw Z}}}async function b8(q,z){let J=F(q,"update.lock"),Q=Date.now()+360000;for(;;){z?.throwIfAborted();try{return await V1(J),await Q0(F(J,"pid"),String(process.pid)),()=>y(()=>h(J,{recursive:!0}))}catch(Z){if(Z.code!=="EEXIST")throw Z;try{let X=Number(await L1(F(J,"pid"),"utf8"));if(!Number.isSafeInteger(X)||X<=0)throw Error(`Invalid runtime update lock: ${J}`);try{process.kill(X,0)}catch(H){if(H.code!=="ESRCH")throw H;await y(()=>h(J,{recursive:!0}));continue}}catch(X){if(X.code!=="ENOENT")throw X}if(Date.now()>=Q)throw Error(`Timed out waiting for runtime update lock: ${J}`);await new Promise((X)=>setTimeout(X,200))}}}async function X0(q,z={}){let J=z.root??e,Q=F(J,q);await V1(Q,{recursive:!0,mode:448});let Z=await b8(Q,z.signal),X,H,B=!1;try{z.report?.(`${q}: 检查 upstream latest`);let Y=K1(q,J),V=await T8(q,z.metadata??((M,x)=>P8(M,x,z.signal)));z.signal?.throwIfAborted();let W=JSON.parse(H1(F8(new URL("../package.json",import.meta.url)),"utf8")).overrides??{},L=M8("sha256").update(JSON.stringify({installFormat:2,versions:Object.entries(V).sort(),security:W,platform:process.platform,arch:process.arch})).digest("hex").slice(0,20),U=F(Q,L);if(!J0(U)){X=await k8(F(Q,".install-")),await Q0(F(X,"package.json"),JSON.stringify({name:`lodestar-runtime-${q}`,version:V[w[q][0]],private:!0,type:"module",dependencies:V,overrides:{...W,...q==="dsh"?V:{}}})+`
|
|
8
|
+
`,{mode:384}),await(z.install??z0)(X,z.signal);for(let[x,_]of Object.entries(V)){let b=JSON.parse(await L1(F(X,"node_modules",x,"package.json"),"utf8"));if(b.version!==_)throw Error(`npm installed ${x}@${b.version}, expected ${_}`)}z.signal?.throwIfAborted();let M=X;await y(()=>B1(M,U)),X=void 0}let O={directory:U,versions:V,checkedAt:Date.now()};return await Y1(Q,O),z.report?.(`${q}: ${w[q][0]}@${V[w[q][0]]}${Y?.directory===U?" 已是 latest":" 已更新,新进程使用新版"}`),O}catch(Y){H=Y,B=Y instanceof u;try{await Y1(Q,{checkedAt:Date.now(),error:j(Y)})}catch(V){throw H=AggregateError([Y,V],`${j(Y)}; recording update failure also failed: ${j(V)}`),H}throw Y}finally{let Y=[];if(X&&!B){let V=X;try{await y(()=>h(V,{recursive:!0}))}catch(W){Y.push(W)}}try{await Z()}catch(V){Y.push(V)}if(Y.length){let V=H?[H,...Y]:Y;throw AggregateError(V,V.map(j).join("; "))}}}var $={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m",red:"\x1B[31m"},v=j8({input:process.stdin,output:process.stdout});async function T(q,z={}){while(!0){let J=z.default?`${$.dim} [${z.default}]${$.reset}`:"",Q=(await v.question(`${$.cyan}? ${$.reset}${q}${J}
|
|
9
9
|
${$.green}>${$.reset} `)).trim();if(!Q&&z.default!==void 0)return z.default;if(!Q&&z.required){console.log(`${$.red}必填,请重新输入${$.reset}`);continue}return Q}}function w8(q){let z="═".repeat(58);console.log(`
|
|
10
10
|
${$.bold}${$.cyan}╔${z}╗${$.reset}`),console.log(`${$.bold}${$.cyan}║ ${q.padEnd(54)} ║${$.reset}`),console.log(`${$.bold}${$.cyan}╚${z}╝${$.reset}
|
|
11
11
|
`)}function c(q,z,J){console.log(`
|
|
12
12
|
${$.bold}${$.yellow}[${q}/${z}] ${J}${$.reset}
|
|
13
|
-
`)}function Y0(q){return q.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function U1(q){try{let z=R8(q,["login","status"],{timeout:1e4,shell:process.platform==="win32"}).toString();return/Logged in using ChatGPT/i.test(z)}catch{return!1}}async function v8(q){return new Promise((z)=>{let J=W1.spawn(q,["login"],{stdio:"inherit",shell:!1});J.on("exit",(Q)=>z(Q===0)),J.on("error",()=>z(!1))})}function f8(){return process.env.CLAUDE_CONFIG_DIR||V0(
|
|
14
|
-
`),{path:J}}catch(z){return{error:z?.message??String(z)}}}function u8(q){try{if(process.platform==="win32")g(process.env.ComSpec??"cmd.exe",["/c","start",'""',q],{detached:!0,stdio:"ignore",windowsHide:!0}).unref();else if(process.platform==="darwin")g("open",[q],{detached:!0,stdio:"ignore"}).unref();else g("xdg-open",[q],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function h8(q,z){try{let Q=await(await fetch("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({app_id:q,app_secret:z}),signal:AbortSignal.timeout(15000)})).json();if(Q.tenant_access_token)return{ok:!0};return{ok:!1,error:`飞书拒绝: code=${Q.code} msg=${Q.msg??"(no msg)"}`}}catch(J){return{ok:!1,error:`网络错误: ${J?.message??String(J)}`}}}function c8(){try{let q=D8(
|
|
13
|
+
`)}function Y0(q){return q.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function U1(q){try{let z=R8(q,["login","status"],{timeout:1e4,shell:process.platform==="win32"}).toString();return/Logged in using ChatGPT/i.test(z)}catch{return!1}}async function v8(q){return new Promise((z)=>{let J=W1.spawn(q,["login"],{stdio:"inherit",shell:!1});J.on("exit",(Q)=>z(Q===0)),J.on("error",()=>z(!1))})}function f8(){return process.env.CLAUDE_CONFIG_DIR||V0(S8(),".claude")}async function E8(q){try{let z=await fetch("https://open.bigmodel.cn/api/anthropic/v1/models",{headers:{Authorization:`Bearer ${q}`},signal:AbortSignal.timeout(1e4)});if(!z.ok)return null;let J=await z.json(),Q=(Array.isArray(J?.data)?J.data:[]).map((L)=>typeof L?.display_name==="string"&&L.display_name?L.display_name:String(L?.id??"")).filter(Boolean);if(!Q.length)return null;let Z=(L)=>{let U=L.match(/(\d+(?:\.\d+)?)/);return U?Number(U[1]):-1},X=(L)=>L.replace(/-Turbo|-Air$/i,""),B=[...Q.filter((L)=>!/-Turbo|-Air/i.test(L))].sort((L,U)=>Z(U)-Z(L)),Y=B[0],V=B[B.length-1],W={};if(Y)W.ANTHROPIC_DEFAULT_OPUS_MODEL=`${Y}[1m]`,W.ANTHROPIC_DEFAULT_SONNET_MODEL=`${Y}[1m]`;if(V&&X(V)!==X(Y))W.ANTHROPIC_DEFAULT_HAIKU_MODEL=V;return Object.keys(W).length?W:null}catch{return null}}async function A8(q){try{let z=f8();G1(z,{recursive:!0});let J=V0(z,"settings.json"),Q={};if(H0(J)){let B=I8(J,"utf8");try{let Y=JSON.parse(B);if(!Y||typeof Y!=="object"||Array.isArray(Y))return{error:`${J} 内容不是 JSON 对象, 拒绝覆盖, 请手动检查`};Q=Y}catch{return{error:`${J} 解析失败 (JSON 语法错), 拒绝覆盖, 请手动修复后重跑`}}}let Z=Q.env&&typeof Q.env==="object"&&!Array.isArray(Q.env)?Q.env:{},X={ANTHROPIC_AUTH_TOKEN:q,ANTHROPIC_BASE_URL:"https://open.bigmodel.cn/api/anthropic",API_TIMEOUT_MS:"3000000",CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:"1"},H=await E8(q);if(H)Object.assign(X,H);return Q.env={...Z,...X},q0(J,JSON.stringify(Q,null,2)+`
|
|
14
|
+
`),{path:J}}catch(z){return{error:z?.message??String(z)}}}function u8(q){try{if(process.platform==="win32")g(process.env.ComSpec??"cmd.exe",["/c","start",'""',q],{detached:!0,stdio:"ignore",windowsHide:!0}).unref();else if(process.platform==="darwin")g("open",[q],{detached:!0,stdio:"ignore"}).unref();else g("xdg-open",[q],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function h8(q,z){try{let Q=await(await fetch("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({app_id:q,app_secret:z}),signal:AbortSignal.timeout(15000)})).json();if(Q.tenant_access_token)return{ok:!0};return{ok:!1,error:`飞书拒绝: code=${Q.code} msg=${Q.msg??"(no msg)"}`}}catch(J){return{ok:!1,error:`网络错误: ${J?.message??String(J)}`}}}function c8(){try{let q=y8(D8(import.meta.url)),z=V0(q,"lodestar.js");if(!H0(z))return{error:`找不到 daemon bundle: ${z}`};let J=g(process.execPath,[z],{detached:!0,stdio:"ignore",windowsHide:!0});return J.unref(),{pid:J.pid}}catch(q){return{error:q?.message??String(q)}}}async function M1(){if(!process.stdin.isTTY)console.error(`${$.red}lodestar-setup: stdin 不是 TTY,无法交互式输入。${$.reset}`),console.error("请直接在 cmd / PowerShell / Terminal 里跑,不要 pipe 或重定向 stdin。"),process.exit(1);if(H0(D)){if(console.log(`${$.yellow}发现已有配置: ${D}${$.reset}`),(await T("覆盖? (y/N)",{default:"n"})).toLowerCase()!=="y"){console.log("已取消"),v.close();return}}w8("Lodestar 安装向导"),console.log("Lodestar 把 Feishu (飞书) 群聊接到 AI agent。"),console.log("默认后端是 Claude Code; Codex 是可选第二后端, 群里发 model 一键切换。"),console.log("每个群对应一个项目目录, agent 在那里跑、能读写文件。"),console.log(),console.log(`${$.yellow}⚠ Claude 官方限制:${$.reset}`),console.log(` ${$.bold}Claude 订阅 (Pro/Max OAuth 登录) 不支持本项目${$.reset},`),console.log(" 必须走 API 方式 —— 推荐 GLM Coding Plan, 或自备 Anthropic API key。"),console.log(),console.log("本向导依次做 4 件事:"),console.log(` ${$.dim}1) 确保 Claude Code CLI 已装好${$.reset}`),console.log(` ${$.dim}2) GLM Coding Plan API key (推荐, 可选) + Codex (可选)${$.reset}`),console.log(` ${$.dim}3) Feishu 自建应用 (含权限 / 事件 / 发版 + 凭据测试)${$.reset}`),console.log(` ${$.dim}4) 工作目录, 自动启动 daemon${$.reset}`),console.log(),await v.question(`${$.dim}按 Enter 开始 (Ctrl+C 退出)...${$.reset}`),c(1,4,"准备 Claude Code CLI"),await X0("claude",{report:(L)=>console.log(L)}),console.log(`${$.green}✓ Claude Code / SDK 已更新${$.reset}: ${$.dim}${Z0("claude","claude")}${$.reset}`),console.log(),console.log(`${$.dim}下一步可选配 GLM Coding Plan 自动写入路由; 不配则用本机 Claude Code 现有配置。${$.reset}`),console.log(`${$.dim}记住: 别用 \`claude\` 走订阅 OAuth 登录 —— 订阅不支持本项目, 要用 API key。${$.reset}`),c(2,4,"GLM Coding Plan (推荐, 可选)"),console.log("GLM Coding Plan 给 Claude Code 接 GLM 系列模型 (支持 1M token 上下文, 中文友好)。"),console.log("订阅后在智谱开放平台拿一个 API key, 粘到下面 —— 向导自动写进 ~/.claude/settings.json。"),console.log(` ${$.dim}拿 key: https://open.bigmodel.cn → 控制台 → API Keys${$.reset}`),console.log(` ${$.dim}不给也行: 以本机 Claude Code 现有配置启动 (确保是 API key 方式, 非订阅)。${$.reset}`),console.log();let q=await T("GLM API key (直接回车跳过)",{});if(q){let L=await A8(q);if("path"in L)console.log(`${$.green}✓ GLM 路由已写入${$.reset}: ${$.dim}${L.path}${$.reset}`),console.log(`${$.dim}模型 slots 按端点当前列表自动选取(最新一代 opus/sonnet, 1M ctx)${$.reset}`);else console.log(`${$.red}✗ 写入失败:${$.reset} ${L.error}`),console.log(`${$.dim}跳过 GLM 配置, 以本机 Claude Code 现有配置启动。${$.reset}`)}else console.log(`${$.dim}已跳过 GLM, 以本机 Claude Code 现有配置启动。${$.reset}`);if(console.log(),console.log(`${$.bold}Codex (可选第二后端)${$.reset}`),console.log(` ${$.dim}想用 Codex 的话, 登录 ChatGPT 订阅即可, 模型/effort 走 ~/.codex/config.toml, 群里发 model 切换。${$.reset}`),(await T("现在顺便配置 Codex 后端吗?",{default:"n"})).toLowerCase()==="y"){await X0("codex",{report:(U)=>console.log(U)});let L=Z0("codex","codex");if(U1(L))console.log(`${$.green}✓ Codex 已登录 ChatGPT${$.reset}`);else if(console.log(`${$.dim}启动 \`codex login\`...${$.reset}`),await v8(L)&&U1(L))console.log(`${$.green}✓ Codex 已登录 ChatGPT${$.reset}`);else console.log(`${$.yellow}Codex 登录未完成 — 不影响默认 Claude 后端; 需要时随时跑 codex login。${$.reset}`)}else console.log(`${$.dim}已跳过 Codex (需要时随时跑 codex login, 群里发 model 切)。${$.reset}`);c(3,4,"Feishu 自建应用");let J="https://open.feishu.cn/app";console.log("打开飞书开放平台 (浏览器):"),console.log(` ${$.cyan}${J}${$.reset}`),u8(J),console.log(`${$.dim}(如果浏览器没自动开, 复制上面 URL 粘到浏览器)${$.reset}`),console.log(),console.log(`${$.bold}详细操作步骤:${$.reset}`),console.log(),console.log(` ${$.bold}① 创建应用${$.reset}`),console.log(` 点 "创建企业自建应用", 填名字 (如 ${$.dim}Lodestar${$.reset}), logo 随意。`),console.log(),console.log(` ${$.bold}② 添加机器人能力${$.reset}`),console.log(` 左侧菜单 "${$.cyan}添加应用能力${$.reset}" → 找到 "机器人" → 点 "${$.bold}添加${$.reset}" 按钮。`),console.log(),console.log(` ${$.bold}③ 申请权限 (左侧 "${$.cyan}权限管理${$.reset}" → "${$.bold}开通权限${$.reset}")${$.reset}`),console.log(` ${$.yellow}缺一个都会让 daemon 启动后默默丢消息, 一定要全开。${$.reset}`),console.log(` ${$.dim}消息类:${$.reset}`),console.log(` • ${$.bold}im:message:send_as_bot${$.reset} ${$.dim}# 以机器人身份发消息${$.reset}`),console.log(` • ${$.bold}im:message${$.reset} ${$.dim}# 接收/操作消息 (核心)${$.reset}`),console.log(` • ${$.bold}im:chat${$.reset} ${$.dim}# 读/写群信息 (匹配群名 ↔ 项目目录)${$.reset}`),console.log(` • ${$.bold}im:chat:create${$.reset} ${$.dim}# wt: 自动创建 worktree 群${$.reset}`),console.log(` • ${$.bold}im:chat:delete${$.reset} ${$.dim}# wt: 解散 worktree 群${$.reset}`),console.log(` • ${$.bold}im:chat.members:read${$.reset} ${$.dim}# wt: 判断发起人是否已在群内${$.reset}`),console.log(` • ${$.bold}im:chat.members:write_only${$.reset} ${$.dim}# wt: 把发起人拉进已有 worktree 群${$.reset}`),console.log(` • ${$.bold}im:resource${$.reset} ${$.dim}# 上传/下载附件 (图文双向)${$.reset}`),console.log(` • ${$.bold}im:message.urgent${$.reset} ${$.dim}# 加急推送 (锁屏通知 / Ask)${$.reset}`),console.log(` • ${$.bold}im:message.group_msg${$.reset} ${$.dim}# 敏感: 接收群里所有消息${$.reset}`),console.log(` ${$.dim}└ 关键: 没它机器人只收 @ 自己的消息, 拿不到群里其他对话, 一定要开${$.reset}`),console.log(` ${$.dim}└ 敏感权限要走审批: 申请时填用途, 个人开发者通常秒过${$.reset}`),console.log(` • ${$.bold}im:message.group_at_msg:readonly${$.reset} ${$.dim}# 读 @ 机器人消息 (兜底)${$.reset}`),console.log(` ${$.dim}卡片类 (Card Kit):${$.reset}`),console.log(` • ${$.bold}cardkit:card:read${$.reset} ${$.dim}# 读卡片状态${$.reset}`),console.log(` • ${$.bold}cardkit:card:write${$.reset} ${$.dim}# 创建/更新卡片 (流式渲染核心)${$.reset}`),console.log(),console.log(` ${$.bold}④ 订阅事件 (左侧 "${$.cyan}事件与回调${$.reset}", 拆两个子页:)${$.reset}`),console.log(` ${$.dim}a)${$.reset} ${$.bold}事件配置${$.reset} 页:`),console.log(` ${$.yellow}• "订阅方式" → 选 "长连接" → 点保存${$.reset}`),console.log(` • 添加事件: ${$.bold}im.message.receive_v1${$.reset} ${$.dim}# 收群消息${$.reset}`),console.log(` ${$.dim}b)${$.reset} ${$.bold}回调配置${$.reset} 页:`),console.log(` ${$.yellow}• "订阅方式" → 选 "长连接" → 点保存${$.reset}`),console.log(` • 添加事件: ${$.bold}card.action.trigger${$.reset} ${$.dim}# 卡片按钮点击回调${$.reset}`),console.log(),console.log(` ${$.bold}⑤ 发布版本${$.reset}`),console.log(` 页面顶部 "${$.bold}创建版本${$.reset}" → 滚到底点 "${$.bold}保存${$.reset}" → 弹框点 "${$.bold}发布${$.reset}"。`),console.log(` ${$.yellow}没发版的应用收不到任何事件 — 这步九成新手会忘!${$.reset}`),console.log(),console.log(` ${$.bold}⑥ 拿凭据${$.reset}`),console.log(` 左侧 "凭证与基础信息" → 顶部 ${$.bold}App ID${$.reset} (${$.dim}cli_...${$.reset}) 和 ${$.bold}App Secret${$.reset}, 待会粘到下面。`),console.log(),console.log(` ${$.bold}⑦ 把机器人拉进群${$.reset}`),console.log(" 想用的飞书群 → 群设置 → 群机器人 → 添加机器人 → 选你的应用。"),console.log(` ${$.yellow}群名要等于 projects_root 下的项目目录名${$.reset} (下一步设, 默认是用户主目录)。`),console.log();let Q="",Z="";while(!0){Q=await T("App ID (以 cli_ 开头)",{required:!0}),Z=await T("App Secret",{required:!0}),console.log(`${$.dim}测试中... (调 tenant_access_token endpoint)${$.reset}`);let L=await h8(Q,Z);if(L.ok){console.log(`${$.green}✓ Feishu 凭据测试通过${$.reset}`);break}if(console.log(`${$.red}✗ 测试失败:${$.reset} ${L.error}`),console.log(`${$.dim}最常见原因: app_id / app_secret 抄错, 或应用还没 "发布上线" (步骤 ⑤)。${$.reset}`),console.log(),(await T("重新填? (Y/n)",{default:"y"})).toLowerCase()==="n")console.log(`${$.yellow}已取消, 配置未写盘。${$.reset}`),v.close(),process.exit(1)}c(4,4,"工作目录 + 启动"),console.log("每个 Feishu 群对应 projects_root 下同名的目录。"),console.log();let X=process.platform==="win32"?process.env.USERPROFILE??"C:\\Users\\Default":process.env.HOME??"/root",H=await T("projects_root",{default:X});G1(r,{recursive:!0});let B=["# Lodestar config — generated by `lodestar-setup`","# Edit by hand or re-run setup to overwrite.","","[feishu]",`app_id = "${Y0(Q)}"`,`app_secret = "${Y0(Z)}"`,"","[runtime]",`projects_root = "${Y0(H)}"`,"","[runtime.agent_auto_update]","codex = false","claude = false","dsh = false",""];q0(D,B.join(`
|
|
15
15
|
`)),console.log(`
|
|
16
|
-
${$.green}${$.bold}✓ 配置已写入${$.reset}`),console.log(` ${$.cyan}${
|
|
17
|
-
${$.bold}启动 daemon...${$.reset}`);let Y=c8(),V=process.platform==="win32"?"\\":"/",
|
|
16
|
+
${$.green}${$.bold}✓ 配置已写入${$.reset}`),console.log(` ${$.cyan}${D}${$.reset}`),console.log(`
|
|
17
|
+
${$.bold}启动 daemon...${$.reset}`);let Y=c8(),V=process.platform==="win32"?"\\":"/",W=process.platform==="win32"?`${process.env.LOCALAPPDATA??"%LOCALAPPDATA%"}\\Lodestar\\daemon-YYYY-MM-DD.log`:`${process.env.HOME??"~"}/.local/share/lodestar/daemon-YYYY-MM-DD.log`;if(Y.pid)console.log(`${$.green}✓ daemon 已在后台启动${$.reset} (pid ${Y.pid})`),console.log(),console.log(`${$.bold}最后一步: 在 Feishu 验证${$.reset}`),console.log(" ① 把机器人拉进任意飞书群"),console.log(` ② 群名 = ${$.cyan}${H}${V}<群名>${$.reset} 下的目录名 (新群第一条消息会自动建)`),console.log(" ③ 在群里发任意一条消息, 默认由 Claude 接管"),console.log(` ${$.dim}(群里发 model 可选择已配置账号、动态模型和 effort)${$.reset}`),console.log(),console.log("日志 (按日滚动, 保留近 7 天):"),console.log(` ${$.cyan}${W}${$.reset}`),console.log(),console.log(`${$.dim}若长期跑后台, Linux 配 systemd --user,macOS 配 launchd,Windows 配任务计划程序。${$.reset}`);else console.log(`${$.yellow}启动失败: ${Y.error}${$.reset}`),console.log(`手动运行: ${$.cyan}lodestar-daemon${$.reset}`);console.log(),v.close()}M1().catch((q)=>{console.error(`
|
|
18
18
|
lodestar-setup: ${q?.message??q}`),process.exit(1)});
|
package/dist/lodestar-stop.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{execSync as f}from"node:child_process";import{existsSync as U,readFileSync as y}from"node:fs";import{homedir as W}from"node:os";import{join as q}from"node:path";var X=W(),B=process.platform==="win32";function b(K,Q,Y){if(K)return K;if(Q)return q(Q,"lodestar");return Y}function H(){if(B)return q(process.env.APPDATA??q(X,"AppData","Roaming"),"Lodestar");return q(X,".config","lodestar")}function V(){if(B)return q(process.env.LOCALAPPDATA??q(X,"AppData","Local"),"Lodestar");return q(X,".local","share","lodestar")}var w=b(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,H()),
|
|
3
|
-
`),Q=parseInt((K[0]??"").trim(),10),Y=(K[1]??"").trim();if(!Number.isFinite(Q)||Q<=0)console.error(`${
|
|
2
|
+
import{execSync as f}from"node:child_process";import{existsSync as U,readFileSync as y}from"node:fs";import{homedir as W}from"node:os";import{join as q}from"node:path";var X=W(),B=process.platform==="win32";function b(K,Q,Y){if(K)return K;if(Q)return q(Q,"lodestar");return Y}function H(){if(B)return q(process.env.APPDATA??q(X,"AppData","Roaming"),"Lodestar");return q(X,".config","lodestar")}function V(){if(B)return q(process.env.LOCALAPPDATA??q(X,"AppData","Local"),"Lodestar");return q(X,".local","share","lodestar")}var w=b(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,H()),z=b(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,V()),x=process.env.LODESTAR_CONFIG??q(w,"config.toml"),Z=q(z,"daemon.pid"),S=q(z,"daemon.log"),E=q(z,"session-chat-map.json"),v=q(z,"session-resume-map.json"),h=q(z,"session-turns-map.json"),k=q(z,"session-model-map.json"),F=q(z,"temp-session-leases.json"),R=q(z,"tasklist-map.json"),m=q(z,"agent-runs"),T=q(z,"agent-session-ids.json"),C=q(z,"managed-claude-plugin"),l=q(z,"dsh"),c=q(z,"codex-accounts"),j=q(z,"codex-accounts.json"),t=q(z,"codex-quota-blocks.json"),_=q(z,"agent-runtimes"),p=q(z,"context-window-cache.json"),A=q(z,"notify-callbacks.json"),I=q(z,"alive-on-shutdown.json"),s=q(z,"inbox"),a=q(z,"debug.sock"),o=q(z,"debug-context.json");import{execSync as G}from"node:child_process";import{readFileSync as L,writeFileSync as d}from"node:fs";function M(K){try{if(process.platform==="linux")return L(`/proc/${K}/cmdline`,"utf8").replace(/\0/g," ").trim();if(process.platform==="darwin")return G(`ps -p ${K} -o args=`,{encoding:"utf8",timeout:2000}).trim();if(process.platform==="win32")return G(`powershell -NoProfile -Command "(Get-CimInstance Win32_Process -Filter 'ProcessId=${K}').CommandLine"`,{encoding:"utf8",timeout:5000}).trim()||null;return null}catch{return null}}function N(K,Q){if(!Number.isFinite(K)||K<=0||!Q)return!1;let Y=M(K);if(!Y)return!1;if(process.platform==="win32")return Y.toLowerCase().includes(Q.toLowerCase());return Y.includes(Q)}var J={reset:"\x1B[0m",bold:"\x1B[1m",green:"\x1B[32m",yellow:"\x1B[33m",red:"\x1B[31m",dim:"\x1B[2m"};function P(K){return new Promise((Q)=>setTimeout(Q,K))}async function u(){if(!U(Z)){console.log(`${J.yellow}Lodestar daemon 未运行${J.reset} ${J.dim}(${Z} 不存在)${J.reset}`);return}let K=y(Z,"utf8").split(`
|
|
3
|
+
`),Q=parseInt((K[0]??"").trim(),10),Y=(K[1]??"").trim();if(!Number.isFinite(Q)||Q<=0)console.error(`${J.red}PID 文件格式坏:${J.reset} ${Z}`),process.exit(1);if(Y&&!N(Q,Y)){console.log(`${J.yellow}PID ${Q} 上没有 daemon (stale 文件)${J.reset}`),console.log(`${J.dim}手删 ${Z} 后再试${J.reset}`);return}console.log(`${J.bold}停止 daemon${J.reset} (pid ${Q})...`);try{if(process.platform==="win32")f(`taskkill /PID ${Q} /T /F`,{stdio:"ignore"});else process.kill(Q,"SIGTERM")}catch($){console.error(`${J.red}发信号失败:${J.reset} ${$?.message??$}`),process.exit(1)}for(let $=0;$<50;$++){if(!U(Z)){console.log(`${J.green}✓ daemon 已停${J.reset}`);return}await P(100)}console.log(`${J.yellow}已发 SIGTERM, 但 5s 内 daemon 没清掉 ${Z}${J.reset}`),console.log(`${J.dim}它可能还在收尾 (落盘 alive marker / 关 WS); 下次启动 pid-guard 会自动判别。${J.reset}`)}u().catch((K)=>{console.error(`${J.red}lodestar-stop:${J.reset} ${K?.message??K}`),process.exit(1)});
|
package/dist/lodestar-update.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{createRequire as z1}from"node:module";var e$=Object.create;var{getPrototypeOf:$1,defineProperty:a,getOwnPropertyNames:L1}=Object;var q1=Object.prototype.hasOwnProperty;function J1($){return this[$]}var Q1,X1,Z1=($,L,q)=>{var J=$!=null&&typeof $==="object";if(J){var Q=L?Q1??=new WeakMap:X1??=new WeakMap,X=Q.get($);if(X)return X}q=$!=null?e$($1($)):{};let B=L||!$||!$.__esModule?a(q,"default",{value:$,enumerable:!0}):q;for(let Y of L1($))if(!q1.call(B,Y))a(B,Y,{get:J1.bind($,Y),enumerable:!0});if(J)Q.set($,B);return B};var O=($,L)=>()=>(L||$((L={exports:{}}).exports,L),L.exports);var y=z1(import.meta.url);var X$=O((
|
|
3
|
-
${Q}${X}`));else L()})})}async function i($,L,q={}){L?.throwIfAborted();let J=q.platform??process.platform,Q=q.timeoutMs??300000,X=q.terminationTimeoutMs??1e4;return await new Promise((B,Y)=>{let Z=(q.spawn??g$.spawn)("npm",["install","--prefix",$,"--include=optional","--no-fund","--no-audit",`--registry=${l1}`],{cwd:$,stdio:["ignore","pipe","pipe"],shell:!1,windowsHide:!0}),z="",
|
|
4
|
-
${z}`),t=(k)=>{if(
|
|
5
|
-
${z}`))}),Z.once("close",async(k,b)=>{M=!0,clearTimeout(o),L?.removeEventListener("abort",
|
|
6
|
-
${z}`));else F()}),L?.aborted)
|
|
7
|
-
`,{mode:384}),await
|
|
8
|
-
`,{mode:384}),await(L.install??i)(X,L.signal);for(let[N,F]of Object.entries(z)){let
|
|
2
|
+
import{createRequire as z1}from"node:module";var e$=Object.create;var{getPrototypeOf:$1,defineProperty:a,getOwnPropertyNames:L1}=Object;var q1=Object.prototype.hasOwnProperty;function J1($){return this[$]}var Q1,X1,Z1=($,L,q)=>{var J=$!=null&&typeof $==="object";if(J){var Q=L?Q1??=new WeakMap:X1??=new WeakMap,X=Q.get($);if(X)return X}q=$!=null?e$($1($)):{};let B=L||!$||!$.__esModule?a(q,"default",{value:$,enumerable:!0}):q;for(let Y of L1($))if(!q1.call(B,Y))a(B,Y,{get:J1.bind($,Y),enumerable:!0});if(J)Q.set($,B);return B};var O=($,L)=>()=>(L||$((L={exports:{}}).exports,L),L.exports);var y=z1(import.meta.url);var X$=O((T0,Q$)=>{Q$.exports=J$;J$.sync=U1;var L$=y("fs");function K1($,L){var q=L.pathExt!==void 0?L.pathExt:process.env.PATHEXT;if(!q)return!0;if(q=q.split(";"),q.indexOf("")!==-1)return!0;for(var J=0;J<q.length;J++){var Q=q[J].toLowerCase();if(Q&&$.substr(-Q.length).toLowerCase()===Q)return!0}return!1}function q$($,L,q){if(!$.isSymbolicLink()&&!$.isFile())return!1;return K1(L,q)}function J$($,L,q){L$.stat($,function(J,Q){q(J,J?!1:q$(Q,$,L))})}function U1($,L){return q$(L$.statSync($),$,L)}});var H$=O((R0,Y$)=>{Y$.exports=z$;z$.sync=W1;var Z$=y("fs");function z$($,L,q){Z$.stat($,function(J,Q){q(J,J?!1:B$(Q,L))})}function W1($,L){return B$(Z$.statSync($),L)}function B$($,L){return $.isFile()&&G1($,L)}function G1($,L){var{mode:q,uid:J,gid:Q}=$,X=L.uid!==void 0?L.uid:process.getuid&&process.getuid(),B=L.gid!==void 0?L.gid:process.getgid&&process.getgid(),Y=parseInt("100",8),Z=parseInt("010",8),z=parseInt("001",8),U=Y|Z,G=q&z||q&Z&&Q===B||q&Y&&J===X||q&U&&X===0;return G}});var K$=O((D0,V$)=>{var j0=y("fs"),j;if(process.platform==="win32"||global.TESTING_WINDOWS)j=X$();else j=H$();V$.exports=u;u.sync=P1;function u($,L,q){if(typeof L==="function")q=L,L={};if(!q){if(typeof Promise!=="function")throw TypeError("callback not provided");return new Promise(function(J,Q){u($,L||{},function(X,B){if(X)Q(X);else J(B)})})}j($,L||{},function(J,Q){if(J){if(J.code==="EACCES"||L&&L.ignoreErrors)J=null,Q=!1}q(J,Q)})}function P1($,L){try{return j.sync($,L||{})}catch(q){if(L&&L.ignoreErrors||q.code==="EACCES")return!1;else throw q}}});var M$=O((v0,O$)=>{var _=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",U$=y("path"),k1=_?";":":",W$=K$(),G$=($)=>Object.assign(Error(`not found: ${$}`),{code:"ENOENT"}),P$=($,L)=>{let q=L.colon||k1,J=$.match(/\//)||_&&$.match(/\\/)?[""]:[..._?[process.cwd()]:[],...(L.path||process.env.PATH||"").split(q)],Q=_?L.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",X=_?Q.split(q):[""];if(_){if($.indexOf(".")!==-1&&X[0]!=="")X.unshift("")}return{pathEnv:J,pathExt:X,pathExtExe:Q}},k$=($,L,q)=>{if(typeof L==="function")q=L,L={};if(!L)L={};let{pathEnv:J,pathExt:Q,pathExtExe:X}=P$($,L),B=[],Y=(z)=>new Promise((U,G)=>{if(z===J.length)return L.all&&B.length?U(B):G(G$($));let W=J[z],M=/^".*"$/.test(W)?W.slice(1,-1):W,P=U$.join(M,$),N=!M&&/^\.[\\\/]/.test($)?$.slice(0,2)+P:P;U(Z(N,z,0))}),Z=(z,U,G)=>new Promise((W,M)=>{if(G===Q.length)return W(Y(U+1));let P=Q[G];W$(z+P,{pathExt:X},(N,F)=>{if(!N&&F)if(L.all)B.push(z+P);else return W(z+P);return W(Z(z,U,G+1))})});return q?Y(0).then((z)=>q(null,z),q):Y(0)},O1=($,L)=>{L=L||{};let{pathEnv:q,pathExt:J,pathExtExe:Q}=P$($,L),X=[];for(let B=0;B<q.length;B++){let Y=q[B],Z=/^".*"$/.test(Y)?Y.slice(1,-1):Y,z=U$.join(Z,$),U=!Z&&/^\.[\\\/]/.test($)?$.slice(0,2)+z:z;for(let G=0;G<J.length;G++){let W=U+J[G];try{if(W$.sync(W,{pathExt:Q}))if(L.all)X.push(W);else return W}catch(M){}}}if(L.all&&X.length)return X;if(L.nothrow)return null;throw G$($)};O$.exports=k$;k$.sync=O1});var F$=O((E0,h)=>{var N$=($={})=>{let L=$.env||process.env;if(($.platform||process.platform)!=="win32")return"PATH";return Object.keys(L).reverse().find((J)=>J.toUpperCase()==="PATH")||"Path"};h.exports=N$;h.exports.default=N$});var S$=O((A0,C$)=>{var x$=y("path"),M1=M$(),N1=F$();function y$($,L){let q=$.options.env||process.env,J=process.cwd(),Q=$.options.cwd!=null,X=Q&&process.chdir!==void 0&&!process.chdir.disabled;if(X)try{process.chdir($.options.cwd)}catch(Y){}let B;try{B=M1.sync($.command,{path:q[N1({env:q})],pathExt:L?x$.delimiter:void 0})}catch(Y){}finally{if(X)process.chdir(J)}if(B)B=x$.resolve(Q?$.options.cwd:"",B);return B}function F1($){return y$($)||y$($,!0)}C$.exports=F1});var _$=O((C1,m)=>{var c=/([()\][%!^"`<>&|;, *?])/g;function x1($){return $=$.replace(c,"^$1"),$}function y1($,L){if($=`${$}`,$=$.replace(/(?=(\\+?)?)\1"/g,"$1$1\\\""),$=$.replace(/(?=(\\+?)?)\1$/,"$1$1"),$=`"${$}"`,$=$.replace(c,"^$1"),L)$=$.replace(c,"^$1");return $}C1.command=x1;C1.argument=y1});var I$=O((u0,f$)=>{f$.exports=/^#!(.*)/});var w$=O((h0,b$)=>{var f1=I$();b$.exports=($="")=>{let L=$.match(f1);if(!L)return null;let[q,J]=L[0].replace(/#! ?/,"").split(" "),Q=q.split("/").pop();if(Q==="env")return J;return J?`${Q} ${J}`:Q}});var R$=O((c0,T$)=>{var l=y("fs"),I1=w$();function b1($){let q=Buffer.alloc(150),J;try{J=l.openSync($,"r"),l.readSync(J,q,0,150,0),l.closeSync(J)}catch(Q){}return I1(q.toString())}T$.exports=b1});var E$=O((m0,v$)=>{var w1=y("path"),j$=S$(),D$=_$(),T1=R$(),R1=process.platform==="win32",j1=/\.(?:com|exe)$/i,D1=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function v1($){$.file=j$($);let L=$.file&&T1($.file);if(L)return $.args.unshift($.file),$.command=L,j$($);return $.file}function E1($){if(!R1)return $;let L=v1($),q=!j1.test(L);if($.options.forceShell||q){let J=D1.test(L);$.command=w1.normalize($.command),$.command=D$.command($.command),$.args=$.args.map((X)=>D$.argument(X,J));let Q=[$.command].concat($.args).join(" ");$.args=["/d","/s","/c",`"${Q}"`],$.command=process.env.comspec||"cmd.exe",$.options.windowsVerbatimArguments=!0}return $}function A1($,L,q){if(L&&!Array.isArray(L))q=L,L=null;L=L?L.slice(0):[],q=Object.assign({},q);let J={command:$,args:L,options:q,file:void 0,original:{command:$,args:L}};return q.shell?J:E1(J)}v$.exports=A1});var h$=O((l0,u$)=>{var g=process.platform==="win32";function d($,L){return Object.assign(Error(`${L} ${$.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${L} ${$.command}`,path:$.command,spawnargs:$.args})}function u1($,L){if(!g)return;let q=$.emit;$.emit=function(J,Q){if(J==="exit"){let X=A$(Q,L);if(X)return q.call($,"error",X)}return q.apply($,arguments)}}function A$($,L){if(g&&$===1&&!L.file)return d(L.original,"spawn");return null}function h1($,L){if(g&&$===1&&!L.file)return d(L.original,"spawnSync");return null}u$.exports={hookChildProcess:u1,verifyENOENT:A$,verifyENOENTSync:h1,notFoundError:d}});var l$=O((g0,f)=>{var c$=y("child_process"),p=E$(),n=h$();function m$($,L,q){let J=p($,L,q),Q=c$.spawn(J.command,J.args,J.options);return n.hookChildProcess(Q,J),Q}function c1($,L,q){let J=p($,L,q),Q=c$.spawnSync(J.command,J.args,J.options);return Q.error=Q.error||n.verifyENOENTSync(Q.status,J),Q}f.exports=m$;f.exports.spawn=m$;f.exports.sync=c1;f.exports._parse=p;f.exports._enoent=n});import{spawn as L0}from"node:child_process";import{existsSync as q0}from"node:fs";import{homedir as B1}from"node:os";import{join as H}from"node:path";var R=B1(),r=process.platform==="win32";function e($,L,q){if($)return $;if(L)return H(L,"lodestar");return q}function Y1(){if(r)return H(process.env.APPDATA??H(R,"AppData","Roaming"),"Lodestar");return H(R,".config","lodestar")}function H1(){if(r)return H(process.env.LOCALAPPDATA??H(R,"AppData","Local"),"Lodestar");return H(R,".local","share","lodestar")}var V1=e(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,Y1()),K=e(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,H1()),Y0=process.env.LODESTAR_CONFIG??H(V1,"config.toml"),$$=H(K,"daemon.pid"),H0=H(K,"daemon.log"),V0=H(K,"session-chat-map.json"),K0=H(K,"session-resume-map.json"),U0=H(K,"session-turns-map.json"),W0=H(K,"session-model-map.json"),G0=H(K,"temp-session-leases.json"),P0=H(K,"tasklist-map.json"),k0=H(K,"agent-runs"),O0=H(K,"agent-session-ids.json"),M0=H(K,"managed-claude-plugin"),N0=H(K,"dsh"),F0=H(K,"codex-accounts"),x0=H(K,"codex-accounts.json"),y0=H(K,"codex-quota-blocks.json"),A=H(K,"agent-runtimes"),C0=H(K,"context-window-cache.json"),S0=H(K,"notify-callbacks.json"),_0=H(K,"alive-on-shutdown.json"),f0=H(K,"inbox"),I0=H(K,"debug.sock"),b0=H(K,"debug-context.json");import{createHash as d1,randomUUID as p1}from"node:crypto";import{existsSync as n$,readFileSync as i$}from"node:fs";import{mkdir as s$,mkdtemp as n1,readFile as t$,rename as o$,rm as v,writeFile as s}from"node:fs/promises";import{join as x,isAbsolute as i1}from"node:path";import{fileURLToPath as s1,pathToFileURL as a0}from"node:url";var g$=Z1(l$(),1);import{execFile as m1}from"node:child_process";var l1="https://registry.npmjs.org";class D extends Error{}function g1($){if(!Number.isSafeInteger($)||$<=0)return Promise.reject(Error(`Invalid npm installer PID: ${$}`));return new Promise((L,q)=>{m1("taskkill",["/PID",String($),"/T","/F"],{windowsHide:!0,timeout:1e4},(J,Q,X)=>{if(J)q(Error(`taskkill npm installer PID ${$} failed: ${J.message}
|
|
3
|
+
${Q}${X}`));else L()})})}async function i($,L,q={}){L?.throwIfAborted();let J=q.platform??process.platform,Q=q.timeoutMs??300000,X=q.terminationTimeoutMs??1e4;return await new Promise((B,Y)=>{let Z=(q.spawn??g$.spawn)("npm",["install","--prefix",$,"--include=optional","--no-fund","--no-audit",`--registry=${l1}`],{cwd:$,stdio:["ignore","pipe","pipe"],shell:!1,windowsHide:!0}),z="",U,G,W=!1,M=!1,P,N=(k)=>{z=(z+k.toString()).slice(-16384)};Z.stdout.on("data",N),Z.stderr.on("data",N);let F=(k)=>{if(W)return;if(W=!0,clearTimeout(o),P)clearTimeout(P);if(L?.removeEventListener("abort",T),k)Y(k);else B()},S=(k)=>new D(`${U?.message??"Agent runtime install failed"}; npm installer PID ${Z.pid??"MISS"} termination unconfirmed: ${k}; partial directory retained: ${$}
|
|
4
|
+
${z}`),t=(k)=>{if(W||M||G)return;U??=Error(k),P=setTimeout(()=>F(S(`stdio did not close within ${X}ms`)),X),G=Promise.resolve().then(async()=>{if(M)throw Error("installer closed before process-tree termination started");if(!Z.pid)throw Error("installer PID unavailable");if(J==="win32")await(q.terminateWindows??g1)(Z.pid);else if(!Z.kill("SIGTERM"))throw Error("npm installer rejected SIGTERM")}),G.catch((b)=>F(S(b instanceof Error?b.message:String(b))))},T=()=>t("Agent runtime install aborted"),o=setTimeout(()=>t(`Agent runtime install timed out after ${Q}ms`),Q);if(L?.addEventListener("abort",T,{once:!0}),Z.on("error",(k)=>{if(U??=k,!Z.pid)F(Error(`${k.message}
|
|
5
|
+
${z}`))}),Z.once("close",async(k,b)=>{M=!0,clearTimeout(o),L?.removeEventListener("abort",T);try{await G}catch(E){F(S(E instanceof Error?E.message:String(E)));return}if(U||k!==0)F(Error(`${U?.message??`npm install exited code=${k} signal=${b}`}
|
|
6
|
+
${z}`));else F()}),L?.aborted)T()})}var d$=["codex","claude","dsh"];var t1="https://registry.npmjs.org",w={codex:["@openai/codex"],claude:["@anthropic-ai/claude-code","@anthropic-ai/claude-agent-sdk","@anthropic-ai/sdk"],dsh:["@deepseek-ai/dsh","@deepseek-ai/dsh-llm-pi-ai","@deepseek-ai/dsh-tool-ask-user"]},C=($)=>$ instanceof Error?$.message:String($);function o1($,L=A){let q=x(L,$,"current.json");if(!n$(q))return null;let J=JSON.parse(i$(q,"utf8"));if(!Number.isFinite(J.checkedAt)||J.directory!==void 0&&!i1(J.directory))throw Error(`Invalid ${$} runtime state: ${q}`);return J}async function a1($,L,q){let J=new AbortController,Q=()=>J.abort(q?.reason);if(q?.addEventListener("abort",Q,{once:!0}),q?.aborted)Q();let X=setTimeout(()=>J.abort(Error("npm registry request timed out")),30000);try{let B=await fetch(`${t1}/${encodeURIComponent($)}/${encodeURIComponent(L)}`,{signal:J.signal});if(!B.ok)throw Error(`${$}@${L}: npm HTTP ${B.status}`);let Y=await B.json();if(Y.name!==$||typeof Y.version!=="string"||!Y.version)throw Error(`Invalid npm manifest: ${$}@${L}`);return Y}finally{clearTimeout(X),q?.removeEventListener("abort",Q)}}async function r1($,L){let q={};if($!=="dsh"){let B=await Promise.all(w[$].map((Y)=>L(Y,"latest")));for(let Y of B)q[Y.name]=Y.version;return q}let J=await L("@deepseek-ai/dsh","latest"),Q=new Set(w.dsh),X=new Set;while(Q.size){let B=[...Q].slice(0,12);for(let Z of B)Q.delete(Z),X.add(Z);let Y=await Promise.all(B.map((Z)=>Z===J.name?J:L(Z,J.version)));for(let Z of Y){if(Z.version!==J.version)throw Error(`DSH release package mismatch: ${Z.name}@${Z.version}, expected ${J.version}`);q[Z.name]=Z.version;for(let z of Object.keys({...Z.dependencies,...Z.peerDependencies,...Z.optionalDependencies}))if(z.startsWith("@deepseek-ai/dsh")&&!X.has(z))Q.add(z)}}return q}async function I($,L=process.platform){for(let q=0;;q++)try{return await $()}catch(J){let Q=J.code;if(L!=="win32"||!["EPERM","EACCES","EBUSY","ENOTEMPTY"].includes(Q??"")||q>=5)throw J;await new Promise((X)=>setTimeout(X,100*(q+1)))}}async function p$($,L){let q=x($,`current-${p1()}.json`),J;try{await s(q,JSON.stringify(L)+`
|
|
7
|
+
`,{mode:384}),await I(()=>o$(q,x($,"current.json")))}catch(Q){throw J=Q,Q}finally{try{await I(()=>v(q,{force:!0}))}catch(Q){if(J)throw AggregateError([J,Q],`${C(J)}; state temporary file cleanup failed: ${C(Q)}`);throw Q}}}async function e1($,L){let q=x($,"update.lock"),J=Date.now()+360000;for(;;){L?.throwIfAborted();try{return await s$(q),await s(x(q,"pid"),String(process.pid)),()=>I(()=>v(q,{recursive:!0}))}catch(Q){if(Q.code!=="EEXIST")throw Q;try{let X=Number(await t$(x(q,"pid"),"utf8"));if(!Number.isSafeInteger(X)||X<=0)throw Error(`Invalid runtime update lock: ${q}`);try{process.kill(X,0)}catch(B){if(B.code!=="ESRCH")throw B;await I(()=>v(q,{recursive:!0}));continue}}catch(X){if(X.code!=="ENOENT")throw X}if(Date.now()>=J)throw Error(`Timed out waiting for runtime update lock: ${q}`);await new Promise((X)=>setTimeout(X,200))}}}async function $0($,L={}){let q=L.root??A,J=x(q,$);await s$(J,{recursive:!0,mode:448});let Q=await e1(J,L.signal),X,B,Y=!1;try{L.report?.(`${$}: 检查 upstream latest`);let Z=o1($,q),z=await r1($,L.metadata??((P,N)=>a1(P,N,L.signal)));L.signal?.throwIfAborted();let U=JSON.parse(i$(s1(new URL("../package.json",import.meta.url)),"utf8")).overrides??{},G=d1("sha256").update(JSON.stringify({installFormat:2,versions:Object.entries(z).sort(),security:U,platform:process.platform,arch:process.arch})).digest("hex").slice(0,20),W=x(J,G);if(!n$(W)){X=await n1(x(J,".install-")),await s(x(X,"package.json"),JSON.stringify({name:`lodestar-runtime-${$}`,version:z[w[$][0]],private:!0,type:"module",dependencies:z,overrides:{...U,...$==="dsh"?z:{}}})+`
|
|
8
|
+
`,{mode:384}),await(L.install??i)(X,L.signal);for(let[N,F]of Object.entries(z)){let S=JSON.parse(await t$(x(X,"node_modules",N,"package.json"),"utf8"));if(S.version!==F)throw Error(`npm installed ${N}@${S.version}, expected ${F}`)}L.signal?.throwIfAborted();let P=X;await I(()=>o$(P,W)),X=void 0}let M={directory:W,versions:z,checkedAt:Date.now()};return await p$(J,M),L.report?.(`${$}: ${w[$][0]}@${z[w[$][0]]}${Z?.directory===W?" 已是 latest":" 已更新,新进程使用新版"}`),M}catch(Z){B=Z,Y=Z instanceof D;try{await p$(J,{checkedAt:Date.now(),error:C(Z)})}catch(z){throw B=AggregateError([Z,z],`${C(Z)}; recording update failure also failed: ${C(z)}`),B}throw Z}finally{let Z=[];if(X&&!Y){let z=X;try{await I(()=>v(z,{recursive:!0}))}catch(U){Z.push(U)}}try{await Q()}catch(z){Z.push(z)}if(Z.length){let z=B?[B,...Z]:Z;throw AggregateError(z,z.map(C).join("; "))}}}async function a$($={}){let L=await Promise.allSettled(d$.map((J)=>$0(J,$))),q=[];for(let J=0;J<L.length;J++){let Q=L[J];if(Q.status==="rejected"){let X=Error(`${d$[J]}: ${C(Q.reason)}`);$.report?.(`Agent 更新失败: ${X.message}`),q.push(X)}}if(q.length)throw AggregateError(q,q.map((J)=>J.message).join(`
|
|
9
9
|
`))}var V={reset:"\x1B[0m",bold:"\x1B[1m",cyan:"\x1B[36m",green:"\x1B[32m",yellow:"\x1B[33m",red:"\x1B[31m",dim:"\x1B[2m"},r$=["@leviyuan/lodestar@latest"];function J0(){let $=process.platform==="win32"?"npm.cmd":"npm";return new Promise((L)=>{let q=L0($,["install","-g","--include=optional",...r$],{stdio:"inherit",shell:process.platform==="win32"});q.on("exit",(J)=>L(J??1)),q.on("error",(J)=>{console.error(`${V.red}spawn npm 失败:${V.reset} ${J.message}`),L(1)})})}async function Q0(){let $=process.argv.includes("--agents-only");if(process.argv.slice(2).some((L)=>L!=="--agents-only"))throw Error("用法: lodestar-update [--agents-only]");if(console.log(`${V.bold}更新 ${$?"":"Lodestar + "}Codex、Claude Code/SDK、DSH${V.reset}`),!$){console.log(`${V.dim}npm i -g ${r$.join(" ")}${V.reset}
|
|
10
10
|
`);let L=await J0();if(L!==0)throw Error(`Lodestar 更新失败 (npm exit ${L})`)}if(await a$({report:(L)=>console.log(L)}),console.log(`
|
|
11
11
|
${V.green}✓ Agent 更新完成,新进程使用新版${V.reset}`),!$&&q0($$))console.log(),console.log(`${V.yellow}检测到 daemon 仍在跑老版本进程, 用新版本需要重启:${V.reset}`),console.log(` ${V.dim}# Linux systemd --user 托管的:${V.reset}`),console.log(` ${V.cyan}systemctl --user restart lodestar${V.reset} ${V.dim}# Linux${V.reset}`),console.log(` ${V.dim}# macOS launchd / Windows 任务计划:用对应服务管理器重启。${V.reset}`),console.log(` ${V.dim}# 或手动重启:${V.reset}`),console.log(` ${V.cyan}lodestar-stop && lodestar-daemon${V.reset}`)}Q0().catch(($)=>{console.error(`${V.red}lodestar-update:${V.reset} ${$?.message??$}`),process.exit(1)});
|
package/dist/lodestar-version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{createRequire as E$}from"node:module";var y$=Object.create;var{getPrototypeOf:T$,defineProperty:
|
|
2
|
+
import{createRequire as E$}from"node:module";var y$=Object.create;var{getPrototypeOf:T$,defineProperty:w,getOwnPropertyNames:R$}=Object;var b$=Object.prototype.hasOwnProperty;function j$($){return this[$]}var w$,v$,D$=($,q,L)=>{var J=$!=null&&typeof $==="object";if(J){var Q=q?w$??=new WeakMap:v$??=new WeakMap,Z=Q.get($);if(Z)return Z}L=$!=null?y$(T$($)):{};let z=q||!$||!$.__esModule?w(L,"default",{value:$,enumerable:!0}):L;for(let Y of R$($))if(!b$.call(z,Y))w(z,Y,{get:j$.bind($,Y),enumerable:!0});if(J)Q.set($,z);return z};var V=($,q)=>()=>(q||$((q={exports:{}}).exports,q),q.exports);var k=E$(import.meta.url);var m=V((e0,c)=>{c.exports=h;h.sync=g$;var A=k("fs");function m$($,q){var L=q.pathExt!==void 0?q.pathExt:process.env.PATHEXT;if(!L)return!0;if(L=L.split(";"),L.indexOf("")!==-1)return!0;for(var J=0;J<L.length;J++){var Q=L[J].toLowerCase();if(Q&&$.substr(-Q.length).toLowerCase()===Q)return!0}return!1}function u($,q,L){if(!$.isSymbolicLink()&&!$.isFile())return!1;return m$(q,L)}function h($,q,L){A.stat($,function(J,Q){L(J,J?!1:u(Q,$,q))})}function g$($,q){return u(A.statSync($),$,q)}});var i=V(($1,p)=>{p.exports=l;l.sync=l$;var g=k("fs");function l($,q,L){g.stat($,function(J,Q){L(J,J?!1:d(Q,q))})}function l$($,q){return d(g.statSync($),q)}function d($,q){return $.isFile()&&d$($,q)}function d$($,q){var{mode:L,uid:J,gid:Q}=$,Z=q.uid!==void 0?q.uid:process.getuid&&process.getuid(),z=q.gid!==void 0?q.gid:process.getgid&&process.getgid(),Y=parseInt("100",8),W=parseInt("010",8),H=parseInt("001",8),G=Y|W,K=L&H||L&W&&Q===z||L&Y&&J===Z||L&G&&Z===0;return K}});var s=V((L1,n)=>{var q1=k("fs"),S;if(process.platform==="win32"||global.TESTING_WINDOWS)S=m();else S=i();n.exports=x;x.sync=p$;function x($,q,L){if(typeof q==="function")L=q,q={};if(!L){if(typeof Promise!=="function")throw TypeError("callback not provided");return new Promise(function(J,Q){x($,q||{},function(Z,z){if(Z)Q(Z);else J(z)})})}S($,q||{},function(J,Q){if(J){if(J.code==="EACCES"||q&&q.ignoreErrors)J=null,Q=!1}L(J,Q)})}function p$($,q){try{return S.sync($,q||{})}catch(L){if(q&&q.ignoreErrors||L.code==="EACCES")return!1;else throw L}}});var q$=V((J1,$$)=>{var P=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",t=k("path"),i$=P?";":":",o=s(),a=($)=>Object.assign(Error(`not found: ${$}`),{code:"ENOENT"}),r=($,q)=>{let L=q.colon||i$,J=$.match(/\//)||P&&$.match(/\\/)?[""]:[...P?[process.cwd()]:[],...(q.path||process.env.PATH||"").split(L)],Q=P?q.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",Z=P?Q.split(L):[""];if(P){if($.indexOf(".")!==-1&&Z[0]!=="")Z.unshift("")}return{pathEnv:J,pathExt:Z,pathExtExe:Q}},e=($,q,L)=>{if(typeof q==="function")L=q,q={};if(!q)q={};let{pathEnv:J,pathExt:Q,pathExtExe:Z}=r($,q),z=[],Y=(H)=>new Promise((G,K)=>{if(H===J.length)return q.all&&z.length?G(z):K(a($));let U=J[H],O=/^".*"$/.test(U)?U.slice(1,-1):U,M=t.join(O,$),C=!O&&/^\.[\\\/]/.test($)?$.slice(0,2)+M:M;G(W(C,H,0))}),W=(H,G,K)=>new Promise((U,O)=>{if(K===Q.length)return U(Y(G+1));let M=Q[K];o(H+M,{pathExt:Z},(C,f$)=>{if(!C&&f$)if(q.all)z.push(H+M);else return U(H+M);return U(W(H,G,K+1))})});return L?Y(0).then((H)=>L(null,H),L):Y(0)},n$=($,q)=>{q=q||{};let{pathEnv:L,pathExt:J,pathExtExe:Q}=r($,q),Z=[];for(let z=0;z<L.length;z++){let Y=L[z],W=/^".*"$/.test(Y)?Y.slice(1,-1):Y,H=t.join(W,$),G=!W&&/^\.[\\\/]/.test($)?$.slice(0,2)+H:H;for(let K=0;K<J.length;K++){let U=G+J[K];try{if(o.sync(U,{pathExt:Q}))if(q.all)Z.push(U);else return U}catch(O){}}}if(q.all&&Z.length)return Z;if(q.nothrow)return null;throw a($)};$$.exports=e;e.sync=n$});var J$=V((Q1,I)=>{var L$=($={})=>{let q=$.env||process.env;if(($.platform||process.platform)!=="win32")return"PATH";return Object.keys(q).reverse().find((J)=>J.toUpperCase()==="PATH")||"Path"};I.exports=L$;I.exports.default=L$});var z$=V((X1,Z$)=>{var Q$=k("path"),s$=q$(),t$=J$();function X$($,q){let L=$.options.env||process.env,J=process.cwd(),Q=$.options.cwd!=null,Z=Q&&process.chdir!==void 0&&!process.chdir.disabled;if(Z)try{process.chdir($.options.cwd)}catch(Y){}let z;try{z=s$.sync($.command,{path:L[t$({env:L})],pathExt:q?Q$.delimiter:void 0})}catch(Y){}finally{if(Z)process.chdir(J)}if(z)z=Q$.resolve(Q?$.options.cwd:"",z);return z}function o$($){return X$($)||X$($,!0)}Z$.exports=o$});var B$=V((e$,f)=>{var _=/([()\][%!^"`<>&|;, *?])/g;function a$($){return $=$.replace(_,"^$1"),$}function r$($,q){if($=`${$}`,$=$.replace(/(?=(\\+?)?)\1"/g,"$1$1\\\""),$=$.replace(/(?=(\\+?)?)\1$/,"$1$1"),$=`"${$}"`,$=$.replace(_,"^$1"),q)$=$.replace(_,"^$1");return $}e$.command=a$;e$.argument=r$});var H$=V((Z1,Y$)=>{Y$.exports=/^#!(.*)/});var K$=V((z1,V$)=>{var L0=H$();V$.exports=($="")=>{let q=$.match(L0);if(!q)return null;let[L,J]=q[0].replace(/#! ?/,"").split(" "),Q=L.split("/").pop();if(Q==="env")return J;return J?`${Q} ${J}`:Q}});var G$=V((B1,U$)=>{var y=k("fs"),J0=K$();function Q0($){let L=Buffer.alloc(150),J;try{J=y.openSync($,"r"),y.readSync(J,L,0,150,0),y.closeSync(J)}catch(Q){}return J0(L.toString())}U$.exports=Q0});var P$=V((Y1,M$)=>{var X0=k("path"),W$=z$(),k$=B$(),Z0=G$(),z0=process.platform==="win32",B0=/\.(?:com|exe)$/i,Y0=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function H0($){$.file=W$($);let q=$.file&&Z0($.file);if(q)return $.args.unshift($.file),$.command=q,W$($);return $.file}function V0($){if(!z0)return $;let q=H0($),L=!B0.test(q);if($.options.forceShell||L){let J=Y0.test(q);$.command=X0.normalize($.command),$.command=k$.command($.command),$.args=$.args.map((Z)=>k$.argument(Z,J));let Q=[$.command].concat($.args).join(" ");$.args=["/d","/s","/c",`"${Q}"`],$.command=process.env.comspec||"cmd.exe",$.options.windowsVerbatimArguments=!0}return $}function K0($,q,L){if(q&&!Array.isArray(q))L=q,q=null;q=q?q.slice(0):[],L=Object.assign({},L);let J={command:$,args:q,options:L,file:void 0,original:{command:$,args:q}};return L.shell?J:V0(J)}M$.exports=K0});var F$=V((H1,O$)=>{var T=process.platform==="win32";function R($,q){return Object.assign(Error(`${q} ${$.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${q} ${$.command}`,path:$.command,spawnargs:$.args})}function U0($,q){if(!T)return;let L=$.emit;$.emit=function(J,Q){if(J==="exit"){let Z=N$(Q,q);if(Z)return L.call($,"error",Z)}return L.apply($,arguments)}}function N$($,q){if(T&&$===1&&!q.file)return R(q.original,"spawn");return null}function G0($,q){if(T&&$===1&&!q.file)return R(q.original,"spawnSync");return null}O$.exports={hookChildProcess:U0,verifyENOENT:N$,verifyENOENTSync:G0,notFoundError:R}});var x$=V((V1,N)=>{var S$=k("child_process"),b=P$(),j=F$();function C$($,q,L){let J=b($,q,L),Q=S$.spawn(J.command,J.args,J.options);return j.hookChildProcess(Q,J),Q}function W0($,q,L){let J=b($,q,L),Q=S$.spawnSync(J.command,J.args,J.options);return Q.error=Q.error||j.verifyENOENTSync(Q.status,J),Q}N.exports=C$;N.exports.spawn=C$;N.exports.sync=W0;N.exports._parse=b;N.exports._enoent=j});import{readFileSync as C0}from"node:fs";import{fileURLToPath as x0}from"node:url";import{existsSync as P0,readFileSync as N0}from"node:fs";import{join as O0,isAbsolute as F0}from"node:path";import{homedir as A$}from"node:os";import{join as X}from"node:path";var F=A$(),v=process.platform==="win32";function D($,q,L){if($)return $;if(q)return X(q,"lodestar");return L}function u$(){if(v)return X(process.env.APPDATA??X(F,"AppData","Roaming"),"Lodestar");return X(F,".config","lodestar")}function h$(){if(v)return X(process.env.LOCALAPPDATA??X(F,"AppData","Local"),"Lodestar");return X(F,".local","share","lodestar")}var c$=D(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,u$()),B=D(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,h$()),R0=process.env.LODESTAR_CONFIG??X(c$,"config.toml"),b0=X(B,"daemon.pid"),j0=X(B,"daemon.log"),w0=X(B,"session-chat-map.json"),v0=X(B,"session-resume-map.json"),D0=X(B,"session-turns-map.json"),E0=X(B,"session-model-map.json"),A0=X(B,"temp-session-leases.json"),u0=X(B,"tasklist-map.json"),h0=X(B,"agent-runs"),c0=X(B,"agent-session-ids.json"),m0=X(B,"managed-claude-plugin"),g0=X(B,"dsh"),l0=X(B,"codex-accounts"),d0=X(B,"codex-accounts.json"),p0=X(B,"codex-quota-blocks.json"),E=X(B,"agent-runtimes"),i0=X(B,"context-window-cache.json"),n0=X(B,"notify-callbacks.json"),s0=X(B,"alive-on-shutdown.json"),t0=X(B,"inbox"),o0=X(B,"debug.sock"),a0=X(B,"debug-context.json");var k0=D$(x$(),1);var I$=["codex","claude","dsh"];function S0($,q=E){let L=O0(q,$,"current.json");if(!P0(L))return null;let J=JSON.parse(N0(L,"utf8"));if(!Number.isFinite(J.checkedAt)||J.directory!==void 0&&!F0(J.directory))throw Error(`Invalid ${$} runtime state: ${L}`);return J}function _$($){return S0($)}var I0=JSON.parse(C0(x0(new URL("../package.json",import.meta.url)),"utf8"));console.log(`Lodestar v${I0.version}`);for(let $ of I$)try{let q=_$($);if(!q){console.log(`${$}: MISS(尚未自动安装)`);continue}if(q.error){console.log(`${$}: MISS(自动更新失败:${q.error})`),process.exitCode=1;continue}let L=$==="dsh"?["@deepseek-ai/dsh"]:Object.keys(q.versions??{});console.log(`${$}: ${L.map((J)=>`${J}@${q.versions?.[J]??"MISS"}`).join(", ")}`),console.log(` ${q.directory}`)}catch(q){console.error(`${$}: MISS(${q})`),process.exitCode=1}console.log(`Runtime: ${process.version} (${process.platform}-${process.arch})`);
|