KQ-2083 · ALLOW/RULES
Allow Rules
A permission prompt that can become a standing rule: Always allow opens a sentence of selects that widens one yes into a pattern (the action, the files, a cost ceiling), with a live rule chip, a reach strip that lights in a cascade the recent requests the rule would have covered, and a conflict that names the deny rule it collides with, rings that rule and holds Create. Create folds the request card on springs.glide into its rule chip while the list opens a slot on the same spring, the chip flies into that slot on glide, and the row's fire count rolls from 0 to 1 on springs.snap as the next waiting request rises in. The builder is a toolbar of select-only comboboxes (Left and Right move, Up and Down change, Enter opens), the rules are roving stops where Enter edits and R revokes after a confirm, and below 30rem the panes sit behind tabs and the chip flies to the Rules tab.
Permissions
5 rules · 3 waiting
Standing rules
14 days · firesUp and Down move between rules. Enter edits a rule, R revokes it after a confirm.
request · write basin-levels.csv · 5 rules
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/allow-rules
Props
- request
- AllowRequest | null
- default defaultAllowRequest
- The permission asked for now: { id, agent, verb, path, size?, cost, reason, at }; null when nothing waits.
- waiting
- AllowRequest[]
- default defaultAllowWaiting
- Requests waiting behind it, in order; each decision brings the next one in.
- templates
- AllowTemplates
- default templatesFor(request)
- The builder's options, narrowest first: { verbs, scopes, costs }, each { id, label, value }.
- rules / defaultRules
- AllowRule[]
- default — / defaultAllowRules
- Standing rules, controlled or initial: { id, effect, pattern, fires, daily?, lastFiredAt? }.
- onRulesChange
- (rules) => void
- default —
- Fires with the whole list after a rule is created or revoked.
- history
- AllowHistoryItem[]
- default defaultAllowHistory (40)
- Recent requests, newest first; the reach strip lights the ones a rule would have covered.
- onAllowOnce
- (request) => void
- default —
- Allow once was pressed.
- onDeny
- (request) => void
- default —
- Deny was pressed.
- onCreateRule
- (rule, request) => void
- default —
- A rule was created from the request; it fires once for it.
- onEditRule
- (rule) => void
- default —
- Enter on a rule, or Edit that rule on a conflict.
- onRevokeRule
- (rule) => void
- default —
- A rule was revoked after its confirm.
- status
- "ready" | "loading" | "empty" | "error"
- default "ready"
- Whether the permissions have loaded.
- onRetry
- () => void
- default —
- Try again was pressed after a failure to load.
- now
- number
- default Oct 17 2026, 14:00 UTC
- The moment ages are counted from, in ms.
- chipStyle
- "pill" | "tag" | "code"
- default "pill"
- How a rule is drawn: a pill with an effect dot, a notched tag, or a mono glob pattern.
- listDensity
- "compact" | "cozy" | "roomy"
- default "cozy"
- Row height of the rules list; compact drops the last-fired line.
- accent
- "cobalt" | "plum" | "mint" | "ink" | string
- default "cobalt"
- Allow rules, the builder and Create: a named pigment or any CSS colour.
- formatMoney
- (amount) => string
- default Intl USD
- How money is written.
- height
- number
- default 560
- Tallest the surface grows, in px, before its panes scroll.
- disabled
- boolean
- default false
- Read only.
- className
- string
- default —
- Classes for the surface.
| Prop | Type | Default | Description |
|---|---|---|---|
| request | AllowRequest | null | defaultAllowRequest | The permission asked for now: { id, agent, verb, path, size?, cost, reason, at }; null when nothing waits. |
| waiting | AllowRequest[] | defaultAllowWaiting | Requests waiting behind it, in order; each decision brings the next one in. |
| templates | AllowTemplates | templatesFor(request) | The builder's options, narrowest first: { verbs, scopes, costs }, each { id, label, value }. |
| rules / defaultRules | AllowRule[] | — / defaultAllowRules | Standing rules, controlled or initial: { id, effect, pattern, fires, daily?, lastFiredAt? }. |
| onRulesChange | (rules) => void | — | Fires with the whole list after a rule is created or revoked. |
| history | AllowHistoryItem[] | defaultAllowHistory (40) | Recent requests, newest first; the reach strip lights the ones a rule would have covered. |
| onAllowOnce | (request) => void | — | Allow once was pressed. |
| onDeny | (request) => void | — | Deny was pressed. |
| onCreateRule | (rule, request) => void | — | A rule was created from the request; it fires once for it. |
| onEditRule | (rule) => void | — | Enter on a rule, or Edit that rule on a conflict. |
| onRevokeRule | (rule) => void | — | A rule was revoked after its confirm. |
| status | "ready" | "loading" | "empty" | "error" | "ready" | Whether the permissions have loaded. |
| onRetry | () => void | — | Try again was pressed after a failure to load. |
| now | number | Oct 17 2026, 14:00 UTC | The moment ages are counted from, in ms. |
| chipStyle | "pill" | "tag" | "code" | "pill" | How a rule is drawn: a pill with an effect dot, a notched tag, or a mono glob pattern. |
| listDensity | "compact" | "cozy" | "roomy" | "cozy" | Row height of the rules list; compact drops the last-fired line. |
| accent | "cobalt" | "plum" | "mint" | "ink" | string | "cobalt" | Allow rules, the builder and Create: a named pigment or any CSS colour. |
| formatMoney | (amount) => string | Intl USD | How money is written. |
| height | number | 560 | Tallest the surface grows, in px, before its panes scroll. |
| disabled | boolean | false | Read only. |
| className | string | — | Classes for the surface. |