Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
5cecab0
feat(db): add parent_tool_use_id and delegation_call_id for sub-agent…
xintaofei May 22, 2026
ecb9186
feat(acp): delegation event variants and parent-binding fields on Con…
xintaofei May 22, 2026
c80ed6d
feat(acp): introduce ConnectionSpawner trait and DelegationLink carrier
xintaofei May 22, 2026
eeb0120
feat(acp): DelegationBroker with depth check, timeout, parent-cancel …
xintaofei May 22, 2026
450e7fc
feat(acp): codeg-mcp companion binary with stdio MCP + UDS broker rou…
xintaofei May 22, 2026
1df13a5
feat(acp): wire delegation listener, MCP injection, lifecycle, settin…
xintaofei May 22, 2026
5f39ce3
feat(conversations): include_children filter + list_child_conversations
xintaofei May 22, 2026
2b1811b
feat(ui): inline DelegatedSubThread + delegation event binding
xintaofei May 22, 2026
b341136
feat(delegation): settings UI, chat-channel relay, full i18n
xintaofei May 22, 2026
f5b1614
fix(delegation): visible settings, MCP _meta fallback, agent card UI
xintaofei May 22, 2026
f821442
refactor(delegation): standalone card, expanded-only outcome with mar…
xintaofei May 22, 2026
c92e608
refactor(delegation): tighter card header + outcome-first expanded body
xintaofei May 22, 2026
6463c8b
fix(delegation): recognize delegation regardless of host title rephra…
xintaofei May 23, 2026
01b9a0a
feat(delegation): live append-only result stream + snapshot rebinding
xintaofei May 23, 2026
0767b6a
fix(delegation): ship codeg-mcp companion across all distribution cha…
xintaofei May 23, 2026
66fb6a1
fix(delegation): unify delegate_to_agent rendering across MCP hosts
xintaofei May 23, 2026
8c11f9e
fix(chat): refine conversation input styling
xintaofei May 24, 2026
3780e86
fix(delegation): emit completion on every terminal path and cascade c…
xintaofei May 24, 2026
3c92496
refactor(delegation): granular child-failure codes and non-blocking p…
xintaofei May 24, 2026
c13739e
refactor(settings): add General page consolidating terminal, renderin…
xintaofei May 24, 2026
9a7ad56
test(delegation): localize delegation status labels and cover real em…
xintaofei May 24, 2026
ec50f2f
fix(chat): scope input focus ring to composer and tighten attached frame
xintaofei May 24, 2026
bd7ef8e
fix(chat): drop attached-frame fill and tighten composer outer spacing
xintaofei May 24, 2026
222cde4
style(delegation): align sub-thread status badge with tool-call badge…
xintaofei May 24, 2026
d167344
fix(chat): constrain composer to message column
xintaofei May 24, 2026
735f6de
chore(acp): update Codex and OpenCode registry versions
xintaofei May 24, 2026
907df4c
style(tauri): format Rust sources
xintaofei May 24, 2026
dfbe656
fix(tabs): activate neighbor after closing active tab
xintaofei May 24, 2026
a700cff
fix: satisfy windows clippy io error lint
xintaofei May 24, 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
84 changes: 81 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,33 @@ jobs:
- name: Install frontend dependencies
run: pnpm install --frozen-lockfile

# Build the `codeg-mcp` companion binary for the matrix target and
# stage it as a Tauri sidecar at
# `src-tauri/binaries/codeg-mcp-<triple>{.exe}`. `tauri-action` (below)
# then bundles it via the `bundle.externalBin` entry in
# `tauri.conf.json` — Tauri installs it next to the main executable
# (Contents/MacOS on macOS, install root on Linux/Windows) where the
# runtime `locate_codeg_mcp_binary()` finds it via `current_exe`
# sibling lookup. The Linux arm64 cross env vars set above also
# apply to this cargo invocation.
- name: Stage codeg-mcp sidecar for Tauri bundle
shell: bash
run: pnpm tauri:prepare-sidecars --target ${{ matrix.target }}

- name: Verify codeg-mcp sidecar landed
shell: bash
run: |
ext=""
case "${{ matrix.target }}" in
*windows*) ext=".exe" ;;
esac
file="src-tauri/binaries/codeg-mcp-${{ matrix.target }}${ext}"
if [ ! -f "$file" ]; then
echo "FATAL: sidecar $file missing after prepare-sidecars"
exit 1
fi
ls -la "$file"

