@springbrand/cli 0.1.0

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 (222) hide show
  1. package/README.md +167 -0
  2. package/dist/commands/auth.d.ts +4 -0
  3. package/dist/commands/auth.d.ts.map +1 -0
  4. package/dist/commands/auth.js +241 -0
  5. package/dist/commands/auth.js.map +1 -0
  6. package/dist/commands/check-version.d.ts +3 -0
  7. package/dist/commands/check-version.d.ts.map +1 -0
  8. package/dist/commands/check-version.js +112 -0
  9. package/dist/commands/check-version.js.map +1 -0
  10. package/dist/commands/config-claude.d.ts +4 -0
  11. package/dist/commands/config-claude.d.ts.map +1 -0
  12. package/dist/commands/config-claude.js +78 -0
  13. package/dist/commands/config-claude.js.map +1 -0
  14. package/dist/commands/connect.d.ts +41 -0
  15. package/dist/commands/connect.d.ts.map +1 -0
  16. package/dist/commands/connect.js +901 -0
  17. package/dist/commands/connect.js.map +1 -0
  18. package/dist/commands/doctor.d.ts +6 -0
  19. package/dist/commands/doctor.d.ts.map +1 -0
  20. package/dist/commands/doctor.js +124 -0
  21. package/dist/commands/doctor.js.map +1 -0
  22. package/dist/commands/upgrade.d.ts +9 -0
  23. package/dist/commands/upgrade.d.ts.map +1 -0
  24. package/dist/commands/upgrade.js +133 -0
  25. package/dist/commands/upgrade.js.map +1 -0
  26. package/dist/index.d.ts +4 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +15 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/lib/agent-detect.d.ts +33 -0
  31. package/dist/lib/agent-detect.d.ts.map +1 -0
  32. package/dist/lib/agent-detect.js +81 -0
  33. package/dist/lib/agent-detect.js.map +1 -0
  34. package/dist/lib/agent-launcher.d.ts +22 -0
  35. package/dist/lib/agent-launcher.d.ts.map +1 -0
  36. package/dist/lib/agent-launcher.js +67 -0
  37. package/dist/lib/agent-launcher.js.map +1 -0
  38. package/dist/lib/auth.d.ts +90 -0
  39. package/dist/lib/auth.d.ts.map +1 -0
  40. package/dist/lib/auth.js +327 -0
  41. package/dist/lib/auth.js.map +1 -0
  42. package/dist/lib/bundled-skill.d.ts +5 -0
  43. package/dist/lib/bundled-skill.d.ts.map +1 -0
  44. package/dist/lib/bundled-skill.js +13 -0
  45. package/dist/lib/bundled-skill.js.map +1 -0
  46. package/dist/lib/claude-config.d.ts +19 -0
  47. package/dist/lib/claude-config.d.ts.map +1 -0
  48. package/dist/lib/claude-config.js +202 -0
  49. package/dist/lib/claude-config.js.map +1 -0
  50. package/dist/lib/cli-install.d.ts +40 -0
  51. package/dist/lib/cli-install.d.ts.map +1 -0
  52. package/dist/lib/cli-install.js +42 -0
  53. package/dist/lib/cli-install.js.map +1 -0
  54. package/dist/lib/command-code-config.d.ts +5 -0
  55. package/dist/lib/command-code-config.d.ts.map +1 -0
  56. package/dist/lib/command-code-config.js +16 -0
  57. package/dist/lib/command-code-config.js.map +1 -0
  58. package/dist/lib/connect-all-auth.d.ts +21 -0
  59. package/dist/lib/connect-all-auth.d.ts.map +1 -0
  60. package/dist/lib/connect-all-auth.js +113 -0
  61. package/dist/lib/connect-all-auth.js.map +1 -0
  62. package/dist/lib/connect-all-summary.d.ts +10 -0
  63. package/dist/lib/connect-all-summary.d.ts.map +1 -0
  64. package/dist/lib/connect-all-summary.js +153 -0
  65. package/dist/lib/connect-all-summary.js.map +1 -0
  66. package/dist/lib/connect-all-uninstall.d.ts +7 -0
  67. package/dist/lib/connect-all-uninstall.d.ts.map +1 -0
  68. package/dist/lib/connect-all-uninstall.js +249 -0
  69. package/dist/lib/connect-all-uninstall.js.map +1 -0
  70. package/dist/lib/connect-all.d.ts +42 -0
  71. package/dist/lib/connect-all.d.ts.map +1 -0
  72. package/dist/lib/connect-all.js +438 -0
  73. package/dist/lib/connect-all.js.map +1 -0
  74. package/dist/lib/connect-auth.d.ts +7 -0
  75. package/dist/lib/connect-auth.d.ts.map +1 -0
  76. package/dist/lib/connect-auth.js +50 -0
  77. package/dist/lib/connect-auth.js.map +1 -0
  78. package/dist/lib/connect-clients.d.ts +108 -0
  79. package/dist/lib/connect-clients.d.ts.map +1 -0
  80. package/dist/lib/connect-clients.js +358 -0
  81. package/dist/lib/connect-clients.js.map +1 -0
  82. package/dist/lib/connect-fallback.d.ts +27 -0
  83. package/dist/lib/connect-fallback.d.ts.map +1 -0
  84. package/dist/lib/connect-fallback.js +166 -0
  85. package/dist/lib/connect-fallback.js.map +1 -0
  86. package/dist/lib/connect-picker.d.ts +19 -0
  87. package/dist/lib/connect-picker.d.ts.map +1 -0
  88. package/dist/lib/connect-picker.js +155 -0
  89. package/dist/lib/connect-picker.js.map +1 -0
  90. package/dist/lib/connect-preflight.d.ts +17 -0
  91. package/dist/lib/connect-preflight.d.ts.map +1 -0
  92. package/dist/lib/connect-preflight.js +81 -0
  93. package/dist/lib/connect-preflight.js.map +1 -0
  94. package/dist/lib/connect-runtime.d.ts +109 -0
  95. package/dist/lib/connect-runtime.d.ts.map +1 -0
  96. package/dist/lib/connect-runtime.js +360 -0
  97. package/dist/lib/connect-runtime.js.map +1 -0
  98. package/dist/lib/constants.d.ts +23 -0
  99. package/dist/lib/constants.d.ts.map +1 -0
  100. package/dist/lib/constants.js +87 -0
  101. package/dist/lib/constants.js.map +1 -0
  102. package/dist/lib/cursor-config.d.ts +16 -0
  103. package/dist/lib/cursor-config.d.ts.map +1 -0
  104. package/dist/lib/cursor-config.js +34 -0
  105. package/dist/lib/cursor-config.js.map +1 -0
  106. package/dist/lib/doctor-checks.d.ts +21 -0
  107. package/dist/lib/doctor-checks.d.ts.map +1 -0
  108. package/dist/lib/doctor-checks.js +312 -0
  109. package/dist/lib/doctor-checks.js.map +1 -0
  110. package/dist/lib/doctor-repairs.d.ts +11 -0
  111. package/dist/lib/doctor-repairs.d.ts.map +1 -0
  112. package/dist/lib/doctor-repairs.js +130 -0
  113. package/dist/lib/doctor-repairs.js.map +1 -0
  114. package/dist/lib/doctor-report.d.ts +195 -0
  115. package/dist/lib/doctor-report.d.ts.map +1 -0
  116. package/dist/lib/doctor-report.js +102 -0
  117. package/dist/lib/doctor-report.js.map +1 -0
  118. package/dist/lib/doctor-telemetry.d.ts +9 -0
  119. package/dist/lib/doctor-telemetry.d.ts.map +1 -0
  120. package/dist/lib/doctor-telemetry.js +63 -0
  121. package/dist/lib/doctor-telemetry.js.map +1 -0
  122. package/dist/lib/harness-detect.d.ts +33 -0
  123. package/dist/lib/harness-detect.d.ts.map +1 -0
  124. package/dist/lib/harness-detect.js +70 -0
  125. package/dist/lib/harness-detect.js.map +1 -0
  126. package/dist/lib/harness-spec.d.ts +285 -0
  127. package/dist/lib/harness-spec.d.ts.map +1 -0
  128. package/dist/lib/harness-spec.js +268 -0
  129. package/dist/lib/harness-spec.js.map +1 -0
  130. package/dist/lib/harness.d.ts +27 -0
  131. package/dist/lib/harness.d.ts.map +1 -0
  132. package/dist/lib/harness.js +125 -0
  133. package/dist/lib/harness.js.map +1 -0
  134. package/dist/lib/hermes-config.d.ts +22 -0
  135. package/dist/lib/hermes-config.d.ts.map +1 -0
  136. package/dist/lib/hermes-config.js +76 -0
  137. package/dist/lib/hermes-config.js.map +1 -0
  138. package/dist/lib/hermes-env.d.ts +19 -0
  139. package/dist/lib/hermes-env.d.ts.map +1 -0
  140. package/dist/lib/hermes-env.js +169 -0
  141. package/dist/lib/hermes-env.js.map +1 -0
  142. package/dist/lib/hermes-plugin.d.ts +40 -0
  143. package/dist/lib/hermes-plugin.d.ts.map +1 -0
  144. package/dist/lib/hermes-plugin.js +168 -0
  145. package/dist/lib/hermes-plugin.js.map +1 -0
  146. package/dist/lib/install-root.d.ts +18 -0
  147. package/dist/lib/install-root.d.ts.map +1 -0
  148. package/dist/lib/install-root.js +55 -0
  149. package/dist/lib/install-root.js.map +1 -0
  150. package/dist/lib/mcp-config.d.ts +36 -0
  151. package/dist/lib/mcp-config.d.ts.map +1 -0
  152. package/dist/lib/mcp-config.js +90 -0
  153. package/dist/lib/mcp-config.js.map +1 -0
  154. package/dist/lib/mcp-endpoint.d.ts +16 -0
  155. package/dist/lib/mcp-endpoint.d.ts.map +1 -0
  156. package/dist/lib/mcp-endpoint.js +41 -0
  157. package/dist/lib/mcp-endpoint.js.map +1 -0
  158. package/dist/lib/mcp-json-config.d.ts +43 -0
  159. package/dist/lib/mcp-json-config.d.ts.map +1 -0
  160. package/dist/lib/mcp-json-config.js +164 -0
  161. package/dist/lib/mcp-json-config.js.map +1 -0
  162. package/dist/lib/notice.d.ts +13 -0
  163. package/dist/lib/notice.d.ts.map +1 -0
  164. package/dist/lib/notice.js +73 -0
  165. package/dist/lib/notice.js.map +1 -0
  166. package/dist/lib/omp-config.d.ts +18 -0
  167. package/dist/lib/omp-config.d.ts.map +1 -0
  168. package/dist/lib/omp-config.js +73 -0
  169. package/dist/lib/omp-config.js.map +1 -0
  170. package/dist/lib/output.d.ts +22 -0
  171. package/dist/lib/output.d.ts.map +1 -0
  172. package/dist/lib/output.js +92 -0
  173. package/dist/lib/output.js.map +1 -0
  174. package/dist/lib/pi-config.d.ts +27 -0
  175. package/dist/lib/pi-config.d.ts.map +1 -0
  176. package/dist/lib/pi-config.js +113 -0
  177. package/dist/lib/pi-config.js.map +1 -0
  178. package/dist/lib/registration-detect.d.ts +28 -0
  179. package/dist/lib/registration-detect.d.ts.map +1 -0
  180. package/dist/lib/registration-detect.js +563 -0
  181. package/dist/lib/registration-detect.js.map +1 -0
  182. package/dist/lib/setup-telemetry.d.ts +273 -0
  183. package/dist/lib/setup-telemetry.d.ts.map +1 -0
  184. package/dist/lib/setup-telemetry.js +309 -0
  185. package/dist/lib/setup-telemetry.js.map +1 -0
  186. package/dist/lib/signals.d.ts +14 -0
  187. package/dist/lib/signals.d.ts.map +1 -0
  188. package/dist/lib/signals.js +29 -0
  189. package/dist/lib/signals.js.map +1 -0
  190. package/dist/lib/skill-install.d.ts +10 -0
  191. package/dist/lib/skill-install.d.ts.map +1 -0
  192. package/dist/lib/skill-install.js +94 -0
  193. package/dist/lib/skill-install.js.map +1 -0
  194. package/dist/lib/skill-paths.d.ts +7 -0
  195. package/dist/lib/skill-paths.d.ts.map +1 -0
  196. package/dist/lib/skill-paths.js +37 -0
  197. package/dist/lib/skill-paths.js.map +1 -0
  198. package/dist/lib/skill-vendor.d.ts +20 -0
  199. package/dist/lib/skill-vendor.d.ts.map +1 -0
  200. package/dist/lib/skill-vendor.js +215 -0
  201. package/dist/lib/skill-vendor.js.map +1 -0
  202. package/dist/lib/skill.d.ts +14 -0
  203. package/dist/lib/skill.d.ts.map +1 -0
  204. package/dist/lib/skill.js +87 -0
  205. package/dist/lib/skill.js.map +1 -0
  206. package/dist/lib/verify.d.ts +35 -0
  207. package/dist/lib/verify.d.ts.map +1 -0
  208. package/dist/lib/verify.js +169 -0
  209. package/dist/lib/verify.js.map +1 -0
  210. package/dist/program.d.ts +8 -0
  211. package/dist/program.d.ts.map +1 -0
  212. package/dist/program.js +54 -0
  213. package/dist/program.js.map +1 -0
  214. package/package.json +55 -0
  215. package/skill/springbrand-action-api/SKILL.md +49 -0
  216. package/skill/springbrand-action-api/references/action-aliases.md +156 -0
  217. package/skill/springbrand-action-api/references/action-discovery.md +95 -0
  218. package/skill/springbrand-connector/SKILL.md +49 -0
  219. package/skill/springbrand-gtm/SKILL.md +34 -0
  220. package/skill/springbrand-platform/SKILL.md +55 -0
  221. package/skill/springbrand-platform/references/plugin-discovery.md +94 -0
  222. package/skill/use-springbrand/SKILL.md +70 -0
