vibe-ready
Composable runtime, logging, scheduling, and storage foundations for vibe-coding Rust projects.
vibe-ready is a small application foundation crate for developers who want to build quickly with AI coding tools. It gives an AI agent a stable set of primitives for project setup: a runtime engine, task execution, scheduled jobs, structured logs, persistent key-value storage, cancellation, status tracking, and a consistent error model.
The goal is simple: describe the product you want, tell your AI to use vibe-ready, and let it assemble the common project infrastructure from this crate instead of reinventing it.
What You Get
- Engine lifecycle: create, run, inspect, and destroy a
VibeEngine. - Runtime execution: run futures synchronously with
invoke, post background work withpost, or use the lower-levelVibeEngineExecutor. - Callback pool: dispatch user callbacks away from async runtime threads with
VibeCallbackExecutor. - Scheduler: priority tasks, delayed tasks, periodic tasks, cancellation tokens, task handles, and task inspection.
- Key-value store: typed values, buckets, TTL, batch operations, transactions, change listeners, and expired-row cleanup.
- Configuration model: app identity, platform, runtime sizing, logging behavior, storage behavior, and backup strategy.
- Logging: structured log records, log listeners, stdout output, optional persistent log storage, standard log fields, and exported log macros.
- Storage backends: Diesel SQLite persistence by default, or no-op backends for tests and lightweight builds.
- Error model: stable error codes, error categories, messages, sources, and context breadcrumbs.
- Platform helpers: current time, async sleep, and task spawning helpers.
- AI-friendly public API: documented re-exports and a
preludefor fast project bootstrapping.
Installation
Add the crate to your Rust project:
[]
= "0.1.1"
For local development from this repository:
[]
= { = "../vibe-ready" }
Default features enable SQLite-backed log and work storage:
[]
= { = "0.1.1", = ["log-diesel", "store-diesel-sqlite"] }
For tests or projects that do not need persistence:
[]
= { = "0.1.1", = false, = ["log-noop", "store-noop"] }
Quick Start
use Duration;
use ;
AI Agent Usage
This README is intentionally written so an AI coding agent can use vibe-ready as a project foundation without reading the entire source tree first.
One-Line Prompt
Use this when asking an AI to build a Rust app:
Build this Rust project using vibe-ready as the foundation: create a VibeEngine, configure app identity and storage, use VibeKvStore for local state, use the scheduler for background jobs, use structured logging, and return VibeResult from fallible app flows.
Detailed AI Prompt
You are building a Rust project with the vibe-ready crate.
Use vibe_ready::prelude::*.
Create configuration with VibeEngineConfig::builder().
Set app_name, namespace, platform, store_root_path when needed, and choose no-op backends for tests.
Create the runtime with VibeEngine::create(config) or VibeEngine::create_with_runtime_handle(config, handle).
Use engine.invoke for async work that must return a value synchronously.
Use engine.post for fire-and-forget async work.
Use engine.post_with_priority, schedule_after, and schedule_every for background jobs.
Use VibeCancellationToken in scheduled tasks and check token.is_cancelled() or await token.cancelled().
Use engine.tasks().list() and count() for diagnostics.
Use engine.store() for app state. Use set/get typed values, buckets, TTL, transactions, batch operations, and on_change listeners instead of creating ad hoc storage.
Use engine.insert_log, engine.set_log_listener, and log_i!/log_e! macros for structured logs.
Return VibeResult<T> from public fallible functions and attach context with VibeEngineError::with_context when useful.
Always call engine.destroy_with_timeout before shutdown in examples and tests.
What AI Should Build With Each Capability
| Need | Use |
|---|---|
| App runtime foundation | VibeEngine, VibeEngineConfig |
| Shared project imports | vibe_ready::prelude::* |
| Local app state | VibeKvStore |
| Namespaced state | VibeKvBucket |
| Temporary state | set_with_ttl, purge_expired |
| Atomic state changes | transaction, VibeKvTx |
| React to state changes | on_change, VibeKvChange |
| Fire-and-forget background work | VibeEngine::post |
| Blocking wait for async result | VibeEngine::invoke |
| Priority background jobs | post_with_priority, VibeTaskPriority |
| Delayed or periodic jobs | schedule_after, schedule_every |
| Cooperative cancellation | VibeCancellationToken, VibeTaskHandle::cancel |
| Task diagnostics | VibeTaskPanel, VibeTaskInfo |
| Structured logs | VibeLogInfo, VibeLogLevel, log_i!, log_e! |
| Stable app errors | VibeEngineError, VibeError, VibeErrorCode, VibeErrorKind, VibeResult, err! |
| Platform time/spawn helpers | vibe_ready::platform::{now, sleep, spawn} |
| Advanced storage access | VibeDbClient, VibeTableKeyVal, VibeDbErrorInfo |
| JSON/display utility macros | array_to_json_string!, obj_array_to_json_string!, basic_type_map_to_json_string!, impl_display_json! |
Core Concepts
Engine
VibeEngine is the main entry point. It owns or connects to a Tokio runtime, initializes logging and work storage, exposes a task executor, and gives the application access to a key-value store.
use ;
Use an external Tokio runtime when the host application already owns one:
use ;
Configuration
VibeEngineConfig::builder() starts with defaults suitable for local development. Configure only what your app needs.
use ;
let config = builder
.platform
.store_root_path
.app_name
.namespace
.log_backend
.log_level
.log_write_to_store
.log_output_stdout
.log_retention_days
.log_max_rows
.store_backend
.encrypt
.runtime_worker_threads
.callback_threads
.queue_capacity
.priority_queue_capacity
.build;
config.validate.expect;
Important configuration fields:
app_name: the application identity used in storage paths and log user ids.namespace: a logical environment, tenant, or product namespace.store_root_path: root path for SDK-managed data.log: log backend, level, stdout behavior, persistence, and retention.store: work-store backend, encryption request, and backup strategy.runtime: Tokio worker threads, callback threads, task queue sizes, and scheduler lane capacity.
Configuration types and options:
VibeAppConfig: explicitapp_nameandnamespacevalues.VibeLogConfig: log backend, level, persistence, stdout output, retention days, and max rows.VibeStoreConfig: store backend, encryption request, and backup strategy.VibeRuntimeConfig: runtime worker threads, callback threads, async/sync queue capacities, and priority queue capacity.VibeLogBackend:NooporDieselSqlite.VibeStoreBackend:NooporDieselSqlite.VibeBackupStrategy:DisabledorManual.VibePlatformType: platform identity. Variants:Android,IOS,HarmonyOS,Windows,MacOS,Linux,Electron,Web,HarmonyOSPC,MiniWeb,PC,IPad,APad,HPad,Unknown.
The builder is the recommended entry point, but a constructed VibeEngineConfig also exposes read-only getters that an AI agent can use for diagnostics: store_path(), is_encrypt(), platform(), app_name(), namespace(), log_config(), store_config(), runtime_config(), and app_store_path().
Runtime Execution
Use invoke when the caller needs a result:
use ;
Use post when the caller does not need a result:
engine.post;
Use executor() for advanced integrations:
// In a function that returns VibeResult<()>:
let executor = engine.executor;
executor.post?;
let callbacks = executor.callback;
callbacks.execute;
VibeCallbackExecutor also exposes once, once2, and once3 helpers that wrap a closure so it runs on the callback pool when invoked with one, two, or three arguments. VibeEngine re-exports the one-argument and two-argument shortcuts as cb_pool_once and cb_pool_once2 for AI-generated bridging code that needs to hand a callback to native or FFI layers.
Scheduler
The scheduler handles priority, delayed, and periodic work.
use Duration;
use ;
// In a function that receives engine: &VibeEngine and returns VibeResult<()>:
let handle = engine.post_with_priority?;
assert_eq!;
let delayed = engine.schedule_after?;
let periodic = engine.schedule_every?;
periodic.cancel;
let task_count = engine.tasks.count?;
let snapshots = engine.tasks.list?;
drop;
Scheduler types:
VibeTaskPriority:High,Normal,Low.VibeTaskKind:Once,Delayed,Periodic.VibeTaskState:Pending,Running,Completed,Cancelled,Failed.VibeTaskHandlemethods:id(),name(),kind(),priority(),state(),token(),info(),cancel(),is_finished(), andjoin().await.VibeTaskPanelmethods:list() -> Result<Vec<VibeTaskInfo>>,count() -> Result<usize>.VibeCancellationTokenmethods:cancel(),is_cancelled(), andcancelled().await.
Key-Value Store
VibeKvStore is the high-level app state API. It supports typed values, named buckets, TTL, batch operations, transactions, and listeners.
use Duration;
use ;
Use buckets for logical separation:
// In a function that returns VibeResult<()>:
let settings = engine.store.bucket;
settings.set?;
assert_eq!;
Use batch operations when writing or reading multiple keys:
// In a function that returns VibeResult<()>:
let store = engine.store;
store.set_many?;
let values = store.get_many?;
store.remove_many?;
drop;
Use inspection and maintenance helpers when an AI agent needs to introspect or clean state:
// In a function that returns VibeResult<()>:
let store = engine.store;
let exists = store.contains?;
let keys = store.list_keys?;
let removed_expired_rows = store.purge_expired?;
drop;
Use transactions for atomic state changes:
// In a function that returns VibeResult<()>:
let result = engine.store.transaction?;
assert_eq!;
Use listeners to react to state changes:
// In a function that returns VibeResult<()>:
let store = engine.store;
let listener_id = store.on_change;
store.set_str?;
assert!;
Pattern matching supports:
- exact keys, for example
"user.name"; - all keys with
"*"; - one trailing wildcard, for example
"user*".
Logging
Use engine logging for explicit log entries:
use VibeLogLevel;
engine.insert_log;
engine.set_log_listener;
Use exported macros for structured logs:
log_i!;
log_s!;
log_e!;
Available log helpers:
log_i!: info log.log_i_!: info log with an extension segment.log_t!: info trace-style log.log_t_!: info trace-style log with an extension segment.log_r!: debug read-style log.log_r_!: debug read-style log with an extension segment.log_s!: debug state-style log.log_s_!: debug state-style log with an extension segment.log_e!: error log.log_e_!: error log with an extension segment.
Standard log field constants are also exported for consistent structured payloads:
CODE_STR: field name for error or status codes.DESC: field name for human-readable descriptions.RET_STR: field name for return values.
Errors
Most fallible APIs return VibeResult<T>, an alias for Result<T, VibeEngineError>.
use ;
Useful error APIs:
from_error_code(VibeErrorCode): construct an error from a stable error code.from_success(): construct a success sentinel value.is_success(): check whether an error represents success.from_u16(u16)/from_u32(u32): construct an error from a raw numeric code.code(): stable numeric code.kind(): high-levelVibeErrorKindcategory.message(): human-readable message.source_message(): optional lower-level source.context(): context breadcrumb list.with_source(...): attach source text.with_context(...): attach context text.
Use err! when you want to log an error with a backtrace and return the same error expression:
use ;
let error = err!;
assert_eq!;
Utility Macros
vibe-ready also exports small utility macros used by generated projects and logging helpers:
let values = vec!;
let json = array_to_json_string!;
assert_eq!;
array_to_json_string!: serializes an array-like value to JSON.obj_array_to_json_string!: renders displayable objects as a JSON-array-like string.basic_type_map_to_json_string!: serializes a string-keyed map of basic values to JSON.impl_display_json!: implementsDisplayfor serializable types by rendering JSON.
Platform Helpers
let timestamp_ms = now;
spawn;
Capabilities
Use VibeCapabilities to inspect compile-time support:
let capabilities = current;
println!;
println!;
Fields:
log_store: log persistence support is compiled in.work_store: work/key-value persistence support is compiled in.network: reserved network API support flag.encryption: reserved encryption support flag.wasm: current target is WebAssembly.tracing: reserved tracing integration flag.metrics: reserved metrics integration flag.
Status Manager
VibeStatusManager tracks VibeConnectionStatus and notifies a listener when the status changes. Most applications do not need it directly, but integrations can use it for connection-like workflows.
use ;
async
Advanced Database APIs
Prefer VibeKvStore for application state. Use VibeDbClient only when an integration needs lower-level row access or custom database operations.
use ;
async
Advanced row types:
VibeKvValue: typed value enum for string, bool, i32, i64, f64, bytes, and JSON.VibeTableKeyVal: row representation for low-level storage APIs.VibeDbErrorInfo: database backend error details.DbError: database error category.
Feature Flags
| Feature | Default | Purpose |
|---|---|---|
log-diesel |
Yes | Enables Diesel SQLite log persistence. |
store-diesel-sqlite |
Yes | Enables Diesel SQLite work/key-value persistence. |
log-noop |
No | Compatibility feature for no-op log behavior. |
store-noop |
No | Compatibility feature for no-op store behavior. |
No-op backends are always available at runtime through VibeLogBackend::Noop and VibeStoreBackend::Noop. They are useful for tests, examples, and generated prototypes.
Common Recipes for AI-Generated Projects
CLI Tool With Persistent State
Tell your AI:
Use vibe-ready to create a CLI app. Store user settings in engine.store().bucket("settings"), use VibeResult for fallible commands, and call destroy_with_timeout before process exit.
Implementation shape:
use *;
Background Worker
Tell your AI:
Use vibe-ready to create a background worker. Use schedule_every for periodic sync, VibeCancellationToken for cooperative cancellation, engine.tasks() for diagnostics, and structured logs for each run.
Implementation shape:
use Duration;
use *;
Local-First App Prototype
Tell your AI:
Use vibe-ready to build a local-first prototype. Put domain state in named VibeKvStore buckets, use transactions for multi-key changes, and use on_change listeners to update derived state.
Implementation shape:
use *;
Test-Friendly Generated Code
Tell your AI:
When writing tests with vibe-ready, configure VibeLogBackend::Noop and VibeStoreBackend::Noop unless persistence behavior is under test.
Implementation shape:
use *;
Public API Map
Most users should import from the prelude:
use *;
Important exported types:
- Engine and configuration:
VibeEngine,VibeEngineState,VibeEngineConfig,VibeEngineConfigBuilder,VibeEngineContext,VibeAppConfig,VibeBackupStrategy,VibeRuntimeConfig,VibeStoreConfig,VibeStoreBackend. - Runtime:
VibeEngineExecutor,VibeCallbackExecutor. - Scheduler:
VibeTaskHandle,VibeTaskInfo,VibeTaskKind,VibeTaskPanel,VibeTaskPriority,VibeTaskState,VibeCancellationToken. - Store:
VibeKvStore,VibeKvBucket,VibeKvTx,VibeKvValue,VibeKvChange,VibeKvChangeKind,VibeKvListenerId. - Database:
VibeDbClient,VibeTableKeyVal,VibeDbErrorInfo,DbError. - Logging:
VibeLogConfig,VibeLogBackend,VibeLogInfo,VibeLogLevel,VibeLogListener,VibeLogger,CODE_STR,DESC,RET_STR. - Errors:
VibeEngineError,VibeError,VibeErrorCode,VibeErrorKind,VibeResult. - Platform and status:
VibePlatformType,VibeConnectionStatus,VibeStatusManager,VibeCapabilities.
Shutdown Pattern
Always shut down engines explicitly in examples, tests, and applications:
engine.destroy_with_timeout?;
Use destroy when you need callback-style reporting:
engine.destroy;
Development
Useful commands for contributors and AI agents:
RUSTDOCFLAGS="-D warnings -D missing_docs"
License
MIT