Commit Graph
8 Commits
Author SHA1 Message Date
d6c2b2c683 feat: add a use/plan/build mode picker and read-only prod sessions (#11940)
* feat: read-only ai sessions on protected workspaces with a use, plan and build picker

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix: address local review findings on the use, plan and build picker

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix: address CI review findings on use mode and protected sessions

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix: hold test-run forms and pending protection lookups to use mode

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* refactor: fetch rules once per send and dedupe helpers and prompt text

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix: send role-locked operators to an admin and cover it with an eval

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* feat: count the work mode each session message runs in

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* chore: regenerate the mcp session definitions after merging main

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* feat: rename build to use & build and let the chat ask to switch modes

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix: word a declined mode switch by the switch, not the mode

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* chore: update ee-repo-ref to 55445977dd05c25791388070182c77f4dbc20c0e

This commit updates the EE repository reference after PR #915 was merged in windmill-ee-private.

Previous ee-repo-ref: 7f7bf7003e356346ce74395af02c5bdf14f38781

New ee-repo-ref: 55445977dd05c25791388070182c77f4dbc20c0e

Automated by sync-ee-ref workflow.

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
2026-10-23 15:53:04 +02:00
AlexRV12andClaude Opus 5 ef8a8e821c fix: check direct-deployment lock and superadmin in the deploy preflight (#10748)
* fix: check direct-deployment lock and superadmin in the deploy preflight

`checkDeployPermission` mirrors the server's `check_deploy_rules` so the deploy
UI can disable an action with a reason instead of letting the click come back
403. It modelled only `RestrictDeployToDeployers`, leaving two terms out:

- `DisableDirectDeployment` was never evaluated. In a workspace carrying only
  that rule the preflight allowed the deploy and the request 403'd.
- The server bypasses on `ApiAuthed.is_admin`, which is `usr.is_admin ||
  super_admin`, while `whoami` reports the two separately. A superadmin who is
  a plain member of the workspace was refused a deploy the server allows.

Evaluate `DisableDirectDeployment` first, as the server does, so the same
message wins when both rules block, and add the superadmin term to the shared
ruleset bypass helper. `wm_deployers` membership is an implicit pass on
`RestrictDeployToDeployers` alone, so it no longer short-circuits the rules
fetch the way admin does — a deployer is still bound by a direct-deployment
lock, and a test pins that.

The operator refusal stays above the admin/superadmin short-circuit: the server
refuses operators in the item handlers whatever their global role, so a
superadmin who is an operator in the workspace is still refused. Its doc no
longer presents that term as part of the `check_deploy_rules` mirror, since the
rule carries no operator term and refusing every kind here is deliberately
stricter than the server.

Callers no longer name which rules the preflight covers. That list rots at every
site that repeats it, so it lives only at the preflight itself.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: apply the direct-deployment refusal only to the kinds the server gates

`check_deploy_rules` runs from the item handlers, and only scripts, flows, apps,
resources, resource types, variables and folders reach it. Schedules and
triggers hit no gate at all: in a `DisableDirectDeployment` workspace the server
returns 200 for a schedule and 403 for a script.

The preflight answers per workspace, and that one answer disabled the deploy
action for every kind, so adding the direct-deployment term would have blocked
schedule and trigger deploys the server accepts. Tag each refusal with the term
that produced it and let callers narrow a direct-deployment refusal to the kinds
the server actually gates; a selection still blocks as soon as one gated kind is
in it.

The deployers-only term keeps applying to every kind. It over-reaches the same
way, but narrowing it would loosen the UI beyond mirroring the new rule, so it
stays as it is and no existing behaviour changes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: mirror the superadmin bypass in the per-item deploy checks too

`checkPathWritePermission` and `canPreserveOnBehalfOf` still tested `is_admin`
alone. The server reads the merged `ApiAuthed.is_admin` in both places —
`is_owner` for path ownership and `can_preserve_on_behalf_of` for the deploy
identity — so a superadmin who is a plain member was refused a write the server
accepts: creating a script in a folder owned by someone else returns 201 for
them.

Also drop the rule enumeration from the session deploy guard's comment, which
named the operator and deployer rules for a preflight that now covers the
direct-deployment lock and answers per kind.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: keep the deploy refusal on an empty selection and match the advice to the fork lock

* fix: mirror the superadmin bypass in the compare page's on-behalf-of gate

* docs: name the variable that tracks the deploy direction

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 12:01:46 +02:00
Ruben FiszelandClaude Opus 5 ecae9320d0 fix: let admins edit the dev workspace lock ruleset (#10512)
* fix: let admins edit the dev workspace lock ruleset

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: route the empty protections panel through the owning workspace

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: make protection rule rename actually apply

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: cache the renamed protection rule query for sqlx offline

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: keep verbatim rule names and scope parent-admin lookup to its workspace

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: store renamed protection rule names verbatim

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 18:25:59 +02:00
hugocasaandClaude Opus 4.8 ebe31aeeac feat(dev-workspace): reflect existing protection rules in lock toggles (#10093)
* feat(dev-workspace): reflect existing protection rules in lock toggles

When creating or attaching a dev workspace, the "block direct edits" and
"prevent forking" toggles now check the root workspace's current protection
rules. If a restriction is already enforced by an existing rule, its toggle is
shown on but locked, with a note, instead of offering a fresh default that could
misrepresent the effect. The value sent to the backend is derived so it stays
consistent with what the locked toggle shows.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs: clarify fail-open comment on dev-workspace lock toggles

Reword the protection-rule fetch comment so the fallback path isn't misread as
dropping protection: a failed fetch falls back to the editable default-on
toggle, and any real rule still enforces server-side.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(dev-workspace): lock protection toggles until rules load

The lock toggles derived alreadyBlocks* from an async fetch, so during the load
window (and the first frame before loading flips) they were editable and the
effective value could be false. A user could turn a lock off and submit before
an existing rule was detected, omitting the reserved rule and silently leaving
prod unprotected once that existing rule was later removed.

Treat "rules not yet known" (loading || current === undefined) the same as
"already enforced": lock the toggle on and keep the effective value true during
that window, so the request can never submit false before the fetch resolves.
Submission stays available (a hung fetch degrades to over-protection, not a
blocked form). Also fixes the stale-value flash when switching base workspace.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(dev-workspace): honor rule bypasses and guard stale protection fetches

Two issues in the protection-rule awareness for the dev-workspace lock toggles:

- Bypassable rules became unconditional locks. alreadyBlocks* used
  isRuleActiveInRulesets, which ignores bypass_users/bypass_groups, and forced
  the request flag to true. The reserved dev_workspace_lock rule is created with
  empty bypass lists, so layering it over an existing rule that let specific
  users through revoked their deploy/forking access. Switch to
  isRuleUnconditionallyActiveInRulesets so a toggle is only shown as already
  enforced (locked) when an existing rule has no bypasses; a bypassable rule
  stays editable, making the lock the user's explicit choice.

- A stale protection fetch could apply another base's rules. The generated
  client can't take an abort signal, so a delayed response for a previous base
  could overwrite the newly selected one. Tag each result with its workspace and
  only trust a result matching the current base; also throw AbortError from a
  superseded fetch so it can't overwrite current.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs: condense protection helper comment to four lines

Trim the isRuleUnconditionallyActiveInRulesets doc comment to satisfy the
AGENTS.md ≤4-line comment rule.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(dev-workspace): align already-enforced note under the toggle label

The note used ml-8, landing under the toggle switch rather than aligned with
the switch edge or the label, so it read as floating. Bump to ml-11 so it lines
up under the label as helper text for that toggle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 10:01:35 +02:00
GuilhemandClaude Opus 4.8 a6c0b3756b feat: chat-scoped session changes bar + unified diff drawer (#9762)
* feat(frontend): chat-scoped unified session changes bar

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(frontend): drop diff-baseline toggle, show natural per-row diffs

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(frontend): carry Draft marker to expanded raw-app file rows

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(frontend): show raw-app Draft badge once at tree root, not per file

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(frontend): reuse shared DraftBadge in session diff drawer

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(frontend): show draft-author avatars in session diff badge, icon-only in sidebar

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(frontend): keep badge pill around avatar in icon-only DraftBadge

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(frontend): small draft marker = indigo pen + avatar; correct itemKind label

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(frontend): drop package-lock churn from merge (match origin/main)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(frontend): dedup diff-button count for legacy fork sessions; test mask helper

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(frontend): collapsible session diff panel + per-row open-diff action

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(frontend): shared sessionDeployModel for review & deploy (S1)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(frontend): model-driven session review drawer, deploy inert (S2)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(frontend): wire session deploy + on-behalf/conflict gating (S3)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(frontend): behind banner + Update fork + deployment request (S4)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(frontend): session changes dock opens drawer by filter (S5)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(frontend): session review UI polish (badge, dock, In parent, tree width)

- draft rows show only the avatar DraftBadge, not a duplicate state pill
- drop redundant dock Review button (same as "N to review")
- rename Done -> In parent with a "deployed in parent workspace" tooltip
- widen the file tree

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(frontend): existence-gate In parent rows; Badge filters; badge hover

- drop discarded mask-only items from the In-parent segment (existence check)
- use the Badge component for the drawer filter segments and the changes dock
- soften the blue Badge hover (blue-50 base was jumping to blue-200)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(frontend): polish session diff drawer (layout, badges, actions)

- remove empty fork-banner gap; uniform sidebar tree padding
- full-bleed diff list: drop card borders/side padding, separators between items
- clamp tree x-overflow; right-align tree badges (min-w-0 on the row button)
- brand-compliant selected filter badges; smaller draft badge
- hide per-row open-diff button when the panel is open
- rename "Delete draft" to "Discard draft" (destructive); remove header Review button
- larger sm deploy/discard action buttons; remove per-item diff-content collapse

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(frontend): session Edits dock — deploy gating + change-op tracking

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(frontend): session bar per-status badges; drop change-op tracking

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(frontend): unwrap raw apps into per-file tree in session diff sidebar

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(frontend): dot-parcours pipeline (badge-derived, melt tooltip) + discard confirm

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(frontend): behind-only session item reads as deployed, not bare

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* style(frontend): even sidebar tree margins; gutter-aware right padding

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(frontend): pass chat id as from_session; wire deploying flag

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(frontend): session diff drawer scroll-to-flush, ordering, spacer, deploy gating

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(frontend): preserve chat mask on compact; guard stale existence checks; clear poll timers

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(frontend): refresh bar after drawer deploys; conflict hint over chip; plain conflict badge

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* style(frontend): diff drawer card layout with flash ring and aligned insets

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(frontend): hide stale deployed chip once row status badge reads deployed

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(frontend): session dock to two states; drop parent deploy

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(frontend): staged deploy animation in session edits drawer

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(frontend): stale-draft warning in session edits drawer

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(frontend): keep chat mask honest on deploy and discard

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(frontend): map trigger_email deploy kind; serialize mask persists

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(frontend): reset mask on new chat; close review-flagged races

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* style(frontend): rename session drawer title to Edited during session

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(frontend): keep mask persist queue alive after a failed save

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(frontend): sync session chatId on chat rotation; gate deploy on canWrite

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(frontend): keep compare handoff for deletion-only session edits

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(frontend): hold deploy success beat across re-keyed rows

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 09:23:54 +02:00
wendrul 2851b6b7ca feat: restriction rulesets for workspaces (#7879) 2026-02-10 16:49:25 +00:00
Ruben Fiszel 309de58134 Revert "feat: restriction rulesets for workspaces (#7791)" (#7820)
This reverts commit a1cd02d7f8.
2026-02-05 18:16:40 +00:00
wendrulandwindmill-internal-app[bot] a1cd02d7f8 feat: restriction rulesets for workspaces (#7791)
* Add frontend for the workspace proctection rules

* api to add and update workspace protection rules

* Fix bypasser selection

* Fix Select bug on refocus

* Change rulesets to use bitflags

* Messages for protection rules errors

* claude remove ui for rules

* Hide edit buttons when rule

* No edit refactor pt1

* Update edit buttons to be disabled when rule is active

* Merge deploy ui and rulsets in one tab

* Remove not cleaned line in migration

* multiple fixes

* Remove old protection rule logic

* Add prrotection rule for deploying through Merge UI

* Add Alert on legacy Deploy UI

* Add backend enforcing of workspace rules

* Finish backend blocking on rulsets

* Last changes to api ruleset blocks

* Prepare sqlx

* Remove unused import and argument

* Update SQLx metadata

* fix npm run check

* Re trigger CI

---------

Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
2026-02-05 18:02:41 +00:00