@my-life-buddies/cli 0.14.1 → 0.15.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.
Files changed (188) hide show
  1. package/README.md +67 -15
  2. package/dist/bin/buddy.js +28 -9
  3. package/dist/bin/buddy.js.map +2 -2
  4. package/dist/bin/core.js +1293 -603
  5. package/dist/bin/core.js.map +4 -4
  6. package/dist/bin/preview.js +43 -8
  7. package/dist/bin/preview.js.map +2 -2
  8. package/dist/web/app.js +11 -6
  9. package/dist/web/widgets.css +59 -28
  10. package/dist/web/widgets.js +230 -76
  11. package/package.json +3 -3
  12. package/resources/README.md +6 -50
  13. package/resources/buddy-creator/INSTALL.md +0 -25
  14. package/resources/buddy-creator/PATCHES.md +0 -53
  15. package/resources/buddy-creator/SKILL.md +0 -76
  16. package/resources/buddy-creator/THIRD_PARTY_NOTICES.md +0 -154
  17. package/resources/buddy-creator/agents/openai.yaml +0 -4
  18. package/resources/buddy-creator/assets/licenses/bail.txt +0 -26
  19. package/resources/buddy-creator/assets/licenses/ccount.txt +0 -26
  20. package/resources/buddy-creator/assets/licenses/character-entities-html4.txt +0 -26
  21. package/resources/buddy-creator/assets/licenses/character-entities-legacy.txt +0 -26
  22. package/resources/buddy-creator/assets/licenses/character-entities.txt +0 -26
  23. package/resources/buddy-creator/assets/licenses/character-reference-invalid.txt +0 -26
  24. package/resources/buddy-creator/assets/licenses/comma-separated-tokens.txt +0 -26
  25. package/resources/buddy-creator/assets/licenses/debug.txt +0 -24
  26. package/resources/buddy-creator/assets/licenses/decode-named-character-reference.txt +0 -26
  27. package/resources/buddy-creator/assets/licenses/dequal.txt +0 -25
  28. package/resources/buddy-creator/assets/licenses/devlop.txt +0 -26
  29. package/resources/buddy-creator/assets/licenses/escape-string-regexp.txt +0 -13
  30. package/resources/buddy-creator/assets/licenses/estree-util-is-identifier-name.txt +0 -26
  31. package/resources/buddy-creator/assets/licenses/extend.txt +0 -27
  32. package/resources/buddy-creator/assets/licenses/hast-util-to-jsx-runtime.txt +0 -26
  33. package/resources/buddy-creator/assets/licenses/hast-util-whitespace.txt +0 -26
  34. package/resources/buddy-creator/assets/licenses/html-url-attributes.txt +0 -25
  35. package/resources/buddy-creator/assets/licenses/inline-style-parser.txt +0 -13
  36. package/resources/buddy-creator/assets/licenses/is-alphabetical.txt +0 -26
  37. package/resources/buddy-creator/assets/licenses/is-alphanumerical.txt +0 -26
  38. package/resources/buddy-creator/assets/licenses/is-decimal.txt +0 -26
  39. package/resources/buddy-creator/assets/licenses/is-hexadecimal.txt +0 -26
  40. package/resources/buddy-creator/assets/licenses/is-plain-obj.txt +0 -13
  41. package/resources/buddy-creator/assets/licenses/longest-streak.txt +0 -26
  42. package/resources/buddy-creator/assets/licenses/markdown-table.txt +0 -26
  43. package/resources/buddy-creator/assets/licenses/mdast-util-find-and-replace.txt +0 -26
  44. package/resources/buddy-creator/assets/licenses/mdast-util-from-markdown.txt +0 -26
  45. package/resources/buddy-creator/assets/licenses/mdast-util-gfm-autolink-literal.txt +0 -26
  46. package/resources/buddy-creator/assets/licenses/mdast-util-gfm-footnote.txt +0 -26
  47. package/resources/buddy-creator/assets/licenses/mdast-util-gfm-strikethrough.txt +0 -26
  48. package/resources/buddy-creator/assets/licenses/mdast-util-gfm-table.txt +0 -26
  49. package/resources/buddy-creator/assets/licenses/mdast-util-gfm-task-list-item.txt +0 -26
  50. package/resources/buddy-creator/assets/licenses/mdast-util-gfm.txt +0 -26
  51. package/resources/buddy-creator/assets/licenses/mdast-util-mdx-expression.txt +0 -26
  52. package/resources/buddy-creator/assets/licenses/mdast-util-mdx-jsx.txt +0 -26
  53. package/resources/buddy-creator/assets/licenses/mdast-util-mdxjs-esm.txt +0 -26
  54. package/resources/buddy-creator/assets/licenses/mdast-util-phrasing.txt +0 -27
  55. package/resources/buddy-creator/assets/licenses/mdast-util-to-hast.txt +0 -26
  56. package/resources/buddy-creator/assets/licenses/mdast-util-to-markdown.txt +0 -26
  57. package/resources/buddy-creator/assets/licenses/mdast-util-to-string.txt +0 -26
  58. package/resources/buddy-creator/assets/licenses/micromark-core-commonmark.txt +0 -26
  59. package/resources/buddy-creator/assets/licenses/micromark-extension-gfm-autolink-literal.txt +0 -26
  60. package/resources/buddy-creator/assets/licenses/micromark-extension-gfm-footnote.txt +0 -26
  61. package/resources/buddy-creator/assets/licenses/micromark-extension-gfm-strikethrough.txt +0 -26
  62. package/resources/buddy-creator/assets/licenses/micromark-extension-gfm-table.txt +0 -26
  63. package/resources/buddy-creator/assets/licenses/micromark-extension-gfm-tagfilter.txt +0 -26
  64. package/resources/buddy-creator/assets/licenses/micromark-extension-gfm-task-list-item.txt +0 -26
  65. package/resources/buddy-creator/assets/licenses/micromark-extension-gfm.txt +0 -26
  66. package/resources/buddy-creator/assets/licenses/micromark-factory-destination.txt +0 -26
  67. package/resources/buddy-creator/assets/licenses/micromark-factory-label.txt +0 -26
  68. package/resources/buddy-creator/assets/licenses/micromark-factory-space.txt +0 -26
  69. package/resources/buddy-creator/assets/licenses/micromark-factory-title.txt +0 -26
  70. package/resources/buddy-creator/assets/licenses/micromark-factory-whitespace.txt +0 -26
  71. package/resources/buddy-creator/assets/licenses/micromark-util-character.txt +0 -26
  72. package/resources/buddy-creator/assets/licenses/micromark-util-chunked.txt +0 -26
  73. package/resources/buddy-creator/assets/licenses/micromark-util-classify-character.txt +0 -26
  74. package/resources/buddy-creator/assets/licenses/micromark-util-combine-extensions.txt +0 -26
  75. package/resources/buddy-creator/assets/licenses/micromark-util-decode-numeric-character-reference.txt +0 -26
  76. package/resources/buddy-creator/assets/licenses/micromark-util-decode-string.txt +0 -26
  77. package/resources/buddy-creator/assets/licenses/micromark-util-encode.txt +0 -26
  78. package/resources/buddy-creator/assets/licenses/micromark-util-html-tag-name.txt +0 -26
  79. package/resources/buddy-creator/assets/licenses/micromark-util-normalize-identifier.txt +0 -26
  80. package/resources/buddy-creator/assets/licenses/micromark-util-resolve-all.txt +0 -26
  81. package/resources/buddy-creator/assets/licenses/micromark-util-sanitize-uri.txt +0 -26
  82. package/resources/buddy-creator/assets/licenses/micromark-util-subtokenize.txt +0 -26
  83. package/resources/buddy-creator/assets/licenses/micromark-util-symbol.txt +0 -26
  84. package/resources/buddy-creator/assets/licenses/micromark-util-types.txt +0 -26
  85. package/resources/buddy-creator/assets/licenses/micromark.txt +0 -26
  86. package/resources/buddy-creator/assets/licenses/ms.txt +0 -25
  87. package/resources/buddy-creator/assets/licenses/parse-entities.txt +0 -26
  88. package/resources/buddy-creator/assets/licenses/phosphor-icons--react.txt +0 -25
  89. package/resources/buddy-creator/assets/licenses/property-information.txt +0 -26
  90. package/resources/buddy-creator/assets/licenses/react-dom.txt +0 -25
  91. package/resources/buddy-creator/assets/licenses/react-markdown.txt +0 -25
  92. package/resources/buddy-creator/assets/licenses/react.txt +0 -25
  93. package/resources/buddy-creator/assets/licenses/remark-gfm.txt +0 -26
  94. package/resources/buddy-creator/assets/licenses/remark-parse.txt +0 -25
  95. package/resources/buddy-creator/assets/licenses/remark-rehype.txt +0 -26
  96. package/resources/buddy-creator/assets/licenses/remark-stringify.txt +0 -25
  97. package/resources/buddy-creator/assets/licenses/scheduler.txt +0 -25
  98. package/resources/buddy-creator/assets/licenses/space-separated-tokens.txt +0 -26
  99. package/resources/buddy-creator/assets/licenses/stringify-entities.txt +0 -26
  100. package/resources/buddy-creator/assets/licenses/style-to-js.txt +0 -26
  101. package/resources/buddy-creator/assets/licenses/style-to-object.txt +0 -26
  102. package/resources/buddy-creator/assets/licenses/trim-lines.txt +0 -26
  103. package/resources/buddy-creator/assets/licenses/trough.txt +0 -25
  104. package/resources/buddy-creator/assets/licenses/types--debug.txt +0 -25
  105. package/resources/buddy-creator/assets/licenses/types--estree-jsx.txt +0 -25
  106. package/resources/buddy-creator/assets/licenses/types--estree.txt +0 -25
  107. package/resources/buddy-creator/assets/licenses/types--hast.txt +0 -25
  108. package/resources/buddy-creator/assets/licenses/types--mdast.txt +0 -25
  109. package/resources/buddy-creator/assets/licenses/types--ms.txt +0 -25
  110. package/resources/buddy-creator/assets/licenses/types--unist.txt +0 -25
  111. package/resources/buddy-creator/assets/licenses/ungap--structured-clone.txt +0 -19
  112. package/resources/buddy-creator/assets/licenses/unified.txt +0 -25
  113. package/resources/buddy-creator/assets/licenses/unist-util-is.txt +0 -26
  114. package/resources/buddy-creator/assets/licenses/unist-util-position.txt +0 -26
  115. package/resources/buddy-creator/assets/licenses/unist-util-stringify-position.txt +0 -26
  116. package/resources/buddy-creator/assets/licenses/unist-util-visit-parents.txt +0 -26
  117. package/resources/buddy-creator/assets/licenses/unist-util-visit.txt +0 -26
  118. package/resources/buddy-creator/assets/licenses/vfile-message.txt +0 -26
  119. package/resources/buddy-creator/assets/licenses/vfile.txt +0 -25
  120. package/resources/buddy-creator/assets/licenses/zwitch.txt +0 -26
  121. package/resources/buddy-creator/assets/preview/assets/index-B5VmkoSx.js +0 -39
  122. package/resources/buddy-creator/assets/preview/assets/index-DWKP6b-3.css +0 -4
  123. package/resources/buddy-creator/assets/preview/brand-logo.png +0 -0
  124. package/resources/buddy-creator/assets/preview/brand.css +0 -100
  125. package/resources/buddy-creator/assets/preview/index.html +0 -7
  126. package/resources/buddy-creator/assets/preview/reader.css +0 -165
  127. package/resources/buddy-creator/assets/preview/reader.js +0 -135
  128. package/resources/buddy-creator/assets/preview/widgets.css +0 -1
  129. package/resources/buddy-creator/assets/preview/widgets.js +0 -168
  130. package/resources/buddy-creator/assets/widget-reference/conversation.png +0 -0
  131. package/resources/buddy-creator/assets/widget-reference/expanded.png +0 -0
  132. package/resources/buddy-creator/assets/widget-v2/app.js +0 -62
  133. package/resources/buddy-creator/assets/widget-v2/style.css +0 -1
  134. package/resources/buddy-creator/assets/widget-v3/app.js +0 -65
  135. package/resources/buddy-creator/assets/widget-v3/style.css +0 -103
  136. package/resources/buddy-creator/assets/widget-v4/app.js +0 -66
  137. package/resources/buddy-creator/assets/widget-v4/style.css +0 -187
  138. package/resources/buddy-creator/references/artifact-schema.md +0 -70
  139. package/resources/buddy-creator/references/catalog.json +0 -401
  140. package/resources/buddy-creator/references/definition.md +0 -24
  141. package/resources/buddy-creator/references/dialogue-examples.md +0 -133
  142. package/resources/buddy-creator/references/host-guide.md +0 -219
  143. package/resources/buddy-creator/references/interview.md +0 -235
  144. package/resources/buddy-creator/references/knowledge.md +0 -40
  145. package/resources/buddy-creator/references/methods.md +0 -77
  146. package/resources/buddy-creator/references/opening.md +0 -14
  147. package/resources/buddy-creator/references/preview-panel.md +0 -66
  148. package/resources/buddy-creator/references/recovery.md +0 -46
  149. package/resources/buddy-creator/references/service.md +0 -76
  150. package/resources/buddy-creator/references/widgets-protocol.md +0 -83
  151. package/resources/buddy-creator/references/widgets.md +0 -99
  152. package/resources/buddy-creator/scripts/buddy.py +0 -108
  153. package/resources/buddy-creator/scripts/buddy_client.py +0 -67
  154. package/resources/buddy-creator/scripts/buddy_core.py +0 -865
  155. package/resources/buddy-creator/scripts/completion.py +0 -296
  156. package/resources/buddy-creator/scripts/interview.py +0 -215
  157. package/resources/buddy-creator/scripts/preview.py +0 -617
  158. package/resources/buddy-creator/scripts/preview_panel.py +0 -80
  159. package/resources/buddy-creator/scripts/sources.py +0 -239
  160. package/resources/buddy-creator/scripts/widget_render.py +0 -66
  161. package/resources/buddy-creator/scripts/widget_render_v1.py +0 -176
  162. package/resources/buddy-creator/scripts/widget_render_v2.py +0 -98
  163. package/resources/buddy-creator/scripts/widget_render_v3.py +0 -86
  164. package/resources/buddy-creator/scripts/widget_render_v4.py +0 -121
  165. package/resources/buddy-creator/scripts/widgets.py +0 -227
  166. package/resources/buddy-creator/version.json +0 -8
  167. package/resources/buddy-creator.manifest.json +0 -791
  168. package/resources/dada-object-avatar/SKILL.md +0 -37
  169. package/resources/dada-object-avatar/agents/openai.yaml +0 -4
  170. package/resources/dada-object-avatar/assets/examples/cat.png +0 -0
  171. package/resources/dada-object-avatar/assets/examples/cooking.png +0 -0
  172. package/resources/dada-object-avatar/assets/examples/divination.png +0 -0
  173. package/resources/dada-object-avatar/assets/examples/doctor.png +0 -0
  174. package/resources/dada-object-avatar/assets/examples/relationship.png +0 -0
  175. package/resources/dada-object-avatar/assets/examples/work.png +0 -0
  176. package/resources/dada-object-avatar/assets/preview.png +0 -0
  177. package/resources/dada-object-avatar/references/evaluation-rubric.md +0 -22
  178. package/resources/dada-object-avatar/references/examples.json +0 -8
  179. package/resources/dada-object-avatar/references/prompt-template.md +0 -27
  180. package/resources/dada-object-avatar/references/style-system.md +0 -54
  181. package/resources/dada-object-avatar/references/subject-design.md +0 -23
  182. package/resources/dada-object-avatar/references/training-guide.md +0 -14
  183. package/resources/dada-object-avatar/references/training-log.jsonl +0 -0
  184. package/resources/dada-object-avatar/references/training-record.schema.json +0 -20
  185. package/resources/dada-object-avatar/scripts/choose_gaze.py +0 -36
  186. package/resources/dada-object-avatar/scripts/record_example.py +0 -22
  187. package/resources/dada-object-avatar/scripts/validate_png.py +0 -52
  188. package/resources/dada-object-avatar.manifest.json +0 -85
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  这份说明按一次开发过程展开:登记搭子,准备工程,在本地预览,然后上传程序包。所有搭子统一使用 `@my-life-buddies/buddy-runtime`,业务能力通过 Prompt、`src/buddy-options.mjs` 和 Tool 实现。
6
6
 
7
- 新建工程动态查询公共 npm 的最新 Runtime,并写入准确版本与锁文件;联网失败时明确提示使用随 CLI 附带的 `0.12.2` 模板。版本选择与联调范围见 [Runtime 集成说明](../../docs/runtime-integration.md)。
7
+ 新建工程动态查询公共 npm 的最新 Runtime,并写入准确版本与锁文件;查询或锁文件生成失败时停止,不回退旧版本。版本选择与联调范围见 [Runtime 集成说明](../../docs/runtime-integration.md)。
8
8
 
9
9
  ## 准备 CLI 和平台地址
10
10
 
@@ -23,6 +23,18 @@ npm run buddy-cli -- --help
23
23
  npm install --global @my-life-buddies/cli@latest --registry=https://registry.npmjs.org/
24
24
  ```
25
25
 
26
+ ### 查看帮助与开发指引
27
+
28
+ ```bash
29
+ buddy-cli --help
30
+ buddy-cli init --help
31
+ buddy-cli guide
32
+ ```
33
+
34
+ `--help` 列出命令,`<命令> --help` 说明当前命令的参数、限制和示例。`guide` 输出 Coding Agent 的完整开发指引,包括资料确认、Skill 接续、实现和交付规则;无需工程、登录或联网,不写文件。让 Agent 开始工作前先读取 `guide`,再按 CLI 返回的 `HANDOFF.md` 继续当前工程。`guide --help` 只显示该命令的简短用法。
35
+
36
+ 命令执行结果只提示当前状态和下一步;完整规则不再重复出现在顶层帮助和成功输出中。后台同一份入口说明见 [CLI 使用指南](../web/web/docs/cli/index.html)。
37
+
26
38
  ### 查看版本和更新 CLI
27
39
 
28
40
  ```bash
@@ -53,7 +65,7 @@ npm run verify:package
53
65
  npm publish --workspace @my-life-buddies/cli
54
66
  ```
55
67
 
56
- 对外只有 `@my-life-buddies/cli@latest`,`publishConfig` 已指定公共 npm 和 `public` 访问级别。Core 和 Preview 保留 monorepo 开发边界并标记为 `private`,构建时合入 CLI 的内部模块;Preview 页面、Creator Skill、完整 dada-object-avatar Skill 和工程模板资源一同进入 CLI 包。安装不会请求 `@buddy/cli-core` 或 `@buddy/preview`。第三方运行依赖按正常 npm dependencies 安装,构建工具 esbuild 不进入安装依赖。根工作区和 Web 同样保持 `private`。
68
+ 对外只有 `@my-life-buddies/cli@latest`,`publishConfig` 已指定公共 npm 和 `public` 访问级别。Core 和 Preview 保留 monorepo 开发边界并标记为 `private`,构建时合入 CLI 的内部模块;Preview 页面和工程模板资源进入 CLI 包;Creator Avatar Skill 使用时独立加载。安装不会请求 `@buddy/cli-core` 或 `@buddy/preview`。第三方运行依赖按正常 npm dependencies 安装,构建工具 esbuild 不进入安装依赖。根工作区和 Web 同样保持 `private`。
57
69
 
58
70
  版本维护:每批修改 CLI 发布内容时递增一次版本,默认 patch;根包和内部工作区版本、依赖引用、锁文件一起更新。Agent 工程自己的项目版本独立。升级 Runtime 时同步模板依赖与模板锁文件,并运行独立安装验收。
59
71
 
@@ -73,11 +85,12 @@ CLI 会把换取到的会话保存到 macOS Keychain。有效会话会复用,
73
85
 
74
86
  | 命令 | 是否需要 Agent 目录 | 会发生什么 |
75
87
  | --- | --- | --- |
76
- | `help`、`--help` | 不需要,也不登录 | 显示参数说明 |
88
+ | `help`、`--help` | 不需要,也不登录 | 列出命令;参数见 `<命令> --help` |
89
+ | `guide` | 不需要,也不登录 | 离线输出 Coding Agent 开发指引,不写文件 |
77
90
  | `--version [--json]` | 不需要,也不登录 | 显示当前运行的 CLI 版本,无需联网 |
78
91
  | `update [--check] [--json]` | 不需要,也不登录 | 检查公共 npm 最新版,或更新 npm 全局 CLI |
79
92
  | `login`、`logout` | 不需要 | 管理账号会话 |
80
- | `models` | 不需要,也不登录 | 工程内读取已安装 Runtime,工程外联网读取 npm 最新版;支持 `--directory`、`--json` |
93
+ | `models` | 不需要,也不登录 | 始终联网读取 npm 最新 Runtime 的模型目录,提示工程版本差异;支持 `--directory`、`--json` |
81
94
  | `init` | 目标目录可以是空目录或已有官方工程 | 登记或恢复云端身份,准备本地文件 |
82
95
  | `dev`、`preview`、`push` | 需要有效清单和完整工程文件 | 运行、调试或打包该工程 |
83
96
  | `status` | 需要含 `buddyId` 的 `buddy.agent.json` | 查询该搭子的云端状态;创作尚未完成时也可使用 |
@@ -92,7 +105,19 @@ CLI 会把换取到的会话保存到 macOS Keychain。有效会话会复用,
92
105
 
93
106
  ## 登记前,先确认资料和头像
94
107
 
95
- `init --mode create` 和 `init --mode direct` 都先保存本地资料草稿。Coding Agent 读取 CLI 返回的 `.buddy/meta/HANDOFF.md`,完整读取随包的 `dada-object-avatar/SKILL.md` 和配套规范,用宿主图片生成能力生成、检查并展示头像。开发者确认实际头像及名称、一句话介绍、详细介绍后,才调用 Meta 创建接口。
108
+ `init --mode create` 和 `init --mode direct` 都先保存本地资料草稿。Coding Agent 读取 CLI 返回的 `.buddy/meta/HANDOFF.md`,完整读取独立下载的 `@my-life-buddies/avatar-creator-skill/SKILL.md` 和配套规范,用宿主图片生成能力生成、检查并展示头像。开发者确认实际头像及名称、一句话介绍、详细介绍后,才调用 Meta 创建接口。
109
+
110
+ 只有需要生成头像时才下载 `@my-life-buddies/avatar-creator-skill`,本地缓存位于 `~/.cache/buddy-cli/avatar-skills/my-life-buddies/<版本>/`,同一次头像创作由 `.buddy/meta/skill-lock.json` 固定版本。已有候选图片、`--avatar` 指定图片及上传重试不需要加载生成 Skill。显式传入 `--avatar-skill-version 1.0.0` 可在未完成的头像准备流程中选择准确版本;这不会删除或重画已有候选图片。宿主图片生成工具仍负责实际生图,CLI 负责确认与上传。
111
+
112
+ Skill 维护者可本地联调(无需发布):
113
+
114
+ ```bash
115
+ BUDDY_AVATAR_SKILL_PATH=/absolute/path/avatar-creator-skill \
116
+ buddy-cli init --mode create --directory ./my-buddy
117
+ ```
118
+
119
+ 本地来源会记录在头像 Skill 锁中;切回 npm 时清除环境变量,并显式传入 `--avatar-skill-version`。首次下载失败会保留草稿,可在同目录重试,也可提供已有图片完成登记。
120
+
96
121
 
97
122
  普通终端不会执行 skill,也不要求安装 Coding Agent:选择本地图片后会打开资料与头像预览,再询问是否确认登记。没有图片或暂不确认时保留草稿,退出码为 2,稍后在原目录继续。
98
123
 
@@ -207,7 +232,7 @@ await BuddyServer.start({
207
232
  });
208
233
  ```
209
234
 
210
- 工程在 `package.json` 声明准确 Runtime 版本,锁文件固定依赖;上传不包含 `node_modules` 或 Runtime 打包副本,部署执行同一份 `npm start`。首次生成 package.json 和 package-lock.json 时查询公共 npm latest,生成准确版本与锁文件。随 CLI 附带的 Runtime `0.12.2` 仅作为明确提示的联网失败兜底。已有工程再次初始化时保留其依赖;安装验收直接从公共 npm 安装。
235
+ 工程在 `package.json` 声明准确 Runtime 版本,锁文件固定依赖;上传不包含 `node_modules` 或 Runtime 打包副本,部署执行同一份 `npm start`。首次生成 package.json 和 package-lock.json 时查询公共 npm latest,生成准确版本与锁文件。查询或锁文件生成失败时停止,不回退内置旧版本。已有工程再次初始化时保留其依赖;安装验收直接从公共 npm 安装。
211
236
 
212
237
  ## 想法还模糊时,先梳理需求
213
238
 
@@ -219,7 +244,7 @@ buddy-cli init --mode create --directory ./study-buddy \
219
244
  --intro "与用户一起明确目标,形成可以坚持的学习安排。"
220
245
  ```
221
246
 
222
- 这个命令先返回头像准备指引。完成头像和资料确认、登记成功后,再返回 `.buddy/creator/HANDOFF.md`。Coding Agent 随后读取内置 Creator Skill,在主对话里继续询问并展示作品预览。
247
+ 这个命令先返回头像准备指引。完成头像和资料确认、登记成功后,再返回 `.buddy/creator/HANDOFF.md`。Coding Agent 随后读取独立下载的 Creator Skill,在主对话里继续询问并展示作品预览。
223
248
 
224
249
  登记时的名称和介绍会写入 `.buddy/creator/initial-context.json`,随接续命令传给 Skill。例如已经明确要做学习搭子,就从具体的学习问题继续聊,不从“什么是搭子”重新开始。这是平台资料的快照,不是采访回答或四册确认的凭据;具体需求仍以你的真实回答和确认来确定。
225
250
 
@@ -234,7 +259,24 @@ buddy-cli init --mode create --directory ./study-buddy \
234
259
  → 基础技术自测 → 打开真实预览 → 开发者体验并反馈
235
260
  ```
236
261
 
237
- 当前内置 Creator Skill 1.4.0,随 CLI 安装,不需要运行时从 GitHub 下载或全局注册。执行它的工具需要 Python 3.9+;登录与身份登记仍要联网。Skill 的作品预览不是 Agent 聊天模拟器。已有作品升级后沿用原工作区,让 Coding Agent 重新读取 Skill 和宿主协议即可按新规则接续。
262
+ CLI 0.15.0 起,Creator 使用独立 npm `@my-life-buddies/buddy-creator-skill`。新项目首次创作查询稳定版,校验后缓存到 `~/.cache/buddy-cli/creator-skills/buddy-creator-skill/<版本>/`,在 `.buddy/creator/skill-lock.json` 记录准确版本与完整性摘要。恢复项目优先使用固定版本缓存,不自动升级,已有缓存时 Skill 准备无需联网(平台身份校验仍需联网)。Skill 负责人独立发包,不再要求重发 CLI。
263
+
264
+ 显式升级某个项目:
265
+
266
+ ```bash
267
+ buddy-cli init --mode create --directory ./study-buddy --creator-version 1.6.0
268
+ ```
269
+
270
+ CLI 只接受协议兼容的准确稳定版本,保留原始背景、身份与作品。未改动的旧版生成接续说明会备份后迁移;开发者自定义说明不覆盖。新项目下载失败会报错并保留登记身份,可在同目录重试。
271
+
272
+ 维护者本地联调:
273
+
274
+ ```bash
275
+ BUDDY_CREATOR_SKILL_PATH=/absolute/path/buddy-creator-skill \
276
+ buddy-cli init --mode create --directory ./study-buddy
277
+ ```
278
+
279
+ 本地来源同样记录在项目中,适合 Skill 开发,不要求发布。要切回 npm,清除环境变量并显式指定 `--creator-version`。Python 执行仍需 3.9+,不安装 Python 第三方依赖。阶段与创作规则由 Skill 的 `references/cli-workflow.md` 管理,CLI 只处理身份、目录和有效交付后的开发接续。
238
280
 
239
281
  创作资料保存在 `.buddy/creator/`。新项目须完成四册、小挂件清单、当前原型和设计验收,并通过交付校验,Skill 才返回 `directive=creator_complete` 和有效的 `completion.manualPath`;明确确认不使用小挂件时无需制造原型,旧项目按 Skill 版本规则接续。完整创建任务中,当前 Coding Agent 退出采访,在同一轮重新读取 `HANDOFF.md`、完整手册及小挂件设计与验收产物,自动开始开发,无需再说“继续”。四册确认或手册文件存在不能单独触发开发。只有影响实现的关键缺口才补问;仅设计、流程测试和暂停仍遵守原范围。
240
282
 
@@ -289,7 +331,13 @@ buddy-cli avatar --buddy-id b_example --file ./avatar.png
289
331
  buddy-cli models
290
332
  ```
291
333
 
292
- 不必先创建工程。工程外执行时,CLI 查询公共 npm latest,把对应 Runtime 安装到 `~/.cache/buddy-cli/runtimes/<版本>`,读取它的枚举;每次查询 latest,同版本复用缓存,不在当前目录创建工程。工程内则离线读取该工程的 Runtime,依赖未安装或版本不匹配时报错,不借用缓存替代。两个命令都显示实际版本;`--json` 返回 `source`(`npm` 或 `project`)、`runtimeVersion` 和目录。选择一个写进现有 `buddy.agent.json`,例如:
334
+ 不必先创建工程。无论是否在工程内,CLI 每次查询公共 npm latest,把对应 Runtime 缓存到 `~/.cache/buddy-cli/runtimes/<版本>` 并读取枚举;同版本复用缓存,不修改工程依赖。查询或下载失败时明确报错,不把旧缓存称为最新版。两个目录命令的 `--json` 返回 `source`(固定为 `npm`)、`runtimeVersion`、目录,以及 `projectRuntimeVersion`、`latestRuntimeVersion`、`versionStatus`、`adaptationRequired`。版本状态为 `no_project`、`unconfigured`、`current`、`update_available` 或 `project_ahead`;没有准确工程版本时返回 `null`,工程未锁定版本或版本与 npm latest 不一致时需要适配。提示输出到 stderr,stdout 保持纯 JSON。
335
+
336
+ 在已有工程执行 `buddy-cli`、`init` 或打开 `preview` 时检查更新并提示适配,但允许继续编辑工程。`dev`、Preview 中每次启动 DEV、文件自动重载,以及 `push` 必须联网查询 npm 最新稳定版,工程声明及实际安装版本必须与本次查询结果完全一致;不接受旧版、超前版、预发布版或范围依赖。查询失败即停止,不使用缓存冒充最新,也没有跳过检查参数。已有 npm 锁文件需与目标版本一致,push 还会按本次查询结果校验实际上传快照及其中的 npm 锁文件。失败信息包含原因和适配提示,CLI 不自动修改工程依赖、模型或数据权限。修复后重新启动;自动重载失败后保存文件可重试。帮助、登录、status、avatar 不查询 Runtime。
337
+
338
+ 此限制由本版 CLI 执行,不修改服务端策略或已部署进程;直接运行工程 `npm start`、旧 CLI 或服务端发布入口不受本版 CLI 检查约束。
339
+
340
+ 选择一个写进现有 `buddy.agent.json`,例如:
293
341
 
294
342
  ```json
295
343
  {
@@ -322,7 +370,7 @@ buddy-cli models
322
370
  }
