Skip to content
Draft
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
a23cc53
refactor(brand): rename Parallel Code -> Forge across code, paths, an…
thunderock Jun 29, 2026
39130f3
docs(brand): repoint attribution to thunderock/forge, keep fork credit
thunderock Jun 29, 2026
7fab8bc
chore(updater): disable on-launch update check for local builds
thunderock Jun 29, 2026
f63c973
feat(brand): new Forge spark mark + ember accent, regenerated icons
thunderock Jun 29, 2026
dece69b
Merge pull request #1 from thunderock/rebrand/forge
thunderock Jun 30, 2026
89557d4
docs(brand): remove upstream Parallel Code YouTube intro link from RE…
thunderock Jun 30, 2026
4a2f2ef
docs(brand): remove upstream Parallel Code YouTube intro link from RE…
thunderock Jun 30, 2026
c341ed5
ci(release): build unsigned macOS test binaries (no Apple account)
thunderock Jun 30, 2026
2c260a1
Merge pull request #3 from thunderock/rebrand/forge
thunderock Jun 30, 2026
837024e
Merge pull request #2 from thunderock/ci/test-release-binaries
thunderock Jun 30, 2026
a2f7bbf
feat(docker): richer multi-stage agent image
thunderock Jun 30, 2026
f10a54d
feat(docker): default to Docker Hub image + CI build/push
thunderock Jun 30, 2026
3432a62
style(store): wrap persistence.ts ternary for prettier
thunderock Jun 30, 2026
06ad847
style(store): apply prettier formatting to persistence.ts
thunderock Jun 30, 2026
c9b49a6
feat(docker): bake gsd into agent image, slim it, seed per-agent HOME
thunderock Jun 30, 2026
5d9f301
Merge pull request #4 from thunderock/docker
thunderock Jun 30, 2026
12b2170
feat(docker): resilient agent image pre-pull with retry + fallback
thunderock Jul 1, 2026
937c1a0
Merge pull request #5 from thunderock/fix
thunderock Jul 1, 2026
384a669
fix(docker): pin lazygit + delta, drop rate-limited GitHub API calls
thunderock Jul 1, 2026
6ccf548
Merge pull request #6 from thunderock/fix
thunderock Jul 1, 2026
8f700e5
feat(docker): fall back to the GitHub release image when a registry i…
thunderock Jul 6, 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
2 changes: 1 addition & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# These are supported funding model platforms

github: [johannesjo] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
github: [thunderock] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
Expand Down
107 changes: 107 additions & 0 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
name: Docker image

# Builds docker/ and publishes the agent image to Docker Hub.
# - Pull request touching docker/**: build (amd64) to VERIFY it compiles — no push.
# - Push to main touching docker/** (or manual dispatch): build multi-arch on
# native runners and push thunderockforge/forge-agent:latest.
#
# Requires repo secrets: DOCKERHUB_USERNAME, DOCKERHUB_TOKEN (a Docker Hub access token).
# Action versions use major tags for readability; pin to SHAs to match release.yml if desired.

on:
push:
branches: [main]
paths:
- 'docker/**'
- '.github/workflows/docker-image.yml'
pull_request:
paths:
- 'docker/**'
- '.github/workflows/docker-image.yml'
workflow_dispatch:

env:
IMAGE: docker.io/thunderockforge/forge-agent

jobs:
# ---- PR verification: prove the image builds, don't push ----
verify:
if: github.event_name == 'pull_request'
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Build (amd64, no push)
uses: docker/build-push-action@v6
with:
context: ./docker
platforms: linux/amd64
push: false

# ---- main / manual: build each arch on its native runner, push by digest ----
build:
if: github.event_name != 'pull_request'
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
arch: amd64
runner: ubuntu-24.04
- platform: linux/arm64
arch: arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
with:
context: ./docker
platforms: ${{ matrix.platform }}
outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true
- name: Export digest
run: |
mkdir -p "${RUNNER_TEMP}/digests"
digest="${{ steps.build.outputs.digest }}"
touch "${RUNNER_TEMP}/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digest-${{ matrix.arch }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1

# ---- combine per-arch digests into one multi-arch :latest tag ----
merge:
if: github.event_name != 'pull_request'
needs: build
runs-on: ubuntu-24.04
steps:
- name: Download digests
uses: actions/download-artifact@v4
with:
path: ${{ runner.temp }}/digests
pattern: digest-*
merge-multiple: true
- uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Create and push manifest list (:latest)
working-directory: ${{ runner.temp }}/digests
run: |
docker buildx imagetools create -t ${{ env.IMAGE }}:latest \
$(printf '${{ env.IMAGE }}@sha256:%s ' *)
- name: Inspect
run: docker buildx imagetools inspect ${{ env.IMAGE }}:latest
81 changes: 41 additions & 40 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,50 +52,51 @@ jobs:
node-version: '22'
cache: npm

