VERO Engineering

OpenCode

AI-Powered Development & DevOps Automation

opencode
you:

Navigate with Space or Arrow Keys

The Traditional Way

Debugging a production incident manually...

Manual Process (15-30 min)
# 1. Check Slack for context - Open browser, find channel - Scroll through messages - Copy error details # 2. Check GitLab for recent deploys - Open GitLab UI - Navigate to pipelines - Check merge requests # 3. Search logs - Open Grafana/Kibana - Write query manually # 4. Check AWS/K8s state - aws cli commands - kubectl commands # 5. Report back to Slack
With OpenCode (2-3 min)
you: Check the payment timeout issue in #incidents and debug it # OpenCode automatically: ✓ Reads Slack thread context ✓ Queries GitLab for recent changes ✓ Searches logs with smart filters ✓ Checks cluster health via AWS ✓ Correlates all findings ✓ Posts summary to Slack thread All in one natural language request

The OpenCode Philosophy

OpenCode doesn't just run scripts.
It orchestrates your entire toolkit through natural conversation.

💬
Natural
Language
🧠
AI
Planning
Skill
Execution
🔄
Feedback
Loop
DEVELOPMENT WORKFLOWS

Skills While Coding

OpenCode isn't just for DevOps - it supercharges your development workflow

🔍 Context Gathering

Pull Jira ticket details, Confluence docs, and Slack discussions into your coding session

📊 Research & Design

Use deep-research.js for architecture decisions with multi-source analysis

🔗 Cross-Repo Edits

Make coordinated changes across client, API, and backend services

📝 Documentation

Auto-update Confluence, post to Slack, and sync Jira status

Press to see examples

Example: Start a Feature with Full Context

opencode — feature development
you: I'm starting VSB-1456, get me the full context
◐ Fetching context from multiple sources...
→ jira-search.js "key = VSB-1456"
→ confluence-search.js "VSB-1456 OR user-preferences"
→ slack-unreads.js --content --channels="backend-dev"
Context assembled:
Jira Ticket: Add user preference sync across devices
Acceptance: Real-time sync, offline support, conflict resolution
Related: VSB-1420 (auth refactor), VSB-1389 (storage layer)
Confluence: "User Preferences Architecture" doc found
Shows: Event-driven sync via Kafka, Redis cache layer
Slack: @backend mentioned conflict resolution approach yesterday
Decision: Last-write-wins with timestamp, UI shows conflicts

Example: Architecture Research

opencode — architecture design
you: research how we should implement rate limiting for the API gateway
◐ Starting deep research...
→ deep-research.js "API rate limiting strategies"
→ confluence-search.js "rate limit OR throttling"
→ gitlab-search "rate.limit" --scope=code
Research complete. Summary:
Existing Implementation:
• auth-service: Token bucket (100 req/min per user)
• payment-service: Fixed window (10 req/sec)
Recommendation for API Gateway:
• Sliding window counter (Redis ZSET)
• Consistent with AWS API Gateway patterns
CROSS-REPO EDITING

Multi-Repository Feature Implementation

Coordinated changes across your entire stack

web-client
React + TypeScript
api-gateway
Node.js + Express
user-service
Go + gRPC
notification-svc
Python + Kafka

Scenario: Add "Email Notification Preferences" Feature

  • UI toggle in settings page (web-client)
  • New API endpoint (api-gateway)
  • Preference storage (user-service)
  • Preference check before sending (notification-svc)

Press to see the workflow

Step 1: Understand the Stack

opencode — cross-repo feature
you: I need to add email notification preferences. Show me how
preferences flow through our stack currently.
◐ Analyzing codebase across repos...
→ Searching web-client/src for preference patterns
→ Searching api-gateway/routes for /preferences
→ Searching user-service for preference storage
Current preference flow mapped:
web-client/
src/components/Settings/PreferencesPanel.tsx
src/api/userPreferences.ts → calls /api/v1/preferences
api-gateway/
routes/preferences.js → proxies to user-service
user-service/
internal/preferences/handler.go → stores in PostgreSQL
internal/preferences/model.go → Preferences struct

Step 2: Modify Backend Services

