@mono-agent/agent-app 0.20.11 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (369) hide show
  1. package/README.md +260 -98
  2. package/dist/adapter-send-tools.d.ts +3 -2
  3. package/dist/adapter-send-tools.d.ts.map +1 -1
  4. package/dist/adapter-send-tools.js +15 -5
  5. package/dist/adapter-send-tools.js.map +1 -1
  6. package/dist/app-controller-channels.d.ts +6 -0
  7. package/dist/app-controller-channels.d.ts.map +1 -1
  8. package/dist/app-controller-channels.js +29 -2
  9. package/dist/app-controller-channels.js.map +1 -1
  10. package/dist/app-controller-continuation.d.ts.map +1 -1
  11. package/dist/app-controller-continuation.js +2 -3
  12. package/dist/app-controller-continuation.js.map +1 -1
  13. package/dist/app-controller-lifecycle.d.ts +4 -0
  14. package/dist/app-controller-lifecycle.d.ts.map +1 -1
  15. package/dist/app-controller-lifecycle.js +7 -0
  16. package/dist/app-controller-lifecycle.js.map +1 -1
  17. package/dist/app-controller-maintenance.d.ts +3 -1
  18. package/dist/app-controller-maintenance.d.ts.map +1 -1
  19. package/dist/app-controller-maintenance.js +3 -0
  20. package/dist/app-controller-maintenance.js.map +1 -1
  21. package/dist/app-controller-monitors.d.ts +26 -0
  22. package/dist/app-controller-monitors.d.ts.map +1 -0
  23. package/dist/app-controller-monitors.js +127 -0
  24. package/dist/app-controller-monitors.js.map +1 -0
  25. package/dist/app-controller-responder.d.ts +9 -17
  26. package/dist/app-controller-responder.d.ts.map +1 -1
  27. package/dist/app-controller-responder.js +54 -86
  28. package/dist/app-controller-responder.js.map +1 -1
  29. package/dist/app-controller-traceability.d.ts.map +1 -1
  30. package/dist/app-controller-traceability.js +3 -0
  31. package/dist/app-controller-traceability.js.map +1 -1
  32. package/dist/app-controller-types.d.ts +1 -0
  33. package/dist/app-controller-types.d.ts.map +1 -1
  34. package/dist/app-controller-utils.d.ts +1 -5
  35. package/dist/app-controller-utils.d.ts.map +1 -1
  36. package/dist/app-controller-utils.js +4 -21
  37. package/dist/app-controller-utils.js.map +1 -1
  38. package/dist/app-controller.d.ts +26 -10
  39. package/dist/app-controller.d.ts.map +1 -1
  40. package/dist/app-controller.js +39 -1
  41. package/dist/app-controller.js.map +1 -1
  42. package/dist/artifact-retention.js +11 -0
  43. package/dist/artifact-retention.js.map +1 -1
  44. package/dist/background.d.ts +0 -6
  45. package/dist/background.d.ts.map +1 -1
  46. package/dist/background.js +5 -58
  47. package/dist/background.js.map +1 -1
  48. package/dist/channel-drivers/slack.d.ts.map +1 -1
  49. package/dist/channel-drivers/slack.js +18 -0
  50. package/dist/channel-drivers/slack.js.map +1 -1
  51. package/dist/channel-drivers/telegram.d.ts.map +1 -1
  52. package/dist/channel-drivers/telegram.js +26 -0
  53. package/dist/channel-drivers/telegram.js.map +1 -1
  54. package/dist/channel-drivers/tui.d.ts +68 -8
  55. package/dist/channel-drivers/tui.d.ts.map +1 -1
  56. package/dist/channel-drivers/tui.js +407 -89
  57. package/dist/channel-drivers/tui.js.map +1 -1
  58. package/dist/channel-runtime-controls.d.ts +2 -1
  59. package/dist/channel-runtime-controls.d.ts.map +1 -1
  60. package/dist/channel-runtime-controls.js +79 -22
  61. package/dist/channel-runtime-controls.js.map +1 -1
  62. package/dist/cli-args.d.ts +5 -8
  63. package/dist/cli-args.d.ts.map +1 -1
  64. package/dist/cli-args.js +33 -52
  65. package/dist/cli-args.js.map +1 -1
  66. package/dist/cli-background-command.d.ts.map +1 -1
  67. package/dist/cli-background-command.js +4 -0
  68. package/dist/cli-background-command.js.map +1 -1
  69. package/dist/cli-commands.d.ts.map +1 -1
  70. package/dist/cli-commands.js +24 -2
  71. package/dist/cli-commands.js.map +1 -1
  72. package/dist/cli-help.d.ts +26 -0
  73. package/dist/cli-help.d.ts.map +1 -1
  74. package/dist/cli-help.js +58 -53
  75. package/dist/cli-help.js.map +1 -1
  76. package/dist/cli-init-command.d.ts +1 -2
  77. package/dist/cli-init-command.d.ts.map +1 -1
  78. package/dist/cli-init-command.js +31 -71
  79. package/dist/cli-init-command.js.map +1 -1
  80. package/dist/cli-install-skill-command.d.ts.map +1 -1
  81. package/dist/cli-install-skill-command.js +12 -3
  82. package/dist/cli-install-skill-command.js.map +1 -1
  83. package/dist/config-reference.d.ts +1 -0
  84. package/dist/config-reference.d.ts.map +1 -1
  85. package/dist/config-reference.js +217 -60
  86. package/dist/config-reference.js.map +1 -1
  87. package/dist/configured-agent.d.ts +27 -4
  88. package/dist/configured-agent.d.ts.map +1 -1
  89. package/dist/configured-agent.js +159 -112
  90. package/dist/configured-agent.js.map +1 -1
  91. package/dist/conversation-title.d.ts.map +1 -1
  92. package/dist/conversation-title.js +9 -2
  93. package/dist/conversation-title.js.map +1 -1
  94. package/dist/cron-control-store.d.ts.map +1 -1
  95. package/dist/cron-control-store.js +4 -2
  96. package/dist/cron-control-store.js.map +1 -1
  97. package/dist/doctor.d.ts +7 -13
  98. package/dist/doctor.d.ts.map +1 -1
  99. package/dist/doctor.js +406 -770
  100. package/dist/doctor.js.map +1 -1
  101. package/dist/first-run-readiness.d.ts.map +1 -1
  102. package/dist/first-run-readiness.js +0 -6
  103. package/dist/first-run-readiness.js.map +1 -1
  104. package/dist/index.d.ts +2 -0
  105. package/dist/index.d.ts.map +1 -1
  106. package/dist/index.js +1 -0
  107. package/dist/index.js.map +1 -1
  108. package/dist/interaction-bridge.d.ts +3 -3
  109. package/dist/interaction-bridge.d.ts.map +1 -1
  110. package/dist/interaction-bridge.js +27 -10
  111. package/dist/interaction-bridge.js.map +1 -1
  112. package/dist/launchd.d.ts +2 -0
  113. package/dist/launchd.d.ts.map +1 -1
  114. package/dist/launchd.js +3 -0
  115. package/dist/launchd.js.map +1 -1
  116. package/dist/local-tui-session.d.ts +14 -0
  117. package/dist/local-tui-session.d.ts.map +1 -0
  118. package/dist/local-tui-session.js +100 -0
  119. package/dist/local-tui-session.js.map +1 -0
  120. package/dist/mcp-apps.d.ts.map +1 -1
  121. package/dist/mcp-apps.js +3 -0
  122. package/dist/mcp-apps.js.map +1 -1
  123. package/dist/memory-journal.d.ts +53 -0
  124. package/dist/memory-journal.d.ts.map +1 -0
  125. package/dist/memory-journal.js +586 -0
  126. package/dist/memory-journal.js.map +1 -0
  127. package/dist/memory-recall.d.ts.map +1 -1
  128. package/dist/memory-recall.js +16 -2
  129. package/dist/memory-recall.js.map +1 -1
  130. package/dist/memory-remember.d.ts +49 -0
  131. package/dist/memory-remember.d.ts.map +1 -0
  132. package/dist/memory-remember.js +190 -0
  133. package/dist/memory-remember.js.map +1 -0
  134. package/dist/memory-retrieval.d.ts +33 -0
  135. package/dist/memory-retrieval.d.ts.map +1 -1
  136. package/dist/memory-retrieval.js +43 -0
  137. package/dist/memory-retrieval.js.map +1 -1
  138. package/dist/model-effort-capabilities.d.ts +8 -9
  139. package/dist/model-effort-capabilities.d.ts.map +1 -1
  140. package/dist/model-effort-capabilities.js +17 -35
  141. package/dist/model-effort-capabilities.js.map +1 -1
  142. package/dist/modules/base.d.ts +3 -4
  143. package/dist/modules/base.d.ts.map +1 -1
  144. package/dist/modules/base.js +4 -6
  145. package/dist/modules/base.js.map +1 -1
  146. package/dist/modules/catalog.d.ts.map +1 -1
  147. package/dist/modules/catalog.js +11 -9
  148. package/dist/modules/catalog.js.map +1 -1
  149. package/dist/modules/known-tools.d.ts +2 -2
  150. package/dist/modules/known-tools.d.ts.map +1 -1
  151. package/dist/modules/known-tools.js +7 -0
  152. package/dist/modules/known-tools.js.map +1 -1
  153. package/dist/monitor-channel-routing.d.ts +20 -0
  154. package/dist/monitor-channel-routing.d.ts.map +1 -0
  155. package/dist/monitor-channel-routing.js +73 -0
  156. package/dist/monitor-channel-routing.js.map +1 -0
  157. package/dist/monitors-command.d.ts +23 -0
  158. package/dist/monitors-command.d.ts.map +1 -0
  159. package/dist/monitors-command.js +217 -0
  160. package/dist/monitors-command.js.map +1 -0
  161. package/dist/monitors-config.d.ts +77 -0
  162. package/dist/monitors-config.d.ts.map +1 -0
  163. package/dist/monitors-config.js +150 -0
  164. package/dist/monitors-config.js.map +1 -0
  165. package/dist/monitors-context.d.ts +58 -0
  166. package/dist/monitors-context.d.ts.map +1 -0
  167. package/dist/monitors-context.js +194 -0
  168. package/dist/monitors-context.js.map +1 -0
  169. package/dist/monitors-runtime.d.ts +36 -0
  170. package/dist/monitors-runtime.d.ts.map +1 -0
  171. package/dist/monitors-runtime.js +103 -0
  172. package/dist/monitors-runtime.js.map +1 -0
  173. package/dist/monitors-service.d.ts +71 -0
  174. package/dist/monitors-service.d.ts.map +1 -0
  175. package/dist/monitors-service.js +1796 -0
  176. package/dist/monitors-service.js.map +1 -0
  177. package/dist/monitors-store.d.ts +93 -0
  178. package/dist/monitors-store.d.ts.map +1 -0
  179. package/dist/monitors-store.js +313 -0
  180. package/dist/monitors-store.js.map +1 -0
  181. package/dist/notify-destinations.d.ts +3 -2
  182. package/dist/notify-destinations.d.ts.map +1 -1
  183. package/dist/notify-destinations.js +6 -7
  184. package/dist/notify-destinations.js.map +1 -1
  185. package/dist/posted-reply-history.d.ts.map +1 -1
  186. package/dist/posted-reply-history.js +40 -3
  187. package/dist/posted-reply-history.js.map +1 -1
  188. package/dist/proactive-notify.d.ts +20 -1
  189. package/dist/proactive-notify.d.ts.map +1 -1
  190. package/dist/proactive-notify.js +56 -3
  191. package/dist/proactive-notify.js.map +1 -1
  192. package/dist/process-job-channel-routing.js +2 -1
  193. package/dist/process-job-channel-routing.js.map +1 -1
  194. package/dist/process-job-output-tail.d.ts +53 -0
  195. package/dist/process-job-output-tail.d.ts.map +1 -0
  196. package/dist/process-job-output-tail.js +257 -0
  197. package/dist/process-job-output-tail.js.map +1 -0
  198. package/dist/process-jobs-config.d.ts +1 -1
  199. package/dist/process-jobs-config.js +1 -1
  200. package/dist/process-jobs-config.js.map +1 -1
  201. package/dist/process-jobs-context.d.ts +11 -1
  202. package/dist/process-jobs-context.d.ts.map +1 -1
  203. package/dist/process-jobs-context.js +55 -11
  204. package/dist/process-jobs-context.js.map +1 -1
  205. package/dist/process-jobs-protection.js +1 -1
  206. package/dist/process-jobs-protection.js.map +1 -1
  207. package/dist/process-jobs-runtime.d.ts.map +1 -1
  208. package/dist/process-jobs-runtime.js +15 -12
  209. package/dist/process-jobs-runtime.js.map +1 -1
  210. package/dist/process-jobs-service.d.ts.map +1 -1
  211. package/dist/process-jobs-service.js +118 -172
  212. package/dist/process-jobs-service.js.map +1 -1
  213. package/dist/process-jobs-store.d.ts +3 -1
  214. package/dist/process-jobs-store.d.ts.map +1 -1
  215. package/dist/process-jobs-store.js +4 -1
  216. package/dist/process-jobs-store.js.map +1 -1
  217. package/dist/process-output-redaction.d.ts +58 -0
  218. package/dist/process-output-redaction.d.ts.map +1 -0
  219. package/dist/process-output-redaction.js +311 -0
  220. package/dist/process-output-redaction.js.map +1 -0
  221. package/dist/project-skills.d.ts +11 -5
  222. package/dist/project-skills.d.ts.map +1 -1
  223. package/dist/project-skills.js +88 -39
  224. package/dist/project-skills.js.map +1 -1
  225. package/dist/provider-auth-checks.d.ts +27 -0
  226. package/dist/provider-auth-checks.d.ts.map +1 -0
  227. package/dist/provider-auth-checks.js +349 -0
  228. package/dist/provider-auth-checks.js.map +1 -0
  229. package/dist/provider-auth-observations.d.ts +22 -0
  230. package/dist/provider-auth-observations.d.ts.map +1 -0
  231. package/dist/provider-auth-observations.js +139 -0
  232. package/dist/provider-auth-observations.js.map +1 -0
  233. package/dist/provider-auth-operator.d.ts +19 -0
  234. package/dist/provider-auth-operator.d.ts.map +1 -0
  235. package/dist/provider-auth-operator.js +560 -0
  236. package/dist/provider-auth-operator.js.map +1 -0
  237. package/dist/provider-auth-status.d.ts +20 -0
  238. package/dist/provider-auth-status.d.ts.map +1 -0
  239. package/dist/provider-auth-status.js +235 -0
  240. package/dist/provider-auth-status.js.map +1 -0
  241. package/dist/provider-model-catalog.d.ts +95 -0
  242. package/dist/provider-model-catalog.d.ts.map +1 -0
  243. package/dist/provider-model-catalog.js +550 -0
  244. package/dist/provider-model-catalog.js.map +1 -0
  245. package/dist/provider-setup.d.ts +26 -13
  246. package/dist/provider-setup.d.ts.map +1 -1
  247. package/dist/provider-setup.js +106 -130
  248. package/dist/provider-setup.js.map +1 -1
  249. package/dist/readiness-probe-worker.d.ts +1 -2
  250. package/dist/readiness-probe-worker.d.ts.map +1 -1
  251. package/dist/readiness-probe-worker.js +3 -8
  252. package/dist/readiness-probe-worker.js.map +1 -1
  253. package/dist/readiness-probe.d.ts +1 -1
  254. package/dist/readiness-probe.d.ts.map +1 -1
  255. package/dist/readiness-probe.js +3 -33
  256. package/dist/readiness-probe.js.map +1 -1
  257. package/dist/reply-artifacts.d.ts +3 -1
  258. package/dist/reply-artifacts.d.ts.map +1 -1
  259. package/dist/reply-artifacts.js +45 -10
  260. package/dist/reply-artifacts.js.map +1 -1
  261. package/dist/request-model-override.d.ts +14 -37
  262. package/dist/request-model-override.d.ts.map +1 -1
  263. package/dist/request-model-override.js +105 -143
  264. package/dist/request-model-override.js.map +1 -1
  265. package/dist/request-scoped-mcp.d.ts +3 -0
  266. package/dist/request-scoped-mcp.d.ts.map +1 -1
  267. package/dist/request-scoped-mcp.js +1 -1
  268. package/dist/request-scoped-mcp.js.map +1 -1
  269. package/dist/run-history.d.ts.map +1 -1
  270. package/dist/run-history.js +56 -13
  271. package/dist/run-history.js.map +1 -1
  272. package/dist/runtime-option-extensions.d.ts +2 -4
  273. package/dist/runtime-option-extensions.d.ts.map +1 -1
  274. package/dist/runtime-option-extensions.js +4 -8
  275. package/dist/runtime-option-extensions.js.map +1 -1
  276. package/dist/runtime-routes.d.ts +5 -5
  277. package/dist/runtime-routes.d.ts.map +1 -1
  278. package/dist/runtime-routes.js +29 -18
  279. package/dist/runtime-routes.js.map +1 -1
  280. package/dist/sandbox-settings-cleanup.d.ts +15 -0
  281. package/dist/sandbox-settings-cleanup.d.ts.map +1 -0
  282. package/dist/sandbox-settings-cleanup.js +88 -0
  283. package/dist/sandbox-settings-cleanup.js.map +1 -0
  284. package/dist/seen-conversations.d.ts +4 -3
  285. package/dist/seen-conversations.d.ts.map +1 -1
  286. package/dist/seen-conversations.js +6 -5
  287. package/dist/seen-conversations.js.map +1 -1
  288. package/dist/session-history.d.ts +14 -0
  289. package/dist/session-history.d.ts.map +1 -1
  290. package/dist/session-history.js +120 -5
  291. package/dist/session-history.js.map +1 -1
  292. package/dist/systemd-command.d.ts +8 -0
  293. package/dist/systemd-command.d.ts.map +1 -0
  294. package/dist/systemd-command.js +206 -0
  295. package/dist/systemd-command.js.map +1 -0
  296. package/dist/systemd.d.ts +51 -0
  297. package/dist/systemd.d.ts.map +1 -0
  298. package/dist/systemd.js +299 -0
  299. package/dist/systemd.js.map +1 -0
  300. package/dist/tool-output-artifacts.d.ts +4 -0
  301. package/dist/tool-output-artifacts.d.ts.map +1 -0
  302. package/dist/tool-output-artifacts.js +17 -0
  303. package/dist/tool-output-artifacts.js.map +1 -0
  304. package/dist/trigger-overrides.d.ts +6 -0
  305. package/dist/trigger-overrides.d.ts.map +1 -1
  306. package/dist/trigger-overrides.js +36 -4
  307. package/dist/trigger-overrides.js.map +1 -1
  308. package/dist/tui-command.d.ts +0 -45
  309. package/dist/tui-command.d.ts.map +1 -1
  310. package/dist/tui-command.js +27 -264
  311. package/dist/tui-command.js.map +1 -1
  312. package/dist/untrusted-text.d.ts +36 -0
  313. package/dist/untrusted-text.d.ts.map +1 -0
  314. package/dist/untrusted-text.js +150 -0
  315. package/dist/untrusted-text.js.map +1 -0
  316. package/dist/web-command.d.ts +3 -0
  317. package/dist/web-command.d.ts.map +1 -1
  318. package/dist/web-command.js +112 -7
  319. package/dist/web-command.js.map +1 -1
  320. package/dist/web-request-coordinator.d.ts +19 -0
  321. package/dist/web-request-coordinator.d.ts.map +1 -0
  322. package/dist/web-request-coordinator.js +242 -0
  323. package/dist/web-request-coordinator.js.map +1 -0
  324. package/dist/wizard/answers.d.ts +3 -9
  325. package/dist/wizard/answers.d.ts.map +1 -1
  326. package/dist/wizard/answers.js +11 -36
  327. package/dist/wizard/answers.js.map +1 -1
  328. package/dist/wizard/from-flags.d.ts +1 -2
  329. package/dist/wizard/from-flags.d.ts.map +1 -1
  330. package/dist/wizard/from-flags.js +8 -3
  331. package/dist/wizard/from-flags.js.map +1 -1
  332. package/dist/wizard/model-discovery.d.ts +7 -8
  333. package/dist/wizard/model-discovery.d.ts.map +1 -1
  334. package/dist/wizard/model-discovery.js +58 -431
  335. package/dist/wizard/model-discovery.js.map +1 -1
  336. package/dist/wizard/presets.js +2 -2
  337. package/dist/wizard/presets.js.map +1 -1
  338. package/dist/wizard/prompts.d.ts +13 -12
  339. package/dist/wizard/prompts.d.ts.map +1 -1
  340. package/dist/wizard/prompts.js +25 -45
  341. package/dist/wizard/prompts.js.map +1 -1
  342. package/dist/wizard/run.d.ts.map +1 -1
  343. package/dist/wizard/run.js +30 -153
  344. package/dist/wizard/run.js.map +1 -1
  345. package/package.json +18 -18
  346. package/schema/mono-agent.config.schema.json +301 -53
  347. package/skills/mono-agent-composer/SKILL.md +5 -5
  348. package/skills/mono-agent-composer/references/config-blueprint.md +61 -47
  349. package/skills/mono-agent-composer/references/discovery-questions.md +18 -18
  350. package/skills/mono-agent-composer/references/feature-coverage.md +39 -21
  351. package/skills/mono-agent-composer/references/package-map.md +26 -17
  352. package/skills/mono-agent-composer/references/playbooks.md +39 -28
  353. package/skills/mono-agent-composer/references/validation.md +4 -3
  354. package/dist/codex-model-catalog.d.ts +0 -15
  355. package/dist/codex-model-catalog.d.ts.map +0 -1
  356. package/dist/codex-model-catalog.js +0 -220
  357. package/dist/codex-model-catalog.js.map +0 -1
  358. package/dist/configuration-proposal-main.d.ts +0 -3
  359. package/dist/configuration-proposal-main.d.ts.map +0 -1
  360. package/dist/configuration-proposal-main.js +0 -13
  361. package/dist/configuration-proposal-main.js.map +0 -1
  362. package/dist/configuration-proposal-tool.d.ts +0 -33
  363. package/dist/configuration-proposal-tool.d.ts.map +0 -1
  364. package/dist/configuration-proposal-tool.js +0 -188
  365. package/dist/configuration-proposal-tool.js.map +0 -1
  366. package/dist/local-configuration.d.ts +0 -99
  367. package/dist/local-configuration.d.ts.map +0 -1
  368. package/dist/local-configuration.js +0 -1330
  369. package/dist/local-configuration.js.map +0 -1
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Shared deterministic checks for model-authored free text that the host is
3
+ * about to display to an operator or persist durably.
4
+ *
5
+ * These are defense in depth, not a guarantee. `SECURITY.md` is explicit that
6
+ * free-form model, user, and tool text may still contain sensitive data: what
7
+ * follows catches known credential shapes and this agent's own configured
8
+ * secrets, not every conceivable secret. Callers reject rather than redact, so
9
+ * a partial match never produces a silently mangled value that still reports
10
+ * success.
11
+ */
12
+ /**
13
+ * Reject terminal and bidi control characters. Ordinary Unicode text and LF
14
+ * newlines stay intact; what goes is anything that could clear, overwrite, or
15
+ * visually reorder text an operator later reads.
16
+ */
17
+ export declare function containsUnsafeReviewControl(value: string): boolean;
18
+ /** Whether the text carries a value shaped like a well-known credential. */
19
+ export declare function containsSecretLikeValue(value: string): boolean;
20
+ /**
21
+ * The live credential values this process actually holds, taken from
22
+ * environment variables whose NAME looks credential-bearing. Matching against
23
+ * these is exact rather than heuristic: it catches the agent echoing back a
24
+ * secret it was configured with, which no shape rule can promise.
25
+ */
26
+ export declare function knownEnvironmentSecretValues(env: Record<string, string | undefined>): readonly string[];
27
+ /**
28
+ * Whether the text contains any of this agent's own configured secret values.
29
+ *
30
+ * Both sides are NFKC-folded before comparison. Callers normalize the text they
31
+ * are about to store, so comparing it against a raw environment value would
32
+ * miss a credential that is itself configured in a compatibility form (a
33
+ * fullwidth password matches only once both sides agree on a domain).
34
+ */
35
+ export declare function containsKnownSecretValue(value: string, secrets: readonly string[]): boolean;
36
+ //# sourceMappingURL=untrusted-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"untrusted-text.d.ts","sourceRoot":"","sources":["../src/untrusted-text.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA+DH;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAYlE;AA4BD,4EAA4E;AAC5E,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAK9D;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,MAAM,EAAE,CAWvG;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAS3F"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Shared deterministic checks for model-authored free text that the host is
3
+ * about to display to an operator or persist durably.
4
+ *
5
+ * These are defense in depth, not a guarantee. `SECURITY.md` is explicit that
6
+ * free-form model, user, and tool text may still contain sensitive data: what
7
+ * follows catches known credential shapes and this agent's own configured
8
+ * secrets, not every conceivable secret. Callers reject rather than redact, so
9
+ * a partial match never produces a silently mangled value that still reports
10
+ * success.
11
+ */
12
+ const BIDI_CONTROL = /\p{Bidi_Control}/u;
13
+ /**
14
+ * Well-known credential shapes that are dangerous even with no surrounding
15
+ * label: OpenAI, GitHub, and Slack tokens, bearer headers, and Telegram bot
16
+ * tokens. Each requires a credential-specific alphabet and length, so prose
17
+ * that merely mentions `sk-` does not match.
18
+ */
19
+ const SECRET_LIKE_VALUE = new RegExp([
20
+ // OpenAI, including project/service-account forms.
21
+ String.raw `sk-[A-Za-z0-9_-]{12,}`,
22
+ // GitHub classic/OAuth/refresh/server/user tokens, plus fine-grained PATs.
23
+ String.raw `gh[pousr]_[A-Za-z0-9]{20,}`,
24
+ String.raw `github_pat_[A-Za-z0-9_]{20,}`,
25
+ // Slack bot/user/app-level tokens.
26
+ String.raw `xox[baprs]-[A-Za-z0-9-]{12,}`,
27
+ String.raw `xapp-[A-Za-z0-9-]{12,}`,
28
+ // AWS access key ids, long-term (AKIA) and temporary STS (ASIA).
29
+ String.raw `A(?:KIA|SIA)[A-Z0-9]{16}`,
30
+ // Telegram bot tokens.
31
+ String.raw `\d{6,12}:[A-Za-z0-9_-]{20,}`,
32
+ ].map((shape) => String.raw `\b${shape}\b`).join("|")
33
+ // Bearer carries its own delimiter, so it is matched separately from the
34
+ // word-bounded shapes above. The payload must look like a token: `\S{12,}`
35
+ // also matched ordinary prose such as "Bearer authentication". Basic is
36
+ // handled by decoding rather than by length — see containsBasicCredential.
37
+ + String.raw `|\bBearer\s+[A-Za-z0-9+/._~-]{16,}={0,2}`,
38
+ // Case-insensitive: a lowercase `bearer ` or `akia…` is the same credential.
39
+ "iu");
40
+ /** Environment variable names whose values are treated as live credentials. */
41
+ const CREDENTIAL_ENV_NAME = /(?:api.?key|credential|password|secret|token)/iu;
42
+ /**
43
+ * Names whose value is provably a variable name or a filesystem location rather
44
+ * than a credential, mirroring the `env`/`path` carve-out that
45
+ * `secretBearingPointer` already applies to config pointers.
46
+ *
47
+ * Deliberately narrow. An earlier revision also excluded `_TOKENS`, `_NAME`,
48
+ * and `_URL`, which dropped genuine credential holders such as
49
+ * `SERVICE_API_TOKENS` and `SLACK_APP_TOKENS` from the scan — and because this
50
+ * helper is shared by security-sensitive persistence guards, so that weakened multiple surfaces
51
+ * at once. The residual cost is accepted and documented: a credential-named
52
+ * budget such as `..._KEEP_RECENT_TOKENS=8000` still makes the literal `8000`
53
+ * unstorable through `Remember`. Favouring a false rejection over a persisted
54
+ * credential is the intended trade here.
55
+ */
56
+ const NON_CREDENTIAL_ENV_NAME = /(?:_ENV|_ENV_VAR|_PATH|_FILE|_DIR)$/iu;
57
+ /**
58
+ * Shortest environment value worth matching.
59
+ *
60
+ * Deliberately low: a short PIN or numeric key is still a credential, and this
61
+ * guard is shared by other persistence checks, so raising it to reduce
62
+ * false positives would quietly widen what both surfaces let through. The
63
+ * name-based exclusion above is the targeted fix for operational settings.
64
+ */
65
+ const MIN_KNOWN_SECRET_LENGTH = 4;
66
+ /**
67
+ * Reject terminal and bidi control characters. Ordinary Unicode text and LF
68
+ * newlines stay intact; what goes is anything that could clear, overwrite, or
69
+ * visually reorder text an operator later reads.
70
+ */
71
+ export function containsUnsafeReviewControl(value) {
72
+ for (const character of value) {
73
+ const codePoint = character.codePointAt(0);
74
+ if ((codePoint <= 0x1f && codePoint !== 0x0a)
75
+ || (codePoint >= 0x7f && codePoint <= 0x9f)
76
+ || BIDI_CONTROL.test(character)) {
77
+ return true;
78
+ }
79
+ }
80
+ return false;
81
+ }
82
+ /**
83
+ * HTTP Basic payloads are base64 of `user:password`, which can be as short as
84
+ * four characters and can contain non-UTF-8 legacy bytes. Decode the candidate
85
+ * instead: a real pair contains a colon and no control bytes, while prose that
86
+ * merely names the scheme ("Basic authentication") does not.
87
+ */
88
+ const BASIC_SCHEME = /\bBasic\s+([A-Za-z0-9+/]{2,}={0,2})(?![A-Za-z0-9+/=])/giu;
89
+ function containsBasicCredential(value) {
90
+ for (const match of value.matchAll(BASIC_SCHEME)) {
91
+ const payload = match[1];
92
+ if (payload === undefined)
93
+ continue;
94
+ const unpaddedPayload = payload.replace(/=+$/u, "");
95
+ if (unpaddedPayload.length % 4 === 1)
96
+ continue;
97
+ const bytes = Buffer.from(payload, "base64");
98
+ // Buffer's base64 decoder is intentionally permissive. Require a canonical
99
+ // round trip so malformed prose is never reinterpreted as a credential.
100
+ if (bytes.toString("base64").replace(/=+$/u, "") !== unpaddedPayload)
101
+ continue;
102
+ if (bytes.includes(0x3a)
103
+ && !bytes.some((byte) => byte <= 0x1f || byte === 0x7f))
104
+ return true;
105
+ }
106
+ return false;
107
+ }
108
+ /** Whether the text carries a value shaped like a well-known credential. */
109
+ export function containsSecretLikeValue(value) {
110
+ // Callers outside Remember also use this guard. Fold compatibility
111
+ // characters here so no caller can accidentally scan a weaker raw form.
112
+ const normalized = value.normalize("NFKC");
113
+ return SECRET_LIKE_VALUE.test(normalized) || containsBasicCredential(normalized);
114
+ }
115
+ /**
116
+ * The live credential values this process actually holds, taken from
117
+ * environment variables whose NAME looks credential-bearing. Matching against
118
+ * these is exact rather than heuristic: it catches the agent echoing back a
119
+ * secret it was configured with, which no shape rule can promise.
120
+ */
121
+ export function knownEnvironmentSecretValues(env) {
122
+ return Object.entries(env)
123
+ .filter(([name, value]) => CREDENTIAL_ENV_NAME.test(name)
124
+ && !NON_CREDENTIAL_ENV_NAME.test(name)
125
+ // Remember persists in NFKC form. Retain a value when either its raw or
126
+ // folded representation reaches the floor so compatibility ligatures
127
+ // cannot disappear from the configured-secret set before comparison.
128
+ && value !== undefined
129
+ && Math.max(value.length, value.normalize("NFKC").length) >= MIN_KNOWN_SECRET_LENGTH)
130
+ .map(([, value]) => value);
131
+ }
132
+ /**
133
+ * Whether the text contains any of this agent's own configured secret values.
134
+ *
135
+ * Both sides are NFKC-folded before comparison. Callers normalize the text they
136
+ * are about to store, so comparing it against a raw environment value would
137
+ * miss a credential that is itself configured in a compatibility form (a
138
+ * fullwidth password matches only once both sides agree on a domain).
139
+ */
140
+ export function containsKnownSecretValue(value, secrets) {
141
+ const folded = value.normalize("NFKC");
142
+ return secrets.some((secret) => {
143
+ const foldedSecret = secret.normalize("NFKC");
144
+ return value.includes(secret)
145
+ || folded.includes(foldedSecret)
146
+ || folded.includes(secret)
147
+ || value.includes(foldedSecret);
148
+ });
149
+ }
150
+ //# sourceMappingURL=untrusted-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"untrusted-text.js","sourceRoot":"","sources":["../src/untrusted-text.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,7 @@ interface StartWebServerOptions {
19
19
  readonly host?: string;
