* fix: handle singlestepflow zombies and stop filtering them from runs page
* fix: support singlestepflow in batch_rerun_jobs
Previous PR added singlestepflow to list_selected_job_groups so the BatchReRun
pane shows them, but batch_rerun_jobs_inner still joined on kind = 'script' /
'flow' with j.runnable_id (which is NULL for SingleStepFlow), so the rows were
silently filtered out — user sees the option, click Re-run, gets zero successes.
Mirror the norm_kind CTE projection from list_selected_job_groups inside
batch_rerun_jobs_inner: pull the wrapped runnable type and pinned script hash
from raw_flow.modules[id='a'], cast back to JOB_KIND so the existing handler
dispatch works unchanged. Path-based schema fallback so input_transforms still
resolve at rerun time.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: project singlestepflow in batch-rerun schema lookups
Codex review pointed out two follow-on regressions from the previous fix:
(1) list_selected_job_groups returned schemas with script_hash=null and
schema=null for singlestepflow rows because the inner schemas subquery still
joined runnable metadata via j.runnable_id (NULL for SingleStepFlow). The
BatchReRun pane consumes every selected.schemas entry through
mergeSchemasForBatchReruns / buildExtraLibForBatchReruns, both of which
assume real schema objects.
(2) When use_latest_version=true, batch_rerun_handle_job re-fetched
latest_schema from v2_job filtering jb.kind='script' or 'flow' — neither
matched singlestepflow, so schema came back NULL and every input_transforms
entry silently no-op'd.
Both queries now project singlestepflow rows via raw_flow.modules[id='a'] —
norm_kind for dispatch and effective_hash for the schemas join, plus a
path-based latest-schema fallback so flow-wrapped SSF (no version pinning)
and any SSF whose pinned hash has been deleted still resolve.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test: add batch_rerun integration tests, fix SSF hash hex parsing
Adds 11 integration tests against /jobs/run/batch_rerun_jobs and
/jobs/list_selected_job_groups (both endpoints had zero CI coverage).
Tests cover the full 4-kind × 3-mode matrix: regular Script and Flow
(baseline regression for the SQL refactor), script-wrapped and flow-
wrapped SingleStepFlow (regression for the bugs this PR fixes), and a
mixed-kind batch.
Writing the tests caught a real bug in the previous commit: ScriptHash
serializes as a 16-char hex string in raw_flow.modules[a].value.hash
(per the custom Serialize impl in windmill-types/scripts.rs), not as
an integer. The earlier `(m->'value'->>'hash')::bigint` cast worked
on the hand-inserted SQL fixture I'd used for live testing (which
embedded the hash as a raw integer) but failed in production where
all SSF jobs are pushed via JobPayload::SingleStepFlow's serialized
form. Replaced with `('x' || lpad(hex, 16, '0'))::bit(64)::bigint` —
preserves the twos-complement bit pattern so both positive and
negative i64 hashes round-trip correctly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Update SQLx metadata
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
* Navigate with arrows
* Jumps to other side item + load 30 more
* No workspace selector
* Recommendations Claude check
* Navigation horizontal
* Same
---------
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
* fix(cli): resolve cross-folder relative imports during lockgen on fresh DB
On a fresh workspace, lockfile generation for scripts that imported other
scripts via cross-folder relative imports (or barrel re-exporters) failed with
"Failed to find relative import" because the dep job's bun build hit the
server before any helper was deployed. Three independent bugs combined to
produce this:
1. wmill sync push --auto-metadata regenerated locks per script without
building a DoubleLinkedDependencyTree or calling uploadScripts, so
temp_script_refs was never sent to dependencies_async.
2. wmill script generate-metadata (the deprecated alias) had its own old
in-line implementation that bypassed the tree entirely.
3. The TypeScript WASM parser dropped re-exports (export * from, export { x }
from) when called with skip_type_only=false — the path used by
parse_relative_imports — so barrel files looked like leaves to the CLI's
dependency tree and their sibling helpers were missing from
temp_script_refs.
Fix:
- sync.ts: --auto-metadata mirrors generate-metadata's flow (dryRun pass to
populate tree → propagateStaleness → uploadScripts → real pass with tree).
- script.ts: deprecated wmill script generate-metadata now delegates to the
canonical generateMetadata, which already does the tree+upload dance.
- parser-ts: visit_export_all and visit_named_export had inverted skip_type_only
guards; aligned with visit_import_decl's pattern.
Includes 4 E2E tests reproducing each customer-hit failure path and a Rust
unit test for the re-export parser fix.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: bump windmill-parser-wasm-ts to 1.695.0
Pin the parser package to the version published with the re-export fix
(visit_export_all / visit_named_export skip_type_only=false) so the CLI
and frontend pick it up at the next release.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(cli): restore legacy stale-check in deprecated alias, add tree to gen pass
Delegating wmill script generate-metadata fully to the canonical handler
broke 4 workspace_deps_filter tests that rely on the legacy hash-with-deps
formula and the "No metadata to update" output string.
Restore the original in-line implementation (legacy stale-check preserved),
but add a DoubleLinkedDependencyTree + uploadScripts pass before the actual
generation step. The customer's bug only manifests on real lockgen, not on
the dry-run staleness check, so this preserves the existing test contract
while still fixing cross-folder relative imports for the deprecated alias.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(flows): inherit flow_env in sub-flow predicates
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(flows): align flow_env lookup with get_root_job_id and tighten gate
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(flows): drop recursive CTE, root_job propagation suffices
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(flows): walk via flow_innermost_root_job to respect imported-flow scope
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(flows): remove flow_env API endpoint, dead code from deno_core era
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The config module imports node:fs/promises (stat, mkdir), which breaks
non-Node bundlers like the Cloudflare Workers build of the hub. The
windmill SPA frontend got away with it via tree-shaking, but stricter
runtimes choke on the bare node: import even when unused.
Stop re-exporting ./config from the main entry and expose it via a
windmill-utils-internal/config subpath instead. CLI code already
deep-imports the source file, so it is unaffected. Bumps the package
to 1.4.0 and updates the frontend dependency to match.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: add ai chat resource action buttons
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: avoid proxied drawer state equality
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: show tool action cards
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Workspace rows in the sidebar picker and the Edit button on the run detail
page now render as `<a href>`, so middle-click and Ctrl/Cmd-click open
them in a new tab. Plain clicks keep their existing in-tab behavior
(workspace store switch / args prefill via `$initialArgsStore`).
The Edit href carries `?workspace=<current>` so the new tab loads the
editor in the same workspace as the run.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(cli): add --as-superadmin flag to workspace list-remote
Wires the existing /workspaces/list_as_superadmin endpoint into the
CLI so superadmins can enumerate every workspace on an instance from
CI tooling, not just the ones the calling user is a member of.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: regenerate CLI prompts and document the regen step
Adds an AGENTS.md note pointing to system_prompts/generate.py so future
CLI command edits keep the agent-facing CLI docs in sync, and
regenerates the auto-generated outputs for the new --as-superadmin flag.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
REVIEW.md is shared across Claude/Codex/Pi reviewers; CLAUDE.md is
Claude-specific noise that doesn't belong in cross-CLI review policy.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Policy is not GitHub-specific (also used by local-review skill); .github/
keeps only CI-tool output-format shims (codex/pi/claude prompt files).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ci: make local-review a single-source-of-truth cross-agent skill
The repo already had parallel skills directories (.agents/skills/ and
.claude/skills/) drifting between agents. Consolidate local-review
onto one canonical file in .agents/ and symlink the .claude/ entry to
it so Claude Code and Pi share the exact same SKILL.md (Anthropic's
Skills format is supported by both, only the discovery directory
differs).
The canonical SKILL.md now points reviewers at
.github/review-prompt-shared.md as the policy source — same shared
prompt the GitHub auto-review workflows already use — so local
reviews and CI reviews stay in lockstep.
Codex CLI doesn't support repo-level slash commands (its prompts live
in ~/.codex/prompts/). For Codex parity, ship scripts/local-review.sh
which pipes the SKILL + shared policy into 'codex exec' (or 'pi -p'
as a uniform entry point). Update AGENTS.md to document the three
invocation paths.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ci: make all skills cross-agent — single source in .agents/, symlink .claude/
Turn every skill into a single canonical file under .agents/skills/ and
a symlink under .claude/skills/. Editing any one SKILL.md now updates
all three CLIs (Claude Code reads .claude/, Codex and Pi auto-discover
.agents/).
Per-skill resolution:
- local-review: already symlinked (prior PR #9037)
- rust-backend, svelte-frontend: identical content → symlink, no edit
- refine: only differed in user_invocable frontmatter → add to canonical
- native-trigger: .claude/ had a newer Step 17 (sidebar visibility)
missing from .agents/ → use Claude content as canonical
- commit: .claude/ embedded a Claude-specific Co-Authored-By trailer
the harness already injects automatically → drop from canonical, use
agent-neutral .agents/ version
- pr: generalize "Run /local-review" to "Invoke the local-review skill
(/local-review in Claude Code, $local-review in Codex, pi --skill
local-review in Pi)" and drop the Claude-specific "Generated with
Claude Code" attribution from the PR body template — the harness
that invoked the skill can add its own trailer if desired
- adding-a-trigger: was only in .claude/ → move to .agents/ canonical
- update-sqlx: was only in .agents/ → add .claude/ symlink
Also drop scripts/local-review.sh — wrapper is redundant now that all
three CLIs natively discover the skill from their respective
directories. Update AGENTS.md accordingly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ci: share review policy across Claude/Codex/Pi via review-prompt-shared.md
All three reviewers now consume a single canonical policy document
(.github/review-prompt-shared.md) covering AGENTS.md compliance,
severity triage (P0/P1/P2), and a checklist for new public surfaces
(auth contract, module placement, half-finished pub fns, input
validation). Each tool's own prompt file shrinks to just its
output-format quirks, and each workflow concatenates shared +
tool-specific at runtime before invoking the model.
Drops the suppressive "Prefer at most 10 findings" / "Keep the review
high signal. If there is no clear issue, return no findings" wording
from Codex and Pi, which was clipping P1 and P2 findings (e.g.
half-finished pub fn, blocking I/O, wrong module placement).
Replaces it with severity triage so both reviewers report all P0/P1
and surface P2 when the diff invites it. Also makes AGENTS.md
authoritative for Codex (was CLAUDE.md, which is just @AGENTS.md in
this repo) and adds an explicit "new public function" checklist that
covers the missing-auth-check failure mode none of the three reviewers
flagged on the test PR.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ci: move test-coverage assessment to shared prompt, slim per-tool prompts
- Replace per-tool 'Reproduction instructions' with a single shared
'Test coverage assessment' section that asks each reviewer to
evaluate automated coverage (sufficient / thin / appropriate) and
describe what manual verification remains, if any.
- Slim per-tool prompts to the absolute minimum: just where to read
context, the comment header, severity tagging, and the Pi-only 'no
preamble' constraint. Everything else lives in the shared policy.
- Drop the model name from Pi's title ('Pi Review (DeepSeek V4)' →
'Pi Review') — the title's job is to let the bot find its own prior
comment when re-reviewing; the model is irrelevant to the reader.
The titles ('## Codex Review', '## Pi Review') stay because Codex and
Pi both post as github-actions[bot], so the heading is the only
discriminator the bot can use to find its own past comment in the
prior-discussion context.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ci: scope test-coverage assessment to layers actually changed
Don't ask reviewers about integration tests on a frontend-only diff or
about playwright tests on a backend-only diff. The shared 'Test
coverage' section now lists categories (backend / frontend / CI-docs)
and tells the reviewer to skip the ones the PR does not touch — only
ask about Rust integration tests when backend handlers/workers/queues
were modified, only ask about frontend tests when components or state
machines were touched, and explicitly call out 'no automated tests
expected' for CI/docs/config diffs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ci: don't ask reviewers to flag missing frontend component tests
The Windmill frontend codebase doesn't generally test Svelte components
— existing tests cover pure-logic utilities only (flowDiff,
previousResults, copilot logic, dbtable queries, etc.). Asking
reviewers to flag every new component for lacking a test would produce
noise inconsistent with the established convention. Limit the
frontend test-coverage check to new pure-logic utilities (files that
would naturally have a sibling *.test.ts).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ci: point local-review skill at the shared review policy
Codex flagged (and Pi confirmed on its second pass) that slimming
.claude/review-prompt.md to output-only broke the local-review skill
contract — the skill still told Claude to read only that file for the
review criteria, so /local-review would no longer apply severity
triage, the public-surface checklist, or AGENTS.md compliance.
Update the skill to read .github/review-prompt-shared.md as the policy
source and .claude/review-prompt.md only for Claude output preferences.
Also align the local output format with the severity-tag convention
used by the workflow reviewers, and replace the lingering
'CLAUDE.md compliance' wording with 'AGENTS.md compliance'.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(flows): don't bubble error when continue_on_error is on the last step
When the last step of a flow (or branch/forloop) failed with continue_on_error
or skip_failures enabled, should_continue_flow resolved to false (because the
flow was at its last step), and the flow was completed with success=false.
This made parent flows / subflows treat the run as a failure even though the
user explicitly asked to continue past errors.
Detect this case and set success=true so the failure is captured in the
result but not propagated.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs: explain why success is overridden post should_continue_flow
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ci: re-review on push, thread prior PR comments into reviewer context
- Add 'synchronize' to all three review workflow triggers so each push
to a PR branch re-runs Claude/Codex/Pi. Existing
cancel-in-progress concurrency groups ensure only the latest push's
review actually executes.
- Fetch the most recent up to 20 PR comments before each review and
inject them into the prompt context so the reviewer can recognize
its own previous review, focus on what changed, and avoid repeating
findings the human already addressed.
- Update the three review prompts (Claude, Codex, Pi) to instruct the
reviewer to honor the prior-discussion section when present.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ci: bump codex CLI to 0.128.0 for gpt-5.5 support
Codex 0.117.0 rejects the gpt-5.5 model with 'requires a newer version
of Codex'. 0.128.0 is the current stable release on npm.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ci: limit synchronize re-trigger to pi review only
Re-running Claude and Codex on every push gets expensive fast on busy
PRs. Pi (DeepSeek-V4) is cheap enough to re-run per push, while
Claude/Codex remain on opened/ready_for_review and re-trigger via
slash commands.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ci: install bubblewrap for codex sandbox; stream pi progress in logs
- Codex's vendored bwrap fails to set up loopback on some ubicloud
runners, leaving codex unable to read any local files. Install the
system bubblewrap package before running codex so its read-only
sandbox works reliably.
- Switch pi to --mode json and pipe events through jq to surface
agent/turn boundaries and tool calls live in the GitHub Actions log,
matching codex's progress visibility. Final assistant text is
extracted from the saved event log into pi-final-message.md for the
PR comment.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ci: drop bubblewrap install, use codex -s danger-full-access
Codex's read-only sandbox uses bwrap which fails to set up loopback on
some ubicloud runners. Rather than apt-installing bubblewrap, switch to
the no-sandbox mode for parity with how Pi and Claude already operate
in the same workflow — runner is ephemeral and we trust the codex
prompt the same way.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ci: bump codex review model from gpt-5.4 to gpt-5.5
gpt-5.5 is positioned as the agentic successor to gpt-5.4 — same
per-token latency, fewer tokens to complete Codex tasks, and
explicitly stronger at holding context across large systems and
multi-tool reasoning, which matches the PR review workload.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ci: add Pi+DeepSeek-V4 review and slash command dispatcher
Auto-reviews now fan out to Claude (Opus), Codex (gpt-5.4), and Pi
(DeepSeek-V4-Pro) on PR open/ready. PR comments support /review (all
three), /codex, /pi, /claude with optional extra context appended to
the prompt. All review workflows now substitute EE code before review
and gate the auto-trigger path on org membership of the PR author.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ci: fix command parser whitespace, align checkout v5, broaden PR perms
- Trim leading/trailing whitespace from comment first line so /review
with leading space parses correctly (caught by Pi review)
- Standardize EE checkout step on actions/checkout@v5 across all three
review workflows (caught by Pi review)
- Bump pull-requests permission to write to satisfy GitHub's PR
comment endpoint when issues=write alone is rejected
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* [ee] fix(autoscaling): consider dedicated workers in scale decisions
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Update ee-repo-ref.txt
* [ee] fix(autoscaling): mirror worker tag precedence (worker_tags wins)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: update ee-repo-ref to 862d487032efe30d1e4a3cd0a1ed7169500c4cd9
This commit updates the EE repository reference after PR #556 was merged in windmill-ee-private.
Previous ee-repo-ref: cf87e9dcef2e95b1834b3f5c154209defc5a9ca2
New ee-repo-ref: 862d487032efe30d1e4a3cd0a1ed7169500c4cd9
Automated by sync-ee-ref workflow.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
Adds three subpath entries to the windmill-components package's `exports`
and `typesVersions` so external consumers (e.g. windmillhub) can import
these components without resorting to private `node_modules` aliases.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: bind MySQL table listing to configured database name
* refactor: drop DATABASE() sentinel and cover single-table fallback
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor: unify MySQL schema-resolution branches via explicit_db binding
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor: replace SELECT * with explicit column lists
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: update sqlx offline query cache
* chore: update sqlx offline query cache
* chore: update sqlx offline query cache with EE support
* chore: update sqlx offline query cache, no deletions
* chore: update sqlx offline query cache after rebase
* fix: correct column names in explicit script query lists
- concurrency_limit → concurrent_limit (matches DB column name)
- runnable_settings → runnable_settings_handle (matches DB column name)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: add missing delete_after_secs column to script queries
Also add integration test covering all explicit-column export queries.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test: add workspace export integration test covering all explicit-column queries
Covers tarball_workspace (folder, script, resource, resource_type, variable,
schedule, usr, group_) and the mcp_oauth_client SELECT query from windmill-mcp.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test: add tarball export integration test covering all explicit-column queries
Single test creates one of each entity type and exercises every runtime-checked
explicit-column query in tarball_workspace. Uses archive_type=tar to avoid
zip feature-gate in CI.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: fix stale verification step and CI contradiction in update-sqlx skill
- Regenerate current_files.txt after EE cache restoration so step 4 reports accurate diff
- Scope "Never use SQLX_OFFLINE=true" to local prepare (CI legitimately uses it)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: remove Co-Authored-By from commit skill template
* refactor: extract SCRIPT_COLUMNS const to single source of truth
Replaces 5 duplicated 44-column lists with a shared const in windmill-types.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* docs: add SAFETY comments to all dynamic SQL call sites
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: address review feedback on SAFETY comments
- Fix missed comment for obo_triggers loop in offboarding.rs
- Fix variable name in comment (table -> table_name) in offboarding.rs
- Fix api-settings comment to reference inline VALID_NAME regex, not validate_dbname()
- Add SAFETY comments to batch_execute calls in api-settings
- Fix db.rs comment: PG_SCHEMA is env var, not compile-time constant
- Add doc comments on RunnableSettingsTraitInternal constants
* docs: remove misleading SAFETY comment on static SQL
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(forks): strip mode/enabled from merge-UI deploy payload
The CompareWorkspaces merge UI deploys a trigger by fetching the full
GET response from the source workspace and spreading it into an
updateXTrigger call on the target. That spread includes `mode` (and the
legacy `enabled`), so a fork→parent (or parent→fork) deploy would
overwrite the target's enabled/disabled state — silently disabling a
parent's trigger when its config is merged from a freshly-cloned fork
(clones are forced `mode='disabled'`). Affects azure/email/gcp/http
whose `update_trigger` SQL writes the `mode` column.
Strip `mode`/`enabled` in `getTriggersDeployData` so the backend's
existing `is_mode_unspecified()` preservation in `update_trigger` keeps
the target row's `mode` untouched. The same preservation already
protects the YAML/CLI round-trip (where the tarball export strips these
fields); this extends the same guarantee to the merge-UI path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(forks): wire Azure and Email triggers through merge UI deploy
CompareWorkspaces.svelte already lists Azure and Email triggers in its
diff (`triggerServices`), but `getTriggersDeployData` and `existsTrigger`
were missing the corresponding branches. Deploying either kind from the
merge UI threw "Unexpected trigger kind". Add the branches with the
same `stripOperationalState` pattern as the rest, and extend the
`triggersKind` whitelist in `checkItemExists`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: surface scope errors as 403 and show real message in CLI
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address review feedback on scope error PR
- Backend: also patch handler-level check_scopes (lib.rs:223) — without
this, endpoints using check_scopes (scripts, flows, jobs, …) still
returned 401 for scope failures, which the CLI would render as the
misleading auth message.
- CLI: strip backend file refs and the duplicated "Permission denied:" /
"Not authorized:" prefix from the surfaced error body.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>