opencode — backend changes
you: add email_notifications boolean to the preferences model
and update the handler to accept it
◐ Modifying user-service...
✓ Edited user-service/internal/preferences/model.go
+ EmailNotifications bool `json:"email_notifications" db:"email_notifications"`
✓ Edited user-service/internal/preferences/handler.go
+ Added field to UpdatePreferences request
+ Added validation (defaults to true for new users)
✓ Created user-service/migrations/003_add_email_prefs.sql
ALTER TABLE preferences ADD COLUMN email_notifications BOOLEAN DEFAULT true;
◐ Running tests...
✓ All 47 tests passing

Step 3: Update API Gateway

opencode — api gateway
you: update the api-gateway to pass through the new field
and add OpenAPI documentation
◐ Updating api-gateway...
✓ Edited api-gateway/routes/preferences.js
+ email_notifications in request validation schema
✓ Edited api-gateway/openapi/preferences.yaml
+ Added email_notifications property (boolean)
+ Added description and default value
✓ Edited api-gateway/tests/preferences.test.js
+ Test case for email_notifications toggle
◐ Running tests...
✓ All 23 tests passing

Step 4: Update Web Client

opencode — frontend
you: add a toggle for email notifications in the preferences panel
match the existing style and add proper types
◐ Updating web-client...
✓ Edited web-client/src/types/preferences.ts
+ emailNotifications: boolean
✓ Edited web-client/src/api/userPreferences.ts
+ Updated API calls to include new field
✓ Edited web-client/src/components/Settings/PreferencesPanel.tsx
+ Added Toggle component with label
+ Connected to preferences state
+ Added loading state during save
◐ Running tests and type check...
✓ Types: No errors
✓ Tests: 156 passing

Step 5: Update Notification Service

opencode — notification service
you: update notification-svc to check user preferences
before sending email notifications
◐ Updating notification-svc...
✓ Edited notification-svc/src/handlers/email_handler.py
+ Added preferences check before send_email()
+ Calls user-service gRPC to fetch preferences
✓ Edited notification-svc/src/clients/user_client.py
+ Added get_email_preference() method
+ Includes caching (5 min TTL)
✓ Edited notification-svc/tests/test_email_handler.py
+ Test: skip when preference disabled
+ Test: send when preference enabled
◐ Running pytest...
✓ 34 tests passing

Cross-Repo Edit Summary

web-client
3 files changed
api-gateway
3 files changed
user-service
3 files changed
notification-svc
3 files changed
12
Files Modified
4
Languages
260
Tests Passing
~10 min
Total Time

One conversation. Full stack feature. All tests passing.

INCIDENT RESPONSE DEMO

Use Case: Production Incident

A timeout alert fires. You need to investigate.

Press to see the workflow

Step 1: Gather Context from Slack

opencode — incident response
you: what's happening in #incidents about payment timeouts?
◐ Reading Slack channel #incidents...
→ slack-unreads.js --channels=incidents --content
Found 3 relevant messages:
@oncall: Payment service timing out since 14:32 UTC
@backend: Seeing 502s on /api/payments/process
@platform: Might be related to yesterday's deploy?

Step 2: Check Recent Deployments

opencode — incident response
opencode: Checking GitLab for recent payment service changes...
→ gitlab-activity-flexible.js 2024-11-28..2024-11-30
Recent deployments to payment-service:
⚠ MR !2847 "Add retry logic for upstream calls"
Merged: yesterday 16:45 UTC by @backend-dev
Changed: src/services/upstream.js (+47, -12)
○ MR !2841 "Update dependencies" - 2 days ago
Likely culprit: MR !2847 introduced new retry logic

Step 3: Search Logs for Evidence

opencode — incident response
opencode: Searching logs for timeout patterns...
→ vero-logs-search.js --service=payment-service --level ERROR --hours 2
Found 847 errors in last 2 hours (normal baseline: ~20)
Top error patterns:
[623x] TimeoutError: upstream request exceeded 30s
[198x] RetryExhausted: max retries (5) reached
[ 26x] ConnectionReset: upstream closed connection
Pattern: New retry logic is amplifying upstream latency

Step 4: Post Summary to Slack

