Skip to content

Commit de84bc7

Browse files
authored
feat(rebrand): env T3CODE_* → BCODE_*, protocol t3:// → bcode://, COM/Linux IDs (#9)
* feat(shared): add env dual-read shim (BCODE_* preferred, T3CODE_* fallback with warning) * feat(rebrand): flip server CLI env vars via Effect Config shim BCODE_* preferred with T3CODE_* fallback + per-key deprecation warning. Rename bootstrap envelope field t3Home -> bcodeHome. Default otlpServiceName flips from t3-server to bcode-server. * feat(rebrand): flip desktop + scripts env readers to new names Desktop app.ts, updateState, terminal Manager, perf harnesses, telemetry, projectScripts, vite/web, dev-runner, build-desktop-artifact, mock-update and misc tests move to BCODE_*. Scripts with user-facing env (dev-runner, build-desktop-artifact) keep a BCODE_* preferred / T3CODE_* fallback shim that warns once per legacy key. projectScriptRuntimeEnv writes both prefixes so user-authored project scripts continue reading legacy names. Terminal env strip filter now drops both BCODE_* and T3CODE_* keys. * feat(rebrand): flip shell capture sentinels __T3CODE_* to __BCODE_* Internal-only markers grep'd out of captured shell output. No persistence or external interface, safe to flip without a legacy-name fallback. * chore(rebrand): add BCODE_* keys to turbo globalEnv alongside T3CODE_* Dual-listing matches the env var shim window: cache invalidation fires when either prefix changes through v0.0.19. The T3CODE_* entries are removed together with the shim in v0.0.20. * feat(rebrand): rename desktop internal protocol scheme t3:// to bcode:// DESKTOP_SCHEME is an electron-internal asset protocol used for packaged UI loading. No OS-level handler is registered via setAsDefaultProtocolClient, so this flip has no external surface and needs no migration shim. * feat(rebrand): rename COM/bundle ID to com.berkayorhan.bcode and artifactName to BCode-* Flips APP_USER_MODEL_ID (Windows AUMID), APP_BUNDLE_ID (macOS plist patching in the electron launcher), and the electron-builder appId + artifactName pattern. Changes the installed-app identity on new installs; existing installs continue to resolve their own identity via electron's userData paths (deliberately kept under the legacy t3code name). * feat(rebrand): rename Linux entry, WM class, and internal t3code identifiers to bcode LINUX_DESKTOP_ENTRY_NAME, LINUX_WM_CLASS, executableName, StartupWMClass, the dev-electron pkill marker arg, the packaged package.json name, the temp stage dir prefixes, and the bcodeCommitHash metadata field all flip to bcode. USER_DATA_DIR_NAME remains 't3code' deliberately (per AGENTS.md) to preserve electron-managed state on existing installs. * test(rebrand): flip release fixture artifact names T3-Code-* to BCode-* Follows the commit 8 artifactName flip: update-manifest test fixtures and release-smoke-test fixture URLs must match the new artifact naming pattern or the tests fail on what's effectively stale hardcoded data. * docs(rebrand): rewrite current docs for BCODE_*, bcode://, ~/.bcode Updates observability, release, perf-benchmarks, quick-start, scripts, KEYBINDINGS, and debugging rule docs to use the new env var names and home directory. Adds an env var deprecation-window note at the top of observability.md. Historical plans and specs are left untouched. * docs(plan): add PR #2 execution breakdown * test(rebrand): assert dual-prefix env keys in project setup script The projectScriptRuntimeEnv helper writes both BCODE_* and T3CODE_* aliases through v0.0.19 so user-authored project scripts keep reading legacy names. The setup-script runner assertion must match that shape. Other projectScripts/ChatView assertions already use toMatchObject partial matching so they were unaffected. * fix(rebrand): address Copilot review on PR #9 - desktop main.ts:1412: write bcodeHome (not t3Home) to the bootstrap envelope so the server honors the desktop-selected base dir after the schema field rename. - turbo.json: add BCODE_WEB_SOURCEMAP and T3CODE_WEB_SOURCEMAP to globalEnv so vite sourcemap changes invalidate turbo cache. - build-desktop-artifact.ts: emit the one-time legacy-env deprecation warning for T3CODE_DESKTOP_UPDATE_REPOSITORY like the other shimmed reads. - observability.md / KEYBINDINGS.md / debugging.md / scripts.md: revert hardcoded ~/.bcode/... paths to ~/.t3/... with a note about the upcoming home-dir flip. The runtime default is still ~/.t3 until PR #3 lands the auto-migration, so user-facing docs must match the current on-disk reality. Env var name flips (BCODE_*) are retained since the shim honors both.
1 parent d91a66e commit de84bc7

