Skip to content

v0.7.0

Choose a tag to compare

@buttjer buttjer released this 24 Jul 13:09
· 155 commits to main since this release
9f3a78a

Added

  • check now warns when local work has not been registered with n8n — a
    node whose //@file: placeholder has moved off what .decanter.json records
    (the shape of a .js.ts conversion), or whose recorded file is gone from
    disk. It stays a warning, not an error: push reconciles the file map, and
    the compliance guard runs before that reconcile, so failing here would refuse
    the one command that fixes it.

  • n8n-decanter --version prints the installed version (-v too), the way
    every CLI is expected to. It answers before any config load or verb dispatch,
    so it works from anywhere — including outside a sync dir. Passed alongside a
    verb it is a hard error naming the flag you meant, so a stray --version
    can't quietly swallow a command.

  • A first init points at n8n's official skills pack. Setup now closes by
    naming n8n-io/skills — the knowledge layer
    that makes agentic workflow building work — and printing the install commands
    for Claude Code, Codex, and skills.sh, with the agent it detects
    from your environment listed first and the activation step each one still
    needs. It prints; it does not install: that would mean spawning a third-party
    CLI to mutate agent state outside the sync dir, and a plugin installed
    mid-session isn't active until the agent reloads. Said once per sync dir (no
    re-init repeats it), on every path including piped and --host-driven runs,
    and it consumes no input — no existing script's stdin changes. (Plan 55.)

  • init can run non-interactively via --host / --token / --api-key.
    Passing any of them drives setup purely from the flags plus any existing
    .env and issues no prompt — so a script or coding agent can bootstrap a
    sync dir without the interactive stdin dance (the field-test agents needed
    20+ tries to drive the old prompt path). --host is required in this mode
    (a scheme-less local host is normalized to http://, like a typed one) and
    wins over an existing .env value; --token sets N8N_MCP_TOKEN (headless
    OAuth is still terminal-only); --api-key sets the optional N8N_API_KEY.
    The flag-less path (interactive, or piped answers) is unchanged. (Plan 35
    field-test finding.)

  • node run now emulates $jmespath. A Code node that calls
    $jmespath(data, expr) (or the $jmesPath alias) runs offline, matching
    n8n's result (backed by jmespath@0.16.0, the version n8n pins). It also
    fills in $items()/$node (views over the fixture's nodes), $vars/
    $secrets (new fixture fields), and $nodeId/$nodeVersion/$webhookId.

  • node run fixtures gained vars and secrets to pin the instance-scoped
    $vars/$secrets when a node reads them.

Changed

  • Breaking: the scaffolded Claude Code settings moved from
    .claude/settings.local.json to .claude/settings.json, and init now
    migrates existing sync dirs. The file holds project policy — decanter's verb
    permissions plus the verify.mjs and mcp-route-check.mjs hooks — with
    nothing machine-specific in it; it was already being committed and tracked in
    the shared .decanter-template.json, so local was the wrong scope, and it
    squatted the one file Claude Code reserves for your own overrides. The
    local slot is now yours: permission lists merge across the two files and a
    deny beats an allow, so a local file can add to the policy but cannot
    unblock what the project denies. On re-init, an untouched copy is moved for
    you; a copy you edited is left exactly where it is and the new file is not
    written (both would register their hooks) — init says what to move, and
    --force resolves it by removing the old file. A settings.local.json that
    init never wrote is never touched. (Plan 56.)

  • Breaking: backup restore takes the backup as an argument, not a flag —
    backup restore <workflow> [<backup>].
    --version <id> and --at <ts>
    are gone. The argument is a backup ref resolved by shape, exactly like a
    <workflow> ref: paste a timestamp (or a prefix — a bare date is enough) or a
    versionId (short or full), whichever column of backup list you have to
    hand. backup restore order-sync 2026-07-24 and backup restore order-sync a1b2c3d4 both just work; a ref that matches nothing is an error, never a
    silent fall back to the latest. The retired flags fail loudly with the
    replacement. This also un-squats --version, which no CLI can spend on a
    verb-scoped meaning (see Added).

  • check's success line now states its scope
    OK (local layout — status compares with n8n) instead of a bare OK. check
    is offline by definition, so green means "well-formed", never "live in n8n".
    The agent guide gained the matching rule, and the .js.ts recipe now ends
    at push rather than check — it previously told you to stop one step short
    of the conversion actually reaching the instance. (Surfaced by the Plan 35
    blind field test: three separate sessions authored code, read a green check
    as "done", and never pushed.)

  • scenario create / scenario check with no workflow now open the picker on
    a terminal
    , like every other ref-taking verb (pull, push, backup …, …).
    They previously hard-errored with a usage line even on a TTY, which made them
    the odd ones out. Piped / non-TTY runs are unchanged — still the usage error —
    so scripts and agent harnesses never block on a prompt. (Surfaced by the Plan
    35 blind field test, where an agent tripped the inconsistency twice.)

  • node run signposts instead of crashing on instance-scoped globals. A
    global whose value lives on the running instance ($vars/$secrets when
    unpinned, $evaluateExpression) now throws a friendly message that names the
    global and points to test (or the fixture field) — never a bare
    ReferenceError. docs/cli/node-run.md documents the covered / partial /
    unsupported boundary.

Fixed

  • The documented Claude Code skills-install commands are no longer
    copy-paste-broken.
    /plugin marketplace add / /plugin install are
    in-session slash commands, but the docs and the scaffolded AGENTS.md
    presented them as shell commands. Both now show the in-session form and the
    real shell equivalents (claude plugin marketplace add … /
    claude plugin install …) separately, plus the post-install activation step
    each agent needs.

  • A .js.ts conversion is no longer reverted by a pull that fires before
    the first TS push.
    Re-pointing a node's //@file: placeholder to a .ts
    file and swapping the source is the sanctioned way to convert a node, but a
    pull landing in the window before the first TS push — notably the
    on-by-default live-mirror background refresh after a structure edit — rewrote
    the placeholder back to .js and left .decanter.json pointing at the
    deleted .js file, so the next push failed with referenced node file missing. Pull now honors the re-pointed placeholder exactly as push does
    (they share one reconcile step). (Plan 35 field-test finding.)

  • init no longer breaks local http instances. A scheme-less host typed
    at the n8n host: prompt now defaults to http:// for local addresses
    (localhost, loopback, private LAN ranges, *.local) and https://
    otherwise. Previously every scheme-less host got https://, so a local n8n
    (plain http) was written to .env as a TLS URL and every sync/guard call
    failed with fetch failed. A scheme you type is still kept as-is.

  • n8n-globals.d.ts no longer over-declares $if/$min/$max. Those are
    n8n expression-language helpers ({{ }} only), not Code-node globals — they
    throw in a real Code node too — so declaring them wrongly type-checked broken
    code. The declared surface now matches what a Code node actually sees, and is
    single-sourced (init copies the one root file — no duplicate template copy).

  • The scaffolded agent permission allowlist (.claude/settings.json — see the
    move under Changed) now
    pre-approves the read-only preflight gate, so an agent following the
    template's recommended edit → check → preflight → push loop no longer stalls
    on a permission prompt at the gate itself. Also dropped the obsolete
    *.remote.js deny rule — those artifacts were removed in the Plan 32 MCP pivot.