ccus-cli 0.2.28 → 0.2.29

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 CHANGED
@@ -206,7 +206,7 @@ ccus aggregate serve --input-dir ./team-exports
206
206
 
207
207
  - `ccus sessions` 默认打包本周;支持 `tw`、`lw`、`today`、`5h` 等与 `export` 相同的范围写法。
208
208
  - 只选择文件中至少一条记录落入时间窗的 session,但 zip 内保存完整原始文件,不裁剪内容。
209
- - Claude 文件保持 `<projectDir>/<sessionId>.jsonl` 路径;Codex rollout 合并 `<CODEX_HOME>/sessions` 与 `%APPDATA%/orca/codex-runtime-home/home/sessions`,按相对路径和 JSONL 事件去重后保持 `codex/<sessions 相对路径>`。
209
+ - Claude 文件保持 `<projectDir>/<sessionId>.jsonl` 路径;Codex rollout 合并 `<CODEX_HOME>/sessions`、`%APPDATA%/orca/codex-runtime-home/home/sessions` 与 `%APPDATA%/orca/codex-accounts/<账号 ID>/home/sessions`,自动发现所有账号,按相对路径和 JSONL 事件去重后保持 `codex/<sessions 相对路径>`。
210
210
  - 默认写入 `<data-dir>/sessions/projects_<start>_<end>_<gitUserName>.zip`;`--out` 可指定路径。
211
211
 
212
212
  ## 多人汇总
@@ -361,7 +361,7 @@ ccus install --codex --uninstall # 移除 ccus 的 Stop hook
361
361
  - **定时同步**:Stop hook 还兜底触发 `ccus sync`(与 Claude statusline 对称)——配过 `ccus sync config --target` 后,Codex 每 turn 结束都会检查 3h 周期,到期自动 export + 复制 bundle(含 Codex token/消息)到目标目录。只用 Codex、不开 Claude Code 时也能自动同步。
362
362
  - **缓存节流**:Stop 每 turn 触发,额度按 5 分钟 TTL 缓存(`codex-quota-cache.json`),新鲜缓存命中秒回不 spawn;过期后依次尝试 app-server 与 wham,两路失败返回空,不回退过期缓存。
363
363
  - **字段映射**:app-server 返回 `primary`(5h)/ `secondary`(weekly)两窗口,取各自的 `usedPercent`(驼峰,clamp 0–100);ccus 填进 `rate_limits.five_hour` / `seven_day` 的 `used_percentage`,`computeStatuslineEvent` 读时自动算出 usage。
