@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.
Files changed (134) hide show
  1. package/dist/server/{utils/executable.d.ts → executable-resolution/executable-resolution.d.ts} +2 -2
  2. package/dist/server/{utils/executable.js → executable-resolution/executable-resolution.js} +16 -14
  3. package/dist/server/executable-resolution/windows.d.ts +18 -0
  4. package/dist/server/executable-resolution/windows.js +62 -0
  5. package/dist/server/server/agent/agent-loading.js +4 -1
  6. package/dist/server/server/agent/agent-manager.d.ts +10 -2
  7. package/dist/server/server/agent/agent-manager.js +34 -46
  8. package/dist/server/server/agent/agent-projections.js +3 -0
  9. package/dist/server/server/agent/agent-prompt.js +19 -1
  10. package/dist/server/server/agent/agent-response-loop.js +2 -4
  11. package/dist/server/server/agent/agent-storage.d.ts +18 -19
  12. package/dist/server/server/agent/agent-storage.js +6 -23
  13. package/dist/server/server/agent/create-agent/create.d.ts +2 -12
  14. package/dist/server/server/agent/create-agent/create.js +28 -30
  15. package/dist/server/server/agent/create-agent-lifecycle-dispatch.d.ts +4 -2
  16. package/dist/server/server/agent/create-agent-lifecycle-dispatch.js +31 -22
  17. package/dist/server/server/agent/import-sessions.d.ts +1 -10
  18. package/dist/server/server/agent/import-sessions.js +1 -53
  19. package/dist/server/server/agent/lifecycle-command.js +5 -4
  20. package/dist/server/server/agent/mcp-server.d.ts +8 -5
  21. package/dist/server/server/agent/mcp-server.js +41 -14
  22. package/dist/server/server/agent/mcp-shared.d.ts +6 -3
  23. package/dist/server/server/agent/mcp-shared.js +3 -0
  24. package/dist/server/server/agent/provider-launch-config.js +1 -1
  25. package/dist/server/server/agent/providers/acp-agent.d.ts +5 -0
  26. package/dist/server/server/agent/providers/acp-agent.js +31 -26
  27. package/dist/server/server/agent/providers/claude/agent.js +45 -6
  28. package/dist/server/server/agent/providers/codex-app-server-agent.js +1 -1
  29. package/dist/server/server/agent/providers/copilot-acp-agent.js +1 -0
  30. package/dist/server/server/agent/providers/cursor-acp-agent.d.ts +0 -7
  31. package/dist/server/server/agent/providers/cursor-acp-agent.js +0 -78
  32. package/dist/server/server/agent/providers/mock-load-test-agent.d.ts +2 -0
  33. package/dist/server/server/agent/providers/mock-load-test-agent.js +73 -1
  34. package/dist/server/server/agent/providers/opencode/server-manager.js +1 -1
  35. package/dist/server/server/agent/structured-generation-providers.js +45 -1
  36. package/dist/server/server/agent-attention-policy.d.ts +12 -3
  37. package/dist/server/server/agent-attention-policy.js +15 -3
  38. package/dist/server/server/auto-archive-on-merge/archive-if-safe.d.ts +7 -6
  39. package/dist/server/server/auto-archive-on-merge/archive-if-safe.js +21 -16
  40. package/dist/server/server/bootstrap.d.ts +3 -0
  41. package/dist/server/server/bootstrap.js +91 -12
  42. package/dist/server/server/config.js +1 -0
  43. package/dist/server/server/daemon-config-store.js +1 -0
  44. package/dist/server/server/exports.d.ts +1 -1
  45. package/dist/server/server/exports.js +1 -1
  46. package/dist/server/server/loop-service.d.ts +24 -24
  47. package/dist/server/server/migrations/backfill-workspace-id.migration.d.ts +9 -0
  48. package/dist/server/server/migrations/backfill-workspace-id.migration.js +60 -0
  49. package/dist/server/server/paseo-worktree-service.d.ts +9 -0
  50. package/dist/server/server/paseo-worktree-service.js +71 -12
  51. package/dist/server/server/path-utils.d.ts +1 -0
  52. package/dist/server/server/path-utils.js +6 -1
  53. package/dist/server/server/persisted-config.d.ts +7 -0
  54. package/dist/server/server/persisted-config.js +1 -0
  55. package/dist/server/server/persistence-hooks.d.ts +1 -0
  56. package/dist/server/server/persistence-hooks.js +13 -5
  57. package/dist/server/server/resolve-workspace-id-for-path.d.ts +3 -0
  58. package/dist/server/server/resolve-workspace-id-for-path.js +41 -0
  59. package/dist/server/server/script-proxy.d.ts +1 -1
  60. package/dist/server/server/script-proxy.js +1 -1
  61. package/dist/server/server/service-proxy.js +1 -1
  62. package/dist/server/server/session.d.ts +31 -6
  63. package/dist/server/server/session.js +640 -196
  64. package/dist/server/server/websocket-server.d.ts +5 -0
  65. package/dist/server/server/websocket-server.js +137 -3
  66. package/dist/server/server/workspace-archive-service.d.ts +60 -3
  67. package/dist/server/server/workspace-archive-service.js +217 -4
  68. package/dist/server/server/workspace-directory.d.ts +20 -2
  69. package/dist/server/server/workspace-directory.js +148 -70
  70. package/dist/server/server/workspace-git-service.js +21 -21
  71. package/dist/server/server/workspace-reconciliation-service.d.ts +1 -1
  72. package/dist/server/server/workspace-reconciliation-service.js +21 -22
  73. package/dist/server/server/workspace-registry-bootstrap.js +23 -10
  74. package/dist/server/server/workspace-registry-model.d.ts +3 -3
  75. package/dist/server/server/workspace-registry-model.js +9 -10
  76. package/dist/server/server/workspace-registry.d.ts +17 -4
  77. package/dist/server/server/workspace-registry.js +27 -0
  78. package/dist/server/server/worktree/commands.d.ts +7 -5
  79. package/dist/server/server/worktree/commands.js +38 -18
  80. package/dist/server/server/worktree-bootstrap.d.ts +1 -0
  81. package/dist/server/server/worktree-bootstrap.js +4 -1
  82. package/dist/server/server/worktree-branch-name-generator.d.ts +5 -1
  83. package/dist/server/server/worktree-branch-name-generator.js +8 -2
  84. package/dist/server/server/worktree-session.d.ts +4 -5
  85. package/dist/server/server/worktree-session.js +9 -3
  86. package/dist/server/services/github-service.js +1 -1
  87. package/dist/server/terminal/activity/terminal-activity-tracker.d.ts +20 -0
  88. package/dist/server/terminal/activity/terminal-activity-tracker.js +59 -0
  89. package/dist/server/terminal/agent-hooks/agent-hook-installer.d.ts +62 -0
  90. package/dist/server/terminal/agent-hooks/agent-hook-installer.js +117 -0
  91. package/dist/server/terminal/agent-hooks/claude/claude-settings.d.ts +7 -0
  92. package/dist/server/terminal/agent-hooks/claude/claude-settings.js +88 -0
  93. package/dist/server/terminal/agent-hooks/claude/claude.d.ts +4 -0
  94. package/dist/server/terminal/agent-hooks/claude/claude.js +47 -0
  95. package/dist/server/terminal/agent-hooks/codex/codex-settings.d.ts +7 -0
  96. package/dist/server/terminal/agent-hooks/codex/codex-settings.js +99 -0
  97. package/dist/server/terminal/agent-hooks/codex/codex.d.ts +4 -0
  98. package/dist/server/terminal/agent-hooks/codex/codex.js +30 -0
  99. package/dist/server/terminal/agent-hooks/opencode/opencode-plugin.d.ts +4 -0
  100. package/dist/server/terminal/agent-hooks/opencode/opencode-plugin.js +46 -0
  101. package/dist/server/terminal/agent-hooks/opencode/opencode.d.ts +3 -0
  102. package/dist/server/terminal/agent-hooks/opencode/opencode.js +23 -0
  103. package/dist/server/terminal/agent-hooks/provider-registry.d.ts +24 -0
  104. package/dist/server/terminal/agent-hooks/provider-registry.js +36 -0
  105. package/dist/server/terminal/agent-hooks/terminal-agent-hook-setting.d.ts +10 -0
  106. package/dist/server/terminal/agent-hooks/terminal-agent-hook-setting.js +26 -0
  107. package/dist/server/terminal/terminal-manager-factory.d.ts +4 -1
  108. package/dist/server/terminal/terminal-manager-factory.js +2 -2
  109. package/dist/server/terminal/terminal-manager.d.ts +33 -2
  110. package/dist/server/terminal/terminal-manager.js +144 -18
  111. package/dist/server/terminal/terminal-output-coalescer.d.ts +4 -0
  112. package/dist/server/terminal/terminal-output-coalescer.js +18 -0
  113. package/dist/server/terminal/terminal-restore.d.ts +1 -0
  114. package/dist/server/terminal/terminal-restore.js +6 -0
  115. package/dist/server/terminal/terminal-session-controller.d.ts +4 -2
  116. package/dist/server/terminal/terminal-session-controller.js +65 -24
  117. package/dist/server/terminal/terminal-worker-process.js +146 -63
  118. package/dist/server/terminal/terminal-worker-protocol.d.ts +19 -14
  119. package/dist/server/terminal/terminal.d.ts +42 -0
  120. package/dist/server/terminal/terminal.js +235 -16
  121. package/dist/server/terminal/worker-terminal-manager.d.ts +1 -0
  122. package/dist/server/terminal/worker-terminal-manager.js +220 -36
  123. package/dist/server/utils/build-metadata-prompt.d.ts +1 -1
  124. package/dist/server/utils/github-remote.js +1 -1
  125. package/dist/server/utils/tree-kill.d.ts +2 -2
  126. package/dist/src/{utils/executable.js → executable-resolution/executable-resolution.js} +16 -14
  127. package/dist/src/executable-resolution/windows.js +62 -0
  128. package/dist/src/server/agent/provider-launch-config.js +1 -1
  129. package/dist/src/server/persisted-config.js +1 -0
  130. package/package.json +10 -5
  131. package/dist/server/server/agent/agent-metadata-generator.d.ts +0 -36
  132. package/dist/server/server/agent/agent-metadata-generator.js +0 -112
  133. package/dist/server/server/paseo-worktree-archive-service.d.ts +0 -41
  134. package/dist/server/server/paseo-worktree-archive-service.js +0 -144
