Skip to content
Merged
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
79 changes: 62 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,12 +266,40 @@ npm run check

## Distribution Artifacts

The CLI package is prepared as `@automattic/wp-codebox-cli` and exposes the
`wp-codebox` binary from `packages/cli/dist/index.js`.
The GitHub Release workspace tarball exposes the stable `wp-codebox` binary from
`packages/cli/dist/index.js`. The scoped npm packages are prepared under
`@automattic/wp-codebox-*`, but they are not published yet; do not document
`npm install -g @automattic/wp-codebox-cli` as an available install path until
the package exists in the registry.

```bash
npm run build
npm pack --workspace @automattic/wp-codebox-cli --dry-run --json
npm pack --json
```

Install a GitHub Release tarball built from a release that includes the root
`bin` mapping when a downstream control plane needs a stable binary path without
pointing at a local feature worktree:

```bash
npm install -g https://github.com/Automattic/wp-codebox/releases/download/v<VERSION>/wp-codebox-workspace-<VERSION>.tgz
wp-codebox commands --json
wp-codebox recipe validate --recipe ./examples/recipes/cookbook/codex-agent-smoke.json --json
```

`v0.4.0` includes the fresh sandbox session fix and Codex recipe example, but its
release asset predates the root `bin` mapping. Release managers need to cut a new
release from a commit containing this section before relying on the GitHub
Release tarball as the stable installed binary path.

For a future npm release, publish all three scoped packages from the same clean
release commit after approval:

```bash
npm publish --workspace @automattic/wp-codebox-core --access public
npm publish --workspace @automattic/wp-codebox-playground --access public
npm publish --workspace @automattic/wp-codebox-cli --access public
```

The WordPress plugin zip is built from `packages/wordpress-plugin` with only the
Expand All @@ -284,10 +312,13 @@ unzip -Z1 packages/wordpress-plugin/dist/wp-codebox.zip

`npm run package-distribution-smoke` validates both artifact shapes. It checks
that the CLI pack includes `package.json`, `README.md`, and compiled `dist/`
files without TypeScript source, then builds the WordPress plugin zip and checks
that it contains the plugin bootstrap, README, PHP sources, checked-in browser
runtime asset, and vendored CLI runtime without package metadata or generated
artifacts.
files without TypeScript source, checks that the root release tarball installs a
`wp-codebox` binary, then builds the WordPress plugin zip and checks that it
contains the plugin bootstrap, README, PHP sources, checked-in browser runtime
asset, and vendored CLI runtime without package metadata or generated artifacts.
`npm run package-installed-binary-smoke` packs the root release tarball, installs
it into a temporary global prefix, and verifies the installed `wp-codebox`
binary can emit the command catalog.

Versioning and release policy:

Expand All @@ -296,18 +327,21 @@ Versioning and release policy:
`@automattic/wp-codebox-playground` stay on the same version.
2. Keep `packages/wordpress-plugin/wp-codebox.php` `Version:` aligned with the
package version used for the matching plugin zip.
3. Treat the npm package and plugin zip as one release unit: publish the CLI,
build the plugin zip from the same commit, and attach the zip to the release.
3. Treat the release tarball, npm packages, and plugin zip as one release unit:
attach the root `wp-codebox-workspace-<version>.tgz` tarball, publish the
scoped npm packages when approved, build the plugin zip from the same commit,
and attach the zip to the release.
4. Use conventional semver: patch for fixes and docs-only distribution updates,
minor for new commands or artifact fields, major for runtime contract breaks.

Install notes by environment:

1. Self-hosted WordPress control planes should install the CLI on the same host
that runs PHP, install `packages/wordpress-plugin/dist/wp-codebox.zip` as the
parent-site plugin, then set `wp_codebox_bin` to the resolved `wp-codebox`
binary path. Component paths can be supplied through
`wp_codebox_component_paths` or the matching filter.
that runs PHP from the GitHub Release workspace tarball, install
`packages/wordpress-plugin/dist/wp-codebox.zip` as the parent-site plugin,
then set `wp_codebox_bin` to the resolved `wp-codebox` binary path. Component
paths can be supplied through `wp_codebox_component_paths` or the matching
filter.
2. Studio or local development environments can run from a checkout with
`npm install`, `npm run build`, and `npm run wp-codebox -- ...`; install the
plugin zip into the local parent site and point `wp_codebox_bin` at either
Expand All @@ -325,11 +359,22 @@ options because the executable path is host-level configuration.
Release checklist:

