@fased/fased 0.1.18 → 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 (228) hide show
  1. package/dist/{agents-B6Phr7_f.js → agents-ChQhgSlb.js} +11 -11
  2. package/dist/{attachment-normalize-CzEnjLNz.js → attachment-normalize-Cr8RzfVf.js} +1 -1
  3. package/dist/{attachment-normalize-Cw5usv34.js → attachment-normalize-DB19KLbl.js} +1 -1
  4. package/dist/{audio-preflight-Bb2vNNbg.js → audio-preflight-BLGP3XdB.js} +1 -1
  5. package/dist/{audio-preflight-CE7uXO4r.js → audio-preflight-BmW52Ycp.js} +1 -1
  6. package/dist/{audio-preflight-DdTXlJCN.js → audio-preflight-CHhcmiXJ.js} +3 -3
  7. package/dist/{audio-preflight-BneukbKN.js → audio-preflight-DAevycUR.js} +2 -2
  8. package/dist/{audio-preflight-DLDBtl4e.js → audio-preflight-DVwcDm03.js} +3 -3
  9. package/dist/{audit-xX6RNayR.js → audit-C5YXYuIL.js} +1 -1
  10. package/dist/{audit-B2R6WwpA.js → audit-DPnCY1UL.js} +1 -1
  11. package/dist/{auth-DtTjcdsn.js → auth-BbQxXxtt.js} +5 -5
  12. package/dist/{auth-choice-DEux81xn.js → auth-choice-D8Q1fQwa.js} +2 -2
  13. package/dist/{auth-choice-DSs5l1Mv.js → auth-choice-DRyuJ7OL.js} +2 -2
  14. package/dist/{auth-choice-prompt-D8d4kRYT.js → auth-choice-prompt-Bs_OE3ai.js} +1 -1
  15. package/dist/{auth-choice-prompt-Dhl403zz.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-DRJ_lg4d.js → channel-web-BYwefJub.js} +1 -1
  21. package/dist/{channel-web-B_R-iuZ6.js → channel-web-Do7PfpgZ.js} +1 -1
  22. package/dist/{channels-D9lINC_R.js → channels-Ca02RvCt.js} +9 -9
  23. package/dist/{channels-B-7M3uYr.js → channels-DrEj3b4G.js} +9 -9
  24. package/dist/{channels-cli-BNR8Ueih.js → channels-cli-CCa-scQg.js} +6 -6
  25. package/dist/{channels-cli-CZZGaHdW.js → channels-cli-b6IPejdy.js} +6 -6
  26. package/dist/{clack-prompter-D2fuSvy3.js → clack-prompter-DhFjwbXA.js} +110 -40
  27. package/dist/{clack-prompter-DsooqWFU.js → clack-prompter-Q_PN4iLX.js} +110 -40
  28. package/dist/cli/daemon-cli.js +1 -1
  29. package/dist/{cli-DDzZu95y.js → cli-DXIWIIJj.js} +3 -3
  30. package/dist/{cli-PJTbyT76.js → cli-eje5udQT.js} +3 -3
  31. package/dist/{command-registry-DH2g-1VS.js → command-registry-Bs12xiCA.js} +9 -9
  32. package/dist/{completion-cli-cirX46xi.js → completion-cli-Btcmy2ZS.js} +2 -2
  33. package/dist/{completion-cli-Cszwcu14.js → completion-cli-RlpZaXwm.js} +1 -1
  34. package/dist/{config-cli-wGaTNazO.js → config-cli-CTo8yFw1.js} +1 -1
  35. package/dist/{config-cli-D-JctiSJ.js → config-cli-D-FqgnuJ.js} +1 -1
  36. package/dist/{config-guard-C74yuV1t.js → config-guard-D6r7usdP.js} +2 -2
  37. package/dist/{config-guard-ComvK070.js → config-guard-DnCSSIeP.js} +1 -1
  38. package/dist/{configure-BZPWTrYa.js → configure-CLTc56jo.js} +16 -16
  39. package/dist/{configure-B3qdEOin.js → configure-D0-Sq2kW.js} +16 -16
  40. package/dist/control-ui/assets/app-DXYMrRJ9.js.map +1 -1
  41. package/dist/{cron-cli-B_Y1xWzG.js → cron-cli-BstCBSyn.js} +2 -2
  42. package/dist/{cron-cli-DV_fO2Av.js → cron-cli-pA06wiEq.js} +2 -2
  43. package/dist/{daemon-cli-DwEfnmS3.js → daemon-cli-DiuXEPjO.js} +1 -1
  44. package/dist/{daemon-cli-D99T8qck.js → daemon-cli-cyqRsnTF.js} +1 -1
  45. package/dist/daemon-cli.js +1 -1
  46. package/dist/{deps-DXHMO1Yj.js → deps-BKAIBkcE.js} +1 -1
  47. package/dist/{deps-5vuaH16V.js → deps-BWo3ls9h.js} +1 -1
  48. package/dist/{doctor-config-flow-4WutpMTV.js → doctor-config-flow-B-I0osH5.js} +1 -1
  49. package/dist/{doctor-config-flow-Cd9O0xNE.js → doctor-config-flow-Ceaz-Gkk.js} +1 -1
  50. package/dist/entry.js +1 -1
  51. package/dist/extensionAPI.js +2 -2
  52. package/dist/{gateway-cli-DxttS--5.js → gateway-cli-BbSS1Nxd.js} +28 -28
  53. package/dist/{gateway-cli-DnTW-Vqh.js → gateway-cli-izDCXWNN.js} +28 -28
  54. package/dist/{health-CK5_7SB-.js → health-DW5NMpNI.js} +2 -2
  55. package/dist/{health-DkKBhl0x.js → health-kF4U3o3b.js} +2 -2
  56. package/dist/{heartbeat-runner-C_SzC_tK.js → heartbeat-runner-BnDruNG2.js} +1 -1
  57. package/dist/{heartbeat-runner-B9_owa4e.js → heartbeat-runner-CJP5uO8S.js} +1 -1
  58. package/dist/{hooks-cli-CF1H42-g.js → hooks-cli-CSFuSiA5.js} +4 -4
  59. package/dist/{hooks-cli-DsUN2nCy.js → hooks-cli-U5qCBqJm.js} +4 -4
  60. package/dist/index.js +9 -9
  61. package/dist/{ipv4-oR6PCFkE.js → ipv4-B42xQEbV.js} +2 -2
  62. package/dist/{ipv4-hmcj6CY1.js → ipv4-DSDJ9Fn2.js} +2 -2
  63. package/dist/{lifecycle-DkQi8XHs.js → lifecycle-Bbry4K-O.js} +1 -1
  64. package/dist/{lifecycle-BtrqlzIp.js → lifecycle-BiNcSCVf.js} +1 -1
  65. package/dist/{list.auth-overview-DqpchDrO.js → list.auth-overview-ByYcn7Ct.js} +1 -1
  66. package/dist/{list.auth-overview-DtfRUx-B.js → list.auth-overview-Di-jSuQF.js} +1 -1
  67. package/dist/llm-slug-generator.js +1 -1
  68. package/dist/{model-catalog--SvucuO6.js → model-catalog-ex4Cpln_.js} +12 -8
  69. package/dist/{models-zXXNWbCe.js → models-BonzQ9Rv.js} +7 -7
  70. package/dist/{models-cli-8b2o7ZBO.js → models-cli-Cc0fVKLR.js} +7 -7
  71. package/dist/{models-cli-DwXIxRSn.js → models-cli-DZ05AYqI.js} +8 -8
  72. package/dist/{node-cli-D55JvlGv.js → node-cli-CKXvITsL.js} +3 -3
  73. package/dist/{node-cli-Dmiet_CN.js → node-cli-Dfl7X414.js} +3 -3
  74. package/dist/{note-DrwZGnSu.js → note-DwkETqd-.js} +2 -0
  75. package/dist/{note-CLUeye9D.js → note-rV2vspIo.js} +2 -0
  76. package/dist/{onboard-CqUH0CNb.js → onboard-BDK2o_5B.js} +8 -8
  77. package/dist/{onboard-BMckmyvg.js → onboard-CpJeEn67.js} +8 -8
  78. package/dist/{onboard-channels-CWZUEiko.js → onboard-channels-CDXretWe.js} +2 -2
  79. package/dist/{onboard-channels-Di1MifgF.js → onboard-channels-ZnUGKi2j.js} +2 -2
  80. package/dist/{onboard-search-CLhDai7x.js → onboard-search-BIltnW27.js} +6 -6
  81. package/dist/{onboard-search-WWi4blgc.js → onboard-search-HgNX3hct.js} +6 -6
  82. package/dist/{onboarding-DsCvgeVW.js → onboarding-Bgx1tJnU.js} +128 -65
  83. package/dist/{onboarding-D4OTdWQp.js → onboarding-CBlXOasA.js} +128 -65
  84. package/dist/{openresponses-http-CFQL8cSe.js → openresponses-http-5S3xc2MZ.js} +1 -1
  85. package/dist/{openresponses-http-qcMe4CnQ.js → openresponses-http-BBNbIRzc.js} +2 -2
  86. package/dist/{openresponses-http-DVyWivMq.js → openresponses-http-BTpFUwym.js} +1 -1
  87. package/dist/{openresponses-http-D6Ttjnvd.js → openresponses-http-COAxhJal.js} +3 -3
  88. package/dist/{openresponses-http-BdrytBTu.js → openresponses-http-o273A5SH.js} +3 -3
  89. package/dist/{parent-default-help-ClCr80XR.js → parent-default-help-BwE33-U1.js} +1 -1
  90. package/dist/{parent-default-help-D_UWzDsy.js → parent-default-help-DzWAx_GB.js} +1 -1
  91. package/dist/{paths-DuymR5Rg.js → paths-Bzz-O3FX.js} +9 -9
  92. package/dist/{pi-embedded-IQzv6URS.js → pi-embedded-Bnuo5tPq.js} +5 -5
  93. package/dist/{pi-embedded-BS0sTNPV.js → pi-embedded-CeuBUTjd.js} +14 -14
  94. package/dist/{plugin-registry-DfiokqgQ.js → plugin-registry-D2IeEq2N.js} +1 -1
  95. package/dist/{plugin-registry-C6ytAnfA.js → plugin-registry-DjTXh-9g.js} +1 -1
  96. package/dist/plugin-sdk/{audio-preflight-Cyb1e94b.js → audio-preflight-CVWduuEO.js} +1 -1
  97. package/dist/plugin-sdk/{audio-preflight-CWTDcoUz.js → audio-preflight-CdPkTmJX.js} +1 -1
  98. package/dist/plugin-sdk/channel-plugin-common.js +1 -1
  99. package/dist/plugin-sdk/{channel-web-CcGhVHhJ.js → channel-web-oM8gCehY.js} +1 -1
  100. package/dist/plugin-sdk/command-status.js +1 -1
  101. package/dist/plugin-sdk/index.js +2 -2
  102. package/dist/plugin-sdk/{openresponses-http-BsP7r5IA.js → openresponses-http-C_9IfZXZ.js} +1 -1
  103. package/dist/plugin-sdk/{openresponses-http-C7iy26fS.js → openresponses-http-_SiZJaK2.js} +1 -1
  104. package/dist/plugin-sdk/{pi-model-discovery-runtime-FgSYY3zE.js → pi-model-discovery-runtime-BWcaNxzp.js} +1 -1
  105. package/dist/plugin-sdk/{registry-DyRgZdL8.js → registry-DXXOSq_V.js} +8 -8
  106. package/dist/plugin-sdk/{reply-K26zHCJ7.js → reply-e-9_IdAa.js} +5 -5
  107. package/dist/plugin-sdk/src/brand.d.ts +2 -2
  108. package/dist/plugin-sdk/{status-DUXaf75C.js → status-D_fsW8e3.js} +5 -5
  109. package/dist/plugin-sdk/{web-BnHwbjCb.js → web-BL2TuPTi.js} +1 -1
  110. package/dist/plugin-sdk/{web-BZ-KI_i-.js → web-CaVSiRWI.js} +2 -2
  111. package/dist/{plugins-cli-1wRgk_1k.js → plugins-cli-BMV70lmj.js} +6 -6
  112. package/dist/{plugins-cli-CHCNHfO2.js → plugins-cli-Bf0I1xYR.js} +6 -6
  113. package/dist/{program-BmRPzUoU.js → program-CZzXG3p4.js} +9 -9
  114. package/dist/{program-context-CRYL81pY.js → program-context-CaLlkx1k.js} +25 -25
  115. package/dist/{prompt-select-styled-BzqepcY0.js → prompt-select-styled-Cj_SHqRt.js} +8 -8
  116. package/dist/{prompt-select-styled-Ixt2Vxqr.js → prompt-select-styled-DVwrrZSb.js} +8 -8
  117. package/dist/{prompt-style-Wxki8rmI.js → prompt-style-CWAacuMq.js} +1 -2
  118. package/dist/{prompt-style-DxKPs6E0.js → prompt-style-Rmj3c-Ir.js} +1 -2
  119. package/dist/{providers-cli-DBG7T-38.js → providers-cli-BWZUM8kN.js} +3 -3
  120. package/dist/{providers-cli-DsUpaNkE.js → providers-cli-Dwb_MRo-.js} +3 -3
  121. package/dist/{pw-ai-BWWVm40d.js → pw-ai-D6eWnTeA.js} +1 -1
  122. package/dist/{register.agent-pKJfY4ij.js → register.agent-C-bHdMXU.js} +12 -12
  123. package/dist/{register.agent-D5MjI275.js → register.agent-D0ZpgSNd.js} +11 -11
  124. package/dist/{register.configure-DUqD_hkp.js → register.configure-B0PTAyow.js} +16 -16
  125. package/dist/{register.configure-BtdBEnbT.js → register.configure-B51e7-qt.js} +16 -16
  126. package/dist/{register.maintenance-Bu9WP0d1.js → register.maintenance-B3cXfhM1.js} +12 -12
  127. package/dist/{register.maintenance-CN_vDSkN.js → register.maintenance-BrmIl5VW.js} +13 -13
  128. package/dist/{register.message-Jpj57foO.js → register.message-Dzs1vNKG.js} +4 -4
  129. package/dist/{register.message-Bmx5XWhU.js → register.message-EKaGgJ9I.js} +4 -4
  130. package/dist/{register.onboard-BBdUy5X-.js → register.onboard-BFPT0Hh1.js} +18 -18
  131. package/dist/{register.onboard-BaIUg7j4.js → register.onboard-DmFrOBs4.js} +18 -18
  132. package/dist/{register.setup-CGKrDEMc.js → register.setup-5M8f6DaB.js} +18 -18
  133. package/dist/{register.setup-CxPYg9dc.js → register.setup-B0beU4w3.js} +18 -18
  134. package/dist/{register.status-health-sessions-Dyyxnfsc.js → register.status-health-sessions-9GJwT82K.js} +7 -7
  135. package/dist/{register.status-health-sessions-C0Tc0YCk.js → register.status-health-sessions-CEIpWahs.js} +7 -7
  136. package/dist/{register.subclis-D76pTHAo.js → register.subclis-C3yGp0vO.js} +17 -17
  137. package/dist/{reply-C-KlztgC.js → reply-B034LmuD.js} +12 -8
  138. package/dist/{run-main-REepjMTK.js → run-main-DYdI5qyZ.js} +18 -18
  139. package/dist/{runtime-helper-grants-vtmIYIZm.js → runtime-helper-grants-9-0EfflU.js} +1 -1
  140. package/dist/{runtime-helper-grants-BQPMglLl.js → runtime-helper-grants-BB9I81Ny.js} +1 -1
  141. package/dist/{sandbox-cli-Cj9M5dH_.js → sandbox-cli-Bl9Lyv-l.js} +3 -3
  142. package/dist/{sandbox-cli-DNh-ozSE.js → sandbox-cli-CAh9nzL6.js} +3 -3
  143. package/dist/{security-cli-B74QtPBv.js → security-cli-Bt7g6fbK.js} +4 -4
  144. package/dist/{security-cli--nwf-QKL.js → security-cli-lQy0YwCb.js} +4 -4
  145. package/dist/{server-CPLhmiQ1.js → server-BKrGeOGh.js} +3 -3
  146. package/dist/{server-CdnHL3HN.js → server-CES-5PaV.js} +3 -3
  147. package/dist/{server-cron-Bga__DzU.js → server-cron-D3WgivDk.js} +2 -2
  148. package/dist/{server-cron-9rZPNOCw.js → server-cron-q6O09WWT.js} +2 -2
  149. package/dist/{server-node-events-NE3EvW3K.js → server-node-events-DE5oWSSB.js} +4 -4
  150. package/dist/{server-node-events-CYM7X9Ka.js → server-node-events-Df_2uVcT.js} +4 -4
  151. package/dist/{status-DNSq7M4m.js → status-CdI_oSZ4.js} +1 -1
  152. package/dist/{status-Cbvyhx9d.js → status-CqIzNbBd.js} +1 -1
  153. package/dist/{status-DX0Q8QQg.js → status-DrXKyHMz.js} +4 -4
  154. package/dist/{status-DfxoXWmn.js → status-ne0p_x1W.js} +4 -4
  155. package/dist/{systemd-linger-9E60sw1j.js → systemd-linger-BTw_D-6k.js} +1 -1
  156. package/dist/{systemd-linger-BYFLOJbt.js → systemd-linger-BlmGMvvA.js} +1 -1
  157. package/dist/{tui-BTgZ8oh1.js → tui-CF9NTWgo.js} +1 -1
  158. package/dist/{tui-DCimzH-j.js → tui-CLXEsHbW.js} +1 -1
  159. package/dist/{tui-cli-DJ8WiWCz.js → tui-cli-Bo8T0iEO.js} +4 -4
  160. package/dist/{tui-cli-BzoEecpB.js → tui-cli-DIHJPDjw.js} +4 -4
  161. package/dist/{update-cli-vLZ2i1bC.js → update-cli-RA5GdCSl.js} +13 -13
  162. package/dist/{update-cli-DLE13jlu.js → update-cli-pAvK-b3V.js} +14 -14
  163. package/dist/{update-runner-DA8lIKi7.js → update-runner-CUbpiOBD.js} +1 -1
  164. package/dist/{update-runner-YRzVDxMy.js → update-runner-kVl9uX8I.js} +1 -1
  165. package/dist/{web-CdUefYwV.js → web-BSGV69pb.js} +4 -4
  166. package/dist/{web-D7U7yJI6.js → web-CFtLg8L6.js} +2 -2
  167. package/dist/{web-BqBwrpRI.js → web-CRHqblTb.js} +4 -4
  168. package/dist/{web-gqp_WLnj.js → web-D7NnzaWN.js} +1 -1
  169. package/dist/{web-DgtV30_7.js → web-R6Wrr8ru.js} +1 -1
  170. package/dist/{web-search-providers.runtime-Dr2M7_ZH.js → web-search-providers.runtime-BQw2Sxko.js} +1 -1
  171. package/dist/{web-search-providers.runtime-JauoxBKh.js → web-search-providers.runtime-E9CDTKMh.js} +1 -1
  172. package/docs/gateway/tailscale.md +44 -0
  173. package/docs/images/screenshots/local/chat-ui-1.png +0 -0
  174. package/docs/images/screenshots/local/final-ui-1.png +0 -0
  175. package/docs/images/screenshots/local/local-ui-1.png +0 -0
  176. package/docs/images/screenshots/local/local-ui-2.png +0 -0
  177. package/docs/images/screenshots/local/model-ui-1.png +0 -0
  178. package/docs/images/screenshots/local/wallet-ui-2.png +0 -0
  179. package/docs/install/index.md +26 -5
  180. package/docs/install/installer.md +11 -11
  181. package/docs/install/node.md +9 -0
  182. package/docs/install/vps.md +27 -7
  183. package/docs/security/baseline-checklist.md +7 -2
  184. package/docs/start/agent-wallet-mining-walkthrough.md +17 -1
  185. package/extensions/acpx/package.json +1 -1
  186. package/extensions/bluebubbles/package.json +1 -1
  187. package/extensions/copilot-proxy/package.json +1 -1
  188. package/extensions/diagnostics-otel/package.json +1 -1
  189. package/extensions/discord/package.json +1 -1
  190. package/extensions/fased-federation/package.json +1 -1
  191. package/extensions/feishu/package.json +1 -1
  192. package/extensions/google-gemini-cli-auth/package.json +1 -1
  193. package/extensions/googlechat/package.json +1 -1
  194. package/extensions/imessage/package.json +1 -1
  195. package/extensions/irc/package.json +1 -1
  196. package/extensions/line/package.json +1 -1
  197. package/extensions/llm-task/package.json +1 -1
  198. package/extensions/lobster/package.json +1 -1
  199. package/extensions/matrix/CHANGELOG.md +12 -0
  200. package/extensions/matrix/package.json +1 -1
  201. package/extensions/mattermost/package.json +1 -1
  202. package/extensions/memory-core/package.json +1 -1
  203. package/extensions/memory-lancedb/package.json +1 -1
  204. package/extensions/minimax-portal-auth/package.json +1 -1
  205. package/extensions/msteams/CHANGELOG.md +12 -0
  206. package/extensions/msteams/package.json +1 -1
  207. package/extensions/nextcloud-talk/package.json +1 -1
  208. package/extensions/nostr/CHANGELOG.md +12 -0
  209. package/extensions/nostr/package.json +1 -1
  210. package/extensions/open-prose/package.json +1 -1
  211. package/extensions/sat-mining/package.json +1 -1
  212. package/extensions/signal/package.json +1 -1
  213. package/extensions/slack/package.json +1 -1
  214. package/extensions/synology-chat/package.json +1 -1
  215. package/extensions/telegram/package.json +1 -1
  216. package/extensions/tlon/package.json +1 -1
  217. package/extensions/twitch/CHANGELOG.md +12 -0
  218. package/extensions/twitch/package.json +1 -1
  219. package/extensions/voice-call/CHANGELOG.md +12 -0
  220. package/extensions/voice-call/package.json +1 -1
  221. package/extensions/whatsapp/package.json +1 -1
  222. package/extensions/zalo/CHANGELOG.md +12 -0
  223. package/extensions/zalo/package.json +1 -1
  224. package/extensions/zalouser/CHANGELOG.md +12 -0
  225. package/extensions/zalouser/package.json +1 -1
  226. package/package.json +1 -1
  227. package/scripts/start-managed.sh +2 -2
  228. package/docs/images/screenshots/local/wallet-ui-1.png +0 -0