323
371
  ```
324
372
 
325
- 完整选项以工程目录运行 `buddy-cli datasets` 的输出为准;脚本可加 `--json`。目录由安装的 Runtime 提供,Runtime 0.12.2 包含 HealthKit 与小红书两类,共 10 项。
373
+ 完整选项以工程目录运行 `buddy-cli datasets` 的输出为准;脚本可加 `--json`。目录由 npm 最新 Runtime 提供,具体条目以查询结果为准;使用新版条目前需完成工程升级与适配。
326
374
 
327
375
  CLI 校验声明,并把清单原样放入源码包。服务端从包中解析申请清单、绑定版本,以及 App 展示和取得用户授权的流程仍需接入;当前 CLI 不会额外调用接口修改平台权限。工程中的声明不代表用户已经授权,也不会自动启用查询工具。
328
376
 
@@ -363,11 +411,11 @@ Preview 展示平台对话记录、发送与流式输出耗时、会话状态和
363
411
 
364
412
  二维码生成已实现并验证解码;手机扫码、App 与实际 MLB 环境的完整链路仍需真机联调。Widget 页面、图片与固定操作复用同一调试连接。
365
413
 
366
- 改完代码后,停止再启动 `dev`,或在 Preview 中重启会话。当前没有源码热重载。原聊天历史从 MLB 读取,不因浏览器刷新就另建一份;服务端数据的保留期限不由 CLI 决定。
414
+ 保存代码、提示词、资料或 Widget 后,CLI 会合并连续修改并自动重启 Runtime;可能中断当前回复。已有 Widget 数据保留,Schema 变更不会自动迁移旧数据。原聊天历史从 MLB 读取,不因浏览器刷新就另建一份;服务端数据的保留期限不由 CLI 决定。
367
415
 
368
416
  ### 什么时候需要另一个服务地址
369
417
 
370
- 需要平台连接的命令默认使用上述 test 地址。`models` 和 `datasets` 不使用平台地址;工程外从公共 npm 获取 Runtime,工程内读取本地依赖。覆盖顺序如下:
418
+ 需要平台连接的命令默认使用上述 test 地址。`models` 和 `datasets` 不使用平台地址;始终从公共 npm 查询最新 Runtime 并读取其目录。覆盖顺序如下:
371
419
 
372
420
  | 命令 | 地址优先级(从高到低) |
373
421
  | --- | --- |
@@ -418,7 +466,7 @@ CLI 不提供 `release`、`publish`、`disable`、`enable` 或 `unpublish`。最
418
466
 
419
467
  维护者可在仓库根目录执行 `npm run verify:package`。它验证 npm 安装、初始化、模板启动和消息链路,MLB 与模型使用测试替身。
420
468
 
421
- `BUDDY_CLI_MOCK_CLOUD=1` 仅用于初始化交互测试,会产生明确标记的 `b_mock_*` 身份。它不提供真实 push 或 status,不能用来判断平台已打通。模型命令在此模式下仍读取同一份本地目录。
469
+ `BUDDY_CLI_MOCK_CLOUD=1` 仅用于初始化交互测试,会产生明确标记的 `b_mock_*` 身份。它不提供真实 push 或 status,不能用来判断平台已打通。模型命令在此模式下仍查询 npm 最新目录。
422
470
 
423
471
 
424
472
  ## 小挂件开发
@@ -429,14 +477,14 @@ CLI 不提供 `release`、`publish`、`disable`、`enable` 或 `unpublish`。最
429
477
 
430
478
  ## 查看数据集,不依赖 Coding Agent
431
479
 
432
- 工程外可以直接执行;在已有工程内,先按工程锁文件安装 Runtime,再执行:
480
+ 工程内外均可直接查询最新目录,不要求先安装工程依赖:
433
481
 
434
482
  ```bash
435
483
  buddy-cli datasets
436
484
  buddy-cli datasets --directory ./my-buddy --json
437
485
  ```
438
486
 
439
- 目录来自所选 Runtime 的 `DATA_ACCESS_CAPABILITIES`,包括 ID、名称、来源和 Schema 版本。JSON 返回 `source`、`runtimeVersion` 和 `datasets` 数组。命令不登录、不启动搭子、不申请权限,也不修改配置;从子目录运行会向上找到工程。工程外需要联网检查 latest,下载失败时明确报错,不把旧缓存称为最新版。
487
+ 目录来自 npm 最新 Runtime 的 `DATA_ACCESS_CAPABILITIES`,包括 ID、名称、来源和 Schema 版本。JSON 返回版本信息、适配状态和 `datasets` 数组(字段见上方模型目录说明)。命令不登录、不启动搭子、不申请权限,也不修改配置;从子目录运行会向上找到工程。每次都需要联网检查 latest,下载失败时明确报错,不把旧缓存称为最新版。
440
488
 
441
489
  开发者将实际选择的 ID 和用途写进 `buddy.agent.json.datasets`。JSON Schema 检查形状与用途;DEV 和上传预检按工程安装的 Runtime 检查所选模型与非空数据声明。目录缺失、依赖未安装或版本不匹配时明确报错。Runtime 0.12.2 有 10 项,但单次数据查询仍最多 8 项。
442
490
 
@@ -457,3 +505,7 @@ CLI 0.14.1 起,开发 Token 优先从工程 `.env` 读取;首次启动时可
457
505
  首次启动 DEV 时,CLI 将 `BUDDY_ID`、开发版 `BUDDY_TOKEN` 和 `MLB_GATEWAY_URL` 写入工程 `.env`,保留其他配置和注释。后续优先复用;`--refresh-token` 重新领取后更新此文件。开发者登录凭据仍使用系统凭据存储。`.env` 加入 Git 忽略,且始终排除在上传包之外。
458
506
 
459
507
  CLI、Preview 与标准 `npm start` 均由 Node 的 `--env-file-if-exists=.env` 加载本地配置,Runtime 自行读取环境变量;托管时平台注入的同名环境变量优先。已有工程显式升级 Runtime 后,CLI 只自动迁移能精确识别的生成入口及标准启动命令,自定义业务代码和脚本保留。
508
+
509
+ ### CLI 0.15.1 的 Skill 包名
510
+
511
+ Creator 使用 `@my-life-buddies/buddy-creator-skill`,头像使用 `@my-life-buddies/avatar-creator-skill`。缓存按新包名分别保存;本次不提供旧包或旧锁文件迁移。
package/dist/bin/buddy.js CHANGED
@@ -67,8 +67,9 @@ function createRuntimeLogForwarder(onLog, secrets) {
67
67
  // apps/cli/src/platform-host.ts
68
68
  import {
69
69
  CloudAuthenticator,
70
+ BuddyDevError,
71
+ checkRuntimeUpdate,
70
72
  DEFAULT_MLB_TEST_URL,
71
- DEVELOPMENT_HANDOFF_SUMMARY,
72
73
  HttpDeveloperPlatformClient,
73
74
  LoopbackBrowserLoginAdapter,
74
75
  MlbDevRegistrationClient,
@@ -99,11 +100,9 @@ var PREVIEW_COMMAND_HELP = `\u7528\u6CD5:
99
100
  --local \u662F\u540E\u53F0\u4E0D\u53EF\u7528\u65F6\u7684\u72EC\u7ACB\u672C\u5730\u9884\u89C8\u5907\u7528\u5165\u53E3\uFF0C--port \u4EC5\u4E0E --local \u4E00\u8D77\u4F7F\u7528\u3002
100
101
  \u4FDD\u6301\u7EC8\u7AEF\u8FD0\u884C\uFF1B\u9000\u51FA CLI \u4F1A\u505C\u6B62 DEV \u5E76\u65AD\u5F00\u8FDE\u63A5\uFF0C\u5237\u65B0\u540E\u53F0\u4E0D\u4F1A\u81EA\u52A8\u542F\u52A8 DEV\u3002
101
102
  \u672A\u914D\u7F6E\u5730\u5740\u65F6\u8FDE\u63A5 MLB \u6D4B\u8BD5\u73AF\u5883 ${DEFAULT_MLB_TEST_URL}\uFF08HTTP \u4EC5\u9650\u6D4B\u8BD5\uFF09\u3002
102
- CLI \u7EDF\u4E00\u542F\u52A8\u5E76\u7BA1\u7406\u5DE5\u7A0B\u4E2D\u7684\u5B98\u65B9 Runtime\u3002
103
+ CLI \u7EDF\u4E00\u542F\u52A8\u5E76\u7BA1\u7406\u5DE5\u7A0B\u4E2D\u7684\u5B98\u65B9 Runtime\uFF1B\u6BCF\u6B21\u542F\u52A8\u6216\u91CD\u8F7D\u5FC5\u987B\u901A\u8FC7 npm \u6700\u65B0\u7A33\u5B9A\u7248\u68C0\u67E5\u3002
103
104
  --refresh-token \u91CD\u65B0\u9886\u53D6\u5DF2\u6709\u5F00\u53D1 Token\uFF0C\u66F4\u65B0\u5DE5\u7A0B .env\uFF1B\u4E0D\u4F1A\u751F\u6210\u65B0\u5BC6\u94A5\u3002
104
- \u6A21\u62DF\u5668\u4F7F\u7528\u5F53\u524D\u5F00\u53D1\u8005\u8D26\u53F7\u8BBF\u95EE <buddyId>-dev \u8C03\u8BD5\u5206\u8EAB\u3002
105
-
106
- ${DEVELOPMENT_HANDOFF_SUMMARY}`;
105
+ \u6A21\u62DF\u5668\u4F7F\u7528\u5F53\u524D\u5F00\u53D1\u8005\u8D26\u53F7\u8BBF\u95EE <buddyId>-dev \u8C03\u8BD5\u5206\u8EAB\u3002`;
107
106
  function valueAfter(args, index, flag) {
108
107
  const value = args[index + 1];
109
108
  if (value === void 0 || !value.trim()) throw new Error(`${flag} \u7F3A\u5C11\u503C`);
@@ -185,6 +184,7 @@ function previewHandle(handle) {
185
184
  });
186
185
  }