1. Run `npm run check` from a clean checkout.
2. Review `npm pack --workspace @automattic/wp-codebox-cli --dry-run --json` before publishing the CLI package.
3. Build `packages/wordpress-plugin/dist/wp-codebox.zip` with `npm run package:wordpress-plugin` and inspect `unzip -Z1 packages/wordpress-plugin/dist/wp-codebox.zip`.
4. Confirm package and plugin versions are aligned on the release commit.
5. Install the CLI in the target environment and configure the WordPress plugin `wp_codebox_bin` option or filter to the resolved `wp-codebox` binary path.
6. Install the plugin zip on the parent site and run the WordPress plugin smoke or equivalent ability registration check in that environment.
2. Run `npm run package-installed-binary-smoke` to verify the root release
tarball installs a working `wp-codebox` binary.
3. Review `npm pack --workspace @automattic/wp-codebox-cli --dry-run --json` before publishing the CLI package.
4. Build `packages/wordpress-plugin/dist/wp-codebox.zip` with
`npm run package:wordpress-plugin` and inspect
`unzip -Z1 packages/wordpress-plugin/dist/wp-codebox.zip`.
5. Confirm package and plugin versions are aligned on the release commit.
6. Build the root release tarball and attach it to the matching GitHub Release:
`npm pack --json`. The expected asset name is
`wp-codebox-workspace-<version>.tgz`.
7. If npm publishing is approved, publish the scoped packages with the exact
`npm publish --workspace ... --access public` commands above.
8. Install the CLI in the target environment and configure the WordPress plugin
`wp_codebox_bin` option or filter to the resolved `wp-codebox` binary path.
9. Install the plugin zip on the parent site and run the WordPress plugin smoke
or equivalent ability registration check in that environment.

## Quick Start

