* fix: scope cloned app policy and custom path to the fork's creator
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: share the app custom-path scoping rule across its call sites
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: tighten the cloned-app-policy comments
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: correct the execution_mode and custom-path scoping rationale
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: allow custom dev workspace environment labels
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: reject dev labels that shadow a tracked branch's namespace
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: guard dev labels against a repo's assumed default branch
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: state the badge-cap rationale once and drop unenforceable openapi constraints
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: offer a fixed list of environment labels instead of free text
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: match the accepted label set to the openapi enum exactly
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: stop describing the label set as dev/staging only
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: add public sharing option for job pages
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: gate public run sharing and address review findings
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: address review nits on public run sharing
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: key public run view on workspace, job and token
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* [ee] feat: improve duckdb isolation
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* chore: update ee-repo-ref to c4e6cbc1a1efeca5b71920c7903db2347d0eeda0
This commit updates the EE repository reference after PR #713 was merged in windmill-ee-private.
Previous ee-repo-ref: f630f7e73cb863e312430738d81d802a3971f7cd
New ee-repo-ref: c4e6cbc1a1efeca5b71920c7903db2347d0eeda0
Automated by sync-ee-ref workflow.
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
* fix: keep the same_worker pin when a suspend ends without approval
A disapproved or timed-out approval gate hands the flow back through the
UpdateFlow channel with unrecoverable = true. That flag means "the previous
step's worker died", and it is read by six sites. Five of them happen to want
what it does here, but continue_on_same_worker and continue_with_runners do
not: the worker that ran the approval step is alive, so unpinning the error
handler and routing it by tag breaks the ./shared contract of a same_worker
flow and can land it on a worker group that cannot run it — the same defect
#10551 fixed for the three producers that hand back a live flow.
Replace the boolean with StepFailureKind so the suspend producer can say
"worker alive, but this failure is not the module's to handle" instead of
overstating a worker death. The failed module's error policy is deliberately
still bypassed: the failure is recorded against the step the gate was holding
back, which never ran, so its retry would re-open the gate and its
continue_on_error would skip it outright (verified: the gated step is marked
Failure with a nil job id and the flow jumps past it). suspend.
continue_on_disapprove_timeout remains the way to continue past a gate.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(flow-editor): flag that continue on error does not cover the approval gate
A resolved approval is recorded against the step the gate holds back, not
the step carrying the suspend, so continue_on_error never sees it: the flow
still stops on a disapproval or timeout. Point users at
suspend.continue_on_disapprove_timeout, which is what actually continues past
a gate, whenever both settings are on and that one is not.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(debugger): install debug session deps from the instance registry settings
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(debugger): keep install-time registry credentials out of the session-visible tree
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: drop em dashes from the debugger registry docs and comments
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(debugger): stop installing for a session that went away during the settings fetch
Also serves nativets sessions the npm settings their installer reads.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
When a module completes without spawning a job — an empty branch, an
empty for-loop, or a module already marked Success — the flow hands
itself back through the UpdateFlow channel, and the result processor
resumed it with unrecoverable = true regardless of what sent it. That
flag means "the previous step's worker died", which holds for none of
the three producers except a suspend that ended without approval.
The stale argument was inert until continue_on_same_worker and
continue_with_runners started reading it, since when the step after such
a module is pushed as an ordinary queued job. It is then routed by tag
and can land on any worker in the pool, breaking both the ./shared
directory contract and the guarantee that a same_worker flow stays on a
worker able to run it — a step whose tag resolves to a worker group that
cannot execute its language fails instantly, taking the flow with it.
Carry the flag on the UpdateFlow message so each producer states its own
case, rather than having the shared receiver assume the worst. The three
that hand back a live flow forward whatever their caller reported, so a
genuinely unrecoverable failure still crosses the hop unchanged.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: allow a dev workspace to have its own dev workspace
Fixes WIN-2324
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep every dev workspace in a chain on a distinct deploy branch
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: count a dev workspace the caller has no seat in as holding its label
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: keep the attach form standing when a candidate takes the last label
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep the label toggle visible when a candidate's dev workspace clashes
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: describe the cycle guard by what holds, not by what changed
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: refuse to archive a fork-backed dev workspace that owns a nested dev
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: put the deploy target and item filters under the pairing they configure
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: refuse to archive any dev workspace that owns a nested dev
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: fix the fixture family count
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: put the deploy target with the pairing line it restates, above protections
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: name the same family head in the workspace menu and the scope picker
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: stop offering to delete a dev workspace from the sidebar settings menu
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: state the visibility boundary the lineage root actually resolves to
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: serialize dev-pairing creation against teardown of the same workspace
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: lock both sides of an attach so adjacent pairings cannot share a label
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: serialize dev pairings on one key, the invariant being chain-wide
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: scope the pairing lock to the chains an operation reads
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: hold the pairing lock across renames and re-check the cycle under it
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: hide the fork-delete action until the workspace entry has loaded
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: lock archive before it reads the pairing state it acts on
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: describe the archive lock test by what it pins, and drop an unused fixture row
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: forward proxy and TLS settings to debugger subprocesses
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: reach uv and the bun debugger with the forwarded network settings
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: map every CA variable spelling onto the one uv reads
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep package-index credentials out of debugged user code
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: install debugger dependencies outside the interpreter running user code
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: sandbox and bound the debugger dependency installer
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: correct the installer timeout rationale
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: scope the uv --cert note to the commands prepare-deps runs
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: build the debug venv against the interpreter that runs the script
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: do not start the debuggee for a session that already went away
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: remove the debug script when the session is gone before it starts
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(mcp): serve the 2026-07-28 spec alongside the legacy protocol
* fix(mcp): keep oauth discovery strict and preserve request limits
* fix(mcp): allow the protocol's own headers through CORS
* fix(mcp): expose the auth challenge to browser clients
* chore: update ee-repo-ref to c1665a881b61616f96ffe7702b44840905304660
This commit updates the EE repository reference after PR #711 was merged in windmill-ee-private.
Previous ee-repo-ref: bc1c001e3e386342415dfb8ac31c6b97f6629320
New ee-repo-ref: c1665a881b61616f96ffe7702b44840905304660
Automated by sync-ee-ref workflow.
---------
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
* fix: honor python index settings in prepare-deps and report install failures
* fix: forward python registry env to the debugger's prepare-deps
* fix: scope registry credentials to the prepare-deps subprocess
* fix: install python debug dependencies from the service, not the session
* fix: bound the debugger dependency install and keep the proxy bypass default
* docs: name the nsjail config that isolates debug sessions
* feat(dbt): reach any dbt adapter through a dbt_profile resource, and constrain the warehouse picker
The workspace dbt warehouse picker listed every resource in the workspace, so a
slack or github resource was an offerable answer to a field that can only be a
warehouse. Constraining it exposed that the set of resource types that actually
work is both smaller than the docs claim and too small to be useful:
- `render_profile` translates only six adapters from a Windmill resource; the
rest (clickhouse, duckdb, salesforce, mssql, oracle) refused one outright.
- `redshift` and `duckdb` name no resource type anywhere, so two of the
adapters the quickstart advertises were unreachable.
- the `databricks` resource carries `workspace_url`, while the renderer demanded
`host`, so that warehouse could never render at all.
So the picker gets a constraint and dbt gets an escape hatch wide enough to make
it honest. `dbt_profile` is a resource whose value IS a `profiles.yml` target —
`{ type, target }` — passed to dbt unchanged, so any adapter and any key it
documents works.
`DbtAdapter` is now open: it carries dbt's own `type:` spelling plus an optional
`KnownAdapter` (the eleven Windmill has facts about — a field mapping, a pip
package, the license gate). Anything else is carried by name and installed as
`dbt-<name>`, the convention every adapter on PyPI follows, so "whatever dbt
supports" no longer means "whatever this enum lists". The license gate is
unaffected: `sqlserver`/`oracle` still resolve to their `KnownAdapter` and are
still gated. The name is confined to `[a-z0-9_-]` starting alphanumeric because
it reaches a pip requirement and a venv path on the host.
Two adjacent fixes fall out: the project's own `profiles.yml` and the
descriptor's `profile.type` now accept any adapter instead of the closed list,
and a databricks resource renders its `host` from `workspace_url`.
The picker is constrained to `dbt_profile` plus the translated types, so nothing
it offers can fail for want of a mapping.
Fixes WIN-2320
* fix: drop the unused DbtAdapter::from_resource_type wrapper
Nothing calls it: a Windmill resource type maps through
KnownAdapter::from_resource_type, and the executor resolves an adapter from
the resource's own dbt spelling or by inference. CI builds with -D warnings,
so the dead wrapper failed every backend check.
* fix(dbt): make dbt_profile the block itself, and address the review findings
**A `dbt_profile`'s value IS a `profiles.yml` output block**, `type` included.
It was `{ type, output }`, which asked the user to restructure their block
before pasting it — a translation step, in the one type that exists to avoid
translation. The schema now declares no properties, so the resource form renders
a single JSON editor over the value.
That means the value's shape can no longer say what it is: a `dbt_profile` and
Windmill's bigquery resource are both objects with a `type` (the latter says
`type: service_account`). So the warehouse carries its resource's type
(`DbtWarehouseConnection.resource_type`), and detection is exact. It also makes
decision 9's "the resource type name is the authority" true at runtime for the
translated path, which until now resolved its adapter by sniffing fields.
Review findings, all three reviewers:
- **[P0] an author-chosen adapter became an unsandboxed PyPI install.** `dbt-` is
not a reserved prefix, and `provision_core_1x` installs through `run_tool`,
outside the nsjail ordinary dependency installation uses — so `dbt-<name>` from
a script author's `type` could run a PEP 517 build backend as the worker. Now
gated on a list of published adapters plus `DBT_EXTRA_ADAPTERS`, so trust stays
the admin's call. The open set survives: the engines that ship their adapters
install nothing and take any type.
- **[P1] `type: fabric` rendered as `sqlserver`.** dbt's `type:` was resolved
through the resource-type table, where `fabric` is a Windmill alias for SQL
Server — so a Fabric profile installed dbt-sqlserver, was enterprise-gated, and
failed on an ODBC driver without ever naming Fabric. dbt types now have their
own table.
- **[P1] two spellings of one adapter compared unequal.** `PartialEq` covers the
carried name, so `postgres` != `postgresql` even resolving to one adapter, and
the descriptor/resource check rejected valid configs with a message naming the
same adapter twice. The name is normalised to the adapter's dbt spelling.
- **[P2] identity keys.** `database_key` is what a Windmill resource spells it,
and only translated adapters have one; the rest read dbt's `database`.
- **[P2] duplicate `sslrootcert`** when a block carried both a PEM and a path.
Verified with three real dbt builds: a flat `dbt_profile` postgres block, the
same with `type: postgresql` under a `profile.type: postgres` descriptor (the
alias case, which failed before), and trino for the unknown-adapter path.
* docs(dbt): say that installing an adapter is gated, not just using one
The open-adapter text promised every future adapter is installed as dbt-<name>,
which ensure_adapter_installable refuses outside PUBLISHED_ADAPTERS and
DBT_EXTRA_ADAPTERS. Separates the two: rendering, licensing and identity are open
to any adapter, and only the dbt-core 1.x PyPI install is gated, because that is
the step that runs outside the sandbox.
* fix(dbt): keep a dbt_profile's own sslrootcert when Windmill writes none
The previous round skipped the block's sslrootcert unconditionally to avoid
emitting the key twice, which drops a path-only CA reference — a certificate
baked into the image or mounted on the worker, which is the block's own trust
source. Skipped now only when a root_certificate_pem is present, which is when
Windmill writes a replacement.
* fix(frontend): let a resource type declare no properties
A schema without `properties` is a JSON-edited resource type, not a broken one -
`dbt_profile` is a profiles.yml block whose keys belong to its adapter, so there
is nothing for Windmill to declare. Both editors assumed properties exist:
- ResourceEditor threw on Object.keys(undefined) while deriving the field order,
which left the drawer on its loading skeleton forever, so the resource could
not be viewed or edited at all.
- ApiConnectForm caught the same throw and reported the type as missing from the
workspace, offering to sync a type it already had.
Both now fall back to the raw JSON editor, which is what usesRawEditor already
intended for a schema with no properties.
* chore: cut the new comments to AGENTS.md's four-line cap
Each still states its constraint once; the long-form rationale belongs in
docs/dbt-runtime.md and the PR, not beside the code.
* fix(dbt): keep a dbt_profile's empty and nested collections intact
A block with no children reads back as null, so `extensions: []` reached the
adapter as a missing value rather than the empty list dbt was handed, and a
nested array went through the scalar path and arrived as a quoted JSON string.
Both are keys dbt passes to the adapter as it finds them, so the type has to
survive: empty collections are emitted inline, and the value half of an entry
recurses instead of bottoming out at a scalar.
The test parses the rendered YAML back rather than string-matching it, since
what matters is what a YAML reader sees.
Also cuts DbtWarehouseConnection.resource_type's comment to the four-line cap.
* fix: reflect custom tag add/remove in the manage-tags drawer immediately
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: do not fail the custom_tags write when the cache refresh errors
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: name the pg login in the job log for token auth modes
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: route remaining pg login defaults through login_name
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: require an explicit user for azure workload identity on postgres
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: show which MCP endpoint tools a token scope will actually expose
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep a wildcard endpoint scope when pruning the MCP endpoint selection
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: drop orphaned matcher comment and name the wildcard remedy in the MCP scope warning
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: let admins edit the dev workspace lock ruleset
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: route the empty protections panel through the owning workspace
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: make protection rule rename actually apply
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: cache the renamed protection rule query for sqlx offline
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep verbatim rule names and scope parent-admin lookup to its workspace
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: store renamed protection rule names verbatim
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: point the MCP app tools at full-code apps
* feat: name the full-code app tools createApp and updateApp
* fix: check the path and writer before compiling, let listApps paginate
* fix: ask the app table who may create, not a restated rule
* fix: guard duplicate mcp tool names and document the create body
* fix: allowlist resource_type and escape search highlights
* fix: bound path length and keep marked-label offsets entity-aware
* fix: match postgres word-char semantics and drop double-escaping
* fix: sanitize db constraint and rls errors instead of relying on the regex
* feat: deploy a raw app from its sources, bundling them on a worker
* refactor: bundle raw app sources with the wmill CLI instead of a second bundler
* fix: address review findings on the raw app source deploy
* fix: bound bundle decompression, drop the npm dependency on slim workers
* fix: stop minting jobs:run for the source deploy, share the decode budget
* feat: let an MCP token grant the scopes its selected tools require
* fix: carry a caller-held extra scope through the MCP proxy
* fix: confine the run scope to the proxied request instead of the token
* fix: mint the run scope only for a token that names the tool
* fix: require write access before compiling, and state the grant where it is granted
* fix: let the database decide write access instead of restating its policies
* fix: answer a write denial with 403, not 401
* fix: surface which auth mode a sql connection used and hint at ms_entraid
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: scope the ms_entraid hint to azure hosts and pin the sentinel trim
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: send prompt_cache_key on the openai responses api
* fix: bound prompt_cache_key to the provider limit and scope it to retryable paths
* fix: keep a digest suffix when bounding long frontend cache keys
* docs: attach the cache-key doc block to the function it describes
* fix: locate coursier artifacts by coordinate so private maven registries work
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: match maven coordinates by path component, longest first
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: skip the empty directory a 404 leaves at a maven coordinate
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: ignore coursier's dot-prefixed bookkeeping when claiming a coordinate
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: stop app updates from silently converting an app between raw and low-code
* fix: lock the app row for the kind guard and route MCP away from raw apps
* style: condense the restore kind-change comment
* feat: wire paged object storage listing module
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* feat: document list_stored_files_paged endpoint in openapi
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* feat: lazily expand s3 explorer folders one level at a time
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* chore: pin ee-repo-ref to the paged listing branch
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* fix: share object_store credential resolution and surface listing errors
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sqq2LhmWaGwP11Cf3UqWxe
* Chevron is cool
* page size 5000
* feat: make the load more row full-width, secondary and chevron-led
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sqq2LhmWaGwP11Cf3UqWxe
* fix: render newly loaded flat pages inside already-expanded folders
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* fix: address review findings in the lazy s3 explorer
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* fix: address review nits in the lazy s3 explorer
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* chore: bump ee-repo-ref after merging main
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* fix: document ambient credential contract and constrain max_keys schema
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* fix: treat an exhausted page token as exhausted, not as a continuation
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* chore: bump ee-repo-ref for canonical prefix validation
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* chore: bump ee-repo-ref for prefix scoping and opaque cursors
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* fix: invalidate a folder's in-flight load when deleting from it
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* fix: discard a stale folder page after its level is invalidated
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* chore: bump ee-repo-ref for bounded local listing
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* fix: label folders whose final path segment is empty
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* feat: search files by any part of their path, not just folder prefix
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* feat: search files by path prefix instead of a full-bucket scan
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* fix: guard stale search responses and describe prefix search accurately
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* chore: bump ee-repo-ref for the search prefix fallback fix
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* chore: regenerate the served openapi specs
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* chore: bump ee-repo-ref for the search cursor fallback fix
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqAc8mz6Gu698kBbJJVwcT
* chore: bump ee-repo-ref for the bounded search scan
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: surface a failed flat listing instead of spinning forever
The flat branch of loadFiles was awaited without a catch, and loadFlatFiles
clears its loading flags only on the success tail. Every caller reaches it
un-awaited, so a rejected listing left the drawer on "Loading content" with
nothing reported. Routing the filter box through this arm made it reachable
per keystroke rather than once per open.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: give back the flat cursor when a page fails to load
"Load more" advanced `page` before requesting it, so a failed page left the
cursor pointing at a `listMarkers` slot that was never filled. The retry sent
no marker at all and silently replayed the first page, and the
`listMarkers.length == page` guard kept it there until the listing was reset.
Only reachable now that a failed page is retryable rather than a permanent
spinner.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: scope the flat cursor rollback to its own listing
The rollback matched on the page number alone, so a page that failed after a
filter or storage change could roll back the *replacement* listing once it had
reached the same number, stranding its cursor. Tie it to the generation the
request was issued under.
The delete replay loop had the mirrored problem: it re-drove `page` by hand and
carried on past a failed page, leaving `page` ahead of `listMarkers` for good.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: skip the delete replay when the fresh listing itself failed
clearAndLoadFiles dropped the result it already computes, so a failed
post-delete listing still ran the replay loop: each page advanced `page` with
an empty `listMarkers`, which never recovers because the marker-length guard
only pushes when the two agree. Every later "Load more" then replayed page one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: stop a superseded lazy load from writing into the search that replaced it
loadFolderPage resolves rather than throwing once its generation is stale, so a
filter change that switches the picker to the flat listing mid-flight left the
lazy branch free to expand a preselected file into the search's results and to
clear the search's loading flags. Guard both on the generation it started under,
as the flat branch already does.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: check the listing generation throughout the reveal walk
Revealing a preselected key is a chain of round trips, so checking once at entry
left the rest of the walk free to keep loading after a filter change had already
switched the picker to the search — under the replacement generation, so the
per-level guards inside loadFolderPage saw nothing wrong.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: let a late metadata failure clear only its own preview
The handler blanked fileMetadata and filePreview without checking that its
request still owned the pane, so selecting a second file while the first was
still loading meant the first's rejection wiped the second's preview.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: key preview ownership on the request, not the selected key
Comparing the selected key let an older request speak for a newer one when both
targeted the same key, which a storage switch does, and made a request whose
selection had moved to something with no metadata return early with the spinner
still up — the case the handler exists to prevent.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: clear the preview when the previewed file is deleted
The lazy branch refetches only the affected level and returns, so it never
reached the reset that the flat refresh gets from clearAndLoadFiles. The pane
renders from fileMetadata rather than from the selection, leaving the deleted
file previewed with working download, move and delete actions.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: retire the in-flight preview load when its file is deleted
Clearing the pane was not enough: a metadata response computed before the DELETE
landed still repopulated it, restoring the deleted file's preview and its
download, move and delete actions. Deleting now retires the owning request, and
the success and preview writes honour that the same way the failure path does.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: clear the preview loading flag when the delete retires its request
Retiring the in-flight metadata load left nobody to report its outcome, so in
lazy mode the pane sat on "Loading..." instead of falling back to the empty
state. The delete owns the flag once it has retired the request.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: drop the regenerated openapi deref artifacts
They are generated files that CI only syntax-validates, never checks against
openapi.yaml, and the committed copies already differ from the spec they derive
from by ~9.7k lines. Regenerating here imported that pre-existing drift into a
feature diff, burying ~800 lines of actual change under ~17k lines of other
changes' staleness. Regenerating them is its own chore.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: state the flat cursor invariant once, where the cursor lives
It was spelled out at four sites, which is what AGENTS.md asks not to do. The
rule now sits on the declaration it constrains and the guards reference it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* nit ui
* fix: add the paged listing to the served openapi json
openapi_json() embeds openapi-deref.json via include_str!, and the Docker build
regenerates only the yaml artifact, so the json is served exactly as committed —
leaving the new operation out of the Scalar API reference.
Spliced in the operation and the two schemas it references rather than
regenerating, which would have re-imported ~7k lines of pre-existing drift
between the committed artifact and the spec it derives from.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: bump ee-repo-ref for the filesystem symlink boundary
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: update ee-repo-ref to 0373b4bfdaf8dd51533552e2e4de63ceb3c18b4d
This commit updates the EE repository reference after PR #697 was merged in windmill-ee-private.
Previous ee-repo-ref: eb1a765bb9b29e0c94a6e4942c304934fa15406e
New ee-repo-ref: 0373b4bfdaf8dd51533552e2e4de63ceb3c18b4d
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>
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
* feat(fork): merge a fork deletion on evidence, not on the counters
`workspace_diff.ahead`/`.behind` record that a write happened on a side,
not what it was or who made it. That leaves one row shape undecidable: an
item the parent has and the fork does not can mean the parent added it,
the fork deleted it, or a git-sync pull reverted a deploy that had just
brought it in. #10467 kept every such row out of the merge direction,
which killed the phantom but also dropped the only way to propagate a
fork-side deletion and left a rename's old path behind in the parent.
Record the evidence instead:
- `workspace_diff` gains, per side, the last event's kind (`write` /
`delete` / `rename_from`) and origin (`authored` / `sync`). Rows
written before the migration have neither and keep #10467's behavior.
- The kind is probed from whether the path still holds an item once the
write has committed; an item kind the probe doesn't map records no
evidence rather than a deletion. Create and update are not split —
nothing at that point tells them apart for every kind, and the
comparison already recomputes existence per side.
- The origin comes from an `X-Windmill-Deploy-Origin` header the API
scopes into a task-local for the request. It is the load-bearing half:
recording `delete` alone would read a git-sync revert as a fork
deletion and reproduce the original bug. Two clients set it — `wmill
sync push` (which the git-sync auto-pull runs inside a job) and the
compare page's parent→fork "Update fork". Merging the other way stays
authored so a deletion keeps propagating up a fork chain.
- The merge direction admits a parent-only row only when the fork's last
event was an authored delete or rename-away. Such a row stays opt-in,
never bulk-selected, and reads "Removes in <parent>"; the update
direction keeps offering it back as "New".
A fork deletion and a rename now merge into the parent, a rename leaves
no duplicate behind, and a fork the parent also edited surfaces in both
directions instead of the parent silently winning.
Fixes WIN-2289
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(fork): address review — detached tallies, enum wire values, doc duplication
Codex P1: a dependency job tallies its deploy whenever it happens to finish,
and the event kind is probed from the state at that moment. If anything
removed the path in between (a git-sync revert), the stale tally read that
deletion as its own and filed it as authored — handing the merge exactly the
removal this is meant to withhold. `tally_deployed_object_changes` now takes
`Option<DeployOrigin>`; `None` bumps the counter and leaves the evidence
columns as the last vouching tally left them, and the worker path passes it.
Covered by extending the removal-origin test: a detached tally after the sync
archive must not disturb `(delete, sync)`.
Also from review:
- `fork_removed_it` compares through `DeployOrigin::as_str()` /
`DeployEventKind::as_str()` rather than repeating their wire values, so a
renamed variant can't silently make the predicate always false.
- `deploy_origin`'s module doc no longer claims `sync` is inert: it cannot
make the merge propose a removal, but it does drop a row out of both sides
of the `all_ahead_items_visible` comparison.
- `WorkspaceDiffRow` says why only the fork half of the evidence is consumed.
- The delete-vs-revert rationale is stated once (the migration) instead of
restated in eight files.
- `PATH_KEYED_TABLES` is swept by a test: its query is built at runtime, so a
wrong table name is not a compile error and would only surface as a failed
tally for that trigger kind in a fork.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(fork): let only a request task vouch for a deploy event
Round 2 found the first fix incomplete. Detaching only the failed/cancelled
dependency path left the common route untouched: a dependency job that
succeeds calls `handle_deployment_metadata` from the worker, where
`deploy_origin::current()` read as `Authored`. A sync archiving the script
while its lock generation was pending then had its deletion probed on
completion and refiled as authored — the same fabricated removal, on the
path most deploys actually take.
`current()` now returns `Option`, `Some` only inside the request scope the
API always enters. Having no scope means "not the task that served this
write", which is true of every worker-side call and needs no marking at the
call site. The integration test drives the real `handle_deployment_metadata`
off a request task instead of the tally directly, and fails without this.
Two more from the same round:
- The script dependency handler passed no `renamed_from`, unlike the flow
and app handlers next to it. A lock-generating create has no earlier
tally, so that was the only chance for the path a rename vacated to be
recorded at all — renames of Python/TS scripts left the old path in the
parent, which the bash-only manual check missed.
- The tally now drops a `renamed_from` equal to the path itself. Callers
pass the previous path whether or not the deploy moved the item, so an
unfiltered one both counted the path twice and stamped it `rename_from`
when nothing was renamed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(fork): carry a deploy's origin into the dependency job it queues
Round 3 caught the previous fix cutting too deep. Refusing a detached tally
any claim also refused its rename evidence, and a lock-generating deploy has
no other tally — so the `renamed_from` added alongside it was inert, and a
renamed flow, app or Python script still left its old path in the parent
with nothing to merge. Flows and apps always generate, so renames worked
essentially nowhere.
The two capabilities are now separate. `TallyEvidence` says whether the
tallying task served the write (`Served`, may probe what the path holds now)
or is reporting one that committed earlier (`Deferred`, may not), and each
column is written only from a source that answers for it. The origin itself
is a fact of the deploy either way, so the request stamps it into the
dependency job's args and the worker re-enters the scope with it — the last
place that knows it handing it to the only tally that will run.
Also from round 3: `WorkspaceDiffRow`'s event fields skip serializing `None`
rather than emitting `null`, matching what the schema declares (OpenAPI
3.0.3 ignores a `description` sibling of `$ref`, so those moved onto the
shared schemas).
Verified against a live worker: renaming a flow in a fork records
`(rename_from, authored)` on the vacated path and the merge offers its
removal, while the deployed path claims nothing.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(fork): mark the CLI's parent-to-fork merge as sync
`wmill workspace merge --direction to-fork` is the CLI's "Update fork" and
deletes items in the fork, but without the marker the compare page sets. Its
deletions were recorded as authored fork decisions, so once the parent
recreated such a path the merge would offer deleting it there.
Also from review: an unrecognized deploy-origin arg now reads as no evidence
rather than as authored — strict where a request header is lenient, since an
unmarked request really is authored but an unreadable stored value is skew.
Reading the arg moved next to `stamp_origin_arg`, the half that writes it, so
the round trip a lock-generating deploy depends on is covered by one test.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: drop the imports the shared arg reader made unused
CI compiles with `-D warnings`, so this was four red Backend jobs rather
than a lint.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(fork): stop a stale deferred rename from restating a removed path
Nothing orders these events. A tally that served the write made its claim
inside its own commit, but a deferred one reports a write that landed at an
unknown remove. So a lock-generating rename whose dependency job finished
after a sync had removed the vacated path could overwrite `(delete, sync)`
with `(rename_from, authored)` — the path is gone either way, so the merge
would then offer removing it from the parent on the strength of the older
event.
A deferred claim now only writes where the side has none, which is the case
it exists for: a vacated path that nothing else has spoken for. The
regression asserts the ordering directly, and fails without the guard.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(fork): record a rename's vacated path from the request that made it
The deferred mechanism could not be made correct, as round 7 showed: its
guard protected an existing row, but that row is deleted as soon as the two
workspaces agree on the path — so a rename job finishing after the
reconciliation inserted fresh, and the stale claim reappeared against
whatever the parent later recreated there. Ordering cannot be recovered
outside the row, because the row is disposable.
So the vacated path is now recorded by the request, which is inside its own
commit and whose row shares the counter's lifetime. A deploy that hands its
metadata to a dependency job — every flow and app, and any script needing a
lock — calls `tally_rename_vacated_path` once its transaction has committed;
scripts reach it through the post-commit hook they already had, which grew a
second variant rather than new plumbing.
That lets the whole deferred apparatus go: `TallyEvidence`, the origin job
arg and its round trip. `deploy_origin::current` is `Some` only inside a
request scope again, and `handle_deployment_metadata` hands `renamed_from`
to the tally only when it can answer for it — git-sync still gets it either
way, so the rename keeps naming itself in the commit message.
The vacated path's kind now reads `delete` rather than `rename_from` for
these deploys, since it is probed rather than declared. The merge treats the
two alike; only the row's tooltip is less specific.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(fork): cover raw-app renames, and stop firing CI before the lock exists
Two things the vacated-path call broke or missed:
- `create_script` reads its third return value as "no lock generation
needed" to decide whether the script is runnable now, and the new
`VacatedPath` variant made that true for renames that do generate. Those
fired dependent CI tests from the API against a version with no lockfile,
and again from the dependency job. The variant now decides it explicitly.
- Raw apps rename through `update_app_raw`, a separate route into
`update_app_internal`, which the new call had not been attached to. Both
routes now go through one helper.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* test(fork): assert the kind only an inline rename can record
`rename_from` is what a deploy says when it knows it moved the item, which
only the path that reports both halves from its own request can. Nothing
pinned it, and that is the side the vacated-path change touched.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: update ee-repo-ref to a45bec03922d305aad5893ed354dc029c7f97bb4
This commit updates the EE repository reference after PR #709 was merged in windmill-ee-private.
Previous ee-repo-ref: 62f494b2a51de0dfc0cfa0c3530ff19a1d32667c
New ee-repo-ref: a45bec03922d305aad5893ed354dc029c7f97bb4
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>
* feat: azure workload identity auth for mssql and postgres resources
* refactor: keep mssql config lines untouched by the auth-mode change
* fix: single-flight token refresh, cache eviction and identity-aware pg cache key
* fix: back off after a failed entra id refresh and normalize blank pg identity fields
* fix: re-check the fallback token lifetime after a failed refresh
* refactor: select workload identity with a sentinel password instead of resource fields
* fix: log the workload identity mode on the postgres path too
* fix: stop reading a parent-only fork item as deleted in the fork
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* style: condense the deploy-direction helper comments
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep the ambiguous half of a one-sided diff out of bulk defaults
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: disable select-all on a removal-only list and cover the hidden source-only row
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep parent-only items out of the fork merge list entirely
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: count the fork banner's ahead/behind with the compare page's predicate
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: open the direction the fork banner's button offers
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: cache the sqlx query for the source-only visibility test
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: don't read an unloaded comparison as nothing to deploy
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: treat an in-flight comparison as unknown in the fork banner
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: show the fork banner to a superadmin who is not a workspace member
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: scope the non-member workspace cache to the current workspace
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: make the non-member workspace cache own exactly one workspace
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: drop the non-member workspace cache when no workspace is open
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: report why a native trigger service refused instead of a 500
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep the cause of an unreachable trigger service in the message
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: degrade a trigger read only for the service's own failures
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: tell a refresh outage apart from a rejected refresh grant
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: treat a rate-limited or timed-out service as an outage, not a refusal
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep a token endpoint's status out of the trigger's
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: read a refused refresh grant off the body, not only the status
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: let a throttled 403 read as an outage, not a permission refusal
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: classify a refresh refusal by its OAuth code, and Google quotas by domain
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: recognize GitHub's other wording for a throttled request
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: return result.json and stdout results from sandboxed containers
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: capture unmasked stdout-only last line, validate container result.json
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: reject image WorkingDir that escapes the container root
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: verify the whole result mount destination against the extracted rootfs
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: name the right skip reason and gate the symlink test to unix
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: give dbt its own editor with an explicitly refreshed model graph
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: bump ee ref for the agent-worker dbt editor graph
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: scope editor graph retention by principal, carry parse context, honor nlang
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: bump ee ref
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep the dbt editor's model graph and log panel mounted across tabs
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep the dbt_edge to dbt_node joins on an index-usable equality
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: poll a parse until the job ends, resolve the project key, correct the docs
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: surface a slow parse's job, bound poll failures, drop banned bindable defaults
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: hide the dbt Generated UI content, not only its tab
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: honor disabled Triggers in the dbt tab fallback, record permissioned_as
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: one dbt pane with the run drawn on the models, and a full-height script graph
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: move the dbt build arguments behind the Build button
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: trim the dbt editor toolbar and stop the graph asserting a cause it lacks
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: mark dbt as alpha in the language picker and announce it once
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: trim the dbt alpha notice
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: give a selected dbt model the whole detail section, with a close that deselects
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: close the dbt detail panel by clicking away, and make its close obvious
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: cache the agent-worker dbt query, which needs the private feature to compile
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: never fall back to a settings tab the embedder disabled
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: preview dbt rows from the same project the graph was parsed from
* feat: hide the script-kind selector for dbt projects
* fix: pin a dbt row preview to the project its graph was parsed from
* fix: pin a dbt row preview to the arguments its graph was parsed under
* fix: keep dbt preview placeholders live while its vars stay pinned
* fix: report a warehouse-less dbt parse's counts and flag stale preview args
* fix: tell the pinned-vars case apart from a stale placeholder
* chore: update ee-repo-ref to 59044635769f18f8ff5073236cfc7b5f41e917cc
This commit updates the EE repository reference after PR #707 was merged in windmill-ee-private.
Previous ee-repo-ref: 7e424384cdd4cef8653b55b04f17ad3f801bc50c
New ee-repo-ref: 59044635769f18f8ff5073236cfc7b5f41e917cc
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>