VirtualList crashes with 'Requested index 0 is outside of range 0..0'
when it mounts with itemCount=0 and a positive height. This happened
because the old condition allowed VirtualList to remount during loading
with zero items but a stale listDivHeight from a previous mount.
Change the guard to displayedFileKeys.length === 0 so VirtualList is
never rendered when there are no items. Show a centered loading spinner
or "no files" message instead.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: prevent AI agent tool jobs from becoming zombies on cancellation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* kill tool tasks on cancel timeout
* fix: address review feedback and update sqlx cache
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: MCP server readiness for Anthropic integrations directory
- Add CORS layer to MCP streamable HTTP endpoint for browser clients
- Add tool result truncation (25K token limit) to prevent oversized responses
- Add HEAD method support on OAuth authorize endpoint
- Skip workspace selection redirect during MCP OAuth flow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address PR #8438 review feedback
- Add DELETE to CORS allowed methods (MCP spec requires DELETE for session termination)
- Add CORS layer to deprecated /sse endpoint for completeness
- Remove redundant .head() on OAuth authorize (axum auto-handles HEAD via GET)
- Fix comment: "chars/token" → "bytes/token" since len() returns bytes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: show cancelled WAC jobs as done in workflow timeline
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: keep polling after cancel so WAC timeline updates to completed state
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: treat WAC as done in LogPanel when loader stops after cancel
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: show preview badge and hide _MODULES arg in run history
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: show preview badge alongside status dot, not instead of it
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add cloud quota usage display and version pruning
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: hard-delete pruned scripts so quota actually decreases
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: update quota error messages to reference workspace settings
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(cli): use local scripts when previewing flows
When previewing a flow, PathScript modules (type: "script") now resolve
to local file content instead of remote versions. This ensures flow
preview and dev mode test the actual local changes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test(cli): add tests for PathScript local replacement in flow preview
Unit tests for replacePathScriptsWithLocal covering:
- basic PathScript→RawScript conversion
- tag_override preservation
- missing local file fallback
- mixed module types
- nested structures (loops, branches)
Integration test verifying flow preview with a PathScript step
uses the local script file content.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(cli): extract shared helpers and add aiagent support for PathScript replacement
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(cli): replace `as any` casts with proper type assertions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(cli): preserve local flow preview script context
* fix(cli): normalize inline flow preview bundles for bun
* fix(cli): make local flow path scripts opt-in
* fix(cli): only merge flow preview config for local mode
* chore(system-prompts): regenerate cli command guidance
* fix(cli): skip deno defaultTs test in CI without deno runtime
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore(cli): clean up local path script helpers
* feat(cli): make flow preview use local path scripts
* fix(cli): ignore normalized preview metadata drift
* chore(cli): address review follow-ups
* test(cli): cover custom bundler path quoting
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* perf: cache composer vendor dir to skip reinstall on repeated php executions
* feat: add COMPOSER_VENDOR_CACHE_DISABLED env var to opt out of vendor caching
---------
Co-authored-by: hugocasa <hugo@casademont.ch>
- Fix debugger HTTP health endpoint to also match /ws_debug/health
(ingress forwards the full path, not just /health)
- Add request logging to all three extra services (LSP, multiplayer,
debugger) for HTTP and WebSocket ping/upgrade events
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(frontend): remove banned $bindable('') pattern from ClearableInput
Switching format types in the flow input editor caused a
props_invalid_value error because ClearableInput used
value = $bindable(''), which conflicts with undefined bindings.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(frontend): restore flow result display in result node
The fix in #8390 changed updateLastJob() to only use testJob when
actively running/streaming, preferring flowStateStore for completed
results. But the result node has moduleId='' and no flowStateStore
entry, so the early return made it always show the empty state.
Add !moduleId to the testJob condition so the result node (which has
no flowStateStore entry) still uses testJob as its only data source.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When switching to a non-main module tab, the test panel now infers
args from the module's code and runs the module's code on Test/Cmd+Enter.
Per-module args and schema are persisted across tab switches.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [ee] improve analytics: add git sync & AI chat telemetry, HMAC-signed download
- Add ai_chat_usage table to track chat sessions (session_id, provider, model, mode, message_count)
- Add POST /w/{workspace}/workspaces/log_chat endpoint with upsert on session_id
- Frontend fires logAiChat on every sendRequest, using HistoryManager's existing chat ID
- EE stats: add git_sync_usage (sync vs promotion repo count) and ai_chat_usage (30-day aggregates)
- Replace RSA+AES-GCM encrypted telemetry download with plaintext JSON + HMAC-SHA256 signature
- Signature (12 hex chars) included in download filename for verification
- Update instance settings telemetry descriptions for both EE and CE
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: make StatsDownload struct pub to fix private-interfaces error
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: update ee-repo-ref to 878cc2044717e0177228529a50433fe2768e70b5
This commit updates the EE repository reference after PR #464 was merged in windmill-ee-private.
Previous ee-repo-ref: 33eb863b6b881bd54ed69a540e0c65d5fe125024
New ee-repo-ref: 878cc2044717e0177228529a50433fe2768e70b5
Automated by sync-ee-ref workflow.
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
* feat(cli): add --env alias for --branch and environments config alias
Add --env as a CLI alias for --branch on sync pull, sync push, workspace
bind, and workspace unbind commands. Add environments as a permanent
config alias for gitBranches in wmill.yaml. This helps users who use
single-branch multi-environment workflows where "branch" terminology
is confusing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: regenerate auto-generated system prompts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: update cloudformation template to use latest cli/images + fix cleanup script
* fix: narrow SG cleanup to k8s-created groups + add CLI install error handling
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add 93 missing integration icons and fix dark mode visibility
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add 11 more integration icons (round 2)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add 5 more integration icons (round 3)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: make instance events webhook URL configurable via superadmin UI
The instance events webhook was previously only configurable via the
INSTANCE_EVENTS_WEBHOOK env var, requiring a restart to change. This
adds a DB-backed global setting with a UI in superadmin settings under
Monitoring > Webhooks, while keeping the env var as an override.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address PR review - prometheus timer bug and cleaner cache init
- Bind prometheus timer to `let timer` and call `stop_and_record()`
after the POST (was silently discarded before)
- Use `Option<Instant>` with `map_or` instead of `checked_sub` trick
for clearer "not yet read" semantics
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: remove env var mention from webhook setting description
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: list all instance events explicitly in webhook description
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: restore send_instance_event guard with AtomicBool for DB setting
Use a shared Arc<AtomicBool> between send_instance_event and the event
loop so we skip channel sends when no webhook is configured (env or DB).
Starts optimistic (true) so the first event triggers a DB read, then
the loop updates it after each cache refresh.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: use static AtomicBool + notify handler for webhook guard
Replace the Arc<AtomicBool> instance field with a global static
INSTANCE_EVENTS_WEBHOOK_DB_ENABLED, updated by the
notify_global_setting_change handler in main.rs. This follows the
established pattern (like REQUIRE_PREEXISTING_USER_FOR_OAUTH) and
avoids the deadlock where the bool could never flip back to true.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: single Arc<RwLock<Option<String>>> for instance webhook URL
Replace the separate INSTANCE_EVENTS_WEBHOOK env var lazy_static and
INSTANCE_EVENTS_WEBHOOK_DB_ENABLED AtomicBool with a single shared
variable. Initialized from env var, then the reload function overwrites
from DB (falls back to env var when DB has no value). Follows the same
pattern as SCIM_TOKEN and other settings.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
* feat: add workspace-specific registry overrides
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: move workspace registries to end of registries tab
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: workspace overrides use field selector instead of showing all fields
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* style: polish workspace registries UI to match design guidelines
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: show field selector directly and fix addField initialization logic
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: namespace pip_resolution_cache by workspace when registry overrides exist
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: namespace binary/bundle caches by workspace when registry overrides exist
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* perf: zero-cost cache suffix when no workspace overrides exist
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: reload workspace_registries via notify events on setting change
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address PR review findings
- Fix discardCategory not reverting workspace_registries changes
- Fix get_no_default: convert to async fn with owned Uuid param
- Fix append_logs: use windmill_queue import already available
- Fix ruby URL parsing: support both comma and whitespace delimiters
- Add WorkspaceRegistryMap type alias to reduce inline type noise
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* all
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add ws_base_url instance setting to override WebSocket base URL
Allow deployments behind reverse proxies to route WebSocket traffic
(LSP, debugger, multiplayer) to a different host/port than the main
frontend via a new instance setting.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: move ws_base_url to Advanced section with toggle and connectivity test
- Move setting from Core to Advanced > WebSocket section
- Render as toggle "Custom websocket base url from frontend to
multiplayer/lsp/debugger" with conditional URL text field
- Add Test connectivity button (always visible) that checks HTTP health
and WebSocket ping for all three services (LSP, Multiplayer, Debugger)
- Add /ws/ping and /ws/health endpoints to LSP service
- Add /ws_mp/health HTTP and __ping__ WS handlers to multiplayer service
- Add /ping WS handler to debugger service
- Add CORS headers to health endpoints for cross-origin testing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: toggle enabled check and testWs promise resolution
- Fix enabled derived to check only for null (not empty string),
otherwise the toggle never turns on since toggleEnabled sets ''
- Fix testWs onclose handler to resolve(false) so the promise
doesn't hang if the server closes without sending a message
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: make connectivity test work with existing services
- HTTP test: accept plain text "ok"/"okay" (old services) in addition
to JSON {"status": "ok"} (new services), reject HTML (SPA fallback)
- WS test: resolve on onopen (connection established) instead of
waiting for a specific pong message, so the test works even with
services that don't have the new /ping handler yet
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add script module mode with folder model for Bun and Python
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add missing modules field to RawCode in bun_executor
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* sqlx
* feat: enrich WAC templates with checkpoint and replay semantics
Add prominent comments explaining that all computation must happen
inside task/step/taskScript or it will be replayed on resume/retry.
Clarify that waitForApproval does not hold a worker and that
approve/reject URLs are available in the timeline step details.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(cli): script module sync idempotency, per-module hash tracking, and preview support
- Fix pull→push idempotency: use `??` instead of `||` for module lock
field so empty strings are preserved (matches API's `lock: ""`)
- Add per-module hash tracking in wmill-lock.yaml following the flow
inline script pattern (SCRIPT_TOP_HASH + per-module subpath hashes)
- Selective module lock regeneration: only regenerate locks for modules
whose content actually changed, not all modules
- Use unfiltered rawWorkspaceDependencies for module hashes to match
what updateModuleLocks passes to fetchScriptLock
- Show changed module names in stale script output for clarity
- Add module support to `script preview` command: read modules from
__mod/ folder and pass them in the preview API request
- Add preview tests for taskScript pattern (flat and folder layout)
- Update test assertion for module stale detection output
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(frontend): WAC UI improvements — reorder templates, module tab rename, import consolidation
- Reorder WAC template buttons: TypeScript before Python in
ScriptBuilder, CreateActionsScript, and CreateActionsFlow
- Remove dropdown items from +Script button (simplify to direct link)
- Move "Import Workflow-as-Code" to +Flow dropdown with dedicated drawer
- Add module tab rename: pencil icon on hover opens popover with
validation, fixed-width icon container prevents layout shift
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: remaining module-mode changes from working branch
- Backend parser updates for WAC detection
- CLI sync/types updates for raw app path and module support
- Frontend UI polish (Dev.svelte, ScriptRow, script hash page)
- Test fixture updates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test(cli): add test for module modification detection in generate-metadata
Verifies that modifying a single module file re-triggers stale
detection and only the changed module is listed, not all modules.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(backend): critical fixes from PR review
- Fix hardcoded dev path in bun_executor.rs WAC v2 wrapper — use
"windmill-client" import instead of absolute filesystem path
- Fix missed no_main_func → auto_kind rename in parser TS test
- Add modules column to clone_script SQL (windmill-common and
windmill-api-workspaces) so cloned scripts retain their modules
- Add modules: None to RawCode structs in worker tests
- Restore complete sqlx cache (merge main's cache + our new queries)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(backend): fix clone warning treated as error in CI
Change `.clone()` on double reference to `*k` dereference in
scripts.rs hash implementation. Update sqlx cache with new query
hashes from modified clone_script SQL.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(frontend): use published parser wasm versions for CI build
The local file:// paths for windmill-parser-wasm-py and
windmill-parser-wasm-ts don't exist in the Cloudflare Pages build
environment. Revert to published npm versions (1.655.0).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(frontend): update parser wasm packages to 1.657.2
Use newly published windmill-parser-wasm-ts and windmill-parser-wasm-py
v1.657.2 which include auto_kind/WAC detection changes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(frontend): regenerate package-lock.json for npm ci compatibility
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(frontend): use main's lockfile as base, update only parser wasm packages
Regenerating package-lock.json from scratch pulled different dependency
versions causing svelte-check type errors. Instead, start from main's
lockfile and only update the two changed packages.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(backend): add modules column to fetch_script_for_update query
The Script<SR> struct has a modules field (FromRow), but
fetch_script_for_update didn't SELECT modules, causing a runtime
error "no column found for name: modules" when the worker processed
dependency jobs. This was the root cause of the relock_skip test
timeout.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(backend): fix script module execution for Python and Bun
- Fix modules not passed through job queue: inject _MODULES into
PushArgs.extra when pushing Code jobs so worker can extract them
- Fix Python module imports: use relative imports (from .helper)
and add sys.path.insert for module directory in wrapper
- Fix Python tests: use relative imports and empty lock to prevent
pip from resolving module names as packages
- Add local file check in Bun loader for module resolution
- Ignore Bun module test (bundle mode loader integration tracked
separately)
- Add missing modules column to fetch_script_for_update query
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(backend): remove unnecessary empty lock in Python module tests
Relative imports (from .helper) are not parsed as pip packages,
so the empty lock workaround is not needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(backend): fix module execution for Python and Bun — all tests pass
Python modules:
- Use relative imports (from .helper import greet) since scripts run
as packages
- Add sys.path.insert for module directory in wrapper to ensure local
modules take precedence over pip packages with same name
Bun modules:
- Use bundled output (./out/main.js) as wrapper import when modules
are present — the bundled output has module content inlined by
Bun.build, avoiding runtime loader resolution issues
- Add local file check in loader.bun.js onResolve to short-circuit
API URL resolution for module files on disk
Job queue:
- Inject _MODULES into PushArgs.extra when pushing Code jobs so
the worker can extract them at execution time
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: address PR review — simplify, fix correctness, remove dead code
Critical fixes:
- Replace all CLI `no_main_func` references with `auto_kind` (string)
to match the backend migration and API changes
- Remove duplicated `compute_python_module_dir` in worker.rs, use
the canonical version from python_executor.rs
High priority:
- Auto-create `__init__.py` in intermediate directories for nested
Python modules so imports like `from .utils.math import add` work
without users manually creating __init__.py files
- Remove redundant `sys_path_insert` — relative imports use Python's
package system, not sys.path
Medium:
- Fix lock file base name extraction: use regex to strip only the
final extension (`.replace(/\.[^.]+$/, '')`) instead of `indexOf(".")`
which breaks for files like `helper.test.ts`
Simplification:
- Remove dead `{#if false}` Popover block in ScriptEditor.svelte
- Guard loader.bun.js local file check to only run for relative paths
(matching the Windows loader pattern)
- Add clarifying comment on Bun dual mechanism (build + run phases)
- Add maintenance comment on manual Hash impl for NewScript
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: final review fixes — stale cleanup, baseName, auto_kind export
- Fix sync.ts baseName extraction using indexOf(".") → regex
(same fix as script.ts/metadata.ts, missed this instance)
- Add stale module file cleanup in writeModulesToDisk: removes files
from __mod/ that are no longer in the modules map before writing,
fixing the pull→push cycle that couldn't delete modules
- Log warning when _MODULES serialization fails in job push instead
of silently dropping modules
- Use strict equality (===) for auto_kind comparison
- Exclude auto_kind from workspace export — it is auto-detected by
the parser at deploy time from script content
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(cli): remove auto_kind from push, comparison, and metadata
auto_kind is auto-detected by the parser at deploy time, so the CLI
should not send it, compare it, or write it to script.yaml.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: remove erroneously added backend/backend/.sqlx directory
Duplicate .sqlx cache was committed at the wrong nested path.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address PR review feedback + fix CI dead_code warning
Frontend (ScriptEditor.svelte):
- Fix switchToMain() missing lastSyncedCode update — prevents stale
code sync on external changes while editing a module tab
- Fix formatAction saving module code to main script's localStorage
draft — now saves main code when on a module tab
- Fix non-null assertion on inferModuleLang in renameModule — fall
back to original language instead of force unwrap
- Remove redundant activeModuleTab truthy check in runTest
CLI (script.ts):
- Clean up empty directories after removing stale module files in
writeModulesToDisk
Backend:
- Add path traversal guard in write_module_files — reject module
paths containing ".."
- Fix dead_code warning on auto_kind field in workspace export struct
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(frontend): improve auto_kind UX + address review findings
- Rename "Include without main function" toggle to "Include library
scripts" in script list (ItemsList.svelte)
- Update NoMainFuncBadge: "No main" → "Library" with clearer tooltip
- Filter module file extensions by main script language — Python
scripts only allow .py modules, TypeScript only .ts, etc.
- Split flushModuleState into flushModuleContent (no UI side-effect)
and flushModuleState (flush + reset tab), reducing duplication
- Dynamic placeholder and hint text in add module popover based on
main script language
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* [ee] feat: instance groups instance-level role support
Add ability to assign instance-level roles (superadmin/devops) to
instance groups. Group members automatically receive the role with
proper precedence: manual elevated roles always win, superadmin > devops.
- Migration: add instance_role to instance_group, role_source to password
- Role propagation on all mutation paths (add/remove/update/delete/import)
- SCIM sync integration (companion PR: windmill-ee-private#463)
- Frontend: role toggle in group editor, role column in tables,
role source indicator in superadmin settings
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: update ee-repo-ref to 278a3887f759f9d1146554baa0765518d5bc70f2
This commit updates the EE repository reference after PR #463 was merged in windmill-ee-private.
Previous ee-repo-ref: b407fe4604153d09ff223e11d43c2df83a1de5d0
New ee-repo-ref: 278a3887f759f9d1146554baa0765518d5bc70f2
Automated by sync-ee-ref workflow.
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
* feat: store hashed tokens in the token table instead of plaintext
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address review issues in token hash migration
- Update all base.sql fixtures to include token_hash/token_prefix columns
- Keep plaintext token for webhook tokens (needed for URL reconstruction)
- Restore get_token_by_prefix to query DB for webhook tokens
- Fix down migration to delete NULL-token rows before restoring NOT NULL
- Update parser fixture standalone schema
- Update EE dedicated_worker_ee.rs to use token_hash/token_prefix
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: restore sqlx offline cache (only add new query files)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: keep writing plaintext token column for backward compat
Write to token column alongside token_hash until MIN_VERSION_SUPPORTS_TOKEN_HASH
(1.649.0) is reached. This ensures older workers can still authenticate
during rolling upgrades. Remove the separate UPDATE in new_webhook_token
since create_token_internal now writes plaintext directly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: branch on MIN_VERSION to write plaintext token or null
Check MIN_VERSION_SUPPORTS_TOKEN_HASH at runtime: write plaintext to
token column while old workers exist, switch to NULL once all workers
are >= 1.649.0.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: set MIN_VERSION_SUPPORTS_TOKEN_HASH to 1.650.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use token_hash for email lookup and expiry notifications
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: rotate webhook tokens instead of recovering plaintext from DB
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: use token_hash for native trigger token lookups and deletes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* sqlx
* refactor: drop webhook_token_prefix from native_trigger table
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: backward compat for token rotation and make webhook_token_hash NOT NULL
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: prevent panic on short superadmin secret token prefix
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: prevent panic on short superadmin secret token prefix
Replace all `token[0..TOKEN_PREFIX_LEN]` slicing with
`token.get(..TOKEN_PREFIX_LEN).unwrap_or(token)` to prevent
panics when a token shorter than 10 chars is provided (e.g.
malformed Authorization header, short superadmin secret).
Co-authored-by: hugocasa <hugocasa@users.noreply.github.com>
* fix: prevent panic on short token prefix slicing
Replace all `token[0..TOKEN_PREFIX_LEN]` with safe
`token.get(..TOKEN_PREFIX_LEN).unwrap_or(token)` to prevent panics
on malformed tokens shorter than 10 characters.
Co-authored-by: hugocasa <hugocasa@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Revert "fix: prevent panic on short superadmin secret token prefix"
This reverts commit 37ec2e5ad5.
* revert: remove unnecessary defensive token prefix slicing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add token_hash to end_user_email test fixture
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test: add integration tests for token hash migration
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: correct token_hash test assertions for cache and version
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: add plaintext column removal reminder to test fixtures
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: log count of orphaned triggers deleted during migration
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: preserve orphaned triggers with error instead of deleting
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: rename token_expiry_notification.token to token_hash and copy owner/expiration in rotate
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: hash existing plaintext values before renaming token_expiry_notification column
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: remove unnecessary length check in token_expiry_notification migration
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* update dates and version
* updat ee ref + sqlx
* improve mcp migration
* fix: atomic token rotation with rollback on trigger update failure
rotate_webhook_token now atomically inserts the new token and deletes
the old one in a single transaction, preventing token leaks.
Returns new_token_hash so callers can clean up the new token if their
subsequent trigger update fails (which involves external HTTP calls
and cannot be in the same DB transaction).
- Handler: wraps post-rotation work; deletes new token on failure
- Google renewal: deletes new token if service_config update fails
- Tests updated to match new atomic semantics
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* higher min version
* fix: defer old token deletion to avoid breaking triggers on update failure
rotate_webhook_token now keeps the old token alive and returns
old_token_hash. Callers delete it only after the trigger row has been
successfully updated. If the external service call or DB update fails,
the trigger keeps working with the old token.
Worst case: if the best-effort delete fails, the old token leaks as an
extra DB row — harmless compared to breaking the trigger.
Also update summarized_schema.txt for renamed columns.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: update ee-repo-ref to 2d0823a471014e2bc2d898c63518323946b7474f
This commit updates the EE repository reference after PR #437 was merged in windmill-ee-private.
Previous ee-repo-ref: 7aef8b06cb6f54c2bc89dd57b70947deed72553c
New ee-repo-ref: 2d0823a471014e2bc2d898c63518323946b7474f
Automated by sync-ee-ref workflow.
* fix: prevent panic on short tokens by using safe prefix extraction
Add safe_token_prefix() helper that uses .get(..TOKEN_PREFIX_LEN).unwrap_or(token)
instead of direct slice indexing, preventing panics when tokens are shorter than
10 characters (e.g., short superadmin secrets or malformed Bearer tokens).
Co-authored-by: Ruben Fiszel <rubenfiszel@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: HugoCasa <hugo@casademont.ch>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: hugocasa <hugocasa@users.noreply.github.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
Co-authored-by: Ruben Fiszel <rubenfiszel@users.noreply.github.com>
* fix: improve OOM killer observability for debugging pod-level kills
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: lower worker oom_score_adj to protect it from OOM killer
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address PR review feedback on OOM observability
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add end_user_email claim to OIDC ID tokens
When a job is triggered by an app end user, the OIDC ID token now
includes the end_user_email claim automatically. The claim is omitted
for jobs without an end user (regular script/flow runs).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* update ee ref
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: return structured error object on AI agent max iterations
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: avoid double serialization in max iterations error
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: replace unwrap with ? for to_raw_value in max iterations error
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add step_id to max iterations error for consistency with SerializedError
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
EE files (*_ee.rs, *_ee.ts, *_ee.svelte) are symlinks from
windmill-ee-private that are gitignored. The walker skipped them
because it respects .gitignore. This adds a separate recursive scan
for _ee files and merges them into the index. Also fixes outline
resolving symlinks via canonicalize, causing path mismatches.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add workspace dependencies support for powershell
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: improve workspace deps editor UX for powershell
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add powershell workspace deps support to CLI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(native-triggers): preserve API error response body in HttpRequestError
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(frontend): use instance credentials for reconnect when instance_shared
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* chore: split debug info for EE release builds
Generate line-table debug info in release builds and split it into
a separate .debug file. The shipped binary remains stripped (same
size as before), while the .debug files are attached to GitHub
releases for both amd64 and arm64 EE builds.
This enables production debugging with gdb/perf by copying the
matching .debug file into a running pod.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: extract debug info via separate Docker stage
Use a `FROM scratch AS debuginfo` stage instead of copying the .debug
file to the final image. This keeps the shipped image at exactly the
same size as before. CI extracts the .debug file using depot's
--target debuginfo with cache hits from the main build.
Also adds gnu_debuglink so gdb auto-discovers the debug file when
placed next to the binary.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [ee] feat: add GET /api/saml/metadata endpoint for SP metadata XML
Serves static SAML 2.0 EntityDescriptor XML so IDPs can configure SSO
without requiring IDP metadata to be set up first in Windmill.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: update ee-repo-ref to b2fde51087d0d0ee0223c15cafb4e8badddd2d13
This commit updates the EE repository reference after PR #461 was merged in windmill-ee-private.
Previous ee-repo-ref: 187f12947b69e584523ace93957d0be0ceb7b37c
New ee-repo-ref: b2fde51087d0d0ee0223c15cafb4e8badddd2d13
Automated by sync-ee-ref workflow.
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
* fix: soft error when AI agent reaches max iterations instead of hard error
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: set output to error message when AI agent reaches max iterations
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add error field to AI agent result for max iterations soft error
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: restore default max iterations to 10
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: include partial result in max iterations error message
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: rename retries tab to error handling and reorganize sections
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: support multiple secret variables during resource creation
When creating a resource, users can now select multiple fields to be
stored as secret variables. If only one field is selected, behavior
is unchanged (single variable with same path as resource). If multiple
fields are selected, each gets its own variable with _field_name appended
to the resource path.
Closes#8384
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
* fix: delete all linked secret variables when resource is deleted
When a resource with multiple secret fields is deleted, also delete
variables matching the {path}_{field_name} pattern in addition to
the exact path variable. Each deleted variable gets its own deployment
metadata update and webhook notification.
Co-authored-by: Diego Imbert <diegoimbert@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update backend/windmill-store/src/resources.rs
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
* fix: only delete linked variables that are actually referenced in resource value
Instead of deleting variables purely based on path prefix matching
(which could accidentally delete unrelated variables), the deletion
now reads the resource value first, extracts all $var: references,
and only deletes variables that are actually used in the resource.
Co-authored-by: Diego Imbert <diegoimbert@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
Co-authored-by: Diego Imbert <diegoimbert@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Diego Imbert <70353967+diegoimbert@users.noreply.github.com>
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>