Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
86596b7
chore: add Claude Code parity roadmap
Mar 31, 2026
943fbe0
Feature 1: Native Desktop Control (Computer Use Tool)
Mar 31, 2026
7ccc621
feat: add Headless Browser Automation tool (WebBrowserTool)
Mar 31, 2026
4ea8b84
Merge pull request #5 from jairad26/feature/desktop-tool
jairad26 Mar 31, 2026
344dc38
Merge pull request #3 from jairad26/feature/browser-tool
jairad26 Mar 31, 2026
e7ddba5
Implement SpawnMultiAgentTool (Swarm) for parallel sub-agent execution
Mar 31, 2026
bdc3f9f
feat: implement Long-Term Semantic Memory (SessionMemory)
Mar 31, 2026
3573ca0
feat: implement Long-Term Semantic Memory (SessionMemory)
Mar 31, 2026
b682caf
Merge pull request #2 from jairad26/feature/swarm-tool
jairad26 Mar 31, 2026
41d4498
Merge pull request #1 from jairad26/feature/session-memory
jairad26 Mar 31, 2026
2c23726
feat: implement strict Zod-based permission router with secondary LLM…
Mar 31, 2026
e8688d3
Merge pull request #4 from jairad26/feature/permission-router
jairad26 Mar 31, 2026
3c64851
docs: update roadmap with phase 3 advanced features and mark phase 1 …
Mar 31, 2026
2b3d3db
fix: add chromium-bidi for Bun CLI builds
Mar 31, 2026
7231e1f
docs: add comprehensive feature roadmap for claude code parity
Mar 31, 2026
6a5daa6
Merge pull request #7 from jairad26/roadmap-final-update
jairad26 Mar 31, 2026
764383f
Merge pull request #6 from jairad26/fix/bun-build-chromium-bidi
jairad26 Mar 31, 2026
6ace249
fix: resolve native addon dependencies for Desktop tool
NicholasDominici Mar 31, 2026
dc3b365
Merge pull request #8 from NicholasDominici/fix/desktop-tool-native-deps
jairad26 Mar 31, 2026
4fb2631
fix: resolve @nut-tree-fork/nut-js from compiled Bun binary
Mar 31, 2026
1acd240
Merge remote-tracking branch 'upstream/dev' into dev
Mar 31, 2026
b70a04d
fix: use grab/grabRegion for screenshots instead of capture
Mar 31, 2026
f13efcd
Merge pull request #11 from jairad26/fix/desktop-screenshot-grab
jairad26 Mar 31, 2026
faa35aa
Add keyboard shortcut support to desktop tool
Mar 31, 2026
92f7217
fix: use imageToJimp for screenshot PNG conversion
Mar 31, 2026
8882046
Merge branch 'anomalyco:dev' into dev
jairad26 Mar 31, 2026
82e9231
docs: Add local opencode override skill and remove chromium-bidi depe…
Mar 31, 2026
b31b0c2
Merge pull request #12 from jairad26/03-31-docs_add_local_opencode_ov…
jairad26 Mar 31, 2026
d5c4315
feat: add worktree sandbox tools
Mar 31, 2026
099476b
Merge pull request #13 from jairad26/03-31-feat_add_worktree_sandbox_…
jairad26 Mar 31, 2026
f7011b5
Merge branch 'anomalyco:dev' into dev
jairad26 Mar 31, 2026
349776b
feat: add session brief tool
Mar 31, 2026
b1e664b
Merge pull request #17 from jairad26/03-31-feat_add_session_brief_tool
jairad26 Mar 31, 2026
9ac0947
feat: add safe session snip tool
Mar 31, 2026
1cbcac8
Merge pull request #18 from jairad26/03-31-feat_add_safe_session_snip…
jairad26 Mar 31, 2026
ca6e7b4
feat: add lightweight trigger service
Mar 31, 2026
7cd2a9a
feat: add lightweight trigger service (#19)
jairad26 Apr 1, 2026
f80c32a
feat: add remote attach preflight
Mar 31, 2026
7eaaeee
feat: add remote attach preflight (#20)
jairad26 Apr 1, 2026
45c789e
feat: execute trigger command actions
Mar 31, 2026
7cfcf47
feat: execute trigger command actions (#21)
jairad26 Apr 1, 2026
e3485ac
feat: add trigger lifecycle controls
Mar 31, 2026
0790023
feat: add trigger lifecycle controls (#22)
jairad26 Apr 1, 2026
7de0762
feat: validate remote session targets
Mar 31, 2026
404313b
feat: validate remote session targets (#23)
jairad26 Apr 1, 2026
6a622ac
feat: add manual trigger fire
Mar 31, 2026
d223e9f
feat: add manual trigger fire (#24)
jairad26 Apr 1, 2026
5e2ab86
feat: confirm remote continue targets
Mar 31, 2026
6acea59
feat: confirm remote continue targets (#25)
jairad26 Apr 1, 2026
ea03bdb
feat: add trigger fire webhook endpoint
Mar 31, 2026
55f609e
feat: add trigger fire webhook endpoint (#26)
jairad26 Apr 1, 2026
b7e620b
feat: pick remote continue sessions
Mar 31, 2026
c1c36a5
feat: pick remote continue sessions (#27)
jairad26 Apr 1, 2026
7faded3
feat: persist trigger state
Mar 31, 2026
bf121e6
feat: persist trigger state (#28)
jairad26 Apr 1, 2026
e5277e5
feat: add TUI remote session picker
Apr 1, 2026
2081b9d
feat: add TUI remote session picker (#29)
jairad26 Apr 1, 2026
9a77680
feat: add trigger webhook secrets
Apr 1, 2026
d62a0c5
feat: add trigger webhook secrets (#30)
jairad26 Apr 1, 2026
00645ed
feat: browse remote child sessions
Apr 1, 2026
63eaee7
feat: browse remote child sessions (#31)
jairad26 Apr 1, 2026
68e7982
feat: record trigger execution state
Apr 1, 2026
004f227
feat: record trigger execution state (#32)
jairad26 Apr 1, 2026
dcaf44a
feat: clarify remote fork targets
Apr 1, 2026
aa78113
feat: clarify remote fork targets (#33)
jairad26 Apr 1, 2026
ad1f850
feat: add one-shot trigger schedules
Apr 1, 2026
3d5d8de
Merge pull request #34 from jairad26/03-31-feat_add_one-shot_trigger_…
jairad26 Apr 1, 2026
30fd48d
feat: browse remote sessions from tui
Apr 1, 2026
879292a
Merge pull request #35 from jairad26/03-31-feat_browse_remote_session…
jairad26 Apr 1, 2026
63828e2
feat: add opencode-memory skill and global session listing
Apr 1, 2026
939819a
Merge pull request #36 from jairad26/03-31-feat_add_opencode-memory_s…
jairad26 Apr 1, 2026
6053fd6
feat: add workspace ID support and webhook triggers
Apr 1, 2026
5bc0750
Merge pull request #37 from jairad26/03-31-feat_add_workspace_id_supp…
jairad26 Apr 1, 2026
559d4a9
feat: add mobile-friendly remote control and trigger management
Apr 1, 2026
9d81506
Merge pull request #38 from jairad26/04-01-feat_add_mobile-friendly_r…
jairad26 Apr 1, 2026
7d125ed
Merge branch 'anomalyco:dev' into dev
jairad26 Apr 1, 2026
5c632f6
feat: replace external spinner with custom implementation
Apr 1, 2026
e6be60e
Merge pull request #39 from jairad26/04-01-feat_replace_external_spin…
jairad26 Apr 1, 2026
06560e0
Merge branch 'anomalyco:dev' into dev
jairad26 Apr 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions .opencode/skills/local-opencode-override/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
name: local-opencode-override
description: Use when a repo-local opencode build should replace the installed `opencode` command in your shell, especially after rebuilding `packages/opencode/dist` during local development.
compatibility: opencode
---

# Local opencode override

Use this when you want `opencode` in your shell to run the binary built from this repo instead of a globally installed copy.

## Preferred approach

Follow the existing OpenCode convention and point `~/.opencode/bin/opencode` at the repo build output.

Why this path:

- the install flow already uses `~/.opencode/bin`
- desktop code and GitHub actions already expect that location
- your shell can keep using `opencode` with no extra alias

## Steps

1. Build the current-platform CLI:

```bash
bun run --cwd packages/opencode build --single --skip-embed-web-ui
```

2. Link the built binary into the standard user bin location:

```bash
mkdir -p "$HOME/.opencode/bin"
ln -sf \
"/absolute/path/to/repo/packages/opencode/dist/opencode-<platform>/bin/opencode" \
"$HOME/.opencode/bin/opencode"
```

Example for this repo on Apple Silicon:

```bash
ln -sf \
"/Users/jairadhakrishnan/github.com/jairad26/opencode/packages/opencode/dist/opencode-darwin-arm64/bin/opencode" \
"$HOME/.opencode/bin/opencode"
```

3. Make sure `~/.opencode/bin` is early in `PATH`.

For zsh:

```bash
export PATH="$HOME/.opencode/bin:$PATH"
```

4. Reload the shell and verify:

```bash
zsh -lc 'hash -r && command -v opencode && opencode --version'
```

## Rebuild behavior

The symlink target path stays the same across rebuilds for the same platform, so rerunning the build replaces the binary in place.

## Alternative

If you only want a temporary override, use the launcher support built into `packages/opencode/bin/opencode`:

```bash
OPENCODE_BIN_PATH="/absolute/path/to/repo/packages/opencode/dist/opencode-<platform>/bin/opencode" opencode
```

## Revert

To stop using the repo build:

```bash
rm -f "$HOME/.opencode/bin/opencode"
```

Then reinstall or relink the version you want.
274 changes: 274 additions & 0 deletions .opencode/skills/opencode-memory/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
---
name: opencode-memory
description: Use when the user asks to recall prior OpenCode work, previous sessions, plans, prompt history, memory, or earlier project context stored on the local machine.
compatibility: opencode
---

# OpenCode Memory Browser

Lightweight, read-only access to your local OpenCode history. No injection, no bloat — just the ability to look things up when it would help.

This skill is specifically about OpenCode data stored on the local machine. It is not for ChatGPT history, Claude cloud history, generic browser history, or external memory products.

All data lives in local SQLite databases and plain files. You query them directly using `sqlite3` via bash. No bundled scripts or external dependencies needed.

## When to Use

### Auto-trigger (agent decides)

- You are resuming work on a project and suspect prior sessions exist.
- The user references something done previously ("we did this before", "last time", "that plan we made").
- A recurring issue suggests checking if it was encountered before.
- The user asks about the state of plans, past decisions, or previous approaches.
- You need context that might exist in history but is not in the current session.

### User-triggered (explicit request)

- "Check my history"
- "What did we do in the last session?"
- "Show me my plans"
- "Search for when we discussed X"
- "What projects have I worked on?"
- "Look at previous conversations about Y"

### Do NOT use when

- The task is clearly brand new with no relevant history.
- Fresh repo context (files, git log) is sufficient.
- The user explicitly says they don't care about prior work.

## Storage Locations

```
Databases: ${XDG_DATA_HOME:-$HOME/.local/share}/opencode/opencode*.db
Plans: ${XDG_DATA_HOME:-$HOME/.local/share}/opencode/plans/*.md
Session diffs: ${XDG_DATA_HOME:-$HOME/.local/share}/opencode/storage/session_diff/<session-id>.json
Prompt history: ${XDG_STATE_HOME:-$HOME/.local/state}/opencode/prompt-history.jsonl
```

The database path respects `$XDG_DATA_HOME` if set (default: `~/.local/share`).

Important: OpenCode may store session history in multiple channel-specific databases such as:

- `opencode.db`
- `opencode-dev.db`
- `opencode-local.db`
- other `opencode-<channel>.db` files

When recalling prior work, search **all local `opencode*.db` files**, not just `opencode.db`.

## Database Schema (what matters)

- **project** — `id` (text PK), `worktree` (path), `name` (often NULL, derive from worktree basename)
- **session** — `id` (text, e.g. `ses_xxx`), `project_id` (FK), `parent_id` (NULL = main session, set = subagent), `title`, `summary`, `time_created`, `time_updated`
- **message** — `id`, `session_id` (FK), `data` (JSON with `$.role` = `"user"` or `"assistant"`), `time_created`
- **part** — `id`, `message_id` (FK), `session_id` (FK), `data` (JSON with `$.type` = `"text"` and `$.text` = content)

Timestamps are Unix milliseconds. Use `datetime(col/1000, 'unixepoch', 'localtime')` to display them.

## Ready-to-Use Queries

All queries use `sqlite3` in read-only mode. Always run via bash.

**Shorthand used below:**

```
DATA_ROOT="${XDG_DATA_HOME:-$HOME/.local/share}/opencode"
STATE_ROOT="${XDG_STATE_HOME:-$HOME/.local/state}/opencode"
DBS=("$DATA_ROOT"/opencode*.db)
```

If the glob does not match anything, verify the storage root first with `ls "$DATA_ROOT"`.

### Quick summary

```bash
for DB in "${DBS[@]}"; do
[ -f "$DB" ] || continue
DB_URI="file:${DB}?mode=ro"
printf '\n== %s ==\n' "$DB"
sqlite3 "$DB_URI" "
SELECT 'projects', COUNT(*) FROM project
UNION ALL SELECT 'sessions (main)', COUNT(*) FROM session WHERE parent_id IS NULL
UNION ALL SELECT 'sessions (total)', COUNT(*) FROM session
UNION ALL SELECT 'messages', COUNT(*) FROM message
UNION ALL SELECT 'todos', COUNT(*) FROM todo;
"
done
```

### List projects

Set `DB_URI` to the database you want to inspect first, for example:

```bash
DB="$DATA_ROOT/opencode-dev.db"
DB_URI="file:${DB}?mode=ro"
```

```bash
sqlite3 "$DB_URI" "
SELECT
COALESCE(p.name, CASE WHEN p.worktree = '/' THEN '(global)' ELSE REPLACE(p.worktree, RTRIM(p.worktree, REPLACE(p.worktree, '/', '')), '') END) AS name,
p.worktree,
(SELECT COUNT(*) FROM session s WHERE s.project_id = p.id AND s.parent_id IS NULL) AS sessions
FROM project p
ORDER BY p.time_updated DESC
LIMIT 10;
"
```

### List recent sessions

```bash
for DB in "${DBS[@]}"; do
[ -f "$DB" ] || continue
DB_URI="file:${DB}?mode=ro"
sqlite3 "$DB_URI" "
SELECT
'${DB}' AS db,
s.id,
COALESCE(s.title, 'untitled') AS title,
COALESCE(p.name, CASE WHEN p.worktree = '/' THEN '(global)' ELSE REPLACE(p.worktree, RTRIM(p.worktree, REPLACE(p.worktree, '/', '')), '') END) AS project,
datetime(s.time_updated/1000, 'unixepoch', 'localtime') AS updated,
(SELECT COUNT(*) FROM message m WHERE m.session_id = s.id) AS msgs
FROM session s
LEFT JOIN project p ON p.id = s.project_id
WHERE s.parent_id IS NULL
ORDER BY s.time_updated DESC
LIMIT 10;
"
done
```

### Sessions for a specific project

Set `DB_URI` to the likely matching database, then replace the worktree path with the actual project path:

```bash
sqlite3 "$DB_URI" "
SELECT s.id, COALESCE(s.title, 'untitled'),
datetime(s.time_updated/1000, 'unixepoch', 'localtime')
FROM session s
JOIN project p ON p.id = s.project_id
WHERE p.worktree = '/path/to/project'
AND s.parent_id IS NULL
ORDER BY s.time_updated DESC
LIMIT 10;
"
```

To find the worktree for the current directory: `git rev-parse --show-toplevel`

### Read messages from a session

Replace the session ID:

```bash
sqlite3 "$DB_URI" "
SELECT
json_extract(m.data, '$.role') AS role,
datetime(m.time_created/1000, 'unixepoch', 'localtime') AS time,
GROUP_CONCAT(json_extract(p.data, '$.text'), char(10)) AS text
FROM message m
LEFT JOIN part p ON p.message_id = m.id
AND json_extract(p.data, '$.type') = 'text'
WHERE m.session_id = 'SESSION_ID_HERE'
GROUP BY m.id
ORDER BY m.time_created ASC
LIMIT 50;
"
```

### Search across all conversations

Replace the search term:

```bash
for DB in "${DBS[@]}"; do
[ -f "$DB" ] || continue
DB_URI="file:${DB}?mode=ro"
sqlite3 "$DB_URI" "
SELECT
'${DB}' AS db,
s.id AS session_id,
COALESCE(s.title, 'untitled') AS title,
json_extract(m.data, '$.role') AS role,
datetime(m.time_created/1000, 'unixepoch', 'localtime') AS time,
substr(json_extract(p.data, '$.text'), 1, 200) AS snippet
FROM part p
JOIN message m ON m.id = p.message_id
JOIN session s ON s.id = m.session_id
WHERE s.parent_id IS NULL
AND json_extract(p.data, '$.type') = 'text'
AND json_extract(p.data, '$.text') LIKE '%SEARCH_TERM%'
ORDER BY m.time_created DESC
LIMIT 10;
"
done
```

### List saved plans

```bash
ls -lt "$DATA_ROOT"/plans/*.md 2>/dev/null | head -20
```

To read a specific plan:

```bash
cat "$DATA_ROOT"/plans/FILENAME.md
```

### Show recent prompt history

```bash
tail -20 "$STATE_ROOT"/prompt-history.jsonl
```

Each line is a JSON object. The user's input is typically in the `input` or `text` field.

## Workflow

### Quick recall (most common)

1. Check **prompt history first** with `rg -n -i "term1|term2" "$STATE_ROOT/prompt-history.jsonl"` to recover the user's original wording and likely time window.
2. Run the **summary** query across all local databases to see which DB/channel has the relevant history.
3. If you need sessions for the current project, get the worktree with `git rev-parse --show-toplevel`, then run the **project sessions** query against the likely matching DB(s).
4. If you need a specific topic, run the **search** query across all DBs using both the exact phrase and adjacent terms.
5. If you need full conversation detail, run the **messages** query with the session ID from the matching DB.

### Plan review

1. List plans with `ls -lt "$DATA_ROOT"/plans/*.md`.
2. Read a plan with `cat "$DATA_ROOT"/plans/<filename>.md`.

### Deep investigation

1. Search prompt history first to anchor wording/date.
2. Run **projects/sessions** across all local DBs.
3. Search with neighboring terms, not just the user’s remembered phrasing.
4. Read only the best candidate session tails before expanding further.
5. Cross-reference with session diffs or plans if needed.

## Critical Rules

1. **Read-only.** Never write to or modify the database or any OpenCode files.
2. **Use bash + sqlite3.** Do not try to read `opencode*.db` with the Read tool — they are binary files. Always query via `sqlite3` in bash.
3. **Don't dump everything.** Use `LIMIT` and `LIKE` to keep output focused. The database can contain tens of thousands of messages.
4. **Summarize for the user.** After retrieving data, distill the relevant parts. Don't paste raw query output.
5. **Respect privacy.** Session history may contain sensitive data. Only surface what is relevant to the current task.
6. **Set path variables first.** At the start of any memory lookup, set `DATA_ROOT`, `STATE_ROOT`, and `DBS` exactly as shown above so the commands work on XDG and non-XDG setups and cover every local channel database.

## Fallback: Web UI

If the user needs visual dashboards or a browsable interface:

1. Check if OpenCode web is running: `curl -s http://127.0.0.1:4096/api/health 2>/dev/null || echo "not running"`
2. If running, direct the user to `http://127.0.0.1:4096`.
3. If not running, suggest `opencode web`.
4. Note: `opencode.local` only works with mDNS enabled (`opencode web --mdns`). Don't assume it exists.

## Deep Reference

See `references/storage-format.md` for the full storage layout, all table schemas, and additional query examples.
Loading
Loading