Skip to content

Studio Code: Read the file a wp_cli --post_content path names - #5305

Merged
chubes4 merged 4 commits into
trunkfrom
studio-code/post-content-file-path
Oct 23, 2026
Merged

chubes4 merged 4 commits into
trunkfrom
studio-code/post-content-file-path

Conversation

@chubes4

@chubes4 chubes4 commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Related issues

How AI was used in this PR

Claude (via the Pi coding agent in a Roadie session) wrote the change and the tests, and ran the checks below. I reviewed the diff and the tool output.

Proposed Changes

WP-CLI's --post_content takes the content itself; post create <file> and post update <id> <file> read it from a file. When post create or post update gets a --post_content value that is the path of a file in the site folder (absolute or relative to it), wp_cli now runs the command with that file as the positional argument, so the post gets the file's content. The result says so:

Read the post content from tmp/y.html, the file --post_content named.
Success: Updated post 6.

  • Unquoted content runs to the end of the command, so flags after the path (--porcelain) are split back out and kept.
  • Content that only looks like a path is saved as written, as before: a missing file, a folder, a file outside the site folder, a path inside text, or anything with markup.
  • Only post create and post update change. Every other command runs as written.
  • Nothing new becomes possible: the rewritten command is one the agent could already run. WP-CLI's post update reads the first non-numeric argument as the file, so several IDs still work.
  • --post_content=$(cat file) is still refused: shell syntax doesn't run, and that's a different mistake.

Testing Instructions

  • npx vitest run apps/cli/lib/tests/wp-cli-post-content.test.ts apps/cli/ai passes (289). New tests cover an absolute path, a relative path with flags around it, five values that look like paths but aren't files, files outside the site folder, and other commands.
  • Real site. The agent wrote tmp/x.html and tmp/y.html, then ran:
    • post create --post_type=page --post_title=Probe --post_status=publish --post_content=<absolute path of x.html> --porcelain: page 6 created.
    • post update 6 --post_content=tmp/y.html: page 6 updated.
    • Page 6's content was then y.html's block markup. Without this change, the first command saves <path> --porcelain as the content.
  • No telemetry changes: the note goes to the tool result only.

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

@chubes4 chubes4 changed the title Studio Code: Refuse a file path passed to wp_cli as post content Studio Code: Read the file a wp_cli --post_content path names Oct 22, 2026
@chubes4
chubes4 marked this pull request as ready for review October 23, 2026 00:08
@wpmobilebot

Copy link
Copy Markdown
Collaborator

📊 Performance Test Results

Comparing c62c4db vs trunk

app-size

Metric trunk c62c4db Diff Change
App Size (Mac) 940.67 MB 940.67 MB +0.00 MB ⚪ 0.0%

site-editor

Metric trunk c62c4db Diff Change
load 1269 ms 1229 ms 40 ms ⚪ 0.0%

site-startup

Metric trunk c62c4db Diff Change
siteCreation 7550 ms 7532 ms 18 ms ⚪ 0.0%
siteStartup 4386 ms 4381 ms 5 ms ⚪ 0.0%

Results are median values from multiple test runs.

Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff)

@chubes4
chubes4 merged commit 51e0330 into trunk Oct 23, 2026
12 checks passed
@chubes4
chubes4 deleted the studio-code/post-content-file-path branch October 23, 2026 00:37
chubes4 added a commit that referenced this pull request Oct 23, 2026
…5310)

## Related issues

- Follows #5305, which stopped `wp_cli post create|update
--post_content=<file>` from saving the file's path. This PR handles
another way a post gets saved wrong while the command still reports
success.

## How AI was used

Claude (via the Pi coding agent in a Roadie session) found the failure
in eval transcripts, wrote the change and tests, and ran the eval below.
I reviewed the diff and the results.

## Proposed Changes

When `wp_cli post create|update --post_content=…` content starts with
`{` but doesn't parse as JSON, the tool saves nothing and returns the
parse error:

```
Nothing was saved: `--post_content` starts with `{` but is not valid JSON (Expected ',' or '}' after property value in JSON at position 174 (line 1 column 175)). WordPress ignores JSON post content that does not parse.
```

Block markup and HTML never start with `{`, so content that does is
JSON, such as a Global Styles post. When WordPress can't parse a Global
Styles post, it ignores the whole post. WP-CLI still saves it and prints
`Success: Updated post 5.`, so the agent has no sign anything went
wrong.

That happened in an eval run of `global-styles-db-override`. The agent's
JSON was missing its last `}`. Over the next 45 tool calls it checked
the CSS, cleared transients, read the theme JSON resolver's source, and
hex-dumped the post before finding the syntax error. The run used 1.4M
tokens; the other runs used about 90k.

The check is in `getUnsupportedWpCliPostContentMessage`, next to the
existing `$(cat …)` refusal. It doesn't depend on post types or the
database. It refuses instead of repairing because there's no single
correct fix for broken JSON.

## Testing Instructions

- `npx vitest run apps/cli/lib/tests/wp-cli-post-content.test.ts` covers
the exact command from the failed run. It is refused with the parse
error, and the same command with the brace restored is accepted.
- **Replay on a real site:** the failed run's command, sent unchanged
through `wp_cli`, was refused with the message above. The Global Styles
post kept its previous valid content (`#f6efe4`, line height `1.7`).
- **Eval:** `global-styles-db-override`, 6 runs on this branch. All 6
passed.

  | Run | Result | Tokens | Calls | What happened |
  |---|---|---|---|---|
| 0 | Pass | 209k | 16 | Refused once, then saved valid JSON on the next
call |
  | 1 | Pass | 110k | 10 | |
| 2 | Pass | 209k | 14 | Refused once, then saved valid JSON on the next
call |
  | 3 | Pass | 203k | 15 | |
| 4 | Pass | 1029k | 42 | Saved with `wp` in Bash, which this check
doesn't cover. Its JSON was missing the last `}`, and it took the same
debugging spiral |
  | 5 | Pass | 200k | 13 | |

In both refused runs, the agent's JSON was valid but `wp_cli` split the
quoting wrong. Run 0 wrapped the whole argument in single quotes, so a
trailing `'` ended up in the content. Run 2 escaped the inner double
quotes with backslashes, so the content was cut to `{\`. On trunk, both
would have been saved and reported as successful.

- `npx vitest run apps/cli/ai
apps/cli/lib/tests/wp-cli-post-content.test.ts` passes. Lint passes, and
the typecheck shows only the existing errors in `commands/export.ts` and
`commands/push.ts`.

## Pre-merge Checklist

- [x] Have you checked for TypeScript, React or other console errors?
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.

2 participants