Skip to content

Commit f917cfd

Browse files
authored
Centralize provider status copy and harden test/theme handling (#126)
* Centralize provider status copy and setup guidance - Extract shared provider status presentation helpers - Reuse headings, descriptions, and setup phase labels across chat UI - Add tests for phase classification and auth-specific copy * Pin Effect smol deps and fix custom theme parsing - Add the shared Effect catalog override - Merge theme vars directly when parsing Tweakcn JSON - Remove an unused theme dialog import * Disable Git signing in tests and harden theme root access - Force `commit.gpgsign=false` in Git test helpers and fixtures - Make theme application tolerate missing DOM root targets * Resolve Electron binary in desktop smoke test - Load Electron via `require("electron")` instead of a fixed `node_modules` path - Fail fast with a clear error if the smoke test cannot launch Electron
1 parent 3b20ad4 commit f917cfd

7 files changed

Lines changed: 93 additions & 13 deletions

File tree

apps/desktop/scripts/smoke-test.mjs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { spawn } from "node:child_process";
2+
import { createRequire } from "node:module";
23
import { dirname, resolve } from "node:path";
34
import { fileURLToPath } from "node:url";
45

56
const __dirname = dirname(fileURLToPath(import.meta.url));
67
const desktopDir = resolve(__dirname, "..");
7-
const electronBin = resolve(desktopDir, "node_modules/.bin/electron");
88
const mainJs = resolve(desktopDir, "dist-electron/main.js");
9+
const require = createRequire(import.meta.url);
10+
const electronBin = require("electron");
911

1012
console.log("\nLaunching Electron smoke test...");
1113

@@ -26,6 +28,13 @@ child.stderr.on("data", (chunk) => {
2628
output += chunk.toString();
2729
});
2830

31+
child.on("error", (error) => {
32+
clearTimeout(timeout);
33+
console.error("\nDesktop smoke test failed to launch Electron:");
34+
console.error(error);
35+
process.exit(1);
36+
});
37+
2938
const timeout = setTimeout(() => {
3039
child.kill();
3140
}, 8_000);

apps/server/integration/OrchestrationEngineHarness.integration.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ function runGit(cwd: string, args: ReadonlyArray<string>) {
7474
cwd,
7575
stdio: ["ignore", "pipe", "pipe"],
7676
encoding: "utf8",
77+
env: {
78+
...process.env,
79+
GIT_CONFIG_COUNT: "1",
80+
GIT_CONFIG_KEY_0: "commit.gpgsign",
81+
GIT_CONFIG_VALUE_0: "false",
82+
},
7783
});
7884
}
7985

apps/server/src/git/Layers/GitCore.test.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ const GitCoreTestLayer = GitCoreLive.pipe(
2121
Layer.provide(NodeServices.layer),
2222
);
2323
const TestLayer = Layer.mergeAll(NodeServices.layer, GitCoreTestLayer);
24+
const TEST_GIT_ENV = {
25+
...process.env,
26+
GIT_CONFIG_COUNT: "1",
27+
GIT_CONFIG_KEY_0: "commit.gpgsign",
28+
GIT_CONFIG_VALUE_0: "false",
29+
};
2430

