prismcast 1.9.0 → 1.10.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 (360) hide show
  1. package/dist/app.d.ts +1 -1
  2. package/dist/app.js +27 -9
  3. package/dist/app.js.map +1 -1
  4. package/dist/browser/cdp.js +7 -7
  5. package/dist/browser/cdp.js.map +1 -1
  6. package/dist/browser/channelSelection.d.ts +41 -11
  7. package/dist/browser/channelSelection.js +75 -24
  8. package/dist/browser/channelSelection.js.map +1 -1
  9. package/dist/browser/display.d.ts +1 -1
  10. package/dist/browser/index.d.ts +8 -8
  11. package/dist/browser/index.js +42 -43
  12. package/dist/browser/index.js.map +1 -1
  13. package/dist/browser/login.d.ts +2 -2
  14. package/dist/browser/login.js +1 -1
  15. package/dist/browser/manifestInterceptor.d.ts +77 -0
  16. package/dist/browser/manifestInterceptor.js +323 -0
  17. package/dist/browser/manifestInterceptor.js.map +1 -0
  18. package/dist/browser/precaching.js +4 -4
  19. package/dist/browser/tuning/comcastPolymer.d.ts +1 -1
  20. package/dist/browser/tuning/cox.d.ts +1 -1
  21. package/dist/browser/tuning/directv.d.ts +1 -1
  22. package/dist/browser/tuning/directv.js +61 -62
  23. package/dist/browser/tuning/directv.js.map +1 -1
  24. package/dist/browser/tuning/fox.d.ts +1 -1
  25. package/dist/browser/tuning/fox.js +171 -14
  26. package/dist/browser/tuning/fox.js.map +1 -1
  27. package/dist/browser/tuning/hbo.d.ts +1 -1
  28. package/dist/browser/tuning/hbo.js +6 -6
  29. package/dist/browser/tuning/hbo.js.map +1 -1
  30. package/dist/browser/tuning/hulu.d.ts +1 -1
  31. package/dist/browser/tuning/hulu.js +117 -110
  32. package/dist/browser/tuning/hulu.js.map +1 -1
  33. package/dist/browser/tuning/shared.d.ts +3 -3
  34. package/dist/browser/tuning/shared.js +5 -5
  35. package/dist/browser/tuning/sling.d.ts +1 -1
  36. package/dist/browser/tuning/sling.js +28 -28
  37. package/dist/browser/tuning/sling.js.map +1 -1
  38. package/dist/browser/tuning/spectrum.d.ts +1 -1
  39. package/dist/browser/tuning/spectrum.js +21 -22
  40. package/dist/browser/tuning/spectrum.js.map +1 -1
  41. package/dist/browser/tuning/thumbnailRow.d.ts +1 -1
  42. package/dist/browser/tuning/thumbnailRow.js +1 -1
  43. package/dist/browser/tuning/tileClick.d.ts +1 -1
  44. package/dist/browser/tuning/tileClick.js +5 -5
  45. package/dist/browser/tuning/xfinity.d.ts +1 -1
  46. package/dist/browser/tuning/youtubeTv.d.ts +1 -1
  47. package/dist/browser/tuning/youtubeTv.js +17 -18
  48. package/dist/browser/tuning/youtubeTv.js.map +1 -1
  49. package/dist/browser/video.d.ts +20 -6
  50. package/dist/browser/video.js +30 -38
  51. package/dist/browser/video.js.map +1 -1
  52. package/dist/channels/index.d.ts +1 -2
  53. package/dist/channels/index.js +73 -40
  54. package/dist/channels/index.js.map +1 -1
  55. package/dist/config/channelForm.d.ts +58 -0
  56. package/dist/config/channelForm.js +129 -0
  57. package/dist/config/channelForm.js.map +1 -0
  58. package/dist/config/consistencyProbe.d.ts +7 -0
  59. package/dist/config/consistencyProbe.js +143 -0
  60. package/dist/config/consistencyProbe.js.map +1 -0
  61. package/dist/config/health.d.ts +4 -3
  62. package/dist/config/health.js +75 -62
  63. package/dist/config/health.js.map +1 -1
  64. package/dist/config/index.d.ts +1 -1
  65. package/dist/config/index.js +19 -12
  66. package/dist/config/index.js.map +1 -1
  67. package/dist/config/paths.d.ts +9 -3
  68. package/dist/config/paths.js +12 -4
  69. package/dist/config/paths.js.map +1 -1
  70. package/dist/config/persistence.context.d.ts +8 -0
  71. package/dist/config/persistence.context.js +30 -0
  72. package/dist/config/persistence.context.js.map +1 -0
  73. package/dist/config/persistence.d.ts +110 -12
  74. package/dist/config/persistence.js +351 -32
  75. package/dist/config/persistence.js.map +1 -1
  76. package/dist/config/presets.d.ts +14 -4
  77. package/dist/config/presets.js +84 -75
  78. package/dist/config/presets.js.map +1 -1
  79. package/dist/config/profiles.d.ts +2 -2
  80. package/dist/config/profiles.js +7 -9
  81. package/dist/config/profiles.js.map +1 -1
  82. package/dist/config/servicePacks.d.ts +2 -2
  83. package/dist/config/servicePacks.js +28 -28
  84. package/dist/config/servicePacks.js.map +1 -1
  85. package/dist/config/services.d.ts +62 -36
  86. package/dist/config/services.js +150 -136
  87. package/dist/config/services.js.map +1 -1
  88. package/dist/config/sites.d.ts +3 -3
  89. package/dist/config/sites.js +16 -16
  90. package/dist/config/sites.js.map +1 -1
  91. package/dist/config/userChannels.d.ts +500 -41
  92. package/dist/config/userChannels.js +1201 -312
  93. package/dist/config/userChannels.js.map +1 -1
  94. package/dist/config/userConfig.d.ts +103 -10
  95. package/dist/config/userConfig.js +277 -117
  96. package/dist/config/userConfig.js.map +1 -1
  97. package/dist/config/userProfiles.d.ts +4 -2
  98. package/dist/config/userProfiles.js +72 -26
  99. package/dist/config/userProfiles.js.map +1 -1
  100. package/dist/hdhr/channelMap.js +8 -11
  101. package/dist/hdhr/channelMap.js.map +1 -1
  102. package/dist/hdhr/deviceId.js +10 -9
  103. package/dist/hdhr/deviceId.js.map +1 -1
  104. package/dist/hdhr/discover.js +4 -5
  105. package/dist/hdhr/discover.js.map +1 -1
  106. package/dist/hdhr/index.js +6 -10
  107. package/dist/hdhr/index.js.map +1 -1
  108. package/dist/index.js +12 -12
  109. package/dist/index.js.map +1 -1
  110. package/dist/native/codecInference.d.ts +44 -0
  111. package/dist/native/codecInference.js +327 -0
  112. package/dist/native/codecInference.js.map +1 -0
  113. package/dist/native/decrypt.d.ts +1 -1
  114. package/dist/native/index.d.ts +5 -5
  115. package/dist/native/index.js +42 -64
  116. package/dist/native/index.js.map +1 -1
  117. package/dist/native/probe.d.ts +27 -9
  118. package/dist/native/probe.js +158 -67
  119. package/dist/native/probe.js.map +1 -1
  120. package/dist/native/proxy.d.ts +4 -2
  121. package/dist/native/proxy.js +52 -49
  122. package/dist/native/proxy.js.map +1 -1
  123. package/dist/native/tokenExpiry.d.ts +22 -0
  124. package/dist/native/tokenExpiry.js +153 -0
  125. package/dist/native/tokenExpiry.js.map +1 -0
  126. package/dist/routes/auth.js +6 -10
  127. package/dist/routes/auth.js.map +1 -1
  128. package/dist/routes/components.js +2 -2
  129. package/dist/routes/components.js.map +1 -1
  130. package/dist/routes/config/channels/endpoints/browse.d.ts +6 -0
  131. package/dist/routes/config/channels/endpoints/browse.js +195 -0
  132. package/dist/routes/config/channels/endpoints/browse.js.map +1 -0
  133. package/dist/routes/config/channels/endpoints/bulk.d.ts +6 -0
  134. package/dist/routes/config/channels/endpoints/bulk.js +128 -0
  135. package/dist/routes/config/channels/endpoints/bulk.js.map +1 -0
  136. package/dist/routes/config/channels/endpoints/crud.d.ts +6 -0
  137. package/dist/routes/config/channels/endpoints/crud.js +504 -0
  138. package/dist/routes/config/channels/endpoints/crud.js.map +1 -0
  139. package/dist/routes/config/channels/endpoints/importExport.d.ts +6 -0
  140. package/dist/routes/config/channels/endpoints/importExport.js +131 -0
  141. package/dist/routes/config/channels/endpoints/importExport.js.map +1 -0
  142. package/dist/routes/config/channels/endpoints/predefined.d.ts +6 -0
  143. package/dist/routes/config/channels/endpoints/predefined.js +78 -0
  144. package/dist/routes/config/channels/endpoints/predefined.js.map +1 -0
  145. package/dist/routes/config/channels/endpoints/prefs.d.ts +6 -0
  146. package/dist/routes/config/channels/endpoints/prefs.js +58 -0
  147. package/dist/routes/config/channels/endpoints/prefs.js.map +1 -0
  148. package/dist/routes/config/channels/endpoints/service.d.ts +6 -0
  149. package/dist/routes/config/channels/endpoints/service.js +149 -0
  150. package/dist/routes/config/channels/endpoints/service.js.map +1 -0
  151. package/dist/routes/config/channels/endpoints/tags.d.ts +6 -0
  152. package/dist/routes/config/channels/endpoints/tags.js +185 -0
  153. package/dist/routes/config/channels/endpoints/tags.js.map +1 -0
  154. package/dist/routes/config/channels/http/handler.d.ts +10 -0
  155. package/dist/routes/config/channels/http/handler.js +20 -0
  156. package/dist/routes/config/channels/http/handler.js.map +1 -0
  157. package/dist/routes/config/channels/http/playlistHint.d.ts +25 -0
  158. package/dist/routes/config/channels/http/playlistHint.js +40 -0
  159. package/dist/routes/config/channels/http/playlistHint.js.map +1 -0
  160. package/dist/routes/config/channels/http/serviceWarning.d.ts +10 -0
  161. package/dist/routes/config/channels/http/serviceWarning.js +28 -0
  162. package/dist/routes/config/channels/http/serviceWarning.js.map +1 -0
  163. package/dist/routes/config/channels/index.d.ts +3 -3
  164. package/dist/routes/config/channels/index.js +1 -1
  165. package/dist/routes/config/channels/index.js.map +1 -1
  166. package/dist/routes/config/channels/{routes.d.ts → setup.d.ts} +1 -1
  167. package/dist/routes/config/channels/setup.js +23 -0
  168. package/dist/routes/config/channels/setup.js.map +1 -0
  169. package/dist/routes/config/channels/table.d.ts +9 -9
  170. package/dist/routes/config/channels/table.js +124 -76
  171. package/dist/routes/config/channels/table.js.map +1 -1
  172. package/dist/routes/config/http/envelope.d.ts +111 -0
  173. package/dist/routes/config/http/envelope.js +103 -0
  174. package/dist/routes/config/http/envelope.js.map +1 -0
  175. package/dist/routes/config/index.d.ts +9 -9
  176. package/dist/routes/config/index.js +2 -2
  177. package/dist/routes/config/index.js.map +1 -1
  178. package/dist/routes/config/services.js +69 -68
  179. package/dist/routes/config/services.js.map +1 -1
  180. package/dist/routes/config/settings.d.ts +1 -1
  181. package/dist/routes/config/settings.js +45 -38
  182. package/dist/routes/config/settings.js.map +1 -1
  183. package/dist/routes/debug.js +12 -11
  184. package/dist/routes/debug.js.map +1 -1
  185. package/dist/routes/icons.js +2 -2
  186. package/dist/routes/icons.js.map +1 -1
  187. package/dist/routes/logs.js +19 -30
  188. package/dist/routes/logs.js.map +1 -1
  189. package/dist/routes/mpegts.js +1 -1
  190. package/dist/routes/playlist.d.ts +1 -1
  191. package/dist/routes/playlist.js +37 -26
  192. package/dist/routes/playlist.js.map +1 -1
  193. package/dist/routes/root/content.js +27 -6
  194. package/dist/routes/root/content.js.map +1 -1
  195. package/dist/routes/root/index.js +2 -5
  196. package/dist/routes/root/index.js.map +1 -1
  197. package/dist/routes/root/scripts/channels.js +16 -16
  198. package/dist/routes/root/scripts/channels.js.map +1 -1
  199. package/dist/routes/root/scripts/config.js +59 -59
  200. package/dist/routes/root/scripts/config.js.map +1 -1
  201. package/dist/routes/root/scripts/index.d.ts +4 -4
  202. package/dist/routes/root/scripts/shared.js +24 -10
  203. package/dist/routes/root/scripts/shared.js.map +1 -1
  204. package/dist/routes/root/scripts/status.d.ts +4 -0
  205. package/dist/routes/root/scripts/status.handlers.d.ts +182 -0
  206. package/dist/routes/root/scripts/status.handlers.js +713 -0
  207. package/dist/routes/root/scripts/status.handlers.js.map +1 -0
  208. package/dist/routes/root/scripts/status.js +86 -488
  209. package/dist/routes/root/scripts/status.js.map +1 -1
  210. package/dist/routes/root/styles.js +5 -5
  211. package/dist/routes/services.js +18 -15
  212. package/dist/routes/services.js.map +1 -1
  213. package/dist/routes/sse.d.ts +16 -0
  214. package/dist/routes/sse.js +29 -0
  215. package/dist/routes/sse.js.map +1 -0
  216. package/dist/routes/streams.js +10 -23
  217. package/dist/routes/streams.js.map +1 -1
  218. package/dist/routes/ui.d.ts +2 -2
  219. package/dist/routes/upgrade.js +6 -7
  220. package/dist/routes/upgrade.js.map +1 -1
  221. package/dist/service/commands.context.d.ts +6 -0
  222. package/dist/service/commands.context.js +47 -0
  223. package/dist/service/commands.context.js.map +1 -0
  224. package/dist/service/commands.d.ts +53 -8
  225. package/dist/service/commands.js +171 -188
  226. package/dist/service/commands.js.map +1 -1
  227. package/dist/service/generators.context.d.ts +6 -0
  228. package/dist/service/generators.context.js +45 -0
  229. package/dist/service/generators.context.js.map +1 -0
  230. package/dist/service/generators.d.ts +56 -16
  231. package/dist/service/generators.js +499 -383
  232. package/dist/service/generators.js.map +1 -1
  233. package/dist/service/index.d.ts +2 -2
  234. package/dist/streaming/clients.d.ts +2 -2
  235. package/dist/streaming/clients.js +2 -2
  236. package/dist/streaming/codec.d.ts +2 -2
  237. package/dist/streaming/codec.js +0 -1
  238. package/dist/streaming/codec.js.map +1 -1
  239. package/dist/streaming/fmp4Segmenter.d.ts +2 -2
  240. package/dist/streaming/fmp4Segmenter.js +12 -12
  241. package/dist/streaming/hls.d.ts +3 -3
  242. package/dist/streaming/hls.js +81 -70
  243. package/dist/streaming/hls.js.map +1 -1
  244. package/dist/streaming/hlsResume.d.ts +3 -3
  245. package/dist/streaming/hlsResume.js +5 -5
  246. package/dist/streaming/hlsSegments.d.ts +5 -2
  247. package/dist/streaming/hlsSegments.js +14 -9
  248. package/dist/streaming/hlsSegments.js.map +1 -1
  249. package/dist/streaming/monitor.d.ts +12 -12
  250. package/dist/streaming/monitor.js +80 -54
  251. package/dist/streaming/monitor.js.map +1 -1
  252. package/dist/streaming/mp4Parser.d.ts +34 -4
  253. package/dist/streaming/mp4Parser.js +111 -29
  254. package/dist/streaming/mp4Parser.js.map +1 -1
  255. package/dist/streaming/mpegts.d.ts +1 -1
  256. package/dist/streaming/mpegts.js +13 -10
  257. package/dist/streaming/mpegts.js.map +1 -1
  258. package/dist/streaming/playlistBuilder.d.ts +1 -1
  259. package/dist/streaming/playlistBuilder.js +2 -2
  260. package/dist/streaming/preroll.d.ts +9 -9
  261. package/dist/streaming/preroll.js +39 -41
  262. package/dist/streaming/preroll.js.map +1 -1
  263. package/dist/streaming/pretune.js +4 -4
  264. package/dist/streaming/pretune.js.map +1 -1
  265. package/dist/streaming/recovery.d.ts +3 -3
  266. package/dist/streaming/recovery.js +4 -4
  267. package/dist/streaming/registry.d.ts +6 -6
  268. package/dist/streaming/setup.d.ts +9 -8
  269. package/dist/streaming/setup.js +97 -49
  270. package/dist/streaming/setup.js.map +1 -1
  271. package/dist/streaming/showInfo.d.ts +9 -3
  272. package/dist/streaming/showInfo.js +26 -18
  273. package/dist/streaming/showInfo.js.map +1 -1
  274. package/dist/streaming/statusEmitter.d.ts +4 -4
  275. package/dist/streaming/statusEmitter.js +2 -2
  276. package/dist/types/channels.d.ts +133 -34
  277. package/dist/types/channels.js +39 -1
  278. package/dist/types/channels.js.map +1 -1
  279. package/dist/types/config.d.ts +20 -1
  280. package/dist/types/index.d.ts +9 -8
  281. package/dist/types/index.js +1 -0
  282. package/dist/types/index.js.map +1 -1
  283. package/dist/types/profiles.d.ts +5 -4
  284. package/dist/types/selection.d.ts +48 -4
  285. package/dist/types/streaming.d.ts +1 -1
  286. package/dist/upgrade/commands.context.d.ts +6 -0
  287. package/dist/upgrade/commands.context.js +29 -0
  288. package/dist/upgrade/commands.context.js.map +1 -0
  289. package/dist/upgrade/commands.d.ts +29 -2
  290. package/dist/upgrade/commands.js +87 -134
  291. package/dist/upgrade/commands.js.map +1 -1
  292. package/dist/upgrade/detection.context.d.ts +6 -0
  293. package/dist/upgrade/detection.context.js +24 -0
  294. package/dist/upgrade/detection.context.js.map +1 -0
  295. package/dist/upgrade/detection.d.ts +140 -10
  296. package/dist/upgrade/detection.js +153 -66
  297. package/dist/upgrade/detection.js.map +1 -1
  298. package/dist/upgrade/index.d.ts +2 -2
  299. package/dist/utils/chromeFetch.d.ts +1 -1
  300. package/dist/utils/chromeFetch.js +1 -1
  301. package/dist/utils/clock.d.ts +14 -0
  302. package/dist/utils/clock.js +28 -0
  303. package/dist/utils/clock.js.map +1 -0
  304. package/dist/utils/debugFilter.d.ts +1 -1
  305. package/dist/utils/debugFilter.js +6 -4
  306. package/dist/utils/debugFilter.js.map +1 -1
  307. package/dist/utils/delay.d.ts +2 -3
  308. package/dist/utils/delay.js +10 -16
  309. package/dist/utils/delay.js.map +1 -1
  310. package/dist/utils/evaluate.js +12 -14
  311. package/dist/utils/evaluate.js.map +1 -1
  312. package/dist/utils/ffmpeg.context.d.ts +6 -0
  313. package/dist/utils/ffmpeg.context.js +31 -0
  314. package/dist/utils/ffmpeg.context.js.map +1 -0
  315. package/dist/utils/ffmpeg.d.ts +85 -29
  316. package/dist/utils/ffmpeg.js +126 -129
  317. package/dist/utils/ffmpeg.js.map +1 -1
  318. package/dist/utils/fileLogger.d.ts +18 -2
  319. package/dist/utils/fileLogger.js +58 -30
  320. package/dist/utils/fileLogger.js.map +1 -1
  321. package/dist/utils/format.d.ts +1 -1
  322. package/dist/utils/format.js +2 -2
  323. package/dist/utils/format.js.map +1 -1
  324. package/dist/utils/html.js +1 -3
  325. package/dist/utils/html.js.map +1 -1
  326. package/dist/utils/index.d.ts +21 -20
  327. package/dist/utils/index.js +1 -0
  328. package/dist/utils/index.js.map +1 -1
  329. package/dist/utils/logger.js +16 -20
  330. package/dist/utils/logger.js.map +1 -1
  331. package/dist/utils/m3u.d.ts +18 -3
  332. package/dist/utils/m3u.js +28 -14
  333. package/dist/utils/m3u.js.map +1 -1
  334. package/dist/utils/memo.d.ts +19 -0
  335. package/dist/utils/memo.js +53 -0
  336. package/dist/utils/memo.js.map +1 -0
  337. package/dist/utils/morganStream.js +2 -2
  338. package/dist/utils/morganStream.js.map +1 -1
  339. package/dist/utils/pid.d.ts +2 -2
  340. package/dist/utils/pid.js +2 -2
  341. package/dist/utils/platform.d.ts +1 -1
  342. package/dist/utils/platform.js +3 -3
  343. package/dist/utils/platform.js.map +1 -1
  344. package/dist/utils/retry.d.ts +2 -0
  345. package/dist/utils/retry.js +9 -7
  346. package/dist/utils/retry.js.map +1 -1
  347. package/dist/utils/sanitize.d.ts +2 -2
  348. package/dist/utils/sanitize.js +4 -4
  349. package/dist/utils/timing.d.ts +6 -3
  350. package/dist/utils/timing.js +10 -6
  351. package/dist/utils/timing.js.map +1 -1
  352. package/dist/utils/version.d.ts +3 -2
  353. package/dist/utils/version.js +14 -27
  354. package/dist/utils/version.js.map +1 -1
  355. package/package.json +13 -7
  356. package/dist/native/intercept.d.ts +0 -35
  357. package/dist/native/intercept.js +0 -181
  358. package/dist/native/intercept.js.map +0 -1
  359. package/dist/routes/config/channels/routes.js +0 -1505
  360. package/dist/routes/config/channels/routes.js.map +0 -1
@@ -1,6 +1,33 @@
1
+ import type { InstallInfo } from "./detection.ts";
1
2
  /**
2
- * Main handler for the `upgrade` subcommand. Parses arguments and executes the appropriate upgrade logic.
3
+ * Result of running an upgrade command. The success flag distinguishes ran-without-error from threw-or-exited-non-zero; the runner does not surface the actual
4
+ * error because execSync's stderr is inherited to the user's terminal directly.
5
+ */
6
+ export interface UpgradeResult {
7
+ readonly success: boolean;
8
+ }
9
+ /**
10
+ * The runtime context handleUpgradeCommand consumes. Each field models one capability the command needs - detection, version lookup, subprocess execution,
11
+ * stdout/stderr output, process termination, and a service-mode probe. Decision logic is a pure function of this shape; production wires it through
12
+ * createDefaultUpgradeContext (in commands.context.ts), tests pass a context literal.
13
+ */
14
+ export interface UpgradeContext {
15
+ readonly detect: () => InstallInfo;
16
+ readonly exit: (code: number) => never;
17
+ readonly fetchLatestVersion: () => Promise<string | null>;
18
+ readonly isService: boolean;
19
+ readonly runUpgradeCommand: (cmd: string, options: {
20
+ cwd?: string;
21
+ }) => UpgradeResult;
22
+ readonly stderr: (line: string) => void;
23
+ readonly stdout: (line: string) => void;
24
+ }
25
+ /**
26
+ * Main handler for the `upgrade` subcommand. Parses arguments and orchestrates the appropriate upgrade flow through the UpgradeContext. Pure function of
27
+ * UpgradeContext modulo the help/usage paths that just write to stdout - no detection, registry, subprocess, or process state is touched outside the context's
28
+ * methods.
3
29
  * @param args - Arguments after 'upgrade' (e.g., ['--check', '--force']).
30
+ * @param ctx - The upgrade context. Defaults to createDefaultUpgradeContext() which wires real runtime I/O.
4
31
  * @returns Exit code (0 for success, 1 for error).
5
32
  */
