@yoooclaw/cli 0.0.1

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 ADDED
@@ -0,0 +1,80 @@
1
+ # @yoooclaw/cli
2
+
3
+ yoooclaw 独立 CLI 工具 —— 自带后台守护进程(daemon),不依赖 openclaw 客户端在线。
4
+ 设计对齐飞书 [lark-cli](https://github.com/larksuite/cli):Service-oriented 命令树、三层命令体系(Shortcuts / Service Commands / Raw API)、统一 `--format`、Agent-Native。
5
+
6
+ 需求详见 [docs/features/prd-yoooclaw-standalone-cli.md](../../docs/features/prd-yoooclaw-standalone-cli.md)。
7
+
8
+ > **状态:脚手架阶段。** 命令树、全局 flags、统一输出 / 错误层、profile 解析、目录布局已贯通;
9
+ > 各 service 的真实逻辑按后续 imp 文档逐个落地,当前 action 返回 `YOOOCLAW_NOT_IMPLEMENTED` 占位。
10
+
11
+ ## 安装与命令
12
+
13
+ 免安装(npx,每次拉取最新版):
14
+
15
+ ```bash
16
+ npx @yoooclaw/cli --help # 主命令
17
+ npx @yoooclaw/cli notification +today
18
+ ```
19
+
20
+ 全局安装(提供 `yoooclaw` / `yc` 两个命令):
21
+
22
+ ```bash
23
+ npm i -g @yoooclaw/cli
24
+ yoooclaw --help # 主命令
25
+ yc --help # 等价短 alias
26
+ ```
27
+
28
+ > `npx @yoooclaw/cli` 始终调用 `yoooclaw` 入口(`yoooclaw` 与 `yc` 指向同一可执行文件,npx 不会歧义)。
29
+ > 需要 Node `>=22.12.0`。
30
+
31
+ ## 命令体系
32
+
33
+ - **Shortcuts**(`+` 前缀):`yoooclaw notification +today`、`yoooclaw light +blink` …
34
+ - **Service commands**:`yoooclaw <service> <subcommand>`,service 见 `yoooclaw --help`。
35
+ - **Raw API**:`yoooclaw api <METHOD> <PATH> [--data ...]` 直达 daemon HTTP 端点。
36
+
37
+ ### 全局 flags
38
+
39
+ | flag | 说明 |
40
+ | ------------------ | ------------------------------------------------- |
41
+ | `--profile <name>` | 切换 profile(默认 `default`) |
42
+ | `--format <fmt>` | `json\|pretty\|table\|ndjson`(TTY 默认 pretty,管道默认 json) |
43
+ | `--quiet` | 抑制进度日志,只输出最终结果 |
44
+ | `--no-color` | 关闭终端颜色 |
45
+
46
+ ### 输出契约
47
+
48
+ 成功与失败共用同一通道(stdout)与可预测结构;失败额外以非零退出码表达:
49
+
50
+ ```json
51
+ { "ok": false, "error": { "code": "YOOOCLAW_NOT_IMPLEMENTED", "message": "...", "hint": "..." } }
52
+ ```
53
+
54
+ 错误码统一前缀 `YOOOCLAW_*`(见 [src/errors.ts](src/errors.ts))。
55
+
56
+ ## 数据目录
57
+
58
+ `~/.yoooclaw/`(可用 `YOOOCLAW_HOME` 覆盖,便于测试 / 多实例)。布局见 [src/paths.ts](src/paths.ts) 与 PRD「数据模型」。
59
+
60
+ ## 开发
61
+
62
+ ```bash
63
+ bun run build # bun 打包 dist/bin.cjs + dist/index.cjs,tsc 出类型
64
+ bun run typecheck
65
+ bun run test
66
+ node dist/bin.cjs --help
67
+ ```
68
+
69
+ ## 源码结构
70
+
71
+ | 文件 | 职责 |
72
+ | ---------------------------------------- | ------------------------------------------ |
73
+ | [src/bin.ts](src/bin.ts) | 可执行入口(package.json#bin) |
74
+ | [src/index.ts](src/index.ts) | 程序化入口 `run(argv)` + 核心模块导出 |
75
+ | [src/command-tree.ts](src/command-tree.ts) | 命令树声明(单一事实来源) |
76
+ | [src/program.ts](src/program.ts) | 据命令树构建 commander 程序 + action 包装 |
77
+ | [src/context.ts](src/context.ts) | 全局 flags → CliContext,profile 解析 |
78
+ | [src/output/format.ts](src/output/format.ts) | `--format` 统一序列化 + 错误 schema |
79
+ | [src/errors.ts](src/errors.ts) | `YOOOCLAW_*` 错误码 + `YoooclawError` |
80
+ | [src/paths.ts](src/paths.ts) | `~/.yoooclaw/` 目录布局解析 |
package/dist/bin.cjs ADDED
@@ -0,0 +1,494 @@
1
+ #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ function __accessProp(key) {
7
+ return this[key];
8
+ }
9
+ var __toCommonJS = (from) => {
10
+ var entry = (__moduleCache ??= new WeakMap).get(from), desc;
11
+ if (entry)
12
+ return entry;
13
+ entry = __defProp({}, "__esModule", { value: true });
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (var key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(entry, key))
17
+ __defProp(entry, key, {
18
+ get: __accessProp.bind(from, key),
19
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
20
+ });
21
+ }
22
+ __moduleCache.set(from, entry);
23
+ return entry;
24
+ };
25
+ var __moduleCache;
26
+ var __returnValue = (v) => v;
27
+ function __exportSetter(name, newValue) {
28
+ this[name] = __returnValue.bind(null, newValue);
29
+ }
30
+ var __export = (target, all) => {
31
+ for (var name in all)
32
+ __defProp(target, name, {
33
+ get: all[name],
34
+ enumerable: true,
35
+ configurable: true,
36
+ set: __exportSetter.bind(all, name)
37
+ });
38
+ };
39
+
40
+ // src/index.ts
41
+ var exports_src = {};
42
+ __export(exports_src, {
43
+ run: () => run,
44
+ resolveFormat: () => resolveFormat,
45
+ resolveActiveProfile: () => resolveActiveProfile,
46
+ renderResult: () => renderResult,
47
+ renderError: () => renderError,
48
+ paths: () => exports_paths,
49
+ buildProgram: () => buildProgram,
50
+ buildContext: () => buildContext,
51
+ YoooclawError: () => YoooclawError,
52
+ ErrorCode: () => ErrorCode,
53
+ COMMAND_TREE: () => COMMAND_TREE,
54
+ CLI_VERSION: () => CLI_VERSION
55
+ });
56
+ module.exports = __toCommonJS(exports_src);
57
+
58
+ // src/program.ts
59
+ var import_commander = require("commander");
60
+
61
+ // src/command-tree.ts
62
+ var COMMAND_TREE = [
63
+ {
64
+ name: "config",
65
+ summary: "配置管理 \uD83D\uDFE2",
66
+ subcommands: [
67
+ { name: "init", summary: "交互式首次向导,生成 config + gateway token" },
68
+ { name: "show", summary: "显示当前 profile 配置(敏感字段遮罩)" },
69
+ { name: "set <key> <value>", summary: "设置单个配置项(点号路径)" },
70
+ { name: "unset <key>", summary: "删除单个配置项" }
71
+ ]
72
+ },
73
+ {
74
+ name: "profile",
75
+ summary: "多 profile 管理 \uD83D\uDFE2",
76
+ subcommands: [
77
+ { name: "list", summary: "列出所有 profile,标注 active" },
78
+ { name: "use <name>", summary: "切换 active profile" },
79
+ { name: "create <name>", summary: "新建 profile(走 config init 向导)" },
80
+ { name: "delete <name>", summary: "删除 profile(非 active,需 --yes)" }
81
+ ]
82
+ },
83
+ {
84
+ name: "auth",
85
+ summary: "凭据与鉴权 \uD83D\uDFE2/\uD83D\uDFE1",
86
+ subcommands: [
87
+ { name: "set-api-key <key>", summary: "写入 account 级 api-key 到共享凭据文件 \uD83D\uDFE2" },
88
+ { name: "token rotate", summary: "生成新 gateway token 并热重载 \uD83D\uDFE1" },
89
+ { name: "status", summary: "显示鉴权状态(本地检查,不调 daemon)\uD83D\uDFE2" },
90
+ { name: "check", summary: "端到端鉴权体检(调 daemon /daemon/status)\uD83D\uDFE1" }
91
+ ]
92
+ },
93
+ {
94
+ name: "daemon",
95
+ summary: "守护进程管理 \uD83D\uDD35",
96
+ subcommands: [
97
+ { name: "start", summary: "启动 daemon(默认后台 detach)" },
98
+ { name: "stop", summary: "停止 daemon(SIGTERM → 10s → SIGKILL)" },
99
+ { name: "restart", summary: "stop + start,保留原启动参数" },
100
+ { name: "status", summary: "打印 daemon 状态(PID/端口/relay/规则数...)" },
101
+ { name: "logs", summary: "跟踪 daemon 日志" }
102
+ ]
103
+ },
104
+ {
105
+ name: "notification",
106
+ summary: "通知查询 \uD83D\uDFE2",
107
+ subcommands: [
108
+ { name: "search", summary: "按筛选条件查询通知,时间倒序" },
109
+ { name: "summary", summary: "聚合统计 + 样例摘要,供 Agent 总结" },
110
+ { name: "stats", summary: "按维度聚合统计" },
111
+ { name: "storage-path", summary: "打印 notifications 目录绝对路径" }
112
+ ],
113
+ shortcuts: [
114
+ { name: "+today", summary: "今日通知摘要" },
115
+ { name: "+recent", summary: "最近 1 小时通知" },
116
+ { name: "+unread", summary: "(预留)未读通知" }
117
+ ]
118
+ },
119
+ {
120
+ name: "sync",
121
+ summary: "通知同步给记忆系统 \uD83D\uDFE2",
122
+ subcommands: [
123
+ { name: "scan", summary: "扫描未处理通知,返回各日期待同步摘要" },
124
+ { name: "fetch", summary: "获取指定日期未处理通知详情" },
125
+ { name: "commit", summary: "标记指定日期当前批次处理完成" }
126
+ ]
127
+ },
128
+ {
129
+ name: "recording",
130
+ summary: "录音管理 \uD83D\uDFE2/\uD83D\uDFE1",
131
+ subcommands: [
132
+ { name: "list", summary: "列出所有录音 \uD83D\uDFE2" },
133
+ { name: "status <id>", summary: "查看单条录音详情 \uD83D\uDFE2" },
134
+ { name: "storage-path", summary: "打印录音存储目录绝对路径 \uD83D\uDFE2" },
135
+ { name: "setup-asr", summary: "交互式配置 ASR 转写参数 \uD83D\uDFE2" }
136
+ ],
137
+ shortcuts: [{ name: "+latest", summary: "展示最新一条录音详情" }]
138
+ },
139
+ {
140
+ name: "image",
141
+ summary: "图片管理 \uD83D\uDFE2",
142
+ subcommands: [
143
+ { name: "list", summary: "列出所有图片" },
144
+ { name: "status <id>", summary: "查看单张图片详情" },
145
+ { name: "path <id>", summary: "打印图片本地文件绝对路径" },
146
+ { name: "storage-path", summary: "打印图片存储目录绝对路径" }
147
+ ],
148
+ shortcuts: [{ name: "+latest", summary: "展示最新一张图片详情" }]
149
+ },
150
+ {
151
+ name: "light",
152
+ summary: "灯效硬件控制 \uD83D\uDFE1",
153
+ subcommands: [
154
+ { name: "send", summary: "发送灯效指令到硬件(--segments / --preset)" }
155
+ ],
156
+ shortcuts: [{ name: "+blink", summary: "灯效连通性测试" }]
157
+ },
158
+ {
159
+ name: "lightrule",
160
+ summary: "灯效规则管理 \uD83D\uDFE1",
161
+ subcommands: [
162
+ { name: "list", summary: "列出所有规则及状态" },
163
+ { name: "show <id>", summary: "查看单条规则详情" },
164
+ { name: "create", summary: "创建规则(--from-file / --intent ...)" },
165
+ { name: "update <id>", summary: "更新现有规则" },
166
+ { name: "delete <id>", summary: "删除规则(--yes)" },
167
+ { name: "enable <id>", summary: "启用单条规则" },
168
+ { name: "disable <id>", summary: "停用单条规则" }
169
+ ],
170
+ shortcuts: [
171
+ { name: "+on", summary: "启用所有规则" },
172
+ { name: "+off", summary: "停用所有规则(保留定义)" }
173
+ ]
174
+ },
175
+ {
176
+ name: "monitor",
177
+ summary: "定时通知监控任务 \uD83D\uDFE1",
178
+ subcommands: [
179
+ { name: "list", summary: "列出所有监控任务" },
180
+ { name: "show <name>", summary: "查看监控任务详情" },
181
+ { name: "create <name>", summary: "创建监控任务(cron 驱动)" },
182
+ { name: "delete <name>", summary: "删除监控任务(--yes)" },
183
+ { name: "enable <name>", summary: "启用监控任务" },
184
+ { name: "disable <name>", summary: "暂停监控任务" }
185
+ ]
186
+ },
187
+ {
188
+ name: "tunnel",
189
+ summary: "Relay 隧道 \uD83D\uDFE1",
190
+ subcommands: [
191
+ { name: "status", summary: "查询 Relay 连接状态" },
192
+ { name: "reconnect", summary: "强制重连" }
193
+ ],
194
+ shortcuts: [{ name: "+test", summary: "端到端联通性自检(echo 回环)" }]
195
+ },
196
+ {
197
+ name: "log",
198
+ summary: "日志检索 \uD83D\uDFE2",
199
+ args: "[keyword]",
200
+ shortcuts: [{ name: "+errors", summary: "昨天起的 error 级日志" }]
201
+ },
202
+ {
203
+ name: "gateway",
204
+ summary: "协议自检 \uD83D\uDFE2/\uD83D\uDFE1",
205
+ subcommands: [
206
+ { name: "test", summary: "模拟手机端调 daemon /notifications,验证连通/鉴权/relay \uD83D\uDFE1" }
207
+ ]
208
+ },
209
+ {
210
+ name: "api",
211
+ summary: "Raw HTTP escape hatch \uD83D\uDFE1",
212
+ args: "<method> <path>"
213
+ },
214
+ {
215
+ name: "migrate",
216
+ summary: "从 openclaw 插件迁移数据 \uD83D\uDFE2",
217
+ subcommands: [
218
+ { name: "from-openclaw", summary: "迁移 notifications/recordings/规则/api-key 到 ~/.yoooclaw" }
219
+ ]
220
+ },
221
+ {
222
+ name: "update",
223
+ summary: "版本检查 \uD83D\uDFE2",
224
+ subcommands: [
225
+ { name: "self", summary: "检查 npm 最新版本并提示(不自动更新)" }
226
+ ]
227
+ },
228
+ {
229
+ name: "doctor",
230
+ summary: "环境自检:Node/目录/keychain/daemon/relay \uD83D\uDFE2/\uD83D\uDFE1"
231
+ }
232
+ ];
233
+
234
+ // src/context.ts
235
+ var import_node_fs = require("node:fs");
236
+
237
+ // src/paths.ts
238
+ var exports_paths = {};
239
+ __export(exports_paths, {
240
+ sharedCredentialsPath: () => sharedCredentialsPath,
241
+ rootDir: () => rootDir,
242
+ profilePaths: () => profilePaths,
243
+ profileDir: () => profileDir,
244
+ activeProfilePath: () => activeProfilePath,
245
+ DEFAULT_PROFILE: () => DEFAULT_PROFILE
246
+ });
247
+ var import_node_os = require("node:os");
248
+ var import_node_path = require("node:path");
249
+ var DEFAULT_PROFILE = "default";
250
+ function rootDir() {
251
+ return process.env.YOOOCLAW_HOME?.trim() || import_node_path.join(import_node_os.homedir(), ".yoooclaw");
252
+ }
253
+ function sharedCredentialsPath() {
254
+ return import_node_path.join(rootDir(), "credentials.json");
255
+ }
256
+ function activeProfilePath() {
257
+ return import_node_path.join(rootDir(), "active-profile");
258
+ }
259
+ function profileDir(profile) {
260
+ return import_node_path.join(rootDir(), "profiles", profile);
261
+ }
262
+ function profilePaths(profile) {
263
+ const dir = profileDir(profile);
264
+ return {
265
+ profile,
266
+ dir,
267
+ config: import_node_path.join(dir, "config.json"),
268
+ credentials: import_node_path.join(dir, "credentials.json"),
269
+ daemonLock: import_node_path.join(dir, "daemon.lock"),
270
+ daemonLog: import_node_path.join(dir, "daemon.log"),
271
+ notifications: import_node_path.join(dir, "notifications"),
272
+ recordings: import_node_path.join(dir, "recordings"),
273
+ images: import_node_path.join(dir, "images"),
274
+ lightRules: import_node_path.join(dir, "light-rules"),
275
+ state: import_node_path.join(dir, "state")
276
+ };
277
+ }
278
+
279
+ // src/errors.ts
280
+ var ErrorCode = {
281
+ UNKNOWN: "YOOOCLAW_UNKNOWN",
282
+ INVALID_ARGUMENT: "YOOOCLAW_INVALID_ARGUMENT",
283
+ NOT_IMPLEMENTED: "YOOOCLAW_NOT_IMPLEMENTED",
284
+ DAEMON_NOT_RUNNING: "YOOOCLAW_DAEMON_NOT_RUNNING",
285
+ DAEMON_ALREADY_RUNNING: "YOOOCLAW_DAEMON_ALREADY_RUNNING",
286
+ UNAUTHORIZED: "YOOOCLAW_UNAUTHORIZED",
287
+ CONFIG_INVALID: "YOOOCLAW_CONFIG_INVALID",
288
+ PROFILE_NOT_FOUND: "YOOOCLAW_PROFILE_NOT_FOUND",
289
+ IMAGE_NOT_READY: "YOOOCLAW_IMAGE_NOT_READY",
290
+ NOT_FOUND: "YOOOCLAW_NOT_FOUND"
291
+ };
292
+
293
+ class YoooclawError extends Error {
294
+ code;
295
+ details;
296
+ exitCode;
297
+ constructor(code, message, details = {}, exitCode = 1) {
298
+ super(message);
299
+ this.name = "YoooclawError";
300
+ this.code = code;
301
+ this.details = details;
302
+ this.exitCode = exitCode;
303
+ }
304
+ toErrorPayload() {
305
+ return { code: this.code, message: this.message, ...this.details };
306
+ }
307
+ }
308
+ function notImplemented(command) {
309
+ return new YoooclawError(ErrorCode.NOT_IMPLEMENTED, `命令 \`${command}\` 尚未实现`, { hint: "该命令处于脚手架阶段,后续按 imp 文档逐步落地" });
310
+ }
311
+
312
+ // src/output/format.ts
313
+ var OUTPUT_FORMATS = [
314
+ "json",
315
+ "pretty",
316
+ "table",
317
+ "ndjson"
318
+ ];
319
+ function resolveFormat(requested, isTty = process.stdout.isTTY ?? false) {
320
+ if (requested && requested !== "auto") {
321
+ if (OUTPUT_FORMATS.includes(requested)) {
322
+ return requested;
323
+ }
324
+ throw new YoooclawError("YOOOCLAW_INVALID_ARGUMENT", `不支持的输出格式:${requested}`, { hint: `可选值:${OUTPUT_FORMATS.join(" | ")} | auto` });
325
+ }
326
+ return isTty ? "pretty" : "json";
327
+ }
328
+ function write(stream, text) {
329
+ stream.write(text.endsWith(`
330
+ `) ? text : text + `
331
+ `);
332
+ }
333
+ function renderResult(data, opts) {
334
+ const stream = opts.stream ?? process.stdout;
335
+ switch (opts.format) {
336
+ case "json":
337
+ write(stream, JSON.stringify(data));
338
+ return;
339
+ case "pretty":
340
+ write(stream, JSON.stringify(data, null, 2));
341
+ return;
342
+ case "ndjson": {
343
+ const rows = Array.isArray(data) ? data : [data];
344
+ for (const row of rows)
345
+ stream.write(JSON.stringify(row) + `
346
+ `);
347
+ return;
348
+ }
349
+ case "table":
350
+ write(stream, renderTable(data));
351
+ return;
352
+ }
353
+ }
354
+ function renderError(err, opts) {
355
+ const stream = opts.stream ?? process.stdout;
356
+ const error = err instanceof YoooclawError ? err.toErrorPayload() : {
357
+ code: "YOOOCLAW_UNKNOWN",
358
+ message: err instanceof Error ? err.message : String(err)
359
+ };
360
+ const payload = { ok: false, error };
361
+ const text = opts.format === "pretty" ? JSON.stringify(payload, null, 2) : JSON.stringify(payload);
362
+ write(stream, text);
363
+ }
364
+ function renderTable(data) {
365
+ if (!Array.isArray(data) || data.length === 0) {
366
+ return JSON.stringify(data, null, 2);
367
+ }
368
+ const rows = data.filter((r) => typeof r === "object" && r !== null && !Array.isArray(r));
369
+ if (rows.length !== data.length) {
370
+ return JSON.stringify(data, null, 2);
371
+ }
372
+ const columns = Array.from(rows.reduce((set, row) => {
373
+ for (const key of Object.keys(row))
374
+ set.add(key);
375
+ return set;
376
+ }, new Set));
377
+ const cell = (v) => v === null || v === undefined ? "" : typeof v === "object" ? JSON.stringify(v) : String(v);
378
+ const widths = columns.map((col) => Math.max(col.length, ...rows.map((row) => cell(row[col]).length)));
379
+ const pad = (text, width) => text.padEnd(width);
380
+ const header = columns.map((col, i) => pad(col, widths[i])).join(" ");
381
+ const divider = widths.map((w) => "-".repeat(w)).join(" ");
382
+ const body = rows.map((row) => columns.map((col, i) => pad(cell(row[col]), widths[i])).join(" ")).join(`
383
+ `);
384
+ return [header, divider, body].join(`
385
+ `);
386
+ }
387
+
388
+ // src/context.ts
389
+ function resolveActiveProfile(flagProfile) {
390
+ if (flagProfile?.trim())
391
+ return flagProfile.trim();
392
+ const envProfile = process.env.YOOOCLAW_PROFILE?.trim();
393
+ if (envProfile)
394
+ return envProfile;
395
+ const file = activeProfilePath();
396
+ if (import_node_fs.existsSync(file)) {
397
+ const name = import_node_fs.readFileSync(file, "utf-8").trim();
398
+ if (name)
399
+ return name;
400
+ }
401
+ return DEFAULT_PROFILE;
402
+ }
403
+ function buildContext(flags) {
404
+ const profile = resolveActiveProfile(flags.profile);
405
+ return {
406
+ profile,
407
+ paths: profilePaths(profile),
408
+ format: resolveFormat(flags.format),
409
+ quiet: flags.quiet ?? false,
410
+ color: flags.color ?? true
411
+ };
412
+ }
413
+
414
+ // src/version.ts
415
+ var import_node_fs2 = require("node:fs");
416
+ function readBuildInjectedVersion() {
417
+ if (false) {}
418
+ const version = "0.0.1".trim();
419
+ return version || undefined;
420
+ }
421
+ function readVersionFromPackageJson() {
422
+ try {
423
+ const packageJsonUrl = new URL("../package.json", "file:///Users/cobb/github/openclaw-plugin/packages/cli/src/version.ts");
424
+ const packageJson = JSON.parse(import_node_fs2.readFileSync(packageJsonUrl, "utf-8"));
425
+ const version = packageJson.version?.trim();
426
+ return version || undefined;
427
+ } catch {
428
+ return;
429
+ }
430
+ }
431
+ var CLI_VERSION = readBuildInjectedVersion() ?? readVersionFromPackageJson() ?? "unknown";
432
+
433
+ // src/program.ts
434
+ function wrapAction(handler) {
435
+ return async (...rawArgs) => {
436
+ const command = rawArgs.at(-1);
437
+ const opts = rawArgs.at(-2);
438
+ const positionals = rawArgs.slice(0, -2);
439
+ const globals = command.optsWithGlobals();
440
+ let ctx;
441
+ try {
442
+ ctx = buildContext(globals);
443
+ const result = await handler(ctx, positionals, opts);
444
+ renderResult(result, { format: ctx.format });
445
+ } catch (err) {
446
+ const format = ctx?.format ?? "json";
447
+ renderError(err, { format });
448
+ process.exitCode = err instanceof YoooclawError ? err.exitCode : 1;
449
+ }
450
+ };
451
+ }
452
+ function stubHandler(commandPath) {
453
+ return () => {
454
+ throw notImplemented(commandPath);
455
+ };
456
+ }
457
+ function attachService(program, spec) {
458
+ const service = program.command(spec.name).description(spec.summary);
459
+ if (!spec.subcommands || spec.subcommands.length === 0) {
460
+ if (spec.args) {
461
+ service.arguments(spec.args);
462
+ }
463
+ service.action(wrapAction(stubHandler(spec.name)));
464
+ } else {
465
+ for (const sub of spec.subcommands) {
466
+ const path = `${spec.name} ${sub.name}`;
467
+ service.command(sub.name).description(sub.summary).action(wrapAction(stubHandler(path)));
468
+ }
469
+ }
470
+ for (const shortcut of spec.shortcuts ?? []) {
471
+ const path = `${spec.name} ${shortcut.name}`;
472
+ service.command(shortcut.name).description(shortcut.summary).action(wrapAction(stubHandler(path)));
473
+ }
474
+ }
475
+ function buildProgram() {
476
+ const program = new import_commander.Command;
477
+ program.name("yoooclaw").description("yoooclaw —— 独立守护进程 + CLI:接收手机通知、Relay 隧道、灯效规则评估(Agent-Native)").version(CLI_VERSION, "-v, --version", "显示 CLI 版本号").option("--profile <name>", "切换 profile(默认 default)").option("--format <format>", "输出格式:json|pretty|table|ndjson(TTY 默认 pretty,管道默认 json)").option("--quiet", "抑制进度日志,只输出最终结果").option("--no-color", "关闭终端颜色").showHelpAfterError();
478
+ for (const spec of COMMAND_TREE) {
479
+ attachService(program, spec);
480
+ }
481
+ return program;
482
+ }
483
+
484
+ // src/index.ts
485
+ async function run(argv = process.argv) {
486
+ const program = buildProgram();
487
+ await program.parseAsync(argv);
488
+ }
489
+
490
+ // src/bin.ts
491
+ run(process.argv);
492
+
493
+ //# debugId=885B6E71DB5ADDF164756E2164756E21
494
+ //# sourceMappingURL=bin.cjs.map
@@ -0,0 +1,18 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/program.ts", "../src/command-tree.ts", "../src/context.ts", "../src/paths.ts", "../src/errors.ts", "../src/output/format.ts", "../src/version.ts", "../src/index.ts", "../src/bin.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * 构建 yoooclaw 的 commander 程序。\n *\n * 命令树来自 command-tree.ts(单一事实来源)。脚手架阶段所有 action 走 notImplemented\n * 占位,但已贯通全局 flags、CliContext 解析与统一输出/错误层 —— 后续替换 action 体即可。\n */\nimport { Command } from \"commander\";\nimport { COMMAND_TREE, type ServiceSpec } from \"./command-tree.js\";\nimport { buildContext, type CliContext, type GlobalFlags } from \"./context.js\";\nimport { renderError, renderResult } from \"./output/format.js\";\nimport { YoooclawError, notImplemented } from \"./errors.js\";\nimport { CLI_VERSION } from \"./version.js\";\n\n/** 命令处理器签名:拿到上下文 + commander 解析后的参数/选项,返回可序列化结果。 */\nexport type CommandHandler = (\n ctx: CliContext,\n args: unknown[],\n opts: Record<string, unknown>,\n) => unknown;\n\n/** 把 handler 包成 commander action:解析 ctx → 执行 → 统一渲染结果 / 错误。 */\nfunction wrapAction(handler: CommandHandler) {\n return async (...rawArgs: unknown[]): Promise<void> => {\n // commander 传参:[...positional, options, command]\n const command = rawArgs.at(-1) as Command;\n const opts = rawArgs.at(-2) as Record<string, unknown>;\n const positionals = rawArgs.slice(0, -2);\n const globals = command.optsWithGlobals() as GlobalFlags;\n\n let ctx: CliContext | undefined;\n try {\n ctx = buildContext(globals);\n const result = await handler(ctx, positionals, opts);\n renderResult(result, { format: ctx.format });\n } catch (err) {\n const format = ctx?.format ?? \"json\";\n renderError(err, { format });\n process.exitCode = err instanceof YoooclawError ? err.exitCode : 1;\n }\n };\n}\n\n/** 脚手架阶段的占位 handler。 */\nfunction stubHandler(commandPath: string): CommandHandler {\n return () => {\n throw notImplemented(commandPath);\n };\n}\n\nfunction attachService(program: Command, spec: ServiceSpec): void {\n const service = program.command(spec.name).description(spec.summary);\n\n // leaf 命令:直接挂 action(如 `yoooclaw doctor` / `yoooclaw api <method> <path>`)\n if (!spec.subcommands || spec.subcommands.length === 0) {\n if (spec.args) {\n // commander 的位置参数声明随命令名给出\n service.arguments(spec.args);\n }\n service.action(wrapAction(stubHandler(spec.name)));\n } else {\n for (const sub of spec.subcommands) {\n const path = `${spec.name} ${sub.name}`;\n service\n .command(sub.name)\n .description(sub.summary)\n .action(wrapAction(stubHandler(path)));\n }\n }\n\n // shortcuts(`+` 前缀)作为该 service 下的子命令注册\n for (const shortcut of spec.shortcuts ?? []) {\n const path = `${spec.name} ${shortcut.name}`;\n service\n .command(shortcut.name)\n .description(shortcut.summary)\n .action(wrapAction(stubHandler(path)));\n }\n}\n\n/** 构建并返回顶层 commander 程序。 */\nexport function buildProgram(): Command {\n const program = new Command();\n\n program\n .name(\"yoooclaw\")\n .description(\n \"yoooclaw —— 独立守护进程 + CLI:接收手机通知、Relay 隧道、灯效规则评估(Agent-Native)\",\n )\n .version(CLI_VERSION, \"-v, --version\", \"显示 CLI 版本号\")\n // 全局 flags(对所有命令生效)\n .option(\"--profile <name>\", \"切换 profile(默认 default)\")\n .option(\n \"--format <format>\",\n \"输出格式:json|pretty|table|ndjson(TTY 默认 pretty,管道默认 json)\",\n )\n .option(\"--quiet\", \"抑制进度日志,只输出最终结果\")\n .option(\"--no-color\", \"关闭终端颜色\")\n // 顶层无子命令时打印帮助\n .showHelpAfterError();\n\n for (const spec of COMMAND_TREE) {\n attachService(program, spec);\n }\n\n return program;\n}\n",
6
+ "/**\n * 命令树声明 —— Service-oriented,对齐 lark-cli 形态与本仓 PRD「命令树总览」。\n *\n * 这是命令树的**单一事实来源**:program.ts 据此构建 commander 程序。\n * 脚手架阶段每个 action 走统一 notImplemented 占位,后续按 service 逐个落地真实逻辑。\n *\n * daemon 依赖标记(仅文档用途,体现在 summary 里):\n * 🟢 不需要 daemon 🟡 需要 daemon 在跑 🔵 进程类(管理 daemon 自身)\n */\n\nexport interface SubcommandSpec {\n /** 子命令名 + 位置参数,如 `show <id>`、`api <method> <path>` */\n name: string;\n summary: string;\n}\n\nexport interface ShortcutSpec {\n /** 含 `+` 前缀的快捷命令名,如 `+today` */\n name: string;\n summary: string;\n}\n\nexport interface ServiceSpec {\n name: string;\n summary: string;\n /** 子命令列表。leaf 命令(直接执行,无子命令)省略此项并提供 `args`。 */\n subcommands?: SubcommandSpec[];\n /** leaf 命令的位置参数,如 `[keyword]`、`<method> <path>`。 */\n args?: string;\n shortcuts?: ShortcutSpec[];\n}\n\nexport const COMMAND_TREE: ServiceSpec[] = [\n {\n name: \"config\",\n summary: \"配置管理 🟢\",\n subcommands: [\n { name: \"init\", summary: \"交互式首次向导,生成 config + gateway token\" },\n { name: \"show\", summary: \"显示当前 profile 配置(敏感字段遮罩)\" },\n { name: \"set <key> <value>\", summary: \"设置单个配置项(点号路径)\" },\n { name: \"unset <key>\", summary: \"删除单个配置项\" },\n ],\n },\n {\n name: \"profile\",\n summary: \"多 profile 管理 🟢\",\n subcommands: [\n { name: \"list\", summary: \"列出所有 profile,标注 active\" },\n { name: \"use <name>\", summary: \"切换 active profile\" },\n { name: \"create <name>\", summary: \"新建 profile(走 config init 向导)\" },\n { name: \"delete <name>\", summary: \"删除 profile(非 active,需 --yes)\" },\n ],\n },\n {\n name: \"auth\",\n summary: \"凭据与鉴权 🟢/🟡\",\n subcommands: [\n { name: \"set-api-key <key>\", summary: \"写入 account 级 api-key 到共享凭据文件 🟢\" },\n { name: \"token rotate\", summary: \"生成新 gateway token 并热重载 🟡\" },\n { name: \"status\", summary: \"显示鉴权状态(本地检查,不调 daemon)🟢\" },\n { name: \"check\", summary: \"端到端鉴权体检(调 daemon /daemon/status)🟡\" },\n ],\n },\n {\n name: \"daemon\",\n summary: \"守护进程管理 🔵\",\n subcommands: [\n { name: \"start\", summary: \"启动 daemon(默认后台 detach)\" },\n { name: \"stop\", summary: \"停止 daemon(SIGTERM → 10s → SIGKILL)\" },\n { name: \"restart\", summary: \"stop + start,保留原启动参数\" },\n { name: \"status\", summary: \"打印 daemon 状态(PID/端口/relay/规则数...)\" },\n { name: \"logs\", summary: \"跟踪 daemon 日志\" },\n ],\n },\n {\n name: \"notification\",\n summary: \"通知查询 🟢\",\n subcommands: [\n { name: \"search\", summary: \"按筛选条件查询通知,时间倒序\" },\n { name: \"summary\", summary: \"聚合统计 + 样例摘要,供 Agent 总结\" },\n { name: \"stats\", summary: \"按维度聚合统计\" },\n { name: \"storage-path\", summary: \"打印 notifications 目录绝对路径\" },\n ],\n shortcuts: [\n { name: \"+today\", summary: \"今日通知摘要\" },\n { name: \"+recent\", summary: \"最近 1 小时通知\" },\n { name: \"+unread\", summary: \"(预留)未读通知\" },\n ],\n },\n {\n name: \"sync\",\n summary: \"通知同步给记忆系统 🟢\",\n subcommands: [\n { name: \"scan\", summary: \"扫描未处理通知,返回各日期待同步摘要\" },\n { name: \"fetch\", summary: \"获取指定日期未处理通知详情\" },\n { name: \"commit\", summary: \"标记指定日期当前批次处理完成\" },\n ],\n },\n {\n name: \"recording\",\n summary: \"录音管理 🟢/🟡\",\n subcommands: [\n { name: \"list\", summary: \"列出所有录音 🟢\" },\n { name: \"status <id>\", summary: \"查看单条录音详情 🟢\" },\n { name: \"storage-path\", summary: \"打印录音存储目录绝对路径 🟢\" },\n { name: \"setup-asr\", summary: \"交互式配置 ASR 转写参数 🟢\" },\n ],\n shortcuts: [{ name: \"+latest\", summary: \"展示最新一条录音详情\" }],\n },\n {\n name: \"image\",\n summary: \"图片管理 🟢\",\n subcommands: [\n { name: \"list\", summary: \"列出所有图片\" },\n { name: \"status <id>\", summary: \"查看单张图片详情\" },\n { name: \"path <id>\", summary: \"打印图片本地文件绝对路径\" },\n { name: \"storage-path\", summary: \"打印图片存储目录绝对路径\" },\n ],\n shortcuts: [{ name: \"+latest\", summary: \"展示最新一张图片详情\" }],\n },\n {\n name: \"light\",\n summary: \"灯效硬件控制 🟡\",\n subcommands: [\n { name: \"send\", summary: \"发送灯效指令到硬件(--segments / --preset)\" },\n ],\n shortcuts: [{ name: \"+blink\", summary: \"灯效连通性测试\" }],\n },\n {\n name: \"lightrule\",\n summary: \"灯效规则管理 🟡\",\n subcommands: [\n { name: \"list\", summary: \"列出所有规则及状态\" },\n { name: \"show <id>\", summary: \"查看单条规则详情\" },\n { name: \"create\", summary: \"创建规则(--from-file / --intent ...)\" },\n { name: \"update <id>\", summary: \"更新现有规则\" },\n { name: \"delete <id>\", summary: \"删除规则(--yes)\" },\n { name: \"enable <id>\", summary: \"启用单条规则\" },\n { name: \"disable <id>\", summary: \"停用单条规则\" },\n ],\n shortcuts: [\n { name: \"+on\", summary: \"启用所有规则\" },\n { name: \"+off\", summary: \"停用所有规则(保留定义)\" },\n ],\n },\n {\n name: \"monitor\",\n summary: \"定时通知监控任务 🟡\",\n subcommands: [\n { name: \"list\", summary: \"列出所有监控任务\" },\n { name: \"show <name>\", summary: \"查看监控任务详情\" },\n { name: \"create <name>\", summary: \"创建监控任务(cron 驱动)\" },\n { name: \"delete <name>\", summary: \"删除监控任务(--yes)\" },\n { name: \"enable <name>\", summary: \"启用监控任务\" },\n { name: \"disable <name>\", summary: \"暂停监控任务\" },\n ],\n },\n {\n name: \"tunnel\",\n summary: \"Relay 隧道 🟡\",\n subcommands: [\n { name: \"status\", summary: \"查询 Relay 连接状态\" },\n { name: \"reconnect\", summary: \"强制重连\" },\n ],\n shortcuts: [{ name: \"+test\", summary: \"端到端联通性自检(echo 回环)\" }],\n },\n {\n name: \"log\",\n summary: \"日志检索 🟢\",\n args: \"[keyword]\",\n shortcuts: [{ name: \"+errors\", summary: \"昨天起的 error 级日志\" }],\n },\n {\n name: \"gateway\",\n summary: \"协议自检 🟢/🟡\",\n subcommands: [\n { name: \"test\", summary: \"模拟手机端调 daemon /notifications,验证连通/鉴权/relay 🟡\" },\n ],\n },\n {\n name: \"api\",\n summary: \"Raw HTTP escape hatch 🟡\",\n args: \"<method> <path>\",\n },\n {\n name: \"migrate\",\n summary: \"从 openclaw 插件迁移数据 🟢\",\n subcommands: [\n { name: \"from-openclaw\", summary: \"迁移 notifications/recordings/规则/api-key 到 ~/.yoooclaw\" },\n ],\n },\n {\n name: \"update\",\n summary: \"版本检查 🟢\",\n subcommands: [\n { name: \"self\", summary: \"检查 npm 最新版本并提示(不自动更新)\" },\n ],\n },\n {\n name: \"doctor\",\n summary: \"环境自检:Node/目录/keychain/daemon/relay 🟢/🟡\",\n },\n];\n",
7
+ "/**\n * 全局执行上下文 —— 由全局 flags 解析得到,贯穿所有命令。\n */\nimport { existsSync, readFileSync } from \"node:fs\";\nimport {\n DEFAULT_PROFILE,\n activeProfilePath,\n profilePaths,\n type ProfilePaths,\n} from \"./paths.js\";\nimport { resolveFormat, type OutputFormat } from \"./output/format.js\";\n\nexport interface GlobalFlags {\n profile?: string;\n format?: string;\n quiet?: boolean;\n color?: boolean;\n}\n\nexport interface CliContext {\n profile: string;\n paths: ProfilePaths;\n format: OutputFormat;\n quiet: boolean;\n color: boolean;\n}\n\n/** 解析当前 active profile:--profile > $YOOOCLAW_PROFILE > active-profile 文件 > default。 */\nexport function resolveActiveProfile(flagProfile?: string): string {\n if (flagProfile?.trim()) return flagProfile.trim();\n const envProfile = process.env.YOOOCLAW_PROFILE?.trim();\n if (envProfile) return envProfile;\n const file = activeProfilePath();\n if (existsSync(file)) {\n const name = readFileSync(file, \"utf-8\").trim();\n if (name) return name;\n }\n return DEFAULT_PROFILE;\n}\n\n/** 把全局 flags 物化成贯穿命令的 CliContext。 */\nexport function buildContext(flags: GlobalFlags): CliContext {\n const profile = resolveActiveProfile(flags.profile);\n return {\n profile,\n paths: profilePaths(profile),\n format: resolveFormat(flags.format),\n quiet: flags.quiet ?? false,\n // commander 对 --no-color 解析为 color:false;缺省 true\n color: flags.color ?? true,\n };\n}\n",
8
+ "/**\n * `~/.yoooclaw/` 目录布局解析(对齐 PRD「数据模型 / 目录布局」)。\n *\n * ~/.yoooclaw/\n * credentials.json account 级共享凭据(api-key),跨 profile 且与插件共享\n * active-profile 当前 active profile 名(文本)\n * profiles/<profile>/\n * config.json\n * credentials.json instance 级密文(gateway token / webhook secret)\n * daemon.lock / daemon.log\n * notifications/ recordings/ images/ light-rules/ state/\n */\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport const DEFAULT_PROFILE = \"default\";\n\n/** CLI 根数据目录。可用 `YOOOCLAW_HOME` 覆盖(测试 / 多实例隔离)。 */\nexport function rootDir(): string {\n return process.env.YOOOCLAW_HOME?.trim() || join(homedir(), \".yoooclaw\");\n}\n\n/** account 级共享凭据文件(顶层,跨 profile + 插件共享)。 */\nexport function sharedCredentialsPath(): string {\n return join(rootDir(), \"credentials.json\");\n}\n\n/** 记录当前 active profile 的文本文件。 */\nexport function activeProfilePath(): string {\n return join(rootDir(), \"active-profile\");\n}\n\n/** 某个 profile 的目录。 */\nexport function profileDir(profile: string): string {\n return join(rootDir(), \"profiles\", profile);\n}\n\nexport interface ProfilePaths {\n profile: string;\n dir: string;\n config: string;\n credentials: string;\n daemonLock: string;\n daemonLog: string;\n notifications: string;\n recordings: string;\n images: string;\n lightRules: string;\n state: string;\n}\n\n/** 解析某个 profile 下的全部关键路径。 */\nexport function profilePaths(profile: string): ProfilePaths {\n const dir = profileDir(profile);\n return {\n profile,\n dir,\n config: join(dir, \"config.json\"),\n credentials: join(dir, \"credentials.json\"),\n daemonLock: join(dir, \"daemon.lock\"),\n daemonLog: join(dir, \"daemon.log\"),\n notifications: join(dir, \"notifications\"),\n recordings: join(dir, \"recordings\"),\n images: join(dir, \"images\"),\n lightRules: join(dir, \"light-rules\"),\n state: join(dir, \"state\"),\n };\n}\n",
9
+ "/**\n * 结构化错误码 —— 进入半正式契约,命名前缀统一 `YOOOCLAW_*`。\n * 命令失败时统一以 `{ ok: false, error: { code, message, ... } }` 输出(见 output/format.ts)。\n */\nexport const ErrorCode = {\n /** 通用 / 未归类错误 */\n UNKNOWN: \"YOOOCLAW_UNKNOWN\",\n /** 参数校验失败 */\n INVALID_ARGUMENT: \"YOOOCLAW_INVALID_ARGUMENT\",\n /** 该命令尚未实现(脚手架阶段占位) */\n NOT_IMPLEMENTED: \"YOOOCLAW_NOT_IMPLEMENTED\",\n /** daemon 未运行 */\n DAEMON_NOT_RUNNING: \"YOOOCLAW_DAEMON_NOT_RUNNING\",\n /** daemon 已在运行(单例保护) */\n DAEMON_ALREADY_RUNNING: \"YOOOCLAW_DAEMON_ALREADY_RUNNING\",\n /** 鉴权失败 / token 不一致 */\n UNAUTHORIZED: \"YOOOCLAW_UNAUTHORIZED\",\n /** 配置缺失或非法 */\n CONFIG_INVALID: \"YOOOCLAW_CONFIG_INVALID\",\n /** profile 不存在 */\n PROFILE_NOT_FOUND: \"YOOOCLAW_PROFILE_NOT_FOUND\",\n /** 图片尚未下载完成 */\n IMAGE_NOT_READY: \"YOOOCLAW_IMAGE_NOT_READY\",\n /** 资源未找到 */\n NOT_FOUND: \"YOOOCLAW_NOT_FOUND\",\n} as const;\n\nexport type ErrorCodeValue = (typeof ErrorCode)[keyof typeof ErrorCode];\n\nexport interface YoooclawErrorDetails {\n hint?: string;\n checkedPaths?: string[];\n [key: string]: unknown;\n}\n\n/**\n * 携带结构化错误码的错误。CLI 顶层捕获后按 `--format` 序列化为统一错误 schema。\n */\nexport class YoooclawError extends Error {\n readonly code: ErrorCodeValue;\n readonly details: YoooclawErrorDetails;\n /** 进程退出码,默认 1 */\n readonly exitCode: number;\n\n constructor(\n code: ErrorCodeValue,\n message: string,\n details: YoooclawErrorDetails = {},\n exitCode = 1,\n ) {\n super(message);\n this.name = \"YoooclawError\";\n this.code = code;\n this.details = details;\n this.exitCode = exitCode;\n }\n\n toErrorPayload(): {\n code: ErrorCodeValue;\n message: string;\n } & YoooclawErrorDetails {\n return { code: this.code, message: this.message, ...this.details };\n }\n}\n\nexport function notImplemented(command: string): YoooclawError {\n return new YoooclawError(\n ErrorCode.NOT_IMPLEMENTED,\n `命令 \\`${command}\\` 尚未实现`,\n { hint: \"该命令处于脚手架阶段,后续按 imp 文档逐步落地\" },\n );\n}\n",
10
+ "/**\n * 统一输出层 —— 所有命令的 stdout 走这里序列化。\n *\n * 支持 `--format json|pretty|table|ndjson`:\n * - json JSON.stringify(data) 单行 (非 TTY / 管道默认)\n * - pretty JSON.stringify(data, null, 2) (TTY 默认;后续可加颜色)\n * - table 表格输出(结果为数组时)\n * - ndjson 每条结果一行 JSON,无包裹数组 (流式 / Agent 消费)\n *\n * 错误与正常输出共用同一 schema:`{ ok: false, error: { code, message, ... } }`。\n */\nimport { YoooclawError, type ErrorCodeValue } from \"../errors.js\";\n\nexport type OutputFormat = \"json\" | \"pretty\" | \"table\" | \"ndjson\";\nexport const OUTPUT_FORMATS: OutputFormat[] = [\n \"json\",\n \"pretty\",\n \"table\",\n \"ndjson\",\n];\n\n/** 解析用户传入的 --format;`auto` / 缺省时按 TTY 判定。 */\nexport function resolveFormat(\n requested: string | undefined,\n isTty = process.stdout.isTTY ?? false,\n): OutputFormat {\n if (requested && requested !== \"auto\") {\n if ((OUTPUT_FORMATS as string[]).includes(requested)) {\n return requested as OutputFormat;\n }\n throw new YoooclawError(\n \"YOOOCLAW_INVALID_ARGUMENT\" as ErrorCodeValue,\n `不支持的输出格式:${requested}`,\n { hint: `可选值:${OUTPUT_FORMATS.join(\" | \")} | auto` },\n );\n }\n return isTty ? \"pretty\" : \"json\";\n}\n\ninterface RenderOptions {\n format: OutputFormat;\n /** 写出目标,默认 process.stdout。便于测试。 */\n stream?: NodeJS.WritableStream;\n}\n\nfunction write(stream: NodeJS.WritableStream, text: string): void {\n stream.write(text.endsWith(\"\\n\") ? text : text + \"\\n\");\n}\n\n/** 渲染一次成功结果。data 任意结构;table/ndjson 在数组时逐行展开。 */\nexport function renderResult(data: unknown, opts: RenderOptions): void {\n const stream = opts.stream ?? process.stdout;\n switch (opts.format) {\n case \"json\":\n write(stream, JSON.stringify(data));\n return;\n case \"pretty\":\n write(stream, JSON.stringify(data, null, 2));\n return;\n case \"ndjson\": {\n const rows = Array.isArray(data) ? data : [data];\n for (const row of rows) stream.write(JSON.stringify(row) + \"\\n\");\n return;\n }\n case \"table\":\n write(stream, renderTable(data));\n return;\n }\n}\n\n/**\n * 渲染错误。统一 schema:{ ok: false, error: {...} }。\n * 默认写 stdout —— 与正常输出同一通道,让 `--format json | jq` 等 Agent 管道能读到错误体;\n * 失败由非零退出码表达。\n */\nexport function renderError(err: unknown, opts: RenderOptions): void {\n const stream = opts.stream ?? process.stdout;\n const error =\n err instanceof YoooclawError\n ? err.toErrorPayload()\n : {\n code: \"YOOOCLAW_UNKNOWN\",\n message: err instanceof Error ? err.message : String(err),\n };\n const payload = { ok: false, error };\n const text =\n opts.format === \"pretty\"\n ? JSON.stringify(payload, null, 2)\n : JSON.stringify(payload);\n write(stream, text);\n}\n\n/** 极简表格渲染:对象数组 → 列对齐文本;其余 fallback 到 pretty JSON。 */\nfunction renderTable(data: unknown): string {\n if (!Array.isArray(data) || data.length === 0) {\n return JSON.stringify(data, null, 2);\n }\n const rows = data.filter(\n (r): r is Record<string, unknown> =>\n typeof r === \"object\" && r !== null && !Array.isArray(r),\n );\n if (rows.length !== data.length) {\n return JSON.stringify(data, null, 2);\n }\n const columns = Array.from(\n rows.reduce<Set<string>>((set, row) => {\n for (const key of Object.keys(row)) set.add(key);\n return set;\n }, new Set()),\n );\n const cell = (v: unknown): string =>\n v === null || v === undefined\n ? \"\"\n : typeof v === \"object\"\n ? JSON.stringify(v)\n : String(v);\n const widths = columns.map((col) =>\n Math.max(col.length, ...rows.map((row) => cell(row[col]).length)),\n );\n const pad = (text: string, width: number) => text.padEnd(width);\n const header = columns.map((col, i) => pad(col, widths[i])).join(\" \");\n const divider = widths.map((w) => \"-\".repeat(w)).join(\" \");\n const body = rows\n .map((row) =>\n columns.map((col, i) => pad(cell(row[col]), widths[i])).join(\" \"),\n )\n .join(\"\\n\");\n return [header, divider, body].join(\"\\n\");\n}\n",
11
+ "import { readFileSync } from \"node:fs\";\n\ndeclare const __CLI_VERSION__: string | undefined;\n\ninterface PackageJson {\n version?: string;\n}\n\nfunction readBuildInjectedVersion(): string | undefined {\n if (typeof __CLI_VERSION__ !== \"string\") {\n return undefined;\n }\n const version = __CLI_VERSION__.trim();\n return version || undefined;\n}\n\nfunction readVersionFromPackageJson(): string | undefined {\n try {\n const packageJsonUrl = new URL(\"../package.json\", import.meta.url);\n const packageJson = JSON.parse(\n readFileSync(packageJsonUrl, \"utf-8\"),\n ) as PackageJson;\n const version = packageJson.version?.trim();\n return version || undefined;\n } catch {\n return undefined;\n }\n}\n\nexport const CLI_VERSION =\n readBuildInjectedVersion() ?? readVersionFromPackageJson() ?? \"unknown\";\n",
12
+ "/**\n * `@yoooclaw/cli` 程序化入口。\n *\n * - `run(argv)` 解析并执行命令(bin.ts 调用)。\n * - 同时再导出核心模块,供测试与未来的程序化集成使用。\n */\nimport { buildProgram } from \"./program.js\";\n\nexport async function run(argv: string[] = process.argv): Promise<void> {\n const program = buildProgram();\n await program.parseAsync(argv);\n}\n\nexport { buildProgram } from \"./program.js\";\nexport { COMMAND_TREE } from \"./command-tree.js\";\nexport { CLI_VERSION } from \"./version.js\";\nexport { ErrorCode, YoooclawError } from \"./errors.js\";\nexport {\n renderResult,\n renderError,\n resolveFormat,\n type OutputFormat,\n} from \"./output/format.js\";\nexport {\n buildContext,\n resolveActiveProfile,\n type CliContext,\n type GlobalFlags,\n} from \"./context.js\";\nexport * as paths from \"./paths.js\";\n",
13
+ "/**\n * yoooclaw CLI 可执行入口。\n * package.json#bin(yoooclaw / yc)指向构建产物 dist/bin.cjs。\n */\nimport { run } from \"./index.js\";\n\nvoid run(process.argv);\n"
14
+ ],
15
+ "mappings": "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",
16
+ "debugId": "885B6E71DB5ADDF164756E2164756E21",
17
+ "names": []
18
+ }