feat(features,gateway,host,desktop): a window writes any trigger, says it in one sentence, and copies a webhook's fresh secret through the host
Merged
DA
4d ago+441+441+012345678901234567890123456789-83-83-01234567890123456789
Summary
Part 1, step 3a of Dean's "GitHub events and webhooks". This is the plumbing behind the editor's Trigger section; the section itself is the next PR. Stacked on #2770.
- The window can write any trigger.
automation-view.tsdrops its schedule-only filter, so a window's create or change may name a GitHub event or a webhook. - The draft model holds the trigger (
automation-draft-model.ts): its kind, plus a GitHub event (a new draft's ispull-request-updated).- A GitHub trigger keeps the label and branch filters it was given, which the editor doesn't show.
- A save sends the trigger only where its kind, its schedule, or its event moved.
- One sentence per trigger (
automationTriggerText), for the list and the editor:- "When a pull request is opened or updated in acme/ledger";
- with filters: "⦠in acme/api, acme/web, or acme/ledger labelled bug or p1 on main";
- "When its webhook is called".
- The
repository-changedreason now reads "It no longer works in the repository the event came from."
- The webhook secret never enters a Gateway answer (root AGENTS.md's "Never").
- A new
automations.copyWebhookSecretmethod has the host mint the secret (32 random bytes) and put it on the system clipboard, through the native node's newos.copyTextcapability. Only then does it send the service the secret's SHA-256 (PATCH { webhookSecretHash }, #2770). - A clipboard that refuses replaces nothing, and the old secret keeps working (Devin's review). The service never sees the secret.
- The window hears
{ automation, secretCopied: true }, never the secret. - The secret a create mints is still dropped by the client, as today.
- Node invocations aren't events and travel only on the node's own connection, and the dev trace taps only voice data-channel events.
- A new
- The list's rows say each trigger as that sentence, naming the repository.
Evidence
- Platform-independent checks:
pnpm check:affectedpasses. - New tests, each failing without its change:
compose-automations.test.ts: the secret is on the clipboard before its hash alone is sent (the hash matches what was copied), the window hears onlysecretCopied, no answer carries the secret, and a refusing clipboard asks the service nothing.automation-client.test.ts: the replace PATCHes{ webhookSecretHash }, and no answer carries a service-minted secret.automations-page.test.ts: a GitHub automation's row says the sentence, naming its repository.automation-draft-model.test.ts: a GitHub-event or webhook draft is made and changed as one, and a GitHub trigger keeps its filters.automation-list-model.test.ts: the GitHub and webhook sentences.automation-acts.test.ts: the voice and call windows are refused the new act.
- Changed: the client test that asserted "the window writes a schedule alone" now asserts a webhook write travels, the deliberate change of this PR.
- Test count: +5.
Invariants
-
./scripts/check.shgreen. (CI) - JSON Schema goldens unchanged.
- Every behavior change has, in this PR, the test that fails without it; no change-detector test added.
- Gateway envelope goldens unchanged. The new method's answer carries no secret.
- No new
asassertion, no run outside the edges, no raw async primitives, and no dropped Effect. - Test count delta listed (+4).
- No hand-rolled file replaced.
- No
CLAUDE.md/AGENTS.mdsentence names a changed part. The "Never" rule holds by design: the secret goes to the clipboard, not a Gateway answer. -
PRIVACY.mdunchanged. - Package deps unchanged.
- Barrel/door rule: the renderer imports only
@luke/features/automation-*doors and@luke/host/acts.
Notes
- A deliberate deviation from "shown once with Copy": the window never shows the secret. Copy mints a fresh one onto the clipboard, and the old one stops working once the new one's hash lands, because AGENTS.md forbids a credential in a Gateway answer and Dean approved only the body carve-out. To show the text itself, Dean would need to approve a second carve-out.
- Mac: this PR has no visible UI change (the editor compiles against the new draft). CI could not verify the Mac UI.
š¤ Generated with Claude Code