6
- export declare function handleUpgradeCommand(args: string[]): Promise<number>;
33
+ export declare function handleUpgradeCommand(args: readonly string[], ctx?: UpgradeContext): Promise<number>;
@@ -1,195 +1,148 @@
1
- /* Copyright(C) 2024-2026, HJD (https://github.com/hjdhjd). All rights reserved.
2
- *
3
- * commands.ts: Upgrade command handlers for PrismCast CLI.
1
+ import { getPackageVersion, isVersionLessThan, normalizeVersion } from "../utils/version.js";
2
+ import { createDefaultUpgradeContext } from "./commands.context.js";
3
+ /* The upgrade subcommand handles `prismcast upgrade [--check] [--force] [-h|--help]`. Detection picks the install method, the registry lookup checks for a
4
+ * newer version, and the runner executes the per-method upgrade command (or prints manual instructions for non-upgradeable methods).
4
5
  */
5
- import { fetchLatestVersion, getPackageVersion, isVersionLessThan, normalizeVersion } from "../utils/version.js";
6
- import { print, printError } from "../utils/cliOutput.js";
7
- import { detectInstallMethod } from "./detection.js";
8
- import { execSync } from "node:child_process";
9
- import { isRunningAsService } from "../utils/platform.js";
10
- /* These handlers implement the `prismcast upgrade` subcommand for detecting the installation method, checking for updates, and executing the appropriate upgrade
11
- * command. The pattern mirrors the service subcommand handlers in service/commands.ts.
12
- */
13
- /**
14
- * Formats the display name for an installation method.
15
- * @param info - The installation info to format.
16
- * @returns A human-readable name for the install method.
17
- */
18
- function formatMethodName(info) {
19
- switch (info.method) {
20
- case "docker": {
21
- return "Docker";
22
- }
23
- case "homebrew": {
24
- return "Homebrew";
25
- }
26
- case "npm-global": {
27
- return "npm (global)";
28
- }
29
- case "npm-local": {
30
- return "npm (local)";
31
- }
32
- default: {
33
- return "Unknown";
34
- }
35
- }
36
- }
37
6
  /**
38
7
  * Prints usage information for the upgrade subcommand.
8
+ * @param ctx - The upgrade context (used for stdout output).
39
9
  */
