- To regenerate the JavaScript SDK, run
./packages/sdk/js/script/build.ts. - ALWAYS USE PARALLEL TOOLS WHEN APPLICABLE.
- The default branch in this repo is
dev. - Local
mainref may not exist; usedevororigin/devfor diffs. - Prefer automation: execute requested actions without confirmation unless blocked by missing info or safety/irreversibility.
This repository is a fork of OpenCode that adds offline/air-gapped deployment support. We regularly sync with upstream to get new features and fixes.
The goal is to make upstream syncs as painless as possible by:
- Centralizing fork-specific logic in dedicated modules (like
packages/opencode/src/offline/) - Minimizing changes to upstream files - when we must modify upstream code, use small guards that delegate to our modules
- Preferring additive changes over modifications - new files never conflict
When adding fork-specific features:
Prefer new files over modifying existing ones:
packages/opencode/src/offline/ <- Fork-specific, never conflicts
packages/opencode/src/some-core/ <- Upstream code, may conflict
When you must modify upstream files, keep changes minimal:
// Good: 2-line guard at top of function
const offlineResult = await Offline.tryResolve(args)
if (offlineResult) return offlineResult
// Bad: Large block of fork logic embedded in function
if (Offline.isEnabled()) {
// ... 20 lines of fork-specific code ...
}Mark fork-specific lines for easy identification:
// offline-fork: use bundled binary in air-gapped mode
const result = await Offline.tryResolveBinary(name)-
Add upstream remote if not already configured:
git remote add upstream https://github.com/anomalyco/opencode.git
-
Fetch and merge upstream changes:
git fetch upstream git checkout -b sync/upstream-$(date +%Y%m%d) dev git merge upstream/dev -
Resolve conflicts:
- Accept upstream changes first
- Re-add minimal fork guards (look for
// offline-fork:comments in git diff)
-
Verify:
bun test OPENCODE_OFFLINE_MODE=true bun dev # Test offline mode still works
-
PR to
devbranch
- Keep things in one function unless composable or reusable
- Avoid
try/catchwhere possible - Avoid using the
anytype - Prefer single word variable names where possible
- Use Bun APIs when possible, like
Bun.file() - Rely on type inference when possible; avoid explicit type annotations or interfaces unless necessary for exports or clarity
- Prefer functional array methods (flatMap, filter, map) over for loops; use type guards on filter to maintain type inference downstream
Prefer single word names for variables and functions. Only use multiple words if necessary.
// Good
const foo = 1
function journal(dir: string) {}
// Bad
const fooBar = 1
function prepareJournal(dir: string) {}Reduce total variable count by inlining when a value is only used once.
// Good
const journal = await Bun.file(path.join(dir, "journal.json")).json()
// Bad
const journalPath = path.join(dir, "journal.json")
const journal = await Bun.file(journalPath).json()Avoid unnecessary destructuring. Use dot notation to preserve context.
// Good
obj.a
obj.b
// Bad
const { a, b } = objPrefer const over let. Use ternaries or early returns instead of reassignment.
// Good
const foo = condition ? 1 : 2
// Bad
let foo
if (condition) foo = 1
else foo = 2Avoid else statements. Prefer early returns.
// Good
function foo() {
if (condition) return 1
return 2
}
// Bad
function foo() {
if (condition) return 1
else return 2
}Use snake_case for field names so column names don't need to be redefined as strings.
// Good
const table = sqliteTable("session", {
id: text().primaryKey(),
project_id: text().notNull(),
created_at: integer().notNull(),
})
// Bad
const table = sqliteTable("session", {
id: text("id").primaryKey(),
projectID: text("project_id").notNull(),
createdAt: integer("created_at").notNull(),
})- Avoid mocks as much as possible
- Test actual implementation, do not duplicate logic into tests
- Tests cannot run from repo root (guard:
do-not-run-tests-from-root); run from package dirs likepackages/opencode.
When making changes to offline-related code, run the containerized offline test suite to verify the bundle still works in an air-gapped environment:
bun install
bun run script/download-offline-deps.ts
bun run script/package-offline-bundle.ts
docker compose -f test/offline/docker-compose.yml up --buildThis builds the full offline bundle, runs it in a RHEL9 container with no outbound network, and validates: environment setup, binary execution, network isolation, web UI serving (bundled SolidJS app), LSP server presence, and CLI commands.
These tests run automatically in CI (.github/workflows/offline-test.yml) on changes to:
packages/opencode/src/offline/**packages/opencode/src/server/server.tsscript/download-offline-deps.ts,script/package-offline-bundle.tstest/offline/**
See test/offline/README.md for details on network isolation modes, interactive exploration, and troubleshooting.