Commit Graph

18 Commits

Author SHA1 Message Date
Diego Imbert 7fb8a2e390 fix(parsers): keep s3 asset path suffix verbatim to preserve storage distinction (#10241)
* fix(parsers): keep s3 asset path suffix verbatim to preserve storage distinction

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01An2pTqSmqJd2XwnagvX4kM

* package json

* fix(pipelines): preserve named storage in generated TS/Python S3 URIs

The TS/Python templates emitted `s3:///${s3Key(path)}`, stripping the
leading slash and pinning the URI to default storage. For a named-storage
asset path (`secondary/key`) that produced `s3:///secondary/key`, which
resolves to the default storage with key `secondary/key`, dropping the
named-storage dependency and reading/writing the wrong object.

Emit the path verbatim after `s3://` (matching the DuckDB template) so a
named-storage input/output keeps its storage; identical to the previous
output for default-storage paths. Removes the now-unused `s3Key` helper.

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

* chore(cli): align bun.lock parser versions with frontend

The PR bumped windmill-parser-wasm-asset (1.749.0→1.753.0) and
windmill-parser-wasm-regex (1.692.0→1.764.0) in package.json and the npm
package-lock.json for both cli and frontend, but cli/bun.lock was left
pinned to the old versions. Sync it so the CLI's wasm asset parser (used
by localGraph inference) matches the frontend and deploy-time parser.

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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
2026-07-21 16:25:06 +00:00
Diego Imbert d24e176816 fix(parser): spurious pg arg inferred from placeholders in comments (#10226)
* fix(parser): ignore pg placeholders in comments, strings and dollar quotes

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NXWRDKzswMeDBP5THXpb9Q

* package json + lock

* chore: remove stray root npm lockfiles

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013kuUhCPD9ph4ZuFd13SCWJ

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 14:36:44 +00:00
hugocasa d0aa7dca13 fix: parse all names in grouped go param declarations (#10165)
* fix: parse all names in grouped go param declarations

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

* chore: bump windmill-parser-wasm-go to 1.761.0

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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 19:24:07 +02:00
Ruben Fiszel ad6f23d6bf fix(cli): HD-1 test_edges + HD-2 scd2 _current write in --local pipeline graph (#9947)
* fix(cli): emit HD-1 test_edges + HD-2 scd2 _current write in --local pipeline graph

Close the remaining local-vs-deployed graph parity gaps in `wmill pipeline
show <folder> --local` so it matches the deployed graph (backend
`asset_graph`, windmill-api-assets):

- HD-1 `test_edges`: synthesize ordering-only producer → tested-script edges
  from parsed `// data_test` annotations. A `relationships` test references
  its `to_path` asset; a custom `// data_test <script>` resolves best-effort
  against that script's parsed reads. Each referenced asset is resolved to its
  in-pipeline producer via the write edges; self-edges and producer-less
  (external) assets are dropped — mirroring the backend set semantics.
  Routed through the asset node in boundedCascade's lineage DAG (asset →
  tested script) so a cold/bounded cascade orders the referenced dimension
  first, matching the frontend.

- HD-2 scd2 `<dim>_current` companion write: a managed `// materialize …
  history` (scd2 && !manual) also produces a `<dim>_current` view. Register it
  as a second write edge and mark the asset `derived_from` its base dimension,
  so a consumer reading only the view links back to the producer instead of
  orphaning. Gated exactly like the backend `MaterializeSpec::write_targets` /
  `scd2_current_target`.

The pinned `windmill-parser-wasm-asset` (1.740.0) predates the `scd2`
materialize flag, so `buildLocalPipelineGraph` takes an injectable parser and
the HD-2 test injects one that re-adds `scd2` for a `history` materialize —
exercising the already-shipped companion-write branch until a wasm carrying
`scd2` is republished (cf. #9926).

Extends cli/test/pipeline_local_graph_unit.test.ts with HD-1 (relationships,
no-producer, self-test, custom) and HD-2 coverage.

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

* chore(cli): pin windmill-parser-wasm-asset 1.749.0, drop HD-2 test parser seam

Now that windmill-parser-wasm-asset 1.749.0 (which serializes the `scd2`
materialize flag) is published, bump the CLI pin and retire the temporary
injection seam:

- Remove the `infer?` parameter from `buildLocalPipelineGraph`; it always uses
  the wasm-backed `inferScriptAssets` again.
- The HD-2 `<dim>_current` companion-write test drives the real wasm directly
  (drops the `inferWithScd2` wrapper that re-added `scd2` against the pinned
  1.740.0 build).

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

* chore(frontend): pin windmill-parser-wasm-asset 1.749.0 to match CLI

Restore the CLI↔frontend lockstep on the asset parser wasm broken by the
previous commit: every other windmill-parser-wasm-* package is pinned to the
same version in both cli/package.json and frontend/package.json, so keep the
asset parser aligned too. The frontend derives materialize/scd2 from its own
TS annotation parser (`parsePipelineAnnotations`), so this bump only affects
body asset inference in the live graph — moving it in step with the CLI
`--local` graph and the deployed backend parser.

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-06 03:08:54 +02:00
Ruben Fiszel 744a7597ed fix(cli): publish all windmill-parser-wasm-* deps so local pipeline graph keeps write edges (#9926)
* fix(cli): publish all windmill-parser-wasm-* deps so local pipeline graph keeps write edges

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

* style: trim explanatory comment blocks to core constraints

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 12:14:22 +02:00
Ruben Fiszel 74f579e6d9 feat(pipeline): local development for data pipelines (CLI --local + pipeline dev preview) (#9840)
* feat(pipeline): local development for data pipelines (CLI --local + pipeline dev preview)

Add the local edit→preview→run loop for data pipelines (folders of `// pipeline`
scripts), the analog of `wmill dev` / `wmill app dev`, usable from a code editor
or an agentic loop — without deploying.

No backend changes: full body inference comes from the same wasm the frontend
uses (windmill-parser-wasm-asset), which returns assets + pipeline annotations in
one call; local runs reuse runScriptPreview with _wmill_skip_asset_dispatch.

- localGraph.ts: wasm-backed working-tree → asset-graph builder (the enabler)
- pipeline show/run --local; new pipeline docs (PIPELINE.md/AGENTS.md) subcommand
- pipeline dev watcher + /pipeline_dev page (PipelineDevView) rendering the same
  PipelineGraphEditor from the pushed local graph, run via preview
- cascadeRun.ts: reusable run primitives extracted from the route page
- regenerated CLI agent docs

See docs/pipeline-local-dev.md for the full design, test steps, and handoff TODOs.
The live `pipeline dev` browser preview is implemented but not yet stack-verified.

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

* feat(pipeline): improve local dev preview (run, activity, responsive)

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

* feat(pipeline): dev-preview args, multi-root run, ws auto-reconnect

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

* fix(pipeline): connect managed-materialize producer in local dev graph

The CLI pinned windmill-parser-wasm-asset ^1.728.1, which predates managed-materialize support (added in 1.733.1); the frontend already pins 1.740.0. The CLI's wasm therefore never emitted `// materialize`, so the producer had no output edge and showed disconnected from its `// on` consumers. Bump the CLI to 1.740.0 (matching the frontend) and translate the parsed materialize target into the producer's write edge + materialize_target, mirroring frontend resolveGraph.ts.

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

* fix(pipeline): harden local-dev CLI (bare-.sql crash, defaultTs, docs clobber)

Review fixes, complementary to the dev-preview/materialize/multi-root work already
on the branch (none overlap those commits):

- localGraph: a bare `.sql` (no dialect) made inferContentTypeFromFilePath throw and
  abort the whole graph build — and wedge `pipeline dev` at startup. Skip the
  unclassifiable file instead. Also map `bunnative` → parse_assets_ts and add
  ruby/rlang/nu/powershell to the `#`-comment fallback.
- show/run/docs/dev: thread the resolved `wmill.yaml` defaultTs into the graph
  builder so `.ts` infers under the workspace's runtime (bun vs deno) instead of
  always bun — `opts.defaultTs` was always undefined (no such CLI flag).
- dev: wrap the startup graph build so a half-written file can't abort the watcher.
- docs: don't clobber a user-authored AGENTS.md/CLAUDE.md — only (over)write the
  pointer when absent or already a generated `@PIPELINE.md` pointer.

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

* fix(pipeline): bind dev WS to loopback + local-graph regression tests

- pipeline dev WS broadcast the folder's full script source (scripts[].content + temp_script_refs) unauthenticated on 0.0.0.0:3201 — bind 127.0.0.1 so it's not LAN-reachable (webview localhost + SSH/devbox port-forward still work).

- Add regression tests for the just-landed local-graph fixes: bare .sql is skipped (was a build/dev-startup crash), defaultTs threads into .ts runtime inference (bun vs deno), and #-comment languages (ruby) use the # annotation fallback.

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

* feat(pipeline): --frontend flag for pipeline dev page origin

wmill pipeline dev opens <remote>/pipeline_dev, but that route only exists in this build's frontend, so it 404s against a remote whose deployed frontend predates it. --frontend <origin> points the page at a locally-run frontend (REMOTE=<remote> npm run dev) while the API/token still target the remote — enabling the live preview against a real backend before the PR is deployed. No behavior change when omitted. Regenerated CLI agent docs.

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

* fix(pipeline): WS session token + details-pane live-reload refresh

Addresses CI review (Codex/Pi/Claude):

- dev WS: a browser tab could open ws://localhost:<port>/ws and receive the folder's full source (browsers don't enforce same-origin on WS, loopback bind alone doesn't help). Gate the upgrade on an unguessable per-session token carried in the dev-page URL (verifyClient → 401 without it). Verified: no-token/bad-token connections get 401 with no bundle.

- details pane: scriptRes keyed on [workspace, selection, draftScript] didn't re-run on a pipeline dev live-reload (same selection), so the open pane showed stale source. Thread a localScriptsVersion (the pushed bundle) into the key. Verified: editing a selected node's file updates the pane source without reselect.

- docs/pipeline-local-dev.md: refresh the stale 'not yet exercised' status + done TODOs.

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

* fix(pipeline): emit volume: annotation assets in local dev graph

Addresses CI review (Codex P1 / Pi P1): the wasm body parser doesn't surface `// volume: <name>` annotations — the frontend (infer.ts:parseVolumeAnnotations) and backend (asset_inference.rs) parse them separately and merge as rw volume assets. localGraph didn't, so a `# volume: cache` producer had no write edge and showed disconnected from its `// on volume://cache` consumer (and pipeline run --local wouldn't schedule downstream). Mirror the leading-comment-block scan (SQL excluded, matching both reference parsers) and merge into inferScriptAssets. Regression test added; verified producer -> volume://cache -> consumer connects.

Also (Codex P2): docs/pipeline-local-dev.md manual browser URL omitted the new ws_token param — without it the WS upgrade is rejected and the page sits disconnected. Doc now says to copy the URL the CLI prints (carries wm_token + ws_token) and recommends --frontend.

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

* fix(pipeline): runAll excludes event roots + review polish

Addresses CI review (Codex P1, Claude P2/P3):

- pipeline run runAll: derive the whole-pipeline selection from validStarts + descendants instead of all runnables, so an unqualified 'pipeline run <folder>' no longer fires event-trigger roots (kafka/mqtt/…) with empty args/side effects. Verified: a kafka root is excluded from the plan.

- cascadeRun.ts runBoundedCascade: use buildLineageDownstreamMap (read-aware) so a pure-reader runs after its producer, and return cyclic — parity with the route page's bounded run (the file is meant to be THE shared correct primitive).

- PipelineGraphEditor: storedRightPaneSize starts at 0 so the orientation-aware default (55% stacked / 40% side-by-side) actually applies on first open.

- localGraph fallbackParse (go/bash): scan only the leading comment header (no body-comment phantom triggers) and strip key=value options from the asset URI; regression test added.

- docs: reject '..' in the folder arg (it writes files under f/<folder>).

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

* fix(pipeline): route local previews to the // tag worker

Addresses CI review P1: the local graph/bundle dropped the parsed `// tag`, so a node annotated `// tag gpu` ran on the default worker in both `pipeline run --local` and `/pipeline_dev`, while the deployed pipeline routes it to that worker tag. Carry the tag through LocalScript / the pushed bundle / LocalScriptContent and pass it to runScriptPreview at all three launch sites. Verified: a duckdb node tagged `bash` produces a job tagged `bash`; regression test added.

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

* fix(pipeline): add asset partitions/schemas routes to OpenAPI, use generated client

The ducklake asset panels (PartitionStatusGrid, SchemaHistoryPanel) hit /assets/partitions and /assets/asset_schemas via raw fetch with cookie-only auth, because those backend routes were never added to openapi.yaml so the generated client had no methods for them. On /pipeline_dev (token-via-URL, no session cookie) the raw fetches 401'd. Add both GET routes + MaterializedPartition/AssetSchemaVersion schemas to openapi.yaml and call them through AssetService, which injects the bearer token, types, and cancellation automatically. Verified: Partitions + Schema tabs load in /pipeline_dev. (backfill stays a raw fetch — it's an EE-only route not in the OSS spec — with the token added inline.)

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

* chore(cli): regenerate bun.lock for windmill-parser-wasm-asset

package.json / package-lock.json carry windmill-parser-wasm-asset@1.740.0 but the tracked bun.lock (the CLI installs/builds/tests via bun) was stale, so fresh bun installs would resolve a different graph than the committed lock. Regenerated.

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

* fix(pipeline): show asset producer + its runs in the dev-preview panel

Selecting a ducklake/asset node in /pipeline_dev showed 'No producer for this asset' because selectionProducers wasn't passed (it's derived from the deployed graph on the route page, absent here). Compute it from the local graph's w/rw write-edges (incl. the // materialize target) and pass it through, mirroring the route page — so the panel shows the producing script and its (preview) runs, including data-test failures.

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

* fix(pipeline): carry annotation metadata onto local-graph runnables

The local graph emitted only path/usage_kind/in_pipeline/materialize_target per runnable, so /pipeline_dev and pipeline show --local weren't the same surface as the deployed graph for annotated scripts — missing the badges/lineage the shared canvas renders. Map the wasm-parsed partition_kind, freshness, tag, retry, data_tests, column_lineage, and materialize_strategy (derived append/merge/replace) onto each runnable, mirroring the deployed AssetGraphRunnableNode.

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

* fix(pipeline): exclude event handlers that are lineage descendants from runAll

The runAll guarantee ('never fires an event handler with empty args') only held for event ROOTS — validStarts excludes them, but runAll then unions in descendants(dag, start), so a kafka/mqtt/... handler that also reads an upstream pipeline asset (a lineage descendant of a valid start) still landed in the plan. Add eventTriggerScripts() and subtract it from the selection after the descendant union. +unit test.

Also: docs/pipeline-local-dev.md recipe used 'pipeline docs demo_pipeline' without --local (default queries the deployed graph → hits the empty hint); add --local.

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

* fix(pipeline): whole-pipeline run cuts at event handlers (drop their downstream too)

The prior runAll fix subtracted event handlers from the selection but left their downstream: for manual_root → asset_x → kafka_handler → asset_y → consumer, deleting only kafka_handler left consumer selected, and topoOrder then ran it as a root with missing/stale event-derived inputs. Replace the descendant-union+delete with reachableCutting(dag, validStarts, eventHandlers): traverse from valid starts but treat event handlers as cut points, so a node reachable ONLY through an event handler is dropped while one reachable via a non-event path stays. +unit test.

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

* fix(pipeline): recover // tag in the go/bash annotation fallback

The wasm path carries out.tag, but the go/bash fallback (and the wasm-error degradation path) only recovered pipeline + on, so a // tag gpu on a bash/go node — or a temporarily-unparseable ts/py/sql node — silently routed the local preview to the default worker while the deployed pipeline routes to the tag. Scan for // tag in fallbackParse too. +test.

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

* refactor(pipeline): extract shared assetProducers helper

The 'who writes this asset' write-edge derivation was copied verbatim in PipelineDevView and the pipeline route page — two copies that would drift. Extract assetProducers(graph, selection) into graphTraversal.ts and use it from both, keeping the dev view and route page in lockstep.

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

* fix(pipeline): only overwrite AGENTS.md/CLAUDE.md when it's the exact generated pointer

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

* fix(pipeline): wire local-dev runs into the selected-node runs pane

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

* fix(pipeline): exclude data_upload/webhook entrypoints from auto CLI runs

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

* feat(pipeline): --upload binds an object to a data_upload/webhook entry point

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

* feat(pipeline): add "Run + downstream" to the dev preview detail form

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

* fix(pipeline): cut non-autorun triggers on all run paths; multi-binding --upload

Address CI review: apply the data_upload/webhook/event barrier cut to the
single-root and bounded (--from/--to) paths, not just whole-pipeline; accumulate
repeatable --upload bindings per script (were overwritten); scope dev upload keys
by script+param to avoid basename clobbering; drop <script> from help text.

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

* fix(pipeline): reseed dev run form when a local edit changes the script's args

The read-only pane is keyed on script.path only, so in /pipeline_dev the selected
node re-resolves on every WS bundle without remounting; PipelineScriptView cloned
script.schema once, so adding/removing args left the run form on a stale schema
(could run with missing inputs). Extract PipelineRunForm (owns the SchemaForm
clone) and key it on the serialized schema: a real arg change reseeds the form,
an unchanged re-resolve keeps in-progress input.

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

* fix(pipeline): don't cut a scheduled/manual root that also has a non-autorun trigger

Address Codex P1: the barrier set subtracted only --upload-bound scripts, so a
script with both `// on schedule` and `// on data_upload` resolved as the start
yet was also a barrier — reachableCutting skipped it, giving an empty run plan.
Subtract all valid starts (schedule/manual roots + bound handlers) from barriers:
a legitimately-scheduled root runs on its schedule path even if it also carries a
caller-input trigger; pure input-only roots stay cut. Adds a regression test.

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

* fix(pipeline): deployed non-autorun enrichment, s3:// storage, --to cut accounting, tag regex

Address CI review (Codex P1/P1/P2, Pi P2):
- Deployed `pipeline run` recovers marker-only data_upload/webhook/email triggers
  from script bodies (like the `show` path) so input-only entrypoints are cut
  instead of auto-run empty on the deployed graph.
- `--upload s3://<storage>/<key>` keeps the named storage (authority) instead of
  folding it into the key, matching the S3Object round-trip convention.
- Bounded `--to` targets cut by a barrier are reported in droppedEnds (+warning),
  not reachableEnds.
- fallbackParse `// tag` matches a single token (\S+), rejecting multi-word prose.

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

* fix(pipeline): header-only deployed marker scan, fail-closed enrichment, default-storage s3 keys

Address CI review (Codex P2, cubic P1/P1/P2):
- Deployed marker recovery scans the LEADING comment header only (shared
  recoverHeaderMarkers helper, reused by the show enrichment too) so a body
  comment `// on data_upload` can't inject a phantom trigger and over-cut.
- Deployed run enrichment fails CLOSED: a script-body fetch error aborts the run
  instead of silently letting an input-only entrypoint run with empty args.
- Revert `--upload s3://` to default-storage whole-path keys (matching pipeline
  `s3://` asset-URI semantics); named-storage authority-splitting broke nested
  default keys like `s3://raw/2026/events.csv`.

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

* fix(pipeline): reject trailing content on fallback native markers; trim s3:/// key

Address CI review (Codex P2, cubic P3):
- fallbackParse now requires a native marker (`// on data_upload`) to stand alone;
  a line with trailing content (`// on data_upload f/foo`, `# on kafka topic`) is
  rejected, matching the canonical parser and keeping local/deployed parity.
- s3UriKey trims a leading slash so the canonical empty-authority default form
  `s3:///key` doesn't leak a leading slash into the object key.

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

* fix(pipeline): persist dev WS token per-port so reconnect survives a CLI restart

Address Codex P2: the /pipeline_dev auto-reconnect reuses the ws_token from the
page URL, but `pipeline dev` minted a fresh random token each start, so a restart
on the same port left the open page rejected by verifyClient forever. Persist the
token per-port under the user-private config dir (0600) and reuse it on restart,
so an already-open page reconnects — matching the reconnect behavior's intent.

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

* fix(pipeline): scope persisted dev WS token by workspace+folder+port

Address cubic P2: keying the persisted token by port alone let a stale browser
tab from a previous folder's session on the same port reconnect and receive a
different folder's source. Scope the token file by workspace+folder+port so a
same-session restart still reconnects, but a different folder on the same port
gets a distinct token that rejects stale cross-folder tabs.

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

* fix(pipeline): caller args can't override skip-dispatch guard; hash the dev token key

Address CI review (Codex P1, cubic P2):
- makeLaunch / CLI run build args with `_wmill_skip_asset_dispatch` LAST (and drop
  any caller-supplied copy) so a run-form/`--upload` arg can't re-enable backend
  asset dispatch while the client orchestrates the cascade (double-run / running
  deployed subscribers from a local preview). Adds a cascadeRun guard test.
- Dev WS token file key is a sha256 of NUL-delimited workspace+folder+port, so
  different folders (`a/b` vs `a_b`) can't collide onto the same token file.

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

* fix(pipeline): canonical s3://storage/key --upload parsing; scope dev token by remote+root

Address Codex P1/P1:
- Restore canonical S3Object URI parsing for `--upload` s3 sources, matching the
  frontend's `parseS3Object` (`s3://<storage>/<key>`, empty authority ⇒ default,
  `s3:///key`/`s3:///nested/key` for the default store). `s3://secondary/k.csv` →
  `{ s3: "k.csv", storage: "secondary" }` so a named-storage object is read from
  the right store. (This is the canonical convention; the default-storage nested
  key is served by the `s3:///` form.)
- Scope the persisted dev WS token by remote+workspace+root+folder+port (was
  workspace+folder+port), so two profiles on different remotes (or local checkouts)
  with the same workspace/folder/port don't share a token — a stale tab can't
  reconnect across a workspace/remote boundary.

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-01 11:41:36 +02:00
hugocasa 468aa230e5 refactor: resolve workspace imports via /f/,/u/ not $f/,$u/ aliases (#9438)
* refactor: resolve workspace imports via /f/,/u/ not $f/,$u/ aliases

Keep the CLI managed tsconfig.wmill.json / `refresh tsconfig` / Deno
import-map QoL from #9378, but re-key it on the existing /f/,/u/ workspace
paths instead of the new $f/,$u/ specifiers. Verified /f/,/u/ resolves in
tsc, Bun, Deno, the in-app ATA editor, and the worker, so the $-prefixed
alias added no value. Drop the $f/,$u/ handling from the parser, dep-map,
deno_executor, bun loaders, ATA, relative_imports and monaco paths; revert
the windmill-parser-wasm-ts bump (1.714.0 -> 1.695.0). Also fold in the
cli/package-lock.json sync for the already-committed pg-gateway dependency.

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

* fix: drop duplicate relative-path check and restore rustfmt formatting

Follow-up cleanups to the previous commit's full-file reverts, which
restored pre-#9378 state that main had since improved:

- relative_imports.ts: remove the redundant duplicate d.startsWith('/')
  (pre-#9378 had it; #9378 had repurposed that line, so main has no dup).
- windmill-parser-ts/src/lib.rs: restore the multi-line new_source_file(...)
  formatting required by backend/rustfmt.toml (the single-line revert would
  fail `cargo fmt --check`). Now differs from main only by the $f//$u/ removal.

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-06-03 17:27:24 +00:00
hugocasa 220cd35cf7 feat: support $f/ and $u/ import path aliases for scripts (#9378)
* feat: support $f/ and $u/ import path aliases for scripts

$f/ and $u/ are local-friendly aliases for the absolute workspace
import paths /f/ and /u/. Unlike the /-prefixed form (which local tools
treat as a filesystem-root path), the $-prefixed form is a bare specifier
that can be remapped via tsconfig paths / Deno import maps, so the same
import resolves on the Windmill worker and in a local editor.

- worker: recognize $f//$u/ in the Deno import map and both Bun loaders
- dep-map/parser: normalize $f/->f/, $u/->u/ for lockgen + dep tracking
- cli: emit $f/$u path aliases in generated tsconfig.json / deno.json
- frontend: ATA + Monaco paths resolve $f//$u/ type hints in the editor

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

* feat(cli): split generated tsconfig into managed + user file with refresh command

Mirror the AGENTS.cli.md/AGENTS.md prompts model for the IDE tsconfig so the
recommended settings can evolve without ever clobbering user customizations:

- tsconfig.wmill.json: wmill-managed, always refreshed, holds recommended
  compilerOptions incl. the $f/$u path aliases (Deno: import_map.wmill.json)
- tsconfig.json: user-owned, created once, just extends the managed file;
  warn (never auto-edit) when an existing one doesn't reference it
- add 'wmill refresh tsconfig'; init generates it unconditionally (no longer
  gated behind resource-type namespace / a bound workspace)
- regenerate CLI guidance docs for the new subcommand

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

* fix(cli): address PR review on $f/ tsconfig generation

- handle existing deno.jsonc so we don't shadow it with a new deno.json
  (P1 identified by cubic)
- fix the bun-types hint that pointed users at the managed do-not-edit
  tsconfig.wmill.json; tell them to install + re-run 'wmill refresh tsconfig'
- document the .ts-extension-only local-resolution limitation (cross-flavor
  .bun.ts/.deno.ts/.fetch.ts scripts won't resolve in a local editor)

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

* feat(cli): warn when a project's tsconfig isn't wired to tsconfig.wmill.json

Mirror the prompts freshness check for the managed tsconfig so users with an
existing setup actually discover they're missing $f//$u/ resolution:

- embed a version hash in tsconfig.wmill.json (excludes the env-dependent
  bun-types 'types' entry so it doesn't false-positive)
- add warnIfTsconfigStale to the main.ts freshness hook, gated identically to
  the prompts check (skips init/refresh/help/version). When a tsconfig.json
  exists it warns one line (stderr) if the managed file is missing, not
  referenced via extends, or out of date; silent for non-TS projects.

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

* refactor(cli): make tsconfig setup equivalent to prompts (auto-wire + stale-only)

Unify the two managed-file systems so they behave identically:

- auto-wire an existing unlinked tsconfig.json/deno.json on init/refresh
  (add extends / importMap; merge into an array extends), instead of only
  warning. Parses JSON and falls back to a warning when it can't round-trip
  (JSONC comments, or a conflicting deno imports/importMap) — never corrupts.
- narrow warnIfTsconfigStale to stale-only, gated on the managed file
  existing, exactly like warnIfPromptsStale: it no longer nags about a
  missing or unlinked tsconfig.json, so a deliberately-custom/unlinked setup
  stays silent and a not-yet-initialized project isn't bothered.

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

* fix(cli): place tsconfig.wmill.json first in extends to preserve user base config

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

* feat(cli): migrate legacy tsconfig and require consent for custom configs

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

* refactor(cli): align prompts wiring to the same consent model

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

* chore(cli): bump windmill-parser-wasm-ts to 1.714.0 for $f/ $u/ aliases

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

* fix(worker): resolve $f/ and $u/ in deno lock generation

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

* test: narrow relative-imports lock-gen guard to deno import-map failure

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

* chore(cli): sync bun.lock with windmill-parser-wasm-ts 1.714.0

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

* fix(cli): warn when a custom tsconfig's paths would shadow $f/ $u/ aliases

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-06-03 11:58:12 +00:00
Diego Imbert 28c8b5c60f feat: CLI datatable serve / psql (#9267)
* feat(cli): add datatable list and run commands

* feat(cli): render datatable query results as a table

* feat(cli): serve datatables as a postgres-wire endpoint

* feat(cli): add 'datatable psql' to launch psql against the proxy

* feat(cli): route datatable serve by client-supplied database name

* override database list + password option

* fix: support extended queries in datatable serve

* fix: correct cloud size threshold log and parse CLI descriptions with parens/trailing comma

* refactor: extract raw_output envelope encoding into pg_raw_output module

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-05-20 16:56:50 +00:00
Ruben Fiszel 40dbab531e fix(cli): resolve cross-folder relative imports during lockgen on fresh DB (#9048)
* 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>
2026-05-05 21:06:53 +00:00
hugocasa 7c227ece0d fix(cli): pin wasm parser versions in published package.json (#8993)
Previously build-npm.ts emitted "*" for every wasm parser dep. Combined
with lockfiles pinning the first resolved version, users who installed
when a parser was briefly behind got stuck on a stale wasm even after
the registry caught up — surfacing as "TypeError: parse_ts_relative_imports
is not a function" warnings during sync/generate-metadata.

Forward the dev package.json specs into the generated package.json
instead, and pin all 12 parsers to the exact versions published on npm
(mirroring frontend/package.json).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 12:13:29 -04:00
hugocasa bef0a36c55 chore: bump windmill-parser-wasm packages to 1.693.1 (#8985)
Bump windmill-parser-wasm-ts, -py and -py-imports to 1.693.1 in
the CLI and frontend after publishing the new versions.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 12:19:46 +00:00
Ruben Fiszel e36d440a25 fix: resolve esbuild host/binary version mismatch in app sync push (#8765)
* fix: resolve esbuild host/binary version mismatch in app sync push

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

* Revert "fix: resolve esbuild host/binary version mismatch in app sync push"

This reverts commit 8822614f8e.

* fix: update esbuild to 0.28.0 and pin version exactly

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

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 16:09:58 +00:00
centdix 5fd2c1a129 chore(cli): separate unit tests from integration tests and fix test cleanup (#8562)
* fix(cli): separate unit tests from integration tests and fix test cleanup

- Rename 14 non-backend test files to *_unit.test.ts convention
- Add UNIT_ONLY env var guard in setup.ts to skip cargo build/backend startup
- Add test:unit and test:integration scripts to package.json
- Use setsid on Linux for process group management so stop() kills both
  cargo and the windmill child process
- Fix exit handler to kill process group instead of just the direct child
- Add cleanupStaleTestResources() to drop orphaned windmill_test_* databases
  and kill orphaned backend processes on startup
- Rewrite TESTING.md with current bun-based instructions

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

* fix(cli): fix process group approach - kill by db name instead of setsid

The setsid approach didn't work because setsid forks, making the PID
we get from Bun.spawn ephemeral. Instead, kill orphaned windmill child
processes by matching our unique database name in /proc/pid/environ.

Also add afterAll hook in setup.ts so full async cleanup (process kill
+ database drop) runs when all tests complete normally, not just on
SIGINT/SIGTERM.

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

* fix(cli): address PR review feedback

- Remove duplicate cleanupStaleTestResources() call in getTestBackend()
  (already called in setup.ts)
- Add regex guard on database names before SQL interpolation
- Extract shared killWindmillProcessesByEnvMatch() helper to deduplicate
  process-killing logic
- Remove redundant test:integration script (test already runs everything)
- Flip setup.ts to if/else pattern for readability

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

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:13:33 +00:00
Pyra 9643006f1e feat(cli): better stale scripts detection #3 (#8480)
* fix

Signed-off-by: pyranota <pyra@duck.com>

* reduce tests

Signed-off-by: pyranota <pyra@duck.com>

* update

Signed-off-by: pyranota <pyra@duck.com>

* fix

Signed-off-by: pyranota <pyra@duck.com>

* update

Signed-off-by: pyranota <pyra@duck.com>

* WIP: stash changes after merge with origin/main

* Delete backend/parsers/windmill-parser-wasm/Cargo.lock

* reset cargo.toml

* feat(cli): integrate dependency tree into generate-metadata command

- Add isDirectlyStale field to DependencyNode for staleness tracking
- Update addScript to accept itemType, folder, isRawApp, isDirectlyStale
- Update propagateStaleness to use isDirectlyStale field instead of parameter
- Handlers now determine staleness and pass it to tree.addScript
- generate-metadata calls propagateStaleness() and populates staleItems from tree
- Pass legacyBehaviour=false and tree to handlers during generation phase

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(cli): store originalPath in tree for correct handler invocation

Scripts need the path with extension to be passed to the handler.
Added originalPath field to DependencyNode to track this.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix parsers

Signed-off-by: pyranota <pyra@duck.com>

* rever sqlx removal

* update sqlx

* feat: make py-imports parser WASM-compatible and add as separate WASM package

Gate heavy deps (sqlx, windmill-common, async-recursion, toml, pep440_rs,
tracing) behind cfg(not(wasm32)). Make parse_code_for_imports,
parse_relative_imports, NImport, and ImportPin public. Remove duplicate
import_parser from parser-py (reset to origin/main). Add py-imports-parser
feature to windmill-parser-wasm and py-imports target to build.nu.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* safer return

* update

* fix: CLI metadata fixes - folder filter, staleness detection, WASM py-imports setup

- Fix lazy_static cfg gating for WASM compatibility (split into separate blocks)
- Fix folder argument filter to match specific file paths (not just directories)
- Fix staleness detection to use checkHash with conf (includes module hashes)
- Convert relative_imports_skip tests from Deno to bun APIs
- Add windmill-parser-wasm-py-imports to CLI and build-npm dependencies
- Relax module stale test to not require per-module change detail in output

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: restore temp_script_refs parameter in parse_python_imports

Re-adds the temp_script_refs parameter that was lost when resetting
py-imports crate to origin/main. This enables resolving relative imports
from not-yet-deployed scripts during CLI lock generation.

* fixes

* extend testsuit

* update ee repo ref

* fix: diff endpoint bytea cast, upload only mismatched scripts

- Add POST /scripts/raw_temp/diff endpoint to batch-compare local content
  hashes against deployed versions using Postgres sha256()
- Use convert_to(content, 'UTF8') instead of content::bytea to avoid
  failure on scripts containing backslash sequences (e.g. \n)
- CLI now diffs all scripts against deployed, uploads only mismatched ones
- propagateStaleness no longer deletes non-stale nodes (needed for diff)
- Suppress verbose log.info messages during metadata generation
- Add E2E tests for locally modified and unpushed helper scripts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* rework

* sqlx

* fixes

* add index

* expand tests

* fix flows

* archive script before executing

* disable tests for ci

* skip Python-dependent E2E tests on CI

Tests requiring the python backend feature are skipped when
CI_MINIMAL_FEATURES=true since CI builds with zip-only features.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: make flow fixture lock optional and reset nonDottedPaths after tests

Flow fixtures no longer emit an empty lock file by default. The lockContent
parameter controls whether a lock: "!inline ..." line appears in flow.yaml.
This prevents flows from appearing "up-to-date" when they should be processed
by generate-metadata.

Also adds afterAll to reset setNonDottedPaths(false) so global state doesn't
leak between test files when run together.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* debug: add error logging in withTestBackend to diagnose CI failures

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* debug: add --bail 1 to CI test runner to show full error on first failure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* debug: include CLI stdout/stderr in assertion message for workspace deps test

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: set WMDEBUG_FORCE_V0_WORKSPACE_DEPENDENCIES in test backend

The workspace deps feature requires workers to report their version, but
in test/CI there are no separate workers (standalone mode). The version
check fails because workers haven't had time to ping yet. Setting this
env var bypasses the version check.

Also reverts --bail 1 from CI workflow now that the root cause is fixed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* debug: add --bail 1 to Windows CI and assertion messages for Windows failure diagnosis

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: replace TEMP_SCRIPT_REFS_PLACEHOLDER in bun builder tests

The loader.bun.js now includes a TEMP_SCRIPT_REFS_PLACEHOLDER that must
be replaced before execution. The builder tests were missing this
replacement, causing all 6 bun_builder_tests to fail.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use cdirFwd in Windows loader filterLoad regex

Raw cdir (with backslashes) interpolated into RegExp causes \r to
become carriage return and \w to become word-char, so filterLoad
never matches main.ts. This prevents replaceRelativeImports from
running, leaving bare relative imports like "./script_b" in the
bundled output, which scanImports then misparses as package ".".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: Windows filterLoad regex + graceful fallback for old backends

- Fix filterLoad in loader.bun.windows.js to match both native backslash
  and forward-slash paths from Bun's resolver by escaping cdir for regex
- Wrap uploadScripts in try/catch so generate-metadata degrades gracefully
  when the backend lacks /raw_temp endpoints (locks use deployed versions)
- Add TODO for missing TEMP_SCRIPT_REFS support in Windows loader

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* debug: add loader/builder debug logging for Windows CI diagnosis

Temporary console.log statements to understand:
- What path Bun passes to onLoad for main.ts
- Whether filterLoad regex matches
- Whether replaceRelativeImports fires
- What the bundled output contains
- What imports scanImports extracts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: trigger CI for cli path

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: trigger CI via workflow file change

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add TEMP_SCRIPT_REFS to Windows loader, use .ts extensions in test imports

- Add TEMP_SCRIPT_REFS_PLACEHOLDER support to loader.bun.windows.js
  (mirrors loader.bun.js) so CLI lock generation can resolve imports
  from locally-modified scripts on Windows
- Use .ts extensions in all test relative imports to work around the
  Windows filterLoad regex bug (replaceRelativeImports doesn't fire
  on Windows, so extensionless imports fail)
- Remove unused uploadSucceeded variable

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Remove debug logging from loader_builder.bun.js

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Remove windmill-parser-wasm-py-imports from frontend package.json

This dependency is only needed by the CLI, not the frontend.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* debug: add temp_script_refs logging for Windows CI investigation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* ci: remove --bail 1 from Windows CLI tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: normalize backslashes in folder filter treePath lookup (Windows)

On Windows, item.path (originalPath) uses backslashes but tree keys
use forward slashes. The isRelevant filter's touchesFolder call
passed the unnormalized path to traverseTransitive, which couldn't
find the node. This caused cross-folder importers to be excluded
from generate-metadata when a folder argument was specified.

Also removes debug logging from previous commit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Update cli-tests.yml

* fix: normalize backslashes in strict-folder-boundaries warning message (Windows)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: update ee-repo-ref to fe8f0d1d7448464c98474d994e6492c0a45e8e38

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

Previous ee-repo-ref: 03e6eaf950776c96b9581848a583af9ad735be60

New ee-repo-ref: fe8f0d1d7448464c98474d994e6492c0a45e8e38

Automated by sync-ee-ref workflow.

* revert cli-tests.yml

---------

Signed-off-by: pyranota <pyra@duck.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
2026-03-23 18:20:19 +00:00
centdix 835db5d290 feat(cli): detect missing folders on sync push and add 'wmill folder add-missing' (#8011)
* fix: auto-create missing folders during sync push for non-admin users

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: show missing folders in sync push summary before confirmation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: improve sync push folder auto-creation error handling and json output

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: only treat 404 as missing folder in getFolder check

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: remove obsolete Deno compatibility layer from yaml-validator

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore(cli): add @types/bun dev dependency

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(cli): replace auto-create folders with `wmill folder add-missing` command

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(cli): improve folder commands with summary field and simpler push API

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(cli): add confirmation prompt to folder add-missing command

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(cli): simplify missing folder check to use local stat instead of remote API

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* update skills

* feat(cli): warn admins but block non-admins on missing folder.meta.yaml

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* cleaning

* cleaning

* test(cli): add tests for missing folder detection and folder commands

- Add tests for `folder new`, `folder push`, `folder add-missing` commands
- Add tests for sync push missing folder.meta.yaml detection (admin warning, non-admin block)
- Fix getBasePostgresUrl to strip query params (e.g. ?sslmode=disable) from DATABASE_URL
- Add createNonAdminUser and runCLIWithToken test utilities to test_backend.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(cli): unify runCLICommand with optional token parameter

Replace separate runCLIWithToken utility with an optional { workspace?, token? }
options object on the existing runCLICommand across all backends.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* own workspace

* test(cli): isolate folder_missing_meta tests with per-test workspace

* test(cli): shorten isolated workspace id/name for workspace limits

* test(cli): archive temp isolated workspaces after each folder test

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-24 08:38:17 +00:00
Ruben Fiszel 4fedfdfd11 feat(cli): add consistent get/list/new subcommands for all item types (#8047)
* feat(cli): add consistent get/list/new subcommands for all item types

Make the CLI consistent so every item type (script, flow, app, resource,
resource-type, variable, schedule, folder, trigger) supports get/list/new
subcommands, enabling the CLI to be used as a full API client in bash
scripts with jq piping.

- Add --json flag to all list commands for machine-readable output
- Register explicit "list" subcommand alongside default action
- Add "get <path> [--json]" subcommand to fetch single items from API
- Rename "bootstrap" to "new" for script/flow, keep "bootstrap" as alias
- Add "new" subcommand for resource, resource-type, variable, schedule,
  folder, and trigger to create local template YAML files
- Update cli-commands skill documentation for wmill init
- Add integration tests for all new commands

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* all

* feat: install wmill CLI in Docker images and use it for bash variable/resource access

- Install windmill-cli via bun in all Dockerfiles that include bun
- DockerfileCli: switch from node:slim to oven/bun:slim
- CLI: auto-configure from WM_WORKSPACE/WM_TOKEN/BASE_INTERNAL_URL env vars
  as last-resort fallback when no workspace is configured
- Frontend: replace curl-based bash snippets with wmill variable/resource get
- Add backend integration tests for wmill CLI in bash scripts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(ci): install windmill-cli in backend test workflow

Ensures wmill is available on PATH for bash integration tests
that use `wmill variable get` and `wmill resource get`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(cli): replace @std/* Deno dependencies with Node.js equivalents

Replace @std/log with a lightweight custom logger (core/log.ts),
@std/path with node:path, and @std/yaml with the yaml npm package.
Also fix process hang on exit, add --node option to install_dev.sh,
and add missing hasRequiredPermissions to NpmProvider.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* all

* all

* all

* refactor(cli): replace @ayonli/jsext and @std/encoding with lightweight alternatives

Replace @ayonli/jsext (8.4MB) with tar-stream (32kB) for tar creation,
replace @std/encoding with Node.js Buffer.toString("hex"), and fix
@windmill-labs/shared-utils to use direct npm instead of JSR mirror.
Also resolve merge conflicts in sync.ts and fix pre-existing type errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cli): use singleQuote YAML output and pass yamlOptions in gitsync pull

The yaml library defaults to double quotes, but the codebase (and tests)
expect single-quoted strings. Add singleQuote: true to yamlOptions and
pass yamlOptions to gitsync-settings pull writeFile calls.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* all

* all

* fix(cli): address code review feedback

- Install CLI from source in backend tests instead of npm
- Fix script bootstrap catch block to re-throw "File already exists"
- Add type-safe local variable after trigger kind validation
- Use created_by instead of policy.on_behalf_of for app get output
- Note --kind is recommended for faster trigger lookup in help text
- Document node symlink purpose in Dockerfiles

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(ci): use /usr/bin for wmill wrapper to ensure it's in PATH

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(ci): install wmill to ~/.local/bin to avoid permission issues

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* ci(backend): switch to Blacksmith runner and add cargo caching

- Switch from ubicloud-standard-16 to blacksmith-16vcpu-ubuntu-2404 for faster NVMe-backed builds
- Add stickydisk for cargo target directory (persistent NVMe cache across runs)
- Add cache for cargo registry and git dependencies
- Upgrade DuckDB FFI cache from actions/cache@v3 to useblacksmith/cache@v1
- Enable CARGO_INCREMENTAL=1 to benefit from persistent target cache

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix ci

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 07:53:28 +00:00
Ruben Fiszel a2cefdf0a2 refactor(cli): migrate CLI from Deno to Bun/Node.js (#8041)
* fix: only enable EE features in test backend when license key is available

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: skip EE tests without license key and exclude test-skills from test discovery

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: unskip passing tests and add duplicate (remote, workspaceId) check in addWorkspace

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(cli): migrate from Deno APIs to Node.js/Bun-compatible APIs

Replace Deno-specific APIs with Node.js equivalents across the entire CLI
codebase to enable running on Node.js/Bun. Switch build system from dnt
to bun, update imports from jsr:/npm: prefixed to bare specifiers, and
add package.json/tsconfig.json for the Node.js ecosystem.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* all

* test(cli): expand test coverage with new integration and unit tests

Add standalone_commands.test.ts covering folder list, schedule list,
resource-type list/push/update, script show/run/bootstrap, and user
commands. Add unit tests for filePathExtensionFromContentType and
removeExtensionToPath. Add git_unit, local_encryption_unit,
resource_folders_unit, and settings_unit test files. Fix schedule
cron expressions (6-field format), add includeSchedules flag, improve
test setup with pre-build and auto-cleanup, and support TEST_CLI_RUNTIME=node.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cli): replace Deno.readFile with node:fs in WASM loaders and add schema parsing tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(cli): switch WASM parsers from local files to npm packages

Use published windmill-parser-wasm-* npm packages instead of local
wasm/ files. A loadParser() helper uses createRequire to resolve the
.wasm binary from node_modules and passes it to init() via
readFileSync, avoiding fetch() and Deno.readFile() patches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test(cli): add coverage for --locks-required lint feature

Add 15 tests covering the lock-checking functionality merged from main:
- checkMissingLocks: standalone scripts (python, bun, bash), inline
  lock file resolution (valid, empty, missing), flow inline rawscripts
  (with/without locks, nested forloopflow), app inline scripts, raw
  apps without backend folder
- runLint --locks-required integration: reports issues when locks
  missing, skips checks when flag absent, passes when locks exist

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* ci(cli): replace Deno with Bun in CI workflows

- cli-tests.yml: remove Deno setup, use `bun test` instead of
  `deno test`, add `bun install` step for dependency installation
- npm_on_release.yml: replace Deno setup with Bun setup for CLI
  publishing
- build.sh: add `bun install` before building so CI has dependencies

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cli): pre-start backend in test preload and remove Deno test leftovers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cli): normalize path separators for Windows compatibility

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* more tests + windows

* ci(cli): use Blacksmith runner for Windows tests

Switch test-windows job from windows-latest to blacksmith-16vcpu-windows-2025
for faster CI execution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cli): fix Windows path separator expectations in unit tests

buildMetadataPath and extractResourceName normalize to forward slashes
internally, so tests should not expect platform-specific separators in
their output.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cli): fix Windows CI test failures for dev_server and script_run

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cli): set BUN_PATH and NODE_BIN_PATH for backend worker on Windows

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* ci(cli): add SSH debug step on Windows test failure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(cli): use native path separators for ignore check in dev mode on Windows

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 21:19:04 +00:00