@leviyuan/lodestar 0.16.0 → 0.16.2
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 +8 -8
- package/dist/lodestar-agent.js +13 -0
- package/dist/lodestar-setup.js +1 -1
- package/dist/lodestar-stop.js +1 -1
- package/dist/lodestar-update.js +1 -1
- package/dist/lodestar.js +158 -191
- package/package.json +4 -4
- package/dist/lodestar-consult.js +0 -13
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ npm i -g @leviyuan/lodestar
|
|
|
35
35
|
| `lodestar-stop` | 停止 daemon |
|
|
36
36
|
| `lodestar-update` | 升级到最新版(含 Codex CLI、Claude Code 和 Claude SDK)|
|
|
37
37
|
| `lodestar-version` | 查看 Lodestar 和 Codex CLI 版本 |
|
|
38
|
-
| `lodestar-
|
|
38
|
+
| `lodestar-agent` | 供主 Agent 把完整任务委派给其他模型并续跑原生会话 |
|
|
39
39
|
|
|
40
40
|
**2. 跑向导**
|
|
41
41
|
|
|
@@ -62,7 +62,7 @@ lodestar-setup
|
|
|
62
62
|
| `clear` / `cl` | 用状态卡展示杀进程并开新 thread(等价 `/clear`)|
|
|
63
63
|
| `compact` / `cm` | 主动触发当前 thread 的上下文压缩,完成后状态卡收束 |
|
|
64
64
|
| `model` / `md` | 展示账号→动态模型→effort 面板,按群持久化 |
|
|
65
|
-
| `
|
|
65
|
+
| `agents` | 查看当前所有可调用的完整 Agent 身份 |
|
|
66
66
|
| `task` | 打开基础飞书任务清单绑定/删除面板 |
|
|
67
67
|
|
|
68
68
|
**并发 worktree 群**
|
|
@@ -97,17 +97,17 @@ lodestar-setup
|
|
|
97
97
|
|
|
98
98
|
## 🎁 附加能力
|
|
99
99
|
|
|
100
|
-
### 🧠
|
|
100
|
+
### 🧠 完整多模型 Agent 委派
|
|
101
101
|
|
|
102
|
-
daemon 会为每个 Token Source
|
|
102
|
+
daemon 会为每个 Token Source 目录中的每个模型生成一个实时 Agent 身份,并采用模型目录声明的真实默认 effort。项目群发 `agents` 可查看身份、模型、默认 effort 与当前 MISS;身份只负责模型路由,不再自动注入任何评审角色或提示词。
|
|
103
103
|
|
|
104
|
-
主 Agent
|
|
104
|
+
主 Agent 每次委派前通过 `lodestar-agent identities --json` 获取实时身份,再把完整原始 prompt 交给 `lodestar-agent run`。同一 prompt 选择多个身份时用重复 `--identity` 合并为一个 run,由 daemon 并发 fan-out;不同任务可以建立多个并行 run。daemon 不理解“评审/实现/研究”等任务语义,也不改写输出格式,全部行为约束都来自主 Agent prompt。
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
Delegated Agent 使用完整能力:Codex 固定 `danger-full-access`,保留 apps、plugins、multi-agent、MCP 与 hooks;Claude/GLM/DeepSeek 使用标准 `claude_code` preset、完整工具、项目 MCP 与 daemon-managed Skills。它们可以真实修改文件、运行命令、联网、调用外部系统并再次委派;这些副作用与主 Agent 在同一工作区立即可见。
|
|
107
107
|
|
|
108
|
-
`lodestar-
|
|
108
|
+
`lodestar-agent` 只能在 Lodestar 管理的 Agent 进程内使用。主 Session 和每个 child 都得到独立随机 capability;child capability 只允许访问自己的 run 子树,父 run 取消时递归吊销。进程治理上限为同时运行 8 个 turn、全局 128 个在途 worker、每 Session 64 个 active run、每子树 32 个 active run、递归深度 8;排队原因会在 run 状态中透明显示,这些上限不改变 Agent 权限。daemon 启动时会安装/更新裸命令和 canonical Skill,并安全清理旧 daemon-owned `lodestar-consult` 命令/Skill。
|
|
109
109
|
|
|
110
|
-
本机 API
|
|
110
|
+
本机 API 为 `GET /agents/identities`、`POST /agents/runs`、`GET|DELETE /agents/runs/<id>`、`POST /agents/runs/<id>/answer` 与 `POST /agents/runs/<id>/follow-up`。模型调用 `AskUserQuestion`/`request_user_input` 时 run 进入 `needs_input`,主 Agent 精确回答后继续;follow-up 新建可追踪 run,但复用同一 provider 原生 session。run 生命周期元数据原子落盘,大 prompt/输出各自存入私有正文文件,避免状态转换反复同步重写巨型 JSON;委派 session 不会混入主会话 `rs`/`fk` 列表。
|
|
111
111
|
|
|
112
112
|
### 📋 基础飞书任务清单
|
|
113
113
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{resolve as E}from"node:path";import{fileURLToPath as b}from"node:url";async function C(e=process.argv.slice(2)){let n=e.shift()??"";if(!n||n==="help"||n==="--help"||n==="-h"){process.stdout.write(`${w()}
|
|
3
|
+
`);return}let t=q();switch(n){case"identities":{let r=await d(t,"GET","/agents/identities");process.stdout.write(e.includes("--json")?`${JSON.stringify(r,null,2)}
|
|
4
|
+
`:A(r));return}case"run":await P(t,e);return;case"follow-up":case"followup":await T(t,e);return;case"answer":await k(t,e);return;case"status":{let r=c(e[0],"status requires run_id"),s=await d(t,"GET",`/agents/runs/${encodeURIComponent(r)}`);if(process.stdout.write($(s)),s.status==="failed"||s.status==="cancelled")process.exitCode=1;return}case"cancel":{let r=c(e[0],"cancel requires run_id"),s=await d(t,"DELETE",`/agents/runs/${encodeURIComponent(r)}`);process.stdout.write(`${JSON.stringify(s)}
|
|
5
|
+
`);return}default:throw Error(w())}}async function P(e,n){let t=g(n,!0),r=await m(t),s={identity_ids:t.identityIds,prompt:r,...t.effort?{effort:t.effort}:{}},i=await d(e,"POST","/agents/runs",s);await y(e,i,t.noWait)}async function T(e,n){let t=c(n.shift(),"follow-up requires run_id"),r=g(n,!1),i={prompt:await m(r),...r.identityId?{identity_id:r.identityId}:{},...r.effort?{effort:r.effort}:{}},o=await d(e,"POST",`/agents/runs/${encodeURIComponent(t)}/follow-up`,i);await y(e,o,r.noWait)}async function k(e,n){let t=c(n.shift(),"answer requires run_id"),r="",s="",i=!1,o={};for(let u=0;u<n.length;u++){let a=n[u],f=()=>c(n[++u],`${a} requires a value`);switch(a){case"--identity":case"-i":r=f();break;case"--request":s=f();break;case"--answer":{let p=f(),l=p.indexOf("=");if(l<=0)throw Error("--answer must be question-or-id=value");o[p.slice(0,l)]=p.slice(l+1);break}case"--stdin":i=!0;break;default:throw Error(`unknown answer option: ${a}`)}}if(i){let u=(await S()).trim(),a;try{a=JSON.parse(u)}catch{throw Error("answer stdin must be a JSON object")}if(!a||typeof a!=="object"||Array.isArray(a))throw Error("answer stdin must be a JSON object");for(let[f,p]of Object.entries(a))o[f]=String(p)}if(!s)throw Error("answer requires --request");if(Object.keys(o).length===0)throw Error("answer requires --answer or --stdin");let I=await d(e,"POST",`/agents/runs/${encodeURIComponent(t)}/answer`,{request_id:s,answers:o,...r?{identity_id:r}:{}});await h(e,String(I.run_id??t))}function g(e,n){let t={identityIds:[],identityId:"",effort:"",prompt:"",noWait:!1,readStdin:!1},r=[];for(let s=0;s<e.length;s++){let i=e[s],o=()=>c(e[++s],`${i} requires a value`);switch(i){case"--identity":case"-i":if(n)t.identityIds.push(o());else t.identityId=o();break;case"--effort":t.effort=o();break;case"--prompt":t.prompt=o();break;case"--stdin":t.readStdin=!0;break;case"--no-wait":t.noWait=!0;break;default:if(i.startsWith("-"))throw Error(`unknown option: ${i}`);r.push(i)}}if(t.identityIds=[...new Set(t.identityIds)],n&&t.identityIds.length===0)throw Error("run requires at least one --identity");if(!t.prompt&&r.length)t.prompt=r.join(" ");if(!t.prompt)t.readStdin=!0;return t}async function m(e){let n=e.readStdin?await S():"",t=e.prompt||n;if(!t.trim())throw Error("agent prompt is empty");return t}async function y(e,n,t){let r=String(n.run_id??"");if(!r)throw Error("agent API returned no run_id");if(t){process.stdout.write(`${JSON.stringify(n,null,2)}
|
|
6
|
+
`);return}await h(e,r)}async function h(e,n){let t=!1,r=()=>{if(t)return;t=!0,d(e,"DELETE",`/agents/runs/${encodeURIComponent(n)}`).then(()=>process.exit(130),(s)=>{process.stderr.write(`lodestar-agent: cancellation failed: ${_(s)}
|
|
7
|
+
`),process.exit(1)})};process.once("SIGINT",r),process.once("SIGTERM",r);try{while(!0){let s=await d(e,"GET",`/agents/runs/${encodeURIComponent(n)}`);if(s.status==="needs_input"||s.status==="completed"||s.status==="failed"||s.status==="cancelled"){if(process.stdout.write($(s)),s.status==="failed"||s.status==="cancelled")process.exitCode=1;return}await new Promise((i)=>setTimeout(i,1000))}}finally{process.off("SIGINT",r),process.off("SIGTERM",r)}}function q(){let e=String(process.env.LODESTAR_AGENT_URL??"").replace(/\/+$/,""),n=String(process.env.LODESTAR_AGENT_CAPABILITY??"");if(!e||!n)throw Error("lodestar-agent must run inside a Lodestar-managed Agent session (missing capability)");return{baseUrl:e,capability:n}}async function d(e,n,t,r){let s=await fetch(`${e.baseUrl}${t}`,{method:n,headers:{authorization:`Bearer ${e.capability}`,...r?{"content-type":"application/json"}:{}},...r?{body:JSON.stringify(r)}:{}}),i=await s.text(),o;try{o=JSON.parse(i)}catch{throw Error(`agent API ${n} ${t} returned HTTP ${s.status}: ${i||"(empty)"}`)}if(!s.ok)throw Error(o?.error??`agent API HTTP ${s.status}`);return o}function A(e){let n=[`catalog ${e.catalog_generation??"MISS"}`];for(let t of e.identities??[])n.push([t.status==="ready"?"✅":"MISS",t.id,t.display_name,t.model,`default-effort=${t.default_effort}`,t.source_default?"source-default":"",t.reason??""].filter(Boolean).join(" · "));for(let t of e.source_failures??[])n.push(`MISS · ${t.display} · ${t.reason}`);return`${n.join(`
|
|
8
|
+
`)}
|
|
9
|
+
`}function $(e){let n=[`# Lodestar agent ${e.run_id??"MISS"}`,"",`- Status: ${e.status??"MISS"}`,`- Depth: ${e.depth??"MISS"}`,...e.parent_run_id?[`- Parent: ${e.parent_run_id} (${e.parent_kind??"delegate"})`]:[]];if(e.error)n.push(`- Error: ${e.error}`);for(let t of e.workers??[]){if(n.push("",`## ${t.identity_name??t.identity_id}`,"",`Status: ${t.status}`),t.session_id)n.push(`Session: ${t.session_id}`);if(t.error)n.push("",`Error: ${t.error}`);if(t.pending_input){n.push("",`Input request: ${t.pending_input.request_id}`);for(let r of t.pending_input.questions??[])if(n.push(`- [${r.id}] ${r.question}`),r.options?.length)n.push(` Options: ${r.options.map((s)=>s.label).join(" / ")}`);n.push("","Answer with:",`lodestar-agent answer ${e.run_id} --identity '${t.identity_id}' --request '${t.pending_input.request_id}' --stdin`)}if(t.output)n.push("",t.output)}if(e.presentation_errors?.length)n.push("","Presentation errors:",...e.presentation_errors.map((t)=>`- ${t}`));return`${n.join(`
|
|
10
|
+
`)}
|
|
11
|
+
`}async function S(){if(process.stdin.isTTY)return"";let e=[];for await(let n of process.stdin)e.push(Buffer.isBuffer(n)?n:Buffer.from(n));return Buffer.concat(e).toString("utf8")}function c(e,n){if(!e?.trim())throw Error(n);return e.trim()}function w(){return["Usage:"," lodestar-agent identities [--json]"," lodestar-agent run --identity <id> [--identity <id>...] [--effort <level>] --stdin"," lodestar-agent follow-up <run_id> [--identity <id>] [--effort <level>] --stdin"," lodestar-agent answer <run_id> [--identity <id>] --request <id> (--answer key=value | --stdin)"," lodestar-agent status <run_id>"," lodestar-agent cancel <run_id>"].join(`
|
|
12
|
+
`)}function _(e){return e instanceof Error?e.message:String(e)}if(process.argv[1]&&E(process.argv[1])===b(import.meta.url))C().catch((e)=>{process.stderr.write(`lodestar-agent: ${_(e)}
|
|
13
|
+
`),process.exitCode=1});export{g as parsePromptArgs,C as main};
|
package/dist/lodestar-setup.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{execSync as C,spawn as G}from"node:child_process";import{existsSync as B,mkdirSync as I,readFileSync as e}from"node:fs";import{createInterface as zz}from"node:readline/promises";import{delimiter as $z,dirname as qz,join as F}from"node:path";import{homedir as Jz}from"node:os";import{fileURLToPath as Qz}from"node:url";import{homedir as h}from"node:os";import{join as Y}from"node:path";var w=h(),g=process.platform==="win32";function S($,q,J){if($)return $;if(q)return Y(q,"lodestar");return J}function m(){if(g)return Y(process.env.APPDATA??Y(w,"AppData","Roaming"),"Lodestar");return Y(w,".config","lodestar")}function p(){if(g)return Y(process.env.LOCALAPPDATA??Y(w,"AppData","Local"),"Lodestar");return Y(w,".local","share","lodestar")}var v=S(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,m()),H=S(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,p()),O=process.env.LODESTAR_CONFIG??Y(v,"config.toml"),Lz=Y(H,"daemon.pid"),Mz=Y(H,"daemon.log"),Gz=Y(H,"session-chat-map.json"),kz=Y(H,"session-resume-map.json"),Oz=Y(H,"session-turns-map.json"),wz=Y(H,"session-model-map.json"),Ez=Y(H,"temp-session-leases.json"),xz=Y(H,"tasklist-map.json"),Bz=Y(H,"
|
|
2
|
+
import{execSync as C,spawn as G}from"node:child_process";import{existsSync as B,mkdirSync as I,readFileSync as e}from"node:fs";import{createInterface as zz}from"node:readline/promises";import{delimiter as $z,dirname as qz,join as F}from"node:path";import{homedir as Jz}from"node:os";import{fileURLToPath as Qz}from"node:url";import{homedir as h}from"node:os";import{join as Y}from"node:path";var w=h(),g=process.platform==="win32";function S($,q,J){if($)return $;if(q)return Y(q,"lodestar");return J}function m(){if(g)return Y(process.env.APPDATA??Y(w,"AppData","Roaming"),"Lodestar");return Y(w,".config","lodestar")}function p(){if(g)return Y(process.env.LOCALAPPDATA??Y(w,"AppData","Local"),"Lodestar");return Y(w,".local","share","lodestar")}var v=S(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,m()),H=S(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,p()),O=process.env.LODESTAR_CONFIG??Y(v,"config.toml"),Lz=Y(H,"daemon.pid"),Mz=Y(H,"daemon.log"),Gz=Y(H,"session-chat-map.json"),kz=Y(H,"session-resume-map.json"),Oz=Y(H,"session-turns-map.json"),wz=Y(H,"session-model-map.json"),Ez=Y(H,"temp-session-leases.json"),xz=Y(H,"tasklist-map.json"),Bz=Y(H,"agent-runs"),Fz=Y(H,"agent-session-ids.json"),vz=Y(H,"managed-claude-plugin"),yz=Y(H,"context-window-cache.json"),Rz=Y(H,"notify-callbacks.json"),Tz=Y(H,"alive-on-shutdown.json"),uz=Y(H,"inbox"),gz=Y(H,"debug.sock"),Sz=Y(H,"debug-context.json");import{chmodSync as c,closeSync as y,fsyncSync as j,mkdirSync as l,openSync as _,renameSync as r,unlinkSync as s,writeFileSync as d}from"node:fs";import{randomUUID as a}from"node:crypto";import{dirname as P}from"node:path";var o=384;var i=448;function n($){let q=P($);l(q,{recursive:!0,mode:i})}function t($,q,J){n($);let Q=`${$}.${process.pid}.${a()}.tmp`,X=null;try{X=_(Q,"wx",J),d(X,q),j(X),y(X),X=null,r(Q,$);try{c($,J)}catch{}if(process.platform!=="win32"){let W=null;try{W=_(P($),"r"),j(W)}catch{}finally{if(W!==null)try{y(W)}catch{}}}}catch(W){if(X!==null)try{y(X)}catch{}try{s(Q)}catch{}throw W}}function R($,q){t($,q,o)}var z={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m",red:"\x1B[31m"},M=zz({input:process.stdin,output:process.stdout});async function L($,q={}){while(!0){let J=q.default?`${z.dim} [${q.default}]${z.reset}`:"",Q=(await M.question(`${z.cyan}? ${z.reset}${$}${J}
|
|
3
3
|
${z.green}>${z.reset} `)).trim();if(!Q&&q.default!==void 0)return q.default;if(!Q&&q.required){console.log(`${z.red}必填,请重新输入${z.reset}`);continue}return Q}}function Yz($){let q="═".repeat(58);console.log(`
|
|
4
4
|
${z.bold}${z.cyan}╔${q}╗${z.reset}`),console.log(`${z.bold}${z.cyan}║ ${$.padEnd(54)} ║${z.reset}`),console.log(`${z.bold}${z.cyan}╚${q}╝${z.reset}
|
|
5
5
|
`)}function E($,q,J){console.log(`
|
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(J,K,Y){if(J)return J;if(K)return q(K,"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()),Q=b(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,V()),x=process.env.LODESTAR_CONFIG??q(w,"config.toml"),Z=q(Q,"daemon.pid"),S=q(Q,"daemon.log"),E=q(Q,"session-chat-map.json"),v=q(Q,"session-resume-map.json"),h=q(Q,"session-turns-map.json"),k=q(Q,"session-model-map.json"),R=q(Q,"temp-session-leases.json"),F=q(Q,"tasklist-map.json"),T=q(Q,"
|
|
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(J,K,Y){if(J)return J;if(K)return q(K,"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()),Q=b(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,V()),x=process.env.LODESTAR_CONFIG??q(w,"config.toml"),Z=q(Q,"daemon.pid"),S=q(Q,"daemon.log"),E=q(Q,"session-chat-map.json"),v=q(Q,"session-resume-map.json"),h=q(Q,"session-turns-map.json"),k=q(Q,"session-model-map.json"),R=q(Q,"temp-session-leases.json"),F=q(Q,"tasklist-map.json"),T=q(Q,"agent-runs"),m=q(Q,"agent-session-ids.json"),C=q(Q,"managed-claude-plugin"),j=q(Q,"context-window-cache.json"),l=q(Q,"notify-callbacks.json"),c=q(Q,"alive-on-shutdown.json"),_=q(Q,"inbox"),t=q(Q,"debug.sock"),A=q(Q,"debug-context.json");import{execSync as G}from"node:child_process";import{readFileSync as L,writeFileSync as D}from"node:fs";function M(J){try{if(process.platform==="linux")return L(`/proc/${J}/cmdline`,"utf8").replace(/\0/g," ").trim();if(process.platform==="darwin")return G(`ps -p ${J} -o args=`,{encoding:"utf8",timeout:2000}).trim();if(process.platform==="win32")return G(`powershell -NoProfile -Command "(Get-CimInstance Win32_Process -Filter 'ProcessId=${J}').CommandLine"`,{encoding:"utf8",timeout:5000}).trim()||null;return null}catch{return null}}function N(J,K){if(!Number.isFinite(J)||J<=0||!K)return!1;let Y=M(J);if(!Y)return!1;if(process.platform==="win32")return Y.toLowerCase().includes(K.toLowerCase());return Y.includes(K)}var z={reset:"\x1B[0m",bold:"\x1B[1m",green:"\x1B[32m",yellow:"\x1B[33m",red:"\x1B[31m",dim:"\x1B[2m"};function P(J){return new Promise((K)=>setTimeout(K,J))}async function u(){if(!U(Z)){console.log(`${z.yellow}Lodestar daemon 未运行${z.reset} ${z.dim}(${Z} 不存在)${z.reset}`);return}let J=y(Z,"utf8").split(`
|
|
3
3
|
`),K=parseInt((J[0]??"").trim(),10),Y=(J[1]??"").trim();if(!Number.isFinite(K)||K<=0)console.error(`${z.red}PID 文件格式坏:${z.reset} ${Z}`),process.exit(1);if(Y&&!N(K,Y)){console.log(`${z.yellow}PID ${K} 上没有 daemon (stale 文件)${z.reset}`),console.log(`${z.dim}手删 ${Z} 后再试${z.reset}`);return}console.log(`${z.bold}停止 daemon${z.reset} (pid ${K})...`);try{if(process.platform==="win32")f(`taskkill /PID ${K} /T /F`,{stdio:"ignore"});else process.kill(K,"SIGTERM")}catch($){console.error(`${z.red}发信号失败:${z.reset} ${$?.message??$}`),process.exit(1)}for(let $=0;$<50;$++){if(!U(Z)){console.log(`${z.green}✓ daemon 已停${z.reset}`);return}await P(100)}console.log(`${z.yellow}已发 SIGTERM, 但 5s 内 daemon 没清掉 ${Z}${z.reset}`),console.log(`${z.dim}它可能还在收尾 (落盘 alive marker / 关 WS); 下次启动 pid-guard 会自动判别。${z.reset}`)}u().catch((J)=>{console.error(`${z.red}lodestar-stop:${z.reset} ${J?.message??J}`),process.exit(1)});
|
package/dist/lodestar-update.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{spawn as g}from"node:child_process";import{existsSync as x}from"node:fs";import{homedir as p}from"node:os";import{join as o}from"node:path";var m=p(),a=process.platform==="win32";function $(t,l,r){if(t)return t;if(l)return o(l,"lodestar");return r}function u(){if(a)return o(process.env.APPDATA??o(m,"AppData","Roaming"),"Lodestar");return o(m,".config","lodestar")}function y(){if(a)return o(process.env.LOCALAPPDATA??o(m,"AppData","Local"),"Lodestar");return o(m,".local","share","lodestar")}var C=$(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,u()),e=$(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,y()),K=process.env.LODESTAR_CONFIG??o(C,"config.toml"),n=o(e,"daemon.pid"),f=o(e,"daemon.log"),S=o(e,"session-chat-map.json"),q=o(e,"session-resume-map.json"),z=o(e,"session-turns-map.json"),J=o(e,"session-model-map.json"),Q=o(e,"temp-session-leases.json"),Y=o(e,"tasklist-map.json"),Z=o(e,"
|
|
2
|
+
import{spawn as g}from"node:child_process";import{existsSync as x}from"node:fs";import{homedir as p}from"node:os";import{join as o}from"node:path";var m=p(),a=process.platform==="win32";function $(t,l,r){if(t)return t;if(l)return o(l,"lodestar");return r}function u(){if(a)return o(process.env.APPDATA??o(m,"AppData","Roaming"),"Lodestar");return o(m,".config","lodestar")}function y(){if(a)return o(process.env.LOCALAPPDATA??o(m,"AppData","Local"),"Lodestar");return o(m,".local","share","lodestar")}var C=$(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,u()),e=$(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,y()),K=process.env.LODESTAR_CONFIG??o(C,"config.toml"),n=o(e,"daemon.pid"),f=o(e,"daemon.log"),S=o(e,"session-chat-map.json"),q=o(e,"session-resume-map.json"),z=o(e,"session-turns-map.json"),J=o(e,"session-model-map.json"),Q=o(e,"temp-session-leases.json"),Y=o(e,"tasklist-map.json"),Z=o(e,"agent-runs"),W=o(e,"agent-session-ids.json"),X=o(e,"managed-claude-plugin"),i=o(e,"context-window-cache.json"),B=o(e,"notify-callbacks.json"),G=o(e,"alive-on-shutdown.json"),N=o(e,"inbox"),U=o(e,"debug.sock"),F=o(e,"debug-context.json");var s={reset:"\x1B[0m",bold:"\x1B[1m",cyan:"\x1B[36m",green:"\x1B[32m",yellow:"\x1B[33m",red:"\x1B[31m",dim:"\x1B[2m"},d=["@leviyuan/lodestar@latest","@openai/codex@latest","@anthropic-ai/claude-code@latest","@anthropic-ai/claude-agent-sdk@latest","@anthropic-ai/sdk@latest"];function b(){let t=process.platform==="win32"?"npm.cmd":"npm";return new Promise((l)=>{let r=g(t,["install","-g","--include=optional",...d],{stdio:"inherit",shell:process.platform==="win32"});r.on("exit",(c)=>l(c??1)),r.on("error",(c)=>{console.error(`${s.red}spawn npm 失败:${s.reset} ${c.message}`),l(1)})})}async function w(){console.log(`${s.bold}更新 Lodestar + Codex CLI + Claude Code / SDK${s.reset}`),console.log(`${s.dim}npm i -g ${d.join(" ")}${s.reset}
|
|
3
3
|
`);let t=await b();if(t!==0)console.error(`
|
|
4
4
|
${s.red}更新失败 (npm exit ${t})${s.reset}`),process.exit(t);if(console.log(`
|
|
5
5
|
${s.green}✓ 更新完成${s.reset}`),x(n))console.log(),console.log(`${s.yellow}检测到 daemon 仍在跑老版本进程, 用新版本需要重启:${s.reset}`),console.log(` ${s.dim}# Linux systemd --user 托管的:${s.reset}`),console.log(` ${s.cyan}systemctl --user restart lodestar${s.reset} ${s.dim}# Linux${s.reset}`),console.log(` ${s.dim}# macOS launchd / Windows 任务计划:用对应服务管理器重启。${s.reset}`),console.log(` ${s.dim}# 或手动重启:${s.reset}`),console.log(` ${s.cyan}lodestar-stop && lodestar-daemon${s.reset}`)}w().catch((t)=>{console.error(`${s.red}lodestar-update:${s.reset} ${t?.message??t}`),process.exit(1)});
|