46 files changed

Lines changed: 851 additions & 365 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.docs/quick-start.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ bun run dev
88
bun run dev:desktop
99

1010
# Desktop development on an isolated port set
11-
T3CODE_DEV_INSTANCE=feature-xyz bun run dev:desktop
11+
BCODE_DEV_INSTANCE=feature-xyz bun run dev:desktop
1212

1313
# Production
1414
bun run build

.docs/scripts.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
- `bun run dev` — Starts contracts, server, and web in `turbo watch` mode.
44
- `bun run dev:server` — Starts just the WebSocket server (uses Bun TypeScript execution).
55
- `bun run dev:web` — Starts just the Vite dev server for the web app.
6-
- Dev commands default `T3CODE_STATE_DIR` to `~/.t3/dev` to keep dev state isolated from desktop/prod state.
6+
- Dev commands default the base dir to `~/.t3` (overridable via `BCODE_HOME` or `--base-dir`) and place dev state under `$BCODE_HOME/dev` to keep it isolated from desktop/prod state.
77
- Override server CLI-equivalent flags from root dev commands with `--`, for example:
88
`bun run dev -- --base-dir ~/.t3-2`
99
- `bun run start` — Runs the production server (serves built web app as static files).
@@ -20,8 +20,8 @@
2020

2121
- Default build is unsigned/not notarized for local sharing.
2222
- The DMG build uses `assets/macos-icon-1024.png` as the production app icon source.
23-
- Desktop production windows load the bundled UI from `t3://app/index.html` (not a `127.0.0.1` document URL).
24-
- Desktop packaging includes `apps/server/dist` (the `t3` backend) and starts it on loopback with an auth token for WebSocket/API traffic.
23+
- Desktop production windows load the bundled UI from `bcode://app/index.html` (not a `127.0.0.1` document URL).
24+
- Desktop packaging includes `apps/server/dist` (the `bcode` backend) and starts it on loopback with an auth token for WebSocket/API traffic.
2525
- Your tester can still open it on macOS by right-clicking the app and choosing **Open** on first launch.
2626
- To keep staging files for debugging package contents, run: `bun run dist:desktop:dmg -- --keep-stage`
2727
- To allow code-signing/notarization when configured in CI/secrets, add: `--signed`.
@@ -33,10 +33,10 @@
3333

3434
## Running multiple dev instances
3535

36-
Set `T3CODE_DEV_INSTANCE` to any value to deterministically shift all dev ports together.
36+
Set `BCODE_DEV_INSTANCE` to any value to deterministically shift all dev ports together.
3737

3838
- Default ports: server `3773`, web `5733`
39-
- Shifted ports: `base + offset` (offset is hashed from `T3CODE_DEV_INSTANCE`)
40-
- Example: `T3CODE_DEV_INSTANCE=branch-a bun run dev:desktop`
39+
- Shifted ports: `base + offset` (offset is hashed from `BCODE_DEV_INSTANCE`)
40+
- Example: `BCODE_DEV_INSTANCE=branch-a bun run dev:desktop`
4141

42-
If you want full control instead of hashing, set `T3CODE_PORT_OFFSET` to a numeric offset.
42+
If you want full control instead of hashing, set `BCODE_PORT_OFFSET` to a numeric offset.

KEYBINDINGS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
T3 Code reads keybindings from:
44

5-
- `~/.t3/keybindings.json`
5+
- `~/.t3/keybindings.json` (home directory flips to `~/.bcode` in a future release with auto-migration)
66

77
The file must be a JSON array of rules:
88

apps/desktop/scripts/dev-electron.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function cleanupStaleDevApps() {
5959
return;
6060
}
6161

62-
spawnSync("pkill", ["-f", "--", `--t3code-dev-root=${desktopDir}`], { stdio: "ignore" });
62+
spawnSync("pkill", ["-f", "--", `--bcode-dev-root=${desktopDir}`], { stdio: "ignore" });
6363
}
6464