187
186
  var BuddyPlatformHost = class {
187
+ #runtimeUpdate;
188
188
  #env;
189
189
  #signal;
190
190
  #openUrl;
@@ -192,14 +192,15 @@ var BuddyPlatformHost = class {
192
192
  #credentialCommandRunner;
193
193
  #mockClient = new MockDeveloperPlatformClient();
194
194
  constructor(options = {}) {
195
+ this.#runtimeUpdate = options.runtimeUpdate;
195
196
  this.#env = options.env ?? process.env;
196
197
  this.#signal = options.signal;
197
198
  this.#openUrl = options.openUrl ?? openExternalUrl;
198
199
  this.#credentialCommandRunner = options.credentialCommandRunner;
199
200
  }
200
201
  cloudOptions() {
201
- const preparePush = async (projectRoot) => {
202
- const plan = await createPushPreflight({ projectRoot });
202
+ const preparePush = async (projectRoot, _config, expectedRuntimeVersion) => {
203
+ const plan = await createPushPreflight({ projectRoot, expectedRuntimeVersion });
203
204
  return createPushSourceBundle(plan);
204
205
  };
205
206
  if (this.#env.BUDDY_CLI_MOCK_CLOUD === "1") {
@@ -270,6 +271,7 @@ var BuddyPlatformHost = class {
270
271
  if (webUrl.protocol !== "https:" && !(webUrl.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(webUrl.hostname)) || webUrl.username || webUrl.password || webUrl.search || webUrl.hash) throw new Error("\u521B\u9020\u8005\u540E\u53F0\u5FC5\u987B\u4F7F\u7528 HTTPS\uFF0C\u672C\u673A\u8C03\u8BD5\u53EF\u4F7F\u7528 loopback HTTP");
271
272
  if (!webUrl.pathname.endsWith("/")) webUrl.pathname += "/";
272
273
  const signal = this.#signal ?? new AbortController().signal;
274
+ await checkRuntimeUpdate(projectRoot, (message) => io.writeError(message), { signal, ...this.#runtimeUpdate });
273
275
  const session = this.#session(baseUrl, webUrl);
274
276
  await session.token({ signal });
275
277
  const starter = this.#previewStarter(baseUrl, manifest.buddyId, session, parsed.refreshToken ?? false);
@@ -304,7 +306,7 @@ var BuddyPlatformHost = class {
304
306
  io.write(`\u642D\u642D${parsed.local ? "\u5907\u7528\u672C\u5730\u9884\u89C8" : "\u540E\u53F0\u5F00\u53D1\u8C03\u8BD5"}\u9875\u9762\u5DF2\u6253\u5F00\uFF1A${parsed.local ? serverHandle.origin.href : pageUrl.href}`);
305
307
  if (!parsed.local) io.write(`${bridge?.reused ? "\u5DF2\u590D\u7528" : "\u5DF2\u8FDE\u63A5"}\u672C\u5730\u5DE5\u7A0B\uFF1A${projectRoot}\uFF08${manifest.buddyId}\uFF09\uFF0C\u8BF7\u5728\u540E\u53F0\u67E5\u770B DEV \u72B6\u6001\u3002`);
306
308
  io.write("\u5728\u9875\u9762\u4E2D\u542F\u52A8 DEV\uFF1B\u6D88\u606F\u4F1A\u7ECF\u8FC7 DEV App Server\uFF0C\u4E0D\u4F1A\u4ECE\u6D4F\u89C8\u5668\u76F4\u8FDE Agent\u3002");
307
- io.write(DEVELOPMENT_HANDOFF_SUMMARY);
309
+ io.write("\u4FDD\u6301\u7EC8\u7AEF\u8FD0\u884C\uFF1BCtrl+C \u505C\u6B62 DEV \u5E76\u65AD\u5F00\u8FDE\u63A5\u3002");
308
310
  if (bridge?.reused) return { exitCode: 0, route: "preview" };
309
311
  if (signal.aborted) return { exitCode: 130, route: "preview" };
310
312
  await (bridge ? bridge.completion : waitForAbort(signal));
@@ -318,7 +320,7 @@ var BuddyPlatformHost = class {
318
320
  #previewStarter(baseUrl, buddyId, session, refreshToken) {
319
321
  const starter = createBuddyDevStarter();
320
322
  return Object.freeze({
321
- start: async ({ projectRoot, signal, onLog }) => {
323
+ start: async ({ projectRoot, signal, onLog, onLifecycle }) => {
322
324
  if ((await readBuddyProjectManifest(projectRoot)).buddyId !== buddyId) throw new Error("\u5DE5\u7A0B buddyId \u5DF2\u6539\u53D8\uFF0C\u8BF7\u9000\u51FA CLI \u540E\u91CD\u65B0\u8FDE\u63A5");
323
325
  const token = await session.token({ signal });
324
326
  const secrets = /* @__PURE__ */ new Set([token.accessToken]);
@@ -329,9 +331,21 @@ var BuddyPlatformHost = class {
329
331
  refreshToken,
330
332
  tokenStoreFor: (id) => this.#buddyTokenStore(baseUrl, token.subject, id)
331
333
  });
334
+ let reloadError;
332
335
  const handle = await starter.start({
333
336
  projectRoot,
334
337
  signal,
338
+ runtimeUpdate: this.#runtimeUpdate,
339
+ onError(error) {
340
+ logs.flush();
341
+ let message = error.message;
342
+ for (const secret of secrets) if (secret) message = message.split(secret).join("[REDACTED]");
343
+ reloadError = { code: error.code, message: message.replace(/[\u0000-\u001f\u007f]/gu, " ").slice(0, 512) };
344
+ },
345
+ onStateChange(phase) {
346
+ if (phase === "reloading") reloadError = void 0;
347
+ if (phase === "reloading" || phase === "reload_failed" || phase === "ready") onLifecycle?.({ phase, ...phase === "reload_failed" && reloadError ? { error: reloadError } : {} });
348
+ },
335
349
  registrationClient: {
336
350
  async register(request, options) {
337
351
  const registered = await registrationClient.register(request, options);
@@ -343,6 +357,11 @@ var BuddyPlatformHost = class {
343
357
  onLog: logs.write
344
358
  }).catch((cause) => {
345
359
  logs.flush();
360
+ if (cause instanceof BuddyDevError && cause.code.startsWith("DEV_RUNTIME_")) {
361
+ let message = cause.message;
362
+ for (const secret of secrets) if (secret) message = message.split(secret).join("[REDACTED]");
363
+ Object.assign(cause, { publicMessage: message.replace(/[\u0000-\u001f\u007f]/gu, " ").slice(0, 512) });
364
+ }
346
365
  throw cause;
347
366
  });
348
367
  const preview = previewHandle(handle);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/bin/buddy.ts", "../../src/platform-host.ts", "../../src/runtime-logs.ts", "../../src/platform-support.ts", "../../src/self-update.ts"],
4
- "sourcesContent": ["#!/usr/bin/env node\n\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { stdin, stderr, stdout } from \"node:process\";\nimport { createRequire } from \"node:module\";\nimport { dirname } from \"node:path\";\nimport { createInterface, type Interface } from \"node:readline/promises\";\nimport {\n PromptCancelledError,\n runBuddyCli,\n type Choice,\n type CliIO,\n type InputOptions,\n type SelectOptions,\n} from \"@buddy/cli-core\";\nimport { BuddyPlatformHost } from \"../platform-host.js\";\nimport { assertSupportedDeveloperPlatform } from \"../platform-support.js\";\nimport { runSelfUpdateCommand } from \"../self-update.js\";\nimport { latestRuntimeTemplate, scaffoldPlatformAgent } from \"@buddy/cli-core/init/scaffold\";\n\nclass TerminalIO implements CliIO {\n readonly canPrompt = Boolean(stdin.isTTY && stdout.isTTY);\n private readline: Interface | undefined;\n private activeQuestion: AbortController | undefined;\n private cancelled = false;\n\n write(message: string): void {\n stdout.write(`${message}\\n`);\n }\n\n writeError(message: string): void {\n stderr.write(`${message}\\n`);\n }\n\n async openMetaPreview(path: string): Promise<void> {\n try { await promisify(execFile)(\"open\", [path]); }\n catch { this.write(`\u8BF7\u6253\u5F00\u672C\u5730\u5934\u50CF\u9884\u89C8\u540E\u518D\u786E\u8BA4\uFF1A${path}`); }\n }\n\n async select<Value extends string>(\n question: string,\n choices: readonly Choice<Value>[],\n options: SelectOptions<Value> = {},\n ): Promise<Value> {\n while (true) {\n this.write(`\\n${question}`);\n choices.forEach((choice, index) => {\n this.write(` ${index + 1}. ${choice.label}`);\n if (choice.description) this.write(` ${choice.description}`);\n });\n\n const defaultIndex = options.defaultValue === undefined\n ? undefined\n : choices.findIndex((choice) => choice.value === options.defaultValue);\n const prompt = defaultIndex === undefined || defaultIndex < 0\n ? \"\u8BF7\u8F93\u5165\u5E8F\u53F7\uFF1A\"\n : `\u8BF7\u8F93\u5165\u5E8F\u53F7\uFF08\u9ED8\u8BA4\uFF1A${defaultIndex + 1}\uFF09\uFF1A`;\n const answer = (await this.question(prompt)).trim();\n if (!answer && defaultIndex !== undefined && defaultIndex >= 0) return choices[defaultIndex]!.value;\n const selected = Number(answer) - 1;\n const choice = choices[selected];\n if (choice) return choice.value;\n this.writeError(`\u8BF7\u8F93\u5165 1 \u5230 ${choices.length} \u4E4B\u95F4\u7684\u5E8F\u53F7\u3002`);\n }\n }\n\n async input(question: string, options: InputOptions = {}): Promise<string> {\n const defaultHint = options.defaultValue === undefined ? \"\" : `\uFF08\u9ED8\u8BA4\uFF1A${options.defaultValue}\uFF09`;\n const answer = (await this.question(`${question}${defaultHint}\uFF1A`)).trim();\n return answer || options.defaultValue || \"\";\n }\n\n close(): void {\n this.readline?.close();\n }\n\n private getReadline(): Interface {\n if (this.readline) return this.readline;\n this.readline = createInterface({ input: stdin, output: stdout });\n this.readline.on(\"SIGINT\", () => {\n this.cancelled = true;\n this.activeQuestion?.abort();\n });\n return this.readline;\n }\n\n private async question(prompt: string): Promise<string> {\n const controller = new AbortController();\n this.activeQuestion = controller;\n try {\n return await this.getReadline().question(prompt, { signal: controller.signal });\n } catch (cause) {\n if (this.cancelled) throw new PromptCancelledError();\n throw cause;\n } finally {\n if (this.activeQuestion === controller) this.activeQuestion = undefined;\n }\n }\n}\n\nconst terminal = new TerminalIO();\nconst lifecycle = new AbortController();\nconst abortFromSignal = (signal: NodeJS.Signals) => {\n if (!lifecycle.signal.aborted) lifecycle.abort(new Error(signal));\n};\nconst onSigint = () => abortFromSignal(\"SIGINT\");\nconst onSigterm = () => abortFromSignal(\"SIGTERM\");\nprocess.on(\"SIGINT\", onSigint);\nprocess.on(\"SIGTERM\", onSigterm);\n\ntry {\n assertSupportedDeveloperPlatform();\n const args = process.argv.slice(2);\n const require = createRequire(import.meta.url);\n const manifestPath = require.resolve(\"@my-life-buddies/cli/package.json\");\n const maintenance = await runSelfUpdateCommand(args, terminal, {\n version: require(manifestPath).version,\n packageRoot: dirname(manifestPath),\n signal: lifecycle.signal,\n });\n const command = args[0];\n let platformHost: BuddyPlatformHost | undefined;\n const host = () => platformHost ??= new BuddyPlatformHost({ signal: lifecycle.signal });\n const result = maintenance ?? await runBuddyCli(args, terminal, {\n runtimeCatalog: { signal: lifecycle.signal },\n scaffoldPlatformAgent: (root, name) => scaffoldPlatformAgent(root, name, {\n resolveDependencies: template => latestRuntimeTemplate(template, {\n signal: lifecycle.signal, report: message => terminal.write(message),\n }),\n }),\n ...(command === \"dev\" ? { dev: host().devOptions() } : {}),\n // Resolve credentials only when a supported command actually needs them.\n get cloud() { return host().cloudOptions(); },\n preview: (previewArgs, io) => host().runPreview(previewArgs, io),\n });\n process.exitCode = result.exitCode;\n} catch (cause) {\n const message = cause instanceof Error ? cause.message : String(cause);\n terminal.writeError(`buddy-cli: ${message}`);\n process.exitCode = 1;\n} finally {\n process.off(\"SIGINT\", onSigint);\n process.off(\"SIGTERM\", onSigterm);\n terminal.close();\n}\n", "import { resolve } from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { readBuddyProjectManifest } from \"@buddy/cli-core/config\";\nimport { createRuntimeLogForwarder } from \"./runtime-logs.js\";\n\nimport {\n CloudAuthenticator,\n DEFAULT_MLB_TEST_URL,\n DEVELOPMENT_HANDOFF_SUMMARY,\n HttpDeveloperPlatformClient,\n LoopbackBrowserLoginAdapter,\n MlbDevRegistrationClient,\n MockDeveloperPlatformClient,\n SystemCloudTokenStore,\n SystemBuddyTokenStore,\n createBuddyDevStarter,\n createPushPreflight,\n createPushSourceBundle,\n resolvePlatformUrl,\n openExternalUrl,\n requireBuddyAgentProjectRoot,\n type CliIO,\n type CredentialCommandRunner,\n type CliRunResult,\n type RunCloudCommandOptions,\n type RunDevCommandOptions,\n} from \"@buddy/cli-core\";\nimport {\n PreviewController,\n MlbSimulatorClient,\n createBuddyPreviewUrl,\n startPreviewControlServer,\n connectPreviewBridge,\n type PreviewBuddyDetails,\n type PreviewDevHandle,\n type PreviewDevStarter,\n} from \"@buddy/preview\";\n\nexport interface ParsedPreviewArguments {\n readonly directory: string;\n readonly appServer?: string;\n readonly port?: number;\n readonly help: boolean;\n readonly local: boolean;\n readonly refreshToken?: boolean;\n readonly buddyId?: string;\n readonly developerWeb?: string;\n}\n\nexport const PREVIEW_COMMAND_HELP = `\u7528\u6CD5:\n buddy-cli preview [--directory <\u9879\u76EE\u76EE\u5F55>] [--buddy-id <\u642D\u5B50 ID>] [--developer-web <\u540E\u53F0 URL>] [--app-server <App Server URL>]\n buddy-cli preview --local [--directory <\u9879\u76EE\u76EE\u5F55>] [--port <\u672C\u5730\u7AEF\u53E3>]\n\n\u8BF4\u660E:\n \u9ED8\u8BA4\u6253\u5F00\u5F53\u524D\u642D\u5B50\u7684\u521B\u9020\u8005\u540E\u53F0\u300C\u5F00\u53D1\u8C03\u8BD5\u300D\uFF0C\u8FDE\u63A5\u672C\u5730\u5DE5\u7A0B\uFF1B\u5728\u540E\u53F0\u542F\u52A8/\u505C\u6B62 DEV\u3001\u8BD5\u804A\u3001\u67E5\u770B Widget\u3001\u65F6\u95F4\u7EBF\u4E0E\u534F\u8BAE\u65E5\u5FD7\u3001\u771F\u673A\u9884\u89C8\u3002\n --buddy-id \u6821\u9A8C\u5F53\u524D\u5DE5\u7A0B\u8EAB\u4EFD\uFF1B\u540E\u53F0\u300C\u83B7\u53D6\u8FDE\u63A5\u6307\u4EE4\u300D\u63D0\u4F9B\u642D\u5B50\u548C\u73AF\u5883\u5B8C\u6574\u53C2\u6570\u3002\n --local \u662F\u540E\u53F0\u4E0D\u53EF\u7528\u65F6\u7684\u72EC\u7ACB\u672C\u5730\u9884\u89C8\u5907\u7528\u5165\u53E3\uFF0C--port \u4EC5\u4E0E --local \u4E00\u8D77\u4F7F\u7528\u3002\n \u4FDD\u6301\u7EC8\u7AEF\u8FD0\u884C\uFF1B\u9000\u51FA CLI \u4F1A\u505C\u6B62 DEV \u5E76\u65AD\u5F00\u8FDE\u63A5\uFF0C\u5237\u65B0\u540E\u53F0\u4E0D\u4F1A\u81EA\u52A8\u542F\u52A8 DEV\u3002\n \u672A\u914D\u7F6E\u5730\u5740\u65F6\u8FDE\u63A5 MLB \u6D4B\u8BD5\u73AF\u5883 ${DEFAULT_MLB_TEST_URL}\uFF08HTTP \u4EC5\u9650\u6D4B\u8BD5\uFF09\u3002\n CLI \u7EDF\u4E00\u542F\u52A8\u5E76\u7BA1\u7406\u5DE5\u7A0B\u4E2D\u7684\u5B98\u65B9 Runtime\u3002\n --refresh-token \u91CD\u65B0\u9886\u53D6\u5DF2\u6709\u5F00\u53D1 Token\uFF0C\u66F4\u65B0\u5DE5\u7A0B .env\uFF1B\u4E0D\u4F1A\u751F\u6210\u65B0\u5BC6\u94A5\u3002\n \u6A21\u62DF\u5668\u4F7F\u7528\u5F53\u524D\u5F00\u53D1\u8005\u8D26\u53F7\u8BBF\u95EE <buddyId>-dev \u8C03\u8BD5\u5206\u8EAB\u3002\n\n${DEVELOPMENT_HANDOFF_SUMMARY}`;\n\nfunction valueAfter(args: readonly string[], index: number, flag: string): string {\n const value = args[index + 1];\n if (value === undefined || !value.trim()) throw new Error(`${flag} \u7F3A\u5C11\u503C`);\n return value;\n}\n\nfunction setOnce(current: string | undefined, value: string, flag: string): string {\n if (current !== undefined) throw new Error(`${flag} \u4E0D\u80FD\u91CD\u590D`);\n return value;\n}\n\nexport function parsePreviewArguments(args: readonly string[]): ParsedPreviewArguments {\n let directory = \".\";\n let directorySet = false;\n let appServer: string | undefined;\n let port: number | undefined;\n let help = false;\n let local = false;\n let refreshToken = false;\n let buddyId: string | undefined;\n let developerWeb: string | undefined;\n for (let index = 0; index < args.length; index += 1) {\n const flag = args[index];\n if (flag === \"--refresh-token\") {\n if (refreshToken) throw new Error(\"--refresh-token \u4E0D\u80FD\u91CD\u590D\");\n refreshToken = true;\n continue;\n }\n if (flag === \"--help\" || flag === \"-h\") {\n if (args.length !== 1) throw new Error(\"--help \u4E0D\u80FD\u548C\u5176\u4ED6 preview \u53C2\u6570\u4E00\u8D77\u4F7F\u7528\");\n help = true;\n continue;\n }\n if (flag === \"--local\") { if (local) throw new Error(\"--local \u4E0D\u80FD\u91CD\u590D\"); local = true; continue; }\n const value = valueAfter(args, index, flag ?? \"\u53C2\u6570\");\n index += 1;\n switch (flag) {\n case \"--buddy-id\":\n buddyId = setOnce(buddyId, value, flag);\n if (!/^[A-Za-z0-9_-]{1,128}$/u.test(buddyId)) throw new Error(\"--buddy-id \u65E0\u6548\");\n break;\n case \"--developer-web\":\n developerWeb = setOnce(developerWeb, value, flag);\n break;\n case \"--directory\":\n if (directorySet) throw new Error(\"--directory \u4E0D\u80FD\u91CD\u590D\");\n directory = value;\n directorySet = true;\n break;\n case \"--port\":\n if (port !== undefined || !/^\\d+$/u.test(value) || Number(value) < 1 || Number(value) > 65535) throw new Error(\"--port \u5FC5\u987B\u662F 1\u201365535 \u7684\u7AEF\u53E3\u4E14\u4E0D\u80FD\u91CD\u590D\");\n port = Number(value);\n break;\n case \"--app-server\":\n appServer = setOnce(appServer, value, flag);\n break;\n default:\n throw new Error(`\u672A\u77E5 preview \u53C2\u6570 ${flag ?? \"\"}`);\n }\n }\n if (port !== undefined && !local) throw new Error(\"--port \u4EC5\u7528\u4E8E --local \u5907\u7528\u9884\u89C8\");\n if (local && developerWeb) throw new Error(\"--local \u4E0D\u9700\u8981 --developer-web\");\n return Object.freeze({ directory, appServer, help, local, buddyId, developerWeb, ...(port === undefined ? {} : { port }), ...(refreshToken ? { refreshToken: true } : {}) });\n}\n\nexport interface BuddyPlatformHostOptions {\n readonly env?: Readonly<NodeJS.ProcessEnv>;\n readonly signal?: AbortSignal;\n readonly openUrl?: (url: URL) => Promise<void>;\n readonly credentialCommandRunner?: CredentialCommandRunner;\n}\n\nfunction waitForAbort(signal: AbortSignal): Promise<void> {\n if (signal.aborted) return Promise.resolve();\n return new Promise((resolveWait) => {\n signal.addEventListener(\"abort\", () => resolveWait(), { once: true });\n });\n}\n\nfunction previewHandle(handle: Awaited<ReturnType<ReturnType<typeof createBuddyDevStarter>[\"start\"]>>): PreviewDevHandle {\n return Object.freeze({\n closed: handle.completion.then((completion) => {\n if (completion.state === \"failed\") throw completion.error ?? new Error(\"DEV \u4F1A\u8BDD\u5F02\u5E38\u7ED3\u675F\");\n }),\n close: () => handle.stop(),\n });\n}\n\nexport class BuddyPlatformHost {\n readonly #env: Readonly<NodeJS.ProcessEnv>;\n readonly #signal: AbortSignal | undefined;\n readonly #openUrl: (url: URL) => Promise<void>;\n readonly #sessions = new Map<string, CloudAuthenticator>();\n readonly #credentialCommandRunner: CredentialCommandRunner | undefined;\n readonly #mockClient = new MockDeveloperPlatformClient();\n\n constructor(options: BuddyPlatformHostOptions = {}) {\n this.#env = options.env ?? process.env;\n this.#signal = options.signal;\n this.#openUrl = options.openUrl ?? openExternalUrl;\n this.#credentialCommandRunner = options.credentialCommandRunner;\n }\n\n cloudOptions(): Omit<RunCloudCommandOptions, \"cwd\"> {\n const preparePush: NonNullable<RunCloudCommandOptions[\"preparePush\"]> = async (\n projectRoot,\n ) => {\n const plan = await createPushPreflight({ projectRoot });\n return createPushSourceBundle(plan);\n };\n if (this.#env.BUDDY_CLI_MOCK_CLOUD === \"1\") {\n const mockToken = {\n accessToken: \"local-mock-access-token\",\n subject: \"account_local_mock\",\n expiresAt: Date.now() + 60 * 60_000,\n };\n return {\n mode: \"local-mock\",\n signal: this.#signal,\n session: {\n async token() { return mockToken; },\n async currentToken() { return mockToken; },\n async clear() {},\n },\n client: this.#mockClient,\n preparePush,\n };\n }\n const baseUrl = this.#configuredServer();\n const session = this.#session(baseUrl);\n return {\n mode: \"cloud\",\n session,\n signal: this.#signal,\n client: new HttpDeveloperPlatformClient({\n baseUrl,\n token: async () => (await session.token({ signal: this.#signal })).accessToken,\n }),\n preparePush,\n };\n }\n\n devOptions(): Omit<RunDevCommandOptions, \"cwd\"> {\n return {\n signal: this.#signal,\n env: this.#env,\n authorize: async ({ appServerUrl: baseUrl }) => {\n await this.#session(baseUrl).token({ signal: this.#signal });\n },\n createRegistrationClient: async ({ appServerUrl: baseUrl, refreshToken }) => {\n const token = await this.#session(baseUrl).token({ signal: this.#signal });\n return new MlbDevRegistrationClient({\n baseUrl,\n developerToken: token.accessToken,\n refreshToken,\n tokenStoreFor: id => this.#buddyTokenStore(baseUrl, token.subject, id),\n });\n },\n };\n }\n\n async runPreview(args: readonly string[], io: CliIO): Promise<CliRunResult> {\n const parsed = parsePreviewArguments(args);\n if (parsed.help) {\n io.write(PREVIEW_COMMAND_HELP);\n return { exitCode: 0, route: \"preview\" };\n }\n\n const projectRoot = await requireBuddyAgentProjectRoot(resolve(process.cwd(), parsed.directory));\n const baseUrl = resolvePlatformUrl({ env: this.#env, override: parsed.appServer, development: true });\n const manifest = await readBuddyProjectManifest(projectRoot);\n if (parsed.buddyId && parsed.buddyId !== manifest.buddyId) throw new Error(`\u5F53\u524D\u5DE5\u7A0B\u5C5E\u4E8E ${manifest.buddyId}\uFF0C\u8FDE\u63A5\u6307\u4EE4\u8981\u6C42 ${parsed.buddyId}\uFF1B\u8BF7\u5728\u6B63\u786E\u642D\u5B50\u7684\u5DE5\u7A0B\u76EE\u5F55\u6267\u884C\u3002`);\n const webUrl = new URL(parsed.developerWeb ?? this.#env.BUDDY_DEVELOPER_WEB_URL ?? \"https://47.116.168.81/developer/\");\n if ((webUrl.protocol !== \"https:\" && !(webUrl.protocol === \"http:\" && [\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(webUrl.hostname)))\n || webUrl.username || webUrl.password || webUrl.search || webUrl.hash) throw new Error(\"\u521B\u9020\u8005\u540E\u53F0\u5FC5\u987B\u4F7F\u7528 HTTPS\uFF0C\u672C\u673A\u8C03\u8BD5\u53EF\u4F7F\u7528 loopback HTTP\");\n if (!webUrl.pathname.endsWith(\"/\")) webUrl.pathname += \"/\";\n const signal = this.#signal ?? new AbortController().signal;\n const session = this.#session(baseUrl, webUrl);\n await session.token({ signal });\n const starter = this.#previewStarter(baseUrl, manifest.buddyId, session, parsed.refreshToken ?? false);\n const controller = new PreviewController({\n projectRoot,\n devStarter: starter,\n readBuddyDetails: async (buddyId) => {\n const token = await this.#session(baseUrl).token({ signal });\n return new MlbSimulatorClient({\n baseUrl,\n buddyId: `${buddyId}-dev`,\n auth: { developerAccessToken: token.accessToken },\n }).details({ signal });\n },\n });\n const serverHandle = await startPreviewControlServer({ controller, port: parsed.port });\n let bridge: Awaited<ReturnType<typeof connectPreviewBridge>> | undefined;\n try {\n const pageUrl = new URL(webUrl);\n pageUrl.hash = `/buddy/${encodeURIComponent(manifest.buddyId)}/debug`;\n if (!parsed.local) bridge = await connectPreviewBridge({ webUrl, platformOrigin: baseUrl.origin, buddyId: manifest.buddyId,\n controller, localServer: serverHandle, token: async () => (await session.token({ signal })).accessToken,\n signal, onStatus: message => io.write(message),\n });\n await this.#openUrl(parsed.local ? serverHandle.bootstrapUrl : pageUrl);\n io.write(`\u642D\u642D${parsed.local ? \"\u5907\u7528\u672C\u5730\u9884\u89C8\" : \"\u540E\u53F0\u5F00\u53D1\u8C03\u8BD5\"}\u9875\u9762\u5DF2\u6253\u5F00\uFF1A${parsed.local ? serverHandle.origin.href : pageUrl.href}`);\n if (!parsed.local) io.write(`${bridge?.reused ? \"\u5DF2\u590D\u7528\" : \"\u5DF2\u8FDE\u63A5\"}\u672C\u5730\u5DE5\u7A0B\uFF1A${projectRoot}\uFF08${manifest.buddyId}\uFF09\uFF0C\u8BF7\u5728\u540E\u53F0\u67E5\u770B DEV \u72B6\u6001\u3002`);\n io.write(\"\u5728\u9875\u9762\u4E2D\u542F\u52A8 DEV\uFF1B\u6D88\u606F\u4F1A\u7ECF\u8FC7 DEV App Server\uFF0C\u4E0D\u4F1A\u4ECE\u6D4F\u89C8\u5668\u76F4\u8FDE Agent\u3002\");\n io.write(DEVELOPMENT_HANDOFF_SUMMARY);\n if (bridge?.reused) return { exitCode: 0, route: \"preview\" };\n if (signal.aborted) return { exitCode: 130, route: \"preview\" };\n await (bridge ? bridge.completion : waitForAbort(signal));\n return { exitCode: 130, route: \"preview\" };\n } finally {\n await bridge?.close().catch(() => undefined);\n await controller.close().catch(() => undefined);\n await serverHandle.close();\n }\n }\n\n #previewStarter(baseUrl: URL, buddyId: string, session: CloudAuthenticator, refreshToken: boolean): PreviewDevStarter {\n const starter = createBuddyDevStarter();\n return Object.freeze({\n start: async ({ projectRoot, signal, onLog }: Parameters<PreviewDevStarter[\"start\"]>[0]) => {\n if ((await readBuddyProjectManifest(projectRoot)).buddyId !== buddyId) throw new Error(\"\u5DE5\u7A0B buddyId \u5DF2\u6539\u53D8\uFF0C\u8BF7\u9000\u51FA CLI \u540E\u91CD\u65B0\u8FDE\u63A5\");\n const token = await session.token({ signal });\n const secrets = new Set([token.accessToken]);\n const logs = createRuntimeLogForwarder(event => onLog?.(event), secrets);\n const registrationClient = new MlbDevRegistrationClient({\n baseUrl,\n developerToken: token.accessToken,\n refreshToken,\n tokenStoreFor: id => this.#buddyTokenStore(baseUrl, token.subject, id),\n });\n const handle = await starter.start({ projectRoot, signal,\n registrationClient: {\n async register(request, options) {\n const registered = await registrationClient.register(request, options);\n secrets.add(registered.agentToken);\n return registered;\n },\n listOnline: options => registrationClient.listOnline(options),\n },\n onLog: logs.write,\n }).catch(cause => { logs.flush(); throw cause; });\n const preview = previewHandle(handle);\n void preview.closed.then(() => logs.flush(), () => logs.flush());\n const devBuddyId = `${handle.devAgentId}-dev`;\n const simulator = new MlbSimulatorClient({\n baseUrl,\n buddyId: devBuddyId,\n auth: { developerAccessToken: token.accessToken },\n });\n let buddy: PreviewBuddyDetails;\n let previewUrl: string;\n try {\n buddy = await simulator.details({ signal });\n previewUrl = createBuddyPreviewUrl(devBuddyId);\n signal.throwIfAborted();\n } catch (cause) {\n // Do not leave an Agent running after a failed/unauthorized profile read.\n await handle.stop();\n throw cause;\n }\n return Object.freeze({\n handle: preview,\n ready: Object.freeze({\n agentId: devBuddyId,\n buddy,\n devicePairing: Object.freeze({ url: previewUrl }),\n simulatorUrl: baseUrl.href,\n }),\n simulator,\n });\n },\n });\n }\n\n #buddyTokenStore(baseUrl: URL, subject: string, buddyId: string): SystemBuddyTokenStore {\n return new SystemBuddyTokenStore({ platformUrl: baseUrl, subject, buddyId, commandRunner: this.#credentialCommandRunner });\n }\n\n #configuredServer(): URL {\n return resolvePlatformUrl({ env: this.#env });\n }\n\n #session(baseUrl: URL, webUrl?: URL): CloudAuthenticator {\n const key = baseUrl.origin;\n let session = this.#sessions.get(key);\n if (!session) {\n session = new CloudAuthenticator(\n new LoopbackBrowserLoginAdapter({\n platformUrl: baseUrl,\n ...(webUrl ? { developerWebUrl: webUrl } : this.#env.BUDDY_DEVELOPER_WEB_URL ? { developerWebUrl: this.#env.BUDDY_DEVELOPER_WEB_URL } : {}),\n openBrowser: this.#openUrl,\n }),\n new SystemCloudTokenStore({\n account: `developer-session:${createHash(\"sha256\").update(key).digest(\"hex\")}`,\n commandRunner: this.#credentialCommandRunner,\n }),\n );\n this.#sessions.set(key, session);\n }\n return session;\n }\n}\n", "import { stripVTControlCharacters } from \"node:util\";\nimport type { DevLogEvent } from \"@buddy/cli-core\";\n\nconst MAX_LOG_LINE = 8_192;\n\n/** Assemble process chunks before masking credentials, including tokens split across chunks. */\nexport function createRuntimeLogForwarder(\n onLog: (event: DevLogEvent) => void,\n secrets: ReadonlySet<string>,\n) {\n const streams = new Map<DevLogEvent[\"source\"], { text: string; truncated: boolean }>();\n const emit = (source: DevLogEvent[\"source\"]) => {\n const pending = streams.get(source);\n if (!pending) return;\n streams.delete(source);\n let text = stripVTControlCharacters(pending.text);\n for (const secret of secrets) if (secret) text = text.split(secret).join(\"[REDACTED]\");\n if (pending.truncated) {\n // ANSI removal can move a credential cut at the raw buffer boundary into\n // the visible prefix. Mask its trailing prefix too, before display truncation.\n for (const secret of secrets) {\n for (let size = Math.min(secret.length - 1, text.length); size > 0; size--) {\n if (text.endsWith(secret.slice(0, size))) {\n text = text.slice(0, -size) + \"[REDACTED]\";\n break;\n }\n }\n }\n }\n text = text.replace(/[\\u0000-\\u0008\\u000b-\\u001f\\u007f]/gu, \"\").trimEnd();\n if (!text) return;\n text = text.slice(0, MAX_LOG_LINE) + (pending.truncated ? \" \u2026[truncated]\" : \"\");\n try { onLog({ source, text }); } catch { /* Diagnostics must not break supervision. */ }\n };\n return {\n write({ source, text }: DevLogEvent) {\n const limit = MAX_LOG_LINE + Math.max(0, ...[...secrets].map(secret => secret.length));\n for (const part of text.split(/(?<=\\n)/u)) {\n const pending = streams.get(source) ?? { text: \"\", truncated: false };\n const available = Math.max(0, limit - pending.text.length);\n pending.text += part.slice(0, available);\n pending.truncated ||= part.length > available;\n streams.set(source, pending);\n if (part.endsWith(\"\\n\")) emit(source);\n }\n },\n flush() { for (const source of streams.keys()) emit(source); },\n };\n}\n", "export class UnsupportedDeveloperPlatformError extends Error {\n constructor(readonly platform: NodeJS.Platform) {\n super(`buddy-cli V1 \u76EE\u524D\u53EA\u652F\u6301 macOS\uFF0C\u5F53\u524D\u7CFB\u7EDF\u662F ${platform}`);\n this.name = \"UnsupportedDeveloperPlatformError\";\n }\n}\n\nexport function assertSupportedDeveloperPlatform(\n platform: NodeJS.Platform = process.platform,\n): void {\n if (platform !== \"darwin\") throw new UnsupportedDeveloperPlatformError(platform);\n}\n", "import { execFile } from \"node:child_process\";\nimport { lstat, readFile, realpath } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { isAbsolute, join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport type { CliIO, CliRunResult } from \"@buddy/cli-core\";\n\nconst PACKAGE = \"@my-life-buddies/cli\";\nconst REGISTRY = \"https://registry.npmjs.org/\";\nconst MANUAL_UPDATE = `npm install --global ${PACKAGE}@latest --registry=${REGISTRY}`;\nconst execute = promisify(execFile);\nconst HELP = `\u7528\u6CD5:\n buddy-cli --version [--json]\n buddy-cli update --check [--json]\n buddy-cli update [--json]\n\n--version \u67E5\u770B\u5F53\u524D\u8FD0\u884C\u7684 CLI \u7248\u672C\uFF08\u65E0\u9700\u8054\u7F51\uFF09\n--check \u68C0\u67E5\u516C\u5171 npm \u7684 latest \u7248\u672C\uFF0C\u4E0D\u5B89\u88C5\n--json \u8F93\u51FA JSON\uFF0C\u4F9B Coding Agent \u6216\u811A\u672C\u8BFB\u53D6\n\n\u65E0\u9700\u767B\u5F55\u642D\u642D\u8D26\u53F7\uFF0C\u4E5F\u65E0\u9700\u8FDB\u5165\u642D\u5B50\u5DE5\u7A0B\u3002\nupdate \u66F4\u65B0\u5F53\u524D npm \u5168\u5C40\u5B89\u88C5\u7684 CLI\uFF0C\u4E0D\u4FEE\u6539\u642D\u5B50\u5DE5\u7A0B\u7684 Runtime \u4F9D\u8D56\u3002\n\u5DF2\u7ECF\u662F\u6700\u65B0\u7248\u6216\u5F53\u524D\u7248\u672C\u66F4\u9AD8\u65F6\u4E0D\u5B89\u88C5\u3001\u4E0D\u964D\u7EA7\u3002\n\u6E90\u7801\u3001npm link\u3001\u5C40\u90E8\u5B89\u88C5\u6216 npx \u8FD0\u884C\u65F6\uFF0C\u8BF7\u4F7F\u7528\u539F\u6765\u7684\u5B89\u88C5\u65B9\u5F0F\u66F4\u65B0\u3002\n\u65E7\u7248 CLI \u5C1A\u65E0 update \u547D\u4EE4\u65F6\uFF0C\u8FD0\u884C\uFF1A\\n ${MANUAL_UPDATE}`;\n\ninterface NpmOptions { cwd: string; signal?: AbortSignal; timeout: number }\ninterface UpdateOptions {\n version: string;\n packageRoot: string;\n signal?: AbortSignal;\n fetch?: typeof globalThis.fetch;\n runNpm?: (args: string[], options: NpmOptions) => Promise<{ stdout: string; stderr: string }>;\n}\n\n// SemVer precedence ignores build metadata; numeric identifiers compare numerically.\nfunction parseVersion(version: unknown): string[] {\n const numeric = \"(?:0|[1-9][0-9]*)\";\n const identifier = `(?:${numeric}|[0-9]*[A-Za-z-][0-9A-Za-z-]*)`;\n const pattern = new RegExp(`^(${numeric})\\\\.(${numeric})\\\\.(${numeric})(?:-(${identifier}(?:\\\\.${identifier})*))?(?:\\\\+[0-9A-Za-z-]+(?:\\\\.[0-9A-Za-z-]+)*)?$`, \"u\");\n const match = typeof version === \"string\" && version.length <= 256 ? pattern.exec(version) : null;\n if (!match || match[0] !== version) throw new Error(\"\u7248\u672C\u4FE1\u606F\u4E0D\u662F\u6709\u6548\u7684 SemVer \u7248\u672C\u53F7\u3002\");\n return [match[1]!, match[2]!, match[3]!, ...(match[4]?.split(\".\") ?? [])];\n}\n\nfunction compareVersions(left: string, right: string): number {\n const a = parseVersion(left);\n const b = parseVersion(right);\n for (let i = 0; i < 3; i++) {\n if (BigInt(a[i]!) !== BigInt(b[i]!)) return BigInt(a[i]!) > BigInt(b[i]!) ? 1 : -1;\n }\n if (a.length === 3 || b.length === 3) return a.length === b.length ? 0 : a.length === 3 ? 1 : -1;\n for (let i = 3; i < Math.max(a.length, b.length); i++) {\n const x = a[i];\n const y = b[i];\n if (x === y) continue;\n if (x === undefined || y === undefined) return x === undefined ? -1 : 1;\n const xn = /^[0-9]+$/u.test(x);\n const yn = /^[0-9]+$/u.test(y);\n if (xn && yn) return BigInt(x) > BigInt(y) ? 1 : -1;\n if (xn !== yn) return xn ? -1 : 1;\n return x > y ? 1 : -1;\n }\n return 0;\n}\n\nasync function latestVersion(options: UpdateOptions): Promise<string> {\n const timeout = AbortSignal.timeout(10_000);\n const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;\n try {\n const response = await (options.fetch ?? globalThis.fetch)(`${REGISTRY}${encodeURIComponent(PACKAGE)}/latest`, {\n signal, headers: { Accept: \"application/json\" }, redirect: \"error\",\n });\n if (!response.ok) throw new Error(`npm \u8FD4\u56DE HTTP ${response.status}`);\n const metadata = await response.json() as { name?: unknown; version?: unknown } | null;\n if (metadata?.name !== PACKAGE) throw new Error(\"npm \u8FD4\u56DE\u7684\u5305\u540D\u4E0D\u5339\u914D\");\n parseVersion(metadata.version);\n return metadata.version as string;\n } catch (cause) {\n if (options.signal?.aborted) throw new Error(\"\u64CD\u4F5C\u5DF2\u53D6\u6D88\u3002\");\n if (timeout.aborted) throw new Error(\"\u68C0\u67E5\u66F4\u65B0\u8D85\u65F6\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5\u3002\");\n throw new Error(`\u65E0\u6CD5\u68C0\u67E5 npm \u66F4\u65B0\uFF1A${cause instanceof Error ? cause.message : String(cause)}\u3002\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002`);\n }\n}\n\nasync function installUpdate(version: string, options: UpdateOptions): Promise<void> {\n const runNpm = options.runNpm ?? ((args, settings) => execute(\"npm\", args, { ...settings, encoding: \"utf8\", maxBuffer: 4 * 1024 * 1024 }));\n const settings = { cwd: homedir(), signal: options.signal, timeout: 10_000 };\n const { stdout } = await runNpm([\"prefix\", \"--global\"], settings);\n const prefix = stdout.trim();\n if (!isAbsolute(prefix) || /[\\r\\n]/u.test(prefix)) throw new Error(\"\u65E0\u6CD5\u786E\u5B9A npm \u5168\u5C40\u5B89\u88C5\u76EE\u5F55\u3002\");\n // The CLI supports macOS, where global packages live under prefix/lib/node_modules.\n const installedRoot = join(prefix, \"lib\", \"node_modules\", PACKAGE);\n let sameInstallation = false;\n try {\n sameInstallation = !(await lstat(installedRoot)).isSymbolicLink()\n && await realpath(installedRoot) === await realpath(options.packageRoot);\n } catch { /* Missing global package means this CLI came from another installation. */ }\n if (!sameInstallation) {\n throw new Error(\"\u5F53\u524D CLI \u4E0D\u662F\u8FD9\u4E2A npm \u73AF\u5883\u7684\u5168\u5C40\u5B89\u88C5\uFF0C\u4E0D\u80FD\u76F4\u63A5\u66F4\u65B0\u3002\u8BF7\u7528\u539F\u6765\u7684\u5B89\u88C5\u65B9\u5F0F\u66F4\u65B0\uFF1B\u82E5\u4F7F\u7528 nvm\uFF0C\u8BF7\u5148\u5207\u6362\u5230\u5B89\u88C5\u8BE5 CLI \u7684 Node.js \u73AF\u5883\u3002\");\n }\n try {\n await runNpm([\n \"install\", \"--global\", `${PACKAGE}@${version}`, \"--prefix\", prefix,\n `--registry=${REGISTRY}`, `--@my-life-buddies:registry=${REGISTRY}`, \"--engine-strict\", \"--no-audit\", \"--no-fund\",\n ], { ...settings, timeout: 180_000 });\n } catch (cause) {\n if (options.signal?.aborted) throw new Error(\"\u66F4\u65B0\u5DF2\u53D6\u6D88\uFF0C\u8BF7\u8FD0\u884C buddy-cli --version \u68C0\u67E5\u5B89\u88C5\u72B6\u6001\u3002\");\n const code = cause && typeof cause === \"object\" && \"code\" in cause ? String(cause.code) : \"unknown\";\n throw new Error(`npm \u5B89\u88C5\u672A\u5B8C\u6210\uFF08${code}\uFF09\u3002\u8BF7\u68C0\u67E5\u7F51\u7EDC\u548C\u5168\u5C40\u76EE\u5F55\u6743\u9650\uFF0C\u7136\u540E\u91CD\u8BD5\uFF1A${MANUAL_UPDATE}`);\n }\n const installed = JSON.parse(await readFile(join(installedRoot, \"package.json\"), \"utf8\"));\n if (installed.name !== PACKAGE || installed.version !== version) {\n throw new Error(`npm \u5DF2\u7ED3\u675F\uFF0C\u4F46\u672A\u786E\u8BA4\u5B89\u88C5\u5230 ${version}\u3002\u8BF7\u8FD0\u884C buddy-cli --version \u68C0\u67E5\uFF0C\u5FC5\u8981\u65F6\u91CD\u8BD5\uFF1A${MANUAL_UPDATE}`);\n }\n}\n\n/** Public CLI maintenance runs before any project or platform credential handling. */\nexport async function runSelfUpdateCommand(\n args: readonly string[],\n io: Pick<CliIO, \"write\" | \"writeError\">,\n options: UpdateOptions,\n): Promise<CliRunResult | undefined> {\n const versionOnly = args[0] === \"--version\" || args[0] === \"-v\";\n if (!versionOnly && args[0] !== \"update\") return undefined;\n const json = args.includes(\"--json\");\n const fail = (message: string, exitCode: number) => {\n if (json) io.write(JSON.stringify({ package: PACKAGE, currentVersion: options.version, error: message }));\n else io.writeError(`buddy-cli: ${message}`);\n return { exitCode };\n };\n const flags = args.slice(1);\n const allowed = versionOnly ? [\"--json\", \"--help\", \"-h\"] : [\"--check\", \"--json\", \"--help\", \"-h\"];\n if (flags.some(flag => !allowed.includes(flag)) || new Set(flags).size !== flags.length) {\n return fail(\"\u53C2\u6570\u65E0\u6548\uFF0C\u8BF7\u8FD0\u884C buddy-cli update --help \u67E5\u770B\u7528\u6CD5\u3002\", 2);\n }\n if (flags.includes(\"--help\") || flags.includes(\"-h\")) {\n if (json) io.write(JSON.stringify({ help: HELP }));\n else io.write(HELP);\n return { exitCode: 0 };\n }\n try {\n parseVersion(options.version);\n if (versionOnly) {\n io.write(json ? JSON.stringify({ package: PACKAGE, version: options.version }) : options.version);\n return { exitCode: 0 };\n }\n const latest = await latestVersion(options);\n const comparison = compareVersions(latest, options.version);\n const check = flags.includes(\"--check\");\n const status = comparison > 0 ? \"update_available\" : comparison < 0 ? \"ahead\" : \"up_to_date\";\n if (!check && comparison > 0) {\n if (!json) io.write(`\u6B63\u5728\u66F4\u65B0 CLI\uFF1A${options.version} \u2192 ${latest}\u2026`);\n await installUpdate(latest, options);\n }\n const updated = !check && comparison > 0;\n if (json) {\n io.write(JSON.stringify({\n package: PACKAGE, currentVersion: options.version, latestVersion: latest,\n updateAvailable: comparison > 0 && !updated, status: updated ? \"updated\" : status,\n ...(updated ? { installedVersion: latest } : {}),\n }));\n } else if (updated) io.write(`CLI \u5DF2\u66F4\u65B0\uFF1A${options.version} \u2192 ${latest}\u3002`);\n else if (comparison > 0) io.write(`\u53D1\u73B0\u65B0\u7248\u672C\uFF1A${options.version} \u2192 ${latest}\u3002\u8FD0\u884C buddy-cli update \u66F4\u65B0\u3002`);\n else if (comparison < 0) io.write(`\u5F53\u524D\u7248\u672C ${options.version} \u9AD8\u4E8E npm latest ${latest}\uFF0C\u65E0\u9700\u66F4\u65B0\u3002`);\n else io.write(`\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\uFF1A${options.version}\u3002`);\n return { exitCode: 0 };\n } catch (cause) {\n return fail(cause instanceof Error ? cause.message : String(cause), 1);\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["#!/usr/bin/env node\n\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { stdin, stderr, stdout } from \"node:process\";\nimport { createRequire } from \"node:module\";\nimport { dirname } from \"node:path\";\nimport { createInterface, type Interface } from \"node:readline/promises\";\nimport {\n PromptCancelledError,\n runBuddyCli,\n type Choice,\n type CliIO,\n type InputOptions,\n type SelectOptions,\n} from \"@buddy/cli-core\";\nimport { BuddyPlatformHost } from \"../platform-host.js\";\nimport { assertSupportedDeveloperPlatform } from \"../platform-support.js\";\nimport { runSelfUpdateCommand } from \"../self-update.js\";\nimport { latestRuntimeTemplate, scaffoldPlatformAgent } from \"@buddy/cli-core/init/scaffold\";\n\nclass TerminalIO implements CliIO {\n readonly canPrompt = Boolean(stdin.isTTY && stdout.isTTY);\n private readline: Interface | undefined;\n private activeQuestion: AbortController | undefined;\n private cancelled = false;\n\n write(message: string): void {\n stdout.write(`${message}\\n`);\n }\n\n writeError(message: string): void {\n stderr.write(`${message}\\n`);\n }\n\n async openMetaPreview(path: string): Promise<void> {\n try { await promisify(execFile)(\"open\", [path]); }\n catch { this.write(`\u8BF7\u6253\u5F00\u672C\u5730\u5934\u50CF\u9884\u89C8\u540E\u518D\u786E\u8BA4\uFF1A${path}`); }\n }\n\n async select<Value extends string>(\n question: string,\n choices: readonly Choice<Value>[],\n options: SelectOptions<Value> = {},\n ): Promise<Value> {\n while (true) {\n this.write(`\\n${question}`);\n choices.forEach((choice, index) => {\n this.write(` ${index + 1}. ${choice.label}`);\n if (choice.description) this.write(` ${choice.description}`);\n });\n\n const defaultIndex = options.defaultValue === undefined\n ? undefined\n : choices.findIndex((choice) => choice.value === options.defaultValue);\n const prompt = defaultIndex === undefined || defaultIndex < 0\n ? \"\u8BF7\u8F93\u5165\u5E8F\u53F7\uFF1A\"\n : `\u8BF7\u8F93\u5165\u5E8F\u53F7\uFF08\u9ED8\u8BA4\uFF1A${defaultIndex + 1}\uFF09\uFF1A`;\n const answer = (await this.question(prompt)).trim();\n if (!answer && defaultIndex !== undefined && defaultIndex >= 0) return choices[defaultIndex]!.value;\n const selected = Number(answer) - 1;\n const choice = choices[selected];\n if (choice) return choice.value;\n this.writeError(`\u8BF7\u8F93\u5165 1 \u5230 ${choices.length} \u4E4B\u95F4\u7684\u5E8F\u53F7\u3002`);\n }\n }\n\n async input(question: string, options: InputOptions = {}): Promise<string> {\n const defaultHint = options.defaultValue === undefined ? \"\" : `\uFF08\u9ED8\u8BA4\uFF1A${options.defaultValue}\uFF09`;\n const answer = (await this.question(`${question}${defaultHint}\uFF1A`)).trim();\n return answer || options.defaultValue || \"\";\n }\n\n close(): void {\n this.readline?.close();\n }\n\n private getReadline(): Interface {\n if (this.readline) return this.readline;\n this.readline = createInterface({ input: stdin, output: stdout });\n this.readline.on(\"SIGINT\", () => {\n this.cancelled = true;\n this.activeQuestion?.abort();\n });\n return this.readline;\n }\n\n private async question(prompt: string): Promise<string> {\n const controller = new AbortController();\n this.activeQuestion = controller;\n try {\n return await this.getReadline().question(prompt, { signal: controller.signal });\n } catch (cause) {\n if (this.cancelled) throw new PromptCancelledError();\n throw cause;\n } finally {\n if (this.activeQuestion === controller) this.activeQuestion = undefined;\n }\n }\n}\n\nconst terminal = new TerminalIO();\nconst lifecycle = new AbortController();\nconst abortFromSignal = (signal: NodeJS.Signals) => {\n if (!lifecycle.signal.aborted) lifecycle.abort(new Error(signal));\n};\nconst onSigint = () => abortFromSignal(\"SIGINT\");\nconst onSigterm = () => abortFromSignal(\"SIGTERM\");\nprocess.on(\"SIGINT\", onSigint);\nprocess.on(\"SIGTERM\", onSigterm);\n\ntry {\n assertSupportedDeveloperPlatform();\n const args = process.argv.slice(2);\n const require = createRequire(import.meta.url);\n const manifestPath = require.resolve(\"@my-life-buddies/cli/package.json\");\n const maintenance = await runSelfUpdateCommand(args, terminal, {\n version: require(manifestPath).version,\n packageRoot: dirname(manifestPath),\n signal: lifecycle.signal,\n });\n const command = args[0];\n let platformHost: BuddyPlatformHost | undefined;\n const host = () => platformHost ??= new BuddyPlatformHost({ signal: lifecycle.signal });\n const result = maintenance ?? await runBuddyCli(args, terminal, {\n runtimeCatalog: { signal: lifecycle.signal },\n scaffoldPlatformAgent: (root, name) => scaffoldPlatformAgent(root, name, {\n resolveDependencies: template => latestRuntimeTemplate(template, {\n signal: lifecycle.signal, report: message => terminal.write(message),\n }),\n }),\n ...(command === \"dev\" ? { dev: host().devOptions() } : {}),\n // Resolve credentials only when a supported command actually needs them.\n get cloud() { return host().cloudOptions(); },\n preview: (previewArgs, io) => host().runPreview(previewArgs, io),\n });\n process.exitCode = result.exitCode;\n} catch (cause) {\n const message = cause instanceof Error ? cause.message : String(cause);\n terminal.writeError(`buddy-cli: ${message}`);\n process.exitCode = 1;\n} finally {\n process.off(\"SIGINT\", onSigint);\n process.off(\"SIGTERM\", onSigterm);\n terminal.close();\n}\n", "import { resolve } from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { readBuddyProjectManifest } from \"@buddy/cli-core/config\";\nimport { createRuntimeLogForwarder } from \"./runtime-logs.js\";\n\nimport {\n CloudAuthenticator,\n BuddyDevError,\n checkRuntimeUpdate,\n type RuntimePackageOptions,\n DEFAULT_MLB_TEST_URL,\n HttpDeveloperPlatformClient,\n LoopbackBrowserLoginAdapter,\n MlbDevRegistrationClient,\n MockDeveloperPlatformClient,\n SystemCloudTokenStore,\n SystemBuddyTokenStore,\n createBuddyDevStarter,\n createPushPreflight,\n createPushSourceBundle,\n resolvePlatformUrl,\n openExternalUrl,\n requireBuddyAgentProjectRoot,\n type CliIO,\n type CredentialCommandRunner,\n type CliRunResult,\n type RunCloudCommandOptions,\n type RunDevCommandOptions,\n} from \"@buddy/cli-core\";\nimport {\n PreviewController,\n MlbSimulatorClient,\n createBuddyPreviewUrl,\n startPreviewControlServer,\n connectPreviewBridge,\n type PreviewBuddyDetails,\n type PreviewDevHandle,\n type PreviewDevStarter,\n} from \"@buddy/preview\";\n\nexport interface ParsedPreviewArguments {\n readonly directory: string;\n readonly appServer?: string;\n readonly port?: number;\n readonly help: boolean;\n readonly local: boolean;\n readonly refreshToken?: boolean;\n readonly buddyId?: string;\n readonly developerWeb?: string;\n}\n\nexport const PREVIEW_COMMAND_HELP = `\u7528\u6CD5:\n buddy-cli preview [--directory <\u9879\u76EE\u76EE\u5F55>] [--buddy-id <\u642D\u5B50 ID>] [--developer-web <\u540E\u53F0 URL>] [--app-server <App Server URL>]\n buddy-cli preview --local [--directory <\u9879\u76EE\u76EE\u5F55>] [--port <\u672C\u5730\u7AEF\u53E3>]\n\n\u8BF4\u660E:\n \u9ED8\u8BA4\u6253\u5F00\u5F53\u524D\u642D\u5B50\u7684\u521B\u9020\u8005\u540E\u53F0\u300C\u5F00\u53D1\u8C03\u8BD5\u300D\uFF0C\u8FDE\u63A5\u672C\u5730\u5DE5\u7A0B\uFF1B\u5728\u540E\u53F0\u542F\u52A8/\u505C\u6B62 DEV\u3001\u8BD5\u804A\u3001\u67E5\u770B Widget\u3001\u65F6\u95F4\u7EBF\u4E0E\u534F\u8BAE\u65E5\u5FD7\u3001\u771F\u673A\u9884\u89C8\u3002\n --buddy-id \u6821\u9A8C\u5F53\u524D\u5DE5\u7A0B\u8EAB\u4EFD\uFF1B\u540E\u53F0\u300C\u83B7\u53D6\u8FDE\u63A5\u6307\u4EE4\u300D\u63D0\u4F9B\u642D\u5B50\u548C\u73AF\u5883\u5B8C\u6574\u53C2\u6570\u3002\n --local \u662F\u540E\u53F0\u4E0D\u53EF\u7528\u65F6\u7684\u72EC\u7ACB\u672C\u5730\u9884\u89C8\u5907\u7528\u5165\u53E3\uFF0C--port \u4EC5\u4E0E --local \u4E00\u8D77\u4F7F\u7528\u3002\n \u4FDD\u6301\u7EC8\u7AEF\u8FD0\u884C\uFF1B\u9000\u51FA CLI \u4F1A\u505C\u6B62 DEV \u5E76\u65AD\u5F00\u8FDE\u63A5\uFF0C\u5237\u65B0\u540E\u53F0\u4E0D\u4F1A\u81EA\u52A8\u542F\u52A8 DEV\u3002\n \u672A\u914D\u7F6E\u5730\u5740\u65F6\u8FDE\u63A5 MLB \u6D4B\u8BD5\u73AF\u5883 ${DEFAULT_MLB_TEST_URL}\uFF08HTTP \u4EC5\u9650\u6D4B\u8BD5\uFF09\u3002\n CLI \u7EDF\u4E00\u542F\u52A8\u5E76\u7BA1\u7406\u5DE5\u7A0B\u4E2D\u7684\u5B98\u65B9 Runtime\uFF1B\u6BCF\u6B21\u542F\u52A8\u6216\u91CD\u8F7D\u5FC5\u987B\u901A\u8FC7 npm \u6700\u65B0\u7A33\u5B9A\u7248\u68C0\u67E5\u3002\n --refresh-token \u91CD\u65B0\u9886\u53D6\u5DF2\u6709\u5F00\u53D1 Token\uFF0C\u66F4\u65B0\u5DE5\u7A0B .env\uFF1B\u4E0D\u4F1A\u751F\u6210\u65B0\u5BC6\u94A5\u3002\n \u6A21\u62DF\u5668\u4F7F\u7528\u5F53\u524D\u5F00\u53D1\u8005\u8D26\u53F7\u8BBF\u95EE <buddyId>-dev \u8C03\u8BD5\u5206\u8EAB\u3002`;\n\nfunction valueAfter(args: readonly string[], index: number, flag: string): string {\n const value = args[index + 1];\n if (value === undefined || !value.trim()) throw new Error(`${flag} \u7F3A\u5C11\u503C`);\n return value;\n}\n\nfunction setOnce(current: string | undefined, value: string, flag: string): string {\n if (current !== undefined) throw new Error(`${flag} \u4E0D\u80FD\u91CD\u590D`);\n return value;\n}\n\nexport function parsePreviewArguments(args: readonly string[]): ParsedPreviewArguments {\n let directory = \".\";\n let directorySet = false;\n let appServer: string | undefined;\n let port: number | undefined;\n let help = false;\n let local = false;\n let refreshToken = false;\n let buddyId: string | undefined;\n let developerWeb: string | undefined;\n for (let index = 0; index < args.length; index += 1) {\n const flag = args[index];\n if (flag === \"--refresh-token\") {\n if (refreshToken) throw new Error(\"--refresh-token \u4E0D\u80FD\u91CD\u590D\");\n refreshToken = true;\n continue;\n }\n if (flag === \"--help\" || flag === \"-h\") {\n if (args.length !== 1) throw new Error(\"--help \u4E0D\u80FD\u548C\u5176\u4ED6 preview \u53C2\u6570\u4E00\u8D77\u4F7F\u7528\");\n help = true;\n continue;\n }\n if (flag === \"--local\") { if (local) throw new Error(\"--local \u4E0D\u80FD\u91CD\u590D\"); local = true; continue; }\n const value = valueAfter(args, index, flag ?? \"\u53C2\u6570\");\n index += 1;\n switch (flag) {\n case \"--buddy-id\":\n buddyId = setOnce(buddyId, value, flag);\n if (!/^[A-Za-z0-9_-]{1,128}$/u.test(buddyId)) throw new Error(\"--buddy-id \u65E0\u6548\");\n break;\n case \"--developer-web\":\n developerWeb = setOnce(developerWeb, value, flag);\n break;\n case \"--directory\":\n if (directorySet) throw new Error(\"--directory \u4E0D\u80FD\u91CD\u590D\");\n directory = value;\n directorySet = true;\n break;\n case \"--port\":\n if (port !== undefined || !/^\\d+$/u.test(value) || Number(value) < 1 || Number(value) > 65535) throw new Error(\"--port \u5FC5\u987B\u662F 1\u201365535 \u7684\u7AEF\u53E3\u4E14\u4E0D\u80FD\u91CD\u590D\");\n port = Number(value);\n break;\n case \"--app-server\":\n appServer = setOnce(appServer, value, flag);\n break;\n default:\n throw new Error(`\u672A\u77E5 preview \u53C2\u6570 ${flag ?? \"\"}`);\n }\n }\n if (port !== undefined && !local) throw new Error(\"--port \u4EC5\u7528\u4E8E --local \u5907\u7528\u9884\u89C8\");\n if (local && developerWeb) throw new Error(\"--local \u4E0D\u9700\u8981 --developer-web\");\n return Object.freeze({ directory, appServer, help, local, buddyId, developerWeb, ...(port === undefined ? {} : { port }), ...(refreshToken ? { refreshToken: true } : {}) });\n}\n\nexport interface BuddyPlatformHostOptions {\n readonly runtimeUpdate?: RuntimePackageOptions;\n readonly env?: Readonly<NodeJS.ProcessEnv>;\n readonly signal?: AbortSignal;\n readonly openUrl?: (url: URL) => Promise<void>;\n readonly credentialCommandRunner?: CredentialCommandRunner;\n}\n\nfunction waitForAbort(signal: AbortSignal): Promise<void> {\n if (signal.aborted) return Promise.resolve();\n return new Promise((resolveWait) => {\n signal.addEventListener(\"abort\", () => resolveWait(), { once: true });\n });\n}\n\nfunction previewHandle(handle: Awaited<ReturnType<ReturnType<typeof createBuddyDevStarter>[\"start\"]>>): PreviewDevHandle {\n return Object.freeze({\n closed: handle.completion.then((completion) => {\n if (completion.state === \"failed\") throw completion.error ?? new Error(\"DEV \u4F1A\u8BDD\u5F02\u5E38\u7ED3\u675F\");\n }),\n close: () => handle.stop(),\n });\n}\n\nexport class BuddyPlatformHost {\n readonly #runtimeUpdate: RuntimePackageOptions | undefined;\n readonly #env: Readonly<NodeJS.ProcessEnv>;\n readonly #signal: AbortSignal | undefined;\n readonly #openUrl: (url: URL) => Promise<void>;\n readonly #sessions = new Map<string, CloudAuthenticator>();\n readonly #credentialCommandRunner: CredentialCommandRunner | undefined;\n readonly #mockClient = new MockDeveloperPlatformClient();\n\n constructor(options: BuddyPlatformHostOptions = {}) {\n this.#runtimeUpdate = options.runtimeUpdate;\n this.#env = options.env ?? process.env;\n this.#signal = options.signal;\n this.#openUrl = options.openUrl ?? openExternalUrl;\n this.#credentialCommandRunner = options.credentialCommandRunner;\n }\n\n cloudOptions(): Omit<RunCloudCommandOptions, \"cwd\"> {\n const preparePush: NonNullable<RunCloudCommandOptions[\"preparePush\"]> = async (\n projectRoot,\n _config,\n expectedRuntimeVersion,\n ) => {\n const plan = await createPushPreflight({ projectRoot, expectedRuntimeVersion });\n return createPushSourceBundle(plan);\n };\n if (this.#env.BUDDY_CLI_MOCK_CLOUD === \"1\") {\n const mockToken = {\n accessToken: \"local-mock-access-token\",\n subject: \"account_local_mock\",\n expiresAt: Date.now() + 60 * 60_000,\n };\n return {\n mode: \"local-mock\",\n signal: this.#signal,\n session: {\n async token() { return mockToken; },\n async currentToken() { return mockToken; },\n async clear() {},\n },\n client: this.#mockClient,\n preparePush,\n };\n }\n const baseUrl = this.#configuredServer();\n const session = this.#session(baseUrl);\n return {\n mode: \"cloud\",\n session,\n signal: this.#signal,\n client: new HttpDeveloperPlatformClient({\n baseUrl,\n token: async () => (await session.token({ signal: this.#signal })).accessToken,\n }),\n preparePush,\n };\n }\n\n devOptions(): Omit<RunDevCommandOptions, \"cwd\"> {\n return {\n signal: this.#signal,\n env: this.#env,\n authorize: async ({ appServerUrl: baseUrl }) => {\n await this.#session(baseUrl).token({ signal: this.#signal });\n },\n createRegistrationClient: async ({ appServerUrl: baseUrl, refreshToken }) => {\n const token = await this.#session(baseUrl).token({ signal: this.#signal });\n return new MlbDevRegistrationClient({\n baseUrl,\n developerToken: token.accessToken,\n refreshToken,\n tokenStoreFor: id => this.#buddyTokenStore(baseUrl, token.subject, id),\n });\n },\n };\n }\n\n async runPreview(args: readonly string[], io: CliIO): Promise<CliRunResult> {\n const parsed = parsePreviewArguments(args);\n if (parsed.help) {\n io.write(PREVIEW_COMMAND_HELP);\n return { exitCode: 0, route: \"preview\" };\n }\n\n const projectRoot = await requireBuddyAgentProjectRoot(resolve(process.cwd(), parsed.directory));\n const baseUrl = resolvePlatformUrl({ env: this.#env, override: parsed.appServer, development: true });\n const manifest = await readBuddyProjectManifest(projectRoot);\n if (parsed.buddyId && parsed.buddyId !== manifest.buddyId) throw new Error(`\u5F53\u524D\u5DE5\u7A0B\u5C5E\u4E8E ${manifest.buddyId}\uFF0C\u8FDE\u63A5\u6307\u4EE4\u8981\u6C42 ${parsed.buddyId}\uFF1B\u8BF7\u5728\u6B63\u786E\u642D\u5B50\u7684\u5DE5\u7A0B\u76EE\u5F55\u6267\u884C\u3002`);\n const webUrl = new URL(parsed.developerWeb ?? this.#env.BUDDY_DEVELOPER_WEB_URL ?? \"https://47.116.168.81/developer/\");\n if ((webUrl.protocol !== \"https:\" && !(webUrl.protocol === \"http:\" && [\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(webUrl.hostname)))\n || webUrl.username || webUrl.password || webUrl.search || webUrl.hash) throw new Error(\"\u521B\u9020\u8005\u540E\u53F0\u5FC5\u987B\u4F7F\u7528 HTTPS\uFF0C\u672C\u673A\u8C03\u8BD5\u53EF\u4F7F\u7528 loopback HTTP\");\n if (!webUrl.pathname.endsWith(\"/\")) webUrl.pathname += \"/\";\n const signal = this.#signal ?? new AbortController().signal;\n await checkRuntimeUpdate(projectRoot, message => io.writeError(message), { signal, ...this.#runtimeUpdate });\n const session = this.#session(baseUrl, webUrl);\n await session.token({ signal });\n const starter = this.#previewStarter(baseUrl, manifest.buddyId, session, parsed.refreshToken ?? false);\n const controller = new PreviewController({\n projectRoot,\n devStarter: starter,\n readBuddyDetails: async (buddyId) => {\n const token = await this.#session(baseUrl).token({ signal });\n return new MlbSimulatorClient({\n baseUrl,\n buddyId: `${buddyId}-dev`,\n auth: { developerAccessToken: token.accessToken },\n }).details({ signal });\n },\n });\n const serverHandle = await startPreviewControlServer({ controller, port: parsed.port });\n let bridge: Awaited<ReturnType<typeof connectPreviewBridge>> | undefined;\n try {\n const pageUrl = new URL(webUrl);\n pageUrl.hash = `/buddy/${encodeURIComponent(manifest.buddyId)}/debug`;\n if (!parsed.local) bridge = await connectPreviewBridge({ webUrl, platformOrigin: baseUrl.origin, buddyId: manifest.buddyId,\n controller, localServer: serverHandle, token: async () => (await session.token({ signal })).accessToken,\n signal, onStatus: message => io.write(message),\n });\n await this.#openUrl(parsed.local ? serverHandle.bootstrapUrl : pageUrl);\n io.write(`\u642D\u642D${parsed.local ? \"\u5907\u7528\u672C\u5730\u9884\u89C8\" : \"\u540E\u53F0\u5F00\u53D1\u8C03\u8BD5\"}\u9875\u9762\u5DF2\u6253\u5F00\uFF1A${parsed.local ? serverHandle.origin.href : pageUrl.href}`);\n if (!parsed.local) io.write(`${bridge?.reused ? \"\u5DF2\u590D\u7528\" : \"\u5DF2\u8FDE\u63A5\"}\u672C\u5730\u5DE5\u7A0B\uFF1A${projectRoot}\uFF08${manifest.buddyId}\uFF09\uFF0C\u8BF7\u5728\u540E\u53F0\u67E5\u770B DEV \u72B6\u6001\u3002`);\n io.write(\"\u5728\u9875\u9762\u4E2D\u542F\u52A8 DEV\uFF1B\u6D88\u606F\u4F1A\u7ECF\u8FC7 DEV App Server\uFF0C\u4E0D\u4F1A\u4ECE\u6D4F\u89C8\u5668\u76F4\u8FDE Agent\u3002\");\n io.write(\"\u4FDD\u6301\u7EC8\u7AEF\u8FD0\u884C\uFF1BCtrl+C \u505C\u6B62 DEV \u5E76\u65AD\u5F00\u8FDE\u63A5\u3002\");\n if (bridge?.reused) return { exitCode: 0, route: \"preview\" };\n if (signal.aborted) return { exitCode: 130, route: \"preview\" };\n await (bridge ? bridge.completion : waitForAbort(signal));\n return { exitCode: 130, route: \"preview\" };\n } finally {\n await bridge?.close().catch(() => undefined);\n await controller.close().catch(() => undefined);\n await serverHandle.close();\n }\n }\n\n #previewStarter(baseUrl: URL, buddyId: string, session: CloudAuthenticator, refreshToken: boolean): PreviewDevStarter {\n const starter = createBuddyDevStarter();\n return Object.freeze({\n start: async ({ projectRoot, signal, onLog, onLifecycle }: Parameters<PreviewDevStarter[\"start\"]>[0]) => {\n if ((await readBuddyProjectManifest(projectRoot)).buddyId !== buddyId) throw new Error(\"\u5DE5\u7A0B buddyId \u5DF2\u6539\u53D8\uFF0C\u8BF7\u9000\u51FA CLI \u540E\u91CD\u65B0\u8FDE\u63A5\");\n const token = await session.token({ signal });\n const secrets = new Set([token.accessToken]);\n const logs = createRuntimeLogForwarder(event => onLog?.(event), secrets);\n const registrationClient = new MlbDevRegistrationClient({\n baseUrl,\n developerToken: token.accessToken,\n refreshToken,\n tokenStoreFor: id => this.#buddyTokenStore(baseUrl, token.subject, id),\n });\n let reloadError: { code: string; message: string } | undefined;\n const handle = await starter.start({ projectRoot, signal, runtimeUpdate: this.#runtimeUpdate,\n onError(error) {\n logs.flush();\n let message = error.message;\n for (const secret of secrets) if (secret) message = message.split(secret).join(\"[REDACTED]\");\n reloadError = { code: error.code, message: message.replace(/[\\u0000-\\u001f\\u007f]/gu, \" \").slice(0, 512) };\n },\n onStateChange(phase) {\n if (phase === \"reloading\") reloadError = undefined;\n if (phase === \"reloading\" || phase === \"reload_failed\" || phase === \"ready\") onLifecycle?.({ phase, ...(phase === \"reload_failed\" && reloadError ? { error: reloadError } : {}) });\n },\n registrationClient: {\n async register(request, options) {\n const registered = await registrationClient.register(request, options);\n secrets.add(registered.agentToken);\n return registered;\n },\n listOnline: options => registrationClient.listOnline(options),\n },\n onLog: logs.write,\n }).catch(cause => {\n logs.flush();\n if (cause instanceof BuddyDevError && cause.code.startsWith(\"DEV_RUNTIME_\")) {\n let message = cause.message;\n for (const secret of secrets) if (secret) message = message.split(secret).join(\"[REDACTED]\");\n Object.assign(cause, { publicMessage: message.replace(/[\\u0000-\\u001f\\u007f]/gu, \" \").slice(0, 512) });\n }\n throw cause;\n });\n const preview = previewHandle(handle);\n void preview.closed.then(() => logs.flush(), () => logs.flush());\n const devBuddyId = `${handle.devAgentId}-dev`;\n const simulator = new MlbSimulatorClient({\n baseUrl,\n buddyId: devBuddyId,\n auth: { developerAccessToken: token.accessToken },\n });\n let buddy: PreviewBuddyDetails;\n let previewUrl: string;\n try {\n buddy = await simulator.details({ signal });\n previewUrl = createBuddyPreviewUrl(devBuddyId);\n signal.throwIfAborted();\n } catch (cause) {\n // Do not leave an Agent running after a failed/unauthorized profile read.\n await handle.stop();\n throw cause;\n }\n return Object.freeze({\n handle: preview,\n ready: Object.freeze({\n agentId: devBuddyId,\n buddy,\n devicePairing: Object.freeze({ url: previewUrl }),\n simulatorUrl: baseUrl.href,\n }),\n simulator,\n });\n },\n });\n }\n\n #buddyTokenStore(baseUrl: URL, subject: string, buddyId: string): SystemBuddyTokenStore {\n return new SystemBuddyTokenStore({ platformUrl: baseUrl, subject, buddyId, commandRunner: this.#credentialCommandRunner });\n }\n\n #configuredServer(): URL {\n return resolvePlatformUrl({ env: this.#env });\n }\n\n #session(baseUrl: URL, webUrl?: URL): CloudAuthenticator {\n const key = baseUrl.origin;\n let session = this.#sessions.get(key);\n if (!session) {\n session = new CloudAuthenticator(\n new LoopbackBrowserLoginAdapter({\n platformUrl: baseUrl,\n ...(webUrl ? { developerWebUrl: webUrl } : this.#env.BUDDY_DEVELOPER_WEB_URL ? { developerWebUrl: this.#env.BUDDY_DEVELOPER_WEB_URL } : {}),\n openBrowser: this.#openUrl,\n }),\n new SystemCloudTokenStore({\n account: `developer-session:${createHash(\"sha256\").update(key).digest(\"hex\")}`,\n commandRunner: this.#credentialCommandRunner,\n }),\n );\n this.#sessions.set(key, session);\n }\n return session;\n }\n}\n", "import { stripVTControlCharacters } from \"node:util\";\nimport type { DevLogEvent } from \"@buddy/cli-core\";\n\nconst MAX_LOG_LINE = 8_192;\n\n/** Assemble process chunks before masking credentials, including tokens split across chunks. */\nexport function createRuntimeLogForwarder(\n onLog: (event: DevLogEvent) => void,\n secrets: ReadonlySet<string>,\n) {\n const streams = new Map<DevLogEvent[\"source\"], { text: string; truncated: boolean }>();\n const emit = (source: DevLogEvent[\"source\"]) => {\n const pending = streams.get(source);\n if (!pending) return;\n streams.delete(source);\n let text = stripVTControlCharacters(pending.text);\n for (const secret of secrets) if (secret) text = text.split(secret).join(\"[REDACTED]\");\n if (pending.truncated) {\n // ANSI removal can move a credential cut at the raw buffer boundary into\n // the visible prefix. Mask its trailing prefix too, before display truncation.\n for (const secret of secrets) {\n for (let size = Math.min(secret.length - 1, text.length); size > 0; size--) {\n if (text.endsWith(secret.slice(0, size))) {\n text = text.slice(0, -size) + \"[REDACTED]\";\n break;\n }\n }\n }\n }\n text = text.replace(/[\\u0000-\\u0008\\u000b-\\u001f\\u007f]/gu, \"\").trimEnd();\n if (!text) return;\n text = text.slice(0, MAX_LOG_LINE) + (pending.truncated ? \" \u2026[truncated]\" : \"\");\n try { onLog({ source, text }); } catch { /* Diagnostics must not break supervision. */ }\n };\n return {\n write({ source, text }: DevLogEvent) {\n const limit = MAX_LOG_LINE + Math.max(0, ...[...secrets].map(secret => secret.length));\n for (const part of text.split(/(?<=\\n)/u)) {\n const pending = streams.get(source) ?? { text: \"\", truncated: false };\n const available = Math.max(0, limit - pending.text.length);\n pending.text += part.slice(0, available);\n pending.truncated ||= part.length > available;\n streams.set(source, pending);\n if (part.endsWith(\"\\n\")) emit(source);\n }\n },\n flush() { for (const source of streams.keys()) emit(source); },\n };\n}\n", "export class UnsupportedDeveloperPlatformError extends Error {\n constructor(readonly platform: NodeJS.Platform) {\n super(`buddy-cli V1 \u76EE\u524D\u53EA\u652F\u6301 macOS\uFF0C\u5F53\u524D\u7CFB\u7EDF\u662F ${platform}`);\n this.name = \"UnsupportedDeveloperPlatformError\";\n }\n}\n\nexport function assertSupportedDeveloperPlatform(\n platform: NodeJS.Platform = process.platform,\n): void {\n if (platform !== \"darwin\") throw new UnsupportedDeveloperPlatformError(platform);\n}\n", "import { execFile } from \"node:child_process\";\nimport { lstat, readFile, realpath } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { isAbsolute, join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport type { CliIO, CliRunResult } from \"@buddy/cli-core\";\n\nconst PACKAGE = \"@my-life-buddies/cli\";\nconst REGISTRY = \"https://registry.npmjs.org/\";\nconst MANUAL_UPDATE = `npm install --global ${PACKAGE}@latest --registry=${REGISTRY}`;\nconst execute = promisify(execFile);\nconst HELP = `\u7528\u6CD5:\n buddy-cli --version [--json]\n buddy-cli update --check [--json]\n buddy-cli update [--json]\n\n--version \u67E5\u770B\u5F53\u524D\u8FD0\u884C\u7684 CLI \u7248\u672C\uFF08\u65E0\u9700\u8054\u7F51\uFF09\n--check \u68C0\u67E5\u516C\u5171 npm \u7684 latest \u7248\u672C\uFF0C\u4E0D\u5B89\u88C5\n--json \u8F93\u51FA JSON\uFF0C\u4F9B Coding Agent \u6216\u811A\u672C\u8BFB\u53D6\n\n\u65E0\u9700\u767B\u5F55\u642D\u642D\u8D26\u53F7\uFF0C\u4E5F\u65E0\u9700\u8FDB\u5165\u642D\u5B50\u5DE5\u7A0B\u3002\nupdate \u66F4\u65B0\u5F53\u524D npm \u5168\u5C40\u5B89\u88C5\u7684 CLI\uFF0C\u4E0D\u4FEE\u6539\u642D\u5B50\u5DE5\u7A0B\u7684 Runtime \u4F9D\u8D56\u3002\n\u5DF2\u7ECF\u662F\u6700\u65B0\u7248\u6216\u5F53\u524D\u7248\u672C\u66F4\u9AD8\u65F6\u4E0D\u5B89\u88C5\u3001\u4E0D\u964D\u7EA7\u3002\n\u6E90\u7801\u3001npm link\u3001\u5C40\u90E8\u5B89\u88C5\u6216 npx \u8FD0\u884C\u65F6\uFF0C\u8BF7\u4F7F\u7528\u539F\u6765\u7684\u5B89\u88C5\u65B9\u5F0F\u66F4\u65B0\u3002\n\u65E7\u7248 CLI \u5C1A\u65E0 update \u547D\u4EE4\u65F6\uFF0C\u8FD0\u884C\uFF1A\\n ${MANUAL_UPDATE}`;\n\ninterface NpmOptions { cwd: string; signal?: AbortSignal; timeout: number }\ninterface UpdateOptions {\n version: string;\n packageRoot: string;\n signal?: AbortSignal;\n fetch?: typeof globalThis.fetch;\n runNpm?: (args: string[], options: NpmOptions) => Promise<{ stdout: string; stderr: string }>;\n}\n\n// SemVer precedence ignores build metadata; numeric identifiers compare numerically.\nfunction parseVersion(version: unknown): string[] {\n const numeric = \"(?:0|[1-9][0-9]*)\";\n const identifier = `(?:${numeric}|[0-9]*[A-Za-z-][0-9A-Za-z-]*)`;\n const pattern = new RegExp(`^(${numeric})\\\\.(${numeric})\\\\.(${numeric})(?:-(${identifier}(?:\\\\.${identifier})*))?(?:\\\\+[0-9A-Za-z-]+(?:\\\\.[0-9A-Za-z-]+)*)?$`, \"u\");\n const match = typeof version === \"string\" && version.length <= 256 ? pattern.exec(version) : null;\n if (!match || match[0] !== version) throw new Error(\"\u7248\u672C\u4FE1\u606F\u4E0D\u662F\u6709\u6548\u7684 SemVer \u7248\u672C\u53F7\u3002\");\n return [match[1]!, match[2]!, match[3]!, ...(match[4]?.split(\".\") ?? [])];\n}\n\nfunction compareVersions(left: string, right: string): number {\n const a = parseVersion(left);\n const b = parseVersion(right);\n for (let i = 0; i < 3; i++) {\n if (BigInt(a[i]!) !== BigInt(b[i]!)) return BigInt(a[i]!) > BigInt(b[i]!) ? 1 : -1;\n }\n if (a.length === 3 || b.length === 3) return a.length === b.length ? 0 : a.length === 3 ? 1 : -1;\n for (let i = 3; i < Math.max(a.length, b.length); i++) {\n const x = a[i];\n const y = b[i];\n if (x === y) continue;\n if (x === undefined || y === undefined) return x === undefined ? -1 : 1;\n const xn = /^[0-9]+$/u.test(x);\n const yn = /^[0-9]+$/u.test(y);\n if (xn && yn) return BigInt(x) > BigInt(y) ? 1 : -1;\n if (xn !== yn) return xn ? -1 : 1;\n return x > y ? 1 : -1;\n }\n return 0;\n}\n\nasync function latestVersion(options: UpdateOptions): Promise<string> {\n const timeout = AbortSignal.timeout(10_000);\n const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;\n try {\n const response = await (options.fetch ?? globalThis.fetch)(`${REGISTRY}${encodeURIComponent(PACKAGE)}/latest`, {\n signal, headers: { Accept: \"application/json\" }, redirect: \"error\",\n });\n if (!response.ok) throw new Error(`npm \u8FD4\u56DE HTTP ${response.status}`);\n const metadata = await response.json() as { name?: unknown; version?: unknown } | null;\n if (metadata?.name !== PACKAGE) throw new Error(\"npm \u8FD4\u56DE\u7684\u5305\u540D\u4E0D\u5339\u914D\");\n parseVersion(metadata.version);\n return metadata.version as string;\n } catch (cause) {\n if (options.signal?.aborted) throw new Error(\"\u64CD\u4F5C\u5DF2\u53D6\u6D88\u3002\");\n if (timeout.aborted) throw new Error(\"\u68C0\u67E5\u66F4\u65B0\u8D85\u65F6\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5\u3002\");\n throw new Error(`\u65E0\u6CD5\u68C0\u67E5 npm \u66F4\u65B0\uFF1A${cause instanceof Error ? cause.message : String(cause)}\u3002\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002`);\n }\n}\n\nasync function installUpdate(version: string, options: UpdateOptions): Promise<void> {\n const runNpm = options.runNpm ?? ((args, settings) => execute(\"npm\", args, { ...settings, encoding: \"utf8\", maxBuffer: 4 * 1024 * 1024 }));\n const settings = { cwd: homedir(), signal: options.signal, timeout: 10_000 };\n const { stdout } = await runNpm([\"prefix\", \"--global\"], settings);\n const prefix = stdout.trim();\n if (!isAbsolute(prefix) || /[\\r\\n]/u.test(prefix)) throw new Error(\"\u65E0\u6CD5\u786E\u5B9A npm \u5168\u5C40\u5B89\u88C5\u76EE\u5F55\u3002\");\n // The CLI supports macOS, where global packages live under prefix/lib/node_modules.\n const installedRoot = join(prefix, \"lib\", \"node_modules\", PACKAGE);\n let sameInstallation = false;\n try {\n sameInstallation = !(await lstat(installedRoot)).isSymbolicLink()\n && await realpath(installedRoot) === await realpath(options.packageRoot);\n } catch { /* Missing global package means this CLI came from another installation. */ }\n if (!sameInstallation) {\n throw new Error(\"\u5F53\u524D CLI \u4E0D\u662F\u8FD9\u4E2A npm \u73AF\u5883\u7684\u5168\u5C40\u5B89\u88C5\uFF0C\u4E0D\u80FD\u76F4\u63A5\u66F4\u65B0\u3002\u8BF7\u7528\u539F\u6765\u7684\u5B89\u88C5\u65B9\u5F0F\u66F4\u65B0\uFF1B\u82E5\u4F7F\u7528 nvm\uFF0C\u8BF7\u5148\u5207\u6362\u5230\u5B89\u88C5\u8BE5 CLI \u7684 Node.js \u73AF\u5883\u3002\");\n }\n try {\n await runNpm([\n \"install\", \"--global\", `${PACKAGE}@${version}`, \"--prefix\", prefix,\n `--registry=${REGISTRY}`, `--@my-life-buddies:registry=${REGISTRY}`, \"--engine-strict\", \"--no-audit\", \"--no-fund\",\n ], { ...settings, timeout: 180_000 });\n } catch (cause) {\n if (options.signal?.aborted) throw new Error(\"\u66F4\u65B0\u5DF2\u53D6\u6D88\uFF0C\u8BF7\u8FD0\u884C buddy-cli --version \u68C0\u67E5\u5B89\u88C5\u72B6\u6001\u3002\");\n const code = cause && typeof cause === \"object\" && \"code\" in cause ? String(cause.code) : \"unknown\";\n throw new Error(`npm \u5B89\u88C5\u672A\u5B8C\u6210\uFF08${code}\uFF09\u3002\u8BF7\u68C0\u67E5\u7F51\u7EDC\u548C\u5168\u5C40\u76EE\u5F55\u6743\u9650\uFF0C\u7136\u540E\u91CD\u8BD5\uFF1A${MANUAL_UPDATE}`);\n }\n const installed = JSON.parse(await readFile(join(installedRoot, \"package.json\"), \"utf8\"));\n if (installed.name !== PACKAGE || installed.version !== version) {\n throw new Error(`npm \u5DF2\u7ED3\u675F\uFF0C\u4F46\u672A\u786E\u8BA4\u5B89\u88C5\u5230 ${version}\u3002\u8BF7\u8FD0\u884C buddy-cli --version \u68C0\u67E5\uFF0C\u5FC5\u8981\u65F6\u91CD\u8BD5\uFF1A${MANUAL_UPDATE}`);\n }\n}\n\n/** Public CLI maintenance runs before any project or platform credential handling. */\nexport async function runSelfUpdateCommand(\n args: readonly string[],\n io: Pick<CliIO, \"write\" | \"writeError\">,\n options: UpdateOptions,\n): Promise<CliRunResult | undefined> {\n const versionOnly = args[0] === \"--version\" || args[0] === \"-v\";\n if (!versionOnly && args[0] !== \"update\") return undefined;\n const json = args.includes(\"--json\");\n const fail = (message: string, exitCode: number) => {\n if (json) io.write(JSON.stringify({ package: PACKAGE, currentVersion: options.version, error: message }));\n else io.writeError(`buddy-cli: ${message}`);\n return { exitCode };\n };\n const flags = args.slice(1);\n const allowed = versionOnly ? [\"--json\", \"--help\", \"-h\"] : [\"--check\", \"--json\", \"--help\", \"-h\"];\n if (flags.some(flag => !allowed.includes(flag)) || new Set(flags).size !== flags.length) {\n return fail(\"\u53C2\u6570\u65E0\u6548\uFF0C\u8BF7\u8FD0\u884C buddy-cli update --help \u67E5\u770B\u7528\u6CD5\u3002\", 2);\n }\n if (flags.includes(\"--help\") || flags.includes(\"-h\")) {\n if (json) io.write(JSON.stringify({ help: HELP }));\n else io.write(HELP);\n return { exitCode: 0 };\n }\n try {\n parseVersion(options.version);\n if (versionOnly) {\n io.write(json ? JSON.stringify({ package: PACKAGE, version: options.version }) : options.version);\n return { exitCode: 0 };\n }\n const latest = await latestVersion(options);\n const comparison = compareVersions(latest, options.version);\n const check = flags.includes(\"--check\");\n const status = comparison > 0 ? \"update_available\" : comparison < 0 ? \"ahead\" : \"up_to_date\";\n if (!check && comparison > 0) {\n if (!json) io.write(`\u6B63\u5728\u66F4\u65B0 CLI\uFF1A${options.version} \u2192 ${latest}\u2026`);\n await installUpdate(latest, options);\n }\n const updated = !check && comparison > 0;\n if (json) {\n io.write(JSON.stringify({\n package: PACKAGE, currentVersion: options.version, latestVersion: latest,\n updateAvailable: comparison > 0 && !updated, status: updated ? \"updated\" : status,\n ...(updated ? { installedVersion: latest } : {}),\n }));\n } else if (updated) io.write(`CLI \u5DF2\u66F4\u65B0\uFF1A${options.version} \u2192 ${latest}\u3002`);\n else if (comparison > 0) io.write(`\u53D1\u73B0\u65B0\u7248\u672C\uFF1A${options.version} \u2192 ${latest}\u3002\u8FD0\u884C buddy-cli update \u66F4\u65B0\u3002`);\n else if (comparison < 0) io.write(`\u5F53\u524D\u7248\u672C ${options.version} \u9AD8\u4E8E npm latest ${latest}\uFF0C\u65E0\u9700\u66F4\u65B0\u3002`);\n else io.write(`\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\uFF1A${options.version}\u3002`);\n return { exitCode: 0 };\n } catch (cause) {\n return fail(cause instanceof Error ? cause.message : String(cause), 1);\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["execFile", "promisify", "settings", "stdout", "promisify", "execFile", "choice", "require"]
7
7
  }