@wasmsoft/fantastic 1.0.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 (456) hide show
  1. package/README.md +65 -0
  2. package/bin/run.js +27 -0
  3. package/bin/supervisor.js +65 -0
  4. package/dist/acquire/central-url.d.ts +9 -0
  5. package/dist/acquire/central-url.d.ts.map +1 -0
  6. package/dist/acquire/central-url.js +74 -0
  7. package/dist/acquire/central-url.js.map +1 -0
  8. package/dist/acquire/code.d.ts +21 -0
  9. package/dist/acquire/code.d.ts.map +1 -0
  10. package/dist/acquire/code.js +66 -0
  11. package/dist/acquire/code.js.map +1 -0
  12. package/dist/acquire/compatibility.d.ts +18 -0
  13. package/dist/acquire/compatibility.d.ts.map +1 -0
  14. package/dist/acquire/compatibility.js +36 -0
  15. package/dist/acquire/compatibility.js.map +1 -0
  16. package/dist/acquire/fetch.d.ts +26 -0
  17. package/dist/acquire/fetch.d.ts.map +1 -0
  18. package/dist/acquire/fetch.js +72 -0
  19. package/dist/acquire/fetch.js.map +1 -0
  20. package/dist/acquire/latest.d.ts +24 -0
  21. package/dist/acquire/latest.d.ts.map +1 -0
  22. package/dist/acquire/latest.js +95 -0
  23. package/dist/acquire/latest.js.map +1 -0
  24. package/dist/backup/archive.d.ts +26 -0
  25. package/dist/backup/archive.d.ts.map +1 -0
  26. package/dist/backup/archive.js +123 -0
  27. package/dist/backup/archive.js.map +1 -0
  28. package/dist/backup/restore.d.ts +46 -0
  29. package/dist/backup/restore.d.ts.map +1 -0
  30. package/dist/backup/restore.js +164 -0
  31. package/dist/backup/restore.js.map +1 -0
  32. package/dist/base-command.d.ts +54 -0
  33. package/dist/base-command.d.ts.map +1 -0
  34. package/dist/base-command.js +120 -0
  35. package/dist/base-command.js.map +1 -0
  36. package/dist/bundle-format/index.d.ts +6 -0
  37. package/dist/bundle-format/index.d.ts.map +1 -0
  38. package/dist/bundle-format/index.js +36 -0
  39. package/dist/bundle-format/index.js.map +1 -0
  40. package/dist/commands/activate.d.ts +15 -0
  41. package/dist/commands/activate.d.ts.map +1 -0
  42. package/dist/commands/activate.js +139 -0
  43. package/dist/commands/activate.js.map +1 -0
  44. package/dist/commands/backup.d.ts +11 -0
  45. package/dist/commands/backup.d.ts.map +1 -0
  46. package/dist/commands/backup.js +75 -0
  47. package/dist/commands/backup.js.map +1 -0
  48. package/dist/commands/config/get.d.ts +10 -0
  49. package/dist/commands/config/get.d.ts.map +1 -0
  50. package/dist/commands/config/get.js +33 -0
  51. package/dist/commands/config/get.js.map +1 -0
  52. package/dist/commands/config/list.d.ts +7 -0
  53. package/dist/commands/config/list.d.ts.map +1 -0
  54. package/dist/commands/config/list.js +43 -0
  55. package/dist/commands/config/list.js.map +1 -0
  56. package/dist/commands/config/set.d.ts +11 -0
  57. package/dist/commands/config/set.d.ts.map +1 -0
  58. package/dist/commands/config/set.js +56 -0
  59. package/dist/commands/config/set.js.map +1 -0
  60. package/dist/commands/db/migrate.d.ts +10 -0
  61. package/dist/commands/db/migrate.d.ts.map +1 -0
  62. package/dist/commands/db/migrate.js +67 -0
  63. package/dist/commands/db/migrate.js.map +1 -0
  64. package/dist/commands/dev.d.ts +19 -0
  65. package/dist/commands/dev.d.ts.map +1 -0
  66. package/dist/commands/dev.js +149 -0
  67. package/dist/commands/dev.js.map +1 -0
  68. package/dist/commands/doctor.d.ts +11 -0
  69. package/dist/commands/doctor.d.ts.map +1 -0
  70. package/dist/commands/doctor.js +75 -0
  71. package/dist/commands/doctor.js.map +1 -0
  72. package/dist/commands/health.d.ts +12 -0
  73. package/dist/commands/health.d.ts.map +1 -0
  74. package/dist/commands/health.js +109 -0
  75. package/dist/commands/health.js.map +1 -0
  76. package/dist/commands/install.d.ts +60 -0
  77. package/dist/commands/install.d.ts.map +1 -0
  78. package/dist/commands/install.js +486 -0
  79. package/dist/commands/install.js.map +1 -0
  80. package/dist/commands/iptv/snapshot.d.ts +10 -0
  81. package/dist/commands/iptv/snapshot.d.ts.map +1 -0
  82. package/dist/commands/iptv/snapshot.js +55 -0
  83. package/dist/commands/iptv/snapshot.js.map +1 -0
  84. package/dist/commands/library/drives.d.ts +7 -0
  85. package/dist/commands/library/drives.d.ts.map +1 -0
  86. package/dist/commands/library/drives.js +71 -0
  87. package/dist/commands/library/drives.js.map +1 -0
  88. package/dist/commands/library/relink.d.ts +10 -0
  89. package/dist/commands/library/relink.d.ts.map +1 -0
  90. package/dist/commands/library/relink.js +72 -0
  91. package/dist/commands/library/relink.js.map +1 -0
  92. package/dist/commands/library/scan.d.ts +16 -0
  93. package/dist/commands/library/scan.d.ts.map +1 -0
  94. package/dist/commands/library/scan.js +87 -0
  95. package/dist/commands/library/scan.js.map +1 -0
  96. package/dist/commands/library/sections.d.ts +7 -0
  97. package/dist/commands/library/sections.d.ts.map +1 -0
  98. package/dist/commands/library/sections.js +33 -0
  99. package/dist/commands/library/sections.js.map +1 -0
  100. package/dist/commands/library/status.d.ts +7 -0
  101. package/dist/commands/library/status.d.ts.map +1 -0
  102. package/dist/commands/library/status.js +37 -0
  103. package/dist/commands/library/status.js.map +1 -0
  104. package/dist/commands/list.d.ts +7 -0
  105. package/dist/commands/list.d.ts.map +1 -0
  106. package/dist/commands/list.js +73 -0
  107. package/dist/commands/list.js.map +1 -0
  108. package/dist/commands/live/channels.d.ts +10 -0
  109. package/dist/commands/live/channels.d.ts.map +1 -0
  110. package/dist/commands/live/channels.js +55 -0
  111. package/dist/commands/live/channels.js.map +1 -0
  112. package/dist/commands/live/test.d.ts +15 -0
  113. package/dist/commands/live/test.d.ts.map +1 -0
  114. package/dist/commands/live/test.js +116 -0
  115. package/dist/commands/live/test.js.map +1 -0
  116. package/dist/commands/logs.d.ts +16 -0
  117. package/dist/commands/logs.d.ts.map +1 -0
  118. package/dist/commands/logs.js +77 -0
  119. package/dist/commands/logs.js.map +1 -0
  120. package/dist/commands/migrate-cli.d.ts +11 -0
  121. package/dist/commands/migrate-cli.d.ts.map +1 -0
  122. package/dist/commands/migrate-cli.js +116 -0
  123. package/dist/commands/migrate-cli.js.map +1 -0
  124. package/dist/commands/owner/reset.d.ts +7 -0
  125. package/dist/commands/owner/reset.d.ts.map +1 -0
  126. package/dist/commands/owner/reset.js +74 -0
  127. package/dist/commands/owner/reset.js.map +1 -0
  128. package/dist/commands/restart.d.ts +11 -0
  129. package/dist/commands/restart.d.ts.map +1 -0
  130. package/dist/commands/restart.js +53 -0
  131. package/dist/commands/restart.js.map +1 -0
  132. package/dist/commands/restore.d.ts +17 -0
  133. package/dist/commands/restore.d.ts.map +1 -0
  134. package/dist/commands/restore.js +148 -0
  135. package/dist/commands/restore.js.map +1 -0
  136. package/dist/commands/self-update.d.ts +10 -0
  137. package/dist/commands/self-update.d.ts.map +1 -0
  138. package/dist/commands/self-update.js +98 -0
  139. package/dist/commands/self-update.js.map +1 -0
  140. package/dist/commands/setup.d.ts +19 -0
  141. package/dist/commands/setup.d.ts.map +1 -0
  142. package/dist/commands/setup.js +111 -0
  143. package/dist/commands/setup.js.map +1 -0
  144. package/dist/commands/shell.d.ts +118 -0
  145. package/dist/commands/shell.d.ts.map +1 -0
  146. package/dist/commands/shell.js +415 -0
  147. package/dist/commands/shell.js.map +1 -0
  148. package/dist/commands/start.d.ts +12 -0
  149. package/dist/commands/start.d.ts.map +1 -0
  150. package/dist/commands/start.js +108 -0
  151. package/dist/commands/start.js.map +1 -0
  152. package/dist/commands/status.d.ts +8 -0
  153. package/dist/commands/status.d.ts.map +1 -0
  154. package/dist/commands/status.js +115 -0
  155. package/dist/commands/status.js.map +1 -0
  156. package/dist/commands/stop.d.ts +11 -0
  157. package/dist/commands/stop.d.ts.map +1 -0
  158. package/dist/commands/stop.js +45 -0
  159. package/dist/commands/stop.js.map +1 -0
  160. package/dist/commands/stream/cancel.d.ts +13 -0
  161. package/dist/commands/stream/cancel.d.ts.map +1 -0
  162. package/dist/commands/stream/cancel.js +31 -0
  163. package/dist/commands/stream/cancel.js.map +1 -0
  164. package/dist/commands/stream/encoders.d.ts +7 -0
  165. package/dist/commands/stream/encoders.d.ts.map +1 -0
  166. package/dist/commands/stream/encoders.js +42 -0
  167. package/dist/commands/stream/encoders.js.map +1 -0
  168. package/dist/commands/stream/queue.d.ts +7 -0
  169. package/dist/commands/stream/queue.d.ts.map +1 -0
  170. package/dist/commands/stream/queue.js +52 -0
  171. package/dist/commands/stream/queue.js.map +1 -0
  172. package/dist/commands/stream/sessions.d.ts +7 -0
  173. package/dist/commands/stream/sessions.d.ts.map +1 -0
  174. package/dist/commands/stream/sessions.js +44 -0
  175. package/dist/commands/stream/sessions.js.map +1 -0
  176. package/dist/commands/uninstall.d.ts +23 -0
  177. package/dist/commands/uninstall.d.ts.map +1 -0
  178. package/dist/commands/uninstall.js +290 -0
  179. package/dist/commands/uninstall.js.map +1 -0
  180. package/dist/commands/update.d.ts +21 -0
  181. package/dist/commands/update.d.ts.map +1 -0
  182. package/dist/commands/update.js +290 -0
  183. package/dist/commands/update.js.map +1 -0
  184. package/dist/commands/watch.d.ts +10 -0
  185. package/dist/commands/watch.d.ts.map +1 -0
  186. package/dist/commands/watch.js +38 -0
  187. package/dist/commands/watch.js.map +1 -0
  188. package/dist/config/local-config.d.ts +22 -0
  189. package/dist/config/local-config.d.ts.map +1 -0
  190. package/dist/config/local-config.js +79 -0
  191. package/dist/config/local-config.js.map +1 -0
  192. package/dist/core-scripts/run.d.ts +22 -0
  193. package/dist/core-scripts/run.d.ts.map +1 -0
  194. package/dist/core-scripts/run.js +65 -0
  195. package/dist/core-scripts/run.js.map +1 -0
  196. package/dist/doctor/check.types.d.ts +51 -0
  197. package/dist/doctor/check.types.d.ts.map +1 -0
  198. package/dist/doctor/check.types.js +14 -0
  199. package/dist/doctor/check.types.js.map +1 -0
  200. package/dist/doctor/checks/core.check.d.ts +11 -0
  201. package/dist/doctor/checks/core.check.d.ts.map +1 -0
  202. package/dist/doctor/checks/core.check.js +104 -0
  203. package/dist/doctor/checks/core.check.js.map +1 -0
  204. package/dist/doctor/checks/data.check.d.ts +11 -0
  205. package/dist/doctor/checks/data.check.d.ts.map +1 -0
  206. package/dist/doctor/checks/data.check.js +70 -0
  207. package/dist/doctor/checks/data.check.js.map +1 -0
  208. package/dist/doctor/checks/environment.check.d.ts +6 -0
  209. package/dist/doctor/checks/environment.check.d.ts.map +1 -0
  210. package/dist/doctor/checks/environment.check.js +70 -0
  211. package/dist/doctor/checks/environment.check.js.map +1 -0
  212. package/dist/doctor/checks/integrity.check.d.ts +4 -0
  213. package/dist/doctor/checks/integrity.check.d.ts.map +1 -0
  214. package/dist/doctor/checks/integrity.check.js +89 -0
  215. package/dist/doctor/checks/integrity.check.js.map +1 -0
  216. package/dist/doctor/checks/isolation.check.d.ts +49 -0
  217. package/dist/doctor/checks/isolation.check.d.ts.map +1 -0
  218. package/dist/doctor/checks/isolation.check.js +220 -0
  219. package/dist/doctor/checks/isolation.check.js.map +1 -0
  220. package/dist/doctor/checks/licence.check.d.ts +8 -0
  221. package/dist/doctor/checks/licence.check.d.ts.map +1 -0
  222. package/dist/doctor/checks/licence.check.js +172 -0
  223. package/dist/doctor/checks/licence.check.js.map +1 -0
  224. package/dist/doctor/checks/ports.check.d.ts +4 -0
  225. package/dist/doctor/checks/ports.check.d.ts.map +1 -0
  226. package/dist/doctor/checks/ports.check.js +52 -0
  227. package/dist/doctor/checks/ports.check.js.map +1 -0
  228. package/dist/doctor/checks/supervisor.check.d.ts +19 -0
  229. package/dist/doctor/checks/supervisor.check.d.ts.map +1 -0
  230. package/dist/doctor/checks/supervisor.check.js +152 -0
  231. package/dist/doctor/checks/supervisor.check.js.map +1 -0
  232. package/dist/doctor/checks/tooling.check.d.ts +3 -0
  233. package/dist/doctor/checks/tooling.check.d.ts.map +1 -0
  234. package/dist/doctor/checks/tooling.check.js +43 -0
  235. package/dist/doctor/checks/tooling.check.js.map +1 -0
  236. package/dist/doctor/registry.d.ts +15 -0
  237. package/dist/doctor/registry.d.ts.map +1 -0
  238. package/dist/doctor/registry.js +53 -0
  239. package/dist/doctor/registry.js.map +1 -0
  240. package/dist/exit-codes.d.ts +18 -0
  241. package/dist/exit-codes.d.ts.map +1 -0
  242. package/dist/exit-codes.js +23 -0
  243. package/dist/exit-codes.js.map +1 -0
  244. package/dist/index.d.ts +2 -0
  245. package/dist/index.d.ts.map +1 -0
  246. package/dist/index.js +16 -0
  247. package/dist/index.js.map +1 -0
  248. package/dist/logs/sink.d.ts +11 -0
  249. package/dist/logs/sink.d.ts.map +1 -0
  250. package/dist/logs/sink.js +73 -0
  251. package/dist/logs/sink.js.map +1 -0
  252. package/dist/logs/tail.d.ts +17 -0
  253. package/dist/logs/tail.d.ts.map +1 -0
  254. package/dist/logs/tail.js +98 -0
  255. package/dist/logs/tail.js.map +1 -0
  256. package/dist/packaging/boot-task.d.ts +56 -0
  257. package/dist/packaging/boot-task.d.ts.map +1 -0
  258. package/dist/packaging/boot-task.js +151 -0
  259. package/dist/packaging/boot-task.js.map +1 -0
  260. package/dist/packaging/install.d.ts +154 -0
  261. package/dist/packaging/install.d.ts.map +1 -0
  262. package/dist/packaging/install.js +381 -0
  263. package/dist/packaging/install.js.map +1 -0
  264. package/dist/packaging/layout.d.ts +153 -0
  265. package/dist/packaging/layout.d.ts.map +1 -0
  266. package/dist/packaging/layout.js +168 -0
  267. package/dist/packaging/layout.js.map +1 -0
  268. package/dist/packaging/machine-path.d.ts +52 -0
  269. package/dist/packaging/machine-path.d.ts.map +1 -0
  270. package/dist/packaging/machine-path.js +237 -0
  271. package/dist/packaging/machine-path.js.map +1 -0
  272. package/dist/packaging/manifest.d.ts +37 -0
  273. package/dist/packaging/manifest.d.ts.map +1 -0
  274. package/dist/packaging/manifest.js +115 -0
  275. package/dist/packaging/manifest.js.map +1 -0
  276. package/dist/packaging/shims.d.ts +31 -0
  277. package/dist/packaging/shims.d.ts.map +1 -0
  278. package/dist/packaging/shims.js +165 -0
  279. package/dist/packaging/shims.js.map +1 -0
  280. package/dist/probes/internal-paths.d.ts +35 -0
  281. package/dist/probes/internal-paths.d.ts.map +1 -0
  282. package/dist/probes/internal-paths.js +58 -0
  283. package/dist/probes/internal-paths.js.map +1 -0
  284. package/dist/probes/internal.client.d.ts +54 -0
  285. package/dist/probes/internal.client.d.ts.map +1 -0
  286. package/dist/probes/internal.client.js +123 -0
  287. package/dist/probes/internal.client.js.map +1 -0
  288. package/dist/probes/port.probe.d.ts +21 -0
  289. package/dist/probes/port.probe.d.ts.map +1 -0
  290. package/dist/probes/port.probe.js +42 -0
  291. package/dist/probes/port.probe.js.map +1 -0
  292. package/dist/probes/service.probe.d.ts +29 -0
  293. package/dist/probes/service.probe.d.ts.map +1 -0
  294. package/dist/probes/service.probe.js +65 -0
  295. package/dist/probes/service.probe.js.map +1 -0
  296. package/dist/profiles/appliance.profile.d.ts +20 -0
  297. package/dist/profiles/appliance.profile.d.ts.map +1 -0
  298. package/dist/profiles/appliance.profile.js +137 -0
  299. package/dist/profiles/appliance.profile.js.map +1 -0
  300. package/dist/profiles/dev.profile.d.ts +22 -0
  301. package/dist/profiles/dev.profile.d.ts.map +1 -0
  302. package/dist/profiles/dev.profile.js +104 -0
  303. package/dist/profiles/dev.profile.js.map +1 -0
  304. package/dist/profiles/resolve.d.ts +37 -0
  305. package/dist/profiles/resolve.d.ts.map +1 -0
  306. package/dist/profiles/resolve.js +198 -0
  307. package/dist/profiles/resolve.js.map +1 -0
  308. package/dist/profiles/types.d.ts +57 -0
  309. package/dist/profiles/types.d.ts.map +1 -0
  310. package/dist/profiles/types.js +15 -0
  311. package/dist/profiles/types.js.map +1 -0
  312. package/dist/registry/local-registry.d.ts +79 -0
  313. package/dist/registry/local-registry.d.ts.map +1 -0
  314. package/dist/registry/local-registry.js +252 -0
  315. package/dist/registry/local-registry.js.map +1 -0
  316. package/dist/render/banner.d.ts +13 -0
  317. package/dist/render/banner.d.ts.map +1 -0
  318. package/dist/render/banner.js +83 -0
  319. package/dist/render/banner.js.map +1 -0
  320. package/dist/render/boot.render.d.ts +123 -0
  321. package/dist/render/boot.render.d.ts.map +1 -0
  322. package/dist/render/boot.render.js +288 -0
  323. package/dist/render/boot.render.js.map +1 -0
  324. package/dist/render/brand.d.ts +16 -0
  325. package/dist/render/brand.d.ts.map +1 -0
  326. package/dist/render/brand.js +22 -0
  327. package/dist/render/brand.js.map +1 -0
  328. package/dist/render/doctor.render.d.ts +12 -0
  329. package/dist/render/doctor.render.d.ts.map +1 -0
  330. package/dist/render/doctor.render.js +95 -0
  331. package/dist/render/doctor.render.js.map +1 -0
  332. package/dist/render/json.d.ts +29 -0
  333. package/dist/render/json.d.ts.map +1 -0
  334. package/dist/render/json.js +19 -0
  335. package/dist/render/json.js.map +1 -0
  336. package/dist/render/licence.render.d.ts +10 -0
  337. package/dist/render/licence.render.d.ts.map +1 -0
  338. package/dist/render/licence.render.js +167 -0
  339. package/dist/render/licence.render.js.map +1 -0
  340. package/dist/render/status.render.d.ts +6 -0
  341. package/dist/render/status.render.d.ts.map +1 -0
  342. package/dist/render/status.render.js +52 -0
  343. package/dist/render/status.render.js.map +1 -0
  344. package/dist/render/theme.d.ts +66 -0
  345. package/dist/render/theme.d.ts.map +1 -0
  346. package/dist/render/theme.js +89 -0
  347. package/dist/render/theme.js.map +1 -0
  348. package/dist/runtime-guard.d.ts +19 -0
  349. package/dist/runtime-guard.d.ts.map +1 -0
  350. package/dist/runtime-guard.js +57 -0
  351. package/dist/runtime-guard.js.map +1 -0
  352. package/dist/shell/input-mode.d.ts +25 -0
  353. package/dist/shell/input-mode.d.ts.map +1 -0
  354. package/dist/shell/input-mode.js +17 -0
  355. package/dist/shell/input-mode.js.map +1 -0
  356. package/dist/shell/parse-line.d.ts +6 -0
  357. package/dist/shell/parse-line.d.ts.map +1 -0
  358. package/dist/shell/parse-line.js +62 -0
  359. package/dist/shell/parse-line.js.map +1 -0
  360. package/dist/shell/suggestions.d.ts +14 -0
  361. package/dist/shell/suggestions.d.ts.map +1 -0
  362. package/dist/shell/suggestions.js +35 -0
  363. package/dist/shell/suggestions.js.map +1 -0
  364. package/dist/supervisor/dependencies.d.ts +2 -0
  365. package/dist/supervisor/dependencies.d.ts.map +1 -0
  366. package/dist/supervisor/dependencies.js +38 -0
  367. package/dist/supervisor/dependencies.js.map +1 -0
  368. package/dist/supervisor/entry.d.ts +36 -0
  369. package/dist/supervisor/entry.d.ts.map +1 -0
  370. package/dist/supervisor/entry.js +171 -0
  371. package/dist/supervisor/entry.js.map +1 -0
  372. package/dist/supervisor/inspect.d.ts +17 -0
  373. package/dist/supervisor/inspect.d.ts.map +1 -0
  374. package/dist/supervisor/inspect.js +39 -0
  375. package/dist/supervisor/inspect.js.map +1 -0
  376. package/dist/supervisor/invocation.d.ts +27 -0
  377. package/dist/supervisor/invocation.d.ts.map +1 -0
  378. package/dist/supervisor/invocation.js +33 -0
  379. package/dist/supervisor/invocation.js.map +1 -0
  380. package/dist/supervisor/monitor.d.ts +63 -0
  381. package/dist/supervisor/monitor.d.ts.map +1 -0
  382. package/dist/supervisor/monitor.js +141 -0
  383. package/dist/supervisor/monitor.js.map +1 -0
  384. package/dist/supervisor/orchestrator.d.ts +52 -0
  385. package/dist/supervisor/orchestrator.d.ts.map +1 -0
  386. package/dist/supervisor/orchestrator.js +154 -0
  387. package/dist/supervisor/orchestrator.js.map +1 -0
  388. package/dist/supervisor/pidfile.d.ts +21 -0
  389. package/dist/supervisor/pidfile.d.ts.map +1 -0
  390. package/dist/supervisor/pidfile.js +39 -0
  391. package/dist/supervisor/pidfile.js.map +1 -0
  392. package/dist/supervisor/process-identity.d.ts +19 -0
  393. package/dist/supervisor/process-identity.d.ts.map +1 -0
  394. package/dist/supervisor/process-identity.js +51 -0
  395. package/dist/supervisor/process-identity.js.map +1 -0
  396. package/dist/supervisor/readiness.d.ts +17 -0
  397. package/dist/supervisor/readiness.d.ts.map +1 -0
  398. package/dist/supervisor/readiness.js +52 -0
  399. package/dist/supervisor/readiness.js.map +1 -0
  400. package/dist/supervisor/restart-consumer.d.ts +37 -0
  401. package/dist/supervisor/restart-consumer.d.ts.map +1 -0
  402. package/dist/supervisor/restart-consumer.js +119 -0
  403. package/dist/supervisor/restart-consumer.js.map +1 -0
  404. package/dist/supervisor/runner.d.ts +2 -0
  405. package/dist/supervisor/runner.d.ts.map +1 -0
  406. package/dist/supervisor/runner.js +118 -0
  407. package/dist/supervisor/runner.js.map +1 -0
  408. package/dist/supervisor/schedule-timer.d.ts +38 -0
  409. package/dist/supervisor/schedule-timer.d.ts.map +1 -0
  410. package/dist/supervisor/schedule-timer.js +148 -0
  411. package/dist/supervisor/schedule-timer.js.map +1 -0
  412. package/dist/supervisor/spawn.d.ts +18 -0
  413. package/dist/supervisor/spawn.d.ts.map +1 -0
  414. package/dist/supervisor/spawn.js +119 -0
  415. package/dist/supervisor/spawn.js.map +1 -0
  416. package/dist/supervisor/state-files.d.ts +33 -0
  417. package/dist/supervisor/state-files.d.ts.map +1 -0
  418. package/dist/supervisor/state-files.js +110 -0
  419. package/dist/supervisor/state-files.js.map +1 -0
  420. package/dist/supervisor/tree-kill.d.ts +14 -0
  421. package/dist/supervisor/tree-kill.d.ts.map +1 -0
  422. package/dist/supervisor/tree-kill.js +82 -0
  423. package/dist/supervisor/tree-kill.js.map +1 -0
  424. package/dist/ui/health-panel.d.ts +8 -0
  425. package/dist/ui/health-panel.d.ts.map +1 -0
  426. package/dist/ui/health-panel.js +91 -0
  427. package/dist/ui/health-panel.js.map +1 -0
  428. package/dist/updating/apply.d.ts +50 -0
  429. package/dist/updating/apply.d.ts.map +1 -0
  430. package/dist/updating/apply.js +172 -0
  431. package/dist/updating/apply.js.map +1 -0
  432. package/dist/updating/download.d.ts +44 -0
  433. package/dist/updating/download.d.ts.map +1 -0
  434. package/dist/updating/download.js +144 -0
  435. package/dist/updating/download.js.map +1 -0
  436. package/dist/updating/rollback.d.ts +33 -0
  437. package/dist/updating/rollback.d.ts.map +1 -0
  438. package/dist/updating/rollback.js +54 -0
  439. package/dist/updating/rollback.js.map +1 -0
  440. package/dist/updating/self.d.ts +16 -0
  441. package/dist/updating/self.d.ts.map +1 -0
  442. package/dist/updating/self.js +50 -0
  443. package/dist/updating/self.js.map +1 -0
  444. package/dist/updating/verify.d.ts +25 -0
  445. package/dist/updating/verify.d.ts.map +1 -0
  446. package/dist/updating/verify.js +51 -0
  447. package/dist/updating/verify.js.map +1 -0
  448. package/dist/updating/versions.d.ts +31 -0
  449. package/dist/updating/versions.d.ts.map +1 -0
  450. package/dist/updating/versions.js +78 -0
  451. package/dist/updating/versions.js.map +1 -0
  452. package/dist/version.d.ts +4 -0
  453. package/dist/version.d.ts.map +1 -0
  454. package/dist/version.js +29 -0
  455. package/dist/version.js.map +1 -0
  456. package/package.json +106 -0
