makiso
Agent handoff and event coordination with PR/Jira integration
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Menú
Agent handoff and event coordination with PR/Jira integration
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Basado en la clasificación ocupacional SOC
| name | makiso |
| description | Agent handoff and event coordination with PR/Jira integration |
| argument-hint | e.g. "handoff push", "handoff pull", "check events", ".check-prs", ".checkall" |
A local-first pub/sub system for coordinating LLM agents with events stored in SQLite. Enhanced with PR comment awareness, Jira status tracking, and workflow routing.
Name origin: "Make it so"
When you see oc-events: command not found, bootstrap using inline SQL. The skill works with just sqlite3 (pre-installed on macOS/Linux).
mkdir -p ~/.config/opencode/makiso
sqlite3 ~/.config/opencode/makiso/events.db "
PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA foreign_keys = ON;
CREATE TABLE IF NOT EXISTS metadata (
key TEXT PRIMARY KEY,
value TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS events (
id TEXT PRIMARY KEY,
topic TEXT NOT NULL,
body TEXT NOT NULL,
metadata TEXT,
correlation_id TEXT,
parent_id TEXT,
status TEXT NOT NULL DEFAULT 'pending',
source TEXT NOT NULL DEFAULT 'agent',
org_id TEXT,
workspace_id TEXT,
project_id TEXT,
repo_id TEXT,
created_at INTEGER NOT NULL,
processed_at INTEGER,
claimed_by TEXT,
claimed_at INTEGER,
expires_at INTEGER
);
CREATE INDEX IF NOT EXISTS idx_events_topic_status ON events(topic, status);
CREATE INDEX IF NOT EXISTS idx_events_created_at ON events(created_at);
CREATE INDEX IF NOT EXISTS idx_events_correlation_id ON events(correlation_id);
CREATE INDEX IF NOT EXISTS idx_events_claimed_by ON events(claimed_by);
CREATE INDEX IF NOT EXISTS idx_events_org_topic_status_created ON events(org_id, topic, status, created_at);
CREATE INDEX IF NOT EXISTS idx_events_org_workspace_topic_status_created ON events(org_id, workspace_id, topic, status, created_at);
CREATE INDEX IF NOT EXISTS idx_events_org_project_topic_status_created ON events(org_id, project_id, topic, status, created_at);
CREATE INDEX IF NOT EXISTS idx_events_org_repo_topic_status_created ON events(org_id, repo_id, topic, status, created_at);
CREATE VIRTUAL TABLE IF NOT EXISTS events_fts USING fts5(
body,
content='events',
content_rowid='rowid'
);
CREATE TRIGGER IF NOT EXISTS events_ai AFTER INSERT ON events BEGIN
INSERT INTO events_fts(rowid, body) VALUES (new.rowid, new.body);
END;
CREATE TRIGGER IF NOT EXISTS events_ad AFTER DELETE ON events BEGIN
INSERT INTO events_fts(events_fts, rowid, body) VALUES ('delete', old.rowid, old.body);
END;
CREATE TRIGGER IF NOT EXISTS events_au AFTER UPDATE ON events BEGIN
INSERT INTO events_fts(events_fts, rowid, body) VALUES ('delete', old.rowid, old.body);
INSERT INTO events_fts(rowid, body) VALUES (new.rowid, new.body);
END;
CREATE TABLE IF NOT EXISTS topics (
name TEXT PRIMARY KEY,
system_prompt TEXT,
description TEXT,
created_at INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS mentions (
event_id TEXT NOT NULL,
mention TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_mentions_mention ON mentions(mention);
CREATE TABLE IF NOT EXISTS tool_calls (
event_id TEXT NOT NULL,
tool_name TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_tool_calls_tool ON tool_calls(tool_name);
"
sqlite3 ~/.config/opencode/makiso/events.db "SELECT name FROM sqlite_master WHERE type='table'"
Expected output: metadata, events, topics, mentions, tool_calls
Before running commands, check if CLI is available:
if command -v oc-events &>/dev/null; then
# Use CLI (preferred)
oc-events push inbox --body "test" --org acme --repo lgapi
else
# Use inline SQL (fallback)
sqlite3 ~/.config/opencode/makiso/events.db "INSERT INTO events..."
fi
Preference order: Use CLI when available; fall back to inline SQL otherwise.
Load this skill IMMEDIATELY when user says:
| Trigger Phrase | Action |
|---|---|
| "check events" | Load skill, run Step 1-3 |
| "any pending tasks?" | Load skill, run Step 1-3 |
| "check event" | Load skill, run Step 1-3 |
| "pending events" | Load skill, run Step 1-3 |
| "events" | Load skill, run Step 1-3 |
| ".check-prs", ".checkprs" | Run .check-prs sub-command |
| ".check-jira", ".checkjira" | Run .check-jira sub-command |
| ".checkbugs", ".check-bugs" | Run .checkbugs sub-command |
| ".checkall", ".check-all" | Run .checkall sub-command |
| ".pullprs", ".pulljira", ".pullbugs" | Run legacy sub-commands |
Do NOT:
Do:
oc-events CLI commandsWhen the user asks you to check for events (e.g., "check events", "any pending tasks?"):
# Use saved context when available (preferred)
oc-events context show
# Or set explicit scope once per repo/session
oc-events context set --org acme --workspace platform --project distribution --repo lgapi
oc-events pull inbox --agent @opencode --scope repo
# Query pending events in the same org/repo:
sqlite3 ~/.config/opencode/makiso/events.db "SELECT id, topic, substr(body, 1, 100), status FROM events WHERE org_id = 'acme' AND repo_id = 'lgapi' AND status = 'pending' ORDER BY created_at DESC LIMIT 20"
IMPORTANT: Always run Step 2 when inbox is empty. Do NOT tell the user "No events found" after only checking the inbox.
For each pending event, check for linked PR and Jira status:
# Extract Jira key (DEV-XXXX) from event body
EVENT_BODY=$(sqlite3 ~/.config/opencode/makiso/events.db "SELECT body FROM events WHERE id = '$EVENT_ID'")
echo "$EVENT_BODY" | grep -oE 'DEV-[0-9]+'
# Check Jira status via Atlassian MCP
atlantide jira get-issue <JIRA_KEY> --fields status
# Check PR comments via Bitbucket MCP
bb pullrequest comment list --pullrequest <PR_NUMBER>
Based on PR/Jira state, route events to appropriate actions:
| State | Route | Action |
|---|---|---|
| PR has unresolved comments | needs-review | Address comments before proceeding |
| PR merged, LLM PROMPT exists | needs-testing | Execute testing instructions |
| PR approved, no blockers | ready-to-merge | Merge PR |
| Jira in "QA" status | qa-testing | Run verification tests |
| Jira in "Prod. Deploy" | production-deploy | Create/deploy tag |
If an event is returned:
oc-events reply <event-id> --status completed --body "your response"Only after checking BOTH inbox AND database: If no events are found in inbox (Step 1) AND no pending events in database (Step 2), then inform the user there are no pending events.
The following sub-commands fetch data from external sources and create events automatically.
When the user says .check-prs, .pullprs, check prs, or pull prs:
Fetch open PRs from Bitbucket
bb pullrequest list --state open --output json
For each PR, enrich with context
# Get PR details
bb pullrequest get <PR_NUMBER>
# Get comment count and unresolved reviewers
bb pullrequest comment list --pullrequest <PR_NUMBER>
# Check CodeRabbit review status (look for @coderabbitai comments)
# Detect LLM PROMPT in PR description or comments
Create events based on PR state
Example event body with metadata
PR Review: {title}
PR: #{number} ({state})
Link: {pr_link}
State: {open|merged|approved|needs_changes}
Comments: {count} unresolved
LLM PROMPT: {detected|none}
Reviewers: {reviewer_list}
Recommended Route: {needs-review|ready-to-merge|needs-testing}
Report summary
**PR Summary:**
- 3 open PRs needing review
- 1 PR ready to merge
- 2 PRs have unresolved comments
When the user says .check-jira, .checkjira, check jira, .pulljira, pull jiras, check issues, or pull issues:
Fetch user's assigned issues from Jira
# Using Atlassian MCP
atlan jira search --jql "assignee = currentUser() AND status NOT IN (Done, Canceled)"
# Or using bb CLI
bb pullrequest list --state open --output json | grep -i "DEV-[0-9]"
For each issue, check linked PR and state
# Get issue details
bb pullrequest get <PR_NUMBER>
# Check PR comments
bb pullrequest comment list --pullrequest <PR_NUMBER>
# Check for LLM PROMPT
Create events based on Jira state
Example event body
Jira Action Required: {summary}
Jira: {key} ({status})
Link: {jira_link}
PR: #{number} ({state})
Comments: {count} unresolved
LLM PROMPT: {detected|none}
Recommended Route: {needs-review|qa-testing|production-deploy}
Report summary
**Jira Summary:**
- 2 issues in PR stage
- 1 issue in QA stage
- 1 issue ready for Prod Deploy
When the user says .checkbugs, .check-bugs, .pullbugs, check bugs, check errors, or pull bugs:
Fetch recent errors from Bugsnag
For each error, check if linked Jira exists
# Extract error code from Bugsnag
ERROR_CODE=$(echo "$error_title" | grep -oE 'DEV-[0-9]+')
# Check Jira status
bb pullrequest list --state open | grep "$ERROR_CODE"
Create events for high-impact errors
Report summary
Start narrow, expand if needed:
First pass: Last 24 hours (--since "24 hours ago")
Second pass: Last 7 days (--since "7 days ago")
Volume threshold:
When dealing with 10+ Bugsnag errors, use consolidation strategy:
Group by file/responsibility:
Priority ranking:
Cross-check recent commits:
# Check if fix already exists locally
git log --since="2 weeks ago" --grep="DEV-XXXX"
git branch -a | grep -iE "(fix|hotfix|bugfix)"
Create consolidated PR events:
pr-consolidation-{theme} (e.g., pr-consolidation-critical-errors){"priority": 1-8, "issue_count": N, "event_count": N}Benefits:
When the user says .checkall, .check-all, .pullall, or check all:
Execute all sub-commands in sequence:
.check-prs.check-jira.checkbugsReport combined summary with unified routing recommendations.
Use CLI when available; inline SQL as fallback. Database path: ~/.config/opencode/makiso/events.db
oc-events context set --org acme --workspace platform --project distribution --repo lgapi
oc-events context show
# Create a handoff and emit copy-paste prompt
oc-events handoff push \
--to claude \
--from codex \
--summary "Finished queue routing changes" \
--goal "Run validation and open PR" \
--next "Run tests,Fix failures,Open PR" \
--files "src/cli.ts,src/db/events.ts" \
--copy
# Pull handoff for target agent
oc-events handoff pull --for claude --agent @claude --scope repo --copy
Use this when switching from one coding agent to another and you want a clean first prompt.
Tip: Use /makiso-handoff to auto-summarize the current session into a handoff — no manual field entry needed.
# CLI (preferred)
oc-events push <topic> --body "message" --org acme --workspace platform --project distribution --repo lgapi
# Inline SQL (fallback)
sqlite3 ~/.config/opencode/makiso/events.db \
"INSERT INTO events (id, topic, body, status, source, org_id, workspace_id, project_id, repo_id, created_at)
VALUES ('$(date +%s)-$$', '<topic>', 'message', 'pending', 'skill', 'acme', 'platform', 'distribution', 'lgapi', $(date +%s)000)"
# CLI (preferred)
oc-events pull <topic> --agent "@opencode" --org acme --repo lgapi --scope repo
# Inline SQL (fallback) - claim and return in one query
sqlite3 -json ~/.config/opencode/makiso/events.db \
"UPDATE events SET status='processing', claimed_by='@opencode', claimed_at=$(date +%s)000
WHERE id = (SELECT id FROM events WHERE topic='<topic>' AND org_id='acme' AND repo_id='lgapi' AND status='pending'
ORDER BY created_at LIMIT 1) RETURNING *"
# CLI (preferred)
oc-events reply <id> --status completed --body "result summary"
# Inline SQL (fallback)
sqlite3 ~/.config/opencode/makiso/events.db \
"UPDATE events SET status='completed', processed_at=$(date +%s)000,
metadata=json_set(COALESCE(metadata,'{}'), '$.reply', 'result summary')
WHERE id='<id>'"
Use --status failed or status='failed' for failures.
# CLI (preferred)
oc-events search "text query" --org acme --scope org
# Inline SQL (fallback)
sqlite3 -json ~/.config/opencode/makiso/events.db \
"SELECT e.* FROM events e
JOIN events_fts fts ON e.rowid = fts.rowid
WHERE events_fts MATCH 'text query' AND e.org_id='acme'
ORDER BY e.created_at DESC LIMIT 20"
# CLI (preferred)
oc-events pull inbox --agent "@opencode" --org acme --repo lgapi --scope repo
# Inline SQL (fallback)
sqlite3 -json ~/.config/opencode/makiso/events.db \
"SELECT id, topic, substr(body, 1, 100) as body_preview, status, created_at
FROM events WHERE topic='inbox' AND org_id='acme' AND repo_id='lgapi' AND status='pending'
ORDER BY created_at DESC LIMIT 20"
# Inline SQL (works with or without CLI)
sqlite3 ~/.config/opencode/makiso/events.db \
"SELECT id, topic, substr(body, 1, 80), status FROM events
WHERE org_id='acme' AND repo_id='lgapi' AND status = 'pending' ORDER BY created_at DESC LIMIT 20"
# CLI (preferred)
oc-events topics list
oc-events topics create <topic> --prompt "..." --description "..."
# Inline SQL (fallback)
sqlite3 -json ~/.config/opencode/makiso/events.db "SELECT * FROM topics"
sqlite3 ~/.config/opencode/makiso/events.db \
"INSERT INTO topics (name, system_prompt, description, created_at)
VALUES ('<topic>', 'prompt text', 'description', $(date +%s)000)"
# CLI (preferred)
oc-events cleanup --completed-days 30 --pending-days 7
# Inline SQL (fallback) - delete completed older than 30 days
sqlite3 ~/.config/opencode/makiso/events.db \
"DELETE FROM events WHERE status='completed'
AND created_at < ($(date +%s) - 30*86400) * 1000"
Before creating new PR events, verify if fix already exists:
# 1. Extract error pattern from Bugsnag
ERROR_KEY="DEV-1831"
ERROR_PATTERN="invalid.*wav|mp3.*validation"
# 2. Search recent commits
git log --since="2 weeks ago" --all --oneline --grep="$ERROR_KEY"
git log --since="2 weeks ago" --all -p | grep -iE "$ERROR_PATTERN"
# 3. Check local unmerged branches
git branch | grep -iE "(fix|hotfix|bugfix)"
git log main..branch-name --oneline
# 4. If fix found, route to deployment instead of new PR
Common scenarios:
For Bugsnag-driven workflows:
| Pattern | Use Case | Example |
|---|---|---|
bugsnag-investigation | Individual error analysis | Single DEV-XXXX deep dive |
investigation-{key}-cross-check | Commit verification | investigation-dev-1831-cross-check |
pr-consolidation-{theme} | Grouped PR planning | pr-consolidation-critical-errors |
{subsystem}-incident | Multi-error incident | audio-processing-incident |
pr-refinement-analysis | Consolidation review | Overlap detection, priority adjustment |
plugin-management | Plugin improvements | Feature requests, refactoring |
plugin-feature-request | New slash commands | Workflow automation ideas |
When processing events, use resume-workflow patterns:
| Scenario | Check | Action |
|---|---|---|
| PR has comments | bb pullrequest comment list --pullrequest <PR> | Route: needs-review |
| PR approved | bb pullrequest get <PR> | Route: ready-to-merge |
| LLM PROMPT exists | Check PR description/comments | Route: needs-testing |
| Jira in QA | atlan jira get-issue <KEY> | Route: qa-testing |
| Jira in Prod Deploy | Check deployment status | Route: production-deploy |
Event: PR Review: Fix implode error in Bandcamp
PR: #1906 (OPEN)
Comments: 0 unresolved
1. Check PR comments: bb pullrequest comment list --pullrequest 1906
→ Result: No unresolved comments
2. Check PR state: bb pullrequest get 1906
→ Result: OPEN, needs_reviewers
3. Determine route: Ready to merge → Route D
4. Execute: Propose merge to developer
~/.config/opencode/makiso/~/.config/opencode/makiso/prompts/~/.config/opencode/makiso/events.dbEnvironment variables (for CLI, optional):
OC_AGENT_ID - Agent identity (default: @opencode)