Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
0633646
feat(providers): add Google Antigravity via the official ACP agent (#…
t3dotgg Sep 3, 2026
2aa907b
fix(mobile): show an error instead of an endless preview spinner (#9123)
t3dotgg Sep 3, 2026
2b745ef
fix(usage): price new models without waiting a day for the rate table…
t3dotgg Sep 3, 2026
19c97ea
fix(web): unlock the composer when preview capture fails (#9127)
t3dotgg Sep 3, 2026
1e05187
fix(antigravity): refresh the model manifest so older Gemini models f…
t3dotgg Sep 3, 2026
fff33f9
perf(ci): reuse dependency checks in release builds (#9399)
t3dotgg Sep 3, 2026
77e35c5
fix(web): send cited messages with Cmd+Enter (#9307)
extoci Sep 3, 2026
098bf53
fix(web): preserve explicit preview navigation URLs (#8902)
nateEc Sep 3, 2026
57626eb
fix(web): prevent loading ssh environments from overriding navigation…
flamboh Sep 3, 2026
cfddb42
fix(mobile): skip unsupported shared settings targets (#9381)
Lucenx9 Sep 3, 2026
2120fbc
fix(web): avoid duplicate Antigravity install status (#9419)
RakshithBhat03 Sep 3, 2026
d4ba2a1
fix(composer): mute fast icon when collapsed (#9451)
maria-rcks Sep 3, 2026
21b9dda
fix(web): unify skeleton loading animations on one pulse (#9448)
maria-rcks Sep 3, 2026
645d585
fix(web): prioritize authored pull requests (#9453)
maria-rcks Sep 3, 2026
4e89d74
fix(web): make project icons the default (#9457)
maria-rcks Sep 3, 2026
c78f05a
fix(server): reuse pr state when settling threads (#9459)
maria-rcks Sep 3, 2026
8bd544c
fix(web): keep agent images collapsed (#9460)
maria-rcks Sep 3, 2026
126afb5
fix(web): banner buttons no longer expand the resting composer (#9452)
juliusmarminge Sep 3, 2026
d5825e1
fix(web): stop clipping the traits chevron on long Codex effort label…
zortos293 Sep 3, 2026
46e8b1a
fix(web): make right panel tabs easier to scroll (#9461)
maria-rcks Sep 3, 2026
db8d60f
fix(web): render transparent previews on white (#9463)
UtkarshUsername Sep 3, 2026
de025aa
fix(mobile): show loading and syncing in the working pill (#9466)
juliusmarminge Sep 3, 2026
36c4e9c
fix(server): keep a/ and b/ prefixes in rendered git patches (#9438)
Mnigos Sep 3, 2026
d2b6f3b
fix(server): full-access OpenCode threads no longer ask for approvals…
shivamhwp Sep 3, 2026
493fbb5
fix(web): reuse pull request list data while loading (#9467)
maria-rcks Sep 3, 2026
0372836
feat(web): let users turn off composer collapse on blur and scroll (#…
juliusmarminge Sep 3, 2026
373be93
fix(web): move workflow approval beside checks (#9465)
maria-rcks Sep 3, 2026
4b8b5d9
fix(desktop): refresh generated annotation styles (#9488)
juliusmarminge Sep 3, 2026
0869ad6
fix(web): let the PR reviewer and label search boxes take keystrokes …
juliusmarminge Sep 3, 2026
77138cf
fix(web): dont collapse composer when interacting with bottom row (#9…
extoci Sep 3, 2026
678f23a
fix(desktop): restore second-press quit fallback (#9485)
maria-rcks Sep 3, 2026
c726c30
fix(web): keep opencode icon hollow in collapsed composer (#9492)
maria-rcks Sep 3, 2026
12e8997
fix(web): keep agent browser preview visible (#9484)
maria-rcks Sep 3, 2026
409bc4f
fix(mobile): keep the machine glyph next to the environment label (#9…
juliusmarminge Sep 3, 2026
80b5373
fix(mobile): let back swipe pop from horizontal scroll edges (#9493)
juliusmarminge Sep 3, 2026
0aae1e2
fix(antigravity): discover legacy workspace skills (#9410)
Lucenx9 Sep 3, 2026
ef4cc60
fix(mobile): resolve Antigravity provider icon and normalize driver m…
Invictine Sep 3, 2026
e01c153
fix(antigravity): forward Google sign-in URLs from browser helper (#9…
WellyngtonF Sep 3, 2026
39449e5
feat(desktop): import browser cookies into a profile (#7255)
juliusmarminge Sep 3, 2026
ff58434
feat(desktop): import from Chrome, Edge, Brave, Vivaldi, Opera, Arc a…
juliusmarminge Sep 3, 2026
498ab9c
feat(desktop): resolve Chromium cookie keys on Linux (#7261)
juliusmarminge Sep 3, 2026
f25e442
fix(antigravity): allow slow runtime startup during setup (#9510)
t3dotgg Sep 3, 2026
baf67b6
fix(antigravity): keep model choices up to date (#9511)
t3dotgg Sep 3, 2026
eb334ca
fix(antigravity): handle native sign-in URLs on stderr (#9514)
t3dotgg Sep 3, 2026
8ea52c8
fix(antigravity): update managed runtime to 1.1.1 (#9509)
t3dotgg Sep 3, 2026
3653cb2
fix(desktop): address the browser import review left over from the st…
juliusmarminge Sep 3, 2026
f8a14b2
feat(antigravity): show subagent calls and results (#9515)
t3dotgg Sep 4, 2026
5d89548
sync: integrate upstream wave 3 through f8a14b28f
cursoragent Sep 4, 2026
bc5b465
fix(sync): restore attachment inline metadata and CI test expectations
cursoragent Sep 4, 2026
5a4970f
chore: format wave 3 files for vp check
cursoragent Sep 4, 2026
93acf6a
fix(web): drop unused react-hooks eslint-disable comments
cursoragent Sep 4, 2026
59efcee
fix(sync): unblock CI after upstream merge leftovers
cursoragent Sep 4, 2026
33d31bd
Merge remote-tracking branch 'origin/codex/sync-upstream-20260904-wav…
cursoragent Sep 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ jobs:
- name: Typecheck
run: vpr typecheck

- name: Install browser secret helper build libraries
run: sudo apt-get update && sudo apt-get install -y libsecret-1-dev pkg-config

- name: Build desktop pipeline
run: vp run build:desktop

Expand Down Expand Up @@ -149,6 +152,9 @@ jobs:
continue-on-error: true
run: vp run --filter @t3tools/desktop ensure:electron

- name: Install browser secret helper build libraries
run: sudo apt-get update && sudo apt-get install -y libsecret-1-dev pkg-config

- name: Test
run: vp run --parallel --concurrency-limit 4 --filter '!t3' --filter '!@t3tools/desktop' --filter '!@t3tools/monorepo' test

Expand Down
30 changes: 28 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ jobs:
node-version-file: package.json
cache: true
run-install: true
env:
pnpm_config_cache_dir: ${{ runner.temp }}/pnpm-metadata

- id: release_meta
name: Resolve release version
Expand Down Expand Up @@ -195,6 +197,14 @@ jobs:
--current-tag "${{ steps.release_meta.outputs.tag }}" \
--github-output

# Share only the verification results, not the large registry metadata cache.
- name: Upload dependency verification
continue-on-error: true
uses: actions/upload-artifact@v7
with:
name: release-dependency-verification
path: ${{ runner.temp }}/pnpm-metadata/lockfile-verified.jsonl

quality:
name: Release quality checks
needs: [preflight]
Expand Down Expand Up @@ -227,6 +237,9 @@ jobs:
- name: Typecheck
run: vp run typecheck

- name: Install browser secret helper build libraries
run: sudo apt-get update && sudo apt-get install -y libsecret-1-dev pkg-config

- name: Test
run: vp run test

Expand Down Expand Up @@ -482,7 +495,18 @@ jobs:
path: ${{ steps.package_cache_path.outputs.path }}
key: windows-release-packages-v1-${{ matrix.arch }}-${{ hashFiles('pnpm-lock.yaml') }}

# pnpm checks the lockfile and policy before reusing this result. A missing
# artifact leaves the cache empty, so installation runs the checks again.
- name: Download dependency verification
continue-on-error: true
uses: actions/download-artifact@v8
with:
name: release-dependency-verification
path: ${{ runner.temp }}/pnpm-metadata

- name: Install desktop dependencies
env:
pnpm_config_cache_dir: ${{ runner.temp }}/pnpm-metadata
run: vp install --filter=@t3tools/desktop... --filter=t3... --filter=@t3tools/scripts...

- name: Cache resource monitor
Expand Down Expand Up @@ -544,12 +568,13 @@ jobs:
exit $code
}

- name: Install ImageMagick
- name: Install Linux desktop build libraries
if: matrix.platform == 'linux'
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y libsecret-1-dev pkg-config
if ! command -v magick >/dev/null 2>&1 && ! command -v convert >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install -y imagemagick
fi

Expand Down Expand Up @@ -624,6 +649,7 @@ jobs:
- name: Build desktop artifact
shell: bash
env:
pnpm_config_cache_dir: ${{ runner.temp }}/pnpm-metadata
T3CODE_DESKTOP_REUSE_RESOURCE_MONITOR: ${{ steps.resource_monitor_cache.outputs.cache-hit == 'true' }}
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
Expand Down
19 changes: 17 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# AGENTS.md

T3 Code is a multi-provider GUI for coding agents. A Node WebSocket server wraps provider CLIs and agents (ACP Agent, Codex, Claude Code, Cursor, Droid, Fx, Grok, OpenCode, Amp, Copilot, Gemini CLI, Hermes Agent, Kilo, Oh My Pi, Pi, and Antigravity) and serves web, desktop, and mobile clients.

## Git & GitHub Policy (CRITICAL — DO NOT VIOLATE)

- This is a FORK of `pingdotgg/t3code`. The upstream remote is READ-ONLY for us.
Expand All @@ -19,7 +21,7 @@

When syncing upstream, preserve these fork features unless the user explicitly asks to remove them:

1. Multi-provider runtime support for the built-in drivers: configurable ACP, Codex CLI, Claude Code, Cursor, Droid, Fx, Grok Build, OpenCode, Amp, Copilot, Gemini CLI, Hermes Agent, Kilo, Oh My Pi, and Pi.
1. Multi-provider runtime support for the built-in drivers: configurable ACP, Codex CLI, Claude Code, Cursor, Droid, Fx, Grok Build, OpenCode, Amp, Copilot, Gemini CLI, Hermes Agent, Kilo, Oh My Pi, Pi, and Antigravity.
2. Usage and limit monitoring, including token/context usage snapshots, provider usage events, Codex account rate-limit streams, and the web rate-limit banner/panel UX.
3. Provider management UX, including custom provider instances, per-instance environment/config/model state, custom model slugs, and provider-scoped traits such as reasoning, context window, fast mode, and agent selection.
4. Provider-neutral orchestration reliability, including SQLite event persistence, command receipts, replay/live stream ordering, session restart/reconnect behavior, and projection consistency.
Expand All @@ -39,7 +41,7 @@ When syncing upstream, preserve these fork features unless the user explicitly a

## Project Snapshot

T3 Code is a multi-provider web GUI for coding agents. This fork supports 15 built-in provider drivers. `BUILT_IN_DRIVERS` in `apps/server/src/provider/builtInDrivers.ts` is the source of truth:
T3 Code is a multi-provider web GUI for coding agents. This fork supports 16 built-in provider drivers. `BUILT_IN_DRIVERS` in `apps/server/src/provider/builtInDrivers.ts` is the source of truth:

- **ACP Agent** — configurable executable and arguments for any stdio ACP implementation
- **Codex CLI** (v0.37.0+) — JSON-RPC over stdio
Expand All @@ -49,6 +51,7 @@ T3 Code is a multi-provider web GUI for coding agents. This fork supports 15 bui
- **Fx** — `fx acp` over stdio
- **Grok Build** — ACP over stdio with xAI protocol extensions
- **OpenCode** — SDK CLI server
- **Antigravity** — official Google ACP agent with managed install and Google sign-in
- **Amp** — Amp Code headless mode (no `/mode free`)
- **Copilot** — GitHub Copilot CLI
- **Gemini CLI** — Google Gemini CLI with persistent JSON
Expand Down Expand Up @@ -104,6 +107,18 @@ Adapters are registered in `provider/Layers/ProviderAdapterRegistry.ts` and look
- `apps/server/src/orchestration/Layers/ProjectionPipeline.ts` — Projects events into queryable state.
- `apps/server/src/ws.ts` — WebSocket RPC server using Effect's `RpcServer.toHttpEffectWebsocket()`.

### Hit every surface

The most common defect in this repo is a change that works on the path you tested and is missing everywhere else. Before calling frontend work done, walk this list and say which entries applied:

- **Entry points.** A behavior reachable from the chat view is usually also reachable from Settings, the command palette, and a keybinding. Fixing one is not fixing the feature.
- **Clients.** Web, desktop (wraps web, adds Electron shell/IPC), and mobile (React Native, separate navigation). Shared logic lives in `packages/client-runtime`.
- **Providers.** ACP Agent, Codex, Claude, Cursor, Droid, Fx, Grok, OpenCode, Antigravity, Amp, Copilot, Gemini CLI, Hermes Agent, Kilo, Oh My Pi, and Pi each have an adapter. Provider-shaped features need a decision per adapter, even if the decision is "not supported here".
- **Contracts.** Anything crossing the wire is typed in `packages/contracts`. Change the schema and the server, web, mobile, and desktop all follow.
- **Reverse states.** If you added a way in, add the way out and the way to see it. Snooze needs unsnooze. Close needs reopen. A one-way door is a bug.
- **Connection modes.** Local, remote/relay, and tunnel behave differently. Multi-device and multi-environment cases are real.
- **Docs.** `docs/` splits by audience. Behavior changes that a user would notice belong in `docs/user/` (shipped-product voice, no repo tooling or source paths); architecture and contributor changes in `docs/internals/`; runbooks in `docs/operations/`; new vocabulary in `docs/internals/glossary.md`.

### Event Sourcing & Orchestration

Provider runtime activity is normalized into canonical `OrchestrationEvent`s by the ingestion layer, persisted in a SQLite event store with sequence-based ordering, and projected into in-memory materialized views. Clients receive ordered events via Effect RPC streams (replay + live merge). Command receipts provide idempotency for reconnects and retries.
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ T3 Code is a minimal web GUI for coding agents made by [Pingdotgg](https://githu

This fork focuses on expanding provider support, keeping usage and limit monitoring visible, improving persistence layers, and refining provider management across the app. The current branded release is [T3 Code v0.0.36 — ACP Edition](https://github.com/aaditagrawal/t3code/releases/tag/v0.0.36).

Works with your subscriptions on Claude Code, Codex, Cursor, Grok Build, OpenCode, Google Antigravity, and the other supported agents below. If they're set up on your computer, T3 Code can control them.

It supports configurable stdio ACP agents, Codex, Claude Code, Cursor, Droid, Fx, Grok Build,
OpenCode, Amp, Copilot, Gemini CLI, Hermes Agent, Kilo, Oh My Pi, and Pi.
OpenCode, Antigravity, Amp, Copilot, Gemini CLI, Hermes Agent, Kilo, Oh My Pi, and Pi.

(NOTE: Amp /mode free is not supported, as Amp Code doesn't support it in headless mode - since they need to show ads for that business model to work.)

Expand All @@ -28,6 +30,7 @@ Adds full provider adapters (server managers, service layers, runtime layers) fo
| Fx | ACP integration through `fx acp` |
| Grok Build | ACP adapter with xAI protocol extensions |
| OpenCode | Adapter with hostname/port/workspace config |
| Antigravity | Official Google ACP agent with managed install and Google sign-in |
| Amp | Adapter + `ampServerManager` for headless Amp sessions |
| GitHub Copilot | Adapter + CLI binary resolution + text generation layer |
| Gemini CLI | **Enhanced:** Adapter + `geminiCliServerManager` with full test coverage |
Expand Down Expand Up @@ -105,7 +108,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/aaditagrawal/t3code/main/scr
### Manual build

> [!WARNING]
> You need at least one supported coding agent installed and authorized. See the supported agents list below.
> You need at least one supported coding agent installed and authorized. See the supported agents list below. Antigravity does not require a CLI: enable it in Settings, then use **Install Antigravity** and **Sign in with Google**.

```bash
# Prerequisites: Bun >=1.3.9, Node >=24.13.1
Expand All @@ -128,6 +131,7 @@ bun run dev
- [Amp](https://ampcode.com)
- [Kilo](https://kilo.dev)
- [OpenCode](https://opencode.ai)
- [Google Antigravity](https://github.com/agentclientprotocol/registry/blob/main/antigravity-acp/agent.json) (enable in Settings, then **Install Antigravity** and **Sign in with Google**)
- [Hermes Agent](https://github.com/NousResearch/hermes-agent) (`hermes-acp`; run `hermes-acp --setup` after installation)
- [Oh My Pi](https://github.com/can1357/oh-my-pi) (install `@oh-my-pi/pi-coding-agent`; T3 Code launches `omp acp`)
- [Pi coding agent](https://www.npmjs.com/package/@earendil-works/pi-coding-agent) (install it together with `pi-acp`, then authenticate with `pi`)
Expand Down
1 change: 1 addition & 0 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"@clerk/electron": "catalog:",
"@clerk/electron-passkeys": "catalog:",
"@effect/platform-node": "catalog:",
"@napi-rs/keyring": "^1.3.0",
"@t3tools/client-runtime": "workspace:*",
"@t3tools/contracts": "workspace:*",
"@t3tools/shared": "workspace:*",
Expand Down
103 changes: 103 additions & 0 deletions apps/desktop/scripts/browser-secret-native.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import * as NodeChildProcess from "node:child_process";
import * as NodeFS from "node:fs";
import * as NodeOS from "node:os";
import * as NodePath from "node:path";
import * as NodeURL from "node:url";
import { afterAll, beforeAll, describe, expect, it } from "vite-plus/test";

// oxlint-disable-next-line t3code/no-global-process-runtime -- The native compiler targets the actual host; this script has no Effect runtime.
const hostArch = process.arch;
// oxlint-disable-next-line t3code/no-global-process-runtime -- Native compilation only runs on the actual Linux host.
const hostPlatform = process.platform;

describe.skipIf(hostPlatform !== "linux")("bundled libsecret helper", () => {
let directory;
let executable;
beforeAll(() => {
directory = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "t3-browser-secret-test-"));
executable = NodePath.join(directory, "t3-browser-secret");
const root = NodeURL.fileURLToPath(new URL("../../../native/browser-secret/", import.meta.url));
const flags = NodeChildProcess.execFileSync(
"pkg-config",
["--cflags", "--libs", "libsecret-1"],
{
encoding: "utf8",
},
)
.trim()
.split(/\s+/);
NodeChildProcess.execFileSync(
process.env.CC || "cc",
[
"-std=c11",
"-Wall",
"-Wextra",
"-Werror",
NodePath.join(root, "main.c"),
NodePath.join(root, "test.c"),
"-Wl,--wrap=secret_service_search_sync",
"-Wl,--wrap=secret_item_get_locked",
"-Wl,--wrap=secret_item_get_secret",
"-o",
executable,
...flags,
],
{ stdio: "pipe" },
);
});
afterAll(() => {
if (directory) NodeFS.rmSync(directory, { recursive: true, force: true });
});

const run = (args) =>
NodeChildProcess.spawnSync(executable, args, {
env: { ...process.env, DBUS_SESSION_BUS_ADDRESS: "unix:path=/unused-test-bus" },
});

it("builds an executable for the requested architecture into a staged resource directory", () => {
const output = NodePath.join(directory, "resources", "browser-secret", "t3-browser-secret");
NodeChildProcess.execFileSync(process.execPath, [
NodeURL.fileURLToPath(new URL("./build-browser-secret.mjs", import.meta.url)),
"--arch",
hostArch,
"--output",
output,
]);
const header = NodeFS.readFileSync(output).subarray(0, 20);
expect(header.toString("hex", 0, 6)).toBe("7f454c460201");
expect(header.readUInt16LE(18)).toBe({ x64: 62, arm64: 183 }[hostArch]);
expect(NodeFS.statSync(output).mode & 0o111).not.toBe(0);
// Invalid arguments exit before the real executable could contact a keyring.
expect(NodeChildProcess.spawnSync(output, []).status).toBe(64);
});

it("preserves the exact secret bytes with no added or removed delimiter", () => {
const result = run(["success"]);
expect(result.status).toBe(0);
expect(result.stdout).toEqual(Buffer.from("secret\0with whitespace \t\r\n"));
expect(result.stderr.length).toBe(0);
});

for (const [scenario, code] of [
["missing", 2],
["empty", 2],
["locked", 3],
["cancelled", 3],
["denied", 3],
["unavailable", 4],
["unloaded", 4],
]) {
it(`reports ${scenario} without emitting a secret`, () => {
const result = run([scenario]);
expect(result.status).toBe(code);
expect(result.stdout.length).toBe(0);
});
}
it("rejects invalid arguments before accessing the keyring", () => {
for (const args of [[], [""], ["chrome", "extra"]]) {
const result = run(args);
expect(result.status).toBe(64);
expect(result.stdout.length).toBe(0);
}
});
});
66 changes: 66 additions & 0 deletions apps/desktop/scripts/build-browser-secret.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import * as NodeChildProcess from "node:child_process";
import * as NodeFS from "node:fs";
import * as NodePath from "node:path";
import * as NodeURL from "node:url";
import * as NodeUtil from "node:util";

// oxlint-disable-next-line t3code/no-global-process-runtime -- The native compiler targets the actual host; this script has no Effect runtime.
const hostArch = process.arch;
// oxlint-disable-next-line t3code/no-global-process-runtime -- Native compilation only runs on the actual Linux host.
const hostPlatform = process.platform;

const { values } = NodeUtil.parseArgs({
options: { output: { type: "string" }, arch: { type: "string", default: hostArch } },
});

if (hostPlatform === "linux") {
const machine = { x64: 62, arm64: 183 }[values.arch];
if (machine === undefined) throw new Error(`Unsupported Linux architecture: ${values.arch}`);
const root = NodeURL.fileURLToPath(new URL("../../../native/browser-secret/", import.meta.url));
const source = NodePath.resolve(root, "main.c");
const output = values.output ?? NodePath.resolve(root, "build", values.arch, "t3-browser-secret");
const matchesArchitecture = (file) => {
const header = NodeFS.readFileSync(file).subarray(0, 20);
return header.toString("hex", 0, 6) === "7f454c460201" && header.readUInt16LE(18) === machine;
};
let current = false;
try {
current =
NodeFS.statSync(output).mtimeMs >=
Math.max(
NodeFS.statSync(source).mtimeMs,
NodeFS.statSync(NodeURL.fileURLToPath(import.meta.url)).mtimeMs,
) && matchesArchitecture(output);
} catch {
/* The first build has no output yet. */
}
if (!current) {
let flags;
try {
flags = NodeChildProcess.execFileSync("pkg-config", ["--cflags", "--libs", "libsecret-1"], {
encoding: "utf8",
})
.trim()
.split(/\s+/);
} catch (cause) {
throw new Error(
"Building the Linux browser import helper requires pkg-config and libsecret development headers (Ubuntu/Debian: libsecret-1-dev).",
{ cause },
);
}
NodeFS.mkdirSync(NodePath.dirname(output), { recursive: true });
const temporary = `${output}.${process.pid}.tmp`;
try {
NodeChildProcess.execFileSync(
process.env.CC || "cc",
["-std=c11", "-O2", "-Wall", "-Wextra", "-Werror", source, "-o", temporary, ...flags],
{ stdio: "inherit" },
);
if (!matchesArchitecture(temporary))
throw new Error(`C compiler did not produce a Linux ${values.arch} executable.`);
NodeFS.renameSync(temporary, output);
} finally {
NodeFS.rmSync(temporary, { force: true });
}
}
}
6 changes: 6 additions & 0 deletions apps/desktop/scripts/dev-electron.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ const remoteDebuggingPort = process.env.T3CODE_DESKTOP_REMOTE_DEBUGGING_PORT?.tr
// oxlint-disable-next-line t3code/no-global-process-runtime -- Standalone dev script has no Effect runtime.
const hostPlatform = NodeOS.platform();

NodeChildProcess.execFileSync(
process.execPath,
[NodePath.join(desktopDir, "scripts/build-browser-secret.mjs")],
{ stdio: "inherit" },
);

await waitForResources({
baseDir: desktopDir,
files: requiredFiles,
Expand Down
7 changes: 7 additions & 0 deletions apps/desktop/scripts/start-electron.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import * as NodeChildProcess from "node:child_process";
import * as NodePath from "node:path";

import { desktopDir, resolveElectronLaunchCommand } from "./electron-launcher.mjs";

NodeChildProcess.execFileSync(
process.execPath,
[NodePath.join(desktopDir, "scripts/build-browser-secret.mjs")],
{ stdio: "inherit" },
);

const childEnv = { ...process.env };
delete childEnv.ELECTRON_RUN_AS_NODE;

Expand Down
Loading
Loading