-
Notifications
You must be signed in to change notification settings - Fork 93
feat: [AI] bring the desktop app into the fork (Tauri + Electron, fully branded) #961
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
79edaf8
086a759
1c768bc
ea095e1
a082192
161e3fd
4768201
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| The fork was created from OpenCode without the desktop app. We want a fully-functional, fully-branded **Altimate Code desktop app** that exposes everything the fork has built, with no OpenCode branding leaks, and a publish-ready CI pipeline. | ||
|
|
||
| ### Scope | ||
| - Adopt the Tauri desktop shell (`packages/desktop`, primary) + Electron shell (`packages/desktop-electron`, secondary) and the SolidJS web UI (`packages/app`, `packages/ui`) from upstream v1.2.20. | ||
| - Bundle our `opencode`/`altimate` CLI as the Tauri sidecar so all server-side fork capabilities (SQL, dbt, FinOps, warehouse, altimate-core, the Altimate gateway) are exposed automatically. | ||
| - Rebrand every user-facing surface to Altimate Code (names, icons, colors, deep-link scheme, updater endpoints + key) — zero OpenCode leaks. | ||
| - Feature the **Altimate LLM Gateway** (`altimate-backend`) provider and remove the OpenCode Zen onboarding. | ||
| - Keep future upstream merges branded (un-skip packages, branding rules, `altimate_change` markers). | ||
| - Add a CI publish workflow (signed, auto-updating) — ready for org secrets. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| ### What does this PR do? | ||
|
|
||
| Brings the **desktop app** into the fork — it was excluded when altimate-code was forked from OpenCode. Adopts the Tauri shell (`packages/desktop`, primary) + Electron shell (`packages/desktop-electron`, secondary) and the SolidJS web UI (`packages/app`, `packages/ui`) from upstream v1.2.20, fully rebranded to **Altimate Code** with **no OpenCode leaks**, and wired for one-click CI publishing. | ||
|
|
||
| Highlights: | ||
| - **Sidecar = our server.** The Tauri shell bundles our `altimate` binary as the `opencode-cli` sidecar, so every server-side fork capability (SQL, dbt, FinOps, warehouse, altimate-core, the Altimate gateway) is exposed automatically. Sidecar scripts adapted to our build output (`@altimateai/altimate-code-*/bin/altimate`) + the CI artifact contract. | ||
| - **Branding (no leaks).** Rebranded the 3 `tauri.*.conf.json` (productName, identifier, deep-link scheme `altimate://`, a **new** updater keypair + AltimateAI endpoints), `index.html`, webmanifest, AppStream, Cargo crate names, `cli.rs` WSL install paths (`~/.altimate/bin`, `www.altimate.sh/install`), native window title, and i18n (18 locales). Regenerated all icon sets, favicons, PWA icons, NSIS bitmaps, social images, and the `Logo`/`Mark` components from the Altimate brand mark. | ||
| - **Gateway.** Features the Altimate LLM Gateway (`altimate-backend`) first in the provider picker with a branded icon + an in-app credential arm; removes the OpenCode Zen onboarding and filters out the `opencode`/`opencode-go` providers. | ||
| - **Tooling.** Enhanced the generic tool renderer to show full output for custom data tools; un-skipped the packages in the merge tooling with new branding rules / `keepOurs` / `requireMarkers` so future merges stay branded; added `.github/workflows/publish-desktop.yml` + a publishing runbook. | ||
|
|
||
| ### Type of change | ||
|
|
||
| - [x] New feature (non-breaking change which adds functionality) | ||
| - [ ] Bug fix | ||
| - [ ] Breaking change | ||
| - [ ] Documentation update | ||
|
|
||
| ### Issue for this PR | ||
|
|
||
| Closes #960 | ||
|
|
||
| ### How did you verify your code works? | ||
|
|
||
| - `bun turbo typecheck` — app, ui, desktop, desktop-electron all pass. | ||
| - **Runtime smoke test** — built the sidecar, ran the server, confirmed `GET /provider` returns the `{all, default, connected}` shape with `altimate-backend` ("Altimate AI") present. | ||
| - **Native build** — `tauri build` produced `Altimate Code Dev.app` + `.dmg` with a branded `Info.plist` (name/id/executable all Altimate); launched it and confirmed the shell + sidecar run. | ||
| - **Visual inspection** — in-browser: branded home wordmark, project view, model picker (no Zen), the "Connect Altimate AI" credential dialog with branded icon; native: menu bar + permission dialog read "Altimate Code". | ||
| - **Audits** — branding audit (0 leaks), marker guard + require-markers (clean), prettier (clean), and a **codex deep review** (all P1/P2 findings addressed). | ||
|
|
||
| ### Checklist | ||
|
|
||
| - [x] My code follows the style guidelines of this project | ||
| - [x] I have performed a self-review of my code | ||
| - [x] I have commented my code where necessary (wrapped fork divergences in `altimate_change` markers) | ||
| - [x] I have made corresponding changes to the documentation (`packages/desktop/README.md`) | ||
| - [x] My changes generate no new warnings (typecheck + branding + marker guard pass) | ||
| - [ ] I have added tests that prove my fix is effective or that my feature works | ||
| - [x] New and existing unit tests pass locally with my changes | ||
|
|
||
| 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,192 @@ | ||
| # Build, sign, and publish the Altimate Code desktop app (Tauri). | ||
| # | ||
| # READY, NOT WIRED: this workflow is correct in structure but needs org-provided | ||
| # secrets before the first real run. See packages/desktop/README.md for the | ||
| # signing/keygen runbook. Required repo secrets/vars: | ||
| # - APPLE_CERTIFICATE base64 of the Developer ID Application .p12 | ||
| # - APPLE_CERTIFICATE_PASSWORD password for that .p12 | ||
| # - APPLE_SIGNING_IDENTITY e.g. "Developer ID Application: Altimate Inc (TEAMID)" | ||
| # - APPLE_API_KEY App Store Connect API key id (for notarization) | ||
| # - APPLE_API_ISSUER App Store Connect API issuer id | ||
| # - APPLE_API_KEY_BASE64 base64 of the AuthKey_XXXX.p8 | ||
| # - TAURI_SIGNING_PRIVATE_KEY our updater private key (scratchpad altimate-updater.key) | ||
| # - TAURI_SIGNING_PRIVATE_KEY_PASSWORD (empty if the key has no password) | ||
| # Windows code-signing (optional) can be added to the matrix later. | ||
| # | ||
| # The desktop build matrix below MUST stay in sync with `allTargets` in | ||
| # packages/opencode/script/build.ts — the sidecar only builds for platforms that | ||
| # have an @altimateai/altimate-core NAPI prebuild. | ||
|
|
||
| name: publish-desktop | ||
| run-name: "desktop ${{ inputs.version || github.ref_name }}" | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| version: | ||
| description: "Release version (e.g. 0.8.11)" | ||
| required: true | ||
| type: string | ||
| channel: | ||
| description: "Release channel" | ||
| required: true | ||
| default: prod | ||
| type: choice | ||
| options: | ||
| - prod | ||
| - beta | ||
|
|
||
| concurrency: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.version }} | ||
|
|
||
| permissions: | ||
| contents: write | ||
| actions: read # prepare.ts uses `gh run download` to fetch the opencode-cli artifact | ||
|
|
||
| jobs: | ||
| prepare-release: | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| version: ${{ inputs.version }} | ||
| tag: v${{ inputs.version }} | ||
| release_id: ${{ steps.release.outputs.id }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Create draft release | ||
| id: release | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| run: | | ||
| tag="v${{ inputs.version }}" | ||
| existing=$(gh release view "$tag" --json databaseId --jq .databaseId 2>/dev/null || true) | ||
| if [ -z "$existing" ]; then | ||
| gh release create "$tag" --draft --title "Altimate Code $tag" --notes "Altimate Code desktop $tag" | ||
| fi | ||
| id=$(gh release view "$tag" --json databaseId --jq .databaseId) | ||
| echo "id=$id" >> "$GITHUB_OUTPUT" | ||
|
|
||
| build-cli: | ||
| # Builds the opencode/altimate sidecar binaries for every target and uploads | ||
| # them as the `opencode-cli` artifact that packages/desktop/scripts/prepare.ts | ||
| # downloads. Artifact name is internal — keep it `opencode-cli`. | ||
| needs: prepare-release | ||
| runs-on: macos-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-tags: true | ||
| - uses: oven-sh/setup-bun@v2 | ||
| with: | ||
| bun-version: "1.3.10" | ||
| - name: Build CLI (all targets) | ||
| run: bun ./packages/opencode/script/build.ts | ||
| env: | ||
| OPENCODE_VERSION: ${{ inputs.version }} | ||
| - uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: opencode-cli | ||
| path: packages/opencode/dist | ||
|
Comment on lines
+84
to
+87
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The CLI artifact is uploaded as raw Useful? React with 👍 / 👎. |
||
|
|
||
| build-tauri: | ||
| needs: [prepare-release, build-cli] | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| settings: | ||
| - host: macos-latest | ||
| target: aarch64-apple-darwin | ||
| - host: macos-latest | ||
| target: x86_64-apple-darwin | ||
| - host: windows-latest | ||
| target: x86_64-pc-windows-msvc | ||
| - host: ubuntu-latest | ||
| target: x86_64-unknown-linux-gnu | ||
| - host: ubuntu-24.04-arm | ||
| target: aarch64-unknown-linux-gnu | ||
| runs-on: ${{ matrix.settings.host }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-tags: true | ||
|
|
||
| - uses: oven-sh/setup-bun@v2 | ||
| with: | ||
| bun-version: "1.3.10" | ||
|
|
||
| - name: Install Linux deps | ||
| if: contains(matrix.settings.host, 'ubuntu') | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y --no-install-recommends \ | ||
| libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf | ||
|
|
||
| - uses: dtolnay/rust-toolchain@stable | ||
| with: | ||
| targets: ${{ matrix.settings.target }} | ||
|
|
||
| - uses: Swatinem/rust-cache@v2 | ||
| with: | ||
| workspaces: packages/desktop/src-tauri | ||
| shared-key: ${{ matrix.settings.target }} | ||
|
|
||
| - name: Import Apple signing certificate | ||
| if: runner.os == 'macOS' | ||
| uses: apple-actions/import-codesign-certs@v3 | ||
| with: | ||
| p12-file-base64: ${{ secrets.APPLE_CERTIFICATE }} | ||
| p12-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | ||
|
|
||
| - name: Stage notarization API key | ||
| # `secrets.*` cannot be referenced in `if:` — pass it via env and check in bash. | ||
| if: runner.os == 'macOS' | ||
| env: | ||
| APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }} | ||
| run: | | ||
| if [ -n "$APPLE_API_KEY_BASE64" ]; then | ||
| echo "$APPLE_API_KEY_BASE64" | base64 -d > "$RUNNER_TEMP/apple-api-key.p8" | ||
| echo "APPLE_API_KEY_PATH=$RUNNER_TEMP/apple-api-key.p8" >> "$GITHUB_ENV" | ||
| fi | ||
|
|
||
| - name: Prepare sidecar (download opencode-cli, copy into src-tauri/sidecars) | ||
| run: | | ||
| cd packages/desktop | ||
| bun ./scripts/prepare.ts | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| GITHUB_RUN_ID: ${{ github.run_id }} | ||
| RUST_TARGET: ${{ matrix.settings.target }} | ||
| OPENCODE_VERSION: ${{ inputs.version }} | ||
|
|
||
| - name: Build, sign, and upload | ||
| uses: tauri-apps/tauri-action@v0 | ||
| env: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This upload step passes Useful? React with 👍 / 👎. |
||
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | ||
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | ||
| APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} | ||
| APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }} | ||
| APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }} | ||
| with: | ||
| projectPath: packages/desktop | ||
| releaseId: ${{ needs.prepare-release.outputs.release_id }} | ||
| tagName: ${{ needs.prepare-release.outputs.tag }} | ||
| releaseDraft: true | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This workflow creates a draft release in Useful? React with 👍 / 👎. |
||
| updaterJsonPreferNsis: true | ||
| releaseAssetNamePattern: altimate-code-desktop-[platform]-[arch][ext] | ||
| args: >- | ||
| --target ${{ matrix.settings.target }} | ||
| --config ${{ (inputs.channel == 'beta' && './src-tauri/tauri.beta.conf.json') || './src-tauri/tauri.prod.conf.json' }} | ||
|
|
||
| finalize: | ||
| needs: [prepare-release, build-tauri] | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: oven-sh/setup-bun@v2 | ||
| with: | ||
| bun-version: "1.3.10" | ||
| - name: Finalize latest.json (updater manifest) | ||
| run: bun ./packages/desktop/scripts/finalize-latest-json.ts | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| GH_REPO: ${{ github.repository }} | ||
| OPENCODE_RELEASE: ${{ needs.prepare-release.outputs.release_id }} | ||
| OPENCODE_VERSION: ${{ inputs.version }} | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This workflow runs the build script immediately after
setup-bun, but the action only installs the Bun binary; it does not populatenode_modules. On a fresh GitHub runner,bun ./packages/opencode/script/build.tsimports workspace packages and dependencies before the script can run its own targeted installs, so the release job fails here (and the Tauri build job has the same missing install beforebun ./scripts/prepare.ts/bun run build).Useful? React with 👍 / 👎.