@@ -2,7 +2,7 @@ import "./paths-C9FmTW1x.js";
2
2
  import { S as resolveUserPath, i as CONFIG_DIR, m as isRecord } from "./agent-paths-DmOVZE7g.js";
3
3
  import { Co as coerceSecretRef, mo as resolveFasedAgentPackageRootSync, wl as installPluginFromNpmSpec } from "./agent-scope-DHrLr5OF.js";
4
4
  import "./commands-registry-BRvZQ1jh.js";
5
- import "./reply-C-KlztgC.js";
5
+ import "./reply-B034LmuD.js";
6
6
  import "./errors-Dx3S3Nrp.js";
7
7
  import "./send-C5_fB8YQ.js";
8
8
  import "./send-jxmRy65D.js";
@@ -37,7 +37,7 @@ import "./ssrf-Blf4NrHS.js";
37
37
  import "./outbound-attachment-CsXJwFsg.js";
38
38
  import "./fetch-CnCPOuq7.js";
39
39
  import "./delivery-queue-DKRjVFlq.js";
40
- import "./deps-DXHMO1Yj.js";
40
+ import "./deps-BKAIBkcE.js";
41
41
  import "./memory-DDpj0IVA.js";
42
42
  import "./memory-search-BwYkW6_V.js";
43
43
  import "./manager-BmONwMiP.js";
