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

@ -1090,9 +1090,9 @@ fn write_mock_agent_process_launcher(path: &Path) -> Result<(), AgentError> {
fs::create_dir_all(parent)?;
}
let script = if cfg!(windows) {
"@echo off\r\necho mock agent process is in-process in sandbox-agent\r\nexit /b 1\r\n"
"@echo off\r\nsandbox-agent mock-agent-process %*\r\n"
} else {
"#!/usr/bin/env sh\necho 'mock agent process is in-process in sandbox-agent'\nexit 1\n"
"#!/usr/bin/env sh\nexec sandbox-agent mock-agent-process \"$@\"\n"
};
write_text_file(path, script)
}

View file

@ -83,6 +83,9 @@ pub enum Command {
InstallAgent(InstallAgentArgs),
/// Inspect locally discovered credentials.
Credentials(CredentialsArgs),
/// Internal: stdio JSON-RPC echo agent for the mock agent process.
#[command(hide = true)]
MockAgentProcess,
}
#[derive(Args, Debug)]
@ -406,6 +409,7 @@ pub fn run_command(command: &Command, cli: &CliConfig) -> Result<(), CliError> {
Command::Daemon(subcommand) => run_daemon(&subcommand.command, cli),
Command::InstallAgent(args) => install_agent_local(args),
Command::Credentials(subcommand) => run_credentials(&subcommand.command),
Command::MockAgentProcess => run_mock_agent_process(),
}
}
@ -929,6 +933,71 @@ fn run_credentials(command: &CredentialsCommand) -> Result<(), CliError> {
}
}
fn run_mock_agent_process() -> Result<(), CliError> {
use std::io::BufRead;
let stdin = std::io::stdin();
let reader = stdin.lock();
for line in reader.lines() {
let line = line.map_err(|e| CliError::Server(format!("stdin read error: {}", e)))?;
if line.trim().is_empty() {
continue;
}
let msg: Value = match serde_json::from_str(&line) {
Ok(v) => v,
Err(e) => {
let err_notification = json!({
"jsonrpc": "2.0",
"method": "mock/parse_error",
"params": {
"error": e.to_string(),
"raw": line,
}
});
write_stdout_line(&serde_json::to_string(&err_notification)?)?;
continue;
}
};
// Echo notification for every message
let echo = json!({
"jsonrpc": "2.0",
"method": "mock/echo",
"params": { "message": msg }
});
write_stdout_line(&serde_json::to_string(&echo)?)?;
let has_method = msg.get("method").and_then(|v| v.as_str()).is_some();
let has_id = msg.get("id").is_some();
if has_method && has_id {
// Request -> respond with echo result
let response = json!({
"jsonrpc": "2.0",
"id": msg["id"],
"result": { "echoed": msg }
});
write_stdout_line(&serde_json::to_string(&response)?)?;
} else if !has_method && has_id {
// Client response
let notification = json!({
"jsonrpc": "2.0",
"method": "mock/client_response",
"params": {
"id": msg["id"],
"result": msg.get("result").unwrap_or(&Value::Null),
"error": msg.get("error").unwrap_or(&Value::Null),
}
});
write_stdout_line(&serde_json::to_string(&notification)?)?;
}
}
Ok(())
}
fn load_json_payload(
json_inline: Option<&str>,
json_file: Option<&std::path::Path>,