xaq-cli 0.0.0 → 0.1.0-nightly.72
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.
- package/LICENSE +21 -0
- package/README.md +79 -0
- package/dist/admin-5gThRwgj.js +162 -0
- package/dist/admin-5gThRwgj.js.map +1 -0
- package/dist/admin-Btrm8mCd.js +218 -0
- package/dist/admin-Btrm8mCd.js.map +1 -0
- package/dist/admin-CWofnT_Q.js +2 -0
- package/dist/api-BFpElwqK.js +89 -0
- package/dist/api-BFpElwqK.js.map +1 -0
- package/dist/audit-BB7jK9Z5.js +2 -0
- package/dist/audit-BVYknW2i.js +79 -0
- package/dist/audit-BVYknW2i.js.map +1 -0
- package/dist/auth-CXmBdMqw.js +2 -0
- package/dist/auth-D-GmwNv-.js +550 -0
- package/dist/auth-D-GmwNv-.js.map +1 -0
- package/dist/brand--ZB8jTn1.js +32 -0
- package/dist/brand--ZB8jTn1.js.map +1 -0
- package/dist/bus-Cz0flS37.js +12 -0
- package/dist/bus-Cz0flS37.js.map +1 -0
- package/dist/bus-OKIGut72.js +2 -0
- package/dist/cli.js +234 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands-BNVLjYXA.js +167 -0
- package/dist/commands-BNVLjYXA.js.map +1 -0
- package/dist/commands-CdA6-WE7.js +112 -0
- package/dist/commands-CdA6-WE7.js.map +1 -0
- package/dist/config-C9XmYZWO.js +94 -0
- package/dist/config-C9XmYZWO.js.map +1 -0
- package/dist/config-CNVi0v5t.js +2 -0
- package/dist/connect-TtJ9n0Rw.js +362 -0
- package/dist/connect-TtJ9n0Rw.js.map +1 -0
- package/dist/content-C1lKMxFS.js +1170 -0
- package/dist/content-C1lKMxFS.js.map +1 -0
- package/dist/content-worker.js +28 -0
- package/dist/content-worker.js.map +1 -0
- package/dist/crypto-fv2fj3S8.js +75 -0
- package/dist/crypto-fv2fj3S8.js.map +1 -0
- package/dist/db-BEUEUPyP.js +561 -0
- package/dist/db-BEUEUPyP.js.map +1 -0
- package/dist/db-Q5BQuwga.js +2 -0
- package/dist/errors-FbMS3QBo.js +39 -0
- package/dist/errors-FbMS3QBo.js.map +1 -0
- package/dist/filter-Ck6OMxvu.js +158 -0
- package/dist/filter-Ck6OMxvu.js.map +1 -0
- package/dist/hermes-CKyzt1mH.js +3 -0
- package/dist/hermes-DHnDTYJp.js +1023 -0
- package/dist/hermes-DHnDTYJp.js.map +1 -0
- package/dist/import-DsN5NZT3.js +910 -0
- package/dist/import-DsN5NZT3.js.map +1 -0
- package/dist/instance-CwWbFbJ8.js +2 -0
- package/dist/instance-Dj9TpJB2.js +195 -0
- package/dist/instance-Dj9TpJB2.js.map +1 -0
- package/dist/listen-B9iO7HgQ.js +1568 -0
- package/dist/listen-B9iO7HgQ.js.map +1 -0
- package/dist/listen-CXVKG9XD.js +2 -0
- package/dist/manage-Bo6COB4p.js +477 -0
- package/dist/manage-Bo6COB4p.js.map +1 -0
- package/dist/manage-DoXqvjnU.js +2 -0
- package/dist/mcpheader-B8c5YO1B.js +2 -0
- package/dist/mcpheader-C9H4vudu.js +185 -0
- package/dist/mcpheader-C9H4vudu.js.map +1 -0
- package/dist/mcpsetup-BnHudwpq.js +2 -0
- package/dist/mcpsetup-DXXo2qjf.js +1053 -0
- package/dist/mcpsetup-DXXo2qjf.js.map +1 -0
- package/dist/node-check-CjTk6VNL.js +24 -0
- package/dist/node-check-CjTk6VNL.js.map +1 -0
- package/dist/paths-d-C2kdjo.js +2 -0
- package/dist/paths-yzOKD6ow.js +46 -0
- package/dist/paths-yzOKD6ow.js.map +1 -0
- package/dist/profile-CcMZ4hn7.js +2 -0
- package/dist/profile-NmMKAczz.js +222 -0
- package/dist/profile-NmMKAczz.js.map +1 -0
- package/dist/prompt-CKMQx_MJ.js +114 -0
- package/dist/prompt-CKMQx_MJ.js.map +1 -0
- package/dist/recipes-C7TIDlRj.js +3 -0
- package/dist/recipes-DG_-doGq.js +314 -0
- package/dist/recipes-DG_-doGq.js.map +1 -0
- package/dist/send-Dk-t8ia-.js +108 -0
- package/dist/send-Dk-t8ia-.js.map +1 -0
- package/dist/server-CDqDp1q3.js +20640 -0
- package/dist/server-CDqDp1q3.js.map +1 -0
- package/dist/service-BVn3soZZ.js +766 -0
- package/dist/service-BVn3soZZ.js.map +1 -0
- package/dist/service-BaWGPmSd.js +2 -0
- package/dist/service-C7jfo-Ex.js +457 -0
- package/dist/service-C7jfo-Ex.js.map +1 -0
- package/dist/service-DxDyKDQ-.js +2 -0
- package/dist/settings-B5qSHxRM.js +134 -0
- package/dist/settings-B5qSHxRM.js.map +1 -0
- package/dist/settings-DQvZaMN1.js +2 -0
- package/dist/setup-token-CwuSzfLK.js +48 -0
- package/dist/setup-token-CwuSzfLK.js.map +1 -0
- package/dist/skill/SKILL.md +445 -0
- package/dist/skill-1UQj3qgW.js +69 -0
- package/dist/skill-1UQj3qgW.js.map +1 -0
- package/dist/skill-pelq18JQ.js +2 -0
- package/dist/ssrf-BlVpGZ7C.js +181 -0
- package/dist/ssrf-BlVpGZ7C.js.map +1 -0
- package/dist/types-BhJDbSzE.js +135 -0
- package/dist/types-BhJDbSzE.js.map +1 -0
- package/dist/ui-B8Sd4Y7Y.js +81 -0
- package/dist/ui-B8Sd4Y7Y.js.map +1 -0
- package/dist/urls-Dp8pBGMU.js +2 -0
- package/dist/urls-U_LfYV61.js +27 -0
- package/dist/urls-U_LfYV61.js.map +1 -0
- package/dist/version-BxH7OuWD.js +20 -0
- package/dist/version-BxH7OuWD.js.map +1 -0
- package/dist/web/assets/_agentId-DonOCOlC.js +1 -0
- package/dist/web/assets/_app-B7t5lEia.js +1 -0
- package/dist/web/assets/_app-DMTGqYpM.js +65 -0
- package/dist/web/assets/_connectionId-DR5vFXOg.js +1 -0
- package/dist/web/assets/_webhookId-LfUlsULp.js +1 -0
- package/dist/web/assets/account-status-CEszs13C.js +1 -0
- package/dist/web/assets/accounts-5m7aiXuZ.js +1 -0
- package/dist/web/assets/accounts-list-YfJzThZa.js +1 -0
- package/dist/web/assets/activity-DOIe7SAg.js +1 -0
- package/dist/web/assets/add-connection-C8JR-13R.js +1 -0
- package/dist/web/assets/agent-create-form-CPxnPYH4.js +1 -0
- package/dist/web/assets/agents-B2Qj5KxT.js +1 -0
- package/dist/web/assets/approvals-BGaVaoFy.js +1 -0
- package/dist/web/assets/approve._id-BLrQnzPM.js +1 -0
- package/dist/web/assets/arrow-left-DZVAXoKj.js +1 -0
- package/dist/web/assets/arrow-right-C2zcqRr2.js +1 -0
- package/dist/web/assets/attention-gO9Nw5uW.js +1 -0
- package/dist/web/assets/audit-BPXXre8S.js +1 -0
- package/dist/web/assets/audit-bits-CGyIprzK.js +1 -0
- package/dist/web/assets/bell-ring-ig3zn1iS.js +1 -0
- package/dist/web/assets/bot-Zk76q_39.js +1 -0
- package/dist/web/assets/calendar-notice-DsCfq3VJ.js +1 -0
- package/dist/web/assets/calendar-plus-Cycfkk0y.js +1 -0
- package/dist/web/assets/calendar-setup-Pn61Wj1n.js +2 -0
- package/dist/web/assets/card-GSO5o-Ug.js +1 -0
- package/dist/web/assets/check-check-Ds1bPIGv.js +1 -0
- package/dist/web/assets/checkbox-B937U-Fd.js +1 -0
- package/dist/web/assets/chevron-right-Cqh4mDk1.js +1 -0
- package/dist/web/assets/chips-input-2xWDofmE.js +1 -0
- package/dist/web/assets/choice-cards-CgAIqBGX.js +1 -0
- package/dist/web/assets/circle-x-DcU-0zVh.js +1 -0
- package/dist/web/assets/command-khhto70y.js +1 -0
- package/dist/web/assets/common-BPZV8TFb.js +1 -0
- package/dist/web/assets/connect-agent-guide-CJdw31p2.js +1 -0
- package/dist/web/assets/connect-host-lr2c3xWh.js +6 -0
- package/dist/web/assets/connection-row-DYx_5o0c.js +1 -0
- package/dist/web/assets/connections-C4NOFb5R.js +1 -0
- package/dist/web/assets/data-table-kW1pkRB5.js +1 -0
- package/dist/web/assets/empty-DzTDioBP.js +1 -0
- package/dist/web/assets/events-C9zJnPKK.js +1 -0
- package/dist/web/assets/eye-B9gT1QSq.js +1 -0
- package/dist/web/assets/eye-off-Diktqz_g.js +1 -0
- package/dist/web/assets/field-C6ejurju.js +1 -0
- package/dist/web/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/dist/web/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/dist/web/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dist/web/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dist/web/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
- package/dist/web/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
- package/dist/web/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
- package/dist/web/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- package/dist/web/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
- package/dist/web/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
- package/dist/web/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/dist/web/assets/get-started-C38bq1gZ.js +2 -0
- package/dist/web/assets/hidden-chars-Dr9TxfvF.js +1 -0
- package/dist/web/assets/index-DGzo3kGh.js +11 -0
- package/dist/web/assets/index-zKOCQLGX.css +2 -0
- package/dist/web/assets/input-CWwJgozn.js +1 -0
- package/dist/web/assets/input-group-HG8OXcJ4.js +1 -0
- package/dist/web/assets/label-multi-select-sH8mllw8.js +1 -0
- package/dist/web/assets/labels-B5UqVwFo.js +1 -0
- package/dist/web/assets/laptop-BxJ4Nbj7.js +1 -0
- package/dist/web/assets/last-call-D-O5O94z.js +1 -0
- package/dist/web/assets/listener-handled-HNCuVrQ7.js +1 -0
- package/dist/web/assets/login-DaeKclcf.js +1 -0
- package/dist/web/assets/mail-C5fm2pTC.js +1 -0
- package/dist/web/assets/mcp-call-UoOTPFyh.js +1 -0
- package/dist/web/assets/mcp-call-card-Cr-OEDX2.js +3 -0
- package/dist/web/assets/message-square-quote-se8Bf3RP.js +1 -0
- package/dist/web/assets/mutations-CLPqJ6cj.js +1 -0
- package/dist/web/assets/network-igNw0VVx.js +1 -0
- package/dist/web/assets/pairing-XjuaVr2u.js +1 -0
- package/dist/web/assets/pairing-notifier-KPzOEZSO.js +1 -0
- package/dist/web/assets/paperclip-znS4iTrg.js +1 -0
- package/dist/web/assets/password-input-DV3aqcNf.js +1 -0
- package/dist/web/assets/pause-o-dK3khK.js +1 -0
- package/dist/web/assets/pencil-DkPFAhEq.js +1 -0
- package/dist/web/assets/play-DvCHND93.js +1 -0
- package/dist/web/assets/plug-CXAniEiR.js +1 -0
- package/dist/web/assets/plug-zap-BwR-l5wb.js +1 -0
- package/dist/web/assets/plus-B_TUslu3.js +1 -0
- package/dist/web/assets/preload-helper-Cc_aKyUb.js +1 -0
- package/dist/web/assets/public-url-rF2Xjyel.js +1 -0
- package/dist/web/assets/queries-Cv3nXx0U.js +42 -0
- package/dist/web/assets/refresh-cw-Ch5FNrby.js +1 -0
- package/dist/web/assets/revealed-keys-C_9NtJPY.js +1 -0
- package/dist/web/assets/rolldown-runtime-XKyaHtl9.js +1 -0
- package/dist/web/assets/rotate-ccw-B-mzPDk0.js +1 -0
- package/dist/web/assets/search-CTVKGomS.js +1 -0
- package/dist/web/assets/select-Bb806bpq.js +1 -0
- package/dist/web/assets/send-DuMVuYs1.js +1 -0
- package/dist/web/assets/settings-BWauhfFf.js +1 -0
- package/dist/web/assets/setup-B7bNKQOp.js +1 -0
- package/dist/web/assets/sheet-CYPwpUsH.js +1 -0
- package/dist/web/assets/shield-alert-CSYB-ThV.js +1 -0
- package/dist/web/assets/shield-check-BulpsYqK.js +1 -0
- package/dist/web/assets/sparkles-CUTiob4K.js +1 -0
- package/dist/web/assets/stamp-BNXUGNa3.js +1 -0
- package/dist/web/assets/step-url-51aMNak-.js +1 -0
- package/dist/web/assets/stream-Du7fY5_Y.js +1 -0
- package/dist/web/assets/tag-I5_-1jFL.js +1 -0
- package/dist/web/assets/terminal-BvxDFTJc.js +1 -0
- package/dist/web/assets/test-email-button-DYi7V_6X.js +1 -0
- package/dist/web/assets/toggle-group-Bdo1gmQ1.js +1 -0
- package/dist/web/assets/trash-Ci0aICEl.js +1 -0
- package/dist/web/assets/use-delivery-speed-BBh7W2q6.js +1 -0
- package/dist/web/assets/use-label-names-BXicesnP.js +1 -0
- package/dist/web/assets/use-sign-out-CPrY_oVO.js +1 -0
- package/dist/web/assets/useInfiniteQuery-DJLIM8yJ.js +1 -0
- package/dist/web/assets/useQuery-MrTwwNy5.js +1 -0
- package/dist/web/assets/useRouterState-D4OBK8l5.js +1 -0
- package/dist/web/assets/webhook-DjeeZiNC.js +1 -0
- package/dist/web/assets/webhook-bits-jw-y2D3u.js +1 -0
- package/dist/web/assets/webhook-sheet-B8h0skDe.js +34 -0
- package/dist/web/assets/webhooks-Cfsdpoyd.js +1 -0
- package/dist/web/assets/x-MF2TZ9aG.js +1 -0
- package/dist/web/favicon.svg +1 -0
- package/dist/web/index.html +27 -0
- package/package.json +98 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listen-B9iO7HgQ.js","names":[],"sources":["../server/listen/grants.ts","../server/listen/dispatcher.ts","../server/listen/exec.ts","../server/listen/logfile.ts","../server/listen/state.ts","../server/listen/lock.ts","../server/listen/sse.ts","../server/listen/stream.ts","../server/listen/listen.ts"],"sourcesContent":["import type { AgentSelf } from \"../../shared/agent-api.ts\";\nimport { safeText } from \"./ui.ts\";\n\ntype Grant = AgentSelf[\"grants\"][number];\n\n/**\n * A grant in plain words, e.g. \"ops@acme.dev: read, draft, send; sends need your approval in the\n * console\". Uses the same wording as the console's approval choices (Read only, Read and draft,\n * Send with my approval, Full access) so the human recognizes what they picked. Calendar access is\n * described after the mail part.\n */\nexport function describeGrant(g: Grant): string {\n const all = g.capabilities;\n const caps = all.filter((c) => !c.startsWith(\"calendar.\"));\n const parts: string[] = [];\n const readOnly = caps.length === 1 && caps[0] === \"read\";\n if (readOnly) parts.push(all.length > 1 ? `${all.join(\", \")}; mail read only (can't draft or send)` : \"read only (can't draft or send)\");\n else parts.push(all.join(\", \") || \"no capabilities\");\n if (caps.includes(\"send\")) {\n if (g.sendMode === \"approval\") parts.push(\"sends need your approval in the console\");\n else if (g.sendMode === \"direct\") parts.push(g.allowTo?.length ? \"sends go out directly to allowed recipients\" : \"sends go out directly\");\n else parts.push(\"sends become Gmail drafts for you to send\");\n // Restrictions the daemon enforces on top of the send mode.\n if (g.allowTo?.length) {\n const shown = g.allowTo.slice(0, 3).map((a) => safeText(a, 80));\n parts.push(`only to ${shown.join(\", \")}${g.allowTo.length > 3 ? ` and ${g.allowTo.length - 3} more` : \"\"}`);\n }\n if (g.replyOnly) parts.push(\"replies in existing threads only\");\n const limits = [g.maxSendsPerHour ? `${g.maxSendsPerHour}/hour` : null, g.maxSendsPerDay ? `${g.maxSendsPerDay}/day` : null].filter(Boolean);\n if (limits.length) parts.push(`at most ${limits.join(\", \")}`);\n } else if (!readOnly && caps.length) {\n parts.push(\"can't send\");\n }\n if (g.labelScope?.length) parts.push(`only label${g.labelScope.length > 1 ? \"s\" : \"\"} ${g.labelScope.map((l) => safeText(l, 60)).join(\", \")}`);\n if (all.includes(\"calendar.write\")) {\n // Older daemons don't report the mode; new grants default to approval.\n parts.push(g.calendarWriteMode === \"direct\" ? \"calendar changes apply directly\" : \"calendar changes need your approval in the console\");\n }\n if (g.calendarScope?.length && all.some((c) => c.startsWith(\"calendar.\"))) {\n parts.push(`only calendar${g.calendarScope.length > 1 ? \"s\" : \"\"} ${g.calendarScope.map((c) => safeText(c, 80)).join(\", \")}`);\n }\n return `${safeText(g.accountEmail || g.accountId, 120)}: ${parts.join(\"; \")}`;\n}\n\ntype ConnectionAccess = NonNullable<AgentSelf[\"connections\"]>[number];\n\nconst LEVEL_WORDS: Record<ConnectionAccess[\"level\"], string> = {\n full: \"full access\",\n ask: \"ask before risky actions\",\n read: \"read only\",\n};\n\n/** A connection grant in plain words, e.g. \"Notion (notion__… tools): ask before risky actions\". */\nexport const describeConnection = (c: ConnectionAccess): string =>\n `${safeText(c.name, 80)} (${safeText(c.slug, 24)}__… tools): ${LEVEL_WORDS[c.level] ?? safeText(String(c.level), 20)}`;\n\n/** One line per mailbox grant and per connection, or a hint when there are none. */\nexport function describeGrants(grants: Grant[], connections: ConnectionAccess[] = []): string[] {\n if (!grants.length && !connections.length) return [\"no mailbox or calendar access yet: add a grant for this agent in the console (Agents page)\"];\n return [...grants.map(describeGrant), ...connections.map(describeConnection)];\n}\n\n/** Whether there's anything to describe (else describeGrants' single line is the \"nothing yet\" hint). */\nexport const hasAccess = (self: Pick<AgentSelf, \"grants\" | \"connections\">) => self.grants.length > 0 || (self.connections?.length ?? 0) > 0;\n\n/** Stable key for \"did the grants change?\" (order-independent; connections too). */\nexport const grantsKey = (grants: Grant[], connections: ConnectionAccess[] = []) =>\n JSON.stringify(connections.length ? [grantsList(grants), connections.map((c) => [c.slug, c.level]).sort()] : grantsList(grants));\n\nconst grantsList = (grants: Grant[]) =>\n (\n grants\n .map((g) => [\n g.accountId,\n [...g.capabilities].sort(),\n g.sendMode,\n g.labelScope ? [...g.labelScope].sort() : null,\n g.allowTo ? [...g.allowTo].sort() : null,\n g.replyOnly ?? null,\n g.maxSendsPerHour ?? null,\n g.maxSendsPerDay ?? null,\n g.calendarScope ? [...g.calendarScope].sort() : null,\n g.calendarWriteMode ?? null,\n ])\n .sort((a, b) => String(a[0]).localeCompare(String(b[0])))\n );\n","import type { WebhookPayload } from \"../../shared/types.ts\";\n\nexport type Target = \"exec\" | \"forward\";\n\nexport interface Job {\n /** Seq of the job's first event (its place in the acknowledgement order). */\n seq: number;\n /** The first event (the only one unless batched). */\n payload: WebhookPayload;\n /** Every event in this job, oldest first: one, or a --batch. */\n payloads: WebhookPayload[];\n /** Seq of the job's newest event: the cursor may advance to it once the job is finished. */\n lastSeq: number;\n /** Targets still to succeed. A retry only re-runs these (exec and forward are tracked separately). */\n remaining: Set<Target>;\n /** Seqs already forwarded (a batch is forwarded one event at a time; a retry skips these). */\n forwarded: Set<number>;\n attempts: number;\n lastError: string | null;\n /** Set by `run` when the receiver said \"too many requests\": retry after this long, without using up an attempt. */\n retryAfterMs?: number;\n /** Attempts that ended rate-limited (they don't count, up to MAX_DEFERRALS). */\n deferrals: number;\n state: \"collecting\" | \"queued\" | \"running\" | \"waiting\" | \"done\";\n outcome?: \"succeeded\" | \"dead\" | \"skipped\";\n firstSeenAt: number;\n}\n\nexport interface DispatcherOptions {\n targets: Target[];\n concurrency: number;\n maxAttempts: number;\n /** Collect events for windowMs after the first one (or until `max` events) and run them as one job. */\n batch?: { windowMs: number; max: number };\n /** Delay before retry number `attempt` (1-based). Default: 5 s doubling, capped at 5 min, ±20 % jitter. */\n retryDelayMs?: (attempt: number) => number;\n /** Runs the job's remaining targets once; removes the ones that succeeded from job.remaining and returns the errors of the rest. */\n run: (job: Job, signal: AbortSignal) => Promise<string[]>;\n /** The contiguous prefix of finished events advanced to `seq`: acknowledge it on the server. */\n onAdvance: (seq: number) => void;\n onDead: (job: Job) => void;\n onFinished?: (job: Job) => void;\n onRetry?: (job: Job, delayMs: number) => void;\n}\n\nexport const defaultRetryDelay = (attempt: number) => Math.min(5000 * 2 ** (attempt - 1), 300_000) * (0.8 + Math.random() * 0.4);\n/** Rate-limited attempts that don't count against --max-attempts, per job (an event, or a whole batch); after that they do. */\nexport const MAX_DEFERRALS = 20;\n\n/**\n * Runs events with bounded concurrency and retries, and tracks the **contiguous prefix** of finished\n * events (succeeded, dead or filtered out). Only that prefix is acknowledged, so a crash never loses\n * an event that was still running, collecting into a batch, or waiting to retry: it is delivered\n * again on restart (at-least-once; handlers dedupe on the event id). Events can finish out of order\n * when concurrency is above 1 or an event is waiting for a retry. A batch job takes its first event's\n * place in that order, so nothing after it is acknowledged before the whole batch has finished.\n */\nexport class Dispatcher {\n private readonly jobs: Job[] = [];\n private running = 0;\n private highestSeen = 0;\n private advancedTo = 0;\n private stopped = false;\n private readonly controller = new AbortController();\n private readonly timers = new Set<NodeJS.Timeout>();\n private idleWaiters: (() => void)[] = [];\n /** The batch still collecting events, if any. */\n private open: { job: Job; timer: NodeJS.Timeout } | null = null;\n\n constructor(private readonly opts: DispatcherOptions) {}\n\n /** Highest seq received this session (sent as Last-Event-ID on reconnect). */\n get lastSeq(): number {\n return this.highestSeen;\n }\n /** Seq the finished prefix reaches. */\n get finishedThrough(): number {\n return this.advancedTo;\n }\n /** Events received but not yet started (for stream backpressure). */\n get backlog(): number {\n return this.jobs.filter((j) => j.state === \"queued\" || j.state === \"collecting\").reduce((n, j) => n + j.payloads.length, 0);\n }\n get inFlight(): number {\n return this.jobs.filter((j) => j.state !== \"done\").length;\n }\n\n /** Seeds the position (the server's acked cursor) so older replays are ignored. */\n seed(seq: number): void {\n this.highestSeen = Math.max(this.highestSeen, seq);\n this.advancedTo = Math.max(this.advancedTo, seq);\n }\n\n /** Adds an event. Returns false when it is a duplicate of one already seen this session. */\n push(payload: WebhookPayload, opts: { skip?: boolean; targets?: Target[] } = {}): boolean {\n const seq = payload.data.seq;\n if (this.stopped || seq <= this.highestSeen) return false;\n this.highestSeen = seq;\n const remaining = new Set(opts.targets ? this.opts.targets.filter((t) => opts.targets!.includes(t)) : this.opts.targets);\n const batch = this.opts.batch && !opts.targets ? this.opts.batch : null;\n if (!opts.skip && remaining.size && batch && this.open) {\n const job = this.open.job;\n job.payloads.push(payload);\n job.lastSeq = seq;\n if (job.payloads.length >= batch.max) this.close();\n return true;\n }\n const job: Job = { seq, payload, payloads: [payload], lastSeq: seq, remaining, forwarded: new Set(), attempts: 0, deferrals: 0, lastError: null, state: \"queued\", firstSeenAt: Date.now() };\n this.jobs.push(job);\n if (opts.skip || remaining.size === 0) {\n job.state = \"done\";\n job.outcome = \"skipped\";\n this.advance();\n } else if (batch && batch.max > 1) {\n job.state = \"collecting\";\n const timer = setTimeout(() => this.close(), batch.windowMs);\n this.open = { job, timer };\n } else {\n this.pump();\n }\n return true;\n }\n\n /** Ends the collecting batch: it runs as soon as a slot is free. */\n private close(): void {\n if (!this.open) return;\n clearTimeout(this.open.timer);\n this.open.job.state = \"queued\";\n this.open = null;\n this.pump();\n }\n\n private pump(): void {\n if (this.stopped) return;\n for (const job of this.jobs) {\n if (this.running >= this.opts.concurrency) break;\n if (job.state === \"queued\") void this.start(job);\n }\n }\n\n private async start(job: Job): Promise<void> {\n job.state = \"running\";\n job.attempts++;\n job.retryAfterMs = undefined;\n this.running++;\n let errors: string[];\n try {\n errors = await this.opts.run(job, this.controller.signal);\n } catch (err) {\n errors = [err instanceof Error ? err.message : String(err)];\n }\n this.running--;\n if (this.stopped) {\n // Interrupted by shutdown: not finished, so not acknowledged; it comes back on restart.\n job.state = \"queued\";\n this.notifyIdle();\n return;\n }\n if (job.remaining.size === 0) {\n job.state = \"done\";\n job.outcome = \"succeeded\";\n this.opts.onFinished?.(job);\n } else {\n job.lastError = errors.join(\"; \") || \"failed\";\n // A rate-limited attempt doesn't use up an attempt (up to MAX_DEFERRALS): the receiver is fine, just busy.\n // Only when the 429 was this attempt's only error: a failing command still counts.\n const deferred = job.retryAfterMs !== undefined && errors.length === 1 && job.deferrals < MAX_DEFERRALS;\n if (deferred) {\n job.deferrals++;\n job.attempts--;\n }\n if (job.attempts >= this.opts.maxAttempts) {\n job.state = \"done\";\n job.outcome = \"dead\";\n this.opts.onDead(job);\n this.opts.onFinished?.(job);\n } else {\n job.state = \"waiting\";\n const delay = deferred ? job.retryAfterMs! : (this.opts.retryDelayMs ?? defaultRetryDelay)(job.attempts);\n this.opts.onRetry?.(job, delay);\n const t = setTimeout(() => {\n this.timers.delete(t);\n if (job.state === \"waiting\") job.state = \"queued\";\n this.pump();\n }, delay);\n this.timers.add(t);\n }\n }\n this.advance();\n this.pump();\n this.notifyIdle();\n }\n\n private advance(): void {\n let to = this.advancedTo;\n // max: a batch's lastSeq can be past the skipped events queued behind it.\n while (this.jobs.length && this.jobs[0]!.state === \"done\") to = Math.max(to, this.jobs.shift()!.lastSeq);\n if (to > this.advancedTo) {\n this.advancedTo = to;\n this.opts.onAdvance(to);\n }\n this.notifyIdle();\n }\n\n private notifyIdle(): void {\n if (this.jobs.length === 0 && this.running === 0) {\n const waiters = this.idleWaiters;\n this.idleWaiters = [];\n for (const w of waiters) w();\n }\n }\n\n /** Resolves once every received event has finished (tests and `dead --replay`). */\n idle(): Promise<void> {\n if (this.jobs.length === 0 && this.running === 0) return Promise.resolve();\n return new Promise((r) => this.idleWaiters.push(r));\n }\n\n /** Stops starting work, aborts what is running (process groups are killed) and waits for it to unwind. A collecting batch isn't run (nor acknowledged). */\n async stop(): Promise<void> {\n this.stopped = true;\n if (this.open) clearTimeout(this.open.timer);\n this.open = null;\n for (const t of this.timers) clearTimeout(t);\n this.timers.clear();\n this.controller.abort();\n while (this.running > 0) await new Promise((r) => setTimeout(r, 20));\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { mkdtempSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { WebhookPayload } from \"../../shared/types.ts\";\nimport { batchEnv, commandInput, eventEnv, UNTRUSTED_NOTICE } from \"./event.ts\";\n\nexport interface CommandResult {\n ok: boolean;\n exitCode: number | null;\n signal: string | null;\n timedOut: boolean;\n durationMs: number;\n stdoutTail: string;\n stderrTail: string;\n error: string | null;\n}\n\nconst TAIL = 4000;\nconst KILL_GRACE_MS = 5000;\n\nclass Tail {\n private buf = \"\";\n push(chunk: Buffer): void {\n this.buf = (this.buf + chunk.toString(\"utf8\")).slice(-TAIL);\n }\n toString(): string {\n return this.buf;\n }\n}\n\n/**\n * The child's environment: ours minus anything xaq-specific (XAQ_* and the pre-rename AGENTINBOX_*:\n * service flags, a master key that happened to be exported…), plus the safe event ids and the event file\n * path. Each of those is set as XAQ_<name> and, for commands written before the rename, AGENTINBOX_<name>.\n */\nexport function childEnv(input: WebhookPayload | WebhookPayload[], eventFile: string): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {};\n for (const [k, v] of Object.entries(process.env)) if (!k.startsWith(\"XAQ_\") && !k.startsWith(\"AGENTINBOX_\")) env[k] = v;\n const ids: Record<string, string> = { ...(Array.isArray(input) ? batchEnv(input) : { ...eventEnv(input), XAQ_EVENT_COUNT: \"1\" }), XAQ_EVENT_FILE: eventFile };\n const legacy = Object.fromEntries(Object.entries(ids).map(([k, v]) => [k.replace(/^XAQ_/, \"AGENTINBOX_\"), v]));\n return { ...env, ...ids, ...legacy };\n}\n\n/** stdin for one event ({ notice, event }) or a --batch ({ notice, events: […] }, even for a batch of one). */\nexport function commandStdin(input: WebhookPayload | WebhookPayload[]): string {\n const body = Array.isArray(input) ? { notice: UNTRUSTED_NOTICE, events: input.map((p) => commandInput(p).event) } : commandInput(input);\n return JSON.stringify(body, null, 2) + \"\\n\";\n}\n\n/** Running commands, so a forced exit (second Ctrl-C) can still kill their process groups and remove temp files. */\nconst active = new Map<number, string>();\n\n/** Synchronous last-resort cleanup before process.exit. */\nexport function killAllRuns(): void {\n for (const [pid, dir] of active) {\n killGroup(pid, \"SIGKILL\");\n rmSync(dir, { recursive: true, force: true });\n }\n active.clear();\n}\n\nfunction groupAlive(pid: number | undefined): boolean {\n if (!pid) return false;\n try {\n process.kill(-pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction killGroup(pid: number | undefined, signal: NodeJS.Signals): void {\n if (!pid) return;\n try {\n // Negative pid: the whole process group (the child is its leader thanks to `detached`).\n process.kill(-pid, signal);\n } catch {\n // Already gone.\n }\n}\n\n/**\n * Runs the configured command for one event, or for a batch (an array). The command string is fixed\n * configuration and goes to `/bin/sh -c` verbatim; it is never built from event data. The events reach\n * the command only as JSON on stdin, as a 0600 file named by XAQ_EVENT_FILE, and as a few\n * validated ids in env. On timeout the whole process group gets SIGTERM, then SIGKILL after a grace period.\n */\nexport function runCommand(command: string, payload: WebhookPayload | WebhookPayload[], opts: { timeoutMs: number; cwd?: string; signal?: AbortSignal }): Promise<CommandResult> {\n const started = performance.now();\n const input = commandStdin(payload);\n // mkdtemp creates the directory 0700; the file inside is 0600 on top.\n const dir = mkdtempSync(join(tmpdir(), \"xaq-event-\"));\n const eventFile = join(dir, \"event.json\");\n writeFileSync(eventFile, input, { mode: 0o600, flag: \"wx\" });\n\n return new Promise<CommandResult>((resolve) => {\n const stdout = new Tail();\n const stderr = new Tail();\n let timedOut = false;\n let settled = false;\n let killTimer: NodeJS.Timeout | undefined;\n\n const child = spawn(\"/bin/sh\", [\"-c\", command], {\n cwd: opts.cwd,\n env: childEnv(payload, eventFile),\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n detached: true,\n });\n\n if (child.pid) active.set(child.pid, dir);\n\n let terminatedAt: number | null = null;\n\n const finish = (r: Omit<CommandResult, \"durationMs\" | \"stdoutTail\" | \"stderrTail\" | \"timedOut\">) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n clearTimeout(killTimer);\n opts.signal?.removeEventListener(\"abort\", onAbort);\n void (async () => {\n if (terminatedAt !== null) {\n // sh is gone, but what it started may not be: wait out the grace period for the group to\n // exit on SIGTERM, then SIGKILL whatever is left.\n while (groupAlive(child.pid) && Date.now() - terminatedAt < KILL_GRACE_MS) await new Promise((res) => setTimeout(res, 100));\n killGroup(child.pid, \"SIGKILL\");\n }\n if (child.pid) active.delete(child.pid);\n // Background processes that inherited the pipes must not keep us waiting.\n await new Promise((res) => setTimeout(res, 50));\n child.stdout?.destroy();\n child.stderr?.destroy();\n rmSync(dir, { recursive: true, force: true });\n resolve({ ...r, ok: r.ok && !timedOut, timedOut, durationMs: Math.round(performance.now() - started), stdoutTail: stdout.toString(), stderrTail: stderr.toString() });\n })();\n };\n\n const terminate = () => {\n if (terminatedAt !== null) return;\n terminatedAt = Date.now();\n killGroup(child.pid, \"SIGTERM\");\n killTimer = setTimeout(() => killGroup(child.pid, \"SIGKILL\"), KILL_GRACE_MS);\n killTimer.unref();\n };\n const timer = setTimeout(() => {\n timedOut = true;\n terminate();\n }, opts.timeoutMs);\n const onAbort = () => terminate();\n opts.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n child.stdout.on(\"data\", (c: Buffer) => stdout.push(c));\n child.stderr.on(\"data\", (c: Buffer) => stderr.push(c));\n // A command that doesn't read stdin closes the pipe early: that's fine.\n child.stdin.on(\"error\", () => {});\n child.stdin.end(input);\n\n child.on(\"error\", (err) => finish({ ok: false, exitCode: null, signal: null, error: `Could not start /bin/sh: ${err.message}` }));\n child.on(\"exit\", (code, signal) => {\n const error = timedOut\n ? `Timed out after ${Math.round(opts.timeoutMs / 1000)} s; the process group was killed`\n : signal\n ? `Killed by ${signal}`\n : code !== 0\n ? `Exited with code ${code}`\n : null;\n finish({ ok: code === 0 && !signal, exitCode: code, signal: signal ?? null, error });\n });\n });\n}\n","import { appendFileSync, existsSync, renameSync, rmSync, statSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport pc from \"picocolors\";\nimport { ensurePrivateDir, tighten } from \"./fsutil.ts\";\n\n// eslint-disable-next-line no-control-regex\nconst ANSI = /\\x1b\\[[0-9;]*m/g;\n\nexport type Level = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport interface ListenLogger {\n debug(msg: string, meta?: Record<string, unknown>): void;\n info(msg: string, meta?: Record<string, unknown>): void;\n warn(msg: string, meta?: Record<string, unknown>): void;\n error(msg: string, meta?: Record<string, unknown>): void;\n}\n\nexport interface LogFileOptions {\n path: string | null;\n /** Rotate when the file passes this size. */\n maxBytes?: number;\n /** Rotated files kept (listen.log.1 … .N). */\n keep?: number;\n /** Console output: friendly one-liners (meta is file-only). */\n console?: boolean;\n debug?: boolean;\n}\n\n/**\n * Structured JSONL log in the state dir (rotated by size, 0600) plus friendly console lines.\n * Meta values go to the file only; the console shows the message.\n */\nexport function createListenLogger(opts: LogFileOptions): ListenLogger {\n const maxBytes = opts.maxBytes ?? 5 * 1024 * 1024;\n const keep = opts.keep ?? 3;\n let size = -1;\n if (opts.path) {\n ensurePrivateDir(dirname(opts.path));\n tighten(opts.path);\n }\n\n const rotate = (path: string) => {\n rmSync(`${path}.${keep}`, { force: true });\n for (let i = keep - 1; i >= 1; i--) if (existsSync(`${path}.${i}`)) renameSync(`${path}.${i}`, `${path}.${i + 1}`);\n renameSync(path, `${path}.1`);\n size = 0;\n };\n\n const toFile = (level: Level, msg: string, meta?: Record<string, unknown>) => {\n if (!opts.path) return;\n const line = JSON.stringify({ ts: new Date().toISOString(), level, msg: msg.replace(ANSI, \"\"), ...meta }) + \"\\n\";\n try {\n if (size < 0) size = existsSync(opts.path) ? statSync(opts.path).size : 0;\n if (size + line.length > maxBytes && size > 0) rotate(opts.path);\n appendFileSync(opts.path, line, { mode: 0o600 });\n size += Buffer.byteLength(line);\n } catch {\n // Logging must never take the listener down (disk full, dir removed…).\n }\n };\n\n const colors: Record<Level, (s: string) => string> = { debug: pc.gray, info: (s) => s, warn: pc.yellow, error: pc.red };\n const toConsole = (level: Level, msg: string) => {\n if (opts.console === false || (level === \"debug\" && !opts.debug)) return;\n const ts = pc.gray(new Date().toTimeString().slice(0, 8));\n const tag = level === \"warn\" ? pc.yellow(\"warn \") : level === \"error\" ? pc.red(\"error \") : \"\";\n // Callers sanitize untrusted parts (subjects, senders, command output) with safeText.\n const text = msg.split(\"\\n\").join(\"\\n \");\n (level === \"error\" || level === \"warn\" ? process.stderr : process.stdout).write(`${ts} ${tag}${colors[level](text)}\\n`);\n };\n\n const emit = (level: Level) => (msg: string, meta?: Record<string, unknown>) => {\n toFile(level, msg, meta);\n toConsole(level, msg);\n };\n return { debug: emit(\"debug\"), info: emit(\"info\"), warn: emit(\"warn\"), error: emit(\"error\") };\n}\n","import { appendFileSync, existsSync, readFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport type { EventType, WebhookPayload } from \"../../shared/types.ts\";\nimport type { Target } from \"./dispatcher.ts\";\nimport { ensurePrivateDir, tighten, writePrivateFile } from \"./fsutil.ts\";\nimport { join } from \"node:path\";\nimport { deadPath, profileStateDir, statusPath } from \"./paths.ts\";\n\n// ───────────── Dead letters ─────────────\n\nexport interface DeadEntry {\n deadAt: string;\n seq: number;\n id: string;\n type: EventType;\n attempts: number;\n error: string;\n /** Targets that never succeeded (a replay only re-runs these). */\n targets: Target[];\n payload: WebhookPayload;\n}\n\nexport function appendDead(profile: string, entry: DeadEntry): void {\n const path = deadPath(profile);\n ensurePrivateDir(dirname(path));\n appendFileSync(path, JSON.stringify(entry) + \"\\n\", { mode: 0o600 });\n tighten(path);\n}\n\nexport function readDead(profile: string): DeadEntry[] {\n const path = deadPath(profile);\n if (!existsSync(path)) return [];\n const out: DeadEntry[] = [];\n for (const line of readFileSync(path, \"utf8\").split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n out.push(JSON.parse(line) as DeadEntry);\n } catch {\n // A torn last line after a crash: skip it.\n }\n }\n return out;\n}\n\nexport function writeDead(profile: string, entries: DeadEntry[]): void {\n writePrivateFile(deadPath(profile), entries.map((e) => JSON.stringify(e) + \"\\n\").join(\"\"));\n}\n\n// ───────────── Consumers this machine has used (the daemon creates a cursor on first connect) ─────────────\n\nconst consumersPath = (profile: string) => join(profileStateDir(profile), \"consumers.json\");\n\nexport function knownConsumers(profile: string): string[] {\n const list: string[] = [];\n try {\n const parsed = JSON.parse(readFileSync(consumersPath(profile), \"utf8\")) as unknown;\n if (Array.isArray(parsed)) list.push(...parsed.filter((c): c is string => typeof c === \"string\"));\n } catch {\n // None yet.\n }\n const last = readStatus(profile)?.consumer;\n if (last && !list.includes(last)) list.push(last);\n return list;\n}\n\nexport function rememberConsumer(profile: string, consumer: string): void {\n const list = knownConsumers(profile);\n if (list.includes(consumer)) return;\n try {\n writePrivateFile(consumersPath(profile), JSON.stringify([...list, consumer]) + \"\\n\");\n } catch {\n // Best effort: only affects the first-run hints.\n }\n}\n\n// ───────────── Status (for `listen status`) ─────────────\n\nexport interface RecentEvent {\n seq: number;\n id: string;\n type: EventType;\n outcome: \"succeeded\" | \"dead\" | \"skipped\" | \"retrying\";\n attempts: number;\n at: string;\n error?: string | null;\n}\n\nexport interface ListenStatus {\n pid: number;\n profile: string;\n url: string;\n consumer: string;\n version: string;\n startedAt: string;\n connected: boolean;\n connectedSince: string | null;\n lastDisconnect: { at: string; reason: string } | null;\n lastEventAt: string | null;\n receivedSeq: number;\n ackedSeq: number;\n running: number;\n recent: RecentEvent[];\n stoppedAt: string | null;\n exitReason: string | null;\n /** What the (last) run executed, flags included. */\n exec?: string | null;\n forward?: string | null;\n /** The (last) run's filters in words, and its --batch window. */\n filters?: string;\n batchSeconds?: number;\n /** Events the filters skipped this run (acknowledged without running anything). */\n skipped?: number;\n}\n\nexport function readStatus(profile: string): ListenStatus | null {\n try {\n return JSON.parse(readFileSync(statusPath(profile), \"utf8\")) as ListenStatus;\n } catch {\n return null;\n }\n}\n\n/** Writes status.json at most once a second (and immediately on `flush`). */\nexport class StatusWriter {\n private timer: NodeJS.Timeout | null = null;\n constructor(\n private readonly profile: string,\n readonly status: ListenStatus,\n /** false: keep the status in memory only (a one-off backfill must not overwrite the listener's status.json). */\n private readonly persist = true,\n ) {}\n\n update(patch: Partial<ListenStatus>): void {\n Object.assign(this.status, patch);\n if (this.timer) return;\n this.timer = setTimeout(() => this.flush(), 1000);\n this.timer.unref();\n }\n\n addRecent(e: RecentEvent): void {\n this.status.recent = [e, ...this.status.recent.filter((r) => r.seq !== e.seq)].slice(0, 20);\n this.update({});\n }\n\n flush(): void {\n if (this.timer) clearTimeout(this.timer);\n this.timer = null;\n if (!this.persist) return;\n try {\n writePrivateFile(statusPath(this.profile), JSON.stringify(this.status, null, 2) + \"\\n\");\n } catch {\n // Status is best effort.\n }\n }\n}\n\n/** Whether a process with this pid is alive (status.json may be left over from a crash). */\nexport function pidAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n return (err as NodeJS.ErrnoException).code === \"EPERM\";\n }\n}\n","import { closeSync, constants, openSync, readFileSync, rmSync, writeSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { ensurePrivateDir } from \"./fsutil.ts\";\nimport { profileStateDir } from \"./paths.ts\";\nimport { pidAlive } from \"./state.ts\";\nimport { NPX } from \"./version.ts\";\n\n/**\n * One listener per profile: two would share a consumer cursor and run every event twice. The lock is\n * a file with the owner's pid and start time, created exclusively; a lock whose process is gone is\n * stale and taken over.\n */\n\nexport const lockPath = (profile: string) => join(profileStateDir(profile), \"listen.lock\");\n\nexport interface LockInfo {\n pid: number;\n startedAt: string;\n}\n\nexport class ProfileLockedError extends Error {\n constructor(\n readonly holder: LockInfo,\n profile: string,\n ) {\n super(\n `Another listener is already running profile \"${profile}\" (pid ${holder.pid}, since ${holder.startedAt}).\\n` +\n ` If it's the background service, check it with \\`${NPX} listen service status${profile === \"default\" ? \"\" : ` --profile ${profile}`}\\`; stop it before running one in the foreground.`,\n );\n }\n}\n\nfunction readLock(path: string): LockInfo | null {\n try {\n const info = JSON.parse(readFileSync(path, \"utf8\")) as LockInfo;\n return typeof info.pid === \"number\" ? info : null;\n } catch {\n return null;\n }\n}\n\n/** Lock files held by this process (a second in-process holder has the same pid). */\nconst held = new Set<string>();\n\n/**\n * Takes an exclusive lock file (pid + start time, created with O_EXCL) or throws `busy(holder)`. A lock\n * whose process is gone is stale and taken over. Returns a release function (also run on process exit).\n */\nexport function acquireFileLock(path: string, busy: (holder: LockInfo) => Error): () => void {\n ensurePrivateDir(dirname(path));\n const mine: LockInfo = { pid: process.pid, startedAt: new Date().toISOString() };\n if (held.has(path)) throw busy(readLock(path) ?? mine);\n for (let attempt = 0; attempt < 3; attempt++) {\n try {\n const fd = openSync(path, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);\n writeSync(fd, JSON.stringify(mine));\n closeSync(fd);\n held.add(path);\n let released = false;\n const release = () => {\n if (released) return;\n released = true;\n held.delete(path);\n process.off(\"exit\", release);\n // Only remove it if it is still ours.\n if (readLock(path)?.pid === process.pid) rmSync(path, { force: true });\n };\n process.on(\"exit\", release);\n return release;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"EEXIST\") throw err;\n }\n const holder = readLock(path);\n if (holder && holder.pid !== process.pid && pidAlive(holder.pid)) throw busy(holder);\n // Stale (crashed process) or unreadable: take it over.\n rmSync(path, { force: true });\n }\n throw new Error(`Could not take the lock ${path}.`);\n}\n\n/** Takes the profile's listener lock or throws ProfileLockedError. */\nexport function acquireProfileLock(profile: string): () => void {\n return acquireFileLock(lockPath(profile), (holder) => new ProfileLockedError(holder, profile));\n}\n\n/**\n * `listen --backfill` has its own lock: it uses its own cursor, so it runs fine next to the profile's\n * listener (or its service), but two backfills at once would run every stored event twice.\n */\nexport const backfillLockPath = (profile: string) => join(profileStateDir(profile), \"backfill.lock\");\n\nexport function acquireBackfillLock(profile: string): () => void {\n return acquireFileLock(\n backfillLockPath(profile),\n (holder) => new Error(`A backfill is already running for profile \"${profile}\" (pid ${holder.pid}, since ${holder.startedAt}). Let it finish, or stop it first.`),\n );\n}\n","/** Minimal, spec-following text/event-stream parser (https://html.spec.whatwg.org/multipage/server-sent-events.html). */\n\nexport interface SseMessage {\n id: string | null;\n event: string;\n data: string;\n}\n\nexport class SseParser {\n private buf = \"\";\n private data: string[] = [];\n private event = \"\";\n private id: string | null = null;\n\n constructor(\n private readonly onMessage: (m: SseMessage) => void,\n private readonly onComment: (text: string) => void = () => {},\n ) {}\n\n push(chunk: string): void {\n this.buf += chunk;\n // A lone \\r at the end may be the first half of \\r\\n: keep it for the next chunk.\n for (;;) {\n const m = /\\r\\n|\\r|\\n/.exec(this.buf);\n if (!m) break;\n if (m[0] === \"\\r\" && m.index === this.buf.length - 1) break;\n const line = this.buf.slice(0, m.index);\n this.buf = this.buf.slice(m.index + m[0].length);\n this.line(line);\n }\n }\n\n private line(line: string): void {\n if (line === \"\") {\n if (this.data.length) this.onMessage({ id: this.id, event: this.event || \"message\", data: this.data.join(\"\\n\") });\n this.data = [];\n this.event = \"\";\n return;\n }\n if (line.startsWith(\":\")) {\n this.onComment(line.slice(1).trim());\n return;\n }\n const colon = line.indexOf(\":\");\n const field = colon < 0 ? line : line.slice(0, colon);\n let value = colon < 0 ? \"\" : line.slice(colon + 1);\n if (value.startsWith(\" \")) value = value.slice(1);\n if (field === \"data\") this.data.push(value);\n else if (field === \"event\") this.event = value;\n else if (field === \"id\" && !value.includes(\"\\0\")) this.id = value;\n // \"retry\" is ignored: reconnect timing is ours (jittered backoff).\n }\n}\n","import type { EventType } from \"../../shared/types.ts\";\nimport { abortable } from \"./abortable.ts\";\nimport { apiError, clientHeader, describeFetchError, userAgent } from \"./api.ts\";\nimport { SseParser, type SseMessage } from \"./sse.ts\";\nimport { safeText } from \"./ui.ts\";\n\nexport type StreamEnd = { kind: \"revoked\"; code: string; reason: string } | { kind: \"fatal\"; reason: string } | { kind: \"stopped\" };\n\n/**\n * Why the daemon refused or ended the stream. Permanent ones end the listener (exit 78); reversible\n * ones (an admin disabled the agent, or took away its last read grant) keep it waiting.\n */\nexport const REFUSALS: Record<string, { permanent: boolean; text: string }> = {\n agent_deleted: { permanent: true, text: \"This agent was deleted in the xaq console.\" },\n key_rotated: { permanent: true, text: \"This agent's API key was replaced (rotated) in the console.\" },\n unauthorized: { permanent: true, text: \"The daemon doesn't recognize this API key (it was rotated, or the agent was deleted).\" },\n agent_disabled: { permanent: false, text: \"An admin disabled this agent. Waiting; it resumes on its own when the agent is re-enabled.\" },\n no_read_grant: { permanent: false, text: \"This agent has no read access to any mailbox or calendar right now. Waiting; it resumes when an admin grants read or calendar.read.\" },\n forbidden: { permanent: false, text: \"The daemon refused access for now. Waiting and retrying.\" },\n};\n\n/** Classifies an HTTP refusal or a `revoked` reason code. 401 is permanent; 403 is reversible unless its code says otherwise. */\nexport function classifyRefusal(code: string | null, status?: number): { code: string; permanent: boolean; text: string } {\n const known = code && REFUSALS[code] ? code : status === 401 ? \"unauthorized\" : status === 403 ? \"forbidden\" : code ? null : \"unauthorized\";\n if (known) return { code: known, ...REFUSALS[known]! };\n // An unknown `revoked` reason: assume permanent (that's what the event means), but show it.\n return { code: code!, permanent: true, text: `Access revoked (${code}).` };\n}\n\nconst BLOCKED_RETRY_MS = 60_000;\n\nexport interface StreamOptions {\n url: string;\n apiKey: string;\n consumer: string;\n types?: EventType[];\n includeBody?: boolean;\n /** `after=<seq>` on every connect (dry runs start at the current head). */\n after?: number;\n /** Ask the daemon to start a new consumer at the oldest event (`start=beginning`) instead of the head. */\n fromStart?: boolean;\n /** Highest seq received so far, sent as Last-Event-ID on reconnect (0 = let the server cursor decide). */\n lastEventId: () => number;\n onOpen: () => void;\n onMessage: (m: SseMessage) => void;\n /** Connection lost / failed; reconnecting after `retryInMs`. */\n onDisconnect: (reason: string, retryInMs: number, opts: { serious: boolean }) => void;\n /** Reversible refusal (agent disabled, no read grant): the stream keeps retrying slowly. */\n onBlocked?: (code: string, text: string) => void;\n /** Wait between attempts while blocked (default 60 s). */\n blockedRetryMs?: number;\n /** Runs before every connection attempt; a returned reason refuses this attempt (re-checked transport). */\n beforeConnect?: () => Promise<string | null>;\n /** True while the local backlog is too large: the stream disconnects and resumes once it drains. */\n shouldPause?: () => boolean;\n /** Silence (no events, no pings) after which the connection is presumed dead. The server pings every 15 s. */\n stallMs?: number;\n minBackoffMs?: number;\n maxBackoffMs?: number;\n /** Tests: the fetch implementation (default: global fetch). */\n fetch?: typeof fetch;\n}\n\n\nclass Stalled extends Error {}\nclass Paused extends Error {}\nclass Reconnect extends Error {}\n\nconst sleepJump = 20_000;\n\n/**\n * Holds the outbound event stream open forever: reconnects with jittered exponential backoff,\n * resumes with Last-Event-ID (the server also resumes from the consumer's acked cursor), treats\n * ~45 s of silence as a dead connection, and reconnects at once after the machine wakes from sleep.\n * Only permanent revocation (401, or `event: revoked` for a deleted agent or replaced key) and\n * unrecoverable request errors end it; a disabled agent or a missing read grant just waits.\n */\nexport class EventStream {\n private stopped = false;\n private current: AbortController | null = null;\n private wake: (() => void) | null = null;\n private failures = 0;\n\n constructor(private readonly o: StreamOptions) {}\n\n stop(): void {\n this.stopped = true;\n this.current?.abort();\n this.wake?.();\n }\n\n /** Forces a reconnect now (network change, wake from sleep). */\n reconnect(): void {\n this.failures = 0;\n this.current?.abort(new Reconnect(\"reconnect requested\"));\n this.wake?.();\n }\n\n private sleep(ms: number): Promise<void> {\n // stop() may have come while we weren't sleeping (its wake-up went to an earlier sleep).\n if (this.stopped) return Promise.resolve();\n return new Promise((resolve) => {\n const t = setTimeout(done, ms);\n function done() {\n clearTimeout(t);\n resolve();\n }\n this.wake = done;\n });\n }\n\n private backoff(): number {\n const min = this.o.minBackoffMs ?? 1000;\n const max = this.o.maxBackoffMs ?? 60_000;\n const cap = Math.min(max, min * 2 ** Math.min(this.failures, 16));\n // Full jitter, but never below `min`, so a fleet of laptops waking together doesn't stampede.\n return Math.round(min + Math.random() * (cap - min));\n }\n\n private streamUrl(): string {\n const u = new URL(`${this.o.url}/agent/v1/events/stream`);\n u.searchParams.set(\"consumer\", this.o.consumer);\n if (this.o.types?.length) u.searchParams.set(\"types\", this.o.types.join(\",\"));\n if (this.o.includeBody) u.searchParams.set(\"include_body\", \"1\");\n if (this.o.fromStart) u.searchParams.set(\"start\", \"beginning\");\n if (this.o.after) u.searchParams.set(\"after\", String(this.o.after));\n return u.toString();\n }\n\n async run(): Promise<StreamEnd> {\n // Laptop sleep: timers stall while suspended, so a big jump in wall-clock time means we just woke up.\n let lastTick = Date.now();\n const sleepWatch = setInterval(() => {\n const now = Date.now();\n if (now - lastTick > sleepJump) this.reconnect();\n lastTick = now;\n }, 5000);\n sleepWatch.unref();\n try {\n while (!this.stopped) {\n while (this.o.shouldPause?.() && !this.stopped) await this.sleep(250);\n if (this.stopped) break;\n const result = await this.connectOnce();\n if (result) return result;\n }\n return { kind: \"stopped\" };\n } finally {\n clearInterval(sleepWatch);\n }\n }\n\n /** One connection. Returns a terminal result, or null to reconnect (after waiting, unless paused). */\n private async connectOnce(): Promise<StreamEnd | null> {\n const ac = new AbortController();\n this.current = ac;\n const stallMs = this.o.stallMs ?? 45_000;\n let stallTimer: NodeJS.Timeout | undefined;\n const armStall = () => {\n clearTimeout(stallTimer);\n stallTimer = setTimeout(() => ac.abort(new Stalled(`no data or ping for ${Math.round(stallMs / 1000)} s`)), stallMs);\n };\n const opened = Date.now();\n let delivered = false;\n let revoked: string | null = null;\n\n try {\n const refused = await this.o.beforeConnect?.();\n if (refused) {\n this.failures++;\n const wait = Math.max(this.backoff(), 30_000);\n this.disconnected(refused, wait, true);\n await this.sleep(wait);\n return null;\n }\n const headers: Record<string, string> = {\n accept: \"text/event-stream\",\n authorization: `Bearer ${this.o.apiKey}`,\n \"cache-control\": \"no-cache\",\n \"user-agent\": userAgent(),\n \"x-agentinbox-client\": clientHeader(),\n };\n const last = this.o.lastEventId();\n if (last > 0) headers[\"last-event-id\"] = String(last);\n armStall();\n const pending = (this.o.fetch ?? fetch)(this.streamUrl(), { headers, signal: ac.signal, redirect: \"error\" });\n // If abort wins, release whatever the fetch still produces.\n pending.then((r) => (ac.signal.aborted ? r.body?.cancel().catch(() => {}) : undefined)).catch(() => {});\n const res = await abortable(pending, ac.signal);\n if (!res.ok) {\n const err = await abortable(apiError(res, \"Opening the event stream\"), ac.signal);\n if (res.status === 401 || res.status === 403) {\n const r = classifyRefusal(err.code, res.status);\n if (r.permanent) return { kind: \"revoked\", code: r.code, reason: r.text };\n clearTimeout(stallTimer);\n this.o.onBlocked?.(r.code, r.text);\n await this.sleep(this.o.blockedRetryMs ?? BLOCKED_RETRY_MS);\n return null;\n }\n if (res.status === 400 || res.status === 422) return { kind: \"fatal\", reason: err.message };\n clearTimeout(stallTimer);\n const longWait = res.status === 404 ? 300_000 : null;\n if (res.status === 404) {\n this.disconnected(\"This xaq server has no /agent/v1 event stream (upgrade the daemon). Retrying in 5 minutes\", longWait!, true);\n await this.sleep(longWait!);\n } else {\n this.failures++;\n const wait = err.retryAfter ? err.retryAfter * 1000 : this.backoff();\n this.disconnected(err.message, wait, res.status >= 500 || res.status === 429 ? false : true);\n await this.sleep(wait);\n }\n return null;\n }\n if (!(res.headers.get(\"content-type\") ?? \"\").includes(\"text/event-stream\") || !res.body) {\n throw new Error(`expected text/event-stream, got ${res.headers.get(\"content-type\") ?? \"no content type\"}`);\n }\n this.o.onOpen();\n armStall();\n\n const parser = new SseParser(\n (m) => {\n if (m.event === \"revoked\") {\n let reason = \"unauthorized\";\n try {\n const r = (JSON.parse(m.data) as { reason?: unknown }).reason;\n if (typeof r === \"string\" && r) reason = safeText(r, 60);\n } catch {\n // Keep the default.\n }\n revoked = reason;\n ac.abort();\n return;\n }\n delivered = true;\n this.o.onMessage(m);\n if (this.o.shouldPause?.()) ac.abort(new Paused(\"backlog full\"));\n },\n () => {},\n );\n const decoder = new TextDecoder();\n const reader = res.body.getReader();\n // Cancel the body on abort (stop, stall, pause, reconnect, revoked), and never wait on a read\n // that undici fails to settle.\n const cancel = () => void reader.cancel().catch(() => {});\n ac.signal.addEventListener(\"abort\", cancel, { once: true });\n try {\n for (;;) {\n const { done, value } = await abortable(reader.read(), ac.signal);\n if (done) break;\n armStall();\n parser.push(decoder.decode(value, { stream: true }));\n if (revoked !== null) break;\n }\n } finally {\n ac.signal.removeEventListener(\"abort\", cancel);\n cancel();\n }\n if (revoked !== null) return this.afterRevoked(revoked);\n throw new Error(\"the server closed the stream\");\n } catch (err) {\n if (revoked !== null) return this.afterRevoked(revoked);\n if (this.stopped) return { kind: \"stopped\" };\n const reason = ac.signal.aborted && ac.signal.reason instanceof Error ? ac.signal.reason : err;\n if (reason instanceof Paused) return null;\n // A connection that was healthy for a while (or delivered events) starts the backoff over.\n if (delivered || Date.now() - opened > 60_000) this.failures = 0;\n if (reason instanceof Reconnect) {\n this.disconnected(\"reconnecting (network change or wake from sleep)\", 0, false);\n return null;\n }\n this.failures++;\n const wait = this.backoff();\n const text = reason instanceof Stalled ? `stream stalled (${reason.message})` : describeFetchError(reason);\n this.disconnected(text, wait, this.failures > 3);\n await this.sleep(wait);\n return null;\n } finally {\n clearTimeout(stallTimer);\n ac.abort();\n this.current = null;\n }\n }\n\n /** `event: revoked`: permanent reasons end the listener; reversible ones wait and retry. */\n private async afterRevoked(code: string): Promise<StreamEnd | null> {\n const r = classifyRefusal(code);\n if (r.permanent) return { kind: \"revoked\", code: r.code, reason: r.text };\n this.o.onBlocked?.(r.code, r.text);\n await this.sleep(this.o.blockedRetryMs ?? BLOCKED_RETRY_MS);\n return null;\n }\n\n private disconnected(reason: string, wait: number, serious: boolean): void {\n if (!this.stopped) this.o.onDisconnect(reason, wait, { serious });\n }\n}\n","import { hostname } from \"node:os\";\nimport pc from \"picocolors\";\nimport type { WebhookPayload } from \"../../shared/types.ts\";\nimport { envVar, underService } from \"../brand.ts\";\nimport { ackEvents, ApiError, getSelf } from \"./api.ts\";\nimport { Dispatcher, type Job, type Target } from \"./dispatcher.ts\";\nimport { parsePayload, skipReason } from \"./event.ts\";\nimport { killAllRuns, runCommand } from \"./exec.ts\";\nimport { existsSync } from \"node:fs\";\nimport { ensurePrivateDir } from \"./fsutil.ts\";\nimport { claudeMcpConfigPath, writeClaudeMcpConfig } from \"./mcpheader.ts\";\nimport { forwardEvent } from \"./forward.ts\";\nimport { createListenLogger, type ListenLogger } from \"./logfile.ts\";\nimport { categoryNote, describeFilter, type EffectiveConfig, type ListenFlags, MAX_BATCH, resolveListen, THROWAWAY_SUFFIXES, throwawayConsumer, typesNotes } from \"./options.ts\";\nimport { oneOffLogPath, DEFAULT_PROFILE, logPath, validProfileName } from \"./paths.ts\";\nimport { describeGrants, grantsKey, hasAccess } from \"./grants.ts\";\nimport { gatewayWarning, routeWarning } from \"./hermes.ts\";\nimport { hermesChangeNote, isHermesRoute, recipeOf, recipeToolFor, shellQuote, SILENT_MARKER, TOOL_LABELS } from \"./recipes.ts\";\nimport { loadProfile, type Profile, saveProfile } from \"./profile.ts\";\nimport { acquireBackfillLock, acquireProfileLock } from \"./lock.ts\";\nimport { appendDead, knownConsumers, rememberConsumer, StatusWriter } from \"./state.ts\";\nimport { EventStream } from \"./stream.ts\";\nimport { checkTransport, insecureBanner } from \"./transport.ts\";\nimport { formatDuration, safeText } from \"./ui.ts\";\nimport { NPX, version } from \"./version.ts\";\n\n/** Exit codes. 78 (EX_CONFIG) means \"don't restart me\": the service units are told not to. */\nexport const EXIT = { ok: 0, error: 1, revoked: 78 } as const;\n\nexport interface RunListenerOptions {\n flags: ListenFlags;\n /** Stops the listener (tests); the CLI uses SIGINT/SIGTERM. */\n signal?: AbortSignal;\n handleSignals?: boolean;\n log?: ListenLogger;\n /** Test knobs. */\n retryDelayMs?: (attempt: number) => number;\n stallMs?: number;\n minBackoffMs?: number;\n maxBackoffMs?: number;\n blockedRetryMs?: number;\n /** Time a service waits before exiting after revocation where the supervisor can't be told not to restart (launchd). */\n revokedExitDelayMs?: number;\n /** How often the agent's access (GET /me) is re-read, so the log shows grant changes. Default 5 min. */\n grantsRefreshMs?: number;\n /**\n * --backfill safety net: quiet time (nothing received, nothing running) after which the rest up to the\n * end is taken to be invisible to this listener (types filter, label scope, retention). Default 60 s.\n */\n backfillIdleMs?: number;\n /** --backfill gives up when the daemon stays unreachable this long. Default 10 min. */\n backfillUnreachableMs?: number;\n}\n\n/** Acknowledges the finished prefix, coalescing and retrying in the background. */\nclass Acker {\n private wanted = 0;\n acked = 0;\n private busy: Promise<void> | null = null;\n private retry: NodeJS.Timeout | null = null;\n constructor(\n private readonly post: (seq: number) => Promise<number>,\n private readonly log: ListenLogger,\n ) {}\n\n request(seq: number): void {\n this.wanted = Math.max(this.wanted, seq);\n this.kick();\n }\n\n private kick(): void {\n if (this.busy || this.retry || this.wanted <= this.acked) return;\n const seq = this.wanted;\n this.busy = this.post(seq)\n .then((acked) => {\n this.acked = Math.max(this.acked, acked, seq);\n })\n .catch((err: unknown) => {\n this.log.debug(`ack failed, retrying: ${err instanceof Error ? err.message : String(err)}`, { seq });\n this.retry = setTimeout(() => {\n this.retry = null;\n this.kick();\n }, 5000);\n this.retry.unref();\n })\n .finally(() => {\n this.busy = null;\n this.kick();\n });\n }\n\n /** Best-effort final ack on shutdown. */\n async flush(timeoutMs = 3000): Promise<void> {\n if (this.retry) clearTimeout(this.retry);\n this.retry = null;\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (this.busy) await Promise.race([this.busy, new Promise((r) => setTimeout(r, 100))]);\n else if (this.wanted > this.acked) {\n this.kick();\n if (this.retry) break;\n } else return;\n }\n }\n}\n\nconst describeEvent = (p: WebhookPayload) => {\n const m = p.data.message;\n const e = p.data.calendarEvent;\n const sender = m?.from?.email ?? (e && !e.organizerSelf ? e.organizer?.email : undefined);\n const who = sender ? ` from ${safeText(sender, 80)}` : \"\";\n const title = m?.subject ?? e?.summary;\n const subject = title ? ` \"${safeText(title, 70)}\"` : \"\";\n return `#${p.data.seq} ${p.type}${who}${subject}${e ? ` (${safeText(e.start, 30)})` : \"\"}`;\n};\n\n/** A finished job in the log: the event, or \"batch of N (#a–#b)\". */\nconst describeJob = (job: Job) =>\n job.payloads.length === 1 ? describeEvent(job.payload) : `batch of ${job.payloads.length} events (#${job.seq}–#${job.lastSeq})`;\n\n/** The last few non-empty lines of a command's output, for the log (sanitized: it may echo email content). */\nconst lastLines = (t: string, n = 3) =>\n t\n .trim()\n .split(\"\\n\")\n .filter((l) => l.trim())\n .slice(-n)\n .map((l) => ` │ ${safeText(l, 300)}`)\n .join(\"\\n\");\n\n/** The agent's whole reply was the triage prompt's \"nothing to do\" (anything more is shown). */\nexport const isSilent = (stdout: string) => stdout.trim() === SILENT_MARKER;\n\nexport async function runListener(opts: RunListenerOptions): Promise<number> {\n const profileName = validProfileName(opts.flags.profile ?? DEFAULT_PROFILE);\n let profile: Profile = loadProfile(profileName);\n const { config, next, changed } = resolveListen(profileName, profile, opts.flags);\n if (changed) {\n saveProfile(profileName, next);\n profile = next;\n }\n // Under launchd, stdout goes to a file nobody rotates; the rotated listen.log already has everything.\n const quietConsole = underService() && process.platform === \"darwin\";\n const backfill = !!opts.flags.backfill;\n const oneOff = backfill || !!opts.flags.dryRun;\n const log = opts.log ?? createListenLogger({ path: oneOff ? oneOffLogPath(profileName) : logPath(profileName), debug: !!envVar(\"DEBUG\"), console: !quietConsole });\n if (opts.flags.save) log.info(`Saved these settings to profile \"${profileName}\".`);\n\n const verdict = await checkTransport(profile.url, { insecure: config.insecure });\n if (verdict.warning) {\n process.stderr.write(`${insecureBanner(verdict.warning)}\\n`);\n log.warn(verdict.warning);\n }\n\n const targets: Target[] = [];\n if (config.exec) targets.push(\"exec\");\n if (config.forward) targets.push(\"forward\");\n const dryRun = !!opts.flags.dryRun;\n if (!targets.length && !dryRun) {\n throw new Error(\n `Nothing to run for events. Pass --exec \"<command>\" and/or --forward http://localhost:<port>/<path> (add --save to keep it in profile \"${profileName}\"),\\n` +\n ` or --dry-run to just print matching events. Recipes: ${NPX} listen --help`,\n );\n }\n\n if (config.exec && process.platform === \"win32\" && !dryRun) {\n throw new Error(\"--exec needs a POSIX shell (/bin/sh) and isn't supported on Windows. Use --forward to a local HTTP handler instead.\");\n }\n\n // One listener per profile (they would share the cursor and run every event twice). A backfill has\n // its own throwaway cursor and lock, so it runs next to the listener; a dry run changes nothing.\n const releaseLock = dryRun ? () => {} : backfill ? acquireBackfillLock(profileName) : acquireProfileLock(profileName);\n try {\n // The daemon creates a consumer's cursor on its first connection (at the head, or at the oldest\n // event with --from-start); after that --from-start has no effect. Dry runs and backfills use their\n // own throwaway consumers that are never advanced, so they create nothing for the real listener.\n const fromStart = !!opts.flags.fromStart || backfill;\n const known = knownConsumers(profileName).includes(config.consumer);\n // A backfill (even a dry one) replays on its own cursor from the oldest event; a dry run peeks from the head.\n const streamConsumer = backfill\n ? throwawayConsumer(config.consumer, THROWAWAY_SUFFIXES.backfill)\n : dryRun\n ? throwawayConsumer(config.consumer, THROWAWAY_SUFFIXES.dryRun)\n : config.consumer;\n let streamAfter = 0;\n if (dryRun && !fromStart) {\n streamAfter = await getSelf(profile.url, profile.apiKey, 8000).then(\n (s) => s.headSeq ?? 0,\n () => 0,\n );\n }\n // --backfill = the mail from before this listener started: it ends where the listener's consumer\n // started on the daemon, so nothing the listener handles (or will handle) runs twice.\n const backfillHead = backfill ? await backfillEnd(profileName, profile, config.consumer, streamConsumer, opts.flags.until, log) : 0;\n const backfillHint = backfillCommand(profileName, profile, config);\n\n if (config.cwdIsDefault) ensurePrivateDir(config.cwd);\n // The Claude Code recipe loads this (keyless) MCP config; recreate it if it's missing.\n if (!existsSync(claudeMcpConfigPath(profileName))) writeClaudeMcpConfig(profileName, `${profile.url}/mcp`);\n if (!quietConsole) printBanner(log, profileName, profile, config, dryRun, backfill);\n // The default narrows what the listener gets without any flag: say so (also in the log file).\n const notes = typesNotes(config);\n for (const m of notes.info) log.info(m);\n for (const m of notes.warn) log.warn(m);\n const categories = categoryNote(profileName, profile, opts.flags, config);\n if (categories) log.info(categories);\n const change = hermesChangeNote(opts.flags.recipe, config.exec);\n if (change) log.info(change);\n if (config.forward && isHermesRoute(config.forward.url) && !dryRun) {\n void gatewayWarning(config.forward.url).then((w) => w && log.warn(w));\n const route = routeWarning(profileName, config.forward.url);\n if (route) log[route.level](route.message);\n }\n if (backfill && backfillHead === 0) {\n log.info(`Nothing to backfill: the listener (consumer \"${config.consumer}\") started with the oldest stored mail, so it handles all of it.`);\n return EXIT.ok;\n }\n if (backfill) {\n log.info(\n `Backfill: handling the mail from before the listener started (events up to #${backfillHead}), oldest first, then exiting${dryRun ? \" (dry run: nothing executed)\" : \"\"}. Everything newer is the listener's.`,\n );\n } else if (dryRun) {\n log.info(fromStart ? \"Dry run from the oldest stored event.\" : \"Dry run: showing new events from now on.\");\n } else if (fromStart && known) {\n log.warn(\n `This listener (consumer \"${config.consumer}\") already has a position on the daemon, so --from-start does nothing.\\n` +\n `--from-start only applies to a new consumer. To run the mail from before this listener started through it once (fine while it runs): ${backfillHint}`,\n );\n } else if (fromStart) {\n log.info(\"Processing every stored event this agent can see, from the oldest (--from-start).\");\n } else if (!known) {\n log.info(`Listening for new events from now on. To also run the mail from before this listener started, once (in another terminal, while this keeps running): ${backfillHint}`);\n }\n\n const status = new StatusWriter(profileName, {\n pid: process.pid,\n profile: profileName,\n url: profile.url,\n consumer: streamConsumer,\n version,\n startedAt: new Date().toISOString(),\n connected: false,\n connectedSince: null,\n lastDisconnect: null,\n lastEventAt: null,\n receivedSeq: 0,\n ackedSeq: 0,\n running: 0,\n recent: [],\n stoppedAt: null,\n exitReason: null,\n exec: config.exec,\n forward: config.forward?.url ?? null,\n filters: describeFilter(config),\n batchSeconds: config.batchSeconds,\n skipped: 0,\n }, !oneOff);\n status.flush();\n\n // Re-checked before every reconnect and ack: a *.ts.net / *.localhost name could start resolving elsewhere.\n const transportOk = () =>\n checkTransport(profile.url, { insecure: config.insecure }).then(\n () => null,\n (err: unknown) => (err instanceof Error ? err.message.split(\"\\n\")[0]! : String(err)),\n );\n\n // Who am I, and what may I do? Informational and not awaited: the stream itself decides whether the\n // key is valid. Re-read on reconnects and every few minutes, so a grant changed in the console shows up.\n let grantsSeen: string | null = null;\n let grantsBusy = false;\n const checkGrants = async () => {\n if (grantsBusy || (await transportOk())) return;\n grantsBusy = true;\n try {\n const self = await getSelf(profile.url, profile.apiKey, 8000);\n const key = grantsKey(self.grants, self.connections);\n if (key === grantsSeen) return;\n const first = grantsSeen === null;\n grantsSeen = key;\n const lines = describeGrants(self.grants, self.connections).map((l) => ` ${hasAccess(self) ? l : pc.yellow(l)}`);\n log.info(`${first ? `Signed in as agent \"${safeText(self.name)}\". Access` : \"Access changed in the console. Now\"}:\\n${lines.join(\"\\n\")}`);\n } catch (err) {\n if (err instanceof ApiError && (err.status === 401 || err.status === 403)) return; // The stream reports it.\n log.debug(`identity check failed: ${err instanceof Error ? err.message : String(err)}`);\n } finally {\n grantsBusy = false;\n }\n };\n void checkGrants();\n const grantsTimer = setInterval(() => void checkGrants(), opts.grantsRefreshMs ?? 5 * 60_000);\n grantsTimer.unref();\n const acker = new Acker(async (seq) => {\n const refused = await transportOk();\n if (refused) throw new Error(refused);\n const acked = (await ackEvents(profile.url, profile.apiKey, config.consumer, seq)).ackedSeq;\n // Shown by `listen status` only once the server has confirmed it.\n status.update({ ackedSeq: acked });\n return acked;\n }, log);\n const timeoutMs = config.timeoutSeconds * 1000;\n\n const batched = config.batchSeconds > 0 && !!config.exec;\n // The Hermes route reads the body as prompt text: send it the cleaned, notice-first form.\n const wrapForward = !!config.forward && isHermesRoute(config.forward.url);\n const runTargets = async (job: Job, signal: AbortSignal): Promise<string[]> => {\n const errors: string[] = [];\n const tag = job.payloads.length === 1 ? `#${job.seq}` : `batch #${job.seq}–#${job.lastSeq} (${job.payloads.length} events)`;\n const ids = job.payloads.map((p) => p.data.id);\n if (job.remaining.has(\"exec\") && config.exec) {\n const r = await runCommand(config.exec, batched ? job.payloads : job.payload, { timeoutMs, signal, cwd: config.cwd });\n const meta = { seq: job.seq, lastSeq: job.lastSeq, ids, attempt: job.attempts, exitCode: r.exitCode, signal: r.signal, durationMs: r.durationMs, stdoutTail: r.stdoutTail, stderrTail: r.stderrTail };\n if (signal.aborted) {\n errors.push(\"stopped\");\n log.debug(`${tag} command stopped by shutdown`, meta);\n } else if (r.ok) {\n job.remaining.delete(\"exec\");\n log.debug(`${tag} command finished in ${formatDuration(r.durationMs)}`, meta);\n // What the agent said goes to the log (and the foreground console): the triage's only output channel.\n if (isSilent(r.stdoutTail)) log.info(pc.gray(` ${tag}: nothing to do`));\n else if (!r.stdoutTail.trim()) log.info(pc.gray(` ${tag}: no output`));\n else log.info(` ${tag} output:\\n${lastLines(r.stdoutTail, 6)}`);\n } else {\n errors.push(`command: ${r.error}`);\n const tail = lastLines(r.stderrTail) || lastLines(r.stdoutTail);\n log.warn(`${tag} command failed (attempt ${job.attempts}/${config.maxAttempts}): ${r.error}${tail ? `\\n${tail}` : \"\"}`, meta);\n }\n }\n if (job.remaining.has(\"forward\") && config.forward) {\n // One POST per event, also in a batch (receivers such as Hermes take one event per request).\n let failed = false;\n for (const p of job.payloads) {\n if (job.forwarded.has(p.data.seq)) continue;\n const r = await forwardEvent(config.forward.url, config.forward.secret, p, { timeoutMs: Math.min(timeoutMs, 30_000), signal, wrap: wrapForward });\n const meta = { seq: p.data.seq, id: p.data.id, attempt: job.attempts, statusCode: r.statusCode, durationMs: r.durationMs, response: r.response };\n if (signal.aborted) {\n errors.push(\"stopped\");\n failed = true;\n break;\n } else if (r.ok) {\n job.forwarded.add(p.data.seq);\n log.debug(`#${p.data.seq} forwarded (${r.statusCode}) in ${formatDuration(r.durationMs)}`, meta);\n } else {\n errors.push(`forward: ${r.error}`);\n failed = true;\n if (r.retryAfterMs !== undefined) {\n job.retryAfterMs = r.retryAfterMs;\n log.info(`#${p.data.seq} forward: the receiver is rate-limiting (429); trying again in ${formatDuration(r.retryAfterMs)} (doesn't count as a failed attempt)`, meta);\n } else log.warn(`#${p.data.seq} forward failed (attempt ${job.attempts}/${config.maxAttempts}): ${r.error}`, meta);\n break;\n }\n }\n if (!failed) job.remaining.delete(\"forward\");\n }\n return errors;\n };\n\n const dispatcher = new Dispatcher({\n targets: dryRun ? [] : targets,\n concurrency: config.concurrency,\n maxAttempts: config.maxAttempts,\n retryDelayMs: opts.retryDelayMs,\n batch: batched && !dryRun ? { windowMs: config.batchSeconds * 1000, max: MAX_BATCH } : undefined,\n run: runTargets,\n onAdvance: (seq) => {\n // Dry runs and backfills never move a server cursor.\n if (dryRun || backfill) return;\n acker.request(seq);\n },\n onRetry: (job, delay) => {\n log.info(`${describeJob(job)}: retrying in ${formatDuration(delay)}`);\n for (const p of job.payloads) status.addRecent({ seq: p.data.seq, id: p.data.id, type: p.type, outcome: \"retrying\", attempts: job.attempts, at: new Date().toISOString(), error: job.lastError });\n },\n onDead: (job) => {\n // Dead letters stay per event, so `listen dead --replay` works the same with or without --batch.\n failed += job.payloads.length;\n for (const p of job.payloads) {\n const targets = [...job.remaining].filter((t) => t !== \"forward\" || !job.forwarded.has(p.data.seq));\n appendDead(profileName, { deadAt: new Date().toISOString(), seq: p.data.seq, id: p.data.id, type: p.type, attempts: job.attempts, error: job.lastError ?? \"failed\", targets, payload: p });\n }\n log.error(`${describeJob(job)}: gave up after ${job.attempts} attempts (${job.lastError}). Saved to dead letters: ${NPX} listen dead${profileName === DEFAULT_PROFILE ? \"\" : ` --profile ${profileName}`}`, {\n seq: job.seq,\n ids: job.payloads.map((p) => p.data.id),\n });\n },\n onFinished: (job) => {\n if (job.outcome === \"succeeded\") handled += job.payloads.length;\n if (job.outcome === \"succeeded\") log.info(`${pc.green(\"✓\")} ${describeJob(job)} ${pc.gray(`(${formatDuration(Date.now() - job.firstSeenAt)})`)}`, { seq: job.seq, ids: job.payloads.map((p) => p.data.id), attempts: job.attempts });\n for (const p of job.payloads) status.addRecent({ seq: p.data.seq, id: p.data.id, type: p.type, outcome: job.outcome === \"dead\" ? \"dead\" : \"succeeded\", attempts: job.attempts, at: new Date().toISOString(), error: job.lastError });\n status.update({ running: dispatcher.inFlight });\n },\n });\n\n let downSince: number | null = null;\n let connectedNow = false;\n /** --backfill: last time something arrived or ran; and whether an event past the end was seen. */\n let lastActivity = Date.now();\n let pastHead = false;\n /** Reversible refusal currently in effect (logged once per change). */\n let blocked: string | null = null;\n const stream = new EventStream({\n url: profile.url,\n apiKey: profile.apiKey,\n consumer: streamConsumer,\n after: streamAfter,\n types: config.types,\n includeBody: config.includeBody,\n lastEventId: () => dispatcher.lastSeq,\n stallMs: opts.stallMs,\n beforeConnect: transportOk,\n fromStart,\n blockedRetryMs: opts.blockedRetryMs,\n onBlocked: (code, text) => {\n downSince ??= Date.now();\n if (blocked !== code) log.warn(`${pc.yellow(\"⏸\")} ${text}`, { code });\n blocked = code;\n status.update({ connected: false, lastDisconnect: { at: new Date().toISOString(), reason: text } });\n },\n minBackoffMs: opts.minBackoffMs,\n maxBackoffMs: opts.maxBackoffMs,\n shouldPause: () => dispatcher.backlog >= 200,\n onOpen: () => {\n const after = downSince ? ` after ${formatDuration(Date.now() - downSince)}` : \"\";\n if (blocked) log.info(\"Access restored.\");\n // A grant may have changed while we were away (or blocked).\n if (blocked || downSince) void checkGrants();\n blocked = null;\n connectedNow = true;\n lastActivity = Date.now();\n log.info(`${pc.green(\"●\")} Connected${after}. ${backfill ? \"Receiving stored events…\" : \"Waiting for events…\"}`);\n if (!dryRun && !backfill) rememberConsumer(profileName, config.consumer);\n downSince = null;\n status.update({ connected: true, connectedSince: new Date().toISOString() });\n },\n onDisconnect: (reason, retryInMs, { serious }) => {\n downSince ??= Date.now();\n connectedNow = false;\n const msg = `${pc.yellow(\"○\")} Disconnected: ${reason}. Reconnecting${retryInMs ? ` in ${formatDuration(retryInMs)}` : \"\"}…`;\n if (serious) log.warn(msg);\n else log.info(msg);\n status.update({ connected: false, lastDisconnect: { at: new Date().toISOString(), reason } });\n },\n onMessage: (m) => {\n if (m.event !== \"mail\") {\n log.debug(`ignoring unknown stream event \"${m.event}\"`);\n return;\n }\n let payload: WebhookPayload;\n try {\n payload = parsePayload(m.data);\n } catch (err) {\n log.warn(`Ignoring a malformed event from the stream: ${(err as Error).message}`, { id: m.id });\n return;\n }\n if (backfill && payload.data.seq > backfillHead) {\n // Newer than the backfill's end: the listener handles it. Stop receiving.\n pastHead = true;\n return;\n }\n lastActivity = Date.now();\n const skip = skipReason(payload, config);\n const match = skip === null;\n if (dryRun && match) {\n log.info(`${pc.cyan(\"→\")} ${describeEvent(payload)} ${pc.gray(\"(dry run: nothing executed, cursor not advanced)\")}`);\n } else if (match) {\n const waits = batched && dispatcher.lastSeq < payload.data.seq ? pc.gray(` (batching for up to ${formatDuration(config.batchSeconds * 1000)})`) : \"\";\n log.info(`${pc.cyan(\"→\")} ${describeEvent(payload)}${waits}`, { seq: payload.data.seq, id: payload.data.id, type: payload.type });\n } else {\n // Dry runs show what the filters skip, to check them; a real listener keeps that in the debug log.\n const line = `skip ${describeEvent(payload)} (${safeText(skip, 120)})`;\n if (dryRun) log.info(pc.gray(` ${line}`));\n else log.debug(line, { seq: payload.data.seq, id: payload.data.id });\n if (dispatcher.lastSeq < payload.data.seq) status.update({ skipped: (status.status.skipped ?? 0) + 1 });\n }\n const accepted = dispatcher.push(payload, { skip: !match });\n if (!accepted) log.debug(`duplicate #${payload.data.seq} ignored`);\n status.update({ receivedSeq: dispatcher.lastSeq, lastEventAt: new Date().toISOString(), running: dispatcher.inFlight });\n },\n });\n\n let stopReason: string | null = null;\n const stop = (why: string) => {\n if (stopReason) return;\n stopReason = why;\n stream.stop();\n };\n // An abort that came while we were starting up (before this listener existed) still stops us.\n if (opts.signal?.aborted) stop(\"stopped\");\n else opts.signal?.addEventListener(\"abort\", () => stop(\"stopped\"), { once: true });\n const onSignal = (sig: NodeJS.Signals) => {\n if (stopReason) {\n log.warn(\"Exiting now.\");\n killAllRuns();\n process.exit(130);\n }\n log.info(`${sig === \"SIGINT\" ? \"\\n\" : \"\"}Stopping (${sig}). Unfinished events will be delivered again next time. Press Ctrl-C again to force.`);\n stop(sig);\n };\n if (opts.handleSignals) {\n process.on(\"SIGINT\", onSignal);\n process.on(\"SIGTERM\", onSignal);\n }\n\n // --backfill ends once it has reached its end seq (an event at or past it arrived) and everything\n // finished. Safety net: a long quiet spell means the rest isn't visible to this listener. It gives\n // up if the daemon stays unreachable.\n let handled = 0;\n let failed = 0;\n let backfillTimer: NodeJS.Timeout | null = null;\n if (backfill) {\n const idleMs = opts.backfillIdleMs ?? 60_000;\n const unreachableMs = opts.backfillUnreachableMs ?? 10 * 60_000;\n backfillTimer = setInterval(() => {\n const now = Date.now();\n if (!connectedNow) {\n if (downSince !== null && now - downSince >= unreachableMs) stop(\"backfill unreachable\");\n return;\n }\n if (dispatcher.inFlight > 0) {\n lastActivity = now;\n return;\n }\n if (pastHead || dispatcher.lastSeq >= backfillHead) stop(\"backfill complete\");\n else if (now - lastActivity >= idleMs) {\n log.info(`No more stored events arrived for ${formatDuration(idleMs)}; the rest up to #${backfillHead} aren't visible to this listener (event types, label scope, or removed by retention).`);\n stop(\"backfill complete\");\n }\n }, 100);\n }\n\n const end = await stream.run();\n if (backfillTimer) clearInterval(backfillTimer);\n clearInterval(grantsTimer);\n await dispatcher.stop();\n if (!dryRun) await acker.flush();\n if (opts.handleSignals) {\n process.off(\"SIGINT\", onSignal);\n process.off(\"SIGTERM\", onSignal);\n }\n\n if (end.kind === \"revoked\") return revokedExit(log, status, profileName, profile, end.reason, opts);\n if (end.kind === \"fatal\") {\n log.error(`The daemon rejected the stream request: ${end.reason}`);\n status.update({ connected: false, stoppedAt: new Date().toISOString(), exitReason: end.reason });\n status.flush();\n return EXIT.revoked;\n }\n status.update({ connected: false, stoppedAt: new Date().toISOString(), exitReason: stopReason ?? \"stopped\" });\n status.flush();\n if (backfill && stopReason === \"backfill unreachable\") {\n log.error(\n `Gave up: the daemon was unreachable for ${formatDuration(opts.backfillUnreachableMs ?? 10 * 60_000)}. ${handled} event${handled === 1 ? \"\" : \"s\"} handled so far; run the backfill again later (it starts over from the oldest event, so handlers should dedupe on the event id).`,\n );\n return EXIT.error;\n }\n if (backfill && stopReason === \"backfill complete\") {\n const p = profileName === DEFAULT_PROFILE ? \"\" : ` --profile ${profileName}`;\n log.info(\n `${failed ? pc.yellow(\"Backfill done\") : `${pc.green(\"✔\")} Backfill done`}: ${handled} event${handled === 1 ? \"\" : \"s\"} handled${failed ? `, ${failed} failed (see ${NPX} listen dead${p})` : \"\"}.`,\n );\n return failed ? EXIT.error : EXIT.ok;\n }\n log.info(\"Stopped.\");\n return EXIT.ok;\n } finally {\n releaseLock();\n }\n}\n\nasync function revokedExit(log: ListenLogger, status: StatusWriter, profileName: string, profile: Profile, reason: string, opts: RunListenerOptions): Promise<number> {\n const p = profileName === DEFAULT_PROFILE ? \"\" : ` --profile ${profileName}`;\n log.error(\n `Access revoked: ${safeText(reason, 300)}\\n` +\n `This key won't work again. Pair again with: ${NPX} connect ${profile.url}${p} --force\\n` +\n `(your listener settings in the profile are kept; restart the listener or its service afterwards)`,\n );\n status.update({ connected: false, stoppedAt: new Date().toISOString(), exitReason: `revoked: ${safeText(reason, 300)}` });\n status.flush();\n // launchd can't be told \"don't restart on this exit code\": wait a long time first so it doesn't spin.\n if (underService() && process.platform === \"darwin\") {\n await new Promise((r) => setTimeout(r, opts.revokedExitDelayMs ?? 15 * 60_000));\n }\n return EXIT.revoked;\n}\n\n/**\n * Where `--backfill` ends: the seq the listener's consumer started at on the daemon (recorded when the\n * consumer was created), or --until. Refuses when that can't be known, rather than replaying mail the\n * listener already handled.\n */\nasync function backfillEnd(profileName: string, profile: Profile, consumer: string, replay: string, until: number | undefined, log: ListenLogger): Promise<number> {\n if (until !== undefined && (!Number.isSafeInteger(until) || until < 0)) throw new Error(\"--until must be an event number (0 or more).\");\n const p = profileName === DEFAULT_PROFILE ? \"\" : ` --profile ${profileName}`;\n let self;\n try {\n self = await getSelf(profile.url, profile.apiKey, 8000);\n } catch (err) {\n throw new Error(`Couldn't ask the daemon where the listener started: ${err instanceof Error ? err.message.split(\"\\n\")[0] : String(err)}`);\n }\n // The replay cursor must still be at 0 (it is never acknowledged): one that moved would skip the\n // start of the range. Older daemons don't reserve the suffix, so check.\n const replayCursor = self.consumers?.find((c) => c.consumer === replay);\n if (replayCursor && replayCursor.ackedSeq > 0) {\n throw new Error(\n `The backfill cursor \"${replay}\" on the daemon has been moved to #${replayCursor.ackedSeq} (something acknowledged it), so a backfill would skip the oldest mail.\\n` +\n ` Use another consumer name for this listener (--consumer <name> --save), or remove that consumer in the console.`,\n );\n }\n const mine = self.consumers?.find((c) => c.consumer === consumer);\n if (until !== undefined) {\n if (mine?.startSeq != null && until > mine.startSeq) {\n log.warn(\n `--until #${until} is past where the listener started (#${mine.startSeq}): ${until === mine.startSeq + 1 ? `event #${until} was` : `events #${mine.startSeq + 1}–#${until} were`} (or will be) handled by the listener too, so ${until === mine.startSeq + 1 ? \"it runs\" : \"they run\"} twice.`,\n );\n }\n return until;\n }\n if (!self.consumers) {\n throw new Error(\n \"This xaq daemon doesn't report where listeners started (it's older than this CLI), so a backfill could re-run mail the listener already handled.\\n\" +\n ` Update xaq, or pass --until <event number>: the newest event to replay (events after it are the listener's).`,\n );\n }\n if (!mine) {\n throw new Error(\n `The listener (consumer \"${consumer}\") hasn't connected yet, so no mail predates it.\\n` +\n ` Start it with --from-start instead: a new listener then begins with the oldest stored mail. E.g. ${NPX} listen${p} --from-start`,\n );\n }\n if (mine.startSeq === null) {\n throw new Error(\n `The daemon doesn't know where consumer \"${consumer}\" started (it was created by an older xaq).\\n` +\n ` Pass --until <event number>: the newest event to replay. The listener's first handled events are in ${NPX} listen status${p} and its log.`,\n );\n }\n return mine.startSeq;\n}\n\n/**\n * The one-off backfill command for this listener: `listen --backfill`, plus the targets when they came\n * from flags rather than the profile (the backfill must run the same thing).\n */\nexport function backfillCommand(profileName: string, profile: Profile, c: EffectiveConfig): string {\n const parts = [`${NPX} listen`];\n if (profileName !== DEFAULT_PROFILE) parts.push(`--profile ${profileName}`);\n parts.push(\"--backfill\");\n const savedExec = profile.exec ?? null;\n const savedForward = profile.forward?.url ?? null;\n if (c.exec !== savedExec || (c.forward?.url ?? null) !== savedForward) {\n const tool = recipeToolFor(c.exec, profileName);\n const fwdTool = c.exec ? null : recipeToolFor(null, profileName, c.forward?.url ?? null);\n if (tool) parts.push(`--recipe ${tool}`);\n else if (c.exec) parts.push(`--exec ${shellQuote(c.exec)}`);\n if (fwdTool) parts.push(`--recipe ${fwdTool}`);\n else if (c.forward) parts.push(`--forward ${shellQuote(c.forward.url)}`);\n }\n return parts.join(\" \");\n}\n\n/** Where the agent's output ends up, said plainly at start (and in `listen status`). */\nexport function outputLine(profileName: string, c: { exec: string | null; forward: { url: string } | null }, log: string): string {\n const r = recipeOf(c, profileName);\n const parts: string[] = [];\n if (c.exec) {\n parts.push(\n r?.exec\n ? `${TOOL_LABELS[r.tool]}'s reply only goes to the listener's log (${log}, and the console when run in the foreground); it can't notify you by itself (--recipe hermes can, see docs)`\n : `your command's last output lines go to the listener's log (${log}, and the console when run in the foreground)`,\n );\n }\n if (c.forward) parts.push(r?.forward ? \"Hermes delivers its triage where its route says (listen hermes); this listener only sees the HTTP status\" : \"the receiver at --forward handles it; this listener only sees the HTTP status\");\n return parts.join(\" · \");\n}\n\nfunction printBanner(log: ListenLogger, name: string, profile: Profile, c: EffectiveConfig, dryRun: boolean, backfill = false): void {\n const lines = [\n `${pc.bold(\"xaq listen\")} ${pc.gray(`v${version}`)} · profile ${pc.cyan(name)} · agent ${pc.cyan(safeText(profile.agentName))}`,\n ` daemon ${profile.url} ${pc.gray(`(consumer ${c.consumer} on ${hostname()})`)}`,\n ];\n if (dryRun) lines.push(` mode ${pc.yellow(\"dry run\")}: matching events are printed; nothing runs and the cursor is not advanced`);\n if (backfill) lines.push(` mode ${pc.yellow(\"backfill\")}: mail from before the listener started, then exit (own cursor; the listener is not affected)`);\n if (c.exec) lines.push(` exec ${safeText(c.exec, 300)}`, ` cwd ${c.cwd}${c.cwdIsDefault ? pc.gray(\" (private; --cwd to change)\") : \"\"}`);\n if (c.forward) lines.push(` forward ${c.forward.url} ${pc.gray(`(signed, see \\`${NPX} listen secret\\`)`)}`);\n lines.push(` events ${describeFilter(c)}${c.includeBody ? \" · with bodies\" : \"\"}`);\n if (c.batchSeconds) {\n lines.push(\n c.exec\n ? ` batch up to ${MAX_BATCH} events per run, collected for ${formatDuration(c.batchSeconds * 1000)} after the first${c.forward ? pc.gray(\" (forward stays one POST per event)\") : \"\"}`\n : pc.gray(` batch ${formatDuration(c.batchSeconds * 1000)} ignored: --batch applies to --exec; forward is one POST per event`),\n );\n }\n lines.push(` limits concurrency ${c.concurrency} · timeout ${c.timeoutSeconds}s · ${c.maxAttempts} attempts`);\n lines.push(` output ${outputLine(name, c, backfill || dryRun ? oneOffLogPath(name) : logPath(name))}`);\n lines.push(pc.gray(` log ${backfill || dryRun ? oneOffLogPath(name) : logPath(name)}`));\n for (const l of lines) process.stdout.write(`${l}\\n`);\n log.debug(\"listener starting\", { profile: name, url: profile.url, consumer: c.consumer, exec: c.exec, forward: c.forward?.url, types: c.types, filter: c.filter });\n}\n"],"mappings":"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"}
|