release: @ruvector/rvagent-wasm 0.2.0 — ruflo ADR-129 integration support

- Bump version 0.1.0 → 0.2.0 in Cargo.toml and test_version_string
- Add CHANGELOG.md with 0.1.0 history and 0.2.0 changes
- Update README: correct package name (@ruvector/rvagent-wasm, not rvagent-wasm)
- Update README: Node.js target docs, JsModelProvider + addMcpTools examples (ADR-129)
- Update README: ruflo/@claude-flow/cli >=3.10.4 compatibility note
- Add .github/workflows/publish-rvagent-wasm.yml for one-shot npm publish via CI

No Rust logic changes. All ADR-129 gap APIs (JsModelProvider, set_model_provider,
addMcpTools, get_state, get_todos, reset, WasmGallery full surface) were already
implemented in 0.1.0. Gaps are purely ruflo TypeScript wiring issues.

Co-Authored-By: RuFlo <ruv@ruv.net>
This commit is contained in:
ruv 2026-05-27 22:45:01 -04:00
parent cf074121e5
commit fc6f8d77eb
6 changed files with 210 additions and 47 deletions

View file

@ -0,0 +1,102 @@
name: Publish @ruvector/rvagent-wasm
on:
workflow_dispatch:
inputs:
version:
description: 'Version to publish (e.g., 0.2.0)'
required: true
type: string
default: '0.2.0'
dry_run:
description: 'Dry run (build only, no publish)'
required: false
type: boolean
default: false
env:
CARGO_TERM_COLOR: always
jobs:
publish:
name: Build and Publish @ruvector/rvagent-wasm
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: release/rvagent-wasm-0.2.0
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- name: Cache Rust
uses: Swatinem/rust-cache@v2
with:
key: rvagent-wasm-${{ inputs.version }}
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Verify version matches input
working-directory: crates/rvAgent/rvagent-wasm
run: |
CARGO_VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/version = "//;s/"//')
echo "Cargo.toml version: $CARGO_VERSION"
echo "Input version: ${{ inputs.version }}"
if [ "$CARGO_VERSION" != "${{ inputs.version }}" ]; then
echo "ERROR: Version mismatch!"
exit 1
fi
- name: Run Rust tests
working-directory: crates/rvAgent/rvagent-wasm
run: cargo test
- name: Build WASM (nodejs target)
working-directory: crates/rvAgent/rvagent-wasm
run: wasm-pack build --target nodejs --release
- name: Fix pkg/package.json name and metadata
working-directory: crates/rvAgent/rvagent-wasm/pkg
run: |
# wasm-pack strips the @ruvector/ scope — restore it
node -e "
const pkg = JSON.parse(require('fs').readFileSync('package.json', 'utf8'));
pkg.name = '@ruvector/rvagent-wasm';
pkg.type = 'module';
pkg.sideEffects = ['./snippets/*'];
require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
"
echo "Fixed package.json:"
cat package.json
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
- name: Publish to npm (dry run)
if: ${{ inputs.dry_run }}
working-directory: crates/rvAgent/rvagent-wasm/pkg
run: npm publish --access public --dry-run
- name: Publish to npm
if: ${{ !inputs.dry_run }}
working-directory: crates/rvAgent/rvagent-wasm/pkg
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Verify published version
if: ${{ !inputs.dry_run }}
run: |
sleep 10
PUBLISHED=$(npm view @ruvector/rvagent-wasm@${{ inputs.version }} version 2>/dev/null || echo "not found")
echo "Published version: $PUBLISHED"
if [ "$PUBLISHED" != "${{ inputs.version }}" ]; then
echo "WARNING: Could not verify published version (may need more time to propagate)"
fi

2
Cargo.lock generated
View file

