Add macOS OpenCode Support

OpenCode·deepseek-v4.1-flash·kernelKain·16h ago·1hr 2min·6 Checkpoints·87 file changes·+2552/-232·1.1M tokens

Work directly in:

/home/kernel-kain/Documents/Github/unfinished-business

Execution rules:

  1. Work only on the main branch.
  2. Begin with:
    • git status
    • git switch main
    • git pull --ff-only origin main
  3. Preserve all unrelated changes, untracked files, and existing stashes. Do not apply, delete, or commit .backboard/, .unfinished-business/, .env files, credentials, or the existing stash unless this phase explicitly requires it.
  4. Read the relevant source, tests, AGENTS.md files, and documentation before editing.
  5. Implement only the phase described below. Do not begin the next phase.
  6. Maintain backward compatibility with existing saved projects through explicit migrations.
  7. Do not expose provider secrets, prompts containing secrets, or private model output in logs, telemetry, screenshots, or error messages.
  8. Add or update tests for every behavior changed.
  9. After implementation, update the relevant project documentation, including:
    • README.md when user-facing behavior changes
    • docs/ARCHITECTURE.md
    • docs/DECISIONS.md
    • docs/IMPLEMENTATION_PLAN.md
    • docs/EVIDENCE.md
    • docs/RELEASE_NOTES.md
    • any phase-specific setup or integration documentation
  10. Mark the phase complete in the implementation plan only after its acceptance criteria pass.
  11. Run all relevant verification. At minimum:
  • npm run typecheck
  • npm test
  • npm run build Run visual, security, budget, contract, migration, or integration tests when affected.
  1. Review the final git diff for accidental files, secrets, debugging output, and unrelated changes.
  2. Commit with the commit message specified by this phase.
  3. Push the commit to origin/main. Never force-push.
  4. If the push is rejected because origin/main advanced, fetch and rebase safely, resolve only scoped conflicts, rerun verification, and push normally.
  5. Finish with:
  • implementation summary
  • changed files
  • documentation updated
  • tests and results
  • known limitations
  • commit hash
  • push result

Do not stop for ordinary implementation decisions. Stop only if there is a destructive conflict, missing required credential, irreconcilable remote conflict, or a decision that would materially change the product’s intended behavior.; I will send the phase prompt just after this so do not look for it

16h ago·0.0s

