@fased/fased 0.1.19 → 0.1.20

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 (201) hide show
  1. package/dist/{agents-ET0n9FED.js → agents-ChQhgSlb.js} +8 -8
  2. package/dist/{attachment-normalize-DMabJMU0.js → attachment-normalize-Cr8RzfVf.js} +1 -1
  3. package/dist/{attachment-normalize-CDK3Kj-a.js → attachment-normalize-DB19KLbl.js} +1 -1
  4. package/dist/{audio-preflight-CKsWKtOL.js → audio-preflight-BLGP3XdB.js} +1 -1
  5. package/dist/{audio-preflight-CK4s7Cpe.js → audio-preflight-BmW52Ycp.js} +1 -1
  6. package/dist/{audio-preflight-DnxL2DTu.js → audio-preflight-CHhcmiXJ.js} +2 -2
  7. package/dist/{audio-preflight-CtOWrCYT.js → audio-preflight-DAevycUR.js} +1 -1
  8. package/dist/{audio-preflight-D4ml3rER.js → audio-preflight-DVwcDm03.js} +2 -2
  9. package/dist/{audit-Cw2GhO1l.js → audit-C5YXYuIL.js} +1 -1
  10. package/dist/{audit-DBfVTWuR.js → audit-DPnCY1UL.js} +1 -1
  11. package/dist/{auth-D6aXaEgt.js → auth-BbQxXxtt.js} +5 -5
  12. package/dist/{auth-choice-CRcRJvDg.js → auth-choice-D8Q1fQwa.js} +1 -1
  13. package/dist/{auth-choice-DCd_rmJr.js → auth-choice-DRyuJ7OL.js} +1 -1
  14. package/dist/{auth-choice-prompt-CHAO6E_x.js → auth-choice-prompt-Bs_OE3ai.js} +1 -1
  15. package/dist/{auth-choice-prompt-BBY8vO5H.js → auth-choice-prompt-EOHB6Adp.js} +1 -1
  16. package/dist/build-info.json +3 -3
  17. package/dist/bundled/boot-md/handler.js +1 -1
  18. package/dist/bundled/session-memory/handler.js +1 -1
  19. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  20. package/dist/{channel-web-rogzKqNR.js → channel-web-BYwefJub.js} +1 -1
  21. package/dist/{channel-web-B90TOW9f.js → channel-web-Do7PfpgZ.js} +1 -1
  22. package/dist/{channels-BDdw6tRB.js → channels-Ca02RvCt.js} +6 -6
  23. package/dist/{channels-CIVRD15I.js → channels-DrEj3b4G.js} +6 -6
  24. package/dist/{channels-cli-BlinY5L-.js → channels-cli-CCa-scQg.js} +5 -5
  25. package/dist/{channels-cli-nB_AyrYg.js → channels-cli-b6IPejdy.js} +5 -5
  26. package/dist/cli/daemon-cli.js +1 -1
  27. package/dist/{cli-BkrcbFie.js → cli-DXIWIIJj.js} +2 -2
  28. package/dist/{cli-DWyf6Ez0.js → cli-eje5udQT.js} +2 -2
  29. package/dist/{command-registry-D0xhHn9Z.js → command-registry-Bs12xiCA.js} +9 -9
  30. package/dist/{completion-cli-BDgp9s2D.js → completion-cli-Btcmy2ZS.js} +2 -2
  31. package/dist/{completion-cli-BpN_WF59.js → completion-cli-RlpZaXwm.js} +1 -1
  32. package/dist/{config-cli-D51JAiE2.js → config-cli-CTo8yFw1.js} +1 -1
  33. package/dist/{config-cli-Di8fNvh8.js → config-cli-D-FqgnuJ.js} +1 -1
  34. package/dist/{configure-ZAJqoe8C.js → configure-CLTc56jo.js} +12 -12
  35. package/dist/{configure-CLUalzZB.js → configure-D0-Sq2kW.js} +12 -12
  36. package/dist/control-ui/assets/app-DXYMrRJ9.js.map +1 -1
  37. package/dist/{cron-cli-CCfMl1ch.js → cron-cli-BstCBSyn.js} +2 -2
  38. package/dist/{cron-cli-COETwgMD.js → cron-cli-pA06wiEq.js} +2 -2
  39. package/dist/{daemon-cli-BwMJ_sub.js → daemon-cli-DiuXEPjO.js} +1 -1
  40. package/dist/{daemon-cli-DUfzwrLw.js → daemon-cli-cyqRsnTF.js} +1 -1
  41. package/dist/daemon-cli.js +1 -1
  42. package/dist/{deps-vuWHR8ix.js → deps-BKAIBkcE.js} +1 -1
  43. package/dist/{deps-BoCGz3bU.js → deps-BWo3ls9h.js} +1 -1
  44. package/dist/entry.js +1 -1
  45. package/dist/extensionAPI.js +1 -1
  46. package/dist/{gateway-cli-DAaMYDEy.js → gateway-cli-BbSS1Nxd.js} +27 -27
  47. package/dist/{gateway-cli-DcooukDx.js → gateway-cli-izDCXWNN.js} +27 -27
  48. package/dist/{health-CD-e8iEW.js → health-DW5NMpNI.js} +2 -2
  49. package/dist/{health-c7sJIXY9.js → health-kF4U3o3b.js} +2 -2
  50. package/dist/{heartbeat-runner-BTRTcwja.js → heartbeat-runner-BnDruNG2.js} +1 -1
  51. package/dist/{heartbeat-runner-DZuApcd1.js → heartbeat-runner-CJP5uO8S.js} +1 -1
  52. package/dist/{hooks-cli-Bq6e41xH.js → hooks-cli-CSFuSiA5.js} +3 -3
  53. package/dist/{hooks-cli--azOmGId.js → hooks-cli-U5qCBqJm.js} +3 -3
  54. package/dist/index.js +7 -7
  55. package/dist/{ipv4-Bxa3Ql2B.js → ipv4-B42xQEbV.js} +2 -2
  56. package/dist/{ipv4-BKbsAV5a.js → ipv4-DSDJ9Fn2.js} +2 -2
  57. package/dist/{lifecycle-DKOezW7h.js → lifecycle-Bbry4K-O.js} +1 -1
  58. package/dist/{lifecycle-DE4kux0k.js → lifecycle-BiNcSCVf.js} +1 -1
  59. package/dist/{list.auth-overview-DQlFpghW.js → list.auth-overview-ByYcn7Ct.js} +1 -1
  60. package/dist/{list.auth-overview-SasQirvR.js → list.auth-overview-Di-jSuQF.js} +1 -1
  61. package/dist/llm-slug-generator.js +1 -1
  62. package/dist/{model-catalog-DHRVUWBf.js → model-catalog-ex4Cpln_.js} +6 -6
  63. package/dist/{models-CIAvUTl5.js → models-BonzQ9Rv.js} +4 -4
  64. package/dist/{models-cli-CxRv-tjs.js → models-cli-Cc0fVKLR.js} +4 -4
  65. package/dist/{models-cli-BW4m-HHk.js → models-cli-DZ05AYqI.js} +5 -5
  66. package/dist/{node-cli-CsYpYqHF.js → node-cli-CKXvITsL.js} +2 -2
  67. package/dist/{node-cli--1sHB0Pz.js → node-cli-Dfl7X414.js} +2 -2
  68. package/dist/{onboard-lbl9C2gj.js → onboard-BDK2o_5B.js} +6 -6
  69. package/dist/{onboard-BoT3D8J9.js → onboard-CpJeEn67.js} +6 -6
  70. package/dist/{onboard-channels-fJXaj04M.js → onboard-channels-CDXretWe.js} +2 -2
  71. package/dist/{onboard-channels-BREKCcFf.js → onboard-channels-ZnUGKi2j.js} +2 -2
  72. package/dist/{onboard-search-D-tM9Xrg.js → onboard-search-BIltnW27.js} +5 -5
  73. package/dist/{onboard-search-C6A1sfph.js → onboard-search-HgNX3hct.js} +5 -5
  74. package/dist/{onboarding-C8AUR3x1.js → onboarding-Bgx1tJnU.js} +53 -44
  75. package/dist/{onboarding-Bejkgd8a.js → onboarding-CBlXOasA.js} +53 -44
  76. package/dist/{openresponses-http-BR0xNXbf.js → openresponses-http-5S3xc2MZ.js} +1 -1
  77. package/dist/{openresponses-http-CyP-RUzR.js → openresponses-http-BBNbIRzc.js} +1 -1
  78. package/dist/{openresponses-http-BYKqYqIr.js → openresponses-http-BTpFUwym.js} +1 -1
  79. package/dist/{openresponses-http-DNXaz2VR.js → openresponses-http-COAxhJal.js} +2 -2
  80. package/dist/{openresponses-http-C8H-a3KL.js → openresponses-http-o273A5SH.js} +2 -2
  81. package/dist/{parent-default-help-B9-EyEJR.js → parent-default-help-BwE33-U1.js} +1 -1
  82. package/dist/{parent-default-help-B57KLY1o.js → parent-default-help-DzWAx_GB.js} +1 -1
  83. package/dist/{pi-embedded-Dtw2m41q.js → pi-embedded-Bnuo5tPq.js} +5 -5
  84. package/dist/{pi-embedded-G-VYb-eT.js → pi-embedded-CeuBUTjd.js} +5 -5
  85. package/dist/{plugin-registry-C5c96kNk.js → plugin-registry-D2IeEq2N.js} +1 -1
  86. package/dist/{plugin-registry-Dr7BDkEc.js → plugin-registry-DjTXh-9g.js} +1 -1
  87. package/dist/plugin-sdk/{audio-preflight-Bf83dqiV.js → audio-preflight-CVWduuEO.js} +1 -1
  88. package/dist/plugin-sdk/{audio-preflight-jaSZX_On.js → audio-preflight-CdPkTmJX.js} +1 -1
  89. package/dist/plugin-sdk/channel-plugin-common.js +1 -1
  90. package/dist/plugin-sdk/{channel-web-Bu6Y92kC.js → channel-web-oM8gCehY.js} +1 -1
  91. package/dist/plugin-sdk/command-status.js +1 -1
  92. package/dist/plugin-sdk/index.js +2 -2
  93. package/dist/plugin-sdk/{openresponses-http-M74cHGFJ.js → openresponses-http-C_9IfZXZ.js} +1 -1
  94. package/dist/plugin-sdk/{openresponses-http-gCxCNpHu.js → openresponses-http-_SiZJaK2.js} +1 -1
  95. package/dist/plugin-sdk/{pi-model-discovery-runtime-FgSYY3zE.js → pi-model-discovery-runtime-BWcaNxzp.js} +1 -1
  96. package/dist/plugin-sdk/{registry-DyRgZdL8.js → registry-DXXOSq_V.js} +8 -8
  97. package/dist/plugin-sdk/{reply-Bu9GXy54.js → reply-e-9_IdAa.js} +5 -5
  98. package/dist/plugin-sdk/src/brand.d.ts +2 -2
  99. package/dist/plugin-sdk/{status-DLh4u6pb.js → status-D_fsW8e3.js} +5 -5
  100. package/dist/plugin-sdk/{web-BqmhQeOi.js → web-BL2TuPTi.js} +1 -1
  101. package/dist/plugin-sdk/{web-BLZesoTn.js → web-CaVSiRWI.js} +2 -2
  102. package/dist/{plugins-cli-CpElRRGB.js → plugins-cli-BMV70lmj.js} +5 -5
  103. package/dist/{plugins-cli-hFcodPhF.js → plugins-cli-Bf0I1xYR.js} +5 -5
  104. package/dist/{program-ByNjbwln.js → program-CZzXG3p4.js} +7 -7
  105. package/dist/{program-context-BJ6EvoUW.js → program-context-CaLlkx1k.js} +24 -24
  106. package/dist/{prompt-select-styled-DyUwhQR0.js → prompt-select-styled-Cj_SHqRt.js} +4 -4
  107. package/dist/{prompt-select-styled-yZlzGWDe.js → prompt-select-styled-DVwrrZSb.js} +4 -4
  108. package/dist/{register.agent-DYThb3Qq.js → register.agent-C-bHdMXU.js} +9 -9
  109. package/dist/{register.agent-QbjX69Zq.js → register.agent-D0ZpgSNd.js} +8 -8
  110. package/dist/{register.configure-CGzVdNRF.js → register.configure-B0PTAyow.js} +12 -12
  111. package/dist/{register.configure-CXn_6bwZ.js → register.configure-B51e7-qt.js} +12 -12
  112. package/dist/{register.maintenance-CiSlTmn6.js → register.maintenance-B3cXfhM1.js} +8 -8
  113. package/dist/{register.maintenance-Cf-qQw2A.js → register.maintenance-BrmIl5VW.js} +9 -9
  114. package/dist/{register.message-CxejzCev.js → register.message-Dzs1vNKG.js} +3 -3
  115. package/dist/{register.message-Bz8Q1BDo.js → register.message-EKaGgJ9I.js} +3 -3
  116. package/dist/{register.onboard-D-DkLJKD.js → register.onboard-BFPT0Hh1.js} +14 -14
  117. package/dist/{register.onboard-DUvd2gzi.js → register.onboard-DmFrOBs4.js} +14 -14
  118. package/dist/{register.setup-BotpXpFX.js → register.setup-5M8f6DaB.js} +14 -14
  119. package/dist/{register.setup-CzJsqVIe.js → register.setup-B0beU4w3.js} +14 -14
  120. package/dist/{register.status-health-sessions-IUpygKVu.js → register.status-health-sessions-9GJwT82K.js} +6 -6
  121. package/dist/{register.status-health-sessions-C9Zx-J4Y.js → register.status-health-sessions-CEIpWahs.js} +6 -6
  122. package/dist/{register.subclis-BtJ07gvR.js → register.subclis-C3yGp0vO.js} +16 -16
  123. package/dist/{reply-BRoR6TOO.js → reply-B034LmuD.js} +6 -6
  124. package/dist/{run-main-J8mnTN8L.js → run-main-DYdI5qyZ.js} +14 -14
  125. package/dist/{runtime-helper-grants-CkoxSD6G.js → runtime-helper-grants-9-0EfflU.js} +1 -1
  126. package/dist/{runtime-helper-grants-DMNl5B0x.js → runtime-helper-grants-BB9I81Ny.js} +1 -1
  127. package/dist/{sandbox-cli-DfarPDi7.js → sandbox-cli-Bl9Lyv-l.js} +2 -2
  128. package/dist/{sandbox-cli-CNyUbQKy.js → sandbox-cli-CAh9nzL6.js} +2 -2
  129. package/dist/{security-cli-DfH_yEpS.js → security-cli-Bt7g6fbK.js} +3 -3
  130. package/dist/{security-cli-DYUEfOxV.js → security-cli-lQy0YwCb.js} +3 -3
  131. package/dist/{server-3-CquHGG.js → server-BKrGeOGh.js} +2 -2
  132. package/dist/{server-OnS0sRn3.js → server-CES-5PaV.js} +2 -2
  133. package/dist/{server-cron-CB9ay7nN.js → server-cron-D3WgivDk.js} +2 -2
  134. package/dist/{server-cron-BclI8dUt.js → server-cron-q6O09WWT.js} +2 -2
  135. package/dist/{server-node-events-B3wjSbTf.js → server-node-events-DE5oWSSB.js} +3 -3
  136. package/dist/{server-node-events-CHH1pmQi.js → server-node-events-Df_2uVcT.js} +3 -3
  137. package/dist/{status-Cf-x3WJB.js → status-CdI_oSZ4.js} +1 -1
  138. package/dist/{status-DhGsqqOx.js → status-CqIzNbBd.js} +1 -1
  139. package/dist/{status-kfsSxAsl.js → status-DrXKyHMz.js} +4 -4
  140. package/dist/{status-SrKDBHd_.js → status-ne0p_x1W.js} +4 -4
  141. package/dist/{tui-CIzUfHHB.js → tui-CF9NTWgo.js} +1 -1
  142. package/dist/{tui-Cvc1YA_t.js → tui-CLXEsHbW.js} +1 -1
  143. package/dist/{tui-cli-D8ECRV-M.js → tui-cli-Bo8T0iEO.js} +3 -3
  144. package/dist/{tui-cli-BxyfSTll.js → tui-cli-DIHJPDjw.js} +3 -3
  145. package/dist/{update-cli-C1i3_uQZ.js → update-cli-RA5GdCSl.js} +9 -9
  146. package/dist/{update-cli-TMwGWZhI.js → update-cli-pAvK-b3V.js} +10 -10
  147. package/dist/{update-runner-ChBrrXIl.js → update-runner-CUbpiOBD.js} +1 -1
  148. package/dist/{update-runner-C6krqlIN.js → update-runner-kVl9uX8I.js} +1 -1
  149. package/dist/{web-vOcMOS29.js → web-BSGV69pb.js} +3 -3
  150. package/dist/{web-l7WkPuq4.js → web-CFtLg8L6.js} +1 -1
  151. package/dist/{web-CjKdghAZ.js → web-CRHqblTb.js} +3 -3
  152. package/dist/{web-CoSbILfi.js → web-D7NnzaWN.js} +1 -1
  153. package/dist/{web-CnR4rHHv.js → web-R6Wrr8ru.js} +1 -1
  154. package/dist/{web-search-providers.runtime-BC_EmT37.js → web-search-providers.runtime-BQw2Sxko.js} +1 -1
  155. package/dist/{web-search-providers.runtime-B09rLDoa.js → web-search-providers.runtime-E9CDTKMh.js} +1 -1
  156. package/docs/install/installer.md +11 -11
  157. package/docs/install/node.md +9 -0
  158. package/docs/security/baseline-checklist.md +7 -2
  159. package/extensions/acpx/package.json +1 -1
  160. package/extensions/bluebubbles/package.json +1 -1
  161. package/extensions/copilot-proxy/package.json +1 -1
  162. package/extensions/diagnostics-otel/package.json +1 -1
  163. package/extensions/discord/package.json +1 -1
  164. package/extensions/fased-federation/package.json +1 -1
  165. package/extensions/feishu/package.json +1 -1
  166. package/extensions/google-gemini-cli-auth/package.json +1 -1
  167. package/extensions/googlechat/package.json +1 -1
  168. package/extensions/imessage/package.json +1 -1
  169. package/extensions/irc/package.json +1 -1
  170. package/extensions/line/package.json +1 -1
  171. package/extensions/llm-task/package.json +1 -1
  172. package/extensions/lobster/package.json +1 -1
  173. package/extensions/matrix/CHANGELOG.md +6 -0
  174. package/extensions/matrix/package.json +1 -1
  175. package/extensions/mattermost/package.json +1 -1
  176. package/extensions/memory-core/package.json +1 -1
  177. package/extensions/memory-lancedb/package.json +1 -1
  178. package/extensions/minimax-portal-auth/package.json +1 -1
  179. package/extensions/msteams/CHANGELOG.md +6 -0
  180. package/extensions/msteams/package.json +1 -1
  181. package/extensions/nextcloud-talk/package.json +1 -1
  182. package/extensions/nostr/CHANGELOG.md +6 -0
  183. package/extensions/nostr/package.json +1 -1
  184. package/extensions/open-prose/package.json +1 -1
  185. package/extensions/sat-mining/package.json +1 -1
  186. package/extensions/signal/package.json +1 -1
  187. package/extensions/slack/package.json +1 -1
  188. package/extensions/synology-chat/package.json +1 -1
  189. package/extensions/telegram/package.json +1 -1
  190. package/extensions/tlon/package.json +1 -1
  191. package/extensions/twitch/CHANGELOG.md +6 -0
  192. package/extensions/twitch/package.json +1 -1
  193. package/extensions/voice-call/CHANGELOG.md +6 -0
  194. package/extensions/voice-call/package.json +1 -1
  195. package/extensions/whatsapp/package.json +1 -1
  196. package/extensions/zalo/CHANGELOG.md +6 -0
  197. package/extensions/zalo/package.json +1 -1
  198. package/extensions/zalouser/CHANGELOG.md +6 -0
  199. package/extensions/zalouser/package.json +1 -1
  200. package/package.json +1 -1
  201. package/scripts/start-managed.sh +2 -2
