@poolzin/pool-bot 2026.2.0 → 2026.2.2

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 (258) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/README-header.png +0 -0
  3. package/dist/agents/bash-tools.exec.js +76 -25
  4. package/dist/agents/cli-runner/helpers.js +9 -11
  5. package/dist/agents/context.js +1 -1
  6. package/dist/agents/identity.js +47 -7
  7. package/dist/agents/memory-search.js +25 -8
  8. package/dist/agents/model-catalog.js +1 -1
  9. package/dist/agents/model-selection.js +21 -0
  10. package/dist/agents/pi-embedded-block-chunker.js +117 -42
  11. package/dist/agents/pi-embedded-helpers/errors.js +183 -78
  12. package/dist/agents/pi-embedded-helpers.js +1 -1
  13. package/dist/agents/pi-embedded-runner/compact.js +8 -10
  14. package/dist/agents/pi-embedded-runner/model.js +62 -3
  15. package/dist/agents/pi-embedded-runner/run/attempt.js +21 -11
  16. package/dist/agents/pi-embedded-runner/run.js +199 -46
  17. package/dist/agents/pi-embedded-runner/system-prompt.js +10 -2
  18. package/dist/agents/pi-embedded-subscribe.js +118 -29
  19. package/dist/agents/pi-tools.js +10 -5
  20. package/dist/agents/poolbot-tools.js +15 -10
  21. package/dist/agents/sandbox-paths.js +31 -0
  22. package/dist/agents/session-tool-result-guard.js +94 -15
  23. package/dist/agents/shell-utils.js +51 -0
  24. package/dist/agents/skills/bundled-context.js +23 -0
  25. package/dist/agents/skills/bundled-dir.js +41 -7
  26. package/dist/agents/skills-install.js +60 -23
  27. package/dist/agents/subagent-announce.js +79 -34
  28. package/dist/agents/tool-policy.conformance.js +14 -0
  29. package/dist/agents/tool-policy.js +24 -0
  30. package/dist/agents/tools/cron-tool.js +166 -19
  31. package/dist/agents/tools/discord-actions-presence.js +78 -0
  32. package/dist/agents/tools/image-tool.js +1 -1
  33. package/dist/agents/tools/message-tool.js +56 -2
  34. package/dist/agents/tools/sessions-history-tool.js +69 -1
  35. package/dist/agents/tools/web-search.js +211 -42
  36. package/dist/agents/usage.js +23 -1
  37. package/dist/agents/workspace-run.js +67 -0
  38. package/dist/agents/workspace-templates.js +44 -0
  39. package/dist/auto-reply/command-auth.js +121 -6
  40. package/dist/auto-reply/envelope.js +74 -82
  41. package/dist/auto-reply/reply/commands-compact.js +1 -0
  42. package/dist/auto-reply/reply/commands-context-report.js +1 -0
  43. package/dist/auto-reply/reply/commands-context.js +1 -0
  44. package/dist/auto-reply/reply/commands-models.js +107 -60
  45. package/dist/auto-reply/reply/commands-ptt.js +171 -0
  46. package/dist/auto-reply/reply/get-reply-run.js +2 -1
  47. package/dist/auto-reply/reply/inbound-context.js +5 -1
  48. package/dist/auto-reply/reply/mentions.js +1 -1
  49. package/dist/auto-reply/reply/model-selection.js +3 -3
  50. package/dist/auto-reply/thinking.js +88 -43
  51. package/dist/browser/bridge-server.js +13 -0
  52. package/dist/browser/cdp.helpers.js +38 -24
  53. package/dist/browser/client-fetch.js +50 -7
  54. package/dist/browser/config.js +1 -10
  55. package/dist/browser/extension-relay.js +101 -40
  56. package/dist/browser/pw-ai.js +1 -1
  57. package/dist/browser/pw-session.js +143 -8
  58. package/dist/browser/pw-tools-core.interactions.js +125 -27
  59. package/dist/browser/pw-tools-core.responses.js +1 -1
  60. package/dist/browser/pw-tools-core.state.js +1 -1
  61. package/dist/browser/routes/agent.act.js +86 -41
  62. package/dist/browser/routes/dispatcher.js +4 -4
  63. package/dist/browser/screenshot.js +1 -1
  64. package/dist/browser/server.js +13 -0
  65. package/dist/build-info.json +3 -3
  66. package/dist/canvas-host/a2ui/index.html +28 -28
  67. package/dist/channels/reply-prefix.js +8 -1
  68. package/dist/cli/cron-cli/register.cron-add.js +61 -40
  69. package/dist/cli/cron-cli/register.cron-edit.js +60 -34
  70. package/dist/cli/cron-cli/shared.js +56 -41
  71. package/dist/cli/dns-cli.js +26 -14
  72. package/dist/cli/gateway-cli/register.js +37 -19
  73. package/dist/cli/memory-cli.js +5 -5
  74. package/dist/cli/parse-bytes.js +37 -0
  75. package/dist/cli/update-cli.js +173 -52
  76. package/dist/commands/agent.js +1 -0
  77. package/dist/commands/auth-choice.apply.oauth.js +1 -1
  78. package/dist/commands/doctor-config-flow.js +61 -5
  79. package/dist/commands/doctor-state-migrations.js +1 -1
  80. package/dist/commands/health.js +1 -1
  81. package/dist/commands/model-allowlist.js +29 -0
  82. package/dist/commands/model-picker.js +2 -1
  83. package/dist/commands/models/list.registry.js +1 -1
  84. package/dist/commands/models/list.status-command.js +43 -23
  85. package/dist/commands/models/shared.js +15 -0
  86. package/dist/commands/onboard-custom.js +384 -0
  87. package/dist/commands/onboard-non-interactive/local/auth-choice-inference.js +35 -0
  88. package/dist/commands/onboard-non-interactive/local/auth-choice.js +6 -3
  89. package/dist/commands/onboard-skills.js +63 -38
  90. package/dist/commands/openai-model-default.js +41 -0
  91. package/dist/compat/legacy-names.js +2 -0
  92. package/dist/config/defaults.js +3 -2
  93. package/dist/config/paths.js +136 -35
  94. package/dist/config/plugin-auto-enable.js +21 -5
  95. package/dist/config/redact-snapshot.js +153 -0
  96. package/dist/config/schema.field-metadata.js +590 -0
  97. package/dist/config/schema.js +2 -2
  98. package/dist/config/sessions/store.js +291 -23
  99. package/dist/config/zod-schema.agent-defaults.js +3 -0
  100. package/dist/config/zod-schema.agent-runtime.js +13 -2
  101. package/dist/config/zod-schema.providers-core.js +142 -0
  102. package/dist/config/zod-schema.session.js +3 -0
  103. package/dist/control-ui/assets/{index-CIRDm-Lu.css → index-CSfXd2LO.css} +1 -1
  104. package/dist/control-ui/assets/{index-CmNMuoem.js → index-HRr1grwl.js} +446 -413
  105. package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -0
  106. package/dist/control-ui/index.html +4 -4
  107. package/dist/cron/delivery.js +57 -0
  108. package/dist/cron/isolated-agent/delivery-target.js +18 -3
  109. package/dist/cron/isolated-agent/helpers.js +22 -5
  110. package/dist/cron/isolated-agent/run.js +172 -63
  111. package/dist/cron/isolated-agent/session.js +2 -0
  112. package/dist/cron/normalize.js +356 -28
  113. package/dist/cron/parse.js +10 -5
  114. package/dist/cron/run-log.js +35 -10
  115. package/dist/cron/schedule.js +41 -6
  116. package/dist/cron/service/jobs.js +208 -35
  117. package/dist/cron/service/ops.js +72 -16
  118. package/dist/cron/service/state.js +2 -0
  119. package/dist/cron/service/store.js +386 -14
  120. package/dist/cron/service/timer.js +390 -147
  121. package/dist/cron/session-reaper.js +86 -0
  122. package/dist/cron/store.js +23 -8
  123. package/dist/cron/validate-timestamp.js +43 -0
  124. package/dist/discord/monitor/agent-components.js +438 -0
  125. package/dist/discord/monitor/allow-list.js +28 -5
  126. package/dist/discord/monitor/gateway-registry.js +29 -0
  127. package/dist/discord/monitor/native-command.js +44 -23
  128. package/dist/discord/monitor/sender-identity.js +45 -0
  129. package/dist/discord/pluralkit.js +27 -0
  130. package/dist/discord/send.outbound.js +92 -5
  131. package/dist/discord/send.shared.js +60 -23
  132. package/dist/discord/targets.js +84 -1
  133. package/dist/entry.js +15 -9
  134. package/dist/extensionAPI.js +8 -0
  135. package/dist/gateway/control-ui.js +8 -1
  136. package/dist/gateway/hooks-mapping.js +3 -0
  137. package/dist/gateway/hooks.js +65 -0
  138. package/dist/gateway/net.js +96 -31
  139. package/dist/gateway/node-command-policy.js +50 -15
  140. package/dist/gateway/origin-check.js +56 -0
  141. package/dist/gateway/protocol/client-info.js +9 -0
  142. package/dist/gateway/protocol/index.js +9 -2
  143. package/dist/gateway/protocol/schema/agents-models-skills.js +71 -1
  144. package/dist/gateway/protocol/schema/cron.js +22 -10
  145. package/dist/gateway/protocol/schema/protocol-schemas.js +16 -2
  146. package/dist/gateway/protocol/schema/sessions.js +12 -0
  147. package/dist/gateway/server/hooks.js +1 -1
  148. package/dist/gateway/server-broadcast.js +26 -9
  149. package/dist/gateway/server-chat.js +112 -23
  150. package/dist/gateway/server-discovery-runtime.js +10 -2
  151. package/dist/gateway/server-http.js +109 -11
  152. package/dist/gateway/server-methods/agent-timestamp.js +60 -0
  153. package/dist/gateway/server-methods/agents.js +321 -2
  154. package/dist/gateway/server-methods/usage.js +559 -16
  155. package/dist/gateway/server-runtime-state.js +22 -8
  156. package/dist/gateway/server-startup-memory.js +16 -0
  157. package/dist/gateway/server.impl.js +5 -1
  158. package/dist/gateway/session-utils.fs.js +23 -25
  159. package/dist/gateway/session-utils.js +20 -10
  160. package/dist/gateway/sessions-patch.js +7 -22
  161. package/dist/gateway/test-helpers.mocks.js +11 -7
  162. package/dist/gateway/test-helpers.server.js +35 -2
  163. package/dist/imessage/constants.js +2 -0
  164. package/dist/imessage/monitor/deliver.js +4 -1
  165. package/dist/imessage/monitor/monitor-provider.js +51 -1
  166. package/dist/infra/bonjour-discovery.js +131 -70
  167. package/dist/infra/control-ui-assets.js +134 -12
  168. package/dist/infra/errors.js +12 -0
  169. package/dist/infra/exec-approvals.js +266 -57
  170. package/dist/infra/format-time/format-datetime.js +79 -0
  171. package/dist/infra/format-time/format-duration.js +81 -0
  172. package/dist/infra/format-time/format-relative.js +80 -0
  173. package/dist/infra/heartbeat-runner.js +140 -49
  174. package/dist/infra/home-dir.js +54 -0
  175. package/dist/infra/net/fetch-guard.js +122 -0
  176. package/dist/infra/net/ssrf.js +65 -29
  177. package/dist/infra/outbound/abort.js +14 -0
  178. package/dist/infra/outbound/message-action-runner.js +77 -13
  179. package/dist/infra/outbound/outbound-session.js +143 -37
  180. package/dist/infra/poolbot-root.js +43 -1
  181. package/dist/infra/session-cost-usage.js +631 -41
  182. package/dist/infra/state-migrations.js +317 -47
  183. package/dist/infra/update-global.js +35 -0
  184. package/dist/infra/update-runner.js +149 -43
  185. package/dist/infra/warning-filter.js +65 -0
  186. package/dist/infra/widearea-dns.js +30 -9
  187. package/dist/logging/redact-identifier.js +12 -0
  188. package/dist/media/fetch.js +81 -58
  189. package/dist/media/store.js +2 -0
  190. package/dist/media-understanding/apply.js +403 -3
  191. package/dist/media-understanding/attachments.js +38 -27
  192. package/dist/media-understanding/defaults.js +16 -0
  193. package/dist/media-understanding/providers/deepgram/audio.js +22 -14
  194. package/dist/media-understanding/providers/google/audio.js +24 -17
  195. package/dist/media-understanding/providers/google/video.js +24 -17
  196. package/dist/media-understanding/providers/image.js +3 -3
  197. package/dist/media-understanding/providers/index.js +4 -1
  198. package/dist/media-understanding/providers/openai/audio.js +22 -14
  199. package/dist/media-understanding/providers/shared.js +16 -11
  200. package/dist/media-understanding/providers/zai/index.js +6 -0
  201. package/dist/media-understanding/runner.js +158 -90
  202. package/dist/memory/batch-voyage.js +277 -0
  203. package/dist/memory/embeddings-voyage.js +75 -0
  204. package/dist/memory/embeddings.js +28 -16
  205. package/dist/memory/internal.js +101 -18
  206. package/dist/memory/manager.js +154 -48
  207. package/dist/memory/search-manager.js +173 -0
  208. package/dist/memory/session-files.js +9 -3
  209. package/dist/node-host/runner.js +34 -24
  210. package/dist/node-host/with-timeout.js +27 -0
  211. package/dist/plugins/commands.js +5 -1
  212. package/dist/plugins/config-state.js +86 -7
  213. package/dist/plugins/source-display.js +51 -0
  214. package/dist/process/exec.js +20 -2
  215. package/dist/routing/resolve-route.js +12 -0
  216. package/dist/routing/session-key.js +15 -0
  217. package/dist/runtime.js +2 -0
  218. package/dist/security/audit-extra.async.js +601 -0
  219. package/dist/security/audit-extra.js +2 -830
  220. package/dist/security/audit-extra.sync.js +505 -0
  221. package/dist/security/channel-metadata.js +34 -0
  222. package/dist/security/external-content.js +88 -6
  223. package/dist/security/skill-scanner.js +330 -0
  224. package/dist/sessions/session-key-utils.js +7 -0
  225. package/dist/signal/monitor/event-handler.js +80 -1
  226. package/dist/slack/monitor/media.js +85 -15
  227. package/dist/tailscale/detect.js +1 -2
  228. package/dist/telegram/bot/helpers.js +109 -28
  229. package/dist/telegram/bot-handlers.js +144 -3
  230. package/dist/telegram/bot-message-context.js +37 -10
  231. package/dist/telegram/bot-message-dispatch.js +54 -17
  232. package/dist/telegram/bot-native-commands.js +86 -29
  233. package/dist/telegram/bot.js +30 -29
  234. package/dist/telegram/model-buttons.js +163 -0
  235. package/dist/telegram/monitor.js +110 -85
  236. package/dist/telegram/send.js +129 -47
  237. package/dist/terminal/restore.js +45 -0
  238. package/dist/test-helpers/state-dir-env.js +16 -0
  239. package/dist/tts/tts.js +12 -6
  240. package/dist/tui/tui-session-actions.js +166 -54
  241. package/dist/utils/fetch-timeout.js +20 -0
  242. package/dist/utils/normalize-secret-input.js +19 -0
  243. package/dist/utils/transcript-tools.js +58 -0
  244. package/dist/utils.js +45 -14
  245. package/dist/version.js +42 -5
  246. package/dist/wizard/clack-prompter.js +9 -6
  247. package/extensions/googlechat/node_modules/.bin/poolbot +21 -0
  248. package/extensions/googlechat/package.json +2 -2
  249. package/extensions/line/node_modules/.bin/poolbot +21 -0
  250. package/extensions/line/package.json +1 -1
  251. package/extensions/matrix/node_modules/.bin/poolbot +21 -0
  252. package/extensions/matrix/package.json +1 -1
  253. package/extensions/memory-core/node_modules/.bin/poolbot +21 -0
  254. package/extensions/memory-core/package.json +4 -1
  255. package/extensions/twitch/node_modules/.bin/poolbot +21 -0
  256. package/extensions/twitch/package.json +1 -1
  257. package/package.json +183 -24
  258. package/dist/control-ui/assets/index-CmNMuoem.js.map +0 -1