opencode — incident response
you: post the findings to the incident thread
→ slackFetch('chat.postMessage', { channel: 'incidents', thread_ts: ... })
✓ Posted to #incidents thread:
*Investigation Summary* AI generated Root Cause: Cascade failure from auth-service degradation • auth-service p99 latency spiked to 4.2s (normally 200ms) • MR !2847 (yesterday) added retry logic: 5 retries × 30s timeout • Combined effect: 150s worst-case per request Immediate Fix: Reduce retry count to 2, add circuit breaker Long-term: Investigate auth-service memory pressure

Full Incident Workflow

💬
Slack
Read context
🦊
GitLab
Find changes
📊
Loki/Logs
Search errors
☁️
AWS/K8s
Check state
Slack
Report back

Total time: ~2 minutes vs 15-30 minutes manually

Use Case: Automated Standup

Generate your daily update from actual work data

Press to see it in action

opencode — daily standup
you: generate my standup for today
◐ Gathering activity from multiple sources...
→ gitlab-personal-activity.js yesterday
→ jira-search.js "assignee = currentUser() AND updated >= -1d"
→ slack-unreads.js --content --channels="backend-dev"
Generated standup:
**Yesterday:** • Merged MR !2851: API rate limiting implementation • Code review on !2849 (auth refactor) - requested changes • VSB-1234: Moved to "In Review" after addressing feedback **Today:** • VSB-1238: Start database migration planning • Follow up on !2849 review comments **Blockers:** • Waiting on DevOps for staging environment access

Use Case: MR Review Analysis

AI-powered analysis of review comments with cross-cutting insights

Press to explore

opencode — code review analysis
you: analyze the review comments on MR !2847
→ gitlab-mr-review-comments-analyzer.js https://gitlab.../merge_requests/2847
◐ Fetching Jira context for VSB-1234...
◐ Fetching GitLab code context...
Analysis of 12 review comments:
Cross-cutting patterns identified:
1. Error handling (3 comments) - missing try/catch blocks
2. Logging concerns (2 comments) - debug logs in prod code
3. Type safety (2 comments) - any types in interfaces
Priority breakdown:
🔴 CRITICAL: 1 🟠 HIGH: 3 🟡 MEDIUM: 5 🟢 LOW: 3
Full report with AI-generated responses available for each comment.
BROWSER AUTOMATION

Use Case: Browser Control

Automate web interactions with AI-powered element detection

🎯 AI-Powered Clicking

smartClick('login button') — AI finds and clicks elements by natural language

📸 Set-of-Marks (SoM)

Industry-standard visual grounding — annotates screenshots for precise element selection

🔐 Profile & Cookie Support

Use Zen/Firefox profiles with saved logins — no need to re-authenticate

🍪 Auto Overlay Dismissal

Automatically handles cookie banners, consent dialogs, and modal popups

Press to see examples

Example: Scrape Internal Dashboard

opencode — browser automation
you: export the monthly analytics from the admin dashboard
◐ Starting browser session with Zen profile...
→ createSession('zen', { headless: false })
✓ Session started (using release profile with saved cookies)
→ navigate('https://admin.company.com/dashboard')
🍪 Dismissed 2 overlay(s): cookie-banner, modal
✓ Page loaded — already authenticated via profile
→ smartClick('Analytics tab')
🤖 AI selected [4]: nav link with "Analytics" text (0.95)
→ smartClick('Export CSV')
📜 Scrolling element into view...
👆 Clicking at viewport position (847, 412)
✓ Download triggered: analytics-nov-2024.csv

Example: Fill and Submit Web Form

opencode — form automation
you: create a support ticket for the payment API timeout issue
◐ Opening support portal...
✓ Navigated to support.company.com/new-ticket
→ smartClick('Category dropdown')
→ smartClick('API Issues option')
→ smartClick('Subject input')
→ humanType('Payment API timeout errors')
→ smartClick('Description textarea')
→ type('Seeing 30s timeouts on /api/payments/process...')
→ smartClick('Priority dropdown')
→ smartClick('High priority')
→ submitForm()
✓ Ticket created! ID: SUPPORT-4821

The API