@@ -1,6 +1,6 @@
1
1
  import { Cu as formatCliCommand, Fn as ensureActiveMemoryPluginAllowlisted, Gu as resolveDefaultAgentId, Qt as readConfigFileSnapshot, Wu as resolveAgentWorkspaceDir, br as collectConfigServiceEnvVars, ma as ensureAuthProfileStore, tn as writeConfigFile } from "./env-C77feXxI.js";
2
2
  import { H as theme, x as resolveUserPath } from "./agent-paths-BI1hx-tF.js";
3
- import { A as waitForGatewayReachable, C as printWizardHeader, E as resolveControlUiLinks, Ha as CONTROL_UI_BOOT_CHECK_PATH, O as summarizeExistingConfig, S as openUrl, T as randomToken, Wa as normalizeControlUiBasePath, bo as enableTailscaleServe, d as DEFAULT_WORKSPACE, f as applyWizardMetadata, g as formatControlUiSshHint, h as ensureWorkspaceAndSessions, k as validateGatewayPasswordInput, m as detectBrowserOpenSupport, to as runFederationAutoConnectOnce, v as handleOnboardingRepair, w as probeGatewayReachable, x as normalizeGatewayTokenInput, xo as findTailscaleBinary, yo as enableTailscaleFunnel } from "./model-catalog-DHRVUWBf.js";
3
+ import { A as waitForGatewayReachable, C as printWizardHeader, E as resolveControlUiLinks, Ha as CONTROL_UI_BOOT_CHECK_PATH, O as summarizeExistingConfig, S as openUrl, T as randomToken, Wa as normalizeControlUiBasePath, bo as enableTailscaleServe, d as DEFAULT_WORKSPACE, f as applyWizardMetadata, g as formatControlUiSshHint, h as ensureWorkspaceAndSessions, k as validateGatewayPasswordInput, m as detectBrowserOpenSupport, to as runFederationAutoConnectOnce, v as handleOnboardingRepair, w as probeGatewayReachable, x as normalizeGatewayTokenInput, xo as findTailscaleBinary, yo as enableTailscaleFunnel } from "./model-catalog-ex4Cpln_.js";
4
4
  import { A as defaultRuntime, Ct as resolveStateDir, E as redactSensitiveText, gt as resolveGatewayPort, j as restoreTerminalState } from "./entry.js";
