@getpaseo/server 0.1.96 → 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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { classifyDirectoryForProjectMembership,
|
|
2
|
+
import { classifyDirectoryForProjectMembership, generateWorkspaceId, } from "./workspace-registry-model.js";
|
|
3
|
+
import { backfillWorkspaceIdForLegacyAgents } from "./migrations/backfill-workspace-id.migration.js";
|
|
3
4
|
import { createPersistedProjectRecord, createPersistedWorkspaceRecord, } from "./workspace-registry.js";
|
|
4
5
|
function minIsoDate(left, right) {
|
|
5
6
|
if (!left) {
|
|
@@ -32,28 +33,33 @@ export async function bootstrapWorkspaceRegistries(options) {
|
|
|
32
33
|
]);
|
|
33
34
|
await Promise.all([options.projectRegistry.initialize(), options.workspaceRegistry.initialize()]);
|
|
34
35
|
if (projectsExists && workspacesExists) {
|
|
36
|
+
await backfillWorkspaceIdForLegacyAgents(options);
|
|
35
37
|
return;
|
|
36
38
|
}
|
|
39
|
+
const existingWorkspaceIdsByCwd = new Map((await options.workspaceRegistry.list()).map((workspace) => [
|
|
40
|
+
path.resolve(workspace.cwd),
|
|
41
|
+
workspace.workspaceId,
|
|
42
|
+
]));
|
|
37
43
|
const records = await options.agentStorage.list();
|
|
38
44
|
const activeRecords = records.filter((record) => !record.archivedAt);
|
|
39
|
-
const
|
|
45
|
+
const recordsByDirectoryKey = new Map();
|
|
40
46
|
const placements = await Promise.all(activeRecords.map(async (record) => {
|
|
41
|
-
const normalizedCwd =
|
|
47
|
+
const normalizedCwd = path.resolve(record.cwd);
|
|
42
48
|
const checkout = await options.workspaceGitService.getCheckout(normalizedCwd);
|
|
43
49
|
const membership = classifyDirectoryForProjectMembership({
|
|
44
50
|
cwd: normalizedCwd,
|
|
45
51
|
checkout,
|
|
46
52
|
});
|
|
47
|
-
return { record, membership,
|
|
53
|
+
return { record, membership, directoryKey: membership.workspaceDirectoryKey };
|
|
48
54
|
}));
|
|
49
|
-
for (const { record, membership,
|
|
50
|
-
const existing =
|
|
55
|
+
for (const { record, membership, directoryKey } of placements) {
|
|
56
|
+
const existing = recordsByDirectoryKey.get(directoryKey) ?? { membership, records: [] };
|
|
51
57
|
existing.records.push(record);
|
|
52
|
-
|
|
58
|
+
recordsByDirectoryKey.set(directoryKey, existing);
|
|
53
59
|
}
|
|
54
60
|
const projectRanges = new Map();
|
|
55
61
|
const workspaceUpsertInputs = [];
|
|
56
|
-
for (const
|
|
62
|
+
for (const entry of recordsByDirectoryKey.values()) {
|
|
57
63
|
const { membership, records: workspaceRecords } = entry;
|
|
58
64
|
const workspaceCwd = membership.checkout.cwd;
|
|
59
65
|
let workspaceCreatedAt = null;
|
|
@@ -71,7 +77,13 @@ export async function bootstrapWorkspaceRegistries(options) {
|
|
|
71
77
|
existingProjectRange.createdAt = minIsoDate(existingProjectRange.createdAt, createdAt);
|
|
72
78
|
existingProjectRange.updatedAt = maxIsoDate(existingProjectRange.updatedAt, updatedAt);
|
|
73
79
|
projectRanges.set(membership.projectKey, existingProjectRange);
|
|
74
|
-
workspaceUpsertInputs.push({
|
|
80
|
+
workspaceUpsertInputs.push({
|
|
81
|
+
workspaceId: existingWorkspaceIdsByCwd.get(workspaceCwd) ?? generateWorkspaceId(),
|
|
82
|
+
membership,
|
|
83
|
+
workspaceCwd,
|
|
84
|
+
createdAt,
|
|
85
|
+
updatedAt,
|
|
86
|
+
});
|
|
75
87
|
}
|
|
76
88
|
await Promise.all(workspaceUpsertInputs.flatMap(({ workspaceId, membership, workspaceCwd, createdAt, updatedAt }) => {
|
|
77
89
|
const projectRange = projectRanges.get(membership.projectKey) ?? {
|
|
@@ -98,11 +110,12 @@ export async function bootstrapWorkspaceRegistries(options) {
|
|
|
98
110
|
})),
|
|
99
111
|
];
|
|
100
112
|
}));
|
|
113
|
+
await backfillWorkspaceIdForLegacyAgents(options);
|
|
101
114
|
options.logger.info({
|
|
102
115
|
projectsFile: path.join(options.paseoHome, "projects", "projects.json"),
|
|
103
116
|
workspacesFile: path.join(options.paseoHome, "projects", "workspaces.json"),
|
|
104
117
|
materializedProjects: projectRanges.size,
|
|
105
|
-
materializedWorkspaces:
|
|
118
|
+
materializedWorkspaces: recordsByDirectoryKey.size,
|
|
106
119
|
}, "Workspace registries bootstrapped from existing agent storage");
|
|
107
120
|
}
|
|
108
121
|
//# sourceMappingURL=workspace-registry-bootstrap.js.map
|
|
@@ -5,7 +5,7 @@ export type PersistedWorkspaceKind = "local_checkout" | "worktree" | "directory"
|
|
|
5
5
|
export interface DirectoryProjectMembership {
|
|
6
6
|
cwd: string;
|
|
7
7
|
checkout: ProjectCheckoutLitePayload;
|
|
8
|
-
|
|
8
|
+
workspaceDirectoryKey: string;
|
|
9
9
|
workspaceKind: PersistedWorkspaceKind;
|
|
10
10
|
workspaceDisplayName: string;
|
|
11
11
|
projectKey: string;
|
|
@@ -17,8 +17,8 @@ export interface DetectStaleWorkspacesInput {
|
|
|
17
17
|
activeWorkspaces: PersistedWorkspaceRecord[];
|
|
18
18
|
checkDirectoryExists: (cwd: string) => Promise<boolean>;
|
|
19
19
|
}
|
|
20
|
-
export declare function
|
|
21
|
-
export declare function
|
|
20
|
+
export declare function generateWorkspaceId(): string;
|
|
21
|
+
export declare function deriveWorkspaceDirectoryKey(cwd: string, checkout: ProjectCheckoutLitePayload): string;
|
|
22
22
|
export declare function deriveProjectGroupingKey(options: {
|
|
23
23
|
cwd: string;
|
|
24
24
|
remoteUrl: string | null;
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
1
2
|
import { resolve } from "node:path";
|
|
2
3
|
import { parseGitRevParsePath } from "../utils/git-rev-parse-path.js";
|
|
3
|
-
export function
|
|
4
|
-
|
|
5
|
-
if (!trimmed) {
|
|
6
|
-
return cwd;
|
|
7
|
-
}
|
|
8
|
-
return resolve(trimmed);
|
|
4
|
+
export function generateWorkspaceId() {
|
|
5
|
+
return `wks_${randomBytes(8).toString("hex")}`;
|
|
9
6
|
}
|
|
10
|
-
|
|
7
|
+
// Path-derived grouping key for a workspace directory. This is NOT the opaque
|
|
8
|
+
// workspace identity (see generateWorkspaceId); never persist or compare it as one.
|
|
9
|
+
export function deriveWorkspaceDirectoryKey(cwd, checkout) {
|
|
11
10
|
const worktreeRoot = checkout.worktreeRoot ? parseGitRevParsePath(checkout.worktreeRoot) : null;
|
|
12
|
-
return worktreeRoot ??
|
|
11
|
+
return worktreeRoot ?? resolve(cwd);
|
|
13
12
|
}
|
|
14
13
|
function deriveRemoteProjectKey(remoteUrl) {
|
|
15
14
|
if (!remoteUrl) {
|
|
@@ -160,7 +159,7 @@ export function buildProjectPlacementForCwd(input) {
|
|
|
160
159
|
};
|
|
161
160
|
}
|
|
162
161
|
export function classifyDirectoryForProjectMembership(input) {
|
|
163
|
-
const normalizedCwd =
|
|
162
|
+
const normalizedCwd = resolve(input.cwd);
|
|
164
163
|
const checkout = {
|
|
165
164
|
...input.checkout,
|
|
166
165
|
cwd: normalizedCwd,
|
|
@@ -173,7 +172,7 @@ export function classifyDirectoryForProjectMembership(input) {
|
|
|
173
172
|
return {
|
|
174
173
|
cwd: normalizedCwd,
|
|
175
174
|
checkout,
|
|
176
|
-
|
|
175
|
+
workspaceDirectoryKey: deriveWorkspaceDirectoryKey(normalizedCwd, checkout),
|
|
177
176
|
workspaceKind: deriveWorkspaceKind(checkout),
|
|
178
177
|
workspaceDisplayName: deriveWorkspaceDisplayName({
|
|
179
178
|
cwd: normalizedCwd,
|
|
@@ -11,19 +11,19 @@ declare const PersistedProjectRecordSchema: z.ZodObject<{
|
|
|
11
11
|
updatedAt: z.ZodString;
|
|
12
12
|
archivedAt: z.ZodNullable<z.ZodString>;
|
|
13
13
|
}, "strip", z.ZodTypeAny, {
|
|
14
|
+
kind: "git" | "non_git";
|
|
14
15
|
createdAt: string;
|
|
15
16
|
updatedAt: string;
|
|
16
17
|
archivedAt: string | null;
|
|
17
|
-
kind: "git" | "non_git";
|
|
18
18
|
projectId: string;
|
|
19
19
|
displayName: string;
|
|
20
20
|
rootPath: string;
|
|
21
21
|
customName: string | null;
|
|
22
22
|
}, {
|
|
23
|
+
kind: "git" | "non_git";
|
|
23
24
|
createdAt: string;
|
|
24
25
|
updatedAt: string;
|
|
25
26
|
archivedAt: string | null;
|
|
26
|
-
kind: "git" | "non_git";
|
|
27
27
|
projectId: string;
|
|
28
28
|
displayName: string;
|
|
29
29
|
rootPath: string;
|
|
@@ -35,27 +35,33 @@ declare const PersistedWorkspaceRecordSchema: z.ZodObject<{
|
|
|
35
35
|
cwd: z.ZodString;
|
|
36
36
|
kind: z.ZodEnum<["local_checkout", "worktree", "directory"]>;
|
|
37
37
|
displayName: z.ZodString;
|
|
38
|
+
title: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodString>>, string | null, string | null | undefined>;
|
|
39
|
+
branch: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodString>>, string | null, string | null | undefined>;
|
|
38
40
|
createdAt: z.ZodString;
|
|
39
41
|
updatedAt: z.ZodString;
|
|
40
42
|
archivedAt: z.ZodNullable<z.ZodString>;
|
|
41
43
|
}, "strip", z.ZodTypeAny, {
|
|
44
|
+
kind: "local_checkout" | "worktree" | "directory";
|
|
42
45
|
workspaceId: string;
|
|
43
46
|
cwd: string;
|
|
47
|
+
title: string | null;
|
|
44
48
|
createdAt: string;
|
|
45
49
|
updatedAt: string;
|
|
46
50
|
archivedAt: string | null;
|
|
47
|
-
kind: "local_checkout" | "worktree" | "directory";
|
|
48
51
|
projectId: string;
|
|
49
52
|
displayName: string;
|
|
53
|
+
branch: string | null;
|
|
50
54
|
}, {
|
|
55
|
+
kind: "local_checkout" | "worktree" | "directory";
|
|
51
56
|
workspaceId: string;
|
|
52
57
|
cwd: string;
|
|
53
58
|
createdAt: string;
|
|
54
59
|
updatedAt: string;
|
|
55
60
|
archivedAt: string | null;
|
|
56
|
-
kind: "local_checkout" | "worktree" | "directory";
|
|
57
61
|
projectId: string;
|
|
58
62
|
displayName: string;
|
|
63
|
+
title?: string | null | undefined;
|
|
64
|
+
branch?: string | null | undefined;
|
|
59
65
|
}>;
|
|
60
66
|
export type PersistedProjectRecord = z.infer<typeof PersistedProjectRecordSchema>;
|
|
61
67
|
export type PersistedWorkspaceRecord = z.infer<typeof PersistedWorkspaceRecordSchema>;
|
|
@@ -127,9 +133,16 @@ export declare function createPersistedWorkspaceRecord(input: {
|
|
|
127
133
|
cwd: string;
|
|
128
134
|
kind: PersistedWorkspaceKind;
|
|
129
135
|
displayName: string;
|
|
136
|
+
title?: string | null;
|
|
137
|
+
branch?: string | null;
|
|
130
138
|
createdAt: string;
|
|
131
139
|
updatedAt: string;
|
|
132
140
|
archivedAt?: string | null;
|
|
133
141
|
}): PersistedWorkspaceRecord;
|
|
142
|
+
export declare function resolveWorkspaceName(input: {
|
|
143
|
+
title: string | null;
|
|
144
|
+
derivedDisplayName: string;
|
|
145
|
+
}): string;
|
|
146
|
+
export declare function resolveWorkspaceDisplayName(record: PersistedWorkspaceRecord): string;
|
|
134
147
|
export {};
|
|
135
148
|
//# sourceMappingURL=workspace-registry.d.ts.map
|
|
@@ -23,6 +23,22 @@ const PersistedWorkspaceRecordSchema = z.object({
|
|
|
23
23
|
cwd: z.string(),
|
|
24
24
|
kind: z.enum(["local_checkout", "worktree", "directory"]),
|
|
25
25
|
displayName: z.string(),
|
|
26
|
+
// User-set title layered over the derived displayName. In Model B the title is
|
|
27
|
+
// the workspace identity; branch/directory are backing metadata. Reconciliation
|
|
28
|
+
// never touches this. Null means "use the derived displayName".
|
|
29
|
+
title: z
|
|
30
|
+
.string()
|
|
31
|
+
.nullable()
|
|
32
|
+
.optional()
|
|
33
|
+
.transform((value) => value ?? null),
|
|
34
|
+
// The worktree's git branch. Decoupled from displayName/title by construction:
|
|
35
|
+
// displayName holds the human name (title), branch holds the git branch. Only
|
|
36
|
+
// worktree workspaces carry a branch; directory/local_checkout leave it null.
|
|
37
|
+
branch: z
|
|
38
|
+
.string()
|
|
39
|
+
.nullable()
|
|
40
|
+
.optional()
|
|
41
|
+
.transform((value) => value ?? null),
|
|
26
42
|
createdAt: z.string(),
|
|
27
43
|
updatedAt: z.string(),
|
|
28
44
|
archivedAt: z.string().nullable(),
|
|
@@ -152,7 +168,18 @@ export function resolveProjectDisplayName(record) {
|
|
|
152
168
|
export function createPersistedWorkspaceRecord(input) {
|
|
153
169
|
return PersistedWorkspaceRecordSchema.parse({
|
|
154
170
|
...input,
|
|
171
|
+
title: input.title ?? null,
|
|
172
|
+
branch: input.branch ?? null,
|
|
155
173
|
archivedAt: input.archivedAt ?? null,
|
|
156
174
|
});
|
|
157
175
|
}
|
|
176
|
+
// The single workspace-name rule: the user-set title always wins; otherwise fall
|
|
177
|
+
// back to the freshest available derived display name (a live branch snapshot when
|
|
178
|
+
// the caller has one, the persisted displayName otherwise).
|
|
179
|
+
export function resolveWorkspaceName(input) {
|
|
180
|
+
return input.title ?? input.derivedDisplayName;
|
|
181
|
+
}
|
|
182
|
+
export function resolveWorkspaceDisplayName(record) {
|
|
183
|
+
return resolveWorkspaceName({ title: record.title, derivedDisplayName: record.displayName });
|
|
184
|
+
}
|
|
158
185
|
//# sourceMappingURL=workspace-registry.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ArchiveDependencies, type ArchiveScope } from "../workspace-archive-service.js";
|
|
2
2
|
import type { CreatePaseoWorktreeInput, CreatePaseoWorktreeResult } from "../paseo-worktree-service.js";
|
|
3
3
|
import { type WorktreeWireError } from "../worktree-errors.js";
|
|
4
4
|
import type { WorkspaceGitService, WorkspaceGitWorktreeInfo } from "../workspace-git-service.js";
|
|
@@ -29,17 +29,19 @@ export type CreatePaseoWorktreeCommandResult<Result extends CreatePaseoWorktreeR
|
|
|
29
29
|
cause: unknown;
|
|
30
30
|
};
|
|
31
31
|
export declare function createPaseoWorktreeCommand<Result extends CreatePaseoWorktreeResult>(dependencies: CreatePaseoWorktreeCommandDependencies<Result>, input: CreatePaseoWorktreeCommandInput): Promise<CreatePaseoWorktreeCommandResult<Result>>;
|
|
32
|
-
export interface
|
|
32
|
+
export interface ArchiveCommandDependencies extends Omit<ArchiveDependencies, "workspaceGitService"> {
|
|
33
33
|
workspaceGitService: Pick<WorkspaceGitService, "getSnapshot" | "listWorktrees">;
|
|
34
34
|
}
|
|
35
|
-
export interface
|
|
35
|
+
export interface ArchiveCommandInput {
|
|
36
36
|
requestId: string;
|
|
37
37
|
repoRoot?: string | null;
|
|
38
38
|
worktreePath?: string;
|
|
39
39
|
worktreeSlug?: string;
|
|
40
40
|
branchName?: string;
|
|
41
|
+
workspaceId?: string;
|
|
42
|
+
scope?: ArchiveScope["kind"];
|
|
41
43
|
}
|
|
42
|
-
export type
|
|
44
|
+
export type ArchiveCommandResult = {
|
|
43
45
|
ok: true;
|
|
44
46
|
removedAgents: string[];
|
|
45
47
|
} | {
|
|
@@ -48,6 +50,6 @@ export type ArchivePaseoWorktreeCommandResult = {
|
|
|
48
50
|
message: string;
|
|
49
51
|
removedAgents: [];
|
|
50
52
|
};
|
|
51
|
-
export declare function
|
|
53
|
+
export declare function archiveCommand(dependencies: ArchiveCommandDependencies, input: ArchiveCommandInput): Promise<ArchiveCommandResult>;
|
|
52
54
|
export {};
|
|
53
55
|
//# sourceMappingURL=commands.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import { getPaseoWorktreesRoot, isPaseoOwnedWorktreeCwd } from "../../utils/worktree.js";
|
|
3
|
-
import {
|
|
3
|
+
import { archiveByScope, resolveWorkspaceIdAtPath, } from "../workspace-archive-service.js";
|
|
4
4
|
import { toWorktreeWireError } from "../worktree-errors.js";
|
|
5
5
|
export async function listPaseoWorktreesCommand(dependencies, input) {
|
|
6
6
|
if (input.reason) {
|
|
@@ -29,31 +29,51 @@ export async function createPaseoWorktreeCommand(dependencies, input) {
|
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
export async function
|
|
32
|
+
export async function archiveCommand(dependencies, input) {
|
|
33
33
|
const resolvedTarget = await resolveArchiveTarget(dependencies, input);
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
const scope = input.scope ?? "workspace";
|
|
35
|
+
if (scope === "worktree") {
|
|
36
|
+
const ownership = await isPaseoOwnedWorktreeCwd(resolvedTarget.targetPath, {
|
|
37
|
+
paseoHome: dependencies.paseoHome,
|
|
38
|
+
worktreesRoot: dependencies.paseoWorktreesBaseRoot,
|
|
39
|
+
});
|
|
40
|
+
if (!ownership.allowed) {
|
|
41
|
+
return {
|
|
42
|
+
ok: false,
|
|
43
|
+
code: "NOT_ALLOWED",
|
|
44
|
+
message: "Worktree is not a Paseo-owned worktree",
|
|
45
|
+
removedAgents: [],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const result = await archiveByScope(dependencies, {
|
|
49
|
+
scope: { kind: "worktree", targetPath: resolvedTarget.targetPath },
|
|
50
|
+
repoRoot: ownership.repoRoot ?? resolvedTarget.repoRoot ?? null,
|
|
51
|
+
repoWorktreesRoot: ownership.worktreeRoot,
|
|
52
|
+
paseoWorktreesBaseRoot: dependencies.paseoWorktreesBaseRoot,
|
|
53
|
+
requestId: input.requestId,
|
|
54
|
+
});
|
|
39
55
|
return {
|
|
40
|
-
ok:
|
|
41
|
-
|
|
42
|
-
|
|
56
|
+
ok: true,
|
|
57
|
+
removedAgents: result.archivedAgentIds,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const workspaceId = input.workspaceId ?? (await resolveWorkspaceIdAtPath(dependencies, resolvedTarget.targetPath));
|
|
61
|
+
if (!workspaceId) {
|
|
62
|
+
dependencies.sessionLogger?.warn({ targetPath: resolvedTarget.targetPath }, "Could not resolve workspace for archive; skipping");
|
|
63
|
+
return {
|
|
64
|
+
ok: true,
|
|
43
65
|
removedAgents: [],
|
|
44
66
|
};
|
|
45
67
|
}
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
worktreesRoot: ownership.worktreeRoot,
|
|
51
|
-
worktreesBaseRoot: dependencies.worktreesRoot,
|
|
68
|
+
const result = await archiveByScope(dependencies, {
|
|
69
|
+
scope: { kind: "workspace", workspaceId },
|
|
70
|
+
repoRoot: resolvedTarget.repoRoot,
|
|
71
|
+
paseoWorktreesBaseRoot: dependencies.paseoWorktreesBaseRoot,
|
|
52
72
|
requestId: input.requestId,
|
|
53
73
|
});
|
|
54
74
|
return {
|
|
55
75
|
ok: true,
|
|
56
|
-
removedAgents,
|
|
76
|
+
removedAgents: result.archivedAgentIds,
|
|
57
77
|
};
|
|
58
78
|
}
|
|
59
79
|
async function resolveArchiveTarget(dependencies, input) {
|
|
@@ -81,7 +101,7 @@ async function resolveArchiveTarget(dependencies, input) {
|
|
|
81
101
|
throw new Error("worktreePath, worktreeSlug, or repoRoot+branchName is required");
|
|
82
102
|
}
|
|
83
103
|
async function resolveWorktreeSlugPath(dependencies, repoRoot, worktreeSlug) {
|
|
84
|
-
const worktreesRoot = await getPaseoWorktreesRoot(repoRoot, dependencies.paseoHome, dependencies.
|
|
104
|
+
const worktreesRoot = await getPaseoWorktreesRoot(repoRoot, dependencies.paseoHome, dependencies.paseoWorktreesBaseRoot);
|
|
85
105
|
return join(worktreesRoot, worktreeSlug);
|
|
86
106
|
}
|
|
87
107
|
//# sourceMappingURL=commands.js.map
|
|
@@ -383,6 +383,7 @@ async function runWorktreeTerminalBootstrap(options, runtimeEnv) {
|
|
|
383
383
|
cwd: options.worktree.worktreePath,
|
|
384
384
|
name: spec.name,
|
|
385
385
|
env: runtimeEnv,
|
|
386
|
+
workspaceId: options.workspaceId,
|
|
386
387
|
});
|
|
387
388
|
await waitForTerminalBootstrapReadiness(terminal);
|
|
388
389
|
terminal.send({
|
|
@@ -550,7 +551,7 @@ async function setupServiceScriptRoute(params) {
|
|
|
550
551
|
return { hostname: registeredRoute.hostname, port, env };
|
|
551
552
|
}
|
|
552
553
|
async function acquireWorkspaceScriptTerminal(params) {
|
|
553
|
-
const { serviceScript, existingRuntimeEntry, terminalManager, repoRoot, scriptName, env } = params;
|
|
554
|
+
const { serviceScript, existingRuntimeEntry, terminalManager, repoRoot, workspaceId, scriptName, env, } = params;
|
|
554
555
|
let reusableTerminal = null;
|
|
555
556
|
if (!serviceScript && existingRuntimeEntry?.terminalId) {
|
|
556
557
|
reusableTerminal = terminalManager.getTerminal(existingRuntimeEntry.terminalId) ?? null;
|
|
@@ -558,6 +559,7 @@ async function acquireWorkspaceScriptTerminal(params) {
|
|
|
558
559
|
const terminal = reusableTerminal ??
|
|
559
560
|
(await terminalManager.createTerminal({
|
|
560
561
|
cwd: repoRoot,
|
|
562
|
+
workspaceId,
|
|
561
563
|
name: scriptName,
|
|
562
564
|
title: scriptName,
|
|
563
565
|
env,
|
|
@@ -612,6 +614,7 @@ export async function spawnWorkspaceScript(options) {
|
|
|
612
614
|
existingRuntimeEntry,
|
|
613
615
|
terminalManager,
|
|
614
616
|
repoRoot,
|
|
617
|
+
workspaceId,
|
|
615
618
|
scriptName,
|
|
616
619
|
env,
|
|
617
620
|
});
|
|
@@ -26,6 +26,10 @@ export interface GenerateBranchNameFromFirstAgentContextOptions {
|
|
|
26
26
|
generateStructuredAgentResponseWithFallback?: typeof generateStructuredAgentResponseWithFallback;
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
|
-
export
|
|
29
|
+
export interface GeneratedWorkspaceName {
|
|
30
|
+
title: string | null;
|
|
31
|
+
branch: string | null;
|
|
32
|
+
}
|
|
33
|
+
export declare function generateBranchNameFromFirstAgentContext(options: GenerateBranchNameFromFirstAgentContextOptions): Promise<GeneratedWorkspaceName | null>;
|
|
30
34
|
export {};
|
|
31
35
|
//# sourceMappingURL=worktree-branch-name-generator.d.ts.map
|
|
@@ -4,6 +4,7 @@ import { resolveStructuredGenerationProviders, } from "./agent/structured-genera
|
|
|
4
4
|
import { buildAgentBranchNameSeed } from "./agent/prompt-attachments.js";
|
|
5
5
|
import { buildMetadataPrompt } from "../utils/build-metadata-prompt.js";
|
|
6
6
|
const BranchNameSchema = z.object({
|
|
7
|
+
title: z.string().min(1).max(80),
|
|
7
8
|
branch: z.string().min(1).max(100),
|
|
8
9
|
});
|
|
9
10
|
async function buildPrompt(seed, options) {
|
|
@@ -13,10 +14,12 @@ async function buildPrompt(seed, options) {
|
|
|
13
14
|
configKey: "branchName",
|
|
14
15
|
before: [
|
|
15
16
|
"Generate a git branch name for a coding agent based on the user prompt and attachments.",
|
|
17
|
+
"Title: a short human-readable sentence-case label for the task (no slug rules, max 80 characters).",
|
|
16
18
|
"Branch: concise lowercase slug using letters, numbers, hyphens, and slashes only.",
|
|
17
19
|
"No spaces, no uppercase, no leading or trailing hyphen, no consecutive hyphens.",
|
|
20
|
+
"The branch is generated directly from the prompt — it is NEVER derived from or slugified from the title.",
|
|
18
21
|
].join("\n"),
|
|
19
|
-
after: "Return JSON only with
|
|
22
|
+
after: "Return JSON only with fields 'title' and 'branch'.",
|
|
20
23
|
trailing: `User context:\n${seed}`,
|
|
21
24
|
});
|
|
22
25
|
}
|
|
@@ -54,7 +57,10 @@ export async function generateBranchNameFromFirstAgentContext(options) {
|
|
|
54
57
|
internal: true,
|
|
55
58
|
},
|
|
56
59
|
});
|
|
57
|
-
return
|
|
60
|
+
return {
|
|
61
|
+
title: result.title.trim() || null,
|
|
62
|
+
branch: result.branch.trim() || null,
|
|
63
|
+
};
|
|
58
64
|
}
|
|
59
65
|
catch (error) {
|
|
60
66
|
const attempts = error instanceof StructuredAgentFallbackError ? error.attempts : undefined;
|
|
@@ -11,7 +11,7 @@ import type { GitHubService } from "../services/github-service.js";
|
|
|
11
11
|
import type { CheckoutExistingBranchResult } from "../utils/checkout-git.js";
|
|
12
12
|
import { type WorktreeConfig } from "../utils/worktree.js";
|
|
13
13
|
import type { CreatePaseoWorktreeInput, CreatePaseoWorktreeResult } from "./paseo-worktree-service.js";
|
|
14
|
-
import type {
|
|
14
|
+
import type { ArchiveDependencies } from "./workspace-archive-service.js";
|
|
15
15
|
export interface NormalizedGitOptions {
|
|
16
16
|
baseBranch?: string;
|
|
17
17
|
createNewBranch: boolean;
|
|
@@ -49,9 +49,7 @@ interface BuildAgentSessionConfigDependencies {
|
|
|
49
49
|
interface CreatePaseoWorktreeInBackgroundDependencies {
|
|
50
50
|
paseoHome?: string;
|
|
51
51
|
worktreesRoot?: string;
|
|
52
|
-
|
|
53
|
-
dedupeGitState?: boolean;
|
|
54
|
-
}) => Promise<void>;
|
|
52
|
+
emitWorkspaceUpdateForWorkspaceId: (workspaceId: string) => Promise<void>;
|
|
55
53
|
cacheWorkspaceSetupSnapshot: (workspaceId: string, snapshot: WorkspaceSetupSnapshot) => void;
|
|
56
54
|
emit: EmitSessionMessage;
|
|
57
55
|
sessionLogger: Logger;
|
|
@@ -112,6 +110,7 @@ interface HandleCreatePaseoWorktreeRequestDependencies {
|
|
|
112
110
|
export declare function buildAgentSessionConfig(dependencies: BuildAgentSessionConfigDependencies, config: AgentSessionConfig, gitOptions?: GitSetupOptions, legacyWorktreeName?: string, firstAgentContext?: FirstAgentContext): Promise<{
|
|
113
111
|
sessionConfig: AgentSessionConfig;
|
|
114
112
|
setupContinuation?: AgentWorktreeSetupContinuation;
|
|
113
|
+
createdWorkspaceId?: string;
|
|
115
114
|
}>;
|
|
116
115
|
export declare function normalizeGitOptions(gitOptions?: GitSetupOptions, legacyWorktreeName?: string): NormalizedGitOptions | null;
|
|
117
116
|
export declare function assertSafeGitRef(ref: string, label: string): void;
|
|
@@ -123,7 +122,7 @@ export declare function handlePaseoWorktreeListRequest(dependencies: {
|
|
|
123
122
|
}, msg: Extract<SessionInboundMessage, {
|
|
124
123
|
type: "paseo_worktree_list_request";
|
|
125
124
|
}>): Promise<void>;
|
|
126
|
-
export declare function handlePaseoWorktreeArchiveRequest(dependencies: Omit<
|
|
125
|
+
export declare function handlePaseoWorktreeArchiveRequest(dependencies: Omit<ArchiveDependencies, "emitWorkspaceUpdatesForWorkspaceIds" | "workspaceGitService"> & {
|
|
127
126
|
emit: EmitSessionMessage;
|
|
128
127
|
workspaceGitService: Pick<WorkspaceGitService, "getSnapshot" | "listWorktrees">;
|
|
129
128
|
emitWorkspaceUpdatesForWorkspaceIds: (workspaceIds: Iterable<string>) => Promise<void>;
|
|
@@ -4,7 +4,7 @@ import { expandTilde } from "../utils/path.js";
|
|
|
4
4
|
import { getWorktreeSetupCommands, resolveWorktreeRuntimeEnv, runWorktreeSetupCommands, slugify, validateBranchSlug, WorktreeSetupError, } from "../utils/worktree.js";
|
|
5
5
|
import { toCheckoutError } from "./checkout-git-utils.js";
|
|
6
6
|
import { toWorktreeWireError } from "./worktree-errors.js";
|
|
7
|
-
import {
|
|
7
|
+
import { archiveCommand, createPaseoWorktreeCommand, listPaseoWorktreesCommand, } from "./worktree/commands.js";
|
|
8
8
|
const SAFE_GIT_REF_PATTERN = /^[A-Za-z0-9._/-]+$/;
|
|
9
9
|
function normalizeFirstAgentContext(request) {
|
|
10
10
|
if (request.firstAgentContext) {
|
|
@@ -22,6 +22,7 @@ export async function buildAgentSessionConfig(dependencies, config, gitOptions,
|
|
|
22
22
|
let cwd = expandTilde(config.cwd);
|
|
23
23
|
const normalized = normalizeGitOptions(gitOptions, legacyWorktreeName);
|
|
24
24
|
let setupContinuation;
|
|
25
|
+
let createdWorkspaceId;
|
|
25
26
|
if (!normalized) {
|
|
26
27
|
return {
|
|
27
28
|
sessionConfig: {
|
|
@@ -49,6 +50,7 @@ export async function buildAgentSessionConfig(dependencies, config, gitOptions,
|
|
|
49
50
|
});
|
|
50
51
|
cwd = createdWorktree.worktree.worktreePath;
|
|
51
52
|
setupContinuation = createdWorktree.setupContinuation;
|
|
53
|
+
createdWorkspaceId = createdWorktree.workspace.workspaceId;
|
|
52
54
|
}
|
|
53
55
|
else if (normalized.createNewBranch) {
|
|
54
56
|
const baseBranch = normalized.baseBranch ??
|
|
@@ -70,6 +72,7 @@ export async function buildAgentSessionConfig(dependencies, config, gitOptions,
|
|
|
70
72
|
cwd,
|
|
71
73
|
},
|
|
72
74
|
setupContinuation,
|
|
75
|
+
createdWorkspaceId,
|
|
73
76
|
};
|
|
74
77
|
}
|
|
75
78
|
function validateNormalizedGitOptions(input) {
|
|
@@ -195,11 +198,13 @@ export async function handlePaseoWorktreeListRequest(dependencies, msg) {
|
|
|
195
198
|
export async function handlePaseoWorktreeArchiveRequest(dependencies, msg) {
|
|
196
199
|
const { requestId } = msg;
|
|
197
200
|
try {
|
|
198
|
-
const result = await
|
|
201
|
+
const result = await archiveCommand(dependencies, {
|
|
199
202
|
requestId,
|
|
200
203
|
worktreePath: msg.worktreePath,
|
|
201
204
|
repoRoot: msg.repoRoot,
|
|
202
205
|
branchName: msg.branchName,
|
|
206
|
+
workspaceId: msg.workspaceId,
|
|
207
|
+
scope: msg.scope,
|
|
203
208
|
});
|
|
204
209
|
if (!result.ok) {
|
|
205
210
|
dependencies.emit({
|
|
@@ -343,6 +348,7 @@ export async function createPaseoWorktreeWorkflow(dependencies, input, options)
|
|
|
343
348
|
startAfterAgentCreate: ({ agentId }) => {
|
|
344
349
|
void runAsyncWorktreeBootstrap({
|
|
345
350
|
agentId,
|
|
351
|
+
workspaceId: workspace.workspaceId,
|
|
346
352
|
worktree: createdWorktree.worktree,
|
|
347
353
|
shouldBootstrap: createdWorktree.created,
|
|
348
354
|
terminalManager: setupContinuation.terminalManager,
|
|
@@ -454,7 +460,7 @@ export async function runWorktreeSetupInBackground(dependencies, options) {
|
|
|
454
460
|
}
|
|
455
461
|
}
|
|
456
462
|
finally {
|
|
457
|
-
await dependencies.
|
|
463
|
+
await dependencies.emitWorkspaceUpdateForWorkspaceId(options.workspaceId);
|
|
458
464
|
}
|
|
459
465
|
}
|
|
460
466
|
//# sourceMappingURL=worktree-session.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { findExecutable } from "../
|
|
2
|
+
import { findExecutable } from "../executable-resolution/executable-resolution.js";
|
|
3
3
|
import { resolveGitHubRemote } from "../utils/github-remote.js";
|
|
4
4
|
import { runGitCommand } from "../utils/run-git-command.js";
|
|
5
5
|
import { execCommand } from "../utils/spawn.js";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { TerminalActivityAttentionReason, TerminalActivityState } from "@getpaseo/protocol/terminal-activity";
|
|
2
|
+
export interface TerminalActivitySnapshot {
|
|
3
|
+
state: TerminalActivityState | null;
|
|
4
|
+
attentionReason: TerminalActivityAttentionReason | null;
|
|
5
|
+
changedAt: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class TerminalActivityTracker {
|
|
8
|
+
private resolvedState;
|
|
9
|
+
private attentionReason;
|
|
10
|
+
private changedAt;
|
|
11
|
+
private readonly changeListeners;
|
|
12
|
+
set(state: TerminalActivityState): void;
|
|
13
|
+
clear(): void;
|
|
14
|
+
clearAttention(): boolean;
|
|
15
|
+
private setState;
|
|
16
|
+
onChange(listener: (snapshot: TerminalActivitySnapshot, previous: TerminalActivitySnapshot) => void): () => void;
|
|
17
|
+
getSnapshot(): TerminalActivitySnapshot;
|
|
18
|
+
dispose(): void;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=terminal-activity-tracker.d.ts.map
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export class TerminalActivityTracker {
|
|
2
|
+
constructor() {
|
|
3
|
+
// unknown != idle: a plain shell, or a terminal whose agent was killed, has no dot or rollup.
|
|
4
|
+
this.resolvedState = null;
|
|
5
|
+
this.attentionReason = null;
|
|
6
|
+
this.changedAt = Date.now();
|
|
7
|
+
this.changeListeners = new Set();
|
|
8
|
+
}
|
|
9
|
+
set(state) {
|
|
10
|
+
if (state === "idle" && this.resolvedState === "working") {
|
|
11
|
+
this.setState("idle", "finished");
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (state === "idle" && this.attentionReason === "finished") {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
this.setState(state === "attention" ? "idle" : state, state === "attention" ? "needs_input" : null);
|
|
18
|
+
}
|
|
19
|
+
clear() {
|
|
20
|
+
this.setState(null, null);
|
|
21
|
+
}
|
|
22
|
+
clearAttention() {
|
|
23
|
+
if (!this.attentionReason) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
this.setState("idle", null);
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
setState(state, attentionReason) {
|
|
30
|
+
if (state === this.resolvedState && attentionReason === this.attentionReason) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const previous = this.getSnapshot();
|
|
34
|
+
this.resolvedState = state;
|
|
35
|
+
this.attentionReason = attentionReason;
|
|
36
|
+
this.changedAt = Date.now();
|
|
37
|
+
const snapshot = this.getSnapshot();
|
|
38
|
+
for (const listener of Array.from(this.changeListeners)) {
|
|
39
|
+
listener(snapshot, previous);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
onChange(listener) {
|
|
43
|
+
this.changeListeners.add(listener);
|
|
44
|
+
return () => {
|
|
45
|
+
this.changeListeners.delete(listener);
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
getSnapshot() {
|
|
49
|
+
return {
|
|
50
|
+
state: this.resolvedState,
|
|
51
|
+
attentionReason: this.attentionReason,
|
|
52
|
+
changedAt: this.changedAt,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
dispose() {
|
|
56
|
+
this.changeListeners.clear();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=terminal-activity-tracker.js.map
|