@@ -25,11 +25,81 @@ export const AgentsListResultSchema = Type.Object({
25
25
  scope: Type.Union([Type.Literal("per-sender"), Type.Literal("global")]),
26
26
  agents: Type.Array(AgentSummarySchema),
27
27
  }, { additionalProperties: false });
28
+ export const AgentsCreateParamsSchema = Type.Object({
29
+ name: NonEmptyString,
30
+ workspace: NonEmptyString,
31
+ emoji: Type.Optional(Type.String()),
32
+ avatar: Type.Optional(Type.String()),
33
+ }, { additionalProperties: false });
34
+ export const AgentsCreateResultSchema = Type.Object({
35
+ ok: Type.Literal(true),
36
+ agentId: NonEmptyString,
37
+ name: NonEmptyString,
38
+ workspace: NonEmptyString,
39
+ }, { additionalProperties: false });
40
+ export const AgentsUpdateParamsSchema = Type.Object({
41
+ agentId: NonEmptyString,
42
+ name: Type.Optional(NonEmptyString),
43
+ workspace: Type.Optional(NonEmptyString),
44
+ model: Type.Optional(NonEmptyString),
45
+ avatar: Type.Optional(Type.String()),
46
+ }, { additionalProperties: false });
47
+ export const AgentsUpdateResultSchema = Type.Object({
48
+ ok: Type.Literal(true),
49
+ agentId: NonEmptyString,
50
+ }, { additionalProperties: false });
51
+ export const AgentsDeleteParamsSchema = Type.Object({
52
+ agentId: NonEmptyString,
53
+ deleteFiles: Type.Optional(Type.Boolean()),
54
+ }, { additionalProperties: false });
55
+ export const AgentsDeleteResultSchema = Type.Object({
56
+ ok: Type.Literal(true),
57
+ agentId: NonEmptyString,
58
+ removedBindings: Type.Integer({ minimum: 0 }),
59
+ }, { additionalProperties: false });
60
+ export const AgentsFileEntrySchema = Type.Object({
61
+ name: NonEmptyString,
62
+ path: NonEmptyString,
63
+ missing: Type.Boolean(),
64
+ size: Type.Optional(Type.Integer({ minimum: 0 })),
65
+ updatedAtMs: Type.Optional(Type.Integer({ minimum: 0 })),
66
+ content: Type.Optional(Type.String()),
67
+ }, { additionalProperties: false });
68
+ export const AgentsFilesListParamsSchema = Type.Object({
69
+ agentId: NonEmptyString,
70
+ }, { additionalProperties: false });
71
+ export const AgentsFilesListResultSchema = Type.Object({
72
+ agentId: NonEmptyString,
73
+ workspace: NonEmptyString,
74
+ files: Type.Array(AgentsFileEntrySchema),
75
+ }, { additionalProperties: false });
76
+ export const AgentsFilesGetParamsSchema = Type.Object({
77
+ agentId: NonEmptyString,
78
+ name: NonEmptyString,
79
+ }, { additionalProperties: false });
80
+ export const AgentsFilesGetResultSchema = Type.Object({
81
+ agentId: NonEmptyString,
82
+ workspace: NonEmptyString,
83
+ file: AgentsFileEntrySchema,
84
+ }, { additionalProperties: false });
85
+ export const AgentsFilesSetParamsSchema = Type.Object({
86
+ agentId: NonEmptyString,
87
+ name: NonEmptyString,
88
+ content: Type.String(),
89
+ }, { additionalProperties: false });
90
+ export const AgentsFilesSetResultSchema = Type.Object({
91
+ ok: Type.Literal(true),
92
+ agentId: NonEmptyString,
93
+ workspace: NonEmptyString,
94
+ file: AgentsFileEntrySchema,
95
+ }, { additionalProperties: false });
28
96
  export const ModelsListParamsSchema = Type.Object({}, { additionalProperties: false });