5
5
  import { n as redactSensitiveUrlLikeString } from "./redact-sensitive-url-BW03TVj8.js";
6
6
  import { a as resolveSignerdBinaryPath, n as installSignerdBinary, o as restartLocalSocketSigner, r as migrateLocalSignerKeystoreToMaterialDir, t as configureWalletForOnboarding } from "./onboarding.wallet--7Yu2hFw.js";
@@ -16,14 +16,14 @@ import { a as resolveHostedOnboardingGatewayStartupMode, i as resolveGatewayStar
16
16
  import { d as buildSystemdUnit, r as isSystemdUserServiceAvailable } from "./systemd-B8OPQXFR.js";
17
17
  import { t as resolveGatewayService } from "./service-2JBjv-ge.js";
18
18
  import { n as auditGatewayServiceConfig, t as SERVICE_AUDIT_CODES } from "./service-audit-COK5O0cM.js";
19
- import { a as promptRemoteGatewayConfig, n as getTailscaleMissingBinNoteLines, r as setupSkills, t as validateIPv4AddressInput, u as promptCustomApiConfig } from "./ipv4-BKbsAV5a.js";
20
- import { s as waitForHostedDashboardBrowserPath } from "./health-CD-e8iEW.js";
21
- import { n as warnIfModelConfigLooksOff, r as applyAuthChoice } from "./auth-choice-CRcRJvDg.js";
22
- import { t as promptAuthChoiceGrouped } from "./auth-choice-prompt-CHAO6E_x.js";
19
+ import { a as promptRemoteGatewayConfig, n as getTailscaleMissingBinNoteLines, r as setupSkills, t as validateIPv4AddressInput, u as promptCustomApiConfig } from "./ipv4-DSDJ9Fn2.js";
20
+ import { s as waitForHostedDashboardBrowserPath } from "./health-DW5NMpNI.js";
21
+ import { n as warnIfModelConfigLooksOff, r as applyAuthChoice } from "./auth-choice-D8Q1fQwa.js";
22
+ import { t as promptAuthChoiceGrouped } from "./auth-choice-prompt-Bs_OE3ai.js";
23
23
  import { n as logConfigUpdated } from "./logging-DZ32I_SP.js";
24
- import { n as setupChannels } from "./onboard-channels-fJXaj04M.js";
24
+ import { n as setupChannels } from "./onboard-channels-CDXretWe.js";
25
25
  import { t as buildWorkspaceHookStatus } from "./hooks-status-DRZciWMZ.js";
26
- import { t as runTui } from "./tui-Cvc1YA_t.js";
26
+ import { t as runTui } from "./tui-CLXEsHbW.js";
27
27
  import { spawn, spawnSync } from "node:child_process";
28
28
  import os from "node:os";
29
29
  import path from "node:path";
@@ -168,7 +168,7 @@ function isHostedSecurityCapableSession(explicitFlag = false) {
168
168
  const sudoersPath = path.join("/etc/sudoers.d", `fased-host-maintenance-${currentUser}`);
169
169
  if (fs.existsSync(sudoersPath)) return true;
170
170
  }
171
- return canRunHostedMaintenanceCommand("sudo -n tailscale status >/dev/null 2>&1") || canRunHostedMaintenanceCommand("sudo -n ufw status >/dev/null 2>&1") || canRunHostedMaintenanceCommand("sudo -n firewall-cmd --state >/dev/null 2>&1") || canRunHostedMaintenanceCommand("sudo -n systemctl is-active --quiet firewalld >/dev/null 2>&1") || canRunHostedMaintenanceCommand("sudo -n systemctl status fased-gateway.service >/dev/null 2>&1");
171
+ return canRunHostedMaintenanceCommand("sudo -n /usr/local/sbin/fased-host-maintenance tailscale-status >/dev/null 2>&1") || canRunHostedMaintenanceCommand("sudo -n /usr/local/sbin/fased-host-maintenance tailnet-ssh-ingress >/dev/null 2>&1") || canRunHostedMaintenanceCommand("sudo -n /usr/local/sbin/fased-host-maintenance firewall-baseline >/dev/null 2>&1") || canRunHostedMaintenanceCommand("sudo -n systemctl status fased-gateway.service >/dev/null 2>&1");
172
172
  }
173
173
 
174
174
  //#endregion
