@leviyuan/lodestar 0.18.9 → 0.18.11
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 +50 -50
- package/dist/lodestar-stop.js +2 -2
- package/dist/lodestar-update.js +48 -48
- package/dist/lodestar-version.js +17 -17
- package/dist/lodestar.js +188 -189
- package/docs/configuration.md +1 -1
- package/docs/models.md +4 -26
- package/docs/usage.md +5 -3
- package/package.json +3 -1
- package/scripts/postinstall.cjs +16 -8
- package/src/data-dir.cjs +18 -0
- package/src/managed-skill-cleanup.cjs +49 -0
package/docs/configuration.md
CHANGED
|
@@ -26,7 +26,7 @@ lodestar-setup
|
|
|
26
26
|
| `lodestar-stop` | 停止 daemon |
|
|
27
27
|
| `lodestar-update` | 升级 Lodestar 及实际使用的 Codex、Claude Code/SDK、DSH;`--agents-only` 仅立即更新 Agent |
|
|
28
28
|
| `lodestar-version` | 查看 Lodestar、实际 Agent 版本、运行目录及更新错误 |
|
|
29
|
-
| `lodestar-agent` |
|
|
29
|
+
| `lodestar-agent` | 由主 Agent 调用已配置模型执行任务,也支持与自身相同的模型 |
|
|
30
30
|
|
|
31
31
|
daemon 启动时不检查 Agent 版本,也不安装或更新 Agent。自动更新默认关闭;首次安装缺少运行文件或需要更新时,运行 `lodestar-update --agents-only`。手动更新和显式开启的自动更新都选择上游 `latest`,独立于 Lodestar 发版,不设置兼容版本白名单。
|
|
32
32
|
|
package/docs/models.md
CHANGED
|
@@ -19,17 +19,19 @@
|
|
|
19
19
|
|
|
20
20
|
同账号切换 Claude 或 DSH 模型从后续回复生效;Codex 的持久设置需重启会话生效。跨账号或后端切换只允许在空闲时进行。来源禁用或目录获取失败显示 `MISS`。
|
|
21
21
|
|
|
22
|
+
模型设置超过 20 秒仍未收到后端确认时,面板显示“确认中”,最终结果回到原卡;等待期间仍可回答 Agent 提问或用 `stop` 打断任务,取消切换需发 `kill` 或 `restart`。模型和思考档位全部确认后才保存选择。若只有模型切换成功,或后端已应用但保存失败,会分别显示实际结果和错误,未确认的值显示 `MISS`;后续输入暂停,重新发送 `md` 完成选择后再继续。已有排队消息保留,设置确认后再提交。
|
|
23
|
+
|
|
22
24
|
## 额度
|
|
23
25
|
|
|
24
26
|
发送 `hi` 查看会话和账号额度。GLM 展示套餐与各窗口用量;Codex 展示额度窗口和账号可用的重置卡次数。
|
|
25
27
|
|
|
26
|
-
回复底部显示 `agent · 模型名/effort`,其中 Agent 为 `claude`、`codex` 或 `dsh`。窗口额度如 `4.1h·7%·[6.9d·17%]`,分别表示重置倒计时与已用百分比,方括号内为周窗口;余额显示 `余额 $12.34` 或 `余额 ¥12.34
|
|
28
|
+
回复底部显示 `agent · 模型名/effort`,其中 Agent 为 `claude`、`codex` 或 `dsh`。窗口额度如 `4.1h·7%·[6.9d·17%]`,分别表示重置倒计时与已用百分比,方括号内为周窗口;余额显示 `余额 $12.34` 或 `余额 ¥12.34`。Codex 的短暂网络失败会有限重试;最终刷新失败或进程已退出时,回复底部按原格式保留同账号上次成功的额度。没有成功缓存、登录认证失败或缓存已被重新登录、删除账号、额度重置操作清除时显示 `MISS`。`hi`、`codex-accounts` 和其他来源的查询失败仍显示 `MISS`。
|
|
27
29
|
|
|
28
30
|
## Claude Code 订阅
|
|
29
31
|
|
|
30
32
|
在运行 Lodestar 的本机通过 `claude auth login` 登录 Claude 订阅后,发送 `md` → Claude Code → **Claude Code 订阅**。来源 id 为 `claude-sub`,可与 GLM、DeepSeek、OpenRouter 同时使用;无需复制登录凭据或填写 API key。
|
|
31
33
|
|
|
32
|
-
发送 `claude-sub` 查看开关和可用状态,`claude-sub on` 启用,`claude-sub off` 禁用。开关对这台 Lodestar 的所有群生效并持久保存,只控制「Claude Code 订阅」来源,保留本机登录态及其他来源。禁用后不查询订阅模型和额度、不接受新任务;尚未送入 Agent
|
|
34
|
+
发送 `claude-sub` 查看开关和可用状态,`claude-sub on` 启用,`claude-sub off` 禁用。开关对这台 Lodestar 的所有群生效并持久保存,只控制「Claude Code 订阅」来源,保留本机登录态及其他来源。禁用后不查询订阅模型和额度、不接受新任务;尚未送入 Agent 的排队消息会提示重发,已经在执行的任务继续完成。再次启用后仍须有有效订阅登录。
|
|
33
35
|
|
|
34
36
|
账号和模型目录通过 Claude Code 原生 SDK 查询,模型与 effort 随目录更新;未登录会显示启用引导,查询失败显示 `MISS`。可选配置节为 `[token_source.claude-sub]`,支持 `enabled`、`display`、`model`、`effort`、`hidden_models` 和 `custom_models`。`enabled = false` 禁用,`enabled = true` 或省略时沿用本机登录检测;群命令更新该字段。
|
|
35
37
|
|
|
@@ -37,30 +39,6 @@
|
|
|
37
39
|
|
|
38
40
|
订阅进程保留本机和项目的 Claude 设置,并在进程内清除其他来源的 API key、模型映射和中转路由。发送任务前会再次核对实际账号是否为第一方订阅。Claude native 继续保留为使用本机完整配置的来源。
|
|
39
41
|
|
|
40
|
-
## ReClaude 拼车
|
|
41
|
-
|
|
42
|
-
在运行 Lodestar 的本机按 [ReClaude 官方说明](https://docs.reclaude.ai/cli/install)安装客户端,执行 `reclaude login` 完成浏览器设备授权并选择拼车组织,再运行 `reclaude daemon --detach` 启动官方后台。Linux 后台由用户 systemd 管理。
|
|
43
|
-
|
|
44
|
-
**客户端会接管本机 Claude 登录**,并在账号变化时终止其管理的 Claude 进程。Lodestar 启用 ReClaude 后停用重复的「Claude Code 订阅」入口。退出 ReClaude 并恢复原生登录按官方客户端的 `reclaude logout` 流程操作。
|
|
45
|
-
|
|
46
|
-
在群内发送 `reclaude-setup <拼车组织 ID> [个人只读 API key]`,然后通过 `md` → Claude Code → **ReClaude** 选择模型。也可以在配置文件中添加:
|
|
47
|
-
|
|
48
|
-
```toml
|
|
49
|
-
[token_source.reclaude]
|
|
50
|
-
agent = "claude"
|
|
51
|
-
auth = "reclaude-login"
|
|
52
|
-
org_id = "填写拼车组织 ID"
|
|
53
|
-
api_key = "填写 rck_ 个人只读 API key"
|
|
54
|
-
# model = "opus" # 可选;模型和 effort 来自 SDK 原生目录
|
|
55
|
-
# effort = "max"
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
个人 `rck_` key 仅查询指定组织的拼车 5 小时额度,不用于模型认证。组织 ID 可从个人 API 的 `GET /api/v1/orgs` 查询。未填写只读 key 不影响已登录客户端的模型调用,额度显示 `MISS`。接口里的美元金额是该窗口的用量口径,不是账户余额;重置时间未返回时保留未知,不推算周额度。
|
|
59
|
-
|
|
60
|
-
模型运行保持 Claude Agent SDK 默认入口,无需设置 `[claude].bin`。ReClaude 来源校验本机设备登录、对应 Claude 凭据、后台进程和 CA,然后只为此来源的 SDK 子进程设置官方本机代理。客户端未运行、登录不匹配、模型目录失败和网关错误均明确报错,不切换到其他账号。安装、登录和后台启动由用户管理,Lodestar 不自动安装或启动 ReClaude。
|
|
61
|
-
|
|
62
|
-
恢复检测脚本为 `bun scripts/watch-reclaude.ts --project <群项目名> --model haiku --interval-seconds 300`。它用极短的真实对话确认恢复,可能消耗拼车额度;首次成功后停止模型请求,经本机通知接口确认群消息发送成功后退出。通知失败每分钟重试,仅重试通知。状态保存在数据目录的 `reclaude-watch/`,已成功或已通知的记录在再次运行时仍有效,不会重复消耗模型额度。`--once` 只执行一轮。常驻时用 `systemd-run --user --unit=cc-<项目>-reclaude-watch -- <Bun绝对路径> <脚本绝对路径> ...` 管理;这不会重启 Lodestar。
|
|
63
|
-
|
|
64
42
|
## OpenRouter
|
|
65
43
|
|
|
66
44
|
OpenRouter 通过 Claude Agent SDK 运行。在群内发送 `openrouter-setup <api_key>`,再通过 `model` 面板选择模型和 effort;自建兼容端点用 `openrouter-setup <base_url> <api_key>`。也可在配置文件中添加:
|
package/docs/usage.md
CHANGED
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
|
|
47
47
|
新会话和委派任务启动时默认自动选号。Plus、Pro 5×、Pro 20× 的周额度分别按 1、5、20 份折算(原生套餐标识为 `plus`、`prolite`、`pro`),周分数为 **周剩余份额 ÷ 距周重置小时数**。Plus 的满 5h 窗口按 0.15 份计算,短窗分数为 **5h 剩余份额 ÷ 距5h重置小时数**,最终取周分数和短窗分数的较小值;Pro 使用周分数。所有模式都选择最高分,同分优先当前可连续使用额度更多的账号。两种窗口约束同一份消耗,不相加。
|
|
48
48
|
|
|
49
|
-
启动和换号优先使用 daemon 内上次成功的额度缓存,能选出账号就直接启动,不等待实时额度查询或其他账号补缓存。网络刷新失败会保留这份缓存;没有可用缓存时才重新查询。`hi`、`codex-accounts`
|
|
49
|
+
启动和换号优先使用 daemon 内上次成功的额度缓存,能选出账号就直接启动,不等待实时额度查询或其他账号补缓存。网络刷新失败会保留这份缓存;没有可用缓存时才重新查询。`hi`、`codex-accounts` 展示实时查询结果,失败显示 `MISS`。回复底部刷新失败或进程已退出时,按原格式显示本条回复所属账号的成功缓存,没有缓存仍显示 `MISS`。重新登录、删除账号及额度重置会清空对应缓存,认证失败也不会继续显示旧额度;已由实际请求确认耗尽的账号,必须通过实时查询确认恢复,不能用旧缓存解除耗尽记录。
|
|
50
50
|
|
|
51
51
|
成功读取 Plus 额度但未返回 5h 窗口时,按满额 0.15 份、完整 5 小时计算短窗分数;界面显示满额,但不编造具体重置时刻。整个请求失败、已返回窗口缺百分比或缺重置时间仍显示 MISS。自动 Ultra 只用 Pro,且启动或换号时周余量至少 0.5 份(Pro 5× 剩 10%,Pro 20× 剩 2.5%);运行中跌破该门槛不立即切号。没有合格 Pro 时等待周额度恢复,不自动用 Plus。其他实际限额、登录状态、目标模型与 effort、账号身份和查询错误仍参与自动选择。
|
|
52
52
|
|
|
@@ -88,7 +88,7 @@ Linux/macOS 下,额外账号通过软链接共用默认账号的配置、会
|
|
|
88
88
|
|
|
89
89
|
## 多模型任务
|
|
90
90
|
|
|
91
|
-
主 Agent
|
|
91
|
+
主 Agent 按任务和可用能力自行选择原生 subagent 或 `lodestar-agent`,调用自身模型或 Agent 时也适用。使用 `lodestar-agent` 时先查询实时身份,再把任务交给一个或多个模型。同一个任务选择多个身份时并发执行;后续追问可继续使用各模型的原生会话。
|
|
92
92
|
|
|
93
93
|
被调用的 Agent 可以编辑文件、执行命令、使用 MCP 和 Skill;委派只允许一层,被调用的 Agent 不能继续派工。它们与主 Agent 共享工作区,修改会立即可见。需要用户输入时暂停,由主 Agent 回填答案后继续。委派产生的会话不会混入主群的 `rs` 历史列表。
|
|
94
94
|
|
|
@@ -141,7 +141,9 @@ curl -sS -X POST http://127.0.0.1:9876/notify \
|
|
|
141
141
|
|
|
142
142
|
Agent 用 `[[send: /abs/path]]` 交付本地文件。**默认沿用直接发送聊天附件的方式**,单文件不能超过 30 MB(30 × 1024 × 1024 字节);超限需先压缩或分卷。原来的文件、图片消息通道保留。
|
|
143
143
|
|
|
144
|
-
Lodestar 启动 Agent
|
|
144
|
+
Lodestar 启动 Agent 时按本群设置直接注入文件交付约定:云空间模式只说明交付标记;聊天附件模式在标记旁附上大小上限和交付前检查要求。文件交付由宿主处理,无需安装或调用 Skill,Agent 无需查询接口或配置来判断交付方式。Agent 只生成、检查本地文件并输出交付标记,不读取飞书凭据,不操作上传、分片、权限或卡片接口;这些由 Lodestar 统一完成。交付标记是提交请求,实际结果以附件、交付卡及错误提示为准。
|
|
145
|
+
|
|
146
|
+
安装或更新时会自动删除旧 `lodestar-files` Skill 在 Codex、Claude 和共享插件目录中的受管副本;新版 daemon 启动时也会清理。清理沿用本机数据目录设置,失败会明确报错;显式设置 `LODESTAR_DISABLE_SKILL_SYNC=1` 时保留手工管理的 Skill。
|
|
145
147
|
|
|
146
148
|
在需要的群中发送 `files on`,开启该群的云空间交付。每个群按 `chat_id` 绑定一个固定文件夹,文件夹名与实际群名一致;之后该群各轮交付都直接放入这个文件夹,不再按轮次创建目录。重启后继续复用原目录,同名群之间独立。群改名后,下次云空间交付或再次执行 `files on` 会同步文件夹名称;目录丢失或不可访问时明确报错,不自动新建空目录掩盖问题。
|
|
147
149
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leviyuan/lodestar",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.11",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -58,6 +58,8 @@
|
|
|
58
58
|
"dist/",
|
|
59
59
|
"docs/",
|
|
60
60
|
"scripts/postinstall.cjs",
|
|
61
|
+
"src/data-dir.cjs",
|
|
62
|
+
"src/managed-skill-cleanup.cjs",
|
|
61
63
|
"README.md",
|
|
62
64
|
"LICENSE"
|
|
63
65
|
],
|
package/scripts/postinstall.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
//
|
|
2
|
+
// 清理废弃的受管 Skill 并提示下一步,不在这里拉起向导或 daemon。
|
|
3
3
|
//
|
|
4
4
|
// 为什么不自动拉向导: npm 7+ pipe 了 postinstall 的 stdio, 自动拉向导只能
|
|
5
5
|
// 靠接管 /dev/tty 把终端塞给子进程 —— 这套机制脆弱 (作者原注 "Tricky")。
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
//
|
|
10
10
|
// 稳的做法是 trigger-on-first-run: 用户在真终端首跑 lodestar-daemon 时,
|
|
11
11
|
// cli.ts 发现没 config + isTTY 就自动进入向导 (真 TTY, readline 一定正常)。
|
|
12
|
-
//
|
|
12
|
+
// 清理仅操作本地 Skill 文件,不读配置或凭据,也不启动子进程。
|
|
13
13
|
|
|
14
14
|
const fs = require('fs')
|
|
15
15
|
|
|
@@ -28,10 +28,18 @@ function termWrite (msg) {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
termWrite(' 启动时不检查或更新 Agent,自动更新默认关闭。\n')
|
|
35
|
-
termWrite(' 安装/更新 Agent: lodestar-update --agents-only;定期更新可在 [runtime.agent_auto_update] 中分别开启 codex、claude、dsh。\n\n')
|
|
31
|
+
async function main () {
|
|
32
|
+
const { removeManagedSkill } = require('../src/managed-skill-cleanup.cjs')
|
|
33
|
+
removeManagedSkill('lodestar-files')
|
|
36
34
|
|
|
37
|
-
|
|
35
|
+
termWrite('\n \x1b[1m\x1b[36m✓ Lodestar 已安装\x1b[0m\n')
|
|
36
|
+
termWrite('\n \x1b[2m下一步: 在终端跑 \x1b[32mlodestar-daemon\x1b[0m\x1b[2m 进入配置向导\x1b[0m')
|
|
37
|
+
termWrite('\n \x1b[2m(首次运行会自动拉起向导; 也可直接跑 \x1b[32mlodestar-setup\x1b[0m\x1b[2m)\x1b[0m\n\n')
|
|
38
|
+
termWrite(' 启动时不检查或更新 Agent,自动更新默认关闭。\n')
|
|
39
|
+
termWrite(' 安装/更新 Agent: lodestar-update --agents-only;定期更新可在 [runtime.agent_auto_update] 中分别开启 codex、claude、dsh。\n\n')
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
main().catch(error => {
|
|
43
|
+
console.error('Lodestar 安装清理失败:', error)
|
|
44
|
+
process.exitCode = 1
|
|
45
|
+
})
|
package/src/data-dir.cjs
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Shared by paths.ts and npm postinstall, including installs from a source checkout.
|
|
2
|
+
const { homedir } = require('node:os')
|
|
3
|
+
const { join } = require('node:path')
|
|
4
|
+
|
|
5
|
+
function lodestarDataDir () {
|
|
6
|
+
if (process.env.LODESTAR_DATA_DIR) return process.env.LODESTAR_DATA_DIR
|
|
7
|
+
if (process.env.XDG_DATA_HOME) return join(process.env.XDG_DATA_HOME, 'lodestar')
|
|
8
|
+
if (process.platform === 'win32') {
|
|
9
|
+
return join(process.env.LOCALAPPDATA ?? join(homedir(), 'AppData', 'Local'), 'Lodestar')
|
|
10
|
+
}
|
|
11
|
+
return join(homedir(), '.local', 'share', 'lodestar')
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function managedClaudePluginDir () {
|
|
15
|
+
return join(lodestarDataDir(), 'managed-claude-plugin')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = { lodestarDataDir, managedClaudePluginDir }
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const { readFileSync, rmSync } = require('node:fs')
|
|
2
|
+
const { homedir } = require('node:os')
|
|
3
|
+
const { join } = require('node:path')
|
|
4
|
+
const { managedClaudePluginDir } = require('./data-dir.cjs')
|
|
5
|
+
|
|
6
|
+
// Requires no config, credentials, Agent runtime, or prior build.
|
|
7
|
+
function removeManagedSkill (name, roots, report = console.log) {
|
|
8
|
+
if (process.env.LODESTAR_DISABLE_SKILL_SYNC === '1') {
|
|
9
|
+
report(`skill: sync disabled, skip removal ${name}`)
|
|
10
|
+
return
|
|
11
|
+
}
|
|
12
|
+
const targetRoots = roots ?? [
|
|
13
|
+
join(homedir(), '.codex', 'skills'),
|
|
14
|
+
join(homedir(), '.claude', 'skills'),
|
|
15
|
+
join(managedClaudePluginDir(), 'skills'),
|
|
16
|
+
]
|
|
17
|
+
const errors = []
|
|
18
|
+
for (const root of targetRoots) {
|
|
19
|
+
const dir = join(root, name)
|
|
20
|
+
const skillFile = join(dir, 'SKILL.md')
|
|
21
|
+
let body
|
|
22
|
+
try {
|
|
23
|
+
body = readFileSync(skillFile, 'utf8')
|
|
24
|
+
} catch (error) {
|
|
25
|
+
if (error.code === 'ENOENT') continue
|
|
26
|
+
const failure = new Error(`skill: obsolete removal failed (${skillFile}): ${error}`, { cause: error })
|
|
27
|
+
report(failure.message)
|
|
28
|
+
errors.push(failure)
|
|
29
|
+
continue
|
|
30
|
+
}
|
|
31
|
+
const frontmatter = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(body)?.[1]
|
|
32
|
+
const declaredName = /^name:[ \t]*(?:"([^"]*)"|'([^']*)'|([^\s#]+))[ \t]*$/m.exec(frontmatter ?? '')
|
|
33
|
+
if (!declaredName || (declaredName[1] ?? declaredName[2] ?? declaredName[3]) !== name) {
|
|
34
|
+
report(`skill: obsolete path preserved because ownership is unclear ${skillFile}`)
|
|
35
|
+
continue
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
rmSync(dir, { recursive: true, force: false })
|
|
39
|
+
report(`skill: removed obsolete ${dir}`)
|
|
40
|
+
} catch (error) {
|
|
41
|
+
const failure = new Error(`skill: obsolete removal failed (${dir}): ${error}`, { cause: error })
|
|
42
|
+
report(failure.message)
|
|
43
|
+
errors.push(failure)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (errors.length) throw new AggregateError(errors, `Failed to remove obsolete Skill ${name}`)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = { removeManagedSkill }
|