charness 3.7.0 → 3.8.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 (359) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/DEVELOPMENT.md +6 -2
  3. package/README.md +5 -5
  4. package/SETUP.md +16 -5
  5. package/agent-plugin/skills/charness-manager/SKILL.md +3 -3
  6. package/dist/adapters/openCodeAdapter.d.ts.map +1 -1
  7. package/dist/adapters/openCodeAdapter.js +2 -1
  8. package/dist/adapters/openCodeAdapter.js.map +1 -1
  9. package/dist/bot.d.ts.map +1 -1
  10. package/dist/bot.js +50 -9
  11. package/dist/bot.js.map +1 -1
  12. package/dist/cli.js +44 -1
  13. package/dist/cli.js.map +1 -1
  14. package/dist/configDirFile.d.ts +7 -3
  15. package/dist/configDirFile.d.ts.map +1 -1
  16. package/dist/configDirFile.js +12 -5
  17. package/dist/configDirFile.js.map +1 -1
  18. package/dist/connectors/telegram/commands/botCore.d.ts +5 -1
  19. package/dist/connectors/telegram/commands/botCore.d.ts.map +1 -1
  20. package/dist/connectors/telegram/commands/runners.d.ts +52 -0
  21. package/dist/connectors/telegram/commands/runners.d.ts.map +1 -0
  22. package/dist/connectors/telegram/commands/runners.js +486 -0
  23. package/dist/connectors/telegram/commands/runners.js.map +1 -0
  24. package/dist/connectors/telegram/runnerPairingMessages.d.ts +27 -0
  25. package/dist/connectors/telegram/runnerPairingMessages.d.ts.map +1 -0
  26. package/dist/connectors/telegram/runnerPairingMessages.js +105 -0
  27. package/dist/connectors/telegram/runnerPairingMessages.js.map +1 -0
  28. package/dist/i18n/de.d.ts.map +1 -1
  29. package/dist/i18n/de.js +58 -0
  30. package/dist/i18n/de.js.map +1 -1
  31. package/dist/i18n/en.d.ts.map +1 -1
  32. package/dist/i18n/en.js +58 -0
  33. package/dist/i18n/en.js.map +1 -1
  34. package/dist/i18n/es.d.ts.map +1 -1
  35. package/dist/i18n/es.js +58 -0
  36. package/dist/i18n/es.js.map +1 -1
  37. package/dist/i18n/fr.d.ts.map +1 -1
  38. package/dist/i18n/fr.js +58 -0
  39. package/dist/i18n/fr.js.map +1 -1
  40. package/dist/i18n/hi.d.ts.map +1 -1
  41. package/dist/i18n/hi.js +58 -0
  42. package/dist/i18n/hi.js.map +1 -1
  43. package/dist/i18n/ja.d.ts.map +1 -1
  44. package/dist/i18n/ja.js +58 -0
  45. package/dist/i18n/ja.js.map +1 -1
  46. package/dist/i18n/ka.d.ts.map +1 -1
  47. package/dist/i18n/ka.js +58 -0
  48. package/dist/i18n/ka.js.map +1 -1
  49. package/dist/i18n/pt.d.ts.map +1 -1
  50. package/dist/i18n/pt.js +58 -0
  51. package/dist/i18n/pt.js.map +1 -1
  52. package/dist/i18n/ru.d.ts.map +1 -1
  53. package/dist/i18n/ru.js +58 -0
  54. package/dist/i18n/ru.js.map +1 -1
  55. package/dist/i18n/uk.d.ts.map +1 -1
  56. package/dist/i18n/uk.js +58 -0
  57. package/dist/i18n/uk.js.map +1 -1
  58. package/dist/i18n/uz.d.ts.map +1 -1
  59. package/dist/i18n/uz.js +58 -0
  60. package/dist/i18n/uz.js.map +1 -1
  61. package/dist/i18n/zh.d.ts.map +1 -1
  62. package/dist/i18n/zh.js +58 -0
  63. package/dist/i18n/zh.js.map +1 -1
  64. package/dist/installManager.d.ts +57 -1
  65. package/dist/installManager.d.ts.map +1 -1
  66. package/dist/installManager.js +88 -10
  67. package/dist/installManager.js.map +1 -1
  68. package/dist/instanceSettings.d.ts +12 -2
  69. package/dist/instanceSettings.d.ts.map +1 -1
  70. package/dist/instanceSettings.js +17 -3
  71. package/dist/instanceSettings.js.map +1 -1
  72. package/dist/outputTrace.d.ts +6 -0
  73. package/dist/outputTrace.d.ts.map +1 -1
  74. package/dist/outputTrace.js +24 -1
  75. package/dist/outputTrace.js.map +1 -1
  76. package/dist/remoteRun/cliArgs.d.ts +2 -0
  77. package/dist/remoteRun/cliArgs.d.ts.map +1 -1
  78. package/dist/remoteRun/cliArgs.js +11 -2
  79. package/dist/remoteRun/cliArgs.js.map +1 -1
  80. package/dist/remoteRun/commands.d.ts +21 -0
  81. package/dist/remoteRun/commands.d.ts.map +1 -1
  82. package/dist/remoteRun/commands.js +38 -17
  83. package/dist/remoteRun/commands.js.map +1 -1
  84. package/dist/remoteRun/interrupts.d.ts +10 -0
  85. package/dist/remoteRun/interrupts.d.ts.map +1 -1
  86. package/dist/remoteRun/interrupts.js +43 -6
  87. package/dist/remoteRun/interrupts.js.map +1 -1
  88. package/dist/remoteRun/output.d.ts +2 -0
  89. package/dist/remoteRun/output.d.ts.map +1 -1
  90. package/dist/remoteRun/output.js +45 -0
  91. package/dist/remoteRun/output.js.map +1 -1
  92. package/dist/remoteRun/pairedRunners.d.ts +51 -0
  93. package/dist/remoteRun/pairedRunners.d.ts.map +1 -0
  94. package/dist/remoteRun/pairedRunners.js +165 -0
  95. package/dist/remoteRun/pairedRunners.js.map +1 -0
  96. package/dist/remoteRun/probe.d.ts +23 -1
  97. package/dist/remoteRun/probe.d.ts.map +1 -1
  98. package/dist/remoteRun/probe.js +45 -11
  99. package/dist/remoteRun/probe.js.map +1 -1
  100. package/dist/remoteRun/remoteRunCli.d.ts +13 -6
  101. package/dist/remoteRun/remoteRunCli.d.ts.map +1 -1
  102. package/dist/remoteRun/remoteRunCli.js +34 -59
  103. package/dist/remoteRun/remoteRunCli.js.map +1 -1
  104. package/dist/remoteRun/runnerClient.d.ts +2 -0
  105. package/dist/remoteRun/runnerClient.d.ts.map +1 -1
  106. package/dist/remoteRun/runnerClient.js +5 -1
  107. package/dist/remoteRun/runnerClient.js.map +1 -1
  108. package/dist/remoteRun/runnerSummary.d.ts +24 -0
  109. package/dist/remoteRun/runnerSummary.d.ts.map +1 -0
  110. package/dist/remoteRun/runnerSummary.js +86 -0
  111. package/dist/remoteRun/runnerSummary.js.map +1 -0
  112. package/dist/remoteRun/runnerWait.d.ts +68 -0
  113. package/dist/remoteRun/runnerWait.d.ts.map +1 -0
  114. package/dist/remoteRun/runnerWait.js +137 -0
  115. package/dist/remoteRun/runnerWait.js.map +1 -0
  116. package/dist/remoteRun/runnerWaitTiming.d.ts +16 -0
  117. package/dist/remoteRun/runnerWaitTiming.d.ts.map +1 -0
  118. package/dist/remoteRun/runnerWaitTiming.js +37 -0
  119. package/dist/remoteRun/runnerWaitTiming.js.map +1 -0
  120. package/dist/remoteRun/runners.d.ts +7 -7
  121. package/dist/remoteRun/runners.d.ts.map +1 -1
  122. package/dist/remoteRun/runners.js +45 -17
  123. package/dist/remoteRun/runners.js.map +1 -1
  124. package/dist/remoteRun/runnersCatalog.d.ts +14 -0
  125. package/dist/remoteRun/runnersCatalog.d.ts.map +1 -0
  126. package/dist/remoteRun/runnersCatalog.js +68 -0
  127. package/dist/remoteRun/runnersCatalog.js.map +1 -0
  128. package/dist/remoteRun/runnersConfig.d.ts +29 -20
  129. package/dist/remoteRun/runnersConfig.d.ts.map +1 -1
  130. package/dist/remoteRun/runnersConfig.js +14 -12
  131. package/dist/remoteRun/runnersConfig.js.map +1 -1
  132. package/dist/remoteRun/ssh.d.ts +22 -2
  133. package/dist/remoteRun/ssh.d.ts.map +1 -1
  134. package/dist/remoteRun/ssh.js +41 -7
  135. package/dist/remoteRun/ssh.js.map +1 -1
  136. package/dist/runnerUtility/adminCheck.d.ts +11 -0
  137. package/dist/runnerUtility/adminCheck.d.ts.map +1 -0
  138. package/dist/runnerUtility/adminCheck.js +68 -0
  139. package/dist/runnerUtility/adminCheck.js.map +1 -0
  140. package/dist/runnerUtility/appInstall.d.ts +25 -0
  141. package/dist/runnerUtility/appInstall.d.ts.map +1 -0
  142. package/dist/runnerUtility/appInstall.js +147 -0
  143. package/dist/runnerUtility/appInstall.js.map +1 -0
  144. package/dist/runnerUtility/appUpdate.d.ts +39 -0
  145. package/dist/runnerUtility/appUpdate.d.ts.map +1 -0
  146. package/dist/runnerUtility/appUpdate.js +90 -0
  147. package/dist/runnerUtility/appUpdate.js.map +1 -0
  148. package/dist/runnerUtility/execEnv.d.ts +21 -0
  149. package/dist/runnerUtility/execEnv.d.ts.map +1 -0
  150. package/dist/runnerUtility/execEnv.js +109 -0
  151. package/dist/runnerUtility/execEnv.js.map +1 -0
  152. package/dist/runnerUtility/execSession.d.ts +13 -0
  153. package/dist/runnerUtility/execSession.d.ts.map +1 -0
  154. package/dist/runnerUtility/execSession.js +58 -0
  155. package/dist/runnerUtility/execSession.js.map +1 -0
  156. package/dist/runnerUtility/hubClient.d.ts +30 -0
  157. package/dist/runnerUtility/hubClient.d.ts.map +1 -0
  158. package/dist/runnerUtility/hubClient.js +127 -0
  159. package/dist/runnerUtility/hubClient.js.map +1 -0
  160. package/dist/runnerUtility/injectStream.d.ts +9 -0
  161. package/dist/runnerUtility/injectStream.d.ts.map +1 -0
  162. package/dist/runnerUtility/injectStream.js +12 -0
  163. package/dist/runnerUtility/injectStream.js.map +1 -0
  164. package/dist/runnerUtility/iosCheck.d.ts +62 -0
  165. package/dist/runnerUtility/iosCheck.d.ts.map +1 -0
  166. package/dist/runnerUtility/iosCheck.js +200 -0
  167. package/dist/runnerUtility/iosCheck.js.map +1 -0
  168. package/dist/runnerUtility/launcher.d.ts +5 -0
  169. package/dist/runnerUtility/launcher.d.ts.map +1 -0
  170. package/dist/runnerUtility/launcher.js +85 -0
  171. package/dist/runnerUtility/launcher.js.map +1 -0
  172. package/dist/runnerUtility/linkLoop.d.ts +47 -0
  173. package/dist/runnerUtility/linkLoop.d.ts.map +1 -0
  174. package/dist/runnerUtility/linkLoop.js +281 -0
  175. package/dist/runnerUtility/linkLoop.js.map +1 -0
  176. package/dist/runnerUtility/localLinkStop.d.ts +23 -0
  177. package/dist/runnerUtility/localLinkStop.d.ts.map +1 -0
  178. package/dist/runnerUtility/localLinkStop.js +79 -0
  179. package/dist/runnerUtility/localLinkStop.js.map +1 -0
  180. package/dist/runnerUtility/machineReport.d.ts +39 -0
  181. package/dist/runnerUtility/machineReport.d.ts.map +1 -0
  182. package/dist/runnerUtility/machineReport.js +161 -0
  183. package/dist/runnerUtility/machineReport.js.map +1 -0
  184. package/dist/runnerUtility/packageId.d.ts +5 -0
  185. package/dist/runnerUtility/packageId.d.ts.map +1 -0
  186. package/dist/runnerUtility/packageId.js +64 -0
  187. package/dist/runnerUtility/packageId.js.map +1 -0
  188. package/dist/runnerUtility/pairingRecovery.d.ts +31 -0
  189. package/dist/runnerUtility/pairingRecovery.d.ts.map +1 -0
  190. package/dist/runnerUtility/pairingRecovery.js +24 -0
  191. package/dist/runnerUtility/pairingRecovery.js.map +1 -0
  192. package/dist/runnerUtility/pueueDaemon.d.ts +36 -0
  193. package/dist/runnerUtility/pueueDaemon.d.ts.map +1 -0
  194. package/dist/runnerUtility/pueueDaemon.js +165 -0
  195. package/dist/runnerUtility/pueueDaemon.js.map +1 -0
  196. package/dist/runnerUtility/runnerCli.d.ts +18 -0
  197. package/dist/runnerUtility/runnerCli.d.ts.map +1 -0
  198. package/dist/runnerUtility/runnerCli.js +184 -0
  199. package/dist/runnerUtility/runnerCli.js.map +1 -0
  200. package/dist/runnerUtility/runnerCommands.d.ts +67 -0
  201. package/dist/runnerUtility/runnerCommands.d.ts.map +1 -0
  202. package/dist/runnerUtility/runnerCommands.js +418 -0
  203. package/dist/runnerUtility/runnerCommands.js.map +1 -0
  204. package/dist/runnerUtility/runnerConfig.d.ts +63 -0
  205. package/dist/runnerUtility/runnerConfig.d.ts.map +1 -0
  206. package/dist/runnerUtility/runnerConfig.js +153 -0
  207. package/dist/runnerUtility/runnerConfig.js.map +1 -0
  208. package/dist/runnerUtility/runnerFlags.d.ts +9 -0
  209. package/dist/runnerUtility/runnerFlags.d.ts.map +1 -0
  210. package/dist/runnerUtility/runnerFlags.js +53 -0
  211. package/dist/runnerUtility/runnerFlags.js.map +1 -0
  212. package/dist/runnerUtility/runnerHome.d.ts +30 -0
  213. package/dist/runnerUtility/runnerHome.d.ts.map +1 -0
  214. package/dist/runnerUtility/runnerHome.js +82 -0
  215. package/dist/runnerUtility/runnerHome.js.map +1 -0
  216. package/dist/runnerUtility/runnerKeys.d.ts +11 -0
  217. package/dist/runnerUtility/runnerKeys.d.ts.map +1 -0
  218. package/dist/runnerUtility/runnerKeys.js +80 -0
  219. package/dist/runnerUtility/runnerKeys.js.map +1 -0
  220. package/dist/runnerUtility/runnerServers.d.ts +40 -0
  221. package/dist/runnerUtility/runnerServers.d.ts.map +1 -0
  222. package/dist/runnerUtility/runnerServers.js +79 -0
  223. package/dist/runnerUtility/runnerServers.js.map +1 -0
  224. package/dist/runnerUtility/serviceManager.d.ts +54 -0
  225. package/dist/runnerUtility/serviceManager.d.ts.map +1 -0
  226. package/dist/runnerUtility/serviceManager.js +413 -0
  227. package/dist/runnerUtility/serviceManager.js.map +1 -0
  228. package/dist/runnerUtility/serviceUnits.d.ts +36 -0
  229. package/dist/runnerUtility/serviceUnits.d.ts.map +1 -0
  230. package/dist/runnerUtility/serviceUnits.js +169 -0
  231. package/dist/runnerUtility/serviceUnits.js.map +1 -0
  232. package/dist/runnerUtility/toolInstall.d.ts +95 -0
  233. package/dist/runnerUtility/toolInstall.d.ts.map +1 -0
  234. package/dist/runnerUtility/toolInstall.js +232 -0
  235. package/dist/runnerUtility/toolInstall.js.map +1 -0
  236. package/dist/runnerUtility/versionPollTiming.d.ts +16 -0
  237. package/dist/runnerUtility/versionPollTiming.d.ts.map +1 -0
  238. package/dist/runnerUtility/versionPollTiming.js +36 -0
  239. package/dist/runnerUtility/versionPollTiming.js.map +1 -0
  240. package/dist/runners/authorizedKeys.d.ts +52 -0
  241. package/dist/runners/authorizedKeys.d.ts.map +1 -0
  242. package/dist/runners/authorizedKeys.js +153 -0
  243. package/dist/runners/authorizedKeys.js.map +1 -0
  244. package/dist/runners/bootstrapLine.d.ts +4 -0
  245. package/dist/runners/bootstrapLine.d.ts.map +1 -0
  246. package/dist/runners/bootstrapLine.js +69 -0
  247. package/dist/runners/bootstrapLine.js.map +1 -0
  248. package/dist/runners/gate.d.ts +41 -0
  249. package/dist/runners/gate.d.ts.map +1 -0
  250. package/dist/runners/gate.js +216 -0
  251. package/dist/runners/gate.js.map +1 -0
  252. package/dist/runners/gateLink.d.ts +26 -0
  253. package/dist/runners/gateLink.d.ts.map +1 -0
  254. package/dist/runners/gateLink.js +240 -0
  255. package/dist/runners/gateLink.js.map +1 -0
  256. package/dist/runners/gateProtocol.d.ts +98 -0
  257. package/dist/runners/gateProtocol.d.ts.map +1 -0
  258. package/dist/runners/gateProtocol.js +149 -0
  259. package/dist/runners/gateProtocol.js.map +1 -0
  260. package/dist/runners/gateWrapper.d.ts +6 -0
  261. package/dist/runners/gateWrapper.d.ts.map +1 -0
  262. package/dist/runners/gateWrapper.js +70 -0
  263. package/dist/runners/gateWrapper.js.map +1 -0
  264. package/dist/runners/hubAddress.d.ts +33 -0
  265. package/dist/runners/hubAddress.d.ts.map +1 -0
  266. package/dist/runners/hubAddress.js +88 -0
  267. package/dist/runners/hubAddress.js.map +1 -0
  268. package/dist/runners/hubAddressCandidates.d.ts +16 -0
  269. package/dist/runners/hubAddressCandidates.d.ts.map +1 -0
  270. package/dist/runners/hubAddressCandidates.js +96 -0
  271. package/dist/runners/hubAddressCandidates.js.map +1 -0
  272. package/dist/runners/hubIds.d.ts +16 -0
  273. package/dist/runners/hubIds.d.ts.map +1 -0
  274. package/dist/runners/hubIds.js +25 -0
  275. package/dist/runners/hubIds.js.map +1 -0
  276. package/dist/runners/hubKey.d.ts +6 -0
  277. package/dist/runners/hubKey.d.ts.map +1 -0
  278. package/dist/runners/hubKey.js +78 -0
  279. package/dist/runners/hubKey.js.map +1 -0
  280. package/dist/runners/hubLock.d.ts +7 -0
  281. package/dist/runners/hubLock.d.ts.map +1 -0
  282. package/dist/runners/hubLock.js +230 -0
  283. package/dist/runners/hubLock.js.map +1 -0
  284. package/dist/runners/hubPackage.d.ts +23 -0
  285. package/dist/runners/hubPackage.d.ts.map +1 -0
  286. package/dist/runners/hubPackage.js +184 -0
  287. package/dist/runners/hubPackage.js.map +1 -0
  288. package/dist/runners/hubPairing.d.ts +63 -0
  289. package/dist/runners/hubPairing.d.ts.map +1 -0
  290. package/dist/runners/hubPairing.js +261 -0
  291. package/dist/runners/hubPairing.js.map +1 -0
  292. package/dist/runners/hubPaths.d.ts +38 -0
  293. package/dist/runners/hubPaths.d.ts.map +1 -0
  294. package/dist/runners/hubPaths.js +94 -0
  295. package/dist/runners/hubPaths.js.map +1 -0
  296. package/dist/runners/hubRegistry.d.ts +112 -0
  297. package/dist/runners/hubRegistry.d.ts.map +1 -0
  298. package/dist/runners/hubRegistry.js +210 -0
  299. package/dist/runners/hubRegistry.js.map +1 -0
  300. package/dist/runners/linkControl.d.ts +27 -0
  301. package/dist/runners/linkControl.d.ts.map +1 -0
  302. package/dist/runners/linkControl.js +124 -0
  303. package/dist/runners/linkControl.js.map +1 -0
  304. package/dist/runners/pairCode.d.ts +30 -0
  305. package/dist/runners/pairCode.d.ts.map +1 -0
  306. package/dist/runners/pairCode.js +46 -0
  307. package/dist/runners/pairCode.js.map +1 -0
  308. package/dist/runners/pairingTiming.d.ts +18 -0
  309. package/dist/runners/pairingTiming.d.ts.map +1 -0
  310. package/dist/runners/pairingTiming.js +42 -0
  311. package/dist/runners/pairingTiming.js.map +1 -0
  312. package/dist/runners/runnerProxy.d.ts +9 -0
  313. package/dist/runners/runnerProxy.d.ts.map +1 -0
  314. package/dist/runners/runnerProxy.js +67 -0
  315. package/dist/runners/runnerProxy.js.map +1 -0
  316. package/dist/runners/runnerRemoval.d.ts +21 -0
  317. package/dist/runners/runnerRemoval.d.ts.map +1 -0
  318. package/dist/runners/runnerRemoval.js +82 -0
  319. package/dist/runners/runnerRemoval.js.map +1 -0
  320. package/dist/runners/runnersCli.d.ts +16 -0
  321. package/dist/runners/runnersCli.d.ts.map +1 -0
  322. package/dist/runners/runnersCli.js +214 -0
  323. package/dist/runners/runnersCli.js.map +1 -0
  324. package/dist/runners/runnersList.d.ts +17 -0
  325. package/dist/runners/runnersList.d.ts.map +1 -0
  326. package/dist/runners/runnersList.js +49 -0
  327. package/dist/runners/runnersList.js.map +1 -0
  328. package/dist/runners/runnersOverview.d.ts +20 -0
  329. package/dist/runners/runnersOverview.d.ts.map +1 -0
  330. package/dist/runners/runnersOverview.js +55 -0
  331. package/dist/runners/runnersOverview.js.map +1 -0
  332. package/dist/runners/sshKeys.d.ts +26 -0
  333. package/dist/runners/sshKeys.d.ts.map +1 -0
  334. package/dist/runners/sshKeys.js +60 -0
  335. package/dist/runners/sshKeys.js.map +1 -0
  336. package/dist/runners/tarArchive.d.ts +20 -0
  337. package/dist/runners/tarArchive.d.ts.map +1 -0
  338. package/dist/runners/tarArchive.js +70 -0
  339. package/dist/runners/tarArchive.js.map +1 -0
  340. package/dist/scheduler/mcpSurface.d.ts +11 -5
  341. package/dist/scheduler/mcpSurface.d.ts.map +1 -1
  342. package/dist/scheduler/mcpSurface.js +59 -26
  343. package/dist/scheduler/mcpSurface.js.map +1 -1
  344. package/dist/selfUpdate/selfCheck.js +2 -2
  345. package/dist/selfUpdate/selfCheck.js.map +1 -1
  346. package/dist/testTimings.d.ts +5 -2
  347. package/dist/testTimings.d.ts.map +1 -1
  348. package/dist/testTimings.js +10 -1
  349. package/dist/testTimings.js.map +1 -1
  350. package/dist/utils/agentEnvironment.d.ts +6 -2
  351. package/dist/utils/agentEnvironment.d.ts.map +1 -1
  352. package/dist/utils/agentEnvironment.js +13 -2
  353. package/dist/utils/agentEnvironment.js.map +1 -1
  354. package/dist/utils/runnersScreenPlan.d.ts +130 -0
  355. package/dist/utils/runnersScreenPlan.d.ts.map +1 -0
  356. package/dist/utils/runnersScreenPlan.js +257 -0
  357. package/dist/utils/runnersScreenPlan.js.map +1 -0
  358. package/package.json +5 -2
  359. package/remoteRun/runner.sh +81 -6
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.serveExec = serveExec;
4
+ const child_process_1 = require("child_process");
5
+ /**
6
+ * @description One `exec` request of a session: the command runs under `bash -c` in a clean environment, its stdin is the channel's
7
+ * (the client's EOF is the command's EOF — phase 1's lease relies on it), its stdout and stderr go back on the channel's two streams,
8
+ * and its end is reported as an exit status or a signal.
9
+ *
10
+ * Sshd's semantics for a channel that is CLOSED by the client: the pipes close, the command is NOT killed. Here: stdout and stderr are
11
+ * destroyed (the command's next write fails, as with a closed pipe), its stdin is closed, and the process runs on. Only the real end
12
+ * of the process closes the books on it ({@link ExecTracker.ended}), which is what «the runner is busy» means.
13
+ */
14
+ const commandNotFoundStatus = 127;
15
+ const signalPrefix = /^SIG/;
16
+ function sendExitStatus(channel, exitCode, signal) {
17
+ try {
18
+ if (signal !== null)
19
+ channel.exit(signal.replace(signalPrefix, ''), false, '');
20
+ else
21
+ channel.exit(exitCode ?? commandNotFoundStatus);
22
+ channel.end();
23
+ }
24
+ catch {
25
+ // The client closed the channel first: nobody is waiting for the status.
26
+ }
27
+ }
28
+ /** @description Run `command` for `channel`. */
29
+ function serveExec(channel, command, options) {
30
+ options.tracker.started();
31
+ const child = (0, child_process_1.spawn)('bash', ['-c', command], { env: options.env, cwd: options.cwd, stdio: ['pipe', 'pipe', 'pipe'] });
32
+ child.stdin.on('error', () => undefined);
33
+ channel.on('error', () => undefined);
34
+ channel.stderr.on('error', () => undefined);
35
+ channel.pipe(child.stdin);
36
+ child.stdout.pipe(channel, { end: false });
37
+ child.stderr.pipe(channel.stderr, { end: false });
38
+ channel.once('close', () => {
39
+ child.stdin.destroy();
40
+ child.stdout.destroy();
41
+ child.stderr.destroy();
42
+ });
43
+ // A failed start emits `error` and then `close`: the command is finished exactly once, or the busy count would go negative.
44
+ let isFinished = false;
45
+ const finish = (exitCode, signal) => {
46
+ if (isFinished)
47
+ return;
48
+ isFinished = true;
49
+ sendExitStatus(channel, exitCode, signal);
50
+ options.tracker.ended();
51
+ };
52
+ child.once('error', (error) => {
53
+ channel.stderr.write(`charness-runner: cannot start the command (${error.message})\n`);
54
+ finish(commandNotFoundStatus, null);
55
+ });
56
+ child.once('close', (exitCode, signal) => finish(exitCode, signal));
57
+ }
58
+ //# sourceMappingURL=execSession.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execSession.js","sourceRoot":"","sources":["../../src/runnerUtility/execSession.ts"],"names":[],"mappings":";;AAsCA,8BA2BC;AAjED,iDAAsC;AAGtC;;;;;;;;GAQG;AAEH,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAClC,MAAM,YAAY,GAAG,MAAM,CAAC;AAa5B,SAAS,cAAc,CAAC,OAAsB,EAAE,QAAuB,EAAE,MAA6B;IACpG,IAAI,CAAC;QACH,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;;YAC1E,OAAO,CAAC,IAAI,CAAC,QAAQ,IAAI,qBAAqB,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,yEAAyE;IAC3E,CAAC;AACH,CAAC;AAED,gDAAgD;AAChD,SAAgB,SAAS,CAAC,OAAsB,EAAE,OAAe,EAAE,OAAoB;IACrF,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IAC1B,MAAM,KAAK,GAAG,IAAA,qBAAK,EAAC,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IACtH,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACrC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC5C,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC1B,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3C,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;QACzB,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACtB,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;IACH,4HAA4H;IAC5H,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,MAAM,MAAM,GAAG,CAAC,QAAuB,EAAE,MAA6B,EAAQ,EAAE;QAC9E,IAAI,UAAU;YAAE,OAAO;QACvB,UAAU,GAAG,IAAI,CAAC;QAClB,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC1C,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8CAA8C,KAAK,CAAC,OAAO,KAAK,CAAC,CAAC;QACvF,MAAM,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AACtE,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { Client, type ClientChannel } from 'ssh2';
2
+ import type { z } from 'zod';
3
+ import { type GateMarker, type GateRequest } from '../runners/gateProtocol';
4
+ export interface HubEndpoint {
5
+ host: string;
6
+ port: number;
7
+ user: string;
8
+ /** `<type> <base64>`: the only host key that is accepted. */
9
+ hostKey: string;
10
+ }
11
+ export type HubConnectionFailure = 'auth' | 'hostKey' | 'network';
12
+ /** @description Why the hub could not be reached: the key was refused (`auth` — for a paired runner, it was removed), the host key is not the pinned one, or the network/sshd. */
13
+ export declare class HubConnectionError extends Error {
14
+ readonly failure: HubConnectionFailure;
15
+ constructor(failure: HubConnectionFailure, message: string);
16
+ }
17
+ /** @description Connect and log in; resolves with the ready client. The caller ends it. */
18
+ export declare function connectToHub(endpoint: HubEndpoint, privateKey: string): Promise<Client>;
19
+ export interface GateAnswer {
20
+ marker: GateMarker;
21
+ /** The channel, positioned right after the marker line (what came with it is put back). */
22
+ channel: ClientChannel;
23
+ }
24
+ /** @description Run the gate request `request` and read its marker line; `null` when the answer has none (the hub refused, or the key line is gone). `body` is sent as stdin and ends it; without one stdin stays open (`link`). */
25
+ export declare function callGate(client: Client, request: GateRequest, body: string | null): Promise<GateAnswer | null>;
26
+ /** @description Everything the channel still sends, as text. */
27
+ export declare function readChannelText(channel: ClientChannel): Promise<string>;
28
+ /** @description A gate request whose answer is one JSON line (`redeem`, `identity`, `unpair`), parsed with `schema`. */
29
+ export declare function requestGateJson<TReply>(client: Client, request: 'redeem' | 'unpair' | 'identity', body: string | null, schema: z.ZodType<TReply>): Promise<TReply>;
30
+ //# sourceMappingURL=hubClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hubClient.d.ts","sourceRoot":"","sources":["../../src/runnerUtility/hubClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAA+B,MAAM,MAAM,CAAC;AAC/E,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAuB,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAejG,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;AAElE,kLAAkL;AAClL,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;gBAE3B,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM;CAK3D;AAiBD,2FAA2F;AAC3F,wBAAgB,YAAY,CAAC,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA+BvF;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,2FAA2F;IAC3F,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,oOAAoO;AACpO,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAkB9G;AAED,gEAAgE;AAChE,wBAAsB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAI7E;AAED,wHAAwH;AACxH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAaxK"}
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HubConnectionError = void 0;
4
+ exports.connectToHub = connectToHub;
5
+ exports.callGate = callGate;
6
+ exports.readChannelText = readChannelText;
7
+ exports.requestGateJson = requestGateJson;
8
+ const ssh2_1 = require("ssh2");
9
+ const gateProtocol_1 = require("../runners/gateProtocol");
10
+ const sshKeys_1 = require("../runners/sshKeys");
11
+ /**
12
+ * @description The runner's side of every conversation with the hub's sshd: an ssh2 client that pins the hub's host key (the one in the
13
+ * pairing code, then in `config.json`), logs in with a key, and runs one of the gate's request words (`redeem`, `package`, `link`,
14
+ * `unpair`). Whatever the hub's shell printed before the gate ran is skipped up to the marker line (`readUntilGateMarker`).
15
+ */
16
+ const connectReadyTimeoutMs = 20 * 1000;
17
+ const keepaliveIntervalMs = 15 * 1000;
18
+ const keepaliveCountMax = 3;
19
+ const clientAuthenticationLevel = 'client-authentication';
20
+ const hostDeniedText = 'Host denied';
21
+ /** @description Why the hub could not be reached: the key was refused (`auth` — for a paired runner, it was removed), the host key is not the pinned one, or the network/sshd. */
22
+ class HubConnectionError extends Error {
23
+ failure;
24
+ constructor(failure, message) {
25
+ super(message);
26
+ this.name = 'HubConnectionError';
27
+ this.failure = failure;
28
+ }
29
+ }
30
+ exports.HubConnectionError = HubConnectionError;
31
+ /** The signature algorithms the client offers for each key type: only those of the pinned key, so a hub with several host keys cannot answer with another one. */
32
+ const hostKeyAlgorithms = {
33
+ 'ssh-ed25519': ['ssh-ed25519'],
34
+ 'ecdsa-sha2-nistp256': ['ecdsa-sha2-nistp256'],
35
+ 'ecdsa-sha2-nistp384': ['ecdsa-sha2-nistp384'],
36
+ 'ecdsa-sha2-nistp521': ['ecdsa-sha2-nistp521'],
37
+ 'ssh-rsa': ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-rsa'],
38
+ };
39
+ function classifyFailure(error) {
40
+ if (error.level === clientAuthenticationLevel)
41
+ return new HubConnectionError('auth', 'the hub refused the runner\'s key');
42
+ if (error.message.includes(hostDeniedText))
43
+ return new HubConnectionError('hostKey', 'the hub\'s ssh host key is not the one pinned at pairing');
44
+ return new HubConnectionError('network', error.message);
45
+ }
46
+ /** @description Connect and log in; resolves with the ready client. The caller ends it. */
47
+ function connectToHub(endpoint, privateKey) {
48
+ const pinned = (0, sshKeys_1.parsePublicKey)(endpoint.hostKey);
49
+ const serverHostKey = pinned === null ? undefined : hostKeyAlgorithms[pinned.type];
50
+ if (pinned === null || serverHostKey === undefined)
51
+ return Promise.reject(new HubConnectionError('hostKey', 'the pinned hub host key does not read'));
52
+ const pinnedBlob = pinned.blob;
53
+ return new Promise((resolve, reject) => {
54
+ const client = new ssh2_1.Client();
55
+ let isReady = false;
56
+ client.once('ready', () => {
57
+ isReady = true;
58
+ resolve(client);
59
+ });
60
+ // Kept for the life of the client: an error after `ready` (a reset connection) must never be an unhandled event; whoever uses the
61
+ // client listens for `close` / `error` itself.
62
+ client.on('error', (error) => {
63
+ if (isReady)
64
+ return;
65
+ client.end();
66
+ reject(classifyFailure(error));
67
+ });
68
+ client.connect({
69
+ host: endpoint.host,
70
+ port: endpoint.port,
71
+ username: endpoint.user,
72
+ privateKey,
73
+ algorithms: { serverHostKey },
74
+ hostVerifier: (key) => Buffer.isBuffer(key) && key.equals(pinnedBlob),
75
+ keepaliveInterval: keepaliveIntervalMs,
76
+ keepaliveCountMax,
77
+ readyTimeout: connectReadyTimeoutMs,
78
+ });
79
+ });
80
+ }
81
+ /** @description Run the gate request `request` and read its marker line; `null` when the answer has none (the hub refused, or the key line is gone). `body` is sent as stdin and ends it; without one stdin stays open (`link`). */
82
+ function callGate(client, request, body) {
83
+ return new Promise((resolve, reject) => {
84
+ client.exec(request, async (error, channel) => {
85
+ if (error !== undefined) {
86
+ reject(new HubConnectionError('network', error.message));
87
+ return;
88
+ }
89
+ if (body !== null)
90
+ channel.end(body);
91
+ const read = await (0, gateProtocol_1.readUntilGateMarker)(channel);
92
+ if (read === null || read.marker.request !== request) {
93
+ channel.destroy();
94
+ resolve(null);
95
+ return;
96
+ }
97
+ channel.unshift(read.rest);
98
+ resolve({ marker: read.marker, channel });
99
+ });
100
+ });
101
+ }
102
+ /** @description Everything the channel still sends, as text. */
103
+ async function readChannelText(channel) {
104
+ const chunks = [];
105
+ for await (const chunk of channel)
106
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
107
+ return Buffer.concat(chunks).toString('utf8');
108
+ }
109
+ /** @description A gate request whose answer is one JSON line (`redeem`, `identity`, `unpair`), parsed with `schema`. */
110
+ async function requestGateJson(client, request, body, schema) {
111
+ const answer = await callGate(client, request, body ?? '');
112
+ if (answer === null)
113
+ throw new HubConnectionError('network', 'the hub did not answer the request');
114
+ const text = await readChannelText(answer.channel);
115
+ let parsedJson;
116
+ try {
117
+ parsedJson = JSON.parse(text);
118
+ }
119
+ catch {
120
+ throw new HubConnectionError('network', 'the hub\'s answer is not valid JSON');
121
+ }
122
+ const parsed = schema.safeParse(parsedJson);
123
+ if (!parsed.success)
124
+ throw new HubConnectionError('network', 'the hub\'s answer is not what this version expects');
125
+ return parsed.data;
126
+ }
127
+ //# sourceMappingURL=hubClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hubClient.js","sourceRoot":"","sources":["../../src/runnerUtility/hubClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { Duplex } from 'stream';
2
+ import type { Server } from 'ssh2';
3
+ /**
4
+ * @description ssh2's `Server.injectSocket` is typed for a `net.Socket` but takes any bidirectional stream «as though it were a TCP
5
+ * socket connection» — the channel the hub's gate speaks over, and a `direct-tcpip` channel of that session, are such streams; this is
6
+ * how the runner serves ssh over a link. The one cast the library's typing needs is here.
7
+ */
8
+ export declare function injectStreamIntoSshServer(server: Server, stream: Duplex): void;
9
+ //# sourceMappingURL=injectStream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectStream.d.ts","sourceRoot":"","sources":["../../src/runnerUtility/injectStream.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAE9E"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.injectStreamIntoSshServer = injectStreamIntoSshServer;
4
+ /**
5
+ * @description ssh2's `Server.injectSocket` is typed for a `net.Socket` but takes any bidirectional stream «as though it were a TCP
6
+ * socket connection» — the channel the hub's gate speaks over, and a `direct-tcpip` channel of that session, are such streams; this is
7
+ * how the runner serves ssh over a link. The one cast the library's typing needs is here.
8
+ */
9
+ function injectStreamIntoSshServer(server, stream) {
10
+ server.injectSocket(stream);
11
+ }
12
+ //# sourceMappingURL=injectStream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectStream.js","sourceRoot":"","sources":["../../src/runnerUtility/injectStream.ts"],"names":[],"mappings":";;AASA,8DAEC;AAPD;;;;GAIG;AACH,SAAgB,yBAAyB,CAAC,MAAc,EAAE,MAAc;IACtE,MAAM,CAAC,YAAY,CAAC,MAAgB,CAAC,CAAC;AACxC,CAAC"}
@@ -0,0 +1,62 @@
1
+ import { z } from 'zod';
2
+ import { type CommandRunner } from '../selfUpdate/commandRunner';
3
+ import type { RunnerHomePaths } from './runnerHome';
4
+ export declare const iosCheckBudgetMs: number;
5
+ /**
6
+ * How the reason of a `fail` record that is the Simulator's own boot refusal begins. `runner.sh` tells the operator «needs the runner
7
+ * user's login session» for those — Apple gives no Simulator to a daemon — and shows the reason itself for every other failure (no
8
+ * runtime installed, the device could not be created); a test pins that the script carries this very text.
9
+ */
10
+ export declare const iosBootFailureReasonPrefix = "the Simulator did not";
11
+ declare const iosCheckSchema: z.ZodObject<{
12
+ status: z.ZodEnum<{
13
+ skipped: "skipped";
14
+ fail: "fail";
15
+ pass: "pass";
16
+ }>;
17
+ checkedAtMs: z.ZodNumber;
18
+ xcode: z.ZodNullable<z.ZodString>;
19
+ reason: z.ZodNullable<z.ZodString>;
20
+ }, z.core.$strict>;
21
+ /** @name IosCheckRecord @description `ios-check.json`. */
22
+ export type IosCheckRecord = z.infer<typeof iosCheckSchema>;
23
+ export interface SimulatorChoice {
24
+ deviceTypeId: string;
25
+ runtimeId: string;
26
+ }
27
+ /** @description The newest available iOS runtime and an iPhone device type (the newest the list names), out of `simctl list runtimes -j` and `list devicetypes -j`. */
28
+ export declare function chooseSimulator(runtimesJson: string, deviceTypesJson: string): SimulatorChoice | null;
29
+ /** @description `16.2 (16C5032a)` out of `xcodebuild -version`, or `null`. */
30
+ export declare function parseXcodeVersion(output: string): string | null;
31
+ export interface IosCheckDeps {
32
+ runner: CommandRunner;
33
+ platform: NodeJS.Platform;
34
+ now: () => number;
35
+ }
36
+ export declare function createIosCheckDeps(): IosCheckDeps;
37
+ export declare function readXcodeVersion(deps: IosCheckDeps): Promise<string | null>;
38
+ /** @description Run the boot check: create → boot → bootstatus → delete. Never throws; the device is deleted whatever happened. */
39
+ export declare function runIosBootCheck(deps: IosCheckDeps): Promise<IosCheckRecord>;
40
+ export declare function readIosCheck(paths: RunnerHomePaths): IosCheckRecord | null;
41
+ /** @description One line, so `runner.sh probe` can read it with `grep`. */
42
+ export declare function writeIosCheck(paths: RunnerHomePaths, record: IosCheckRecord): void;
43
+ /** @description Check again when there is no result yet or Xcode is another one than the last result saw (a version, a build, gone). */
44
+ export declare function checkShouldRunIosCheck(last: IosCheckRecord | null, currentXcode: string | null): boolean;
45
+ export interface IosRefreshOptions {
46
+ /**
47
+ * The link just started (a terminal, a LaunchAgent, a LaunchDaemon): check regardless of what the last result says. Whether the Simulator
48
+ * boots depends on WHO runs the link — a result from an interactive login proves nothing for a daemon that replaced it, and a daemon's
49
+ * «fail» must not outlive a switch to a login session — so the same Xcode version is no reason to trust an older result. Within one run
50
+ * (the hourly look) only a different Xcode starts a check.
51
+ */
52
+ isStartup: boolean;
53
+ }
54
+ /**
55
+ * @description At the link's start (always) and then once an hour (when Xcode is not what the last result saw): run the boot check and record it.
56
+ * At the start the old record is deleted first: a paired Mac with no record answers «being checked», so an answer given by another account or
57
+ * kind of service is never offered while the new check runs. (`runIosBootCheck` never throws — a failed boot is a `fail` record; what can
58
+ * throw here is writing the record, and the callers log that.)
59
+ */
60
+ export declare function refreshIosCheck(paths: RunnerHomePaths, deps: IosCheckDeps, options: IosRefreshOptions): Promise<IosCheckRecord | null>;
61
+ export {};
62
+ //# sourceMappingURL=iosCheck.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iosCheck.d.ts","sourceRoot":"","sources":["../../src/runnerUtility/iosCheck.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAgBpD,eAAO,MAAM,gBAAgB,QAAa,CAAC;AAG3C;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,0BAA0B,CAAC;AAElE,QAAA,MAAM,cAAc;;;;;;;;;kBAMlB,CAAC;AAEH,0DAA0D;AAC1D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAgCD,uKAAuK;AACvK,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAOrG;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI/D;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC1B,GAAG,EAAE,MAAM,MAAM,CAAC;CACnB;AAED,wBAAgB,kBAAkB,IAAI,YAAY,CAEjD;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIjF;AAQD,mIAAmI;AACnI,wBAAsB,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CA2BjF;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,cAAc,GAAG,IAAI,CAO1E;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAElF;AAED,wIAAwI;AACxI,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAGxG;AAED,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAQ5I"}
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.iosBootFailureReasonPrefix = exports.iosCheckBudgetMs = void 0;
37
+ exports.chooseSimulator = chooseSimulator;
38
+ exports.parseXcodeVersion = parseXcodeVersion;
39
+ exports.createIosCheckDeps = createIosCheckDeps;
40
+ exports.readXcodeVersion = readXcodeVersion;
41
+ exports.runIosBootCheck = runIosBootCheck;
42
+ exports.readIosCheck = readIosCheck;
43
+ exports.writeIosCheck = writeIosCheck;
44
+ exports.checkShouldRunIosCheck = checkShouldRunIosCheck;
45
+ exports.refreshIosCheck = refreshIosCheck;
46
+ const fs = __importStar(require("fs"));
47
+ const zod_1 = require("zod");
48
+ const configDirFile_1 = require("../configDirFile");
49
+ const commandRunner_1 = require("../selfUpdate/commandRunner");
50
+ /**
51
+ * @description Can this runner drive the iOS Simulator? Apple: the Simulator is not available to a LaunchDaemon or a process started as
52
+ * another user — it needs the account's own login session. So the runner does not guess from «Xcode is installed»: it really boots one.
53
+ * A bounded check (create a device → boot it → wait for the boot to finish → delete it) runs when the link starts and whenever Xcode
54
+ * changes, and its result is written to `ios-check.json`, one line, for `runner.sh probe` to turn into the `ios` capability:
55
+ *
56
+ * pass the Simulator boots here → `ios`
57
+ * fail it does not → «ios: no — needs the runner user's login session» (a helper in that user's GUI session is a follow-up)
58
+ * skipped not macOS, or no Xcode → nothing to say
59
+ *
60
+ * Whatever happens, the simulator device the check made is deleted again.
61
+ */
62
+ const stepTimeoutMs = 60 * 1000;
63
+ exports.iosCheckBudgetMs = 180 * 1000;
64
+ const checkDeviceName = 'charness-runner-boot-check';
65
+ /**
66
+ * How the reason of a `fail` record that is the Simulator's own boot refusal begins. `runner.sh` tells the operator «needs the runner
67
+ * user's login session» for those — Apple gives no Simulator to a daemon — and shows the reason itself for every other failure (no
68
+ * runtime installed, the device could not be created); a test pins that the script carries this very text.
69
+ */
70
+ exports.iosBootFailureReasonPrefix = 'the Simulator did not';
71
+ const iosCheckSchema = zod_1.z.strictObject({
72
+ status: zod_1.z.enum(['pass', 'fail', 'skipped']),
73
+ checkedAtMs: zod_1.z.number().int().nonnegative(),
74
+ /** `16.2 (16C5032a)`: what Xcode was when this was checked; a different one means check again. */
75
+ xcode: zod_1.z.string().nullable(),
76
+ reason: zod_1.z.string().nullable(),
77
+ });
78
+ function compareVersions(left, right) {
79
+ const leftParts = left.split('.').map(Number);
80
+ const rightParts = right.split('.').map(Number);
81
+ for (let index = 0; index < Math.max(leftParts.length, rightParts.length); index += 1) {
82
+ const difference = (leftParts[index] ?? 0) - (rightParts[index] ?? 0);
83
+ if (difference !== 0)
84
+ return difference;
85
+ }
86
+ return 0;
87
+ }
88
+ function parseJsonObject(text) {
89
+ try {
90
+ return JSON.parse(text);
91
+ }
92
+ catch {
93
+ return null;
94
+ }
95
+ }
96
+ /** @description The newest available iOS runtime and an iPhone device type (the newest the list names), out of `simctl list runtimes -j` and `list devicetypes -j`. */
97
+ function chooseSimulator(runtimesJson, deviceTypesJson) {
98
+ const runtimes = parseJsonObject(runtimesJson)?.runtimes ?? [];
99
+ const deviceTypes = parseJsonObject(deviceTypesJson)?.devicetypes ?? [];
100
+ const ios = runtimes.filter((runtime) => runtime.platform === 'iOS' && runtime.isAvailable !== false).sort((left, right) => compareVersions(right.version, left.version));
101
+ const iphones = deviceTypes.filter((deviceType) => deviceType.productFamily === 'iPhone');
102
+ const iphone = iphones.at(-1);
103
+ return ios.length === 0 || iphone === undefined ? null : { runtimeId: ios[0].identifier, deviceTypeId: iphone.identifier };
104
+ }
105
+ /** @description `16.2 (16C5032a)` out of `xcodebuild -version`, or `null`. */
106
+ function parseXcodeVersion(output) {
107
+ const version = /Xcode\s+(\S+)/.exec(output)?.[1];
108
+ const build = /Build version\s+(\S+)/.exec(output)?.[1];
109
+ return version === undefined ? null : build === undefined ? version : `${version} (${build})`;
110
+ }
111
+ function createIosCheckDeps() {
112
+ return { runner: commandRunner_1.runCommand, platform: process.platform, now: Date.now };
113
+ }
114
+ async function readXcodeVersion(deps) {
115
+ if (deps.platform !== 'darwin')
116
+ return null;
117
+ const result = await deps.runner('xcodebuild', ['-version'], { timeoutMs: stepTimeoutMs });
118
+ return result.ok ? parseXcodeVersion(result.stdout) : null;
119
+ }
120
+ /** `simctl <step> failed: <last line of its stderr>` (or how it ended): the reason for a simctl command that did not work at all, which is not the same as «nothing installed». */
121
+ function describeSimctlFailure(stepName, result) {
122
+ const lastErrorLine = result.stderr.trim().split('\n').slice(-1)[0];
123
+ return `simctl ${stepName} failed: ${lastErrorLine !== '' ? lastErrorLine : result.isTimedOut ? 'no answer in time' : `exit ${result.exitCode ?? 'none'}`}`;
124
+ }
125
+ /** @description Run the boot check: create → boot → bootstatus → delete. Never throws; the device is deleted whatever happened. */
126
+ async function runIosBootCheck(deps) {
127
+ const xcode = await readXcodeVersion(deps);
128
+ const record = (status, reason) => ({ status, checkedAtMs: deps.now(), xcode, reason });
129
+ if (deps.platform !== 'darwin')
130
+ return record('skipped', 'not macOS');
131
+ if (xcode === null)
132
+ return record('skipped', 'no Xcode');
133
+ const deadline = deps.now() + exports.iosCheckBudgetMs;
134
+ const step = (args) => deps.runner('xcrun', ['simctl', ...args], { timeoutMs: Math.max(1000, Math.min(stepTimeoutMs, deadline - deps.now())) });
135
+ const runtimes = await step(['list', 'runtimes', '-j']);
136
+ const deviceTypes = await step(['list', 'devicetypes', '-j']);
137
+ // A simctl that cannot be run (it cannot reach CoreSimulator, for one) is told as that — «no runtime installed» is only for a list that worked.
138
+ if (!runtimes.ok)
139
+ return record('fail', describeSimctlFailure('list runtimes', runtimes));
140
+ if (!deviceTypes.ok)
141
+ return record('fail', describeSimctlFailure('list devicetypes', deviceTypes));
142
+ const choice = chooseSimulator(runtimes.stdout, deviceTypes.stdout);
143
+ if (choice === null)
144
+ return record('fail', 'no iOS simulator runtime and iPhone device type are installed');
145
+ const created = await step(['create', checkDeviceName, choice.deviceTypeId, choice.runtimeId]);
146
+ if (!created.ok)
147
+ return record('fail', describeSimctlFailure('create', created));
148
+ const udid = created.stdout.trim();
149
+ if (udid === '')
150
+ return record('fail', 'the Simulator device could not be created');
151
+ try {
152
+ const boot = await step(['boot', udid]);
153
+ if (!boot.ok)
154
+ return record('fail', `${exports.iosBootFailureReasonPrefix} boot: ${boot.stderr.trim().split('\n').slice(-1)[0]}`);
155
+ const status = await step(['bootstatus', udid, '-b']);
156
+ return status.ok ? record('pass', null) : record('fail', `${exports.iosBootFailureReasonPrefix} finish booting: ${status.stderr.trim().split('\n').slice(-1)[0]}`);
157
+ }
158
+ finally {
159
+ await step(['shutdown', udid]);
160
+ await step(['delete', udid]);
161
+ }
162
+ }
163
+ function readIosCheck(paths) {
164
+ try {
165
+ const parsed = iosCheckSchema.safeParse(JSON.parse(fs.readFileSync(paths.iosCheck, 'utf8')));
166
+ return parsed.success ? parsed.data : null;
167
+ }
168
+ catch {
169
+ return null;
170
+ }
171
+ }
172
+ /** @description One line, so `runner.sh probe` can read it with `grep`. */
173
+ function writeIosCheck(paths, record) {
174
+ (0, configDirFile_1.writeTextFileAtomically)(paths.iosCheck, `${JSON.stringify(iosCheckSchema.parse(record))}\n`, 0o644);
175
+ }
176
+ /** @description Check again when there is no result yet or Xcode is another one than the last result saw (a version, a build, gone). */
177
+ function checkShouldRunIosCheck(last, currentXcode) {
178
+ if (currentXcode === null)
179
+ return last === null || last.status !== 'skipped' || last.xcode !== null;
180
+ return last === null || last.xcode !== currentXcode;
181
+ }
182
+ /**
183
+ * @description At the link's start (always) and then once an hour (when Xcode is not what the last result saw): run the boot check and record it.
184
+ * At the start the old record is deleted first: a paired Mac with no record answers «being checked», so an answer given by another account or
185
+ * kind of service is never offered while the new check runs. (`runIosBootCheck` never throws — a failed boot is a `fail` record; what can
186
+ * throw here is writing the record, and the callers log that.)
187
+ */
188
+ async function refreshIosCheck(paths, deps, options) {
189
+ if (deps.platform !== 'darwin')
190
+ return null;
191
+ if (options.isStartup)
192
+ fs.rmSync(paths.iosCheck, { force: true });
193
+ const current = await readXcodeVersion(deps);
194
+ if (!options.isStartup && !checkShouldRunIosCheck(readIosCheck(paths), current))
195
+ return null;
196
+ const record = await runIosBootCheck(deps);
197
+ writeIosCheck(paths, record);
198
+ return record;
199
+ }
200
+ //# sourceMappingURL=iosCheck.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iosCheck.js","sourceRoot":"","sources":["../../src/runnerUtility/iosCheck.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { RunnerHomePaths } from './runnerHome';
2
+ export declare function renderLauncher(paths: Pick<RunnerHomePaths, 'currentApp'>, nodePath: string): string;
3
+ /** @description Write the launcher (when it differs) and return its path. */
4
+ export declare function ensureLauncher(paths: RunnerHomePaths, nodePath: string): string;
5
+ //# sourceMappingURL=launcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../../src/runnerUtility/launcher.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAapD,wBAAgB,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAkBnG;AAED,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAW/E"}