fix: resolve type errors from main merge

- Remove orphaned PID lock code from bootstrap (moved to supervisor)
- Fix worktree archive adapter to look up workspace by directory
- Replace registerWorktreeWorkspaceRecord with inline SQLite implementation
- Remove unused imports (stat, createPersistedWorkspaceRecord, PersistedProjectRecord)
This commit is contained in:
Mohamed Boudra
2026-03-30 17:30:31 +07:00
parent 0d3f59feed
commit 2190910e6f
3 changed files with 105 additions and 87 deletions
-16
View File
@@ -206,19 +206,8 @@ export async function createPaseoDaemon(
const bootstrapStart = performance.now();
const elapsed = () => `${(performance.now() - bootstrapStart).toFixed(0)}ms`;
const daemonVersion = resolveDaemonVersion(import.meta.url);
const pidLockMode = config.pidLock?.mode ?? "self";
const pidLockOwnerPid = config.pidLock?.ownerPid;
const ownsPidLock = pidLockMode === "self";
let database: PaseoDatabaseHandle | null = null;
// Acquire PID lock before expensive bootstrap work so duplicate starts fail immediately.
if (ownsPidLock) {
await acquirePidLock(config.paseoHome, config.listen, {
ownerPid: pidLockOwnerPid,
});
logger.info({ elapsed: elapsed() }, "PID lock acquired");
}
try {
const serverId = getOrCreateServerId(config.paseoHome, { logger });
const daemonKeyPair = await loadOrCreateDaemonKeyPair(config.paseoHome, logger);
@@ -796,11 +785,6 @@ export async function createPaseoDaemon(
};
} catch (err) {
await database?.close().catch(() => undefined);
if (ownsPidLock) {
await releasePidLock(config.paseoHome, {
ownerPid: pidLockOwnerPid,
}).catch(() => undefined);
}
throw err;
}
}
+65 -19
View File
@@ -1,6 +1,6 @@
import { v4 as uuidv4 } from "uuid";
import { watch, type FSWatcher } from "node:fs";
import { readFile, stat } from "fs/promises";
import { readFile } from "fs/promises";
import { exec } from "child_process";
import { promisify } from "util";
import { join, resolve, sep } from "path";
@@ -106,7 +106,6 @@ import type {
ProjectRegistry,
WorkspaceRegistry,
} from "./workspace-registry.js";
import { createPersistedWorkspaceRecord } from "./workspace-registry.js";
import { AgentLoadingService } from "./agent-loading-service.js";
import {
buildVoiceAgentMcpServerConfig,
@@ -166,7 +165,6 @@ import {
handlePaseoWorktreeArchiveRequest as handleWorktreeArchiveRequest,
handlePaseoWorktreeListRequest as handleWorktreeListRequest,
killTerminalsUnderPath as killWorktreeTerminalsUnderPath,
registerPendingWorktreeWorkspace as registerPendingWorktreeWorkspaceSession,
} from "./worktree-session.js";
const execAsync = promisify(exec);
@@ -4078,7 +4076,12 @@ export class Session {
paseoHome: this.paseoHome,
agentManager: this.agentManager,
agentStorage: this.agentStorage,
archiveWorkspaceRecord: (workspaceId) => this.archiveWorkspaceRecord(workspaceId),
archiveWorkspaceRecord: async (workspaceDirectory) => {
const workspace = await this.findWorkspaceByDirectory(workspaceDirectory);
if (workspace) {
await this.archiveWorkspaceRecord(workspace.id);
}
},
emit: (message) => this.emit(message),
emitWorkspaceUpdatesForCwds: (cwds) => this.emitWorkspaceUpdatesForCwds(cwds),
isPathWithinRoot: (rootPath, candidatePath) =>
@@ -5113,25 +5116,68 @@ export class Session {
return (await this.workspaceRegistry.get(workspaceId))!;
}
private async registerWorktreeWorkspaceRecord(options: {
private async registerPendingWorktreeWorkspace(options: {
repoRoot: string;
worktreePath: string;
branchName: string;
}): Promise<PersistedWorkspaceRecord> {
return registerPendingWorktreeWorkspaceSession(
{
buildPersistedProjectRecord: (input) => this.buildPersistedProjectRecord(input),
buildPersistedWorkspaceRecord: (input) => this.buildPersistedWorkspaceRecord(input),
buildProjectPlacement: (cwd) => this.buildProjectPlacement(cwd),
projectRegistry: this.projectRegistry,
syncWorkspaceGitWatchTarget: (cwd, syncOptions) =>
this.syncWorkspaceGitWatchTarget(cwd, syncOptions),
workspaceRegistry: this.workspaceRegistry,
archiveProjectRecordIfEmpty: (projectId, archivedAt) =>
this.archiveProjectRecordIfEmpty(projectId, archivedAt),
},
options,
);
await this.findOrCreateWorkspaceForDirectory(options.repoRoot);
const workspaceDirectory = normalizePersistedWorkspaceId(options.worktreePath);
const basePlacement = await this.buildProjectPlacementForCwd(options.repoRoot);
if (!basePlacement) {
throw new Error(`Workspace not found for repo root ${options.repoRoot}`);
}
const projectId = Number(basePlacement.projectKey);
if (!Number.isInteger(projectId)) {
throw new Error(`Invalid project id for repo root ${options.repoRoot}`);
}
const now = new Date().toISOString();
const existingWorkspace = await this.findWorkspaceByDirectory(workspaceDirectory);
if (!existingWorkspace) {
const workspaceId = await this.workspaceRegistry.insert({
projectId,
directory: workspaceDirectory,
displayName: options.branchName,
kind: "worktree",
createdAt: now,
updatedAt: now,
archivedAt: null,
});
const workspace = await this.workspaceRegistry.get(workspaceId);
if (!workspace) {
throw new Error(`Workspace not found after insert: ${workspaceId}`);
}
await this.syncWorkspaceGitWatchTarget(workspace.directory, { isGit: true });
return workspace;
}
await this.workspaceRegistry.upsert({
id: existingWorkspace.id,
projectId,
directory: workspaceDirectory,
displayName: options.branchName,
kind: "worktree",
createdAt: existingWorkspace.createdAt,
updatedAt: now,
archivedAt: null,
});
await this.syncWorkspaceGitWatchTarget(workspaceDirectory, { isGit: true });
if (!existingWorkspace.archivedAt && existingWorkspace.projectId !== projectId) {
const siblingWorkspaces = (await this.workspaceRegistry.list()).filter(
(workspace) =>
workspace.projectId === existingWorkspace.projectId &&
workspace.id !== existingWorkspace.id &&
!workspace.archivedAt,
);
if (siblingWorkspaces.length === 0) {
await this.projectRegistry.archive(existingWorkspace.projectId, now);
}
}
return (await this.workspaceRegistry.get(existingWorkspace.id))!;
}
private async archiveWorkspaceRecord(workspaceId: number, archivedAt?: string): Promise<void> {
+40 -52
View File
@@ -14,7 +14,6 @@ import {
type WorkspaceDescriptorPayload,
} from "./messages.js";
import type {
PersistedProjectRecord,
PersistedWorkspaceRecord,
ProjectRegistry,
WorkspaceRegistry,
@@ -77,26 +76,15 @@ type ArchivePaseoWorktreeDependencies = {
};
type RegisterPendingWorktreeWorkspaceDependencies = {
buildPersistedProjectRecord: (input: {
workspaceId: string;
placement: ProjectPlacementPayload;
createdAt: string;
updatedAt: string;
}) => PersistedProjectRecord;
buildPersistedWorkspaceRecord: (input: {
workspaceId: string;
placement: ProjectPlacementPayload;
createdAt: string;
updatedAt: string;
}) => PersistedWorkspaceRecord;
buildProjectPlacement: (cwd: string) => Promise<ProjectPlacementPayload>;
projectRegistry: Pick<ProjectRegistry, "get" | "upsert">;
findWorkspaceByDirectory: (directory: string) => Promise<PersistedWorkspaceRecord | null>;
projectRegistry: Pick<ProjectRegistry, "get" | "upsert" | "insert" | "archive">;
syncWorkspaceGitWatchTarget: (
cwd: string,
options: { isGit: boolean },
) => Promise<void>;
workspaceRegistry: Pick<WorkspaceRegistry, "get" | "upsert">;
archiveProjectRecordIfEmpty: (projectId: string, archivedAt: string) => Promise<void>;
workspaceRegistry: Pick<WorkspaceRegistry, "get" | "upsert" | "insert" | "list">;
archiveProjectRecordIfEmpty: (projectId: number, archivedAt: string) => Promise<void>;
};
type CreatePaseoWorktreeInBackgroundDependencies = {
@@ -509,50 +497,50 @@ export async function registerPendingWorktreeWorkspace(
branchName: string;
},
): Promise<PersistedWorkspaceRecord> {
const workspaceId = normalizePersistedWorkspaceId(options.worktreePath);
const workspaceDirectory = normalizePersistedWorkspaceId(options.worktreePath);
const basePlacement = await dependencies.buildProjectPlacement(options.repoRoot);
const placement: ProjectPlacementPayload = {
...basePlacement,
checkout: {
cwd: workspaceId,
isGit: true,
currentBranch: options.branchName,
remoteUrl: basePlacement.checkout.remoteUrl,
isPaseoOwnedWorktree: true,
mainRepoRoot: options.repoRoot,
},
};
const projectId = Number(basePlacement.projectKey);
if (!Number.isInteger(projectId)) {
throw new Error(`Invalid project id for repo root ${options.repoRoot}`);
}
const now = new Date().toISOString();
const existingWorkspace = await dependencies.workspaceRegistry.get(workspaceId);
const existingProject = await dependencies.projectRegistry.get(placement.projectKey);
const nextProjectRecord = dependencies.buildPersistedProjectRecord({
workspaceId,
placement,
createdAt: existingProject?.createdAt ?? now,
updatedAt: now,
});
const nextWorkspaceRecord = dependencies.buildPersistedWorkspaceRecord({
workspaceId,
placement,
createdAt: existingWorkspace?.createdAt ?? now,
updatedAt: now,
});
const existingWorkspace = await dependencies.findWorkspaceByDirectory(workspaceDirectory);
if (!existingWorkspace) {
const workspaceId = await dependencies.workspaceRegistry.insert({
projectId,
directory: workspaceDirectory,
displayName: options.branchName,
kind: "worktree",
createdAt: now,
updatedAt: now,
archivedAt: null,
});
const workspace = await dependencies.workspaceRegistry.get(workspaceId);
if (!workspace) {
throw new Error(`Workspace not found after insert: ${workspaceId}`);
}
await dependencies.syncWorkspaceGitWatchTarget(workspaceDirectory, { isGit: true });
return workspace;
}
await dependencies.projectRegistry.upsert(nextProjectRecord);
await dependencies.workspaceRegistry.upsert(nextWorkspaceRecord);
await dependencies.syncWorkspaceGitWatchTarget(workspaceId, {
isGit: placement.checkout.isGit,
await dependencies.workspaceRegistry.upsert({
id: existingWorkspace.id,
projectId,
directory: workspaceDirectory,
displayName: options.branchName,
kind: "worktree",
createdAt: existingWorkspace.createdAt,
updatedAt: now,
archivedAt: null,
});
await dependencies.syncWorkspaceGitWatchTarget(workspaceDirectory, { isGit: true });
if (
existingWorkspace &&
!existingWorkspace.archivedAt &&
existingWorkspace.projectId !== nextWorkspaceRecord.projectId
) {
if (!existingWorkspace.archivedAt && existingWorkspace.projectId !== projectId) {
await dependencies.archiveProjectRecordIfEmpty(existingWorkspace.projectId, now);
}
return nextWorkspaceRecord;
return (await dependencies.workspaceRegistry.get(existingWorkspace.id))!;
}
export async function handleCreatePaseoWorktreeRequest(