Expand Down
21 changes: 21 additions & 0 deletions examples/recipes/cookbook/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,27 @@ npm run wp-codebox -- recipe-run \
--json
```

When running from an installed release binary, replace `npm run wp-codebox --`
with `wp-codebox`:

```bash
wp-codebox recipe-run \
--recipe ./examples/recipes/cookbook/codex-agent-smoke.json \
--json
```

The stable installed path is the GitHub Release workspace tarball from a release
that includes the root `bin` mapping, not the unpublished npm package:

```bash
npm install -g https://github.com/Automattic/wp-codebox/releases/download/v<VERSION>/wp-codebox-workspace-<VERSION>.tgz
```

`v0.4.0` includes the fresh sandbox session fix used by the Codex smoke path, but
its release asset predates the root `bin` mapping. Release managers should cut a
new release, attach a new root workspace tarball, and publish the scoped npm
packages from the same commit once npm publishing is approved.

The expected successful response is a JSON recipe run whose agent runtime
reports the Playground site title and active theme. Fleet runners such as
Homeboy should generate one recipe/run per task and own queueing,
Expand Down
3 changes: 3 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
"import": "./packages/cli/dist/index.js"
}
},
"bin": {
"wp-codebox": "packages/cli/dist/index.js"
},
"files": [
"packages/runtime-core/dist",
"packages/runtime-core/package.json",
Expand All @@ -34,6 +37,7 @@
"postinstall": "node scripts/normalize-playground-sqlite-package.mjs",
"package:wordpress-plugin": "tsx scripts/build-wordpress-plugin-zip.ts",
"package-distribution-smoke": "tsx scripts/package-distribution-smoke.ts",
"package-installed-binary-smoke": "tsx scripts/package-installed-binary-smoke.ts",
"release:package": "tsx scripts/package-release-artifact.ts",
"artifact-bundle-verifier-smoke": "tsx scripts/artifact-bundle-verifier-smoke.ts",
"artifact-redaction-smoke": "tsx scripts/artifact-redaction-smoke.ts",
Expand Down
17 changes: 12 additions & 5 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,32 @@ reviewable artifact bundles. **Secure coding environments inside WordPress** —

## Install

The public `@automattic/wp-codebox-cli` npm package is not published yet. Until
that package exists, install a GitHub Release workspace tarball built from a
release that includes the root `bin` mapping:

```bash
npm install -g @automattic/wp-codebox-cli
npm install -g https://github.com/Automattic/wp-codebox/releases/download/v<VERSION>/wp-codebox-workspace-<VERSION>.tgz
wp-codebox --help
```

The package exposes the `wp-codebox` binary and includes the compiled
`dist/` entrypoint only. Build from source with `npm run build` before running
local package validation.
Release tarball installs expose the `wp-codebox` binary from the compiled
`packages/cli/dist/` entrypoint. Build from source with `npm run build` before
running local package validation.

## Smoke

```bash
npm run build
npm run package-distribution-smoke
npm run package-installed-binary-smoke
```

The distribution smoke runs `npm pack --dry-run --json` and verifies the package
contains `package.json`, `README.md`, and the compiled CLI entrypoint used by the
published binary.
published binary. The installed binary smoke packs the root release tarball,
installs it into a temporary global prefix, and verifies `wp-codebox commands
--json` works from that installed path.

## Discovery

Expand Down
7 changes: 7 additions & 0 deletions scripts/package-distribution-smoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const execFileAsync = promisify(execFile)
const repoRoot = resolve(import.meta.dirname, "..")

const rootPackage = JSON.parse(await readFile(resolve(repoRoot, "package.json"), "utf8")) as {
bin?: Record<string, string>
dependencies?: Record<string, string>
devDependencies?: Record<string, string>
}
Expand Down Expand Up @@ -47,6 +48,12 @@ assert.ok(
rootPackedFiles.has("scripts/normalize-playground-sqlite-package.mjs"),
"Root package should ship the Playground SQLite package normalizer for clean installs",
)
assert.equal(
rootPackage.bin?.["wp-codebox"],
"packages/cli/dist/index.js",
"Root release tarball should install the stable wp-codebox binary",
)
assert.ok(rootPackedFiles.has("packages/cli/dist/index.js"), "Root package should ship the compiled CLI binary target")

await execFileAsync("npm", ["run", "package:wordpress-plugin"], { cwd: repoRoot, maxBuffer: 1024 * 1024 * 10 })
const pluginZip = resolve(repoRoot, "packages", "wordpress-plugin", "dist", "wp-codebox.zip")
Expand Down
45 changes: 45 additions & 0 deletions scripts/package-installed-binary-smoke.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import assert from "node:assert/strict"
import { execFile } from "node:child_process"
import { mkdir, mkdtemp, rm } from "node:fs/promises"
import { tmpdir } from "node:os"
import { join, resolve } from "node:path"
import { promisify } from "node:util"

const execFileAsync = promisify(execFile)
const repoRoot = resolve(import.meta.dirname, "..")
const tempRoot = await mkdtemp(join(tmpdir(), "wp-codebox-installed-binary-smoke-"))
const packRoot = join(tempRoot, "pack")
const installRoot = join(tempRoot, "install")

try {
await execFileAsync("npm", ["run", "build"], { cwd: repoRoot, maxBuffer: 1024 * 1024 * 10 })
await mkdir(packRoot, { recursive: true })

const { stdout: packStdout } = await execFileAsync("npm", ["pack", "--json", "--pack-destination", packRoot], {
cwd: repoRoot,
maxBuffer: 1024 * 1024 * 10,
})
const [pack] = JSON.parse(packStdout) as Array<{ filename: string }>
const tarballPath = join(packRoot, pack.filename)

await execFileAsync("npm", ["install", "--global", tarballPath, "--prefix", installRoot, "--no-audit", "--no-fund"], {
cwd: repoRoot,
maxBuffer: 1024 * 1024 * 40,
})

const binaryPath = join(installRoot, "bin", "wp-codebox")
const { stdout } = await execFileAsync(binaryPath, ["commands", "--json"], {
cwd: repoRoot,
maxBuffer: 1024 * 1024 * 10,
})
const catalog = JSON.parse(stdout) as { schema?: string; commands?: Array<{ id?: string }> }
assert.equal(catalog.schema, "wp-codebox/command-catalog/v1", "Installed binary should emit the command catalog")
assert.ok(
catalog.commands?.some((command) => command.id === "wp-codebox.agent-sandbox-run"),
"Installed binary should expose the agent sandbox recipe helper",
)

console.log("Package installed binary smoke passed")
} finally {
await rm(tempRoot, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 })
}