shov
v3.12.0
Published
Shov CLI - Ship Production Backends in Seconds, Not Weeks with vector search and real-time streaming
Maintainers
Readme
Shov CLI
Ship Production Backends in Seconds, Not Weeks. Full-stack deployment with unified data engine and real-time streaming. Create projects, store data, and build apps with zero setup.
Installation
npm install -g shovQuick Start
1. Create a new project
# Create an anonymous project (default: creates ./shov/ directory with starter files)
shov new
# Create a named project
shov new my-project
# Create a project with email verification (for account management)
shov new my-project --email [email protected]
# Use TypeScript instead of JavaScript
shov new my-project --lang ts
shov new my-project --typescript # shorthand
# Custom code directory location
shov new my-project --code-dir . # Current directory (like Next.js)
shov new my-project --code-dir ./backend # Custom directory
shov new my-project --code-dir ./api # Another custom location
# Create project on server only (no local files)
shov new my-project --remote-only
shov new my-project --no-local # alias
# Combined options
shov new my-project --ts --code-dir ./backend --email [email protected]
# With starter templates (recommended syntax)
shov new my-app --b2c --ts --code-dir ./shov
shov new my-saas --b2b --ts --code-dir ./backend
# With starter templates + frontend (auto-configured!)
shov new my-app --b2c --react # B2C + React (VITE_SHOV_URL in .env)
shov new my-app --b2c --ts --vue # B2C + TypeScript + Vue
shov new my-saas --b2b --nextjs # B2B + Next.js (NEXT_PUBLIC_SHOV_URL in .env.local)
shov new my-saas --b2b --ts --nextjs # B2B + TypeScript + Next.jsThis will:
- Create a new Shov project (anonymous by default)
- Generate an API key
- Download starter files to local directory (default:
./shov/) - Save configuration to
.shovfile (includes project, API key, org, URL) - Add environment variables to your
.envfile (includesSHOV_PROJECT,SHOV_API_KEY,SHOV_ORG,SHOV_URL) - If email is provided, send a verification code for account linking
Claiming Anonymous Projects
If you created a project anonymously, you can claim it later to manage it from your dashboard:
# Claim an anonymous project
shov claim my-anonymous-project [email protected]
# The CLI will:
# 1. Send a verification code to your email
# 2. Prompt you to enter the code
# 3. Complete the claim processThis allows you to:
- Access the project from the Shov dashboard
- Manage team members and permissions
- View usage analytics and billing
2. Store and retrieve data
# Set a key-value pair
shov set hello "world"
# Get a value
shov get hello
# Store JSON data
shov set user '{"name":"Alice","age":25}'3. Work with collections
# Add items to a collection
shov add users '{"name":"Alice","age":25,"role":"admin"}'
shov add users '{"name":"Bob","age":30,"role":"user"}'
# Find items with advanced filters
shov where users -f '{"age":25}'
shov where users -f '{"age": {"$gte": 18}, "role": {"$in": ["admin", "moderator"]}}'
shov where users -f '{"name": {"$like": "A%"}, "age": {"$between": [20, 35]}}'
# Count items in collections
shov count users
shov count users -f '{"role": "admin"}'
shov count users -f '{"age": {"$gte": 18}, "status": "active"}'
# Find all items in a collection
shov where usersCommands
Project Management
shov new [projectName]- Create a new Shov project and API key--email <email>- Link project to your email (requires verification)
shov claim <projectName> <email>- Claim an anonymous project by associating it with your emailshov config- Show current project configuration
Data Operations
shov set <key> <value>- Set a key-value pairshov get <key>- Get a value by keyshov forget <key>- Delete a key-value pairshov add <collection> <value>- Add an item to a collectionshov where <collection>- Find items in a collection (returns all if no filter)shov count <collection>- Count items in a collection with optional filteringshov add-many <collection> <json_array>- Add multiple items to a collection at onceshov update <collection> <id> <value>- Update an item by collection and IDshov remove <collection> <id>- Remove an item from a collection by IDshov clear <collection>- Clear all items from a collectionshov batch <operations>- Execute multiple operations atomically in a single transactionshov contents- List all memory contents (keys, collections, files)
File Operations
shov upload <file_path>- Upload a fileshov upload-url <file_name>- Generate a pre-signed URL for client-side uploadsshov forget-file <filename>- Delete a file by filename
Authentication
shov send-otp <email>- Send a verification code to an emailshov verify-otp <email> <code>- Verify an email with a code
Real-time Streaming
shov token streaming <subscriptions>- Create a streaming token for browser-side connectionsshov subscribe <subscriptions>- Subscribe to real-time updates via Server-Sent Eventsshov broadcast <subscription> <message>- Broadcast a message to active subscribers
Code Functions
shov code list- List all deployed code filesshov code write <name> <file>- Write (create or overwrite) a code file deployed to the global edge networkshov code read <name>- Read the source code of a deployed code fileshov code pull- Download all code files from your project to local directoryshov code delete <name>- Delete a code file from the global networkshov code rollback <name> [version]- Rollback a code file to a previous versionshov code logs [name]- View real-time logs from your code functions
Secrets Management
shov secrets list- List all secret names (values never shown for security)shov secrets set <name> <value>- Set a secret for code functionsshov secrets set-many <secrets-json>- Set multiple secrets at once (bulk operation)shov secrets delete <name>- Delete a secret from code functions
Backup & Restore (Time-Travel)
shov restore- Restore your backend from a backup--from <timestamp>- When to restore from (e.g., "2 hours ago", "2024-10-01 14:30")--to <environment>- Target environment (default: current)--to-new-env <name>- Create new environment from backup--code- Restore only code files--data- Restore only data--files- Restore only uploaded files--secrets- Restore only secrets--all- Restore everything (default if no flags)-y, --yes- Skip confirmation prompts
shov clone <source> <target>- Clone entire environment (code, data, files, secrets)-y, --yes- Skip confirmation prompts
shov history- View backup history--env <environment>- Filter by environment (default: production)--type <type>- Filter by type (code, data, files, secrets)--limit <number>- Number of backups to show (default: 50)--json- Output JSON for scripting
shov rollback- Quick rollback to 1 hour ago (shortcut for restore)--from <timestamp>- Override default (1 hour ago)--to <environment>- Target environment-y, --yes- Skip confirmation prompts
Options
All data commands support these options:
-p, --project <name>- Specify project name-k, --key <apikey>- Specify API key--json- Output structured JSON for scripting (available on get, where commands)--limit <number>- Alias for --top-k (pagination)--offset <number>- Skip results for pagination
If project/key not provided, values are read from .shov configuration file.
Configuration
The CLI stores configuration in a .shov file in your project directory:
{
"project": "my-app",
"apiKey": "sk_live_...",
"email": "[email protected]"
}Examples
Basic Key-Value Storage
# String values
shov set app_name "My Awesome App"
shov get app_name
# JSON values
shov set config '{"theme":"dark","lang":"en"}'
shov get configCollections
# Add users
shov add users '{"id":1,"name":"Alice","role":"admin"}'
shov add users '{"id":2,"name":"Bob","role":"user"}'
# Add multiple users at once
shov add-many users '[
{"id":3,"name":"Charlie","role":"user"},
{"id":4,"name":"Diana","role":"admin"}
]'
# Find users with specific roles
shov where users -f '{"role":"admin"}'
# Get all users (no filter)
shov where users
# Update a user by collection and ID
shov update users user-id-123 '{"name":"Alice Smith","role":"super-admin"}'
# Remove a user by collection and ID
shov remove users user-id-123
# View all contents
shov contents
# Clear all users
shov clear usersFile Operations
# Upload a file directly
shov upload ./document.pdf
# Generate a pre-signed URL for client-side uploads
shov upload-url document.pdf
# Delete a file
shov forget-file document.pdfFiltered Queries
# Add some test data
shov add-many products '[
{"name":"Fender Stratocaster","type":"Electric Guitar","price":1299},
{"name":"Roland TD-27KV","type":"Electronic Drums","price":2499}
]'
# Query with filters
shov where products --filter '{"type":"Electric Guitar"}'
shov where products --filter '{"price": {"$between": [100, 500]}}'
shov where products --filter '{"price": {"$gte": 1000}}'
# Get structured JSON output for scripting
shov where products --filter '{"type":"Electric Guitar"}' --jsonAuthentication
# Get a login code
shov send-otp [email protected]
# Verify the code
shov verify-otp [email protected] 123456Atomic Transactions
# Execute multiple operations atomically
shov batch '[
{"type": "set", "name": "user:123", "value": {"name": "John", "email": "[email protected]"}},
{"type": "add", "collection": "orders", "value": {"userId": "123", "total": 99.99}},
{"type": "update", "collection": "inventory", "id": "item-456", "value": {"stock": 10}}
]'
# E-commerce checkout example (atomic transaction)
shov batch '[
{"type": "add", "collection": "orders", "value": {"userId": "123", "items": [{"id": "prod-1", "qty": 2}], "total": 199.98}},
{"type": "update", "collection": "inventory", "id": "prod-1", "value": {"stock": 8}},
{"type": "set", "name": "user:123:last_order", "value": "order-abc123"}
]'
# Read-your-writes consistency
shov batch '[
{"type": "set", "name": "counter", "value": 1},
{"type": "get", "name": "counter"},
{"type": "set", "name": "counter", "value": 2}
]' --jsonSupported operation types in batch:
set- Set key-value pairsget- Read values (for read-your-writes consistency)add- Add items to collectionsupdate- Update collection items by IDremove- Remove collection items by IDforget- Delete keysclear- Clear entire collections
⚠️ Important: All operations in a batch are executed atomically. If any operation fails, the entire batch is rolled back and no changes are made.
Real-time Streaming
# Create a streaming token for browser-side connections
shov token streaming '[
{"collection": "users", "filters": {"status": "active"}},
{"key": "config"},
{"channel": "notifications"}
]' --expires 3600
# Subscribe to real-time updates (keeps connection open)
shov subscribe '[
{"collection": "users"},
{"key": "config"},
{"channel": "chat"}
]'
# This will show live updates as they happen. Press Ctrl+C to stop.
# In another terminal, broadcast messages to subscribers
shov broadcast '{"channel": "chat"}' '{"user": "Alice", "message": "Hello everyone!"}'
# Broadcast to collection subscribers
shov broadcast '{"collection": "users", "filters": {"role": "admin"}}' '{"type": "alert", "text": "System maintenance"}'
# Broadcast to key subscribers
shov broadcast '{"key": "config"}' '{"theme": "dark", "updated_at": "2024-01-15T10:30:00Z"}'Real-time Features:
- Collection Subscriptions: Get notified when items are added, updated, or removed
- Key Subscriptions: Real-time updates when specific keys change
- Custom Channels: Send and receive custom messages for chat, notifications, etc.
- Filtered Subscriptions: Only receive updates matching your criteria
- Auto-broadcasts: All data writes (set, add, update, remove) automatically notify subscribers
Code Functions
# List all deployed code files
shov code list
# Write a code file (creates new or overwrites existing)
echo 'export default async function(req) {
return new Response(JSON.stringify({ message: "Hello from the edge!" }));
}' > index.js
shov code write index.js index.js
# Read a code file's source
shov code read index.js
# Pull all code files to local directory
shov code pull
# Downloads: index.js, routes.js, routes/*, services/*, etc.
# Pull to specific directory
shov code pull --output ./my-code/
# Update by writing again (overwrite)
shov code write index.js index-v2.js
# View real-time logs
shov code logs
# Rollback to previous version
shov code rollback index.js
# Delete a code file
shov code delete index.jsSecrets Management
# List all secret names
shov secrets list
# Set a secret for all functions
shov secrets set DATABASE_URL "postgresql://user:pass@localhost:5432/db"
# Set a secret for specific functions
shov secrets set API_KEY "sk_live_abc123" --functions "user-auth,payment-api"
# Set multiple secrets at once
shov secrets set-many '[
{"name": "DATABASE_URL", "value": "postgresql://user:pass@localhost:5432/db"},
{"name": "REDIS_URL", "value": "redis://localhost:6379"},
{"name": "JWT_SECRET", "value": "super-secret-jwt-key"}
]'
# Delete a secret
shov secrets delete OLD_API_KEYJSON Output & Scripting
Use --json flag for structured output suitable for automation:
# Get structured JSON output
shov get config --json
# Output: {"success": true, "key": "config", "value": {...}, "project": "my-project"}
# Query with JSON output for parsing
shov where products --filter '{"category":"electronics"}' --json | jq '.items[].value.name'
# Pipe results to other tools
shov where users --json | jq '.items | length' # Count users
# Use in shell scripts
RESULT=$(shov get user_count --json)
if echo "$RESULT" | jq -e '.success' > /dev/null; then
COUNT=$(echo "$RESULT" | jq -r '.value')
echo "Current user count: $COUNT"
fiIntegration with Existing Projects
# Initialize in existing project (less common)
cd my-existing-project
shov init --project my-project --key shov_live_...
# Or use environment variables
export SHOV_PROJECT=my-project
export SHOV_API_KEY=shov_live_...
shov get some_keyJavaScript SDK
For programmatic access, use the Shov JavaScript SDK:
npm install shov-jsimport { Shov } from 'shov-js'
const shov = new Shov({
project: 'my-project',
apiKey: 'shov_live_...'
})
// Key-value operations
await shov.set('hello', 'world')
const value = await shov.get('hello')
await shov.forget('hello')
// Collections
await shov.add('users', { name: 'Alice', age: 25 })
const users = await shov.where('users', { filter: { age: 25 } })
// Filtered queries
const results = await shov.where('users', { filter: { name: 'Alice' } })
// Atomic transactions
const batchResult = await shov.batch([
{ type: 'set', name: 'user:123', value: { name: 'John', email: '[email protected]' } },
{ type: 'add', collection: 'orders', value: { userId: '123', total: 99.99 } },
{ type: 'update', collection: 'inventory', id: 'item-456', value: { stock: 10 } }
])
// Real-time streaming
const { eventSource, close } = await shov.subscribe([
{ collection: 'users' },
{ channel: 'notifications' }
], {
onMessage: (data) => console.log('Update:', data),
onError: (error) => console.error('Stream error:', error)
})
// Broadcast messages
await shov.broadcast(
{ channel: 'notifications' },
{ text: 'Hello from the app!' }
)
// Close stream when done
// close()Backup & Restore Examples
# View backup history
shov history
# Restore from 2 hours ago (natural language!)
shov restore --from "2 hours ago"
# Restore to specific timestamp
shov restore --from "2024-10-01 14:30:00"
# Quick emergency rollback
shov rollback --yes
# Restore only code to staging
shov restore --from "2 hours ago" --code --to staging
# Create debug environment from yesterday
shov restore --from "1 day ago" --to-new-env "debug-yesterday"
# Clone production to staging
shov clone production staging
# Clone with immediate confirmation
shov clone production staging --yes
# View specific environment history
shov history --env production --type code --limit 100
# Interactive restore (no flags needed)
shov restore
# CLI will prompt you for:
# - When to restore from
# - What to restore (code/data/files/secrets)
# - Where to restore toNatural Language Timestamps:
"2 hours ago","30 minutes ago""3 days ago","1 week ago""last tuesday","yesterday"- Or use exact:
"2024-10-01 14:30:00"
Selective Restore:
# Just code + secrets
shov restore --from "2 hours ago" --code
# Just data
shov restore --from "1 day ago" --data
# Just files
shov restore --from "3 days ago" --files
# Everything
shov restore --from "2 hours ago" --allNext.js Integration
Create a new Next.js app with Shov pre-configured:
npx create-next-app@latest my-app --use-npm
cd my-app
shov init
npm install shov-jsThen use in your app:
// lib/shov.js
import { Shov } from 'shov-js'
export const shov = new Shov({
project: process.env.SHOV_PROJECT,
apiKey: process.env.SHOV_API_KEY
})
// pages/api/users.js
import { shov } from '../../lib/shov'
export default async function handler(req, res) {
if (req.method === 'POST') {
const user = await shov.add('users', req.body)
res.json(user)
} else {
// Example: find users matching a query parameter
const users = await shov.where('users', { filter: req.query })
res.json(users)
}
}Support
- Issues: GitHub Issues
License
MIT
