mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-21 08:02:26 +00:00
workflow-execution-time-display
2028 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
66c0334e70 |
chore(main): release 1.721.0 (#9480)
* chore(main): release 1.721.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
a3740d571a |
chore(main): release 1.720.0 (#9464)
* chore(main): release 1.720.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
e8e0701a36 |
feat(api): add endpoint to update token label (#9474)
* feat(api): add endpoint to update token label Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(api): prevent renaming the session token label Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(api): restrict token-label edits to user tokens, not just session Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): edit token label in the edit modal instead of inline Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(api): reject relabeling tokens to reserved system-token names Centralize the is_user_token classifier in windmill-common and reuse it to reject labels colliding with system-token namespaces (ephemeral*, debugger-token, mcp-oauth-*), not just session. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(api): match ephemeral label case-insensitively and cap label length Align the canonical is_user_token, the SQL guard and the frontend mirror on a case-insensitive `ephemeral` match (so a token can't be relabeled to a casing the backend allows but the UI hides), reject labels over the VARCHAR(1000) column limit with a 400, and add unit tests for is_user_token. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
004339032e |
chore(main): release 1.719.0 (#9459)
* chore(main): release 1.719.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
3887bf67dc |
chore(main): release 1.718.0 (#9450)
* chore(main): release 1.718.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
90677872f6 |
fix: distinguish canceled jobs in runs (#9452)
* fix: distinguish canceled jobs in runs
* fix: order status=failure|canceled by completed_at to use partial index
The new `status` query param replaced the legacy `success=false` filter on
the Runs page, but the ORDER BY switch in list_completed_jobs_query only
flipped to v2_job_completed.completed_at for success==Some(false). With
status=failure|canceled (and success=None), the query fell back to ordering
by v2_job.created_at, which the partial index
ix_v2_job_completed_failure_workspace (workspace_id, completed_at DESC WHERE
status IN ('failure','canceled')) cannot serve.
EXPLAIN ANALYZE on 500k rows (1% failure/canceled): ordering by completed_at
uses the partial index (~150 buffers, 0.3ms); ordering by created_at scans
the v2_job created_at index and probes/discards 99% of rows via the join
(~49k buffers, 31ms). Switch the ordering to completed_at for
failure/canceled so the partial index serves both filtering and ordering.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test: trim order-by regression test to the failure/canceled case
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix: only treat canceled as a terminal status icon for completed jobs
Guard the canceled branch in JobStatusIcon and getJobStatusKind with
`'success' in job` so a job that is still running while being canceled keeps
its running icon/favicon until it completes, instead of immediately showing
the gray Canceled state. Also clarify the openapi `status` param is an exact
match (status=success excludes skipped, unlike success=true).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|
|
24fa61d3c0 |
chore(main): release 1.717.1 (#9444)
* chore(main): release 1.717.1 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
6b6c16e6bc |
chore(main): release 1.717.0 (#9439)
* chore(main): release 1.717.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
d537c82c4f |
chore(main): release 1.716.0 (#9430)
* chore(main): release 1.716.0 * Apply automatic changes * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
cf5fefb521 | feat: add metadata generation model setting (#9418) | ||
|
|
47c96204de |
chore(main): release 1.715.0 (#9421)
* chore(main): release 1.715.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
89a7a37776 |
fix(backend): authorize single-job read endpoints by job/flow visibility (#9416)
* fix(backend): authorize single-job read endpoints by job/flow visibility Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(jobs): share read links + cached access checks for run visibility - Cache the job read-access RLS probe (size-bounded LRU keyed by the caller's authz-relevant identity + job id; no TTL since job-side inputs are immutable). - Inherit visibility along the full parent_job chain so any flow you can see lets you read its (deeply nested) steps. - Share read links: GET /jobs/job_view_token/{id} mints a stateless HMAC(workspace_key, job_id) token (only if the caller can read the job); the token grants an authenticated member read of that job and its flow subtree via a ?view_token query param or X-View-Token header. Run page gains a Share button and honors a ?view_token link. - Denied-but-existing reads now return 403 with guidance to request a share link (vs 404 for non-existent), and the run page renders that case with instructions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(jobs): address PR review — scope-tag check on mint, constant-time view-token verify - P1 (Codex): get_job_view_token now enforces the caller's if_jobs:filter_tags scope before minting, so a tag-scoped token can't mint a transferable link for a job outside its tags. Adds a scoped-token regression test (allowed + denied). - Constant-time view-token verification (HmacSha256::verify_slice) instead of comparing hex strings (Claude/Pi nit). - get_completed_job_result: an authed reader passing an invalid suspended-secret triple now falls through to the normal visibility gate instead of erroring out (Claude nit); unauthenticated callers still rejected. - Length-prefix the read-access cache key fields so no input values can collide. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(api): add job_view_token to openapi spec; use generated client in run page Addresses Codex review nit: the new GET /jobs/job_view_token/{id} endpoint was missing from openapi.yaml (the source the frontend client is generated from). Adds the path + operationId getJobViewToken, and switches the run page's Share button from a raw fetch to JobService.getJobViewToken. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): carry view_token on share-link downloads Addresses Codex review: download actions bypass the request interceptor that adds X-View-Token (downloadViaClient uses raw fetch; cookie-mode downloads use plain hrefs), so a share-link viewer got 403 downloading logs/results/args. Append the view_token query param to the job download paths (result/logs/args/flow-all-logs) via a new appendViewToken() helper, covering both client-fetch and href modes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(jobs): enforce tag scope in require_job_read_access (view-token use side) Addresses Codex P1: the view_token use-side bypassed if_jobs:filter_tags on handlers that don't tag-filter their data query (result_by_id, get_flow_job_debug_info, get_otel_traces) — a tag-scoped token could use someone else's valid share token to read out-of-scope job data. Move the tag-scope check into require_job_read_access (runs before any created_by/view_token/RLS grant), so it applies uniformly to every gated handler; removes the now-redundant explicit check in get_job_view_token. Adds a use-side regression test (scoped token + valid out-of-scope view_token denied on otel/result_by_id; in-scope still allowed). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): include workspace in share read link Addresses Codex P1: the copied share URL omitted the workspace. The token is signed with the run's workspace key and the logged layout only switches $workspaceStore when the URL carries workspace=, so a recipient whose persisted active workspace differs would open the link against the wrong workspace and the token would fail validation. Pin workspace= alongside view_token in the link. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(jobs): authorize get_result_maybe get_started branch for queued jobs Addresses Codex P1: get_completed_job_result_maybe only gated when a completed row existed; with ?get_started=true a non-reader reached the fallback branch and got started:true for a running private job. Now fetches created_by and authorizes (created_by/view_token/RLS, or anonymous for unauth) before disclosing running-state; a non-existent job still returns started:false (leaks nothing). Adds a regression test with a queued (no completed row) private job. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
00cd89fff3 |
chore(main): release 1.714.1 (#9408)
* chore(main): release 1.714.1 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
2ac198396e |
chore(main): release 1.714.0 (#9390)
* chore(main): release 1.714.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
32b4771f19 |
chore(main): release 1.713.1 (#9389)
* chore(main): release 1.713.1 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
b16828d480 |
chore(main): release 1.713.0 (#9369)
* chore(main): release 1.713.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
b0c3b01d31 |
fix(cli): preserve user drafts on sync push and permissioned-as (#9381)
CLI deploys (sync push, set-permissioned-as) went through the same create/update endpoints as a UI "deploy from draft", which delete the draft at that path. That silently wiped teammates' in-progress drafts on every push. Add a transient skip_draft_deletion deploy flag (mirroring deployment_message) that the CLI sets; the backend then skips the DELETE FROM draft for scripts, flows, and apps. UI deploys are unchanged. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
889101b7f0 |
chore(main): release 1.712.0 (#9340)
* chore(main): release 1.712.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
a9e5140995 |
feat: warn when custom instance db is shared across workspaces (#9359)
* feat: warn when custom instance db is shared across workspaces * Fix leaking workspace names * sqlx prepare |
||
|
|
8d72a7a4a4 |
chore(main): release 1.711.0 (#9337)
* chore(main): release 1.711.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
edea1b3631 |
chore(main): release 1.710.1 (#9327)
* chore(main): release 1.710.1 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
80f6a5a6e8 |
chore(main): release 1.710.0 (#9323)
* chore(main): release 1.710.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
f9c7fa2e43 |
chore(main): release 1.709.0 (#9312)
* chore(main): release 1.709.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
b125eca762 |
feat(service-accounts): allow choosing role at creation time (#9307)
* [ee] feat(service-accounts): allow choosing role at creation time Previously, service accounts were hardcoded to operator and could not be used as the CLI sync user since they had no write access. They also only counted as 0.5 seat each. This change: - Extends `NewServiceAccount` to accept optional `is_admin` / `operator` (defaults to `operator=true` for backward compatibility). - Exposes a role picker in `AddUser.svelte` when creating a service account (Operator / Developer / Admin). - Lets admins update a service account's role from the user list (it used to be locked to "Operator" with a tooltip). - Updates the OpenAPI spec + regenerates the frontend client. A developer/admin service account counts as 1 seat under the existing seat-cap logic (operators stay at 0.5). Companion PR on windmill-ee-private updates the `INSERT INTO usr` to honour the chosen role. Fixes WIN-1985 * [ee] feat(service-accounts): wm_deployers opt-in for Dev role When creating a service account with role=Developer, surface a toggle "Add to wm_deployers" (recommended). Members of wm_deployers can deploy on behalf of other users — the typical setup when the service account is used as the CLI sync / CI deploy identity. - `NewServiceAccount` gains an optional `add_to_deployers` flag. - Frontend defaults the toggle to on but only shows it under Developer (admins have it implicitly; operators can't deploy). - Tooltip links to docs.windmill.dev "Run on behalf of". Companion EE PR updates the handler to INSERT into usr_to_group for wm_deployers when the flag is set. Refs WIN-1985 * chore: update ee-repo-ref to 974ed42067d9f63acb42332b671b8c01ffd4b625 This commit updates the EE repository reference after PR #589 was merged in windmill-ee-private. Previous ee-repo-ref: f7dbc3cc2ba21c396f4828881e3b9d9ab6f50c69 New ee-repo-ref: 974ed42067d9f63acb42332b671b8c01ffd4b625 Automated by sync-ee-ref workflow. * [ee] fix(service-accounts): unhardcode role in superadmin user list Two review issues from the merged #9307 / #589: 1. P1 — The global Users tab in #superadmin-settings still pinned every service account to "Operator". Now it shows the actual role (Admin / Operator / Developer), derived from the SA's usr row. - `list_users_as_super_admin`: replaced `true as operator_only` with the real `operator` value, and added `is_workspace_admin` from the row (NULL for password users since their admin status is per-workspace). - `global_whoami`: when the email belongs to a service account, look up its real `operator` / `is_admin` instead of pinning to operator. - `SuperadminSettingsInner.svelte`: drop the hardcoded "Operator" badge; render Admin / Operator / Developer using the new fields, matching the workspace-level view. 2. P2 — Regenerate the bundled `openapi-deref.{yaml,json}` so the `createServiceAccount` body (now exposing `is_admin`, `operator`, `add_to_deployers`) and the new `GlobalUserInfo.is_workspace_admin` field show up at runtime in `/api/openapi.{yaml,json}`. Bumps `ee-repo-ref.txt` to the EE follow-up that adds the offline seat-cap check on `create_service_account`. Refs WIN-1985 * chore: update ee-repo-ref to b7a6068c1f3dc845e012959268b2426f0de4d697 This commit updates the EE repository reference after PR #590 was merged in windmill-ee-private. Previous ee-repo-ref: 0b1307c21d1bfd6fb43a03c2ba39d2a8bf8e6470 New ee-repo-ref: b7a6068c1f3dc845e012959268b2426f0de4d697 Automated by sync-ee-ref workflow. --------- Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com> |
||
|
|
577a730e90 |
audit-log workspace-fairness cap transitions (#9306)
* feat(queue): audit-log workspace-fairness cap transitions When the cloud per-workspace fairness mechanism adds a workspace to the capped set or releases one, write `workspace_fairness.capped` / `workspace_fairness.uncapped` audit-log entries to the affected workspace. The cluster admin can review the full timeline from the `admins` workspace audit view with `all_workspaces=true`; per-workspace owners see their own events in their normal audit list. Only the per-cycle refresh winner emits entries (matching where the heavy aggregation runs), so a fleet of N workers does not produce N duplicates per transition. The diff is computed against the value already in `background_task_state` rather than the winner's in-memory cache, so a freshly-restarted process winning the claim does not spuriously emit "newly capped" entries for workspaces that were already capped before it started. Audit writes are best-effort: failures are logged via tracing and do not abort the refresh cycle. Fixes WIN-1984 * feat(queue): scope fairness audit to admins workspace + queue-metrics pane - Write `workspace_fairness.capped` / `workspace_fairness.uncapped` to the `admins` workspace (was: per-affected-workspace) with the affected workspace_id moved to the `resource` field. Cluster admins now get the full timeline in one place without `all_workspaces=true`. - Add `GET /workers/workspace_fairness_events` returning the last 100 events. Cloud-gated (returns `[]` on non-cloud) and devops-only. - Add a `WorkspaceFairnessEvents` Section to the Queue Metrics drawer, rendered only when `isCloudHosted()` is true. Shows time / event badge / workspace / parameters with a refresh button. Fixes WIN-1984 |
||
|
|
ff685eb2d3 |
chore(main): release 1.708.0 (#9304)
* chore(main): release 1.708.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
7b11ebe5f5 |
chore(main): release 1.707.0 (#9285)
* chore(main): release 1.707.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
dcee8cc0d3 |
feat(github-app): hide cloud-only UI on self-managed + admin assignment UI (#9299)
* feat(github-app): hide cloud-only UI on self-managed + admin assignment UI
Two related UX fixes for the GitHub App self-managed (GHES) integration:
1. On self-managed instances, the per-installation Export button and the
"Import installation from other instance" section in the workspace UI both
hide. Both round-trip a JWT carrying only {installation_id, account_id} with
no github_base_url, so they would produce broken cloud-style installs on a
self-managed instance. The previous Export attempt also failed with
"No JWT token received from server" because self-managed installs store an
empty JWT by design.
2. New "Workspace assignments" panel in instance settings (GhesAppSettings.svelte)
that auto-discovers installations of the configured GHES App and lets the
super-admin assign them to specific workspaces. Workspace users without
GitHub permissions no longer need to install the App themselves — the admin
provisions the link from instance settings. Admin-provisioned installs show a
"Provisioned by admin" badge in the workspace UI and can only be removed by
the super-admin from instance settings.
Backend support is in the EE companion PR
windmill-labs/windmill-ee-private#588.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: update ee-repo-ref to da5189cf69a453de3855057f41be0d84e5910707
This commit updates the EE repository reference after PR #588 was merged in windmill-ee-private.
Previous ee-repo-ref: d959b83ce413ad531e9cc28e0f8199cdecb73a31
New ee-repo-ref: da5189cf69a453de3855057f41be0d84e5910707
Automated by sync-ee-ref workflow.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
|
||
|
|
9b218dc405 |
chore(main): release 1.706.1 (#9281)
* chore(main): release 1.706.1 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
e6f80dad1c |
chore(main): release 1.706.0 (#9270)
* chore(main): release 1.706.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
9cb34397eb |
chore(main): release 1.705.0 (#9229)
* chore(main): release 1.705.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
0f7dd86e5c |
feat: persistent in-editor drafts via UserDraft (#9121)
* refactor(frontend): remove localStorage-backed autosave drafts
Strip the per-editor localStorage autosave for flows, apps and raw apps,
along with the associated restore toasts and diff actions, so we can
replace them with a unified UserDraft service in a follow-up. The
backend DraftService (DB-backed drafts) is untouched.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(frontend): add UserDraft service for per-workspace local drafts
Introduces UserDraft, a key-value store keyed by
`{workspace}/{itemKind}/{path}` and backed by localStorage. Supports
save/get/remove plus a reactive use() handle so multiple component
instances observing the same draft stay in sync via a shared $state
loaded through useLocalStorageValue. Designed to host drafts for
scripts, flows, apps, raw apps, resources, variables, and all trigger
kinds.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* tests
* nit schedule_ prefix
* feat(frontend): persist deep mutations in useLocalStorageValue
Track the serialized value alongside the $state and add an $effect that
deep-reads it (via readFieldsRecursively). When a deep mutation produces
a serialization that differs from the last persisted blob, write it to
localStorage. The setter keeps writing synchronously so callers reading
localStorage right after assignment still see the new value; the effect
no-ops on those because lastSerialized was already updated by the setter.
Undefined values are persisted as a removal.
UserDraft no longer needs its own removeItem workarounds for undefined
values — useLocalStorageValue handles that uniformly now.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(frontend): add defaultValue + empty-path handling to UserDraft
UserDraft.use() accepts an opts.defaultValue used when no localStorage
entry exists yet. It is not persisted on first read — only an actual
mutation writes through.
Empty paths (new items) bypass localStorage entirely. The entry still
lives in the in-memory Map so multiple components on the same /add page
share state, but save/get/remove/use never read or write localStorage
with an empty path. Once the item is saved and the route navigates to
its new URL, a fresh use() on the non-empty path takes over.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(frontend): wire script editor to UserDraft
The script editor's top-level state now lives in UserDraft.use(), keyed
on the route's path (page.params.path on /scripts/edit, '' on /scripts/add).
Deep edits inside ScriptBuilder persist automatically; deploy and draft
restore now call UserDraft.remove to clear the local autosave alongside
the backend draft.
Replaces the URL-hash autosave that ScriptBuilder used to write via
replaceStateFn — that prop is now gone, the encodeScriptState debounce
is gone, and Triggers no longer takes a saveSessionDraft callback.
Viewing a specific historical hash (?hash=...) is kept draft-free by
passing '' as the path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(frontend): wire flow editor to UserDraft
flows/add and flows/edit drive the flow value through a StateStore
adapter backed by UserDraft.use, so every edit auto-persists at
userdraft/w/{ws}/flow/{path} without touching FlowBuilder's internal
.val convention. On returning visits the local autosave wins and a
toast offers a diff against the latest backend draft/deployed version;
on a fresh visit the backend value is written into the handle. Deploy,
save-as-draft rename, restore-draft and restore-deployed each call
UserDraft.remove on the route path so the local autosave doesn't
outlive the action.
Adds UserDraft.has() for "is there already a local draft?" detection
in the load path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(frontend): wire app editor to UserDraft
AppEditor registers a UserDraft.use<App> handle for its current path
(empty path for /apps/add stays in-memory) and a single $effect
deep-tracks the internal stateApp and forwards every mutation to the
handle. useLocalStorageValue's lastSerialized check then dedupes the
actual localStorage writes per tick, so even fast drag/resize loops
only persist when the JSON output really changes.
/apps/edit overlays a local autosave from UserDraft.get on top of the
backend value when one exists, with the existing "Discard / Show diff"
toast wired to UserDraft.remove. Deploy, save-as-draft, restore-draft
and restore-deployed all call UserDraft.remove on the relevant path,
including the JSON editor save paths.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(frontend): wire raw app editor to UserDraft
/apps_raw/edit owns the canonical raw-app state (files, runnables,
data, summary) in four $state vars; a single $effect deep-tracks them
and forwards the bundle to a UserDraft.use<RawAppDraft> handle so each
mutation tick persists at userdraft/w/{ws}/raw_app/{path} (deduped by
useLocalStorageValue's serialized check). On load the route overlays
the local autosave on top of backend.draft/deployed and offers a
"Discard / Show diff" toast when they diverge; matching local entries
are silently dropped. Deploy, save-as-draft rename, restore-draft and
restore-deployed each call UserDraft.remove on the route path.
/apps_raw/add keeps the same shape (UserDraft.use with empty path)
so the draft is in-memory only and we drop it explicitly when the
initial save creates the real path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(frontend): wire resource editor to UserDraft
ResourceEditor registers a UserDraft.use<ResourceState> handle keyed
on the initialPath (empty for new resources, in-memory only). A
$effect deep-tracks the current workspace's edit state and forwards
mutations to the handle; on bootstrap and lazy backend-fetch the
local autosave wins over the backend value when they diverge. After
a successful save() we call UserDraft.remove so the local autosave
doesn't outlive the deploy. Cross-workspace deploys always start from
the live backend value rather than the local draft.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(frontend): wire variable editor to UserDraft
VariableEditor persists the current workspace's edit state via
UserDraft.save on every mutation, keyed on editPath ('' for new
variables → in-memory only). Backend fetches now overlay a matching
local autosave when one exists, and initNew() rehydrates from the
in-memory empty-path entry so opening a fresh "Add variable" drawer
keeps any unsaved work from the previous open. After a successful
save we drop the corresponding entry.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* editor external changes sync
* fix(frontend): don't UserDraft.remove flows while route is still mounted
The /flows/add and /flows/edit routes drive FlowBuilder from a flowStore
whose getter reads flowHandle.draft directly. Calling UserDraft.remove
synchronously before goto() therefore wiped the in-memory entry, made
flowStore.val collapse to emptyFlow(), and tripped
UnsavedConfirmationModal against the just-saved value — even though the
deploy/save-draft itself succeeded.
Drop those explicit removes in onSaveInitial, /add onDeploy, and
/edit onDeploy. The empty-path entry self-cleans on unmount via
onDestroy ref counting; for the non-empty edit path the next visit's
load-time diff will silently overwrite localStorage when the local
autosave matches the deployed value. Restore-draft/restore-deployed
keep their explicit remove because they navigate to the same route
(no modal) and loadFlow immediately rehydrates the handle.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Revert "fix(frontend): don't UserDraft.remove flows while route is still mounted"
This reverts commit
|
||
|
|
9c28bbfd69 |
feat(frontend): new path component (#9017)
* stash
* ui nits
* Fix contenteditable feedback look (duplicate typing)
* fix right icon wrong position with placeholder
* user editor in Path editor takes correct width
* nits
* nit
* chore: remove assets-operator changes (moved to separate PR)
These files were mistakenly included in this PR and belong in a dedicated PR
("Allow assets page to operators").
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: remove sidebar assets-operator change (moved to separate PR)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix disabled
* border nit
* Fix disabled styling
* Apply suggestion from @cubic-dev-ai[bot]
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
* nit
* Update frontend/src/lib/components/text_input/TextInput.svelte
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
* Fix disabled tabindex and aria-disabled on contenteditable Select
The useContentEditable branch had an unconditional tabindex="0", keeping
a disabled Select in the tab order, and was missing aria-disabled.
Mirror the TextInput div branch.
Co-authored-by: Diego Imbert <diegoimbert@users.noreply.github.com>
* fix: drop obsolete hideFullPath prop from EditorHeader Path usage
* invalidate autocomplete paths on deploy
* nit pixel
* use Badge in auto complete
* nit prevent default
* fix(autocomplete): don't let stale fetch clobber forced refresh
A non-forced fetchWorkspacePaths() that started before invalidateWorkspacePaths()
could still resolve afterward, overwrite the cache, and clear forceNextFetch —
making the post-deploy refresh a no-op. Only write back from the promise that
is still the current pending one, and only clear the force flag when the
completing fetch was itself forced.
* refactor(path): drop unreachable 'group' branch in owner-kind setter
The Select only offers user/folder, so the 'group' branch was dead. Leave a
short note pointing at validateName which still accepts 'group' for
forward-compat.
* fix(path): respect disableEditing on owner-kind selector
Other path-editor controls disable on (disabled || disableEditing); the
owner-kind Select only checked `disabled`, so read-only users (trigger
editors with !can_write) could still toggle User/Folder and mutate the
bound path. Reuse the existing nameDisabled flag.
* Revert "fix(autocomplete): don't let stale fetch clobber forced refresh"
This reverts commit
|
||
|
|
2a780ad87a |
feat: resolve relative imports from local content in script/flow preview (#9233)
* feat: thread temp_script_refs into preview jobs Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: resolve python preview relative imports from temp script refs Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: use local relative imports in wmill script preview Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: use local relative imports in wmill flow preview Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: add temp_script_refs to Preview and FlowPreview openapi schemas Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: pass temp_script_refs to bun lockfile gen for no-lock preview Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor: route script preview through shared buildPreviewTempScriptRefs Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: resolve local relative imports in wmill app dev inline scripts Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: address cubic review — bundle cache key, preview-mode gate, error masking Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * perf: skip dep-tree build when previewed script has no relative imports; narrow old-backend classifier Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: address review issues (preview-only gate, bundle preview, app dev cwd) Three P1s flagged in repeated codex/pi reviews on PR #9233: - Gate _TEMP_SCRIPT_REFS extraction on JobKind::Preview (bun + python executors) and propagation in worker_flow on JobKind::FlowPreview. job.args includes caller-controlled request args, so honoring this key on deployed runs would let a caller swap import resolution to local content uploaded via /raw_temp. - run_bundle_preview_script now injects temp_script_refs into PushArgs.extra, mirroring run_preview_script — closes the silent data drop for the bundle preview path. - wmill app dev chdirs to the wmill.yaml root before buildPreviewTempScriptRefs and restores after, so the `cd <app>__raw_app && wmill app dev` invocation (cwd is the raw_app folder, no app_folder arg) still walks sibling workspace scripts like f/lib.ts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(ee): bump ee-repo-ref to 5b347d6 (handle_python_deps arity fix) Picks up the EE arity fix so cargo_test + check_ee_full compile cleanly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(ee): bump ee-repo-ref to 52e273d (agent-workers bundle path arity fix) Picks up windmill-ee-private 52e273d which adds the missing &None arg to compute_bundle_local_and_remote_path in windmill-api-agent-workers/src/ee.rs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(ee): bump ee-repo-ref to 2d6ffd3 (EE main merged in) Previous bump pinned an older EE commit, missing the audit-log object-store export module (EE PR #579, commit ec3cd35) and other EE main updates. The CE backend's `crate::ee_oss::anchor_audit_logs_s3_checkpoint_env_var` and `export_audit_logs_to_object_store` references need the new EE definitions. Merged origin/main into the EE branch and pinned the merge commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: update ee-repo-ref to b0c87b1272c25dca4aa9148c87fb024a9d9ef322 This commit updates the EE repository reference after PR #583 was merged in windmill-ee-private. Previous ee-repo-ref: 2d6ffd32c99bd93e79cf78675cb89499a81b17e1 New ee-repo-ref: b0c87b1272c25dca4aa9148c87fb024a9d9ef322 Automated by sync-ee-ref workflow. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com> |
||
|
|
d08f72b3e1 |
feat(vault): optional KV secret path prefix setting (WIN-1960) (#9249)
* feat(vault): add optional KV secret path prefix setting (WIN-1960) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: update ee-repo-ref to 0189ba6504fd70eb4929e4881d624d48efd14aee This commit updates the EE repository reference after PR #581 was merged in windmill-ee-private. Previous ee-repo-ref: e32e8d6483550c67897e09b6f900dff1034bdae8 New ee-repo-ref: 0189ba6504fd70eb4929e4881d624d48efd14aee Automated by sync-ee-ref workflow. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com> |
||
|
|
285a78752a |
feat(indexer): observability for unavailable search index (WIN-1956) (#9239)
* [ee] feat(indexer): observability for unavailable search index A user hit `Not found: There is no index reader to search from` when searching service logs and could not tell whether it was a config error or a bug, and asked for visibility into the indexer status (WIN-1956). Backend (EE companion PR): - Replace the opaque error with an actionable message explaining the likely causes (indexer disabled, still starting, or blocked acquiring the indexer lock) and pointing to the status panel. - Add a coarse `state` (running | stale | never_started) to `/indexer/status`, derived from the lock row, distinguishing a never-configured indexer from a stale/blocked one. Frontend: - Instance Settings > Indexer now shows Running / Stale / Not started with a tooltip explaining what to check for each. - Service logs search now catches failures and shows an inline, actionable Alert instead of an unhandled rejection. Fixes WIN-1956 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: update ee-repo-ref to 017d36418a65ce5c840c502e3174df0c393612ba This commit updates the EE repository reference after PR #580 was merged in windmill-ee-private. Previous ee-repo-ref: 18b7e1b30a1ff582c4a072580bbb8aec34e22cdc New ee-repo-ref: 017d36418a65ce5c840c502e3174df0c393612ba Automated by sync-ee-ref workflow. * fix(indexer): address review nits - IndexerMemorySettings: older backends without `state` reporting `is_alive: false` now show "Stopped" (red) again instead of falling through to "Unknown" (codex/cubic P2). - ServiceLogsInner: clear stale logs/counts on a failed search so the error isn't shown alongside results from a previous query (codex P2). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com> |
||
|
|
ba6fb7021b |
feat: export audit logs to a dedicated object store folder (#9207)
* feat: export audit logs to dedicated object store folder * fix: gap-free audit export via snapshot-xmin gate and stable object keys * test: add integration test for audit log object store exporter * fix: cursor audit export on snapshot xmin to prevent id-leapfrog loss * fix: protect audit s3 checkpoint from config sync and bound export interval * fix: anchor audit s3 checkpoint at enable time to not skip first-window rows * fix: anchor first audit export at the enable transaction's xid * fix: use epoch timestamp floor on first audit export run to not drop old backlog * fix: anchor audit export at startup for env-var enable path * fix: anchor audit export via enabling-txn snapshot xmin trigger * fix: bound the bootstrap audit export to MAX_XID_INTERVAL per tick * refactor: store audit export cursor in background_task_state, add status endpoint * docs: align store_audit_logs_s3 setting text with the actual enable-boundary contract * [ee] refactor: move audit s3 export core logic to EE, gate on Enterprise license * chore: update ee-repo-ref to ec3cd353245e1cdf6a290528dbd7f2ac2498386c This commit updates the EE repository reference after PR #579 was merged in windmill-ee-private. Previous ee-repo-ref: 4ffc6d5f874e64d7dc4a147b4e73baa6c44867a5 New ee-repo-ref: ec3cd353245e1cdf6a290528dbd7f2ac2498386c Automated by sync-ee-ref workflow. --------- Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com> |
||
|
|
c8ab030aa4 |
chore(main): release 1.704.1 (#9226)
* chore(main): release 1.704.1 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
11c03ca14e |
chore(main): release 1.704.0 (#9210)
* chore(main): release 1.704.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
4e91f83b8f |
chore(main): release 1.703.3 (#9200)
* chore(main): release 1.703.3 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
20719b4731 |
chore(main): release 1.703.2 (#9195)
* chore(main): release 1.703.2 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
fa090f3081 |
chore(main): release 1.703.1 (#9182)
* chore(main): release 1.703.1 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
e3a3dbb89c |
chore(main): release 1.703.0 (#9170)
* chore(main): release 1.703.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
7f589a8c7d |
chore(main): release 1.702.1 (#9166)
* chore(main): release 1.702.1 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
90f494975d |
chore(main): release 1.702.0 (#9160)
* chore(main): release 1.702.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
e5286f4607 |
feat: include service accounts in instance settings users list (#9157)
* feat: include service accounts in instance settings users list Service accounts (workspace-scoped, no password row) now appear in the superadmin users list with a Bot icon, workspace badge, and a link to manage them in the workspace settings. Role is locked to Operator. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: update sqlx offline cache Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: use composite key for users each block Service accounts can share emails across workspaces, so key by email + workspace_id to avoid Svelte each_key_duplicate. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
4f3a1e3109 |
chore(main): release 1.701.0 (#9131)
* chore(main): release 1.701.0 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
d666e8431c |
feat: read-only flag on API tokens (#9144)
* feat: read-only flag on API tokens, orthogonal to scopes Add a per-token `read_only` boolean set at creation time. When true, the token can only call HTTP methods classified as Read (GET/HEAD/OPTIONS). Mutating methods and job-run actions are rejected with 403, regardless of which scopes are attached. Surfaced as a prominent toggle in the standard token-creation flow and a discreet `2xs` toggle in MCP mode (where users often want write access, so we don't bias them toward enabling it). MCP enforcement: read-only tokens hide all script/flow/hub tools from `list_tools` and only see endpoint tools whose method is GET, and the runner rejects `call_tool` on anything mutating. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: review fixes for read-only token flag - Exempt /api/mcp/* and /mcp/* paths from the read-only middleware check. MCP transport runs over POST (streamable HTTP / SSE), so otherwise the middleware would 403 every MCP request before the runner could enforce read-only at the tool-call level. - Tighten is_endpoint_read_only to GET only, matching the read_only_hint that create_endpoint_annotations actually emits. - Add unit test for check_read_only_for_route covering GET/HEAD/OPTIONS, mutating methods, and run paths. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: bump ee-repo-ref to read-only-trigger-toggle Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(frontend): make read-only toggle discreet in both modes Match the MCP-mode treatment in standard mode: text-tertiary, 2xs, shared "Read-only" label. The tooltip switches per mode so the explanation still fits the context. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(frontend): gate read-only toggle behind Limit token permissions The read-only toggle now only shows when the user has limited the token's scopes (standard mode) or in MCP mode (which always picks an MCP scope). Turning the limit off also resets read-only so it doesn't silently stick. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(frontend): hide incompatible MCP tools when read-only is on When the read-only toggle is on in MCP mode: - Endpoint badges and the custom-mode endpoint MultiSelect filter to GET. - Already-selected non-GET endpoints are pruned from the scope. - The scripts/flows preview is replaced with a note explaining they're hidden (the runner already rejects script/flow runs for read-only). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(frontend): place read-only toggle at top of limited scope area The previous gate required at least one scope to be picked before the read-only toggle appeared, which made it look missing while the user was still building their scope list. Move the toggle inside ScopesPicker: - Standard mode: sits directly under the "Limit token permissions" toggle whenever Limit is on, before the scope selector. - MCP mode: sits at the top of the MCP scope block. readOnly is now $bindable on ScopesPicker so CreateToken still owns the value. The auto-reset on un-limit moves into ScopesPicker too. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(frontend): nest read-only toggle inside the scope list card Place the read-only toggle at the top of the scope list (between the Selected Scopes summary and the bordered domain list) via a new optional topSlot snippet on ScopeSelector. Keeps ScopeSelector decoupled from read-only specifics; ScopesPicker fills the slot. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: update ee-repo-ref to 9bc8160be50b3e57a60daf4e1b71c389a6e02b8a This commit updates the EE repository reference after PR #571 was merged in windmill-ee-private. Previous ee-repo-ref: f53d26e6685dfd60bfa67686fbd7358169cfd130 New ee-repo-ref: 9bc8160be50b3e57a60daf4e1b71c389a6e02b8a Automated by sync-ee-ref workflow. * fix: address CI review for read-only token flag - P1 (Codex): narrow the MCP middleware exemption from "any /api/mcp/*" to just the streamable HTTP transport endpoints (/api/mcp/gateway, /api/mcp/w/{ws}/{mcp,sse,list_tools}). Without this, a read-only token could POST /api/mcp/gateway/oauth/server/approve and mint a follow-on non-read-only MCP token via the OAuth code/token exchange. - P2 (Claude/cubic): fix test comment/assertion mismatch — the run-path assertion now exercises GET (which is what the RUN_PATH_ACTIONS elevation comment describes) in addition to POST. Add a regression assertion for /api/mcp/gateway/oauth/server/approve. - P2 (cubic): short-circuit script/flow/hub-script/resource fetches in MCP list_tools when read_only is on — they would only be discarded below, so skipping the DB and resource fan-out is pure win. - P2 (cubic): when scopes are pre-supplied via the CreateToken prop, the ScopesPicker isn't rendered, which previously hid the read-only toggle entirely. Render it next to the pre-supplied scopes display. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com> |
||
|
|
c6346aabe0 |
chore(main): release 1.700.2 (#9117)
* chore(main): release 1.700.2 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |
||
|
|
411ca47ffd |
chore(main): release 1.700.1 (#9114)
* chore(main): release 1.700.1 * Apply automatic changes --------- Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com> |