@@ -74,14 +74,14 @@ import "./progress-DZRfIFVb.js";
74
74
  import "./replies-Do40G8fO.js";
75
75
  import "./skills-remote-BghdrdFV.js";
76
76
  import "./skill-commands-QW8zKXC_.js";
77
- import "./prompt-style-Wxki8rmI.js";
77
+ import "./prompt-style-CWAacuMq.js";
78
78
  import "./pairing-labels-D2yOKhoV.js";
79
79
  import { t as enablePluginInConfig } from "./enable-D3_YPNIT.js";
80
80
  import { t as buildNpmResolutionInstallFields } from "./installs-DDbnXe4x.js";
81
- import "./status-DNSq7M4m.js";
81
+ import "./status-CdI_oSZ4.js";
82
82
  import "./update-Dew6hqdf.js";
83
- import { o as finalizeInstalledPluginConfig } from "./lifecycle-DkQi8XHs.js";
84
- import { t as resolvePluginWebSearchProviders } from "./web-search-providers.runtime-JauoxBKh.js";
83
+ import { o as finalizeInstalledPluginConfig } from "./lifecycle-Bbry4K-O.js";
84
+ import { t as resolvePluginWebSearchProviders } from "./web-search-providers.runtime-E9CDTKMh.js";
85
85
  import fs from "node:fs";
