mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-08-25 14:53:34 +00:00
* feat: add WASM extension versioning with WIT compat checks and CI enforcement Phase 1 — WIT Versioning & Compatibility Checks: - Version WIT packages as `package near:[email protected];` - Add `semver` crate for version parsing and comparison - Add `WIT_TOOL_VERSION` / `WIT_CHANNEL_VERSION` host constants - Add `version` and `wit_version` fields to capabilities schemas - Add `wit_version` column to `wasm_tools` DB table (both backends) - Add load-time `check_wit_version_compat()` with semver rules - Add `IncompatibleWitVersion` error variants for tools and channels - Enhance instantiation errors with WIT version mismatch hints - Update all 14 capabilities JSON and 14 registry JSON files Phase 2 — Upgrade-in-Place & Channel DB Storage: - Change tool store to DELETE-before-INSERT (one version per extension) - Create `wasm_channels` table (PostgreSQL migration + libSQL schema) - Add `WasmChannelStore` trait with PostgreSQL and libSQL backends - Add `extension_info` tool showing version, WIT version, and status - Wire `ExtensionInfoTool` into tool registry (7 extension tools) Phase 3 — CI Version-Bump Enforcement: - Add `scripts/check-version-bumps.sh` checking WIT/tool/channel versions - Add `version-check` CI job (PR-only) to `.github/workflows/test.yml` - Support `[skip-version-check]` label/commit message bypass Includes 7 regression tests for WIT version compatibility checking and 2 integration tests for WIT version annotation verification. [skip-regression-check] Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: address PR review feedback for WASM extension versioning - Wrap PostgreSQL DELETE+INSERT in transactions for both tool and channel store() methods to prevent data loss on partial failure (Gemini, Copilot) - Rename StoredWasmChannelWithBinary.tool → .channel (copy-paste fix) - Remove unused WasmError::IncompatibleWitVersion variant (dead code) - Map channel loader WIT mismatch to IncompatibleWitVersion instead of generic Config error, simplify variant to single String message - Fix extension_info description to match actual returned fields - Add schema test for ExtensionInfoTool matching existing test pattern - Fix CI script to fail fast on git errors instead of silent bypass [skip-regression-check] Co-Authored-By: Claude Opus 4.6 <[email protected]> --------- Co-authored-by: Claude Opus 4.6 <[email protected]>
93 lines
2.6 KiB
Rust
93 lines
2.6 KiB
Rust
//! Error types for WASM channels.
|
|
|
|
use std::path::PathBuf;
|
|
|
|
/// Error during WASM channel operations.
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum WasmChannelError {
|
|
#[error("Channel {name} failed to start: {reason}")]
|
|
StartupFailed { name: String, reason: String },
|
|
|
|
#[error("Channel {name} callback failed: {reason}")]
|
|
CallbackFailed { name: String, reason: String },
|
|
|
|
#[error("Channel {name} WASM execution trapped: {reason}")]
|
|
Trapped { name: String, reason: String },
|
|
|
|
#[error("Channel {name} callback '{callback}' timed out")]
|
|
Timeout { name: String, callback: String },
|
|
|
|
#[error("Channel {name} execution panicked: {reason}")]
|
|
ExecutionPanicked { name: String, reason: String },
|
|
|
|
#[error("Channel {name} emit rate limited")]
|
|
EmitRateLimited { name: String },
|
|
|
|
#[error("Channel {name} HTTP path not allowed: {path}")]
|
|
PathNotAllowed { name: String, path: String },
|
|
|
|
#[error("Channel {name} polling interval too short: {interval_ms}ms (minimum: {min_ms}ms)")]
|
|
PollIntervalTooShort {
|
|
name: String,
|
|
interval_ms: u32,
|
|
min_ms: u32,
|
|
},
|
|
|
|
#[error("Channel {name} workspace path escape attempt: {path}")]
|
|
WorkspaceEscape { name: String, path: String },
|
|
|
|
#[error("Channel {name} exhausted fuel limit ({limit})")]
|
|
FuelExhausted { name: String, limit: u64 },
|
|
|
|
#[error("IO error: {0}")]
|
|
Io(#[from] std::io::Error),
|
|
|
|
#[error("WASM file not found: {0}")]
|
|
WasmNotFound(PathBuf),
|
|
|
|
#[error("Capabilities file not found: {0}")]
|
|
CapabilitiesNotFound(PathBuf),
|
|
|
|
#[error("Invalid capabilities JSON: {0}")]
|
|
InvalidCapabilities(String),
|
|
|
|
#[error("WASM compilation error: {0}")]
|
|
Compilation(String),
|
|
|
|
#[error("WASM instantiation error: {0}")]
|
|
Instantiation(String),
|
|
|
|
#[error("Invalid channel name: {0}")]
|
|
InvalidName(String),
|
|
|
|
#[error("Channel {name} not found")]
|
|
NotFound { name: String },
|
|
|
|
#[error("Channel module missing export: {0}")]
|
|
MissingExport(String),
|
|
|
|
#[error("Invalid response from WASM: {0}")]
|
|
InvalidResponse(String),
|
|
|
|
#[error("Runtime not initialized")]
|
|
RuntimeNotInitialized,
|
|
|
|
#[error("Configuration error: {0}")]
|
|
Config(String),
|
|
|
|
#[error("Webhook registration failed for channel {name}: {reason}")]
|
|
WebhookRegistration { name: String, reason: String },
|
|
|
|
#[error("HTTP request error: {0}")]
|
|
HttpRequest(String),
|
|
|
|
#[error("WIT version mismatch: {0}")]
|
|
IncompatibleWitVersion(String),
|
|
}
|
|
|
|
impl From<crate::tools::wasm::WasmError> for WasmChannelError {
|
|
fn from(err: crate::tools::wasm::WasmError) -> Self {
|
|
WasmChannelError::Compilation(err.to_string())
|
|
}
|
|
}
|