Merge branch 'main' into dev

Resolve 38 conflicts preserving both sides' work:
- Server: DB-based registries (dev) + WorkspaceGitService/DaemonConfigStore (main)
- App: script proxy/voice MCP (dev) + pin/hide tabs/bootstrap boundary (main)
- Shared: WorkspaceScriptPayload (dev) + git/GitHub runtime schemas (main)
- Deleted workspace-registry-bootstrap.ts (dev's DB approach supersedes)
This commit is contained in:
Mohamed Boudra
2026-04-14 03:05:45 +07:00
333 changed files with 13490 additions and 6317 deletions
@@ -617,7 +617,9 @@ const x = 1;
writeFileSync(join(repoDir, "conflict.txt"), "local\n");
execSync("git add conflict.txt", { cwd: repoDir });
execSync("git -c commit.gpgsign=false commit -m 'local rebase conflict commit'", { cwd: repoDir });
execSync("git -c commit.gpgsign=false commit -m 'local rebase conflict commit'", {
cwd: repoDir,
});
const otherClone = join(tempDir, "other-clone");
execSync(`git clone ${remoteDir} ${otherClone}`);
+19 -20
View File
@@ -191,7 +191,6 @@ type CheckoutFileChange = {
isUntracked?: boolean;
};
function normalizeBranchSuggestionName(raw: string): string | null {
const trimmed = raw.trim();
if (!trimmed) {
@@ -678,7 +677,7 @@ async function requireGitRepo(cwd: string): Promise<void> {
}
}
async function getCurrentBranch(cwd: string): Promise<string | null> {
export async function getCurrentBranch(cwd: string): Promise<string | null> {
const { stdout } = await execAsync("git rev-parse --abbrev-ref HEAD", {
cwd,
env: READ_ONLY_GIT_ENV,
@@ -700,7 +699,7 @@ async function getWorktreeRoot(cwd: string): Promise<string | null> {
}
}
async function getMainRepoRoot(cwd: string): Promise<string> {
export async function getMainRepoRoot(cwd: string): Promise<string> {
const { stdout: commonDirOut } = await execAsync(
"git rev-parse --path-format=absolute --git-common-dir",
{ cwd, env: READ_ONLY_GIT_ENV },
@@ -717,9 +716,7 @@ async function getMainRepoRoot(cwd: string): Promise<string> {
env: READ_ONLY_GIT_ENV,
});
const worktrees = parseWorktreeList(worktreeOut);
const nonBareNonPaseo = worktrees.filter(
(wt) => !wt.isBare && !isPaseoWorktreePath(wt.path),
);
const nonBareNonPaseo = worktrees.filter((wt) => !wt.isBare && !isPaseoWorktreePath(wt.path));
const childrenOfBareRepo = nonBareNonPaseo.filter((wt) => isDescendantPath(wt.path, normalized));
const mainChild = childrenOfBareRepo.find((wt) => basename(wt.path) === "main");
return mainChild?.path ?? childrenOfBareRepo[0]?.path ?? nonBareNonPaseo[0]?.path ?? normalized;
@@ -844,7 +841,7 @@ async function isWorkingTreeDirty(cwd: string): Promise<boolean> {
return stdout.trim().length > 0;
}
async function getOriginRemoteUrl(cwd: string): Promise<string | null> {
export async function getOriginRemoteUrl(cwd: string): Promise<string | null> {
try {
const { stdout } = await execAsync("git config --get remote.origin.url", {
cwd,
@@ -857,12 +854,12 @@ async function getOriginRemoteUrl(cwd: string): Promise<string | null> {
}
}
async function hasOriginRemote(cwd: string): Promise<boolean> {
export async function hasOriginRemote(cwd: string): Promise<boolean> {
const url = await getOriginRemoteUrl(cwd);
return url !== null;
}
async function resolveAbsoluteGitDir(cwd: string): Promise<string | null> {
export async function resolveAbsoluteGitDir(cwd: string): Promise<string | null> {
try {
const { stdout } = await execAsync("git rev-parse --absolute-git-dir", {
cwd,
@@ -1042,7 +1039,16 @@ async function getAheadOfOrigin(cwd: string, currentBranch: string): Promise<num
const count = Number.parseInt(stdout.trim(), 10);
return Number.isNaN(count) ? null : count;
} catch {
return null;
try {
const { stdout } = await execAsync(`git rev-list --count ${currentBranch}`, {
cwd,
env: READ_ONLY_GIT_ENV,
});
const count = Number.parseInt(stdout.trim(), 10);
return Number.isNaN(count) ? null : count;
} catch {
return null;
}
}
}
@@ -1630,11 +1636,7 @@ export async function getCheckoutDiff(
if (diffBytes >= TOTAL_DIFF_MAX_BYTES) {
break;
}
const { text, truncated, stat } = await getUntrackedDiffText(
cwd,
change,
ignoreWhitespace,
);
const { text, truncated, stat } = await getUntrackedDiffText(cwd, change, ignoreWhitespace);
if (!compare.includeStructured) {
if (stat?.isBinary) {
@@ -2015,7 +2017,7 @@ type CheckRunNode = z.infer<typeof CheckRunNodeSchema>;
type StatusContextNode = z.infer<typeof StatusContextNodeSchema>;
async function resolveGhPath(): Promise<string> {
export async function resolveGhPath(): Promise<string> {
if (cachedGhPath === undefined) {
cachedGhPath = await findExecutable("gh");
}
@@ -2238,7 +2240,6 @@ async function resolveGitHubRepo(cwd: string): Promise<string | null> {
return null;
}
export async function createPullRequest(
cwd: string,
options: CreatePullRequestOptions,
@@ -2340,9 +2341,7 @@ async function getPullRequestStatusUncached(cwd: string): Promise<PullRequestSta
return { status: null, githubFeaturesEnabled: true };
}
const mergedAt =
typeof pr.mergedAt === "string" && pr.mergedAt.trim().length > 0
? pr.mergedAt
: null;
typeof pr.mergedAt === "string" && pr.mergedAt.trim().length > 0 ? pr.mergedAt : null;
const state =
mergedAt !== null
? "merged"
+8 -14
View File
@@ -1,10 +1,6 @@
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
import {
findExecutableSync,
quoteWindowsArgument,
quoteWindowsCommand,
} from "./executable.js";
import { findExecutableSync, quoteWindowsArgument, quoteWindowsCommand } from "./executable.js";
type FindExecutableDependencies = NonNullable<Parameters<typeof findExecutableSync>[1]>;
@@ -46,20 +42,18 @@ describe("findExecutableSync", () => {
"C:\\nvm4w\\nodejs\\codex\r\nC:\\nvm4w\\nodejs\\codex.cmd\r\n",
);
expect(findExecutableSync("codex", findExecutableDependencies)).toBe("C:\\nvm4w\\nodejs\\codex");
expect(findExecutableSync("codex", findExecutableDependencies)).toBe(
"C:\\nvm4w\\nodejs\\codex",
);
});
test("on Unix, uses the last line from which output", () => {
findExecutableDependencies.execFileSync.mockReturnValue(
"/usr/local/bin/codex\n",
);
findExecutableDependencies.execFileSync.mockReturnValue("/usr/local/bin/codex\n");
expect(findExecutableSync("codex", findExecutableDependencies)).toBe("/usr/local/bin/codex");
expect(findExecutableDependencies.execFileSync).toHaveBeenCalledWith(
"which",
["codex"],
{ encoding: "utf8" },
);
expect(findExecutableDependencies.execFileSync).toHaveBeenCalledWith("which", ["codex"], {
encoding: "utf8",
});
});
test("warns and returns null when the final which line is not an absolute path", () => {
+6 -5
View File
@@ -66,10 +66,12 @@ export function findExecutableSync(
if (deps.platform() === "win32") {
try {
const out = deps.execFileSync("where.exe", [trimmed], {
encoding: "utf8",
windowsHide: true,
}).trim();
const out = deps
.execFileSync("where.exe", [trimmed], {
encoding: "utf8",
windowsHide: true,
})
.trim();
return (
out
.split(/\r?\n/)
@@ -160,4 +162,3 @@ export function quoteWindowsArgument(argument: string): string {
if (argument.startsWith('"') && argument.endsWith('"')) return argument;
return `"${argument}"`;
}
+1 -5
View File
@@ -1,8 +1,4 @@
import {
spawn,
type ChildProcess,
type SpawnOptions,
} from "node:child_process";
import { spawn, type ChildProcess, type SpawnOptions } from "node:child_process";
/**
* Platform-aware spawn that centralizes Windows shell and quoting concerns.
+2 -3
View File
@@ -13,9 +13,7 @@ import {
runWorktreeSetupCommands,
slugify,
} from "./worktree";
import {
getPaseoWorktreeMetadataPath,
} from "./worktree-metadata.js";
import { getPaseoWorktreeMetadataPath } from "./worktree-metadata.js";
import { execSync } from "child_process";
import { mkdtempSync, rmSync, existsSync, realpathSync, writeFileSync, readFileSync } from "fs";
import { dirname, join } from "path";
@@ -161,6 +159,7 @@ describe("createWorktree", () => {
execSync(`git clone ${remoteDir} ${remoteCloneDir}`);
execSync("git config user.email 'test@test.com'", { cwd: remoteCloneDir });
execSync("git config user.name 'Test'", { cwd: remoteCloneDir });
execSync("git checkout -B main origin/main", { cwd: remoteCloneDir });
writeFileSync(join(remoteCloneDir, "file.txt"), "from-origin\n");
execSync("git add file.txt", { cwd: remoteCloneDir });
execSync("git -c commit.gpgsign=false commit -m 'advance origin main'", {