browser-control.js
// Create persistent session
const { createSession } = await import('~/.../browser-control.js');
const s = await createSession('zen', { headless: false });
// AI-powered interaction (auto-scrolls if needed)
await s.navigate('https://example.com'); // auto-dismisses overlays
await s.smartClick('search box'); // AI finds + scrolls + clicks
await s.humanType('my query'); // types with human-like delays
await s.press('Enter'); // press any key
await s.fullPageScreenshot('/tmp/full.png'); // entire page
await s.close();

Browser Engine Options

  • Playwright (chrome/chromium/edge) — Fast, stealth, CAPTCHA detection
  • Selenium (zen/firefox/safari) — Real profiles with saved sessions

Key Session Methods

Navigation & Interaction

  • navigate(url) — auto-dismisses overlays
  • smartClick(description) — AI-powered click
  • clickAt(x, y) — coordinate click
  • type(text) / humanType(text)
  • press(key) — Enter, Tab, Escape...
  • submitForm() — submit active form

Page Analysis

  • getAllClickableElements() — entire page
  • getClickableElements() — viewport only
  • getContext() — page text & metadata
  • getPageInfo() — dimensions & scroll
  • detectCaptcha() — check for blocks
  • getCookies() — read all cookies

Screenshots & Scrolling

  • screenshot(path) — viewport capture
  • fullPageScreenshot(path) — entire page
  • scroll('down', 400) — by direction
  • scrollTo(x, y) — absolute position
  • scrollElementIntoView(el) — center element

Advanced Features

  • dismissOverlays() — banners/modals
  • solveCaptcha() — 2captcha or manual
  • clickByDescriptionSoM() — Set-of-Marks
  • evaluate(js) — run JS in page
  • waitFor(selector) — wait for element

Browser Automation Flow

🚀
Create Session
Load profile
🌐
Navigate
Dismiss overlays
🔍
Find Elements
AI analysis
📜
Auto-Scroll
Into viewport
👆
Click/Type
At coordinates

smartClick() combines AI element detection + auto-scroll + coordinate clicking — one method does it all

DATABASE OPERATIONS

Use Case: Cassandra + Schema Knowledge Base

Query clusters across environments with AI-powered schema understanding

🧠 Schema KB

SQLite knowledge base with 86 tables, relationships, and usage patterns — AI-queryable

🔗 Relationships

Understand how tables connect: feeds_into, partitioned_by, aggregates, filters

🔐 Automatic Auth

JumpCloud → Vault auth, SSH tunnels for prd — no prompts needed

⚡ Daemon Mode

Persistent connections via background daemon — ~15ms query latency

Press to see examples

Example: Query User Data Across Environments

opencode — cassandra query
you: check if user abc123 exists in vero.users on dev
◐ Connecting to Cassandra...
→ cassandra-query.js dev cass000 "SELECT * FROM vero.users WHERE user_id = 'abc123'"
🔐 Authenticating to Vault via JumpCloud LDAP...
Query returned 1 row:
user_id: abc123
email: user@example.com
created_at: 2024-03-15 10:30:00
status: active
you: now check the same user in prd
→ cassandra-query.js prd cass000 "SELECT * FROM vero.users WHERE user_id = 'abc123'"
🔒 Establishing SSH tunnel through bastion...
Query returned 1 row (prd):
user_id: abc123
status: suspended
Note: User status differs between dev (active) and prd (suspended)

Example: Auto-Discover Table Location

opencode — table discovery
you: which cluster has the payment_events table?
→ cassandra-cache-mappings.js --find payment.payment_events
Found payment.payment_events:
dev: cass002
stg: cass002
prd: cass002
you: show me the schema for that table
→ cassandra-query.js dev cass002 "DESCRIBE TABLE payment.payment_events"
Table schema:
CREATE TABLE payment.payment_events (
event_id uuid,
user_id text,
event_type text,
amount decimal,
created_at timestamp,
PRIMARY KEY ((user_id), created_at, event_id)
) WITH CLUSTERING ORDER BY (created_at DESC);

Example: Daemon Mode for Fast Queries