- name: Build and upload to draft release (Linux arm64)
if: matrix.target == 'aarch64-unknown-linux-gnu'
uses: tauri-apps/tauri-action@v0.6.1
Expand Down Expand Up @@ -425,15 +452,24 @@ jobs:
pnpm install --frozen-lockfile
pnpm build

- name: Build server binary
- name: Build server + codeg-mcp companion
working-directory: src-tauri
run: cargo build --release --bin codeg-server --no-default-features --target ${{ matrix.target }}
# `codeg-mcp` is the stdio MCP companion the runtime injects per
# session (see acp/delegation/companion.rs). Built with the same
# `--no-default-features --target` flags as the server so it shares
# the cross-compile env (Linux arm64) without dragging in tauri
# runtime deps.
run: |
cargo build --release --bin codeg-server --no-default-features --target ${{ matrix.target }}
cargo build --release --bin codeg-mcp --no-default-features --target ${{ matrix.target }}

- name: Package (Unix)
if: runner.os != 'Windows'
run: |
mkdir -p dist/${{ matrix.artifact }}
cp src-tauri/target/${{ matrix.target }}/release/codeg-server dist/${{ matrix.artifact }}/
cp src-tauri/target/${{ matrix.target }}/release/codeg-mcp dist/${{ matrix.artifact }}/
chmod +x dist/${{ matrix.artifact }}/codeg-server dist/${{ matrix.artifact }}/codeg-mcp
cp -r out dist/${{ matrix.artifact }}/web
cd dist && tar czf ${{ matrix.artifact }}.tar.gz ${{ matrix.artifact }}

Expand All @@ -443,9 +479,42 @@ jobs:
run: |
New-Item -ItemType Directory -Force -Path dist/${{ matrix.artifact }}
Copy-Item src-tauri/target/${{ matrix.target }}/release/codeg-server.exe dist/${{ matrix.artifact }}/
Copy-Item src-tauri/target/${{ matrix.target }}/release/codeg-mcp.exe dist/${{ matrix.artifact }}/
Copy-Item -Recurse out dist/${{ matrix.artifact }}/web
Compress-Archive -Path dist/${{ matrix.artifact }} -DestinationPath dist/${{ matrix.artifact }}.zip

- name: Smoke test packaged artifact (Unix)
if: runner.os != 'Windows'
run: |
set -euo pipefail
test -x "dist/${{ matrix.artifact }}/codeg-server"
test -x "dist/${{ matrix.artifact }}/codeg-mcp"
# `codeg-mcp --help` exits 0 without flags and prints the usage
# line. Only run it for native targets; cross-compiled arm64
# binaries on x64 runners can't execute.
if [ "${{ matrix.target }}" = "x86_64-unknown-linux-gnu" ] || \
[ "${{ matrix.target }}" = "x86_64-apple-darwin" ] || \
[ "${{ matrix.target }}" = "aarch64-apple-darwin" ]; then
"dist/${{ matrix.artifact }}/codeg-mcp" --help | grep -F 'codeg-mcp --parent-connection-id'
else
echo "skipping codeg-mcp --help on cross-target ${{ matrix.target }}"
fi

