charness 3.6.0 → 3.7.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 (582) hide show
  1. package/CHANGELOG.md +274 -0
  2. package/DEVELOPMENT.md +31 -5
  3. package/MIGRATION_RENAME_TO_CHARNESS.md +3 -2
  4. package/README.md +84 -782
  5. package/SETUP.md +37 -10
  6. package/agent-plugin/.claude-plugin/plugin.json +7 -0
  7. package/agent-plugin/README.md +35 -0
  8. package/agent-plugin/skills/charness-delegate-claude/SKILL.md +85 -0
  9. package/agent-plugin/skills/charness-delegate-claude/summarize-events.py +90 -0
  10. package/agent-plugin/skills/charness-delegate-opencode/SKILL.md +68 -0
  11. package/agent-plugin/skills/charness-manager/SKILL.md +152 -0
  12. package/dist/adapters/adapterNames.d.ts +6 -0
  13. package/dist/adapters/adapterNames.d.ts.map +1 -1
  14. package/dist/adapters/adapterNames.js +8 -2
  15. package/dist/adapters/adapterNames.js.map +1 -1
  16. package/dist/adapters/claudeCliAdapter.d.ts +8 -0
  17. package/dist/adapters/claudeCliAdapter.d.ts.map +1 -1
  18. package/dist/adapters/claudeCliAdapter.js +42 -5
  19. package/dist/adapters/claudeCliAdapter.js.map +1 -1
  20. package/dist/adapters/claudeJsonStreamAdapter.d.ts +10 -9
  21. package/dist/adapters/claudeJsonStreamAdapter.d.ts.map +1 -1
  22. package/dist/adapters/claudeJsonStreamAdapter.js +53 -55
  23. package/dist/adapters/claudeJsonStreamAdapter.js.map +1 -1
  24. package/dist/adapters/createAdapter.d.ts +8 -0
  25. package/dist/adapters/createAdapter.d.ts.map +1 -1
  26. package/dist/adapters/createAdapter.js +14 -2
  27. package/dist/adapters/createAdapter.js.map +1 -1
  28. package/dist/adapters/openCodeAdapter.d.ts +43 -6
  29. package/dist/adapters/openCodeAdapter.d.ts.map +1 -1
  30. package/dist/adapters/openCodeAdapter.js +95 -6
  31. package/dist/adapters/openCodeAdapter.js.map +1 -1
  32. package/dist/agentLogin/agentLogin.d.ts +1 -1
  33. package/dist/agentLogin/agentLogin.d.ts.map +1 -1
  34. package/dist/apiRetryKick.d.ts +4 -3
  35. package/dist/apiRetryKick.d.ts.map +1 -1
  36. package/dist/apiRetryKick.js +16 -9
  37. package/dist/apiRetryKick.js.map +1 -1
  38. package/dist/bot.d.ts.map +1 -1
  39. package/dist/bot.js +1313 -381
  40. package/dist/bot.js.map +1 -1
  41. package/dist/cli/claudeProfiles.d.ts +11 -6
  42. package/dist/cli/claudeProfiles.d.ts.map +1 -1
  43. package/dist/cli/claudeProfiles.js +50 -22
  44. package/dist/cli/claudeProfiles.js.map +1 -1
  45. package/dist/cli/hot.d.ts +5 -0
  46. package/dist/cli/hot.d.ts.map +1 -1
  47. package/dist/cli/hot.js +71 -25
  48. package/dist/cli/hot.js.map +1 -1
  49. package/dist/cli/tscWatchGuard.d.ts +95 -0
  50. package/dist/cli/tscWatchGuard.d.ts.map +1 -0
  51. package/dist/cli/tscWatchGuard.js +295 -0
  52. package/dist/cli/tscWatchGuard.js.map +1 -0
  53. package/dist/cli.js +12 -1
  54. package/dist/cli.js.map +1 -1
  55. package/dist/connectors/jira/answerSink.d.ts +10 -0
  56. package/dist/connectors/jira/answerSink.d.ts.map +1 -1
  57. package/dist/connectors/jira/answerSink.js +13 -0
  58. package/dist/connectors/jira/answerSink.js.map +1 -1
  59. package/dist/connectors/jira/config.d.ts +2 -0
  60. package/dist/connectors/jira/config.d.ts.map +1 -1
  61. package/dist/connectors/jira/config.js +9 -1
  62. package/dist/connectors/jira/config.js.map +1 -1
  63. package/dist/connectors/jira/connector.d.ts +11 -1
  64. package/dist/connectors/jira/connector.d.ts.map +1 -1
  65. package/dist/connectors/jira/connector.js +13 -1
  66. package/dist/connectors/jira/connector.js.map +1 -1
  67. package/dist/connectors/jira/inbound.d.ts +29 -4
  68. package/dist/connectors/jira/inbound.d.ts.map +1 -1
  69. package/dist/connectors/jira/inbound.js +71 -8
  70. package/dist/connectors/jira/inbound.js.map +1 -1
  71. package/dist/connectors/jira/issueBlocks.d.ts +5 -0
  72. package/dist/connectors/jira/issueBlocks.d.ts.map +1 -1
  73. package/dist/connectors/jira/issueBlocks.js +11 -0
  74. package/dist/connectors/jira/issueBlocks.js.map +1 -1
  75. package/dist/connectors/jira/prompt.d.ts +4 -0
  76. package/dist/connectors/jira/prompt.d.ts.map +1 -1
  77. package/dist/connectors/jira/prompt.js +11 -2
  78. package/dist/connectors/jira/prompt.js.map +1 -1
  79. package/dist/connectors/telegram/bindPicker.d.ts +5 -0
  80. package/dist/connectors/telegram/bindPicker.d.ts.map +1 -1
  81. package/dist/connectors/telegram/bindPicker.js +18 -1
  82. package/dist/connectors/telegram/bindPicker.js.map +1 -1
  83. package/dist/connectors/telegram/bindPickerClaims.d.ts +46 -0
  84. package/dist/connectors/telegram/bindPickerClaims.d.ts.map +1 -0
  85. package/dist/connectors/telegram/bindPickerClaims.js +83 -0
  86. package/dist/connectors/telegram/bindPickerClaims.js.map +1 -0
  87. package/dist/connectors/telegram/bindSweep.d.ts +32 -0
  88. package/dist/connectors/telegram/bindSweep.d.ts.map +1 -0
  89. package/dist/connectors/telegram/bindSweep.js +47 -0
  90. package/dist/connectors/telegram/bindSweep.js.map +1 -0
  91. package/dist/connectors/telegram/bindingWelcome.d.ts +23 -0
  92. package/dist/connectors/telegram/bindingWelcome.d.ts.map +1 -0
  93. package/dist/connectors/telegram/bindingWelcome.js +26 -0
  94. package/dist/connectors/telegram/bindingWelcome.js.map +1 -0
  95. package/dist/connectors/telegram/botApiConnection.d.ts +74 -0
  96. package/dist/connectors/telegram/botApiConnection.d.ts.map +1 -0
  97. package/dist/connectors/telegram/botApiConnection.js +201 -0
  98. package/dist/connectors/telegram/botApiConnection.js.map +1 -0
  99. package/dist/connectors/telegram/commands/botCore.d.ts +8 -2
  100. package/dist/connectors/telegram/commands/botCore.d.ts.map +1 -1
  101. package/dist/connectors/telegram/commands/botSkills.d.ts +21 -0
  102. package/dist/connectors/telegram/commands/botSkills.d.ts.map +1 -0
  103. package/dist/connectors/telegram/commands/botSkills.js +133 -0
  104. package/dist/connectors/telegram/commands/botSkills.js.map +1 -0
  105. package/dist/connectors/telegram/commands/callbackMessage.d.ts +5 -0
  106. package/dist/connectors/telegram/commands/callbackMessage.d.ts.map +1 -1
  107. package/dist/connectors/telegram/commands/callbackMessage.js +9 -0
  108. package/dist/connectors/telegram/commands/callbackMessage.js.map +1 -1
  109. package/dist/connectors/telegram/commands/compaction.d.ts +65 -3
  110. package/dist/connectors/telegram/commands/compaction.d.ts.map +1 -1
  111. package/dist/connectors/telegram/commands/compaction.js +512 -94
  112. package/dist/connectors/telegram/commands/compaction.js.map +1 -1
  113. package/dist/connectors/telegram/commands/displayModes.d.ts +1 -1
  114. package/dist/connectors/telegram/commands/displayModes.d.ts.map +1 -1
  115. package/dist/connectors/telegram/commands/displayModes.js +6 -18
  116. package/dist/connectors/telegram/commands/displayModes.js.map +1 -1
  117. package/dist/connectors/telegram/commands/fallbackChain.js +5 -5
  118. package/dist/connectors/telegram/commands/fallbackChain.js.map +1 -1
  119. package/dist/connectors/telegram/commands/reminders.d.ts +1 -1
  120. package/dist/connectors/telegram/commands/reminders.d.ts.map +1 -1
  121. package/dist/connectors/telegram/commands/reminders.js +4 -15
  122. package/dist/connectors/telegram/commands/reminders.js.map +1 -1
  123. package/dist/connectors/telegram/commands/selfUpdate.d.ts.map +1 -1
  124. package/dist/connectors/telegram/commands/selfUpdate.js +1 -11
  125. package/dist/connectors/telegram/commands/selfUpdate.js.map +1 -1
  126. package/dist/connectors/telegram/commands/taskAgents.d.ts +22 -0
  127. package/dist/connectors/telegram/commands/taskAgents.d.ts.map +1 -0
  128. package/dist/connectors/telegram/commands/taskAgents.js +104 -0
  129. package/dist/connectors/telegram/commands/taskAgents.js.map +1 -0
  130. package/dist/connectors/telegram/commands/todo.d.ts +82 -0
  131. package/dist/connectors/telegram/commands/todo.d.ts.map +1 -0
  132. package/dist/connectors/telegram/commands/todo.js +384 -0
  133. package/dist/connectors/telegram/commands/todo.js.map +1 -0
  134. package/dist/connectors/telegram/commands/topicCommand.d.ts +6 -2
  135. package/dist/connectors/telegram/commands/topicCommand.d.ts.map +1 -1
  136. package/dist/connectors/telegram/commands/topicCommand.js +6 -9
  137. package/dist/connectors/telegram/commands/topicCommand.js.map +1 -1
  138. package/dist/connectors/telegram/openBindMessages.d.ts +45 -0
  139. package/dist/connectors/telegram/openBindMessages.d.ts.map +1 -0
  140. package/dist/connectors/telegram/openBindMessages.js +67 -0
  141. package/dist/connectors/telegram/openBindMessages.js.map +1 -0
  142. package/dist/connectors/telegram/outputFlushPlan.d.ts +49 -0
  143. package/dist/connectors/telegram/outputFlushPlan.d.ts.map +1 -1
  144. package/dist/connectors/telegram/outputFlushPlan.js +46 -0
  145. package/dist/connectors/telegram/outputFlushPlan.js.map +1 -1
  146. package/dist/connectors/telegram/pendingTopicName.d.ts +26 -0
  147. package/dist/connectors/telegram/pendingTopicName.d.ts.map +1 -0
  148. package/dist/connectors/telegram/pendingTopicName.js +27 -0
  149. package/dist/connectors/telegram/pendingTopicName.js.map +1 -0
  150. package/dist/connectors/test/connector.d.ts.map +1 -1
  151. package/dist/connectors/test/connector.js +6 -1
  152. package/dist/connectors/test/connector.js.map +1 -1
  153. package/dist/i18n/de.d.ts.map +1 -1
  154. package/dist/i18n/de.js +90 -7
  155. package/dist/i18n/de.js.map +1 -1
  156. package/dist/i18n/en.d.ts.map +1 -1
  157. package/dist/i18n/en.js +90 -7
  158. package/dist/i18n/en.js.map +1 -1
  159. package/dist/i18n/es.d.ts.map +1 -1
  160. package/dist/i18n/es.js +90 -7
  161. package/dist/i18n/es.js.map +1 -1
  162. package/dist/i18n/fr.d.ts.map +1 -1
  163. package/dist/i18n/fr.js +90 -7
  164. package/dist/i18n/fr.js.map +1 -1
  165. package/dist/i18n/hi.d.ts.map +1 -1
  166. package/dist/i18n/hi.js +90 -7
  167. package/dist/i18n/hi.js.map +1 -1
  168. package/dist/i18n/ja.d.ts.map +1 -1
  169. package/dist/i18n/ja.js +90 -7
  170. package/dist/i18n/ja.js.map +1 -1
  171. package/dist/i18n/ka.d.ts.map +1 -1
  172. package/dist/i18n/ka.js +90 -7
  173. package/dist/i18n/ka.js.map +1 -1
  174. package/dist/i18n/pt.d.ts.map +1 -1
  175. package/dist/i18n/pt.js +90 -7
  176. package/dist/i18n/pt.js.map +1 -1
  177. package/dist/i18n/ru.d.ts.map +1 -1
  178. package/dist/i18n/ru.js +90 -7
  179. package/dist/i18n/ru.js.map +1 -1
  180. package/dist/i18n/uk.d.ts.map +1 -1
  181. package/dist/i18n/uk.js +90 -7
  182. package/dist/i18n/uk.js.map +1 -1
  183. package/dist/i18n/uz.d.ts.map +1 -1
  184. package/dist/i18n/uz.js +90 -7
  185. package/dist/i18n/uz.js.map +1 -1
  186. package/dist/i18n/zh.d.ts.map +1 -1
  187. package/dist/i18n/zh.js +90 -7
  188. package/dist/i18n/zh.js.map +1 -1
  189. package/dist/i18n.d.ts +1 -1
  190. package/dist/i18n.js +1 -1
  191. package/dist/installManager.d.ts +13 -0
  192. package/dist/installManager.d.ts.map +1 -1
  193. package/dist/installManager.js +38 -4
  194. package/dist/installManager.js.map +1 -1
  195. package/dist/instanceSettings.d.ts +40 -1
  196. package/dist/instanceSettings.d.ts.map +1 -1
  197. package/dist/instanceSettings.js +105 -26
  198. package/dist/instanceSettings.js.map +1 -1
  199. package/dist/openCodeQuestionFlow.d.ts +30 -0
  200. package/dist/openCodeQuestionFlow.d.ts.map +1 -1
  201. package/dist/openCodeQuestionFlow.js +43 -0
  202. package/dist/openCodeQuestionFlow.js.map +1 -1
  203. package/dist/postToSession.d.ts +20 -5
  204. package/dist/postToSession.d.ts.map +1 -1
  205. package/dist/postToSession.js +38 -7
  206. package/dist/postToSession.js.map +1 -1
  207. package/dist/remoteRun/cliArgs.d.ts +73 -0
  208. package/dist/remoteRun/cliArgs.d.ts.map +1 -0
  209. package/dist/remoteRun/cliArgs.js +197 -0
  210. package/dist/remoteRun/cliArgs.js.map +1 -0
  211. package/dist/remoteRun/commands.d.ts +56 -0
  212. package/dist/remoteRun/commands.d.ts.map +1 -0
  213. package/dist/remoteRun/commands.js +306 -0
  214. package/dist/remoteRun/commands.js.map +1 -0
  215. package/dist/remoteRun/depsPlan.d.ts +16 -0
  216. package/dist/remoteRun/depsPlan.d.ts.map +1 -0
  217. package/dist/remoteRun/depsPlan.js +82 -0
  218. package/dist/remoteRun/depsPlan.js.map +1 -0
  219. package/dist/remoteRun/exitCodes.d.ts +34 -0
  220. package/dist/remoteRun/exitCodes.d.ts.map +1 -0
  221. package/dist/remoteRun/exitCodes.js +38 -0
  222. package/dist/remoteRun/exitCodes.js.map +1 -0
  223. package/dist/remoteRun/foreground.d.ts +29 -0
  224. package/dist/remoteRun/foreground.d.ts.map +1 -0
  225. package/dist/remoteRun/foreground.js +159 -0
  226. package/dist/remoteRun/foreground.js.map +1 -0
  227. package/dist/remoteRun/interrupts.d.ts +17 -0
  228. package/dist/remoteRun/interrupts.d.ts.map +1 -0
  229. package/dist/remoteRun/interrupts.js +41 -0
  230. package/dist/remoteRun/interrupts.js.map +1 -0
  231. package/dist/remoteRun/jobFiles.d.ts +31 -0
  232. package/dist/remoteRun/jobFiles.d.ts.map +1 -0
  233. package/dist/remoteRun/jobFiles.js +84 -0
  234. package/dist/remoteRun/jobFiles.js.map +1 -0
  235. package/dist/remoteRun/jobFormat.d.ts +16 -0
  236. package/dist/remoteRun/jobFormat.d.ts.map +1 -0
  237. package/dist/remoteRun/jobFormat.js +130 -0
  238. package/dist/remoteRun/jobFormat.js.map +1 -0
  239. package/dist/remoteRun/jobId.d.ts +15 -0
  240. package/dist/remoteRun/jobId.d.ts.map +1 -0
  241. package/dist/remoteRun/jobId.js +85 -0
  242. package/dist/remoteRun/jobId.js.map +1 -0
  243. package/dist/remoteRun/jobMeta.d.ts +18 -0
  244. package/dist/remoteRun/jobMeta.d.ts.map +1 -0
  245. package/dist/remoteRun/jobMeta.js +33 -0
  246. package/dist/remoteRun/jobMeta.js.map +1 -0
  247. package/dist/remoteRun/jobQuery.d.ts +12 -0
  248. package/dist/remoteRun/jobQuery.d.ts.map +1 -0
  249. package/dist/remoteRun/jobQuery.js +22 -0
  250. package/dist/remoteRun/jobQuery.js.map +1 -0
  251. package/dist/remoteRun/jobRecords.d.ts +22 -0
  252. package/dist/remoteRun/jobRecords.d.ts.map +1 -0
  253. package/dist/remoteRun/jobRecords.js +145 -0
  254. package/dist/remoteRun/jobRecords.js.map +1 -0
  255. package/dist/remoteRun/jobState.d.ts +62 -0
  256. package/dist/remoteRun/jobState.d.ts.map +1 -0
  257. package/dist/remoteRun/jobState.js +132 -0
  258. package/dist/remoteRun/jobState.js.map +1 -0
  259. package/dist/remoteRun/leaseTiming.d.ts +18 -0
  260. package/dist/remoteRun/leaseTiming.d.ts.map +1 -0
  261. package/dist/remoteRun/leaseTiming.js +43 -0
  262. package/dist/remoteRun/leaseTiming.js.map +1 -0
  263. package/dist/remoteRun/output.d.ts +35 -0
  264. package/dist/remoteRun/output.d.ts.map +1 -0
  265. package/dist/remoteRun/output.js +82 -0
  266. package/dist/remoteRun/output.js.map +1 -0
  267. package/dist/remoteRun/pathPatterns.d.ts +33 -0
  268. package/dist/remoteRun/pathPatterns.d.ts.map +1 -0
  269. package/dist/remoteRun/pathPatterns.js +115 -0
  270. package/dist/remoteRun/pathPatterns.js.map +1 -0
  271. package/dist/remoteRun/probe.d.ts +56 -0
  272. package/dist/remoteRun/probe.d.ts.map +1 -0
  273. package/dist/remoteRun/probe.js +123 -0
  274. package/dist/remoteRun/probe.js.map +1 -0
  275. package/dist/remoteRun/project.d.ts +26 -0
  276. package/dist/remoteRun/project.d.ts.map +1 -0
  277. package/dist/remoteRun/project.js +159 -0
  278. package/dist/remoteRun/project.js.map +1 -0
  279. package/dist/remoteRun/projectConfig.d.ts +38 -0
  280. package/dist/remoteRun/projectConfig.d.ts.map +1 -0
  281. package/dist/remoteRun/projectConfig.js +87 -0
  282. package/dist/remoteRun/projectConfig.js.map +1 -0
  283. package/dist/remoteRun/remoteRunCli.d.ts +15 -0
  284. package/dist/remoteRun/remoteRunCli.d.ts.map +1 -0
  285. package/dist/remoteRun/remoteRunCli.js +144 -0
  286. package/dist/remoteRun/remoteRunCli.js.map +1 -0
  287. package/dist/remoteRun/remoteRunError.d.ts +14 -0
  288. package/dist/remoteRun/remoteRunError.d.ts.map +1 -0
  289. package/dist/remoteRun/remoteRunError.js +28 -0
  290. package/dist/remoteRun/remoteRunError.js.map +1 -0
  291. package/dist/remoteRun/rsync.d.ts +17 -0
  292. package/dist/remoteRun/rsync.d.ts.map +1 -0
  293. package/dist/remoteRun/rsync.js +39 -0
  294. package/dist/remoteRun/rsync.js.map +1 -0
  295. package/dist/remoteRun/runnerClient.d.ts +50 -0
  296. package/dist/remoteRun/runnerClient.d.ts.map +1 -0
  297. package/dist/remoteRun/runnerClient.js +139 -0
  298. package/dist/remoteRun/runnerClient.js.map +1 -0
  299. package/dist/remoteRun/runners.d.ts +57 -0
  300. package/dist/remoteRun/runners.d.ts.map +1 -0
  301. package/dist/remoteRun/runners.js +181 -0
  302. package/dist/remoteRun/runners.js.map +1 -0
  303. package/dist/remoteRun/runnersConfig.d.ts +44 -0
  304. package/dist/remoteRun/runnersConfig.d.ts.map +1 -0
  305. package/dist/remoteRun/runnersConfig.js +107 -0
  306. package/dist/remoteRun/runnersConfig.js.map +1 -0
  307. package/dist/remoteRun/safeCopy.d.ts +31 -0
  308. package/dist/remoteRun/safeCopy.d.ts.map +1 -0
  309. package/dist/remoteRun/safeCopy.js +137 -0
  310. package/dist/remoteRun/safeCopy.js.map +1 -0
  311. package/dist/remoteRun/sendPlan.d.ts +67 -0
  312. package/dist/remoteRun/sendPlan.d.ts.map +1 -0
  313. package/dist/remoteRun/sendPlan.js +139 -0
  314. package/dist/remoteRun/sendPlan.js.map +1 -0
  315. package/dist/remoteRun/ssh.d.ts +62 -0
  316. package/dist/remoteRun/ssh.d.ts.map +1 -0
  317. package/dist/remoteRun/ssh.js +202 -0
  318. package/dist/remoteRun/ssh.js.map +1 -0
  319. package/dist/remoteRun/submit.d.ts +29 -0
  320. package/dist/remoteRun/submit.d.ts.map +1 -0
  321. package/dist/remoteRun/submit.js +142 -0
  322. package/dist/remoteRun/submit.js.map +1 -0
  323. package/dist/requests/answerRequest.d.ts +5 -0
  324. package/dist/requests/answerRequest.d.ts.map +1 -1
  325. package/dist/requests/answerRequest.js +16 -1
  326. package/dist/requests/answerRequest.js.map +1 -1
  327. package/dist/requests/requestLedger.d.ts +13 -0
  328. package/dist/requests/requestLedger.d.ts.map +1 -1
  329. package/dist/requests/requestLedger.js +9 -0
  330. package/dist/requests/requestLedger.js.map +1 -1
  331. package/dist/requests/topicRequestSettle.d.ts +30 -0
  332. package/dist/requests/topicRequestSettle.d.ts.map +1 -0
  333. package/dist/requests/topicRequestSettle.js +23 -0
  334. package/dist/requests/topicRequestSettle.js.map +1 -0
  335. package/dist/requests/wakeUpEngine.d.ts +4 -0
  336. package/dist/requests/wakeUpEngine.d.ts.map +1 -1
  337. package/dist/requests/wakeUpEngine.js +5 -1
  338. package/dist/requests/wakeUpEngine.js.map +1 -1
  339. package/dist/scheduler/delivery.d.ts +2 -0
  340. package/dist/scheduler/delivery.d.ts.map +1 -1
  341. package/dist/scheduler/delivery.js +8 -4
  342. package/dist/scheduler/delivery.js.map +1 -1
  343. package/dist/scheduler/mcpSurface.d.ts +59 -10
  344. package/dist/scheduler/mcpSurface.d.ts.map +1 -1
  345. package/dist/scheduler/mcpSurface.js +276 -79
  346. package/dist/scheduler/mcpSurface.js.map +1 -1
  347. package/dist/scheduler/recurrence.d.ts +5 -0
  348. package/dist/scheduler/recurrence.d.ts.map +1 -1
  349. package/dist/scheduler/recurrence.js +12 -2
  350. package/dist/scheduler/recurrence.js.map +1 -1
  351. package/dist/scheduler/strictToolInput.d.ts +45 -0
  352. package/dist/scheduler/strictToolInput.d.ts.map +1 -0
  353. package/dist/scheduler/strictToolInput.js +155 -0
  354. package/dist/scheduler/strictToolInput.js.map +1 -0
  355. package/dist/scheduler/types.d.ts +5 -0
  356. package/dist/scheduler/types.d.ts.map +1 -1
  357. package/dist/scheduler/workerWatch.d.ts +23 -0
  358. package/dist/scheduler/workerWatch.d.ts.map +1 -0
  359. package/dist/scheduler/workerWatch.js +26 -0
  360. package/dist/scheduler/workerWatch.js.map +1 -0
  361. package/dist/selfUpdate/emittedSource.d.ts +11 -0
  362. package/dist/selfUpdate/emittedSource.d.ts.map +1 -0
  363. package/dist/selfUpdate/emittedSource.js +24 -0
  364. package/dist/selfUpdate/emittedSource.js.map +1 -0
  365. package/dist/selfUpdate/gitSource.d.ts +0 -6
  366. package/dist/selfUpdate/gitSource.d.ts.map +1 -1
  367. package/dist/selfUpdate/gitSource.js +2 -18
  368. package/dist/selfUpdate/gitSource.js.map +1 -1
  369. package/dist/selfUpdate/updatePending.d.ts +1 -1
  370. package/dist/sendErrorClassifier.d.ts +10 -0
  371. package/dist/sendErrorClassifier.d.ts.map +1 -1
  372. package/dist/sendErrorClassifier.js +22 -0
  373. package/dist/sendErrorClassifier.js.map +1 -1
  374. package/dist/state.d.ts +78 -7
  375. package/dist/state.d.ts.map +1 -1
  376. package/dist/state.js +125 -8
  377. package/dist/state.js.map +1 -1
  378. package/dist/stateFile.d.ts +9 -0
  379. package/dist/stateFile.d.ts.map +1 -0
  380. package/dist/stateFile.js +57 -0
  381. package/dist/stateFile.js.map +1 -0
  382. package/dist/stt/sttInstall.d.ts +7 -3
  383. package/dist/stt/sttInstall.d.ts.map +1 -1
  384. package/dist/stt/sttInstall.js +8 -4
  385. package/dist/stt/sttInstall.js.map +1 -1
  386. package/dist/stt/sttSettings.d.ts +2 -1
  387. package/dist/stt/sttSettings.d.ts.map +1 -1
  388. package/dist/stt/sttSettings.js +3 -2
  389. package/dist/stt/sttSettings.js.map +1 -1
  390. package/dist/stt/transcribeChain.js +2 -0
  391. package/dist/stt/transcribeChain.js.map +1 -1
  392. package/dist/testTimings.d.ts +13 -3
  393. package/dist/testTimings.d.ts.map +1 -1
  394. package/dist/testTimings.js +26 -2
  395. package/dist/testTimings.js.map +1 -1
  396. package/dist/todos/board.d.ts +83 -0
  397. package/dist/todos/board.d.ts.map +1 -0
  398. package/dist/todos/board.js +227 -0
  399. package/dist/todos/board.js.map +1 -0
  400. package/dist/todos/format.d.ts +33 -0
  401. package/dist/todos/format.d.ts.map +1 -0
  402. package/dist/todos/format.js +90 -0
  403. package/dist/todos/format.js.map +1 -0
  404. package/dist/todos/merge.d.ts +46 -0
  405. package/dist/todos/merge.d.ts.map +1 -0
  406. package/dist/todos/merge.js +137 -0
  407. package/dist/todos/merge.js.map +1 -0
  408. package/dist/todos/midTurn.d.ts +75 -0
  409. package/dist/todos/midTurn.d.ts.map +1 -0
  410. package/dist/todos/midTurn.js +214 -0
  411. package/dist/todos/midTurn.js.map +1 -0
  412. package/dist/todos/nag.d.ts +85 -0
  413. package/dist/todos/nag.d.ts.map +1 -0
  414. package/dist/todos/nag.js +103 -0
  415. package/dist/todos/nag.js.map +1 -0
  416. package/dist/todos/order.d.ts +25 -0
  417. package/dist/todos/order.d.ts.map +1 -0
  418. package/dist/todos/order.js +61 -0
  419. package/dist/todos/order.js.map +1 -0
  420. package/dist/todos/projects.d.ts +102 -0
  421. package/dist/todos/projects.d.ts.map +1 -0
  422. package/dist/todos/projects.js +342 -0
  423. package/dist/todos/projects.js.map +1 -0
  424. package/dist/todos/registry.d.ts +64 -0
  425. package/dist/todos/registry.d.ts.map +1 -0
  426. package/dist/todos/registry.js +116 -0
  427. package/dist/todos/registry.js.map +1 -0
  428. package/dist/todos/reminderEngine.d.ts +78 -0
  429. package/dist/todos/reminderEngine.d.ts.map +1 -0
  430. package/dist/todos/reminderEngine.js +162 -0
  431. package/dist/todos/reminderEngine.js.map +1 -0
  432. package/dist/todos/store.d.ts +34 -0
  433. package/dist/todos/store.d.ts.map +1 -0
  434. package/dist/todos/store.js +208 -0
  435. package/dist/todos/store.js.map +1 -0
  436. package/dist/todos/tools.d.ts +26 -0
  437. package/dist/todos/tools.d.ts.map +1 -0
  438. package/dist/todos/tools.js +25 -0
  439. package/dist/todos/tools.js.map +1 -0
  440. package/dist/todos/types.d.ts +85 -0
  441. package/dist/todos/types.d.ts.map +1 -0
  442. package/dist/todos/types.js +30 -0
  443. package/dist/todos/types.js.map +1 -0
  444. package/dist/trackers/taskAgentLimit.d.ts +58 -0
  445. package/dist/trackers/taskAgentLimit.d.ts.map +1 -0
  446. package/dist/trackers/taskAgentLimit.js +62 -0
  447. package/dist/trackers/taskAgentLimit.js.map +1 -0
  448. package/dist/trackers/taskAgentSlots.d.ts +109 -0
  449. package/dist/trackers/taskAgentSlots.d.ts.map +1 -0
  450. package/dist/trackers/taskAgentSlots.js +227 -0
  451. package/dist/trackers/taskAgentSlots.js.map +1 -0
  452. package/dist/trackers/types.d.ts +14 -0
  453. package/dist/trackers/types.d.ts.map +1 -0
  454. package/dist/trackers/types.js +3 -0
  455. package/dist/trackers/types.js.map +1 -0
  456. package/dist/types.d.ts +80 -4
  457. package/dist/types.d.ts.map +1 -1
  458. package/dist/utils/adoptReplayGate.d.ts +16 -0
  459. package/dist/utils/adoptReplayGate.d.ts.map +1 -0
  460. package/dist/utils/adoptReplayGate.js +35 -0
  461. package/dist/utils/adoptReplayGate.js.map +1 -0
  462. package/dist/utils/agentPlugin.d.ts +113 -0
  463. package/dist/utils/agentPlugin.d.ts.map +1 -0
  464. package/dist/utils/agentPlugin.js +192 -0
  465. package/dist/utils/agentPlugin.js.map +1 -0
  466. package/dist/utils/autoContinueOnLimit.d.ts +7 -4
  467. package/dist/utils/autoContinueOnLimit.d.ts.map +1 -1
  468. package/dist/utils/autoContinueOnLimit.js +8 -5
  469. package/dist/utils/autoContinueOnLimit.js.map +1 -1
  470. package/dist/utils/botSkills.d.ts +62 -0
  471. package/dist/utils/botSkills.d.ts.map +1 -0
  472. package/dist/utils/botSkills.js +53 -0
  473. package/dist/utils/botSkills.js.map +1 -0
  474. package/dist/utils/botSkillsSetting.d.ts +7 -0
  475. package/dist/utils/botSkillsSetting.d.ts.map +1 -0
  476. package/dist/utils/botSkillsSetting.js +9 -0
  477. package/dist/utils/botSkillsSetting.js.map +1 -0
  478. package/dist/utils/claudeCodeVersion.d.ts +7 -0
  479. package/dist/utils/claudeCodeVersion.d.ts.map +1 -1
  480. package/dist/utils/claudeCodeVersion.js +14 -1
  481. package/dist/utils/claudeCodeVersion.js.map +1 -1
  482. package/dist/utils/claudeCompactHook.d.ts +33 -15
  483. package/dist/utils/claudeCompactHook.d.ts.map +1 -1
  484. package/dist/utils/claudeCompactHook.js +36 -17
  485. package/dist/utils/claudeCompactHook.js.map +1 -1
  486. package/dist/utils/claudeCompactSummary.d.ts +15 -0
  487. package/dist/utils/claudeCompactSummary.d.ts.map +1 -0
  488. package/dist/utils/claudeCompactSummary.js +96 -0
  489. package/dist/utils/claudeCompactSummary.js.map +1 -0
  490. package/dist/utils/claudeLimitSwitch.d.ts +11 -9
  491. package/dist/utils/claudeLimitSwitch.d.ts.map +1 -1
  492. package/dist/utils/claudeLimitSwitch.js +18 -16
  493. package/dist/utils/claudeLimitSwitch.js.map +1 -1
  494. package/dist/utils/claudeProfiles.d.ts +5 -0
  495. package/dist/utils/claudeProfiles.d.ts.map +1 -1
  496. package/dist/utils/claudeProfiles.js +14 -0
  497. package/dist/utils/claudeProfiles.js.map +1 -1
  498. package/dist/utils/claudeSessionTitle.d.ts +2 -1
  499. package/dist/utils/claudeSessionTitle.d.ts.map +1 -1
  500. package/dist/utils/claudeSessionTitle.js +14 -14
  501. package/dist/utils/claudeSessionTitle.js.map +1 -1
  502. package/dist/utils/claudeUsage.d.ts +95 -15
  503. package/dist/utils/claudeUsage.d.ts.map +1 -1
  504. package/dist/utils/claudeUsage.js +241 -41
  505. package/dist/utils/claudeUsage.js.map +1 -1
  506. package/dist/utils/claudeUsageRefresher.d.ts +10 -0
  507. package/dist/utils/claudeUsageRefresher.d.ts.map +1 -1
  508. package/dist/utils/claudeUsageRefresher.js +11 -0
  509. package/dist/utils/claudeUsageRefresher.js.map +1 -1
  510. package/dist/utils/claudeUserEntry.d.ts +50 -0
  511. package/dist/utils/claudeUserEntry.d.ts.map +1 -0
  512. package/dist/utils/claudeUserEntry.js +120 -0
  513. package/dist/utils/claudeUserEntry.js.map +1 -0
  514. package/dist/utils/clearThreadOutputQueues.d.ts +4 -3
  515. package/dist/utils/clearThreadOutputQueues.d.ts.map +1 -1
  516. package/dist/utils/clearThreadOutputQueues.js +1 -1
  517. package/dist/utils/clearThreadOutputQueues.js.map +1 -1
  518. package/dist/utils/compactOnIdle.d.ts +33 -13
  519. package/dist/utils/compactOnIdle.d.ts.map +1 -1
  520. package/dist/utils/compactOnIdle.js +35 -15
  521. package/dist/utils/compactOnIdle.js.map +1 -1
  522. package/dist/utils/fallbackBridge.d.ts +5 -0
  523. package/dist/utils/fallbackBridge.d.ts.map +1 -1
  524. package/dist/utils/fallbackBridge.js +19 -3
  525. package/dist/utils/fallbackBridge.js.map +1 -1
  526. package/dist/utils/fallbackChain.d.ts +9 -3
  527. package/dist/utils/fallbackChain.d.ts.map +1 -1
  528. package/dist/utils/fallbackChain.js +21 -3
  529. package/dist/utils/fallbackChain.js.map +1 -1
  530. package/dist/utils/fileSendPlan.d.ts +6 -0
  531. package/dist/utils/fileSendPlan.d.ts.map +1 -1
  532. package/dist/utils/fileSendPlan.js +11 -0
  533. package/dist/utils/fileSendPlan.js.map +1 -1
  534. package/dist/utils/fileSendService.d.ts +7 -1
  535. package/dist/utils/fileSendService.d.ts.map +1 -1
  536. package/dist/utils/fileSendService.js +6 -2
  537. package/dist/utils/fileSendService.js.map +1 -1
  538. package/dist/utils/groupFinalizePlan.d.ts +8 -10
  539. package/dist/utils/groupFinalizePlan.d.ts.map +1 -1
  540. package/dist/utils/groupFinalizePlan.js +8 -12
  541. package/dist/utils/groupFinalizePlan.js.map +1 -1
  542. package/dist/utils/jsonStreamHost.d.ts +13 -0
  543. package/dist/utils/jsonStreamHost.d.ts.map +1 -1
  544. package/dist/utils/jsonStreamHost.js +13 -0
  545. package/dist/utils/jsonStreamHost.js.map +1 -1
  546. package/dist/utils/messageSendService.d.ts +5 -3
  547. package/dist/utils/messageSendService.d.ts.map +1 -1
  548. package/dist/utils/messageSendService.js +12 -5
  549. package/dist/utils/messageSendService.js.map +1 -1
  550. package/dist/utils/openCodeCompactPlugin.d.ts +39 -14
  551. package/dist/utils/openCodeCompactPlugin.d.ts.map +1 -1
  552. package/dist/utils/openCodeCompactPlugin.js +106 -38
  553. package/dist/utils/openCodeCompactPlugin.js.map +1 -1
  554. package/dist/utils/promptDelivery.d.ts +29 -12
  555. package/dist/utils/promptDelivery.d.ts.map +1 -1
  556. package/dist/utils/promptDelivery.js +13 -5
  557. package/dist/utils/promptDelivery.js.map +1 -1
  558. package/dist/utils/sentKindsSummary.d.ts +10 -0
  559. package/dist/utils/sentKindsSummary.d.ts.map +1 -0
  560. package/dist/utils/sentKindsSummary.js +18 -0
  561. package/dist/utils/sentKindsSummary.js.map +1 -0
  562. package/dist/utils/telegramError.d.ts +6 -0
  563. package/dist/utils/telegramError.d.ts.map +1 -1
  564. package/dist/utils/telegramError.js +12 -0
  565. package/dist/utils/telegramError.js.map +1 -1
  566. package/dist/utils/topicView.d.ts +1 -1
  567. package/dist/utils/topicView.js +1 -1
  568. package/dist/utils/transcribeAudio.d.ts +10 -0
  569. package/dist/utils/transcribeAudio.d.ts.map +1 -1
  570. package/dist/utils/transcribeAudio.js +22 -3
  571. package/dist/utils/transcribeAudio.js.map +1 -1
  572. package/dist/utils/transcriptErrorTime.d.ts +8 -0
  573. package/dist/utils/transcriptErrorTime.d.ts.map +1 -0
  574. package/dist/utils/transcriptErrorTime.js +56 -0
  575. package/dist/utils/transcriptErrorTime.js.map +1 -0
  576. package/dist/utils/wedgeRecovery.d.ts +2 -0
  577. package/dist/utils/wedgeRecovery.d.ts.map +1 -1
  578. package/dist/utils/wedgeRecovery.js +1 -1
  579. package/dist/utils/wedgeRecovery.js.map +1 -1
  580. package/package.json +11 -3
  581. package/remoteRun/runner.sh +1242 -0
  582. package/stt/gigaam_sidecar.py +555 -50
