fix: mock agent process, React 18/19 types, release version refs

- Add hidden `mock-agent-process` CLI subcommand implementing a stdio
  JSON-RPC echo agent (ported from examples/mock-acp-agent)
- Update write_mock_agent_process_launcher() to exec the new subcommand
  instead of exiting with error
- Update sdks/react to support React 18 and 19 peer dependencies
- Update @types/react to v19 across workspace (pnpm override + inspector)
- Fix RefObject<T | null> compatibility for React 19 useRef() signatures
- Add version reference replacement logic to release update_version.ts
  covering all docs, examples, and code files listed in CLAUDE.md
- Add missing files to CLAUDE.md Install Version References list
  (architecture.mdx, boxlite, modal, computesdk docs and examples)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nathan Flurry 2026-03-15 22:36:48 -07:00
parent 2f9f25ae54
commit bf543d225d
14 changed files with 296 additions and 100 deletions

View file

@ -2,6 +2,7 @@ import * as fs from "node:fs/promises";
import { join } from "node:path";
import { $ } from "execa";
import { glob } from "glob";
import * as semver from "semver";
import type { ReleaseOpts } from "./main";
function assert(condition: any, message?: string): asserts condition {
@ -10,13 +11,56 @@ function assert(condition: any, message?: string): asserts condition {
}
}
// Files containing version references that need channel/image tag updates.
// Keep in sync with CLAUDE.md "Install Version References" section.
const VERSION_REFERENCE_FILES = [
"README.md",
"docs/acp-http-client.mdx",
"docs/cli.mdx",
"docs/quickstart.mdx",
"docs/sdk-overview.mdx",
"docs/react-components.mdx",
"docs/session-persistence.mdx",
"docs/architecture.mdx",
"docs/deploy/local.mdx",
"docs/deploy/cloudflare.mdx",
"docs/deploy/vercel.mdx",
"docs/deploy/daytona.mdx",
"docs/deploy/e2b.mdx",
"docs/deploy/docker.mdx",
"docs/deploy/boxlite.mdx",
"docs/deploy/modal.mdx",
"docs/deploy/computesdk.mdx",
"frontend/packages/website/src/components/GetStarted.tsx",
".claude/commands/post-release-testing.md",
"examples/cloudflare/Dockerfile",
"examples/boxlite/Dockerfile",
"examples/boxlite-python/Dockerfile",
"examples/daytona/src/index.ts",
"examples/shared/src/docker.ts",
"examples/docker/src/index.ts",
"examples/e2b/src/index.ts",
"examples/vercel/src/index.ts",
"sdks/typescript/src/providers/shared.ts",
"scripts/release/main.ts",
"scripts/release/promote-artifacts.ts",
"scripts/release/sdk.ts",
"scripts/sandbox-testing/test-sandbox.ts",
];
export async function updateVersion(opts: ReleaseOpts) {
// 1. Update workspace version and internal crate versions in root Cargo.toml
// 1. Read current version from Cargo.toml before overwriting
const cargoTomlPath = join(opts.root, "Cargo.toml");
let cargoContent = await fs.readFile(cargoTomlPath, "utf-8");
const oldVersionMatch = cargoContent.match(/\[workspace\.package\]\nversion = "([^"]+)"/);
assert(oldVersionMatch, "Could not find workspace.package version in Cargo.toml");
const oldVersion = oldVersionMatch[1];
const oldParsed = semver.parse(oldVersion);
assert(oldParsed, `Could not parse old version: ${oldVersion}`);
const oldMinorChannel = `${oldParsed.major}.${oldParsed.minor}.x`;
// Update [workspace.package] version
assert(/\[workspace\.package\]\nversion = ".*"/.test(cargoContent), "Could not find workspace.package version in Cargo.toml");
cargoContent = cargoContent.replace(/\[workspace\.package\]\nversion = ".*"/, `[workspace.package]\nversion = "${opts.version}"`);
// Discover internal crates from [workspace.dependencies] by matching
@ -69,4 +113,70 @@ export async function updateVersion(opts: ReleaseOpts) {
await fs.writeFile(fullPath, updated);
await $({ cwd: opts.root })`git add ${relPath}`;
}
// 3. Update version references across docs, examples, and code
await updateVersionReferences(opts, oldVersion, oldMinorChannel);
}
async function updateVersionReferences(opts: ReleaseOpts, oldVersion: string, oldMinorChannel: string) {
const newMinorChannel = opts.minorVersionChannel;
// Find old Docker image tags by scanning for rivetdev/sandbox-agent:<version>-full patterns
// The old version might be a different patch or RC, so we match any version-full tag
const oldDockerTagPattern = /rivetdev\/sandbox-agent:([0-9]+\.[0-9]+\.[0-9]+(?:-[a-zA-Z0-9.]+)?)-full/;
console.log(`\nUpdating version references:`);
console.log(` Old minor channel: ${oldMinorChannel}`);
console.log(` New minor channel: ${newMinorChannel}`);
console.log(` New Docker tag: ${opts.version}-full`);
const modifiedFiles: string[] = [];
for (const relPath of VERSION_REFERENCE_FILES) {
const fullPath = join(opts.root, relPath);
let content: string;
try {
content = await fs.readFile(fullPath, "utf-8");
} catch (err: any) {
if (err.code === "ENOENT") {
console.log(` ⚠️ Skipping ${relPath} (file not found)`);
continue;
}
throw err;
}
const original = content;
// Replace minor channel references (e.g. sandbox-agent@0.3.x -> sandbox-agent@0.4.x)
content = content.replaceAll(`sandbox-agent@${oldMinorChannel}`, `sandbox-agent@${newMinorChannel}`);
content = content.replaceAll(`@sandbox-agent/cli@${oldMinorChannel}`, `@sandbox-agent/cli@${newMinorChannel}`);
content = content.replaceAll(`@sandbox-agent/react@${oldMinorChannel}`, `@sandbox-agent/react@${newMinorChannel}`);
// Replace install script URL channel
content = content.replaceAll(`releases.rivet.dev/sandbox-agent/${oldMinorChannel}/`, `releases.rivet.dev/sandbox-agent/${newMinorChannel}/`);
// Replace Docker image tags (rivetdev/sandbox-agent:<anything>-full -> rivetdev/sandbox-agent:<version>-full)
content = content.replaceAll(
new RegExp(`rivetdev/sandbox-agent:[0-9]+\\.[0-9]+\\.[0-9]+(?:-[a-zA-Z0-9.]+)?-full`, "g"),
`rivetdev/sandbox-agent:${opts.version}-full`,
);
// Replace standalone version-full references in prose (e.g. "The `0.3.2-full` tag pins...")
// Match backtick-wrapped version-full patterns
content = content.replaceAll(new RegExp("`[0-9]+\\.[0-9]+\\.[0-9]+(?:-[a-zA-Z0-9.]+)?-full`", "g"), `\`${opts.version}-full\``);
if (content !== original) {
await fs.writeFile(fullPath, content);
modifiedFiles.push(relPath);
console.log(`${relPath}`);
}
}
if (modifiedFiles.length > 0) {
await $({ cwd: opts.root })`git add ${modifiedFiles}`;
console.log(`\nUpdated ${modifiedFiles.length} files with version references.`);
} else {
console.log(`\nNo version reference files needed updates.`);
}
}