Commit Graph
15007 Commits
Author SHA1 Message Date
1e192f2d86 feat(apps): authorize deployed-app S3 reads on-behalf of the author for logged-in viewers (#10048)
* feat(apps): authorize deployed-app S3 reads on-behalf of the author for logged-in viewers

A logged-in user viewing a deployed app now reads S3 files (rich result,
table/image/PDF preview, CSV export, download, metadata) the same way an
anonymous viewer already does: on-behalf of the app author per the app policy's
execution_mode, gated by an app-provenance check — instead of against the
viewer's own S3 permissions. This aligns S3 with every other thing an app does
(scripts, flows, resources all already run on-behalf of the author) and lets an
operator who lacks folder S3 permission still see data rendered inside the app.

The raw job_helpers/* S3 API stays viewer-scoped: a viewer who lacks folder
permission is still denied there. Only which endpoint the app frontend uses for
logged-in deployed viewers changes.

Backend:
- Add app-scoped, provenance-gated apps_u/* variants for all S3 display ops
  (download_s3_file already existed; add download_s3_parquet_file_as_csv,
  load_file_metadata, load_file_preview, load_parquet_preview, load_csv_preview,
  load_table_count). Each routes through one shared helper
  (app_s3_on_behalf_and_provenance) that scope-confines an app embed token,
  resolves the on-behalf identity, and runs the provenance gate ONCE before
  dispatching to the EE *_internal S3 helpers.
- Close the confused-deputy hole in check_if_allowed_to_access_s3_file_from_app:
  the unconditional Ok() bypass for a logged-in, non-embed session now only
  applies in viewer execution mode (where the on-behalf identity IS the viewer,
  so the viewer's own permissions still bound the read downstream). Author-mode
  reads (anonymous/publisher) always enforce provenance, for anonymous and
  logged-in viewers alike, so a viewer cannot launder the author's S3
  permissions with an arbitrary file_key.

Frontend:
- Route the deployed-app view through apps_u/* using the app-viewer isEditor
  signal instead of login state (the old $userStore proxy wrongly sent
  logged-in deployed viewers to the viewer-scoped job_helpers API). Editor and
  preview keep viewer identity via job_helpers.

execution_mode: viewer remains the escape hatch for per-viewer S3 enforcement.

Fixes provenance-gated S3 display for logged-in operators on deployed apps.

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

* docs(backend): document cargo features, restarting the dev backend, and filesystem object storage

The dev backend runs `cargo watch --features quickjs` by default, which omits S3,
EE, MCP, and non-JS runtimes — feature-gated routes then 404 or return a
"requires <feature>" stub at runtime. Add a backend/CLAUDE.md section that:

- explains that you must restart the backend with the appropriate features to
  exercise gated functionality, with the pid/cwd-scoped restart recipe (never
  pkill target/debug/windmill) and the PORT=$BACKEND_PORT gotcha;
- documents what each commonly-toggled feature gate does (private, enterprise,
  license, parquet, duckdb, language runtimes, mcp, trigger kinds, no_auth) plus
  common combinations;
- documents using the built-in FilesystemStorage large-file storage for dev
  workspace object storage (hidden from the UI dropdown; set via
  edit_large_file_storage_config), including the advanced_permissions shape.

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

* fix(apps): don't flatten inner query in app-scoped S3 preview routes

axum's `Query` uses `serde_urlencoded`, which cannot deserialize the typed
(numeric/bool) fields of a `#[serde(flatten)]`-ed struct and 400s on `limit` /
`offset` ("invalid type: string, expected u32"). The app-scoped
load_csv_preview / load_parquet_preview / load_table_count routes flattened
LoadPreviewQuery / LoadCountQuery, so their previews were broken. Restate the
fields directly on the outer query structs (with an into_inner() to rebuild the
inner query) and extend the CE OSS stub to match.

Also bumps ee-repo-ref.txt for the companion EE csv-separator panic fix.

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

* fix: address CI review — nested DisplayResult routing, byte-range contract, docs, tests

- [P1] Thread `appPath` into the nested `DisplayResult`s (render_all children and
  the expanded-result drawer) so logged-in deployed viewers route nested/expanded
  S3 tables, images, PDFs, and downloads through `apps_u/*` too, not job_helpers.
- [P2] Mark `read_bytes_from`/`read_bytes_length` required on the
  `apps_u/load_file_preview` route (they are non-optional in LoadFilePreviewQuery),
  and mirror the full query shape in the CE OSS stub so the byte-range contract is
  enforced identically on CE and EE.
- [P2] Fix the backend retrigger command in backend/CLAUDE.md: cargo watch runs
  from `backend/`, so `touch README.md` (not `backend/README.md`).
- [P2] Trim app_s3_onbehalf.rs comments per AGENTS.md (state the invariant once,
  no drafting-history narration).
- Extend the integration test to cover the table-count, csv-preview (numeric
  limit/offset deserialization), and file-preview (byte-range required) routes.

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

* docs(apps): tighten S3 provenance-gate comments per AGENTS.md

Consolidate the viewer-mode / author-mode rationale to ≤4 lines at each branch
of the gate, and drop the repeated explanation from the shared
app_s3_on_behalf_and_provenance doc comment (which now just states what the
helper does). No behavior change.

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

* chore: update ee-repo-ref to f292a1040da6a667ce7c22abf63ec0debfdd480f

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

Previous ee-repo-ref: a582389084eb363997cb5e8053f29220e0d3eaec

New ee-repo-ref: f292a1040da6a667ce7c22abf63ec0debfdd480f

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>
2026-07-11 10:14:40 +02:00
Ruben FiszelandClaude Opus 4.8 3e251db7c8 add local-review-codex skill and bump CI codex to gpt-5.6-sol (#10051)
* feat: add local-review-codex skill and bump CI codex to gpt-5.6-sol

Add a `/local-review-codex` skill that runs the same Codex review as the
codex-pr-review GitHub action, locally and scoped to unpushed work
(committed + uncommitted), so contributors can catch what CI would flag
before pushing. Same REVIEW.md policy, gpt-5.6-sol model, and xhigh
reasoning effort as CI; runs read-only so it cannot modify the tree.

Also bump the CI codex-pr-review job to model gpt-5.6-sol on Codex CLI
0.144.1 (from gpt-5.5 / 0.128.0), and document the new skill in AGENTS.md.

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

* fix(local-review-codex): use bash in docs and fall back to origin/main

Address CI review findings:
- Docs invoked the runner with `sh`, which ignores the Bash shebang and
  fails on `set -o pipefail` under Dash (/bin/sh on Debian/Ubuntu). Use
  `bash` and note it in SKILL.md.
- Default base `main` is unresolved in checkouts that only have
  `origin/main`; resolve through a local ref first, then fall back to the
  remote-tracking ref. Fix the misleading `git fetch` recovery hint.
- Pin the codex-not-found install hint to @0.144.1 to match the workflow.

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 06:37:39 +02:00
Ruben FiszelandClaude Opus 4.8 e668193a93 fix(frontend): don't re-seed empty editor on stale ?new_draft after draft exists (#10044)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 06:18:00 +02:00
Ruben FiszelandClaude Opus 4.8 5844c32ac5 fix: enforce read authorization when signing S3 objects (#10049)
`sign_s3_objects` minted a long-lived HMAC bearer signature for any S3 key
handed to it, by any authenticated workspace member, with no check that the
caller was allowed to read that key. Since `validate_s3_signature` only
verifies the HMAC and expiry at fetch time, any member (operators included)
could mint a transferable capability to read arbitrary S3 keys, bypassing the
advanced S3 permission rules (`check_lfs_object_path_permissions`).

Authorize the read at mint time: add an `ApiAuthed` extractor and, before
signing each key, require the caller's own `S3Permission::READ` via
`get_workspace_s3_resource_and_check_paths`. A caller can no longer sign a key
they cannot themselves read. The fetch-side validators are left unchanged.

The only legitimate caller is the wmill SDK invoked from an app-author job,
whose token authenticates as the executing (author) identity — which can read
the key — so authorized app display is unaffected.

Adds an integration test proving an authorized caller can sign a readable key
(and the signature validates end-to-end through the presigned fetch route)
while an unauthorized caller is refused.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 05:57:48 +02:00
ab38e1418e fix: keep agent-worker server job-completed processor alive & self-healing (#10033)
* fix: keep agent-worker server job-completed processor alive on init-script failure

The agent-worker API server's background job-completed processors relay
completions on behalf of many remote agent workers. The processor loop exited
(dropping its receiver) on an init-script failure, but on the server that failed
init script belongs to a remote worker, not the server. Once enough processors
exited, the shared completion channel disconnected and every /send_result POST
returned 500, stranding completions and creating zombie-job restart loops.

Add an is_agent_server flag so server relay processors don't self-terminate on
init-script failure. Pins the EE companion change.

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

* chore: bump EE ref for send_result wait-for-processor change

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

* test: agent-worker server survives a failed init script

End-to-end regression for the agent-worker-server processor bug: an agent worker
runs a failing init script, POSTs the failed init-script completion to
/send_result, and the test asserts the server's background job-completed
processor stays alive (a subsequent job completes and no bg-processor critical
alert is raised). Fails if the is_agent_server guard is removed (the processor
breaks, the supervisor raises a critical alert).

Requires --features enterprise,license,private,agent_worker_server.

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

* test: replace heavyweight init-script e2e with focused unit tests

The panic/respawn/alert and 503 timeout paths are now covered by fast, deterministic
unit tests in windmill-api-agent-workers (supervise_processor, classify_send). Drop
the enterprise-only, global-config-mutating e2e in favor of those. Bump EE ref.

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

* chore: update ee-repo-ref to bc45d9275d4307132927dc8ad3e82049b1aed463

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

Previous ee-repo-ref: 2aca03f28bb37e938ae548b81f1620b2e00dc0f7

New ee-repo-ref: bc45d9275d4307132927dc8ad3e82049b1aed463

Automated by sync-ee-ref workflow.

* chore: bump EE ref for bg-processor alert rate-limiting

Picks up windmill-ee-private#654: exponential backoff + rate-limited critical
alerts in supervise_processor, addressing the code-review nit.

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

* chore: update ee-repo-ref to d48c0e01e8601a372353c032dd237ddb6fa3bbad

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

Previous ee-repo-ref: f89eeb6e333614850ef650e7df78e3c2335f107c

New ee-repo-ref: d48c0e01e8601a372353c032dd237ddb6fa3bbad

Automated by sync-ee-ref workflow.

* chore: bump EE ref for graceful-shutdown-during-backoff fix

Picks up windmill-ee-private#655: supervise_processor re-checks shutdown before
respawn and selects on the shutdown broadcast during backoff, so a crash-loop
backoff can't hang graceful shutdown. Addresses the Codex P1.

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

* chore: update ee-repo-ref to 9bc5dfb9ce73a2d9b981a1de86eea6aa26688b79

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

Previous ee-repo-ref: 8dc3b3d9ec8f9c28b227d36c2a1327b4b2017665

New ee-repo-ref: 9bc5dfb9ce73a2d9b981a1de86eea6aa26688b79

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>
2026-07-10 23:42:30 +02:00
Ruben FiszelandClaude Opus 4.8 d35402d08e chore: bump Rust to 1.97.0 in worker build images and CI (#10047)
Update the pinned Rust toolchain from 1.93.0 to 1.97.0 (latest stable,
released 2026-07-09) across the worker/server build Dockerfiles
(Dockerfile, docker/DockerfileFull, docker/DockerfileFullEe) and all CI
workflows that pin a toolchain.

Verified the backend compiles cleanly with 1.97.0 under `-D warnings`
(the default RUSTFLAGS used by actions-rust-lang/setup-rust-toolchain).

Fixes WIN-2155

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 23:35:41 +02:00
Ruben FiszelandClaude Opus 4.8 8343203ec2 feat(mcp): add multi-workspace MCP tokens via the gateway endpoint (#10043)
* feat(mcp): add multi-workspace MCP tokens via the gateway endpoint

A single MCP token with no bound workspace (workspace_id NULL + mcp scope)
now works across every workspace the token owner can access, served through
the existing /api/mcp/gateway endpoint. This avoids having to register one
MCP server entry per workspace in clients like Claude/Cursor.

In multi-workspace mode the runner exposes a synthetic `list_workspaces`
tool plus the generic API endpoint tools, each workspace-scoped one gaining
a required `workspace_id` argument (mirroring the proxy pattern users built
externally). Per-workspace scripts/flows are not enumerated to avoid
flooding the tool list — they are run via runScriptByPath/runFlowByPath
with an explicit workspace_id.

Auth is resolved per tool call: the gateway middleware detects a
workspace-less mcp token and marks the request MultiWorkspaceMcp, and the
runner resolves a per-workspace ApiAuthed from the raw token via the
AuthCache (validating membership; superadmins may act in any workspace).
Single-workspace tokens are unchanged.

Frontend: the MCP token creation flow gains an "All workspaces" option that
produces a workspace-less token and the gateway URL.

Fixes WIN-2153

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

* test(mcp): cover multi-workspace endpoint tool transformation

Unit tests for endpoint_tool_to_mcp_tool_multi and list_workspaces_tool:
workspace-scoped tools gain a required workspace_id arg, global tools are
left unchanged, workspace_id is not duplicated, and list_workspaces takes
no arguments.

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

* fix(mcp): forward script/flow args for runScriptByPath/runFlowByPath

These endpoints have an additionalProperties body (no declared properties),
so build_request_body previously returned an empty body and dropped every
script/flow argument. This was latent for the per-path run endpoints and
became load-bearing in multi-workspace mode, where scripts/flows can only be
run via runScriptByPath/runFlowByPath — parameterized runs silently lost
their arguments.

build_request_body now forwards all arguments not consumed by a path/query
parameter for pass-through (additionalProperties) bodies, keeping the strict
declared-only behavior for endpoints with explicit properties. The runner
strips the synthetic workspace_id argument before dispatch so it can't leak
into the forwarded body.

Reported by Codex review on #10043.

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

* feat(mcp): note workspace_id requirement in multi-workspace tool descriptions

Workspace-scoped tools already gain a required workspace_id parameter (with
its own schema description) in multi-workspace mode, but the tool's prose
description was unchanged. Append a note so models/clients that read the
description text know to pass workspace_id (and to call list_workspaces
first). Global tool descriptions are left untouched.

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

* refactor(mcp): trim multi-workspace tool/arg descriptions

The workspace_id note repeats across every workspace-scoped tool in each
tools/list, so keep it terse: description suffix "Requires `workspace_id`."
and arg description "Target workspace id (from list_workspaces)." to avoid
spending tokens on repeated boilerplate.

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

* fix(mcp): enforce script/flow path scopes for multi-workspace run-by-path

In multi-workspace mode runScriptByPath/runFlowByPath are the only way to run
scripts/flows, but they were authorized against the endpoint scope only — never
the caller's mcp:scripts:/mcp:flows: path scopes. A granular token could run
items outside its allowed paths (e.g. mcp:scripts:f/team/* + mcp:endpoints:*
running f/other/secret), and a mcp:endpoints:* token could run arbitrary
scripts.

Now these two endpoints are authorized by the script/flow scope of the
requested path (matching single-workspace mode's per-item tools): exposed in
list_tools only when the token grants some script/flow (McpScopeConfig::has_any),
and at call time the path is checked via is_allowed("script"/"flow", path).

Verified e2e: mcp:scripts:f/team/* runs f/team/* but is denied f/other/*;
mcp:endpoints:* alone no longer exposes or runs run-by-path.

Reported by Codex + Pi review on #10043.

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

* fix(mcp): deny run-by-path for mcp:favorites multi-workspace tokens

mcp:favorites sets granular=false, so the previous run-by-path scope check
(gated on `granular`) was skipped entirely — a default "Favorites only"
all-workspaces token could run any script/flow by naming its path, bypassing
the favorites restriction.

Favorites are an enumerated set reachable only through per-item tools, not by
arbitrary path, so they grant nothing for run-by-path. has_any() now returns
true only for mcp:all (not favorites), and the call-time check drops the
`granular` gate and relies on is_allowed() directly (already false for
favorites, true for mcp:all, pattern-matched for granular).

Verified e2e: mcp:favorites no longer exposes or runs run-by-path; mcp:all
still runs; granular script scopes still path-enforced.

Reported by Codex review on #10043.

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 23:32:30 +02:00
hugocasaandClaude Opus 4.8 3b0781761b fix(frontend): show nested restart button for subflows nested in containers (#10042)
* fix(frontend): show nested restart button for subflows nested in containers

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

* fix(frontend): keep nested-restart flat fallback anchored to the leaf

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 15:23:09 +00:00
Ruben Fiszel 40f93cee87 unblock EE CUDA image build on trixie by allowing SHA1 for NVIDIA repo (#10040) 2026-07-10 15:02:08 +00:00
hugocasaandClaude Opus 4.8 1c88242849 fix(frontend): show optimistic user message and fork-creation label before beforeSend (#10037)
* fix(frontend): show optimistic user message and fork-creation label before beforeSend

In AI chat, `sendRequest` previously set `loading` and pushed the user
message only after the `beforeSend()` hook completed. For forked sessions
`beforeSend` runs several sequential API calls (materialize session, flush
files, create workspace fork, load copilot config) that take seconds, while
the composer clears its textarea immediately. The result: the message text
vanished into a void with no bubble and no loading indicator until the fork
finished.

Now the user bubble and loading indicator are shown optimistically before
`beforeSend`, with context elements and the snapshot attached afterwards. A
general-purpose `loadingLabel` lets any `beforeSend` hook describe its
pre-flight work; the session hook sets "Creating workspace fork..." around
`commitSessionWorkspace`. If `beforeSend` throws, the optimistic bubble and
loading state are rolled back.

Fixes WIN-2150

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

* fix(frontend): make Stop/Escape cancel the send during the beforeSend pre-flight

Showing the loading indicator before beforeSend also exposed the Stop
button and Escape handler during "Creating workspace fork...", but the
abort controller was created after beforeSend, so cancel() had nothing to
abort and the request still fired once the pre-flight resolved.

Create the abort controller before beforeSend and check `signal.aborted`
after it: a Stop/Escape during the pre-flight now rolls back the optimistic
turn and skips the request. Factor the rollback into a shared helper reused
by the beforeSend-failure and cancel paths, and refresh the now-stale
beforeSend doc comment.

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

* fix(frontend): restore prompt and hand off queued message on pre-flight cancel

The pre-flight abort check rolled back the optimistic turn and returned
early, skipping the recovery the main cancel path runs. Because the input
clears its composer on send, a Stop/Escape during "Creating workspace
fork..." lost the typed prompt from both the bubble and the composer, and
bypassed the queued-message handoff.

Mirror the main "cancelled before usable output" path: restore the prompt
to the composer via the same restoreInstructions helper, or auto-send a
queued message when one is taking over, and return true so a parent
queued-flush doesn't re-queue the cancelled turn.

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 14:54:54 +00:00
Ruben Fiszelandrubenfiszel 38a190b53a chore(main): release 1.754.0 (#10017)
* chore(main): release 1.754.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
v1.754.0
2026-07-10 13:59:22 +00:00
GuilhemandClaude Opus 4.8 c5060a1e9a fix: scope AI-session flow/script editors to the session workspace (#10025)
* fix: scope flow script-edit drawer to session workspace and fix scroll

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

* fix: scope flow schema inference to session workspace

Thread an optional workspace through loadSchemaFromPath/loadSchemaFlow/
loadSchemaFromModule/loadFlowModuleState/initFlowState/pickScript/pickFlow
and pass the op (session) workspace at fork-context call sites, so a flow
opened in an AI session resolves path-referenced scripts/subflows against
the session workspace instead of the nav workspace.

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

* fix: scope script editor log panel and git-repo pickers to op workspace

LogPanel and the ansible git-repo viewer/picker read the nav workspace
directly; pass the script editor's op workspace so past-test results/logs
and git-repo resource/file lookups target the session workspace in a fork.

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

* docs: correct session pipeline trigger-editor workspace comment

The comment claimed session activation syncs $workspaceStore; SessionPicker
intentionally does not, so trigger create/edit/delete from a fork session's
pipeline canvas writes to the nav workspace. Document the known limitation.

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

* fix: forward op workspace to git-repo S3 file browser

GitRepoViewer scoped its own calls to the op workspace but rendered the
nested S3FilePickerInner without workspace={ws}, so the file list/preview/
metadata still queried the nav workspace with a session-workspace prefix.
Addresses Codex review on #10025.

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 13:51:16 +00:00
Ruben FiszelandClaude Opus 4.8 15f9e9b48f perf: skip redundant retry-chain job query for successful top-level scripts (#10035)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 13:48:37 +00:00
03535691d6 fix(frontend): open new script/flow/app in AI session (not-found + friendly tab) (#10028)
* fix(frontend): open new script/flow/app in AI session without "not found"

"Open in AI session" on a never-deployed item opened the session preview
against the friendly live-edited path (script.path / $pathStore) instead of
the URL draft path the editor loads and saves by, so get-by-path 404'd. It
also flushed only queued autosaves, so an untouched new item — which never
triggered autosave — had no draft row to load at all.

Target the URL draft path (userDraftPath / liveEditorDraftStoragePath;
raw-app already used appPath), and add UserDraft.forcePersist to materialize
a brand-new draft in beforeOpen, gated to never-deployed items where there is
no deployed baseline to discard against.

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

* fix(frontend): label a new session preview tab by its friendly name

A never-deployed item's preview tab read draft_<uuid> instead of the typed/
auto name. The sessions page can't reactively read a runtime cell's state
across reactive roots, so the live editor (SessionEditorTarget, handed the
runtime as a prop) now stamps a transient friendlyLabel onto the tab model —
which the page does observe — via a pure draftFriendlyLeaf helper. Unifies
scripts, flows and raw apps through one path.

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

* fix(frontend): address review nits on AI-session open

- Flow drawer (FlowEditorDrawer) mounts FlowBuilder with no
  liveEditorDraftStoragePath, so gating the AI button solely on it hid the
  session entry point there; fall back to $pathStore (the pre-PR behavior for
  those deployed-flow drawers) while the main editor still prefers the URL
  draft path.
- Clear a tab's stamped friendlyLabel when it is retargeted, so a draft tab's
  friendly name no longer lingers after navigating to a plain page.
- Trim the repeated persist-hook comments to satisfy the AGENTS.md comment rule.

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>
2026-07-10 13:39:52 +00:00
hugocasaandClaude Opus 4.8 6c521e9d87 fix(backend): propagate script timeout when restarting perpetual scripts (#10029)
Perpetual scripts (restart_unless_cancelled) re-pushed their restart job
with custom_timeout = None, so every rerun ignored the script's
configured timeout and fell back to the instance-level job_default_timeout.
Only the first run honored the script timeout.

Fetch the script timeout alongside restart_unless_cancelled (both cached
by the immutable script hash) and pass it as custom_timeout when
re-pushing the perpetual job.

Fixes WIN-2149

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 13:33:54 +00:00
Ruben FiszelandClaude Opus 4.8 c029d6dcde fix(security): drop --allow-run from Deno sandbox (GHSA-gj6h-vw66-mr8f) (#10039)
The `// sandbox` annotation (and global nsjail sandboxing) restricted Deno to
`--allow-run=git,/usr/bin/chromium`. Both binaries can be coerced into spawning
`/bin/sh`, escaping Deno's permission model:

- git via hook configs, e.g. `git -c core.fsmonitor='/bin/sh -c <cmd>' status`
- chromium via subprocess-launcher flags, e.g. `--renderer-cmd-prefix` /
  `--gpu-launcher`, pointed at a launcher the script writes into `./`

Because the subprocess is spawned by git/chromium — not Deno — it is invisible
to Deno's permission checks, giving any user with script-execution permission
arbitrary OS command execution (root, in the default worker container).

Critically, the Deno runtime is the ONE language never wrapped in nsjail (there
is no run.deno.config.proto; every other language has one). So for deno the Deno
permission model is the *entire* sandbox — there is no OS-level containment to
fall back on, and handing it any subprocess-spawning binary is an unconditional
escape regardless of the nsjail setting.

Fix: emit no `--allow-run` in the restricted path, denying all subprocess
execution. The advisory's alternative (inject `-c core.fsmonitor=false ...`)
doesn't apply — the user controls the git/chromium argv, so any injected
hardening is overridden. Admins who accept the risk (e.g. puppeteer) can still
re-add specific binaries via `DENO_FLAGS`.

Verified with both PoCs on a running worker: git and chromium invocations now
return `Requires run access to "<bin>"`; the sandbox escapes are closed.

Fixes WIN-2151

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 13:33:22 +00:00
Ruben FiszelandClaude Opus 4.8 689b20a470 fix(security): remove git from Deno sandbox allow-run (GHSA-gj6h-vw66-mr8f) (#10038)
The `// sandbox` annotation restricts Deno to `--allow-run=git,/usr/bin/chromium`.
git can be coerced into spawning `/bin/sh` via hook configs such as
`git -c core.fsmonitor=<cmd> status`, and that subprocess is spawned by git —
not Deno — so it is invisible to Deno's permission model. This let any user
with script-execution permission run arbitrary OS commands as root inside the
worker, fully defeating the sandbox.

The advisory's alternative (injecting `-c core.fsmonitor=false -c
core.hooksPath=/dev/null`) does not apply here: the user's own script invokes
git directly via `Deno.Command`, so Windmill cannot inject hardening flags into
that call. Removing git from the allowlist is the only complete fix. git was
originally allowed for git-sync-adjacent use, which no longer needs it.

Verified with the advisory PoC: git invocation now returns
`Requires run access to "git"` and the sandbox escape is closed. chromium
(puppeteer) support is preserved.

Fixes WIN-2151

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 12:51:09 +00:00
Ruben FiszelandClaude Opus 4.8 9feda57c15 perf: index v2_job(parent_job) to speed up run child-job listing (#10034)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 07:51:16 +00:00
hugocasaandClaude Opus 4.8 5a460dbec6 fix: accept bunnative language in AI chat flow step validation (#10030)
* fix: accept bunnative language in AI chat flow step validation

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

* chore: regenerate copilot flow schema from openflow spec

Run gen_openflow_schema.sh + minifiedOpenflowJson.sh instead of hand-patching. Also syncs three fields the checked-in generated files had drifted from since the last regen (reasoning_effort, reasoning_token_delta streaming event, aiagent tag).

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

* chore: regenerate system prompts for bunnative openflow schema

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 09:24:09 +02:00
AlexRV12andClaude Opus 4.8 5387076c1c fix(frontend): persist per-session preview panel resize width (#10031)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 09:23:43 +02:00
AlexRV12 3704d00956 fix: sync theme into session page preview iframes on toggle (#10018) 2026-07-09 19:56:50 +02:00
AlexRV12 d7a9b46ab9 fix(sessions): open test pane when enabling debug so the debug UI is visible (#9998) 2026-07-09 19:53:55 +02:00
GuilhemandClaude Opus 4.8 9036ac789f fix(frontend): name the draft in AI chat test-run confirmation (#10024)
* fix(frontend): name the draft in AI chat test-run confirmation

The confirmation card shown before an AI-chat test run displayed a
static, generic header ("Run script test"). Make it name the target
and clarify it runs the user's draft.

- Tool.confirmationMessage now accepts a function of the parsed args;
  shared.ts resolves it before setting the tool status.
- test_run_script/flow/step (global chat) build a dynamic header
  naming the script/flow/step, e.g. "Run a test of your draft of X".
- In-editor script/flow test-run tools say "Run a test of your draft".

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

* fix(frontend): fall back to tool name in YOLO tooltip for function messages

The auto-accept ("bypassed in current mode") tooltip rendered
confirmationMessage directly. Now that it can be a function of the call
args, render the tool name instead of the function source there.

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

* fix(frontend): use neutral wording in test-run confirmations

The global test-run tools fall back to deployed content when no draft
exists, so "your draft" could contradict what actually runs. Drop the
draft claim and just name the target: "Run a test of X".

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 14:45:16 +00:00
GuilhemandClaude Opus 4.8 368fd2d9e4 fix: resolve fork family/picker for superadmin visiting a non-member workspace (#10023)
* fix: populate fork base picker for superadmin visiting a non-member workspace

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

* fix: resolve fork family for superadmin across sidebar picker and scope header

Extract the superadmin-visited-workspace fallback into a shared useForkableWorkspaces composable and apply it to WorkspaceFamilyPicker and WorkspaceScopeHeader so the sidebar fork picker and its fork-count trigger resolve the family for a superadmin viewing a non-member workspace.

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

* fix: resolve superadmin-visited workspace name in the scope trigger chip

The sidebar scope trigger next to the fork picker read $userWorkspaces directly, so a superadmin viewing a non-member workspace saw its raw id instead of the resolved name/family. Thread the folded-in forkable list into WorkspaceScopeTrigger, and trim the now-duplicated per-site rationale comments to a pointer at the composable.

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 14:40:46 +00:00
GuilhemandClaude Opus 4.8 c537d45e49 fix(frontend): persist forked "Copy of X" script drafts (#10021)
* fix(frontend): persist forked "Copy of X" script drafts

Forking a script ("Copy of X"), hub-forking, or seeding a new draft from
a URL/YAML/JSON import opened the editor with pre-filled content, but the
saved draft never appeared in the scripts list.

The edit route suspends autosave for every `?new_draft=true` load
(`UserDraft.stopSync`) so the seed write doesn't post as the user's first
edit, expecting ScriptBuilder to lift it. ScriptBuilder's `restartSync`
only ran inside `if (script.content == '')`, so a non-empty seed (fork /
hub / import) skipped it and left autosave suspended for the session —
both autosave and explicit Ctrl+S then silently no-op'd, so the draft was
never written and never listed.

Add an `else if` branch for pre-filled `new_draft` seeds that runs the
same stores-gated restart cascade (restart only, no template seeding),
restoring parity with the empty-new-script flow. The empty-seed block is
unchanged.

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

* docs: condense scheduleRestartSync comments to ≤4 lines

Address Codex review P2: trim the helper and new-branch comments to the
core invariant per AGENTS.md's comment-length rule.

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 09:01:53 +00:00
GuilhemandClaude Opus 4.8 c139eed631 fix: session preview tab labels, splitter hover, and diff-drawer sizing (#10008)
* fix: show pending friendly path in new raw app session tab

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

* fix: reveal a subtle rounded grabber on the sessions chat/preview splitter on hover

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

* fix: cap session diff blocks so each item's card fits the drawer viewport

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

* fix: floor flow diff cap at its min height and tidy diff/splitter comments

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 01:54:58 +02:00
AlexRV12andClaude Opus 4.8 756979852c feat: add multi-select mode to copilot askUserQuestion (#10016)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 01:54:19 +02:00
GuilhemandClaude Opus 4.8 c000bbca28 fix(frontend): scope raw-app, flow and script editors to the session workspace (#10015)
* fix(frontend): scope raw-app/flow/script editors to the session workspace

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

* fix(frontend): scope flow and script editor operations to the session workspace

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

* fix(frontend): scope flow preview, inline-script creation and datatable schema to the session workspace

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

* fix(frontend): address Codex review — thread session workspace through flow resource pickers, script fetch, preview cancel/recording and path collision check

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

* fix(frontend): address Claude review — pass session workspace to preview FlowStatusViewer and align FlowChatManager guards

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

* fix(frontend): address Pi review — show acting workspace in script-not-found message and fetch picked script from it in EditorBar

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

* fix(frontend): address Codex review round 2 — thread session workspace into flow step test, raw-app inline runnable, inline editor toolbars and MCP OAuth path

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

* fix(frontend): address Codex review round 3 — thread session workspace into dynamic-input helpers and the flow-preview argument side panel (history/saved-inputs/captures)

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

* fix(frontend): address Codex review round 4 — thread session workspace into nested flow/script drawers, flow chat inputs and the flow input side tabs

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

* fix(frontend): address Codex review round 5 — thread session workspace into script-module fork/reload and key the raw-app schema cache by workspace

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

* fix(frontend): address Codex review round 6 — key the DB manager schema cache by acting workspace

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

* fix(frontend): address Codex review round 7 — thread session workspace into resource-valued arg pickers and the editor variable/resource helper drawers

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

* fix(frontend): scope the flow asset explorer's ResourceEditorDrawer to the acting workspace

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

* fix: thread acting workspace through flow asset explore controls

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

* fix: thread acting workspace through SQL REPL, secret args, helper forms, S3 inputs, saved inputs

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 01:53:43 +02:00
Ruben Fiszelandrubenfiszel 9ad6927231 chore(main): release 1.753.0 (#9997)
* chore(main): release 1.753.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
v1.753.0
2026-07-08 16:46:15 +00:00
Ruben FiszelandClaude Opus 4.8 f28ea9cb99 feat(db-health): add connection sizing guidance (#10014)
* feat(db-health): add connection sizing guidance

The Database Connections panel showed current/max connections but gave no
guidance on how to size max_connections for the deployment. Derive an estimate
from the live worker fleet: each worker instance shares a pool sized
DEFAULT_MAX_CONNECTIONS_WORKER + (workers - 1), and each server opens up to
DEFAULT_MAX_CONNECTIONS_SERVER (both overridable via DATABASE_CONNECTIONS).

The endpoint now returns live worker/instance counts, the default per-server
and per-worker pool sizes, the estimated peak worker connections, the reserved
superuser connections, and a recommended max_connections floor (workers + one
server + 25% headroom). Servers do not ping worker_ping, so the recommendation
assumes one server and exposes the per-server increment. The panel renders this
as a sizing breakdown and warns when max_connections is below the recommended
floor.

Fixes WIN-2147

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

* refactor(db-health): single source for pool-size constants + sizing tests

Address review: db_connect.rs kept its own copies of DEFAULT_MAX_CONNECTIONS_*
that duplicate the windmill_common constants the sizing guidance reads, so
tuning the runtime pool size would silently leave the guidance stale. Re-export
the windmill_common constants from db_connect.rs so there is one source of truth.

Add unit tests for compute_connection_sizing covering the zero-fleet, single
worker, multi-instance, and reserved-clamp cases.

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

* feat(db-health): 20% headroom and 200-connection minimum floor

Lower the sizing headroom from 25% to 20% and never recommend below 200
connections (postgres defaults to 100; cheap headroom for growth/bursts/psql).
Update the guidance message and unit tests accordingly.

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

* fix(db-health): honor DATABASE_CONNECTIONS in sizing recommendation

Address Codex P1: the runtime caps every process's pool at DATABASE_CONNECTIONS
when set (db_connect.rs), but the sizing guidance always used the default 50/5
pools. For a tuned deployment this under-estimated worker demand and could hide
a genuine under-provisioning (e.g. DATABASE_CONNECTIONS=100 with 5 instances is
500 worker connections, not 25).

compute_connection_sizing now takes the effective DATABASE_CONNECTIONS override
(read the same way db_connect.rs reads it): when set, each worker instance and
server pool is that value and the worker estimate is override * instances. The
response exposes server_pool_size / worker_pool_size (effective) and
database_connections_override; the panel renders both pool rows and labels them
(default) vs (DATABASE_CONNECTIONS), and the message states which source is used.
Adds a unit test for the override path.

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

* fix(db-health): exclude agent workers from connection sizing

Agent workers reach the API over HTTP (MODE=agent, Connection::Http) and hold
no postgres pool, but their pings still land in worker_ping (written server-side
by /api/agent_workers/update_ping). Counting them inflated the connection
estimate. Filter the fleet query by the worker-name prefixes: DB-connected
workers use "wk-" (WORKER_NAME_PREFIX), agent workers use "ag-"
(AGENT_WORKER_NAME_PREFIX). Only wk- workers/instances feed the estimate; ag-
workers are counted separately and surfaced as context ("N agent workers
excluded — they use HTTP, not postgres connections"). Adds a unit test.

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 16:42:39 +00:00
Ruben FiszelandClaude Opus 4.8 735f2b20c4 docs(cli): clarify workspace fork naming and parent-workspace context (Fixes WIN-2148) (#10012)
* docs(cli): clarify workspace fork naming and parent-workspace context

Expand `wmill workspace fork`'s help and interactive prompts so the two
positional arguments are self-explanatory:

- Command description now explains that the fork is created from the
  currently active (parent) workspace, that `workspace_name` is a
  friendly display name that may contain spaces (quote it), and that
  `workspace_id` is a bare slug auto-prefixed with `wm-fork-` which also
  determines the git branch name.
- Interactive name/id prompts reworded to match.

Regenerated system_prompts CLI guidance to reflect the new description.

Fixes WIN-2148

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

* feat(cli): default fork name to "<parent>'s fork", make it optional

The fork's display name is no longer effectively required — it now
defaults to "<parent workspace name>'s fork" (fetched via
get_workspace_name, falling back to the local profile name / id) and
stays fully overridable via the positional argument or interactive
prompt.

To produce this default, `setClient` and the parent-name lookup are
moved ahead of the name/id resolution. The id default is decoupled from
the possessive display name: when auto-naming, the id/branch slug is
derived from "<parent>-fork" (e.g. wm-fork-acme-fork) rather than the
awkward "<parent>-s-fork". Branch-rename forks keep their branch-derived
id.

Regenerated system_prompts CLI guidance.

Fixes WIN-2148

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

* docs(cli): fix workspace fork help — parent is branch-resolved, not active profile

Addresses the codex/pi review: the fork help said the parent is the
"currently active" workspace and told users to `wmill workspace switch`,
but createWorkspaceFork resolves the parent from the current git branch's
wmill.yaml mapping (tryResolveBranchWorkspace) and ignores the active
profile. Reword to describe the actual branch-based resolution.

Regenerated system_prompts CLI guidance.

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

* docs(cli): note branch-derived fork id default in rename workflows

Addresses the codex review: the `[workspace_id]` help and the interactive
prompt said the default id is derived from the name, but rename workflows
(non-base branch / --from-branch) keep the branch-derived default
(`branchDefaultId ?? branchToForkId(idBasis)`) to keep the id/branch
aligned with the branch being converted. Document that special case
rather than changing the intentional behavior.

Regenerated system_prompts CLI guidance.

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

* fix(cli): cap auto fork name at 50 chars for long parent names

Addresses the codex review: the "<parent>'s fork" default appended
"'s fork" to a parent name that can itself be up to 50 chars (varchar(50)),
so a parent name over 43 chars produced a default exceeding the limit and
tripped the effectiveName.length > 50 guard — failing `wmill workspace
fork --yes` (or accepting the interactive default) for a valid parent.
Truncate the parent portion so the generated default stays within 50.

Verified end-to-end: a 48-char parent name now yields a 49-char default
("... Team's fork") and the fork is created successfully.

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 16:41:32 +00:00
Ruben FiszelandClaude Opus 4.8 99d0047515 fix: name the offending item when a fork fails on a NUL escape (#10013)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 16:22:44 +00:00
hugocasaandClaude Fable 5 f65fe7bf58 fix: replicate external secret backend secrets when forking a workspace (#10007)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 14:59:26 +00:00
GuilhemandClaude Opus 4.8 b847ca2bc7 feat: condensed top bar for session preview editors (#10011)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 14:35:57 +00:00
hugocasaandClaude Fable 5 c4cb2f373b fix: preserve worker group tag override on 'Run again' (#10004)
* fix: preserve worker group tag override on 'Run again'

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: keep tag override in sharable hash on args change

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: disambiguate reserved __tag hash key from args named __tag

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: prefix carried tag in sharable hash and react to tag changes

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: re-resolve dynamic tags on 'Run again' with an explanatory note

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: treat only $args-templated tags as dynamic on 'Run again'

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: let a carried tag coexist with an arg named __tag via duplicate keys

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 14:35:33 +00:00
GuilhemandClaude Opus 4.8 32c398f27d feat(sessions): scoped preview refresh + multi-target live editors + pipeline preview (#10006)
* perf(sessions): scope preview-tab refresh to items a chat tool touched

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

* refactor(sessions): drop dead editor pane, scope raw-app reload by path

Multi-target migration P0. SessionWrapper's inline editor pane was dead (the sessions page always mounts it with hideEditor); remove it and the single-target machinery (setSessionTarget/pickEditorTarget/target-keyed editor views). Scope the raw-app file/runnable preview reload to args.path (the app's workspace path) instead of the session target.

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

* refactor(sessions): back editor state with per-(kind,path) cells

Multi-target migration P1. Replace the three per-kind singleton stores/slots with per-(kind,path) cell maps, created on demand and kept (eviction deferred to P3). The runtime's public interface is unchanged: the flowStore/scriptStore/savedScript/rawApp/... getters and slot(kind) now forward to the 'active cell' per kind (a single-target shim, tracked by activePath, removed in P2 when the UI mounts one editor per tab). loadFlow/loadScript/loadRawApp and syncPreviewWithDeployed operate on the resolved cell; load logic and semantics are otherwise unchanged, so loading one item no longer clobbers another's state.

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

* feat(sessions): mount every editable preview tab as its own live editor

Multi-target migration P2 — the behavioral flip. resolvePreviewTab no longer takes a target: any editable route (script/flow/raw_app) resolves to an in-process editor, so several items are live at once (iframes remain only for real pages and regular non-raw apps). Each editor binds its own per-(kind,path) cell; the draft codecs close over that cell's store so two editors never cross-write. The single-target shim (activePath + the flowStore/scriptStore/... getters + slot(kind)) is removed; runtime exposes flowCell/scriptCell/rawAppCell(path). Tab open/navigate dedupe by (kind,path) and no longer setTarget. setLiveEditorDraft is gated on the visible tab (isActiveTab) so N editors don't clobber the one-per-(workspace,kind) live-draft slot (path re-key deferred to P4).

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

* perf(sessions): evict unreferenced editor cells; drop dead warm-editor LRU

Multi-target migration P3. Bound the per-(kind,path) editor cell maps: pruneEditorCells drops every cell no open preview tab still references, wired to a new onTabsChanged adapter callback fired on each tab-set change — so closing or navigating a tab away from an item reclaims its cell (dedupe keeps <=1 editor tab per item, so a pruned item has no live editor to strand). Also remove the now-dead editorWarmIds/promoteEditorWarm/MAX_WARM_EDITORS warm-editor LRU: its only reader (SessionWrapper.mountEditor) was removed in P0, and mounted editors are already capped per-tab by mountedTabKeys.

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

* refactor(sessions): retire session.target; preview is fully tab-driven

Multi-target migration P4 (final). Remove the session.target field and setSessionTarget: the preview is driven entirely by the tab model now (P2). hydratePreviewTabs no longer seeds a tab from target (saved previewTabs only); openEditorInSession seeds the preview via resetSessionPreviewTabs; normalizeLegacySession drops the retired target field from old records. The setLiveEditorDraft focus gate (isActiveTab, one-per-(workspace,kind)) is kept as-is; a per-path re-key is a possible future refinement, not needed for correctness.

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

* docs(sessions): describe editor cells as-is, not by their refactor history

Address standards review: AGENTS.md requires comments describe the code as it is, not its drafting history. Drop the 'used to be per-kind singletons' / 'pre-refactor empty editor' / 'now' phrasings from the cell comments.

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

* docs(sessions): update stale runtime.rawApp.val comments to cell.store

Address spec review: two comments still referenced the removed runtime.rawApp.val accessor; the live code uses the per-cell store now.

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

* docs(sessions): fix editor-cell comments after main merge

Main's #9993 added svelte-ignore comments describing the old
runtime.savedFlow.val / runtime.rawApp.val singleton bindings. The
multi-target refactor binds each tab's own editor cell (cell.store /
cell.saved), so update the comment text to match; the ownership_invalid_binding
directives themselves remain correct (the targets are still runtime-owned).

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

* feat(sessions): restore data-pipeline preview as a live editor tab

The multi-target refactor removed the old single-target editor pane —
PipelineEditorView's only mount point — so open_preview(kind="pipeline")
opened nothing, even though the chat tool and system prompt still make it
the first step of pipeline authoring.

Route a /pipeline/<folder> preview tab to the in-process graph editor:
- previewRouter: parsePipelineRoute + resolvePreviewTab map the folder to a
  pipeline editor slot; PreviewSlot.editorKind gains 'pipeline'.
- previewTargetForSessionTarget('pipeline') returns the folder route target
  (was undefined); open() keeps a single pipeline tab and retargets it to the
  requested folder, since all pipeline tabs share one runtime.pipelineEditorState.
- PreviewTabHost mounts PipelineEditorView for the pipeline slot.
- PipelineEditorView gains an `active` prop; AI-helper registration and the
  live-badge poll now gate on isActiveSession && active.

Register the pipeline tools on the session's own chat, not the singleton:
PreviewTabHost mounts the view outside the SessionWrapper subtree that
provides the scoped aiChatManager context, so getAiChatManager() fell back to
the app-wide singleton — build_pipeline_node / edit_pipeline_node never
reached the session chat and the model fell back to write_script (whose draft
never appears on the canvas). Use runtime.manager directly instead.

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

* fix(sessions): scope list-page preview refresh to the page each tool changes

The scoped-refresh pass reloaded every open list-page preview tab on any
workspace mutation (reloadPages: boolean), so creating a schedule also
refreshed the Resources / Variables tabs.

Replace the blanket flag with the specific page paths each tool can change:
write_schedule → /schedules, write_resource → /resources, write_variable →
/variables, create_folder → /folders, write_trigger → the trigger kind's page;
delete/deploy/discard/rebase map their `type` to its page (none for
script/flow/app). Item-editor writes now reload no pages — their live editor
self-syncs. reloadTabs refreshes a list-page tab only when its own path is in
the touched set.

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

* refactor(sessions): drop the inert item-reload path; extract a tested previewReload module

Post multi-target, every editable item is a live editor whose reload() no-ops,
and the one iframe item kind (legacy drag-drop apps) is never emitted as a
scope — so the whole `scopes` half of the preview-reload machinery could never
fire. Remove it (PreviewKind, PreviewScope, scopeKey, itemTypeToPreviewKind,
pendingScopes, and the item-route branch of reloadTabs); the `pages` path
already covers every real reload.

Lift the surviving pure logic out of the 900-line route component into
previewReload.ts — toolReloadEffect(name,args) -> {pages} and a new
tabsToReload(tabs,pages) mirroring selectPreviewTabsToClose — and cover it with
previewReload.test.ts (per-tool page mapping, item kinds reload nothing, the
unknown/local-tool silent-stale guard, loc-over-url matching).

Also clear session.target leftovers: delete the unread EDITOR_TARGET_KINDS
export and rewrite five comments that still described the removed single-target
pane / target-record write.

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

* docs(sessions): state the preview-reload self-sync invariant once

Consolidate the "live editors self-sync, only list pages reload" rationale
to previewReload.ts and drop the drafting-history phrasings the review
flagged: the update_user_instructions incident and the "(not the runtime)"
contrast in sessionDraftCodecs.

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

* fix(sessions): follow the editor cell when a live tab retargets

Address PR review findings on the multi-target preview.

P1 (Codex) — draft sync stayed bound to the old cell after an in-place tab
retarget. useUserDraftSync captured `codec` once, but navigate() re-points a
live editor tab (script/flow/raw_app) to another item without remounting, so
path/workspace/ready followed the new item while the codec still read/wrote the
previous cell's store — cross-writing drafts. Make `codec` a reactive getter
like the hook's other inputs; SessionEditorTarget rebuilds it per path.

P2 (Claude) — navigate() now enforces the single-pipeline-tab invariant that
open() does: retargeting to a /pipeline/<folder> route focuses and re-points the
existing pipeline tab instead of turning the active tab into a second editor
racing the shared pipelineEditorState.

P2 (Claude) — the deploy-in-session handler peeked an editor slot via the
create-on-miss cell accessors, allocating an empty cell for items with no open
tab. Add a non-creating runtime.loadedEditorPath(kind, path) and use it.

P2 (Claude) — correct a SessionPicker comment left stale by the session.target
removal (the preview no longer seeds from a target).

Tests: two navigate() pipeline-invariant cases. npm run check 0 errors; 167
session unit tests pass.

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 14:34:13 +00:00
GuilhemandClaude Opus 4.8 fb12b23e01 fix: session preview editors and picker dropdown overflow (#10010)
* fix: constrain script/flow/raw-app editors to container height in session preview

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

* fix: clip session preview picker dropdown to popover so it stops overflowing the page

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 13:56:31 +00:00
GuilhemandClaude Opus 4.8 a00ee5196b feat: shared tab system, universal markdown code blocks, subtle scrollbars (#10003)
* feat: universal styled markdown code blocks with copy button and subtle scrollbar

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

* feat(sessions): use the shared DraggableTabs for the preview tab strip

The session preview tabs were bespoke markup; converge them onto the same
DraggableTabs component the raw-app editor uses, gaining drag-reorder and
keyboard nav. The active tab keeps its breadcrumb/router picker via a new
tabAccessory snippet, and tabs persist their new order.

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

* fix(sessions): keep the new-tab + button right after the last tab

Add an afterTabs snippet to DraggableTabs that renders inside the scroll row
after the tabs (unlike trailing, which stays pinned outside it), and move the
session preview "+" there so it sits next to the last tab.

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

* feat(tabs): use the subtle ScrollableX scrollbar for Tabs/TabsV2 headers

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

* style(sessions): use bg-surface for the preview tab strip

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

* style(tabs): add subtle shadow-sm to the selected DraggableTabs tab

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

* style(tabs): drop selected-tab shadow; session strip bg-surface-secondary/50

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

* style(sessions): drop persistent bg on preview bar buttons, hover-only

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

* refactor(scrollbar): share a .scrollbar-subtle utility across tabs and chat

Extract ScrollableX's hover-revealed scrollbar styling into a global
.scrollbar-subtle utility (both axes, size via --wm-scrollbar-size), have
ScrollableX consume it, and apply it to the AI chat message list so the chat
scrollbar matches the tabs.

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

* fix: address review — scope HighlightCode copy button, plaintext unknown fences, Tailwind ScrollableX

- HighlightCode: keep the subtle CopyButton + surface chip behind buttonsOnHover
  so the ~20 non-markdown callers keep the original light copy Button.
- MarkdownCodeBlock: unlabeled/unknown fences render as plaintext instead of
  being mis-colored as TypeScript; added common language aliases (ts/js/py/...)
  so real languages still highlight.
- ScrollableX: replace the custom <style> block with Tailwind overflow classes.

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

* style: make chat and session-sidebar typing dots slightly smaller

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

* fix: address auto-review — powershell fence to plaintext + reorder tests

- MarkdownCodeBlock: drop 'powershell' from the sql group so it renders
  plaintext instead of SQL-colored (no powershell highlighter in the map).
- sessionPreviewTabs.test.ts: cover reorder (reorders+persists, ignores
  unknown ids / keeps omitted at end, no-op when unchanged).

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

* fix: keep scrollbar-hidden on Tabs row as TroubleshootFlowTutorial selector hook

codex-review: removing scrollbar-hidden broke the tutorial's '.border-b.flex
.flex-row.whitespace-nowrap.scrollbar-hidden.mx-auto' selector. The class is
inert on the non-scrolling row (ScrollableX owns the scroll) but is kept as the
tutorial's stable hook.

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

* fix: preserve raw <pre> content in MarkdownCodeBlock (codex-review)

As the universal pre renderer, MarkdownCodeBlock also handles sanitized raw
HTML <pre>text</pre> from rehypeRaw, where the text is a direct child of <pre>
(no <code>). Fall back to that text child so raw pre content isn't dropped to
an empty block. Kitchen-sink sample gains a raw <pre> case.

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 12:01:05 +00:00
GuilhemandClaude Opus 4.8 286da005ef feat: AI chat background jobs tray with detach, approval and preview (#9982)
* feat(ai-chat): background jobs tray with detach, approval and preview

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

* feat(ai-chat): route exec_datatable_sql through the jobs tray

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

* feat(ai-chat): jobs tray — orange queued badge, 5-recent pagination, drop remove button

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

* fix(sessions): silence dev-only false-positive binding warnings

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

* fix(sessions): silence dev-only false-positive binding warning in FlowEditorView

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

* feat(ai-chat): auto-expand jobs tray on approval, close modal on resume

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

* feat(ai-chat): let the AI set a per-call inline wait before jobs detach

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

* feat(ai-chat): auto-resume the chat when a background job finishes while idle

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

* feat(ai-chat): merge jobs tray and edits bar into a segmented session bar

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

* fix(ai-chat): address review — canceled-job handling, cross-chat poll guard, tests

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

* fix(ai-chat): gray chip dot for canceled-only jobs instead of green

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

* fix(ai-chat): keep jobs segment right-aligned when there are no edits

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

* fix(ai-chat): address /review — drain snapshot, live region, a11y, leading-ellipsis, remove dev harness

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

* fix(ai-chat): announce all same-tick job completions; drop redundant aria-live

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

* fix(ai-chat): guard poller re-entrancy; datatable error fallback (auto-review P2/nit)

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

* fix(ai-chat): honor tool formatter on detached job completion; coalesce poller

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

* fix(ai-chat): persist tool result formatter so rehydrated detached jobs keep contract

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 10:11:29 +02:00
Ruben FiszelandClaude Opus 4.8 d467161117 fix: bump bundled Go CLIs to patched versions to clear image CVEs (#9996)
The runtime image bundles several Go CLIs whose pinned versions were built
with an outdated Go toolchain (go1.21.7 for kubectl/helm), which image
scanners flag for fixable Go stdlib CVEs. Bump each to the latest release
built on the current patched Go 1.26.4:

- kubectl 1.28.7 (EOL) -> 1.36.2 (latest stable)
- helm 3.14.3 -> 3.21.2 (latest v3; staying on v3 to avoid the Helm 4
  breaking changes for a bundled CLI users depend on)
- crane v0.20.6 -> v0.21.7

crane is also updated in DockerfileSlim/DockerfileSlimEe (the slim images
don't bundle kubectl/helm). The docker client comes from the floating
docker:29-dind tag, which already rebuilds to a current Go toolchain.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 00:25:41 +02:00
Ruben FiszelandClaude Opus 4.8 1ed979a2de refresh picomatch in lockfile to unbreak npm ci (#9994)
The ai-evals CI job's `npm ci` (frontend) failed with:

    npm error `npm ci` can only install packages when your package.json
    and package-lock.json are in sync.
    Missing: picomatch@4.0.5 from lock file

`picomatch` is a floating transitive: svelte-check pulls it as an
`optional peer` at `^4.0.4`, and vite/vitest/tinyglobby at `^4.0.x`. The
lock pinned 4.0.3/4.0.4, but 4.0.5 was published upstream. On a cold-cache
CI runner npm re-resolves those ranges against the registry and picks the
latest (4.0.5), which isn't in the lock — so `npm ci`'s sync check fails.
It passes locally only because a warm npm cache still serves 4.0.4.

Fix: `npm update picomatch --package-lock-only` (npm 10.9.8, matching CI's
node 22) to refresh every picomatch node to 4.0.5 (and the 2.x line to
2.3.2). Lockfile-only, all semver-patch; no package.json change. Verified
`npm ci --dry-run` is back in sync with a cold cache.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 22:12:35 +02:00
Ruben Fiszelandrubenfiszel 223e1569ce chore(main): release 1.752.0 (#9974)
* chore(main): release 1.752.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
v1.752.0
2026-07-07 22:10:10 +02:00
Ruben FiszelandClaude Fable 5 f7efb646bf fix(pipelines): live materialize/dataset editing — stale graph, phantom drafts, stale Save-all deploys (#9990)
* fix(pipelines): live materialize/dataset edits reflect on the graph; no phantom draft after deploy

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(pipelines): Save all deploys the open pane's live buffer, not the stale draft snapshot

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(pipelines): pin deployedFromPane to the shipped content so mid-deploy keystrokes still promote to a draft

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(pipelines): draft rename ping-pong loop, stale rename deploys, inactive-draft input lineage

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(pipelines): dedupe inferred-lineage overlay against accumulated edges; first draft teardown still captures reads

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(pipelines): record an authoritative empty read capture on uncaptured draft entries

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(pipelines): teardown skip compares lineage too, so access-only overrides still persist

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* style(pipelines): compress persist-back guard comments to the invariant

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 22:00:39 +02:00
AlexRV12andClaude Opus 4.8 a6276b5900 feat: smooth bursty AI chat streaming with a typewriter reveal (#9991)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 21:49:51 +02:00
GuilhemandClaude Opus 4.8 6b01caaf26 fix(ai): flow writer builds approval steps as scripts, not identity (#9985)
* fix(ai): flow writer builds approval steps as scripts with getResumeUrls, not identity

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

* test(ai-evals): accept rawscript or script for approval step type

The flow-writer prompt allows an approval step to be `type: rawscript`
or `type: script`, but the topLevelStepTypes check pinned an exact
`rawscript` match, so a valid `type: script` approval would fail
deterministically. Let the check accept a list of allowed types.

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 21:47:14 +02:00
GuilhemandClaude Opus 4.8 804178f5e1 fix(sessions): auto-rename regression + preview-panel and fork nits (#9993)
* perf(sessions): don't mount preview tabs when side panel is collapsed

* fix(sessions): cap metadata max_tokens so Anthropic auto-rename works

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

* fix(sessions): drop redundant -fork suffix from auto-generated fork names

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

* fix(sessions): default 'also delete forked workspace' to false

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

* fix(copilot): apply metadata max_tokens cap on the OpenAI Responses path

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 21:46:10 +02:00
GuilhemandClaude Opus 4.8 63e3e7735f lign copy button on fork-less workspace rows (#9992)
The hover-revealed copy button in the workspace picker sat flush against
the menu's right edge on fork-less rows, because only forked rows render
an expand chevron that insets the copy button. Reserve the chevron's slot
on fork-less rows so copy buttons align across rows and keep right padding.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 18:25:33 +00:00
GuilhemandClaude Opus 4.8 4bb82ad6cd feat: open runs/schedules pages from AI chat in session preview tabs (#9976)
* feat(copilot): open runs/schedules pages in session preview tabs

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

* fix(copilot): drop buggy in-place nav, always chip outside a session

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

* feat(copilot): open_page covers variables/resources/assets/audit-logs/settings, perm-gated

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

* feat(copilot): open_page adds folders, groups and all trigger kinds (EE-gated)

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

* feat(copilot): close_page tool to close session preview tabs

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

* fix(copilot): fail-closed on unavailable trigger_kind in open_page handler

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

* fix(copilot): gate open_page on operator_settings, keep open_preview mention preview-only

Gate the open_page page set on the workspace operator_settings for operators
(mirrors OperatorMenu) instead of hardcoding runs/assets, with an empty-enum
guard. Also move the open_preview cross-reference out of the always-on prompt
line into the preview-gated block so it isn't advertised when preview tools
are off.

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

* fix(copilot): gate open_page on the session's operating workspace

A session chat targets its own (possibly forked) workspace while $workspaceStore
stays on the navigation workspace, so operator_settings must be read for the
operating workspace, not the global store. Thread it through GlobalToolHelpers
so both setSchema (advertised enum) and the handler guard gate on the same
workspace; the global side-panel chat still follows the live store.

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 17:21:34 +00:00
GuilhemandClaude Opus 4.8 7046dc6dfb fix(sessions): scope fork session Edits to session-edited items only (#9989)
* fix(sessions): scope fork session Edits to session-edited items only

A session chat with an undefined modified-items mask fell back to showing every draft in its (possibly forked) workspace, so the Edits bar/diff drawer listed all fork drafts instead of just what the session edited. Always track session chats: seed an empty mask for legacy chats in loadPastChat and guard the not-yet-persisted-chat case in initRuntime.

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

* docs: clarify session chats always persist their modified-items mask

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 17:21:11 +00:00
Ruben FiszelandClaude Fable 5 88c2d0e8e3 feat(cli): clarify fork-branch workspace auto-targeting in output (#9988)
* feat(cli): clarify fork-branch workspace auto-targeting in output

* fix(cli): auth comes from saved profile, not wmill.yaml, in fork notes

* fix(cli): consolidate workspace resolution logs, fork-target last-used profile

* chore: regenerate system prompts

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(cli): fork-target interactively created profiles, dedupe workspace line

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 17:08:09 +00:00