364
- - **token / 消息 / 额度都进 export / aggregate**:Codex 的 token、用户消息数、API 请求数合并读取 `<CODEX_HOME>/sessions` 与 `%APPDATA%/orca/codex-runtime-home/home/sessions` 的 rollout;同一相对路径的副本按 JSONL 事件去重,并排除 `source.subagent.other="guardian"` 的 Codex Desktop 内部安全审查会话。统计进入 `ccus export` 的 `weeklySummary.codex` / `dailySummaries[].codex` 段;Stop 落盘的额度快照(`source="codex"` 事件)也进 export/aggregate——export bundle 里 Codex 额度单列到 codex 段、与 Claude 分开看,aggregate daily/weekly CSV 则把 Codex **叠加进 Claude 主字段**合计(累加量相加、额度 peak 取两源 max、latest 两源相加、7d 累计含两源读数),不再单列 `codex*` 列;detail.csv 的 `source` 列区分来源。
364
+ - **token / 消息 / 额度都进 export / aggregate**:Codex 的 token、用户消息数、API 请求数合并读取 `<CODEX_HOME>/sessions`、`%APPDATA%/orca/codex-runtime-home/home/sessions` 与 `%APPDATA%/orca/codex-accounts/<账号 ID>/home/sessions` 的 rollout;`CODEX_HOME` 指向 Orca runtime 或托管账号时仍扫描标准 `~/.codex/sessions`,其它自定义目录沿用原有覆盖语义。同一相对路径的副本按 JSONL 事件去重,并排除 `source.subagent.other="guardian"` 的 Codex Desktop 内部安全审查会话。统计进入 `ccus export` 的 `weeklySummary.codex` / `dailySummaries[].codex` 段;Stop 落盘的额度快照(`source="codex"` 事件)也进 export/aggregate——export bundle 里 Codex 额度单列到 codex 段、与 Claude 分开看,aggregate daily/weekly CSV 则把 Codex **叠加进 Claude 主字段**合计(累加量相加、额度 peak 取两源 max、latest 两源相加、7d 累计含两源读数),不再单列 `codex*` 列;detail.csv 的 `source` 列区分来源。
365
365
  - **Windows**:`install --codex` 在 Windows 写 `ccus.cmd __codex-hook`(npm 全局装会生成 `ccus.cmd`);Windows 上 Stop hook 偶发收到非法 JSON(已知 bug #23784),ccus 容错按无 payload 处理、仍照常拉额度 + 落盘。
366
366
 
367
367
  > 该路径依赖 Codex 内部 app-server 协议(`account/rateLimits/read` 的返回结构)与 hooks payload schema,随版本变;解析层宽松,字段缺失返回 null、失败静默。
package/dist/lib/paths.js CHANGED
@@ -19,6 +19,7 @@ exports.getCodexConfigPath = getCodexConfigPath;
19
19
  exports.getCodexHooksPath = getCodexHooksPath;
20
20
  exports.getClaudeDataDir = getClaudeDataDir;
21
21
  exports.getClaudeSettingsPath = getClaudeSettingsPath;
22
+ const node_fs_1 = __importDefault(require("node:fs"));
22
23
  const node_os_1 = __importDefault(require("node:os"));
23
24
  const node_path_1 = __importDefault(require("node:path"));
24
25
  /**
@@ -85,19 +86,46 @@ function getOrcaCodexHome() {
85
86
  const appData = process.env.APPDATA;
86
87
  return appData ? node_path_1.default.join(appData, "orca", "codex-runtime-home", "home") : null;
87
88
  }
89
+ /** 动态发现 Orca 托管账号,添加/移除账号后下一次扫描即可生效。 */
90
+ function getOrcaCodexAccountHomes() {
91
+ const appData = process.env.APPDATA;
92
+ if (!appData) {
93
+ return [];
94
+ }
95
+ const accountsRoot = node_path_1.default.join(appData, "orca", "codex-accounts");
96
+ try {
97
+ return node_fs_1.default.readdirSync(accountsRoot, { withFileTypes: true })
98
+ .filter((entry) => entry.isDirectory())
99
+ .map((entry) => node_path_1.default.resolve(accountsRoot, entry.name, "home"))
100
+ .sort();
101
+ }
102
+ catch (error) {
103
+ const code = error.code;
104
+ if (code === "ENOENT" || code === "ENOTDIR") {
105
+ return [];
106
+ }
107
+ throw error;
108
+ }
109
+ }
88
110
  /**
89
111
  * Codex session 的全部数据源。
90
112
  *
91
- * 默认合并 `~/.codex` 与 Orca runtime home;`CODEX_HOME` 指向 Orca 时仍保留
113
+ * 默认合并 `~/.codex`、Orca runtime home 与各托管账号 home;`CODEX_HOME` 指向 Orca 时仍保留
92
114
  * `~/.codex`,其它显式覆盖则沿用原有覆盖语义。路径按平台规则去重。
93
115
  */
94
116
  function getCodexSessionHomes() {
95
117
  const configuredHome = node_path_1.default.resolve(getCodexHome());
96
118
  const defaultHome = node_path_1.default.resolve(node_path_1.default.join(node_os_1.default.homedir(), ".codex"));
97
119
  const orcaHome = getOrcaCodexHome();
98
- const candidates = orcaHome && samePath(configuredHome, orcaHome)
99
- ? [defaultHome, configuredHome]
100
- : [configuredHome, ...(orcaHome ? [node_path_1.default.resolve(orcaHome)] : [])];
120
+ const orcaHomes = [
121
+ ...(orcaHome ? [node_path_1.default.resolve(orcaHome)] : []),
122
+ ...getOrcaCodexAccountHomes(),
123
+ ];
124
+ const candidates = [
125
+ ...(orcaHomes.some((home) => samePath(configuredHome, home)) ? [defaultHome] : []),
126
+ configuredHome,
127
+ ...orcaHomes,
128
+ ];
101
129
  const seen = new Set();
102
130
  return candidates.filter((candidate) => {
103
131
  const key = pathKey(candidate);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccus-cli",
3
- "version": "0.2.28",
3
+ "version": "0.2.29",
4
4
  "description": "Claude Code statusline usage logger and dashboard CLI",
5
5
  "type": "commonjs",
6
6
  "bin": {