@@ -0,0 +1,37 @@
1
+ import type { RestartRequestFile, RestartScope } from "../contracts/core.js";
2
+ import type { Profile, ServiceName } from "../profiles/types.js";
3
+ /**
4
+ * AR: يترجم نطاقًا إلى الخدمات التي يشملها، أو ‎undefined‎ ليعني «كلّ ما في ملفّ التشغيل بترتيبه».
5
+ * **القائمة الشاملة لا تُكتب يدويًا**: الجهاز خدمتان والمستودع ثلاث، وقائمةٌ ثابتة هنا كانت
6
+ * ستحاول إعادة تشغيل واجهةٍ لا وجود لها على الجهاز فتُبلّغ فشلًا كاذبًا.
7
+ * EN: Translates a scope into the services it covers, or `undefined` meaning "everything in the
8
+ * profile, in its order". **The catch-all list is not written by hand**: the appliance has two
9
+ * services and the repository three, and a fixed list here would try to restart a portal that
10
+ * does not exist on the appliance and report a false failure.
11
+ */
12
+ export declare function servicesForScope(scope: RestartScope): ServiceName[] | undefined;
13
+ export interface RestartExecution {
14
+ scope: RestartScope;
15
+ reason: RestartRequestFile["reason"];
16
+ ok: boolean;
17
+ detail: string;
18
+ }
19
+ export interface ConsumeOptions {
20
+ /**
21
+ * AR: يُسأل قبل التنفيذ حين يطلب الطلب تأجيلًا (‎force:false‎ وجدولٌ يحترم المشاهدين). يعيد
22
+ * سببًا عربيًّا للتأجيل، أو ‎null‎ للمضيّ. المشرف لا يعرف من يشاهد — النواة تعرف — فيُحقن.
23
+ * EN: Asked before executing when the request permits deferral (`force:false` on a schedule that
24
+ * respects viewers). Returns an Arabic reason to defer, or `null` to proceed. The supervisor
25
+ * does not know who is watching — the core does — so it is injected.
26
+ */
27
+ deferIf?: () => Promise<string | null>;
28
+ onEvent?: (message: string) => void;
29
+ }
30
+ /**
31
+ * AR: يستهلك الطلب المعلّق إن وُجد وينفّذه. يعيد ‎null‎ حين لا طلب — وهي الحالة الغالبة في كل جولة.
32
+ * EN: Consumes the pending request if there is one and executes it. Returns `null` when there is no
33
+ * request — which is the usual case on every round.
34
+ */
35
+ export declare function consumeRestartRequest(profile: Profile, options?: ConsumeOptions): Promise<RestartExecution | null>;
36
+ export declare function executeRestart(profile: Profile, request: RestartRequestFile, options?: ConsumeOptions): Promise<RestartExecution>;
37
+ //# sourceMappingURL=restart-consumer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restart-consumer.d.ts","sourceRoot":"","sources":["../../src/supervisor/restart-consumer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAsB,kBAAkB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AA+BjE;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,WAAW,EAAE,GAAG,SAAS,CAG/E;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACrC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACvC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAKlC;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,kBAAkB,EAC3B,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CA4B3B"}
@@ -0,0 +1,119 @@
1
+ import { execa } from "execa";
2
+ import { restartServices } from "./orchestrator.js";
3
+ import { REMOTE_STATE_FILES, takeStateJson, writeStateJson } from "./state-files.js";
4
+ // AR: تنفيذ طلب إعادة التشغيل (٠٢٠/US1، US2).
5
+ //
6
+ // **هنا وحده يقع الفعل.** النواة تكتب طلبًا، وهذا الملف — الذي يعيش في عملية تنجو من موتها —
7
+ // ينفّذه. الاتجاه مقصود ولا يُعكَس: النواة لا تملك ‎spawn‎ ولا ‎taskkill‎ ولا ‎shutdown‎
8
+ // (يحرسه ‎core-never-restarts-itself.spec.ts‎).
9
+ //
10
+ // **والنتيجة تُكتب بعد التنفيذ لا قبله.** «آخر إعادة تشغيل» في لوحة المالك يجب أن تعني «وقعت»
11
+ // لا «طُلبت»: طلبٌ فشل تنفيذه ثم عُرض كنجاح هو أسوأ من غياب السطر أصلًا، لأنه يغلق التحقيق.
12
+ //
13
+ // **و‎machine‎ حالة خاصة تُكتَب نتيجتها قبل الأمر.** بعد ‎shutdown /r‎ لا يبقى شيء ليكتب:
14
+ // العملية تموت مع الآلة. فتُكتب أولًا، وتُصحَّح ضمنًا إن فشل الأمر (نبقى أحياء فنكتب الفشل).
15
+ //
16
+ // EN: Executing a restart request (020/US1, US2).
17
+ //
18
+ // **This is the only place the act happens.** The core writes a request, and this file — living
19
+ // in a process that outlives it — carries it out. The direction is deliberate and never
20
+ // reversed: the core holds no `spawn`, no `taskkill` and no `shutdown` (guarded by
21
+ // `core-never-restarts-itself.spec.ts`).
22
+ //
23
+ // **And the outcome is written after the act, not before.** "Last restart" in the owner's panel
24
+ // must mean "it happened", not "it was asked for": a request that failed and was then shown as a
25
+ // success is worse than no line at all, because it closes the investigation.
26
+ //
27
+ // **`machine` is the one case whose outcome is written first.** After `shutdown /r` there is
28
+ // nothing left to write with: the process dies with the machine. So it is written first, and
29
+ // implicitly corrected if the command fails (we are still alive, so we write the failure).
30
+ /**
31
+ * AR: يترجم نطاقًا إلى الخدمات التي يشملها، أو ‎undefined‎ ليعني «كلّ ما في ملفّ التشغيل بترتيبه».
32
+ * **القائمة الشاملة لا تُكتب يدويًا**: الجهاز خدمتان والمستودع ثلاث، وقائمةٌ ثابتة هنا كانت
33
+ * ستحاول إعادة تشغيل واجهةٍ لا وجود لها على الجهاز فتُبلّغ فشلًا كاذبًا.
34
+ * EN: Translates a scope into the services it covers, or `undefined` meaning "everything in the
35
+ * profile, in its order". **The catch-all list is not written by hand**: the appliance has two
36
+ * services and the repository three, and a fixed list here would try to restart a portal that
37
+ * does not exist on the appliance and report a false failure.
38
+ */
39
+ export function servicesForScope(scope) {
40
+ if (scope === "machine" || scope === "services")
41
+ return undefined;
42
+ return [scope];
43
+ }
44
+ /**
45
+ * AR: يستهلك الطلب المعلّق إن وُجد وينفّذه. يعيد ‎null‎ حين لا طلب — وهي الحالة الغالبة في كل جولة.
46
+ * EN: Consumes the pending request if there is one and executes it. Returns `null` when there is no
47
+ * request — which is the usual case on every round.
48
+ */
49
+ export async function consumeRestartRequest(profile, options = {}) {
50
+ const request = takeStateJson(profile, REMOTE_STATE_FILES.restartRequest);
51
+ if (!request)
52
+ return null;
53
+ return executeRestart(profile, request, options);
54
+ }
55
+ export async function executeRestart(profile, request, options = {}) {
56
+ if (!request.force && options.deferIf) {
57
+ const reason = await options.deferIf();
58
+ if (reason) {
59
+ // AR: **يُعاد كتابة الطلب** لا يُهمَل: التأجيل يعني «لاحقًا» لا «أُلغي». وإسقاطه هنا كان
60
+ // سيجعل جدولًا يوميًّا يفقد جولته كاملة لأن ضيفًا شاهد دقيقتين.
61
+ // EN: **The request is written back** rather than dropped: a deferral means "later", not
62
+ // "cancelled". Dropping it here would make a daily schedule lose its whole round because
63
+ // one guest watched for two minutes.
64
+ writeStateJson(profile, REMOTE_STATE_FILES.restartRequest, request);
65
+ options.onEvent?.(`deferred (${reason})`);
66
+ return { scope: request.scope, reason: request.reason, ok: false, detail: `deferred — ${reason}` };
67
+ }
68
+ }
69
+ if (request.scope === "machine")
70
+ return restartMachine(profile, request, options);
71
+ const { started } = await restartServices(profile, { only: servicesForScope(request.scope) });
72
+ const ok = started.ok;
73
+ const detail = ok
74
+ ? `restarted ${request.scope}`
75
+ : `failed to restart ${request.scope}: ${started.steps.find((step) => step.status === "failed")?.readiness?.reason ?? "unknown reason"}`;
76
+ if (ok)
77
+ recordOutcome(profile, request);
78
+ options.onEvent?.(detail);
79
+ return { scope: request.scope, reason: request.reason, ok, detail };
80
+ }
81
+ /**
82
+ * AR: يعيد تشغيل الآلة. **الأمر الوحيد في المستودع كلّه الذي يُطفئ عتادًا**، ولذلك يعيش هنا وحده
83
+ * وخلف بوّابتين سبقتاه: النواة رفضت الطلب أصلًا ما لم تكن مهمة الإقلاع مسجَّلة، والواجهة عطّلت
84
+ * الزرّ بالسبب نفسه. المهلة عشر ثوانٍ تعطي الخدمات فرصة الإغلاق النظيف قبل أن يقطع ويندوز.
85
+ * EN: Restarts the machine. **The only command in the whole repository that powers hardware down**,
86
+ * which is why it lives here alone and behind two gates that came before it: the core refused
87
+ * the request unless a boot task is registered, and the portal disabled the button for the same
88
+ * reason. The ten-second delay gives the services a chance to close cleanly before Windows cuts
89
+ * them off.
90
+ */
91
+ async function restartMachine(profile, request, options) {
92
+ if (process.platform !== "win32") {
93
+ const detail = "a machine restart is only supported on Windows";
94
+ options.onEvent?.(detail);
95
+ return { scope: request.scope, reason: request.reason, ok: false, detail };
96
+ }
97
+ // تُكتب قبل الأمر: بعده لا تبقى عملية تكتب. وإن فشل الأمر بقينا أحياء فصحّحنا السطر بأنفسنا.
98
+ recordOutcome(profile, request);
99
+ try {
100
+ await execa("shutdown", ["/r", "/t", "10", "/c", "Fantastic scheduled restart"], { windowsHide: true });
101
+ options.onEvent?.("the machine restarts in 10 seconds");
102
+ return { scope: request.scope, reason: request.reason, ok: true, detail: "machine restart requested" };
103
+ }
104
+ catch (error) {
105
+ const detail = `the machine restart was refused: ${error instanceof Error ? error.message : String(error)}`;
106
+ options.onEvent?.(detail);
107
+ return { scope: request.scope, reason: request.reason, ok: false, detail };
108
+ }
109
+ }
110
+ /** يكتب ما وقع فعلًا. تقرؤه النواة لتعرض «آخر إعادة تشغيل» بلا أن تفترضها عن نفسها. */
111
+ function recordOutcome(profile, request) {
112
+ const outcome = {
113
+ at: new Date().toISOString(),
114
+ scope: request.scope,
115
+ reason: request.reason,
116
+ };
117
+ writeStateJson(profile, REMOTE_STATE_FILES.restartOutcome, outcome);
118
+ }
119
+ //# sourceMappingURL=restart-consumer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restart-consumer.js","sourceRoot":"","sources":["../../src/supervisor/restart-consumer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/supervisor/runner.ts"],"names":[],"mappings":""}
@@ -0,0 +1,118 @@
1
+ import { spawn } from "node:child_process";
2
+ import { StringDecoder } from "node:string_decoder";
3
+ import stripAnsi from "strip-ansi";
4
+ import { LAUNCH_PAYLOAD_ENV, resolveInvocation } from "./invocation.js";
5
+ // AR: المشرف الصغير الذي يقف بين الـ CLI والخدمة. عملية واحدة لكل خدمة، لا تفعل شيئًا سوى إطلاقها
6
+ // وتمرير مخرجها إلى ملف السجلّ ثم الموت معها.
7
+ //
8
+ // **لماذا يوجد أصلًا؟ مقياس على ويندوز، لا تجميل.** كان الـ CLI يُطلق كل خدمة بـ ‎detached‎،
9
+ // ومعناها على ويندوز ‎DETACHED_PROCESS‎: عملية **بلا كونسول**. و‎npm run‎ يشغّل سكربت الحزمة عبر
10
+ // ‎cmd.exe‎، وتطبيق كونسول يولده أبٌ بلا كونسول يحصل على **كونسول جديد بنافذة مرئية**. فكانت
11
+ // ثلاث نوافذ سوداء تفتح مع كل ‎fantastic start‎ — ولأن النافذة تملك الكونسول، إغلاق أيّ منها
12
+ // يرسل ‎CTRL_CLOSE_EVENT‎ إلى كل ما هو موصول به، فتموت الخدمة كلها بسحبة فأرة.
13
+ //
14
+ // المخرج الوحيد الذي يتيحه Node: ‎windowsHide‎ يترجَم إلى ‎CREATE_NO_WINDOW‎، وهذا العَلَم يعطي
15
+ // العملية **كونسولًا بلا نافذة** حين يكون أبوها بلا كونسول — وترثه كل ذريّتها، بما فيها
16
+ // ‎cmd.exe‎. لكن libuv يتجاهل العَلَم إذا كان أيّ من الأنابيب واصفَ ملف موروثًا، وDETACHED_PROCESS
17
+ // يتقدّم عليه أصلًا. فلا سبيل إلى الجمع بين «ينجو من إغلاق الطرفية» و«بلا نافذة» في إطلاق واحد.
18
+ //
19
+ // فالإطلاق طبقتان: الـ CLI يُطلق **هذا الملف** منفصلًا (بلا كونسول، ينجو)، وهذا الملف يُطلق
20
+ // الخدمة بأنابيب و‎windowsHide‎ (كونسول بلا نافذة، ترثه الذرّية). قِيس: صفر نوافذ، والشجرة كاملة
21
+ // تبقى حيّة بعد إغلاق نافذة الإطلاق.
22
+ // EN: The small supervisor that sits between the CLI and a service. One process per service, doing
23
+ // nothing but launching it, forwarding its output to the log file, and dying with it.
24
+ //
25
+ // **Why it exists at all — measured on Windows, not decoration.** The CLI used to launch each
26
+ // service `detached`, which on Windows means DETACHED_PROCESS: a process with **no console**.
27
+ // `npm run` runs the package script through cmd.exe, and a console application spawned by a
28
+ // console-less parent gets a **brand-new console with a visible window**. So three black windows
29
+ // opened on every `fantastic start` — and because the window owns the console, closing any one of
30
+ // them sends CTRL_CLOSE_EVENT to everything attached to it, killing the whole service with a
31
+ // mouse click.
32
+ //
33
+ // The only lever Node exposes: `windowsHide` maps to CREATE_NO_WINDOW, and that flag gives a
34
+ // process **a console with no window** when its parent has no console — which its entire
35
+ // descendancy inherits, cmd.exe included. But libuv skips the flag if any stdio entry is an
36
+ // inherited file descriptor, and DETACHED_PROCESS overrides it regardless. So "survives the
37
+ // terminal closing" and "draws no window" cannot be had in a single spawn.
38
+ //
39
+ // Hence two layers: the CLI launches **this file** detached (no console, survives), and this file
40
+ // launches the service with pipes and `windowsHide` (windowless console, inherited by the tree).
41
+ // Measured: zero windows, and the whole tree stays alive after the launching window closes.
42
+ /** يكتب سطرًا إلى ملف السجلّ. مخرَجنا القياسي **هو** واصف ملف السجلّ، ورّثه إيّانا الـ CLI. */
43
+ function write(line) {
44
+ process.stdout.write(`${line}\n`);
45
+ }
46
+ /**
47
+ * يجمّع القطع في أسطر كاملة قبل الكتابة. الأنبوب يقطع حيث شاء، وسطر سجلّ منقطع في منتصفه غير قابل
48
+ * للبحث. ويُجرَّد من ANSI هنا: هذه الطبقة هي أول موضع في التاريخ يمكنه ذلك — الإطلاق المباشر إلى
49
+ * واصف ملف لم يكن يمرّ بأحد.
50
+ *
51
+ * ‎StringDecoder‎ لا ‎chunk.toString()‎: سجلات النواة عربية، والحرف العربي بايتان في UTF-8. والأنبوب
52
+ * يقطع عند حدّ البايت لا حدّ الحرف، فحرف يقع نصفه في قطعة ونصفه في التالية يخرج من ‎toString‎
53
+ * علامتَي استفهام لا يعيدهما شيء. المفكّك يحتفظ بالبايتات المعلّقة حتى يكتمل الحرف.
54
+ */
55
+ function createLineWriter() {
56
+ const decoder = new StringDecoder("utf8");
57
+ let pending = "";
58
+ return {
59
+ push(chunk) {
60
+ pending += decoder.write(chunk);
61
+ const lines = pending.split(/\r?\n/);
62
+ pending = lines.pop() ?? "";
63
+ for (const line of lines)
64
+ write(stripAnsi(line));
65
+ },
66
+ flush() {
67
+ pending += decoder.end();
68
+ if (pending.trim().length > 0)
69
+ write(stripAnsi(pending));
70
+ pending = "";
71
+ },
72
+ };
73
+ }
74
+ function readPayload() {
75
+ const raw = process.env[LAUNCH_PAYLOAD_ENV];
76
+ if (!raw)
77
+ throw new Error(`${LAUNCH_PAYLOAD_ENV} is missing — this entry is launched by the CLI, not by hand.`);
78
+ return JSON.parse(raw);
79
+ }
80
+ function main() {
81
+ const payload = readPayload();
82
+ // تُحذف من نسختنا فلا تتسرّب إلى بيئة الخدمة ولا إلى أي عملية تحتها.
83
+ delete process.env[LAUNCH_PAYLOAD_ENV];
84
+ const { file, argv } = resolveInvocation(payload.command, payload.args);
85
+ const child = spawn(file, argv, {
86
+ cwd: payload.cwd,
87
+ // ‎NO_COLOR‎ احتياطًا: الأدوات تُعطّل التلوين خارج الطرفية، لكن سجلًّا ملوّثًا بـ ANSI لا يُبحث فيه.
88
+ env: { ...process.env, ...payload.env, NO_COLOR: "1" },
89
+ // أنابيب لا واصفات موروثة: هذا بالضبط شرط libuv لتمرير ‎CREATE_NO_WINDOW‎. لا خطر من امتلاء
90
+ // الأنبوب لأننا نحيا ما دامت الخدمة تحيا فنستنزفه دائمًا.
91
+ stdio: ["ignore", "pipe", "pipe"],
92
+ windowsHide: true,
93
+ });
94
+ write(`--- ${payload.label} started (runner ${process.pid}, service ${child.pid ?? "?"}) ---`);
95
+ const writer = createLineWriter();
96
+ child.stdout?.on("data", writer.push);
97
+ child.stderr?.on("data", writer.push);
98
+ child.on("error", (error) => {
99
+ writer.flush();
100
+ write(`--- ${payload.label} failed to launch: ${error.message} ---`);
101
+ process.exit(1);
102
+ });
103
+ // نموت مع الخدمة. لازم لا مستحبّ: سجلّ العملية يحمل رقمنا نحن، فلو بقينا حيّين بعد موتها لقال
104
+ // ‎status‎ إنها تعمل وهي ميتة.
105
+ child.on("exit", (code, signal) => {
106
+ writer.flush();
107
+ write(`--- ${payload.label} exited (code ${code ?? "—"}, signal ${signal ?? "—"}) ---`);
108
+ process.exit(code ?? 1);
109
+ });
110
+ }
111
+ try {
112
+ main();
113
+ }
114
+ catch (error) {
115
+ write(`--- runner aborted: ${error instanceof Error ? error.message : String(error)} ---`);
116
+ process.exit(1);
117
+ }
118
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/supervisor/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { RestartOutcomeFile, RestartScheduleFile } from "../contracts/core.js";
2
+ import type { Profile } from "../profiles/types.js";
3
+ import { type ConsumeOptions, type RestartExecution } from "./restart-consumer.js";
4
+ /** بين محاولتين بعد تأجيل. ربع ساعة: أقصر منها يزعج، وأطول منها يفوّت نافذة هدوء قصيرة. */
5
+ export declare const DEFER_RETRY_MS: number;
6
+ /** أقصى ما نؤجّل قبل التخلّي عن الجولة. */
7
+ export declare const DEFER_CEILING_MS: number;
8
+ /**
9
+ * AR: موعد الجولة التالية بالمللي ثانية، أو ‎null‎ حين لا جدول. **دالّة خالصة**: الزمن يُمرَّر،
10
+ * فتُختبَر سنةٌ من الجداول في مللي ثانية.
11
+ * EN: When the next round is due in milliseconds, or `null` when nothing is scheduled. **A pure
12
+ * function**: time is passed in, so a year of schedules is tested in a millisecond.
13
+ */
14
+ export declare function dueAt(schedule: RestartScheduleFile, lastRestartAt: string | null, now: number): number | null;
15
+ export interface ScheduleTimerOptions extends ConsumeOptions {
16
+ /** يُحقَن في الاختبار. الافتراض: قراءة المرآة من مجلد الحالة. */
17
+ readSchedule?: () => RestartScheduleFile | null;
18
+ readLastRestart?: () => RestartOutcomeFile | null;
19
+ }
20
+ /**
21
+ * AR: يقرّر في كل جولة: أحان الموعد؟ وهل نؤجّل؟ وهل بلغنا السقف؟ لا مؤقّت داخله ولا ساعة: الزمن
22
+ * يُمرَّر من الخارج، فهذه الحلقة كلّها قابلة للاختبار بلا انتظار ثانية واحدة.
23
+ * EN: Decides on each round: is it due? should it defer? has it hit the ceiling? It holds no timer
24
+ * and no clock: time comes in from outside, so this whole loop is testable without waiting a
25
+ * single second.
26
+ */
27
+ export declare class ScheduleTimer {
28
+ private readonly profile;
29
+ private readonly options;
30
+ /** متى بدأ التأجيل الحالي، أو ‎null‎ حين لا تأجيل جارٍ. */
31
+ private deferringSince;
32
+ private nextAttemptAt;
33
+ constructor(profile: Profile, options?: ScheduleTimerOptions);
34
+ round(now?: number): Promise<RestartExecution | null>;
35
+ private readSchedule;
36
+ private readLastRestart;
37
+ }
38
+ //# sourceMappingURL=schedule-timer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule-timer.d.ts","sourceRoot":"","sources":["../../src/supervisor/schedule-timer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAsB,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACxG,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAAkB,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AA+CnG,2FAA2F;AAC3F,eAAO,MAAM,cAAc,QAAc,CAAC;AAE1C,2CAA2C;AAC3C,eAAO,MAAM,gBAAgB,QAAgB,CAAC;AAE9C;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,QAAQ,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiB7G;AAED,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC1D,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,mBAAmB,GAAG,IAAI,CAAC;IAChD,eAAe,CAAC,EAAE,MAAM,kBAAkB,GAAG,IAAI,CAAC;CACnD;AAED;;;;;;GAMG;AACH,qBAAa,aAAa;IAMtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAN1B,2DAA2D;IAC3D,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,aAAa,CAAK;gBAGP,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,oBAAyB;IAG/C,KAAK,CAAC,GAAG,GAAE,MAAmB,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAsDvE,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,eAAe;CAIxB"}
@@ -0,0 +1,148 @@
1
+ import { REMOTE_STATE_FILES, readStateJson } from "./state-files.js";
2
+ import { executeRestart } from "./restart-consumer.js";
3
+ // AR: المؤقّت الدوريّ (٠٢٠/US2).
4
+ //
5
+ // **لماذا يعيش المؤقّت في المشرف لا في النواة؟** لأن الجدول وُضع أصلًا لعلاج التعليق، ومؤقّتٌ
6
+ // داخل النواة يتعلّق معها — أي يفشل في اللحظة الوحيدة التي بُني لها. المشرف يقرأ مرآة الجدول
7
+ // من مجلد الحالة (‎restart.schedule.json‎) بلا أن يفتح قاعدة البيانات، وهي قاعدة قائمة في
8
+ // المستودع لا استثناء لها.
9
+ //
10
+ // **والمرساة هي آخر إعادة تشغيل وقعت، لا لحظة الحفظ.** بدونها يعيد كل حفظ ضبطَ العدّاد، فجهازٌ
11
+ // يُعدَّل جدوله كل يوم لا يُعاد تشغيله أبدًا — عطبٌ صامت تمامًا: الإعداد مفعّل، والزمن يمرّ،
12
+ // ولا شيء يقع. وهي المرساة نفسها التي تحسب بها النواة ‎nextRestartAt‎، فلا تتباعد اللوحة عن
13
+ // الفعل.
14
+ //
15
+ // **والتأجيل له سقف.** «لا نقطع أحدًا» قاعدة، لكن جهازًا في استراحة ممتلئة قد لا يخلو ست ساعات
16
+ // متّصلة، وجدولٌ يؤجّل إلى الأبد هو جدولٌ لا وجود له. عند السقف **نتخلّى عن الجولة** ولا نقطع:
17
+ // تفويت صيانة أهون من قطع فيلم على ضيف — والجولة التالية تأتي في موعدها.
18
+ //
19
+ // EN: The periodic timer (020/US2).
20
+ //
21
+ // **Why does the timer live in the supervisor rather than the core?** Because the schedule
22
+ // exists to cure hangs, and a timer inside the core hangs with it — failing at the one moment it
23
+ // was built for. The supervisor reads the schedule's mirror from the state dir
24
+ // (`restart.schedule.json`) without opening the database, which is a standing repository rule
25
+ // with no exception.
26
+ //
27
+ // **And the anchor is the last restart that actually happened, not the moment of saving.**
28
+ // Without that every save resets the counter, so an appliance whose schedule is edited daily is
29
+ // never restarted at all — a perfectly silent defect: the setting is on, time passes, and
30
+ // nothing happens. It is the same anchor the core uses to compute `nextRestartAt`, so the panel
31
+ // and the act never drift apart.
32
+ //
33
+ // **And deferral has a ceiling.** "Cut nobody off" is a rule, but an appliance in a full
34
+ // rest-house may not go quiet for six straight hours, and a schedule that defers forever is a
35
+ // schedule that does not exist. At the ceiling **we abandon the round** rather than cut: missing
36
+ // one maintenance window is a smaller harm than cutting a guest's film — and the next round
37
+ // arrives on time.
38
+ const HOURS = {
39
+ "2h": 2,
40
+ "4h": 4,
41
+ "6h": 6,
42
+ "12h": 12,
43
+ "24h": 24,
44
+ weekly: 24 * 7,
45
+ };
46
+ /** بين محاولتين بعد تأجيل. ربع ساعة: أقصر منها يزعج، وأطول منها يفوّت نافذة هدوء قصيرة. */
47
+ export const DEFER_RETRY_MS = 15 * 60_000;
48
+ /** أقصى ما نؤجّل قبل التخلّي عن الجولة. */
49
+ export const DEFER_CEILING_MS = 6 * 3_600_000;
50
+ /**
51
+ * AR: موعد الجولة التالية بالمللي ثانية، أو ‎null‎ حين لا جدول. **دالّة خالصة**: الزمن يُمرَّر،
52
+ * فتُختبَر سنةٌ من الجداول في مللي ثانية.
53
+ * EN: When the next round is due in milliseconds, or `null` when nothing is scheduled. **A pure
54
+ * function**: time is passed in, so a year of schedules is tested in a millisecond.
55
+ */
56
+ export function dueAt(schedule, lastRestartAt, now) {
57
+ if (!schedule.autoEnabled)
58
+ return null;
59
+ const hours = HOURS[schedule.every];
60
+ const parsed = lastRestartAt ? Date.parse(lastRestartAt) : Number.NaN;
61
+ const anchor = Number.isFinite(parsed) ? parsed : now;
62
+ const due = new Date(anchor + hours * 3_600_000);
63
+ // الساعة المفضّلة للجداول اليومية فأطول وحدها: تثبيت جدول كل ساعتين على الرابعة يحوّله جدولًا
64
+ // يوميًّا بصمت — إعدادٌ يُقبَل ويعني غير ما يقول.
65
+ if (schedule.atHour !== null && hours >= 24) {
66
+ due.setHours(schedule.atHour, 0, 0, 0);
67
+ if (due.getTime() <= now)
68
+ due.setDate(due.getDate() + 1);
69
+ }
70
+ return due.getTime();
71
+ }
72
+ /**
73
+ * AR: يقرّر في كل جولة: أحان الموعد؟ وهل نؤجّل؟ وهل بلغنا السقف؟ لا مؤقّت داخله ولا ساعة: الزمن
74
+ * يُمرَّر من الخارج، فهذه الحلقة كلّها قابلة للاختبار بلا انتظار ثانية واحدة.
75
+ * EN: Decides on each round: is it due? should it defer? has it hit the ceiling? It holds no timer
76
+ * and no clock: time comes in from outside, so this whole loop is testable without waiting a
77
+ * single second.
78
+ */
79
+ export class ScheduleTimer {
80
+ profile;
81
+ options;
82
+ /** متى بدأ التأجيل الحالي، أو ‎null‎ حين لا تأجيل جارٍ. */
83
+ deferringSince = null;
84
+ nextAttemptAt = 0;
85
+ constructor(profile, options = {}) {
86
+ this.profile = profile;
87
+ this.options = options;
88
+ }
89
+ async round(now = Date.now()) {
90
+ const schedule = this.readSchedule();
91
+ if (!schedule?.autoEnabled) {
92
+ this.deferringSince = null;
93
+ return null;
94
+ }
95
+ if (now < this.nextAttemptAt)
96
+ return null;
97
+ const last = this.readLastRestart();
98
+ const due = dueAt(schedule, last?.at ?? null, now);
99
+ if (due === null || now < due)
100
+ return null;
101
+ if (this.deferringSince !== null && now - this.deferringSince >= DEFER_CEILING_MS) {
102
+ // AR: بلغنا السقف. **نتخلّى ولا نقطع**، ونحرّك المرساة إلى الآن فلا نعيد المحاولة فورًا
103
+ // في الجولة التالية — وإلّا صار «التخلّي» حلقةً محمومة كل ثانية.
104
+ // EN: The ceiling is reached. **We abandon rather than cut**, and move the anchor to now so we
105
+ // do not retry immediately on the next round — otherwise "abandoning" becomes a hot loop
106
+ // every second.
107
+ this.deferringSince = null;
108
+ this.nextAttemptAt = now + HOURS[schedule.every] * 3_600_000;
109
+ this.options.onEvent?.("the scheduled restart was abandoned — guests were watching for six hours");
110
+ return null;
111
+ }
112
+ const request = {
113
+ scope: schedule.scope,
114
+ reason: "scheduled",
115
+ // AR: الجدول **لا يقطع أبدًا** حين اختار المالك ذلك. و‎force‎ هنا معناه «لا تسأل» لا «اقطع»،
116
+ // فيُشتقّ من إعداده هو لا من رغبتنا في أن ينجح.
117
+ // EN: A schedule **never cuts** when the owner chose so. `force` here means "do not ask" rather
118
+ // than "cut", so it is derived from the owner's own setting rather than from our wish for
119
+ // the round to succeed.
120
+ force: !schedule.deferWhileWatching,
121
+ requestedAt: new Date(now).toISOString(),
122
+ };
123
+ const execution = await executeRestart(this.profile, request, {
124
+ deferIf: this.options.deferIf,
125
+ onEvent: this.options.onEvent,
126
+ });
127
+ if (execution.ok) {
128
+ this.deferringSince = null;
129
+ this.nextAttemptAt = 0;
130
+ return execution;
131
+ }
132
+ // تأجيل (أو فشل): نعاود بعد ربع ساعة، ونبدأ عدّ السقف من أوّل تأجيل لا من آخره.
133
+ this.deferringSince ??= now;
134
+ this.nextAttemptAt = now + DEFER_RETRY_MS;
135
+ return execution;
136
+ }
137
+ readSchedule() {
138
+ if (this.options.readSchedule)
139
+ return this.options.readSchedule();
140
+ return readStateJson(this.profile, REMOTE_STATE_FILES.restartSchedule);
141
+ }
142
+ readLastRestart() {
143
+ if (this.options.readLastRestart)
144
+ return this.options.readLastRestart();
145
+ return readStateJson(this.profile, REMOTE_STATE_FILES.restartOutcome);
146
+ }
147
+ }
148
+ //# sourceMappingURL=schedule-timer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule-timer.js","sourceRoot":"","sources":["../../src/supervisor/schedule-timer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { type ResultPromise } from "execa";
2
+ import type { Profile, ServiceDefinition } from "../profiles/types.js";
3
+ import { type PidRecord } from "./pidfile.js";
4
+ /** يُطلق خدمة في الخلفية ويسجّل هويتها. العملية تحيا بعد خروج الـ CLI. */
5
+ export declare function launchDetached(profile: Profile, definition: ServiceDefinition): Promise<PidRecord>;
6
+ export interface AttachedService {
7
+ definition: ServiceDefinition;
8
+ child: ResultPromise;
9
+ pid: number;
10
+ close: () => void;
11
+ }
12
+ export interface AttachOptions {
13
+ /** يُنادى لكل سطر مخرَج، لعرضه ببادئة ملوّنة. */
14
+ onLine: (service: ServiceDefinition, line: string) => void;
15
+ }
16
+ /** يُطلق خدمة مرتبطة بالطرفية: الأسطر تذهب إلى الشاشة وإلى ملف السجلّ معًا. */
17
+ export declare function launchAttached(profile: Profile, definition: ServiceDefinition, options: AttachOptions): AttachedService;
18
+ //# sourceMappingURL=spawn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../src/supervisor/spawn.ts"],"names":[],"mappings":"AAIA,OAAO,EAAS,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAElD,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAIvE,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAyB9D,0EAA0E;AAC1E,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,iBAAiB,GAC5B,OAAO,CAAC,SAAS,CAAC,CA+CpB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,iBAAiB,CAAC;IAC9B,KAAK,EAAE,aAAa,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,MAAM,EAAE,CAAC,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5D;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,iBAAiB,EAC7B,OAAO,EAAE,aAAa,GACrB,eAAe,CA+CjB"}