opencode — cassandra daemon
you: I need to run several queries on dev cass000, use daemon mode
→ cassandra-daemon.js start dev cass000
Starting cassandra daemon for dev/cass000...
✓ Daemon started and ready (socket: /tmp/cassandra-daemon-dev-cass000.sock)
you: query 1: count users created today
→ cassandra-query.js dev cass000 --daemon "SELECT COUNT(*) FROM vero.users..."
✓ 847 users (query: 23ms)
you: query 2: check failed payments
→ cassandra-query.js dev cass000 --daemon "SELECT * FROM payment.events..."
✓ 12 failed payments (query: 18ms)
you: query 3: get session counts
→ cassandra-query.js dev cass000 --daemon "SELECT COUNT(*) FROM auth.sessions..."
✓ 15,432 sessions (query: 15ms)
Daemon auto-shuts down after 30min idle

Search Tables by Pattern

opencode — table search
you: find all tables related to streaming
→ cassandra-cache-mappings.js --search "*stream*"
Found 8 matching tables:
streaming.events dev:cass001 stg:cass001 prd:cass001
streaming.sessions dev:cass001 stg:cass001 prd:cass001
streaming.analytics dev:cass001 stg:cass001 prd:cass001
vero.stream_history dev:cass000 stg:cass000 prd:cass000
vero.stream_metadata dev:cass000 stg:cass000 prd:cass000
analytics.stream_events dev:cass002 stg:cass002 prd:cass002
analytics.stream_metrics dev:cass002 stg:cass002 prd:cass002
logs.stream_errors dev:cass003 stg:cass003 prd:cass003
you: list all tables in the vero keyspace
→ cassandra-cache-mappings.js --list vero
vero.users, vero.sessions, vero.profiles, vero.stream_history...
Total: 24 tables in vero keyspace

Schema Knowledge Base: Semantic Search

opencode — schema knowledge base
you: where are user feeds stored?
→ schema-kb.js --search "user feed timeline"
Found in Schema KB:
vero_social_stream.streams
Main user feed/timeline storage. Posts from followed
users are fan-out written here for efficient retrieval.
you: how do posts get to user feeds?
→ schema-kb.js --relations vero_social_post.posts
Relationships:
feeds_into → vero_social_stream.streams
Posts are distributed to user streams/feeds
aggregates → vero_social_post_counter.likes
aggregates → vero_social_post_counter.comments

Schema Knowledge Base: Full Table Details

opencode — table details
you: show me full details for the streams table
→ schema-kb.js --table vero_social_stream.streams
## vero_social_stream.streams
Domain: feeds
Description: Main user feed/timeline storage
### Usage
StreamsRepository (read, write)
→ social/domain/StreamsRepository.java
### Relates To
partitioned_by → vero_social_stream.epochs
### Referenced By
vero_social_post.posts feeds_into
vero_social_follow.user_followers determines_content
vero_social_hidden_stream.hidden_stream filters

Cassandra + Schema KB Overview

🧠
schema-kb
Understand schema
🔍
cache-mappings
Find clusters
daemon
Fast queries
🔐
Vault
Auto auth
📊
query
Execute CQL
86
Tables in KB
24
Relationships
271
Query Patterns
~15ms
Daemon Queries

Ask: "where are user feeds stored?" → Schema KB finds the table → OpenCode queries it

Use Case: Cross-Platform Search

Find information wherever it lives

opencode — unified search
you: find everything about the OAuth migration project
◐ Searching across platforms in parallel...
→ confluence-search.js "OAuth migration"
→ jira-search.js "text ~ 'OAuth migration'"
→ gitlabFetch('/api/v4/search?scope=merge_requests&search=oauth')
→ slackFetch('search.messages', { query: "OAuth migration" })
Found 23 results:
📄 Confluence: "OAuth 2.0 Migration Plan" (updated 3 days ago)
🎫 Jira: VSB-892 "Implement OAuth2 flow" (In Progress)
🦊 GitLab: MR !2834 "OAuth provider refactor" (Open)
💬 Slack: #backend discussion thread (yesterday)

How It Works

Skills
Modular JavaScript/TypeScript scripts for each integration
Identity
Secure credential management via ~/.secrets/
Runtime
Bun for fast execution with native TypeScript support
Orchestration
AI plans and chains skills based on natural language intent
Caching
Smart caching of users, channels, and frequently accessed data
Audio Feedback
TTS notifications via Kokoro for long-running operations
skill execution
$ bun ~/.config/opencode/skills/<category>/<skill>.js [args]

