@getpaseo/server 0.1.88 → 0.1.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server/server/agent/agent-manager.js +4 -1
- package/dist/server/server/agent/agent-prompt.js +4 -1
- package/dist/server/server/agent/agent-sdk-types.d.ts +1 -0
- package/dist/server/server/agent/agent-storage.d.ts +22 -22
- package/dist/server/server/agent/agent-storage.js +2 -9
- package/dist/server/server/agent/create-agent/create.d.ts +2 -0
- package/dist/server/server/agent/create-agent/create.js +26 -7
- package/dist/server/server/agent/create-agent-lifecycle-dispatch.d.ts +1 -0
- package/dist/server/server/agent/create-agent-lifecycle-dispatch.js +4 -0
- package/dist/server/server/agent/create-agent-mode.d.ts +3 -8
- package/dist/server/server/agent/create-agent-mode.js +16 -2
- package/dist/server/server/agent/import-sessions.js +1 -1
- package/dist/server/server/agent/mcp-server.d.ts +1 -0
- package/dist/server/server/agent/mcp-server.js +113 -70
- package/dist/server/server/agent/provider-snapshot-manager.d.ts +2 -1
- package/dist/server/server/agent/provider-snapshot-manager.js +18 -2
- package/dist/server/server/agent/providers/acp-agent.d.ts +3 -3
- package/dist/server/server/agent/providers/acp-agent.js +18 -13
- package/dist/server/server/agent/providers/codex-app-server-agent.js +16 -22
- package/dist/server/server/agent/providers/mock-load-test-agent.d.ts +2 -0
- package/dist/server/server/agent/providers/mock-load-test-agent.js +69 -2
- package/dist/server/server/agent/providers/opencode-agent.js +19 -8
- package/dist/server/server/agent/providers/pi/agent.js +13 -0
- package/dist/server/server/agent/providers/pi/rpc-types.d.ts +3 -0
- package/dist/server/server/agent/timeline-projection.js +30 -1
- package/dist/server/server/atomic-file.d.ts +3 -0
- package/dist/server/server/atomic-file.js +19 -0
- package/dist/server/server/auto-archive-on-merge/archive-if-safe.d.ts +1 -0
- package/dist/server/server/auto-archive-on-merge/archive-if-safe.js +10 -2
- package/dist/server/server/bootstrap.d.ts +7 -2
- package/dist/server/server/bootstrap.js +154 -115
- package/dist/server/server/chat/chat-service.js +2 -4
- package/dist/server/server/config.js +41 -0
- package/dist/server/server/daemon-keypair.js +2 -2
- package/dist/server/server/loop-service.d.ts +26 -22
- package/dist/server/server/loop-service.js +27 -9
- package/dist/server/server/package-version.d.ts +2 -2
- package/dist/server/server/paseo-worktree-archive-service.d.ts +2 -0
- package/dist/server/server/paseo-worktree-archive-service.js +28 -9
- package/dist/server/server/persisted-config.d.ts +84 -28
- package/dist/server/server/persisted-config.js +20 -3
- package/dist/server/server/pid-lock.d.ts +2 -2
- package/dist/server/server/private-files.d.ts +0 -1
- package/dist/server/server/private-files.js +0 -5
- package/dist/server/server/schedule/service.d.ts +6 -0
- package/dist/server/server/schedule/service.js +41 -18
- package/dist/server/server/schedule/store.js +3 -2
- package/dist/server/server/script-health-monitor.d.ts +4 -4
- package/dist/server/server/script-health-monitor.js +6 -6
- package/dist/server/server/script-proxy.d.ts +2 -39
- package/dist/server/server/script-proxy.js +1 -244
- package/dist/server/server/script-route-branch-handler.d.ts +2 -2
- package/dist/server/server/script-route-branch-handler.js +3 -37
- package/dist/server/server/script-status-projection.d.ts +6 -4
- package/dist/server/server/script-status-projection.js +85 -37
- package/dist/server/server/server-id.js +3 -3
- package/dist/server/server/service-proxy.d.ts +237 -0
- package/dist/server/server/service-proxy.js +714 -0
- package/dist/server/server/session.d.ts +12 -18
- package/dist/server/server/session.js +206 -117
- package/dist/server/server/speech/providers/local/worker-client.js +1 -11
- package/dist/server/server/websocket-server.d.ts +7 -4
- package/dist/server/server/websocket-server.js +9 -4
- package/dist/server/server/workspace-bootstrap-dedupe.d.ts +34 -0
- package/dist/server/server/workspace-bootstrap-dedupe.js +23 -0
- package/dist/server/server/workspace-directory.d.ts +8 -0
- package/dist/server/server/workspace-directory.js +141 -11
- package/dist/server/server/workspace-git-service.d.ts +3 -0
- package/dist/server/server/workspace-git-service.js +53 -12
- package/dist/server/server/workspace-registry.d.ts +2 -2
- package/dist/server/server/workspace-registry.js +2 -6
- package/dist/server/server/workspace-service-env.d.ts +1 -0
- package/dist/server/server/workspace-service-env.js +23 -18
- package/dist/server/server/worktree/commands.d.ts +2 -0
- package/dist/server/server/worktree/commands.js +4 -1
- package/dist/server/server/worktree-bootstrap.d.ts +4 -3
- package/dist/server/server/worktree-bootstrap.js +14 -13
- package/dist/server/server/worktree-core.d.ts +1 -0
- package/dist/server/server/worktree-core.js +2 -0
- package/dist/server/server/worktree-session.d.ts +6 -2
- package/dist/server/server/worktree-session.js +3 -0
- package/dist/server/services/github-service.d.ts +1 -0
- package/dist/server/services/github-service.js +7 -1
- package/dist/server/utils/checkout-git.d.ts +6 -3
- package/dist/server/utils/checkout-git.js +40 -38
- package/dist/server/utils/worktree.d.ts +17 -12
- package/dist/server/utils/worktree.js +39 -22
- package/dist/src/server/persisted-config.js +20 -3
- package/dist/src/server/private-files.js +0 -5
- package/package.json +9 -7
- package/dist/server/server/editor-targets.d.ts +0 -18
- package/dist/server/server/editor-targets.js +0 -109
- package/dist/server/utils/script-hostname.d.ts +0 -8
- package/dist/server/utils/script-hostname.js +0 -14
|
@@ -17,6 +17,7 @@ export async function createPaseoWorktreeCommand(dependencies, input) {
|
|
|
17
17
|
...input,
|
|
18
18
|
runSetup: false,
|
|
19
19
|
paseoHome: input.paseoHome ?? dependencies.paseoHome,
|
|
20
|
+
worktreesRoot: input.worktreesRoot ?? dependencies.worktreesRoot,
|
|
20
21
|
});
|
|
21
22
|
return { ok: true, createdWorktree };
|
|
22
23
|
}
|
|
@@ -32,6 +33,7 @@ export async function archivePaseoWorktreeCommand(dependencies, input) {
|
|
|
32
33
|
const resolvedTarget = await resolveArchiveTarget(dependencies, input);
|
|
33
34
|
const ownership = await isPaseoOwnedWorktreeCwd(resolvedTarget.targetPath, {
|
|
34
35
|
paseoHome: dependencies.paseoHome,
|
|
36
|
+
worktreesRoot: dependencies.worktreesRoot,
|
|
35
37
|
});
|
|
36
38
|
if (!ownership.allowed) {
|
|
37
39
|
return {
|
|
@@ -46,6 +48,7 @@ export async function archivePaseoWorktreeCommand(dependencies, input) {
|
|
|
46
48
|
targetPath: resolvedTarget.targetPath,
|
|
47
49
|
repoRoot,
|
|
48
50
|
worktreesRoot: ownership.worktreeRoot,
|
|
51
|
+
worktreesBaseRoot: dependencies.worktreesRoot,
|
|
49
52
|
requestId: input.requestId,
|
|
50
53
|
});
|
|
51
54
|
return {
|
|
@@ -78,7 +81,7 @@ async function resolveArchiveTarget(dependencies, input) {
|
|
|
78
81
|
throw new Error("worktreePath, worktreeSlug, or repoRoot+branchName is required");
|
|
79
82
|
}
|
|
80
83
|
async function resolveWorktreeSlugPath(dependencies, repoRoot, worktreeSlug) {
|
|
81
|
-
const worktreesRoot = await getPaseoWorktreesRoot(repoRoot, dependencies.paseoHome);
|
|
84
|
+
const worktreesRoot = await getPaseoWorktreesRoot(repoRoot, dependencies.paseoHome, dependencies.worktreesRoot);
|
|
82
85
|
return join(worktreesRoot, worktreeSlug);
|
|
83
86
|
}
|
|
84
87
|
//# sourceMappingURL=commands.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Logger } from "pino";
|
|
2
2
|
import type { TerminalManager } from "../terminal/terminal-manager.js";
|
|
3
3
|
import { runWorktreeSetupCommands, type WorktreeConfig, type WorktreeSetupCommandResult } from "../utils/worktree.js";
|
|
4
|
-
import { type
|
|
4
|
+
import { type ServiceProxySubsystem } from "./service-proxy.js";
|
|
5
5
|
import type { WorkspaceScriptRuntimeStore } from "./workspace-script-runtime-store.js";
|
|
6
6
|
import type { AgentTimelineItem, ToolCallDetail } from "./agent/agent-sdk-types.js";
|
|
7
7
|
export interface WorktreeBootstrapTerminalResult {
|
|
@@ -58,7 +58,8 @@ interface SpawnWorkspaceScriptOptions {
|
|
|
58
58
|
scriptName: string;
|
|
59
59
|
daemonPort?: number | null;
|
|
60
60
|
daemonListenHost?: string | null;
|
|
61
|
-
|
|
61
|
+
serviceProxyPublicBaseUrl?: string | null;
|
|
62
|
+
serviceProxy: ServiceProxySubsystem;
|
|
62
63
|
runtimeStore: WorkspaceScriptRuntimeStore;
|
|
63
64
|
terminalManager: TerminalManager;
|
|
64
65
|
logger?: Logger;
|
|
@@ -67,7 +68,7 @@ interface SpawnWorkspaceScriptOptions {
|
|
|
67
68
|
export declare function spawnWorkspaceScript(options: SpawnWorkspaceScriptOptions): Promise<WorktreeScriptResult>;
|
|
68
69
|
export declare function teardownWorktreeScripts(options: {
|
|
69
70
|
hostnames: string[];
|
|
70
|
-
|
|
71
|
+
serviceProxy: Pick<ServiceProxySubsystem, "removeServiceRoutesByHostnames">;
|
|
71
72
|
logger: Logger;
|
|
72
73
|
}): void;
|
|
73
74
|
export {};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { v4 as uuidv4 } from "uuid";
|
|
2
|
-
import { buildScriptHostname } from "../utils/script-hostname.js";
|
|
3
2
|
import { getScriptConfigs, getWorktreeTerminalSpecs, isServiceScript, paseoConfigParseError, processCarriageReturns, readPaseoConfig, resolveWorktreeRuntimeEnv, runWorktreeSetupCommands, WorktreeSetupError, } from "../utils/worktree.js";
|
|
4
|
-
import { findFreePort } from "./
|
|
3
|
+
import { findFreePort } from "./service-proxy.js";
|
|
5
4
|
import { assertNoServiceEnvNameCollisions, buildWorkspaceServiceEnv, } from "./workspace-service-env.js";
|
|
6
5
|
import { ensureWorkspaceServicePortPlan, requirePlannedWorkspaceServicePort, refreshWorkspaceServicePort, } from "./workspace-service-port-registry.js";
|
|
7
6
|
const MAX_WORKTREE_SETUP_COMMAND_OUTPUT_BYTES = 64 * 1024;
|
|
@@ -501,8 +500,7 @@ export async function runAsyncWorktreeBootstrap(options) {
|
|
|
501
500
|
await runWorktreeTerminalBootstrap(options, runtimeEnv);
|
|
502
501
|
}
|
|
503
502
|
async function setupServiceScriptRoute(params) {
|
|
504
|
-
const { scriptConfigs, config, scriptName, projectSlug, branchName, workspaceId, daemonPort, daemonListenHost, existingRuntimeEntry,
|
|
505
|
-
const hostname = buildScriptHostname({ projectSlug, branchName, scriptName });
|
|
503
|
+
const { scriptConfigs, config, scriptName, projectSlug, branchName, workspaceId, daemonPort, daemonListenHost, serviceProxyPublicBaseUrl, existingRuntimeEntry, serviceProxy, } = params;
|
|
506
504
|
const serviceDeclarations = [];
|
|
507
505
|
for (const [configuredScriptName, scriptConfig] of scriptConfigs) {
|
|
508
506
|
if (isServiceScript(scriptConfig)) {
|
|
@@ -538,16 +536,18 @@ async function setupServiceScriptRoute(params) {
|
|
|
538
536
|
branchName,
|
|
539
537
|
daemonPort,
|
|
540
538
|
daemonListenHost,
|
|
539
|
+
serviceProxyPublicBaseUrl,
|
|
541
540
|
peers,
|
|
542
541
|
});
|
|
543
|
-
|
|
544
|
-
hostname,
|
|
542
|
+
const registeredRoute = serviceProxy.registerWorkspaceService({
|
|
545
543
|
port,
|
|
546
544
|
workspaceId,
|
|
547
545
|
projectSlug,
|
|
546
|
+
branchName,
|
|
548
547
|
scriptName,
|
|
548
|
+
publicBaseUrl: serviceProxyPublicBaseUrl ?? null,
|
|
549
549
|
});
|
|
550
|
-
return { hostname, port, env };
|
|
550
|
+
return { hostname: registeredRoute.hostname, port, env };
|
|
551
551
|
}
|
|
552
552
|
async function acquireWorkspaceScriptTerminal(params) {
|
|
553
553
|
const { serviceScript, existingRuntimeEntry, terminalManager, repoRoot, scriptName, env } = params;
|
|
@@ -565,7 +565,7 @@ async function acquireWorkspaceScriptTerminal(params) {
|
|
|
565
565
|
return { terminal, reusableTerminal };
|
|
566
566
|
}
|
|
567
567
|
export async function spawnWorkspaceScript(options) {
|
|
568
|
-
const { repoRoot, workspaceId, projectSlug, branchName, scriptName, daemonPort, daemonListenHost,
|
|
568
|
+
const { repoRoot, workspaceId, projectSlug, branchName, scriptName, daemonPort, daemonListenHost, serviceProxyPublicBaseUrl, serviceProxy, runtimeStore, terminalManager, logger, onLifecycleChanged, } = options;
|
|
569
569
|
const configResult = readPaseoConfig(repoRoot);
|
|
570
570
|
if (!configResult.ok) {
|
|
571
571
|
throw paseoConfigParseError(configResult);
|
|
@@ -598,8 +598,9 @@ export async function spawnWorkspaceScript(options) {
|
|
|
598
598
|
workspaceId,
|
|
599
599
|
daemonPort,
|
|
600
600
|
daemonListenHost,
|
|
601
|
+
serviceProxyPublicBaseUrl,
|
|
601
602
|
existingRuntimeEntry,
|
|
602
|
-
|
|
603
|
+
serviceProxy,
|
|
603
604
|
});
|
|
604
605
|
hostname = serviceSetup.hostname;
|
|
605
606
|
port = serviceSetup.port;
|
|
@@ -631,7 +632,7 @@ export async function spawnWorkspaceScript(options) {
|
|
|
631
632
|
disposeLifecycleListeners?.();
|
|
632
633
|
disposeLifecycleListeners = null;
|
|
633
634
|
if (input.removeRoute && hostname) {
|
|
634
|
-
|
|
635
|
+
serviceProxy.removeWorkspaceService({ workspaceId, scriptName });
|
|
635
636
|
}
|
|
636
637
|
runtimeStore.set({
|
|
637
638
|
workspaceId,
|
|
@@ -689,7 +690,7 @@ export async function spawnWorkspaceScript(options) {
|
|
|
689
690
|
catch (error) {
|
|
690
691
|
disposeLifecycleListeners?.();
|
|
691
692
|
if (routeRegistered && hostname) {
|
|
692
|
-
|
|
693
|
+
serviceProxy.removeServiceRoutesByHostnames([hostname]);
|
|
693
694
|
}
|
|
694
695
|
if (runtimeRegistered) {
|
|
695
696
|
runtimeStore.remove({ workspaceId, scriptName });
|
|
@@ -707,9 +708,9 @@ export async function spawnWorkspaceScript(options) {
|
|
|
707
708
|
}
|
|
708
709
|
}
|
|
709
710
|
export function teardownWorktreeScripts(options) {
|
|
710
|
-
const { hostnames,
|
|
711
|
+
const { hostnames, serviceProxy, logger } = options;
|
|
712
|
+
serviceProxy.removeServiceRoutesByHostnames(hostnames);
|
|
711
713
|
for (const hostname of hostnames) {
|
|
712
|
-
routeStore.removeRoute(hostname);
|
|
713
714
|
logger.info({ hostname }, "Removed script proxy route");
|
|
714
715
|
}
|
|
715
716
|
}
|
|
@@ -54,6 +54,7 @@ export async function createWorktreeCore(input, deps) {
|
|
|
54
54
|
slug: normalizedSlug,
|
|
55
55
|
repoRoot,
|
|
56
56
|
paseoHome: input.paseoHome,
|
|
57
|
+
worktreesRoot: input.worktreesRoot,
|
|
57
58
|
});
|
|
58
59
|
if (existingWorktree) {
|
|
59
60
|
return { worktree: existingWorktree, intent, repoRoot, created: false };
|
|
@@ -65,6 +66,7 @@ export async function createWorktreeCore(input, deps) {
|
|
|
65
66
|
source: intent,
|
|
66
67
|
runSetup: input.runSetup ?? true,
|
|
67
68
|
paseoHome: input.paseoHome,
|
|
69
|
+
worktreesRoot: input.worktreesRoot,
|
|
68
70
|
}),
|
|
69
71
|
intent,
|
|
70
72
|
repoRoot,
|
|
@@ -5,7 +5,7 @@ import type { PersistedWorkspaceRecord } from "./workspace-registry.js";
|
|
|
5
5
|
import type { WorkspaceGitService } from "./workspace-git-service.js";
|
|
6
6
|
import { runAsyncWorktreeBootstrap } from "./worktree-bootstrap.js";
|
|
7
7
|
import type { TerminalManager } from "../terminal/terminal-manager.js";
|
|
8
|
-
import type {
|
|
8
|
+
import type { ServiceProxySubsystem } from "./service-proxy.js";
|
|
9
9
|
import type { WorkspaceScriptRuntimeStore } from "./workspace-script-runtime-store.js";
|
|
10
10
|
import type { GitHubService } from "../services/github-service.js";
|
|
11
11
|
import type { CheckoutExistingBranchResult } from "../utils/checkout-git.js";
|
|
@@ -31,6 +31,7 @@ type AgentWorktreeSetupTimelineWriter = (input: {
|
|
|
31
31
|
}) => Promise<boolean>;
|
|
32
32
|
interface BuildAgentSessionConfigDependencies {
|
|
33
33
|
paseoHome?: string;
|
|
34
|
+
worktreesRoot?: string;
|
|
34
35
|
sessionLogger: Logger;
|
|
35
36
|
workspaceGitService?: WorkspaceGitService;
|
|
36
37
|
createPaseoWorktree: (input: CreatePaseoWorktreeInput, options?: {
|
|
@@ -47,6 +48,7 @@ interface BuildAgentSessionConfigDependencies {
|
|
|
47
48
|
}
|
|
48
49
|
interface CreatePaseoWorktreeInBackgroundDependencies {
|
|
49
50
|
paseoHome?: string;
|
|
51
|
+
worktreesRoot?: string;
|
|
50
52
|
emitWorkspaceUpdateForCwd: (cwd: string, options?: {
|
|
51
53
|
dedupeGitState?: boolean;
|
|
52
54
|
}) => Promise<void>;
|
|
@@ -55,10 +57,11 @@ interface CreatePaseoWorktreeInBackgroundDependencies {
|
|
|
55
57
|
sessionLogger: Logger;
|
|
56
58
|
terminalManager: TerminalManager | null;
|
|
57
59
|
archiveWorkspaceRecord: (workspaceId: string) => Promise<void>;
|
|
58
|
-
|
|
60
|
+
serviceProxy: ServiceProxySubsystem | null;
|
|
59
61
|
scriptRuntimeStore: WorkspaceScriptRuntimeStore | null;
|
|
60
62
|
getDaemonTcpPort: (() => number | null) | null;
|
|
61
63
|
getDaemonTcpHost: (() => string | null) | null;
|
|
64
|
+
serviceProxyPublicBaseUrl?: string | null;
|
|
62
65
|
onScriptsChanged: ((workspaceId: string, workspaceDirectory: string) => void) | null;
|
|
63
66
|
}
|
|
64
67
|
interface CreatePaseoWorktreeWorkflowDependencies extends CreatePaseoWorktreeInBackgroundDependencies {
|
|
@@ -100,6 +103,7 @@ interface HandleWorkspaceSetupStatusRequestDependencies {
|
|
|
100
103
|
}
|
|
101
104
|
interface HandleCreatePaseoWorktreeRequestDependencies {
|
|
102
105
|
paseoHome?: string;
|
|
106
|
+
worktreesRoot?: string;
|
|
103
107
|
describeWorkspaceRecord: (result: CreatePaseoWorktreeResult) => Promise<WorkspaceDescriptorPayload>;
|
|
104
108
|
emit: EmitSessionMessage;
|
|
105
109
|
sessionLogger: Logger;
|
|
@@ -41,6 +41,7 @@ export async function buildAgentSessionConfig(dependencies, config, gitOptions,
|
|
|
41
41
|
firstAgentContext,
|
|
42
42
|
runSetup: false,
|
|
43
43
|
paseoHome: dependencies.paseoHome,
|
|
44
|
+
worktreesRoot: dependencies.worktreesRoot,
|
|
44
45
|
}, {
|
|
45
46
|
resolveDefaultBranch: normalized.baseBranch
|
|
46
47
|
? async () => normalized.baseBranch
|
|
@@ -241,6 +242,7 @@ export async function handleCreatePaseoWorktreeRequest(dependencies, request) {
|
|
|
241
242
|
try {
|
|
242
243
|
const commandResult = await createPaseoWorktreeCommand({
|
|
243
244
|
paseoHome: dependencies.paseoHome,
|
|
245
|
+
worktreesRoot: dependencies.worktreesRoot,
|
|
244
246
|
createPaseoWorktreeWorkflow: dependencies.createPaseoWorktreeWorkflow,
|
|
245
247
|
}, {
|
|
246
248
|
cwd: request.cwd,
|
|
@@ -304,6 +306,7 @@ export async function createPaseoWorktreeWorkflow(dependencies, input, options)
|
|
|
304
306
|
...input,
|
|
305
307
|
runSetup: false,
|
|
306
308
|
paseoHome: input.paseoHome ?? dependencies.paseoHome,
|
|
309
|
+
worktreesRoot: input.worktreesRoot ?? dependencies.worktreesRoot,
|
|
307
310
|
}, options?.resolveDefaultBranch
|
|
308
311
|
? { resolveDefaultBranch: options.resolveDefaultBranch }
|
|
309
312
|
: undefined);
|
|
@@ -228,6 +228,7 @@ export interface GitHubService {
|
|
|
228
228
|
retainCurrentPullRequestStatusPoll?(options: {
|
|
229
229
|
cwd: string;
|
|
230
230
|
headRef: string;
|
|
231
|
+
headRepositoryOwner?: string;
|
|
231
232
|
onStatus?: (status: GitHubCurrentPullRequestStatus | null) => void;
|
|
232
233
|
onError?: (error: unknown) => void;
|
|
233
234
|
}): {
|
|
@@ -425,7 +425,10 @@ export function createGitHubService(options = {}) {
|
|
|
425
425
|
return buildCacheKey({
|
|
426
426
|
cwd: target.cwd,
|
|
427
427
|
method: "getCurrentPullRequestStatus",
|
|
428
|
-
args: {
|
|
428
|
+
args: {
|
|
429
|
+
headRef: target.headRef,
|
|
430
|
+
headRepositoryOwner: target.headRepositoryOwner,
|
|
431
|
+
},
|
|
429
432
|
});
|
|
430
433
|
}
|
|
431
434
|
function updatePollTargetAfterSuccess(update) {
|
|
@@ -465,6 +468,7 @@ export function createGitHubService(options = {}) {
|
|
|
465
468
|
await api.getCurrentPullRequestStatus({
|
|
466
469
|
cwd: target.cwd,
|
|
467
470
|
headRef: target.headRef,
|
|
471
|
+
headRepositoryOwner: target.headRepositoryOwner,
|
|
468
472
|
reason: "self-heal-github",
|
|
469
473
|
});
|
|
470
474
|
}
|
|
@@ -601,6 +605,7 @@ export function createGitHubService(options = {}) {
|
|
|
601
605
|
updatePollTargetAfterSuccess({
|
|
602
606
|
cwd: input.cwd,
|
|
603
607
|
headRef: input.headRef,
|
|
608
|
+
headRepositoryOwner: input.headRepositoryOwner,
|
|
604
609
|
status,
|
|
605
610
|
notify: input.reason === "self-heal-github",
|
|
606
611
|
});
|
|
@@ -795,6 +800,7 @@ export function createGitHubService(options = {}) {
|
|
|
795
800
|
target = {
|
|
796
801
|
cwd: input.cwd,
|
|
797
802
|
headRef: input.headRef,
|
|
803
|
+
headRepositoryOwner: input.headRepositoryOwner,
|
|
798
804
|
retainCount: 0,
|
|
799
805
|
timer: null,
|
|
800
806
|
latestStatus: null,
|
|
@@ -130,6 +130,7 @@ export interface MergeFromBaseOptions {
|
|
|
130
130
|
}
|
|
131
131
|
export interface CheckoutContext {
|
|
132
132
|
paseoHome?: string;
|
|
133
|
+
worktreesRoot?: string;
|
|
133
134
|
logger?: Pick<Logger, "trace">;
|
|
134
135
|
facts?: CheckoutSnapshotFacts | null;
|
|
135
136
|
}
|
|
@@ -149,7 +150,6 @@ export type CheckoutSnapshotFacts = {
|
|
|
149
150
|
comparisonBaseRef: string | null;
|
|
150
151
|
branchRemoteName: string | null;
|
|
151
152
|
branchMergeRef: string | null;
|
|
152
|
-
trackedOriginBranch: string | null;
|
|
153
153
|
pullRequestLookupTarget: PullRequestStatusLookupTarget | null;
|
|
154
154
|
};
|
|
155
155
|
export declare function getCurrentBranch(cwd: string): Promise<string | null>;
|
|
@@ -159,8 +159,11 @@ export interface GitWorktreeEntry {
|
|
|
159
159
|
branchRef?: string;
|
|
160
160
|
isBare?: boolean;
|
|
161
161
|
}
|
|
162
|
-
/** Check whether a path
|
|
163
|
-
export declare function isPaseoWorktreePath(p: string
|
|
162
|
+
/** Check whether a path is under Paseo's worktree root. */
|
|
163
|
+
export declare function isPaseoWorktreePath(p: string, options?: {
|
|
164
|
+
paseoHome?: string;
|
|
165
|
+
worktreesRoot?: string;
|
|
166
|
+
}): boolean;
|
|
164
167
|
/** True when `child` is strictly inside `parent` (handles both `/` and `\`). */
|
|
165
168
|
export declare function isDescendantPath(child: string, parent: string): boolean;
|
|
166
169
|
export declare function parseWorktreeList(output: string): GitWorktreeEntry[];
|
|
@@ -7,7 +7,7 @@ import { parseGitHubRepoFromRemote } from "../server/workspace-git-metadata.js";
|
|
|
7
7
|
import { GitHubAuthenticationError, GitHubCliMissingError, GitHubCommandError, createGitHubService, resolveGitHubRepo, } from "../services/github-service.js";
|
|
8
8
|
import { parseGitRevParsePath, resolveGitRevParsePath } from "./git-rev-parse-path.js";
|
|
9
9
|
import { runGitCommand } from "./run-git-command.js";
|
|
10
|
-
import { isPaseoOwnedWorktreeCwd } from "./worktree.js";
|
|
10
|
+
import { isPaseoOwnedWorktreeCwd, resolvePaseoWorktreesBaseRoot } from "./worktree.js";
|
|
11
11
|
import { readPaseoWorktreeMetadata } from "./worktree-metadata.js";
|
|
12
12
|
const READ_ONLY_GIT_ENV = {
|
|
13
13
|
GIT_OPTIONAL_LOCKS: "0",
|
|
@@ -570,7 +570,7 @@ export async function getMainRepoRoot(cwd) {
|
|
|
570
570
|
});
|
|
571
571
|
return getMainRepoRootFromCommonDir(cwd, resolveGitRevParsePath(cwd, commonDirOut));
|
|
572
572
|
}
|
|
573
|
-
async function getMainRepoRootFromCommonDir(cwd, commonDir) {
|
|
573
|
+
async function getMainRepoRootFromCommonDir(cwd, commonDir, context) {
|
|
574
574
|
if (!commonDir) {
|
|
575
575
|
throw new Error("Not in a git repository");
|
|
576
576
|
}
|
|
@@ -583,13 +583,20 @@ async function getMainRepoRootFromCommonDir(cwd, commonDir) {
|
|
|
583
583
|
envOverlay: READ_ONLY_GIT_ENV,
|
|
584
584
|
});
|
|
585
585
|
const worktrees = parseWorktreeList(worktreeOut);
|
|
586
|
-
const nonBareNonPaseo = worktrees.filter((wt) => !wt.isBare &&
|
|
586
|
+
const nonBareNonPaseo = worktrees.filter((wt) => !wt.isBare &&
|
|
587
|
+
!isPaseoWorktreePath(wt.path, {
|
|
588
|
+
paseoHome: context?.paseoHome,
|
|
589
|
+
worktreesRoot: context?.worktreesRoot,
|
|
590
|
+
}));
|
|
587
591
|
const childrenOfBareRepo = nonBareNonPaseo.filter((wt) => isDescendantPath(wt.path, normalized));
|
|
588
592
|
const mainChild = childrenOfBareRepo.find((wt) => basename(wt.path) === "main");
|
|
589
593
|
return mainChild?.path ?? childrenOfBareRepo[0]?.path ?? nonBareNonPaseo[0]?.path ?? normalized;
|
|
590
594
|
}
|
|
591
|
-
/** Check whether a path
|
|
592
|
-
export function isPaseoWorktreePath(p) {
|
|
595
|
+
/** Check whether a path is under Paseo's worktree root. */
|
|
596
|
+
export function isPaseoWorktreePath(p, options) {
|
|
597
|
+
if (options?.worktreesRoot || options?.paseoHome) {
|
|
598
|
+
return isDescendantPath(p, resolvePaseoWorktreesBaseRoot(options));
|
|
599
|
+
}
|
|
593
600
|
return /[/\\]\.paseo[/\\]worktrees[/\\]/.test(p);
|
|
594
601
|
}
|
|
595
602
|
/** True when `child` is strictly inside `parent` (handles both `/` and `\`). */
|
|
@@ -669,7 +676,10 @@ async function getPaseoWorktreeForCwd(cwd, context, knownWorktreeRoot) {
|
|
|
669
676
|
if (!/[\\/]worktrees[\\/]/.test(cwd)) {
|
|
670
677
|
return { isPaseoOwnedWorktree: false };
|
|
671
678
|
}
|
|
672
|
-
const ownership = await isPaseoOwnedWorktreeCwd(cwd, {
|
|
679
|
+
const ownership = await isPaseoOwnedWorktreeCwd(cwd, {
|
|
680
|
+
paseoHome: context?.paseoHome,
|
|
681
|
+
worktreesRoot: context?.worktreesRoot,
|
|
682
|
+
});
|
|
673
683
|
if (!ownership.allowed) {
|
|
674
684
|
return { isPaseoOwnedWorktree: false };
|
|
675
685
|
}
|
|
@@ -965,52 +975,46 @@ async function getAheadBehind(cwd, baseRef, currentBranch, context) {
|
|
|
965
975
|
}
|
|
966
976
|
return { ahead, behind };
|
|
967
977
|
}
|
|
968
|
-
async function getAheadOfOrigin(cwd, currentBranch,
|
|
978
|
+
async function getAheadOfOrigin(cwd, currentBranch, context) {
|
|
969
979
|
if (!currentBranch) {
|
|
970
980
|
return null;
|
|
971
981
|
}
|
|
972
|
-
const
|
|
973
|
-
|
|
982
|
+
const upstreamRef = await getConfiguredUpstreamRef(cwd, currentBranch, context);
|
|
983
|
+
if (!upstreamRef) {
|
|
984
|
+
return null;
|
|
985
|
+
}
|
|
974
986
|
try {
|
|
975
|
-
const { stdout } = await runGitCommand(["rev-list", "--count",
|
|
987
|
+
const { stdout } = await runGitCommand(["rev-list", "--count", `${upstreamRef}..${currentBranch}`], { cwd, envOverlay: READ_ONLY_GIT_ENV, logger: context?.logger });
|
|
976
988
|
const count = Number.parseInt(stdout.trim(), 10);
|
|
977
989
|
return Number.isNaN(count) ? null : count;
|
|
978
990
|
}
|
|
979
991
|
catch {
|
|
980
|
-
|
|
981
|
-
return null;
|
|
982
|
-
}
|
|
983
|
-
if (!baseRef || normalizeLocalBranchRefName(baseRef) === currentBranch) {
|
|
984
|
-
return null;
|
|
985
|
-
}
|
|
986
|
-
try {
|
|
987
|
-
const comparisonBaseRef = await resolveBestComparisonBaseRef(cwd, baseRef, context);
|
|
988
|
-
const { stdout } = await runGitCommand(["rev-list", "--count", `${comparisonBaseRef}..${currentBranch}`], { cwd, envOverlay: READ_ONLY_GIT_ENV, logger: context?.logger });
|
|
989
|
-
const count = Number.parseInt(stdout.trim(), 10);
|
|
990
|
-
return Number.isNaN(count) ? null : count;
|
|
991
|
-
}
|
|
992
|
-
catch {
|
|
993
|
-
return null;
|
|
994
|
-
}
|
|
992
|
+
return null;
|
|
995
993
|
}
|
|
996
994
|
}
|
|
997
|
-
async function
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
if (remoteName !== "origin") {
|
|
995
|
+
async function getConfiguredUpstreamRef(cwd, currentBranch, context) {
|
|
996
|
+
const remoteName = context?.facts?.isGit && context.facts.currentBranch === currentBranch
|
|
997
|
+
? context.facts.branchRemoteName
|
|
998
|
+
: await getGitConfigValue(cwd, `branch.${currentBranch}.remote`, context);
|
|
999
|
+
if (!remoteName) {
|
|
1003
1000
|
return null;
|
|
1004
1001
|
}
|
|
1005
|
-
const mergeRef =
|
|
1006
|
-
|
|
1002
|
+
const mergeRef = context?.facts?.isGit && context.facts.currentBranch === currentBranch
|
|
1003
|
+
? context.facts.branchMergeRef
|
|
1004
|
+
: await getGitConfigValue(cwd, `branch.${currentBranch}.merge`, context);
|
|
1005
|
+
const upstreamBranch = parseBranchMergeHeadRef(mergeRef);
|
|
1006
|
+
return upstreamBranch ? `${remoteName}/${upstreamBranch}` : null;
|
|
1007
1007
|
}
|
|
1008
1008
|
async function getBehindOfOrigin(cwd, currentBranch, context) {
|
|
1009
1009
|
if (!currentBranch) {
|
|
1010
1010
|
return null;
|
|
1011
1011
|
}
|
|
1012
|
+
const upstreamRef = await getConfiguredUpstreamRef(cwd, currentBranch, context);
|
|
1013
|
+
if (!upstreamRef) {
|
|
1014
|
+
return null;
|
|
1015
|
+
}
|
|
1012
1016
|
try {
|
|
1013
|
-
const { stdout } = await runGitCommand(["rev-list", "--count", `${currentBranch}
|
|
1017
|
+
const { stdout } = await runGitCommand(["rev-list", "--count", `${currentBranch}..${upstreamRef}`], { cwd, envOverlay: READ_ONLY_GIT_ENV, logger: context?.logger });
|
|
1014
1018
|
const count = Number.parseInt(stdout.trim(), 10);
|
|
1015
1019
|
return Number.isNaN(count) ? null : count;
|
|
1016
1020
|
}
|
|
@@ -1076,7 +1080,7 @@ export async function getCheckoutSnapshotFacts(cwd, context) {
|
|
|
1076
1080
|
? readPaseoWorktreeBaseRef(inspected.paseoWorktree.worktreeRoot)
|
|
1077
1081
|
: null;
|
|
1078
1082
|
const resolvedBaseRef = storedBaseRef ?? (await resolveBaseRef(cwd));
|
|
1079
|
-
const mainRepoRoot = await getMainRepoRootFromCommonDir(cwd, inspected.gitCommonDir).catch(() => null);
|
|
1083
|
+
const mainRepoRoot = await getMainRepoRootFromCommonDir(cwd, inspected.gitCommonDir, context).catch(() => null);
|
|
1080
1084
|
let comparisonBaseRef = null;
|
|
1081
1085
|
if (resolvedBaseRef &&
|
|
1082
1086
|
inspected.currentBranch &&
|
|
@@ -1095,7 +1099,6 @@ export async function getCheckoutSnapshotFacts(cwd, context) {
|
|
|
1095
1099
|
}
|
|
1096
1100
|
}
|
|
1097
1101
|
}
|
|
1098
|
-
const trackedOriginBranch = branchRemoteName === "origin" ? parseBranchMergeHeadRef(branchMergeRef) : null;
|
|
1099
1102
|
const pullRequestLookupTarget = inspected.currentBranch
|
|
1100
1103
|
? buildPullRequestLookupTargetFromBranchConfig({
|
|
1101
1104
|
currentBranch: inspected.currentBranch,
|
|
@@ -1118,7 +1121,6 @@ export async function getCheckoutSnapshotFacts(cwd, context) {
|
|
|
1118
1121
|
comparisonBaseRef,
|
|
1119
1122
|
branchRemoteName,
|
|
1120
1123
|
branchMergeRef,
|
|
1121
|
-
trackedOriginBranch,
|
|
1122
1124
|
pullRequestLookupTarget,
|
|
1123
1125
|
};
|
|
1124
1126
|
}
|
|
@@ -1228,7 +1230,7 @@ export async function getCheckoutStatus(cwd, context) {
|
|
|
1228
1230
|
? getAheadBehind(cwd, baseRef, currentBranch, factsContext)
|
|
1229
1231
|
: Promise.resolve(null),
|
|
1230
1232
|
hasRemote && currentBranch
|
|
1231
|
-
? getAheadOfOrigin(cwd, currentBranch,
|
|
1233
|
+
? getAheadOfOrigin(cwd, currentBranch, factsContext)
|
|
1232
1234
|
: Promise.resolve(null),
|
|
1233
1235
|
hasRemote && currentBranch
|
|
1234
1236
|
? getBehindOfOrigin(cwd, currentBranch, factsContext)
|
|
@@ -83,6 +83,10 @@ export interface PaseoWorktreeOwnership {
|
|
|
83
83
|
worktreeRoot?: string;
|
|
84
84
|
worktreePath?: string;
|
|
85
85
|
}
|
|
86
|
+
export interface WorktreeRootOptions {
|
|
87
|
+
paseoHome?: string;
|
|
88
|
+
worktreesRoot?: string;
|
|
89
|
+
}
|
|
86
90
|
export type WorktreeSource = {
|
|
87
91
|
kind: "branch-off";
|
|
88
92
|
baseBranch: string;
|
|
@@ -104,11 +108,13 @@ export interface CreateWorktreeOptions {
|
|
|
104
108
|
source: WorktreeSource;
|
|
105
109
|
runSetup: boolean;
|
|
106
110
|
paseoHome?: string;
|
|
111
|
+
worktreesRoot?: string;
|
|
107
112
|
}
|
|
108
113
|
interface ResolveExistingWorktreeForSlugOptions {
|
|
109
114
|
slug: string;
|
|
110
115
|
repoRoot: string;
|
|
111
116
|
paseoHome?: string;
|
|
117
|
+
worktreesRoot?: string;
|
|
112
118
|
}
|
|
113
119
|
export declare class BranchAlreadyCheckedOutError extends Error {
|
|
114
120
|
readonly branchName: string;
|
|
@@ -164,32 +170,31 @@ export declare function runWorktreeTeardownCommands(options: {
|
|
|
164
170
|
*/
|
|
165
171
|
export declare function getGitCommonDir(cwd: string): Promise<string>;
|
|
166
172
|
export declare function deriveWorktreeProjectHash(cwd: string): Promise<string>;
|
|
167
|
-
export declare function
|
|
168
|
-
export declare function
|
|
169
|
-
export declare function
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
export declare function listPaseoWorktrees({ cwd, paseoHome, }: {
|
|
173
|
+
export declare function resolvePaseoWorktreesBaseRoot(options?: WorktreeRootOptions): string;
|
|
174
|
+
export declare function getPaseoWorktreesRoot(cwd: string, paseoHome?: string, worktreesRoot?: string): Promise<string>;
|
|
175
|
+
export declare function computeWorktreePath(cwd: string, slug: string, paseoHome?: string, worktreesRoot?: string): Promise<string>;
|
|
176
|
+
export declare function isPaseoOwnedWorktreeCwd(cwd: string, options?: WorktreeRootOptions): Promise<PaseoWorktreeOwnership>;
|
|
177
|
+
export declare function listPaseoWorktrees({ cwd, paseoHome, worktreesRoot, }: {
|
|
173
178
|
cwd: string;
|
|
174
179
|
paseoHome?: string;
|
|
180
|
+
worktreesRoot?: string;
|
|
175
181
|
}): Promise<PaseoWorktreeInfo[]>;
|
|
176
|
-
export declare function resolveExistingWorktreeForSlug({ slug, repoRoot, paseoHome, }: ResolveExistingWorktreeForSlugOptions): Promise<WorktreeConfig | null>;
|
|
177
|
-
export declare function resolvePaseoWorktreeRootForCwd(cwd: string, options?: {
|
|
178
|
-
paseoHome?: string;
|
|
179
|
-
}): Promise<{
|
|
182
|
+
export declare function resolveExistingWorktreeForSlug({ slug, repoRoot, paseoHome, worktreesRoot, }: ResolveExistingWorktreeForSlugOptions): Promise<WorktreeConfig | null>;
|
|
183
|
+
export declare function resolvePaseoWorktreeRootForCwd(cwd: string, options?: WorktreeRootOptions): Promise<{
|
|
180
184
|
repoRoot: string;
|
|
181
185
|
worktreeRoot: string;
|
|
182
186
|
worktreePath: string;
|
|
183
187
|
} | null>;
|
|
184
|
-
export declare function deletePaseoWorktree({ cwd, worktreePath, worktreeSlug, worktreesRoot, paseoHome, }: {
|
|
188
|
+
export declare function deletePaseoWorktree({ cwd, worktreePath, worktreeSlug, worktreesRoot, paseoHome, worktreesBaseRoot, }: {
|
|
185
189
|
cwd: string | null;
|
|
186
190
|
worktreePath?: string;
|
|
187
191
|
worktreeSlug?: string;
|
|
188
192
|
worktreesRoot?: string;
|
|
189
193
|
paseoHome?: string;
|
|
194
|
+
worktreesBaseRoot?: string;
|
|
190
195
|
}): Promise<void>;
|
|
191
196
|
/**
|
|
192
197
|
* Create a git worktree with proper naming conventions
|
|
193
198
|
*/
|
|
194
|
-
export declare const createWorktree: ({ cwd, source, worktreeSlug, runSetup, paseoHome, }: CreateWorktreeOptions) => Promise<WorktreeConfig>;
|
|
199
|
+
export declare const createWorktree: ({ cwd, source, worktreeSlug, runSetup, paseoHome, worktreesRoot, }: CreateWorktreeOptions) => Promise<WorktreeConfig>;
|
|
195
200
|
//# sourceMappingURL=worktree.d.ts.map
|