Add Plandex preset, fix render_drift_json escaping on Linux, + parallel-worktree follow-ups - #91
Merged
Merged
Conversation
Plandex (plandex/pdx) is a Go-binary terminal agent for large, multi-step tasks. The preset fetches the release tarball onto PATH at build (it is not an npm package), allowlists only the Plandex Cloud backend api-v2.plandex.ai (which proxies the model calls), forwards OpenRouter/OpenAI/Anthropic BYO keys, persists the .plandex-home-v2 auth/session dir, and launches the REPL in Full Auto (--full) with the plandex.ai version ping suppressed.
…y host The shipped plandex preset allowlists api-v2.plandex.ai - Plandex Cloud's backend, which proxies the model calls and accepts POST bodies exactly like api.anthropic.com. It is a model/agent-stream host of the same class as the cursor/amp/qwen/crush hosts already classified, so plandex users must get the same session-start laundering nudge. Add it to laundering_host() AND the _LAUNDER_COVER anchor list (so a parent wildcard covering it, e.g. .plandex.ai, is caught too). Regression: verify-laundering-gate.bats - the exact host flagged, plus a .plandex.ai parent wildcard.
Add the plandex row to the agents.md preset table and the two README preset enumerations (nine -> ten). The preset itself ships in the feat(agents) commit; the GIF alt-text still shows the pre-plandex nine (the demo asset is unchanged).
The escaping used a gsub whose replacement contains a backslash, and mawk (Debian/CI) and the BSD awk on macOS interpret a backslash in a gsub replacement differently: mawk did not double an embedded backslash. So a package name or version containing a backslash or a doublequote rendered as malformed JSON on Linux, in the lock --check/--diff --json and workspace diff drift contract. Escape char-by-char via portable string concatenation instead: identical, correct output on both awks. Also adds the regression tests these renderers never had (both were stubbed out everywhere): render_drift_json object shapes, its backslash/doublequote escaping, and empty-stdin; plus the render_drift_human +/-/~ table. Those tests surfaced the divergence - green on macOS, red on the Linux gate.
…ore its worktree scratch Invoking the workflow by name with an args object delivers args to the script as a JSON string, so the stock args.streams guard saw undefined and threw before any agent ran. Parse args when it arrives as a string. Also gitignore .claude/worktrees/ (the per-run isolated worktree scratch, which otherwise shows as untracked) and record the real-run gotchas in the workflow README: a fresh worktree lacks the bats submodule (make setup), test-unit runs >2min, and the wt/<id> branches + worktrees survive for the driver to integrate/prune.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Integrated output of the first
parallel-worktreeworkflow dry-run, gated on macOS and the Linux VM.Commits (rebase-merge, land individually)
agents/plandex.config.sh); auto-discovered, egress locked toapi-v2.plandex.ai(verified against the Plandex CLI source, not its docs).api-v2.plandex.ai: the preset's proxy backend accepts POST bodies like the cursor/amp/qwen/crush hosts, so it belongs inlaundering_host()+ the wildcard-cover anchor. Regression tests added.plandexin theagents.mdpreset table + the README enumerations.render_drift_jsonJSON-escaping portable across awks. It escaped via agsubwhose replacement contains a backslash; mawk (Debian/CI) and macOS's BSD awk disagree there, so mawk did not double an embedded backslash — a package name/version containing\or"produced malformed JSON on Linux in thelock --json/workspace diffdrift contract. Now escapes char-by-char. Surfaced by the new regression tests: green on macOS, red on the Linux gate.SLUICE_EGRESS_FLAG_BYTES(was omitted despite the "every user-facing knob" promise).parallel-worktreetolerate string-deliveredargs, gitignore its.claude/worktrees/scratch, and record field gotchas in the workflow README.Gate
build-check+lint+test-unit(380/380) — greenlint+build-check+test-unit(380/380) — greenDeferred follow-up
nightly-agents.batsplandex probe (nightly/engine lane — cannot be validated in the unit lane).