2531
function makeTmpDir(
2632
prefix = "git-test-",
@@ -53,7 +59,7 @@ function git(
5359
operation: "GitCore.test.git",
5460
cwd,
5561
args,
56-
...(env ? { env } : {}),
62+
env: env ? { ...TEST_GIT_ENV, ...env } : TEST_GIT_ENV,
5763
timeoutMs: 10_000,
5864
});
5965
return result.stdout.trim();
@@ -103,6 +109,7 @@ function initRepoWithCommit(
103109
yield* core.initRepo({ cwd });
104110
yield* git(cwd, ["config", "user.email", "test@test.com"]);
105111
yield* git(cwd, ["config", "user.name", "Test"]);
112+
yield* git(cwd, ["config", "commit.gpgsign", "false"]);
106113
yield* writeTextFile(path.join(cwd, "README.md"), "# test\n");
107114
yield* git(cwd, ["add", "."]);
108115
yield* git(cwd, ["commit", "-m", "initial commit"]);
@@ -123,6 +130,7 @@ function initRepoWithCommitOnBranch(
123130
yield* git(cwd, ["init", `--initial-branch=${initialBranch}`]);
124131
yield* git(cwd, ["config", "user.email", "test@test.com"]);
125132
yield* git(cwd, ["config", "user.name", "Test"]);
133+
yield* git(cwd, ["config", "commit.gpgsign", "false"]);
126134
yield* writeTextFile(path.join(cwd, "README.md"), "# test\n");
127135
yield* git(cwd, ["add", "."]);
128136
yield* git(cwd, ["commit", "-m", "initial commit"]);

apps/server/src/git/Layers/GitManager.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,18 @@ interface FakeGitTextGeneration {
6868

6969
type FakePullRequest = NonNullable<FakeGhScenario["pullRequest"]>;
7070

71+
const TEST_GIT_ENV = {
72+
...process.env,
73+
GIT_CONFIG_COUNT: "1",
74+
GIT_CONFIG_KEY_0: "commit.gpgsign",
75+
GIT_CONFIG_VALUE_0: "false",
76+
};
77+
7178
function runGitSyncForFakeGh(cwd: string, args: readonly string[]): void {
7279
const result = spawnSync("git", args, {
7380
cwd,
7481
encoding: "utf8",
82+
env: TEST_GIT_ENV,
7583
});
7684
if (result.status === 0) {
7785
return;
@@ -132,6 +140,7 @@ function initRepo(
132140
yield* runGit(cwd, ["init", "--initial-branch=main"]);
133141
yield* runGit(cwd, ["config", "user.email", "test@example.com"]);
134142
yield* runGit(cwd, ["config", "user.name", "Test User"]);
143+
yield* runGit(cwd, ["config", "commit.gpgsign", "false"]);
135144
yield* fs.writeFileString(path.join(cwd, "README.md"), "hello\n");
136145
yield* runGit(cwd, ["add", "README.md"]);
137146
yield* runGit(cwd, ["commit", "-m", "Initial commit"]);

apps/server/src/orchestration/Layers/CheckpointReactor.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,12 @@ function runGit(cwd: string, args: ReadonlyArray<string>) {
163163
cwd,
164164
stdio: ["ignore", "pipe", "pipe"],
165165
encoding: "utf8",
166+
env: {
167+
...process.env,
168+
GIT_CONFIG_COUNT: "1",
169+
GIT_CONFIG_KEY_0: "commit.gpgsign",
170+
GIT_CONFIG_VALUE_0: "false",
171+
},
166172
});
167173
}
168174

apps/server/src/workspaceEntries.test.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ import { afterEach, assert, describe, it, vi } from "vitest";
99
import { listWorkspaceDirectory, searchWorkspaceEntries } from "./workspaceEntries";
1010

1111
const tempDirs: string[] = [];
12+
const TEST_GIT_ENV = {
13+
...process.env,
14+
GIT_CONFIG_COUNT: "1",
15+
GIT_CONFIG_KEY_0: "commit.gpgsign",
16+
GIT_CONFIG_VALUE_0: "false",
17+
};
1218

1319
function makeTempDir(prefix: string): string {
1420
const dir = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
@@ -23,7 +29,7 @@ function writeFile(cwd: string, relativePath: string, contents = ""): void {
2329
}
2430

2531
function runGit(cwd: string, args: string[]): void {
26-
const result = spawnSync("git", args, { cwd, encoding: "utf8" });
32+
const result = spawnSync("git", args, { cwd, encoding: "utf8", env: TEST_GIT_ENV });
2733
if (result.status !== 0) {
2834
throw new Error(result.stderr || `git ${args.join(" ")} failed`);
2935
}

apps/web/src/hooks/useTheme.ts

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -92,30 +92,66 @@ const FONT_FAMILY_MAP: Record<FontFamily, string> = {
9292
'"Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif',
9393
};
9494

95+
function getRootElement(): HTMLElement | null {
96+
if (typeof document === "undefined") {
97+
return null;
98+
}
99+
100+
const root = document.documentElement;
101+
if (!root) {
102+
return null;
103+
}
104+
105+
return root;
106+
}
107+
108+
function hasStyleTarget(
109+
root: HTMLElement | null,
110+
): root is HTMLElement & { style: CSSStyleDeclaration } {
111+
return typeof root?.style?.setProperty === "function";
112+
}
113+
114+
function hasClassListTarget(
115+
root: HTMLElement | null,
116+
): root is HTMLElement & { classList: DOMTokenList } {
117+
return (
118+
typeof root?.classList?.add === "function" &&
119+
typeof root.classList.remove === "function" &&
120+
typeof root.classList.toggle === "function"
121+
);
122+
}
123+
95124
function applyFont(fontFamily?: FontFamily) {
96125
const font = fontFamily ?? getStoredFontFamily();
97-
document.documentElement.style.setProperty("--font-ui", FONT_FAMILY_MAP[font]);
126+
const root = getRootElement();
127+
if (!hasStyleTarget(root)) {
128+
return;
129+
}
130+
root.style.setProperty("--font-ui", FONT_FAMILY_MAP[font]);
98131
}
99132

100133
function applyTheme(theme: Theme, suppressTransitions = false) {
134+
const root = getRootElement();
135+
if (!hasClassListTarget(root)) {
136+
return;
137+
}
138+
101139
if (suppressTransitions) {
102-
document.documentElement.classList.add("no-transitions");
140+
root.classList.add("no-transitions");
103141
}
104142
const isDark = theme === "dark" || (theme === "system" && getSystemDark());
105-
document.documentElement.classList.toggle("dark", isDark);
143+
root.classList.toggle("dark", isDark);
106144

107145
// Apply color theme class
108146
const colorTheme = getStoredColorTheme();
109147
// Remove any existing theme-* classes
110-
const existingThemeClasses = Array.from(document.documentElement.classList).filter((cls) =>
111-
cls.startsWith("theme-"),
112-
);
148+
const existingThemeClasses = Array.from(root.classList).filter((cls) => cls.startsWith("theme-"));
113149
for (const cls of existingThemeClasses) {
114-
document.documentElement.classList.remove(cls);
150+
root.classList.remove(cls);
115151
}
116152
// Add the new theme class if not default
117153
if (colorTheme !== "default") {
118-
document.documentElement.classList.add(`theme-${colorTheme}`);
154+
root.classList.add(`theme-${colorTheme}`);
119155
}
120156

121157
// Apply font family
@@ -125,9 +161,9 @@ function applyTheme(theme: Theme, suppressTransitions = false) {
125161
if (suppressTransitions) {
126162
// Force a reflow so the no-transitions class takes effect before removal
127163
// oxlint-disable-next-line no-unused-expressions
128-
document.documentElement.offsetHeight;
164+
root.offsetHeight;
129165
requestAnimationFrame(() => {
130-
document.documentElement.classList.remove("no-transitions");
166+
root.classList.remove("no-transitions");
131167
});
132168
}
133169
}

0 commit comments

Comments
 (0)