- name: Import code signing certificate
env:
DMG_CERT: ${{ secrets.DMG_CERT }}
DMG_CERT_PWD: ${{ secrets.DMG_CERT_PWD }}
run: |
CERTIFICATE_PATH="$RUNNER_TEMP/build_certificate.p12"
KEYCHAIN_PATH="$RUNNER_TEMP/app-signing.keychain-db"
KEYCHAIN_PWD=$(openssl rand -base64 32)

echo -n "$DMG_CERT" | base64 --decode -o "$CERTIFICATE_PATH"

security create-keychain -p "$KEYCHAIN_PWD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 3600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PWD" "$KEYCHAIN_PATH"

security import "$CERTIFICATE_PATH" -P "$DMG_CERT_PWD" \
-A -t cert -f pkcs12 -k "$KEYCHAIN_PATH"

security set-key-partition-list -S apple-tool:,apple:,codesign: \
-s -k "$KEYCHAIN_PWD" "$KEYCHAIN_PATH"

security list-keychains -d user -s "$KEYCHAIN_PATH"

- name: Prepare API key for notarization
env:
APPLE_API_KEY_B64: ${{ secrets.APPLE_API_KEY }}
run: |
mkdir -p "$RUNNER_TEMP/private_keys"
echo -n "$APPLE_API_KEY_B64" | base64 --decode > "$RUNNER_TEMP/private_keys/AuthKey.p8"

- run: npm ci

- name: Build, sign, and publish
# Unsigned test build — no Apple Developer cert or notarization required.
# To restore signed + notarized releases: re-add the cert-import and
# notarization-key steps, set APPLE_API_KEY/APPLE_API_KEY_ID/APPLE_API_ISSUER,
# and drop the CSC_IDENTITY_AUTO_DISCOVERY + -c.mac.notarize=false overrides.
- name: Build (unsigned) and publish
env:
NODE_OPTIONS: '--max-old-space-size=4096'
APPLE_API_KEY: ${{ runner.temp }}/private_keys/AuthKey.p8
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
CSC_IDENTITY_AUTO_DISCOVERY: 'false'
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npm run build -- --universal --publish always
run: npm run build -- --universal -c.mac.notarize=false --publish always

# Attach the agent image as a per-arch tarball to the release, so the app can fetch
# it host-side and `docker load` it when the Docker daemon can't reach a registry
# (e.g. it runs in a VM with no egress). Built on native runners — no QEMU.
agent-image:
needs: create-release
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
runner: ubuntu-24.04
- arch: arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

- name: Cleanup signing artifacts
if: always()
- name: Build agent image (${{ matrix.arch }})
run: docker build -t thunderockforge/forge-agent:latest ./docker

- name: Save + compress + checksum
run: |
security delete-keychain "$RUNNER_TEMP/app-signing.keychain-db" 2>/dev/null || true
rm -f "$RUNNER_TEMP/private_keys/AuthKey.p8" 2>/dev/null || true
rm -f "$RUNNER_TEMP/build_certificate.p12" 2>/dev/null || true
set -euo pipefail
asset="forge-agent-${{ matrix.arch }}.tar.gz"
docker save thunderockforge/forge-agent:latest | gzip > "$asset"
sha256sum "$asset" > "$asset.sha256"
ls -lh "$asset" "$asset.sha256"

- name: Upload image asset to the release
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
with:
draft: true
files: |
forge-agent-${{ matrix.arch }}.tar.gz
forge-agent-${{ matrix.arch }}.tar.gz.sha256
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ coverage
# Local auto-update test server payload (build artifacts, not source).
update-test/
# Runtime data dir written by the app (MCP coordinator state, etc.)
.parallel-code/
.forge/
.worktrees
.idea
.claude
Expand Down
10 changes: 5 additions & 5 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
title = "Gitleaks config for Parallel Code"
title = "Gitleaks config for Forge"

[extend]
# Use the default Gitleaks ruleset as the base
useDefault = true

[[rules]]
id = "parallel-code-mcp-token"
description = "Parallel Code MCP bearer token"
regex = '''PARALLEL_CODE_MCP_TOKEN\s*[=:]\s*['"]?[A-Za-z0-9+/_-]{20,}['"]?'''
tags = ["token", "parallel-code"]
id = "forge-mcp-token"
description = "Forge MCP bearer token"
regex = '''FORGE_MCP_TOKEN\s*[=:]\s*['"]?[A-Za-z0-9+/_-]{20,}['"]?'''
tags = ["token", "forge"]

[[rules]]
id = "bearer-token-in-url"
Expand Down
2 changes: 1 addition & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ node_modules/
.worktrees/
.claude/
.remember/
.parallel-code/
.forge/
.enzyme/
.omc/
.planning/
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Parallel Code
# Forge

Electron desktop app — SolidJS frontend, Node.js backend. Published for **macOS and Linux only** (no Windows).

Expand Down
Loading