mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-20 16:02:19 +00:00
df6e511763dbead310cf26ed7ed0dd37557d2e09
13742 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
df6e511763 |
chore(main): release 1.747.0 (#9901)
* chore(main): release 1.747.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>v1.747.0 |
||
|
|
1b6065fa92 |
fix(kafka): set https.ca.location=probe for OAUTHBEARER OIDC token endpoint (#9897)
* fix(kafka): set https.ca.location=probe for OAUTHBEARER OIDC token endpoint Bump EE ref to pull in the mod_ee.rs change that sets https.ca.location for the Kafka OAUTHBEARER (OIDC) token endpoint HTTPS request. EE companion: windmill-labs/windmill-ee-private#642 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: update ee-repo-ref to 81d8a449effdc540a6e8810668dd5d4aea0c485a This commit updates the EE repository reference after PR #642 was merged in windmill-ee-private. Previous ee-repo-ref: a6761c3cbbf788c7273296f49bb0c39eef85afb9 New ee-repo-ref: 81d8a449effdc540a6e8810668dd5d4aea0c485a Automated by sync-ee-ref workflow. --------- Co-authored-by: Claude Opus 4.8 (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> |
||
|
|
4ba17d0f9c |
fix: prevent truncated tool call args from bricking AI chat sessions (#9902)
* fix(frontend): prevent truncated ai chat tool-call arguments from bricking the session Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: heal empty tool-call arguments when replaying chat history Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: state sanitize invariant without drafting history Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
d600c7ecfe |
fix(ai): route Azure Foundry Claude models via Anthropic Messages API (#9908)
* fix(ai): route Azure Foundry Claude models via Anthropic Messages API Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(ai): keep explicit Azure OpenAI deployment base URLs intact build_azure_openai_url only appends /openai/v1 for a bare resource root; any base with an explicit path (e.g. .../openai/deployments/<id>) is preserved. Adds a regression test and a unit test for usesAnthropicMessagesApi. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(ai): enable Claude extended thinking on Azure Foundry Route azure_foundry+Claude through the Anthropic reasoning branch (adaptive thinking + output_config.effort) instead of the gpt/o gate, and recognize claude-sonnet-5. Live-verified: sonnet-5 and opus-4-8 on Foundry accept the low/medium/high/xhigh/max ladder and render summarized thinking. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
ae85d27437 |
feat(frontend): add federatedTokenFile field to instance object storage Azure config (#9904)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
3ec1f164be |
fix: strip NUL characters from app values at save time (#9903)
App values are persisted to a json column, which permits the JSON NUL escape (backslash-u-0000), but are later converted to jsonb (e.g. a workspace fork clone_apps, search indexing), which rejects it with "unsupported Unicode escape sequence" -- silently making the app un-forkable. The usual source is a binary file such as .DS_Store accidentally bundled into a raw app file map. A real NUL is unstorable in jsonb either way, and frontend code that needs the character writes it as the source escape (which JSON-encodes to an escaped backslash + literal u0000 and is left untouched), so rather than hard-failing the save we strip genuine NULs and warn. Add strip_null_chars and apply it at both app_version insert sites (create_app_internal and update_app_internal, covering the regular and raw create/update routes). It removes a genuine NUL escape (odd run of backslashes before u0000) while preserving an even run. Returns a borrowed Cow (no allocation) when the value is already clean. Covered by unit tests. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
5c521d808a |
fix(forks): clone only the current raw-app bundle, via server-side copy (#9899)
* fix(forks): clone only the current raw-app bundle, via server-side copy Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(forks): fall back to get+put when object-store copy is unsupported Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
bcb4dd8d27 | docs link | ||
|
|
fad5419b9d |
chore(main): release 1.746.0 (#9872)
* chore(main): release 1.746.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>v1.746.0 |
||
|
|
84141add1d |
feat(pipelines): workspace duckdb macro libraries (// macros / // use) (#9890)
* feat(pipelines): parse duckdb macro-library annotations (// macros, // use) * feat(pipelines): duckdb macro registry tables + deploy-path validation and writes * feat(pipelines): inject workspace duckdb macros into consumer jobs at run time * feat(pipelines): surface macro libraries and lib-consumer edges in asset graph api * feat(frontend): macro-library nodes, lib-consumer edges and scaffold in pipeline graph * docs: mark dbt gap #7 (packages/macros) shipped via workspace macro libraries * fix(pipelines): review fixes - char-safe parsing, local macros win, fork clone, trust-model docs * feat(frontend): duckdb macro autocomplete + workspace macro explorer drawer * fix(pipelines): address CI review - use-setup retention, splice past local defs, orphan filter, full consumer rescan, index-keyed strip * fix(pipelines): inject provider library setup for implicitly-called macros too * fix(pipelines): rls-gate macro listing + honor library-level // use transitively * fix(pipelines): weave injected macros around local definitions by bind order * fix(pipelines): injected library setup always runs before user blocks * perf(pipelines): cache macro registry per workspace with notify-event invalidation * perf(pipelines): disable macro registry cache on cloud |
||
|
|
af01e90b5c |
feat(s3): replace CE 50MB upload cap with 10GiB workspace storage quota (#9874)
* fix(s3_proxy): enforce CE 50MB upload cap on multipart uploads Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(s3): replace CE 50MB upload cap with 10GiB workspace storage quota Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(s3): gate CE quota OSS stubs to not(enterprise) to match callers Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(s3): delta-aware CE storage quota + guard usage-load retry loop Account for the overwritten object's size in the quota check so valid same-size overwrites near quota are not rejected (Codex review), and stop the storage-usage $effect from re-firing on persistent API errors (Pi review). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(s3): count chunked PUTs; revert overreaching volume quota copy Volumes write to workspace storage via a separate worker-side path with its own 50MB-per-file cap that this PR does not change, so revert the drawer copy that claimed they count toward the 10GiB quota (Codex review). Bump ee-repo-ref for the chunked-PUT accounting fix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(s3): add SQLx cache for CE usage-bump/quota queries; exclude volumes Regenerate the missing offline SQLx cache for the not(enterprise) bump and remaining-quota queries so the private CE offline build compiles, and bump ee-repo-ref for the volumes/-prefix exclusion from the counted quota (Codex review). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(s3): always HEAD for CE upload delta so overwrites don't inflate usage Bump ee-repo-ref for the fast-path overwrite-accounting fix (Codex review). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(s3): reserve volumes/ prefix on CE write surfaces to close quota bypass Reject direct writes to the reserved volume prefix on the app-upload surface and add the OSS stub; bump ee-repo-ref (Codex review). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(s3): refuse new multipart work when CE workspace is at quota Bump ee-repo-ref for the multipart-initiate/part quota gate (Codex review). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(s3): reserve in-flight multipart bytes against CE storage quota Add workspace_multipart_inflight table + grants, SQLx cache for the reservation queries, and bump ee-repo-ref. Bounds abandoned multipart uploads that the list-based recount can't see (Codex review). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(s3): clear multipart reservation only after a successful complete Add exclude-upload arg to the OSS quota stub/caller and the SQLx cache for the updated remaining-quota query; bump ee-repo-ref (Codex review). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(s3): per-part multipart reservation; commit only on part success Per-part workspace_multipart_inflight schema (upload_id, part_id) so retries replace rather than double-count; SQLx cache for the reworked queries; bump ee-repo-ref (Codex review). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * perf(s3): HEAD the multipart overwrite target once per upload, not per part SQLx cache for the stored-credit lookup; bump ee-repo-ref. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore: update ee-repo-ref to bea5a8b5120d6d69cab1ad4611ebe463559bd200 This commit updates the EE repository reference after PR #640 was merged in windmill-ee-private. Previous ee-repo-ref: 6e6ff86f1939cf74736b7d435bf6851416437523 New ee-repo-ref: bea5a8b5120d6d69cab1ad4611ebe463559bd200 Automated by sync-ee-ref workflow. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com> |
||
|
|
7c7d7474cc |
feat: support workspace forks on cloud using parent workspace limits (#9864)
* feat: support workspace forks on cloud using parent workspace limits Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: clarify count_paid_seats approximates rather than mirrors billing seats Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: non-admin fork UI, attach cap, and fork-count for cloud forks Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: cloud fork billing cache on rename, usage display, attach cap edge Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat: fork count in cloud quotas + fork billing points to parent Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: invalidate billing/fork caches on fork deletion for id reuse Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: gate fork usage remap on CLOUD_HOSTED, not just the cloud feature Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: note cloud feature vs CLOUD_HOSTED gating in backend guide Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: reserve fork-cap slots for an attach candidate's whole subtree Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: invalidate team-plan cache on delete, raise fork depth cap Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat: cap fork nesting depth (MAX_FORK_DEPTH, default 5) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: fork count/height robust to cycles and deleted intermediates Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): reset fork button loading state on creation error Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: invalidate billing cache for attached fork subtree; helper auth docs Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
d15033cde6 |
fix: invalidate bun bundle cache on transitive relative-import changes (#9891)
* fix: invalidate bun bundle cache on transitive relative-import changes Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: do not memoize transient fetch errors in bundle-key import cache Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: use regular comment on lazy_static block (deny unused_doc_comments) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: align bundle-key import version selection with loader content endpoint Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
a49c0871d7 |
fix(frontend): show inline workspace name editor on general settings (Fixes GIT-911) (#9892)
* fix(frontend): show inline workspace name editor on general settings Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): guard rename and support enter-to-save on workspace name Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
d9b080f57f |
feat(ai): add Azure AI Foundry as a native AI provider (#9879)
* feat(ai): add Azure AI Foundry as a native AI provider Adds `azure_foundry` as a new AIProvider variant wired through the AI chat (copilot) and AI agent flow steps. Foundry's chat completions API is OpenAI-compatible and uses Azure conventions (api-key header, Azure URL building), so it reuses the existing OpenAI-compatible query builder and proxy path via the shared `is_azure` helper (renamed from `is_azure_openai`). Backend (windmill-ai): - New `AzureFoundry` enum variant (serde `azure_foundry`) - `get_base_url` requires a resource base URL (like Azure OpenAI / Custom) - `is_azure()` covers Azure OpenAI + Foundry (api-key auth, Azure URL) - Added to OpenAI-compatible proxy support and HttpForward proxy mode - New proxy URL unit test Frontend (copilot): - New provider entry, completion config, model-token handling, streamed usage tracking, and reasoning registry (all model-id-gated, so a no-op for Foundry's non-OpenAI catalog) - Treated as a chat-completions provider, not the OpenAI Responses API OpenAPI: - `azure_foundry` added to AIProvider (openapi.yaml) and AIProviderKind (openflow.openapi.yaml); regenerated CLI guidance Note: the `azure_foundry` resource type (base_url + optional api_key) is hub-managed and must be published to the Windmill Hub separately. Fixes WIN-2122 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(ai): add azure_foundry to copilot flow Zod provider enum The tracked copilot flow schema (openFlowZod.gen.ts and its openFlow.json source) still carried the old AIProvider enum, so validateFlowModules / validateSpecialFlowModule rejected AI-generated flow edits that create or update an aiagent module with provider kind "azure_foundry" before they could be saved. Add the value to both (preserving the generated single-line format) and a regression test over the flow-module validation path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(ai): lead provider list with OpenAI, Anthropic, Google AI Reorder AI_PROVIDERS so the three primary direct providers come first. The AIProviderPicker renders the first three entries as quick-access buttons, so these become the defaults (previously OpenAI, Azure OpenAI, Azure Foundry); Azure OpenAI / Azure Foundry stay adjacent right after. No logic depends on provider order (only per-provider defaultModels[0] is read). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
186ac4933b |
fix(frontend): home New submenus fall back below, hugging the right edge (#9894)
* fix(frontend): home New submenus fall back below hugging the right edge Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(frontend): re-hug submenu on window resize even without a melt reposition Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
37bb57474e | fix: make SMTP username and password optional in frontend validation (#9895) | ||
|
|
5af91a677c |
fix: stale AI chat context picker after workspace item changes (#9893)
* fix: revalidate workspace items cache on context picker open The chat context picker (and workspace drill pickers) read from a module-level cache that was only invalidated from two editor save paths, so items created or deleted anywhere else stayed stale until a full page reload. Make the loader do real stale-while-revalidate: cached items render instantly and each workspace+kind is re-fetched once per picker mount, keeping the state reference stable when nothing changed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: retry failed picker revalidation and handle its rejection Mark a workspace+kind as revalidated only after the fetch succeeds, so a failed revalidation is retried on the next ensureLoaded call instead of stranding stale data for the rest of the mount. Catch the rejection (callers fire-and-forget) and log it. Also dedupe the stale-while-revalidate rationale to its canonical comment site in workspacePicker.ts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
789450731b |
fix(triggers): retry transient websocket connect failures before disabling (#9887)
A websocket trigger is permanently disabled (with a critical alert) when a single connect attempt in get_consumer fails. Gateway endpoints fronted by edge proxies (e.g. Discord behind Cloudflare) sporadically answer the upgrade handshake with a transient 502/520, so a long-lived trigger that reconnects frequently eventually catches one and dies until a human re-enables it. Retry transient failures (HTTP 5xx/429 handshake responses and IO errors) up to 5 attempts with exponential backoff before surfacing the error, and report retry progress through the trigger's error status. Permanent-looking errors (bad URL, other 4xx, protocol/TLS mismatch) still disable immediately. Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
5745dfc6ea | smooth local pipeline dogfooding (#9888) | ||
|
|
53bbb92953 |
feat(pipeline): backfill a range of partitions from the asset drawer (#9885)
* feat(pipeline): backfill a range of partitions from the asset drawer (ee) * feat(pipeline): cancel in-flight backfill job and show cancelling state * refactor(pipeline): move backfill range logic behind private feature * fix(pipeline): close backfill cancel-launch race and record dispatch intent * docs(openapi): producer_path also covers SDK write-edge producers * chore: update ee-repo-ref to c3852ecb36bd0be1a74c63169e513888f3347850 This commit updates the EE repository reference after PR #641 was merged in windmill-ee-private. Previous ee-repo-ref: 7c1450ef89fbc9e844a121b39cafe0d7235d704b New ee-repo-ref: c3852ecb36bd0be1a74c63169e513888f3347850 Automated by sync-ee-ref workflow. --------- Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com> |
||
|
|
d65f58c388 |
fix: pipeline dogfooding fixes — SCD2 data-test scope, --partition, s3object upload binding (#9875)
* fix: scope SCD2 built-in data tests to current rows Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat: add --partition to pipeline run and fix duckdb s3object upload binding Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: note filesystem storage type is dev-only in storage settings Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: use ISO week for weekly partition default in pipeline run Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
9c758df5eb |
reserve more fixed height for unsaved-changes banner to avoid content shift (#9873)
* fix(frontend): reserve fixed height for unsaved-changes banner to avoid content shift Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): remove border around reserved banner slot and shrink it Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): tighten top padding under the unsaved-changes banner Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): give unsaved-changes banner buttons minimal vertical breathing room Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(frontend): drop redundant Metadata section title in trigger and script editors Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): tuck schedule editor labels under summary to match convention Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * revert(frontend): keep Metadata section title in ScriptBuilder for a separate PR Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): drop leftover header-content margin on headless Section Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): drop top padding above resource editor first field Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * style(frontend): match variable editor bottom padding to resource Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): add Path label in new resource form to match edit Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): reserve half the banner height to halve the idle gap Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): reserve a third of the banner height when idle Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): don't reserve banner slot or tighten top for new entities Gate the reserved-height slot and the tight content top padding on the banner's baseline (bannerReserved) instead of merely on the banner snippet being present, so new-entity drawers keep normal top spacing and add no empty slot. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(frontend): trim banner comments to the 4-line invariant limit Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(frontend): describe partial-reserve banner behavior accurately Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
b92a86b8b3 |
fix: polish pipeline graph view (layout, viewport, minimap, lineage, timestamps) (#9883)
* fix(frontend): keep pipeline graph layered when lineage has cycles Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(frontend): fit pipeline graph to visible canvas on initial load Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(frontend): style pipeline minimap so it reads as a minimap Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(parser): don't infer s3 reads from bare string-literal mentions in sql Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(duckdb): render temporal values as ISO strings in job results Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(frontend): key pipeline viewport fit on the loaded graph's folder Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(parser): treat list/named read-fn arguments as definitive s3 reads Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
20351a6b4c |
feat(frontend): pipelines index page and sql editor hint (#9881)
* feat(frontend): surface pipelines in sidebar nav, index page and sql editor hint Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(frontend): remove pipelines sidebar nav item Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
7b04820f8e |
feat(frontend): group compare & deploy items by folder (#9880)
* feat(frontend): group compare & deploy items by folder Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(frontend): group folder items with their folder, fix disabled hint Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
659642e488 | fix(parsers): infer py s3 assets from S3Object constructor and dict forms (#9877) | ||
|
|
b883adbc00 |
fix(duckdb): auto-declare partition arg for // partitioned scripts (#9878)
* fix(duckdb): auto-declare the partition arg for // partitioned scripts Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(cli): pipeline run --arg to pass plain run args to cascade scripts Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
e77b7523a5 | nit enterprise implies license feature | ||
|
|
79897950e7 |
fix(frontend): stack cron field and cron builder button on narrow screens (#9871)
The cron schedule row placed the input next to a shrink-0 button group, so on narrow layouts the buttons kept their width and squeezed the input to near-zero. Make the row wrap and give the input a min width so the buttons drop below it, keeping both visible. Fixes WIN-2121 Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
9a24cd2bef |
chore(main): release 1.745.0 (#9858)
* chore(main): release 1.745.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>v1.745.0 |
||
|
|
1a9debb689 |
fix(jobs): give flow dynselect a path and its worker tag, like scripts (#9867)
Fetching options for a `dynselect`/`dynmultiselect` input was inconsistent between deployed scripts and deployed flows: - scripts ran through `push_script_job_by_path_into_queue` — a `script` job with the script's path, tag, lock and codebase resolution; - flows ran their schema dyn-select code as an anonymous `preview` with no path and no tag (always the language default), and reported access failures as a raw `SqlErr: no rows`. Deployed scripts are left exactly as they were (that path already handles tag/lock/codebase/on-behalf-of correctly). The flow branch now: - carries the flow path on the preview job, - reads the flow's `tag` under RLS and routes the job to it (falling back to the language default when unset), matching the script's worker group, and - runs `check_tag_available_for_workspace` on that tag — the same gate a normal flow run and the script path apply — so a caller who can read the flow but is not allowed to use its (custom/scoped) worker tag is rejected consistently. The flow's tag read runs on every request, so it also serves as the per-request access check, replacing the raw error with a clean `NotAuthorized` / `NotFound`. Entrypoint-name validation now covers all branches (it is interpolated into the generated wrapper). Inline is unchanged: a `preview` with no path on the language default, blocked for operators. Fixes WIN-2118 Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
20cd1a02d5 |
feat(forks): partial-visibility deploy + surface hidden items (#9868)
* fix(forks): let partial-visibility users deploy the visible subset The fork Compare & Deploy page hid the deploy button entirely whenever the comparison reported any item not visible to the user (all_ahead/all_behind flags), telling them to hand the deploy to someone with full access. But the non-visible items are already filtered out of the diff list, and the UI already supports deploying an arbitrary subset via per-item selection — so blocking everything was inconsistent and, for stale/phantom rows, blocked on items that don't even exist. Show the deploy footer regardless; the user acts on the visible/selected items (the per-item disabled conditions are unchanged). The hidden-items notice is kept but downgraded to a non-blocking, direction-scoped banner that explains the excluded items instead of removing the action. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(forks): surface hidden-item counts by kind + admin path list WIP: expose items dropped by the visibility filter (hidden_ahead/hidden_behind in the compare response): by-kind counts for everyone, kind+path only for admins. * fix(forks): don't close the deployment request on a partial (hidden-items) deploy Making the deploy button reachable in the partial-visibility case exposed a bug: a clean merge-into-parent deploy unconditionally closed any open fork deployment request as "merged" — marking its comments obsolete and notifying the requester and assignees of a merge — even when hidden ahead changes were excluded from the list and left undeployed. Only close the request as merged when the full ahead set was visible (all_ahead_items_visible); otherwise leave it open (with a toast) so someone with full access can finish it. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
a73b14d902 |
fix(cli): correct misleading delete-fork command description (#9870)
* fix(cli): correct misleading delete-fork command description The `wmill workspace delete-fork` description claimed it deletes "a forked workspace and git branch", but the implementation only deletes the Windmill workspace via the backend API and removes the local workspace profile. No git operations are performed, so the remote branch is left untouched. Drop the "and git branch" clause and regenerate the derived guidance/system-prompt files. Fixes WIN-2120 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(cli): permanently delete temp workspaces in folder test cleanup The isolated-workspace test helper archived each temp workspace on teardown. After #9865 added a CE cap of 1 archived workspace, the second archive-cleanup is refused, so temp workspaces leak into the active set and hit the 2-workspace CE cap — failing every subsequent create/fork across the shared test backend. Permanently delete the workspace instead (DELETE /api/workspaces/delete), which frees the slot without occupying the archived quota. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Ruben Fiszel <ruben@windmill.dev> |
||
|
|
7363d2c217 |
fix(forks): require admin of both sides for the compare visibility guard (#9869)
The blast-radius guard added in #9866 forced `all_ahead_items_visible` true for any fork/target admin. But `filter_visible_diffs` keeps a modified/conflict row (one that exists in the source AND the fork) only when the caller can see it on both sides, so an ahead diff can be dropped for a source-side visibility gap even when the caller is a fork admin. Forcing the flag on fork-admin alone then wrongly reported "all ahead items visible", letting the UI enable deployment from an incomplete comparison. Gate the guard on admin of BOTH the source and the fork (superadmin satisfies both), which is what actually guarantees full visibility of every item on every side. Adds a regression test where a fork admin who is only a plain member of the parent (no access to the item's folder) must still get `all_ahead_items_visible = false`, plus the superadmin sanity path. Also restores the SQLx offline cache entry for the phantom-trigger test INSERT that #9866 landed without (CI/`SQLX_OFFLINE=true` builds failed on it), and adds entries for the new test's all-literal queries. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
6a6f12960e |
fix(forks): reset diff tally on trigger delete + guard compare visibility for admins (#9866)
Deleting a trigger left a stale `workspace_diff` row: `delete_trigger` (the generic TriggerCrud handler) was the only delete path that never called `handle_deployment_metadata`, unlike every other kind. Because `compare_workspaces` trusts a cached `has_changes=true` row for non-script/flow kinds and the visibility filter then drops it (the trigger no longer exists), a deleted trigger became a phantom "ahead" item that flipped `all_ahead_items_visible` to false — hiding the deploy button and showing a "changes not visible to your user" warning that even a superadmin could not resolve (`reset_diff_tally` doesn't clear a `has_changes=true` row either). - delete_trigger now re-tallies via handle_deployment_metadata, so the next compare re-evaluates and corrects/removes the row (matches resource/variable/ folder/schedule deletes). - compare_workspaces forces the visibility flags true per side for anyone who sees that side in full: target/fork admin (or superadmin) for ahead items, source/parent admin (or superadmin) for behind items. The flag is a pure visibility guarantee — the deploy itself is authorized separately — so for such users a dropped diff is provably a phantom, never a permission gap. - Add a regression test asserting a phantom trigger diff row no longer blocks a superadmin while still (conservatively) warning a partial-context user. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
d7be355290 | sqlx nits | ||
|
|
efb62c5e99 |
enforce CE workspace limit when unarchiving (#9865)
* fix(workspaces): enforce CE workspace limit when unarchiving Unarchiving a workspace re-activates a soft-deleted (deleted = true) workspace, effectively bringing it back to the active set. On CE this bypassed the 2-workspace cap that create_workspace enforces, letting a user exceed the limit by archiving and re-unarchiving. Run the same _check_nb_of_workspaces guard before flipping deleted back to false. The workspace being restored is still deleted = true at that point, so it is correctly excluded from the count. Fixes WIN-2119 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(workspaces): cap CE archived workspaces at 1 Complements the unarchive-limit fix: without a cap on archived workspaces, a CE user could stockpile many soft-deleted workspaces (each of which still occupies its workspace id and can later be unarchived). Refuse a new archive on CE when an archived workspace already exists, mirroring the create/unarchive workspace-count guards. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
76a9523009 |
feat: use derived username instead of email for non-member superadmins (#9857)
* feat: use derived username instead of email for non-member superadmins Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: address review - drop redundant username cache, guard whoami membership by email Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor: use explicit non_member boolean instead of role string for superadmin banner Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: resolve email from password table for non-member superadmin permissioned_as Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: resolve non-member superadmin drafts via shared username->email resolver Adds resolve_username_to_email (usr, then super_admin password fallback for both derived-username and email modes) and uses it in get_email_from_permissioned_as and the drafts get/list endpoints, so a non-member superadmin's drafts resolve and no email leaks into the drafts payload. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test: superadmin-not-in-workspace schedule uses derived username as permissioned_as Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: resolve non-member superadmin identity in draft owner-circles, username_to_email, and home filter Applies the password-fallback username resolution to the script/flow/app/draft owner-circle subqueries and the username_to_email endpoint (was an admins-workspace 'username == email' hack), and switches the home items-list user-folder filter to the non_member flag instead of the now-broken username-contains-@ heuristic. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: backfill non-member superadmin favorites from email to derived username Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: propagate DB errors in username resolution instead of leaking email (CI review) Addresses cubic-dev-ai P2: get_instance_username_or_fallback_to_email now returns Result and only falls back to the email for a genuine 'no derived username'; a query error propagates so callers fail closed rather than leaking the raw email as the acting username. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: clarify non-member superadmin popover (username used + admin permissions) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: keep username_to_email endpoint member-only to not disclose non-member superadmin email (CI review) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: forbid disabling automate_username_creation once usernames assigned (CI review) Makes the setting effectively one-way once instance-wide usernames exist, so the global-uniqueness invariant that keeps stored u/<username> identities (schedules/triggers/drafts/superadmin ownership) unambiguous can never be dropped back to workspace-local uniqueness. Re-saving false on an already-disabled instance stays a no-op. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
35861641f8 |
fix(offboarding): make global reassignment per-workspace and optional (#9863)
* fix(offboarding): make global reassignment per-workspace and optional Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(offboarding): handle sole-member workspaces in workspace-level removal Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(offboarding): show close action instead of dead-end in reassign-only sole-member case Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(offboarding): prevent no-op success in global reassign-only with no reassignable workspace Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
289017bcb2 |
feat(frontend): add zoom and download to Mermaid graphs (#9859)
* feat(frontend): add zoom and download to Mermaid graphs Mermaid diagrams in the AI chat could only be viewed inline with horizontal scroll. Add a download-as-SVG button and an expand button that opens a fullscreen modal with pan/drag and zoom (mouse wheel plus in/out/reset controls), reusing the existing `panzoom` dependency. Fixes WIN-2117 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): guard panzoom action against close-before-import race Address review nit: if the modal closes before the dynamic import('panzoom') resolves, destroy() ran while instance was still undefined (disposing nothing) and the late .then() built a leaked panzoom on a detached node. A disposed flag makes the cleanup airtight. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
383c70523b |
fix(folders): allow dots and at-signs in folder owner validation (#9856)
Folder owners use the format u/<username>, and usernames are frequently email addresses containing `.` and `@`. The folder creation path bypasses validate_owner(), so these owners get inserted successfully, but add_owner and remove_owner both call validate_owner() and rejected any later modification of email-style owners. Extend the character allowlist to accept `.` and `@` (and update the error message). SQL injection risk is already mitigated by the bind-parameter queries introduced alongside this validation. Fixes WIN-2116 Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
cfcc0b9453 |
chore(main): release 1.744.0 (#9839)
* chore(main): release 1.744.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>v1.744.0 |
||
|
|
74f579e6d9 |
feat(pipeline): local development for data pipelines (CLI --local + pipeline dev preview) (#9840)
* feat(pipeline): local development for data pipelines (CLI --local + pipeline dev preview) Add the local edit→preview→run loop for data pipelines (folders of `// pipeline` scripts), the analog of `wmill dev` / `wmill app dev`, usable from a code editor or an agentic loop — without deploying. No backend changes: full body inference comes from the same wasm the frontend uses (windmill-parser-wasm-asset), which returns assets + pipeline annotations in one call; local runs reuse runScriptPreview with _wmill_skip_asset_dispatch. - localGraph.ts: wasm-backed working-tree → asset-graph builder (the enabler) - pipeline show/run --local; new pipeline docs (PIPELINE.md/AGENTS.md) subcommand - pipeline dev watcher + /pipeline_dev page (PipelineDevView) rendering the same PipelineGraphEditor from the pushed local graph, run via preview - cascadeRun.ts: reusable run primitives extracted from the route page - regenerated CLI agent docs See docs/pipeline-local-dev.md for the full design, test steps, and handoff TODOs. The live `pipeline dev` browser preview is implemented but not yet stack-verified. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(pipeline): improve local dev preview (run, activity, responsive) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(pipeline): dev-preview args, multi-root run, ws auto-reconnect Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): connect managed-materialize producer in local dev graph The CLI pinned windmill-parser-wasm-asset ^1.728.1, which predates managed-materialize support (added in 1.733.1); the frontend already pins 1.740.0. The CLI's wasm therefore never emitted `// materialize`, so the producer had no output edge and showed disconnected from its `// on` consumers. Bump the CLI to 1.740.0 (matching the frontend) and translate the parsed materialize target into the producer's write edge + materialize_target, mirroring frontend resolveGraph.ts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): harden local-dev CLI (bare-.sql crash, defaultTs, docs clobber) Review fixes, complementary to the dev-preview/materialize/multi-root work already on the branch (none overlap those commits): - localGraph: a bare `.sql` (no dialect) made inferContentTypeFromFilePath throw and abort the whole graph build — and wedge `pipeline dev` at startup. Skip the unclassifiable file instead. Also map `bunnative` → parse_assets_ts and add ruby/rlang/nu/powershell to the `#`-comment fallback. - show/run/docs/dev: thread the resolved `wmill.yaml` defaultTs into the graph builder so `.ts` infers under the workspace's runtime (bun vs deno) instead of always bun — `opts.defaultTs` was always undefined (no such CLI flag). - dev: wrap the startup graph build so a half-written file can't abort the watcher. - docs: don't clobber a user-authored AGENTS.md/CLAUDE.md — only (over)write the pointer when absent or already a generated `@PIPELINE.md` pointer. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): bind dev WS to loopback + local-graph regression tests - pipeline dev WS broadcast the folder's full script source (scripts[].content + temp_script_refs) unauthenticated on 0.0.0.0:3201 — bind 127.0.0.1 so it's not LAN-reachable (webview localhost + SSH/devbox port-forward still work). - Add regression tests for the just-landed local-graph fixes: bare .sql is skipped (was a build/dev-startup crash), defaultTs threads into .ts runtime inference (bun vs deno), and #-comment languages (ruby) use the # annotation fallback. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(pipeline): --frontend flag for pipeline dev page origin wmill pipeline dev opens <remote>/pipeline_dev, but that route only exists in this build's frontend, so it 404s against a remote whose deployed frontend predates it. --frontend <origin> points the page at a locally-run frontend (REMOTE=<remote> npm run dev) while the API/token still target the remote — enabling the live preview against a real backend before the PR is deployed. No behavior change when omitted. Regenerated CLI agent docs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): WS session token + details-pane live-reload refresh Addresses CI review (Codex/Pi/Claude): - dev WS: a browser tab could open ws://localhost:<port>/ws and receive the folder's full source (browsers don't enforce same-origin on WS, loopback bind alone doesn't help). Gate the upgrade on an unguessable per-session token carried in the dev-page URL (verifyClient → 401 without it). Verified: no-token/bad-token connections get 401 with no bundle. - details pane: scriptRes keyed on [workspace, selection, draftScript] didn't re-run on a pipeline dev live-reload (same selection), so the open pane showed stale source. Thread a localScriptsVersion (the pushed bundle) into the key. Verified: editing a selected node's file updates the pane source without reselect. - docs/pipeline-local-dev.md: refresh the stale 'not yet exercised' status + done TODOs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): emit volume: annotation assets in local dev graph Addresses CI review (Codex P1 / Pi P1): the wasm body parser doesn't surface `// volume: <name>` annotations — the frontend (infer.ts:parseVolumeAnnotations) and backend (asset_inference.rs) parse them separately and merge as rw volume assets. localGraph didn't, so a `# volume: cache` producer had no write edge and showed disconnected from its `// on volume://cache` consumer (and pipeline run --local wouldn't schedule downstream). Mirror the leading-comment-block scan (SQL excluded, matching both reference parsers) and merge into inferScriptAssets. Regression test added; verified producer -> volume://cache -> consumer connects. Also (Codex P2): docs/pipeline-local-dev.md manual browser URL omitted the new ws_token param — without it the WS upgrade is rejected and the page sits disconnected. Doc now says to copy the URL the CLI prints (carries wm_token + ws_token) and recommends --frontend. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): runAll excludes event roots + review polish Addresses CI review (Codex P1, Claude P2/P3): - pipeline run runAll: derive the whole-pipeline selection from validStarts + descendants instead of all runnables, so an unqualified 'pipeline run <folder>' no longer fires event-trigger roots (kafka/mqtt/…) with empty args/side effects. Verified: a kafka root is excluded from the plan. - cascadeRun.ts runBoundedCascade: use buildLineageDownstreamMap (read-aware) so a pure-reader runs after its producer, and return cyclic — parity with the route page's bounded run (the file is meant to be THE shared correct primitive). - PipelineGraphEditor: storedRightPaneSize starts at 0 so the orientation-aware default (55% stacked / 40% side-by-side) actually applies on first open. - localGraph fallbackParse (go/bash): scan only the leading comment header (no body-comment phantom triggers) and strip key=value options from the asset URI; regression test added. - docs: reject '..' in the folder arg (it writes files under f/<folder>). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): route local previews to the // tag worker Addresses CI review P1: the local graph/bundle dropped the parsed `// tag`, so a node annotated `// tag gpu` ran on the default worker in both `pipeline run --local` and `/pipeline_dev`, while the deployed pipeline routes it to that worker tag. Carry the tag through LocalScript / the pushed bundle / LocalScriptContent and pass it to runScriptPreview at all three launch sites. Verified: a duckdb node tagged `bash` produces a job tagged `bash`; regression test added. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): add asset partitions/schemas routes to OpenAPI, use generated client The ducklake asset panels (PartitionStatusGrid, SchemaHistoryPanel) hit /assets/partitions and /assets/asset_schemas via raw fetch with cookie-only auth, because those backend routes were never added to openapi.yaml so the generated client had no methods for them. On /pipeline_dev (token-via-URL, no session cookie) the raw fetches 401'd. Add both GET routes + MaterializedPartition/AssetSchemaVersion schemas to openapi.yaml and call them through AssetService, which injects the bearer token, types, and cancellation automatically. Verified: Partitions + Schema tabs load in /pipeline_dev. (backfill stays a raw fetch — it's an EE-only route not in the OSS spec — with the token added inline.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(cli): regenerate bun.lock for windmill-parser-wasm-asset package.json / package-lock.json carry windmill-parser-wasm-asset@1.740.0 but the tracked bun.lock (the CLI installs/builds/tests via bun) was stale, so fresh bun installs would resolve a different graph than the committed lock. Regenerated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): show asset producer + its runs in the dev-preview panel Selecting a ducklake/asset node in /pipeline_dev showed 'No producer for this asset' because selectionProducers wasn't passed (it's derived from the deployed graph on the route page, absent here). Compute it from the local graph's w/rw write-edges (incl. the // materialize target) and pass it through, mirroring the route page — so the panel shows the producing script and its (preview) runs, including data-test failures. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): carry annotation metadata onto local-graph runnables The local graph emitted only path/usage_kind/in_pipeline/materialize_target per runnable, so /pipeline_dev and pipeline show --local weren't the same surface as the deployed graph for annotated scripts — missing the badges/lineage the shared canvas renders. Map the wasm-parsed partition_kind, freshness, tag, retry, data_tests, column_lineage, and materialize_strategy (derived append/merge/replace) onto each runnable, mirroring the deployed AssetGraphRunnableNode. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): exclude event handlers that are lineage descendants from runAll The runAll guarantee ('never fires an event handler with empty args') only held for event ROOTS — validStarts excludes them, but runAll then unions in descendants(dag, start), so a kafka/mqtt/... handler that also reads an upstream pipeline asset (a lineage descendant of a valid start) still landed in the plan. Add eventTriggerScripts() and subtract it from the selection after the descendant union. +unit test. Also: docs/pipeline-local-dev.md recipe used 'pipeline docs demo_pipeline' without --local (default queries the deployed graph → hits the empty hint); add --local. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): whole-pipeline run cuts at event handlers (drop their downstream too) The prior runAll fix subtracted event handlers from the selection but left their downstream: for manual_root → asset_x → kafka_handler → asset_y → consumer, deleting only kafka_handler left consumer selected, and topoOrder then ran it as a root with missing/stale event-derived inputs. Replace the descendant-union+delete with reachableCutting(dag, validStarts, eventHandlers): traverse from valid starts but treat event handlers as cut points, so a node reachable ONLY through an event handler is dropped while one reachable via a non-event path stays. +unit test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): recover // tag in the go/bash annotation fallback The wasm path carries out.tag, but the go/bash fallback (and the wasm-error degradation path) only recovered pipeline + on, so a // tag gpu on a bash/go node — or a temporarily-unparseable ts/py/sql node — silently routed the local preview to the default worker while the deployed pipeline routes to the tag. Scan for // tag in fallbackParse too. +test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(pipeline): extract shared assetProducers helper The 'who writes this asset' write-edge derivation was copied verbatim in PipelineDevView and the pipeline route page — two copies that would drift. Extract assetProducers(graph, selection) into graphTraversal.ts and use it from both, keeping the dev view and route page in lockstep. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): only overwrite AGENTS.md/CLAUDE.md when it's the exact generated pointer Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): wire local-dev runs into the selected-node runs pane Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): exclude data_upload/webhook entrypoints from auto CLI runs Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(pipeline): --upload binds an object to a data_upload/webhook entry point Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(pipeline): add "Run + downstream" to the dev preview detail form Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): cut non-autorun triggers on all run paths; multi-binding --upload Address CI review: apply the data_upload/webhook/event barrier cut to the single-root and bounded (--from/--to) paths, not just whole-pipeline; accumulate repeatable --upload bindings per script (were overwritten); scope dev upload keys by script+param to avoid basename clobbering; drop <script> from help text. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): reseed dev run form when a local edit changes the script's args The read-only pane is keyed on script.path only, so in /pipeline_dev the selected node re-resolves on every WS bundle without remounting; PipelineScriptView cloned script.schema once, so adding/removing args left the run form on a stale schema (could run with missing inputs). Extract PipelineRunForm (owns the SchemaForm clone) and key it on the serialized schema: a real arg change reseeds the form, an unchanged re-resolve keeps in-progress input. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): don't cut a scheduled/manual root that also has a non-autorun trigger Address Codex P1: the barrier set subtracted only --upload-bound scripts, so a script with both `// on schedule` and `// on data_upload` resolved as the start yet was also a barrier — reachableCutting skipped it, giving an empty run plan. Subtract all valid starts (schedule/manual roots + bound handlers) from barriers: a legitimately-scheduled root runs on its schedule path even if it also carries a caller-input trigger; pure input-only roots stay cut. Adds a regression test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): deployed non-autorun enrichment, s3:// storage, --to cut accounting, tag regex Address CI review (Codex P1/P1/P2, Pi P2): - Deployed `pipeline run` recovers marker-only data_upload/webhook/email triggers from script bodies (like the `show` path) so input-only entrypoints are cut instead of auto-run empty on the deployed graph. - `--upload s3://<storage>/<key>` keeps the named storage (authority) instead of folding it into the key, matching the S3Object round-trip convention. - Bounded `--to` targets cut by a barrier are reported in droppedEnds (+warning), not reachableEnds. - fallbackParse `// tag` matches a single token (\S+), rejecting multi-word prose. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): header-only deployed marker scan, fail-closed enrichment, default-storage s3 keys Address CI review (Codex P2, cubic P1/P1/P2): - Deployed marker recovery scans the LEADING comment header only (shared recoverHeaderMarkers helper, reused by the show enrichment too) so a body comment `// on data_upload` can't inject a phantom trigger and over-cut. - Deployed run enrichment fails CLOSED: a script-body fetch error aborts the run instead of silently letting an input-only entrypoint run with empty args. - Revert `--upload s3://` to default-storage whole-path keys (matching pipeline `s3://` asset-URI semantics); named-storage authority-splitting broke nested default keys like `s3://raw/2026/events.csv`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): reject trailing content on fallback native markers; trim s3:/// key Address CI review (Codex P2, cubic P3): - fallbackParse now requires a native marker (`// on data_upload`) to stand alone; a line with trailing content (`// on data_upload f/foo`, `# on kafka topic`) is rejected, matching the canonical parser and keeping local/deployed parity. - s3UriKey trims a leading slash so the canonical empty-authority default form `s3:///key` doesn't leak a leading slash into the object key. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): persist dev WS token per-port so reconnect survives a CLI restart Address Codex P2: the /pipeline_dev auto-reconnect reuses the ws_token from the page URL, but `pipeline dev` minted a fresh random token each start, so a restart on the same port left the open page rejected by verifyClient forever. Persist the token per-port under the user-private config dir (0600) and reuse it on restart, so an already-open page reconnects — matching the reconnect behavior's intent. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): scope persisted dev WS token by workspace+folder+port Address cubic P2: keying the persisted token by port alone let a stale browser tab from a previous folder's session on the same port reconnect and receive a different folder's source. Scope the token file by workspace+folder+port so a same-session restart still reconnects, but a different folder on the same port gets a distinct token that rejects stale cross-folder tabs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): caller args can't override skip-dispatch guard; hash the dev token key Address CI review (Codex P1, cubic P2): - makeLaunch / CLI run build args with `_wmill_skip_asset_dispatch` LAST (and drop any caller-supplied copy) so a run-form/`--upload` arg can't re-enable backend asset dispatch while the client orchestrates the cascade (double-run / running deployed subscribers from a local preview). Adds a cascadeRun guard test. - Dev WS token file key is a sha256 of NUL-delimited workspace+folder+port, so different folders (`a/b` vs `a_b`) can't collide onto the same token file. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipeline): canonical s3://storage/key --upload parsing; scope dev token by remote+root Address Codex P1/P1: - Restore canonical S3Object URI parsing for `--upload` s3 sources, matching the frontend's `parseS3Object` (`s3://<storage>/<key>`, empty authority ⇒ default, `s3:///key`/`s3:///nested/key` for the default store). `s3://secondary/k.csv` → `{ s3: "k.csv", storage: "secondary" }` so a named-storage object is read from the right store. (This is the canonical convention; the default-storage nested key is served by the `s3:///` form.) - Scope the persisted dev WS token by remote+workspace+root+folder+port (was workspace+folder+port), so two profiles on different remotes (or local checkouts) with the same workspace/folder/port don't share a token — a stale tab can't reconnect across a workspace/remote boundary. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
1c46f899ca |
fix(mcp): stop double-escaping string query params in build_query_string (#9855)
MCP tool arguments were converted to URL query values via `value.to_string()`
+ `trim_matches('"')`. For string values containing JSON (e.g. the `args`/`result`
filters on job listing, `args` on schedule listing), `to_string()` JSON-encodes the
string and escapes inner quotes with backslashes; stripping the outer quotes leaves
`{\"k\":\"v\"}`, which the backend's `serde_json::from_str` then fails to parse,
falling back to `FALSE` and returning zero results.
Use `value.as_str()` to emit the raw string content for `Value::String`, falling
back to `value.to_string()` for non-string types (numbers, booleans). Adds
regression tests covering JSON-string, non-string, and plain-string params.
Fixes WIN-2114
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|
|
b52972d0de |
fix: validate workspace name length (max 50 chars) on create and fork (#9854)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
293647de4c |
fix: grant workspace_diff, materialized_partition, debounce_stale_data to windmill roles (#9853)
Same grant gap already fixed for notify_event (20260619091631), script_trigger (20260619112847), and dispatch_event: tables created after the one-time GRANT ALL in 20250205131523 rely on ALTER DEFAULT PRIVILEGES, which only covers objects created by the role that set them. On deployments whose migration runner is a different role, these tables end up ungranted, and writes that run under the RLS role (a transaction opened via user_db.begin(&authed) -> SET LOCAL ROLE windmill_user/windmill_admin) fail with "permission denied for table <name>". Audited every table created after 20250205131523: these three are the only ones with a confirmed write on a user_db transaction that lacked a grant: - workspace_diff: UPDATE in set_ws_specific (workspaces.rs) - materialized_partition: INSERT via record_materialization (assets API); sibling materialized_asset_schema was already granted - debounce_stale_data: DELETE in resume_suspended_trigger_jobs (global_handler.rs) GRANT is idempotent so re-application is a no-op. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
5a661279a3 |
feat(pipelines): add managed SCD2 history materialize strategy (#9850)
* feat(pipelines): add managed SCD2 history materialize strategy `// materialize ducklake://... key=<col> history [track=...]` (alias: `scd2`) upgrades the keyed merge to SCD type 2: diff the current snapshot against live rows, close changed versions (valid_to/is_current) and open new ones in one transaction, keeping full history. Adds a consumer-convenience <dim>_current view; effective-dated joins via native ASOF JOIN >= valid_from. Managed, so // data_test and schema capture work (unlike manual mode). Non-partitioned v1, soft-delete on absence. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(pipelines): document scd2 track= spacing, reserved _current suffix, schema-freeze Addresses non-blocking CI-review nits on the new SCD2 public surface. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipelines): null-safe scd2 key matching + create _current view inside txn Addresses CI review: (1) Codex P1 — NULL natural keys were flagged as changed but silently dropped because `key IN (...)` never matches NULL; close/open now match with `IS NOT DISTINCT FROM` via correlated EXISTS. (2) cubic P2 — the `<dim>_current` view was created after COMMIT and CREATE VIEW advances the DuckLake snapshot, so the summary recorded the view's snapshot instead of the data write; the view is now created inside the write transaction. Validated both against a real DuckLake (NULL key materialized; one snapshot per run). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipelines): create scd2 _current view with IF NOT EXISTS to keep no-change runs no-op Addresses CI review (Codex P2): CREATE OR REPLACE VIEW advances the DuckLake snapshot every run, so an unchanged rerun still minted/recorded a snapshot. The view definition is static, so IF NOT EXISTS creates it once (folded into the first data-write snapshot) and is a true no-op thereafter — verified an unchanged rerun keeps max(snapshot_id) constant. Also softens the reserved-name collision: IF NOT EXISTS skips silently instead of erroring. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(pipelines): add scd2 deletes=close (hard-delete-close) Opt-in `deletes=close` closes the current version of a key that disappears from the snapshot (dbt's hard_deletes=close); default stays soft-delete. Codegen adds a vanished-key temp set (current keys EXCEPT snapshot keys) + a second null-safe close UPDATE with no reopen; a reappearing key opens a fresh version (validity gap = correct SCD2). Wired through both parsers with parity fixtures/tests, worker derivation, unit + codegen tests, and docs. Verified end-to-end against a real DuckLake incl. delete-close + reactivation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipelines): align materialize deploy precedence warning with runtime (scd2>append>merge) The deploy-time conflict warning only knew append>key, so warned 'append wins' while the runtime (duckdb_executor) runs SCD2 (history wins). Warn for history+append (history wins, append ignored) before the append+key case, mirroring the runtime strategy precedence. (Pi review P2.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipelines): register scd2 _current view as a produced asset for cascade dispatch The docs present the companion <dim>_current view as a subscribable produced asset (// on ducklake://.../<dim>_current), but deploy registered only the base table as a write asset, so a subscriber on the view would never be dispatched (the cascade fans out from deploy-time asset rows). Register <dim>_current as a produced write asset when scd2 so those subscribers fire. (Codex review P1.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(pipelines): don't register _current asset for manual+history (no view created) Manual mode short-circuits before the scd2 codegen, so no <dim>_current view is created; gate the produced-asset registration on !manual so a contradictory // materialize manual ... history doesn't leave a false write edge dispatching subscribers on a nonexistent view. (Codex review P2.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
f05b50d29a |
fix: grant dispatch_event table to windmill roles (#9852)
The dispatch_event table (migration 20260523055641) was created relying on ALTER DEFAULT PRIVILEGES to reach windmill_user/windmill_admin. Those default privileges only apply to objects created by the role that set them (20250205131523), so deployments whose migration runner is a different role leave dispatch_event ungranted. Direct writes then run as the invoking role and fail with "permission denied for table dispatch_event" -- notably the DELETE in delete_jobs (windmill-common/src/jobs.rs) that reaps a job's side rows on schedule disable, and the dispatcher insert in asset_dispatch.rs. Grant explicitly, same fix as notify_event (20260619091631) and script_trigger (20260619112847). GRANT is idempotent so re-application (squash, or an operator who already granted manually) is a no-op. Fixes WIN-2112 Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
68bf0daf58 |
feat(ansible): support repo-provided ansible.cfg in delegate_to_git_repo (#9851)
* feat(ansible): support repo-provided ansible.cfg in delegate_to_git_repo Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(ansible): accept colon delimiter and collections_paths alias in cfg parser Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |