Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
ce7594b
Add OpenClaw runtime information
guilhermexp Mar 29, 2026
4da6a3d
chore(desktop): align release pipeline and embedded runtime
guilhermexp Mar 29, 2026
83ce54f
chore(desktop): update embedded openclaw runtime
guilhermexp Mar 30, 2026
f4c0735
feat: Copy capability source dirs to bundled output
guilhermexp Mar 30, 2026
1737509
feat(desktop): add inline audio player for TTS tool results
guilhermexp Mar 31, 2026
40aafff
feat(desktop): add artifact preview panel with split view for file re…
guilhermexp Mar 31, 2026
fbb41bb
Refactor UI colors to new palette
guilhermexp Mar 31, 2026
1dee6bb
Update client.ts
guilhermexp Mar 31, 2026
99e5f4c
Refactor analytics to no-op in main/renderer
guilhermexp Mar 31, 2026
400745a
Refactor: Reclaim default port in dev mode
guilhermexp Mar 31, 2026
12468ba
feat: Add support for audio attachments and inline media playback
guilhermexp Apr 1, 2026
1af6855
Refactor voice message recording button behavior
guilhermexp Apr 1, 2026
86d3f70
Fix: Prevent premature cancellation of voice recording
guilhermexp Apr 1, 2026
309faa1
feat: Add auto collapse to ActionLog
guilhermexp Apr 1, 2026
37d896a
fix(ci): add contents write permission to sync-openclaw workflow
guilhermexp Apr 1, 2026
f5d23ed
fix(lint): resolve 9 no-unused-vars errors for CI
guilhermexp Apr 1, 2026
ac18056
style: format all files with prettier
guilhermexp Apr 1, 2026
0e6058e
fix(ci): skip esbuild in verify job to prevent OOM crash
guilhermexp Apr 1, 2026
f1faf50
fix(ci): also skip bundle verify in verify job
guilhermexp Apr 1, 2026
69c3953
fix(ci): pass GITHUB_TOKEN to runtime fetch steps
guilhermexp Apr 1, 2026
29080d3
fix(ci): simplify verify job to lint+types+build only
guilhermexp Apr 1, 2026
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
107 changes: 77 additions & 30 deletions .github/workflows/build-desktop.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build Desktop App
name: Desktop CI

on:
push:
Expand All @@ -9,7 +9,8 @@ on:
workflow_dispatch:

jobs:
build-mac:
verify:
if: github.event_name != 'push' || !startsWith(github.ref, 'refs/tags/v')
runs-on: macos-latest
Comment on lines +12 to 14

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

The new Windows installer path is only tested on release tags.

Line 14 still hardcodes verify to macos-latest, and Line 54 only runs --mac zip, while Line 77 introduces the Windows NSIS target only in the tag-gated release matrix. That makes a v* tag the first time the Windows packaging path runs, so NSIS/path/signing regressions can land on main unnoticed and fail only during release.

💡 Suggested smoke-build matrix for verify
   verify:
     if: github.event_name != 'push' || !startsWith(github.ref, 'refs/tags/v')
-    runs-on: macos-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        include:
+          - os: macos-latest
+            smoke_args: --mac zip
+            artifact_name: openspace-smoke-mac
+          - os: windows-latest
+            smoke_args: --win nsis
+            artifact_name: openspace-smoke-win
+    runs-on: ${{ matrix.os }}
@@
       - name: Package smoke build
         env:
           CSC_IDENTITY_AUTO_DISCOVERY: false
-        run: cd desktop && npx electron-builder --publish never --mac zip
+        run: cd desktop && npx electron-builder --publish never ${{ matrix.smoke_args }}
@@
       - name: Upload smoke artifacts
         uses: actions/upload-artifact@v4
         with:
-          name: openspace-smoke-mac-${{ github.sha }}
+          name: ${{ matrix.artifact_name }}-${{ github.sha }}

Also applies to: 51-55, 69-79

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/build-desktop.yml around lines 12 - 14, The verify job is
only running on macOS and only building the mac zip, while the Windows NSIS
packaging is gated to release tags; update the verify job and its build matrix
so it runs on both macos-latest and windows-latest (or add a separate verify job
for windows) and include the Windows NSIS/installer build target in the
non-tagged verify matrix (remove or replicate the NSIS target from the tag-only
release matrix) so Windows packaging, path, and signing are exercised on normal
pushes; target identifiers to change: the verify job name "verify", the
"runs-on: macos-latest" value, the build matrix entries that currently only
include "--mac zip", and the release matrix block that introduces the NSIS
target.

steps:
- uses: actions/checkout@v4
Expand All @@ -25,50 +26,96 @@ jobs:
version: 10

- name: Install OpenClaw deps
run: cd openclaw && pnpm install
run: cd openclaw && pnpm install --frozen-lockfile

- name: Build OpenClaw
run: cd openclaw && pnpm build && pnpm ui:build

- name: Install Desktop deps
run: cd desktop && npm install
run: cd desktop && npm ci

- name: Run Desktop checks
run: cd desktop && npm run check:ci

- name: Build Desktop
run: cd desktop && npm run build:all

release:
if: startsWith(github.ref, 'refs/tags/v')
strategy:
fail-fast: false
matrix:
include:
- os: macos-latest
electron_args: --mac zip
artifact_name: openspace-release-mac
- os: windows-latest
electron_args: --win nsis
artifact_name: openspace-release-win
runs-on: ${{ matrix.os }}
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- uses: actions/setup-node@v4
with:
node-version: "22"

- uses: pnpm/action-setup@v4
with:
version: 10

- name: Install OpenClaw deps
run: cd openclaw && pnpm install --frozen-lockfile

- name: Build OpenClaw
run: cd openclaw && pnpm build && pnpm ui:build

- name: Install Desktop deps
run: cd desktop && npm ci

- name: Run Desktop checks
run: cd desktop && npm run check:ci

- name: Prepare OpenClaw bundle
run: cd desktop && npm run prepare:openclaw
run: cd desktop && npm run prepare:openclaw:ci

- name: Prepare runtimes
run: cd desktop && npm run prepare:node
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: cd desktop && npm run prepare:runtimes

- name: Build Desktop
run: cd desktop && npm run build:all