40
- function printUpgradeUsage() {
41
- print("Usage: prismcast upgrade [options]");
42
- print("");
43
- print("Upgrade PrismCast to the latest version.");
44
- print("");
45
- print("Options:");
46
- print(" --check Show upgrade information without upgrading");
47
- print(" --force Upgrade even if already up to date");
48
- print(" -h, --help Show this help message");
10
+ function printUpgradeUsage(ctx) {
11
+ ctx.stdout("Usage: prismcast upgrade [options]");
12
+ ctx.stdout("");
13
+ ctx.stdout("Upgrade PrismCast to the latest version.");
14
+ ctx.stdout("");
15
+ ctx.stdout("Options:");
16
+ ctx.stdout(" --check Show upgrade information without upgrading");
17
+ ctx.stdout(" --force Upgrade even if already up to date");
18
+ ctx.stdout(" -h, --help Show this help message");
49
19
  }
50
20
  /**
51
- * Prints the upgrade check summary (shared between --check mode and the pre-upgrade display).
21
+ * Prints the upgrade summary table (shared between --check mode and the pre-upgrade display).
22
+ * @param ctx - The upgrade context (used for stdout output).
52
23
  * @param info - The detected installation info.
53
24
  * @param currentVersion - The currently running version.
54
25
  * @param latestVersion - The latest available version, or null if unknown.
55
26
  */
56
- function printUpgradeInfo(info, currentVersion, latestVersion) {
57
- print("PrismCast Upgrade Check");
58
- print("\u2500".repeat(40));
59
- print("Current version: v" + currentVersion);
27
+ function printUpgradeInfo(ctx, info, currentVersion, latestVersion) {
28
+ ctx.stdout("PrismCast Upgrade Check");
29
+ ctx.stdout("─".repeat(40));
30
+ ctx.stdout("Current version: v" + currentVersion);
60
31
  if (latestVersion) {
61
- print("Latest version: v" + latestVersion);
32
+ ctx.stdout("Latest version: v" + latestVersion);
62
33
  }
63
34
  else {
64
- print("Latest version: (unable to check)");
35
+ ctx.stdout("Latest version: (unable to check)");
65
36
  }
66
- print("Install method: " + formatMethodName(info));
37
+ ctx.stdout("Install method: " + info.displayName);
67
38
  if (info.upgradeable) {
68
- print("Upgrade command: " + info.upgradeCommand);
39
+ ctx.stdout("Upgrade command: " + info.upgradeCommand);
69
40
  }
70
41
  }
71
42
  /**
72
- * Handles the --check flag: prints upgrade information and exits.
43
+ * Prints the full report for a non-upgradeable install method - the summary table, a blank line, the strategy's manual upgrade message, and the indented
44
+ * command. Single source of truth for "this is what the user sees when we cannot upgrade in-place," shared between the --check flow and the main upgrade flow.
45
+ * The parameter type is the narrow NonUpgradeableInstallInfo variant; callers narrow via the discriminated union before invoking, so manualUpgradeMessage is
46
+ * always in scope.
47
+ * @param ctx - The upgrade context (used for stdout output).
48
+ * @param info - The detected non-upgradeable installation info.
49
+ * @param currentVersion - The currently running version.
50
+ * @param latestVersion - The latest available version, or null if unknown.
51
+ */
52
+ function printNonUpgradeableSummary(ctx, info, currentVersion, latestVersion) {
53
+ printUpgradeInfo(ctx, info, currentVersion, latestVersion);
54
+ ctx.stdout("");
55
+ for (const line of info.manualUpgradeMessage) {
56
+ ctx.stdout(line);
57
+ }
58
+ ctx.stdout(" " + info.upgradeCommand);
59
+ }
60
+ /**
61
+ * Handles the --check flag: prints upgrade information and exits with 0.
62
+ * @param ctx - The upgrade context.
73
63
  * @param info - The detected installation info.
74
64
  * @param currentVersion - The currently running version.
75
65
  * @param latestVersion - The latest available version, or null if unknown.
76
- * @returns Exit code (0 for success).
66
+ * @returns Exit code (0).
77
67
  */
78
- function handleCheck(info, currentVersion, latestVersion) {
79
- printUpgradeInfo(info, currentVersion, latestVersion);
80
- print("");
68
+ function handleCheck(ctx, info, currentVersion, latestVersion) {
81
69
  if (!info.upgradeable) {
82
- // Docker or unknown: show manual instructions using the command from detection.
83
- if (info.method === "docker") {
84
- print("To upgrade, pull the latest image and recreate the container:");
85
- print(" " + info.upgradeCommand);
86
- }
87
- else {
88
- print("Unable to detect installation method. Please upgrade manually:");
89
- print(" " + info.upgradeCommand);
90
- }
70
+ printNonUpgradeableSummary(ctx, info, currentVersion, latestVersion);
91
71
  return 0;
92
72
  }
73
+ printUpgradeInfo(ctx, info, currentVersion, latestVersion);
74
+ ctx.stdout("");
93
75
  if (!latestVersion) {
94
- print("Run 'prismcast upgrade --force' to upgrade without a version check.");
76
+ ctx.stdout("Run 'prismcast upgrade --force' to upgrade without a version check.");
95
77
  }
96
78
  else if (!isVersionLessThan(currentVersion, latestVersion)) {
97
- print("PrismCast v" + currentVersion + " is already the latest version.");
79
+ ctx.stdout("PrismCast v" + currentVersion + " is already the latest version.");
98
80
  }
99
81
  else {
100
- print("Run 'prismcast upgrade' to upgrade.");
82
+ ctx.stdout("Run 'prismcast upgrade' to upgrade.");
101
83
  }
102
84
  return 0;
103
85
  }
104
86
  /**
105
- * Executes the upgrade command for the detected installation method.
106
- * @param info - The detected installation info.
107
- * @returns True if the upgrade command succeeded, false otherwise.
108
- */
109
- function executeUpgrade(info) {
110
- try {
111
- // For npm-local, run the install from the project directory that contains the dependency.
112
- const options = { encoding: "utf-8", stdio: "inherit" };
113
- if ((info.method === "npm-local") && info.packageDir) {
114
- options.cwd = info.packageDir;
115
- }
116
- execSync(info.upgradeCommand, options);
117
- return true;
118
- }
119
- catch {
120
- return false;
121
- }
122
- }
123
- /**
124
- * Main handler for the `upgrade` subcommand. Parses arguments and executes the appropriate upgrade logic.
87
+ * Main handler for the `upgrade` subcommand. Parses arguments and orchestrates the appropriate upgrade flow through the UpgradeContext. Pure function of
88
+ * UpgradeContext modulo the help/usage paths that just write to stdout - no detection, registry, subprocess, or process state is touched outside the context's
89
+ * methods.
125
90
  * @param args - Arguments after 'upgrade' (e.g., ['--check', '--force']).
91
+ * @param ctx - The upgrade context. Defaults to createDefaultUpgradeContext() which wires real runtime I/O.
126
92
  * @returns Exit code (0 for success, 1 for error).
127
93
  */
128
- export async function handleUpgradeCommand(args) {
129
- // Parse flags.
94
+ export async function handleUpgradeCommand(args, ctx = createDefaultUpgradeContext()) {
130
95
  const showHelp = args.includes("--help") || args.includes("-h") || args.includes("help");
131
96
  const checkOnly = args.includes("--check");
132
97
  const force = args.includes("--force");
133
98
  if (showHelp) {
134
- printUpgradeUsage();
99
+ printUpgradeUsage(ctx);
135
100
  return 0;
136
101
  }
137
- // Detect installation method.
138
- const info = detectInstallMethod();
102
+ const info = ctx.detect();
139
103
  const currentVersion = normalizeVersion(getPackageVersion());
140
- // Fetch the latest version from npm.
141
- const latestVersion = await fetchLatestVersion();
142
- // Handle --check mode.
104
+ const latestVersion = await ctx.fetchLatestVersion();
143
105
  if (checkOnly) {
144
- return handleCheck(info, currentVersion, latestVersion);
106
+ return handleCheck(ctx, info, currentVersion, latestVersion);
145
107
  }
146
- // If the installation is not upgradeable (Docker or unknown), print instructions and exit.
108
+ // Non-upgradeable methods (docker, unknown): delegate to the shared summary helper, which is the SSOT for the version-table-plus-manual-instructions report.
109
+ // The InstallInfo union narrows on `!info.upgradeable` to expose manualUpgradeMessage; the consumer never switches on info.method.
147
110
  if (!info.upgradeable) {
148
- printUpgradeInfo(info, currentVersion, latestVersion);
149
- print("");
150
- if (info.method === "docker") {
151
- print("Docker containers cannot be upgraded in-place.");
152
- print("To upgrade, pull the latest image and recreate the container:");
153
- print(" " + info.upgradeCommand);
154
- }
155
- else {
156
- print("Unable to detect installation method. Please upgrade manually:");
157
- print(" " + info.upgradeCommand);
158
- }
111
+ printNonUpgradeableSummary(ctx, info, currentVersion, latestVersion);
159
112
  return 0;
160
113
  }
161
- // Check if already up to date (skip with --force or if version check failed).
114
+ // Already-current short-circuit: skip when --force is set or when we could not check the registry. Without --force, an indeterminate version check is fatal
115
+ // because we should not blindly run npm install when we can not see whether it would do anything.
162
116
  if (!force && latestVersion && !isVersionLessThan(currentVersion, latestVersion)) {
163
- print("PrismCast v" + currentVersion + " is already the latest version.");
164
- print("Use --force to upgrade anyway.");
117
+ ctx.stdout("PrismCast v" + currentVersion + " is already the latest version.");
118
+ ctx.stdout("Use --force to upgrade anyway.");
165
119
  return 0;
166
120
  }
167
- // If we couldn't check the latest version and --force wasn't specified, warn the user.
168
121
  if (!force && !latestVersion) {
169
- printError("Unable to check for updates. Run with --force to upgrade anyway.");
122
+ ctx.stderr("Unable to check for updates. Run with --force to upgrade anyway.");
170
123
  return 1;
171
124
  }
172
- // Show what we're about to do.
173
- print("Upgrading PrismCast...");
174
- print("Install method: " + formatMethodName(info));
175
- print("Running: " + info.upgradeCommand);
176
- print("");
177
- // Execute the upgrade.
178
- if (!executeUpgrade(info)) {
179
- printError("");
180
- printError("Upgrade failed. Check the output above for details.");
125
+ // Pre-upgrade announcement so the user knows what is about to run.
126
+ ctx.stdout("Upgrading PrismCast...");
127
+ ctx.stdout("Install method: " + info.displayName);
128
+ ctx.stdout("Running: " + info.upgradeCommand);
129
+ ctx.stdout("");
130
+ // Execute the upgrade. packageDir is set only by the npm-local strategy (it is the lone field in ResolvableFields and only npm-local declares a resolver),
131
+ // so reading it directly is sufficient - the runner uses it as cwd when present and falls back to process.cwd() when absent.
132
+ const result = ctx.runUpgradeCommand(info.upgradeCommand, { cwd: info.packageDir });
133
+ if (!result.success) {
134
+ ctx.stderr("");
135
+ ctx.stderr("Upgrade failed. Check the output above for details.");
181
136
  return 1;
182
137
  }
183
- print("");
184
- print("Upgrade complete.");
185
- // Handle restart: if running as a service, the service manager will restart PrismCast when we exit.
186
- if (isRunningAsService()) {
187
- print("Restarting PrismCast via service manager...");
188
- process.exit(0);
189
- }
190
- else {
191
- print("Please restart PrismCast manually to use the new version.");
138
+ ctx.stdout("");
139
+ ctx.stdout("Upgrade complete.");
140
+ // Service-managed processes restart automatically when we exit; manual installs need a user-driven restart.
141
+ if (ctx.isService) {
142
+ ctx.stdout("Restarting PrismCast via service manager...");
143
+ ctx.exit(0);
192
144
  }
145
+ ctx.stdout("Please restart PrismCast manually to use the new version.");
193
146
  return 0;
194
147
  }
195
148
  //# sourceMappingURL=commands.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/upgrade/commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/upgrade/commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { DetectionContext } from "./detection.ts";
2
+ /**
3
+ * Builds the default DetectionContext from real runtime I/O.
4
+ * @returns A DetectionContext populated from the live process.
5
+ */
6
+ export declare function createDefaultDetectionContext(): DetectionContext;
@@ -0,0 +1,24 @@
1
+ import { execSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { isRunningInContainer } from "../utils/platform.js";
4
+ import url from "node:url";
5
+ /**
6
+ * Builds the default DetectionContext from real runtime I/O.
7
+ * @returns A DetectionContext populated from the live process.
8
+ */
9
+ export function createDefaultDetectionContext() {
10
+ return {
11
+ currentFile: url.fileURLToPath(import.meta.url),
12
+ fileExists: existsSync,
13
+ isContainer: isRunningInContainer(),
14
+ runCommand: (cmd) => {
15
+ try {
16
+ return execSync(cmd, { encoding: "utf-8", timeout: 5000 }).trim();
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ }
22
+ };
23
+ }
24
+ //# sourceMappingURL=detection.context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detection.context.js","sourceRoot":"","sources":["../../src/upgrade/detection.context.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,GAAG,MAAM,UAAU,CAAC;AAE3B;;;GAGG;AACH,MAAM,UAAU,6BAA6B;IAE3C,OAAO;QAEL,WAAW,EAAE,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QAC/C,UAAU,EAAE,UAAU;QACtB,WAAW,EAAE,oBAAoB,EAAE;QACnC,UAAU,EAAE,CAAC,GAAW,EAAiB,EAAE;YAEzC,IAAI,CAAC;gBAEH,OAAO,QAAQ,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACpE,CAAC;YAAC,MAAM,CAAC;gBAEP,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,15 +1,145 @@
1
- export type InstallMethod = "docker" | "homebrew" | "npm-global" | "npm-local" | "unknown";
2
1
  /**
3
- * Information about the detected installation method and how to upgrade.
2
+ * The runtime context detection consumes. Each field is one narrow capability the decision logic depends on - the path of the running module, whether we are
3
+ * inside a Docker container, the ability to run a shell command and read its trimmed stdout, the ability to check that a path exists. Decision logic is a pure
4
+ * function of this shape; the default adapter wires it from real I/O, tests pass a context literal.
4
5
  */
5
- export interface InstallInfo {
6
- method: InstallMethod;
7
- packageDir?: string;
8
- upgradeCommand: string;
9
- upgradeable: boolean;
6
+ export interface DetectionContext {
7
+ readonly currentFile: string;
8
+ readonly fileExists: (path: string) => boolean;
9
+ readonly isContainer: boolean;
10
+ readonly runCommand: (cmd: string) => string | null;
10
11
  }
11
12
  /**
12
- * Detects how PrismCast was installed by examining the path of the running code. Detection order: Docker container, Homebrew, npm global, npm local, unknown.
13
- * @returns Installation information including method, whether it is upgradeable, and the appropriate upgrade command.
13
+ * The narrow set of InstallInfo fields a strategy's resolver may compute from the runtime context. Today there's only one - npm-local's packageDir, derived
14
+ * from the consumer's project root - but the dedicated type guarantees the resolver cannot accidentally override the strategy's constant fields. Adding a new
15
+ * resolvable field is an additive edit here; strategies opt in by declaring the field on their resolve return.
14
16
  */
15
- export declare function detectInstallMethod(): InstallInfo;
17
+ export interface ResolvableFields {
18
+ readonly packageDir?: string;
19
+ }
20
+ /**
21
+ * Common fields shared by every install strategy. Generic in the literal id type so each strategy declaration carries its own narrow id (e.g.,
22
+ * InstallStrategyBase<"docker">), which the registry then harvests into the RegisteredMethod literal union.
23
+ *
24
+ * Strategies own no state and perform no I/O outside what the context exposes.
25
+ */
26
+ interface InstallStrategyBase<M extends string = string> {
27
+ readonly displayName: string;
28
+ readonly id: M;
29
+ readonly matches: (ctx: DetectionContext) => boolean;
30
+ readonly resolve?: (ctx: DetectionContext) => ResolvableFields;
31
+ readonly upgradeCommand: string;
32
+ }
33
+ /**
34
+ * Strategy variant for install methods the tool can upgrade in place. The runner invokes upgradeCommand directly; no manual-instruction strings are needed.
35
+ */
36
+ export interface UpgradeableInstallStrategy<M extends string = string> extends InstallStrategyBase<M> {
37
+ readonly upgradeable: true;
38
+ }
39
+ /**
40
+ * Strategy variant for install methods the tool cannot upgrade in place. Carries manualUpgradeMessage - the user-facing prose lines that explain why the
41
+ * automated path is unavailable and what the user should do instead. The dispatcher copies this onto the resulting InstallInfo so the consumer (commands.ts)
42
+ * never has to switch on the install method to choose its messaging.
43
+ */
44
+ export interface NonUpgradeableInstallStrategy<M extends string = string> extends InstallStrategyBase<M> {
45
+ readonly manualUpgradeMessage: readonly string[];
46
+ readonly upgradeable: false;
47
+ }
48
+ /**
49
+ * Discriminated union of install-method strategies. Discriminator is `upgradeable`. Consumers narrow on it to access manualUpgradeMessage with type safety;
50
+ * structurally impossible to declare an upgradeable strategy that carries manual instructions or a non-upgradeable strategy that omits them.
51
+ */
52
+ export type InstallStrategy<M extends string = string> = UpgradeableInstallStrategy<M> | NonUpgradeableInstallStrategy<M>;
53
+ declare const STRATEGY_TUPLE: readonly [{
54
+ readonly displayName: "Docker";
55
+ readonly id: "docker";
56
+ readonly manualUpgradeMessage: readonly ["Docker containers cannot be upgraded in-place.", "To upgrade, pull the latest image and recreate the container:"];
57
+ readonly matches: (ctx: DetectionContext) => boolean;
58
+ readonly upgradeCommand: "docker pull ghcr.io/hjdhjd/prismcast:latest && docker compose up -d";
59
+ readonly upgradeable: false;
60
+ }, {
61
+ readonly displayName: "Homebrew";
62
+ readonly id: "homebrew";
63
+ readonly matches: (ctx: DetectionContext) => boolean;
64
+ readonly upgradeCommand: "brew update && brew upgrade prismcast";
65
+ readonly upgradeable: true;
66
+ }, {
67
+ readonly displayName: "npm (global)";
68
+ readonly id: "npm-global";
69
+ readonly matches: (ctx: DetectionContext) => boolean;
70
+ readonly upgradeCommand: "npm install -g prismcast@latest";
71
+ readonly upgradeable: true;
72
+ }, {
73
+ readonly displayName: "npm (local)";
74
+ readonly id: "npm-local";
75
+ readonly matches: (ctx: DetectionContext) => boolean;
76
+ readonly resolve: (ctx: DetectionContext) => ResolvableFields;
77
+ readonly upgradeCommand: "npm install prismcast@latest";
78
+ readonly upgradeable: true;
79
+ }];
80
+ /**
81
+ * The literal-union type of install method ids that strategies actually register for. Derived from the strategy tuple rather than declared in parallel - adding
82
+ * a strategy automatically widens this type, removing one is impossible without removing the strategy. There is no way for the type and the registry to drift.
83
+ */
84
+ export type RegisteredMethod = typeof STRATEGY_TUPLE[number]["id"];
85
+ /**
86
+ * The install-method strategy registry. Same runtime data as STRATEGY_TUPLE; the public name carries the wide InstallStrategy<RegisteredMethod> type so the
87
+ * dispatcher (and any future consumer that iterates) sees the union uniformly. Order is priority order: docker first (container probe is unambiguous), homebrew
88
+ * (path marker is unambiguous), npm-global (requires successful npm prefix lookup), npm-local (broader path marker). Adding a new install method is appending an
89
+ * entry to STRATEGY_TUPLE.
90
+ */
91
+ export declare const INSTALL_STRATEGIES: readonly InstallStrategy<RegisteredMethod>[];
92
+ /**
93
+ * The full install-method discriminator. Adds the unknown sentinel that the dispatcher returns when no strategy in the registry matches; everything else is
94
+ * registered. Consumers (e.g., commands.ts's switch on info.method) that need exhaustive coverage get it via this type.
95
+ */
96
+ export type InstallMethod = RegisteredMethod | "unknown";
97
+ /**
98
+ * Common fields shared by every InstallInfo variant. Mirrors InstallStrategyBase but with `method: InstallMethod` instead of `id: M`, and extends ResolvableFields
99
+ * so packageDir is optionally present on either variant.
100
+ */
101
+ interface InstallInfoBase extends ResolvableFields {
102
+ readonly displayName: string;
103
+ readonly method: InstallMethod;
104
+ readonly upgradeCommand: string;
105
+ }
106
+ /**
107
+ * InstallInfo variant for upgradeable install methods. The upgrade runner can invoke upgradeCommand directly.
108
+ */
109
+ export interface UpgradeableInstallInfo extends InstallInfoBase {
110
+ readonly upgradeable: true;
111
+ }
112
+ /**
113
+ * InstallInfo variant for non-upgradeable install methods. Carries manualUpgradeMessage - the prose lines printed before the indented upgradeCommand. The
114
+ * structural guarantee that manualUpgradeMessage exists exactly when upgradeable is false means consumers (commands.ts) can narrow on `!info.upgradeable` and
115
+ * read the message with type safety, rather than switching on info.method to pick the right messaging.
116
+ */
117
+ export interface NonUpgradeableInstallInfo extends InstallInfoBase {
118
+ readonly manualUpgradeMessage: readonly string[];
119
+ readonly upgradeable: false;
120
+ }
121
+ /**
122
+ * Information about the detected installation method and how to upgrade. Discriminated union over `upgradeable`; consumers narrow on it to choose between
123
+ * "run the command" and "print manual instructions" without ever switching on info.method.
124
+ */
125
+ export type InstallInfo = UpgradeableInstallInfo | NonUpgradeableInstallInfo;
126
+ /**
127
+ * The fallback InstallInfo returned when no strategy in the registry matches. Development builds, npx invocations, and unrecognized layouts land here. The
128
+ * upgrade command points at the canonical npm-global install path because that is the most likely successful manual upgrade, but upgradeable is false so the
129
+ * tool prints instructions rather than running the command.
130
+ */
131
+ export declare const UNKNOWN_INSTALL: NonUpgradeableInstallInfo;
132
+ /**
133
+ * Detects the installation method. Walks INSTALL_STRATEGIES in priority order; on the first match, builds an InstallInfo by composing the strategy's optional
134
+ * resolver output with the strategy's constant fields. The resolver's return type is restricted to ResolvableFields, so it cannot override id, displayName,
135
+ * upgradeCommand, or upgradeable; the spread order also places constants after the resolved fields as belt-and-suspenders. The strategy's `upgradeable`
136
+ * discriminator selects which InstallInfo variant the dispatcher emits, carrying manualUpgradeMessage through for the non-upgradeable case.
137
+ *
138
+ * Pure function of DetectionContext - all I/O happens inside the context's runCommand and fileExists callbacks, which the default adapter wires to real system
139
+ * calls and tests stub inline. Falls back to UNKNOWN_INSTALL when no strategy matches.
140
+ *
141
+ * @param ctx - The runtime context. Defaults to createDefaultDetectionContext() which builds one from real I/O.
142
+ * @returns Installation information.
143
+ */
144
+ export declare function detectInstallMethod(ctx?: DetectionContext): InstallInfo;
145
+ export {};