86
86
  import path from "node:path";
87
87
 
@@ -2,7 +2,7 @@ import { $c as installPluginFromNpmSpec, Wa as coerceSecretRef, pd as resolveFas
2
2
  import { i as CONFIG_DIR, p as isRecord, x as resolveUserPath } from "./agent-paths-BI1hx-tF.js";
3
3
  import "./send-D7X0_iFp.js";
4
4
  import "./send-BFEd4vCM.js";
5
- import "./model-catalog--SvucuO6.js";
5
+ import "./model-catalog-ex4Cpln_.js";
6
6
  import "./github-copilot-token-A9DiaCB0.js";
7
7
  import "./reply-prefix-TUhpEtvr.js";
8
8
  import "./memory-2keYbXkc.js";
@@ -44,7 +44,7 @@ import "./send-C-su1wPZ.js";
44
44
  import "./outbound-attachment-Bh4FmcYg.js";
45
45
  import "./fetch-BVvWzHT_.js";
46
46
  import "./delivery-queue-55Cityuq.js";
47
- import "./deps-5vuaH16V.js";
47
+ import "./deps-BWo3ls9h.js";
48
48
  import "./frontmatter-D2UNJikU.js";
49
49
  import "./skills-Dis31awJ.js";
50
50
  import "./skills-remote-CIAB0AXm.js";
@@ -71,14 +71,14 @@ import "./cli-utils-XevKf-tr.js";
71
71
  import "./help-format-B2DRdx98.js";
72
72
  import "./progress-DkVYFLij.js";
73
73
  import "./replies-FXlmpJVO.js";
74
- import "./prompt-style-DxKPs6E0.js";
74
+ import "./prompt-style-Rmj3c-Ir.js";
75
75
  import "./pairing-labels-BCM1S2e_.js";
76
76
  import { t as enablePluginInConfig } from "./enable-C4xB2A3x.js";
77
77
  import { t as buildNpmResolutionInstallFields } from "./installs-Cha8QIzO.js";
78
- import "./status-Cbvyhx9d.js";
78
+ import "./status-CqIzNbBd.js";
79
79
  import "./update-D4rhRm3D.js";
80
- import { o as finalizeInstalledPluginConfig } from "./lifecycle-BtrqlzIp.js";
81
- import { t as resolvePluginWebSearchProviders } from "./web-search-providers.runtime-Dr2M7_ZH.js";
80
+ import { o as finalizeInstalledPluginConfig } from "./lifecycle-BiNcSCVf.js";
81
+ import { t as resolvePluginWebSearchProviders } from "./web-search-providers.runtime-BQw2Sxko.js";
82
82
  import path from "node:path";
83
83
  import fs from "node:fs";
84
84
 
@@ -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--SvucuO6.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-hmcj6CY1.js";
20
- import { s as waitForHostedDashboardBrowserPath } from "./health-CK5_7SB-.js";
21
- import { n as warnIfModelConfigLooksOff, r as applyAuthChoice } from "./auth-choice-DEux81xn.js";
22
- import { t as promptAuthChoiceGrouped } from "./auth-choice-prompt-D8d4kRYT.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-CWZUEiko.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-DCimzH-j.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`,
@@ -1357,7 +1359,7 @@ async function finalizeOnboardingWizard(options) {
1357
1359
  const systemdAvailable = process.platform === "linux" ? await isSystemdUserServiceAvailable() : true;
1358
1360
  if (process.platform === "linux" && !systemdAvailable && !strictVps && flow !== "quickstart") await prompter.note("Systemd user services are unavailable. Skipping lingering checks and user-service install.", "Systemd");
1359
1361
  if (process.platform === "linux" && systemdAvailable && strictVps) {} else if (process.platform === "linux" && systemdAvailable) {
1360
- const { ensureSystemdUserLingerInteractive } = await import("./systemd-linger-BYFLOJbt.js").then((n) => n.r);
1362
+ const { ensureSystemdUserLingerInteractive } = await import("./systemd-linger-BlmGMvvA.js").then((n) => n.r);
1361
1363
  await ensureSystemdUserLingerInteractive({
1362
1364
  runtime,
1363
1365
  prompter: {
@@ -2462,7 +2464,7 @@ async function finalizeOnboardingWizard(options) {
2462
2464
  fallbackHint: !strictVps ? controlUiOpenHint : void 0
2463
2465
  }), "Dashboard ready");
2464
2466
  }
2465
- await prompter.outro(strictVps ? "Setup complete. Use HOSTED ACCESS above: Web UI, SSH, or fallback tunnel." : controlUiOpened ? "Setup complete. Next: Agent > Models, then Chat." : "Setup complete. Use the dashboard link above, then use Agent > Models and Chat.");
2467
+ if (!strictVps) await prompter.outro(controlUiOpened ? "Setup complete. Next: Agent > Models, then Chat." : "Setup complete. Use the dashboard link above, then use Agent > Models and Chat.");
2466
2468
  return { launchedTui };
2467
2469
  }
2468
2470
 
@@ -2746,6 +2748,8 @@ const LOW_MEMORY_SWAP_THRESHOLD_MB = 2304;
2746
2748
  const LOW_MEMORY_HOSTING_SWAP_GB = 4;
2747
2749
  const HOSTING_SWAP_GB = 2;
2748
2750
  const TAILSCALE_INTERACTIVE_TIMEOUT_MS = 120 * 1e3;
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";
2749
2753
  function detectTotalMemoryMb() {
2750
2754
  if (process.platform === "linux") try {
2751
2755
  const match = fs.readFileSync("/proc/meminfo", "utf8").match(/^MemTotal:\s+(\d+)\s+kB/m);
@@ -2778,29 +2782,67 @@ function run(command, logPath) {
2778
2782
  detail: detail || `${command} (exit=${proc.status ?? "unknown"})`
2779
2783
  };
2780
2784
  }
2781
- function runInteractive(command, logPath, options) {
2782
- if (logPath) appendHostSecurityLog(logPath, command, "interactive command started; output shown in terminal");
2783
- const proc = spawnSync("bash", ["-lc", command], {
2784
- stdio: [
2785
+ async function runInteractive(command, logPath, options) {
2786
+ if (logPath) appendHostSecurityLog(logPath, command, "interactive command started; output captured for framed wizard display");
2787
+ return await new Promise((resolve) => {
2788
+ const proc = spawn("bash", ["-lc", command], { stdio: [
2785
2789
  "ignore",
2786
- "inherit",
2787
- "inherit"
2788
- ],
2789
- timeout: options?.timeoutMs,
2790
- killSignal: "SIGINT"
2790
+ "pipe",
2791
+ "pipe"
2792
+ ] });
2793
+ let output = "";
2794
+ let loginUrlShown = false;
2795
+ let timedOut = false;
2796
+ let noteQueue = Promise.resolve();
2797
+ const timer = options?.timeoutMs && options.timeoutMs > 0 ? setTimeout(() => {
2798
+ timedOut = true;
2799
+ proc.kill("SIGINT");
2800
+ }, options.timeoutMs) : null;
2801
+ const maybeShowLoginUrl = (chunk) => {
2802
+ output += chunk;
2803
+ if (loginUrlShown) return;
2804
+ const loginUrl = output.match(TAILSCALE_LOGIN_URL_RE)?.[0];
2805
+ if (!loginUrl) return;
2806
+ loginUrlShown = true;
2807
+ if (options?.prompter) {
2808
+ const message = [
2809
+ noteHeading("Open login URL"),
2810
+ "Open this URL in your local browser:",
2811
+ ...noteCommands([loginUrl]),
2812
+ "Return here after approving this VPS."
2813
+ ].join("\n");
2814
+ noteQueue = noteQueue.then(() => options.prompter?.note(message, options.noteTitle ?? "Tailscale login URL"));
2815
+ }
2816
+ };
2817
+ proc.stdout?.on("data", (chunk) => {
2818
+ maybeShowLoginUrl(String(chunk));
2819
+ });
2820
+ proc.stderr?.on("data", (chunk) => {
2821
+ maybeShowLoginUrl(String(chunk));
2822
+ });
2823
+ proc.on("error", (error) => {
2824
+ output += `\n${error instanceof Error ? error.message : String(error)}`;
2825
+ });
2826
+ proc.on("close", (code) => {
2827
+ if (timer) clearTimeout(timer);
2828
+ const detail = timedOut ? `${command} timed out after ${Math.round((options?.timeoutMs ?? 0) / 1e3)}s\n${output}`.trim() : `${command} (exit=${code ?? "unknown"})\n${output}`.trim();
2829
+ if (logPath) appendHostSecurityLog(logPath, command, detail);
2830
+ noteQueue.then(() => {
2831
+ if (code === 0) {
2832
+ resolve({
2833
+ ok: true,
2834
+ detail
2835
+ });
2836
+ return;
2837
+ }
2838
+ resolve({
2839
+ ok: false,
2840
+ detail,
2841
+ timedOut
2842
+ });
2843
+ });
2844
+ });
2791
2845
  });
2792
- const timedOut = proc.error?.code === "ETIMEDOUT";
2793
- const detail = timedOut ? `${command} timed out after ${Math.round((options?.timeoutMs ?? 0) / 1e3)}s` : `${command} (exit=${proc.status ?? "unknown"})`;
2794
- if (logPath) appendHostSecurityLog(logPath, command, detail);
2795
- if (proc.status === 0) return {
2796
- ok: true,
2797
- detail
2798
- };
2799
- return {
2800
- ok: false,
2801
- detail,
2802
- timedOut
2803
- };
2804
2846
  }
2805
2847
  function buildTailscaleLoginWaitCommand(command) {
2806
2848
  return [
@@ -2808,7 +2850,7 @@ function buildTailscaleLoginWaitCommand(command) {
2808
2850
  `bash -lc ${shellQuote(command)} &`,
2809
2851
  "ts_pid=$!",
2810
2852
  "for _ in $(seq 1 55); do",
2811
- " 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`,
2812
2854
  " kill -INT \"$ts_pid\" >/dev/null 2>&1 || true",
2813
2855
  " wait \"$ts_pid\" >/dev/null 2>&1 || true",
2814
2856
  " exit 0",
@@ -2821,15 +2863,19 @@ function buildTailscaleLoginWaitCommand(command) {
2821
2863
  "done",
2822
2864
  "kill -INT \"$ts_pid\" >/dev/null 2>&1 || true",
2823
2865
  "wait \"$ts_pid\" >/dev/null 2>&1 || true",
2824
- "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`,
2825
2867
  " exit 0",
2826
2868
  "fi",
2827
2869
  "exit 124"
2828
2870
  ].join("\n");
2829
2871
  }
2830
- function runInteractiveTailscaleLogin(command, logPath) {
2831
- if (logPath) appendHostSecurityLog(logPath, command, "interactive Tailscale login started; output shown in terminal");
2832
- const result = runInteractive(buildTailscaleLoginWaitCommand(command), void 0, { timeoutMs: TAILSCALE_INTERACTIVE_TIMEOUT_MS });
2872
+ async function runInteractiveTailscaleLogin(command, logPath, prompter) {
2873
+ if (logPath) appendHostSecurityLog(logPath, command, "interactive Tailscale login started; login URL shown in framed wizard note");
2874
+ const result = await runInteractive(buildTailscaleLoginWaitCommand(command), void 0, {
2875
+ timeoutMs: TAILSCALE_INTERACTIVE_TIMEOUT_MS,
2876
+ prompter,
2877
+ noteTitle: "Tailscale login URL"
2878
+ });
2833
2879
  if (logPath) appendHostSecurityLog(logPath, "tailscale login result", result.ok ? "tailnet IP appeared or tailscale up completed" : result.detail ?? "tailscale login failed");
2834
2880
  if (result.ok) return {
2835
2881
  ok: true,
@@ -2870,21 +2916,29 @@ function tailscaleTimedOutButReady(result, logPath, runner = run) {
2870
2916
  function shellQuote(value) {
2871
2917
  return `'${value.replace(/'/g, "'\\''")}'`;
2872
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
+ }
2873
2925
  function isTailscaleLoggedIn(logPath, runner = run) {
2874
- 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;
2875
2927
  }
2876
2928
  function hasTailscaleIp(logPath, runner = run) {
2877
- 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;
2878
2930
  }
2879
2931
  function readTailscaleIp(logPath, runner = run) {
2880
2932
  const probe = runner("tailscale ip -4", logPath);
2881
- 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);
2882
2935
  if (!sudoProbe.ok || !sudoProbe.detail) return;
2883
2936
  return sudoProbe.detail.match(/\b\d{1,3}(?:\.\d{1,3}){3}\b/)?.[0];
2884
2937
  }
2885
2938
  function readTailscaleSelf(logPath, runner = run) {
2886
2939
  const probe = runner("tailscale status --json", logPath);
2887
- 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);
2888
2942
  if (!sudoProbe.ok || !sudoProbe.detail) return { ipv4: readTailscaleIp(logPath, runner) };
2889
2943
  try {
2890
2944
  const parsed = JSON.parse(sudoProbe.detail);
@@ -2990,7 +3044,8 @@ function verifyTailnetSshServerPrerequisites(params) {
2990
3044
  };
2991
3045
  }
2992
3046
  function ensureTailnetSshIngressForVerification(params) {
2993
- const result = (params.runner ?? run)([
3047
+ const runner = params.runner ?? run;
3048
+ const command = [
2994
3049
  "if command -v ufw >/dev/null 2>&1; then",
2995
3050
  " if sudo -n ufw status | grep -qi '^Status: active'; then",
2996
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",
@@ -3001,7 +3056,9 @@ function ensureTailnetSshIngressForVerification(params) {
3001
3056
  " sudo -n firewall-cmd --permanent --zone=trusted --add-interface=tailscale0 >/dev/null 2>&1 || true",
3002
3057
  " sudo -n firewall-cmd --reload >/dev/null 2>&1 || true",
3003
3058
  "fi"
3004
- ].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);
3005
3062
  if (!result.ok) return {
3006
3063
  ok: false,
3007
3064
  detail: result.detail ?? "could not prepare tailnet SSH firewall rule before verification"
@@ -3088,7 +3145,7 @@ async function confirmTailnetSshBeforeLockdown(params) {
3088
3145
  return false;
3089
3146
  }
3090
3147
  await prompter.note(formatTailscaleAccountBrowserLoginNote(), "Tailscale login");
3091
- const tsReset = interactiveRunner("sudo -n tailscale logout && sudo -n tailscale up --ssh --accept-routes --reset", logPath);
3148
+ const tsReset = await interactiveRunner(hostMaintenanceCommand("tailscale-up-reset-ssh"), logPath, prompter);
3092
3149
  const acceptedTimedOutLogin = tailscaleTimedOutButReady(tsReset, logPath, runner);
3093
3150
  if (!tsReset.ok && !acceptedTimedOutLogin || !hasTailscaleIp(logPath, runner)) {
3094
3151
  runtime.error("Hosting setup stopped before SSH/firewall lock-down.");
@@ -3132,9 +3189,9 @@ function ensureTailscaleServe(port, logPath) {
3132
3189
  ok: true,
3133
3190
  detail: `tailscale serve --bg -> 127.0.0.1:${port}`
3134
3191
  };
3135
- 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 {
3136
3193
  ok: true,
3137
- detail: `sudo tailscale serve --bg -> 127.0.0.1:${port}`
3194
+ detail: `host maintenance tailscale serve -> 127.0.0.1:${port}`
3138
3195
  };
3139
3196
  if (run(`tailscale serve https / http://127.0.0.1:${port}`, logPath).ok) return {
3140
3197
  ok: true,
@@ -3158,7 +3215,7 @@ function isTailscaleServeReady(port) {
3158
3215
  ],
3159
3216
  encoding: "utf8"
3160
3217
  });
3161
- 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")], {
3162
3219
  stdio: [
3163
3220
  "ignore",
3164
3221
  "pipe",
@@ -3191,6 +3248,7 @@ function packageInstallCommand(packages) {
3191
3248
  }
3192
3249
  function tailscaleInstallCommand() {
3193
3250
  return [
3251
+ `${hostMaintenanceCommand("tailscale-install-start")} && exit 0`,
3194
3252
  "if command -v tailscale >/dev/null 2>&1; then",
3195
3253
  " :",
3196
3254
  "elif command -v apt-get >/dev/null 2>&1; then",
@@ -3216,6 +3274,7 @@ function tailscaleInstallCommand() {
3216
3274
  }
3217
3275
  function firewallBaselineCommand() {
3218
3276
  return [
3277
+ `${hostMaintenanceCommand("firewall-baseline")} && exit 0`,
3219
3278
  "if command -v ufw >/dev/null 2>&1 || command -v apt-get >/dev/null 2>&1; then",
3220
3279
  " command -v ufw >/dev/null 2>&1 || { " + packageInstallCommand(["ufw"]) + "; }",
3221
3280
  " sudo -n ufw default deny incoming",
@@ -3239,13 +3298,14 @@ function firewallBaselineCommand() {
3239
3298
  }
3240
3299
  function automaticUpdatesCommand() {
3241
3300
  return [
3301
+ `${hostMaintenanceCommand("automatic-updates")} && exit 0`,
3242
3302
  "if command -v apt-get >/dev/null 2>&1; then",
3243
3303
  " " + packageInstallCommand(["unattended-upgrades"]),
3244
3304
  " sudo -n systemctl enable --now unattended-upgrades >/dev/null 2>&1 || true",
3245
3305
  " sudo -n systemctl enable --now apt-daily.timer apt-daily-upgrade.timer",
3246
3306
  "elif command -v dnf >/dev/null 2>&1 || command -v dnf5 >/dev/null 2>&1; then",
3247
3307
  " (" + packageInstallCommand(["dnf5-plugin-automatic"]) + ") || (" + packageInstallCommand(["dnf-automatic"]) + ")",
3248
- " sudo -n sed -i 's/^apply_updates[[:space:]]*=.*/apply_updates = yes/' /etc/dnf/automatic.conf >/dev/null 2>&1 || true",
3308
+ " sudo -n /usr/local/sbin/fased-host-maintenance enable-dnf-automatic >/dev/null 2>&1 || sudo -n sed -i 's/^apply_updates[[:space:]]*=.*/apply_updates = yes/' /etc/dnf/automatic.conf >/dev/null 2>&1 || true",
3249
3309
  " sudo -n systemctl enable --now dnf5-automatic.timer >/dev/null 2>&1 || sudo -n systemctl enable --now dnf-automatic.timer",
3250
3310
  "elif command -v yum >/dev/null 2>&1; then",
3251
3311
  " (" + packageInstallCommand(["dnf-automatic"]) + ") || (" + packageInstallCommand(["yum-cron"]) + ")",
@@ -3256,6 +3316,9 @@ function automaticUpdatesCommand() {
3256
3316
  "fi"
3257
3317
  ].join("\n");
3258
3318
  }
3319
+ function sshHardeningCommand() {
3320
+ return hostMaintenanceCommand("harden-ssh");
3321
+ }
3259
3322
  function failOrContinue(params) {
3260
3323
  const { opts, runtime, step, detail } = params;
3261
3324
  const body = detail ? `${step}: ${detail}` : step;
@@ -3300,8 +3363,8 @@ async function applyHostingSecurity(params) {
3300
3363
  validate: (value) => value.trim() ? void 0 : "Required"
3301
3364
  })).trim();
3302
3365
  else await prompter.note(formatTailscaleBrowserLoginNote(), "Tailscale login");
3303
- 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";
3304
- const tsReset = tsAuthkey ? run(resetCommand, logPath) : runInteractiveTailscaleLogin(resetCommand, logPath);
3366
+ const resetCommand = tsAuthkey ? hostMaintenanceCommandWithInput("tailscale-up-reset-authkey-ssh", tsAuthkey) : hostMaintenanceCommand("tailscale-up-reset-ssh");
3367
+ const tsReset = tsAuthkey ? run(resetCommand, logPath) : await runInteractiveTailscaleLogin(resetCommand, logPath, prompter);
3305
3368
  if (!tsReset.ok && !tailscaleTimedOutButReady(tsReset, logPath)) return {
3306
3369
  ok: false,
3307
3370
  detail: tsReset.detail ?? "tailscale account switch failed"
@@ -3424,7 +3487,7 @@ async function applyHostingSecurity(params) {
3424
3487
  logPath
3425
3488
  };
3426
3489
  }
3427
- } 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);
3428
3491
  if (prompter && opts.nonInteractive !== true) await prompter.note(formatLocalDeviceTailnetRequirementNote(), "Local device requirement");
3429
3492
  let tsHealthy = isTailscaleLoggedIn(logPath);
3430
3493
  if (tsHealthy && prompter && opts.nonInteractive !== true) {
@@ -3433,7 +3496,7 @@ async function applyHostingSecurity(params) {
3433
3496
  initialValue: false
3434
3497
  })) {
3435
3498
  if (prompter) await prompter.note(formatTailscaleBrowserLoginNote(), "Tailscale login");
3436
- const tsReset = runInteractiveTailscaleLogin("sudo -n tailscale logout && sudo -n tailscale up --ssh --accept-routes --reset", logPath);
3499
+ const tsReset = await runInteractiveTailscaleLogin(hostMaintenanceCommand("tailscale-up-reset-ssh"), logPath, prompter);
3437
3500
  if (!tsReset.ok && !tailscaleTimedOutButReady(tsReset, logPath)) {
3438
3501
  checks.push({
3439
3502
  name: "tailscale",
@@ -3476,7 +3539,7 @@ async function applyHostingSecurity(params) {
3476
3539
  })).trim();
3477
3540
  }
3478
3541
  if (tsAuthkey) {
3479
- const tsUp = run(`sudo -n tailscale up --authkey ${JSON.stringify(tsAuthkey)} --ssh`, logPath);
3542
+ const tsUp = run(hostMaintenanceCommandWithInput("tailscale-up-authkey-ssh", tsAuthkey), logPath);
3480
3543
  if (!tsUp.ok) {
3481
3544
  checks.push({
3482
3545
  name: "tailscale",
@@ -3520,7 +3583,7 @@ async function applyHostingSecurity(params) {
3520
3583
  };
3521
3584
  } else {
3522
3585
  if (prompter) await prompter.note(formatTailscaleBrowserLoginNote(), "Tailscale login");
3523
- const tsUp = runInteractiveTailscaleLogin("sudo -n tailscale up --ssh", logPath);
3586
+ const tsUp = await runInteractiveTailscaleLogin(hostMaintenanceCommand("tailscale-up-ssh"), logPath, prompter);
3524
3587
  if (!tsUp.ok && !tailscaleTimedOutButReady(tsUp, logPath)) {
3525
3588
  checks.push({
3526
3589
  name: "tailscale",
@@ -3575,7 +3638,7 @@ async function applyHostingSecurity(params) {
3575
3638
  detail: "tailnet IP present; verifying app SSH before lock-down"
3576
3639
  });
3577
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();
3578
- 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);
3579
3642
  if (!await confirmTailnetSshBeforeLockdown({
3580
3643
  opts,
3581
3644
  runtime,
@@ -3647,7 +3710,7 @@ async function applyHostingSecurity(params) {
3647
3710
  ok: true,
3648
3711
  detail: "default-deny public ingress with tailnet SSH/HTTPS access"
3649
3712
  });
3650
- const sshRes = run("sudo -n sed -i 's/^#\\?PasswordAuthentication .*/PasswordAuthentication no/' /etc/ssh/sshd_config; sudo -n sed -i 's/^#\\?PermitRootLogin .*/PermitRootLogin no/' /etc/ssh/sshd_config; sudo -n systemctl restart ssh || sudo -n systemctl restart sshd", logPath);
3713
+ const sshRes = run(sshHardeningCommand(), logPath);
3651
3714
  if (!sshRes.ok) {
3652
3715
  checks.push({
3653
3716
  name: "ssh",
@@ -3672,7 +3735,7 @@ async function applyHostingSecurity(params) {
3672
3735
  ok: true,
3673
3736
  detail: "password auth/root login disabled and ssh restarted"
3674
3737
  });
3675
- 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)`);
3676
3739
  if (!f2bRes.ok) {
3677
3740
  checks.push({
3678
3741
  name: "fail2ban",
@@ -3722,7 +3785,7 @@ async function applyHostingSecurity(params) {
3722
3785
  ok: true,
3723
3786
  detail: "automatic security updates enabled"
3724
3787
  });
3725
- runtime.log("Hosting host hardening complete.");
3788
+ appendHostSecurityLog(logPath, "hosting host hardening complete", "enforced");
3726
3789
  return {
3727
3790
  profile,
3728
3791
  checks,