-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathjustfile
More file actions
462 lines (374 loc) · 17.8 KB
/
justfile
File metadata and controls
462 lines (374 loc) · 17.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
# justfile - Root task orchestration for opencode-cloud
# Default recipe
default: list
# List available recipes
list:
@just --list
# Check required and optional local development tooling.
check-dev-prereqs:
./scripts/check-dev-prereqs.sh
# Setup development environment (run once after cloning)
setup: check-dev-prereqs
git config core.hooksPath .githooks
git -c url."https://github.com/".insteadOf=git@github.com: submodule update --init --recursive packages/opencode
bun install --cwd packages/opencode --frozen-lockfile
bun install --frozen-lockfile
@echo "✓ Development environment ready!"
@echo "Next: just dev"
# Build everything
build: build-rust build-node build-opencode build-opencode-broker
# Warn if packages/opencode commit differs from Dockerfile OPENCODE_COMMIT pin.
warn-opencode-pin-drift:
@if [ ! -f packages/opencode/.git ] && [ ! -d packages/opencode/.git ]; then \
:; \
else \
dockerfile="packages/core/src/docker/Dockerfile"; \
dockerfile_pinned_commit="$(grep -oE 'OPENCODE_COMMIT=\"[^\"]+\"' "$dockerfile" | head -n1 | sed -E 's/OPENCODE_COMMIT=\"([^\"]+)\"/\1/')"; \
submodule_commit="$(git -C packages/opencode rev-parse HEAD 2>/dev/null || true)"; \
if [ -n "$dockerfile_pinned_commit" ] && [ -n "$submodule_commit" ] && [ "$dockerfile_pinned_commit" != "$submodule_commit" ]; then \
echo "Warning: Dockerfile OPENCODE_COMMIT pin ($dockerfile_pinned_commit) differs from packages/opencode ($submodule_commit)."; \
echo " Run: just update-opencode-commit"; \
fi; \
fi
# Compile and run the occ binary (arguments automatically get passed to the binary)
# Example: just run --version
run *args: warn-opencode-pin-drift
cargo run -p opencode-cloud --bin occ -- {{args}}
# Start occ with local opencode submodule and cached sandbox image rebuild.
dev: warn-opencode-pin-drift
just run start --yes --local-opencode-submodule --cached-rebuild-sandbox-image
# --- Shared check/build base targets (used by local + CI wrappers) ---
check-rust-format:
cargo fmt --all -- --check
check-rust-clippy:
cargo clippy --all-targets --all-features -- -D warnings
build-rust-workspace:
cargo build --workspace
verify-cli-version:
cargo run -p opencode-cloud -- --version
build-core-bindings:
bun run --cwd packages/core build
check-opencode-stack: lint-opencode build-opencode lint-opencode-broker
test-slow-suite: test-all-slow
# Build Rust packages
build-rust: build-rust-workspace
# --- Node CLI (Mac / local dev) ---
# Build Node CLI for Mac: compile Rust occ, copy to cli-node/bin/, then build the wrapper.
# Use this when developing or testing the npm CLI locally (resolves binary from bin/ fallback).
build-node-cli-mac:
cargo build -p opencode-cloud --bin occ
@mkdir -p packages/cli-node/bin
@cp target/debug/occ packages/cli-node/bin/occ
bun run --cwd packages/cli-node build
@echo "✓ Node CLI built for Mac (binary in packages/cli-node/bin/)"
# Run Node CLI on Mac. Pass args through (e.g. just run-node-cli-mac --version).
# Requires build-node-cli-mac first; uses bin/occ as fallback.
run-node-cli-mac *args:
node packages/cli-node/dist/index.js {{args}}
# Build Node packages (including NAPI bindings)
build-node:
bun install
bun run --cwd packages/core build
bun run --cwd packages/cli-node build
# --- opencode Submodule Checks ---
# Ensure opencode submodule is initialized in this worktree
opencode-submodule-check:
@if [ -f packages/opencode/.git ] || [ -d packages/opencode/.git ]; then \
:; \
else \
echo "Submodule packages/opencode is not initialized."; \
echo "Run: git submodule update --init --recursive"; \
exit 1; \
fi
# Sync opencode dependencies with lockfile
opencode-install-if-needed: opencode-submodule-check
bun install --cwd packages/opencode --frozen-lockfile
# Regenerate opencode OpenAPI + SDK artifacts.
# Run this whenever fork-auth/opencode routes or schemas change so generated clients stay in sync.
sync-opencode-sdk: opencode-install-if-needed
bun run --cwd packages/opencode script/generate.ts
# Run opencode guardrails that catch parity/boundary drift early.
check-opencode-guardrails: opencode-install-if-needed
bun run --cwd packages/opencode rules:parity:check
bun run --cwd packages/opencode sdk:parity:check
bun run --cwd packages/opencode fork:boundary:check
# Run opencode guardrails with safe local autofix for boundary manifest drift.
# Intended for local pre-commit paths only; CI/pre-push must stay strict.
check-opencode-guardrails-autofix: opencode-install-if-needed
bun run --cwd packages/opencode rules:parity:check
bun run --cwd packages/opencode sdk:parity:check
FORK_BOUNDARY_AUTOFIX=1 bun run --cwd packages/opencode fork:boundary:check
# Typecheck opencode workspace
# Keep scripts.typecheck defined in each fork-* package so Turbo executes its task.
lint-opencode: opencode-install-if-needed check-fork-typecheck-wiring
bun --cwd packages/opencode turbo typecheck
# Verify every fork-* package exposes scripts.typecheck for Turbo wiring
check-fork-typecheck-wiring: opencode-submodule-check
./scripts/check-fork-typecheck-wiring.sh
# Build the shared app package
build-opencode-app: opencode-install-if-needed
bun run --cwd packages/opencode/packages/app build
# Build opencode single-ui artifact using local models fixture for deterministic output
build-opencode-single-ui: opencode-install-if-needed
@tmpfile="$(mktemp)"; \
trap 'rm -f "$tmpfile"' EXIT; \
perl -pe 'chomp if eof' "{{justfile_directory()}}/packages/opencode/packages/opencode/test/tool/fixtures/models-api.json" > "$tmpfile"; \
MODELS_DEV_API_JSON="$tmpfile" bun run --cwd packages/opencode/packages/opencode build-single-ui
# Smoke-check compiled opencode binary startup.
smoke-opencode-compiled: build-opencode-single-ui
bun run --cwd packages/opencode/packages/opencode smoke:compiled
# Build opencode app and opencode binary/ui artifact
build-opencode: build-opencode-app build-opencode-single-ui smoke-opencode-compiled
# Lint opencode-broker Rust crate
lint-opencode-broker: opencode-submodule-check
cargo fmt --manifest-path packages/opencode/packages/opencode-broker/Cargo.toml --all -- --check
cargo clippy --manifest-path packages/opencode/packages/opencode-broker/Cargo.toml --all-targets -- -D warnings
# Build opencode-broker Rust crate
build-opencode-broker: opencode-submodule-check
cargo build --manifest-path packages/opencode/packages/opencode-broker/Cargo.toml
# Test opencode-broker Rust crate
test-opencode-broker: opencode-submodule-check
cargo test --manifest-path packages/opencode/packages/opencode-broker/Cargo.toml
# Run e2e tests (boots server in-process, seeds data, runs Playwright)
e2e: opencode-install-if-needed
bun run --cwd packages/opencode/packages/app test:e2e:local
# Optional app unit test gate (not part of default pre-commit)
test-opencode-ui: opencode-install-if-needed
bun run --cwd packages/opencode/packages/app test:unit
# Run opencode upstream unit tests (turbo: opencode + fork-tests + app)
# `--only` intentionally avoids Turbo dependency graph tasks (like `^build`)
# because CI build coverage for opencode already runs via lint/build targets.
test-opencode-unit: opencode-install-if-needed
bun --cwd packages/opencode turbo test --only
# Debug path: include Turbo dependency build graph (`^build`) during tests.
test-opencode-unit-with-build: opencode-install-if-needed
bun --cwd packages/opencode turbo test
# Optional submodule drift and dirty state check
check-opencode-submodule-drift:
git submodule status --recursive
git submodule foreach --recursive 'git status --short --branch'
# Ensure pinned opencode submodule commit is remotely fetchable
check-opencode-submodule-published:
./scripts/check-opencode-submodule-published.sh --from-index
# Update opencode submodule + Dockerfile OPENCODE_COMMIT pin
update-opencode-commit:
./scripts/update-opencode-commit.sh
# Format opencode-broker Rust crate
fmt-opencode-broker: opencode-submodule-check
cargo fmt --manifest-path packages/opencode/packages/opencode-broker/Cargo.toml --all
# --- Docker Sandbox Image ---
# Build Docker sandbox image with BuildKit caching (amd64 only, for local dev)
# Use DOCKER_BUILDKIT=1 for layer caching and faster rebuilds
# The image is tagged as opencode-cloud-sandbox:dev
build-docker:
@echo "Building Docker sandbox image..."
@cp packages/core/src/docker/Dockerfile Dockerfile.build
DOCKER_BUILDKIT=1 docker build \
-f Dockerfile.build \
-t opencode-cloud-sandbox:dev \
--build-arg BUILDKIT_INLINE_CACHE=1 \
.
@rm -f Dockerfile.build
@echo "✓ Docker image built: opencode-cloud-sandbox:dev"
# Build Docker sandbox image with no cache (clean rebuild)
build-docker-no-cache:
@echo "Building Docker sandbox image (no cache)..."
@cp packages/core/src/docker/Dockerfile Dockerfile.build
DOCKER_BUILDKIT=1 docker build \
-f Dockerfile.build \
-t opencode-cloud-sandbox:dev \
--no-cache \
.
@rm -f Dockerfile.build
@echo "✓ Docker image built (no cache): opencode-cloud-sandbox:dev"
# Verify Docker build stages (builds opencode-build stage only, faster than full build)
check-docker:
@echo "Checking Dockerfile syntax and build stages..."
@cp packages/core/src/docker/Dockerfile Dockerfile.build
DOCKER_BUILDKIT=1 docker build \
-f Dockerfile.build \
--target opencode-build \
-t opencode-cloud-sandbox:check \
.
@rm -f Dockerfile.build
@docker rmi opencode-cloud-sandbox:check 2>/dev/null || true
@echo "✓ Dockerfile check passed"
# Run all tests (fast)
test-all-fast: test-rust-fast test-node test-opencode-fork-tests test-opencode-broker test-opencode-unit
# Run all tests (slow, includes doc-tests)
test-all-slow: test-rust test-node test-opencode-fork-tests test-opencode-broker test-opencode-unit
# Run all tests (fast)
test: test-all-fast
# Run Rust tests
test-rust:
cargo test --workspace
# Run Rust tests without doc-tests (fast)
test-rust-fast:
cargo test --workspace --tests
# Run Node tests
test-node:
cargo build -p opencode-cloud
bun run --cwd packages/cli-node build
bun run --cwd packages/cli-node test
# Run opencode fork tests (Bun workspace under submodule)
test-opencode-fork-tests: opencode-install-if-needed
OPENCODE_CONFIG_CONTENT='{"auth":{"enabled":false}}' bun test --cwd packages/opencode/packages/fork-tests
# Run Rust doc-tests (slow)
test-doc-slow:
cargo test --workspace --doc
# Lint everything
lint: lint-rust lint-node lint-shell lint-workflows check-readme-badges lint-opencode lint-opencode-broker
# Lint Rust code
lint-rust: check-rust-format check-rust-clippy
# Lint Rust code in Linux container (catches platform-gated code issues)
# Use this before pushing to catch CI failures on Linux
# Requires: Docker running
lint-rust-linux:
docker run --rm -v "{{justfile_directory()}}":/workspace -w /workspace rust:1.89 \
cargo clippy --all-targets --all-features -- -D warnings
# Lint Rust code for all platforms (local + Linux via Docker)
# Use this before pushing to catch CI failures early
lint-rust-cross: lint-rust lint-rust-linux
# Lint Node code
lint-node:
bun --workspaces --if-present run lint
# Lint shell scripts
lint-shell:
shellcheck scripts/*.sh
# Lint GitHub Actions workflows (root repo only; shellcheck disabled — covered by lint-shell)
lint-workflows:
actionlint -shellcheck= -pyflakes= .github/workflows/*.yml
# --- CI wrappers (CI install remains stricter than local by design) ---
ci-node-install:
bun install --frozen-lockfile --ignore-scripts
ci-node-install-cli-only:
bun install --filter opencode-cloud --frozen-lockfile --ignore-scripts
# Keep browser install colocated with `ci-e2e` execution and use
# PLAYWRIGHT_BROWSERS_PATH=0 by default to pin browser binaries to Bun's
# installed playwright-core version.
ci-e2e *args:
bun install --cwd packages/opencode --frozen-lockfile --ignore-scripts
@set -- {{args}}; \
if [ "${1:-}" = "--" ]; then shift; fi; \
models_path="${OPENCODE_MODELS_PATH:-{{justfile_directory()}}/packages/opencode/packages/opencode/test/tool/fixtures/models-api.json}"; \
if [ ! -f "$models_path" ]; then \
echo "Error: OPENCODE_MODELS_PATH file does not exist: $models_path"; \
exit 1; \
fi; \
playwright_browsers_path="${PLAYWRIGHT_BROWSERS_PATH:-0}"; \
if [ "${CI:-}" = "true" ] || [ "${CI:-}" = "1" ]; then \
PLAYWRIGHT_BROWSERS_PATH="$playwright_browsers_path" ./packages/opencode/packages/app/node_modules/.bin/playwright install --with-deps chromium; \
else \
PLAYWRIGHT_BROWSERS_PATH="$playwright_browsers_path" ./packages/opencode/packages/app/node_modules/.bin/playwright install chromium; \
fi; \
CI="${CI:-true}" OPENCODE_DISABLE_MODELS_FETCH="${OPENCODE_DISABLE_MODELS_FETCH:-true}" OPENCODE_MODELS_PATH="$models_path" PLAYWRIGHT_BROWSERS_PATH="$playwright_browsers_path" bun run --cwd packages/opencode/packages/app test:e2e:local -- "$@"
ci-lint: lint-rust check-opencode-guardrails check-opencode-stack
ci-build: build-rust build-core-bindings
ci-test: test-slow-suite
ci-verify: verify-cli-version
ci-checks: ci-lint ci-build ci-test ci-verify
# Check for Dockerfile tool version updates
check-updates:
./scripts/check-dockerfile-updates.sh
# Sync generated README badge blocks from fork-ui badge catalog
sync-readme-badges: opencode-submodule-check
bun scripts/sync-readme-badges.ts
# Validate generated README badge blocks are up to date
check-readme-badges: opencode-submodule-check
bun scripts/sync-readme-badges.ts --check
# --- DigitalOcean Marketplace ---
# Validate the DigitalOcean Marketplace Packer template
do-marketplace-validate:
packer init infra/digitalocean/packer/opencode-marketplace.pkr.hcl
packer fmt -check infra/digitalocean/packer/opencode-marketplace.pkr.hcl
packer validate -var-file=infra/digitalocean/packer/variables.pkr.hcl \
infra/digitalocean/packer/opencode-marketplace.pkr.hcl
# Build the DigitalOcean Marketplace snapshot
do-marketplace-build:
packer init infra/digitalocean/packer/opencode-marketplace.pkr.hcl
packer build -var-file=infra/digitalocean/packer/variables.pkr.hcl \
infra/digitalocean/packer/opencode-marketplace.pkr.hcl
# Pre-commit checks with conditional Docker stage build for Docker-risk changes.
# This keeps routine commits fast while still catching Docker context regressions.
pre-commit: check-opencode-submodule-published sync-opencode-sdk check-opencode-guardrails-autofix fmt lint build test-all-fast
@PLAYWRIGHT_WORKERS="${PLAYWRIGHT_WORKERS:-1}" \
OPENCODE_E2E_CLEAN_SESSION_STATE="${OPENCODE_E2E_CLEAN_SESSION_STATE:-0}" \
just e2e
@if ./scripts/should-run-docker-check.sh; then \
echo "Running Docker stage check because Docker-risk files changed..."; \
just check-docker; \
else \
echo "Skipping Docker stage check (no Docker-risk file changes)."; \
fi
# Pre-commit checks including Docker build (requires Docker)
pre-commit-full: check-opencode-submodule-published sync-opencode-sdk check-opencode-guardrails-autofix fmt lint build test-all-fast build-docker
@PLAYWRIGHT_WORKERS="${PLAYWRIGHT_WORKERS:-1}" \
OPENCODE_E2E_CLEAN_SESSION_STATE="${OPENCODE_E2E_CLEAN_SESSION_STATE:-0}" \
just e2e
@echo "✓ Full pre-commit checks passed (including Docker build)"
# Format everything
fmt: fmt-opencode-broker
cargo fmt --all
bun --workspaces --if-present run format
# Clean all build artifacts
clean:
cargo clean
bun --workspaces --if-present run clean
# Release build
release:
cargo build --workspace --release
bun install
bun run --cwd packages/core build
# Publish to crates.io (core first, then cli)
publish-crates: lint test-all-slow
@echo "Publishing opencode-cloud-core to crates.io..."
cargo publish -p opencode-cloud-core
@echo ""
@echo "Waiting 5s for crates.io to index..."
@sleep 5
@echo ""
@echo "Publishing opencode-cloud to crates.io..."
cargo publish -p opencode-cloud
@echo ""
@echo "✓ crates.io publish complete!"
# Publish to npm (core first, then cli)
publish-npm: lint test-all-slow build-node
@echo "Publishing @opencode-cloud/core to npm..."
bun publish --cwd packages/core --access public
@echo ""
@echo "Waiting 5s for npm to index..."
@sleep 5
@echo ""
@echo "Publishing opencode-cloud to npm..."
bun publish --cwd packages/cli-node --access public
@echo ""
@echo "✓ npm publish complete!"
# Publish to both crates.io and npm
publish-all: publish-crates publish-npm
@echo ""
@echo "✓ All packages published!"
# Dry-run for both crates.io and npm
publish-all-dry-run: publish-crates-dry-run publish-npm-dry-run
@echo ""
@echo "✓ All packages ready (dry-run)!"
# Dry-run for crates.io
publish-crates-dry-run:
@echo "Dry-run: opencode-cloud-core (crates.io)..."
cargo publish -p opencode-cloud-core --dry-run
@echo "✓ opencode-cloud-core ready"
@echo ""
@echo "Dry-run: opencode-cloud (crates.io)..."
@echo "(Note: this will fail if core is not yet on crates.io)"
@echo "(Note: this fails when updating the dependency version of the opencode-cloud-core package in the root Cargo.toml)"
@echo "(Note: this is expected to fail, so commenting it out for now)"
#cargo publish -p opencode-cloud --dry-run
@echo "✓ opencode-cloud ready"
# Dry-run for npm
publish-npm-dry-run: build-node
@echo "Dry-run: @opencode-cloud/core (npm)..."
bun publish --cwd packages/core --access public --dry-run
@echo "✓ @opencode-cloud/core ready"
@echo ""
@echo "Dry-run: opencode-cloud (npm)..."
bun publish --cwd packages/cli-node --access public --dry-run
@echo "✓ opencode-cloud ready"