@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.
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
@@ -2,31 +2,32 @@ import type { Logger } from "pino";
2
2
  import type { AgentManager } from "../agent/agent-manager.js";
3
3
  import type { AgentStorage } from "../agent/agent-storage.js";
4
4
  import type { DaemonConfigStore } from "../daemon-config-store.js";
5
- import { archivePaseoWorktree, killTerminalsUnderPath } from "../paseo-worktree-archive-service.js";
6
- import { isSameOrDescendantPath } from "../path-utils.js";
5
+ import { archiveByScope, type ActiveWorkspaceRef, killTerminalsForWorkspace, resolveWorkspaceIdAtPath } from "../workspace-archive-service.js";
7
6
  import type { WorkspaceGitRuntimeSnapshot, WorkspaceGitServiceImpl } from "../workspace-git-service.js";
8
7
  import type { GitHubService } from "../../services/github-service.js";
9
8
  import type { TerminalManager } from "../../terminal/terminal-manager.js";
10
9
  import { isPaseoOwnedWorktreeCwd } from "../../utils/worktree.js";
11
10
  export interface AutoArchiveArchiveOptions {
12
11
  paseoHome: string;
13
- worktreesRoot?: string;
12
+ paseoWorktreesBaseRoot?: string;
14
13
  daemonConfigStore: DaemonConfigStore;
15
14
  workspaceGitService: WorkspaceGitServiceImpl;
16
15
  github: GitHubService;
17
16
  agentManager: AgentManager;
18
17
  agentStorage: AgentStorage;
19
18
  terminalManager: TerminalManager;
19
+ findWorkspaceIdForCwd: (cwd: string) => Promise<string | null>;
20
+ listActiveWorkspaces: () => Promise<ActiveWorkspaceRef[]>;
20
21
  archiveWorkspaceRecord: (workspaceId: string) => Promise<void>;
21
22
  markWorkspaceArchiving: (workspaceIds: Iterable<string>, archivingAt: string) => void;
22
23
  clearWorkspaceArchiving: (workspaceIds: Iterable<string>) => void;
23
24
  emitWorkspaceUpdatesForWorkspaceIds: (workspaceIds: Iterable<string>) => Promise<void>;
24
25
  }
25
26
  export interface ArchiveIfSafeDependencies {
26
- archivePaseoWorktree: typeof archivePaseoWorktree;
27
+ archiveByScope: typeof archiveByScope;
28
+ resolveWorkspaceIdAtPath: typeof resolveWorkspaceIdAtPath;
27
29
  isPaseoOwnedWorktreeCwd: typeof isPaseoOwnedWorktreeCwd;
28
- killTerminalsUnderPath: typeof killTerminalsUnderPath;
29
- isPathWithinRoot: typeof isSameOrDescendantPath;
30
+ killTerminalsForWorkspace: typeof killTerminalsForWorkspace;
30
31
  }