@@ -0,0 +1,137 @@
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.getProtectedPathReason = getProtectedPathReason;
37
+ exports.copyFetchedFiles = copyFetchedFiles;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const pathPatterns_1 = require("./pathPatterns");
41
+ const projectConfig_1 = require("./projectConfig");
42
+ const copiedFileModeMask = 0o777;
43
+ function listFetchedEntries(directory, relativeDirectory, found) {
44
+ for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
45
+ const relativePath = relativeDirectory === '' ? entry.name : path.posix.join(relativeDirectory, entry.name);
46
+ if (entry.isDirectory())
47
+ listFetchedEntries(path.join(directory, entry.name), relativePath, found);
48
+ else
49
+ found.push({ relativePath, kind: entry.isFile() ? 'file' : 'other' });
50
+ }
51
+ }
52
+ /** Create the directories of `relativeDirectory` under `rootReal`, refusing a symlink or a non-directory on the way. `false` = unsafe. */
53
+ function ensureSafeDirectory(rootReal, relativeDirectory) {
54
+ let current = rootReal;
55
+ for (const part of relativeDirectory.split('/').filter((segment) => segment !== '')) {
56
+ current = path.join(current, part);
57
+ let stat;
58
+ try {
59
+ stat = fs.lstatSync(current);
60
+ }
61
+ catch {
62
+ stat = null;
63
+ }
64
+ if (stat === null)
65
+ fs.mkdirSync(current);
66
+ else if (!stat.isDirectory())
67
+ return false;
68
+ }
69
+ return true;
70
+ }
71
+ const gitDirectoryName = '.git';
72
+ /** Is `relativePath` the folder `directory` or inside it? `''` is the project root: everything. Case-insensitive, like the disks that make `.Git` the same as `.git`. */
73
+ function checkIsInsideDirectory(relativePath, directory) {
74
+ if (directory === '')
75
+ return true;
76
+ const lowerPath = relativePath.toLowerCase();
77
+ const lowerDirectory = directory.toLowerCase();
78
+ return lowerPath === lowerDirectory || lowerPath.startsWith(`${lowerDirectory}/`);
79
+ }
80
+ /**
81
+ * @description Why a path may never be copied in, whatever a `pull:` pattern says — or `null`. A broad pattern (`**`) is a trust in the
82
+ * runner for what it names, but some files turn that into code running on the MAIN box: anything under a `.git` (a hook, or
83
+ * `core.hooksPath` / `fsmonitor` in its `config`, run at the next git command), the project's own `.remote-run` (it decides what is sent,
84
+ * installed and pulled next time), and anything in a folder git takes hooks from (`hookDirectories`: `getHookDirectories` in `project.ts` —
85
+ * husky's `.husky`, a `core.hooksPath` inside the project). Compared case-insensitively: on a case-insensitive disk `.Git/hooks` IS
86
+ * `.git/hooks`. Other tools that run commands at commit (lint-staged and lefthook configs, `package.json` scripts) are not recognised:
87
+ * that is what keeping `pull:` narrow is for.
88
+ */
89
+ function getProtectedPathReason(relativePath, hookDirectories = []) {
90
+ if (relativePath.split('/').some((part) => part.toLowerCase() === gitDirectoryName))
91
+ return 'inside a .git';
92
+ if (relativePath.toLowerCase() === projectConfig_1.projectConfigName)
93
+ return "the project's .remote-run";
94
+ const hookDirectory = hookDirectories.find((directory) => checkIsInsideDirectory(relativePath, directory));
95
+ if (hookDirectory !== undefined)
96
+ return hookDirectory === '' ? 'in a project whose git hooks folder is the project root' : `inside the git hooks folder ${hookDirectory}`;
97
+ return null;
98
+ }
99
+ /** @description Copy the files of `fetchedRoot` that `patterns` name into `projectRoot`, as the module comment says. */
100
+ function copyFetchedFiles(params) {
101
+ const isNamed = (0, pathPatterns_1.createPathMatcher)(params.patterns);
102
+ const rootReal = fs.realpathSync(params.projectRoot);
103
+ const entries = [];
104
+ listFetchedEntries(params.fetchedRoot, '', entries);
105
+ const result = { copied: [], refusedCount: 0 };
106
+ for (const entry of entries) {
107
+ const isInside = !entry.relativePath.split('/').includes('..') && !path.isAbsolute(entry.relativePath);
108
+ if (entry.kind !== 'file' || !isInside || !isNamed(entry.relativePath) || getProtectedPathReason(entry.relativePath, params.hookDirectories) !== null) {
109
+ result.refusedCount += 1;
110
+ continue;
111
+ }
112
+ const destination = path.join(rootReal, entry.relativePath);
113
+ if (!ensureSafeDirectory(rootReal, path.posix.dirname(entry.relativePath) === '.' ? '' : path.posix.dirname(entry.relativePath))) {
114
+ result.refusedCount += 1;
115
+ continue;
116
+ }
117
+ let existing;
118
+ try {
119
+ existing = fs.lstatSync(destination);
120
+ }
121
+ catch {
122
+ existing = null;
123
+ }
124
+ if (existing !== null && !existing.isFile()) {
125
+ result.refusedCount += 1;
126
+ continue;
127
+ }
128
+ const source = path.join(params.fetchedRoot, entry.relativePath);
129
+ const temporary = `${destination}.remote-run-${process.pid}.tmp`;
130
+ fs.copyFileSync(source, temporary);
131
+ fs.chmodSync(temporary, fs.statSync(source).mode & copiedFileModeMask);
132
+ fs.renameSync(temporary, destination);
133
+ result.copied.push(entry.relativePath);
134
+ }
135
+ return result;
136
+ }
137
+ //# sourceMappingURL=safeCopy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safeCopy.js","sourceRoot":"","sources":["../../src/remoteRun/safeCopy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @description What goes to the runner and how: the file list (git decides, `.remote-run` trims and opts in), the files held back
3
+ * because they look like secrets, and the rsync argument lists. Pure — the git calls and the process spawns are elsewhere.
4
+ *
5
+ * Sent: tracked and untracked-not-ignored files, submodules included. Never sent: what `.gitignore` names (the runner keeps its own
6
+ * `node_modules`, `build`, caches), `.git` unless `--with-git`, `exclude:` paths, and secret-looking files unless `send:` names them.
7
+ */
8
+ /**
9
+ * rsync decides a file is unchanged when its size and mtime match, and by default the mtime is compared in WHOLE SECONDS: an edit of the
10
+ * same length within the second of the previous version would be skipped, and the runner would keep the old file. A negative modify
11
+ * window compares the nanoseconds too (rsync 3.1.3 or newer on both ends; older ones fall back to seconds).
12
+ */
13
+ export declare const rsyncNanosecondWindowArg = "--modify-window=-1";
14
+ /** @description Does the NAME of `relativePath` look like a secret (`.env`, `.env.*` but not its templates, `*.pem`, `*.p12`, `*.key`, `.npmrc`)? */
15
+ export declare function checkIsSecretLookingFile(relativePath: string): boolean;
16
+ export interface SendListInput {
17
+ /** What git lists as sendable: tracked + untracked-not-ignored, submodule files included, relative to the project root, all of them present on disk. */
18
+ files: readonly string[];
19
+ /** Ignored files that exist (git's `-o -i`), consulted ONLY for what `send:` names. */
20
+ ignoredFiles: readonly string[];
21
+ exclude: readonly string[];
22
+ send: readonly string[];
23
+ }
24
+ export interface SendPlan {
25
+ /** What is sent, sorted. */
26
+ files: string[];
27
+ /** Secret-looking files NOT sent (the caller says which and how to opt in). */
28
+ heldBack: string[];
29
+ /** Names with a newline that `exclude:` does not drop: the whole run is refused (the runner reads its lists one name per line). */
30
+ refused: string[];
31
+ }
32
+ /** @description Turn git's lists into the send plan. `exclude:` beats `send:`; a name with a newline that is not excluded is refused. */
33
+ export declare function planSendList(input: SendListInput): SendPlan;
34
+ /** @description The NUL-separated list `rsync --files-from=- --from0` reads. */
35
+ export declare function formatNulSeparatedList(files: readonly string[]): string;
36
+ /** @description The list the runner diffs between two submits to find deletions: one path per line. */
37
+ export declare function formatManifest(files: readonly string[]): string;
38
+ export interface RsyncSendParams {
39
+ /** The ssh command rsync runs (`-e`), already joined. */
40
+ sshCommand: string;
41
+ /** The project root on this machine. */
42
+ sourceRoot: string;
43
+ /** `host:/path/stage/<job>/` */
44
+ destination: string;
45
+ /** The runner's current copy, so unchanged files are copied locally instead of sent again; `null` on a first send. */
46
+ copyDestination: string | null;
47
+ }
48
+ /**
49
+ * @description `rsync` of the listed files into the job's stage dir. `--copy-dest` (not `--link-dest`): a staged file is a real copy,
50
+ * so a job that rewrites a file in place (`jest -u`) can never change what a queued job of the same project is going to apply.
51
+ */
52
+ export declare function buildRsyncSendArgs(params: RsyncSendParams): string[];
53
+ /** @description `rsync` of the project's `.git` directory into the stage dir (`--with-git`). */
54
+ export declare function buildRsyncGitArgs(params: RsyncSendParams): string[];
55
+ /** @description `rsync` of a small local folder (the job's meta files) to `destination`. */
56
+ export declare function buildRsyncMetaArgs(params: {
57
+ sshCommand: string;
58
+ sourceDirectory: string;
59
+ destination: string;
60
+ }): string[];
61
+ /** @description `rsync` of a job's result files into a local temp folder: no symlinks at all, the runner is not trusted to write into the main box. */
62
+ export declare function buildRsyncFetchArgs(params: {
63
+ sshCommand: string;
64
+ source: string;
65
+ destinationDirectory: string;
66
+ }): string[];
67
+ //# sourceMappingURL=sendPlan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sendPlan.d.ts","sourceRoot":"","sources":["../../src/remoteRun/sendPlan.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AAEH;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAM7D,qJAAqJ;AACrJ,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAKtE;AAED,MAAM,WAAW,aAAa;IAC5B,wJAAwJ;IACxJ,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,uFAAuF;IACvF,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,mIAAmI;IACnI,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,yIAAyI;AACzI,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,QAAQ,CAe3D;AAED,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAEvE;AAED,uGAAuG;AACvG,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAE/D;AAED,MAAM,WAAW,eAAe;IAC9B,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,sHAAsH;IACtH,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,EAAE,CAYpE;AAED,gGAAgG;AAChG,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,EAAE,CAUnE;AAED,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,EAAE,CAEzH;AAED,uJAAuJ;AACvJ,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,oBAAoB,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,EAAE,CAE1H"}
@@ -0,0 +1,139 @@
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.rsyncNanosecondWindowArg = void 0;
37
+ exports.checkIsSecretLookingFile = checkIsSecretLookingFile;
38
+ exports.planSendList = planSendList;
39
+ exports.formatNulSeparatedList = formatNulSeparatedList;
40
+ exports.formatManifest = formatManifest;
41
+ exports.buildRsyncSendArgs = buildRsyncSendArgs;
42
+ exports.buildRsyncGitArgs = buildRsyncGitArgs;
43
+ exports.buildRsyncMetaArgs = buildRsyncMetaArgs;
44
+ exports.buildRsyncFetchArgs = buildRsyncFetchArgs;
45
+ const path = __importStar(require("path"));
46
+ const pathPatterns_1 = require("./pathPatterns");
47
+ /**
48
+ * @description What goes to the runner and how: the file list (git decides, `.remote-run` trims and opts in), the files held back
49
+ * because they look like secrets, and the rsync argument lists. Pure — the git calls and the process spawns are elsewhere.
50
+ *
51
+ * Sent: tracked and untracked-not-ignored files, submodules included. Never sent: what `.gitignore` names (the runner keeps its own
52
+ * `node_modules`, `build`, caches), `.git` unless `--with-git`, `exclude:` paths, and secret-looking files unless `send:` names them.
53
+ */
54
+ /**
55
+ * rsync decides a file is unchanged when its size and mtime match, and by default the mtime is compared in WHOLE SECONDS: an edit of the
56
+ * same length within the second of the previous version would be skipped, and the runner would keep the old file. A negative modify
57
+ * window compares the nanoseconds too (rsync 3.1.3 or newer on both ends; older ones fall back to seconds).
58
+ */
59
+ exports.rsyncNanosecondWindowArg = '--modify-window=-1';
60
+ /** A secret-looking file that is only a template of one (`.env.example`) is sent: it holds no secret. */
61
+ const templateEnvSuffixes = ['.example', '.sample', '.template'];
62
+ const secretFileExtensions = ['.pem', '.p12', '.key'];
63
+ /** @description Does the NAME of `relativePath` look like a secret (`.env`, `.env.*` but not its templates, `*.pem`, `*.p12`, `*.key`, `.npmrc`)? */
64
+ function checkIsSecretLookingFile(relativePath) {
65
+ const name = path.posix.basename(relativePath);
66
+ if (name === '.npmrc' || name === '.env')
67
+ return true;
68
+ if (name.startsWith('.env.'))
69
+ return !templateEnvSuffixes.some((suffix) => name.endsWith(suffix));
70
+ return secretFileExtensions.some((extension) => name.endsWith(extension) && name.length > extension.length);
71
+ }
72
+ /** @description Turn git's lists into the send plan. `exclude:` beats `send:`; a name with a newline that is not excluded is refused. */
73
+ function planSendList(input) {
74
+ const isExcluded = (0, pathPatterns_1.createPathMatcher)(input.exclude);
75
+ const isOptedIn = (0, pathPatterns_1.createPathMatcher)(input.send);
76
+ const candidates = new Set(input.files);
77
+ for (const ignoredFile of input.ignoredFiles) {
78
+ if (isOptedIn(ignoredFile))
79
+ candidates.add(ignoredFile);
80
+ }
81
+ const plan = { files: [], heldBack: [], refused: [] };
82
+ for (const file of [...candidates].sort()) {
83
+ if (isExcluded(file))
84
+ continue;
85
+ if (file.includes('\n'))
86
+ plan.refused.push(file);
87
+ else if (checkIsSecretLookingFile(file) && !isOptedIn(file))
88
+ plan.heldBack.push(file);
89
+ else
90
+ plan.files.push(file);
91
+ }
92
+ return plan;
93
+ }
94
+ /** @description The NUL-separated list `rsync --files-from=- --from0` reads. */
95
+ function formatNulSeparatedList(files) {
96
+ return files.map((file) => `${file}\0`).join('');
97
+ }
98
+ /** @description The list the runner diffs between two submits to find deletions: one path per line. */
99
+ function formatManifest(files) {
100
+ return files.map((file) => `${file}\n`).join('');
101
+ }
102
+ /**
103
+ * @description `rsync` of the listed files into the job's stage dir. `--copy-dest` (not `--link-dest`): a staged file is a real copy,
104
+ * so a job that rewrites a file in place (`jest -u`) can never change what a queued job of the same project is going to apply.
105
+ */
106
+ function buildRsyncSendArgs(params) {
107
+ return [
108
+ '-a',
109
+ exports.rsyncNanosecondWindowArg,
110
+ '--from0',
111
+ '--files-from=-',
112
+ ...(params.copyDestination === null ? [] : [`--copy-dest=${params.copyDestination}`]),
113
+ '-e',
114
+ params.sshCommand,
115
+ `${params.sourceRoot}/`,
116
+ params.destination,
117
+ ];
118
+ }
119
+ /** @description `rsync` of the project's `.git` directory into the stage dir (`--with-git`). */
120
+ function buildRsyncGitArgs(params) {
121
+ return [
122
+ '-a',
123
+ exports.rsyncNanosecondWindowArg,
124
+ ...(params.copyDestination === null ? [] : [`--copy-dest=${params.copyDestination}`]),
125
+ '-e',
126
+ params.sshCommand,
127
+ `${params.sourceRoot}/.git/`,
128
+ `${params.destination}.git/`,
129
+ ];
130
+ }
131
+ /** @description `rsync` of a small local folder (the job's meta files) to `destination`. */
132
+ function buildRsyncMetaArgs(params) {
133
+ return ['-rt', '-e', params.sshCommand, `${params.sourceDirectory}/`, params.destination];
134
+ }
135
+ /** @description `rsync` of a job's result files into a local temp folder: no symlinks at all, the runner is not trusted to write into the main box. */
136
+ function buildRsyncFetchArgs(params) {
137
+ return ['-rt', '--no-links', '-e', params.sshCommand, `${params.source}/`, `${params.destinationDirectory}/`];
138
+ }
139
+ //# sourceMappingURL=sendPlan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sendPlan.js","sourceRoot":"","sources":["../../src/remoteRun/sendPlan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import { type ChildProcessWithoutNullStreams } from 'child_process';
2
+ import type { RunnerConfig } from './runnersConfig';
3
+ /** @description Where remote-run keeps its local cache (ssh control sockets, the last probe of each runner): `${XDG_CACHE_HOME:-~/.cache}/charness/remote-run`. */
4
+ export declare function getRemoteRunCacheDir(env?: NodeJS.ProcessEnv, homeDir?: string): string;
5
+ /** @description Create the cache dir (mode 0700) and its ssh folder. */
6
+ export declare function ensureRemoteRunCacheDir(cacheDir: string): void;
7
+ /** @description The ssh options of every call to `runner` (without the destination): the operator's own first — ssh keeps the first value of an option — then ours. */
8
+ export declare function buildSshArgs(runner: Pick<RunnerConfig, 'sshOptions'>, cacheDir: string): string[];
9
+ /** @description One word quoted for a POSIX shell (`shellSingleQuote`; an already plain word stays as it is, so the commands read well in a log). */
10
+ export declare function quoteShellWord(word: string): string;
11
+ /** @description The words of an argument list as one string rsync's `-e` and a shell both read back as the same words. */
12
+ export declare function joinShellWords(words: readonly string[]): string;
13
+ /** @description The `-e` command of rsync: `ssh <options> <destination>` is rsync's to complete, so this is `ssh <options>`. */
14
+ export declare function buildRsyncSshCommand(runner: Pick<RunnerConfig, 'sshOptions'>, cacheDir: string): string;
15
+ /** @description A path for the REMOTE shell: a leading `~` stays unquoted so the runner's shell expands it. */
16
+ export declare function quoteRemotePath(remotePath: string): string;
17
+ export interface RunnerScriptCall {
18
+ runner: Pick<RunnerConfig, 'workDir' | 'pueue'>;
19
+ /** `runner-<sha8>.sh` */
20
+ scriptName: string;
21
+ subcommand: string;
22
+ /** After the work dir the script always gets first. */
23
+ args: readonly string[];
24
+ }
25
+ /** @description The command line that runs one subcommand of the uploaded script on the runner (Pueue's binary and config through the environment). */
26
+ export declare function buildRunnerScriptCommand(call: RunnerScriptCall): string;
27
+ /** @description The command that writes the script from stdin into `<workDir>/bin/` unless it is already there (a temp file and a rename, so a half upload is never run). */
28
+ export declare function buildScriptUploadCommand(runner: Pick<RunnerConfig, 'workDir'>, scriptName: string): string;
29
+ export declare function buildScriptExistsCommand(runner: Pick<RunnerConfig, 'workDir'>, scriptName: string): string;
30
+ /** The exit status ssh itself reports when it could not run the command. */
31
+ export declare const sshFailureExitCode = 255;
32
+ /**
33
+ * @description Did the ssh call end because the CONNECTION failed (ssh's own status 255, or a process that was killed), rather than
34
+ * because the command on the runner ended with a status of its own? The runner script's refusals exit 125 and a job's code is whatever its
35
+ * command returned, so only this one is worth opening the connection again for.
36
+ */
37
+ export declare function checkIsConnectionLost(exitCode: number | null): boolean;
38
+ export interface SshRunResult {
39
+ /** `null` when the process was killed (a timeout). */
40
+ exitCode: number | null;
41
+ stdout: string;
42
+ stderr: string;
43
+ isTimedOut: boolean;
44
+ }
45
+ export interface SshRunParams {
46
+ runner: Pick<RunnerConfig, 'ssh' | 'sshOptions'>;
47
+ cacheDir: string;
48
+ remoteCommand: string;
49
+ /** Written to the command's stdin, then closed. */
50
+ input?: string;
51
+ /** The deadline; the ssh process is killed when it passes. */
52
+ timeoutMs: number;
53
+ /** Ends the call from outside (a caller's own, shared deadline): the ssh process is killed and the result says it was cut off. */
54
+ signal?: AbortSignal;
55
+ }
56
+ /** @description Run one command on the runner and collect its output, with a deadline. */
57
+ export declare function runSshCommand(params: SshRunParams): Promise<SshRunResult>;
58
+ /** @description Start a long-lived ssh command whose streams the caller handles itself (the lease, `exec`, `wait`); the caller owns its deadline and its end. */
59
+ export declare function spawnSshStream(params: Omit<SshRunParams, 'input' | 'timeoutMs'>): ChildProcessWithoutNullStreams;
60
+ /** @description Close the master connection of a runner (`ssh -O exit`), best effort: a lingering master is harmless (ControlPersist ends it) but a test wants none left. */
61
+ export declare function closeSshMaster(runner: Pick<RunnerConfig, 'ssh' | 'sshOptions'>, cacheDir: string): Promise<void>;
62
+ //# sourceMappingURL=ssh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssh.d.ts","sourceRoot":"","sources":["../../src/remoteRun/ssh.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,202 @@
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.sshFailureExitCode = void 0;
37
+ exports.getRemoteRunCacheDir = getRemoteRunCacheDir;
38
+ exports.ensureRemoteRunCacheDir = ensureRemoteRunCacheDir;
39
+ exports.buildSshArgs = buildSshArgs;
40
+ exports.quoteShellWord = quoteShellWord;
41
+ exports.joinShellWords = joinShellWords;
42
+ exports.buildRsyncSshCommand = buildRsyncSshCommand;
43
+ exports.quoteRemotePath = quoteRemotePath;
44
+ exports.buildRunnerScriptCommand = buildRunnerScriptCommand;
45
+ exports.buildScriptUploadCommand = buildScriptUploadCommand;
46
+ exports.buildScriptExistsCommand = buildScriptExistsCommand;
47
+ exports.checkIsConnectionLost = checkIsConnectionLost;
48
+ exports.runSshCommand = runSshCommand;
49
+ exports.spawnSshStream = spawnSshStream;
50
+ exports.closeSshMaster = closeSshMaster;
51
+ const child_process_1 = require("child_process");
52
+ const fs = __importStar(require("fs"));
53
+ const os = __importStar(require("os"));
54
+ const path = __importStar(require("path"));
55
+ const tmuxExec_1 = require("../utils/tmuxExec");
56
+ /**
57
+ * @description Everything that touches ssh: the argument lists (pure, unit-tested), the quoting for the remote shell, and the process
58
+ * helpers. Always non-interactive (`BatchMode`: a password or an unknown host key is an error, never a prompt), host keys checked as the
59
+ * operator's ssh config says (never `StrictHostKeyChecking=no`), one master connection per runner shared by the several short calls of a
60
+ * run (`ControlMaster`), and every spawned command with a deadline: a blocked connection must end in time, not hang the agent.
61
+ */
62
+ const connectTimeoutSeconds = 15;
63
+ const serverAliveIntervalSeconds = 15;
64
+ const serverAliveCountMax = 3;
65
+ const controlPersistSeconds = 60;
66
+ /** The longest a unix socket path may be (sun_path, with a margin); ssh refuses a longer ControlPath. */
67
+ const unixSocketPathLimit = 100;
68
+ /** `%C` in a ControlPath expands to a 40-character hash. */
69
+ const controlPathHashLength = 40;
70
+ const cacheDirectoryMode = 0o700;
71
+ /** @description Where remote-run keeps its local cache (ssh control sockets, the last probe of each runner): `${XDG_CACHE_HOME:-~/.cache}/charness/remote-run`. */
72
+ function getRemoteRunCacheDir(env = process.env, homeDir = os.homedir()) {
73
+ const cacheHome = env.XDG_CACHE_HOME !== undefined && env.XDG_CACHE_HOME !== '' ? env.XDG_CACHE_HOME : path.join(homeDir, '.cache');
74
+ return path.join(cacheHome, 'charness', 'remote-run');
75
+ }
76
+ /** @description Create the cache dir (mode 0700) and its ssh folder. */
77
+ function ensureRemoteRunCacheDir(cacheDir) {
78
+ fs.mkdirSync(path.join(cacheDir, 'ssh'), { recursive: true, mode: cacheDirectoryMode });
79
+ fs.chmodSync(cacheDir, cacheDirectoryMode);
80
+ fs.chmodSync(path.join(cacheDir, 'ssh'), cacheDirectoryMode);
81
+ }
82
+ /** @description The ssh options of every call to `runner` (without the destination): the operator's own first — ssh keeps the first value of an option — then ours. */
83
+ function buildSshArgs(runner, cacheDir) {
84
+ const controlDirectory = path.join(cacheDir, 'ssh');
85
+ const isControlPathShortEnough = controlDirectory.length + 1 + controlPathHashLength <= unixSocketPathLimit;
86
+ return [
87
+ ...(runner.sshOptions ?? []),
88
+ '-o', 'BatchMode=yes',
89
+ '-o', `ConnectTimeout=${connectTimeoutSeconds}`,
90
+ '-o', `ServerAliveInterval=${serverAliveIntervalSeconds}`,
91
+ '-o', `ServerAliveCountMax=${serverAliveCountMax}`,
92
+ ...(isControlPathShortEnough
93
+ ? ['-o', 'ControlMaster=auto', '-o', `ControlPath=${path.join(controlDirectory, '%C')}`, '-o', `ControlPersist=${controlPersistSeconds}`]
94
+ : ['-o', 'ControlMaster=no']),
95
+ ];
96
+ }
97
+ const safeWordPattern = /^[A-Za-z0-9_@%+=:,./-]+$/;
98
+ /** @description One word quoted for a POSIX shell (`shellSingleQuote`; an already plain word stays as it is, so the commands read well in a log). */
99
+ function quoteShellWord(word) {
100
+ return word !== '' && safeWordPattern.test(word) ? word : (0, tmuxExec_1.shellSingleQuote)(word);
101
+ }
102
+ /** @description The words of an argument list as one string rsync's `-e` and a shell both read back as the same words. */
103
+ function joinShellWords(words) {
104
+ return words.map(quoteShellWord).join(' ');
105
+ }
106
+ /** @description The `-e` command of rsync: `ssh <options> <destination>` is rsync's to complete, so this is `ssh <options>`. */
107
+ function buildRsyncSshCommand(runner, cacheDir) {
108
+ return joinShellWords(['ssh', ...buildSshArgs(runner, cacheDir)]);
109
+ }
110
+ /** @description A path for the REMOTE shell: a leading `~` stays unquoted so the runner's shell expands it. */
111
+ function quoteRemotePath(remotePath) {
112
+ if (remotePath === '~')
113
+ return '~';
114
+ if (remotePath.startsWith('~/'))
115
+ return `~/${quoteShellWord(remotePath.slice(2))}`;
116
+ return quoteShellWord(remotePath);
117
+ }
118
+ /** @description The command line that runs one subcommand of the uploaded script on the runner (Pueue's binary and config through the environment). */
119
+ function buildRunnerScriptCommand(call) {
120
+ const environment = [
121
+ ...(call.runner.pueue?.bin === undefined ? [] : [`PUEUE_BIN=${quoteRemotePath(call.runner.pueue.bin)}`]),
122
+ ...(call.runner.pueue?.config === undefined ? [] : [`PUEUE_CONFIG=${quoteRemotePath(call.runner.pueue.config)}`]),
123
+ ];
124
+ const scriptPath = `${quoteRemotePath(call.runner.workDir)}/bin/${call.scriptName}`;
125
+ return [...environment, 'bash', scriptPath, call.subcommand, quoteRemotePath(call.runner.workDir), ...call.args.map(quoteShellWord)].join(' ');
126
+ }
127
+ /** @description The command that writes the script from stdin into `<workDir>/bin/` unless it is already there (a temp file and a rename, so a half upload is never run). */
128
+ function buildScriptUploadCommand(runner, scriptName) {
129
+ const binDirectory = `${quoteRemotePath(runner.workDir)}/bin`;
130
+ const target = `${binDirectory}/${scriptName}`;
131
+ const temporary = `${binDirectory}/.${scriptName}.$$`;
132
+ return `mkdir -p ${binDirectory} && cat > ${temporary} && chmod 755 ${temporary} && mv -f ${temporary} ${target}`;
133
+ }
134
+ function buildScriptExistsCommand(runner, scriptName) {
135
+ return `test -f ${quoteRemotePath(runner.workDir)}/bin/${scriptName}`;
136
+ }
137
+ /** The exit status ssh itself reports when it could not run the command. */
138
+ exports.sshFailureExitCode = 255;
139
+ /**
140
+ * @description Did the ssh call end because the CONNECTION failed (ssh's own status 255, or a process that was killed), rather than
141
+ * because the command on the runner ended with a status of its own? The runner script's refusals exit 125 and a job's code is whatever its
142
+ * command returned, so only this one is worth opening the connection again for.
143
+ */
144
+ function checkIsConnectionLost(exitCode) {
145
+ return exitCode === null || exitCode === exports.sshFailureExitCode;
146
+ }
147
+ /** @description Run one command on the runner and collect its output, with a deadline. */
148
+ function runSshCommand(params) {
149
+ return new Promise((resolve) => {
150
+ const child = (0, child_process_1.spawn)('ssh', [...buildSshArgs(params.runner, params.cacheDir), params.runner.ssh, params.remoteCommand], { stdio: ['pipe', 'pipe', 'pipe'] });
151
+ let stdout = '';
152
+ let stderr = '';
153
+ let isTimedOut = false;
154
+ const cutOff = () => {
155
+ isTimedOut = true;
156
+ child.kill('SIGKILL');
157
+ };
158
+ const timer = setTimeout(cutOff, params.timeoutMs);
159
+ if (params.signal?.aborted === true)
160
+ cutOff();
161
+ else
162
+ params.signal?.addEventListener('abort', cutOff, { once: true });
163
+ const settle = () => {
164
+ clearTimeout(timer);
165
+ params.signal?.removeEventListener('abort', cutOff);
166
+ };
167
+ child.stdout.setEncoding('utf8');
168
+ child.stderr.setEncoding('utf8');
169
+ child.stdout.on('data', (chunk) => { stdout += chunk; });
170
+ child.stderr.on('data', (chunk) => { stderr += chunk; });
171
+ child.stdin.on('error', () => { });
172
+ child.on('error', (error) => {
173
+ settle();
174
+ resolve({ exitCode: exports.sshFailureExitCode, stdout, stderr: `${stderr}${error.message}\n`, isTimedOut });
175
+ });
176
+ child.on('close', (exitCode) => {
177
+ settle();
178
+ resolve({ exitCode, stdout, stderr, isTimedOut });
179
+ });
180
+ child.stdin.end(params.input ?? '');
181
+ });
182
+ }
183
+ /** @description Start a long-lived ssh command whose streams the caller handles itself (the lease, `exec`, `wait`); the caller owns its deadline and its end. */
184
+ function spawnSshStream(params) {
185
+ return (0, child_process_1.spawn)('ssh', [...buildSshArgs(params.runner, params.cacheDir), params.runner.ssh, params.remoteCommand], { stdio: ['pipe', 'pipe', 'pipe'] });
186
+ }
187
+ /** @description Close the master connection of a runner (`ssh -O exit`), best effort: a lingering master is harmless (ControlPersist ends it) but a test wants none left. */
188
+ function closeSshMaster(runner, cacheDir) {
189
+ return new Promise((resolve) => {
190
+ const child = (0, child_process_1.spawn)('ssh', [...buildSshArgs(runner, cacheDir), '-O', 'exit', runner.ssh], { stdio: 'ignore' });
191
+ const timer = setTimeout(() => child.kill('SIGKILL'), connectTimeoutSeconds * 1000);
192
+ child.on('close', () => {
193
+ clearTimeout(timer);
194
+ resolve();
195
+ });
196
+ child.on('error', () => {
197
+ clearTimeout(timer);
198
+ resolve();
199
+ });
200
+ });
201
+ }
202
+ //# sourceMappingURL=ssh.js.map