Skip to content

fix(drawer): implicit webhook input + 'any' type for trigger drawers#171

Merged
bobakemamian merged 3 commits intomainfrom
fix/validate-webhook-input
Apr 21, 2026
Merged

fix(drawer): implicit webhook input + 'any' type for trigger drawers#171
bobakemamian merged 3 commits intomainfrom
fix/validate-webhook-input

Conversation

@bobakemamian
Copy link
Copy Markdown
Contributor

Auto-declares an implicit webhook input for drawers with kind=webhook triggers + adds 'any' type compatibility fallback so ${inputs.webhook.body.*} refs pass --summary validation. Caught during real-world Apify setup.

bobakemamian and others added 3 commits April 20, 2026 19:12
Before: a drawer with a webhook trigger couldn't pass `buttons drawer
NAME --summary` validation because refs like
`${inputs.webhook.body.resource.defaultDatasetId}` hit "unknown
drawer input 'webhook'" — the input is populated by the listener
dispatcher, not declared in drawer.json.

Now: when a drawer has kind=webhook in Triggers, the validator
auto-declares an implicit InputDef{Name:"webhook", Type:"any"}. The
"any" type compatibly matches string/int/bool at the arg-type check
(fall-through to press-time best-effort resolution) so downstream
steps reading webhook fields pass validation regardless of arg type.

This was caught during the real-world Apify webhook setup — the
on-apify-done drawer needed `${inputs.webhook.body.resource.defaultDatasetId}`
to flow into an `apify-fetch-dataset` button that declares a string
arg, and the validator blocked the press every time.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two linked fixes so secret-bearing files in .buttons/ can't
accidentally ship in a commit:

1) `buttons init` now writes a .gitignore that covers everything in
   .buttons/ that can hold secrets or per-machine state:
     - batteries.json  (API keys, 0600 on disk but 'git add -A' ignores
       perms)
     - webhook.json    (tunnel hostname + id; machine-specific)
     - buttons/*/pressed/ + drawers/*/pressed/  (run history with
       press-time args)
     - idempotency/   (cached results keyed on args)
     - queues/        (file-lock state)

2) Older projects that already ran `buttons init` before this fix
   shipped get upgraded in place. The init path now reads an existing
   .gitignore and appends any missing secret patterns under an
   "Added by buttons upgrade" header, idempotent and append-only so
   user customisations are preserved.

3) `buttons batteries set --local` (or local-default in a project)
   now runs the same ensure-pattern check on .buttons/.gitignore
   before returning success, so a battery set in a project that
   somehow missed the init .gitignore still gets covered. Emits a
   "added batteries.json to .buttons/.gitignore" notice in stderr
   and the JSON payload so the user knows we touched their repo.
   Global scope (~/.buttons/) skips the check since it's outside any
   repo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
gosec G703 flagged os.WriteFile calls on paths ending in
.buttons/.gitignore because the path traces back to config.DataDir()
which reads BUTTONS_HOME. The filename is a literal and the parent
directory is constrained to BUTTONS_HOME / discovered .buttons/ /
~/.buttons — no user-tainted path-traversal vector.

#nosec with a rationale comment at each site.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bobakemamian bobakemamian merged commit ed9cbef into main Apr 21, 2026
16 checks passed
@bobakemamian bobakemamian deleted the fix/validate-webhook-input branch April 21, 2026 00:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant