Skip to content
Merged
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
15 changes: 13 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,19 @@ jobs:
with:
targets: ${{ matrix.target }}

- name: Install protoc
run: sudo apt-get update && sudo apt-get install -y protobuf-compiler
- name: Install system dependencies
run: |
sudo apt-get update && sudo apt-get install -y protobuf-compiler
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash -
sudo apt-get install -y nodejs

- name: Install bun
uses: oven-sh/setup-bun@v2

- name: Build OpenCode embed
run: |
cd interface && bun install --frozen-lockfile && cd ..
./scripts/build-opencode-embed.sh

- name: Determine version tag
id: version
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
# Interface
interface/node_modules/
interface/dist/
interface/public/opencode-embed/
.opencode-build-cache/

.idea
list/
Expand Down
21 changes: 18 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
RUN curl -fsSL https://bun.sh/install | bash
ENV PATH="/root/.bun/bin:${PATH}"

# Node 22+ is required for the OpenCode embed Vite build.
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /build

# 1. Fetch and cache Rust dependencies.
Expand All @@ -26,14 +31,24 @@ RUN mkdir src && echo "fn main() {}" > src/main.rs && touch src/lib.rs \
&& cargo build --release \
&& rm -rf src

# 2. Build the frontend.
# 2. Install frontend dependencies.
COPY interface/package.json interface/
RUN cd interface && bun install

# 3. Build the OpenCode embed bundle (live coding UI in Workers tab).
# Must run before the frontend build so the embed assets in
# interface/public/opencode-embed/ are included in the Vite output.
COPY scripts/build-opencode-embed.sh scripts/
COPY interface/opencode-embed-src/ interface/opencode-embed-src/
RUN ./scripts/build-opencode-embed.sh

# 4. Build the frontend (includes OpenCode embed assets from step 3).
COPY interface/ interface/
RUN cd interface && bun run build

# 3. Copy source and compile the real binary.
# build.rs runs the frontend build (already done above, node_modules present).
# 5. Copy source and compile the real binary.
# build.rs is skipped (SPACEBOT_SKIP_FRONTEND_BUILD=1) since the
# frontend is already built above with the OpenCode embed included.
# prompts/ is needed for include_str! in src/prompts/text.rs.
# migrations/ is needed for sqlx::migrate! in src/db.rs.
# docs/ is needed for rust-embed in src/self_awareness.rs.
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,11 @@ Read the full vision in the [roadmap](docs/content/docs/(deployment)/roadmap.mdx
```bash
git clone https://github.com/spacedriveapp/spacebot
cd spacebot

# Optional: build the OpenCode embedded UI (requires Node 22+ and bun)
# Without this, OpenCode workers still work — the Workers tab shows a transcript view instead.
# ./scripts/build-opencode-embed.sh

cargo build --release
```

Expand Down
36 changes: 36 additions & 0 deletions docs/content/docs/(features)/opencode.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,39 @@ webfetch = "allow"
```

The OpenCode server is a child process managed by Spacebot. It persists across worker invocations for the same directory. Multiple workers targeting the same directory share the same server (different sessions).

## Embedded Web UI

When you view an OpenCode worker in the Workers tab, Spacebot can show the full interactive OpenCode interface inline — the same editor, terminal, and conversation view you'd get from OpenCode's standalone app.

The embedded UI uses a Shadow DOM for CSS isolation and a memory router to avoid conflicts with Spacebot's own routing. All API and SSE traffic is proxied through Spacebot's reverse proxy at `/api/opencode/{port}/`, keeping everything same-origin.

### Building the embed

The embed bundle is not included in the repository. Build it with:

```bash
# Requires Node 22+ and bun
./scripts/build-opencode-embed.sh
# or: just build-opencode-embed
```

This clones OpenCode at a pinned upstream commit, copies the embed entry points from `interface/opencode-embed-src/`, builds with Vite, and outputs to `interface/public/opencode-embed/`. The output is ~46MB (mostly shiki grammar chunks for syntax highlighting) and is gitignored.

If you use [fnm](https://github.com/Schniz/fnm) for Node version management:

```bash
eval "$(fnm env)" && fnm use v24.14.0 && ./scripts/build-opencode-embed.sh
```

### Without the embed

Everything works without building the embed. OpenCode workers still run normally — the Workers tab falls back to the transcript view, which shows tool calls, status updates, and results. The only difference is you don't get the live interactive OpenCode UI.

### Updating the pinned commit

The OpenCode commit is pinned in `scripts/build-opencode-embed.sh` as `OPENCODE_COMMIT`. To update:

1. Change the commit hash in the script
2. Re-run `./scripts/build-opencode-embed.sh`
3. Test the embedded UI in the Workers tab
6 changes: 6 additions & 0 deletions docs/content/docs/(getting-started)/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,18 @@ cd spacebot
# Optional: build the web UI (React + Vite, embedded into the binary)
cd interface && bun install && cd ..

# Optional: build the OpenCode embed (live coding UI in the Workers tab)
# Requires Node 22+ (use fnm: fnm install v24.14.0 && fnm use v24.14.0)
./scripts/build-opencode-embed.sh

# Install the binary
cargo install --path .
```

The `build.rs` script automatically runs `bun run build` during compilation if `interface/node_modules` exists. Without it, the binary still works — you just get an empty UI on the web dashboard.

The OpenCode embed step (`build-opencode-embed.sh`) clones OpenCode at a pinned commit, builds the embeddable SPA, and places it in `interface/public/opencode-embed/`. This is optional — without it, OpenCode workers still function normally, but the Workers tab will show a transcript view instead of the live interactive OpenCode UI.

## Configure

Spacebot needs at least one LLM provider key. You can either set an environment variable or create a config file.
Expand Down
16 changes: 16 additions & 0 deletions interface/opencode-embed-src/embed-entry.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* SPA entry point for the embeddable OpenCode build.
*
* Unlike entry.tsx, this does NOT auto-render. Instead it attaches
* `mountOpenCode` to the window object so the host app can call it
* after loading this script.
*
* This file is used as the entry in index-embed.html for a normal
* Vite SPA build (not library mode), so we get full code splitting.
*/

import { mountOpenCode } from "./embed"
export type { MountOpenCodeConfig, MountOpenCodeHandle } from "./embed"

// Attach to window so the host app can call it after script load.
;(window as any).__opencode_embed__ = { mountOpenCode }
Loading
Loading