Integration Ecosystem

💬
Slack
🦊
GitLab
🎫
Jira
📚
Confluence
☁️
AWS
📊
Loki/Grafana
🗄️
Cassandra
🌐
Browser
🎮
Discord
🎵
Spotify
📱
macOS
🤖
AI/LLMs
AUDIO FEEDBACK

Text-to-Speech Notifications

Kokoro TTS provides audio feedback for long-running operations

Automatic Policy

TTS triggers automatically after 3+ operations complete — keeps you informed while multitasking

Multi-Voice Support

40+ voices including US/UK English, French, Italian, Japanese, and Mandarin Chinese

Background Execution

Runs async (&) so it doesn't block the AI — audio plays while work continues

Local & Fast

Kokoro runs locally — no API calls, instant response, works offline after model download

Press down to see usage

TTS Usage Examples

tts-kokoro.js
// Policy from AGENTS.md - auto TTS after 3+ ops
bun -e "const{speak}=await import(
'$HOME/.config/opencode/skills/media/tts-kokoro.js');
await speak('Done');" &
// CLI usage
$ bun ~/.../tts-kokoro.js "Task complete"
$ bun ~/.../tts-kokoro.js "Bonjour" --voice ff_siwis
$ bun ~/.../tts-kokoro.js "Fast" --speed 1.5
// Programmatic API
const { speak } = await import('~/.../tts-kokoro.js');
await speak('Build succeeded', { voice: 'am_adam' });

Available Voice Categories

  • US English: af_sarah, am_adam, af_nova, af_sky, am_michael, af_bella, am_fenrir...
  • British: bf_alice, bf_emma, bf_isabella, bm_george, bm_lewis, bm_daniel...
  • French: ff_siwis
  • Japanese: jf_alpha, jf_gongitsune, jm_kumo, jf_nezumi, jf_tebukuro...
  • Chinese: zf_xiaobei, zf_xiaoni, zf_xiaoxiao, zf_xiaoyi, zm_yunjian, zm_yunxi...
  • Italian: if_sara, im_nicola
  • Portuguese: pf_dora, pm_alex, pm_santa
  • Hindi: hf_alpha, hf_beta, hm_omega, hm_psi

Configuration Architecture

Five key files power the OpenCode skills ecosystem

📋
AGENTS.md
AI Instructions
opencode.json
App Config
🚀
skill-init.js
Environment Setup
👤
identity.env
Personal Info
🔒
vdp.env
Infra Secrets

Press down to explore each file

AGENTS.md — AI System Instructions

~/.config/opencode/AGENTS.md
# OpenCode Skills
**Runtime**: `bun` | **Secrets**: `~/.secrets/`
**Identity**: `~/.config/opencode/identity.env`
## Policies
- **TTS** (3+ ops): `bun -e "...speak('Done');" &`
- **Parallel**: Multiple Task tools in ONE response
- **AI disclaimer**: Slack: `*AI generated*`
## Skills
| Category | Skill | Triggers | Example |
| workflows | daily-standup.js | standup |

Purpose

  • Injected into AI context — AI reads on every session
  • Skill catalog — all skills with triggers
  • Policies — TTS, parallel execution
  • URLs — internal service endpoints

Key Sections

  • Skill table with triggers and examples
  • Security policies (never print keys)
  • Browser automation API reference

opencode.json — Application Configuration

~/.config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"theme": "opencode",
"model": "openrouter/anthropic/claude-sonnet-4.5",
"small_model": "openrouter/google/gemini-2.5-flash-lite",
"provider": {
"openrouter": {
"options": {
"apiKey": "{file:../../.secrets/openrouter-key}"
}
}
},
"autoupdate": true
}

Purpose

  • Model selection — which AI models to use
  • Provider config — API keys, endpoints
  • Thinking mode — extended reasoning tokens
  • MCP servers — Model Context Protocol

Key Features

  • {file:...} loads secrets from files
  • JSON Schema validation
  • Multi-provider support