@ -11027,7 +11027,7 @@ dependencies = [
[[package]]
name = "rvagent-wasm"
version = "0.1.0"
version = "0.2.0"
dependencies = [
"js-sys",
"serde",

View file

@ -0,0 +1,48 @@
# Changelog — @ruvector/rvagent-wasm
All notable changes to this package will be documented here.
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [0.2.0] — 2026-05-27
### Added
- `CHANGELOG.md` (this file)
- ruflo / `@claude-flow/cli` integration documentation in README
- ADR-129 reference: documents `JsModelProvider` + `addMcpTools()` wiring patterns
- Explicit Node.js CommonJS usage examples (`require('@ruvector/rvagent-wasm/rvagent_wasm.js')`)
- `WasmRvfBuilder.addMcpTools()` usage example showing ruflo ADR-129 Gap 2 pattern
- `WasmGallery` direct API examples (Gap 3 / Gap 4 methods already implemented)
- Security limits documented: RVF 10 MB max, capability delegation depth 10, gallery 100 custom
### Changed
- Version bumped from 0.1.0 to 0.2.0
- README corrected: package name is `@ruvector/rvagent-wasm` (not unscoped `rvagent-wasm`)
- README corrected: published artifact uses `nodejs` wasm-pack target (not `web`)
- README: import example updated from browser ESM to Node.js CommonJS (primary usage)
- `pkg/package.json` name field fixed to `@ruvector/rvagent-wasm` (scoped)
### No Rust changes
All WASM-level APIs are identical to 0.1.0. The full ADR-129 gap surface
(`JsModelProvider`, `set_model_provider`, `addMcpTools`, `get_state`, `get_todos`, `reset`,
all `WasmGallery` methods) was already implemented in 0.1.0. This release documents and
republishes with corrected metadata.
### Compatible with
- `@claude-flow/cli >= 3.10.4`
- wasm-pack 0.14.x, 0.15.x
- Rust 1.80+, wasm32-unknown-unknown target
---
## [0.1.0] — 2026-03-17
### Added
- Initial release
- `WasmAgent`: agent execution with virtual filesystem, conversation history, `JsModelProvider` callback
- `JsModelProvider`: JS-to-Rust model callback bridge (`async (messagesJson) => string`)
- `WasmRvfBuilder`: RVF cognitive container builder (tools, prompts, skills, mcp_tools, capabilities, orchestrator)
- `WasmGallery`: 6 built-in templates (coder, researcher, tester, reviewer, security, swarm-orchestrator)
- `WasmMcpServer`: MCP JSON-RPC server running in WASM
- Virtual filesystem tools: `read_file`, `write_file`, `edit_file`, `list_files`, `write_todos`
- SHA3-256 checksum on RVF containers
- Security: request size limits, path traversal protection, capability delegation depth limit

View file

@ -1,6 +1,6 @@
[package]
name = "rvagent-wasm"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
description = "rvAgent WASM bindings — browser and Node.js agent execution"
license = "MIT OR Apache-2.0"

View file

@ -13,22 +13,32 @@ WASM bindings for rvAgent — run AI agents entirely in the browser or Node.js.
## Installation
```bash
# Build from source
cd crates/rvAgent/rvagent-wasm
wasm-pack build --target web
npm install @ruvector/rvagent-wasm
```
# Or use the pre-built package
npm install rvagent-wasm # (Not yet published)
## Building from Source
```bash
cd crates/rvAgent/rvagent-wasm
# Node.js target (used by ruflo / @claude-flow/cli >= 3.10.4)
wasm-pack build --target nodejs --release
# Browser target
wasm-pack build --target web --release
```
## Usage
### WasmAgent
### WasmAgent (Node.js / ruflo integration)
```javascript
import init, { WasmAgent } from 'rvagent-wasm';
// Node.js CommonJS (used by ruflo / @claude-flow/cli)
const { WasmAgent, JsModelProvider } = require('@ruvector/rvagent-wasm/rvagent_wasm.js');
await init();
// Browser ESM
// import init, { WasmAgent } from '@ruvector/rvagent-wasm';
// await init();
// Create an agent
const agent = new WasmAgent(JSON.stringify({
@ -38,15 +48,13 @@ const agent = new WasmAgent(JSON.stringify({
max_turns: 50
}));
// Connect a model provider (calls your LLM API)
agent.set_model_provider(async (messagesJson) => {
// Wire a real LLM via JsModelProvider (ADR-129 Gap 1 pattern)
const provider = new JsModelProvider(async (messagesJson) => {
const messages = JSON.parse(messagesJson);
const response = await fetch('/api/chat', {
method: 'POST',
body: JSON.stringify({ messages })
});
return (await response.json()).content;
const response = await callYourLLM({ messages });
return JSON.stringify({ role: 'assistant', content: response.content });
});
agent.set_model_provider(provider.complete.bind(provider));
// Send a prompt
const result = await agent.prompt("Write a hello world function");
@ -66,9 +74,7 @@ console.log(agent.get_todos()); // []
Run an MCP server entirely in the browser:
```javascript
import init, { WasmMcpServer } from 'rvagent-wasm';
await init();
const { WasmMcpServer } = require('@ruvector/rvagent-wasm/rvagent_wasm.js');
const mcp = new WasmMcpServer("rvagent-wasm");
@ -92,32 +98,24 @@ const result = mcp.call_tool("write_file", JSON.stringify({
### Gallery System
Access built-in agent templates:
Access built-in agent templates directly:
```javascript
const { WasmGallery } = require('@ruvector/rvagent-wasm/rvagent_wasm.js');
const gallery = new WasmGallery();
// List all templates
const templates = mcp.handle_request(JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "gallery/list",
params: {}
}));
const templates = gallery.list();
// Search templates
const searchResults = mcp.handle_request(JSON.stringify({
jsonrpc: "2.0",
id: 2,
method: "gallery/search",
params: { query: "coding assistant" }
}));
const results = gallery.search("security testing");
// Load a template
const loaded = mcp.handle_request(JSON.stringify({
jsonrpc: "2.0",
id: 3,
method: "gallery/load",
params: { id: "claude-code" }
}));
// Get template details
const coder = gallery.get("coder");
// Load as RVF container
const rvfBytes = gallery.loadRvf("coder"); // Uint8Array
```
## Available Tools
@ -183,20 +181,22 @@ const loaded = mcp.handle_request(JSON.stringify({
| `name()` | Get server name |
| `version()` | Get server version |
## Building
## Development
```bash
# Install wasm-pack
cargo install wasm-pack
# Build for Node.js (published artifact)
wasm-pack build --target nodejs --release
# Build for web
wasm-pack build --target web
wasm-pack build --target web --release
# Build for Node.js
wasm-pack build --target nodejs
# Run tests
# Run Rust unit tests (61 tests, no WASM runtime needed)
cargo test
# Run WASM tests in browser
wasm-pack test --headless --chrome
```
@ -226,6 +226,19 @@ rvagent-wasm/
└── rvagent_wasm_bg.wasm
```
## ruflo / @claude-flow/cli Integration
Compatible with `@claude-flow/cli >= 3.10.4`. ADR-129 closes two gaps in the ruflo-side wiring:
- **Gap 1**: Wire `JsModelProvider` so `wasm_agent_prompt` uses a real LLM (not echo stub)
- **Gap 2**: Call `WasmRvfBuilder.addMcpTools()` in `buildRvfContainer` and expose `wasm_agent_compose`
All needed methods (`JsModelProvider`, `set_model_provider`, `addMcpTools`, `get_state`,
`get_todos`, `reset`) are implemented in this WASM package. The gaps are purely TypeScript
wiring issues in the ruflo consumer layer.
See [ADR-129](https://github.com/ruvnet/ruflo/blob/main/v3/docs/adr/ADR-129-rvagent-full-integration.md).
## Related Crates
| Crate | Description |

View file

@ -375,7 +375,7 @@ mod tests {
#[test]
fn test_version_string() {
assert_eq!(VERSION, "0.1.0");
assert_eq!(VERSION, "0.2.0");
}
#[test]