@@ -1,19 +1,15 @@
1
1
  import type { Logger } from "pino";
2
2
  import type { TerminalManager } from "../../../terminal/terminal-manager.js";
3
- import type { WorkspaceGitService } from "../../workspace-git-service.js";
4
3
  import type { AgentWorktreeSetupContinuation, CreatePaseoWorktreeWorkflowFn } from "../../worktree-session.js";
5
4
  import type { AgentAttachment, FirstAgentContext, GitSetupOptions } from "../../messages.js";
6
5
  import type { AgentManager, ManagedAgent } from "../agent-manager.js";
7
- import type { StructuredGenerationDaemonConfig } from "../structured-generation-providers.js";
8
6
  import type { AgentSessionConfig } from "../agent-sdk-types.js";
9
7
  import type { AgentStorage } from "../agent-storage.js";
10
8
  import type { ProviderSnapshotManager } from "../provider-snapshot-manager.js";
11
- export interface CreateAgentWorkspace {
12
- workspaceId: string;
13
- }
14
9
  export interface CreateAgentSessionWorktreeResult {
15
10
  sessionConfig: AgentSessionConfig;
16
11
  setupContinuation?: AgentWorktreeSetupContinuation;
12
+ createdWorkspaceId?: string;
17
13
  }
18
14
  interface CreateAgentCommandDependencies {
19
15
  agentManager: AgentManager;
@@ -21,11 +17,10 @@ interface CreateAgentCommandDependencies {
21
17
  logger: Logger;
22
18
  paseoHome?: string;
23
19
  worktreesRoot?: string;
24
- workspaceGitService?: Pick<WorkspaceGitService, "getSnapshot" | "listWorktrees" | "resolveRepoRoot">;
25
20
  terminalManager?: TerminalManager | null;
26
21
  providerSnapshotManager: ProviderSnapshotManager;
27
- daemonConfig?: StructuredGenerationDaemonConfig | null;
28
22
  createPaseoWorktree?: CreatePaseoWorktreeWorkflowFn;
23
+ ensureWorkspaceForCreate?: (cwd: string) => Promise<string>;
29
24
  }
30
25
  export interface CreateAgentFromSessionInput {
31
26
  kind: "session";
@@ -44,13 +39,8 @@ export interface CreateAgentFromSessionInput {
44
39
  labels: Record<string, string>;
45
40
  env?: Record<string, string>;
46
41
  provisionalTitle: string | null;
47
- explicitTitle: string | null;
48
42
  firstAgentContext: FirstAgentContext;
49
43
  buildSessionConfig: (config: AgentSessionConfig, gitOptions?: GitSetupOptions, legacyWorktreeName?: string, firstAgentContext?: FirstAgentContext) => Promise<CreateAgentSessionWorktreeResult>;
50
- resolveWorkspace: (input: {
51
- cwd: string;
52
- workspaceId?: string;
53
- }) => Promise<CreateAgentWorkspace>;
54
44
  }
55
45
  export interface CreateAgentFromMcpInput {
56
46
  kind: "mcp";
@@ -1,7 +1,6 @@
1
1
  import { PARENT_AGENT_ID_LABEL } from "@getpaseo/protocol/agent-labels";
2
2
  import { expandUserPath, resolvePathFromBase } from "../../path-utils.js";
3
3
  import { toWorktreeRequestError } from "../../worktree-errors.js";
4
- import { scheduleAgentMetadataGeneration } from "../agent-metadata-generator.js";
5
4
  import { setupFinishNotification, startCreatedAgentInitialPrompt } from "../agent-prompt.js";
6
5
  import { normalizeClientMessageId, resolveClientMessageId } from "../../client-message-id.js";
7
6
  import { resolveRequiredProviderModel } from "../mcp-shared.js";
@@ -39,11 +38,7 @@ export async function createAgentCommand(dependencies, input) {
39
38
  }
40
39
  async function resolveSessionCreateAgent(dependencies, input) {
41
40
  const trimmedPrompt = input.initialPrompt?.trim();
42
- const { sessionConfig, setupContinuation } = await input.buildSessionConfig(input.config, input.git, input.worktreeName, input.firstAgentContext);
43
- const workspace = await input.resolveWorkspace({
44
- cwd: sessionConfig.cwd,
45
- workspaceId: input.workspaceId,
46
- });
41
+ const { sessionConfig, setupContinuation, createdWorkspaceId } = await input.buildSessionConfig(input.config, input.git, input.worktreeName, input.firstAgentContext);
47
42
  const prompt = buildAgentPrompt(trimmedPrompt ?? "", input.images, input.attachments);
48
43
  const hasPromptContent = Array.isArray(prompt) ? prompt.length > 0 : prompt.length > 0;
49
44
  const clientMessageId = normalizeClientMessageId(input.clientMessageId);
@@ -57,15 +52,16 @@ async function resolveSessionCreateAgent(dependencies, input) {
57
52
  config: sessionConfig,
58
53
  createOptions: {
59
54
  labels: input.labels,
60
- workspaceId: workspace.workspaceId,
61
55
  initialPrompt: trimmedPrompt,
62
56
  env: input.env,
63
57
  initialTitle: input.provisionalTitle,
58
+ // A legacy git/worktreeName worktree creates a fresh workspace, so the
59
+ // agent belongs to that workspace, not the source one (mirrors the MCP
60
+ // path). createdWorkspaceId is the freshly created worktree's workspace.
61
+ workspaceId: setupContinuation ? createdWorkspaceId : input.workspaceId,
64
62
  },
65
- metadataInitialPrompt: trimmedPrompt,
66
63
  prompt: hasPromptContent ? prompt : undefined,
67
64
  runOptions,
68
- explicitTitle: input.explicitTitle,
69
65
  setupContinuation,
70
66
  background: true,
71
67
  promptFailure: "throw",
@@ -88,12 +84,21 @@ async function resolveMcpCreateAgent(dependencies, input) {
88
84
  allowCustomCwd: input.callerContext?.allowCustomCwd ?? true,
89
85
  })
90
86
  : expandUserPath(input.cwd ?? process.cwd());
91
- const { resolvedCwd, setupContinuation } = await resolveMcpCwd({
87
+ const { resolvedCwd, setupContinuation, createdWorkspaceId } = await resolveMcpCwd({
92
88
  dependencies,
93
89
  cwd,
94
90
  worktree: input.worktree,
95
91
  initialPrompt: input.initialPrompt,
96
92
  });
93
+ // A child agent created in its parent's working tree belongs to the parent's
94
+ // workspace. When a new worktree is created the child lives in that fresh
95
+ // workspace, so it is stamped with the new worktree's workspaceId instead
96
+ // (mirrors the session path) — keeping the agent discoverable by
97
+ // workspaceId-scoped archive. With neither a parent nor a worktree, the agent
98
+ // mints its own workspace; ownership is never resolved from cwd.
99
+ const workspaceId = setupContinuation
100
+ ? createdWorkspaceId
101
+ : (parentAgent?.workspaceId ?? (await ensureWorkspaceForMcpCreate(dependencies, resolvedCwd)));
97
102
  const { modeId: resolvedMode, featureValues: resolvedFeatures } = await dependencies.providerSnapshotManager.resolveCreateConfig({
98
103
  cwd: resolvedCwd,
99
104
  provider,
@@ -119,33 +124,25 @@ async function resolveMcpCreateAgent(dependencies, input) {
119
124
  thinkingOptionId: input.thinking,
120
125
  ...(resolvedFeatures ? { featureValues: resolvedFeatures } : {}),
121
126
  },
122
- createOptions: labels ? { labels } : undefined,
123
- metadataInitialPrompt: trimmedPrompt,
127
+ createOptions: labels || workspaceId
128
+ ? {
129
+ ...(labels ? { labels } : {}),
130
+ ...(workspaceId ? { workspaceId } : {}),
131
+ }
132
+ : undefined,
124
133
  prompt: trimmedPrompt,
125
- explicitTitle: input.title.trim(),
126
134
  setupContinuation,
127
135
  background: input.background,
128
136
  promptFailure: "log",
129
137
  };
130
138
  }
139
+ async function ensureWorkspaceForMcpCreate(dependencies, cwd) {
140
+ if (!dependencies.ensureWorkspaceForCreate) {
141
+ return undefined;
142
+ }
143
+ return dependencies.ensureWorkspaceForCreate(cwd);
144
+ }
131
145
  async function sendInitialPrompt(dependencies, resolved, snapshot) {
132
- scheduleAgentMetadataGeneration({
133
- agentManager: dependencies.agentManager,
134
- agentId: snapshot.id,
135
- cwd: snapshot.cwd,
136
- workspaceGitService: dependencies.workspaceGitService,
137
- providerSnapshotManager: dependencies.providerSnapshotManager,
138
- daemonConfig: dependencies.daemonConfig,
139
- currentSelection: {
140
- provider: snapshot.provider,
141
- model: snapshot.runtimeInfo?.model ?? resolved.config.model,
142
- thinkingOptionId: snapshot.runtimeInfo?.thinkingOptionId ?? resolved.config.thinkingOptionId ?? null,
143
- },
144
- initialPrompt: resolved.metadataInitialPrompt,
145
- explicitTitle: resolved.explicitTitle,
146
- paseoHome: dependencies.paseoHome,
147
- logger: dependencies.logger,
148
- });
149
146
  try {
150
147
  const prompt = resolved.prompt;
151
148
  if (prompt === undefined) {
@@ -256,6 +253,7 @@ async function resolveMcpCwd(params) {
256
253
  return {
257
254
  resolvedCwd: createdWorktree.worktree.worktreePath,
258
255
  setupContinuation: createdWorktree.setupContinuation,
256
+ createdWorkspaceId: createdWorktree.workspace.workspaceId,
259
257
  };
260
258
  }
261
259
  async function createMcpWorktree(options) {
@@ -1,5 +1,6 @@
1
1
  import type pino from "pino";
2
2
  import type { GitHubService } from "../../services/github-service.js";
3
+ import { type ActiveWorkspaceRef } from "../workspace-archive-service.js";
3
4
  import type { CreatePaseoWorktreeWorkflowFn, CreatePaseoWorktreeWorkflowResult } from "../worktree-session.js";
4
5
  import type { WorkspaceGitService } from "../workspace-git-service.js";
5
6
  import type { CreateAgentWorktreeTarget, FirstAgentContext, SessionOutboundMessage } from "../messages.js";
@@ -14,14 +15,15 @@ interface CreateAgentLifecycleDispatchDependencies {
14
15
  workspaceGitService: WorkspaceGitService;
15
16
  createPaseoWorktreeWorkflow: CreatePaseoWorktreeWorkflowFn;
16
17
  archiveAgentForClose: (agentId: string) => Promise<unknown>;
18
+ findWorkspaceIdForCwd: (cwd: string) => Promise<string | null>;
19
+ listActiveWorkspaces: () => Promise<ActiveWorkspaceRef[]>;
17
20
  archiveWorkspaceRecord: (workspaceId: string) => Promise<void>;
18
21
  emit: (message: SessionOutboundMessage) => void;
19
22
  emitAgentRemove: (agentId: string) => void;
20
23
  emitWorkspaceUpdatesForWorkspaceIds: (workspaceIds: Iterable<string>) => Promise<void>;
21
24
  markWorkspaceArchiving: (workspaceIds: Iterable<string>, archivingAt: string) => void;
22
25
  clearWorkspaceArchiving: (workspaceIds: Iterable<string>) => void;
23
- isPathWithinRoot: (rootPath: string, candidatePath: string) => boolean;
24
- killTerminalsUnderPath: (rootPath: string) => Promise<void>;
26
+ killTerminalsForWorkspace: (workspaceId: string) => Promise<void>;
25
27
  logger: pino.Logger;
26
28
  }
27
29
  export declare class CreateAgentLifecycleDispatch {
@@ -1,6 +1,6 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { isPaseoOwnedWorktreeCwd } from "../../utils/worktree.js";
3
- import { archivePaseoWorktree } from "../paseo-worktree-archive-service.js";
3
+ import { archiveByScope, resolveWorkspaceIdAtPath, } from "../workspace-archive-service.js";
4
4
  export class CreateAgentLifecycleDispatch {
5
5
  constructor(dependencies) {
6
6
  this.dependencies = dependencies;
@@ -114,27 +114,36 @@ export class CreateAgentLifecycleDispatch {
114
114
  if (!ownership.allowed) {
115
115
  throw new Error("Auto-created worktree is not a Paseo-owned worktree");
116
116
  }
117
- await archivePaseoWorktree({
118
- paseoHome: this.dependencies.paseoHome,
119
- worktreesRoot: this.dependencies.worktreesRoot,
120
- github: this.dependencies.github,
121
- workspaceGitService: this.dependencies.workspaceGitService,
122
- agentManager: this.dependencies.agentManager,
123
- agentStorage: this.dependencies.agentStorage,
124
- archiveWorkspaceRecord: this.dependencies.archiveWorkspaceRecord,
125
- emitWorkspaceUpdatesForWorkspaceIds: this.dependencies.emitWorkspaceUpdatesForWorkspaceIds,
126
- markWorkspaceArchiving: this.dependencies.markWorkspaceArchiving,
127
- clearWorkspaceArchiving: this.dependencies.clearWorkspaceArchiving,
128
- isPathWithinRoot: this.dependencies.isPathWithinRoot,
129
- killTerminalsUnderPath: this.dependencies.killTerminalsUnderPath,
130
- sessionLogger: this.dependencies.logger,
131
- }, {
132
- targetPath: options.worktreePath,
133
- repoRoot: options.repoRoot ?? ownership.repoRoot ?? null,
134
- worktreesRoot: ownership.worktreeRoot,
135
- worktreesBaseRoot: this.dependencies.worktreesRoot,
136
- requestId: randomUUID(),
137
- });
117
+ const workspaceId = await resolveWorkspaceIdAtPath({
118
+ findWorkspaceIdForCwd: this.dependencies.findWorkspaceIdForCwd,
119
+ listActiveWorkspaces: this.dependencies.listActiveWorkspaces,
120
+ }, options.worktreePath);
121
+ if (!workspaceId) {
122
+ this.dependencies.logger.warn({ worktreePath: options.worktreePath }, "Could not resolve workspace for auto-archive; skipping");
123
+ }
124
+ else {
125
+ await archiveByScope({
126
+ paseoHome: this.dependencies.paseoHome,
127
+ paseoWorktreesBaseRoot: this.dependencies.worktreesRoot,
128
+ github: this.dependencies.github,
129
+ workspaceGitService: this.dependencies.workspaceGitService,
130
+ agentManager: this.dependencies.agentManager,
131
+ agentStorage: this.dependencies.agentStorage,
132
+ findWorkspaceIdForCwd: this.dependencies.findWorkspaceIdForCwd,
133
+ listActiveWorkspaces: this.dependencies.listActiveWorkspaces,
134
+ archiveWorkspaceRecord: this.dependencies.archiveWorkspaceRecord,
135
+ emitWorkspaceUpdatesForWorkspaceIds: this.dependencies.emitWorkspaceUpdatesForWorkspaceIds,
136
+ markWorkspaceArchiving: this.dependencies.markWorkspaceArchiving,
137
+ clearWorkspaceArchiving: this.dependencies.clearWorkspaceArchiving,
138
+ killTerminalsForWorkspace: this.dependencies.killTerminalsForWorkspace,
139
+ sessionLogger: this.dependencies.logger,
140
+ }, {
141
+ scope: { kind: "workspace", workspaceId },
142
+ repoRoot: options.repoRoot ?? ownership.repoRoot ?? null,
143
+ paseoWorktreesBaseRoot: this.dependencies.worktreesRoot,
144
+ requestId: randomUUID(),
145
+ });
146
+ }
138
147
  if (options.agentId) {
139
148
  this.dependencies.emitAgentRemove(options.agentId);
140
149
  }
@@ -4,10 +4,7 @@ import type { ProviderSnapshotManager } from "./provider-snapshot-manager.js";
4
4
  import type { AgentManager, ManagedAgent } from "./agent-manager.js";
5
5
  import type { AgentStorage } from "./agent-storage.js";
6
6
  import type { AgentProvider } from "./agent-sdk-types.js";
7
- import { scheduleAgentMetadataGeneration } from "./agent-metadata-generator.js";
8
- import type { StructuredGenerationDaemonConfig } from "./structured-generation-providers.js";
9
7
  import type { FetchRecentProviderSessionsRequestMessage, ImportAgentRequestMessageSchema, RecentProviderSessionDescriptorPayload } from "@getpaseo/protocol/messages";
10
- import type { WorkspaceGitService } from "../workspace-git-service.js";
11
8
  type ImportAgentRequestMessage = z.infer<typeof ImportAgentRequestMessageSchema>;
12
9
  export interface NormalizedImportAgentRequest {
13
10
  provider: AgentProvider;
@@ -32,16 +29,10 @@ export interface ListImportableProviderSessionsResult {
32
29
  }
33
30
  export interface ImportProviderSessionInput {
34
31
  request: NormalizedImportAgentRequest;
32
+ workspaceId: string;
35
33
  agentManager: AgentManager;
36
34
  agentStorage: AgentStorage;
37
- workspaceGitService?: Pick<WorkspaceGitService, "resolveRepoRoot">;
38
- providerSnapshotManager?: Pick<ProviderSnapshotManager, "listProviders">;
39
- daemonConfig?: StructuredGenerationDaemonConfig | null;
40
- paseoHome?: string;
41
35
  logger: Logger;
42
- deps?: {
43
- scheduleAgentMetadataGeneration?: typeof scheduleAgentMetadataGeneration;
44
- };
45
36
  }
46
37
  export interface ImportProviderSessionResult {
47
38
  snapshot: ManagedAgent;
@@ -1,5 +1,3 @@
1
- import { scheduleAgentMetadataGeneration } from "./agent-metadata-generator.js";
2
- import { resolveCreateAgentTitles } from "./create-agent-title.js";
3
1
  import { unarchiveAgentState } from "./agent-prompt.js";
4
2
  import { toRecentProviderSessionDescriptorPayload } from "./agent-projections.js";
5
3
  import { createRealpathAwarePathMatcher } from "../../utils/path.js";
@@ -79,19 +77,10 @@ export async function importProviderSession(input) {
79
77
  provider,
80
78
  providerHandleId,
81
79
  cwd,
80
+ workspaceId: input.workspaceId,
82
81
  labels,
83
82
  });
84
83
  await unarchiveAgentState(input.agentStorage, input.agentManager, snapshot.id);
85
- scheduleImportedAgentMetadata({
86
- snapshot,
87
- agentManager: input.agentManager,
88
- workspaceGitService: input.workspaceGitService,
89
- providerSnapshotManager: input.providerSnapshotManager,
90
- daemonConfig: input.daemonConfig,
91
- paseoHome: input.paseoHome,
92
- logger: input.logger,
93
- scheduleAgentMetadataGeneration: input.deps?.scheduleAgentMetadataGeneration ?? scheduleAgentMetadataGeneration,
94
- });
95
84
  return {
96
85
  snapshot,
97
86
  timelineSize: input.agentManager.getTimeline(snapshot.id).length,
@@ -107,35 +96,6 @@ async function unarchiveAgentByHandle(agentStorage, agentManager, handle) {
107
96
  }
108
97
  await unarchiveAgentState(agentStorage, agentManager, matched.id);
109
98
  }
110
- function scheduleImportedAgentMetadata(input) {
111
- const initialPrompt = getFirstUserMessageText(input.agentManager.getTimeline(input.snapshot.id));
112
- if (!initialPrompt) {
113
- return;
114
- }
115
- const { explicitTitle } = resolveCreateAgentTitles({
116
- configTitle: input.snapshot.config.title,
117
- initialPrompt,
118
- });
119
- input.scheduleAgentMetadataGeneration({
120
- agentManager: input.agentManager,
121
- agentId: input.snapshot.id,
122
- cwd: input.snapshot.cwd,
123
- workspaceGitService: input.workspaceGitService,
124
- providerSnapshotManager: input.providerSnapshotManager,
125
- daemonConfig: input.daemonConfig,
126
- currentSelection: {
127
- provider: input.snapshot.provider,
128
- model: input.snapshot.runtimeInfo?.model ?? input.snapshot.config.model,
129
- thinkingOptionId: input.snapshot.runtimeInfo?.thinkingOptionId ??
130
- input.snapshot.config.thinkingOptionId ??
131
- null,
132
- },
133
- initialPrompt,
134
- explicitTitle,
135
- paseoHome: input.paseoHome,
136
- logger: input.logger,
137
- });
138
- }
139
99
  function parseRecentProviderSessionsSince(since) {
140
100
  if (!since) {
141
101
  return null;
@@ -157,18 +117,6 @@ function buildImportPersistenceHandle(input) {
157
117
  },
158
118
  };
159
119
  }
160
- function getFirstUserMessageText(timeline) {
161
- for (const item of timeline) {
162
- if (item.type !== "user_message") {
163
- continue;
164
- }
165
- const text = item.text.trim();
166
- if (text) {
167
- return text;
168
- }
169
- }
170
- return null;
171
- }
172
120
  async function collectImportedProviderSessionHandles(agentManager, agentStorage) {
173
121
  const handles = new Set();
174
122
  for (const agent of agentManager.listAgents()) {
@@ -24,15 +24,16 @@ export async function cancelAgentRunCommand(dependencies, agentId) {
24
24
  }
25
25
  export async function archiveAgentCommand(dependencies, agentId) {
26
26
  const liveAgent = dependencies.agentManager.getAgent(agentId);
27
+ let record;
27
28
  if (liveAgent) {
28
29
  await cancelAgentRunCommand(dependencies, agentId);
29
30
  await dependencies.agentManager.clearAgentAttention(agentId).catch(() => undefined);
30
31
  await dependencies.agentManager.archiveAgent(agentId);
32
+ record = await dependencies.agentStorage.get(agentId);
31
33
  }
32
34
  else {
33
- await archiveStoredAgent(dependencies, agentId);
35
+ record = await archiveStoredAgent(dependencies, agentId);
34
36
  }
35
- const record = await dependencies.agentStorage.get(agentId);
36
37
  if (!record) {
37
38
  throw new Error(`Agent not found in storage after archive: ${agentId}`);
38
39
  }
@@ -76,9 +77,9 @@ async function archiveStoredAgent(dependencies, agentId) {
76
77
  throw new Error(`Agent not found: ${agentId}`);
77
78
  }
78
79
  if (existing.archivedAt) {
79
- return;
80
+ return existing;
80
81
  }
81
82
  const archivedAt = new Date().toISOString();
82
- await dependencies.agentManager.archiveSnapshot(agentId, archivedAt);
83
+ return dependencies.agentManager.archiveSnapshot(agentId, archivedAt);
83
84
  }
84
85
  //# sourceMappingURL=lifecycle-command.js.map
@@ -2,7 +2,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import type { Logger } from "pino";
3
3
  import type { AgentManager } from "./agent-manager.js";
4
4
  import type { AgentStorage } from "./agent-storage.js";
5
- import { type ArchivePaseoWorktreeDependencies } from "../paseo-worktree-archive-service.js";
5
+ import { type ArchiveDependencies } from "../workspace-archive-service.js";
6
6
  import type { VoiceCallerContext, VoiceSpeakHandler } from "../voice-types.js";
7
7
  import type { TerminalManager } from "../../terminal/terminal-manager.js";
8
8
  import type { CreatePaseoWorktreeWorkflowFn } from "../worktree-session.js";
@@ -19,11 +19,14 @@ export interface AgentMcpServerOptions {
19
19
  providerSnapshotManager: ProviderSnapshotManager;
20
20
  github?: GitHubService;
21
21
  workspaceGitService?: Pick<WorkspaceGitService, "getSnapshot" | "listWorktrees" | "resolveRepoRoot">;
22
- archiveWorkspaceRecord?: ArchivePaseoWorktreeDependencies["archiveWorkspaceRecord"];
23
- emitWorkspaceUpdatesForWorkspaceIds?: ArchivePaseoWorktreeDependencies["emitWorkspaceUpdatesForWorkspaceIds"];
24
- markWorkspaceArchiving?: ArchivePaseoWorktreeDependencies["markWorkspaceArchiving"];
25
- clearWorkspaceArchiving?: ArchivePaseoWorktreeDependencies["clearWorkspaceArchiving"];
22
+ findWorkspaceIdForCwd?: ArchiveDependencies["findWorkspaceIdForCwd"];
23
+ listActiveWorkspaces?: ArchiveDependencies["listActiveWorkspaces"];
24
+ archiveWorkspaceRecord?: ArchiveDependencies["archiveWorkspaceRecord"];
25
+ emitWorkspaceUpdatesForWorkspaceIds?: ArchiveDependencies["emitWorkspaceUpdatesForWorkspaceIds"];
26
+ markWorkspaceArchiving?: ArchiveDependencies["markWorkspaceArchiving"];
27
+ clearWorkspaceArchiving?: ArchiveDependencies["clearWorkspaceArchiving"];
26
28
  createPaseoWorktree?: CreatePaseoWorktreeWorkflowFn;
29
+ ensureWorkspaceForCreate?: (cwd: string) => Promise<string>;
27
30
  paseoHome?: string;
28
31
  worktreesRoot?: string;
29
32
  /**
@@ -7,7 +7,7 @@ import { curateAgentActivity } from "./activity-curator.js";
7
7
  import { selectItemsByProjectedLimit } from "./timeline-projection.js";
8
8
  import { ensureAgentLoaded } from "./agent-loading.js";
9
9
  import { isStoredAgentProviderAvailable } from "../persistence-hooks.js";
10
- import { killTerminalsUnderPath, } from "../paseo-worktree-archive-service.js";
10
+ import { killTerminalsForWorkspace, } from "../workspace-archive-service.js";
11
11
  import { WaitForAgentTracker } from "./wait-for-agent-tracker.js";
12
12
  import { createAgentCommand } from "./create-agent/create.js";
13
13
  import { expandUserPath, isSameOrDescendantPath, resolvePathFromBase } from "../path-utils.js";
@@ -18,7 +18,7 @@ import { sendPromptToAgent, setupFinishNotification } from "./agent-prompt.js";
18
18
  import { respondToAgentPermission } from "./permission-response.js";
19
19
  import { archiveAgentCommand, cancelAgentRunCommand, closeAgentCommand, setAgentModeCommand, updateAgentCommand, } from "./lifecycle-command.js";
20
20
  import { WorktreeRequestError } from "../worktree-errors.js";
21
- import { archivePaseoWorktreeCommand, createPaseoWorktreeCommand, listPaseoWorktreesCommand, } from "../worktree/commands.js";
21
+ import { archiveCommand, createPaseoWorktreeCommand, listPaseoWorktreesCommand, } from "../worktree/commands.js";
22
22
  function addModelVisibleStructuredContent(result) {
23
23
  if (result.structuredContent === undefined || result.content.length > 0) {
24
24
  return result;
@@ -346,6 +346,20 @@ export async function createAgentMcpServer(options) {
346
346
  }
347
347
  return expandUserPath(trimmedCwd);
348
348
  };
349
+ async function resolveTerminalWorkspaceId(resolvedCwd) {
350
+ // An MCP-spawned terminal belongs to the caller agent's workspace. Only if
351
+ // the caller has no workspace do we mint one for the cwd.
352
+ const callerAgent = callerAgentId ? agentManager.getAgent(callerAgentId) : null;
353
+ if (callerAgent?.workspaceId) {
354
+ return callerAgent.workspaceId;
355
+ }
356
+ if (!options.ensureWorkspaceForCreate) {
357
+ throw new Error(callerAgentId
358
+ ? `Caller agent ${callerAgentId} has no workspace and workspace minting is not configured`
359
+ : "workspaceId is required outside an agent-scoped session");
360
+ }
361
+ return options.ensureWorkspaceForCreate(resolvedCwd);
362
+ }
349
363
  const buildCallerAgentScheduleConfigExtras = (callerAgent) => {
350
364
  return {
351
365
  ...(callerAgent.config.thinkingOptionId
@@ -644,10 +658,12 @@ export async function createAgentMcpServer(options) {
644
658
  logger: childLogger,
645
659
  paseoHome: options.paseoHome,
646
660
  worktreesRoot: options.worktreesRoot,
647
- workspaceGitService: options.workspaceGitService,
648
661
  terminalManager,
649
662
  providerSnapshotManager,
650
663
  createPaseoWorktree: options.createPaseoWorktree,
664
+ ...(options.ensureWorkspaceForCreate
665
+ ? { ensureWorkspaceForCreate: options.ensureWorkspaceForCreate }
666
+ : {}),
651
667
  }, {
652
668
  kind: "mcp",
653
669
  provider: parsedArgs.provider,
@@ -913,7 +929,7 @@ export async function createAgentMcpServer(options) {
913
929
  if (!record || record.internal) {
914
930
  throw new Error(`Agent ${agentId} not found`);
915
931
  }
916
- const structuredSnapshot = buildStoredAgentPayload(record, providerSnapshotManager.listRegisteredProviderIds());
932
+ const structuredSnapshot = buildStoredAgentPayload(record, new Set(providerSnapshotManager.listRegisteredProviderIds()));
917
933
  return {
918
934
  content: [],
919
935
  structuredContent: ensureValidJson({
@@ -950,7 +966,7 @@ export async function createAgentMcpServer(options) {
950
966
  const liveAgents = await Promise.all(liveSnapshots.map((snapshot) => serializeSnapshotWithMetadata(agentStorage, snapshot, childLogger)));
951
967
  const liveIds = new Set(liveSnapshots.map((snapshot) => snapshot.id));
952
968
  const storedRecords = await agentStorage.list();
953
- const registeredProviderIds = providerSnapshotManager.listRegisteredProviderIds();
969
+ const registeredProviderIds = new Set(providerSnapshotManager.listRegisteredProviderIds());
954
970
  const storedAgents = storedRecords
955
971
  .filter((record) => !record.internal && !liveIds.has(record.id))
956
972
  .filter((record) => includeArchived || !record.archivedAt)
@@ -1106,8 +1122,11 @@ export async function createAgentMcpServer(options) {
1106
1122
  if (!terminalManager) {
1107
1123
  throw new Error("Terminal manager is not configured");
1108
1124
  }
1125
+ const resolvedCwd = resolveScopedCwd(cwd, { required: true });
1126
+ const workspaceId = await resolveTerminalWorkspaceId(resolvedCwd);
1109
1127
  const terminal = await terminalManager.createTerminal({
1110
- cwd: resolveScopedCwd(cwd, { required: true }),
1128
+ cwd: resolvedCwd,
1129
+ workspaceId,
1111
1130
  ...(name?.trim() ? { name: name.trim() } : {}),
1112
1131
  });
1113
1132
  return {
@@ -1661,7 +1680,7 @@ export async function createAgentMcpServer(options) {
1661
1680
  throw new Error("WorkspaceGitService is required to archive worktrees");
1662
1681
  }
1663
1682
  const repoRoot = await options.workspaceGitService.resolveRepoRoot(resolvedCwd);
1664
- const result = await archivePaseoWorktreeCommand(archiveWorktreeDependencies(options, {
1683
+ const result = await archiveCommand(archiveWorktreeDependencies(options, {
1665
1684
  agentManager,
1666
1685
  agentStorage,
1667
1686
  terminalManager: terminalManager ?? null,
@@ -1671,6 +1690,9 @@ export async function createAgentMcpServer(options) {
1671
1690
  repoRoot,
1672
1691
  worktreePath,
1673
1692
  worktreeSlug,
1693
+ // This tool archives every workspace on the directory, then removes the
1694
+ // directory. Disk removal is derived from scope + last-reference.
1695
+ scope: "worktree",
1674
1696
  });
1675
1697
  if (!result.ok) {
1676
1698
  throw new Error(result.message);
@@ -1765,7 +1787,7 @@ export async function createAgentMcpServer(options) {
1765
1787
  return payload.pendingPermissions.map((request) => ({
1766
1788
  agentId: agent.id,
1767
1789
  status: payload.status,
1768
- request,
1790
+ request: sanitizePermissionRequest(request),
1769
1791
  }));
1770
1792
  });
1771
1793
  return {
@@ -1809,6 +1831,12 @@ function archiveWorktreeDependencies(options, context) {
1809
1831
  if (!options.archiveWorkspaceRecord) {
1810
1832
  throw new Error("Workspace registry archiver is required to archive worktrees");
1811
1833
  }
1834
+ if (!options.findWorkspaceIdForCwd) {
1835
+ throw new Error("Workspace resolver is required to archive worktrees");
1836
+ }
1837
+ if (!options.listActiveWorkspaces) {
1838
+ throw new Error("Active workspace lister is required to archive worktrees");
1839
+ }
1812
1840
  if (!options.emitWorkspaceUpdatesForWorkspaceIds) {
1813
1841
  throw new Error("Workspace update emitter is required to archive worktrees");
1814
1842
  }
@@ -1820,22 +1848,21 @@ function archiveWorktreeDependencies(options, context) {
1820
1848
  }
1821
1849
  return {
1822
1850
  paseoHome: options.paseoHome,
1823
- worktreesRoot: options.worktreesRoot,
1851
+ paseoWorktreesBaseRoot: options.worktreesRoot,
1824
1852
  github: options.github,
1825
1853
  workspaceGitService: options.workspaceGitService,
1826
1854
  agentManager: context.agentManager,
1827
1855
  agentStorage: context.agentStorage,
1856
+ findWorkspaceIdForCwd: options.findWorkspaceIdForCwd,
1857
+ listActiveWorkspaces: options.listActiveWorkspaces,
1828
1858
  archiveWorkspaceRecord: options.archiveWorkspaceRecord,
1829
1859
  emitWorkspaceUpdatesForWorkspaceIds: options.emitWorkspaceUpdatesForWorkspaceIds,
1830
1860
  markWorkspaceArchiving: options.markWorkspaceArchiving,
1831
1861
  clearWorkspaceArchiving: options.clearWorkspaceArchiving,
1832
- isPathWithinRoot: isSameOrDescendantPath,
1833
- killTerminalsUnderPath: (rootPath) => killTerminalsUnderPath({
1862
+ killTerminalsForWorkspace: (workspaceId) => killTerminalsForWorkspace({
1834
1863
  terminalManager: context.terminalManager,
1835
- isPathWithinRoot: isSameOrDescendantPath,
1836
- killTrackedTerminal: () => { },
1837
1864
  sessionLogger: context.logger,
1838
- }, rootPath),
1865
+ }, workspaceId),
1839
1866
  sessionLogger: context.logger,
1840
1867
  };
1841
1868
  }
@@ -215,6 +215,8 @@ export declare function waitForAgentWithTimeout(agentManager: AgentManager, agen
215
215
  signal?: AbortSignal;
216
216
  waitForActive?: boolean;
217
217
  }): Promise<WaitForAgentResult>;
218
+ export declare function sanitizePermissionRequest(permission: AgentPermissionRequest): AgentPermissionRequest;
219
+ export declare function sanitizePermissionRequest(permission: null | undefined): null;
218
220
  export declare function sanitizePermissionRequest(permission: AgentPermissionRequest | null | undefined): AgentPermissionRequest | null;
219
221
  export declare function resolveAgentTitle(agentStorage: AgentStorage, agentId: string, logger: Logger): Promise<string | null>;
220
222
  export declare function serializeSnapshotWithMetadata(agentStorage: AgentStorage, snapshot: ManagedAgent, logger: Logger): Promise<{
@@ -233,17 +235,18 @@ export declare function serializeSnapshotWithMetadata(agentStorage: AgentStorage
233
235
  pendingPermissions: import("@getpaseo/protocol/agent-types").AgentPermissionRequest[];
234
236
  persistence: import("@getpaseo/protocol/agent-types").AgentPersistenceHandle | null;
235
237
  labels: Record<string, string>;
238
+ attentionReason?: "finished" | "error" | "permission" | null | undefined;
236
239
  thinkingOptionId?: string | null | undefined;
240
+ workspaceId?: string | undefined;
237
241
  features?: ({
238
- type: "toggle";
239
242
  value: boolean;
243
+ type: "toggle";
240
244
  id: string;
241
245
  label: string;
242
246
  description?: string | undefined;
243
247
  icon?: string | undefined;
244
248
  tooltip?: string | undefined;
245
249
  } | {
246
- type: "select";
247
250
  value: string | null;
248
251
  options: {
249
252
  id: string;
@@ -252,6 +255,7 @@ export declare function serializeSnapshotWithMetadata(agentStorage: AgentStorage
252
255
  metadata?: Record<string, unknown> | undefined;
253
256
  isDefault?: boolean | undefined;
254
257
  }[];
258
+ type: "select";
255
259
  id: string;
256
260
  label: string;
257
261
  description?: string | undefined;
@@ -263,7 +267,6 @@ export declare function serializeSnapshotWithMetadata(agentStorage: AgentStorage
263
267
  lastUsage?: import("@getpaseo/protocol/agent-types").AgentUsage | undefined;
264
268
  lastError?: string | undefined;
265
269
  requiresAttention?: boolean | undefined;
266
- attentionReason?: "finished" | "error" | "permission" | null | undefined;
267
270
  attentionTimestamp?: string | null | undefined;
268
271
  archivedAt?: string | null | undefined;
269
272
  providerUnavailable?: boolean | undefined;
@@ -133,6 +133,9 @@ export function sanitizePermissionRequest(permission) {
133
133
  if (sanitized.input === undefined) {
134
134
  delete sanitized.input;
135
135
  }
136
+ if (sanitized.detail === undefined) {
137
+ delete sanitized.detail;
138
+ }
136
139
  if (sanitized.suggestions === undefined) {
137
140
  delete sanitized.suggestions;
138
141
  }
@@ -1,5 +1,5 @@
1
1
  import { isAbsolute } from "node:path";
2
- import { executableExists, findExecutable } from "../../utils/executable.js";
2
+ import { executableExists, findExecutable, } from "../../executable-resolution/executable-resolution.js";
3
3
  import { createExternalProcessEnv } from "../paseo-env.js";
4
4
  export { AgentProviderRuntimeSettingsMapSchema, ProviderCommandSchema, ProviderOverrideSchema, ProviderOverridesSchema, ProviderProfileModelSchema, ProviderRuntimeSettingsSchema, } from "@getpaseo/protocol/provider-config";
5
5
  import { ProviderOverrideSchema, ProviderOverridesSchema, ProviderRuntimeSettingsSchema, } from "@getpaseo/protocol/provider-config";