skill-init.js — Environment Bootstrap

bun ~/.config/opencode/skill-init.js
Checking System Dependencies
+ Bun JavaScript runtime (bun)
+ Git version control (git)
+ Kokoro TTS (kokoro-tts)
Checking Identity Configuration
+ Identity file (identity.env)
Checking API Keys
+ Atlassian (~/.secrets/atlassian-key)
+ Slack (~/.secrets/slack-xoxp-key)
+ GitLab (~/.secrets/gitlab-key)
Initializing Caches
+ Jira users cache
+ Slack channels cache
Environment fully configured!

Purpose

  • Environment validation — checks all deps
  • API key verification — validates secrets
  • Auto-setup — creates identity.env from template
  • Security enforcement — fixes file permissions

What It Checks

  • System deps: bun, git, curl, python, kokoro-tts
  • API keys: Atlassian, Slack, GitLab, OpenRouter
  • Directories: ~/.secrets/, ~/.config/opencode/
  • Caches: Jira/Slack/GitLab users, channels
  • Installs: browser automation drivers

Run with --check-only to verify without installing, or --force to refresh all caches

identity.env — Personal Information

~/.config/opencode/identity.env
# Personal identity for AI context
FULL_NAME="Your Full Name"
EMAIL="you@company.com"
SLACK_USER_ID="U12345678"
GITLAB_USERNAME="yourusername"
JIRA_USERNAME="you@company.com"
TIMEZONE="America/New_York"
LOCATION="City, Country"

Purpose

  • Personalization — AI knows who you are
  • Cross-platform identity — maps accounts
  • Automatic filtering — "my commits" works

How It's Used

  • GitLab: Filter personal activity reports
  • Jira: Default assignee for searches
  • Slack: Identify your user ID
  • Standups: "What did I do yesterday?"

Auto-created from identity.env.template on first run of skill-init.js

vdp.env — Infrastructure Secrets

~/.config/opencode/vdp.env
# Infrastructure credentials (chmod 0600)
VAULT_ADDR_TEMPLATE="https://vault.{env}.vdp.vero.host"
JUMPCLOUD_USERNAME="your_username"
JUMPCLOUD_PASSWORD="your_password"
# Grafana hosts for log searches
VDP_DEV_HOST="grafana.dev.vdp.vero.host"
VDP_STG_HOST="grafana.stg.vdp.vero.host"
VDP_PRD_HOST="grafana.prd.vdp.vero.host"

Purpose

  • Vault auth — JumpCloud LDAP credentials
  • Non-interactive — No password prompts
  • Token caching — Auto-renewed per env

Used By Skills

  • cassandra-query.js — Vault → DB creds
  • cassandra-daemon.js — Persistent conns
  • vero-logs-search.js — Loki logs

Security: Never print these values. JUMPCLOUD_PASSWORD enables fully automatic Vault auth (no prompts).

Pre-Built Workflows

End-to-end automation in ~/.config/opencode/skills/workflows/

🌅 daily-standup.js

GitLab commits + Jira updates + Slack + Calendar into one standup report

📊 activity-report.js

Team activity from Slack + GitLab with TODOs and blockers

🔍 jira-review-mr-workflow.js

Fetch review tickets, analyze MRs, post AI reviews to GitLab + Jira

🦊 post-gitlab-activity.js

GitLab activity report posted to Slack with threaded sections

📝 opencode-commit-publish.js

Commit + push + AI release notes to Slack in one command

🔧 Build Your Own

Compose skills into custom workflows with shared APIs

All support --dry-run --verbose --output — or invoke via natural language

NOTABLE NEW FEATURES

Recent Skill Enhancements

New capabilities across the skills ecosystem

🧠 Knowledge Bases

SQLite-backed KBs for Schema, Git Repos, and VDP Gateway API — semantic search & relationships

💬 Enhanced Slack

Mark channels as read, upload files, date range filtering, wildcard channel matching

📱 macOS Integrations

WhatsApp send via Baileys, Calendar CRUD, Mail operations, Messages access

🎮 Discord & AI

AI summaries, attachment downloads, deep research with web search & extended thinking

Press to explore each category

Knowledge Base Skills