- name: Smoke test packaged artifact (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
if (-not (Test-Path "dist/${{ matrix.artifact }}/codeg-server.exe")) {
throw "codeg-server.exe missing from packaged artifact"
}
if (-not (Test-Path "dist/${{ matrix.artifact }}/codeg-mcp.exe")) {
throw "codeg-mcp.exe missing from packaged artifact"
}
$help = & "dist/${{ matrix.artifact }}/codeg-mcp.exe" --help
if ($help -notlike "*codeg-mcp --parent-connection-id*") {
throw "codeg-mcp --help output unexpected: $help"
}

- name: Upload artifact for Docker build (Linux only)
if: startsWith(matrix.target, 'x86_64-unknown-linux') || startsWith(matrix.target, 'aarch64-unknown-linux')
uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -492,11 +561,20 @@ jobs:

- name: Prepare Docker build context
run: |
set -euo pipefail
mkdir -p dist/amd64 dist/arm64
cp artifacts/linux-x64/codeg-server dist/amd64/codeg-server
cp artifacts/linux-x64/codeg-mcp dist/amd64/codeg-mcp
cp artifacts/linux-arm64/codeg-server dist/arm64/codeg-server
cp artifacts/linux-arm64/codeg-mcp dist/arm64/codeg-mcp
cp -r artifacts/linux-x64/web dist/web
chmod +x dist/amd64/codeg-server dist/arm64/codeg-server
chmod +x dist/amd64/codeg-server dist/amd64/codeg-mcp \
dist/arm64/codeg-server dist/arm64/codeg-mcp
# Fail fast if any companion went missing — Docker would otherwise
# produce an image where delegation silently degrades.
for f in dist/amd64/codeg-mcp dist/arm64/codeg-mcp; do
test -x "$f" || { echo "FATAL: $f missing or non-exec"; exit 1; }
done

- name: Set up QEMU (for multi-arch manifest)
uses: docker/setup-qemu-action@v3
Expand Down
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,9 @@ coverage/
# Agent
.claude
.docs
docs/superpowers
docs/superpowers

# Tauri sidecar staging (built per-target by prepare-sidecars.mjs).
# The binaries are platform-specific build artifacts; ship them through
# release.yml, not git.
src-tauri/binaries/
9 changes: 7 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ COPY public/ ./public/
COPY next.config.ts tsconfig.json postcss.config.mjs components.json ./
RUN pnpm build

# Stage 2: Build Rust server binary
# Stage 2: Build Rust server binary + codeg-mcp companion
FROM rust:slim-bookworm AS backend
RUN apt-get update && apt-get install -y pkg-config libssl-dev && rm -rf /var/lib/apt/lists/*
WORKDIR /app/src-tauri
COPY src-tauri/ ./
RUN cargo build --release --bin codeg-server --no-default-features
# codeg-mcp is the stdio MCP companion the runtime injects per session
# (see acp/delegation/companion.rs). It must ship next to codeg-server so
# `locate_codeg_mcp_binary()` finds it via the exe-sibling lookup.
RUN cargo build --release --bin codeg-server --no-default-features \
&& cargo build --release --bin codeg-mcp --no-default-features

# Stage 3: Runtime
FROM node:22-bookworm-slim
Expand All @@ -29,6 +33,7 @@ RUN apt-get update && apt-get install -y \
&& rm -rf /var/lib/apt/lists/*

COPY --from=backend /app/src-tauri/target/release/codeg-server /usr/local/bin/codeg-server
COPY --from=backend /app/src-tauri/target/release/codeg-mcp /usr/local/bin/codeg-mcp
COPY --from=frontend /app/out /app/web

ENV CODEG_STATIC_DIR=/app/web
Expand Down
4 changes: 4 additions & 0 deletions Dockerfile.ci
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ RUN apt-get update && apt-get install -y \
&& rm -rf /var/lib/apt/lists/*

COPY dist/${TARGETARCH}/codeg-server /usr/local/bin/codeg-server
# codeg-mcp is the stdio MCP companion the runtime injects per session
# (see acp/delegation/companion.rs). It must ship next to codeg-server so
# `locate_codeg_mcp_binary()` finds it via the exe-sibling lookup.
COPY dist/${TARGETARCH}/codeg-mcp /usr/local/bin/codeg-mcp
COPY dist/web /app/web

ENV CODEG_STATIC_DIR=/app/web
Expand Down
67 changes: 52 additions & 15 deletions install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,17 @@ $ErrorActionPreference = "Stop"
$Repo = "xintaofei/codeg"
$Artifact = "codeg-server-windows-x64"

# Stale codeg-server binaries elsewhere in PATH are removed by default so the
# user's `codeg-server` command always runs the freshly installed binary. Pass
# -NoCleanup (or set CODEG_NO_CLEANUP=1) to disable.
# Names of binaries this installer manages. codeg-server is the user-facing
# entry point; codeg-mcp is the stdio MCP companion that the server's ACP
# layer spawns per session for delegation. Both must live in the same
# directory — `locate_codeg_mcp_binary()` in src-tauri/src/acp/connection.rs
# resolves the companion as a sibling of the running server executable.
$ManagedBins = @("codeg-server", "codeg-mcp")

# Stale codeg-server / codeg-mcp binaries elsewhere in PATH are removed by
# default so the user's `codeg-server` command always runs the freshly
# installed binary AND the runtime locates the matching companion via the
# exe-sibling lookup. Pass -NoCleanup (or set CODEG_NO_CLEANUP=1) to disable.
$Cleanup = -not $NoCleanup
if ($env:CODEG_NO_CLEANUP -eq "1") {
$Cleanup = $false
Expand Down Expand Up @@ -87,6 +95,10 @@ $PathConflicts = @()
$seenReal = @{}
$pathDirs = @()
if ($env:Path) { $pathDirs = $env:Path.Split(';') }
# Scan PATH for both managed binaries — a stale `codeg-mcp.exe` in an earlier
# PATH entry would be picked by the runtime's `which` fallback once
# `codeg-server.exe` was upgraded out from under it, breaking delegation in
# subtle ways. Track conflicts uniformly for cleanup.
foreach ($dir in $pathDirs) {
if (-not $dir) { continue }
# Match by canonical path string so the destination is recognized even when
Expand All @@ -95,13 +107,15 @@ foreach ($dir in $pathDirs) {
if ($dirReal -eq $InstallDirReal) {
break
}
foreach ($leaf in @("codeg-server.exe", "codeg-server")) {
$bin = Join-Path $dir $leaf
if (Test-Path -LiteralPath $bin -PathType Leaf) {
$real = Get-CanonicalPath $bin
if ($seenReal.ContainsKey($real)) { continue }
$seenReal[$real] = $true
$PathConflicts += $bin
foreach ($name in $ManagedBins) {
foreach ($leaf in @("$name.exe", $name)) {
$bin = Join-Path $dir $leaf
if (Test-Path -LiteralPath $bin -PathType Leaf) {
$real = Get-CanonicalPath $bin
if ($seenReal.ContainsKey($real)) { continue }
$seenReal[$real] = $true
$PathConflicts += $bin
}
}
}
}
Expand Down Expand Up @@ -199,15 +213,25 @@ Write-Host "Extracting..."
Expand-Archive -Path $ZipPath -DestinationPath $TmpDir -Force

# ── Install ──
#
# Verify both binaries are present in the archive BEFORE writing anything
# to InstallDir. Without the companion, delegation degrades silently on
# every new ACP session — fail fast instead.

New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null

$BinarySrc = Join-Path $TmpDir $Artifact "codeg-server.exe"
if (-not (Test-Path $BinarySrc)) {
Write-Error "Binary not found in archive"
exit 1
foreach ($name in $ManagedBins) {
$src = Join-Path $TmpDir $Artifact "$name.exe"
if (-not (Test-Path $src)) {
Write-Error "$name.exe not found in archive $Artifact.zip — release is incomplete, please report."
exit 1
}
}
foreach ($name in $ManagedBins) {
$src = Join-Path $TmpDir $Artifact "$name.exe"
$dst = Join-Path $InstallDir "$name.exe"
Copy-Item $src -Destination $dst -Force
}
Copy-Item $BinarySrc -Destination (Join-Path $InstallDir "codeg-server.exe") -Force

# Re-canonicalize destination now that the file exists. Pre-install canon may
# leave the final non-existent component unresolved, which would mis-compare
Expand Down Expand Up @@ -279,8 +303,21 @@ if (-not $InstalledVer) { $InstalledVer = $TargetVer }

Write-Host ""
Write-Host "codeg-server installed to $InstallDir\codeg-server.exe"
Write-Host "codeg-mcp installed to $InstallDir\codeg-mcp.exe"
Write-Host "Version: $InstalledVer"

# Final smoke: codeg-mcp.exe must exist next to codeg-server.exe so the
# runtime's `locate_codeg_mcp_binary()` exe-sibling lookup hits. A failure
# here means the zip was malformed or a previous Copy-Item was silently
# blocked — surface it loudly rather than ship a half-broken install.
$McpPath = Join-Path $InstallDir "codeg-mcp.exe"
if (-not (Test-Path -LiteralPath $McpPath)) {
Write-Host ""
Write-Host "Error: $McpPath missing after install."
Write-Host " Delegation (sub-agent tooling) will not work. Re-run the installer."
$ExitStatus = 1
}

# Verify the user's `codeg-server` command actually resolves to the new binary.
$ActiveBinAfter = ""
$resolvedAfter = Get-Command codeg-server -ErrorAction SilentlyContinue
Expand Down
Loading
Loading