29
97
  export const ModelsListResultSchema = Type.Object({
30
98
  models: Type.Array(ModelChoiceSchema),
31
99
  }, { additionalProperties: false });
32
- export const SkillsStatusParamsSchema = Type.Object({}, { additionalProperties: false });
100
+ export const SkillsStatusParamsSchema = Type.Object({
101
+ agentId: Type.Optional(NonEmptyString),
102
+ }, { additionalProperties: false });
33
103
  export const SkillsBinsParamsSchema = Type.Object({}, { additionalProperties: false });
34
104
  export const SkillsBinsResultSchema = Type.Object({
35
105
  bins: Type.Array(NonEmptyString),
@@ -3,7 +3,7 @@ import { NonEmptyString } from "./primitives.js";
3
3
  export const CronScheduleSchema = Type.Union([
4
4
  Type.Object({
5
5
  kind: Type.Literal("at"),
6
- atMs: Type.Integer({ minimum: 0 }),
6
+ at: NonEmptyString,
7
7
  }, { additionalProperties: false }),
8
8
  Type.Object({
9
9
  kind: Type.Literal("every"),
@@ -27,8 +27,9 @@ export const CronPayloadSchema = Type.Union([
27
27
  model: Type.Optional(Type.String()),
28
28
  thinking: Type.Optional(Type.String()),
29
29
  timeoutSeconds: Type.Optional(Type.Integer({ minimum: 1 })),
30
+ allowUnsafeExternalContent: Type.Optional(Type.Boolean()),
30
31
  deliver: Type.Optional(Type.Boolean()),
31
- channel: Type.Optional(Type.Union([Type.Literal("last"), NonEmptyString])),
32
+ channel: Type.Optional(Type.String()),
32
33
  to: Type.Optional(Type.String()),
33
34
  bestEffortDeliver: Type.Optional(Type.Boolean()),
34
35
  }, { additionalProperties: false }),
@@ -44,16 +45,24 @@ export const CronPayloadPatchSchema = Type.Union([
44
45
  model: Type.Optional(Type.String()),
45
46
  thinking: Type.Optional(Type.String()),
46
47
  timeoutSeconds: Type.Optional(Type.Integer({ minimum: 1 })),
48
+ allowUnsafeExternalContent: Type.Optional(Type.Boolean()),
47
49
  deliver: Type.Optional(Type.Boolean()),
48
- channel: Type.Optional(Type.Union([Type.Literal("last"), NonEmptyString])),
50
+ channel: Type.Optional(Type.String()),
49
51
  to: Type.Optional(Type.String()),
50
52
  bestEffortDeliver: Type.Optional(Type.Boolean()),
51
53
  }, { additionalProperties: false }),
52
54
  ]);
53
- export const CronIsolationSchema = Type.Object({
54
- postToMainPrefix: Type.Optional(Type.String()),
55
- postToMainMode: Type.Optional(Type.Union([Type.Literal("summary"), Type.Literal("full")])),
56
- postToMainMaxChars: Type.Optional(Type.Integer({ minimum: 0 })),
55
+ export const CronDeliverySchema = Type.Object({
56
+ mode: Type.Union([Type.Literal("none"), Type.Literal("announce")]),
57
+ channel: Type.Optional(Type.Union([Type.Literal("last"), NonEmptyString])),
58
+ to: Type.Optional(Type.String()),
59
+ bestEffort: Type.Optional(Type.Boolean()),
60
+ }, { additionalProperties: false });
61
+ export const CronDeliveryPatchSchema = Type.Object({
62
+ mode: Type.Optional(Type.Union([Type.Literal("none"), Type.Literal("announce")])),
63
+ channel: Type.Optional(Type.Union([Type.Literal("last"), NonEmptyString])),
64
+ to: Type.Optional(Type.String()),
65
+ bestEffort: Type.Optional(Type.Boolean()),
57
66
  }, { additionalProperties: false });
58
67
  export const CronJobStateSchema = Type.Object({
59
68
  nextRunAtMs: Type.Optional(Type.Integer({ minimum: 0 })),
@@ -62,6 +71,7 @@ export const CronJobStateSchema = Type.Object({
62
71
  lastStatus: Type.Optional(Type.Union([Type.Literal("ok"), Type.Literal("error"), Type.Literal("skipped")])),
63
72
  lastError: Type.Optional(Type.String()),
64
73
  lastDurationMs: Type.Optional(Type.Integer({ minimum: 0 })),
74
+ consecutiveErrors: Type.Optional(Type.Integer({ minimum: 0 })),
65
75
  }, { additionalProperties: false });
66
76
  export const CronJobSchema = Type.Object({
67
77
  id: NonEmptyString,
@@ -76,7 +86,7 @@ export const CronJobSchema = Type.Object({
76
86
  sessionTarget: Type.Union([Type.Literal("main"), Type.Literal("isolated")]),
77
87
  wakeMode: Type.Union([Type.Literal("next-heartbeat"), Type.Literal("now")]),
78
88
  payload: CronPayloadSchema,
79
- isolation: Type.Optional(CronIsolationSchema),
89
+ delivery: Type.Optional(CronDeliverySchema),
80
90
  state: CronJobStateSchema,
81
91
  }, { additionalProperties: false });
82
92
  export const CronListParamsSchema = Type.Object({
@@ -93,7 +103,7 @@ export const CronAddParamsSchema = Type.Object({
93
103
  sessionTarget: Type.Union([Type.Literal("main"), Type.Literal("isolated")]),
94
104
  wakeMode: Type.Union([Type.Literal("next-heartbeat"), Type.Literal("now")]),
95
105
  payload: CronPayloadSchema,
96
- isolation: Type.Optional(CronIsolationSchema),
106
+ delivery: Type.Optional(CronDeliverySchema),
97
107
  }, { additionalProperties: false });
98
108
  export const CronJobPatchSchema = Type.Object({
99
109
  name: Type.Optional(NonEmptyString),
@@ -105,7 +115,7 @@ export const CronJobPatchSchema = Type.Object({
105
115
  sessionTarget: Type.Optional(Type.Union([Type.Literal("main"), Type.Literal("isolated")])),
106
116
  wakeMode: Type.Optional(Type.Union([Type.Literal("next-heartbeat"), Type.Literal("now")])),
107
117
  payload: Type.Optional(CronPayloadPatchSchema),
108
- isolation: Type.Optional(CronIsolationSchema),
118
+ delivery: Type.Optional(CronDeliveryPatchSchema),
109
119
  state: Type.Optional(Type.Partial(CronJobStateSchema)),
110
120
  }, { additionalProperties: false });
111
121
  export const CronUpdateParamsSchema = Type.Union([
@@ -153,6 +163,8 @@ export const CronRunLogEntrySchema = Type.Object({
153
163
  status: Type.Optional(Type.Union([Type.Literal("ok"), Type.Literal("error"), Type.Literal("skipped")])),
154
164
  error: Type.Optional(Type.String()),
155
165
  summary: Type.Optional(Type.String()),
166
+ sessionId: Type.Optional(NonEmptyString),
167
+ sessionKey: Type.Optional(NonEmptyString),
156
168
  runAtMs: Type.Optional(Type.Integer({ minimum: 0 })),
157
169
  durationMs: Type.Optional(Type.Integer({ minimum: 0 })),
158
170
  nextRunAtMs: Type.Optional(Type.Integer({ minimum: 0 })),
@@ -1,5 +1,5 @@
1
1
  import { AgentEventSchema, AgentIdentityParamsSchema, AgentIdentityResultSchema, AgentParamsSchema, AgentWaitParamsSchema, PollParamsSchema, SendParamsSchema, WakeParamsSchema, } from "./agent.js";
2
- import { AgentSummarySchema, AgentsListParamsSchema, AgentsListResultSchema, ModelChoiceSchema, ModelsListParamsSchema, ModelsListResultSchema, SkillsBinsParamsSchema, SkillsBinsResultSchema, SkillsInstallParamsSchema, SkillsStatusParamsSchema, SkillsUpdateParamsSchema, } from "./agents-models-skills.js";
2
+ import { AgentSummarySchema, AgentsCreateParamsSchema, AgentsCreateResultSchema, AgentsDeleteParamsSchema, AgentsDeleteResultSchema, AgentsFileEntrySchema, AgentsFilesGetParamsSchema, AgentsFilesGetResultSchema, AgentsFilesListParamsSchema, AgentsFilesListResultSchema, AgentsFilesSetParamsSchema, AgentsFilesSetResultSchema, AgentsListParamsSchema, AgentsListResultSchema, AgentsUpdateParamsSchema, AgentsUpdateResultSchema, ModelChoiceSchema, ModelsListParamsSchema, ModelsListResultSchema, SkillsBinsParamsSchema, SkillsBinsResultSchema, SkillsInstallParamsSchema, SkillsStatusParamsSchema, SkillsUpdateParamsSchema, } from "./agents-models-skills.js";
3
3
  import { ChannelsLogoutParamsSchema, ChannelsStatusParamsSchema, ChannelsStatusResultSchema, TalkModeParamsSchema, WebLoginStartParamsSchema, WebLoginWaitParamsSchema, } from "./channels.js";
4
4
  import { ConfigApplyParamsSchema, ConfigGetParamsSchema, ConfigPatchParamsSchema, ConfigSchemaParamsSchema, ConfigSchemaResponseSchema, ConfigSetParamsSchema, UpdateRunParamsSchema, } from "./config.js";
5
5
  import { CronAddParamsSchema, CronJobSchema, CronListParamsSchema, CronRemoveParamsSchema, CronRunLogEntrySchema, CronRunParamsSchema, CronRunsParamsSchema, CronStatusParamsSchema, CronUpdateParamsSchema, } from "./cron.js";
@@ -8,7 +8,7 @@ import { DevicePairApproveParamsSchema, DevicePairListParamsSchema, DevicePairRe
8
8
  import { ConnectParamsSchema, ErrorShapeSchema, EventFrameSchema, GatewayFrameSchema, HelloOkSchema, RequestFrameSchema, ResponseFrameSchema, ShutdownEventSchema, TickEventSchema, } from "./frames.js";
9
9
  import { ChatAbortParamsSchema, ChatEventSchema, ChatHistoryParamsSchema, ChatInjectParamsSchema, ChatSendParamsSchema, LogsTailParamsSchema, LogsTailResultSchema, } from "./logs-chat.js";
10
10
  import { NodeDescribeParamsSchema, NodeEventParamsSchema, NodeInvokeParamsSchema, NodeInvokeResultParamsSchema, NodeInvokeRequestEventSchema, NodeListParamsSchema, NodePairApproveParamsSchema, NodePairListParamsSchema, NodePairRejectParamsSchema, NodePairRequestParamsSchema, NodePairVerifyParamsSchema, NodeRenameParamsSchema, } from "./nodes.js";
11
- import { SessionsCompactParamsSchema, SessionsDeleteParamsSchema, SessionsListParamsSchema, SessionsPatchParamsSchema, SessionsPreviewParamsSchema, SessionsResetParamsSchema, SessionsResolveParamsSchema, } from "./sessions.js";
11
+ import { SessionsCompactParamsSchema, SessionsDeleteParamsSchema, SessionsListParamsSchema, SessionsPatchParamsSchema, SessionsPreviewParamsSchema, SessionsResetParamsSchema, SessionsResolveParamsSchema, SessionsUsageParamsSchema, } from "./sessions.js";
12
12
  import { PresenceEntrySchema, SnapshotSchema, StateVersionSchema } from "./snapshot.js";
13
13
  import { WizardCancelParamsSchema, WizardNextParamsSchema, WizardNextResultSchema, WizardStartParamsSchema, WizardStartResultSchema, WizardStatusParamsSchema, WizardStatusResultSchema, WizardStepSchema, } from "./wizard.js";
14
14
  export const ProtocolSchemas = {
@@ -49,6 +49,7 @@ export const ProtocolSchemas = {
49
49
  SessionsResetParams: SessionsResetParamsSchema,
50
50
  SessionsDeleteParams: SessionsDeleteParamsSchema,
51
51
  SessionsCompactParams: SessionsCompactParamsSchema,
52
+ SessionsUsageParams: SessionsUsageParamsSchema,
52
53
  ConfigGetParams: ConfigGetParamsSchema,
53
54
  ConfigSetParams: ConfigSetParamsSchema,
54
55
  ConfigApplyParams: ConfigApplyParamsSchema,
@@ -72,6 +73,19 @@ export const ProtocolSchemas = {
72
73
  AgentSummary: AgentSummarySchema,
73
74
  AgentsListParams: AgentsListParamsSchema,
74
75
  AgentsListResult: AgentsListResultSchema,
76
+ AgentsCreateParams: AgentsCreateParamsSchema,
77
+ AgentsCreateResult: AgentsCreateResultSchema,
78
+ AgentsUpdateParams: AgentsUpdateParamsSchema,
79
+ AgentsUpdateResult: AgentsUpdateResultSchema,
80
+ AgentsDeleteParams: AgentsDeleteParamsSchema,
81
+ AgentsDeleteResult: AgentsDeleteResultSchema,
82
+ AgentsFileEntry: AgentsFileEntrySchema,
83
+ AgentsFilesListParams: AgentsFilesListParamsSchema,
84
+ AgentsFilesListResult: AgentsFilesListResultSchema,
85
+ AgentsFilesGetParams: AgentsFilesGetParamsSchema,
86
+ AgentsFilesGetResult: AgentsFilesGetResultSchema,
87
+ AgentsFilesSetParams: AgentsFilesSetParamsSchema,
88
+ AgentsFilesSetResult: AgentsFilesSetResultSchema,
75
89
  ModelChoice: ModelChoiceSchema,
76
90
  ModelsListParams: ModelsListParamsSchema,
77
91
  ModelsListResult: ModelsListResultSchema,
@@ -67,3 +67,15 @@ export const SessionsCompactParamsSchema = Type.Object({
67
67
  key: NonEmptyString,
68
68
  maxLines: Type.Optional(Type.Integer({ minimum: 1 })),
69
69
  }, { additionalProperties: false });
70
+ export const SessionsUsageParamsSchema = Type.Object({
71
+ /** Specific session key to analyze; if omitted returns all sessions. */
72
+ key: Type.Optional(NonEmptyString),
73
+ /** Start date for range filter (YYYY-MM-DD). */
74
+ startDate: Type.Optional(Type.String({ pattern: "^\\d{4}-\\d{2}-\\d{2}$" })),
75
+ /** End date for range filter (YYYY-MM-DD). */
76
+ endDate: Type.Optional(Type.String({ pattern: "^\\d{4}-\\d{2}-\\d{2}$" })),
77
+ /** Maximum sessions to return (default 50). */
78
+ limit: Type.Optional(Type.Integer({ minimum: 1 })),
79
+ /** Include context weight breakdown (systemPromptReport). */
80
+ includeContextWeight: Type.Optional(Type.Boolean()),
81
+ }, { additionalProperties: false });
@@ -25,7 +25,7 @@ export function createGatewayHooksRequestHandler(params) {
25
25
  enabled: true,
26
26
  createdAtMs: now,
27
27
  updatedAtMs: now,
28
- schedule: { kind: "at", atMs: now },
28
+ schedule: { kind: "at", at: new Date(now).toISOString() },
29
29
  sessionTarget: "isolated",
30
30
  wakeMode: value.wakeMode,
31
31
  payload: {
@@ -13,20 +13,24 @@ const EVENT_SCOPE_GUARDS = {
13
13
  };
14
14
  function hasEventScope(client, event) {
15
15
  const required = EVENT_SCOPE_GUARDS[event];
16
- if (!required)
16
+ if (!required) {
17
17
  return true;
18
+ }
18
19
  const role = client.connect.role ?? "operator";
19
- if (role !== "operator")
20
+ if (role !== "operator") {
20
21
  return false;
22
+ }
21
23
  const scopes = Array.isArray(client.connect.scopes) ? client.connect.scopes : [];
22
- if (scopes.includes(ADMIN_SCOPE))
24
+ if (scopes.includes(ADMIN_SCOPE)) {
23
25
  return true;
26
+ }
24
27
  return required.some((scope) => scopes.includes(scope));
25
28
  }
26
29
  export function createGatewayBroadcaster(params) {
27
30
  let seq = 0;
28
- const broadcast = (event, payload, opts) => {
29
- const eventSeq = ++seq;
31
+ const broadcastInternal = (event, payload, opts, targetConnIds) => {
32
+ const isTargeted = Boolean(targetConnIds);
33
+ const eventSeq = isTargeted ? undefined : ++seq;
30
34
  const frame = JSON.stringify({
31
35
  type: "event",
32
36
  event,
@@ -36,8 +40,9 @@ export function createGatewayBroadcaster(params) {
36
40
  });
37
41
  const logMeta = {
38
42
  event,
39
- seq: eventSeq,
43
+ seq: eventSeq ?? "targeted",
40
44
  clients: params.clients.size,
45
+ targets: targetConnIds ? targetConnIds.size : undefined,
41
46
  dropIfSlow: opts?.dropIfSlow,
42
47
  presenceVersion: opts?.stateVersion?.presence,
43
48
  healthVersion: opts?.stateVersion?.health,
@@ -47,11 +52,16 @@ export function createGatewayBroadcaster(params) {
47
52
  }
48
53
  logWs("out", "event", logMeta);
49
54
  for (const c of params.clients) {
50
- if (!hasEventScope(c, event))
55
+ if (targetConnIds && !targetConnIds.has(c.connId)) {
56
+ continue;
57
+ }
58
+ if (!hasEventScope(c, event)) {
51
59
  continue;
60
+ }
52
61
  const slow = c.socket.bufferedAmount > MAX_BUFFERED_BYTES;
53
- if (slow && opts?.dropIfSlow)
62
+ if (slow && opts?.dropIfSlow) {
54
63
  continue;
64
+ }
55
65
  if (slow) {
56
66
  try {
57
67
  c.socket.close(1008, "slow consumer");
@@ -69,5 +79,12 @@ export function createGatewayBroadcaster(params) {
69
79
  }
70
80
  }
71
81
  };
72
- return { broadcast };
82
+ const broadcast = (event, payload, opts) => broadcastInternal(event, payload, opts);
83
+ const broadcastToConnIds = (event, payload, connIds, opts) => {
84
+ if (connIds.size === 0) {
85
+ return;
86
+ }
87
+ broadcastInternal(event, payload, opts, connIds);
88
+ };
89
+ return { broadcast, broadcastToConnIds };
73
90
  }
@@ -10,8 +10,9 @@ import { formatForLog } from "./ws-log.js";
10
10
  */
11
11
  function shouldSuppressHeartbeatBroadcast(runId) {
12
12
  const runContext = getAgentRunContext(runId);
13
- if (!runContext?.isHeartbeat)
13
+ if (!runContext?.isHeartbeat) {
14
14
  return false;
15
+ }
15
16
  try {
16
17
  const cfg = loadConfig();
17
18
  const visibility = resolveHeartbeatVisibility({ cfg, channel: "webchat" });
@@ -36,23 +37,28 @@ export function createChatRunRegistry() {
36
37
  const peek = (sessionId) => chatRunSessions.get(sessionId)?.[0];
37
38
  const shift = (sessionId) => {
38
39
  const queue = chatRunSessions.get(sessionId);
39
- if (!queue || queue.length === 0)
40
+ if (!queue || queue.length === 0) {
40
41
  return undefined;
42
+ }
41
43
  const entry = queue.shift();
42
- if (!queue.length)
44
+ if (!queue.length) {
43
45
  chatRunSessions.delete(sessionId);
46
+ }
44
47
  return entry;
45
48
  };
46
49
  const remove = (sessionId, clientRunId, sessionKey) => {
47
50
  const queue = chatRunSessions.get(sessionId);
48
- if (!queue || queue.length === 0)
51
+ if (!queue || queue.length === 0) {
49
52
  return undefined;
53
+ }
50
54
  const idx = queue.findIndex((entry) => entry.clientRunId === clientRunId && (sessionKey ? entry.sessionKey === sessionKey : true));
51
- if (idx < 0)
55
+ if (idx < 0) {
52
56
  return undefined;
57
+ }
53
58
  const [entry] = queue.splice(idx, 1);
54
- if (!queue.length)
59
+ if (!queue.length) {
55
60
  chatRunSessions.delete(sessionId);
61
+ }
56
62
  return entry;
57
63
  };
58
64
  const clear = () => {
@@ -79,13 +85,69 @@ export function createChatRunState() {
79
85
  clear,
80
86
  };
81
87
  }
82
- export function createAgentEventHandler({ broadcast, nodeSendToSession, agentRunSeq, chatRunState, resolveSessionKeyForRun, clearAgentRunContext, }) {
88
+ const TOOL_EVENT_RECIPIENT_TTL_MS = 10 * 60 * 1000;
89
+ const TOOL_EVENT_RECIPIENT_FINAL_GRACE_MS = 30 * 1000;
90
+ export function createToolEventRecipientRegistry() {
91
+ const recipients = new Map();
92
+ const prune = () => {
93
+ if (recipients.size === 0) {
94
+ return;
95
+ }
96
+ const now = Date.now();
97
+ for (const [runId, entry] of recipients) {
98
+ const cutoff = entry.finalizedAt
99
+ ? entry.finalizedAt + TOOL_EVENT_RECIPIENT_FINAL_GRACE_MS
100
+ : entry.updatedAt + TOOL_EVENT_RECIPIENT_TTL_MS;
101
+ if (now >= cutoff) {
102
+ recipients.delete(runId);
103
+ }
104
+ }
105
+ };
106
+ const add = (runId, connId) => {
107
+ if (!runId || !connId) {
108
+ return;
109
+ }
110
+ const now = Date.now();
111
+ const existing = recipients.get(runId);
112
+ if (existing) {
113
+ existing.connIds.add(connId);
114
+ existing.updatedAt = now;
115
+ }
116
+ else {
117
+ recipients.set(runId, {
118
+ connIds: new Set([connId]),
119
+ updatedAt: now,
120
+ });
121
+ }
122
+ prune();
123
+ };
124
+ const get = (runId) => {
125
+ const entry = recipients.get(runId);
126
+ if (!entry) {
127
+ return undefined;
128
+ }
129
+ entry.updatedAt = Date.now();
130
+ prune();
131
+ return entry.connIds;
132
+ };
133
+ const markFinal = (runId) => {
134
+ const entry = recipients.get(runId);
135
+ if (!entry) {
136
+ return;
137
+ }
138
+ entry.finalizedAt = Date.now();
139
+ prune();
140
+ };
141
+ return { add, get, markFinal };
142
+ }
143
+ export function createAgentEventHandler({ broadcast, broadcastToConnIds, nodeSendToSession, agentRunSeq, chatRunState, resolveSessionKeyForRun, clearAgentRunContext, toolEventRecipients, }) {
83
144
  const emitChatDelta = (sessionKey, clientRunId, seq, text) => {
84
145
  chatRunState.buffers.set(clientRunId, text);
85
146
  const now = Date.now();
86
147
  const last = chatRunState.deltaSentAt.get(clientRunId) ?? 0;
87
- if (now - last < 150)
148
+ if (now - last < 150) {
88
149
  return;
150
+ }
89
151
  chatRunState.deltaSentAt.set(clientRunId, now);
90
152
  const payload = {
91
153
  runId: clientRunId,
@@ -139,23 +201,26 @@ export function createAgentEventHandler({ broadcast, nodeSendToSession, agentRun
139
201
  broadcast("chat", payload);
140
202
  nodeSendToSession(sessionKey, "chat", payload);
141
203
  };
142
- const shouldEmitToolEvents = (runId, sessionKey) => {
204
+ const resolveToolVerboseLevel = (runId, sessionKey) => {
143
205
  const runContext = getAgentRunContext(runId);
144
206
  const runVerbose = normalizeVerboseLevel(runContext?.verboseLevel);
145
- if (runVerbose)
146
- return runVerbose === "on";
147
- if (!sessionKey)
148
- return false;
207
+ if (runVerbose) {
208
+ return runVerbose;
209
+ }
210
+ if (!sessionKey) {
211
+ return "off";
212
+ }
149
213
  try {
150
214
  const { cfg, entry } = loadSessionEntry(sessionKey);
151
215
  const sessionVerbose = normalizeVerboseLevel(entry?.verboseLevel);
152
- if (sessionVerbose)
153
- return sessionVerbose === "on";
216
+ if (sessionVerbose) {
217
+ return sessionVerbose;
218
+ }
154
219
  const defaultVerbose = normalizeVerboseLevel(cfg.agents?.defaults?.verboseDefault);
155
- return defaultVerbose === "on";
220
+ return defaultVerbose ?? "off";
156
221
  }
157
222
  catch {
158
- return false;
223
+ return "off";
159
224
  }
160
225
  };
161
226
  return (evt) => {
@@ -166,10 +231,17 @@ export function createAgentEventHandler({ broadcast, nodeSendToSession, agentRun
166
231
  // Include sessionKey so Control UI can filter tool streams per session.
167
232
  const agentPayload = sessionKey ? { ...evt, sessionKey } : evt;
168
233
  const last = agentRunSeq.get(evt.runId) ?? 0;
169
- if (evt.stream === "tool" && !shouldEmitToolEvents(evt.runId, sessionKey)) {
170
- agentRunSeq.set(evt.runId, evt.seq);
171
- return;
172
- }
234
+ const isToolEvent = evt.stream === "tool";
235
+ const toolVerbose = isToolEvent ? resolveToolVerboseLevel(evt.runId, sessionKey) : "off";
236
+ // Build tool payload: strip result/partialResult unless verbose=full
237
+ const toolPayload = isToolEvent && toolVerbose !== "full"
238
+ ? (() => {
239
+ const data = evt.data ? { ...evt.data } : {};
240
+ delete data.result;
241
+ delete data.partialResult;
242
+ return sessionKey ? { ...evt, sessionKey, data } : { ...evt, data };
243
+ })()
244
+ : agentPayload;
173
245
  if (evt.seq !== last + 1) {
174
246
  broadcast("agent", {
175
247
  runId: evt.runId,
@@ -184,10 +256,26 @@ export function createAgentEventHandler({ broadcast, nodeSendToSession, agentRun
184
256
  });
185
257
  }
186
258
  agentRunSeq.set(evt.runId, evt.seq);
187
- broadcast("agent", agentPayload);
259
+ if (isToolEvent) {
260
+ // Always broadcast tool events to registered WS recipients with
261
+ // tool-events capability, regardless of verboseLevel. The verbose
262
+ // setting only controls whether tool details are sent as channel
263
+ // messages to messaging surfaces (Telegram, Discord, etc.).
264
+ const recipients = toolEventRecipients.get(evt.runId);
265
+ if (recipients && recipients.size > 0) {
266
+ broadcastToConnIds("agent", toolPayload, recipients);
267
+ }
268
+ }
269
+ else {
270
+ broadcast("agent", agentPayload);
271
+ }
188
272
  const lifecyclePhase = evt.stream === "lifecycle" && typeof evt.data?.phase === "string" ? evt.data.phase : null;
189
273
  if (sessionKey) {
190
- nodeSendToSession(sessionKey, "agent", agentPayload);
274
+ // Send tool events to node/channel subscribers only when verbose is enabled;
275
+ // WS clients already received the event above via broadcastToConnIds.
276
+ if (!isToolEvent || toolVerbose !== "off") {
277
+ nodeSendToSession(sessionKey, "agent", isToolEvent ? toolPayload : agentPayload);
278
+ }
191
279
  if (!isAborted && evt.stream === "assistant" && typeof evt.data?.text === "string") {
192
280
  emitChatDelta(sessionKey, clientRunId, evt.seq, evt.data.text);
193
281
  }
@@ -215,6 +303,7 @@ export function createAgentEventHandler({ broadcast, nodeSendToSession, agentRun
215
303
  }
216
304
  }
217
305
  if (lifecyclePhase === "end" || lifecyclePhase === "error") {
306
+ toolEventRecipients.markFinal(evt.runId);
218
307
  clearAgentRunContext(evt.runId);
219
308
  }
220
309
  };
@@ -1,6 +1,6 @@
1
1
  import { startGatewayBonjourAdvertiser } from "../infra/bonjour.js";
2
2
  import { pickPrimaryTailnetIPv4, pickPrimaryTailnetIPv6 } from "../infra/tailnet.js";
3
- import { WIDE_AREA_DISCOVERY_DOMAIN, writeWideAreaGatewayZone } from "../infra/widearea-dns.js";
3
+ import { resolveWideAreaDiscoveryDomain, writeWideAreaGatewayZone } from "../infra/widearea-dns.js";
4
4
  import { formatBonjourInstanceName, resolveBonjourCliPath, resolveTailnetDnsHint, } from "./server-discovery.js";
5
5
  export async function startGatewayDiscovery(params) {
6
6
  let bonjourStop = null;
@@ -40,6 +40,13 @@ export async function startGatewayDiscovery(params) {
40
40
  }
41
41
  }
42
42
  if (params.wideAreaDiscoveryEnabled) {
43
+ const wideAreaDomain = resolveWideAreaDiscoveryDomain({
44
+ configDomain: params.wideAreaDiscoveryDomain ?? undefined,
45
+ });
46
+ if (!wideAreaDomain) {
47
+ params.logDiscovery.warn("discovery.wideArea.enabled is true, but no domain was configured; set discovery.wideArea.domain to enable unicast DNS-SD");
48
+ return { bonjourStop };
49
+ }
43
50
  const tailnetIPv4 = pickPrimaryTailnetIPv4();
44
51
  if (!tailnetIPv4) {
45
52
  params.logDiscovery.warn("discovery.wideArea.enabled is true, but no Tailscale IPv4 address was found; skipping unicast DNS-SD zone update");
@@ -48,6 +55,7 @@ export async function startGatewayDiscovery(params) {
48
55
  try {
49
56
  const tailnetIPv6 = pickPrimaryTailnetIPv6();
50
57
  const result = await writeWideAreaGatewayZone({
58
+ domain: wideAreaDomain,
51
59
  gatewayPort: params.port,
52
60
  displayName: formatBonjourInstanceName(params.machineDisplayName),
53
61
  tailnetIPv4,
@@ -58,7 +66,7 @@ export async function startGatewayDiscovery(params) {
58
66
  sshPort,
59
67
  cliPath: resolveBonjourCliPath(),
60
68
  });
61
- params.logDiscovery.info(`wide-area DNS-SD ${result.changed ? "updated" : "unchanged"} (${WIDE_AREA_DISCOVERY_DOMAIN} → ${result.zonePath})`);
69
+ params.logDiscovery.info(`wide-area DNS-SD ${result.changed ? "updated" : "unchanged"} (${wideAreaDomain} → ${result.zonePath})`);
62
70
  }
63
71
  catch (err) {
64
72
  params.logDiscovery.warn(`wide-area discovery update failed: ${String(err)}`);