🗄️ schema-kb.js

Cassandra schema with semantic search

  • 86 tables with descriptions
  • Relationship mapping
  • --search "user feed"
  • --relations streams

📁 git-repos-kb.js

Local git repository indexing

  • Full-text search
  • Language & framework filter
  • --lang TypeScript
  • --commits repo 20

🔌 vdp-gateway-kb.js

OpenAPI spec discovery

  • Endpoint & schema explore
  • Auto-refresh from remote
  • --endpoint /api/x GET
  • --tag authentication
knowledge base queries
you: which tables store user timelines?
→ schema-kb.js --search "user timeline feed"
Found: vero_social_stream.streams — Main feed storage
Relationships: posts feeds_into → streams

Enhanced Slack Skills

slack-mark-read.js
# Mark all channels as read
$ bun slack-mark-read.js --all
✓ Marked 12 channels as read
# Mark specific channel
$ bun slack-mark-read.js backend-dev
✓ Marked #backend-dev as read
slack-upload-file.js
# Upload file to channel
$ bun slack-upload-file.js \
--file=/tmp/report.pdf \
--target=backend-dev --title="Report"
✓ Uploaded to #backend-dev

Other Slack Improvements

  • --oldest / --latest date filtering
  • --channels="backend-*" wildcards
  • --include-read fetch read messages
  • --with-directives AI summary hints
  • --thread-ts for thread replies
  • DM and group message support

macOS System Integrations

📅 Calendar

  • List/search events
  • Create events
  • Update & delete
  • Multi-calendar

📧 Mail

  • List inbox
  • Read messages
  • Download attachments
  • Archive/delete/send

💬 WhatsApp

  • Send text messages
  • Send images
  • QR auth (Baileys)
  • List contacts

💬 Messages

  • Read iMessage/SMS
  • Search conversations
  • History access
  • Read-only
macos skills examples
you: what meetings do I have tomorrow?
→ macos-calendar.js list 2025-12-03
Found 3 events: 09:00 Standup, 14:00 Design Review, 16:30 1:1
you: send WhatsApp to John: "Running 10 min late"
→ macos-whatsapp-send.js --send --to "+1..." --message "..."
✓ Message sent to John

Discord & AI Enhancements

discord-fetch-messages.js
# Fetch with AI summary
$ bun discord-fetch-messages.js --channel="123" --ai-summary
# Download attachments
$ bun discord-fetch-messages.js --channel="123" --download-attachments
# By server & channel name
$ bun discord-fetch-messages.js --server="OpenCode" --channel-name="general"
deep-research.js
# Opus 4.5 + Exa web search
$ bun deep-research.js "GraphQL federation patterns"
# Control reasoning depth
$ bun deep-research.js --reasoning-effort=high "Design ML pipeline"
# Pure reasoning (no web)
$ bun deep-research.js --no-search "Analyze algorithm"

Deep Research Features

  • Claude Opus 4.5 extended thinking
  • Exa web search integration
  • Streaming with visible reasoning
  • Configurable reasoning effort
  • Up to 20 search results
  • System message customization

Confluence & Jira Improvements

confluence-post-comment.js

  • Post comments to any page
  • --reply to reply to comments
  • --ai adds AI generated marker
  • Supports stdin for long content
  • Accepts page ID or full URL

jira-search.js

  • Full JQL support with examples
  • --comments include comments
  • --expand changelog for history
  • --fetch-all pagination
  • --json structured output
jira & confluence
you: find all my open tickets with comments
→ jira-search.js "assignee = currentUser() AND resolution is EMPTY" --comments
Found 8 issues with comments
you: add a note to the VSB-1234 Confluence page
→ confluence-post-comment.js 4067262513 --ai '<p>Analysis...</p>'
✓ Comment posted (AI generated)

Transform Your Workflow

10x
Faster debugging
0
Context switches
Composability

One interface. All your tools. Natural language.

🔊 Audio feedback when tasks complete  |  🔒 Secure secrets management  |  👤 Personal identity context
Get Started

Start Automating

get started
$ bun ~/.config/opencode/skill-init.js
# Validates deps, keys, identity, and initializes caches

Just describe what you need. OpenCode handles the rest.