@getpaseo/server 0.1.95 → 0.1.97-beta.1
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/{utils/executable.d.ts → executable-resolution/executable-resolution.d.ts} +2 -2
- package/dist/server/{utils/executable.js → executable-resolution/executable-resolution.js} +16 -14
- package/dist/server/executable-resolution/windows.d.ts +18 -0
- package/dist/server/executable-resolution/windows.js +62 -0
- package/dist/server/server/agent/agent-loading.js +4 -1
- package/dist/server/server/agent/agent-manager.d.ts +10 -2
- package/dist/server/server/agent/agent-manager.js +34 -46
- package/dist/server/server/agent/agent-projections.js +3 -0
- package/dist/server/server/agent/agent-prompt.js +19 -1
- package/dist/server/server/agent/agent-response-loop.js +2 -4
- package/dist/server/server/agent/agent-storage.d.ts +18 -19
- package/dist/server/server/agent/agent-storage.js +6 -23
- package/dist/server/server/agent/create-agent/create.d.ts +2 -12
- package/dist/server/server/agent/create-agent/create.js +28 -30
- package/dist/server/server/agent/create-agent-lifecycle-dispatch.d.ts +4 -2
- package/dist/server/server/agent/create-agent-lifecycle-dispatch.js +31 -22
- package/dist/server/server/agent/import-sessions.d.ts +1 -10
- package/dist/server/server/agent/import-sessions.js +1 -53
- package/dist/server/server/agent/lifecycle-command.js +5 -4
- package/dist/server/server/agent/mcp-server.d.ts +8 -5
- package/dist/server/server/agent/mcp-server.js +41 -14
- package/dist/server/server/agent/mcp-shared.d.ts +6 -3
- package/dist/server/server/agent/mcp-shared.js +3 -0
- package/dist/server/server/agent/provider-launch-config.js +1 -1
- package/dist/server/server/agent/providers/acp-agent.d.ts +5 -0
- package/dist/server/server/agent/providers/acp-agent.js +31 -26
- package/dist/server/server/agent/providers/claude/agent.js +45 -6
- package/dist/server/server/agent/providers/codex-app-server-agent.js +1 -1
- package/dist/server/server/agent/providers/copilot-acp-agent.js +1 -0
- package/dist/server/server/agent/providers/cursor-acp-agent.d.ts +0 -7
- package/dist/server/server/agent/providers/cursor-acp-agent.js +0 -78
- 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 +73 -1
- package/dist/server/server/agent/providers/opencode/server-manager.js +1 -1
- package/dist/server/server/agent/structured-generation-providers.js +45 -1
- package/dist/server/server/agent-attention-policy.d.ts +12 -3
- package/dist/server/server/agent-attention-policy.js +15 -3
- package/dist/server/server/auto-archive-on-merge/archive-if-safe.d.ts +7 -6
- package/dist/server/server/auto-archive-on-merge/archive-if-safe.js +21 -16
- package/dist/server/server/bootstrap.d.ts +3 -0
- package/dist/server/server/bootstrap.js +91 -12
- package/dist/server/server/config.js +1 -0
- package/dist/server/server/daemon-config-store.js +1 -0
- package/dist/server/server/exports.d.ts +1 -1
- package/dist/server/server/exports.js +1 -1
- package/dist/server/server/loop-service.d.ts +24 -24
- package/dist/server/server/migrations/backfill-workspace-id.migration.d.ts +9 -0
- package/dist/server/server/migrations/backfill-workspace-id.migration.js +60 -0
- package/dist/server/server/paseo-worktree-service.d.ts +9 -0
- package/dist/server/server/paseo-worktree-service.js +71 -12
- package/dist/server/server/path-utils.d.ts +1 -0
- package/dist/server/server/path-utils.js +6 -1
- package/dist/server/server/persisted-config.d.ts +7 -0
- package/dist/server/server/persisted-config.js +1 -0
- package/dist/server/server/persistence-hooks.d.ts +1 -0
- package/dist/server/server/persistence-hooks.js +13 -5
- package/dist/server/server/resolve-workspace-id-for-path.d.ts +3 -0
- package/dist/server/server/resolve-workspace-id-for-path.js +41 -0
- package/dist/server/server/script-proxy.d.ts +1 -1
- package/dist/server/server/script-proxy.js +1 -1
- package/dist/server/server/service-proxy.js +1 -1
- package/dist/server/server/session.d.ts +31 -6
- package/dist/server/server/session.js +640 -196
- package/dist/server/server/websocket-server.d.ts +5 -0
- package/dist/server/server/websocket-server.js +137 -3
- package/dist/server/server/workspace-archive-service.d.ts +60 -3
- package/dist/server/server/workspace-archive-service.js +217 -4
- package/dist/server/server/workspace-directory.d.ts +20 -2
- package/dist/server/server/workspace-directory.js +148 -70
- package/dist/server/server/workspace-git-service.js +21 -21
- package/dist/server/server/workspace-reconciliation-service.d.ts +1 -1
- package/dist/server/server/workspace-reconciliation-service.js +21 -22
- package/dist/server/server/workspace-registry-bootstrap.js +23 -10
- package/dist/server/server/workspace-registry-model.d.ts +3 -3
- package/dist/server/server/workspace-registry-model.js +9 -10
- package/dist/server/server/workspace-registry.d.ts +17 -4
- package/dist/server/server/workspace-registry.js +27 -0
- package/dist/server/server/worktree/commands.d.ts +7 -5
- package/dist/server/server/worktree/commands.js +38 -18
- package/dist/server/server/worktree-bootstrap.d.ts +1 -0
- package/dist/server/server/worktree-bootstrap.js +4 -1
- package/dist/server/server/worktree-branch-name-generator.d.ts +5 -1
- package/dist/server/server/worktree-branch-name-generator.js +8 -2
- package/dist/server/server/worktree-session.d.ts +4 -5
- package/dist/server/server/worktree-session.js +9 -3
- package/dist/server/services/github-service.js +1 -1
- package/dist/server/terminal/activity/terminal-activity-tracker.d.ts +20 -0
- package/dist/server/terminal/activity/terminal-activity-tracker.js +59 -0
- package/dist/server/terminal/agent-hooks/agent-hook-installer.d.ts +62 -0
- package/dist/server/terminal/agent-hooks/agent-hook-installer.js +117 -0
- package/dist/server/terminal/agent-hooks/claude/claude-settings.d.ts +7 -0
- package/dist/server/terminal/agent-hooks/claude/claude-settings.js +88 -0
- package/dist/server/terminal/agent-hooks/claude/claude.d.ts +4 -0
- package/dist/server/terminal/agent-hooks/claude/claude.js +47 -0
- package/dist/server/terminal/agent-hooks/codex/codex-settings.d.ts +7 -0
- package/dist/server/terminal/agent-hooks/codex/codex-settings.js +99 -0
- package/dist/server/terminal/agent-hooks/codex/codex.d.ts +4 -0
- package/dist/server/terminal/agent-hooks/codex/codex.js +30 -0
- package/dist/server/terminal/agent-hooks/opencode/opencode-plugin.d.ts +4 -0
- package/dist/server/terminal/agent-hooks/opencode/opencode-plugin.js +46 -0
- package/dist/server/terminal/agent-hooks/opencode/opencode.d.ts +3 -0
- package/dist/server/terminal/agent-hooks/opencode/opencode.js +23 -0
- package/dist/server/terminal/agent-hooks/provider-registry.d.ts +24 -0
- package/dist/server/terminal/agent-hooks/provider-registry.js +36 -0
- package/dist/server/terminal/agent-hooks/terminal-agent-hook-setting.d.ts +10 -0
- package/dist/server/terminal/agent-hooks/terminal-agent-hook-setting.js +26 -0
- package/dist/server/terminal/terminal-manager-factory.d.ts +4 -1
- package/dist/server/terminal/terminal-manager-factory.js +2 -2
- package/dist/server/terminal/terminal-manager.d.ts +33 -2
- package/dist/server/terminal/terminal-manager.js +144 -18
- package/dist/server/terminal/terminal-output-coalescer.d.ts +4 -0
- package/dist/server/terminal/terminal-output-coalescer.js +18 -0
- package/dist/server/terminal/terminal-restore.d.ts +1 -0
- package/dist/server/terminal/terminal-restore.js +6 -0
- package/dist/server/terminal/terminal-session-controller.d.ts +4 -2
- package/dist/server/terminal/terminal-session-controller.js +65 -24
- package/dist/server/terminal/terminal-worker-process.js +146 -63
- package/dist/server/terminal/terminal-worker-protocol.d.ts +19 -14
- package/dist/server/terminal/terminal.d.ts +42 -0
- package/dist/server/terminal/terminal.js +235 -16
- package/dist/server/terminal/worker-terminal-manager.d.ts +1 -0
- package/dist/server/terminal/worker-terminal-manager.js +220 -36
- package/dist/server/utils/build-metadata-prompt.d.ts +1 -1
- package/dist/server/utils/github-remote.js +1 -1
- package/dist/server/utils/tree-kill.d.ts +2 -2
- package/dist/src/{utils/executable.js → executable-resolution/executable-resolution.js} +16 -14
- package/dist/src/executable-resolution/windows.js +62 -0
- package/dist/src/server/agent/provider-launch-config.js +1 -1
- package/dist/src/server/persisted-config.js +1 -0
- package/package.json +10 -5
- package/dist/server/server/agent/agent-metadata-generator.d.ts +0 -36
- package/dist/server/server/agent/agent-metadata-generator.js +0 -112
- package/dist/server/server/paseo-worktree-archive-service.d.ts +0 -41
- package/dist/server/server/paseo-worktree-archive-service.js +0 -144
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// COMPAT(workspaceIdBackfill): one-time legacy backfill, delete after 2026-12-16
|
|
2
|
+
// once floor >= the release that always stamps workspaceId at create time.
|
|
3
|
+
//
|
|
4
|
+
// This is the ONLY place in the codebase that maps a cwd to a workspaceId.
|
|
5
|
+
// Every other code path treats a record's `workspaceId` field as authoritative
|
|
6
|
+
// ownership. Legacy agent records persisted before workspaceId stamping have no
|
|
7
|
+
// owner, so this migration stamps each one with the workspace that owned its
|
|
8
|
+
// directory at the time it was written. It runs once at startup and writes the
|
|
9
|
+
// id back to storage, after which all runtime code can assume the field exists.
|
|
10
|
+
import { homedir } from "node:os";
|
|
11
|
+
import { resolve, sep } from "node:path";
|
|
12
|
+
// Picks the workspace that owned `cwd` for a legacy, unstamped agent record.
|
|
13
|
+
// Prefers an exact-cwd workspace (oldest wins) and otherwise attributes to the
|
|
14
|
+
// deepest enclosing workspace directory, never letting the home directory own
|
|
15
|
+
// descendants. Used only by the one-time backfill below.
|
|
16
|
+
function resolveLegacyWorkspaceOwner(cwd, workspaces) {
|
|
17
|
+
const normalizedCwd = resolve(cwd);
|
|
18
|
+
const userHome = resolve(homedir());
|
|
19
|
+
const activeWorkspaces = Array.from(workspaces).filter((workspace) => !workspace.archivedAt);
|
|
20
|
+
const exactMatches = activeWorkspaces.filter((workspace) => resolve(workspace.cwd) === normalizedCwd);
|
|
21
|
+
if (exactMatches.length > 0) {
|
|
22
|
+
return oldestWorkspace(exactMatches).workspaceId;
|
|
23
|
+
}
|
|
24
|
+
const prefixMatches = activeWorkspaces.filter((workspace) => {
|
|
25
|
+
const workspaceCwd = resolve(workspace.cwd);
|
|
26
|
+
if (workspaceCwd === userHome) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
return normalizedCwd === workspaceCwd || normalizedCwd.startsWith(`${workspaceCwd}${sep}`);
|
|
30
|
+
});
|
|
31
|
+
if (prefixMatches.length === 0) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const deepestPrefixLength = Math.max(...prefixMatches.map((workspace) => resolve(workspace.cwd).length));
|
|
35
|
+
return oldestWorkspace(prefixMatches.filter((workspace) => resolve(workspace.cwd).length === deepestPrefixLength)).workspaceId;
|
|
36
|
+
}
|
|
37
|
+
function oldestWorkspace(workspaces) {
|
|
38
|
+
return workspaces.reduce((oldest, candidate) => candidate.createdAt < oldest.createdAt ? candidate : oldest);
|
|
39
|
+
}
|
|
40
|
+
export async function backfillWorkspaceIdForLegacyAgents(options) {
|
|
41
|
+
const workspaceRecords = await options.workspaceRegistry.list();
|
|
42
|
+
const records = await options.agentStorage.list();
|
|
43
|
+
let migrated = 0;
|
|
44
|
+
for (const record of records) {
|
|
45
|
+
if (record.workspaceId) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const workspaceId = resolveLegacyWorkspaceOwner(record.cwd, workspaceRecords);
|
|
49
|
+
if (!workspaceId) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
await options.agentStorage.upsert({ ...record, workspaceId });
|
|
53
|
+
migrated += 1;
|
|
54
|
+
}
|
|
55
|
+
if (migrated > 0) {
|
|
56
|
+
options.logger.info({ migrated }, "Backfilled workspaceId for legacy agent records");
|
|
57
|
+
}
|
|
58
|
+
return migrated;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=backfill-workspace-id.migration.js.map
|
|
@@ -40,4 +40,13 @@ export declare function attemptFirstAgentBranchAutoName(options: {
|
|
|
40
40
|
renameCurrentBranch?: typeof renameCurrentBranch;
|
|
41
41
|
localBranchExists?: typeof localBranchExists;
|
|
42
42
|
}): Promise<AttemptFirstAgentBranchAutoNameResult>;
|
|
43
|
+
export interface CreateLocalCheckoutWorkspaceDeps {
|
|
44
|
+
projectRegistry: Pick<ProjectRegistry, "get" | "list" | "upsert">;
|
|
45
|
+
workspaceRegistry: Pick<WorkspaceRegistry, "list" | "upsert">;
|
|
46
|
+
workspaceGitService: Pick<WorkspaceGitService, "getCheckout">;
|
|
47
|
+
}
|
|
48
|
+
export declare function createLocalCheckoutWorkspace(options: {
|
|
49
|
+
cwd: string;
|
|
50
|
+
title?: string | null;
|
|
51
|
+
}, deps: CreateLocalCheckoutWorkspaceDeps): Promise<PersistedWorkspaceRecord>;
|
|
43
52
|
//# sourceMappingURL=paseo-worktree-service.d.ts.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
1
2
|
import { createPersistedProjectRecord, createPersistedWorkspaceRecord, } from "./workspace-registry.js";
|
|
2
|
-
import { deriveProjectGroupingName,
|
|
3
|
+
import { classifyDirectoryForProjectMembership, deriveProjectGroupingName, generateWorkspaceId, } from "./workspace-registry-model.js";
|
|
3
4
|
import { createWorktreeCore, } from "./worktree-core.js";
|
|
4
5
|
import { validateBranchSlug } from "../utils/worktree.js";
|
|
5
6
|
import { getCurrentBranch, localBranchExists, renameCurrentBranch } from "../utils/checkout-git.js";
|
|
@@ -107,18 +108,20 @@ function maybeMarkFirstAgentBranchAutoNameEligible(options) {
|
|
|
107
108
|
});
|
|
108
109
|
}
|
|
109
110
|
async function upsertWorkspaceForWorktree(options) {
|
|
110
|
-
const normalizedCwd =
|
|
111
|
-
const normalizedInputCwd =
|
|
112
|
-
const normalizedRepoRoot =
|
|
113
|
-
|
|
111
|
+
const normalizedCwd = resolve(options.worktree.worktreePath);
|
|
112
|
+
const normalizedInputCwd = resolve(options.inputCwd);
|
|
113
|
+
const normalizedRepoRoot = resolve(options.repoRoot);
|
|
114
|
+
// Creation never deduplicates by directory: a worktree directory may back
|
|
115
|
+
// more than one workspace. We still resolve the source project from the
|
|
116
|
+
// originating checkout, but always mint a fresh workspace record.
|
|
114
117
|
const sourceProject = await resolveSourceProjectForWorktree({
|
|
115
118
|
inputCwd: normalizedInputCwd,
|
|
116
119
|
projectId: options.projectId,
|
|
117
120
|
repoRoot: normalizedRepoRoot,
|
|
118
|
-
existingWorkspace,
|
|
121
|
+
existingWorkspace: null,
|
|
119
122
|
deps: options.deps,
|
|
120
123
|
});
|
|
121
|
-
const workspaceId =
|
|
124
|
+
const workspaceId = generateWorkspaceId();
|
|
122
125
|
const now = new Date().toISOString();
|
|
123
126
|
await options.deps.projectRegistry.upsert(createPersistedProjectRecord({
|
|
124
127
|
projectId: sourceProject.projectId,
|
|
@@ -136,13 +139,73 @@ async function upsertWorkspaceForWorktree(options) {
|
|
|
136
139
|
cwd: normalizedCwd,
|
|
137
140
|
kind: "worktree",
|
|
138
141
|
displayName: options.worktree.branchName || normalizedCwd,
|
|
139
|
-
|
|
142
|
+
branch: options.worktree.branchName || null,
|
|
143
|
+
createdAt: now,
|
|
140
144
|
updatedAt: now,
|
|
141
145
|
archivedAt: null,
|
|
142
146
|
});
|
|
143
147
|
await options.deps.workspaceRegistry.upsert(workspace);
|
|
144
148
|
return (await options.deps.workspaceRegistry.get(workspace.workspaceId)) ?? workspace;
|
|
145
149
|
}
|
|
150
|
+
// Always create a NEW workspace record backed by the existing directory `cwd`.
|
|
151
|
+
// Never reuses a same-cwd record: a directory may back any number of
|
|
152
|
+
// workspaces. Used by explicit user creation.
|
|
153
|
+
export async function createLocalCheckoutWorkspace(options, deps) {
|
|
154
|
+
const normalizedCwd = resolve(options.cwd);
|
|
155
|
+
const checkout = await deps.workspaceGitService.getCheckout(normalizedCwd);
|
|
156
|
+
const membership = classifyDirectoryForProjectMembership({ cwd: normalizedCwd, checkout });
|
|
157
|
+
const now = new Date().toISOString();
|
|
158
|
+
const projectRecord = await resolveProjectRecordForMembership({
|
|
159
|
+
membership,
|
|
160
|
+
timestamp: now,
|
|
161
|
+
projectRegistry: deps.projectRegistry,
|
|
162
|
+
});
|
|
163
|
+
await deps.projectRegistry.upsert(projectRecord);
|
|
164
|
+
const trimmedTitle = options.title?.trim();
|
|
165
|
+
// Persist the live git branch into the dedicated `branch` field so
|
|
166
|
+
// buildWorkspaceCheckout reports the real branch for directory/local_checkout
|
|
167
|
+
// workspaces too (it reads workspace.branch). Same source deriveWorkspaceDisplayName
|
|
168
|
+
// reads. HEAD/detached resolves to null — there is no branch to report.
|
|
169
|
+
const currentBranch = checkout.currentBranch?.trim() ?? null;
|
|
170
|
+
const branch = currentBranch && currentBranch.toUpperCase() !== "HEAD" ? currentBranch : null;
|
|
171
|
+
const workspace = createPersistedWorkspaceRecord({
|
|
172
|
+
workspaceId: generateWorkspaceId(),
|
|
173
|
+
projectId: projectRecord.projectId,
|
|
174
|
+
cwd: normalizedCwd,
|
|
175
|
+
kind: membership.workspaceKind,
|
|
176
|
+
displayName: membership.workspaceDisplayName,
|
|
177
|
+
branch,
|
|
178
|
+
title: trimmedTitle ? trimmedTitle : null,
|
|
179
|
+
createdAt: now,
|
|
180
|
+
updatedAt: now,
|
|
181
|
+
});
|
|
182
|
+
await deps.workspaceRegistry.upsert(workspace);
|
|
183
|
+
return workspace;
|
|
184
|
+
}
|
|
185
|
+
async function resolveProjectRecordForMembership(options) {
|
|
186
|
+
const rootPath = options.membership.projectRootPath;
|
|
187
|
+
const projects = await options.projectRegistry.list();
|
|
188
|
+
const existingProject = projects.find((project) => !project.archivedAt && project.rootPath === rootPath) ??
|
|
189
|
+
projects.find((project) => project.rootPath === rootPath) ??
|
|
190
|
+
null;
|
|
191
|
+
if (!existingProject) {
|
|
192
|
+
return createPersistedProjectRecord({
|
|
193
|
+
projectId: options.membership.projectKey,
|
|
194
|
+
rootPath,
|
|
195
|
+
kind: options.membership.projectKind,
|
|
196
|
+
displayName: options.membership.projectName,
|
|
197
|
+
createdAt: options.timestamp,
|
|
198
|
+
updatedAt: options.timestamp,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
...existingProject,
|
|
203
|
+
rootPath,
|
|
204
|
+
kind: options.membership.projectKind,
|
|
205
|
+
archivedAt: null,
|
|
206
|
+
updatedAt: options.timestamp,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
146
209
|
function sourceProjectFromRecord(record) {
|
|
147
210
|
return {
|
|
148
211
|
projectId: record.projectId,
|
|
@@ -211,8 +274,4 @@ async function findWorkspaceForSource(options) {
|
|
|
211
274
|
workspaces.find((workspace) => workspace.cwd === options.repoRoot && !workspace.archivedAt) ??
|
|
212
275
|
null);
|
|
213
276
|
}
|
|
214
|
-
async function findWorkspaceByDirectory(cwd, workspaceRegistry) {
|
|
215
|
-
const workspaces = await workspaceRegistry.list();
|
|
216
|
-
return workspaces.find((workspace) => workspace.cwd === cwd) ?? null;
|
|
217
|
-
}
|
|
218
277
|
//# sourceMappingURL=paseo-worktree-service.js.map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare function assertAbsolutePath(cwd: string): void;
|
|
1
2
|
export declare function expandUserPath(value: string): string;
|
|
2
3
|
export declare function resolvePathFromBase(baseCwd: string, requestedPath: string): string;
|
|
3
4
|
export declare function isSameOrDescendantPath(basePath: string, candidatePath: string): boolean;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { homedir } from "node:os";
|
|
2
|
-
import { isAbsolute, resolve } from "node:path";
|
|
2
|
+
import { isAbsolute, posix, resolve, win32 } from "node:path";
|
|
3
|
+
export function assertAbsolutePath(cwd) {
|
|
4
|
+
if (!posix.isAbsolute(cwd) && !win32.isAbsolute(cwd)) {
|
|
5
|
+
throw new Error("cwd must be absolute path");
|
|
6
|
+
}
|
|
7
|
+
}
|
|
3
8
|
function hasHomePrefix(value) {
|
|
4
9
|
return value === "~" || value.startsWith("~/");
|
|
5
10
|
}
|
|
@@ -20,6 +20,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
20
20
|
injectIntoAgents: z.ZodOptional<z.ZodBoolean>;
|
|
21
21
|
}, z.ZodTypeAny, "passthrough">>>;
|
|
22
22
|
autoArchiveAfterMerge: z.ZodOptional<z.ZodBoolean>;
|
|
23
|
+
enableTerminalAgentHooks: z.ZodOptional<z.ZodBoolean>;
|
|
23
24
|
appendSystemPrompt: z.ZodOptional<z.ZodString>;
|
|
24
25
|
terminalProfiles: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
25
26
|
id: z.ZodString;
|
|
@@ -98,6 +99,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
98
99
|
hostnames?: true | string[] | undefined;
|
|
99
100
|
allowedHosts?: true | string[] | undefined;
|
|
100
101
|
autoArchiveAfterMerge?: boolean | undefined;
|
|
102
|
+
enableTerminalAgentHooks?: boolean | undefined;
|
|
101
103
|
appendSystemPrompt?: string | undefined;
|
|
102
104
|
terminalProfiles?: z.objectOutputType<{
|
|
103
105
|
id: z.ZodString;
|
|
@@ -133,6 +135,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
133
135
|
hostnames?: true | string[] | undefined;
|
|
134
136
|
allowedHosts?: true | string[] | undefined;
|
|
135
137
|
autoArchiveAfterMerge?: boolean | undefined;
|
|
138
|
+
enableTerminalAgentHooks?: boolean | undefined;
|
|
136
139
|
appendSystemPrompt?: string | undefined;
|
|
137
140
|
terminalProfiles?: z.objectInputType<{
|
|
138
141
|
id: z.ZodString;
|
|
@@ -167,6 +170,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
167
170
|
listen?: string | undefined;
|
|
168
171
|
hostnames?: true | string[] | undefined;
|
|
169
172
|
autoArchiveAfterMerge?: boolean | undefined;
|
|
173
|
+
enableTerminalAgentHooks?: boolean | undefined;
|
|
170
174
|
appendSystemPrompt?: string | undefined;
|
|
171
175
|
terminalProfiles?: z.objectOutputType<{
|
|
172
176
|
id: z.ZodString;
|
|
@@ -202,6 +206,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
202
206
|
hostnames?: true | string[] | undefined;
|
|
203
207
|
allowedHosts?: true | string[] | undefined;
|
|
204
208
|
autoArchiveAfterMerge?: boolean | undefined;
|
|
209
|
+
enableTerminalAgentHooks?: boolean | undefined;
|
|
205
210
|
appendSystemPrompt?: string | undefined;
|
|
206
211
|
terminalProfiles?: z.objectInputType<{
|
|
207
212
|
id: z.ZodString;
|
|
@@ -899,6 +904,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
899
904
|
listen?: string | undefined;
|
|
900
905
|
hostnames?: true | string[] | undefined;
|
|
901
906
|
autoArchiveAfterMerge?: boolean | undefined;
|
|
907
|
+
enableTerminalAgentHooks?: boolean | undefined;
|
|
902
908
|
appendSystemPrompt?: string | undefined;
|
|
903
909
|
terminalProfiles?: z.objectOutputType<{
|
|
904
910
|
id: z.ZodString;
|
|
@@ -1045,6 +1051,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
1045
1051
|
hostnames?: true | string[] | undefined;
|
|
1046
1052
|
allowedHosts?: true | string[] | undefined;
|
|
1047
1053
|
autoArchiveAfterMerge?: boolean | undefined;
|
|
1054
|
+
enableTerminalAgentHooks?: boolean | undefined;
|
|
1048
1055
|
appendSystemPrompt?: string | undefined;
|
|
1049
1056
|
terminalProfiles?: z.objectInputType<{
|
|
1050
1057
|
id: z.ZodString;
|
|
@@ -187,6 +187,7 @@ export const PersistedConfigSchema = z
|
|
|
187
187
|
.passthrough()
|
|
188
188
|
.optional(),
|
|
189
189
|
autoArchiveAfterMerge: z.boolean().optional(),
|
|
190
|
+
enableTerminalAgentHooks: z.boolean().optional(),
|
|
190
191
|
appendSystemPrompt: z.string().optional(),
|
|
191
192
|
terminalProfiles: z.array(TerminalProfileSchema).optional(),
|
|
192
193
|
cors: z
|
|
@@ -24,6 +24,7 @@ export declare function extractTimestamps(record: StoredAgentRecord): {
|
|
|
24
24
|
updatedAt: Date;
|
|
25
25
|
lastUserMessageAt: Date | null;
|
|
26
26
|
labels?: Record<string, string>;
|
|
27
|
+
workspaceId?: string;
|
|
27
28
|
};
|
|
28
29
|
export declare function toAgentPersistenceHandle(registeredProviders: Iterable<AgentProvider>, handle: StoredAgentRecord["persistence"]): AgentPersistenceHandle | null;
|
|
29
30
|
export {};
|
|
@@ -2,6 +2,15 @@ import { stripInternalPaseoMcpServer } from "./agent/runtime-mcp-config.js";
|
|
|
2
2
|
function getLogger(logger) {
|
|
3
3
|
return logger.child({ module: "persistence" });
|
|
4
4
|
}
|
|
5
|
+
function isProviderRegistered(validProviders, provider) {
|
|
6
|
+
if (!validProviders) {
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
if (validProviders instanceof Set) {
|
|
10
|
+
return validProviders.has(provider);
|
|
11
|
+
}
|
|
12
|
+
return new Set(validProviders).has(provider);
|
|
13
|
+
}
|
|
5
14
|
/**
|
|
6
15
|
* Attach AgentStorage persistence to an AgentManager instance so every
|
|
7
16
|
* agent_state snapshot is flushed to disk.
|
|
@@ -35,9 +44,7 @@ export function buildConfigOverrides(record) {
|
|
|
35
44
|
});
|
|
36
45
|
}
|
|
37
46
|
export function buildSessionConfig(record, options) {
|
|
38
|
-
|
|
39
|
-
const isValidProvider = validProviders ? new Set(validProviders).has(record.provider) : true;
|
|
40
|
-
if (!isValidProvider) {
|
|
47
|
+
if (!isProviderRegistered(options?.validProviders, record.provider)) {
|
|
41
48
|
return null;
|
|
42
49
|
}
|
|
43
50
|
const overrides = buildConfigOverrides(record);
|
|
@@ -54,7 +61,7 @@ export function buildSessionConfig(record, options) {
|
|
|
54
61
|
});
|
|
55
62
|
}
|
|
56
63
|
export function isStoredAgentProviderAvailable(record, validProviders) {
|
|
57
|
-
return
|
|
64
|
+
return isProviderRegistered(validProviders, record.provider);
|
|
58
65
|
}
|
|
59
66
|
export function extractTimestamps(record) {
|
|
60
67
|
return {
|
|
@@ -62,6 +69,7 @@ export function extractTimestamps(record) {
|
|
|
62
69
|
updatedAt: new Date(record.lastActivityAt ?? record.updatedAt),
|
|
63
70
|
lastUserMessageAt: record.lastUserMessageAt ? new Date(record.lastUserMessageAt) : null,
|
|
64
71
|
labels: record.labels,
|
|
72
|
+
workspaceId: record.workspaceId,
|
|
65
73
|
};
|
|
66
74
|
}
|
|
67
75
|
export function toAgentPersistenceHandle(registeredProviders, handle) {
|
|
@@ -69,7 +77,7 @@ export function toAgentPersistenceHandle(registeredProviders, handle) {
|
|
|
69
77
|
return null;
|
|
70
78
|
}
|
|
71
79
|
const provider = handle.provider;
|
|
72
|
-
if (!
|
|
80
|
+
if (!isProviderRegistered(registeredProviders, provider)) {
|
|
73
81
|
return null;
|
|
74
82
|
}
|
|
75
83
|
if (!handle.sessionId) {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { resolve, sep } from "node:path";
|
|
3
|
+
// external path→workspace adapter, not ownership.
|
|
4
|
+
//
|
|
5
|
+
// Resolves a raw filesystem path to a single workspace id ONLY at the boundary
|
|
6
|
+
// where a client hands the daemon a bare worktree path with no id:
|
|
7
|
+
// archive-by-path (old client / CLI), auto-archive-after-merge, and the MCP
|
|
8
|
+
// `archive_worktree` tool. It is NEVER used to attribute agent status or place
|
|
9
|
+
// agents under a workspace — those are keyed by `workspaceId`, and git facts
|
|
10
|
+
// derive from a workspace's OWN cwd (id → cwd).
|
|
11
|
+
//
|
|
12
|
+
// Resolution: an exact directory match wins; otherwise the deepest enclosing
|
|
13
|
+
// workspace directory, never the home directory; null when nothing encloses it.
|
|
14
|
+
export function resolveWorkspaceIdForPath(cwd, workspaces) {
|
|
15
|
+
const workspaceRecords = Array.from(workspaces);
|
|
16
|
+
const resolvedCwd = resolve(cwd);
|
|
17
|
+
const exactMatch = workspaceRecords.find((workspace) => resolve(workspace.cwd) === resolvedCwd);
|
|
18
|
+
if (exactMatch) {
|
|
19
|
+
return exactMatch.workspaceId;
|
|
20
|
+
}
|
|
21
|
+
const userHome = resolve(homedir());
|
|
22
|
+
let bestMatchLength = 0;
|
|
23
|
+
let bestMatch = null;
|
|
24
|
+
for (const workspace of workspaceRecords) {
|
|
25
|
+
if (workspace.archivedAt)
|
|
26
|
+
continue;
|
|
27
|
+
const workspaceCwd = resolve(workspace.cwd);
|
|
28
|
+
if (workspaceCwd === userHome)
|
|
29
|
+
continue;
|
|
30
|
+
const prefix = workspaceCwd.endsWith(sep) ? workspaceCwd : `${workspaceCwd}${sep}`;
|
|
31
|
+
if (!resolvedCwd.startsWith(prefix)) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (workspaceCwd.length > bestMatchLength) {
|
|
35
|
+
bestMatchLength = workspaceCwd.length;
|
|
36
|
+
bestMatch = workspace;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return bestMatch?.workspaceId ?? null;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=resolve-workspace-id-for-path.js.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { createScriptProxyMiddleware, createScriptProxyUpgradeHandler, findFreePort, ScriptRouteStore, } from "./service-proxy.js";
|
|
1
|
+
export { createScriptProxyMiddleware, createScriptProxyUpgradeHandler, findFreePort, ScriptRouteStore, ServiceProxyRouteCollisionError, } from "./service-proxy.js";
|
|
2
2
|
export type { ScriptRoute, ScriptRouteEntry } from "./service-proxy.js";
|
|
3
3
|
//# sourceMappingURL=script-proxy.d.ts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { createScriptProxyMiddleware, createScriptProxyUpgradeHandler, findFreePort, ScriptRouteStore, } from "./service-proxy.js";
|
|
1
|
+
export { createScriptProxyMiddleware, createScriptProxyUpgradeHandler, findFreePort, ScriptRouteStore, ServiceProxyRouteCollisionError, } from "./service-proxy.js";
|
|
2
2
|
//# sourceMappingURL=script-proxy.js.map
|
|
@@ -187,7 +187,7 @@ function sameRouteOwner(left, right) {
|
|
|
187
187
|
}
|
|
188
188
|
export class ServiceProxyRouteCollisionError extends Error {
|
|
189
189
|
constructor(hostname, existing, incoming) {
|
|
190
|
-
super(`
|
|
190
|
+
super(`Another workspace is already serving "${incoming.scriptName}" at ${hostname}. Stop that service or run this one on a different branch to free the address.`);
|
|
191
191
|
this.hostname = hostname;
|
|
192
192
|
this.existing = existing;
|
|
193
193
|
this.incoming = incoming;
|
|
@@ -16,6 +16,7 @@ import { type PersistedWorkspaceRecord, type ProjectRegistry, type WorkspaceRegi
|
|
|
16
16
|
import { DownloadTokenStore } from "./file-download/token-store.js";
|
|
17
17
|
import { PushTokenStore } from "./push/token-store.js";
|
|
18
18
|
import type { ServiceProxySubsystem } from "./service-proxy.js";
|
|
19
|
+
import { renameCurrentBranch as renameCurrentBranchDefault } from "../utils/checkout-git.js";
|
|
19
20
|
import { CheckoutDiffManager } from "./checkout-diff-manager.js";
|
|
20
21
|
import { type Resolvable } from "./speech/provider-resolver.js";
|
|
21
22
|
import type { SpeechReadinessSnapshot } from "./speech/speech-runtime.js";
|
|
@@ -24,6 +25,7 @@ import { FileBackedChatService } from "./chat/chat-service.js";
|
|
|
24
25
|
import { LoopService } from "./loop-service.js";
|
|
25
26
|
import { ScheduleService } from "./schedule/service.js";
|
|
26
27
|
import { type GitHubService } from "../services/github-service.js";
|
|
28
|
+
import { generateBranchNameFromFirstAgentContext } from "./worktree-branch-name-generator.js";
|
|
27
29
|
export declare function resolveWaitForFinishError(options: {
|
|
28
30
|
status: "permission" | "error" | "idle";
|
|
29
31
|
final: AgentSnapshotPayload | null;
|
|
@@ -44,6 +46,7 @@ export interface SessionOptions {
|
|
|
44
46
|
clientCapabilities?: Record<string, unknown> | null;
|
|
45
47
|
onMessage: (msg: SessionOutboundMessage) => void;
|
|
46
48
|
onBinaryMessage?: (frame: Uint8Array) => void;
|
|
49
|
+
getTransportBufferedAmount?: () => number | null;
|
|
47
50
|
onLifecycleIntent?: (intent: SessionLifecycleIntent) => void;
|
|
48
51
|
logger: pino.Logger;
|
|
49
52
|
downloadTokenStore: DownloadTokenStore;
|
|
@@ -61,6 +64,8 @@ export interface SessionOptions {
|
|
|
61
64
|
checkoutDiffManager: CheckoutDiffManager;
|
|
62
65
|
github?: GitHubService;
|
|
63
66
|
createAgentMcpTransport?: AgentMcpTransportFactory;
|
|
67
|
+
renameCurrentBranch?: typeof renameCurrentBranchDefault;
|
|
68
|
+
generateWorkspaceName?: typeof generateBranchNameFromFirstAgentContext;
|
|
64
69
|
workspaceGitService: WorkspaceGitService;
|
|
65
70
|
daemonConfigStore: DaemonConfigStore;
|
|
66
71
|
mcpBaseUrl?: string | null;
|
|
@@ -96,6 +101,7 @@ export interface SessionOptions {
|
|
|
96
101
|
daemonVersion?: string;
|
|
97
102
|
daemonRuntimeConfig?: {
|
|
98
103
|
listen: string | null;
|
|
104
|
+
appBaseUrl?: string;
|
|
99
105
|
relay: {
|
|
100
106
|
enabled: boolean;
|
|
101
107
|
endpoint: string;
|
|
@@ -127,6 +133,7 @@ export declare class Session {
|
|
|
127
133
|
private readonly sessionId;
|
|
128
134
|
private readonly onMessage;
|
|
129
135
|
private readonly onBinaryMessage;
|
|
136
|
+
private readonly getTransportBufferedAmount;
|
|
130
137
|
private readonly onLifecycleIntent;
|
|
131
138
|
private readonly sessionLogger;
|
|
132
139
|
private readonly paseoHome;
|
|
@@ -159,12 +166,15 @@ export declare class Session {
|
|
|
159
166
|
private readonly loopService;
|
|
160
167
|
private readonly checkoutDiffManager;
|
|
161
168
|
private readonly github;
|
|
169
|
+
private readonly renameCurrentBranch;
|
|
170
|
+
private readonly generateWorkspaceName;
|
|
162
171
|
private readonly workspaceGitService;
|
|
163
172
|
private readonly daemonConfigStore;
|
|
164
173
|
private readonly mcpBaseUrl;
|
|
165
174
|
private readonly downloadTokenStore;
|
|
166
175
|
private readonly pushTokenStore;
|
|
167
176
|
private unsubscribeAgentEvents;
|
|
177
|
+
private unsubscribeTerminalWorkspaceContributionEvents;
|
|
168
178
|
private agentUpdatesSubscription;
|
|
169
179
|
private workspaceUpdatesSubscription;
|
|
170
180
|
private clientActivity;
|
|
@@ -212,7 +222,6 @@ export declare class Session {
|
|
|
212
222
|
markWorkspaceArchivingForExternalMutation(workspaceIds: Iterable<string>, archivingAt: string): void;
|
|
213
223
|
clearWorkspaceArchivingForExternalMutation(workspaceIds: Iterable<string>): void;
|
|
214
224
|
emitWorkspaceUpdatesForExternalWorkspaceIds(workspaceIds: Iterable<string>): Promise<void>;
|
|
215
|
-
emitWorkspaceUpdatesForExternalCwds(cwds: Iterable<string>): Promise<void>;
|
|
216
225
|
warmWorkspaceGitDataForWorkspace(workspace: PersistedWorkspaceRecord): Promise<void>;
|
|
217
226
|
/**
|
|
218
227
|
* Get the client's current activity state
|
|
@@ -220,6 +229,7 @@ export declare class Session {
|
|
|
220
229
|
getClientActivity(): {
|
|
221
230
|
deviceType: "web" | "mobile";
|
|
222
231
|
focusedAgentId: string | null;
|
|
232
|
+
focusedTerminalId: string | null;
|
|
223
233
|
lastActivityAt: Date;
|
|
224
234
|
appVisible: boolean;
|
|
225
235
|
appVisibilityChangedAt: Date;
|
|
@@ -264,11 +274,10 @@ export declare class Session {
|
|
|
264
274
|
private getAgentUpdateTargetId;
|
|
265
275
|
private bufferOrEmitAgentUpdate;
|
|
266
276
|
private flushBootstrappedAgentUpdates;
|
|
267
|
-
private findWorkspaceByDirectory;
|
|
268
277
|
private findExactWorkspaceByDirectory;
|
|
269
278
|
private resolveWorkspaceDirectory;
|
|
270
279
|
private buildProjectPlacementForWorkspace;
|
|
271
|
-
private
|
|
280
|
+
private buildProjectPlacementForWorkspaceId;
|
|
272
281
|
private forwardAgentUpdate;
|
|
273
282
|
/**
|
|
274
283
|
* Main entry point for processing session messages
|
|
@@ -303,6 +312,7 @@ export declare class Session {
|
|
|
303
312
|
private unarchiveAgentByHandle;
|
|
304
313
|
private handleUpdateAgentRequest;
|
|
305
314
|
private handleProjectRenameRequest;
|
|
315
|
+
private handleWorkspaceTitleSetRequest;
|
|
306
316
|
private toVoiceFeatureUnavailableContext;
|
|
307
317
|
private resolveModeReadinessState;
|
|
308
318
|
private getVoiceFeatureUnavailableResponseMetadata;
|
|
@@ -326,7 +336,6 @@ export declare class Session {
|
|
|
326
336
|
* Handle create agent request
|
|
327
337
|
*/
|
|
328
338
|
private handleCreateAgentRequest;
|
|
329
|
-
private resolveCreateAgentWorkspace;
|
|
330
339
|
private handleResumeAgentRequest;
|
|
331
340
|
private handleImportAgentRequest;
|
|
332
341
|
private handleRefreshAgentRequest;
|
|
@@ -335,6 +344,10 @@ export declare class Session {
|
|
|
335
344
|
private buildAgentSessionConfig;
|
|
336
345
|
private scheduleAutoNameWorkspaceBranchForFirstAgent;
|
|
337
346
|
private maybeAutoNameWorkspaceBranchForFirstAgent;
|
|
347
|
+
private applyGeneratedWorkspaceTitle;
|
|
348
|
+
private generateWorkspaceTitleFromContext;
|
|
349
|
+
private maybeAutoNameDirectoryWorkspaceTitle;
|
|
350
|
+
private scheduleAutoNameLocalWorkspaceTitleForFirstAgent;
|
|
338
351
|
private emitProviderDisabledResponse;
|
|
339
352
|
private handleListProviderModelsRequest;
|
|
340
353
|
private handleListProviderModesRequest;
|
|
@@ -372,6 +385,7 @@ export declare class Session {
|
|
|
372
385
|
* Handle client heartbeat for activity tracking
|
|
373
386
|
*/
|
|
374
387
|
private handleClientHeartbeat;
|
|
388
|
+
private clearFocusedTerminalAttention;
|
|
375
389
|
/**
|
|
376
390
|
* Handle push token registration
|
|
377
391
|
*/
|
|
@@ -393,6 +407,7 @@ export declare class Session {
|
|
|
393
407
|
private removeWorkspaceGitWatchTarget;
|
|
394
408
|
private removeWorkspaceGitSubscription;
|
|
395
409
|
private workspaceGitDescriptorStateKey;
|
|
410
|
+
private resolveWorkspaceGitWatchTarget;
|
|
396
411
|
private shouldSkipWorkspaceGitWatchUpdate;
|
|
397
412
|
private rememberWorkspaceGitDescriptorState;
|
|
398
413
|
private handleWorkspaceGitBranchSnapshot;
|
|
@@ -437,13 +452,14 @@ export declare class Session {
|
|
|
437
452
|
* Handle file download token request scoped to a workspace cwd
|
|
438
453
|
*/
|
|
439
454
|
private handleFileDownloadTokenRequest;
|
|
455
|
+
private listTerminalActivityContributions;
|
|
440
456
|
/**
|
|
441
457
|
* Build the current agent list payload (live + persisted), optionally filtered by labels.
|
|
442
458
|
*/
|
|
443
459
|
private listAgentPayloads;
|
|
444
460
|
private resolveAgentIdentifier;
|
|
445
461
|
private getAgentPayloadById;
|
|
446
|
-
private
|
|
462
|
+
private buildActiveProjectPlacementsByWorkspaceId;
|
|
447
463
|
private collectFetchAgentsEntries;
|
|
448
464
|
private listFetchAgentsEntries;
|
|
449
465
|
private readonly agentsPager;
|
|
@@ -457,7 +473,7 @@ export declare class Session {
|
|
|
457
473
|
markWorkspaceArchiving(workspaceIds: Iterable<string>, archivingAt: string): void;
|
|
458
474
|
clearWorkspaceArchiving(workspaceIds: Iterable<string>): void;
|
|
459
475
|
private buildWorkspaceDescriptorMap;
|
|
460
|
-
private
|
|
476
|
+
private findWorkspaceIdForCwd;
|
|
461
477
|
private matchesWorkspaceFilter;
|
|
462
478
|
private listFetchWorkspacesEntries;
|
|
463
479
|
private bufferOrEmitWorkspaceUpdate;
|
|
@@ -468,10 +484,14 @@ export declare class Session {
|
|
|
468
484
|
private resolveProjectRecordForPlacement;
|
|
469
485
|
private ensureWorkspaceRecordUnarchived;
|
|
470
486
|
private createPaseoWorktree;
|
|
487
|
+
private listActiveWorkspaceRefs;
|
|
471
488
|
private archiveWorkspaceRecord;
|
|
489
|
+
private teardownArchivedWorkspace;
|
|
472
490
|
private reconcileAndEmitWorkspaceUpdates;
|
|
473
491
|
private reconcileActiveWorkspaceRecords;
|
|
474
492
|
private emitWorkspaceUpdatesForWorkspaceIds;
|
|
493
|
+
private resolveEmptyProjectForArchivedWorkspace;
|
|
494
|
+
private emitWorkspaceUpdateForTerminalContribution;
|
|
475
495
|
private emitWorkspaceUpdateForCwd;
|
|
476
496
|
private handleFetchAgents;
|
|
477
497
|
private handleFetchAgentHistory;
|
|
@@ -479,6 +499,11 @@ export declare class Session {
|
|
|
479
499
|
private handleFetchWorkspacesRequest;
|
|
480
500
|
private buildBootstrapSnapshot;
|
|
481
501
|
private registerWorkspaceForImportedAgent;
|
|
502
|
+
private handleWorkspaceCreateRequest;
|
|
503
|
+
private handleWorkspaceCreateLocal;
|
|
504
|
+
private scheduleWorkspaceNaming;
|
|
505
|
+
private handleWorkspaceCreateWorktree;
|
|
506
|
+
private resolveWorktreeSourceCwd;
|
|
482
507
|
private handleOpenProjectRequest;
|
|
483
508
|
private buildWorkspaceScriptPayloadSnapshot;
|
|
484
509
|
private resolveWorkspaceScriptGitMetadata;
|