Baseline is clean and up to date:

  • Branch: main, tracking origin/main, up to date
  • Working tree: no modified or staged files; only untracked .backboard/, which I'll leave untouched
  • Stashes preserved (I won't touch them)
  • HEAD: ddf632a feat(demo): unify the project revival story

Send the phase prompt and I'll read the relevant source, tests, AGENTS.md files, and docs before implementing.

Implement Phase 7: support macOS alongside Linux.

Objectives:

  • Remove Linux-only OpenCode assumptions.
  • Support Apple Silicon and Intel macOS.
  • Keep Linux deployment working.

Implementation requirements:

  1. Inspect current OpenCode CLI/client compatibility before changing package versions.
  2. Replace the Linux-only runtime dependency with either:
    • the official cross-platform OpenCode CLI package; or
    • a well-tested platform-aware resolver.
  3. Prefer a valid globally installed opencode executable when available.
  4. Keep CLI and client versions compatible and pinned through the lockfile.
  5. Isolate any Render-specific Linux binary behavior from local development.
  6. Replace hardcoded Linux executable paths.
  7. Replace hardcoded /tmp and browser paths with platform-aware resolution.
  8. Support:
    • linux x64;
    • macOS Apple Silicon;
    • macOS Intel.
  9. Update setup UI and docs with npm and Homebrew installation paths.
  10. Add clear diagnostics for:
    • executable missing;
    • unsupported architecture;
    • incompatible CLI version;
    • permission problem;
    • server failed to start.
  11. Add CI jobs for Linux and macOS covering:
    • dependency installation;
    • CLI resolution;
    • typecheck;
    • tests;
    • build;
    • workspace path safety;
    • OpenCode smoke test where practical.
  12. Do not claim a platform is supported unless automated or recorded manual evidence exists.

Acceptance criteria:

  • Linux behavior remains operational.
  • No user-facing setup command contains a Linux-only package path.
  • macOS resolves an appropriate OpenCode executable.
  • Workspace security handles /Users, /Volumes, and resolved temporary paths safely.
  • Setup documentation clearly distinguishes tested and untested configurations.

Commit message:

feat(platform): add macOS OpenCode support

16h ago·0.0s

Implementation summary

Platform Phase 7 is implemented and verified:

  • Replaced @opencode/cli-linux-x64-baseline with the official cross-platform @opencode/cli@2.0.32, still locked with @opencode/client@2.0.32.
  • Added a single platform-aware resolver:
    1. explicit UB_OPENCODE_EXECUTABLE
    2. compatible global opencode on PATH
    3. lockfile-installed @opencode/cli binary
  • Supported platforms are limited to Linux x64, macOS Apple Silicon, and macOS Intel. Unsupported hosts fail before probing with OPENCODE_PLATFORM_UNSUPPORTED.
  • Added diagnostics for missing CLI, permission failures, incompatible/untested versions, unsupported architecture, and server start failures.
  • Updated the Render supervisor to use the shared resolver and environment-derived XDG paths, removing the hardcoded Linux binary path.
  • Replaced Playwright’s /tmp path with os.tmpdir() and added standard macOS browser locations.
  • Hardened workspace security for /Users, /Volumes, /System, /private, /private/tmp, /private/var/tmp, /private/var/folders, and resolved temporary roots.
  • Added npm run diagnose:platform and npm run smoke:opencode.
  • Added CI for ubuntu-latest, macos-15, and macos-15-intel.
  • Fixed CI-discovered cross-platform path/timing races in terminal run handling.

Changed files

Core runtime:

  • src/server/opencode/executable.ts — new resolver and diagnostics
  • src/server/render-start.ts — shared resolver, Render isolation
  • src/server/security/workspace.ts — macOS/resolved-temp root safety
  • src/server/opencode/connection.ts — platform diagnostic repair text
  • src/server/experience/service.ts — deterministic terminal cancellation/retry behavior

Scripts and configuration:

  • scripts/opencode-platform-diagnostic.ts
  • scripts/opencode-smoke.ts
  • scripts/preflight.mjs
  • package.json, package-lock.json
  • playwright.config.ts
  • .github/workflows/sentry-release.yml
  • .env.example
  • render.demo.yaml

UI:

  • src/web/setup.ts
  • src/web/landing/LandingPage.tsx

Tests:

  • tests/platform.test.ts — new platform/resolver/diagnostic/CI contract coverage
  • tests/security.test.ts
  • tests/web.test.ts
  • tests/connection.test.ts
  • tests/observable-runs.test.ts
  • tests/oracle-discovery.test.ts
  • tests/fixtures/fake-opencode-server.mjs

Documentation updated

  • README.md
  • docs/ARCHITECTURE.md
  • docs/DECISIONS.md — Platform Phase 7 decisions P7-01 through P7-08
  • docs/IMPLEMENTATION_PLAN.md
  • docs/EVIDENCE.md
  • docs/RELEASE_NOTES.md
  • docs/CHANGELOG.md
  • docs/LOCAL_SETUP.md
  • docs/OPENCODE_INTEGRATION.md
  • docs/HOSTED_DEPLOYMENT.md
  • docs/OPERATIONS_AND_RECOVERY.md
  • docs/PRODUCT_BRIEF.md
  • docs/TOOL_CATALOG.md
  • docs/UX_AND_VISUAL_SYSTEM.md
  • docs/DEMO_AND_SUBMISSION.md

Tests and results

Local Linux verification:

  • npm run typecheck — PASS
  • npm test — 200 passed, 0 failed
  • npm run test:platform — PASS, 25 tests
  • npm run build — PASS
  • npm run budget — PASS (initial JS 201.5 KiB, all JS 280.1 KiB, CSS 17.0 KiB, hero 581.2 KiB)
  • npm run test:visual — PASS, 20 Playwright tests
  • npm run diagnose:platform — PASS, linux-x64, version 2.0.32
  • npm run smoke:opencode — PASS, server /api/info reports 2.0.32
  • node scripts/preflight.mjs — PASS for required checks
  • npm audit --omit=dev --audit-level=high — PASS; six pre-existing moderate advisories remain
  • Render supervisor smoke — PASS, health endpoint returned ok

CI:

  • Run 41252770576 — PASS for linux-x64, darwin-arm64, darwin-x64
  • Run 41253037115 — final docs commit, PASS for all three platforms

Known limitations

  • macOS evidence is automated CI evidence; no separate manual macOS session is recorded.
  • Homebrew installs the current tap version, not necessarily 2.0.32; the resolver warns when the patch is untested.
  • Windows, Linux ARM64, and 32-bit hosts are unsupported and explicitly rejected.
  • The official @opencode/cli package may install multiple compatible Linux x64 variants selected by its postinstall.
  • No live provider inference was performed in this phase.
  • No schema migration was required; schema v7 and saved projects are unchanged.
  • Render deployment remains an external, separately authorized action.
  • GitHub Actions reports a Node 20 deprecation warning for actions/checkout/setup-node/upload-artifact; it does not fail the jobs.

Commit hashes

  • Phase commit: 1835049 — feat(platform): add macOS OpenCode support
  • CI stabilization: 3ae73f3 — fix(platform): stabilize macOS and CI verification
  • Runtime race stabilization: 2dd9acb — fix(runtime): stabilize terminal run races across platforms
  • Evidence/docs: 6641d71 — docs(platform): record the green macOS CI matrix

Final HEAD: 6641d71

Push result

Pushed normally to origin/main:

No force-push. Final worktree contains only the pre-existing untracked .backboard/, which was preserved untouched.

Implement Phase 8: perform final quality, accessibility, security, and release hardening.

Objectives:

  • Verify the complete upgraded workflow.
  • Resolve remaining visual and accessibility problems.
  • Produce honest release evidence and documentation.

Implementation requirements:

  1. Test the complete user journey:
    • project source selection;
    • Oracle questions;
    • proposal approval;
    • section drafting;
    • revision preview;
    • approvals;
    • Maker scope;
    • live progress;
    • timeout recovery;
    • Witness evidence.
  2. Add responsive coverage for at least:
    • 390px
    • 768px
    • 1440px
  3. Audit:
    • keyboard navigation;
    • focus order;
    • visible focus;
    • screen-reader announcements;
    • reduced motion;
    • WCAG AA contrast;
    • zoom and text reflow;
    • long model names;
    • long generated sections;
    • empty, loading, error, and offline states.
  4. Add security tests for:
    • secret redaction;
    • malicious Markdown;
    • repository path traversal;
    • unsafe remote URLs;
    • duplicate operations;
    • stale revisions;
    • replayed mutation requests.
  5. Upgrade vulnerable dependencies carefully, including Sentry packages, without combining unrelated major migrations.
  6. Run the complete project verification suite.
  7. Refresh visual snapshots only after manual inspection.
  8. Update:
    • architecture;
    • setup;
    • OpenCode integration;
    • security model;
    • recovery behavior;
    • supported platforms;
    • limitations;
    • release notes;
    • implementation-plan completion state.
  9. Produce an evidence matrix mapping major product claims to tests, screenshots, or native session evidence.
  10. Prepare hackathon/release copy and assets in the repository, but do not publish an external submission without explicit authorization.

Acceptance criteria:

  • All automated verification passes.
  • No high-severity accessibility or security issue remains open.
  • Documentation matches actual behavior.
  • Every important product claim has evidence or is explicitly labelled as a limitation.
  • The repository is clean after commit and push.

Commit message:

chore(release): harden and document the upgraded workshop

15h ago·14.9s

Implementation summary

Phase 8 hardening is complete and pushed.

  • Added a deterministic complete workshop journey test: source selection → Oracle questions → proposal → product approval → revision preview/supersede/accept → all eight section approvals → Maker scope → live progress → timeout → reconciliation → Node evidence → Witness drafts → export.
  • Added 768px responsive snapshots for landing, workshop, demo, and onboarding while keeping 390px and 1440px coverage.
  • Fixed the tablet header so the brand, engine state, and model controls remain readable.
  • Made revision review a keyboard-operable ARIA tab panel with Arrow/Home/End support, roving tabindex, aria-controls, and a labelled panel.
  • Added polite live progress announcements to Activity & results.
  • Added deliberate loading and offline states; a lost API connection now shows an actionable connection-loss alert and reload action instead of raw fetch text.
  • Added coverage for 200% zoom, long model identities, long unbroken Markdown, focus return, extended contrast tokens, reduced motion, loading, offline, empty, permission, and provider-error states.
  • Extended security coverage for local-source traversal/broad roots/system symlinks, unsafe remote URL schemes/ports/credentials/query/fragment/traversal, failed imports, stale revisions, duplicate approvals, and replayed memory mutations.
  • Kept Sentry at 11.10.0 and overrode only the vulnerable transitive glob/minimatch pair. Both npm audit commands now report 0 vulnerabilities.
  • Added a security model, hackathon/release copy, and an asset manifest. Nothing was published or submitted externally.

Changed files

Code and tests:

  • tests/journey.test.ts
  • tests/visual/hardening.spec.ts
  • tests/visual/landing.spec.ts
  • tests/visual/snapshots/landing-tablet.png
  • tests/visual/snapshots/workshop-tablet.png
  • tests/visual/snapshots/demo-tablet.png
  • tests/visual/snapshots/onboarding-tablet.png
  • tests/visual/snapshots/workshop-offline.png
  • tests/http-workflow.test.ts
  • tests/oracle-discovery.test.ts
  • tests/security.test.ts
  • tests/web.test.ts
  • src/web/components/RevisionReview.tsx
  • src/web/components/RunInspector.tsx
  • src/web/workshop/WorkshopPage.tsx
  • src/web/styles.css
  • src/server/security/workspace.ts
  • package.json, package-lock.json

Documentation and release assets:

  • docs/SECURITY_MODEL.md
  • docs/release/HACKATHON_COPY.md
  • README.md
  • docs/ARCHITECTURE.md
  • docs/DECISIONS.md
  • docs/IMPLEMENTATION_PLAN.md
  • docs/EVIDENCE.md
  • docs/RELEASE_NOTES.md
  • docs/CHANGELOG.md
  • docs/LOCAL_SETUP.md
  • docs/OPENCODE_INTEGRATION.md
  • docs/OPERATIONS_AND_RECOVERY.md
  • docs/DEMO_AND_SUBMISSION.md
  • docs/TOOL_CATALOG.md
  • docs/UX_AND_VISUAL_SYSTEM.md

Documentation updated

  • Architecture now documents the accessibility/responsive/resilience verification layer.
  • Security model maps trust boundaries and threats to tests.
  • Setup and integration docs include the current verification gate.
  • Recovery docs describe deterministic terminal cancellation/retry behavior.
  • Evidence includes the Phase 8 matrix, commands, screenshots, CI run, and explicit limitations.
  • Implementation plan marks Phase 8 complete.
  • Release notes, changelog, tool catalog, UX system, product demo/submission docs, and platforms/limitations were refreshed.
  • Hackathon pitch, short/long description, demo script, claim checklist, limits, and asset manifest are prepared in docs/release/HACKATHON_COPY.md; no external submission was made.

Tests and results

Local Linux verification:

  • npm run typecheck — PASS
  • npm test — 207 passed, 0 failed
  • npm run build — PASS
  • npm run budget — PASS: initial JS 201.5 KiB, all JS 280.4 KiB, CSS 17.0 KiB, hero 581.2 KiB
  • npm run test:visual — 26 passed
  • npm run test:platform — PASS, 25 tests
  • npm run diagnose:platform — PASS, linux-x64, OpenCode 2.0.32
  • npm run smoke:opencode — PASS, server /api/info reports 2.0.32
  • node scripts/preflight.mjs — PASS for required checks
  • npm audit --omit=dev --audit-level=high — PASS, 0 vulnerabilities
  • npm audit — PASS, 0 vulnerabilities
  • npm ci — PASS against the updated lockfile

CI:

  • Run 41255172209 — PASS for linux-x64, darwin-arm64, darwin-x64
  • Run 41255384016 — final docs commit, PASS for all three platforms

Known limitations

  • The complete journey test uses a deterministic guide and makes no live provider call.
  • macOS execution is verified by CI; no separate manual macOS session is recorded.
  • Automated Chromium checks cover the stated widths and states but do not replace a full manual screen-reader or cross-browser audit.
  • The Playwright suite is run locally; CI covers install, CLI resolution, typecheck, tests, build, workspace safety, and OpenCode smoke.
  • Sentry live release/source-map/trace verification still requires authorized credentials and a deployment.
  • No public hosted URL, recorded video, published article, or external submission is asserted.
  • The Node check is a bounded child process, not an OS sandbox; the app remains single-project and not multi-tenant.
  • The glob/minimatch override should be re-checked when Sentry updates its bundler dependencies.

Commit hashes

  • Phase commit: 0ee2ac2 — chore(release): harden and document the upgraded workshop
  • Evidence follow-up: 8f4637d — docs(release): record the Phase 8 CI evidence

Final HEAD: 8f4637d

Push result

Pushed normally to origin/main:

No force-push. Final worktree contains only the pre-existing untracked .backboard/, preserved untouched.

run the project so i can test

15h ago·0.1s
15h ago·0.1s

The project is running.

I connected the app to OpenCode successfully:

  • State: connected
  • OpenCode server: 2.0.32
  • Compatible: yes
  • Models discovered: 465
  • Diagnostics: none

Port 4200 is already occupied by litellm, so this project is using UB_PORT=4210 from .env; Vite proxies /api there.

Logs:

  • OpenCode: /tmp/opencode/ub-run/opencode.log
  • Vite: /tmp/opencode/ub-run/vite.log

The OpenCode password was not printed. Saved state remains under .unfinished-business/.

If the API needs restarting later, run npm run dev; if OpenCode needs restarting, use the project’s npx --no-install opencode serve --hostname 127.0.0.1 --port 4096 with the password from .env.