20
20
  readonly port?: number;
21
21
  readonly theme?: WebTheme;
22
+ readonly name?: string;
22
23
  readonly registryDirs?: readonly string[];
23
24
  readonly stateDir?: string;
24
25
  readonly env?: Record<string, string | undefined>;
@@ -37,6 +38,7 @@ export interface RunWebCommandOptions {
37
38
  readonly host?: string;
38
39
  readonly port?: number;
39
40
  readonly theme?: string;
41
+ readonly name?: string;
40
42
  readonly loopback?: boolean;
41
43
  readonly follow?: boolean;
42
44
  readonly lines?: number;
@@ -87,6 +89,7 @@ export interface RunWebCommandDeps {
87
89
  stop(): void;
88
90
  };
89
91
  readonly homeDir?: string;
92
+ readonly systemd?: import("./systemd.js").SystemdDeps;
90
93
  }
91
94
  export interface TailscaleServeOwnership {
92
95
  readonly schema: typeof TAILSCALE_OWNERSHIP_SCHEMA;
@@ -1 +1 @@
1
- {"version":3,"file":"web-command.d.ts","sourceRoot":"","sources":["../src/web-command.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AA4BhD,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EAGZ,yBAAyB,EAC1B,MAAM,cAAc,CAAC;AAetB,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,uBAAuB,CAAC;AAE9E,OAAO,EAAE,yCAAyC,EAAE,MAAM,wCAAwC,CAAC;AAEnG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AASlE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,eAAO,MAAM,gBAAgB,YAAY,CAAC;AAC1C,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAGrC,eAAO,MAAM,sBAAsB,kCAAkC,CAAC;AAGtE,QAAA,MAAM,0BAA0B,sCAAsC,CAAC;AAWvE,UAAU,eAAe;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,UAAU,qBAAqB;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC;IAC1B,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CACnD;AAED,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CACnD;AAED,UAAU,sBAAsB;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACjD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;AAEhF,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAChD,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAChD,QAAQ,CAAC,SAAS,CAAC,EAAE,eAAe,CAAC;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;IACnC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IACpF,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAC5C,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE;QACtC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;QAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;KAC3B,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACpC,QAAQ,CAAC,2BAA2B,CAAC,EAAE,OAAO,yCAAyC,CAAC;IACxF,QAAQ,CAAC,yBAAyB,CAAC,EAAE,CACnC,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,MAAM,KACR,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAChG,QAAQ,CAAC,wBAAwB,CAAC,EAAE,MAAM,SAAS,MAAM,EAAE,CAAC;IAC5D,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAChC,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,GAAG,YAAY,GAAG,YAAY,CAAC,EACjE,YAAY,EAAE,gCAAgC,KAC3C;QAAE,IAAI,IAAI,IAAI,CAAA;KAAE,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAsCD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,MAAM,EAAE,OAAO,0BAA0B,CAAC;IACnD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,0EAA0E;IAC1E,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,KAAK,oBAAoB,GACrB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,uBAAuB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAClG;IACE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,4FAA4F;IAC5F,QAAQ,CAAC,uBAAuB,CAAC,EAAE,IAAI,CAAC;CACzC,CAAC;AAaN,MAAM,MAAM,QAAQ,GAAG,eAAe,CAAC;AAEvC,wBAAgB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,QAAQ,CAEnD;AAED,wBAAgB,aAAa,IAAI,MAAM,CAiBtC;AAED,kFAAkF;AAClF,wBAAsB,aAAa,CACjC,OAAO,EAAE,oBAAoB,EAC7B,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,MAAM,CAAC,CAsCjB;AAqoCD,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAElE;AA0BD,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,QAAQ,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EACvC,IAAI,EAAE,iBAAiB,EACvB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,oBAAoB,CAAC,CAyH/B;AA6CD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAc1F;AAyCD,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,QAAQ,EACf,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAuB9G;AAyDD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS,CAM5F"}
1
+ {"version":3,"file":"web-command.d.ts","sourceRoot":"","sources":["../src/web-command.ts"],"names":[],"mappings":"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"}
@@ -37,6 +37,9 @@ const TAILSCALE_STATUS_RETRY_MS = 200;
37
37
  const WEB_PACKAGE_NAME = "@mono-agent/web";
38
38
  const WEB_THEMES = ["evergreen", "ocean", "plum", "terracotta"];
39
39
  const DEFAULT_WEB_THEME = "evergreen";
40
+ // Mirrors WEB_CONSOLE_NAME_MAX_CHARACTERS in @mono-agent/web; declared locally so this
41
+ // command keeps its type-only dependency on the lazily loaded web package.
42
+ const WEB_CONSOLE_NAME_MAX_CHARACTERS = 80;
40
43
  export function webPaths(homeDir) {
41
44
  return managedWebPaths(homeDir);
42
45
  }
@@ -45,16 +48,17 @@ export function renderWebHelp() {
45
48
  "mono-agent web — always-on multi-agent web console",
46
49
  "",
47
50
  " mono-agent web",
48
- " mono-agent web start [--host <addr> | --loopback] [--port <n>] [--theme <name>]",
49
- " mono-agent web restart [--host <addr> | --loopback] [--port <n>] [--theme <name>]",
51
+ " mono-agent web start [--host <addr> | --loopback] [--port <n>] [--theme <name>] [--name <label>]",
52
+ " mono-agent web restart [--host <addr> | --loopback] [--port <n>] [--theme <name>] [--name <label>]",
50
53
  " mono-agent web stop | status",
51
54
  " mono-agent web logs [--follow|-f] [--lines <n>]",
52
- " mono-agent web run [--host <addr> | --loopback] [--port <n>] [--theme <name>]",
55
+ " mono-agent web run [--host <addr> | --loopback] [--port <n>] [--theme <name>] [--name <label>]",
53
56
  " mono-agent web reset --all --yes",
54
57
  "",
55
58
  `Default bind: ${DEFAULT_WEB_HOST}:${String(DEFAULT_WEB_PORT)} (LAN/Tailnet reachable; no app login).`,
56
59
  `Themes: ${WEB_THEMES.join(", ")} (default: ${DEFAULT_WEB_THEME}).`,
57
- "--loopback narrows the bind to 127.0.0.1. start/restart claim a free Tailscale Serve HTTPS port without replacing existing handlers.",
60
+ "--name sets the installed PWA label, browser tab title, and rail brand; --name - restores the hostname default.",
61
+ "--loopback narrows the bind to 127.0.0.1. macOS start/restart claim a free Tailscale Serve HTTPS port; Linux HTTPS routes are externally managed.",
58
62
  "",
59
63
  ].join("\n");
60
64
  }
@@ -74,6 +78,40 @@ export async function runWebCommand(options, deps = {}) {
74
78
  stdout.write(renderWebHelp());
75
79
  return 2;
76
80
  }
81
+ if ((deps.platform ?? process.platform) === "linux" && action !== "run" && action !== "reset") {
82
+ if (action === undefined)
83
+ stdout.write(renderWebHelp());
84
+ const { runSystemdWebCommand } = await import("./systemd-command.js");
85
+ const { isSystemdUserManagerUnavailable } = await import("./systemd.js");
86
+ try {
87
+ return await runSystemdWebCommand(options, {
88
+ ...deps.systemd,
89
+ ...(deps.homeDir === undefined ? {} : { homeDir: deps.homeDir }),
90
+ stdout, stderr,
91
+ });
92
+ }
93
+ catch (error) {
94
+ if (!isSystemdUserManagerUnavailable(error) || (action !== undefined && action !== "status"))
95
+ throw error;
96
+ if (action === undefined) {
97
+ await statusWeb(options, deps, false);
98
+ return 0;
99
+ }
100
+ return await statusWeb(options, deps, true);
101
+ }
102
+ }
103
+ if ((deps.platform ?? process.platform) === "linux" && action === "reset") {
104
+ const { withSystemdLock, SYSTEMD_WEB_IDENTITY } = await import("./systemd.js");
105
+ try {
106
+ return await withSystemdLock(SYSTEMD_WEB_IDENTITY, {
107
+ ...deps.systemd, ...(deps.homeDir === undefined ? {} : { homeDir: deps.homeDir }),
108
+ }, () => resetWeb(options, deps));
109
+ }
110
+ catch (error) {
111
+ stderr.write(ui.errorLine(`Linux web reset failed: ${errorMessage(error)}`));
112
+ return 1;
113
+ }
114
+ }
77
115
  if (action === undefined) {
78
116
  stdout.write(renderWebHelp());
79
117
  await statusWeb(options, deps, false);
@@ -108,9 +146,15 @@ function validateWebFlags(action, options) {
108
146
  if (options.theme !== undefined && !isWebTheme(options.theme)) {
109
147
  return `--theme must be one of: ${WEB_THEMES.join(", ")}.`;
110
148
  }
111
- if ((options.host !== undefined || options.port !== undefined || options.theme !== undefined || options.loopback === true)
149
+ if (options.name !== undefined) {
150
+ const nameError = invalidWebConsoleName(options.name);
151
+ if (nameError !== undefined)
152
+ return nameError;
153
+ }
154
+ if ((options.host !== undefined || options.port !== undefined || options.theme !== undefined
155
+ || options.name !== undefined || options.loopback === true)
112
156
  && action !== "start" && action !== "restart" && action !== "run") {
113
- return "--host, --port, --theme, and --loopback are only supported for web start, restart, or run.";
157
+ return "--host, --port, --theme, --name, and --loopback are only supported for web start, restart, or run.";
114
158
  }
115
159
  if ((options.follow === true || options.lines !== undefined) && action !== "logs") {
116
160
  return "--follow and --lines are only supported for mono-agent web logs.";
@@ -129,6 +173,7 @@ async function runWebForeground(options, deps) {
129
173
  const host = effectiveHost(options);
130
174
  const port = options.port ?? DEFAULT_WEB_PORT;
131
175
  const theme = selectedWebTheme(options.theme);
176
+ const consoleName = selectedWebConsoleName(options.name);
132
177
  const paths = webPaths(deps.homeDir);
133
178
  await (deps.prepareState ?? defaultPrepareWebState)({ stateDir: paths.stateDir, env: options.env });
134
179
  const registryDir = resolveGlobalTraceRegistryDir(options.env);
@@ -136,7 +181,15 @@ async function runWebForeground(options, deps) {
136
181
  let handle;
137
182
  try {
138
183
  const startServer = deps.startServer ?? defaultStartWebServer;
139
- handle = await startServer({ host, port, theme, registryDirs: [registryDir], stateDir: paths.stateDir, env: options.env });
184
+ handle = await startServer({
185
+ host,
186
+ port,
187
+ theme,
188
+ ...(consoleName === undefined ? {} : { name: consoleName }),
189
+ registryDirs: [registryDir],
190
+ stateDir: paths.stateDir,
191
+ env: options.env,
192
+ });
140
193
  }
141
194
  catch (error) {
142
195
  stderr.write(ui.errorLine(`mono-agent web failed to start: ${errorMessage(error)}`));
@@ -242,6 +295,10 @@ async function startWebBackground(options, deps, restart) {
242
295
  stderr.write(ui.errorLine(`mono-agent web is already managed by launchd; use \`mono-agent web restart --theme ${options.theme}\` to change its theme.`));
243
296
  return 1;
244
297
  }
298
+ if (options.name !== undefined) {
299
+ stderr.write(ui.errorLine(`mono-agent web is already managed by launchd; use \`mono-agent web restart --name ${shellQuote(options.name)}\` to change its name.`));
300
+ return 1;
301
+ }
245
302
  if (helper.loaded) {
246
303
  try {
247
304
  const loadedHelper = await (deps.inspectMaintenanceService ?? launchdWebMaintenanceInfo)(launchctl, uid);
@@ -394,6 +451,7 @@ async function startWebBackground(options, deps, restart) {
394
451
  const host = effectiveHost(options, priorRecord?.host);
395
452
  const port = options.port ?? priorRecord?.port ?? DEFAULT_WEB_PORT;
396
453
  const theme = selectedWebTheme(options.theme, priorRecord?.theme);
454
+ const consoleName = selectedWebConsoleName(options.name, priorRecord?.name);
397
455
  if (existingPlist !== undefined) {
398
456
  try {
399
457
  pendingMaintenanceIntent = await maintainStoppedWebLogsBeforePublication(paths, pendingMaintenanceIntent, deps.now ?? Date.now);
@@ -430,6 +488,7 @@ async function startWebBackground(options, deps, restart) {
430
488
  host,
431
489
  port,
432
490
  theme,
491
+ ...(consoleName === undefined ? {} : { name: consoleName }),
433
492
  updatedAt: new Date((deps.now ?? Date.now)()).toISOString(),
434
493
  };
435
494
  const plist = buildWebPlistXml({
@@ -440,6 +499,7 @@ async function startWebBackground(options, deps, restart) {
440
499
  host,
441
500
  port,
442
501
  theme,
502
+ ...(consoleName === undefined ? {} : { name: consoleName }),
443
503
  stdoutPath: paths.launchd.stdoutPath,
444
504
  stderrPath: paths.launchd.stderrPath,
445
505
  environment,
@@ -613,6 +673,7 @@ async function statusWeb(options, deps, strictExit) {
613
673
  const host = record?.host ?? DEFAULT_WEB_HOST;
614
674
  const port = record?.port ?? DEFAULT_WEB_PORT;
615
675
  const theme = record?.theme ?? DEFAULT_WEB_THEME;
676
+ const consoleName = record?.name;
616
677
  let service = { loaded: false };
617
678
  let helper = { loaded: false };
618
679
  if ((deps.platform ?? process.platform) === "darwin") {
@@ -719,6 +780,9 @@ async function statusWeb(options, deps, strictExit) {
719
780
  : "stopped"],
720
781
  ["bind", recordRead.kind === "invalid" ? "invalid service record" : `${host}:${String(port)}`],
721
782
  ["theme", recordRead.kind === "invalid" ? "invalid service record" : theme],
783
+ ["name", recordRead.kind === "invalid"
784
+ ? "invalid service record"
785
+ : consoleName ?? "— (machine hostname)"],
722
786
  ["state", paths.stateDir],
723
787
  ["pid", service.pid === undefined ? "—" : String(service.pid)],
724
788
  ["log maintenance", maintenanceSummary],
@@ -773,6 +837,16 @@ async function resetWeb(options, deps) {
773
837
  const stderr = deps.stderr ?? process.stderr;
774
838
  const stdout = deps.stdout ?? process.stdout;
775
839
  const paths = webPaths(deps.homeDir);
840
+ if ((deps.platform ?? process.platform) === "linux") {
841
+ const { inspectSystemd, readSystemdDefinition, SYSTEMD_WEB_IDENTITY } = await import("./systemd.js");
842
+ const systemdDeps = { ...deps.systemd, ...(deps.homeDir === undefined ? {} : { homeDir: deps.homeDir }) };
843
+ const service = await inspectSystemd(SYSTEMD_WEB_IDENTITY, systemdDeps).catch(() => undefined);
844
+ const definition = await readSystemdDefinition(SYSTEMD_WEB_IDENTITY, systemdDeps);
845
+ if (definition !== undefined || (service?.pid ?? 0) > 0 || service?.activeState === "activating") {
846
+ stderr.write(ui.errorLine("Run mono-agent web stop before resetting the systemd console."));
847
+ return 1;
848
+ }
849
+ }
776
850
  if ((deps.platform ?? process.platform) === "darwin") {
777
851
  const launchctl = deps.launchctl ?? makeLaunchctlRunner();
778
852
  const uid = (deps.getuid ?? requiredUid)();
@@ -843,6 +917,35 @@ function selectedWebTheme(value, priorTheme) {
843
917
  return priorTheme ?? DEFAULT_WEB_THEME;
844
918
  return value;
845
919
  }
920
+ /**
921
+ * Console label precedence: this invocation's flag, then the persisted record, then
922
+ * undefined so the worker falls back to the machine hostname. A single hyphen resets
923
+ * the persisted choice to that fallback.
924
+ */
925
+ function selectedWebConsoleName(value, priorName) {
926
+ if (value === undefined)
927
+ return priorName;
928
+ const name = value.trim();
929
+ return name === "-" ? undefined : name;
930
+ }
931
+ /** Reject labels the manifest, launchd argv, or launcher cannot carry faithfully. */
932
+ function invalidWebConsoleName(value) {
933
+ const name = value.trim();
934
+ if (name.length === 0)
935
+ return "--name must not be empty.";
936
+ if (/[\u0000-\u001f\u007f-\u009f\u2028-\u202e]/u.test(name)) {
937
+ return "--name must not contain control characters, line separators, or bidirectional overrides.";
938
+ }
939
+ if ([...name].length > WEB_CONSOLE_NAME_MAX_CHARACTERS) {
940
+ return `--name must be at most ${String(WEB_CONSOLE_NAME_MAX_CHARACTERS)} characters.`;
941
+ }
942
+ return undefined;
943
+ }
944
+ function shellQuote(value) {
945
+ if (/^[A-Za-z0-9_./:@%+=,-]+$/u.test(value))
946
+ return value;
947
+ return `'${value.replaceAll("'", `'"'"'`)}'`;
948
+ }
846
949
  async function ensureWebDirectories(paths) {
847
950
  for (const path of [
848
951
  dirname(paths.stateDir),
@@ -1556,6 +1659,8 @@ async function readServiceRecord(path) {
1556
1659
  if (!isRecord(value) || value.schema !== WEB_SERVICE_SCHEMA || typeof value.host !== "string"
1557
1660
  || !Number.isSafeInteger(value.port) || value.port < 1 || value.port > 65_535
1558
1661
  || (value.theme !== undefined && !isWebTheme(value.theme))
1662
+ || (value.name !== undefined
1663
+ && (typeof value.name !== "string" || invalidWebConsoleName(value.name) !== undefined))
1559
1664
  || typeof value.updatedAt !== "string") {
1560
1665
  return { kind: "invalid", detail: "the web service record has an invalid schema; repair or remove ~/.mono-agent/web/service.json" };
1561
1666
  }