Skip to content

Commit 92ddb0b

Browse files
committed
Merge PR #6: migrate plugin to first-class OpenCode TUI
2 parents 5bb1bcb + 8880e6e commit 92ddb0b

304 files changed

Lines changed: 70302 additions & 28040 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,31 @@ jobs:
2020
with:
2121
node-version: 24
2222

23+
- name: Setup Bun
24+
uses: oven-sh/setup-bun@v2
25+
with:
26+
bun-version: 1.3
27+
2328
- name: Install dependencies
24-
run: npm install
29+
run: bun install --frozen-lockfile
2530

2631
- name: Run type check
27-
run: npm run typecheck
32+
run: bun run typecheck
2833

2934
- name: Build
30-
run: npm run build
35+
run: bun run build
36+
37+
- name: Smoke test TUI
38+
run: bun run --cwd packages/opencode smoke:tui
3139

3240
- name: Run tests
33-
run: npm test
41+
run: bun run test
42+
43+
- name: Run E2E tests
44+
run: bun run test:e2e
45+
46+
- name: Check formatting
47+
run: bun run format:check
48+
49+
- name: Lint
50+
run: bun run lint

.github/workflows/release.yml

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,34 @@ jobs:
3434
with:
3535
node-version: "24"
3636

37+
- name: Setup Bun
38+
uses: oven-sh/setup-bun@v2
39+
with:
40+
bun-version: 1.3
41+
3742
- name: Install dependencies
38-
run: npm install
43+
run: bun install --frozen-lockfile
3944

4045
- name: TypeScript typecheck
41-
run: npm run typecheck
46+
run: bun run typecheck
4247

4348
- name: Build
44-
run: npm run build
49+
run: bun run build
50+
51+
- name: Smoke test TUI
52+
run: bun run --cwd packages/opencode smoke:tui
4553

4654
- name: Test
47-
run: npm test
55+
run: bun run test
56+
57+
- name: Run E2E tests
58+
run: bun run test:e2e
59+
60+
- name: Check formatting
61+
run: bun run format:check
62+
63+
- name: Lint
64+
run: bun run lint
4865

4966
publish-npm:
5067
name: Publish ${{ matrix.package }} to npm
@@ -72,11 +89,16 @@ jobs:
7289
node-version: "24"
7390
registry-url: "https://registry.npmjs.org"
7491

92+
- name: Setup Bun
93+
uses: oven-sh/setup-bun@v2
94+
with:
95+
bun-version: 1.3
96+
7597
- name: Ensure latest npm (for trusted publishing)
7698
run: npm install -g npm@latest
7799

78100
- name: Install dependencies
79-
run: npm install
101+
run: bun install --frozen-lockfile
80102

81103
- name: Resolve release version
82104
id: version
@@ -89,7 +111,7 @@ jobs:
89111
run: node scripts/version-sync.mjs "${{ steps.version.outputs.version }}"
90112

91113
- name: Build
92-
run: npm run build
114+
run: bun run build
93115

94116
- name: Check whether package version is already published
95117
id: published

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ out
66
dist
77
*.tgz
88

9+
# precompiled OpenTUI sidebar tree (regenerated by build:tui)
10+
packages/opencode/src/tui-compiled/
11+
912
# code coverage
1013
coverage
1114
*.lcov

AGENTS.MD

