Commit Graph

13905 Commits

Author SHA1 Message Date
hugocasa e33bc30ff3 feat(git-sync): gate GitHub PRs on Windmill CI test results (WIN-2051)
Add a "Windmill CI tests" GitHub check run on any PR against the tracked
branch, so a workspace-fork customer can mark it a required status check and
have Windmill's own CI tests (the `// test:` annotation) block the PR —
replacing the GitHub Action that polls the CI-test results API.

Driven by the pull_request webhook (same event as the Phase 4 diff check): a
new git_sync_ci_test_check table tracks one check per (fork workspace, PR head
commit); a per-ci_test-job completion hook (result_processor) and the git-sync
poller sweep (monitor) conclude it. Reuses the Checks: write grant from #9552;
token repos keep the documented Action. See docs Phase 7.

EE logic lives in windmill-ee-private (git_sync_ee.rs); see ee-repo-ref.txt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 18:12:29 +02:00
hugocasa e57973cbd9 docs(git-sync): frame permission update against GitHub Actions, not polling
Existing installations don't have polling; their git-to-Windmill direction
runs on GitHub Actions today, so the approval text describes the update as
replacing those workflows and notes every feature is opt-in.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-14 13:20:20 +02:00
hugocasa 41029678c4 docs(git-sync): GHES self-managed app permission setup
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-10 11:13:54 +02:00
hugocasa 52a1547651 feat(git-sync): default the managed PR on for new app-backed promotion repos
A promotion deploy's wm_deploy/** branch exists to be merged; without a PR
it's an orphaned branch. Fork PRs stay opt-in. Also scope the sync-repo
auto-pull default to sync mode so promotion repos can't pick it up.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-09 21:09:41 +02:00
hugocasa 41f33b65c0 fix(git-sync): fork PRs are opt-in on new connections too
Only auto-pull and fork sync default on for new app-backed connections;
opening pull requests stays a deliberate per-repo decision.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-09 21:02:00 +02:00
hugocasa 8f08d0e460 copy(git-sync): fork workflow hint links to git_sync#github-actions
open-pr-on-fork-commit is documented on the git_sync page, not deploy_gh_gl.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-09 20:51:24 +02:00
hugocasa a0e67a0bc1 copy(git-sync): anchor docs links to their exact sections
GitHub App references point at integrations/git_repository#github-app, the
workflow hints at deploy_gh_gl#github-actions-setup, and the sync workflow
at git_sync#github-actions (all anchors verified against the live docs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-09 20:45:35 +02:00
hugocasa a3f83f1e7c copy(git-sync): keep the GitHub Action conflict note on app repos
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-09 20:42:03 +02:00
hugocasa 8c90043aad copy(git-sync): single info box for token-repo pull guidance
Merges the instant-pull recommendation with the GitHub Action conflict note,
shown only for non-app repos; app repos need neither, and the redundant
'instant webhook sync requires' line is gone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-09 20:39:29 +02:00
hugocasa 5ee9ca9b23 feat(git-sync): app-aware pull defaults, always webhook delivery, token-repo guidance
- Pull-from-Git defaults on only for app-backed repos (applied when the
  selected resource resolves); polling is opt-in for token repositories,
  with a warning alert recommending the GitHub App (instant pull + in-app
  PRs) or the sync GitHub workflow
- App repos always use webhook delivery with polling fallback: the delivery
  selector is gone and a stored polling mode is normalized back to auto
- Post-save modal reflects the auto-pull state instead of telling the user
  to turn on a toggle that is already on
