Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/coding-agent/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

### Fixed

- Fixed `senpi --neo -- ...` so Rust TUI flags after the sentinel reach the native binary instead of being rejected by the Node CLI parser.

### Removed

## [2026.5.24] - 2026-05-24
Expand Down
5 changes: 5 additions & 0 deletions packages/coding-agent/src/cli/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ export function parseArgs(args: string[]): Args {
result.offline = true;
} else if (arg === "--neo") {
result.neo = true;
} else if (arg === "--") {
if (!result.neo) {
result.messages.push(...args.slice(i + 1));
}
break;
} else if (arg.startsWith("@")) {
result.fileArgs.push(arg.slice(1)); // Remove @ prefix
} else if (arg.startsWith("--")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
* caller to the Rust `senpi-neo-tui` binary via the `--` sentinel.
*
* Without the sentinel split, the senpi argparser eats `--theme`,
* `--demo`, etc. and either errors out (they mean something completely
* different on the senpi side, e.g. `--theme <path>` loads a theme file)
* or silently swallows them, so the neo TUI never sees its own flags
* and `senpi --neo --theme dracula` becomes a lie in the docs.
* `--demo`, etc. and either errors out (for unknown Rust-only flags)
* or treats them as senpi-side options, so the neo TUI never sees its own
* flags and `senpi --neo -- --theme dracula` becomes a lie in the docs.
*
* Source of truth: {@link splitNeoArgs} in
* `packages/coding-agent/src/modes/neo-mode.ts`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
* Regression: `--neo` flag must round-trip through `parseArgs` cleanly and
* coexist with the rest of the senpi CLI surface.
*
* The flag dispatch into the Rust binary lives in a later wave; this test
* only locks the arg-parser contract so future renames or accidental
* removals fail loudly.
* The sentinel split into backend args vs Rust TUI args lives in neo-mode;
* this file locks the parser contract so forwarded neo flags do not get
* rejected before that split can run.
*/

import { describe, expect, test } from "vitest";
Expand Down Expand Up @@ -44,4 +44,12 @@ describe("--neo flag", () => {
const parsed = parseArgs(["--neo"]);
expect(parsed.unknownFlags.has("neo")).toBe(false);
});

test("--neo allows a -- sentinel for Rust TUI flags", () => {
const parsed = parseArgs(["--neo", "--", "--list-themes", "--theme", "dracula"]);
expect(parsed.neo).toBe(true);
expect(parsed.diagnostics).toEqual([]);
expect(parsed.unknownFlags.size).toBe(0);
expect(parsed.messages).toEqual([]);
});
});