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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user