@@ -546,16 +546,18 @@ async function installRootServiceMaintenanceAccess(params) {
546
546
  const sudoers = [
547
547
  `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl restart ${safeServiceName}.service`,
548
548
  `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl restart --no-block ${safeServiceName}.service`,
549
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl start --no-block ${safeServiceName}.service`,
550
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl enable --now ${safeServiceName}.service`,
549
551
  `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl status ${safeServiceName}.service`,
550
- `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl status ${safeServiceName}.service *`,
551
- `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl status ${safeServiceName} *`,
552
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl status ${safeServiceName}.service --no-pager`,
552
553
  `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl is-active ${safeServiceName}.service`,
553
- `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl is-active ${safeServiceName}.service *`,
554
- `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl is-active ${safeServiceName} *`,
555
- `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl show ${safeServiceName}.service *`,
556
- `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl show ${safeServiceName} *`,
557
- `${safeUser} ALL=(root) NOPASSWD: /usr/bin/journalctl -u ${safeServiceName}.service *`,
558
- `${safeUser} ALL=(root) NOPASSWD: /usr/bin/journalctl -u ${safeServiceName} *`
554
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl is-active ${safeServiceName}`,
555
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl show ${safeServiceName}.service -p ActiveState --value`,
556
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl cat ${safeServiceName}.service`,
557
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/journalctl -u ${safeServiceName}.service -n 50 --no-pager`,
558
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/journalctl -u ${safeServiceName}.service -n 120 --no-pager`,
559
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/journalctl -u ${safeServiceName} -n 50 --no-pager`,
560
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/journalctl -u ${safeServiceName} -n 120 --no-pager`
559
561
  ].join("\n");
560
562
  return await runShell([
561
563
  `echo '${Buffer.from(`${sudoers}\n`, "utf8").toString("base64")}' | base64 -d | sudo -n tee '${sudoersPath}' >/dev/null`,
@@ -2747,6 +2749,7 @@ const LOW_MEMORY_HOSTING_SWAP_GB = 4;
2747
2749
  const HOSTING_SWAP_GB = 2;
2748
2750
  const TAILSCALE_INTERACTIVE_TIMEOUT_MS = 120 * 1e3;
2749
2751
  const TAILSCALE_LOGIN_URL_RE = /https:\/\/login\.tailscale\.com\/a\/[A-Za-z0-9_-]+/i;
2752
+ const HOST_MAINTENANCE_HELPER = "/usr/local/sbin/fased-host-maintenance";
2750
2753
  function detectTotalMemoryMb() {
2751
2754
  if (process.platform === "linux") try {
2752
2755
  const match = fs.readFileSync("/proc/meminfo", "utf8").match(/^MemTotal:\s+(\d+)\s+kB/m);
@@ -2847,7 +2850,7 @@ function buildTailscaleLoginWaitCommand(command) {
2847
2850
  `bash -lc ${shellQuote(command)} &`,
2848
2851
  "ts_pid=$!",
2849
2852
  "for _ in $(seq 1 55); do",
2850
- " if tailscale ip -4 >/dev/null 2>&1 || sudo -n tailscale ip -4 >/dev/null 2>&1; then",
2853
+ ` if tailscale ip -4 >/dev/null 2>&1 || ${hostMaintenanceCommand("tailscale-ip4")} >/dev/null 2>&1 || sudo -n tailscale ip -4 >/dev/null 2>&1; then`,
2851
2854
  " kill -INT \"$ts_pid\" >/dev/null 2>&1 || true",
2852
2855
  " wait \"$ts_pid\" >/dev/null 2>&1 || true",
2853
2856
  " exit 0",
@@ -2860,7 +2863,7 @@ function buildTailscaleLoginWaitCommand(command) {
2860
2863
  "done",
2861
2864
  "kill -INT \"$ts_pid\" >/dev/null 2>&1 || true",
2862
2865
  "wait \"$ts_pid\" >/dev/null 2>&1 || true",
2863
- "if tailscale ip -4 >/dev/null 2>&1 || sudo -n tailscale ip -4 >/dev/null 2>&1; then",
2866
+ `if tailscale ip -4 >/dev/null 2>&1 || ${hostMaintenanceCommand("tailscale-ip4")} >/dev/null 2>&1 || sudo -n tailscale ip -4 >/dev/null 2>&1; then`,
2864
2867
  " exit 0",
2865
2868
  "fi",
2866
2869
  "exit 124"
@@ -2913,21 +2916,29 @@ function tailscaleTimedOutButReady(result, logPath, runner = run) {
2913
2916
  function shellQuote(value) {
2914
2917
  return `'${value.replace(/'/g, "'\\''")}'`;
2915
2918
  }
2919
+ function hostMaintenanceCommand(action) {
2920
+ return `sudo -n ${HOST_MAINTENANCE_HELPER} ${action}`;
2921
+ }
2922
+ function hostMaintenanceCommandWithInput(action, input) {
2923
+ return `printf '%s\\n' ${shellQuote(input)} | ${hostMaintenanceCommand(action)}`;
2924
+ }
2916
2925
  function isTailscaleLoggedIn(logPath, runner = run) {
2917
- return runner("tailscale status >/dev/null 2>&1", logPath).ok || runner("sudo -n tailscale status >/dev/null 2>&1", logPath).ok;
2926
+ return runner("tailscale status >/dev/null 2>&1", logPath).ok || runner(`${hostMaintenanceCommand("tailscale-status")} >/dev/null 2>&1`, logPath).ok || runner("sudo -n tailscale status >/dev/null 2>&1", logPath).ok;
2918
2927
  }
2919
2928
  function hasTailscaleIp(logPath, runner = run) {
2920
- return runner("tailscale ip -4 >/dev/null 2>&1", logPath).ok || runner("sudo -n tailscale ip -4 >/dev/null 2>&1", logPath).ok;
2929
+ return runner("tailscale ip -4 >/dev/null 2>&1", logPath).ok || runner(`${hostMaintenanceCommand("tailscale-ip4")} >/dev/null 2>&1`, logPath).ok || runner("sudo -n tailscale ip -4 >/dev/null 2>&1", logPath).ok;
2921
2930
  }
2922
2931
  function readTailscaleIp(logPath, runner = run) {
2923
2932
  const probe = runner("tailscale ip -4", logPath);
2924
- const sudoProbe = probe.ok ? probe : runner("sudo -n tailscale ip -4", logPath);
2933
+ const helperProbe = probe.ok ? probe : runner(hostMaintenanceCommand("tailscale-ip4"), logPath);
2934
+ const sudoProbe = helperProbe.ok ? helperProbe : runner("sudo -n tailscale ip -4", logPath);
2925
2935
  if (!sudoProbe.ok || !sudoProbe.detail) return;
2926
2936
  return sudoProbe.detail.match(/\b\d{1,3}(?:\.\d{1,3}){3}\b/)?.[0];
2927
2937
  }
2928
2938
  function readTailscaleSelf(logPath, runner = run) {
2929
2939
  const probe = runner("tailscale status --json", logPath);
2930
- const sudoProbe = probe.ok ? probe : runner("sudo -n tailscale status --json", logPath);
2940
+ const helperProbe = probe.ok ? probe : runner(hostMaintenanceCommand("tailscale-status-json"), logPath);
2941
+ const sudoProbe = helperProbe.ok ? helperProbe : runner("sudo -n tailscale status --json", logPath);
2931
2942
  if (!sudoProbe.ok || !sudoProbe.detail) return { ipv4: readTailscaleIp(logPath, runner) };
2932
2943
  try {
2933
2944
  const parsed = JSON.parse(sudoProbe.detail);
@@ -3033,7 +3044,8 @@ function verifyTailnetSshServerPrerequisites(params) {
3033
3044
  };
3034
3045
  }
3035
3046
  function ensureTailnetSshIngressForVerification(params) {
3036
- const result = (params.runner ?? run)([
3047
+ const runner = params.runner ?? run;
3048
+ const command = [
3037
3049
  "if command -v ufw >/dev/null 2>&1; then",
3038
3050
  " if sudo -n ufw status | grep -qi '^Status: active'; then",
3039
3051
  " sudo -n ufw insert 1 allow in on tailscale0 to any port 22 proto tcp || sudo -n ufw allow in on tailscale0 to any port 22 proto tcp",
@@ -3044,7 +3056,9 @@ function ensureTailnetSshIngressForVerification(params) {
3044
3056
  " sudo -n firewall-cmd --permanent --zone=trusted --add-interface=tailscale0 >/dev/null 2>&1 || true",
3045
3057
  " sudo -n firewall-cmd --reload >/dev/null 2>&1 || true",
3046
3058
  "fi"
3047
- ].join("\n"), params.logPath);
3059
+ ].join("\n");
3060
+ const helperResult = runner(hostMaintenanceCommand("tailnet-ssh-ingress"), params.logPath);
3061
+ const result = helperResult.ok ? helperResult : runner(command, params.logPath);
3048
3062
  if (!result.ok) return {
3049
3063
  ok: false,
3050
3064
  detail: result.detail ?? "could not prepare tailnet SSH firewall rule before verification"
@@ -3131,7 +3145,7 @@ async function confirmTailnetSshBeforeLockdown(params) {
3131
3145
  return false;
3132
3146
  }
3133
3147
  await prompter.note(formatTailscaleAccountBrowserLoginNote(), "Tailscale login");
3134
- const tsReset = await interactiveRunner("sudo -n tailscale logout && sudo -n tailscale up --ssh --accept-routes --reset", logPath, prompter);
3148
+ const tsReset = await interactiveRunner(hostMaintenanceCommand("tailscale-up-reset-ssh"), logPath, prompter);
3135
3149
  const acceptedTimedOutLogin = tailscaleTimedOutButReady(tsReset, logPath, runner);
3136
3150
  if (!tsReset.ok && !acceptedTimedOutLogin || !hasTailscaleIp(logPath, runner)) {
3137
3151
  runtime.error("Hosting setup stopped before SSH/firewall lock-down.");
@@ -3175,9 +3189,9 @@ function ensureTailscaleServe(port, logPath) {
3175
3189
  ok: true,
3176
3190
  detail: `tailscale serve --bg -> 127.0.0.1:${port}`
3177
3191
  };
3178
- if (run(`sudo -n tailscale serve --bg http://127.0.0.1:${port}`, logPath).ok) return {
3192
+ if (run(hostMaintenanceCommandWithInput("tailscale-serve", String(port)), logPath).ok) return {
3179
3193
  ok: true,
3180
- detail: `sudo tailscale serve --bg -> 127.0.0.1:${port}`
3194
+ detail: `host maintenance tailscale serve -> 127.0.0.1:${port}`
3181
3195
  };
3182
3196
  if (run(`tailscale serve https / http://127.0.0.1:${port}`, logPath).ok) return {
3183
3197
  ok: true,
@@ -3201,7 +3215,7 @@ function isTailscaleServeReady(port) {
3201
3215
  ],
3202
3216
  encoding: "utf8"
3203
3217
  });
3204
- if ((probe.status ?? 1) !== 0) probe = spawnSync("bash", ["-lc", "sudo -n tailscale serve status"], {
3218
+ if ((probe.status ?? 1) !== 0) probe = spawnSync("bash", ["-lc", hostMaintenanceCommand("tailscale-serve-status")], {
3205
3219
  stdio: [
3206
3220
  "ignore",
3207
3221
  "pipe",
@@ -3234,6 +3248,7 @@ function packageInstallCommand(packages) {
3234
3248
  }
3235
3249
  function tailscaleInstallCommand() {
3236
3250
  return [
3251
+ `${hostMaintenanceCommand("tailscale-install-start")} && exit 0`,
3237
3252
  "if command -v tailscale >/dev/null 2>&1; then",
3238
3253
  " :",
3239
3254
  "elif command -v apt-get >/dev/null 2>&1; then",
@@ -3259,6 +3274,7 @@ function tailscaleInstallCommand() {
3259
3274
  }
3260
3275
  function firewallBaselineCommand() {
3261
3276
  return [
3277
+ `${hostMaintenanceCommand("firewall-baseline")} && exit 0`,
3262
3278
  "if command -v ufw >/dev/null 2>&1 || command -v apt-get >/dev/null 2>&1; then",
3263
3279
  " command -v ufw >/dev/null 2>&1 || { " + packageInstallCommand(["ufw"]) + "; }",
3264
3280
  " sudo -n ufw default deny incoming",
@@ -3282,6 +3298,7 @@ function firewallBaselineCommand() {
3282
3298
  }
3283
3299
  function automaticUpdatesCommand() {
3284
3300
  return [
3301
+ `${hostMaintenanceCommand("automatic-updates")} && exit 0`,
3285
3302
  "if command -v apt-get >/dev/null 2>&1; then",
3286
3303
  " " + packageInstallCommand(["unattended-upgrades"]),
3287
3304
  " sudo -n systemctl enable --now unattended-upgrades >/dev/null 2>&1 || true",
@@ -3300,15 +3317,7 @@ function automaticUpdatesCommand() {
3300
3317
  ].join("\n");
3301
3318
  }
3302
3319
  function sshHardeningCommand() {
3303
- return [
3304
- "if sudo -n /usr/local/sbin/fased-host-maintenance harden-ssh >/dev/null 2>&1; then",
3305
- " :",
3306
- "else",
3307
- " sudo -n sed -i 's/^#\\?PasswordAuthentication .*/PasswordAuthentication no/' /etc/ssh/sshd_config",
3308
- " sudo -n sed -i 's/^#\\?PermitRootLogin .*/PermitRootLogin no/' /etc/ssh/sshd_config",
3309
- " sudo -n systemctl restart ssh || sudo -n systemctl restart sshd",
3310
- "fi"
3311
- ].join("\n");
3320
+ return hostMaintenanceCommand("harden-ssh");
3312
3321
  }
3313
3322
  function failOrContinue(params) {
3314
3323
  const { opts, runtime, step, detail } = params;
@@ -3354,7 +3363,7 @@ async function applyHostingSecurity(params) {
3354
3363
  validate: (value) => value.trim() ? void 0 : "Required"
3355
3364
  })).trim();
3356
3365
  else await prompter.note(formatTailscaleBrowserLoginNote(), "Tailscale login");
3357
- const resetCommand = tsAuthkey ? `sudo -n tailscale logout && sudo -n tailscale up --ssh --accept-routes --reset --authkey ${JSON.stringify(tsAuthkey)}` : "sudo -n tailscale logout && sudo -n tailscale up --ssh --accept-routes --reset";
3366
+ const resetCommand = tsAuthkey ? hostMaintenanceCommandWithInput("tailscale-up-reset-authkey-ssh", tsAuthkey) : hostMaintenanceCommand("tailscale-up-reset-ssh");
3358
3367
  const tsReset = tsAuthkey ? run(resetCommand, logPath) : await runInteractiveTailscaleLogin(resetCommand, logPath, prompter);
3359
3368
  if (!tsReset.ok && !tailscaleTimedOutButReady(tsReset, logPath)) return {
3360
3369
  ok: false,
@@ -3478,7 +3487,7 @@ async function applyHostingSecurity(params) {
3478
3487
  logPath
3479
3488
  };
3480
3489
  }
3481
- } else if (hasCommand("systemctl")) run("sudo -n systemctl enable --now tailscaled >/dev/null 2>&1 || true", logPath);
3490
+ } else if (hasCommand("systemctl")) run(`${hostMaintenanceCommand("tailscale-install-start")} >/dev/null 2>&1 || sudo -n systemctl enable --now tailscaled >/dev/null 2>&1 || true`, logPath);
3482
3491
  if (prompter && opts.nonInteractive !== true) await prompter.note(formatLocalDeviceTailnetRequirementNote(), "Local device requirement");
3483
3492
  let tsHealthy = isTailscaleLoggedIn(logPath);
3484
3493
  if (tsHealthy && prompter && opts.nonInteractive !== true) {
@@ -3487,7 +3496,7 @@ async function applyHostingSecurity(params) {
3487
3496
  initialValue: false
3488
3497
  })) {
3489
3498
  if (prompter) await prompter.note(formatTailscaleBrowserLoginNote(), "Tailscale login");
3490
- const tsReset = await runInteractiveTailscaleLogin("sudo -n tailscale logout && sudo -n tailscale up --ssh --accept-routes --reset", logPath, prompter);
3499
+ const tsReset = await runInteractiveTailscaleLogin(hostMaintenanceCommand("tailscale-up-reset-ssh"), logPath, prompter);
3491
3500
  if (!tsReset.ok && !tailscaleTimedOutButReady(tsReset, logPath)) {
3492
3501
  checks.push({
3493
3502
  name: "tailscale",
@@ -3530,7 +3539,7 @@ async function applyHostingSecurity(params) {
3530
3539
  })).trim();
3531
3540
  }
3532
3541
  if (tsAuthkey) {
3533
- const tsUp = run(`sudo -n tailscale up --authkey ${JSON.stringify(tsAuthkey)} --ssh`, logPath);
3542
+ const tsUp = run(hostMaintenanceCommandWithInput("tailscale-up-authkey-ssh", tsAuthkey), logPath);
3534
3543
  if (!tsUp.ok) {
3535
3544
  checks.push({
3536
3545
  name: "tailscale",
@@ -3574,7 +3583,7 @@ async function applyHostingSecurity(params) {
3574
3583
  };
3575
3584
  } else {
3576
3585
  if (prompter) await prompter.note(formatTailscaleBrowserLoginNote(), "Tailscale login");
3577
- const tsUp = await runInteractiveTailscaleLogin("sudo -n tailscale up --ssh", logPath, prompter);
3586
+ const tsUp = await runInteractiveTailscaleLogin(hostMaintenanceCommand("tailscale-up-ssh"), logPath, prompter);
3578
3587
  if (!tsUp.ok && !tailscaleTimedOutButReady(tsUp, logPath)) {
3579
3588
  checks.push({
3580
3589
  name: "tailscale",
@@ -3629,7 +3638,7 @@ async function applyHostingSecurity(params) {
3629
3638
  detail: "tailnet IP present; verifying app SSH before lock-down"
3630
3639
  });
3631
3640
  const operatorUser = run("id -u app >/dev/null 2>&1", logPath).ok ? "app" : process.env.SUDO_USER?.trim() || process.env.USER?.trim() || process.env.LOGNAME?.trim();
3632
- if (operatorUser) run(`sudo -n tailscale set --operator='${operatorUser}' >/dev/null 2>&1 || true`, logPath);
3641
+ if (operatorUser) run(`${hostMaintenanceCommand("tailscale-set-operator-self")} >/dev/null 2>&1 || true`, logPath);
3633
3642
  if (!await confirmTailnetSshBeforeLockdown({
3634
3643
  opts,
3635
3644
  runtime,
@@ -3726,7 +3735,7 @@ async function applyHostingSecurity(params) {
3726
3735
  ok: true,
3727
3736
  detail: "password auth/root login disabled and ssh restarted"
3728
3737
  });
3729
- const f2bRes = runHostSetupCommand(`${packageInstallCommand(["fail2ban"])}\nsudo -n systemctl enable --now fail2ban`);
3738
+ const f2bRes = runHostSetupCommand(`${hostMaintenanceCommand("fail2ban-enable")} || (${packageInstallCommand(["fail2ban"])}\nsudo -n systemctl enable --now fail2ban)`);
3730
3739
  if (!f2bRes.ok) {
3731
3740
  checks.push({
3732
3741
  name: "fail2ban",
@@ -1,7 +1,7 @@
1
1
  import { _ as resolveStateDir, u as resolveGatewayPort } from "./paths-C9FmTW1x.js";
2
2
  import { S as resolveUserPath, U as theme } from "./agent-paths-DmOVZE7g.js";
3
3
  import { Ga as ensureAuthProfileStore, Mn as writeConfigFile, Zr as collectConfigServiceEnvVars, d as resolveDefaultAgentId, dd as formatCliCommand, fr as ensureActiveMemoryPluginAllowlisted, kn as readConfigFileSnapshot, u as resolveAgentWorkspaceDir } from "./agent-scope-DHrLr5OF.js";
4
- import { Bt as detectBrowserOpenSupport, Ht as formatControlUiSshHint, Jt as openUrl, Lt as DEFAULT_WORKSPACE, Mo as runFederationAutoConnectOnce, Qo as findTailscaleBinary, Qt as resolveControlUiLinks, Rt as applyWizardMetadata, Vt as ensureWorkspaceAndSessions, Wt as handleOnboardingRepair, Xo as enableTailscaleFunnel, Xt as probeGatewayReachable, Yt as printWizardHeader, Zo as enableTailscaleServe, Zt as randomToken, en as summarizeExistingConfig, nn as waitForGatewayReachable, qt as normalizeGatewayTokenInput, tn as validateGatewayPasswordInput, xo as normalizeControlUiBasePath, yo as CONTROL_UI_BOOT_CHECK_PATH } from "./reply-BRoR6TOO.js";
4
+ import { Bt as detectBrowserOpenSupport, Ht as formatControlUiSshHint, Jt as openUrl, Lt as DEFAULT_WORKSPACE, Mo as runFederationAutoConnectOnce, Qo as findTailscaleBinary, Qt as resolveControlUiLinks, Rt as applyWizardMetadata, Vt as ensureWorkspaceAndSessions, Wt as handleOnboardingRepair, Xo as enableTailscaleFunnel, Xt as probeGatewayReachable, Yt as printWizardHeader, Zo as enableTailscaleServe, Zt as randomToken, en as summarizeExistingConfig, nn as waitForGatewayReachable, qt as normalizeGatewayTokenInput, tn as validateGatewayPasswordInput, xo as normalizeControlUiBasePath, yo as CONTROL_UI_BOOT_CHECK_PATH } from "./reply-B034LmuD.js";
5
5
  import { d as defaultRuntime, f as restoreTerminalState, s as redactSensitiveText } from "./errors-Dx3S3Nrp.js";
6
6
  import { a as resolveSignerdBinaryPath, n as installSignerdBinary, o as restartLocalSocketSigner, r as migrateLocalSignerKeystoreToMaterialDir, t as configureWalletForOnboarding } from "./onboarding.wallet-CQG8MiG_.js";
7
7
  import { i as resolveLocalSignerRunAsUser, n as resolveLocalSignerBackendSocketPath, o as resolveLocalSignerSocketPath, r as resolveLocalSignerMaterialRootDir, t as ensureWalletStateDir } from "./wallet-runtime-config-BlRWvEER.js";
@@ -17,14 +17,14 @@ import { a as resolveHostedOnboardingGatewayStartupMode, i as resolveGatewayStar
17
17
  import { d as buildSystemdUnit, r as isSystemdUserServiceAvailable } from "./systemd-CmxDYXvt.js";
18
18
  import { t as resolveGatewayService } from "./service-Bsg622jp.js";
19
19
  import { n as auditGatewayServiceConfig, t as SERVICE_AUDIT_CODES } from "./service-audit-BRLbvcxT.js";
20
- import { a as promptRemoteGatewayConfig, n as getTailscaleMissingBinNoteLines, r as setupSkills, t as validateIPv4AddressInput, u as promptCustomApiConfig } from "./ipv4-Bxa3Ql2B.js";
21
- import { o as waitForHostedDashboardBrowserPath } from "./health-c7sJIXY9.js";
22
- import { n as warnIfModelConfigLooksOff, r as applyAuthChoice } from "./auth-choice-DCd_rmJr.js";
23
- import { t as promptAuthChoiceGrouped } from "./auth-choice-prompt-BBY8vO5H.js";
20
+ import { a as promptRemoteGatewayConfig, n as getTailscaleMissingBinNoteLines, r as setupSkills, t as validateIPv4AddressInput, u as promptCustomApiConfig } from "./ipv4-B42xQEbV.js";
21
+ import { o as waitForHostedDashboardBrowserPath } from "./health-kF4U3o3b.js";
22
+ import { n as warnIfModelConfigLooksOff, r as applyAuthChoice } from "./auth-choice-DRyuJ7OL.js";
23
+ import { t as promptAuthChoiceGrouped } from "./auth-choice-prompt-EOHB6Adp.js";
24
24
  import { n as logConfigUpdated } from "./logging-Dv2wthF_.js";
25
- import { n as setupChannels } from "./onboard-channels-BREKCcFf.js";
25
+ import { n as setupChannels } from "./onboard-channels-ZnUGKi2j.js";
26
26
  import { t as buildWorkspaceHookStatus } from "./hooks-status-BielXMUB.js";
27
- import { t as runTui } from "./tui-CIzUfHHB.js";
27
+ import { t as runTui } from "./tui-CF9NTWgo.js";
28
28
  import fs from "node:fs";
29
29
  import os from "node:os";
30
30
  import path from "node:path";
@@ -169,7 +169,7 @@ function isHostedSecurityCapableSession(explicitFlag = false) {
169
169
  const sudoersPath = path.join("/etc/sudoers.d", `fased-host-maintenance-${currentUser}`);
170
170
  if (fs.existsSync(sudoersPath)) return true;
171
171
  }
172
- return canRunHostedMaintenanceCommand("sudo -n tailscale status >/dev/null 2>&1") || canRunHostedMaintenanceCommand("sudo -n ufw status >/dev/null 2>&1") || canRunHostedMaintenanceCommand("sudo -n firewall-cmd --state >/dev/null 2>&1") || canRunHostedMaintenanceCommand("sudo -n systemctl is-active --quiet firewalld >/dev/null 2>&1") || canRunHostedMaintenanceCommand("sudo -n systemctl status fased-gateway.service >/dev/null 2>&1");
172
+ return canRunHostedMaintenanceCommand("sudo -n /usr/local/sbin/fased-host-maintenance tailscale-status >/dev/null 2>&1") || canRunHostedMaintenanceCommand("sudo -n /usr/local/sbin/fased-host-maintenance tailnet-ssh-ingress >/dev/null 2>&1") || canRunHostedMaintenanceCommand("sudo -n /usr/local/sbin/fased-host-maintenance firewall-baseline >/dev/null 2>&1") || canRunHostedMaintenanceCommand("sudo -n systemctl status fased-gateway.service >/dev/null 2>&1");
173
173
  }
174
174
 
175
175
  //#endregion
@@ -547,16 +547,18 @@ async function installRootServiceMaintenanceAccess(params) {
547
547
  const sudoers = [
548
548
  `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl restart ${safeServiceName}.service`,
549
549
  `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl restart --no-block ${safeServiceName}.service`,
550
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl start --no-block ${safeServiceName}.service`,
551
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl enable --now ${safeServiceName}.service`,
550
552
  `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl status ${safeServiceName}.service`,
551
- `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl status ${safeServiceName}.service *`,
552
- `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl status ${safeServiceName} *`,
553
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl status ${safeServiceName}.service --no-pager`,
553
554
  `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl is-active ${safeServiceName}.service`,
554
- `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl is-active ${safeServiceName}.service *`,
555
- `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl is-active ${safeServiceName} *`,
556
- `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl show ${safeServiceName}.service *`,
557
- `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl show ${safeServiceName} *`,
558
- `${safeUser} ALL=(root) NOPASSWD: /usr/bin/journalctl -u ${safeServiceName}.service *`,
559
- `${safeUser} ALL=(root) NOPASSWD: /usr/bin/journalctl -u ${safeServiceName} *`
555
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl is-active ${safeServiceName}`,
556
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl show ${safeServiceName}.service -p ActiveState --value`,
557
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/systemctl cat ${safeServiceName}.service`,
558
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/journalctl -u ${safeServiceName}.service -n 50 --no-pager`,
559
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/journalctl -u ${safeServiceName}.service -n 120 --no-pager`,
560
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/journalctl -u ${safeServiceName} -n 50 --no-pager`,
561
+ `${safeUser} ALL=(root) NOPASSWD: /usr/bin/journalctl -u ${safeServiceName} -n 120 --no-pager`
560
562
  ].join("\n");
561
563
  return await runShell([
562
564
  `echo '${Buffer.from(`${sudoers}\n`, "utf8").toString("base64")}' | base64 -d | sudo -n tee '${sudoersPath}' >/dev/null`,
@@ -2748,6 +2750,7 @@ const LOW_MEMORY_HOSTING_SWAP_GB = 4;
2748
2750
  const HOSTING_SWAP_GB = 2;
2749
2751
  const TAILSCALE_INTERACTIVE_TIMEOUT_MS = 120 * 1e3;
2750
2752
  const TAILSCALE_LOGIN_URL_RE = /https:\/\/login\.tailscale\.com\/a\/[A-Za-z0-9_-]+/i;
2753
+ const HOST_MAINTENANCE_HELPER = "/usr/local/sbin/fased-host-maintenance";
2751
2754
  function detectTotalMemoryMb() {
2752
2755
  if (process.platform === "linux") try {
2753
2756
  const match = fs.readFileSync("/proc/meminfo", "utf8").match(/^MemTotal:\s+(\d+)\s+kB/m);
@@ -2848,7 +2851,7 @@ function buildTailscaleLoginWaitCommand(command) {
2848
2851
  `bash -lc ${shellQuote(command)} &`,
2849
2852
  "ts_pid=$!",
2850
2853
  "for _ in $(seq 1 55); do",
2851
- " if tailscale ip -4 >/dev/null 2>&1 || sudo -n tailscale ip -4 >/dev/null 2>&1; then",
2854
+ ` if tailscale ip -4 >/dev/null 2>&1 || ${hostMaintenanceCommand("tailscale-ip4")} >/dev/null 2>&1 || sudo -n tailscale ip -4 >/dev/null 2>&1; then`,
2852
2855
  " kill -INT \"$ts_pid\" >/dev/null 2>&1 || true",
2853
2856
  " wait \"$ts_pid\" >/dev/null 2>&1 || true",
2854
2857
  " exit 0",
@@ -2861,7 +2864,7 @@ function buildTailscaleLoginWaitCommand(command) {
2861
2864
  "done",
2862
2865
  "kill -INT \"$ts_pid\" >/dev/null 2>&1 || true",
2863
2866
  "wait \"$ts_pid\" >/dev/null 2>&1 || true",
2864
- "if tailscale ip -4 >/dev/null 2>&1 || sudo -n tailscale ip -4 >/dev/null 2>&1; then",
2867
+ `if tailscale ip -4 >/dev/null 2>&1 || ${hostMaintenanceCommand("tailscale-ip4")} >/dev/null 2>&1 || sudo -n tailscale ip -4 >/dev/null 2>&1; then`,
2865
2868
  " exit 0",
2866
2869
  "fi",
2867
2870
  "exit 124"
@@ -2914,21 +2917,29 @@ function tailscaleTimedOutButReady(result, logPath, runner = run) {
2914
2917
  function shellQuote(value) {
2915
2918
  return `'${value.replace(/'/g, "'\\''")}'`;
2916
2919
  }
2920
+ function hostMaintenanceCommand(action) {
2921
+ return `sudo -n ${HOST_MAINTENANCE_HELPER} ${action}`;
2922
+ }
2923
+ function hostMaintenanceCommandWithInput(action, input) {
2924
+ return `printf '%s\\n' ${shellQuote(input)} | ${hostMaintenanceCommand(action)}`;
2925
+ }
2917
2926
  function isTailscaleLoggedIn(logPath, runner = run) {
2918
- return runner("tailscale status >/dev/null 2>&1", logPath).ok || runner("sudo -n tailscale status >/dev/null 2>&1", logPath).ok;
2927
+ return runner("tailscale status >/dev/null 2>&1", logPath).ok || runner(`${hostMaintenanceCommand("tailscale-status")} >/dev/null 2>&1`, logPath).ok || runner("sudo -n tailscale status >/dev/null 2>&1", logPath).ok;
2919
2928
  }
2920
2929
  function hasTailscaleIp(logPath, runner = run) {
2921
- return runner("tailscale ip -4 >/dev/null 2>&1", logPath).ok || runner("sudo -n tailscale ip -4 >/dev/null 2>&1", logPath).ok;
2930
+ return runner("tailscale ip -4 >/dev/null 2>&1", logPath).ok || runner(`${hostMaintenanceCommand("tailscale-ip4")} >/dev/null 2>&1`, logPath).ok || runner("sudo -n tailscale ip -4 >/dev/null 2>&1", logPath).ok;
2922
2931
  }
2923
2932
  function readTailscaleIp(logPath, runner = run) {
2924
2933
  const probe = runner("tailscale ip -4", logPath);
2925
- const sudoProbe = probe.ok ? probe : runner("sudo -n tailscale ip -4", logPath);
2934
+ const helperProbe = probe.ok ? probe : runner(hostMaintenanceCommand("tailscale-ip4"), logPath);
2935
+ const sudoProbe = helperProbe.ok ? helperProbe : runner("sudo -n tailscale ip -4", logPath);
2926
2936
  if (!sudoProbe.ok || !sudoProbe.detail) return;
2927
2937
  return sudoProbe.detail.match(/\b\d{1,3}(?:\.\d{1,3}){3}\b/)?.[0];
2928
2938
  }
2929
2939
  function readTailscaleSelf(logPath, runner = run) {
2930
2940
  const probe = runner("tailscale status --json", logPath);
2931
- const sudoProbe = probe.ok ? probe : runner("sudo -n tailscale status --json", logPath);
2941
+ const helperProbe = probe.ok ? probe : runner(hostMaintenanceCommand("tailscale-status-json"), logPath);
2942
+ const sudoProbe = helperProbe.ok ? helperProbe : runner("sudo -n tailscale status --json", logPath);
2932
2943
  if (!sudoProbe.ok || !sudoProbe.detail) return { ipv4: readTailscaleIp(logPath, runner) };
2933
2944
  try {
2934
2945
  const parsed = JSON.parse(sudoProbe.detail);
@@ -3034,7 +3045,8 @@ function verifyTailnetSshServerPrerequisites(params) {
3034
3045
  };
3035
3046
  }
3036
3047
  function ensureTailnetSshIngressForVerification(params) {
3037
- const result = (params.runner ?? run)([
3048
+ const runner = params.runner ?? run;
3049
+ const command = [
3038
3050
  "if command -v ufw >/dev/null 2>&1; then",
3039
3051
  " if sudo -n ufw status | grep -qi '^Status: active'; then",
3040
3052
  " sudo -n ufw insert 1 allow in on tailscale0 to any port 22 proto tcp || sudo -n ufw allow in on tailscale0 to any port 22 proto tcp",
@@ -3045,7 +3057,9 @@ function ensureTailnetSshIngressForVerification(params) {
3045
3057
  " sudo -n firewall-cmd --permanent --zone=trusted --add-interface=tailscale0 >/dev/null 2>&1 || true",
3046
3058
  " sudo -n firewall-cmd --reload >/dev/null 2>&1 || true",
3047
3059
  "fi"
3048
- ].join("\n"), params.logPath);
3060
+ ].join("\n");
3061
+ const helperResult = runner(hostMaintenanceCommand("tailnet-ssh-ingress"), params.logPath);
3062
+ const result = helperResult.ok ? helperResult : runner(command, params.logPath);
3049
3063
  if (!result.ok) return {
3050
3064
  ok: false,
3051
3065
  detail: result.detail ?? "could not prepare tailnet SSH firewall rule before verification"
@@ -3132,7 +3146,7 @@ async function confirmTailnetSshBeforeLockdown(params) {
3132
3146
  return false;
3133
3147
  }
3134
3148
  await prompter.note(formatTailscaleAccountBrowserLoginNote(), "Tailscale login");
3135
- const tsReset = await interactiveRunner("sudo -n tailscale logout && sudo -n tailscale up --ssh --accept-routes --reset", logPath, prompter);
3149
+ const tsReset = await interactiveRunner(hostMaintenanceCommand("tailscale-up-reset-ssh"), logPath, prompter);
3136
3150
  const acceptedTimedOutLogin = tailscaleTimedOutButReady(tsReset, logPath, runner);
3137
3151
  if (!tsReset.ok && !acceptedTimedOutLogin || !hasTailscaleIp(logPath, runner)) {
3138
3152
  runtime.error("Hosting setup stopped before SSH/firewall lock-down.");
@@ -3176,9 +3190,9 @@ function ensureTailscaleServe(port, logPath) {
3176
3190
  ok: true,
3177
3191
  detail: `tailscale serve --bg -> 127.0.0.1:${port}`
3178
3192
  };
3179
- if (run(`sudo -n tailscale serve --bg http://127.0.0.1:${port}`, logPath).ok) return {
3193
+ if (run(hostMaintenanceCommandWithInput("tailscale-serve", String(port)), logPath).ok) return {
3180
3194
  ok: true,
3181
- detail: `sudo tailscale serve --bg -> 127.0.0.1:${port}`
3195
+ detail: `host maintenance tailscale serve -> 127.0.0.1:${port}`
3182
3196
  };
3183
3197
  if (run(`tailscale serve https / http://127.0.0.1:${port}`, logPath).ok) return {
3184
3198
  ok: true,
@@ -3202,7 +3216,7 @@ function isTailscaleServeReady(port) {
3202
3216
  ],
3203
3217
  encoding: "utf8"
3204
3218
  });
3205
- if ((probe.status ?? 1) !== 0) probe = spawnSync("bash", ["-lc", "sudo -n tailscale serve status"], {
3219
+ if ((probe.status ?? 1) !== 0) probe = spawnSync("bash", ["-lc", hostMaintenanceCommand("tailscale-serve-status")], {
3206
3220
  stdio: [
3207
3221
  "ignore",
3208
3222
  "pipe",
@@ -3235,6 +3249,7 @@ function packageInstallCommand(packages) {
3235
3249
  }
3236
3250
  function tailscaleInstallCommand() {
3237
3251
  return [
3252
+ `${hostMaintenanceCommand("tailscale-install-start")} && exit 0`,
3238
3253
  "if command -v tailscale >/dev/null 2>&1; then",
3239
3254
  " :",
3240
3255
  "elif command -v apt-get >/dev/null 2>&1; then",
@@ -3260,6 +3275,7 @@ function tailscaleInstallCommand() {
3260
3275
  }
3261
3276
  function firewallBaselineCommand() {
3262
3277
  return [
3278
+ `${hostMaintenanceCommand("firewall-baseline")} && exit 0`,
3263
3279
  "if command -v ufw >/dev/null 2>&1 || command -v apt-get >/dev/null 2>&1; then",
3264
3280
  " command -v ufw >/dev/null 2>&1 || { " + packageInstallCommand(["ufw"]) + "; }",
3265
3281
  " sudo -n ufw default deny incoming",
@@ -3283,6 +3299,7 @@ function firewallBaselineCommand() {
3283
3299
  }
3284
3300
  function automaticUpdatesCommand() {
3285
3301
  return [
3302
+ `${hostMaintenanceCommand("automatic-updates")} && exit 0`,
3286
3303
  "if command -v apt-get >/dev/null 2>&1; then",
3287
3304
  " " + packageInstallCommand(["unattended-upgrades"]),
3288
3305
  " sudo -n systemctl enable --now unattended-upgrades >/dev/null 2>&1 || true",
@@ -3301,15 +3318,7 @@ function automaticUpdatesCommand() {
3301
3318
  ].join("\n");
3302
3319
  }
3303
3320
  function sshHardeningCommand() {
3304
- return [
3305
- "if sudo -n /usr/local/sbin/fased-host-maintenance harden-ssh >/dev/null 2>&1; then",
3306
- " :",
3307
- "else",
3308
- " sudo -n sed -i 's/^#\\?PasswordAuthentication .*/PasswordAuthentication no/' /etc/ssh/sshd_config",
3309
- " sudo -n sed -i 's/^#\\?PermitRootLogin .*/PermitRootLogin no/' /etc/ssh/sshd_config",
3310
- " sudo -n systemctl restart ssh || sudo -n systemctl restart sshd",
3311
- "fi"
3312
- ].join("\n");
3321
+ return hostMaintenanceCommand("harden-ssh");
3313
3322
  }
3314
3323
  function failOrContinue(params) {
3315
3324
  const { opts, runtime, step, detail } = params;
@@ -3355,7 +3364,7 @@ async function applyHostingSecurity(params) {
3355
3364
  validate: (value) => value.trim() ? void 0 : "Required"
3356
3365
  })).trim();
3357
3366
  else await prompter.note(formatTailscaleBrowserLoginNote(), "Tailscale login");
3358
- const resetCommand = tsAuthkey ? `sudo -n tailscale logout && sudo -n tailscale up --ssh --accept-routes --reset --authkey ${JSON.stringify(tsAuthkey)}` : "sudo -n tailscale logout && sudo -n tailscale up --ssh --accept-routes --reset";
3367
+ const resetCommand = tsAuthkey ? hostMaintenanceCommandWithInput("tailscale-up-reset-authkey-ssh", tsAuthkey) : hostMaintenanceCommand("tailscale-up-reset-ssh");
3359
3368
  const tsReset = tsAuthkey ? run(resetCommand, logPath) : await runInteractiveTailscaleLogin(resetCommand, logPath, prompter);
3360
3369
  if (!tsReset.ok && !tailscaleTimedOutButReady(tsReset, logPath)) return {
3361
3370
  ok: false,
@@ -3479,7 +3488,7 @@ async function applyHostingSecurity(params) {
3479
3488
  logPath
3480
3489
  };
3481
3490
  }
3482
- } else if (hasCommand("systemctl")) run("sudo -n systemctl enable --now tailscaled >/dev/null 2>&1 || true", logPath);
3491
+ } else if (hasCommand("systemctl")) run(`${hostMaintenanceCommand("tailscale-install-start")} >/dev/null 2>&1 || sudo -n systemctl enable --now tailscaled >/dev/null 2>&1 || true`, logPath);
3483
3492
  if (prompter && opts.nonInteractive !== true) await prompter.note(formatLocalDeviceTailnetRequirementNote(), "Local device requirement");
3484
3493
  let tsHealthy = isTailscaleLoggedIn(logPath);
3485
3494
  if (tsHealthy && prompter && opts.nonInteractive !== true) {
@@ -3488,7 +3497,7 @@ async function applyHostingSecurity(params) {
3488
3497
  initialValue: false
3489
3498
  })) {
3490
3499
  if (prompter) await prompter.note(formatTailscaleBrowserLoginNote(), "Tailscale login");
3491
- const tsReset = await runInteractiveTailscaleLogin("sudo -n tailscale logout && sudo -n tailscale up --ssh --accept-routes --reset", logPath, prompter);
3500
+ const tsReset = await runInteractiveTailscaleLogin(hostMaintenanceCommand("tailscale-up-reset-ssh"), logPath, prompter);
3492
3501
  if (!tsReset.ok && !tailscaleTimedOutButReady(tsReset, logPath)) {
3493
3502
  checks.push({
3494
3503
  name: "tailscale",
@@ -3531,7 +3540,7 @@ async function applyHostingSecurity(params) {
3531
3540
  })).trim();
3532
3541
  }
3533
3542
  if (tsAuthkey) {
3534
- const tsUp = run(`sudo -n tailscale up --authkey ${JSON.stringify(tsAuthkey)} --ssh`, logPath);
3543
+ const tsUp = run(hostMaintenanceCommandWithInput("tailscale-up-authkey-ssh", tsAuthkey), logPath);
3535
3544
  if (!tsUp.ok) {
3536
3545
  checks.push({
3537
3546
  name: "tailscale",
@@ -3575,7 +3584,7 @@ async function applyHostingSecurity(params) {
3575
3584
  };
3576
3585
  } else {
3577
3586
  if (prompter) await prompter.note(formatTailscaleBrowserLoginNote(), "Tailscale login");
3578
- const tsUp = await runInteractiveTailscaleLogin("sudo -n tailscale up --ssh", logPath, prompter);
3587
+ const tsUp = await runInteractiveTailscaleLogin(hostMaintenanceCommand("tailscale-up-ssh"), logPath, prompter);
3579
3588
  if (!tsUp.ok && !tailscaleTimedOutButReady(tsUp, logPath)) {
3580
3589
  checks.push({
3581
3590
  name: "tailscale",
@@ -3630,7 +3639,7 @@ async function applyHostingSecurity(params) {
3630
3639
  detail: "tailnet IP present; verifying app SSH before lock-down"
3631
3640
  });
3632
3641
  const operatorUser = run("id -u app >/dev/null 2>&1", logPath).ok ? "app" : process.env.SUDO_USER?.trim() || process.env.USER?.trim() || process.env.LOGNAME?.trim();
3633
- if (operatorUser) run(`sudo -n tailscale set --operator='${operatorUser}' >/dev/null 2>&1 || true`, logPath);
3642
+ if (operatorUser) run(`${hostMaintenanceCommand("tailscale-set-operator-self")} >/dev/null 2>&1 || true`, logPath);
3634
3643
  if (!await confirmTailnetSshBeforeLockdown({
3635
3644
  opts,
3636
3645
  runtime,
@@ -3727,7 +3736,7 @@ async function applyHostingSecurity(params) {
3727
3736
  ok: true,
3728
3737
  detail: "password auth/root login disabled and ssh restarted"
3729
3738
  });
3730
- const f2bRes = runHostSetupCommand(`${packageInstallCommand(["fail2ban"])}\nsudo -n systemctl enable --now fail2ban`);
3739
+ const f2bRes = runHostSetupCommand(`${hostMaintenanceCommand("fail2ban-enable")} || (${packageInstallCommand(["fail2ban"])}\nsudo -n systemctl enable --now fail2ban)`);
3731
3740
  if (!f2bRes.ok) {
3732
3741
  checks.push({
3733
3742
  name: "fail2ban",
@@ -2,7 +2,7 @@ import { Ui as logWarn, wa as defaultRuntime } from "./agent-scope-Cb1u7HE7.js";
2
2
  import "./github-copilot-token-DYrFvncE.js";
3
3
  import "./send-vR6HwT94.js";
4
4
  import "./send-BQMxv218.js";
5
- import { $ as emitAgentEvent, B as DEFAULT_INPUT_IMAGE_MIMES, G as normalizeMimeList, H as DEFAULT_INPUT_TIMEOUT_MS, K as resolveInputFileLimits, U as extractFileContentFromSource, V as DEFAULT_INPUT_MAX_REDIRECTS, W as extractImageContentFromSource, a as agentCommand, at as setSseHeaders, et as onAgentEvent, i as resolveAssistantStreamDeltaText, it as sendJson, n as handleGatewayPostJsonEndpoint, nt as resolveAgentIdForRequest, ot as writeDone, r as buildAgentMessageFromConversationEntries, rt as resolveSessionKey, tt as createDefaultDeps, z as DEFAULT_INPUT_IMAGE_MAX_BYTES } from "./pi-embedded-Dtw2m41q.js";
5
+ import { $ as emitAgentEvent, B as DEFAULT_INPUT_IMAGE_MIMES, G as normalizeMimeList, H as DEFAULT_INPUT_TIMEOUT_MS, K as resolveInputFileLimits, U as extractFileContentFromSource, V as DEFAULT_INPUT_MAX_REDIRECTS, W as extractImageContentFromSource, a as agentCommand, at as setSseHeaders, et as onAgentEvent, i as resolveAssistantStreamDeltaText, it as sendJson, n as handleGatewayPostJsonEndpoint, nt as resolveAgentIdForRequest, ot as writeDone, r as buildAgentMessageFromConversationEntries, rt as resolveSessionKey, tt as createDefaultDeps, z as DEFAULT_INPUT_IMAGE_MAX_BYTES } from "./pi-embedded-Bnuo5tPq.js";
6
6
  import "./diagnostic-D6XQAXl4.js";
7
7
  import "./diagnostic-session-state-CexmAKza.js";
8
8
  import "./send-Da1hCe1A.js";
@@ -2,7 +2,7 @@ import { Sa as defaultRuntime, Vi as logWarn } from "./agent-scope-DUKEZjqM.js";
2
2
  import "./github-copilot-token-CNsqwfnE.js";
3
3
  import "./send-CFSRf7De.js";
4
4
  import "./send-gtmn6YeH.js";
5
- import { B as DEFAULT_INPUT_IMAGE_MIMES, G as normalizeMimeList, H as DEFAULT_INPUT_TIMEOUT_MS, K as resolveInputFileLimits, U as extractFileContentFromSource, V as DEFAULT_INPUT_MAX_REDIRECTS, W as extractImageContentFromSource, a as agentCommand, at as sendJson, et as emitAgentEvent, i as resolveAssistantStreamDeltaText, it as resolveSessionKey, n as handleGatewayPostJsonEndpoint, nt as createDefaultDeps, ot as setSseHeaders, r as buildAgentMessageFromConversationEntries, rt as resolveAgentIdForRequest, st as writeDone, tt as onAgentEvent, z as DEFAULT_INPUT_IMAGE_MAX_BYTES } from "./pi-embedded-G-VYb-eT.js";
5
+ import { B as DEFAULT_INPUT_IMAGE_MIMES, G as normalizeMimeList, H as DEFAULT_INPUT_TIMEOUT_MS, K as resolveInputFileLimits, U as extractFileContentFromSource, V as DEFAULT_INPUT_MAX_REDIRECTS, W as extractImageContentFromSource, a as agentCommand, at as sendJson, et as emitAgentEvent, i as resolveAssistantStreamDeltaText, it as resolveSessionKey, n as handleGatewayPostJsonEndpoint, nt as createDefaultDeps, ot as setSseHeaders, r as buildAgentMessageFromConversationEntries, rt as resolveAgentIdForRequest, st as writeDone, tt as onAgentEvent, z as DEFAULT_INPUT_IMAGE_MAX_BYTES } from "./pi-embedded-CeuBUTjd.js";
6
6
  import "./reply-prefix-Bitnsmpd.js";
7
7
  import "./diagnostic-_BiQ6GgD.js";
8
8
  import "./diagnostic-session-state-CL_QxyRg.js";
@@ -1,6 +1,6 @@
1
1
  import "./github-copilot-token-Dy7Y_jbI.js";
2
2
  import { la as logWarn, qo as defaultRuntime } from "./paths-OUJyk-5R.js";
3
- import { B as extractImageContentFromSource, F as DEFAULT_INPUT_IMAGE_MAX_BYTES, H as resolveInputFileLimits, I as DEFAULT_INPUT_IMAGE_MIMES, L as DEFAULT_INPUT_MAX_REDIRECTS, R as DEFAULT_INPUT_TIMEOUT_MS, V as normalizeMimeList, X as emitAgentEvent, Z as onAgentEvent, a as agentCommand, at as sendJson, i as resolveAssistantStreamDeltaText, it as resolveSessionKey, n as handleGatewayPostJsonEndpoint, nt as createDefaultDeps, ot as setSseHeaders, r as buildAgentMessageFromConversationEntries, rt as resolveAgentIdForRequest, st as writeDone, z as extractFileContentFromSource } from "./auth-D6aXaEgt.js";
3
+ import { B as extractImageContentFromSource, F as DEFAULT_INPUT_IMAGE_MAX_BYTES, H as resolveInputFileLimits, I as DEFAULT_INPUT_IMAGE_MIMES, L as DEFAULT_INPUT_MAX_REDIRECTS, R as DEFAULT_INPUT_TIMEOUT_MS, V as normalizeMimeList, X as emitAgentEvent, Z as onAgentEvent, a as agentCommand, at as sendJson, i as resolveAssistantStreamDeltaText, it as resolveSessionKey, n as handleGatewayPostJsonEndpoint, nt as createDefaultDeps, ot as setSseHeaders, r as buildAgentMessageFromConversationEntries, rt as resolveAgentIdForRequest, st as writeDone, z as extractFileContentFromSource } from "./auth-BbQxXxtt.js";
4
4
  import "./send-D96gGRQz.js";
5
5
  import "./send-BFoI9HuU.js";
6
6
  import "./skill-commands-DvoCSQnx.js";
@@ -2,7 +2,7 @@ import { bd as logWarn } from "./env-C77feXxI.js";
2
2
  import "./agent-paths-BI1hx-tF.js";
3
3
  import "./send-D7X0_iFp.js";
4
4
  import "./send-BFEd4vCM.js";
5
- import { Ai as buildAgentMessageFromConversationEntries, Ii as resolveAssistantStreamDeltaText, Li as agentCommand, _a as resolveAgentIdForRequest, an as DEFAULT_INPUT_IMAGE_MAX_BYTES, ba as setSseHeaders, cn as DEFAULT_INPUT_TIMEOUT_MS, dn as normalizeMimeList, fn as resolveInputFileLimits, ia as emitAgentEvent, ki as handleGatewayPostJsonEndpoint, ln as extractFileContentFromSource, oa as onAgentEvent, on as DEFAULT_INPUT_IMAGE_MIMES, sn as DEFAULT_INPUT_MAX_REDIRECTS, un as extractImageContentFromSource, va as resolveSessionKey, xa as writeDone, ya as sendJson } from "./model-catalog-DHRVUWBf.js";
5
+ import { Ai as buildAgentMessageFromConversationEntries, Ii as resolveAssistantStreamDeltaText, Li as agentCommand, _a as resolveAgentIdForRequest, an as DEFAULT_INPUT_IMAGE_MAX_BYTES, ba as setSseHeaders, cn as DEFAULT_INPUT_TIMEOUT_MS, dn as normalizeMimeList, fn as resolveInputFileLimits, ia as emitAgentEvent, ki as handleGatewayPostJsonEndpoint, ln as extractFileContentFromSource, oa as onAgentEvent, on as DEFAULT_INPUT_IMAGE_MIMES, sn as DEFAULT_INPUT_MAX_REDIRECTS, un as extractImageContentFromSource, va as resolveSessionKey, xa as writeDone, ya as sendJson } from "./model-catalog-ex4Cpln_.js";
6
6
  import "./github-copilot-token-A9DiaCB0.js";
7
7
  import { A as defaultRuntime } from "./entry.js";
8
8
  import "./reply-prefix-TUhpEtvr.js";
@@ -45,7 +45,7 @@ import "./send-C-su1wPZ.js";
45
45
  import "./outbound-attachment-Bh4FmcYg.js";
46
46
  import "./fetch-BVvWzHT_.js";
47
47
  import "./delivery-queue-55Cityuq.js";
48
- import { t as createDefaultDeps } from "./deps-BoCGz3bU.js";
48
+ import { t as createDefaultDeps } from "./deps-BWo3ls9h.js";
49
49
  import "./frontmatter-D2UNJikU.js";
50
50
  import "./skills-Dis31awJ.js";
51
51
  import "./skills-remote-CIAB0AXm.js";