Lines changed: 72 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,28 @@ OpenCode plugin for Google Antigravity OAuth. Intercepts `fetch()` calls to `gen
99
## Build & Test Commands
1010

1111
```bash
12-
npm install # Install dependencies
13-
npm run build # Compile (tsc -p tsconfig.build.json)
14-
npm run typecheck # Type-check only (tsc --noEmit)
15-
npm test # Run all tests (vitest run)
16-
npx vitest run src/plugin/auth.test.ts # Single test file
17-
npx vitest run -t "test name here" # Single test by name
18-
npx vitest --watch src/plugin/auth.test.ts # Watch mode, single file
19-
npm run test:coverage # Coverage report
20-
npm run test:e2e:models # E2E: model availability check
21-
npm run test:e2e:regression # E2E: regression suite
12+
bun install # Install dependencies
13+
bun run build # Compile (tsc -p tsconfig.build.json)
14+
bun run typecheck # Type-check only (tsc --noEmit)
15+
bun run test # Run all unit tests (bun test --isolate across packages)
16+
bun test --isolate src/plugin/auth.test.ts # Single test file
17+
bun test --isolate -t "test name here" # Single test by name (uses bun:test's -t filter)
18+
bun test --isolate --watch src/plugin/auth.test.ts # Watch mode, single file
19+
bun run test:e2e # Deterministic e2e flows (mock Antigravity server, no network)
20+
bun run test:e2e:models # Live Antigravity model inventory (CI-gated, network)
21+
bun run test:e2e:regression # Cross-model + Gemini CLI regression (network)
22+
bun run --cwd packages/opencode smoke:tui # Pack-and-install smoke test for the TUI subpath
2223
```
2324

24-
No linter or formatter is configured. Style is enforced by convention (see below).
25+
Format and lint via Biome:
26+
27+
```bash
28+
bun run format # biome format --write .
29+
bun run format:check # biome format . (CI gate)
30+
bun run lint # biome lint . (CI gate)
31+
```
32+
33+
Pre-commit hooks (`.lefthook.yml`) run Biome on changed `*.{ts,tsx,js,mjs,json,jsonc,yml,yaml}` files via `bunx biome check --staged --no-errors-on-unmatched`. The repo pins the toolchain in `mise.toml` (`bun = "1.3"`, `node = "24"`) and CI uses `oven-sh/setup-bun@v2` with `bun-version: 1.3`.
2534

2635
## TypeScript Configuration
2736

@@ -70,7 +79,7 @@ No linter or formatter is configured. Style is enforced by convention (see below
7079

7180
### Formatting
7281
- 2-space indentation
73-
- Double quotes for strings
82+
- Single quotes for strings (Biome `quoteStyle: single`)
7483
- Trailing commas in multiline constructs
7584
- No semicolons (project convention)
7685

@@ -80,24 +89,49 @@ No linter or formatter is configured. Style is enforced by convention (see below
8089

8190
## Module Structure
8291

92+
The repository is a Bun workspace with three packages. The pre-monorepo
93+
single-root-`src/` layout was retired when the project split into
94+
`packages/{core,opencode,pi}` so the harness-agnostic engine, the host
95+
adapter, and the Pi host can ship on independent cadences.
96+
8397
```
84-
src/
85-
├── plugin.ts # Main entry, fetch interceptor
86-
├── constants.ts # Endpoints, headers, API config, system prompts
87-
├── antigravity/oauth.ts # OAuth token exchange
88-
└── plugin/
89-
├── auth.ts # Token validation & refresh
90-
├── request.ts # Request transformation (core logic)
91-
├── request-helpers.ts # Schema cleaning, thinking filters
92-
├── thinking-recovery.ts # Turn boundary detection
93-
├── recovery.ts # Session recovery (tool_result_missing)
94-
├── quota.ts # Quota checking (API usage stats)
95-
├── cache.ts # Auth & signature caching
96-
├── accounts.ts # Multi-account management & storage
97-
├── storage.ts # Persistent storage schemas (Zod)
98-
├── fingerprint.ts # Device fingerprint generation & headers
99-
├── project.ts # Managed project context resolution
100-
└── debug.ts # Debug logging utilities
98+
packages/
99+
├── core/ # Harness-agnostic engine — auth, transform, storage, fingerprinting
100+
│ └── src/
101+
│ ├── index.ts # Public barrel
102+
│ ├── account-manager.ts # Per-account selection, rate-limit, quota, fingerprint
103+
│ ├── account-storage.ts # v4 schema + lock-held read-modify-write + fail-closed unreadable
104+
│ ├── agy-transport.ts # Bounded TLS pool, gzip/chunk decode, idle watchdog
105+
│ ├── agy-request-metadata.ts
106+
│ ├── antigravity/oauth.ts # OAuth token exchange + refresh
107+
│ ├── auth.ts # Token validation helpers
108+
│ ├── file-lock.ts # Fenced file lock for concurrent writes
109+
│ ├── fingerprint.ts # Device fingerprint construction
110+
│ ├── model-registry.ts # Anthropic / Gemini / GPT-OSS model definitions
111+
│ ├── project.ts # Managed project resolution
112+
│ ├── quota-manager.ts # Quota caching + fallbacks
113+
│ ├── rotation.ts # Account rotation state
114+
│ └── transform/ # Claude / Gemini / cross-model sanitizer + tests
115+
├── opencode/ # OpenCode host adapter — plugin entry, fetch interceptor, TUI
116+
│ └── src/
117+
│ ├── cli.ts # `antigravity-auth` CLI (login / list / quota)
118+
│ ├── plugin/ # Plugin factory, OAuth methods, account access, fetch
119+
│ │ ├── fetch-interceptor.ts # Outer/inner loop, retry/quota/routing pipeline
120+
│ │ ├── auth-loader.ts # Host `auth.loader()` integration
121+
│ │ ├── oauth-methods.ts # OAuth menu + callbacks
122+
│ │ ├── persist-account-pool.ts # Lock-held append after fresh OAuth login
123+
│ │ ├── storage.ts # Host-path adapter for account pool (re-exports core errors)
124+
│ │ └── ui/ # TUI sidebar, auth menu, quota-status, command dialogs
125+
│ ├── tui/ # Precompiled + raw TUI sources
126+
│ ├── rpc/ # Loopback RPC server + client (sidebar notifications)
127+
│ └── hooks/ # Lifecycle hooks (auto-update checker, etc.)
128+
└── pi/ # Pi host adapter — thinner facade around core
129+
└── src/
130+
├── index.ts # Public barrel — `streamCortexKitAntigravity` + OAuth helpers
131+
├── convert.ts # Pi <-> Antigravity message-shape conversion
132+
├── credential-cache.ts # Packed refresh token cache
133+
├── paths.ts # Pi AGENT_DIR + account-pool path resolution
134+
└── stream.ts # Stream factory consumed by `index.ts`
101135
```
102136

103137
## Key Design Patterns
@@ -130,15 +164,19 @@ Per-account device fingerprints stored in `antigravity-accounts.json`. Each fing
130164

131165
## Testing
132166

133-
- Framework: **Vitest 3** with native ESM
134-
- Config: `vitest.config.ts`
135-
- Tests colocated: `src/plugin/foo.test.ts` next to `src/plugin/foo.ts`
136-
- Use `describe`/`it`/`expect` standard Vitest API
137-
- Mock with `vi.fn()`, `vi.spyOn()`, `vi.mock()`
167+
- Framework: **Bun's test runner** (`bun test`; the `bun:test` module re-exports a jest-compatible namespace)
168+
- Config: no per-package config — Bun discovers `*.test.ts` next to source. The `bunfig.toml` at the root and in each workspace preloads `test/setup.ts` (env-isolation + a per-test mkdtemp root + a `globalThis.stubbed` / `unstubAllGlobals` / `freshImport` helper). The e2e workspace uses `bunfig.toml` `root = "./src"` so its tests stay isolated from the unit workspace.
169+
- Tests colocated: `src/plugin/foo.test.ts` next to `src/plugin/foo.ts`. The e2e workspace uses `*.e2e.test.ts` so the root `bun run test` and `bun run test:e2e` selectors can target them precisely.
170+
- Use `describe`/`it`/`expect` from `bun:test` — the standard API.
171+
- Mock with `mock()`, `spyOn()`, and the `jest` namespace exported from `bun:test` (`jest.fn`, `jest.spyOn`, `jest.setSystemTime`, etc.). The `test/setup.ts` preload patches `jest.setSystemTime` / `jest.useRealTimers` so they also spy on `Date.now()` (Bun's `bun:test` clock only fakes the timer queue, not the wall clock).
138172

139173
## Documentation
140174

141175
- [README.md](README.md) — Installation & usage
142176
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) — Detailed architecture guide
143177
- [docs/ANTIGRAVITY_API_SPEC.md](docs/ANTIGRAVITY_API_SPEC.md) — API reference
144178
- [CHANGELOG.md](CHANGELOG.md) — Version history
179+
- [ARCHITECTURE.md](ARCHITECTURE.md) and [STRUCTURE.md](STRUCTURE.md) — repo-level architecture and file-system map
180+
- [biome.json](biome.json) — formatter + linter config
181+
- [lefthook.yml](lefthook.yml) — pre-commit Biome hook
182+
- [mise.toml](mise.toml) — pinned `bun` + `node` versions

0 commit comments

Comments
 (0)