- name: Package
- name: Package and publish release assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CSC_IDENTITY_AUTO_DISCOVERY: false
run: cd desktop && npx electron-builder --publish never
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
CSC_NAME: ${{ secrets.CSC_NAME }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
NOTARYTOOL_PROFILE: ${{ secrets.NOTARYTOOL_PROFILE }}
NOTARYTOOL_KEY: ${{ secrets.NOTARYTOOL_KEY }}
NOTARYTOOL_KEY_ID: ${{ secrets.NOTARYTOOL_KEY_ID }}
NOTARYTOOL_ISSUER: ${{ secrets.NOTARYTOOL_ISSUER }}
NOTARIZE: ${{ vars.OPENSPACE_NOTARIZE }}
run: cd desktop && npx electron-builder ${{ matrix.electron_args }} --publish always

- name: Upload artifacts
- name: Upload published artifacts
uses: actions/upload-artifact@v4
with:
name: openspace-mac-${{ github.sha }}
path: desktop/release/*.{dmg,zip}
name: ${{ matrix.artifact_name }}-${{ github.sha }}
path: |
desktop/release/*.zip
desktop/release/*.dmg
desktop/release/*.exe
desktop/release/*.blockmap
desktop/release/*.yml
if-no-files-found: warn

release:
needs: build-mac
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
with:
name: openspace-mac-${{ github.sha }}
path: artifacts

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
draft: true
files: artifacts/*
generate_release_notes: true
2 changes: 2 additions & 0 deletions .github/workflows/sync-openclaw.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ on:
jobs:
sync:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
Expand Down
62 changes: 51 additions & 11 deletions desktop/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
# Atomic Bot Desktop
# OpenSpace Desktop

Cross-platform Electron desktop app for [Atomic Bot](https://atomicbot.ai) — an AI assistant that makes things for you.
Cross-platform Electron desktop app for OpenSpace.

**Platforms:** macOS (arm64 / x64) · Windows (x64)

## Quick Start

```bash
# Install dependencies (from repo root)
pnpm install
# From repo root, install monorepo + desktop deps
cd openclaw && pnpm install
cd ../desktop && npm install

# Prepare bundled runtimes
# Prepare bundled runtimes used by the packaged app
npm run prepare:all

# Build & launch in dev mode
Expand All @@ -22,7 +23,7 @@ npm run dev
The app follows a standard Electron multi-process model with a clear separation of concerns:

```
apps/electron-desktop/
desktop/
├── src/ # Main process + preload
│ ├── main.ts # Electron entry point
│ ├── preload.ts # Context bridge (window.openclawDesktop)
Expand Down Expand Up @@ -128,13 +129,52 @@ Channel names live in `ipc-channels.ts`; the full API surface is declared in `de
| `npm run format` | Check formatting (Prettier) |
| `npm run format:fix` | Fix formatting (Prettier) |

## Release & Auto-update

The packaged app uses `electron-updater` with the GitHub provider configured in `package.json`. Release builds are published to the GitHub Releases page of `guilhermexp/openspace`.

Manual download assets:

- macOS: `.dmg`
- Windows: `.exe`

Auto-update assets:

- macOS: `.zip`, `.blockmap`, `latest-mac.yml`
- Windows: `.exe`, `.blockmap`, `latest.yml`

If you mirror installers on an external site, keep GitHub Releases as the canonical update feed unless you also migrate the app to a generic update provider.

Guia de secrets e variables:

- [release-secrets-checklist.md](/Users/guilhermevarela/Documents/Projetos/openspace/desktop/docs/release-secrets-checklist.md)
Comment on lines +148 to +150

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix the absolute path and translate to English.

Line 148 contains Portuguese text, and line 150 uses an absolute local filesystem path that won't work for other users.

🔧 Proposed fix
-Guia de secrets e variables:
+Secrets and variables guide:

-- [release-secrets-checklist.md](/Users/guilhermevarela/Documents/Projetos/openspace/desktop/docs/release-secrets-checklist.md)
+- [release-secrets-checklist.md](docs/release-secrets-checklist.md)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Guia de secrets e variables:
- [release-secrets-checklist.md](/Users/guilhermevarela/Documents/Projetos/openspace/desktop/docs/release-secrets-checklist.md)
Secrets and variables guide:
- [release-secrets-checklist.md](docs/release-secrets-checklist.md)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@desktop/README.md` around lines 148 - 150, Translate the Portuguese heading
and surrounding text to English and replace the absolute local path with a
repo-relative link; specifically, change the heading "Guia de secrets e
variables:" (and any Portuguese lines) to e.g. "Secrets and variables guide:"
and update the link from
"/Users/guilhermevarela/Documents/Projetos/openspace/desktop/docs/release-secrets-checklist.md"
to a relative path like "docs/release-secrets-checklist.md" so the README
references a repository file rather than a local filesystem location.


Tag-driven release flow:

1. Run `npm run release patch|minor|major` inside `desktop/`
2. Push the branch and tag
3. GitHub Actions builds macOS + Windows artifacts and publishes them to the draft release
4. Publish the draft release after both platform jobs complete

Optional signing/notarization secrets for release CI:

- `CSC_LINK`
- `CSC_KEY_PASSWORD`
- `CSC_NAME`
- `APPLE_ID`
- `APPLE_APP_SPECIFIC_PASSWORD`
- `APPLE_TEAM_ID`
- `NOTARYTOOL_PROFILE` or `NOTARYTOOL_KEY` + `NOTARYTOOL_KEY_ID` + `NOTARYTOOL_ISSUER`
- repo variable `OPENSPACE_NOTARIZE=1` to enable notarization steps

## Environment Variables

| Variable | Context | Description |
| ----------------------------- | -------- | ------------------------------------------------------- |
| `VITE_BACKEND_URL` | Renderer | Override API backend URL (set in `renderer/.env.local`) |
| `OPENCLAW_DESKTOP_NODE_BIN` | Main | Custom Node binary path for development |
| `CSC_IDENTITY_AUTO_DISCOVERY` | Build | Set to `false` to skip code signing |
| Variable | Context | Description |
| ---------------------------------------------------------------- | -------- | ------------------------------------------------------- |
| `VITE_BACKEND_URL` | Renderer | Override API backend URL (set in `renderer/.env.local`) |
| `OPENCLAW_DESKTOP_NODE_BIN` | Main | Custom Node binary path for development |
| `CSC_IDENTITY_AUTO_DISCOVERY` | Build | Set to `false` to skip code signing |
| `OPENCLAW_GOG_OAUTH_CLIENT_SECRET_PATH` / `..._B64` / `..._JSON` | Build | Stage the gog OAuth client secret for packaged builds |

## Adding New Features

Expand Down
30 changes: 15 additions & 15 deletions desktop/docs/gateway-message-metadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ CSS em: `ui/src/styles/chat/grouped.css` (classes `.msg-meta__*`)

### 4.1 Parser de historico

Arquivo: `apps/electron-desktop/renderer/src/store/slices/chat/chat-utils.ts`
Arquivo: `desktop/renderer/src/store/slices/chat/chat-utils.ts`

O `parseHistoryMessages()` extrai `usage` e `model` de cada mensagem raw:

Expand All @@ -163,7 +163,7 @@ const messageModel =

### 4.2 Tipos

Arquivo: `apps/electron-desktop/renderer/src/store/slices/chat/chat-types.ts`
Arquivo: `desktop/renderer/src/store/slices/chat/chat-types.ts`

```typescript
type UiMessageUsage = {
Expand All @@ -182,12 +182,12 @@ type UiMessage = {

### 4.3 Componente de renderizacao

Arquivo: `apps/electron-desktop/renderer/src/ui/chat/components/MessageMeta.tsx`
Arquivo: `desktop/renderer/src/ui/chat/components/MessageMeta.tsx`

Renderiza inline abaixo de cada mensagem do assistente:

```
Atomic Bot 13:40 ↑4k ↓371 R26k W212 claude-opus-4-6
OpenSpace 13:40 ↑4k ↓371 R26k W212 claude-opus-4-6
```
Comment on lines 189 to 191

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add language specifier to fenced code block.

The code block at line 189 is missing a language specifier. Since it shows rendered UI output text, consider using text or plaintext.

📝 Suggested fix
-```
+```text
 OpenSpace  13:40  ↑4k  ↓371  R26k  W212  claude-opus-4-6
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.22.0)

[warning] 189-189: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@desktop/docs/gateway-message-metadata.md` around lines 189 - 191, The fenced
code block containing the UI output line "OpenSpace  13:40  ↑4k  ↓371  R26k 
W212  claude-opus-4-6" is missing a language specifier; update that fence (the
triple-backtick block around that string) to include a language like text or
plaintext (e.g., change ``` to ```text) so the block is treated as plain text in
rendered docs.


Props recebidas diretamente da mensagem:
Expand All @@ -200,7 +200,7 @@ Fallback: se `model` nao vier na mensagem, le do config (`agents.defaults.model.

### 4.4 Integracao no ChatMessageList

Arquivo: `apps/electron-desktop/renderer/src/ui/chat/components/ChatMessageList.tsx`
Arquivo: `desktop/renderer/src/ui/chat/components/ChatMessageList.tsx`

```tsx
{
Expand All @@ -226,19 +226,19 @@ Arquivo: `apps/electron-desktop/renderer/src/ui/chat/components/ChatMessageList.
[Redux Store] → UiMessage com usage/model
[MessageMeta] → renderiza inline: "Atomic Bot 13:40 ↑4k ↓371 R26k claude-opus-4-6"
[MessageMeta] → renderiza inline: "OpenSpace 13:40 ↑4k ↓371 R26k claude-opus-4-6"
```

---

## 6. Referencia de arquivos

| Arquivo | Responsabilidade |
| ------------------------------------------------------------------------------ | ---------------------------------------- |
| `ui/src/ui/chat/grouped-render.ts` | Control UI — extrai e renderiza metadata |
| `ui/src/styles/chat/grouped.css` | Control UI — estilos `.msg-meta__*` |
| `apps/electron-desktop/renderer/src/store/slices/chat/chat-types.ts` | Tipos `UiMessageUsage`, `UiMessage` |
| `apps/electron-desktop/renderer/src/store/slices/chat/chat-utils.ts` | Parser `parseHistoryMessages()` |
| `apps/electron-desktop/renderer/src/ui/chat/components/MessageMeta.tsx` | Componente de metadata inline |
| `apps/electron-desktop/renderer/src/ui/chat/components/MessageMeta.module.css` | Estilos do MessageMeta |
| `apps/electron-desktop/renderer/src/ui/chat/components/ChatMessageList.tsx` | Integracao do MessageMeta nas mensagens |
| Arquivo | Responsabilidade |
| ---------------------------------------------------------------- | ---------------------------------------- |
| `ui/src/ui/chat/grouped-render.ts` | Control UI — extrai e renderiza metadata |
| `ui/src/styles/chat/grouped.css` | Control UI — estilos `.msg-meta__*` |
| `desktop/renderer/src/store/slices/chat/chat-types.ts` | Tipos `UiMessageUsage`, `UiMessage` |
| `desktop/renderer/src/store/slices/chat/chat-utils.ts` | Parser `parseHistoryMessages()` |
| `desktop/renderer/src/ui/chat/components/MessageMeta.tsx` | Componente de metadata inline |
| `desktop/renderer/src/ui/chat/components/MessageMeta.module.css` | Estilos do MessageMeta |
| `desktop/renderer/src/ui/chat/components/ChatMessageList.tsx` | Integracao do MessageMeta nas mensagens |
Loading
Loading