- Non-app PR hints recommend the GitHub App explicitly

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-09 13:47:44 +02:00
hugocasa fdce2d40d3 fix(git-sync): runtime license gate for in-app PR creation
promotion_open_prs/fork_open_prs are rejected on save without an Enterprise
plan (like auto_pull), and the deploy completion hook re-checks the plan
before opening PRs so flags stored while licensed stop driving GitHub calls
after a lapse.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-09 10:43:39 +02:00
hugocasa b812cd3c56 fix(git-sync): resolve branch-less resources' default branch for fork sync
A git resource without an explicit branch polled as the bare "HEAD" ref,
which the fork/dev-label fan-out cannot scope (wm-fork/<branch>/*), so fork
sync silently never ran on polling-only repos. Resolve the remote's default
branch name with `ls-remote --symref HEAD` (one call for name + head sha);
"HEAD" only remains when resolution fails. The polling e2e test now uses a
branch-less resource to cover this shape.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-09 10:29:55 +02:00
hugocasa 419fdef8b2 copy(git-sync): both directions in page/card descriptions; clearer promotion flow
- Page header and sync-card description mention the pull direction, not only
  push-on-deploy
- Promotion description walks the actual flow (wm_deploy/** branch, merge to
  promote, sync the target workspace) and points at the PR toggle / workflow;
  the Git Promotion docs link now also shows on configured cards, not only in
  the empty state

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-09 09:56:15 +02:00
hugocasa 319872b567 style(git-sync): inline EE badge on gated toggles (matches settings nav)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-09 09:50:30 +02:00
hugocasa dabb6b877f fix(git-sync): targeted jsonb update for open_pr_error (no full-blob clobber)
The full read-modify-write raced the poller's concurrent last_synced_sha /
last_pull_status writes on the same column; mirror the EE status writer and
update only the matching repository element's open_pr_error key.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-08 20:13:10 +02:00
hugocasa 1d2680e03c chore(git-sync): bump pull script pin to hub/28787 (synthetic PR ref support)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-08 19:48:33 +02:00
hugocasa 6301d3fb6c fix(git-sync): no parent-only defaults on fork repos; rename strips webhook state
- addSyncRepository skips the auto_pull/fork_open_prs defaults on fork/dev
  workspaces where the backend rejects them (saving a new sync repo from an
  EE fork 400'd deterministically)
- change_workspace_id strips webhook id/secret/error from the copied git_sync
  and deletes the stale GitHub hooks post-commit: they deliver to the old
  (archived) workspace URL, so the new workspace would report a live webhook
  while polling at the relaxed interval; next save re-registers cleanly
- EE: PR diff checks for contributor-fork PRs clone the synthetic
  pull/<n>/head ref (head.ref doesn't exist in the base repo)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-08 19:34:12 +02:00
hugocasa 6a90fe7a9f chore(git-sync): bump hub script pins (push 28786, pull 28785)
Published from windmill-integrations #163 with windmill-cli@1.753.1-gitsync.0:
dev-workspace label deploys, fork-of-dev rooting, fork checkout on the
existing remote branch, and the pushed-flag result.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-08 19:25:17 +02:00
hugocasa 9438e7cfa0 Merge remote-tracking branch 'origin/main' into explore-git-sync-improvements 2026-07-08 19:05:16 +02:00
hugocasa 9a234fb7f6 fix(git-sync): detach clears standalone parent; reject label == tracked branch
- detach_dev_workspace clears parent_workspace_id for prefix-less (attached
  standalone) workspaces so they stop classifying as forks and deploying to
  wm-fork/** branches; wm-fork- re-designated forks keep their parent; cache
  invalidations mirror attach
- dev-workspace create/attach reject an environment label that equals a
  git-sync repository's tracked branch (prod's or the candidate's): deploys
  would target the very branch the repo syncs from, and the CLI guard would
  fail every push job after the fact
- CLI unit tests: prefix-less fork beats wm_deploy derivation; isForkWorkspace
  parent-id argument

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-08 18:55:19 +02:00
Ruben Fiszel 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 Fiszel 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 Fiszel 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
hugocasa 1aa8e1665e fix(git-sync): license-gate preserved auto-pull; attach strips parent-only settings
- edit_git_sync_repository re-checks the runtime Enterprise gate against the
  EFFECTIVE repo state after preservation: the older-client arm copies the
  existing auto_pull back, which the request-side check never saw
- attach_dev_workspace now mirrors the fork-creation copy on the attached
  workspace's own git sync: promotion repos dropped, auto_pull/fork PRs/PR
  error stripped, and any managed webhook deleted after commit (the attached
  workspace is parent-managed and must not keep pulling its old tracked branch)
- integration test: attaching an auto-pull-enabled workspace strips it

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-08 18:39:07 +02:00
hugocasa 5787c2c355 fix: cfg-gate scope-note helper (dead code on OSS builds)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-08 18:32:52 +02:00
hugocasa 3ab398d6fc feat(git-sync): clearer card copy/structure; surface PR-creation failures
- Fork sync toggle renamed and kept in the pull section; the fork PR toggle
  moves to the push section with a note that push settings apply to forks
- Fork/dev workspaces' push section names their actual branch instead of the
  tracked-branch line; promotion repos hide the pull direction (promotion
  pushes deploy branches on top of a sync-mode setup)
- Promotion mode line describes the wm_deploy/** branch + merge-to-promote
  flow; workflow-fallback hints lead with the how-to and link to the docs;
  test connection button demoted from accent per brand guidelines
- New server-owned open_pr_error on repo settings: the deploy completion hook
  records why a PR couldn't be opened (e.g. app permission not yet approved)
  and clears it on the next success; shown as a warning under the PR toggles

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-08 18:26:49 +02:00
Ruben Fiszel 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
hugocasa 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
hugocasa 78b7dd5103 fix(git-sync): explain in-sync PR verdicts with the repo's sync filter scope
A PR that only touches files outside the repository's include paths gets
"In sync", which reads as a wrong verdict; the check summary (and managed
comment) now name the filters, e.g. "Only files matching this repository's
sync filters deploy on merge: `f/**` (excluding `f/pat/**`)."

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-08 16:49:57 +02:00
Guilhem 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
hugocasa 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
Guilhem 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
Guilhem 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
hugocasa 132197e30c fix(git-sync): runtime license gate for auto-pull saves; user/group promotion-branch parity
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-08 14:36:06 +02:00
Guilhem 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
hugocasa 41cc2072ac test: auto-pull e2e integration tests; fix PR comment table formatting
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-08 12:58:08 +02:00
hugocasa 0307b7fda6 chore: refresh package-lock after main merge (windmill-utils-internal 1.8.2)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-08 12:06:52 +02:00
hugocasa 5aab289854 Merge remote-tracking branch 'origin/main' into explore-git-sync-improvements
# Conflicts:
#	backend/ee-repo-ref.txt
2026-07-08 12:00:39 +02:00
hugocasa c8ff4e6096 fix(git-sync): EE-gate auto-pull UI, fork pull clone_ref, no-op push PR gate
- CE: the auto-pull and fork-PR toggles are disabled with an EE badge, and
  new sync repos only default them on when licensed (basic git sync is
  available on CE since #8493, but auto-pull is EE and the backend rejects it)
- The pull modal passes clone_ref for wm-fork- forks (wm-fork/<tracked>/<id>)
  so a manual pull fetches the fork branch instead of the tracked branch head
- PR-on-deploy skips no-op pushes: when the push script reports pushed=false
  (e.g. the deploy was caused by an auto-pull), the completion hook no longer
  ensures a PR, so closed PRs aren't recreated by the sync loop

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-08 11:29:23 +02:00
Guilhem 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
hugocasa cc552f06e2 feat(git-sync): PR deploy-preview comment, clearer check copy, app-only hints
- The PR diff completion hook maintains one managed comment on the PR
  (Cloudflare deploy-preview style: workspace, status, commit, collapsible
  change list), upserted per synchronize via a hidden marker. The check run
  stays for required-check gating.
- A settings difference in the diff summary is worded by cause: the PR
  changes wmill.yaml, vs pre-existing drift between the repo's wmill.yaml
  and the workspace, vs undetermined (neutral wording).
- Deploy-status check titles name the target workspace ("Deployed 2
  change(s) to staging"), since GitHub shows a head commit's checks on any
  PR containing it and a bare "Deployed" read as if the PR had deployed.
- Token-based repos see a hint pointing at the open-pr-on-commit /
  open-pr-on-fork-commit workflows where the app-only PR toggles would be;
  an API-set toggle on a non-app repo now logs a warning naming the
  fallback; the design doc lists app-only features and their degradation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm
2026-07-08 09:56:49 +02:00
Ruben Fiszel 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 Fiszel 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 Fiszel 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 Fiszel 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
AlexRV12 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
Guilhem 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
Guilhem 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
Guilhem 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
Guilhem 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