6565
function startApp() {
@@ -69,7 +69,7 @@ function startApp() {
6969

7070
const app = spawn(
7171
resolveElectronPath(),
72-
[`--t3code-dev-root=${desktopDir}`, "dist-electron/main.js"],
72+
[`--bcode-dev-root=${desktopDir}`, "dist-electron/main.js"],
7373
{
7474
cwd: desktopDir,
7575
env: childEnv,

apps/desktop/scripts/electron-launcher.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { fileURLToPath } from "node:url";
1919

2020
const isDevelopment = Boolean(process.env.VITE_DEV_SERVER_URL);
2121
const APP_DISPLAY_NAME = isDevelopment ? "T3 Code (Dev)" : "T3 Code (Alpha)";
22-
const APP_BUNDLE_ID = isDevelopment ? "com.t3tools.t3code.dev" : "com.t3tools.t3code";
22+
const APP_BUNDLE_ID = isDevelopment ? "com.berkayorhan.bcode.dev" : "com.berkayorhan.bcode";
2323
const LAUNCHER_VERSION = 1;
2424

2525
const __dirname = dirname(fileURLToPath(import.meta.url));

apps/desktop/src/main.ts

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import type {
3434
import { autoUpdater } from "electron-updater";
3535

3636
import type { ContextMenuItem } from "@bcode/contracts";
37+
import { readEnv } from "@bcode/shared/env";
3738
import { RotatingFileSink } from "@bcode/shared/logging";
3839
import { parsePersistedServerObservabilitySettings } from "@bcode/shared/serverSettings";
3940
import { DEFAULT_DESKTOP_BACKEND_PORT, resolveDesktopBackendPort } from "./backendPort";
@@ -100,22 +101,22 @@ const SET_SAVED_ENVIRONMENT_SECRET_CHANNEL = "desktop:set-saved-environment-secr
100101
const REMOVE_SAVED_ENVIRONMENT_SECRET_CHANNEL = "desktop:remove-saved-environment-secret";
101102
const GET_SERVER_EXPOSURE_STATE_CHANNEL = "desktop:get-server-exposure-state";
102103
const SET_SERVER_EXPOSURE_MODE_CHANNEL = "desktop:set-server-exposure-mode";
103-
const BASE_DIR = process.env.T3CODE_HOME?.trim() || Path.join(OS.homedir(), ".t3");
104+
const BASE_DIR = readEnv("HOME")?.trim() || Path.join(OS.homedir(), ".t3");
104105
const STATE_DIR = Path.join(BASE_DIR, "userdata");
105106
const DESKTOP_SETTINGS_PATH = Path.join(STATE_DIR, "desktop-settings.json");
106107
const CLIENT_SETTINGS_PATH = Path.join(STATE_DIR, "client-settings.json");
107108
const SAVED_ENVIRONMENT_REGISTRY_PATH = Path.join(STATE_DIR, "saved-environments.json");
108-
const DESKTOP_SCHEME = "t3";
109+
const DESKTOP_SCHEME = "bcode";
109110
const ROOT_DIR = Path.resolve(__dirname, "../../..");
110111
const isDevelopment = Boolean(process.env.VITE_DEV_SERVER_URL);
111112
const desktopAppBranding: DesktopAppBranding = resolveDesktopAppBranding({
112113
isDevelopment,
113114
appVersion: app.getVersion(),
114115
});
115116
const APP_DISPLAY_NAME = desktopAppBranding.displayName;
116-
const APP_USER_MODEL_ID = isDevelopment ? "com.t3tools.t3code.dev" : "com.t3tools.t3code";
117-
const LINUX_DESKTOP_ENTRY_NAME = isDevelopment ? "t3code-dev.desktop" : "t3code.desktop";
118-
const LINUX_WM_CLASS = isDevelopment ? "t3code-dev" : "t3code";
117+
const APP_USER_MODEL_ID = isDevelopment ? "com.berkayorhan.bcode.dev" : "com.berkayorhan.bcode";
118+
const LINUX_DESKTOP_ENTRY_NAME = isDevelopment ? "bcode-dev.desktop" : "bcode.desktop";
119+
const LINUX_WM_CLASS = isDevelopment ? "bcode-dev" : "bcode";
119120
const USER_DATA_DIR_NAME = isDevelopment ? "t3code-dev" : "t3code";
120121
const LEGACY_USER_DATA_DIR_NAME = isDevelopment ? "T3 Code (Dev)" : "T3 Code (Alpha)";
121122
const COMMIT_HASH_PATTERN = /^[0-9a-f]{7,40}$/i;
@@ -259,13 +260,15 @@ function resolveDesktopDevServerUrl(): string {
259260

260261
function backendChildEnv(): NodeJS.ProcessEnv {
261262
const env = { ...process.env };
262-
delete env.T3CODE_PORT;
263-
delete env.T3CODE_MODE;
264-
delete env.T3CODE_NO_BROWSER;
265-
delete env.T3CODE_HOST;
266-
delete env.T3CODE_DESKTOP_WS_URL;
267-
delete env.T3CODE_DESKTOP_LAN_ACCESS;
268-
delete env.T3CODE_DESKTOP_LAN_HOST;
263+
for (const prefix of ["BCODE_", "T3CODE_"] as const) {
264+
delete env[`${prefix}PORT`];
265+
delete env[`${prefix}MODE`];
266+
delete env[`${prefix}NO_BROWSER`];
267+
delete env[`${prefix}HOST`];
268+
delete env[`${prefix}DESKTOP_WS_URL`];
269+
delete env[`${prefix}DESKTOP_LAN_ACCESS`];
270+
delete env[`${prefix}DESKTOP_LAN_HOST`];
271+
}
269272
return env;
270273
}
271274

@@ -286,7 +289,7 @@ function getDesktopSecretStorage() {
286289
}
287290

288291
function resolveAdvertisedHostOverride(): string | undefined {
289-
const override = process.env.T3CODE_DESKTOP_LAN_HOST?.trim();
292+
const override = readEnv("DESKTOP_LAN_HOST")?.trim();
290293
return override && override.length > 0 ? override : undefined;
291294
}
292295

@@ -703,8 +706,8 @@ function resolveEmbeddedCommitHash(): string | null {
703706

704707
try {
705708
const raw = FS.readFileSync(packageJsonPath, "utf8");
706-
const parsed = JSON.parse(raw) as { t3codeCommitHash?: unknown };
707-
return normalizeCommitHash(parsed.t3codeCommitHash);
709+
const parsed = JSON.parse(raw) as { bcodeCommitHash?: unknown };
710+
return normalizeCommitHash(parsed.bcodeCommitHash);
708711
} catch {
709712
return null;
710713
}
@@ -715,7 +718,7 @@ function resolveAboutCommitHash(): string | null {
715718
return aboutCommitHashCache;
716719
}
717720

718-
const envCommitHash = normalizeCommitHash(process.env.T3CODE_COMMIT_HASH);
721+
const envCommitHash = normalizeCommitHash(readEnv("COMMIT_HASH"));
719722
if (envCommitHash) {
720723
aboutCommitHashCache = envCommitHash;
721724
return aboutCommitHashCache;
@@ -870,13 +873,13 @@ function dispatchMenuAction(action: string): void {
870873

871874
function handleCheckForUpdatesMenuClick(): void {
872875
const hasUpdateFeedConfig =
873-
readAppUpdateYml() !== null || Boolean(process.env.T3CODE_DESKTOP_MOCK_UPDATES);
876+
readAppUpdateYml() !== null || Boolean(readEnv("DESKTOP_MOCK_UPDATES"));
874877
const disabledReason = getAutoUpdateDisabledReason({
875878
isDevelopment,
876879
isPackaged: app.isPackaged,
877880
platform: process.platform,
878881
appImage: process.env.APPIMAGE,
879-
disabledByEnv: process.env.T3CODE_DISABLE_AUTO_UPDATE === "1",
882+
disabledByEnv: readEnv("DISABLE_AUTO_UPDATE") === "1",
880883
hasUpdateFeedConfig,
881884
});
882885
if (disabledReason) {
@@ -1147,14 +1150,14 @@ function applyAutoUpdaterChannel(channel: DesktopUpdateChannel): void {
11471150

11481151
function shouldEnableAutoUpdates(): boolean {
11491152
const hasUpdateFeedConfig =
1150-
readAppUpdateYml() !== null || Boolean(process.env.T3CODE_DESKTOP_MOCK_UPDATES);
1153+
readAppUpdateYml() !== null || Boolean(readEnv("DESKTOP_MOCK_UPDATES"));
11511154
return (
11521155
getAutoUpdateDisabledReason({
11531156
isDevelopment,
11541157
isPackaged: app.isPackaged,
11551158
platform: process.platform,
11561159
appImage: process.env.APPIMAGE,
1157-
disabledByEnv: process.env.T3CODE_DISABLE_AUTO_UPDATE === "1",
1160+
disabledByEnv: readEnv("DISABLE_AUTO_UPDATE") === "1",
11581161
hasUpdateFeedConfig,
11591162
}) === null
11601163
);
@@ -1240,7 +1243,7 @@ async function installDownloadedUpdate(): Promise<{ accepted: boolean; completed
12401243

12411244
function configureAutoUpdater(): void {
12421245
const githubToken =
1243-
process.env.T3CODE_DESKTOP_UPDATE_GITHUB_TOKEN?.trim() || process.env.GH_TOKEN?.trim() || "";
1246+
readEnv("DESKTOP_UPDATE_GITHUB_TOKEN")?.trim() || process.env.GH_TOKEN?.trim() || "";
12441247
if (githubToken) {
12451248
// When a token is provided, re-configure the feed with `private: true` so
12461249
// electron-updater uses the GitHub API (api.github.com) instead of the
@@ -1256,10 +1259,10 @@ function configureAutoUpdater(): void {
12561259
}
12571260
}
12581261

1259-
if (process.env.T3CODE_DESKTOP_MOCK_UPDATES) {
1262+
if (readEnv("DESKTOP_MOCK_UPDATES")) {
12601263
autoUpdater.setFeedURL({
12611264
provider: "generic",
1262-
url: `http://localhost:${process.env.T3CODE_DESKTOP_MOCK_UPDATE_SERVER_PORT ?? 3000}`,
1265+
url: `http://localhost:${readEnv("DESKTOP_MOCK_UPDATE_SERVER_PORT") ?? 3000}`,
12631266
});
12641267
}
12651268

@@ -1406,7 +1409,7 @@ function startBackend(): void {
14061409
mode: "desktop",
14071410
noBrowser: true,
14081411
port: backendPort,
1409-
t3Home: BASE_DIR,
1412+
bcodeHome: BASE_DIR,
14101413
host: backendBindHost,
14111414
desktopBootstrapToken: backendBootstrapToken,
14121415
...(backendObservabilitySettings.otlpTracesUrl
@@ -2040,9 +2043,9 @@ configureAppIdentity();
20402043

20412044
async function bootstrap(): Promise<void> {
20422045
writeDesktopLogHeader("bootstrap start");
2043-
const configuredBackendPort = resolveConfiguredDesktopBackendPort(process.env.T3CODE_PORT);
2046+
const configuredBackendPort = resolveConfiguredDesktopBackendPort(readEnv("PORT"));
20442047
if (isDevelopment && configuredBackendPort === undefined) {
2045-
throw new Error("T3CODE_PORT is required in desktop development.");
2048+
throw new Error("BCODE_PORT is required in desktop development.");
20462049
}
20472050

20482051
backendPort =

apps/desktop/src/updateState.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ describe("getAutoUpdateDisabledReason", () => {
113113
disabledByEnv: true,
114114
hasUpdateFeedConfig: true,
115115
}),
116-
).toContain("T3CODE_DISABLE_AUTO_UPDATE");
116+
).toContain("BCODE_DISABLE_AUTO_UPDATE");
117117
});
118118

119119
it("reports linux non-AppImage builds as disabled", () => {

apps/desktop/src/updateState.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export function getAutoUpdateDisabledReason(args: {
4343
return "Automatic updates are only available in packaged production builds.";
4444
}
4545
if (args.disabledByEnv) {
46-
return "Automatic updates are disabled by the T3CODE_DISABLE_AUTO_UPDATE setting.";
46+
return "Automatic updates are disabled by the BCODE_DISABLE_AUTO_UPDATE setting.";
4747
}
4848
if (args.platform === "linux" && !args.appImage) {
4949
return "Automatic updates on Linux require running the AppImage build.";

apps/server/integration/perf/serverPerfHarness.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ import type {
3636
import { seedPerfState, type PerfSeededState } from "./seedPerfState.ts";
3737

3838
const repoRoot = fileURLToPath(new URL("../../../../", import.meta.url));
39-
const PERF_ARTIFACT_DIR_ENV = "T3CODE_PERF_ARTIFACT_DIR";
40-
const PERF_PROVIDER_ENV = "T3CODE_PERF_PROVIDER";
41-
const PERF_SCENARIO_ENV = "T3CODE_PERF_SCENARIO";
42-
const AUTO_BOOTSTRAP_PROJECT_ENV = "T3CODE_AUTO_BOOTSTRAP_PROJECT_FROM_CWD";
39+
const PERF_ARTIFACT_DIR_ENV = "BCODE_PERF_ARTIFACT_DIR";
40+
const PERF_PROVIDER_ENV = "BCODE_PERF_PROVIDER";
41+
const PERF_SCENARIO_ENV = "BCODE_PERF_SCENARIO";
42+
const AUTO_BOOTSTRAP_PROJECT_ENV = "BCODE_AUTO_BOOTSTRAP_PROJECT_FROM_CWD";
4343

4444
const makeWsRpcClient = RpcClient.make(WsRpcGroup);
4545
type WsRpcClient =

0 commit comments

Comments
 (0)