Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
6,047 changes: 3,030 additions & 3,017 deletions bun.lock

Large diffs are not rendered by default.

54 changes: 54 additions & 0 deletions conductor/tracks/literbike-provider-guts_20260315/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Track: replace opencode model routing guts with literbike

## Objective

Route all model calls through literbike modelmux at localhost:8888
instead of opencode's current per-provider fetch() calls.
Achieve this without forking opencode or splitting the repo.

## GitHub strategy

Three PRs, each standalone and mergeable:

### PR 1 (upstream opencode): snapshot retention
- Fix GHSA-xv3r-6x54-766h: prune ~/.local/share/opencode/snapshot/
- Max 5 snapshots, configurable via opencode.json
- Prune stale .db files for deleted branches
- Scope: packages/opencode/src/ only
- No literbike dependency. Purely defensive.
- File: conductor/tracks/snapshot-retention-policy_20260315/plan.md

### PR 2 (upstream opencode): literbike provider completeness
- opencode already has literbike provider stub at localhost:8888
- Expand model list dynamically from GET localhost:8888/v1/models
- Auth: none (local sidecar, no key in opencode config)
- No fork needed — just fleshing out existing stub
- Depends on: modelmux binary running (literbike side)

### PR 3 (literbike): @literbike/ai-sdk-provider npm package
- Vercel AI SDK provider shim so opencode's TypeScript layer
can call literbike using the same interface as anthropic/openai
- Publishes to npm as @literbike/ai-sdk-provider
- opencode imports it; literbike controls the routing

## What stays in literbike (no opencode PR needed)

- All provider routing logic (keymux/dsel)
- Quota tracking, rate limiting, health state
- Anthropic x-api-key transform
- Streaming SSE passthrough
- macOS menubar icon / LaunchAgent

## Status

- [x] PR 1 scope defined (snapshot-retention-policy track)
- [ ] PR 1 implementation: find snapshot write path, add retention
- [ ] PR 2: dynamic model list from localhost:8888/v1/models
- [ ] PR 3: @literbike/ai-sdk-provider scaffold

## Avoiding the fork

opencode is MIT licensed. The provider stub is already there.
PRs 1 and 2 are non-controversial — bug fix + extending an existing stub.
If upstream rejects, ship as a patch applied at install time (patches/).
Hard fork only if upstream goes hostile or abandons the project.
25 changes: 25 additions & 0 deletions conductor/tracks/snapshot-retention-policy_20260315/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Track: Snapshot retention policy (200GB leak fix)

Root cause of GHSA-xv3r-6x54-766h: `~/.local/share/opencode/snapshot/` accumulates
one bare git repo per session with no TTL or size cap. 22 snapshots = 408MB on one
machine; scales to 200GB+ on aarch64 Macs with busy sessions or large repos.

Also: one SQLite `.db` file per git branch, never pruned.

## Observed state (jnorthrup machine)
- `~/.local/share/opencode/opencode.db` — 259MB
- `~/.local/share/opencode/snapshot/` — 22 dirs, 408MB total, largest 183MB
- Total: 1.6GB on a single machine after normal use

## Scope
- `packages/opencode/src/` — find snapshot write path, add retention policy
- Default: keep last 5 snapshots, delete oldest on creation of new one
- Configurable via opencode.json: `{ "snapshot": { "max_count": 5 } }`
- Target branch: advisory-fix-1 on anomalyco/opencode-ghsa-xv3r-6x54-766h

## Status
- [ ] Locate snapshot creation code in CLI source
- [ ] Add retention enforcement on snapshot write
- [ ] Add db file pruning for stale branch databases
- [ ] Push to advisory-fix-1
- [ ] Update GHSA-xv3r-6x54-766h advisory with root cause detail
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"packages/slack"
],
"catalog": {
"@types/bun": "1.3.9",
"@types/bun": "1.3.10",
"@octokit/rest": "22.0.0",
"@hono/zod-validator": "0.4.2",
"ulid": "3.0.1",
Expand All @@ -37,7 +37,7 @@
"@cloudflare/workers-types": "4.20251008.0",
"@openauthjs/openauth": "0.0.0-20250322224806",
"@pierre/diffs": "1.1.0-beta.18",
"@solid-primitives/storage": "4.3.3",
"@solid-primitives/storage": "4.3.4",
"@tailwindcss/vite": "4.1.11",
"diff": "8.0.2",
"dompurify": "3.3.1",
Expand All @@ -53,9 +53,10 @@
"marked-shiki": "1.2.1",
"@playwright/test": "1.51.0",
"typescript": "5.8.2",
"@typescript/native-preview": "7.0.0-dev.20251207.1",
"@typescript/native-preview": "7.0.0-dev.20260314.1",
"zod": "4.1.8",
"remeda": "2.26.0",
"semver": "7.7.4",
"shiki": "3.20.0",
"solid-list": "0.3.0",
"tailwindcss": "4.1.11",
Expand All @@ -64,7 +65,7 @@
"@solidjs/meta": "0.29.4",
"@solidjs/router": "0.15.4",
"@solidjs/start": "https://pkg.pr.new/@solidjs/start@dfb2020",
"solid-js": "1.9.10",
"solid-js": "1.9.11",
"vite-plugin-solid": "2.11.10"
}
},
Expand All @@ -76,7 +77,7 @@
"glob": "13.0.5",
"husky": "9.1.7",
"prettier": "3.6.2",
"semver": "^7.6.0",
"semver": "catalog:",
"sst": "3.18.10",
"turbo": "2.8.13"
},
Expand Down
1 change: 1 addition & 0 deletions packages/app/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"allowJs": true,
"resolveJsonModule": true,
"strict": true,
"types": ["node", "bun"],
"noEmit": false,
"emitDeclarationOnly": true,
"outDir": "node_modules/.ts-dist",
Expand Down
6 changes: 6 additions & 0 deletions packages/console/app/src/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,9 @@
export declare module "@solidjs/start/server" {
export type APIEvent = { request: Request }
}

declare module "solid-js/web" {
interface RequestEvent {
locals: Record<string, any>
}
}
Loading
Loading