31
32
  export declare function archiveIfSafe(input: {
32
33
  cwd: string;
@@ -1,11 +1,10 @@
1
- import { archivePaseoWorktree, killTerminalsUnderPath } from "../paseo-worktree-archive-service.js";
2
- import { isSameOrDescendantPath } from "../path-utils.js";
1
+ import { archiveByScope, killTerminalsForWorkspace, resolveWorkspaceIdAtPath, } from "../workspace-archive-service.js";
3
2
  import { isPaseoOwnedWorktreeCwd } from "../../utils/worktree.js";
4
3
  const defaultDependencies = {
5
- archivePaseoWorktree,
4
+ archiveByScope,
5
+ resolveWorkspaceIdAtPath,
6
6
  isPaseoOwnedWorktreeCwd,
7
- killTerminalsUnderPath,
8
- isPathWithinRoot: isSameOrDescendantPath,
7
+ killTerminalsForWorkspace,
9
8
  };
10
9
  export async function archiveIfSafe(input) {
11
10
  const { cwd, pullRequest, inFlight, options, log } = input;
@@ -42,36 +41,42 @@ export async function archiveIfSafe(input) {
42
41
  }
43
42
  const ownership = await deps.isPaseoOwnedWorktreeCwd(cwd, {
44
43
  paseoHome: options.paseoHome,
45
- worktreesRoot: options.worktreesRoot,
44
+ worktreesRoot: options.paseoWorktreesBaseRoot,
46
45
  });
47
46
  if (!ownership.allowed) {
48
47
  return;
49
48
  }
50
49
  try {
51
- await deps.archivePaseoWorktree({
50
+ const workspaceId = await deps.resolveWorkspaceIdAtPath({
51
+ findWorkspaceIdForCwd: options.findWorkspaceIdForCwd,
52
+ listActiveWorkspaces: options.listActiveWorkspaces,
53
+ }, cwd);
54
+ if (!workspaceId) {
55
+ log.warn({ cwd }, "Auto-archive could not resolve a workspace for cwd; skipping");
56
+ return;
57
+ }
58
+ await deps.archiveByScope({
52
59
  paseoHome: options.paseoHome,
53
- worktreesRoot: options.worktreesRoot,
60
+ paseoWorktreesBaseRoot: options.paseoWorktreesBaseRoot,
54
61
  github: options.github,
55
62
  workspaceGitService: options.workspaceGitService,
56
63
  agentManager: options.agentManager,
57
64
  agentStorage: options.agentStorage,
65
+ findWorkspaceIdForCwd: options.findWorkspaceIdForCwd,
66
+ listActiveWorkspaces: options.listActiveWorkspaces,
58
67
  archiveWorkspaceRecord: options.archiveWorkspaceRecord,
59
68
  emitWorkspaceUpdatesForWorkspaceIds: options.emitWorkspaceUpdatesForWorkspaceIds,
60
69
  markWorkspaceArchiving: options.markWorkspaceArchiving,
61
70
  clearWorkspaceArchiving: options.clearWorkspaceArchiving,
62
- isPathWithinRoot: deps.isPathWithinRoot,
63
- killTerminalsUnderPath: (rootPath) => deps.killTerminalsUnderPath({
71
+ killTerminalsForWorkspace: (workspaceIdToKill) => deps.killTerminalsForWorkspace({
64
72
  terminalManager: options.terminalManager,
65
- isPathWithinRoot: deps.isPathWithinRoot,
66
- killTrackedTerminal: () => { },
67
73
  sessionLogger: log,
68
- }, rootPath),
74
+ }, workspaceIdToKill),
69
75
  sessionLogger: log,
70
76
  }, {
71
- targetPath: cwd,
77
+ scope: { kind: "workspace", workspaceId },
72
78
  repoRoot: ownership.repoRoot ?? null,
73
- worktreesRoot: ownership.worktreeRoot,
74
- worktreesBaseRoot: options.worktreesRoot,
79
+ paseoWorktreesBaseRoot: options.paseoWorktreesBaseRoot,
75
80
  requestId: "auto-archive-on-merge",
76
81
  });
77
82
  log.info({ cwd }, "Auto-archived worktree after PR merge");
@@ -1,3 +1,4 @@
1
+ import express from "express";
1
2
  import type { Logger } from "pino";
2
3
  export type ListenTarget = {
3
4
  type: "tcp";
@@ -26,6 +27,7 @@ import { type ServiceProxySubsystem } from "./service-proxy.js";
26
27
  import { WorkspaceScriptRuntimeStore } from "./workspace-script-runtime-store.js";
27
28
  import { type HostnamesConfig } from "./hostnames.js";
28
29
  import { type DaemonAuthConfig } from "./auth.js";
30
+ export declare function createTerminalActivityRouteHandler(terminalManager: TerminalManager): express.RequestHandler;
29
31
  export type PaseoOpenAIConfig = OpenAiSpeechProviderConfig;
30
32
  export type PaseoLocalSpeechConfig = LocalSpeechProviderConfig;
31
33
  export interface PaseoSpeechSttLanguages {
@@ -57,6 +59,7 @@ export interface PaseoDaemonConfig {
57
59
  mcpEnabled?: boolean;
58
60
  mcpInjectIntoAgents?: boolean;
59
61
  autoArchiveAfterMerge?: boolean;
62
+ enableTerminalAgentHooks?: boolean;
60
63
  appendSystemPrompt?: string;
61
64
  terminalProfiles?: TerminalProfile[];
62
65
  staticDir: string;
@@ -7,6 +7,7 @@ import { hostname as getHostname } from "node:os";
7
7
  import path from "node:path";
8
8
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
9
9
  import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
10
+ import { z } from "zod";
10
11
  import { createBranchChangeRouteHandler } from "./script-route-branch-handler.js";
11
12
  function resolveBoundListenTarget(listenTarget, httpServer) {
12
13
  if (listenTarget.type !== "tcp") {
@@ -72,7 +73,7 @@ function formatListenTarget(listenTarget) {
72
73
  }
73
74
  import { VoiceAssistantWebSocketServer } from "./websocket-server.js";
74
75
  import { createGitHubService } from "../services/github-service.js";
75
- import { createPaseoWorktree as createRegisteredPaseoWorktree } from "./paseo-worktree-service.js";
76
+ import { createPaseoWorktree as createRegisteredPaseoWorktree, createLocalCheckoutWorkspace, } from "./paseo-worktree-service.js";
76
77
  import { createPaseoWorktreeWorkflow } from "./worktree-session.js";
77
78
  import { DownloadTokenStore } from "./file-download/token-store.js";
78
79
  import { createSpeechService } from "./speech/speech-runtime.js";
@@ -90,10 +91,12 @@ import { LoopService } from "./loop-service.js";
90
91
  import { ScheduleService } from "./schedule/service.js";
91
92
  import { DaemonConfigStore } from "./daemon-config-store.js";
92
93
  import { WorkspaceGitServiceImpl } from "./workspace-git-service.js";
93
- import { archivePersistedWorkspaceRecord } from "./workspace-archive-service.js";
94
+ import { resolveWorkspaceIdForPath } from "./resolve-workspace-id-for-path.js";
95
+ import { archivePersistedWorkspaceRecord, } from "./workspace-archive-service.js";
94
96
  import { setupAutoArchiveOnMerge } from "./auto-archive-on-merge/index.js";
95
97
  import { wrapSessionMessage } from "./messages.js";
96
98
  import { createConfiguredTerminalManager } from "../terminal/terminal-manager-factory.js";
99
+ import { applyTerminalAgentHookSetting } from "../terminal/agent-hooks/terminal-agent-hook-setting.js";
97
100
  import { createConnectionOfferV2, encodeOfferToFragmentUrl } from "./connection-offer.js";
98
101
  import { loadOrCreateDaemonKeyPair } from "./daemon-keypair.js";
99
102
  import { startRelayTransport } from "./relay-transport.js";
@@ -127,6 +130,56 @@ function createAgentMcpBaseUrl(listenTarget) {
127
130
  const host = resolveAgentMcpClientHost(listenTarget.host);
128
131
  return new URL("/mcp/agents", `http://${formatHostForHttpUrl(host)}:${listenTarget.port}`).toString();
129
132
  }
133
+ function createTerminalActivityUrl(listenTarget) {
134
+ if (!listenTarget || listenTarget.type !== "tcp") {
135
+ return null;
136
+ }
137
+ const host = resolveAgentMcpClientHost(listenTarget.host);
138
+ return new URL("/api/terminal-activity", `http://${formatHostForHttpUrl(host)}:${listenTarget.port}`).toString();
139
+ }
140
+ const TerminalActivityReportSchema = z.object({
141
+ terminalId: z.string().min(1),
142
+ token: z.string().min(1),
143
+ state: z.enum(["running", "idle", "needs-input"]),
144
+ });
145
+ const TERMINAL_ACTIVITY_STATE_MAP = {
146
+ running: "working",
147
+ idle: "idle",
148
+ "needs-input": "attention",
149
+ };
150
+ const LOOPBACK_REMOTE_ADDRESSES = new Set(["127.0.0.1", "::1", "::ffff:127.0.0.1"]);
151
+ function isLoopbackRemoteAddress(remoteAddress) {
152
+ return remoteAddress !== undefined && LOOPBACK_REMOTE_ADDRESSES.has(remoteAddress);
153
+ }
154
+ export function createTerminalActivityRouteHandler(terminalManager) {
155
+ return async (req, res) => {
156
+ if (!isLoopbackRemoteAddress(req.socket.remoteAddress)) {
157
+ res.status(403).json({ error: "Forbidden" });
158
+ return;
159
+ }
160
+ const parsed = TerminalActivityReportSchema.safeParse(req.body);
161
+ if (!parsed.success) {
162
+ res.status(400).json({ error: "Invalid terminal activity report" });
163
+ return;
164
+ }
165
+ const validation = terminalManager.validateTerminalActivityToken(parsed.data.terminalId, parsed.data.token);
166
+ if (validation !== "valid") {
167
+ res.status(403).json({ error: "Forbidden" });
168
+ return;
169
+ }
170
+ try {
171
+ const updated = await terminalManager.setTerminalActivity(parsed.data.terminalId, TERMINAL_ACTIVITY_STATE_MAP[parsed.data.state]);
172
+ if (!updated) {
173
+ res.status(403).json({ error: "Forbidden" });
174
+ return;
175
+ }
176
+ res.status(204).end();
177
+ }
178
+ catch {
179
+ res.status(500).json({ error: "Failed to update terminal activity" });
180
+ }
181
+ };
182
+ }
130
183
  function summarizeAgentMcpDebugMessage(body) {
131
184
  if (!body || typeof body !== "object" || Array.isArray(body)) {
132
185
  return {
@@ -173,6 +226,7 @@ export async function createPaseoDaemon(config, rootLogger) {
173
226
  providers: config.metadataGeneration?.providers ?? [],
174
227
  },
175
228
  autoArchiveAfterMerge: config.autoArchiveAfterMerge ?? false,
229
+ enableTerminalAgentHooks: config.enableTerminalAgentHooks ?? false,
176
230
  appendSystemPrompt: config.appendSystemPrompt ?? "",
177
231
  ...(config.terminalProfiles !== undefined
178
232
  ? { terminalProfiles: config.terminalProfiles }
@@ -198,6 +252,10 @@ export async function createPaseoDaemon(config, rootLogger) {
198
252
  const app = express();
199
253
  let boundListenTarget = null;
200
254
  let workspaceRegistry = null;
255
+ const terminalManager = createConfiguredTerminalManager({
256
+ getTerminalActivityUrl: () => createTerminalActivityUrl(boundListenTarget),
257
+ });
258
+ applyTerminalAgentHookSetting({ store: daemonConfigStore, logger });
201
259
  const serviceProxyPublicBaseUrl = config.serviceProxy?.publicBaseUrl
202
260
  ? config.serviceProxy.publicBaseUrl
203
261
  : null;
@@ -274,13 +332,14 @@ export async function createPaseoDaemon(config, rootLogger) {
274
332
  }
275
333
  next();
276
334
  });
335
+ // Local, harmless, and token-gated; deliberately skips daemon auth.
336
+ app.post("/api/terminal-activity", express.json(), createTerminalActivityRouteHandler(terminalManager));
277
337
  app.use(createRequireBearerMiddleware(config.auth, (context) => {
278
338
  logger.warn(context, "Rejected HTTP request with invalid daemon password");
279
339
  }));
340
+ app.use(express.json());
280
341
  // Serve static files from public directory
281
342
  app.use("/public", express.static(staticDir));
282
- // Middleware
283
- app.use(express.json());
284
343
  // Health check endpoint
285
344
  app.get("/api/health", (_req, res) => {
286
345
  res.json({ status: "ok", timestamp: new Date().toISOString() });
@@ -361,7 +420,6 @@ export async function createPaseoDaemon(config, rootLogger) {
361
420
  paseoHome: config.paseoHome,
362
421
  logger,
363
422
  });
364
- const terminalManager = createConfiguredTerminalManager();
365
423
  const github = createGitHubService();
366
424
  const workspaceGitService = new WorkspaceGitServiceImpl({
367
425
  logger,
@@ -468,9 +526,27 @@ export async function createPaseoDaemon(config, rootLogger) {
468
526
  await archivePersistedWorkspaceRecord({
469
527
  workspaceId,
470
528
  workspaceRegistry,
471
- projectRegistry,
472
529
  });
473
530
  };
531
+ // external path→workspace adapter, not ownership: archive-by-path requests that
532
+ // arrive with a worktree path and no workspaceId (old clients / CLI).
533
+ const findWorkspaceIdForCwdExternal = async (cwd) => {
534
+ return resolveWorkspaceIdForPath(cwd, await workspaceRegistry.list());
535
+ };
536
+ const ensureWorkspaceForCreateExternal = async (cwd) => {
537
+ const workspace = await createLocalCheckoutWorkspace({ cwd }, { projectRegistry, workspaceRegistry, workspaceGitService });
538
+ return workspace.workspaceId;
539
+ };
540
+ const listActiveWorkspacesExternal = async () => {
541
+ const workspaces = await workspaceRegistry.list();
542
+ return workspaces
543
+ .filter((workspace) => !workspace.archivedAt)
544
+ .map((workspace) => ({
545
+ workspaceId: workspace.workspaceId,
546
+ cwd: workspace.cwd,
547
+ kind: workspace.kind,
548
+ }));
549
+ };
474
550
  const markWorkspaceArchivingExternal = (workspaceIds, archivingAt) => {
475
551
  const workspaceIdList = Array.from(workspaceIds);
476
552
  for (const session of wsServer?.listActiveSessions() ?? []) {
@@ -492,7 +568,7 @@ export async function createPaseoDaemon(config, rootLogger) {
492
568
  };
493
569
  setupAutoArchiveOnMerge({
494
570
  paseoHome: config.paseoHome,
495
- worktreesRoot: config.worktreesRoot,
571
+ paseoWorktreesBaseRoot: config.worktreesRoot,
496
572
  daemonConfigStore,
497
573
  workspaceGitService,
498
574
  github,
@@ -500,6 +576,8 @@ export async function createPaseoDaemon(config, rootLogger) {
500
576
  agentStorage,
501
577
  terminalManager,
502
578
  logger,
579
+ findWorkspaceIdForCwd: findWorkspaceIdForCwdExternal,
580
+ listActiveWorkspaces: listActiveWorkspacesExternal,
503
581
  archiveWorkspaceRecord: archiveWorkspaceRecordExternal,
504
582
  markWorkspaceArchiving: markWorkspaceArchivingExternal,
505
583
  clearWorkspaceArchiving: clearWorkspaceArchivingExternal,
@@ -520,10 +598,13 @@ export async function createPaseoDaemon(config, rootLogger) {
520
598
  providerSnapshotManager,
521
599
  github,
522
600
  workspaceGitService,
601
+ findWorkspaceIdForCwd: findWorkspaceIdForCwdExternal,
602
+ listActiveWorkspaces: listActiveWorkspacesExternal,
523
603
  archiveWorkspaceRecord: archiveWorkspaceRecordExternal,
524
604
  emitWorkspaceUpdatesForWorkspaceIds: emitWorkspaceUpdatesExternal,
525
605
  markWorkspaceArchiving: markWorkspaceArchivingExternal,
526
606
  clearWorkspaceArchiving: clearWorkspaceArchivingExternal,
607
+ ensureWorkspaceForCreate: ensureWorkspaceForCreateExternal,
527
608
  createPaseoWorktree: async (input, serviceOptions) => {
528
609
  return createPaseoWorktreeWorkflow({
529
610
  paseoHome: config.paseoHome,
@@ -546,11 +627,8 @@ export async function createPaseoDaemon(config, rootLogger) {
546
627
  ?.listActiveSessions()
547
628
  .map((session) => session.warmWorkspaceGitDataForWorkspace(workspace)) ?? []);
548
629
  },
549
- emitWorkspaceUpdateForCwd: async (cwd, emitOptions) => {
550
- await Promise.all(wsServer
551
- ?.listActiveSessions()
552
- .map((session) => session.emitWorkspaceUpdatesForExternalCwds([cwd])) ?? []);
553
- void emitOptions;
630
+ emitWorkspaceUpdateForWorkspaceId: async (workspaceId) => {
631
+ await emitWorkspaceUpdatesExternal([workspaceId]);
554
632
  },
555
633
  cacheWorkspaceSetupSnapshot: () => { },
556
634
  emit: emitExternalSessionMessage,
@@ -762,6 +840,7 @@ export async function createPaseoDaemon(config, rootLogger) {
762
840
  }, projectRegistry, workspaceRegistry, chatService, loopService, scheduleService, checkoutDiffManager, serviceProxy, scriptRuntimeStore, handleBranchChange, () => (boundListenTarget?.type === "tcp" ? boundListenTarget.port : null), () => (boundListenTarget?.type === "tcp" ? boundListenTarget.host : null), (hostname) => scriptHealthMonitor.getHealthForHostname(hostname), workspaceGitService, github, config.pushNotificationSender, providerSnapshotManager, {
763
841
  listen: formatListenTarget(boundListenTarget ?? listenTarget),
764
842
  worktreesRoot: config.worktreesRoot,
843
+ appBaseUrl: config.appBaseUrl,
765
844
  relay: {
766
845
  enabled: relayEnabled,
767
846
  endpoint: relayEndpoint,
@@ -229,6 +229,7 @@ export function loadConfig(paseoHome, options) {
229
229
  mcpEnabled,
230
230
  mcpInjectIntoAgents,
231
231
  autoArchiveAfterMerge,
232
+ enableTerminalAgentHooks: persisted.daemon?.enableTerminalAgentHooks ?? false,
232
233
  appendSystemPrompt,
233
234
  terminalProfiles,
234
235
  mcpDebug: env.MCP_DEBUG === "1",
@@ -146,6 +146,7 @@ function mergeMutableConfigIntoPersistedConfig(params) {
146
146
  injectIntoAgents: mutable.mcp.injectIntoAgents,
147
147
  },
148
148
  autoArchiveAfterMerge: mutable.autoArchiveAfterMerge,
149
+ enableTerminalAgentHooks: mutable.enableTerminalAgentHooks,
149
150
  appendSystemPrompt: mutable.appendSystemPrompt,
150
151
  ...(mutable.terminalProfiles !== undefined
151
152
  ? { terminalProfiles: mutable.terminalProfiles }
@@ -14,7 +14,7 @@ export { DirectTcpHostConnectionSchema, type DirectTcpHostConnection, type Norma
14
14
  export { ensureLocalSpeechModels, listLocalSpeechModels, type LocalSpeechModelId, type LocalSttModelId, type LocalTtsModelId, } from "./speech/providers/local/models.js";
15
15
  export { applySherpaLoaderEnv, resolveSherpaLoaderEnv, sherpaLoaderEnvKey, sherpaPlatformArch, sherpaPlatformPackageName, type SherpaLoaderEnvKey, type SherpaLoaderEnvResolution, } from "./speech/providers/local/sherpa/sherpa-runtime-env.js";
16
16
  export { type ProviderOverride, type ProviderProfileModel, } from "./agent/provider-launch-config.js";
17
- export { findExecutable } from "../utils/executable.js";
17
+ export { findExecutable } from "../executable-resolution/executable-resolution.js";
18
18
  export { execCommand, spawnProcess } from "../utils/spawn.js";
19
19
  export { AGENT_PROVIDER_DEFINITIONS, BUILTIN_PROVIDER_IDS, type AgentProviderDefinition, } from "@getpaseo/protocol/provider-manifest";
20
20
  export type { AgentMode, AgentUsage, AgentCapabilityFlags, AgentPermissionRequest, AgentTimelineItem, ProviderSnapshotEntry, } from "./agent/agent-sdk-types.js";
@@ -14,7 +14,7 @@ export { PARENT_AGENT_ID_LABEL } from "@getpaseo/protocol/agent-labels";
14
14
  export { DirectTcpHostConnectionSchema, } from "@getpaseo/protocol/host-connection-schema";
15
15
  export { ensureLocalSpeechModels, listLocalSpeechModels, } from "./speech/providers/local/models.js";
16
16
  export { applySherpaLoaderEnv, resolveSherpaLoaderEnv, sherpaLoaderEnvKey, sherpaPlatformArch, sherpaPlatformPackageName, } from "./speech/providers/local/sherpa/sherpa-runtime-env.js";
17
- export { findExecutable } from "../utils/executable.js";
17
+ export { findExecutable } from "../executable-resolution/executable-resolution.js";
18
18
  export { execCommand, spawnProcess } from "../utils/spawn.js";
19
19
  // Provider manifest (source of truth for provider definitions)
20
20
  export { AGENT_PROVIDER_DEFINITIONS, BUILTIN_PROVIDER_IDS, } from "@getpaseo/protocol/provider-manifest";
@@ -34,17 +34,17 @@ declare const LoopVerifyCheckResultSchema: z.ZodObject<{
34
34
  startedAt: z.ZodString;
35
35
  completedAt: z.ZodString;
36
36
  }, "strip", z.ZodTypeAny, {
37
+ stdout: string;
37
38
  exitCode: number;
38
39
  command: string;
39
- stdout: string;
40
40
  stderr: string;
41
41
  startedAt: string;
42
42
  completedAt: string;
43
43
  passed: boolean;
44
44
  }, {
45
+ stdout: string;
45
46
  exitCode: number;
46
47
  command: string;
47
- stdout: string;
48
48
  stderr: string;
49
49
  startedAt: string;
50
50
  completedAt: string;
@@ -57,15 +57,15 @@ declare const LoopVerifyPromptResultSchema: z.ZodObject<{
57
57
  startedAt: z.ZodString;
58
58
  completedAt: z.ZodString;
59
59
  }, "strip", z.ZodTypeAny, {
60
- reason: string;
61
60
  startedAt: string;
62
61
  completedAt: string;
62
+ reason: string;
63
63
  passed: boolean;
64
64
  verifierAgentId: string | null;
65
65
  }, {
66
- reason: string;
67
66
  startedAt: string;
68
67
  completedAt: string;
68
+ reason: string;
69
69
  passed: boolean;
70
70
  verifierAgentId: string | null;
71
71
  }>;
@@ -87,17 +87,17 @@ declare const LoopIterationRecordSchema: z.ZodObject<{
87
87
  startedAt: z.ZodString;
88
88
  completedAt: z.ZodString;
89
89
  }, "strip", z.ZodTypeAny, {
90
+ stdout: string;
90
91
  exitCode: number;
91
92
  command: string;
92
- stdout: string;
93
93
  stderr: string;
94
94
  startedAt: string;
95
95
  completedAt: string;
96
96
  passed: boolean;
97
97
  }, {
98
+ stdout: string;
98
99
  exitCode: number;
99
100
  command: string;
100
- stdout: string;
101
101
  stderr: string;
102
102
  startedAt: string;
103
103
  completedAt: string;
@@ -110,15 +110,15 @@ declare const LoopIterationRecordSchema: z.ZodObject<{
110
110
  startedAt: z.ZodString;
111
111
  completedAt: z.ZodString;
112
112
  }, "strip", z.ZodTypeAny, {
113
- reason: string;
114
113
  startedAt: string;
115
114
  completedAt: string;
115
+ reason: string;
116
116
  passed: boolean;
117
117
  verifierAgentId: string | null;
118
118
  }, {
119
- reason: string;
120
119
  startedAt: string;
121
120
  completedAt: string;
121
+ reason: string;
122
122
  passed: boolean;
123
123
  verifierAgentId: string | null;
124
124
  }>>;
@@ -132,18 +132,18 @@ declare const LoopIterationRecordSchema: z.ZodObject<{
132
132
  workerOutcome: "completed" | "failed" | "canceled" | null;
133
133
  failureReason: string | null;
134
134
  verifyChecks: {
135
+ stdout: string;
135
136
  exitCode: number;
136
137
  command: string;
137
- stdout: string;
138
138
  stderr: string;
139
139
  startedAt: string;
140
140
  completedAt: string;
141
141
  passed: boolean;
142
142
  }[];
143
143
  verifyPrompt: {
144
- reason: string;
145
144
  startedAt: string;
146
145
  completedAt: string;
146
+ reason: string;
147
147
  passed: boolean;
148
148
  verifierAgentId: string | null;
149
149
  } | null;
@@ -157,18 +157,18 @@ declare const LoopIterationRecordSchema: z.ZodObject<{
157
157
  workerOutcome: "completed" | "failed" | "canceled" | null;
158
158
  failureReason: string | null;
159
159
  verifyChecks: {
160
+ stdout: string;
160
161
  exitCode: number;
161
162
  command: string;
162
- stdout: string;
163
163
  stderr: string;
164
164
  startedAt: string;
165
165
  completedAt: string;
166
166
  passed: boolean;
167
167
  }[];
168
168
  verifyPrompt: {
169
- reason: string;
170
169
  startedAt: string;
171
170
  completedAt: string;
171
+ reason: string;
172
172
  passed: boolean;
173
173
  verifierAgentId: string | null;
174
174
  } | null;
@@ -216,17 +216,17 @@ declare const LoopRecordSchema: z.ZodObject<{
216
216
  startedAt: z.ZodString;
217
217
  completedAt: z.ZodString;
218
218
  }, "strip", z.ZodTypeAny, {
219
+ stdout: string;
219
220
  exitCode: number;
220
221
  command: string;
221
- stdout: string;
222
222
  stderr: string;
223
223
  startedAt: string;
224
224
  completedAt: string;
225
225
  passed: boolean;
226
226
  }, {
227
+ stdout: string;
227
228
  exitCode: number;
228
229
  command: string;
229
- stdout: string;
230
230
  stderr: string;
231
231
  startedAt: string;
232
232
  completedAt: string;
@@ -239,15 +239,15 @@ declare const LoopRecordSchema: z.ZodObject<{
239
239
  startedAt: z.ZodString;
240
240
  completedAt: z.ZodString;
241
241
  }, "strip", z.ZodTypeAny, {
242
- reason: string;
243
242
  startedAt: string;
244
243
  completedAt: string;
244
+ reason: string;
245
245
  passed: boolean;
246
246
  verifierAgentId: string | null;
247
247
  }, {
248
- reason: string;
249
248
  startedAt: string;
250
249
  completedAt: string;
250
+ reason: string;
251
251
  passed: boolean;
252
252
  verifierAgentId: string | null;
253
253
  }>>;
@@ -261,18 +261,18 @@ declare const LoopRecordSchema: z.ZodObject<{
261
261
  workerOutcome: "completed" | "failed" | "canceled" | null;
262
262
  failureReason: string | null;
263
263
  verifyChecks: {
264
+ stdout: string;
264
265
  exitCode: number;
265
266
  command: string;
266
- stdout: string;
267
267
  stderr: string;
268
268
  startedAt: string;
269
269
  completedAt: string;
270
270
  passed: boolean;
271
271
  }[];
272
272
  verifyPrompt: {
273
- reason: string;
274
273
  startedAt: string;
275
274
  completedAt: string;
275
+ reason: string;
276
276
  passed: boolean;
277
277
  verifierAgentId: string | null;
278
278
  } | null;
@@ -286,18 +286,18 @@ declare const LoopRecordSchema: z.ZodObject<{
286
286
  workerOutcome: "completed" | "failed" | "canceled" | null;
287
287
  failureReason: string | null;
288
288
  verifyChecks: {
289
+ stdout: string;
289
290
  exitCode: number;
290
291
  command: string;
291
- stdout: string;
292
292
  stderr: string;
293
293
  startedAt: string;
294
294
  completedAt: string;
295
295
  passed: boolean;
296
296
  }[];
297
297
  verifyPrompt: {
298
- reason: string;
299
298
  startedAt: string;
300
299
  completedAt: string;
300
+ reason: string;
301
301
  passed: boolean;
302
302
  verifierAgentId: string | null;
303
303
  } | null;
@@ -351,18 +351,18 @@ declare const LoopRecordSchema: z.ZodObject<{
351
351
  workerOutcome: "completed" | "failed" | "canceled" | null;
352
352
  failureReason: string | null;
353
353
  verifyChecks: {
354
+ stdout: string;
354
355
  exitCode: number;
355
356
  command: string;
356
- stdout: string;
357
357
  stderr: string;
358
358
  startedAt: string;
359
359
  completedAt: string;
360
360
  passed: boolean;
361
361
  }[];
362
362
  verifyPrompt: {
363
- reason: string;
364
363
  startedAt: string;
365
364
  completedAt: string;
365
+ reason: string;
366
366
  passed: boolean;
367
367
  verifierAgentId: string | null;
368
368
  } | null;
@@ -413,18 +413,18 @@ declare const LoopRecordSchema: z.ZodObject<{
413
413
  workerOutcome: "completed" | "failed" | "canceled" | null;
414
414
  failureReason: string | null;
415
415
  verifyChecks: {
416
+ stdout: string;
416
417
  exitCode: number;
417
418
  command: string;
418
- stdout: string;
419
419
  stderr: string;
420
420
  startedAt: string;
421
421
  completedAt: string;
422
422
  passed: boolean;
423
423
  }[];
424
424
  verifyPrompt: {
425
- reason: string;
426
425
  startedAt: string;
427
426
  completedAt: string;
427
+ reason: string;
428
428
  passed: boolean;
429
429
  verifierAgentId: string | null;
430
430
  } | null;
@@ -0,0 +1,9 @@
1
+ import type { Logger } from "pino";
2
+ import type { AgentStorage } from "../agent/agent-storage.js";
3
+ import type { WorkspaceRegistry } from "../workspace-registry.js";
4
+ export declare function backfillWorkspaceIdForLegacyAgents(options: {
5
+ agentStorage: AgentStorage;
6
+ workspaceRegistry: WorkspaceRegistry;
7
+ logger: Logger;
8
+ }): Promise<number>;
9
+ //# sourceMappingURL=backfill-workspace-id.migration.d.ts.map