mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-03 08:02:19 +00:00
4b09558e13fadca6fe604c231a5cdfb896d4d0f8
14880
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4b09558e13 |
feat: start a deferred queued job now without changing its id (#11347)
* feat: start a deferred queued job now without changing its id Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: refuse starting a schedule's upcoming tick early Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: hide run now on upcoming schedule ticks and register its audit op Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
245628210f |
perf: skip parent status write when a parallel loop iteration starts (#11348)
* perf: skip parent status write when a parallel loop iteration starts Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: keep the loop viewer off the parent job while a parallel loop runs Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: state what a parallel module's job would hold Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * perf: test the parallel module with one containment check Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
bc4f872f10 |
perf: skip the flow_env ancestor walk for sub-flows with nothing to inherit (#11349)
* perf: skip the flow_env ancestor walk for sub-flows with nothing to inherit Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: keep the flow_env mark out of sub-flow definitions replayed by restarts Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test: align the guest scopable-path test with app path validation Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
d18d7043df |
feat: infer a script's schema when a deploy (e.g. MCP) sends none (#11339)
* feat: infer a script's schema from its code when a deploy sends none Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: merge an inferred schema into the previous one the way the editor does Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: parse non-JSON TS defaults natively and keep the schema on a failed inference Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: type untyped TS params from their literal shape when the default can't be evaluated Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: read literal TS defaults off the AST so the server types them like the editor Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: word the script schema description for both create and update Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: note that dbt scripts derive their schema from the descriptor Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
0bac766756 |
feat: refresh MCP tools when scripts and flows change (#11337)
* feat: notify MCP clients when a workspace's scripts or flows change Advertise tools.listChanged and implement subscriptions/listen, so a 2026-07-28 client refreshes its tool list when scripts or flows are deployed, archived, renamed or deleted. Changes reach every replica via new statement-level notify_event triggers; MCP-originated changes also signal the serving replica inline. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: signal each workspace once per notify-event poll batch Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: signal script/flow path moves, keep unrelated updates trigger-free Row-level UPDATE OF archived/deleted/path triggers with a WHEN guard replace the statement-level ones, which built transition tables for every UPDATE on script and flow. Path moves from username changes and offboarding are now signalled. subscriptions/listen is refused when the client asks for nothing this server sends. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: signal path moves only for unarchived versions A username change or offboarding rewrites the path of every version, archived ones included, which would queue one notify_event per version. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * refactor: detect MCP tool-list changes by polling a workspace fingerprint Replace the notify_event triggers and poller hook with a per-process, per-workspace poll of a hash over the live scripts and flows, run only while a subscriptions/listen stream watches that workspace. Every write path (UI, CLI, git sync, user renames, workspace moves) is covered with no migration; an MCP-originated change polls at once. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: announce the first fingerprint so a change before the baseline is not lost Also poll immediately after a script/flow mutation through a multi-workspace token, and pin the fingerprint test on a lock update, which is the unrelated write that actually happens. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: open every tool-list subscription with one notification A subscriber joining an existing watcher missed a change the watcher recorded before it subscribed. Also move the fingerprint query to a runnables module, since it spans scripts and flows. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
1fd729ac1a |
feat: add an instance-wide accent color setting with sidebar tint (#11335)
* feat: add an instance-wide accent color setting with sidebar tint Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: paint the cached accent before the license resolves Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat: serve the banner and accent color from one cached endpoint Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: invalidate the instance ui cache and bound it with a ttl Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: keep the instance ui ttl under the client poll period Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * refactor: load the banner and accent color once per page load Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * refactor: read the banner and accent color without a server cache Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: show a cleared accent color as off Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
2f1953ea10 |
restore the operator alias in the offline seat-count query (#11336)
* fix: restore the operator alias in the offline seat-count query Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore: update ee-repo-ref to bf64ca98472a57cbfd150f8876877d2d4d9c217e This commit updates the EE repository reference after PR #827 was merged in windmill-ee-private. Previous ee-repo-ref: 59ac4f6e051fa9b6656b5d34759c09a04c4d8b85 New ee-repo-ref: bf64ca98472a57cbfd150f8876877d2d4d9c217e 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> |
||
|
|
ebb3048ca0 |
feat: mount session list pages in process instead of iframes (#11289)
* feat: mount session list pages in process instead of iframes * fix: seed filter defaults from the query, not the cached search params * fix: type trigger list rows from the generated trigger types * fix: judge hosted lists by the operating workspace's rules and keep role-gated filters * fix: keep the user folders filter key for every role, hidden where it does not apply * fix: drop the user folders filter for users it is not offered to * fix: wait for a known user before dropping the user folders filter * style: tint trigger rows for every kind and align the schedules footer wording * fix: stamp edited_at when a schedule is updated --------- Co-authored-by: Ruben Fiszel <ruben@windmill.dev> |
||
|
|
d02ff9ac24 |
fix: centre the toggle knob inside its track (#11314)
* fix: centre the toggle knob inside its track The knob was positioned against the toggle's wrapper rather than the track, so its 2px inset resolved to a 1px gap inside the track's 1px border. On a 1x screen a toggle that lands on a fractional x blurs its edges across a whole pixel, which swallows that 1px gap and makes the knob look like it overflows the track. Position the knob inside the track's border with a 2px gap on every side, size the toggle in whole px so the 18px root font of large screens cannot make the track fractional, and give each size an explicit checked translate now that the knob is no longer exactly one translate-x-full wide. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * refactor: hoist the toggle knob's shared inset out of the size branches Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore(frontend): add a Toggles tab to the kitchen sink Covers the four sizes, the three colors, the label and EE-badge variants, and a grid of quarter-pixel offsets: the knob's gap against the track border only misreads once the track lands between device pixels. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
1b74939952 |
feat: support aiagent steps in test_run_step (#11321)
* fix: support aiagent steps in test_run_step Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: offer the agent's tools as a picker in the step run form Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: run a blank tool list as no tools when the step form is bypassed Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
9375c93fd8 |
fix: trust the system CA store for SMTP TLS (#11328)
* fix: trust the system CA store for SMTP TLS Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci: run the smtp-gated backend tests Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore: depend on webpki-roots 1 directly Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore: update ee-repo-ref to 48193da8cb30bc4ae82a50f944caef85d8a20b48 This commit updates the EE repository reference after PR #826 was merged in windmill-ee-private. Previous ee-repo-ref: cd3447143b25d9f3301975feca4b202755f2508f New ee-repo-ref: 48193da8cb30bc4ae82a50f944caef85d8a20b48 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> |
||
|
|
8525206361 |
fix: pass the schedule's custom tag when using run now (#11322)
* fix: pass the schedule's tag when using run now on a schedule Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep flow schedules on the flow's own tag for run now Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
98d3897b8c |
fix: hide answer actions until the chat turn ends (#11323)
* fix: hide answer actions until the chat turn ends Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: keep the last turn's answer actions during a manual compaction Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: note answer actions stay hidden while a turn waits on the user Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
2f2882adff |
fix: label chat job links with the end of the job id (#11324)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
9b46b21f51 |
feat(cli): include extra paths in codebase digest for monorepo imports (#11327)
* feat(cli): hash codebase extra_digest_paths and warn on uncovered bundle inputs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cli): cache codebase digest only once complete, skip entry in warning Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cli): accept string extra_digest_paths, always print uncovered-input warning Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cli): clarify extra_digest_paths resolution and missing-path error Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
c232ea43b4 |
fix: limit compare page guidance to fork deploys (#11300)
* fix: limit compare page guidance to fork deploys * fix: make open_page compare fork-only and drop stale api catalog bullet * fix: always open the compare page in fork mode from open_page * fix: drop the ignored mode argument from open_page |
||
|
|
80903c9a64 |
feat: per-folder AI chat instructions via ai_instruction resources (#11325)
* feat: give the AI chat per-folder instructions from ai_instruction resources Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: hold a change back until the model has read its folder instructions Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: find nested trigger paths and scope instruction deliveries by workspace Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: cap folder instructions per result and record holds as their own outcome Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: show a held call as its own row and cover group folders Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: state how folder instructions combine with workspace and user ones Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
504d01a563 |
feat: rework the git sync setup into a guided flow (#11308)
* feat: rework git sync settings into a flat repo list and setup modal Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: add the connect step for gitlab and github in git sync setup Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: open the github app install page from the git sync setup next step Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: let git sync setup set the repository folder Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: add the configure sync step to git sync setup Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: even out the git sync filter settings columns Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: pin the filter input to the bottom of the filter list Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: frame the git sync path filters in a box with an empty hint Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * refactor: use a multiselect for the git sync path filters Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: grey out the skipped connect step in git sync setup Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: move the check job line to the bottom of the setup modal Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: hide the check job line once the repository check resolved Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: center the repository check loader in the setup modal Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: stop the setup modal shifting when the check job id arrives Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: move the existing resource hint to the setup modal footer Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: always show the existing resource option when one exists Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: drop the card and collapse from the git sync filter settings Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: use a success alert for the pull from git notice Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: make initializing the repository a step of the git sync setup Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: hide the push job lines once they succeed Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: reword the push step intro Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: copy button on the cli snippet and a taller changes list Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: match the push step loading to the check step Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: stop the push step shifting when a job id arrives Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: let the changes list fill the push step Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: end the git sync setup on a done step instead of a modal Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: delete a git sync repository from a row menu with a confirmation Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: lift the git sync done message off the notices Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: restore github app installation transfer between instances Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: address regressions from the git sync setup rework Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: keep the overlay z-index floor in step with the ai chat Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: hold the push state in the setup dialog, not in the step it destroys Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: block every dismissal while setup work is in flight and keep sync reachable Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: regenerate the resource path when the repository changes Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: configure the resource the connect step actually created Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: keep a modal open when a drawer above it takes the click Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: snapshot the topmost surface for keyboard clicks too Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: size the add repository buttons and explain git promotion Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * revert: drop the promotion-first action from the empty state Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: shrink the test connection result line Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: offer the fork sync and fork pull request toggles during setup Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: group promotion repositories under their own label Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: offer the deploy branch pull request toggle during setup Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: wait for the repository credential before saving the setup Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: ignore a superseded credential load and drop the bindable default Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: key setup readiness to the repository it was loaded for Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: tie setup readiness to the attempt that asked for it Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: link to where the access token is created Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: say plainly how each provider connects Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: sync resources, variables, schedules and triggers by default Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: use the accent colour for the token help link Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * style: move the CI/CD deploy hint next to the pull toggle Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: keep setup gated when the connection could not be read Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: only explain pull-from-git where the workspace can turn it on Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: offer a save retry once the repository is initialized Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: say when pulling fell back to polling on the last setup step Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: clear the initialized flag when a new draft starts Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
6cd70a8e08 |
feat: filter ai session tools to the user's workspace capabilities (#10719)
* feat: filter ai session tools to the user's workspace capabilities Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: correct and tighten comments on the session capability filter Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: gate session deploy tools on DisableDirectDeployment and the pipeline prompt * fix: gate create_folder on the deploy capability * refactor: assemble session prompt and tools through one seam * docs: state the capability filter as best-effort, not a guarantee * refactor: take the whole deploy gate from the shared preflight `checkDeployPermission` now evaluates `DisableDirectDeployment` and folds superadmin into the admin bypass itself, so the resolver's local composition of those two terms is redundant. Delegate outright and drop the protection-rule fetch it needed, along with the two tests that restated rule semantics the preflight's own suite now pins. The preflight's per-kind narrowing stays unused: the filter runs on tool names, before the model has named a kind, so a direct-deployment lock withholds the deploy tools for schedules and triggers too. * fix: address review findings on the session capability filter Six findings from the Claude and Codex review rounds. - `discard_local_draft` is ungated. The backend exempts discarding your OWN draft from `require_can_write_path` precisely so drafts stay cleanable after a role change; gating it stranded that cleanup. - `deploy` splits into `deploy` and `deploy_gated_kinds`, mirroring `deployPermissionForKind`. A direct-deployment lock stops only the kinds that reach `check_deploy_rules`, so schedules and triggers stay deployable and the two kind-taking deploy tools survive the lock; `create_folder` does not, folder being a gated kind. The prompt now names the lock and what it leaves deployable, instead of implying nothing can be deployed. - `COVERED_ENDPOINTS` keyed `createApp` / `updateApp`, which the MCP catalog does not expose; the app-authoring endpoints it does expose, `createAppRawSource` and `updateAppRawSource`, were uncovered and reachable through `call_api_endpoint`. - The YOLO tooltip listed tools a restricted session never ships. Both it and the token estimate now read one `shippedTools`, and `sessionAccess` is reactive so the UI follows the resolution. * fix: restore the covered API-catalog names for the raw-app endpoints `COVERED_ENDPOINTS` is matched against `EndpointTool.name`, which openapi.yaml overrides with `x-mcp-tool-name` for these two operations: `createAppRawSource` and `updateAppRawSource` are served as `createApp` and `updateApp` (`mcp/auto_generated_endpoints.rs`). Keying them by operationId left both raw-app POST endpoints discoverable and callable through the API catalog tools. Restore the exposed names and record why they differ from the operationIds. * docs: state each capability invariant once, and document the draft discard The asymmetric admin/operator precedence was restated three times in sessionAccess.ts and again in its test, the fail-open rationale twice, and the deploy split across four sites. Each now lives at the one place someone would break it, within the four-line budget, with the other sites pointing at it. Ungating discard_local_draft left it undocumented for the read-only profile, which is the profile the backend exemption exists for: the only bullet naming it sits under the draft-writing gate, beneath an opener saying no change is possible. Add the one line that profile needs. * docs: record why the session tool filter runs unconditionally The filter would strip everything from a non-GLOBAL toolset, whose names carry no policy entries. That cannot happen — `changeMode` refuses to move a session chat out of GLOBAL, and `sessionAccess` is only ever set for session chats — but the dependency was not visible at the filter itself. * fix: match the server's deploy gate exactly, never exceed it The filter must be as strict as the server and no stricter. Schedules and triggers reach no deploy rule — `check_deploy_rules` runs only from the gated kinds' handlers — so no workspace refuses `deploy_workspace_item` or `delete_workspace_item` outright, whatever refusal `checkDeployPermission` reports. Gating them on a deploy capability withheld operations the server performs. Neither tool now requires a capability. Deploying still needs a draft to deploy, so it keeps the authoring relevance; deleting a deployed item does not, so it is ungated. `deploy` returns to one capability, covering the kinds the rules gate, and `create_folder` — whose kind is one of them — is the only tool that names it. The session-state note now states which kinds a refusing workspace still accepts. * feat: gate the new app-runnable preview tool on run_preview Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * fix: fail open when whoami resolves without a role Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * fix: count plan-mode tools in the shipped toolset Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * docs: drop the dead capability assertion and the repeated deploy rationale Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * refactor: drop dead code and a duplicated invariant from the session filter Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * refactor: reduce SessionAccess to the capability set it is read for Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * refactor: gate session tools on permission alone, never on relevance Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * test: pin the filter to the outbound request and widen the description sweep Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * refactor: collapse SessionAccess to a capability set and merge adjacent gates Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * fix: gate get_db_schema on run_preview, it runs a query script Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * fix: reuse the cached workspace role and derive the exhaustiveness list from assembly Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * revert: keep tool names in descriptions that ship with them Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * fix: let an admin who is also an operator deploy, as the server does Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * fix: derive the deploy capability from the protection rules alone Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * fix: stop the datatable instructions naming a tool a session may not have Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * fix: keep the prompt and tool results honest for a profile that cannot draft Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * refactor: move tool policies onto the tools and gate kinds per handler Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * chore: tighten stale comments and name deploy in the operator prompt Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * fix: keep the assembled tool list raw so narrowing can clone its defs Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * fix: point an operator at a workspace admin for code the role refuses Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * fix: resolve session permissions when the assistant settings modal opens Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L99mAR4LitqTcYY1Kn1ATH * refactor: return per-chat tool schemas instead of writing them to shared tools Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: forward this through the eval tool wrapper so tools see their sent def Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test: pin identity and contents in the session filter and schema tests Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: note why the overhead estimate skips per-chat tool schemas Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
0e53d53b07 |
fix: space chat rows evenly after thinking and answers (#11315)
* fix: space chat rows evenly after thinking and answers Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: keep a flow step's answer actions and space its step label Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: pick the answer that shows actions from later answers, not the next row Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: group answer actions by the step run's job, not its label Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs: state the per-run action row rule in AssistantMessage comments Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
62d0088de5 |
feat: show restart from failed step in run page top bar (#11317)
* feat: show restart from failed step in run page top bar Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: keep failed-step restart button when selection is not restartable Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat: add restart link to the failed run status line Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: use the input error color for the progress bar error state Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat: mention restarting on a fixed flow version in the error line Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat: show a chevron on the restart button when it opens a picker Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: shrink run page top bar buttons so the bar fits on one line Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: target the step that failed the run, not a tolerated failure Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: address review nits on the restart link Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: skip canceled runs and match the restart link label to its text Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
5b03c1732e |
fix: build ag grid link cells as DOM nodes with a vetted href (#11316)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
ceb17223dc |
fix: bill from a single service account telemetry count (#11301)
* [ee] fix: bill from a single service account telemetry count Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * [ee] fix: count service accounts held in forks Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * chore: update ee-repo-ref to ed5a367b4def5280c3a5e1090e7abfa099a01042 This commit updates the EE repository reference after PR #824 was merged in windmill-ee-private. Previous ee-repo-ref: bc1fe61364c2a731ec26186eb04596254886a74c New ee-repo-ref: ed5a367b4def5280c3a5e1090e7abfa099a01042 Automated by sync-ee-ref workflow. --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com> |
||
|
|
7593597617 |
fix: validate app and trigger paths, refuse traversal in workspace export (#11311)
* fix: enforce proper_id paths on apps and triggers, refuse traversal in export Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: skip proper_id on tables already holding non-conforming paths Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test: pin archive entry path traversal guard Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: refuse windows-normalized traversal in export, check raw app path early Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: only treat a colon in the first archive segment as a drive prefix Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test: accept a colon past the first archive segment Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * revert: drop proper_id migration, keep path validation in the API Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: validate paths in bulk http trigger creation Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
1de54eeea4 |
feat(ai-chat): show native script edit diffs (#11278)
* feat(ai-chat): show native script edit diffs * fix: render streamed edit diffs * fix: render in-editor script edit diffs * style: soften diff context separators * fix: render full script update diffs * fix: support empty script diffs * fix: bound streamed tool diffs * fix: preserve trailing diff context * fix: defer collapsed tool diffs * fix: retain full-code streaming previews * fix: preserve created script diffs * fix: disambiguate collapsed diff keys * fix: render final newline diffs * fix: preserve multiline diff highlighting * fix: highlight diff sides as complete sources * fix: bound completed tool diffs * fix: diff large completed tool edits Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: bound tool diff rendering Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: bound tool diff highlighting and expand omitted rows Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: reveal omitted diff rows in chunks and bound long-line highlighting Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: collapse written scripts, skip empty diff bodies and fit line numbers Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: keep whole-file tool diffs collapsed while running Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: classify whole-file tool calls by argument shape Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: reopen failed diff cards and keep empty streamed replacements Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
fa0fc24269 |
feat: render a tool's web search result as the session web search card (#11313)
* feat: render a tool's web search result as the session web search card
Any tool whose result is exactly `{ sources: [{ url, title? }], query? }`
now renders as the card the AI session shows for a provider-side web
search, in the agent step trace and in the flow chat. The provider-side
search itself gets the same card on both surfaces: its citations, which
the worker records on the assistant turn that follows, move onto the
search row.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep the trace tool label off the lazily fetched job
The web search card's label read the tool's job, which is only fetched
once the row is expanded, so the query suffix appeared only after the
row had been opened. The shape of the result decides the label; the
job's failure still decides whether the sources or the error show.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep unrenderable sources and tool hostnames out of the search card
A result whose urls the card cannot render — relative, or javascript: —
matched the shape and replaced the tool's own output with an empty list,
so the predicate now requires what the renderer accepts. A tool's sources
can name internal services, so they no longer resolve a favicon through
Google's service; provider-side search results still do. An absent
optional reaches JSON as null from a Python tool, which now reads as
absent rather than rejecting the whole result.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: name the host when a source carries a blank title
A source whose title is an empty string rendered as a link with no text
at all, the empty title also suppressing the hostname beside it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
40476e7be9 |
ci: skip the AI reviews and the Discord notice on Dependabot PRs (#11307)
* ci: skip the AI reviews and the Discord notice on Dependabot PRs
They already do not review them, they just fail while doing so. The Claude
action rejects a bot actor outright ("Workflow initiated by non-human actor"),
and the Codex and Pi jobs find no API key because GitHub gives Dependabot-
triggered runs a separate secret scope from Actions. Verified on #11302: zero
reviews posted, the only comment is a Cloudflare deployment notice, while
codex-review and pi-review both reported success.
So every Dependabot PR carried two permanently red checks that meant nothing,
which is the worst kind of signal — it buries a Dependabot PR that genuinely is
broken, and a green tick that means "skipped" reads exactly like one that means
"looked and approved".
Skipping states it honestly. The workflow_call branch is untouched, so a review
can still be requested on a specific bot PR when the diff deserves one, which is
worth doing for a grouped security update that swaps a cipher or drops a parser
rather than just moving a version.
The Discord notice is excluded for the same reason plus its own: nobody wants a
forum thread per lockfile bump.
Not fixed here, deliberately: making these actually review bot PRs would need
the org's review credentials copied into the Dependabot secret scope, which is a
wider grant than this is worth given the PRs in question are lockfile diffs.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* ci: gate the close-time Discord job too, and trim the comments
Both reviewers caught the same gap: merge_success_emoji runs on every `closed`
event with no exclusion, and the reusable workflow it calls exits 1 when it
cannot find a thread. Since open_thread no longer creates one for Dependabot,
the failure would have moved from open-time to merge-time rather than going
away. Gated to match.
The comments are cut from eight lines to two per file. AGENTS.md:205 asks for
constraints in <=4 lines, stated once, describing the code as it is — mine
narrated the drafting history and argued the change to a reviewer, both of which
belong in the PR description. Also drops "bot-authored", which overstated a
condition that only covers dependabot[bot].
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
318f89960e |
feat: count enabled service accounts as operator seats (#11297)
* [ee] feat: count enabled service accounts as operator seats Bumps the EE pin to the change that reports enabled service accounts in telemetry, so the portal bills each as half a seat, and counts them against the offline license seat cap. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * chore: update ee-repo-ref to 0914cece0eb508150898022a0d78da9caa0a1c6d This commit updates the EE repository reference after PR #823 was merged in windmill-ee-private. Previous ee-repo-ref: 27b9970ceba778442f803e55255eb5db25f59a97 New ee-repo-ref: 0914cece0eb508150898022a0d78da9caa0a1c6d Automated by sync-ee-ref workflow. --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Ruben Fiszel <ruben@windmill.dev> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com> |
||
|
|
d8aaa73573 |
feat: chat with a saved agent from the agent editor (#11292)
* feat: chat with a saved agent from the agent editor * fix: keep agent chats apart from a same-path flow's conversations * fix: point an agent editor chat's model gap at the agent, not a step * fix: match the memory gate's icon to the chat's empty state |
||
|
|
89323fb025 |
refactor: separate the tools the chat sends from the ones it has (#11295)
* refactor: split the chat's tool list into sent-now and available-in-session views Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * refactor: drop the forward-looking ticket reference from the tool-base comment Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * refactor: make the readonly tool seam enforceable and the comments accurate Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
42655ff5ef |
fix: memoize the resolved authed so one request resolves identity once (#11299)
* fix: memoize the resolved authed so one request resolves identity once Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test: pin that the memo preserves job token provenance Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
ea0b947644 |
fix: stop the chat repeating run results the card already shows (#11293)
* fix: tell the chat not to repeat run results the card already shows * fix: add the run result note on completion, background runs included * fix: skip the run result note on failed runs * fix: keep the run result note off background completions |
||
|
|
592ef73610 |
fix: keep a watched job's code when its completion update drops it (#11290)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
7dec3d9771 |
feat(db-manager): add a schema diagram view (#11030)
* feat(datatables): put a data table's connection under Postgres roles A data table backed by the instance database resolved to exactly one Postgres connection, `custom_instance_user`, for everyone who could reach it at all. There was no way to say this job reads, that one writes, this one never sees the salaries table. A data table role is now a real Postgres login on the cluster, defined once for the instance by a superadmin and named exactly as they named it. A script that declares `-- role analytics` connects as `analytics`, and Postgres decides what it may touch — grants are ordinary SQL. Windmill answers only "may this caller ask for this role", from the tenant lists on the data table entry: `u/alice`, `g/analysts`, `f/finance` or `*`. A data table with no `permissions` block behaves exactly as before. Everything that opens a connection on someone's behalf goes through one chokepoint, `get_datatable_resource_from_db`, which takes the identity explicitly and fails closed when there is none. The role logs in as itself — never `SET ROLE`, which a script could `RESET ROLE` its way out of. A fork's data table entry becomes a pointer at the workspace that governs it rather than a copy of it. The settings clone used to hand a fork a byte-identical entry naming the parent's database, which a fork admin could edit to grant themselves `admin` there; a pointer has nothing local to edit, and its tenants are evaluated as a member of the governing workspace, by email. `permissions` is stripped from the workspace export and ignored on import: tenants name principals of one workspace, and a settings push is not where an access decision should be made. Operations that see the whole database whatever the roles grant stay with the governing workspace's admins: editing the roles, a migration that declares none, and opening a replication stream for a Postgres trigger or capture. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ti5HyeTikPMYyW8YSdiHR * fix(datatables): gate the paths that reach a whole database as admin Auditing what still resolved through the unchecked resolver turned up three that act for a caller and hand back the admin connection: `resolve_pg_source_checked` (behind schema export, the full-schema read, database creation, import and the forked-database drop), the connection test, and the schema snapshot a fork clone takes of its parent. On a data table under roles each let any workspace member — or a fork admin who is nobody in the governing workspace — read or copy the whole database whatever its roles grant. All three now require admin reach on the governing workspace. A dump taken under a restricted role would be a silently truncated copy rather than an error, so refusing is the only right answer for the copy paths. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ti5HyeTikPMYyW8YSdiHR * fix(datatables): confine roles to the instance database, and stop a fork reaching the parent's bookkeeping A data table role is a login on Windmill's own Postgres. Nothing stopped a workspace admin putting a *resource-backed* data table under roles, at which point the executor dialled the host that resource names — one the admin chose — with the role's real cluster password, and `CONNECT` is granted to every registered instance database. Both ends now refuse: the permissions endpoint rejects the save, and the chokepoint refuses to substitute credentials on a non-instance entry rather than trusting the record it read. Two more places reached the governing database without answering to it. The initial-migration generator returned a `pg_dump` of the whole schema to any member. And the migration rename/delete cascade followed a fork's pointer into the parent, so a fork admin renaming or removing their own local entry relabelled or wiped the parent's `_wm_migrations` — after which the parent re-runs every migration from zero. The remote half is now skipped when the entry resolves into another workspace, which is also just correct: a fork renaming what it calls a data table changes nothing about the data table. Also: revoking a tenant now bounces the replication streams of every workspace holding an entry that resolves here, not only the governing one, so a fork's trigger stops rather than living on inside its open connection; the instance role catalog and the governing workspace's tenant lists are no longer returned to someone who cannot edit them; and the tenant rename dedup collapses non-adjacent duplicates, per role rather than once any role changed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ti5HyeTikPMYyW8YSdiHR * fix(datatables): fail loudly where a role or a pointer can be left half-recorded Three ways the feature could end up in a state nobody could see or undo. Creating a role writes the cluster first and the catalog second, but the catalog write was an `UPDATE` that matched nothing when the instance Postgres settings row was absent — leaving a live login with a password nobody recorded: invisible to the catalog, un-recreatable because the name is taken, and un-deletable because there is no entry to delete. It now errors, so the operation is retryable once the row is restored. Deleting a workspace only nulls the fork lineage; the data table entries pointing at it are left resolving to nothing. Sweeping them is not an option — turning a pointer back into a copy would hand each fork the database outright — so the delete now names the data tables it stranded, and resolving one says which workspace is missing rather than reporting a data table this workspace never had. `InstanceDatatableRole` derived `Debug` while holding a Postgres password; it is now hand-written so `{:?}` on the catalog cannot put a live credential in a log line. Adds the two branches the reviews found unpinned: a caller who is not a member of the governing workspace at all, and `NoIdentity` — the compatibility path for an agent worker that predates this and sends no job id. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ti5HyeTikPMYyW8YSdiHR * fix(datatables): unbreak two operator messages and two comments that described other code The two strings this branch added for states an operator hits once — the catalog write that matched nothing, and the delete that stranded a pointer — were collapsed from their multi-line form with the indentation left in, so both rendered with a fourteen-space gap mid-sentence. `list_datatables` claimed to report a chain it cannot follow and then dropped it; it does drop it, and the comment now says why that is the right place to stay quiet. The non-superadmin check in `edit_datatable_config` was introduced as also covering references, which it does not and need not: `reference` is overwritten from the stored entry for every caller before the check runs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ti5HyeTikPMYyW8YSdiHR * fix(datatables): serialize role catalog mutations, and state each helper's authorization contract The catalog is one JSON document, so create, rename, enable and delete are all read-modify-write. Two concurrent creates read the same snapshot, both succeed in the cluster, and the second write drops the first — leaving a live Postgres login with a password nobody recorded, which is the exact state the delete path exists to prevent. Every mutation now runs in one transaction holding an advisory lock across the read, the cluster DDL and the write, so a lost update cannot happen and a failure rolls the whole thing back. The DDL helpers take that transaction rather than the pool, which is what makes the lock cover them. Their statements moved off `sqlx::raw_sql`: the simple protocol is only needed for genuinely multi-statement SQL, and its future is not `Send`, which an axum handler holding the transaction requires. Each of these is one statement anyway. The new cross-crate surface now says what callers must do. `read_role_catalog` returns plaintext credentials; `create`/`rename`/`set_login`/`drop_instance_role` and `converge_connect_grants` mutate cluster-wide state; `read_datatable_entry` reads a workspace's raw config. All of them are superadmin-gated by their current handlers, but nothing said so at the definition, which is where the next caller looks. Also: the roles table reloads after a failed login toggle instead of leaving it claiming a flip that did not land; the rename affordance is the design-system `Button`, not a raw one; and `resolve_datatable_pg_as_caller` drops a `role` parameter no caller ever filled — browsing resolves as the data table's default until the database manager grows a picker. Why role passwords stay a plain `String` while the instance user's password beside them is a `StringOrSecretRef`, asked three times across reviews: that one is a secret ref because an operator supplies it and may want it from their own backend, while these are minted here and never entered by anyone, so there is nothing for a ref to point at. Encrypting generated secrets at rest is a separate change that would take the replication password with it. Now said at the field. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ti5HyeTikPMYyW8YSdiHR * fix(datatables): give the role catalog its own row, out of reach of the config machinery Putting it inside `custom_instance_pg_databases` was the wrong call, and it cost two ways. The catalog serializes a generated Postgres password per role, and that row is the operator-facing instance config, so the passwords reached `get_instance_config` and its YAML editor — a live cluster credential in a response body, a UI field and any log of either. Worse in the other direction: `to_settings_map` strips the catalog, so a full-row upsert of that key writes the row back without it and the catalog is gone, while the cluster keeps every login it described. `custom_instance_replication_pwd` is the precedent and says exactly why — a generated secret, written only by the server, never operator-authored, hidden so the config machinery cannot read, rewrite or drop it. The catalog is the same thing, so it now has the same shape: `datatable_roles`, in `HIDDEN_SETTINGS`, `PROTECTED_SETTINGS` and the agent-worker denylist. No redaction to keep in step with three code paths, and no way for a neighbouring write to take it out. Two races on the same shared documents. `edit_datatable_config` read the stored data tables outside its transaction and then wrote the whole `datatable` document, so a permissions save committing in between was silently rolled back; it now reads under `FOR UPDATE`. And `set_datatable_permissions` validated role ids against the catalog before opening its transaction, so a deletion in between let it write a deleted role back — including as the default, which every later job then fails on; it now holds the catalog lock and the settings row across validation and write. Completes the authorization contracts the previous commit claimed but did not finish: `read_datatable_entry` (which it named and missed), `resolve_governing_datatable`, whose whole job is to answer for a workspace the caller may not belong to, and `converge_connect_grants_with`, which had not inherited its wrapper's. Also the generic Python SDK reference: `_format_py_params` learned the bare `*` last time, but `extract_py_functions` is a second formatter and still rendered `datatable(name, role)`, so code written from that page passed a keyword-only argument positionally. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ti5HyeTikPMYyW8YSdiHR * fix(datatables): make the concurrency test pin the handlers, and the contracts describe what is enforced The concurrency test reimplemented the read-modify-write inline, so deleting the lock from all three handlers left it green — it pinned Postgres, not the code it was written for. It now drives `create_datatable_role` twice concurrently and asserts the catalog kept both names. Checked the way the last one should have been: removing the lock from the handler makes it fail with "wmtest_a_… is a live cluster login the catalog forgot". The contracts added last commit were stricter than this PR's own callers, which is worse than none — the next reader sees a rule already broken and learns to ignore it. `read_role_catalog` said superadmin-only while two of its four callers are open to any workspace member, and `converge_connect_grants` said superadmin while `set_datatable_permissions` reaches it as a workspace admin. Both were fine on substance: the rule that actually holds is about the credential never reaching a response, log, audit record or export, not about who may call. They now say that. `read_datatable_entry` gets the same treatment rather than the one the earlier message claimed for it: it is the primitive every resolution goes through, so it is deliberately open, and what must not escape is `permissions` — it names the governing workspace's users, groups and folders. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ti5HyeTikPMYyW8YSdiHR * fix(datatables): close the last ways a role or a pointer can be left pointing at nothing The raw settings readers hand back whatever is in the row, so moving the catalog into its own `global_settings` key protected the config machinery and left `GET /settings/global/datatable_roles` and the settings listing returning every live password. Both now filter that one key. The neighbouring `custom_instance_replication_pwd` has the same shape and is not touched here: it predates this and widening the fix to it is a decision about an operator workflow, not a consequence of this change. Three ways a save could leave something resolving to nothing: A permissioned data table could be moved to a PostgreSQL resource. The block was carried across as a server-owned field, the runtime refuses roles on a resource-backed table, so the save succeeded and every job afterwards failed. Refused instead — turning roles off first is one step, and it keeps discarding an access decision something somebody chose. Renaming a governing data table left every fork pointing at the old name: the data table disappears from their pickers and their jobs stop, with nothing in the renaming workspace to suggest why. The rename now follows into the pointers in the same transaction. Deleting one cannot be followed the same way, so it is reported instead — the response names what it stranded, the way deleting a workspace does, and the fork's own error already says which workspace is gone. Also: `ensure_instance_db_grant_options_unchecked` claimed superadmin while the permissions handler reaches it as a workspace admin (the same class fixed last commit, one instance missed); the role entry kept an `instance_config_schema` derive it no longer needs; `write_role_catalog` was the one writer of that table not stamping `updated_at`; and the concurrency test dropped its roles only on success — a failing run is exactly the one that creates them without recording them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ti5HyeTikPMYyW8YSdiHR * refactor(datatables): put the role catalog in its own table, not in global_settings Five findings across three rounds were all the same choice. A set of live Postgres credentials was living in `global_settings`, which has generic read, list, write, config-export and CLI round-trip paths that know nothing about what they carry: the passwords reached the instance config and its YAML editor, a full-row upsert of a neighbouring key erased the catalog, `GET /settings/global/{key}` and the settings listing returned them raw, and this round the redaction that fixed the last two turned `wmill instance push` into something that wipes every password — a fix breaking the assumption the previous fix made. `POST /settings/global/datatable_roles` could also empty it outside the lock. The approved plan offered a table or `global_settings`, so this is the other option it already allowed rather than a new design. `datatable_role` is a table: no generic settings path can read it, list it, export it, write it or round-trip it, so none of the five needs a guard. The redaction, the hidden/protected/agent-denylist entries and the JSON document all go with it. One row per role also removes the read-modify-write the concurrency work was about: two concurrent creates are two inserts, and the unique index on `name` is what settles a collision. The advisory lock stays for the one window rows do not cover — `CREATE ROLE` is invisible to another transaction until commit, so without it both creates pass their `pg_roles` check. Also from this round: rename mappings are checked against the configuration they claim to describe, since fork pointers are rewritten from them — a caller could otherwise submit `main -> missing` against an unchanged config and repoint every fork of `main` at a name nothing has, and `A -> B` plus `B -> C` moved what pointed at `A` all the way to `C`. And the warning naming forks a delete stranded reached the response but not the screen: both the data table settings save and the workspace delete now show it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ti5HyeTikPMYyW8YSdiHR * fix(datatables): validate a rename against the save it describes, and re-check under the locks Three from the round, all about deciding on state that could already have moved. A permission save resolved the data table and checked it was instance-backed before taking any lock, then wrote under one. A config save committing in between could move the table onto a PostgreSQL resource — recreating exactly what the transition guard refuses — or rename it, in which case the write targeted a key that no longer existed and reported success having changed nothing. It now re-resolves and re-checks on the locked state. Rename validation checked that the source existed before and the target existed after, which still accepts `main -> decoy` against a save that keeps both: every fork of `main` then follows onto a different data table, silently, because it keeps resolving. The rule is now the actual old-to-new key transition — a source may only survive if another rename took its name, and a target may only pre-exist if another rename freed it. That also stops two sources sharing one target, and it admits a swap, which the previous guard refused: `datatables` is keyed by name, so a swap cannot be done one save at a time, and refusing it was a regression against main. The pointer cascade now runs in two passes through a temporary name, the way the migration cascade one layer down already handles the same shape, so `A -> B` with `B -> C` moves each pointer once from what it named before the save. The tenant mutators say what they are for: they write an access decision for any workspace named, with an arbitrary mutation, and exist for the transaction that frees or renames a principal. Editing a decision on purpose belongs in the permissions endpoint. Carried in the same change: the stranded-fork list is a field rather than a phrase to grep out of a success string; the pointer cascade matches with `EXISTS` instead of a `LIKE` over the whole document, so a workspace whose pointers name something else is not rewritten to a byte-identical value under an exclusive lock; and `InstanceDatatableRole` drops the serde derives left over from the JSON document, one of which would emit `pwd`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ti5HyeTikPMYyW8YSdiHR * fix(datatables): cascade on the leave route that is used, gate migrations before the admin connection, and drop a role atomically The tenant cascade on leaving went onto `/users/leave`. The UI and the generated client call `/workspaces/leave` — a different handler in a different crate with the same name — which deleted the membership and left `u/<username>` in the tenant lists. Leaving and rejoining therefore restored the access the leave was supposed to end, and a later account taking the username would have inherited it. The regression test drives the route the client actually calls; without the fix it fails with "leaving kept the tenant". The migration endpoints authorized too late. `run_datatable_migrations` opened the data table's admin connection, created `_wm_migrations` and read it before reaching the per-migration role check — so with nothing pending, nothing was checked at all. Rollback returned before its check when nothing was applied, and the status endpoint had none. All three now ask, before any connection is opened, whether the caller can reach the data table as any role at all; which role a given migration runs as is still decided per migration, and by the executor after that. Deleting a role committed the cluster drop and the catalog row, then swept the tenant lists in separate transactions. A sweep failing part-way left workspaces naming a role nothing can connect as, while the retry answered `NotFound` because the catalog entry was already gone. The sweep now runs in the same transaction, so the drop, the row and every tenant list commit together. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ti5HyeTikPMYyW8YSdiHR * fix(datatables): refuse to copy a data table that is under roles pg_dump carries no roles and the import runs with --no-privileges, so a copied data table arrives owned by the admin connection with no GRANT for any role. The settings clone brings `permissions` across, so the fork's tenants pass Windmill's check, connect as the role they were given, and are denied by Postgres on everything: an entry that reads as configured and answers nothing. Refuse the copy — in the import endpoint before any data moves, and in the fork path the CLI takes. Replaying the source's owners and ACLs into the clone is what lifts this, and is a change of its own. Dropping `permissions` from the copy instead would be the unsafe half, since the copy holds the parent's rows. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ti5HyeTikPMYyW8YSdiHR * fix(datatables): refuse the clone's database too, not only its data A clone is two endpoints: `create_pg_database` then `import_pg_database`. Only the second refused a data table under roles, so a fork asking to clone one created and registered an empty `wm_fork_…` instance database and then failed — and nothing collects it, since `drop_forked_datatable_databases` only drops entries carrying `forked_from` and no entry names this one. Refuse in both, so the clone stops before a database exists. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ti5HyeTikPMYyW8YSdiHR * nit worker error msg * fix pg_dump stuck on version 17 on nix * fix(datatables): refuse a malformed role annotation instead of ignoring it `-- Role operator`, `-- role operator;` and `-- role operator -- why` all failed the annotation parser's exact-match rule, so the query fell through to the data table's default role and ran, silently, under a login the author did not choose. Naming a role exists precisely to not do that. A leading comment whose first word is `role` is now an annotation attempt: the keyword matches case-insensitively, one trailing `;` is tolerated, and anything else is an error naming the line. Only callers that already know the target is a `datatable://` reference ever run this, so ordinary SQL keeps its comments. Also bumps the dev shell's postgres client to 18 — it trailed the server the dev database runs, which takes out every data table export, clone and fork-with-data. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ti5HyeTikPMYyW8YSdiHR * fix(datatables): refuse a malformed role query string instead of ignoring it `?Role=analytics`, `?role=` and `?x=1&role=…` all fell through the reference parser's exact-match rule, so the connection resolved to the data table's default role and ran under a login the caller never asked for — the URI half of the same trap as a malformed `-- role` annotation. The key now matches case-insensitively, and anything else in the query string is an error naming it; `role` is the only parameter a reference takes. Callers that only need the entry keep a lenient `datatable_ref_name`, since they never act on the role. The DuckDB `ATTACH` parser propagates it rather than attaching under the default. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ti5HyeTikPMYyW8YSdiHR * fix(datatables): carry the role annotation into the row_to_json retry The retry rebuilds its SQL from `pruneComments(code)`, so the leading comment block never reached the second attempt — and with it the `-- role <name>` line that decides which login the query runs as. The retry connected as the data table's default role instead, so a query the first attempt was denied could succeed on the second, reported as "recovered with the row_to_json fix". Carry the leading comment block over. The retry itself is unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BjfMkJyKzodxkobqGZ6Lqb * chore(datatables): don't mount the roles UI until the ACL editor lands Enforcement ships first. The permissions drawer is what turns roles on, and the catalog section is what creates them — both are only useful once there is a way to grant a role the privileges it needs, which arrives with the ACL editor. Left mounted they would offer a feature whose other half does not exist. The two components are complete and reviewed; only their call sites here are commented out, with a note pointing the follow-up PRs at them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BjfMkJyKzodxkobqGZ6Lqb * fix(datatables): honour `-- role: x`, and fix the DuckDB attach test Two review findings, both real. `attach_datatable_parses_name_and_role` never compiled: `parse_attach_datatable` returns `Result<Option<_>>` now and one call site kept a single `unwrap`. Its `?Role=analytics` case also asserted a refusal, contradicting the parser in the same commit, which matches the key case-insensitively. Replaced with the cases that are genuinely malformed, and a positive one for the cased key. `-- role: analytics` fell through to the default role — the silent fallback the strict parser exists to remove, for the spelling most likely to be typed. The keyword now accepts an optional colon, attached or spaced, while a word that merely starts with it (`rolebased`) is still not an attempt. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BjfMkJyKzodxkobqGZ6Lqb * fix(datatables): clone a fork's pointer instead of failing after the copy Forking a fork with cloning left an orphan database. The preflight resolves the pointer and sees the governing entry, so both endpoints ran and filled the new database; `apply_forked_datatable` then refused the inherited pointer and rolled the fork back, stranding a registered `wm_fork_*` that no entry names and whose name blocks the retry. Refusing earlier would have been the smaller change, but forking a fork and cloning worked before pointers existed, so it would trade an orphan for a regression. Resolve what the pointer names and write the terminal entry the clone needs: the whole `database` object rather than a patch of its `resource_path`, since a pointer has none, and `reference` removed with it. Also accepts `-- role=x` and `-- Role = x`, two more spellings that fell through to the default role. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BjfMkJyKzodxkobqGZ6Lqb * fix(datatables): refuse to roll back the catalog while roles exist The down migration dropped the table and left every role behind: live Postgres logins whose passwords only that table carried, so after a revert Windmill could neither use, disable nor delete them, and re-applying could not recreate them because the names were taken. Cleaning up here is not possible either — dropping a role means reassigning what it owns in every instance database, and a migration runs in one — so it now refuses while the catalog is non-empty and says to delete the roles through instance settings, which does the cluster work. Also enforces the instance-only invariant the resolved-pointer clone relies on rather than only asserting it in a comment. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BjfMkJyKzodxkobqGZ6Lqb * refactor(datatables): settle clonability in one place, before anything is created A clone is three stages a workspace apart — `create_pg_database`, then `import_pg_database`, then `apply_forked_datatable` inside the fork transaction. Only the third can roll back, and `CREATE DATABASE` is not transactional, so any refusal that lives there strands a registered `wm_fork_*` that no entry names and whose name blocks the retry. That orphan has now been fixed three times, most recently reintroduced by a guard added one commit ago. Patching each new refusal into the first endpoint is not the fix; having two places that can refuse is. `ensure_datatable_is_clonable` now answers every reason a copy can be refused and returns what it resolved, and the stage that writes the entry only does the work. Also takes an ACCESS EXCLUSIVE lock before the rollback guard counts, so a role created concurrently cannot slip between the check and the drop. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BjfMkJyKzodxkobqGZ6Lqb * fix(datatables): let a retried clone reclaim its own leftover database A clone creates its target database one request before it copies into it, and the fork that would name it is written a request after that. Any failure in between — a pg_dump error, a bad restore, a dropped connection, the source's roles changing mid-flow — left a registered `wm_fork_*` that no entry names, and every retry then failed on its name. This predates data table roles. `create_pg_database` now reclaims such a leftover before creating: only a `wm_fork_*` database Windmill registered as a data table database and that no data table or ducklake entry names, in any workspace, archived ones included. The drop never terminates connections, so a clone still copying into it makes the reclaim fail instead of being cut off. It is limited to callers who administer the source — reaching it is not enough, since on a data table without roles every member reaches it — and anyone else gets the refusal an existing database always got. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Revert "fix(datatables): let a retried clone reclaim its own leftover database" This reverts commit |
||
|
|
25c8bfaab4 |
chore(main): release 1.817.0 (#11268)
* chore(main): release 1.817.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>v1.817.0 |
||
|
|
841f7e1436 |
fix(cli): sync workspace dependency files on Windows and fix CLI tests (#11288)
* fix(cli): sync workspace dependency files on Windows Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test(cli): pin workspace dependency path parsing on both separators Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(cli): classify workspace dependency files on either separator Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test(cli): check out the fork deploy clone without autocrlf Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
732214361f |
fix: stop the raw app editor stealing focus in ai sessions (#11287)
* fix: preserve raw app editor focus during ai file updates * fix: sync ai file edits through the existing files effect * docs: explain raw app file synchronization dependency * fix: avoid echoing raw app files back into the editor * fix: synchronize raw app file operations through one effect * fix: stop session draft sync from re-applying the editor's own edits Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: open raw app files without taking focus and follow idle ai edits Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: keep selecting raw app documents that live outside the app files Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: tie a pending raw app editor focus request to the picked file Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore: pin ui_builder to 60b6904 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: always send explicit raw app file replacements to the editor Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Guilhem Lemouel <guilhemlemouel@gmail.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
02006f364a |
fix: keep a cancel that lands after a worker last read its queue row (#11246)
* fix: keep a cancel that lands after a worker last read its queue row Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix: take the cancellation from the queue row the completion deletes Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * test: wait for the completion to block on the row instead of a timer Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * refactor: settle a missed cancel from the deleted queue row alone Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
7d0f2ce3bf |
fix: size the AI chat output budget by model, not provider (#11286)
* fix: size the AI chat output budget by model, not provider Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: keep self-hosted open-weight models on the fallback output budget Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore: point ee-repo-ref at the free tier output clamp change Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: treat codestral as open-weight for the output budget Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore: update ee-repo-ref to 559a9ff78ea03439553cf2b412e73765762e9013 This commit updates the EE repository reference after PR #821 was merged in windmill-ee-private. Previous ee-repo-ref: 953f7c1cc9a70b740d5d1b129cb1401950854b02 New ee-repo-ref: 559a9ff78ea03439553cf2b412e73765762e9013 Automated by sync-ee-ref workflow. --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com> |
||
|
|
efa7a0a70a |
feat: allow workspace-scoped dynamic custom tags (#11283)
* feat: check dynamic worker tags on the tag they resolve to Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test: pin the tag check after a flow preprocessor resolves the tag Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: keep tied tag placeholders exact and drop an unresolvable flow tag Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: describe tied tag placeholders in the custom tags editor Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: check workflow-as-code task tags on the tag they resolve to Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: judge a preprocessed flow's tag as written when it is run Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: check a preprocessed flow's own tag, as written only where it reads args Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: explain dynamic tags in the worker tag picker Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: look up worker availability for typed static tags Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: poll worker availability with the tag list as it is at each run Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: allow workspace-scoped dynamic custom tags Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test: pin the $workspace lookup for scoped custom tag patterns Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: keep a tag listed with its own scope inside it past matching patterns Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: warn when a scoped custom tag is also listed for every workspace Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
e7ba5954b6 |
feat: add workspace mentions to AI composer (#11264)
* feat: add workspace mentions to AI composer * fix: ignore embedded mention text in composer * fix: sync only standalone composer mentions * fix: keep punctuation-adjacent mentions active * fix: use unicode mention boundaries * fix: handle unicode mention prefixes * fix: avoid rescanning mention prefixes |
||
|
|
faf7b22be0 |
fix: apply token path scopes to the native trigger list (#11281)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
586699c493 |
fix: apply SSRF validation to workspace webhook URLs (#11285)
* fix: apply SSRF validation to workspace webhook URLs Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * test: assert edit_webhook refuses a private webhook URL Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix: stop the webhook sender following redirects past the SSRF check Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
9ad2c91ddb |
fix: enforce token path scopes on GET /raw_apps/list (#11284)
* fix: enforce token path scopes on GET /raw_apps/list Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: apply the raw app scope filter before the page limit Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test: cover the bare prefix path in the raw app scope test Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
58217006ec |
fix: stop cutting DeepSeek chat turns off mid-thought (#11282)
* fix: stop cutting DeepSeek chat turns off mid-thought Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test: pin the Anthropic max_tokens stop as a turn failure Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: drop the send-failure prefix from the output-limit toast Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
46206a2787 |
refactor(ai-chat): assemble the global prompt and tools in one place (#11252)
* refactor(ai-chat): assemble the global prompt and tools in one place Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * refactor(ai-chat): derive assembly opts, harden omission tests Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
69fafb9262 |
feat: check dynamic worker tags on the tag they resolve to (#11271)
* feat: check dynamic worker tags on the tag they resolve to Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test: pin the tag check after a flow preprocessor resolves the tag Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: keep tied tag placeholders exact and drop an unresolvable flow tag Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: describe tied tag placeholders in the custom tags editor Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: check workflow-as-code task tags on the tag they resolve to Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: judge a preprocessed flow's tag as written when it is run Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: check a preprocessed flow's own tag, as written only where it reads args Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: explain dynamic tags in the worker tag picker Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: look up worker availability for typed static tags Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: poll worker availability with the tag list as it is at each run Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: warn on custom tags with nothing fixed at their start or end Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: open the broad custom tag warning from the keyboard Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
5798bd07e7 |
build derived release images from this run's image digest, not :dev (#11280)
* fix: build derived release images from this run's image digest, not :dev Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: scope the digest comment to jobs that build from, extract or retag Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
9e58f9a20f |
chore(security): resolve Dependabot alerts in backend/Cargo.lock and windmill-parser-wasm/Cargo.lock (#11182)
Targeted dependency bumps only; no behavior change intended. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
9936673ee6 |
fix: clear the impersonation token from session storage on logout (#11274)
Impersonating a service account stashes the impersonator's own auth token under `pre_impersonation_token` in sessionStorage so the banner can restore it. Ending impersonation removed it, but logging out did not: `clearUser()` only reset the in-memory stores, leaving a usable token readable for the lifetime of the tab. Remove both impersonation keys as part of `clearUser()`, in their own try/catch so a storage failure (the opaque-origin iframe shim path) cannot skip the server-side logout. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |