Skip to content

feat: v1.8.0 — mutation verbs honour --json / --jq / --template - #4

Merged
trngthnh369 merged 1 commit into
mainfrom
feat/json-mutation-verbs
Aug 15, 2026
Merged

trngthnh369 merged 1 commit into
mainfrom
feat/json-mutation-verbs

Conversation

@trngthnh369

Copy link
Copy Markdown
Owner

Follow-up to the review finding on #3, done properly across all mutation verbs
instead of just archive.

The bug

--json silently did nothing on every state-changing command. They wrote a
status line straight to stdout and never went through printData:

$ n8nctl workflow archive 58 --json | jq .id
parse error: Invalid numeric literal at line 1, column 2

No error, no signal — a script just gets ✓ archived workflow 58 "wf" where it
expected JSON. 19 commands now route their result through a new printMutation
helper: workflow activate/deactivate/archive/unarchive/delete/refresh/tag/
transfer, tag create/update/delete, variable set/delete, execution delete,
credential delete/transfer, user delete/role, project create/update/delete/
add-user/remove-user. --dry-run previews are machine-readable too, flagged
"dryRun": true.

Opt-in on purpose — NOT a breaking change

printData's contract §2 says non-TTY is always JSON. Applying that here would
switch piped output to JSON for every existing caller, silently breaking any
script that greps the status line. So printMutation deviates deliberately:

stdout stderr
no output flag (TTY or piped) status line — unchanged —
--json / --jq / --template machine-readable data status line
n8nctl workflow activate 58 | cat          # ✓ activated workflow 58 "wf"   <- unchanged
n8nctl workflow activate 58 --json         # {"id":"58","name":"wf","active":true}
n8nctl workflow archive 58 --jq '.id'      # "58"
n8nctl workflow delete 58 --dry-run --json # {"id":"58",...,"dryRun":true}

Full contract-§2 alignment stays available as a deliberate major-version
decision; it's documented in the helper rather than smuggled in here.

printMutation takes a PrintContext, not a Factory — lib/output.ts must not
depend on factory.ts, which would close an import cycle of exactly the kind that
caused the completion flake fixed in #2.

Verified

  • 511 tests (+9), coverage gate green, lint/build/audit clean.
  • The 502 pre-existing tests passed unchanged — that's the empirical evidence
    for the non-breaking claim, since the default path is untouched.
  • Live through the built CLI: no flag + pipe still emits text; --json pipes
    parseable JSON; --jq filters a field; the status line lands on stderr.

Not tagged — v1.8.0 is bumped in package.json + CHANGELOG.md; tagging
(which triggers the npm release) is left for you.

🤖 Generated with Claude Code

`--json` silently did nothing on every state-changing command. They printed a
status line straight to stdout and never went through `printData`, so a script
doing `n8nctl workflow archive X --json | jq` got human text and failed to
parse — with no error to say why. This was flagged in review of #3 and left as
a follow-up because fixing it for `archive` alone would have made it the odd
one out among the mutation verbs.

19 commands now route their result through a new `printMutation` helper:
workflow activate/deactivate/archive/unarchive/delete/refresh/tag/transfer,
tag create/update/delete, variable set/delete, execution delete, credential
delete/transfer, user delete/role, project create/update/delete/add-user/
remove-user. --dry-run previews are machine-readable too, flagged "dryRun".

## Opt-in on purpose — this is NOT a breaking change

printData's contract §2 says non-TTY is always JSON. Applying that here would
have switched piped output to JSON for every existing caller, silently
breaking any script that greps the status line. So printMutation deviates
deliberately: with no output flag the status line still goes to stdout exactly
as before, piped or not. Only an explicit --json/--jq/--template switches
stdout to data, and then the human line moves to stderr so stdout stays pure.

Full contract-§2 alignment remains available as a deliberate major-version
decision; it is documented in the helper rather than smuggled in here.

`printMutation` takes a PrintContext, not a Factory — lib/output.ts must not
depend on factory.ts, which would close an import cycle of exactly the kind
that caused the completion flake in #2.

## Verified

- 511 tests (+9), coverage gate green, lint/build/audit clean.
- The 502 pre-existing tests passed UNCHANGED, which is the empirical evidence
  for the non-breaking claim: the default path is untouched.
- Live through the built CLI: no flag + pipe still emits text; --json pipes
  parseable JSON; --jq filters a field; the status line lands on stderr.
@trngthnh369
trngthnh369 merged commit e0ae079 into main Aug 15, 2026
7 checks passed
@trngthnh369
trngthnh369 deleted the feat/json-mutation-verbs branch August 15, 2026 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant