Commit Graph

13161 Commits

Author SHA1 Message Date
Ruben Fiszel 322bee625c feat(pipeline): cascade option on graph Run + match button heights 2026-05-13 16:58:45 +00:00
Ruben Fiszel 3ed9c27772 feat(pipeline): split-button Test with optional downstream cascade 2026-05-13 16:47:16 +00:00
Ruben Fiszel 638b947d00 test: cover asset-trigger dispatch end-to-end through worker 2026-05-13 16:34:44 +00:00
Ruben Fiszel e7cdc994ef Merge branch 'main' into feat/asset-graph-view 2026-05-11 22:38:47 +00:00
Ruben Fiszel 9da13d0180 update prompts 2026-05-11 22:34:09 +00:00
Ruben Fiszel ac3c155541 fix: mask oauth client secret in instance settings (#9112)
* feat: mask oauth client secret in instance settings

* fix: address ci review - migrate nextcloud + use Password small prop

* fix: associate client secret labels with input via for/id
2026-05-11 22:30:15 +00:00
Ruben Fiszel 07d3ffbf34 system prompts refresh 2026-05-11 22:13:58 +00:00
hugocasa 9c6cd8c852 offline (URL-bound) license keys (#9089)
* [ee] feat(license): offline (URL-bound) license keys

Offline keys are a 4-segment variant for air-gapped customers — no
phone-home, embedded seat/CU caps, locked to the instance's base_url.
Existing 3-segment online keys are unchanged.

Companion PRs:
- windmill-labs/windmill-ee-private (full design + EE impl)
- windmill-labs/windmill-customer-service (issuance + portal)
- windmill-labs/windmill-cf-worker-keygen (signing)

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

* [ee] refactor(license): bind offline keys via instance hash; simpler CU enforcement

- /settings/license_status now surfaces an `instance_hash` superadmins share
  with support when requesting an offline key
- OfflineMetadata: `hash` replaces `base_url`; OfflineCapStatus reports
  `current_cu` (last 2min) and drops the grace-period fields
- verify_license_key now takes a db so EE can recheck the hash
- InstanceSetting.svelte: hash copy-block + simpler status panel
- Bump ee-repo-ref

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

* [ee] chore(license): bump ee-repo-ref

Pulls in the current_cu clamp + prod public key restoration.

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

* [ee] refactor(license): split instance_hash endpoint; minimal cap UI; restore workers expiry toast

- `instance_hash` is no longer part of /settings/license_status responses; it
  lives at GET /settings/instance_hash (super-admin only) so it isn't re-emitted
  on every status poll. The UI doesn't show it — admins fetch it explicitly when
  requesting a key from support.
- InstanceSetting offline cap UI is now two compact green/red status lines
  (Seats X.X/Y and CUs X.X/Y) placed above the action buttons, matching the
  existing "Latest key renewal" badge style. The block-panel is gone.
- "Latest key renewal" line and the "Renew key" button are now hidden when an
  offline key is loaded (renewal is server-disabled for offline keys).
- Restore parseLicenseKey + checkLicenseExpiration toast on /workers
  (works for both 3- and 4-segment keys).

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

* [ee] chore(license): bump ee-repo-ref

Pulls in the plain-SHA256 instance hash + stats_ee revert.

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

* [ee] chore(license): bump ee-repo-ref

Picks up the alert wording change.

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

* [ee] chore(license): bump ee-repo-ref

Picks up the instance_uid cache so the periodic verify_license_key cycle
no longer hits global_settings.

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

* [ee] refactor(license): rename /settings/license_status → /offline_license_status

The endpoint was only used by the offline-license UI; the other fields it
returned (license_key_id, license_key_valid, kind, offline metadata) were
unused. Rename to clarify scope and flatten the response — it now returns
just the OfflineCapStatus (or null when no offline license is loaded).

Frontend uses `offlineCapStatus != null` as the "is offline" check.

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

* [ee] fix(ci): regenerate sqlx cache for the inline worker_ping query

After reverting unused stats_ee helpers (fetch_worker_pings*), the
inline `sqlx::query_as!(WorkerPingRecord, ...)` in get_stats_payload
lost its cache entry — CI's check_ee_full + cargo_test were failing
under SQLX_OFFLINE=true with E0282 type-inference errors.

Re-running update_sqlx.sh regenerates the cache file under its
current hash and prunes a couple of stale entries.

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

* [ee] fix(license): address cubic-bot review

- get_offline_license_status: propagate enforce_offline_caps errors as 500
  instead of swallowing into a "no offline license" (Option::None) response
- canonical_base_url: rewrite the doc to match the actual fallback behavior
  (lowercase + trailing-slash strip on URL parse failure); the original
  cross-service contract is gone since the customer-service no longer
  canonicalizes (treats the instance hash as opaque)
- check_seat_cap_for_new_user: take an email and short-circuit when the
  email is already in `usr ∪ workspace_invite` so net-zero invite upserts
  and invite→user transitions aren't spuriously blocked at cap. Mirrors
  the dedup rule the count itself uses.
- Bump ee-repo-ref to pull in the EE-side change

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

* [ee] chore(license): bump ee-repo-ref

Picks up the exact-delta seat-cap check (replaces the simple existence
short-circuit). Regenerates the new sqlx cache for the bool_and query.

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

* [ee] fix(license): propagate get_instance_hash errors; bump ee-repo-ref

- get_instance_hash: replace `.ok().flatten()` with map_err+? so DB errors
  during instance_uid lookup surface as 500 instead of silently returning
  `{"instance_hash": null}` (same pattern get_offline_license_status already uses)
- Bump ee-repo-ref to pull in the enforce_offline_caps cached-state preservation

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

* chore: update ee-repo-ref to c6cd1afe2d9e04809b30751cd1687b28a65e62b1

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

Previous ee-repo-ref: a6d91016ae0d43c46604313aecae3aa9c778c8e0

New ee-repo-ref: c6cd1afe2d9e04809b30751cd1687b28a65e62b1

Automated by sync-ee-ref workflow.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <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>
2026-05-11 22:09:21 +00:00
Samuel Wilk 1abfe9de39 Add max-iterations to OpenAPI spec for AI Agent (#9103) 2026-05-11 22:03:04 +00:00
Ruben Fiszel f8ba0840d7 feat(vault): configurable JWT auth mount path and setup-doc fixes (#9100)
* chore: narrow secret-file Read deny rule to dotfiles/extensions

* feat(vault): configurable JWT auth mount path and fix setup docs

* chore: bump ee-repo-ref for vault jwt mount path

* chore: bump ee-repo-ref after rebase onto EE main

* chore: update ee-repo-ref to a1cd60b54e8595b4e5ce6b654e675e4bbe2253b2

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

Previous ee-repo-ref: c274f233a0ebb54afa296c3db15ff330e1baebcf

New ee-repo-ref: a1cd60b54e8595b4e5ce6b654e675e4bbe2253b2

Automated by sync-ee-ref workflow.

---------

Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
2026-05-11 21:54:40 +00:00
Ruben Fiszel 0a5f8dcd48 deps: pin tokio-postgres to forked branch with query_typed_raw deadlock fix (#9106)
* deps: pin tokio-postgres to MaterializeInc fork to fix query_typed_raw deadlock

`pg_executor`'s `Client::query_typed_raw` (and `Client::prepare` on the
streaming path) deadlock when the result schema contains a column whose
Oid the client doesn't know yet — citext, custom enums, custom domains,
postgis types. Easy to reproduce against any partitioned table with a
citext column: ~100+ rows is enough on localhost, less on slower links.
`psql` works fine for the same query because the simple-query protocol
doesn't trigger the typeinfo lookup path.

## Root cause (unchanged tokio-postgres bug for years)

`query::query_typed` calls `get_type(client, oid).await` synchronously
while still holding the original query's `Responses` stream. The
original query's `DataRow`s back up in the per-request
`mpsc::channel(1)`, `Connection::poll_read` stops draining the wire,
and the typeinfo sub-query response (queued on the same socket behind
those DataRows) never arrives. Classic head-of-line blocking.

## Fix

Pin `tokio-postgres` / `postgres-types` / `postgres-protocol` (via
[patch.crates-io]) and the workspace `rust-postgres` /
`rust-postgres-native-tls` aliases to the
[MaterializeInc rust-postgres fork at `78c1222577`](https://github.com/MaterializeInc/rust-postgres/tree/master).
MI's [PR #33 "bigger-channels"](https://github.com/MaterializeInc/rust-postgres/pull/33)
(merged 2025-12-11) resized the per-request response channel from
`mpsc::channel(1)` → `mpsc::channel(1024)`. That gives the connection
task 1024 batches of headroom while a streaming consumer is paused
mid-stream — orders of magnitude more than realistic typeinfo
deferral needs (≈3 batches).

## Why MaterializeInc and not a windmill-labs fork

`windmill-trigger-postgres` already depended on the imor fork for the
`postgres-replication` crate (logical replication: `CopyBothDuplex`,
`LogicalReplicationStream`, `TupleData` decoding including binary
tuples). That crate has never been on upstream rust-postgres — petrosagg's
[PR #752](https://github.com/rust-postgres/rust-postgres/pull/752) was
closed in 2021 in favour of a smaller split,
[PR #778](https://github.com/rust-postgres/rust-postgres/pull/778) is
still open today after five years. petrosagg keeps the replication work
alive on the MaterializeInc fork.

MaterializeInc is a strict superset of what we previously got from imor:
- imor's binary-tuple commit (sha `20265ef38e`) was merged into MI master.
- petrosagg has added perf + correctness fixes on top (allocation reuse,
  proper decoding fixes).
- The deadlock mitigation (`channel(1024)`) was added three weeks before
  this issue surfaced.

MI tracks upstream rust-postgres with a periodic catch-up merge (12-18 mo
cadence; last on 2025-12-03, ~100 commits picked up). Not an abandoned
fork.

## Why this works now (didn't on earlier attempt)

A previous attempt at this PR (`248ccb5a97`) hit CI failure because the
MI fork's `postgres-types 0.2.11` requires `serde_core ^1.0.221`, but
Windmill's workspace pinned `serde = "=1.0.220"` for swc_common 0.37.5's
`pub use serde::__private as serde;` hack. Bumping serde above 1.0.220
broke the swc_ecma_ast `Deserialize` derive under the
`enterprise,deno_core,…` feature set.

The earlier blocker is now resolved by #9111 which bumped the deno +
swc pin set to a "goldilocks" combination where `swc_common 14.0.4`
drops the `__private` hack, freeing the workspace serde pin to `^1`.
serde now resolves to 1.0.228, which satisfies MI's `serde_core ^1.0.221`
requirement transitively — no extra workspace pin needed.

## Diff shape

Two files only:
- `backend/Cargo.toml` (+34/-1): three new `[patch.crates-io]` entries
  (`tokio-postgres`, `postgres-types`, `postgres-protocol` → MI fork)
  plus comment block, plus the two workspace deps (`rust-postgres` /
  `rust-postgres-native-tls`) repointed from imor's fork to MI's.
- `backend/Cargo.lock` — auto-regenerated. Replaces all `imor/rust-postgres`
  references with `MaterializeInc/rust-postgres`, bumps the affected
  crate versions to MI's set (tokio-postgres 0.7.11 → 0.7.15,
  postgres-types 0.2.7 → 0.2.11, postgres-protocol 0.6.7 → 0.6.9,
  postgres-native-tls 0.5.0 → 0.5.2). No source code changes.

## Verification

- `cargo check --features quickjs` → clean.
- `cargo check -p windmill-worker --features quickjs` → clean (pg_executor
  builds).
- Repro tested earlier in the thread that produced this PR: the
  partitioned-citext-table query on Neon goes from "hangs indefinitely"
  (server idle on `wait_event=ClientRead` while client awaits typeinfo
  behind undrained DataRows) to "completes in ~1.0s, 100 rows" with the
  MI fork's `bounded(1024)` response channel.

## Caveats

- **`bounded(1024)` is a mitigation, not a closure.** Theoretical failure
  mode remains at >~64 MB single-query results with a custom-Oid column
  (typeinfo defers for >1024 batches of ~64 KB each). The strict-correct
  fix is `mpsc::unbounded()` — proposed as a follow-up PR to MI. For
  realistic Windmill workloads, 1024 batches of headroom is well past
  the ~3-batch typeinfo deferral that's actually needed.
- **`postgres-replication` is now upstream-of-fork's only home.** No
  realistic path to upstream rust-postgres merging it. The MI pin is
  intended to stay in place until either upstream changes course
  (unlikely) or MI publishes to crates.io (also unlikely — they don't
  publish releases of the fork).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

* chore: update ee-repo-ref to 8fe0d290fb0b71c24184eb5ad99bbdc7c813697c

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

Previous ee-repo-ref: 4d01d171228196f28ddabc1150242bfab623d5cf

New ee-repo-ref: 8fe0d290fb0b71c24184eb5ad99bbdc7c813697c

Automated by sync-ee-ref workflow.

---------

Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
2026-05-11 21:43:18 +00:00
Ruben Fiszel e3a914fd48 download files via openapi client when token is set (#9102) 2026-05-11 21:39:41 +00:00
Ruben Fiszel 3cd0eac8c1 deps: bump deno_core / deno_ast / swc to the goldilocks pin set; drop serde ceiling (#9111)
* deps: bump deno_core / deno_ast / swc to the goldilocks pin set; drop serde ceiling

Bumps every deno_* and swc_* workspace dep to a hand-picked "goldilocks"
combination that drops the serde =1.0.220 ceiling without crashing into
the rustls / aws-sdk resolver wall that the obvious deno v2.6.0 target
hits.

## What's the goldilocks set

| crate            | old      | new       | source                                |
|------------------|----------|-----------|---------------------------------------|
| deno_core        | 0.336.0  | 0.352.0   | deno v2.4.0                           |
| deno_fetch       | 0.214.0  | 0.233.0   | deno v2.4.0                           |
| deno_tls         | 0.177.0  | 0.196.0   | deno v2.4.0 (last permissive-rustls)  |
| deno_console     | 0.190.0  | 0.209.0   | deno v2.4.0                           |
| deno_url         | 0.190.0  | 0.209.0   | deno v2.4.0                           |
| deno_webidl      | 0.190.0  | 0.209.0   | deno v2.4.0                           |
| deno_web         | 0.221.0  | 0.240.0   | deno v2.4.0                           |
| deno_io          | 0.100.0  | 0.119.0   | deno v2.4.0                           |
| deno_net         | 0.182.0  | 0.201.0   | deno v2.4.0                           |
| deno_permissions | 0.49.0   | 0.68.0    | deno v2.4.0                           |
| deno_telemetry   | 0.12.0   | 0.31.0    | deno v2.4.0                           |
| deno_error       | =0.5.5   | =0.6.1    | deno v2.4.0                           |
| deno_ast         | =0.44.0  | =0.51.0   | **override** — see "load-bearing" below |
| deno_fs          | (new)    | 0.119.0   | new workspace dep — FetchPermissions exposes deno_fs::CheckedPath / GetPath as public API |
| v8               | =130.0.7 | =137.1.0  | deno_core 0.352 transitive            |
| swc_common       | =0.37.5  | =14.0.4   | **the load-bearing pin**              |
| swc_ecma_ast     | =0.118.2 | =15.0.0   | matched set with swc_common 14.0.4    |
| swc_ecma_parser  | =0.149.1 | =24.0.3   | matched set                           |
| swc_ecma_visit   | =0.104.8 | =15.0.0   | matched set                           |
| serde            | =1.0.220 | ^1        | **freed** (resolves to 1.0.228+)      |

## Why this combination and not v2.6.0

The obvious target was deno v2.6.0 (with deno_ast 0.52 → swc_common 17,
well past the `__private` ceiling). That hits three resolver collisions:

1. libsqlite3-sys: deno_cache → rusqlite 0.37 → libsqlite3-sys 0.35
   vs sqlx → libsqlite3-sys 0.30. **Already killed by PR #9110** —
   we dropped deno_runtime, which is what pulled in deno_cache.
2. fqdn 0.4.6/0.4.7 yanked, required by deno_permissions 0.81.0. Solvable
   by injecting the yanked entry into Cargo.lock manually but ugly.
3. rustls: deno_tls 0.198+ hard-pins `=0.23.28`, but aws-sdk-bedrockruntime
   1.122.0 → aws-smithy-http-client 1.1.5 wants `^0.23.31`. Within-major
   conflict, no resolver path. The unbeatable wall.

Goldilocks-set choice sidesteps (2) and (3) entirely:

- `deno_tls 0.196.0` was the last version before deno tightened
  `rustls ^0.23.11` (range, accepts 0.23.31) to exact `=0.23.28`. With
  ^0.23.11, the resolver picks rustls 0.23.35 (latest 0.23 patch) which
  satisfies both deno_tls's `>=0.23.11` and aws-sdk's `>=0.23.31`. Verified
  empirically: lockfile has rustls 0.23.35 after this bump.
- `deno_permissions 0.68.0` (v2.4.0's pin) doesn't depend on fqdn at all.
  The fqdn dep was added in a later deno_permissions release.

## Why deno_ast =0.51.0 specifically (not 0.48.0 from v2.4.0)

`swc_common 14.0.4` is the first patch that **drops the
`pub use serde::__private as serde;` line** in `src/private/mod.rs`. Older
14.0.x and all 0.37.5–13.x revisions still have it, and that line is
what was capping `serde = "=1.0.220"` (the workspace pin's "stuck because
of swc" comment). Empirically verified by inspecting the tarballs of
14.0.0 / 14.0.1 / 14.0.2 / 14.0.3 / 14.0.4:

    14.0.0: has hack
    14.0.1: has hack
    14.0.2: has hack
    14.0.3: has hack
    14.0.4: NO HACK    ← inflection point

`deno_ast 0.51.0` pins `swc_common =14.0.4` exactly — older deno_ast
versions pin earlier swc_common patches that still have the hack.
Notably, deno v2.4.0 itself pins `deno_ast =0.48.0` (swc_common 9.2.0,
still has hack) — we deliberately deviate from v2.4.0's deno_ast pin
to escape the swc serde wall, while keeping the rest of v2.4.0's pin
set for resolver compatibility with aws-sdk. deno_ast 0.51 was never
shipped in any deno release (v2.4.5 used 0.49, v2.5.0 jumped to 0.50,
v2.6.0 to 0.52), but it's published on crates.io and compatible with
v2.4.0's deno_core 0.352.

## What this unblocks

- PR #9106's `serde = "=1.0.224"` bump variant can rebase onto this
  and resolve cleanly (MaterializeInc/rust-postgres' `postgres-types`
  needs `serde_core ^1.0.221`, which is satisfied now that we're on
  serde 1.0.228).
- Future deno_* / swc_* bumps no longer need to argue about the serde
  ceiling — it's gone.

## What changes in source code

This commit is Cargo.toml + Cargo.lock only. Source changes that the
new deno_core / deno_fetch API requires live in the follow-up commits:

- `parsers/windmill-parser-{ts,ts-asset,wac}`: swc 0.37 → 14
  (`code.into()` ambiguity fix at 5 sites)
- `windmill-runtime-nativets/build.rs` + `src/lib.rs`: deno_core 0.336
  → 0.352 API moves (`init_ops_and_esm()` → `init()`,
  `FetchPermissions` / `NetPermissions` trait signature updates,
  `deno_tls::Proxy` enum shape change)

A companion change in windmill-ee-private adjusts
`otel_tracing_proxy_ee.rs:521` for `deno_telemetry::init`'s second arg
becoming by-value (was `&OtelConfig`).

* fix(parsers): adapt to swc_common 14 BytesStr ambiguity

swc 0.37.5 → 14.0.4 changed `SourceMap::new_source_file`'s `src` argument
from `String` to `impl Into<BytesStr>`. With `BytesStr` available, the
existing call sites' `code.into()` on a `&str` becomes ambiguous between
`Into<Bytes>` (from the bytes crate) and `Into<BytesStr>` (from
bytes_str). Switch to `code.to_string()` to produce an owned `String`
that satisfies `From<String> for BytesStr` unambiguously.

Five call sites across three crates:
- windmill-parser-ts/src/lib.rs (3 sites)
- windmill-parser-ts-asset/src/lib.rs (1 site)
- windmill-parser-wac/src/typescript.rs (1 site)

* fix(nativets): adapt to deno_core 0.352 / deno_fetch 0.233 API changes

The goldilocks deno bump (deno_core 0.336 → 0.352, deno_fetch 0.214 →
0.233, etc.) ripples through nativets' build.rs and src/lib.rs.
Source-level changes required:

## 1. `extension!` macro: `init_ops_and_esm()` and `init_ops()` removed

deno_core 0.352's `extension!` macro now generates a single `init()`
function on the extension struct (full: ops + esm), plus `lazy_init()`
(ops only, with `needs_lazy_init = true` and a contract that the
caller invokes `JsRuntime::lazy_init_extensions` after construction).

- `build.rs` (snapshot creation, wants both ops and esm baked in):
  `X::init_ops_and_esm(...)` → `X::init(...)`.
- `src/lib.rs:create_nativets_runtime` (runtime, was using `init_ops()`
  because the snapshot already provides esm): also → `X::init(...)`.
  deno_core's snapshot path skips esm re-execution when the snapshot
  provides them, so the esm registration is a no-op at runtime. This
  is how deno's own v2.4.0 runtime works.

Avoided `lazy_init` because it requires plumbing
`JsRuntime::lazy_init_extensions(ext_args_vec)` correctly across the
codebase, which is invasive for no behavioural benefit.

## 2. Local `fetch` extension now declared in both build.rs and lib.rs

deno_core 0.352 validates extension order between snapshot and runtime.
Our snapshot's last extension is the local `fetch` ext (which provides
ext:fetch/src/runtime.js). To avoid a runtime panic:

    "Extensions from snapshot loaded in wrong order: expected fetch but got windmill"

…the runtime extension list now ends with `fetch::init()` matching the
snapshot order. The macro requires the same `esm` argument to type-check,
even though the ESM is not re-executed at runtime (it's in the snapshot).

## 3. `FetchPermissions` and `NetPermissions` trait shape

`deno_fetch::FetchPermissions` (deno_fetch 0.233.0) added new methods
and changed signatures:

- `check_read` / `check_write`: now take `path: Cow<'a, Path>` plus
  a new `get_path: &'a dyn deno_fs::GetPath` parameter, and return
  `Result<deno_fs::CheckedPath<'a>, FsError>` instead of `Result<Cow<Path>, FsError>`.
- New `check_write` (didn't exist) and `check_net_vsock` methods.

`deno_net::NetPermissions` (deno_net 0.201.0) gained `check_vsock`
and `check_write_path` now takes `Cow<'_, Path>`.

For `build.rs`'s `PermissionsContainer` (used only during snapshot
creation, where permissions are never actually checked): all methods
`unreachable!("snapshotting")`.

For `src/lib.rs`'s `PermissionsContainer` (used at runtime — the
nativets policy is "allow everything"): `check_read` / `check_write`
return `Ok(CheckedPath::Unresolved(path))`, `check_*_vsock` return
`Ok(())`. Smoke tests confirm fetch/net/url/web/blob/timers/structuredClone
behaviour is intact end-to-end.

## 4. `deno_tls::Proxy` is now an enum

`deno_tls::Proxy` was a struct, is now an enum with `Http`, `Https`,
`Socks5` variants. Our call site uses HTTP proxies — switched the
struct literal `deno_tls::Proxy { url, basic_auth }` to
`deno_tls::Proxy::Http { url, basic_auth }`.

## 5. New `deno_fs` direct workspace dep

`FetchPermissions` exposes `deno_fs::CheckedPath` and `deno_fs::GetPath`
as part of its public API. We can't avoid naming `deno_fs` directly any
more. Pinned to 0.119.0 (v2.4.0's matched version, transitively present
already through deno_fetch). Added to workspace `[dependencies]` plus
nativets's `[dependencies]` and `[build-dependencies]`.

## Validation

`cargo check --features enterprise,deno_core,duckdb,license,python,rust,scoped_cache,parquet,private,private_registry_test,csharp,php,ruby,mysql,quickjs,mcp,run_inline`
→ clean.

`cargo test -p windmill-runtime-nativets smoke -- --ignored --skip smoke_net_`
→ 8 passed; 0 failed (the full local smoke suite covering fetch,
setTimeout/Promise.all, URL/SearchParams, Blob/btoa/atob, large payload
roundtrip, error propagation, concurrent isolates, TS enum/union
transpile).

Network smoke tests (`smoke_net_fetch_example_com`,
`smoke_net_fetch_json_and_headers`) not run as part of the validation
gate but expected to pass — the change preserves deno_fetch behaviour
through the trait surface.

* chore: update ee-repo-ref to pick up deno_telemetry::init by-value fix

Points at windmill-ee-private branch deps/bump-deno-and-swc-goldilocks
which contains the companion otel_tracing_proxy_ee.rs adjustment for
deno_telemetry 0.12 → 0.31 (second arg of `init` is now by-value).
EE-only file, doesn't affect OSS build.

* chore(nix): bump rusty_v8 in flake.nix to 137.1.0 to match Cargo.toml

Cargo.toml's v8 pin moved from =130.0.7 to =137.1.0 as part of the
deno_core 0.336 → 0.352 bump, but I missed the comment directly above
the version pin:

    # Exact version NOTE: Do not forget to update version and hash in flake.nix

flake.nix provides the prebuilt librusty_v8 binary that the v8 crate
links against. A version mismatch would either fail to fetch (if the
137.1.0 release didn't exist) or cause link-time symbol mismatches.
Nix is used by rust-client-check.yml and rust_on_release.yml in CI,
plus the dev shell — stale flake pin breaks all of those.

Updates x86_64-linux's sha256 to match the actual hash of
librusty_v8_release_x86_64-unknown-linux-gnu.a.gz at the 137.1.0 tag.
Other targets (aarch64-linux, x86_64-darwin, aarch64-darwin) remain
as lib.fakeHash — they were already placeholders in the previous
pin, so we don't regress on them.

Caught by both cubic and Pi reviewers on PR #9111.

* docs(nativets): clarify snapshot-prefix rule in extension-order comment

Claude reviewer caught that the doc comment claimed the runtime
extension list matches the snapshot's order — implying an exact match.
The truth is more permissive: deno_core 0.352 requires the snapshot's
extension list to be a *prefix* of the runtime's, not an exact match.
Runtime is allowed to append extra extensions (which we do — the
windmill `ext` carrying our ops is the last entry at runtime but absent
from the snapshot).

The code is correct as-is; only the comment wording was misleading.

Also fixes the same wording in PR description.
2026-05-11 21:13:24 +00:00
Ruben Fiszel 36b316d9e8 deps(nativets): inline maybe_transpile_source, drop deno_runtime (#9110)
windmill-runtime-nativets was the workspace's only consumer of the
deno_runtime crate, and its only use of it was one call site in
build.rs:

    deno_runtime::transpile::maybe_transpile_source(specifier, source)

That function (`deno_runtime-0.198.0/transpile.rs`, ~80 lines) is a pure
deno_ast + deno_core + deno_error wrapper — it doesn't touch any
deno_runtime state. Inline it verbatim into our build.rs and drop the
entire deno_runtime dep.

Why this matters now: deno_runtime transitively pulls in deno_cache →
rusqlite → libsqlite3-sys. From deno_cache 0.128.0 (Feb-Mar 2025)
onwards, rusqlite was bumped to ^0.34, which means libsqlite3-sys ^0.35.
sqlx 0.8 transitively requires libsqlite3-sys ^0.30. Cargo's `links =
"sqlite3"` rule allows only one libsqlite3-sys in a build graph, so the
two crates collide on any deno release ≥ v2.5. Inlining the transpile
helper sidesteps the collision entirely — sqlx-sqlite stays the sole
libsqlite3-sys consumer at 0.30.1.

All other appearances of "deno_runtime" in the source tree are for a
Windmill-internal function named `setup_deno_runtime`, not the crate.

Build artifacts validated:
- `cargo check --features quickjs` → green.
- `cargo test -p windmill-runtime-nativets smoke -- --ignored --skip smoke_net_`
  → 8 passed (the in-process V8 runtime + deno_fetch + deno_web + swc
  transpilation surface still works end-to-end through the inlined
  function).
- `cargo tree --invert deno_cache` → "did not match any packages"
  (gone from the graph).
- Single `libsqlite3-sys` entry in Cargo.lock at 0.30.1 (sqlx's).
2026-05-11 20:21:46 +00:00
brone1323 9f79a86a68 fix: add Input, Result, Trigger to reserved flow step IDs (#9109)
Renaming a flow step to 'Input', 'Result', or 'Trigger' would silently
corrupt the UI — the flow editor panel would switch to rendering the
special Input/Result/Trigger node instead of the step's config panel,
making the step inaccessible without editing YAML directly.

These virtual node IDs were already handled as reserved by
multiSelectUtils.ts but were missing from the forbiddenIds list that
drives the IdEditorInput validation, so users got no warning.

Fixes #7139
2026-05-11 19:51:49 +00:00
Ruben Fiszel 1e89aff2d6 test(nativets): add #[ignore]'d smoke suite for deno_core / deno_ast / swc bumps (#9108)
Adds ten `#[ignore]`'d integration tests in
backend/windmill-runtime-nativets/src/smoke_tests.rs exercising the JS
API surface that the existing nativets tests in tests/worker.rs don't
reach. Run them when bumping the deno_core / deno_ast / deno_runtime /
swc_* pins in backend/Cargo.toml, not on every CI:

    cargo test -p windmill-runtime-nativets smoke -- --ignored
    # skip network-dependent ones with `--skip smoke_net_`

Why here and not in tests/worker.rs:
windmill-runtime-nativets is the only consumer of the deno_core crate
in the workspace — ScriptLang::Deno spawns the external `deno` binary
via deno_executor.rs, while ScriptLang::Nativets is the only path that
loads the in-process V8 runtime. So a deno_core / deno_ast bump can
only break things downstream of this crate. Co-locating the smoke
tests with the runtime they exercise means they hit the right surface
directly, skip the entire job-queue / worker / API-server stack, and
run in <1s end-to-end (vs. ~30-60s per test for the worker-level
nativets tests).

The tests use the existing `PrewarmedIsolate::spawn` API (already
public for the dedicated-worker path), which gives a clean
"compile-TS → load module → execute main(args) → return JSON" entry
point with no DB or queue plumbing required.

Coverage:
- smoke_basic_value_passing — args binding + return marshaling
- smoke_transpile_enum_and_union — TS-specific syntax (enums,
  discriminated unions, casts) through swc_ecma_parser / swc_ecma_ast
- smoke_set_timeout_and_promise_all — deno_web timer ops + V8
  microtask drain order
- smoke_url_and_searchparams — deno_url surface
- smoke_web_blob_btoa_atob — deno_web Blob + base64 ops
- smoke_large_payload_roundtrip — 512 KB string in/out through the
  op-table boundary
- smoke_error_propagation_with_message — thrown Error must surface
  in PrewarmedResult::Err with original message
- smoke_concurrent_isolates — 8 isolates spawned in parallel from
  the same tokio runtime; catches V8 isolate-setup races
- smoke_net_fetch_example_com — deno_fetch end-to-end against
  example.com
- smoke_net_fetch_json_and_headers — deno_fetch with custom request
  headers + Response.json() against httpbin.org/anything

`structuredClone` is not currently wired into the nativets global —
documented in the smoke_web_blob_btoa_atob test in case that ever
changes.

All ten tests pass locally against the current pinned versions
(deno_core 0.336.0 / deno_ast =0.44.0 / swc_common =0.37.5).
2026-05-11 18:43:54 +00:00
Diego Imbert 20ecd904e7 feat(operators): allow operators to access assets page (#9095)
* feat(operators): allow operators to access assets page

Adds the "assets" key to workspace operator_settings (defaulting to true
for existing and new workspaces) and toggles the frontend default so the
assets page is visible to operators by default.

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

* nit: remove settings btn when not available

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 18:36:34 +00:00
Ruben Fiszel 03e8bc8c14 perf: lazy-load script editor history and hit partial index (#9107) 2026-05-11 17:20:46 +00:00
centdix 6f7d31e56b refactor: move ai image handling to windmill-ai (#9098) 2026-05-11 14:59:40 +00:00
hugocasa bbef5c9dd4 ping PR author when auto-review verdict is not good to merge (#9101)
* feat(ci): ping PR author when auto-review verdict is not good to merge

* fix(ci): drop (unknown) author fallback and clarify verdict-line rule
2026-05-11 14:56:52 +00:00
Ruben Fiszel 7734b206ab all 2026-05-11 14:49:19 +00:00
Ruben Fiszel 8809b4ea83 all 2026-05-11 14:49:13 +00:00
Ruben Fiszel 05172ac3bd fix: populate raw_code for flowscript and appscript runs (#9104) 2026-05-11 13:54:50 +00:00
Diego Imbert e43a958c5c feat(forks): prompt to delete forked children when deleting a fork (#9097)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-11 12:30:37 +00:00
centdix 27acbbf3d5 refactor: move ai sse plumbing to windmill-ai (#9059)
* docs: refine windmill ai refactor plan

* refactor: move ai sse plumbing to windmill-ai

* refactor: remove ai re-export shims

* fix: update ee ai memory ref

* chore: update ee-repo-ref to d3bc7fa85195b46b7a38d43c2f806520bf8b5454

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

Previous ee-repo-ref: ff35bf7cc198e13884b33654e1d6dbd8a8b314d3

New ee-repo-ref: d3bc7fa85195b46b7a38d43c2f806520bf8b5454

Automated by sync-ee-ref workflow.

---------

Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
2026-05-11 10:01:45 +00:00
hugocasa 23bb1b541e fix(frontend): mark Path dirty when folder picker changes selection (#9096)
* fix(frontend): enable move button when only folder changes

* fix(frontend): mark Path dirty when folder picker changes selection

* fix(frontend): preserve script auto-derive for new items in Path dirty effect
2026-05-11 10:01:13 +00:00
Diego Imbert da9e416b8e workspace specific nit fixes (#9072)
* fix: capture linked variables in trash on bulk resource delete

delete_resources_bulk grew linked-variable cascade deletion in an
earlier commit on this branch but only mirrored the deletion side of
delete_resource — not the trashbin capture side. Linked variables
deleted via bulk were permanently lost while their single-delete
counterparts could be recovered from trash.

Fetch each resource's linked variable rows as JSON before bulk delete
and stash them under `trash_data['linked_variables']` of that
resource's trash entry, matching the shape produced by single-resource
delete.

* fix: ws_specific cleanup gaps in variable rename + bulk delete; tooltip

Four spots:

1. update_variable rename block: when a variable is renamed and a
   linked resource at the same path is renamed alongside, also move
   any explicit ws_specific 'resource' marker from the old path to
   the new one. Symmetric with what update_resource already does for
   ws_specific 'variable'.

2. delete_variables_bulk: clean ws_specific 'resource' rows for any
   linked resource paths before the resource DELETE. Without this,
   bulk-delete leaves orphaned markers that would cause a freshly
   recreated resource at the same path to be falsely treated as
   workspace-specific. (linked_resource trash capture is already
   present in the bulk path — the reviewer note about that was
   inaccurate against the current code.)

3. list_ws_specific: ORDER BY item_kind, path so the CLI sees a
   stable list across pulls/pushes — cheap on a small per-workspace
   row set and avoids spurious diffs.

4. VariableForm tooltip: mirror the resource form so users who find a
   variable already toggled know it may have been auto-marked by a
   workspace-specific resource referencing it, and that disabling
   doesn't retroactively un-mark the referencing resource.

* sqlx prepare
2026-05-11 07:56:52 +00:00
Ruben Fiszel 99ab97215c feat(pipeline): optional AI prompt when creating a pipeline script 2026-05-10 14:16:05 +00:00
Ruben Fiszel f9de54799a fix(pipeline): refetch asset graph after persisted-script save 2026-05-10 12:43:51 +00:00
Ruben Fiszel 46d5979d82 fix(pipeline): untrack inferredWrites cache mutation to break effect loop 2026-05-10 12:39:23 +00:00
Ruben Fiszel e3ef08639f fix(pipeline): keep inferred body writes on the canvas across selection changes 2026-05-10 12:35:27 +00:00
Ruben Fiszel 8fd95474cb fix(pipeline): snapshot live draft writes at persist time so they survive reload 2026-05-10 12:31:18 +00:00
Ruben Fiszel f17d5d8f6a fix(pipeline): persist inferred body assets at save so edges survive page reload 2026-05-10 12:30:07 +00:00
Ruben Fiszel 13d54fb4c7 fix(pipeline): overlay live body-asset writes for persisted scripts too 2026-05-10 12:23:27 +00:00
Ruben Fiszel d80d6d7451 Merge remote-tracking branch 'origin/main' into feat/asset-graph-view 2026-05-10 12:07:37 +00:00
Ruben Fiszel b95f0e2379 style(log-viewer): tighter top bar (icons, hyphenated label, scoped overflow) (#9094)
- duration/mem-peak labels replaced by Timer/Cpu icons with tooltips
- 'Auto scroll' -> 'auto-scroll' (lowercase, hyphenated, whitespace-nowrap)
- top bar gets overflow-x-auto so it scrolls horizontally instead of pushing the entire log panel into overflow when narrow
2026-05-10 12:06:25 +00:00
Ruben Fiszel c77938f25b fix(log-viewer): scope overflow-x to top bar so pre doesn't drive panel width 2026-05-10 12:03:40 +00:00
Ruben Fiszel 0a9f1451d7 style(log-viewer): force horizontal scrollbar instead of vertical 2026-05-10 12:01:44 +00:00
Ruben Fiszel bd59a8a045 style(log-viewer): lowercase auto-scroll label, force vertical scrollbar 2026-05-10 12:00:45 +00:00
Ruben Fiszel 64eecdf0d1 style(log-viewer): hyphenate Auto-scroll label and prevent wrapping 2026-05-10 11:59:29 +00:00
Ruben Fiszel 7e93abef9e style(log-viewer): replace took/mem-peak labels with timer/cpu icons 2026-05-10 11:58:07 +00:00
Ruben Fiszel b1c07008ef fix(pipeline): test button cross-browser placement (no overflow trick) 2026-05-10 11:55:40 +00:00
Ruben Fiszel 497b63b623 feat(pipeline): compact preview layout, two-way Test/Run sync 2026-05-10 11:49:57 +00:00
Ruben Fiszel 835daea364 feat(pipeline): add run button on script nodes + recomputing hint on preview 2026-05-10 11:35:13 +00:00
Ruben Fiszel e135cc5495 feat(pipeline): animate graph edges only while a runnable is executing 2026-05-10 11:28:47 +00:00
Ruben Fiszel a09e8988d9 fix(pipeline): persist live writes per draft to keep output node fresh after switch 2026-05-10 07:04:18 +00:00
Ruben Fiszel d10bcac27c fix(pipeline): persist draft body edits across node switches 2026-05-10 06:59:47 +00:00
Ruben Fiszel 9fb355a9af fix(pipeline): live-update graph for annotations and body assets 2026-05-10 06:41:20 +00:00
Ruben Fiszel d3486b7134 all 2026-05-09 22:08:08 +00:00
Ruben Fiszel ba3d05c2fc feat(cli): auto-infer args for wmill app push (#9091)
Run `wmill app push` from inside an app folder (e.g. `f/foo/my_app.app/`)
with no args. The local path defaults to CWD, and the remote path is
derived from CWD relative to `wmill.yaml`, with `.app`/`.raw_app`/
`__app`/`__raw_app` suffixes stripped. Either, both, or neither
positional argument can be passed.

Also resolves `file_path` against the user's original CWD before
`resolveWorkspace` may chdir to the wmill.yaml root, so a relative
`file_path` argument is interpreted from where the user invoked the
command (previously it could resolve against the wrong directory).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 21:21:45 +00:00