fix(FN-XXXX): tokenize backup-command matcher

Two follow-ups to the in-process backup interception:

- Previously the matcher only allowed a bare `npx` prefix, so the
  canonical zero-install form `npx -y runfusion.ai backup --create`
  (and any `npx --yes` / `-p <pkg>` / `--package=<pkg>` variant) fell
  through to the legacy shell-out path. The matcher now consumes any
  number of npx flags before the binary token so all canonical
  invocations route through the in-process executor.
- Previously the matcher accepted arbitrary text after `--create` and
  the runner silently dropped it. Authors writing
  `fn backup --create && notify-send done` or
  `fn backup --create | tee log` reasonably expected the trailing
  side effect to fire. The matcher now refuses any command containing
  shell continuations / redirections / substitutions
  (`&&`, `||`, `|`, `;`, `>`, `<`, backticks, `$()`), and rejects
  trailing positional arguments. Such commands shell out as the user
  wrote them.

The matcher is now a small tokenizer rather than a regex collection,
so the contract is easier to read and the unit-test grid covers each
permitted prefix combination plus all the previously-unhandled shell
forms.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-05-01 22:58:18 -07:00
parent 31195374d4
commit dd291db725
3 changed files with 108 additions and 17 deletions

View File

@@ -0,0 +1,5 @@
---
"@runfusion/fusion": patch
---
Tokenize `isInProcessBackupCommand` so it accepts the full canonical zero-install form `npx -y runfusion.ai backup --create` (and other npx flag combinations such as `--yes`, `-p <pkg>`, `--package=<pkg>`) and refuses commands that embed shell continuations or redirections (`&&`, `||`, `|`, `;`, `>`, `<`, backticks, `$()`). The previous regex permitted only a bare `npx` prefix and silently swallowed any tail after `--create`, which meant `npx -y runfusion.ai backup --create` still hit the legacy shell-out and `fn backup --create && notify-send done` lost its trailing side effect when intercepted. The new matcher only intercepts when the entire command is a plain in-process backup invocation; anything else continues through the shell as authored.