@@ -0,0 +1,273 @@
1
+ /** 复刻自 tiny-fish CLI 编译产物:setup-telemetry.d.ts + setup-telemetry.impl.js */
2
+ import { z } from 'zod';
3
+ import { AuthMode, Registered } from './harness-detect.js';
4
+ /**
5
+ * `SPRINGBRAND_NO_TELEMETRY` suppresses ALL CLI-emitted network analytics
6
+ * (setup_completed, connect-event, update check). Any value except `0`/`false`
7
+ * opts out — a privacy switch must not fail closed on `true`.
8
+ */
9
+ export declare function telemetryDisabled(): boolean;
10
+ /**
11
+ * The one POST to `/api/cli/connect-event`, and the only place its security-relevant
12
+ * properties live: `redirect: "error"`, the 2s cap, trusted-origin notice capture. Never
13
+ * throws. `endpoint` is the caller's — connect and setup target the `--url` being installed
14
+ * against, upgrade has none and uses BASE_URL.
15
+ *
16
+ * Carries no credential: install events are anonymous, and the endpoint reads no
17
+ * Authorization. Attribution rides `attempt_id` in the body instead.
18
+ */
19
+ export declare function postConnectEvent(options: {
20
+ endpoint: string;
21
+ body: string;
22
+ /** 2 where a lost event costs a headline metric — stale keep-alive sockets eat post-install POSTs. */
23
+ attempts: number;
24
+ label: string;
25
+ }): Promise<void>;
26
+ declare const harnessResultSchema: z.ZodObject<{
27
+ harness: z.ZodEnum<{
28
+ openclaw: "openclaw";
29
+ omp: "omp";
30
+ grok: "grok";
31
+ cursor: "cursor";
32
+ codex: "codex";
33
+ hermes: "hermes";
34
+ "command-code": "command-code";
35
+ opencode: "opencode";
36
+ pi: "pi";
37
+ "claude-code": "claude-code";
38
+ }>;
39
+ detected: z.ZodBoolean;
40
+ installed: z.ZodBoolean;
41
+ verify_depth: z.ZodNullable<z.ZodEnum<{
42
+ health: "health";
43
+ "health+auth": "health+auth";
44
+ }>>;
45
+ verify_ok: z.ZodNullable<z.ZodBoolean>;
46
+ }, z.core.$strip>;
47
+ /** First act of a `--all` run; everything upstream of it stays invisible. */
48
+ export declare function sendSetupStarted(mcpUrl: string, attemptId?: string): Promise<void>;
49
+ /** Terminal state for a run the key gate stopped; fires instead of setup_started. */
50
+ export declare function sendSetupBlocked(mcpUrl: string, detail: SetupBlockedDetail): Promise<void>;
51
+ export declare const setupCompletedPayloadSchema: z.ZodObject<{
52
+ harnesses: z.ZodArray<z.ZodObject<{
53
+ harness: z.ZodEnum<{
54
+ openclaw: "openclaw";
55
+ omp: "omp";
56
+ grok: "grok";
57
+ cursor: "cursor";
58
+ codex: "codex";
59
+ hermes: "hermes";
60
+ "command-code": "command-code";
61
+ opencode: "opencode";
62
+ pi: "pi";
63
+ "claude-code": "claude-code";
64
+ }>;
65
+ detected: z.ZodBoolean;
66
+ installed: z.ZodBoolean;
67
+ verify_depth: z.ZodNullable<z.ZodEnum<{
68
+ health: "health";
69
+ "health+auth": "health+auth";
70
+ }>>;
71
+ verify_ok: z.ZodNullable<z.ZodBoolean>;
72
+ }, z.core.$strip>>;
73
+ cli_version: z.ZodString;
74
+ mode: z.ZodOptional<z.ZodEnum<{
75
+ all: "all";
76
+ pick: "pick";
77
+ pick_numeric: "pick_numeric";
78
+ }>>;
79
+ connect_attempt_id: z.ZodOptional<z.ZodUUID>;
80
+ }, z.core.$strip>;
81
+ /** `toVersion` is null when the run was interrupted or the installed version could not be read. */
82
+ export declare function sendUpgradeCompleted(fromVersion: string, toVersion: string | null, outcome: UpgradeOutcome, scope: UpgradeScope): Promise<void>;
83
+ export declare function sendSetupCompleted(mcpUrl: string, harnesses: HarnessResult[], mode?: SetupMode, attemptId?: string): Promise<void>;
84
+ export declare const DOCTOR_ERROR_CLASSES: readonly ["command_not_found", "timeout", "spawn_error", "nonzero_exit", "unexpected_error"];
85
+ /** Derived, not read: the catch is generic, so only the code is trustworthy. */
86
+ export declare function doctorErrorClass(error: unknown): DoctorErrorClass;
87
+ declare const doctorCompletedPayloadSchema: z.ZodObject<{
88
+ outcome: z.ZodLiteral<"completed">;
89
+ schema_version: z.ZodInt;
90
+ cli_version: z.ZodString;
91
+ ok_harnesses: z.ZodBoolean;
92
+ ok_cli: z.ZodBoolean;
93
+ checks_pass: z.ZodInt;
94
+ checks_fail: z.ZodInt;
95
+ checks_warn: z.ZodInt;
96
+ checks_skip: z.ZodInt;
97
+ repairs_offered: z.ZodInt;
98
+ repair_actions: z.ZodArray<z.ZodEnum<{
99
+ connect: "connect";
100
+ "auth-login": "auth-login";
101
+ }>>;
102
+ repairs_attempted: z.ZodInt;
103
+ repairs_succeeded: z.ZodInt;
104
+ fix_mode: z.ZodEnum<{
105
+ none: "none";
106
+ fix: "fix";
107
+ fix_yes: "fix_yes";
108
+ }>;
109
+ harness_scope: z.ZodEnum<{
110
+ [x: string]: string;
111
+ }>;
112
+ is_human_initiated: z.ZodBoolean;
113
+ failed_check_ids: z.ZodArray<z.ZodString>;
114
+ failed_harnesses: z.ZodArray<z.ZodEnum<{
115
+ openclaw: "openclaw";
116
+ omp: "omp";
117
+ grok: "grok";
118
+ cursor: "cursor";
119
+ codex: "codex";
120
+ hermes: "hermes";
121
+ "command-code": "command-code";
122
+ opencode: "opencode";
123
+ pi: "pi";
124
+ "claude-code": "claude-code";
125
+ }>>;
126
+ harnesses: z.ZodArray<z.ZodObject<{
127
+ harness: z.ZodEnum<{
128
+ openclaw: "openclaw";
129
+ omp: "omp";
130
+ grok: "grok";
131
+ cursor: "cursor";
132
+ codex: "codex";
133
+ hermes: "hermes";
134
+ "command-code": "command-code";
135
+ opencode: "opencode";
136
+ pi: "pi";
137
+ "claude-code": "claude-code";
138
+ }>;
139
+ detected: z.ZodBoolean;
140
+ registered: z.ZodEnum<typeof Registered>;
141
+ auth_mode: z.ZodEnum<typeof AuthMode>;
142
+ proves_harness_reach: z.ZodBoolean;
143
+ }, z.core.$strip>>;
144
+ duration_ms: z.ZodInt;
145
+ hermes_plugin_version: z.ZodOptional<z.ZodString>;
146
+ hermes_plugin_expected_version: z.ZodOptional<z.ZodString>;
147
+ }, z.core.$strip>;
148
+ declare const doctorCouldNotRunPayloadSchema: z.ZodObject<{
149
+ outcome: z.ZodLiteral<"could_not_run">;
150
+ error_class: z.ZodEnum<{
151
+ timeout: "timeout";
152
+ command_not_found: "command_not_found";
153
+ spawn_error: "spawn_error";
154
+ nonzero_exit: "nonzero_exit";
155
+ unexpected_error: "unexpected_error";
156
+ }>;
157
+ schema_version: z.ZodInt;
158
+ cli_version: z.ZodString;
159
+ fix_mode: z.ZodEnum<{
160
+ none: "none";
161
+ fix: "fix";
162
+ fix_yes: "fix_yes";
163
+ }>;
164
+ harness_scope: z.ZodEnum<{
165
+ [x: string]: string;
166
+ }>;
167
+ is_human_initiated: z.ZodBoolean;
168
+ duration_ms: z.ZodInt;
169
+ }, z.core.$strip>;
170
+ declare const doctorPayloadSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
171
+ outcome: z.ZodLiteral<"completed">;
172
+ schema_version: z.ZodInt;
173
+ cli_version: z.ZodString;
174
+ ok_harnesses: z.ZodBoolean;
175
+ ok_cli: z.ZodBoolean;
176
+ checks_pass: z.ZodInt;
177
+ checks_fail: z.ZodInt;
178
+ checks_warn: z.ZodInt;
179
+ checks_skip: z.ZodInt;
180
+ repairs_offered: z.ZodInt;
181
+ repair_actions: z.ZodArray<z.ZodEnum<{
182
+ connect: "connect";
183
+ "auth-login": "auth-login";
184
+ }>>;
185
+ repairs_attempted: z.ZodInt;
186
+ repairs_succeeded: z.ZodInt;
187
+ fix_mode: z.ZodEnum<{
188
+ none: "none";
189
+ fix: "fix";
190
+ fix_yes: "fix_yes";
191
+ }>;
192
+ harness_scope: z.ZodEnum<{
193
+ [x: string]: string;
194
+ }>;
195
+ is_human_initiated: z.ZodBoolean;
196
+ failed_check_ids: z.ZodArray<z.ZodString>;
197
+ failed_harnesses: z.ZodArray<z.ZodEnum<{
198
+ openclaw: "openclaw";
199
+ omp: "omp";
200
+ grok: "grok";
201
+ cursor: "cursor";
202
+ codex: "codex";
203
+ hermes: "hermes";
204
+ "command-code": "command-code";
205
+ opencode: "opencode";
206
+ pi: "pi";
207
+ "claude-code": "claude-code";
208
+ }>>;
209
+ harnesses: z.ZodArray<z.ZodObject<{
210
+ harness: z.ZodEnum<{
211
+ openclaw: "openclaw";
212
+ omp: "omp";
213
+ grok: "grok";
214
+ cursor: "cursor";
215
+ codex: "codex";
216
+ hermes: "hermes";
217
+ "command-code": "command-code";
218
+ opencode: "opencode";
219
+ pi: "pi";
220
+ "claude-code": "claude-code";
221
+ }>;
222
+ detected: z.ZodBoolean;
223
+ registered: z.ZodEnum<typeof Registered>;
224
+ auth_mode: z.ZodEnum<typeof AuthMode>;
225
+ proves_harness_reach: z.ZodBoolean;
226
+ }, z.core.$strip>>;
227
+ duration_ms: z.ZodInt;
228
+ hermes_plugin_version: z.ZodOptional<z.ZodString>;
229
+ hermes_plugin_expected_version: z.ZodOptional<z.ZodString>;
230
+ }, z.core.$strip>, z.ZodObject<{
231
+ outcome: z.ZodLiteral<"could_not_run">;
232
+ error_class: z.ZodEnum<{
233
+ timeout: "timeout";
234
+ command_not_found: "command_not_found";
235
+ spawn_error: "spawn_error";
236
+ nonzero_exit: "nonzero_exit";
237
+ unexpected_error: "unexpected_error";
238
+ }>;
239
+ schema_version: z.ZodInt;
240
+ cli_version: z.ZodString;
241
+ fix_mode: z.ZodEnum<{
242
+ none: "none";
243
+ fix: "fix";
244
+ fix_yes: "fix_yes";
245
+ }>;
246
+ harness_scope: z.ZodEnum<{
247
+ [x: string]: string;
248
+ }>;
249
+ is_human_initiated: z.ZodBoolean;
250
+ duration_ms: z.ZodInt;
251
+ }, z.core.$strip>], "outcome">;
252
+ export declare function sendDoctorCompleted(mcpUrl: string, payload: DoctorPayload): Promise<void>;
253
+ export type SetupBlockReason = 'key_rejected' | 'key_malformed' | 'key_environment_mismatch' | 'key_unreadable';
254
+ export type SetupBlockedMode = 'all' | 'pick' | 'single';
255
+ export interface SetupBlockedDetail {
256
+ blockReason: SetupBlockReason;
257
+ keySource: 'env' | 'config' | 'explicit';
258
+ /** Only a server answer has one; a malformed key never reaches the API. */
259
+ status?: number;
260
+ mode: SetupBlockedMode;
261
+ attemptId?: string;
262
+ }
263
+ type SetupCompletedPayload = z.infer<typeof setupCompletedPayloadSchema>;
264
+ export type HarnessResult = z.infer<typeof harnessResultSchema>;
265
+ export type SetupMode = NonNullable<SetupCompletedPayload['mode']>;
266
+ export type UpgradeOutcome = 'updated' | 'failed' | 'interrupted';
267
+ export type UpgradeScope = 'both' | 'cli' | 'skill';
268
+ export type DoctorErrorClass = (typeof DOCTOR_ERROR_CLASSES)[number];
269
+ export type DoctorCompletedPayload = z.infer<typeof doctorCompletedPayloadSchema>;
270
+ export type DoctorCouldNotRunPayload = z.infer<typeof doctorCouldNotRunPayloadSchema>;
271
+ export type DoctorPayload = z.infer<typeof doctorPayloadSchema>;
272
+ export {};
273
+ //# sourceMappingURL=setup-telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-telemetry.d.ts","sourceRoot":"","sources":["../../src/lib/setup-telemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,309 @@
1
+ /** 复刻自 tiny-fish CLI 编译产物:setup-telemetry.d.ts + setup-telemetry.impl.js */
2
+ import { z } from 'zod';
3
+ import { BASE_URL, CLI_INVOCATION_ID, CLI_VERSION } from './constants.js';
4
+ import { ALL_HARNESSES, AuthMode, Registered } from './harness-detect.js';
5
+ import { detectHarness, detectRuntimeEnv } from './harness.js';
6
+ import { captureNotice } from './notice.js';
7
+ import { errLine } from './output.js';
8
+ const CONNECT_EVENT_TIMEOUT_MS = 2_000;
9
+ /**
10
+ * `SPRINGBRAND_NO_TELEMETRY` suppresses ALL CLI-emitted network analytics
11
+ * (setup_completed, connect-event, update check). Any value except `0`/`false`
12
+ * opts out — a privacy switch must not fail closed on `true`.
13
+ */
14
+ export function telemetryDisabled() {
15
+ const value = (process.env['SPRINGBRAND_NO_TELEMETRY'] ?? '').trim().toLowerCase();
16
+ return value !== '' && value !== '0' && value !== 'false';
17
+ }
18
+ // Only these origins may have their response headers read as a SpringBrand advisory.
19
+ // `--url` accepts any http(s) URL, so a user-supplied host must not print its own text.
20
+ const TRUSTED_TELEMETRY_HOST_SUFFIXES = ['.springbrand.ai', '.springbrand.io'];
21
+ const TRUSTED_TELEMETRY_LOOPBACK_HOSTS = ['localhost', '127.0.0.1', '[::1]'];
22
+ function isTrustedTelemetryOrigin(endpoint) {
23
+ let url;
24
+ try {
25
+ url = new URL(endpoint);
26
+ }
27
+ catch {
28
+ return false;
29
+ }
30
+ const host = url.hostname.toLowerCase();
31
+ // Loopback may use http for local dev; every other trusted origin must be https.
32
+ if (TRUSTED_TELEMETRY_LOOPBACK_HOSTS.includes(host))
33
+ return true;
34
+ if (url.protocol !== 'https:')
35
+ return false;
36
+ return TRUSTED_TELEMETRY_HOST_SUFFIXES.some((suffix) => host === suffix.slice(1) || host.endsWith(suffix));
37
+ }
38
+ /**
39
+ * The one POST to `/api/cli/connect-event`, and the only place its security-relevant
40
+ * properties live: `redirect: "error"`, the 2s cap, trusted-origin notice capture. Never
41
+ * throws. `endpoint` is the caller's — connect and setup target the `--url` being installed
42
+ * against, upgrade has none and uses BASE_URL.
43
+ *
44
+ * Carries no credential: install events are anonymous, and the endpoint reads no
45
+ * Authorization. Attribution rides `attempt_id` in the body instead.
46
+ */
47
+ export async function postConnectEvent(options) {
48
+ const { endpoint, body, attempts, label } = options;
49
+ if (telemetryDisabled())
50
+ return;
51
+ // Swallows its own write failure so callers can treat this function as total.
52
+ const debug = (line) => {
53
+ if (!process.env['SPRINGBRAND_DEBUG'])
54
+ return;
55
+ try {
56
+ errLine(`${label} telemetry ${line}`);
57
+ }
58
+ catch {
59
+ // no stderr to report to
60
+ }
61
+ };
62
+ const trusted = isTrustedTelemetryOrigin(endpoint);
63
+ for (let attempt = 0; attempt < attempts; attempt++) {
64
+ try {
65
+ const response = await fetch(endpoint, {
66
+ method: 'POST',
67
+ headers: { 'content-type': 'application/json' },
68
+ body,
69
+ redirect: 'error',
70
+ signal: AbortSignal.timeout(CONNECT_EVENT_TIMEOUT_MS),
71
+ });
72
+ // Before the ok branch so a rejected event still yields a notice; gated on origin so a
73
+ // `--url` host cannot print its own text as a SpringBrand advisory.
74
+ if (trusted)
75
+ captureNotice(response.headers);
76
+ if (response.ok)
77
+ return;
78
+ // 4xx will reject the same body again (schema mismatch, e.g. new stages on an old server).
79
+ const willRetry = response.status >= 500 && attempt < attempts - 1;
80
+ if (!willRetry)
81
+ debug(`rejected: HTTP ${response.status}`);
82
+ if (response.status < 500)
83
+ return;
84
+ }
85
+ catch (e) {
86
+ debug(`failed: ${e instanceof Error ? e.message : String(e)}`);
87
+ }
88
+ }
89
+ }
90
+ const harnessResultSchema = z.object({
91
+ harness: z.enum(ALL_HARNESSES),
92
+ detected: z.boolean(),
93
+ installed: z.boolean(),
94
+ verify_depth: z.enum(['health', 'health+auth']).nullable(),
95
+ verify_ok: z.boolean().nullable(),
96
+ });
97
+ /** First act of a `--all` run; everything upstream of it stays invisible. */
98
+ export async function sendSetupStarted(mcpUrl, attemptId) {
99
+ if (telemetryDisabled())
100
+ return;
101
+ // Route 400s a bad id and postConnectEvent never retries 4xx, losing the whole event.
102
+ const stamped = attemptId && z.uuid().safeParse(attemptId).success ? attemptId : undefined;
103
+ await postConnectEvent({
104
+ endpoint: new URL('/api/cli/connect-event', mcpUrl).toString(),
105
+ body: JSON.stringify({
106
+ event: 'setup_started',
107
+ cli_version: CLI_VERSION,
108
+ runtime_platform: process.platform,
109
+ ...(stamped ? { connect_attempt_id: stamped } : {}),
110
+ cli_invocation_id: CLI_INVOCATION_ID,
111
+ runtime_env: detectRuntimeEnv(),
112
+ }),
113
+ attempts: 1,
114
+ label: 'setup',
115
+ });
116
+ }
117
+ /** Terminal state for a run the key gate stopped; fires instead of setup_started. */
118
+ export async function sendSetupBlocked(mcpUrl, detail) {
119
+ if (telemetryDisabled())
120
+ return;
121
+ const stamped = detail.attemptId && z.uuid().safeParse(detail.attemptId).success ? detail.attemptId : undefined;
122
+ await postConnectEvent({
123
+ endpoint: new URL('/api/cli/connect-event', mcpUrl).toString(),
124
+ body: JSON.stringify({
125
+ event: 'setup_blocked',
126
+ cli_version: CLI_VERSION,
127
+ block_reason: detail.blockReason,
128
+ key_source: detail.keySource,
129
+ ...(detail.status !== undefined ? { status: detail.status } : {}),
130
+ mode: detail.mode,
131
+ runtime_platform: process.platform,
132
+ ...(stamped ? { connect_attempt_id: stamped } : {}),
133
+ cli_invocation_id: CLI_INVOCATION_ID,
134
+ runtime_env: detectRuntimeEnv(),
135
+ }),
136
+ attempts: 1,
137
+ label: 'setup',
138
+ });
139
+ }
140
+ export const setupCompletedPayloadSchema = z.object({
141
+ harnesses: z
142
+ .array(harnessResultSchema)
143
+ .length(ALL_HARNESSES.length)
144
+ .refine((results) => new Set(results.map((r) => r.harness)).size === ALL_HARNESSES.length, {
145
+ message: 'expected one result per harness',
146
+ }),
147
+ cli_version: z.string(),
148
+ // Segments picker runs from --all runs; the server field shipped first.
149
+ mode: z.enum(['all', 'pick', 'pick_numeric']).optional(),
150
+ connect_attempt_id: z.uuid().optional(),
151
+ });
152
+ /** `toVersion` is null when the run was interrupted or the installed version could not be read. */
153
+ export async function sendUpgradeCompleted(fromVersion, toVersion, outcome, scope) {
154
+ await postConnectEvent({
155
+ endpoint: new URL('/api/cli/connect-event', BASE_URL).toString(),
156
+ body: JSON.stringify({
157
+ event: 'upgrade_completed',
158
+ from_version: fromVersion,
159
+ to_version: toVersion,
160
+ outcome,
161
+ scope,
162
+ cli_invocation_id: CLI_INVOCATION_ID,
163
+ runtime_env: detectRuntimeEnv(),
164
+ }),
165
+ attempts: 1,
166
+ label: 'upgrade',
167
+ });
168
+ }
169
+ export async function sendSetupCompleted(mcpUrl, harnesses, mode, attemptId) {
170
+ // Ahead of the parse so an opt-out run prints no telemetry debug.
171
+ if (telemetryDisabled())
172
+ return;
173
+ let endpoint;
174
+ let body;
175
+ try {
176
+ // Parse inside try — schema violation must not crash finished setup.
177
+ const payload = setupCompletedPayloadSchema.parse({
178
+ harnesses,
179
+ cli_version: CLI_VERSION,
180
+ ...(mode ? { mode } : {}),
181
+ // Guarded here, not only at the route: a parse throw drops the whole event, not one field.
182
+ ...(attemptId && z.uuid().safeParse(attemptId).success
183
+ ? { connect_attempt_id: attemptId }
184
+ : {}),
185
+ });
186
+ endpoint = new URL('/api/cli/connect-event', mcpUrl).toString();
187
+ body = JSON.stringify({
188
+ event: 'setup_completed',
189
+ ...payload,
190
+ cli_invocation_id: CLI_INVOCATION_ID,
191
+ runtime_env: detectRuntimeEnv(),
192
+ });
193
+ }
194
+ catch (e) {
195
+ if (process.env['SPRINGBRAND_DEBUG']) {
196
+ errLine(`setup telemetry skipped: ${e instanceof Error ? e.message : String(e)}`);
197
+ }
198
+ return;
199
+ }
200
+ await postConnectEvent({ endpoint, body, attempts: 2, label: 'setup' });
201
+ }
202
+ const DOCTOR_HARNESS_SCOPES = ['all', ...ALL_HARNESSES];
203
+ // Mirrors the route's cap; drops what the route would 400 un-retried.
204
+ const versionSchema = z
205
+ .string()
206
+ .max(32)
207
+ .regex(/^[\x20-\x7E]*$/);
208
+ // Ids, harnesses and auth modes are authored here; `detail` never leaves.
209
+ // The plugin version is machine-supplied, sanitized before reaching this schema.
210
+ // Caps mirror the route's schema: a payload the server would 400 is dropped here instead,
211
+ // because postConnectEvent never retries a 4xx and the event would vanish silently.
212
+ // Same spellings as cli_connect_stage.failure_reason; the type pins them.
213
+ export const DOCTOR_ERROR_CLASSES = [
214
+ 'command_not_found',
215
+ 'timeout',
216
+ 'spawn_error',
217
+ 'nonzero_exit',
218
+ 'unexpected_error',
219
+ ];
220
+ /** Derived, not read: the catch is generic, so only the code is trustworthy. */
221
+ export function doctorErrorClass(error) {
222
+ const code = error?.code;
223
+ if (code === 'ENOENT')
224
+ return 'command_not_found';
225
+ if (code === 'ETIMEDOUT')
226
+ return 'timeout';
227
+ return code ? 'spawn_error' : 'unexpected_error';
228
+ }
229
+ const doctorCompletedPayloadSchema = z.object({
230
+ outcome: z.literal('completed'),
231
+ schema_version: z.int().positive(),
232
+ cli_version: z.string().max(32),
233
+ ok_harnesses: z.boolean(),
234
+ ok_cli: z.boolean(),
235
+ checks_pass: z.int().nonnegative().max(256),
236
+ checks_fail: z.int().nonnegative().max(256),
237
+ checks_warn: z.int().nonnegative().max(256),
238
+ checks_skip: z.int().nonnegative().max(256),
239
+ /** Offered by the pre-repair report; the verdicts describe the machine after it. */
240
+ repairs_offered: z.int().nonnegative().max(256),
241
+ repair_actions: z.array(z.enum(['connect', 'auth-login'])).max(8),
242
+ repairs_attempted: z.int().nonnegative().max(256),
243
+ repairs_succeeded: z.int().nonnegative().max(256),
244
+ fix_mode: z.enum(['none', 'fix', 'fix_yes']),
245
+ /** "all" unless --harness scoped the run; the counts above cover only that scope. */
246
+ harness_scope: z.enum(DOCTOR_HARNESS_SCOPES),
247
+ is_human_initiated: z.boolean(),
248
+ /** Flat and distinct: PostHog cannot group by array elements of an object. */
249
+ failed_check_ids: z.array(z.string().regex(/^[a-z0-9-]{1,64}$/)).max(32),
250
+ failed_harnesses: z.array(z.enum(ALL_HARNESSES)).max(16),
251
+ harnesses: z
252
+ .array(z.object({
253
+ harness: z.enum(ALL_HARNESSES),
254
+ detected: z.boolean(),
255
+ registered: z.enum(Registered),
256
+ auth_mode: z.enum(AuthMode),
257
+ proves_harness_reach: z.boolean(),
258
+ }))
259
+ .max(16),
260
+ duration_ms: z.int().nonnegative().max(3_600_000),
261
+ /** Bounded here, not on the report: a reject drops only telemetry. */
262
+ hermes_plugin_version: versionSchema.optional(),
263
+ hermes_plugin_expected_version: versionSchema.optional(),
264
+ });
265
+ // Detection threw, so there is no report to aggregate: enumerated outcome and timing only.
266
+ const doctorCouldNotRunPayloadSchema = z.object({
267
+ outcome: z.literal('could_not_run'),
268
+ error_class: z.enum(DOCTOR_ERROR_CLASSES),
269
+ schema_version: z.int().positive(),
270
+ cli_version: z.string().max(32),
271
+ fix_mode: z.enum(['none', 'fix', 'fix_yes']),
272
+ harness_scope: z.enum(DOCTOR_HARNESS_SCOPES),
273
+ is_human_initiated: z.boolean(),
274
+ duration_ms: z.int().nonnegative().max(3_600_000),
275
+ });
276
+ const doctorPayloadSchema = z.discriminatedUnion('outcome', [
277
+ doctorCompletedPayloadSchema,
278
+ doctorCouldNotRunPayloadSchema,
279
+ ]);
280
+ export async function sendDoctorCompleted(mcpUrl, payload) {
281
+ if (telemetryDisabled())
282
+ return;
283
+ let endpoint;
284
+ let body;
285
+ try {
286
+ // Parse inside try — a schema violation must not fail a diagnosis that already ran.
287
+ const parsed = doctorPayloadSchema.parse(payload);
288
+ endpoint = new URL('/api/cli/connect-event', mcpUrl).toString();
289
+ // Stamped after the parse: process-derived and bounded, cannot trip route caps.
290
+ body = JSON.stringify({
291
+ event: 'doctor_completed',
292
+ ...parsed,
293
+ runtime_platform: process.platform,
294
+ node_version: process.version,
295
+ calling_harness: detectHarness() ?? 'none',
296
+ cli_invocation_id: CLI_INVOCATION_ID,
297
+ runtime_env: detectRuntimeEnv(),
298
+ });
299
+ }
300
+ catch (e) {
301
+ if (process.env['SPRINGBRAND_DEBUG']) {
302
+ errLine(`doctor telemetry skipped: ${e instanceof Error ? e.message : String(e)}`);
303
+ }
304
+ return;
305
+ }
306
+ // One attempt: doctor just probed this origin, so a stale keep-alive socket is not the risk.
307
+ await postConnectEvent({ endpoint, body, attempts: 1, label: 'doctor' });
308
+ }
309
+ //# sourceMappingURL=setup-telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-telemetry.js","sourceRoot":"","sources":["../../src/lib/setup-telemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /** 复刻自 tiny-fish CLI 编译产物:signals.d.ts + signals.impl.js */
2
+ export declare const SIGNAL_EXIT_CODES: {
3
+ readonly SIGHUP: 129;
4
+ readonly SIGINT: 130;
5
+ readonly SIGTERM: 143;
6
+ };
7
+ /**
8
+ * Without a parent handler, terminal Ctrl+C kills this process inside spawn.sync before the
9
+ * child result exists — no event, no flush. `onSignal` runs at most once; a second signal
10
+ * exits rather than waiting on it.
11
+ */
12
+ export declare function installSignalGuard(onSignal: (signal: TerminalSignal) => Promise<void> | void): () => void;
13
+ export type TerminalSignal = keyof typeof SIGNAL_EXIT_CODES;
14
+ //# sourceMappingURL=signals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../src/lib/signals.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAG5D,eAAO,MAAM,iBAAiB,EAAE;IAC5B,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC;CACoB,CAAC;AAC/C;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,cAmB5F;AAGD,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,iBAAiB,CAAC"}
@@ -0,0 +1,29 @@
1
+ /** 复刻自 tiny-fish CLI 编译产物:signals.d.ts + signals.impl.js */
2
+ // 128 + signal number
3
+ export const SIGNAL_EXIT_CODES = { SIGHUP: 129, SIGINT: 130, SIGTERM: 143 };
4
+ /**
5
+ * Without a parent handler, terminal Ctrl+C kills this process inside spawn.sync before the
6
+ * child result exists — no event, no flush. `onSignal` runs at most once; a second signal
7
+ * exits rather than waiting on it.
8
+ */
9
+ export function installSignalGuard(onSignal) {
10
+ let handling = false;
11
+ const handlers = ['SIGINT', 'SIGTERM', 'SIGHUP'].map((signal) => {
12
+ const handler = () => {
13
+ const exit = () => process.exit(SIGNAL_EXIT_CODES[signal]);
14
+ if (handling)
15
+ return exit();
16
+ handling = true;
17
+ void Promise.resolve(onSignal(signal))
18
+ .catch(() => { })
19
+ .finally(exit);
20
+ };
21
+ process.on(signal, handler);
22
+ return [signal, handler];
23
+ });
24
+ return () => {
25
+ for (const [signal, handler] of handlers)
26
+ process.off(signal, handler);
27
+ };
28
+ }
29
+ //# sourceMappingURL=signals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signals.js","sourceRoot":"","sources":["../../src/lib/signals.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAE5D,sBAAsB;AACtB,MAAM,CAAC,MAAM,iBAAiB,GAI1B,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AAC/C;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAA0D;IACzF,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,MAAM,QAAQ,GAAoC,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACvG,MAAM,OAAO,GAAG,GAAG,EAAE;YACjB,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC3D,IAAI,QAAQ;gBACR,OAAO,IAAI,EAAE,CAAC;YAClB,QAAQ,GAAG,IAAI,CAAC;YAChB,KAAK,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;iBACjC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;iBAChB,OAAO,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC,CAAC;QACF,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC5B,OAAO,CAAC,MAAM,EAAE,OAAO,CAAU,CAAC;IACtC,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,EAAE;QACR,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,QAAQ;YACpC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC,CAAC;AACN,CAAC"}