@getpaseo/server 0.1.88 → 0.1.90

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/dist/server/server/agent/agent-manager.js +4 -1
  2. package/dist/server/server/agent/agent-prompt.js +4 -1
  3. package/dist/server/server/agent/agent-sdk-types.d.ts +1 -0
  4. package/dist/server/server/agent/agent-storage.d.ts +22 -22
  5. package/dist/server/server/agent/agent-storage.js +2 -9
  6. package/dist/server/server/agent/create-agent/create.d.ts +2 -0
  7. package/dist/server/server/agent/create-agent/create.js +26 -7
  8. package/dist/server/server/agent/create-agent-lifecycle-dispatch.d.ts +1 -0
  9. package/dist/server/server/agent/create-agent-lifecycle-dispatch.js +4 -0
  10. package/dist/server/server/agent/create-agent-mode.d.ts +3 -8
  11. package/dist/server/server/agent/create-agent-mode.js +16 -2
  12. package/dist/server/server/agent/import-sessions.js +1 -1
  13. package/dist/server/server/agent/mcp-server.d.ts +1 -0
  14. package/dist/server/server/agent/mcp-server.js +113 -70
  15. package/dist/server/server/agent/provider-snapshot-manager.d.ts +2 -1
  16. package/dist/server/server/agent/provider-snapshot-manager.js +18 -2
  17. package/dist/server/server/agent/providers/acp-agent.d.ts +3 -3
  18. package/dist/server/server/agent/providers/acp-agent.js +18 -13
  19. package/dist/server/server/agent/providers/codex-app-server-agent.js +16 -22
  20. package/dist/server/server/agent/providers/mock-load-test-agent.d.ts +2 -0
  21. package/dist/server/server/agent/providers/mock-load-test-agent.js +69 -2
  22. package/dist/server/server/agent/providers/opencode-agent.js +19 -8
  23. package/dist/server/server/agent/providers/pi/agent.js +13 -0
  24. package/dist/server/server/agent/providers/pi/rpc-types.d.ts +3 -0
  25. package/dist/server/server/agent/timeline-projection.js +30 -1
  26. package/dist/server/server/atomic-file.d.ts +3 -0
  27. package/dist/server/server/atomic-file.js +19 -0
  28. package/dist/server/server/auto-archive-on-merge/archive-if-safe.d.ts +1 -0
  29. package/dist/server/server/auto-archive-on-merge/archive-if-safe.js +10 -2
  30. package/dist/server/server/bootstrap.d.ts +7 -2
  31. package/dist/server/server/bootstrap.js +154 -115
  32. package/dist/server/server/chat/chat-service.js +2 -4
  33. package/dist/server/server/config.js +41 -0
  34. package/dist/server/server/daemon-keypair.js +2 -2
  35. package/dist/server/server/loop-service.d.ts +26 -22
  36. package/dist/server/server/loop-service.js +27 -9
  37. package/dist/server/server/package-version.d.ts +2 -2
  38. package/dist/server/server/paseo-worktree-archive-service.d.ts +2 -0
  39. package/dist/server/server/paseo-worktree-archive-service.js +28 -9
  40. package/dist/server/server/persisted-config.d.ts +84 -28
  41. package/dist/server/server/persisted-config.js +20 -3
  42. package/dist/server/server/pid-lock.d.ts +2 -2
  43. package/dist/server/server/private-files.d.ts +0 -1
  44. package/dist/server/server/private-files.js +0 -5
  45. package/dist/server/server/schedule/service.d.ts +6 -0
  46. package/dist/server/server/schedule/service.js +41 -18
  47. package/dist/server/server/schedule/store.js +3 -2
  48. package/dist/server/server/script-health-monitor.d.ts +4 -4
  49. package/dist/server/server/script-health-monitor.js +6 -6
  50. package/dist/server/server/script-proxy.d.ts +2 -39
  51. package/dist/server/server/script-proxy.js +1 -244
  52. package/dist/server/server/script-route-branch-handler.d.ts +2 -2
  53. package/dist/server/server/script-route-branch-handler.js +3 -37
  54. package/dist/server/server/script-status-projection.d.ts +6 -4
  55. package/dist/server/server/script-status-projection.js +85 -37
  56. package/dist/server/server/server-id.js +3 -3
  57. package/dist/server/server/service-proxy.d.ts +237 -0
  58. package/dist/server/server/service-proxy.js +714 -0
  59. package/dist/server/server/session.d.ts +12 -18
  60. package/dist/server/server/session.js +206 -117
  61. package/dist/server/server/speech/providers/local/worker-client.js +1 -11
  62. package/dist/server/server/websocket-server.d.ts +7 -4
  63. package/dist/server/server/websocket-server.js +9 -4
  64. package/dist/server/server/workspace-bootstrap-dedupe.d.ts +34 -0
  65. package/dist/server/server/workspace-bootstrap-dedupe.js +23 -0
  66. package/dist/server/server/workspace-directory.d.ts +8 -0
  67. package/dist/server/server/workspace-directory.js +141 -11
  68. package/dist/server/server/workspace-git-service.d.ts +3 -0
  69. package/dist/server/server/workspace-git-service.js +53 -12
  70. package/dist/server/server/workspace-registry.d.ts +2 -2
  71. package/dist/server/server/workspace-registry.js +2 -6
  72. package/dist/server/server/workspace-service-env.d.ts +1 -0
  73. package/dist/server/server/workspace-service-env.js +23 -18
  74. package/dist/server/server/worktree/commands.d.ts +2 -0
  75. package/dist/server/server/worktree/commands.js +4 -1
  76. package/dist/server/server/worktree-bootstrap.d.ts +4 -3
  77. package/dist/server/server/worktree-bootstrap.js +14 -13
  78. package/dist/server/server/worktree-core.d.ts +1 -0
  79. package/dist/server/server/worktree-core.js +2 -0
  80. package/dist/server/server/worktree-session.d.ts +6 -2
  81. package/dist/server/server/worktree-session.js +3 -0
  82. package/dist/server/services/github-service.d.ts +1 -0
  83. package/dist/server/services/github-service.js +7 -1
  84. package/dist/server/utils/checkout-git.d.ts +6 -3
  85. package/dist/server/utils/checkout-git.js +40 -38
  86. package/dist/server/utils/worktree.d.ts +17 -12
  87. package/dist/server/utils/worktree.js +39 -22
  88. package/dist/src/server/persisted-config.js +20 -3
  89. package/dist/src/server/private-files.js +0 -5
  90. package/package.json +9 -7
  91. package/dist/server/server/editor-targets.d.ts +0 -18
  92. package/dist/server/server/editor-targets.js +0 -109
  93. package/dist/server/utils/script-hostname.d.ts +0 -8
  94. package/dist/server/utils/script-hostname.js +0 -14
@@ -2,6 +2,7 @@ import { z } from "zod";
2
2
  import type { Logger } from "pino";
3
3
  import type { AgentManager } from "./agent/agent-manager.js";
4
4
  import type { AgentProvider } from "./agent/agent-sdk-types.js";
5
+ import type { ProviderSnapshotManager } from "./agent/provider-snapshot-manager.js";
5
6
  declare const LoopLogEntrySchema: z.ZodObject<{
6
7
  seq: z.ZodNumber;
7
8
  timestamp: z.ZodString;
@@ -10,16 +11,16 @@ declare const LoopLogEntrySchema: z.ZodObject<{
10
11
  level: z.ZodEnum<["info", "error"]>;
11
12
  text: z.ZodString;
12
13
  }, "strip", z.ZodTypeAny, {
14
+ text: string;
13
15
  level: "error" | "info";
14
16
  source: "worker" | "loop" | "verifier" | "verify-check";
15
- text: string;
16
17
  timestamp: string;
17
18
  seq: number;
18
19
  iteration: number | null;
19
20
  }, {
21
+ text: string;
20
22
  level: "error" | "info";
21
23
  source: "worker" | "loop" | "verifier" | "verify-check";
22
- text: string;
23
24
  timestamp: string;
24
25
  seq: number;
25
26
  iteration: number | null;
@@ -33,16 +34,16 @@ declare const LoopVerifyCheckResultSchema: z.ZodObject<{
33
34
  startedAt: z.ZodString;
34
35
  completedAt: z.ZodString;
35
36
  }, "strip", z.ZodTypeAny, {
36
- command: string;
37
37
  exitCode: number;
38
+ command: string;
38
39
  stdout: string;
39
40
  stderr: string;
40
41
  startedAt: string;
41
42
  completedAt: string;
42
43
  passed: boolean;
43
44
  }, {
44
- command: string;
45
45
  exitCode: number;
46
+ command: string;
46
47
  stdout: string;
47
48
  stderr: string;
48
49
  startedAt: string;
@@ -86,16 +87,16 @@ declare const LoopIterationRecordSchema: z.ZodObject<{
86
87
  startedAt: z.ZodString;
87
88
  completedAt: z.ZodString;
88
89
  }, "strip", z.ZodTypeAny, {
89
- command: string;
90
90
  exitCode: number;
91
+ command: string;
91
92
  stdout: string;
92
93
  stderr: string;
93
94
  startedAt: string;
94
95
  completedAt: string;
95
96
  passed: boolean;
96
97
  }, {
97
- command: string;
98
98
  exitCode: number;
99
+ command: string;
99
100
  stdout: string;
100
101
  stderr: string;
101
102
  startedAt: string;
@@ -131,8 +132,8 @@ declare const LoopIterationRecordSchema: z.ZodObject<{
131
132
  workerOutcome: "completed" | "failed" | "canceled" | null;
132
133
  failureReason: string | null;
133
134
  verifyChecks: {
134
- command: string;
135
135
  exitCode: number;
136
+ command: string;
136
137
  stdout: string;
137
138
  stderr: string;
138
139
  startedAt: string;
@@ -156,8 +157,8 @@ declare const LoopIterationRecordSchema: z.ZodObject<{
156
157
  workerOutcome: "completed" | "failed" | "canceled" | null;
157
158
  failureReason: string | null;
158
159
  verifyChecks: {
159
- command: string;
160
160
  exitCode: number;
161
+ command: string;
161
162
  stdout: string;
162
163
  stderr: string;
163
164
  startedAt: string;
@@ -215,16 +216,16 @@ declare const LoopRecordSchema: z.ZodObject<{
215
216
  startedAt: z.ZodString;
216
217
  completedAt: z.ZodString;
217
218
  }, "strip", z.ZodTypeAny, {
218
- command: string;
219
219
  exitCode: number;
220
+ command: string;
220
221
  stdout: string;
221
222
  stderr: string;
222
223
  startedAt: string;
223
224
  completedAt: string;
224
225
  passed: boolean;
225
226
  }, {
226
- command: string;
227
227
  exitCode: number;
228
+ command: string;
228
229
  stdout: string;
229
230
  stderr: string;
230
231
  startedAt: string;
@@ -260,8 +261,8 @@ declare const LoopRecordSchema: z.ZodObject<{
260
261
  workerOutcome: "completed" | "failed" | "canceled" | null;
261
262
  failureReason: string | null;
262
263
  verifyChecks: {
263
- command: string;
264
264
  exitCode: number;
265
+ command: string;
265
266
  stdout: string;
266
267
  stderr: string;
267
268
  startedAt: string;
@@ -285,8 +286,8 @@ declare const LoopRecordSchema: z.ZodObject<{
285
286
  workerOutcome: "completed" | "failed" | "canceled" | null;
286
287
  failureReason: string | null;
287
288
  verifyChecks: {
288
- command: string;
289
289
  exitCode: number;
290
+ command: string;
290
291
  stdout: string;
291
292
  stderr: string;
292
293
  startedAt: string;
@@ -309,16 +310,16 @@ declare const LoopRecordSchema: z.ZodObject<{
309
310
  level: z.ZodEnum<["info", "error"]>;
310
311
  text: z.ZodString;
311
312
  }, "strip", z.ZodTypeAny, {
313
+ text: string;
312
314
  level: "error" | "info";
313
315
  source: "worker" | "loop" | "verifier" | "verify-check";
314
- text: string;
315
316
  timestamp: string;
316
317
  seq: number;
317
318
  iteration: number | null;
318
319
  }, {
320
+ text: string;
319
321
  level: "error" | "info";
320
322
  source: "worker" | "loop" | "verifier" | "verify-check";
321
- text: string;
322
323
  timestamp: string;
323
324
  seq: number;
324
325
  iteration: number | null;
@@ -328,12 +329,12 @@ declare const LoopRecordSchema: z.ZodObject<{
328
329
  activeWorkerAgentId: z.ZodNullable<z.ZodString>;
329
330
  activeVerifierAgentId: z.ZodNullable<z.ZodString>;
330
331
  }, "strip", z.ZodTypeAny, {
331
- status: "running" | "failed" | "succeeded" | "stopped";
332
332
  cwd: string;
333
333
  name: string | null;
334
- createdAt: string;
335
334
  id: string;
335
+ status: "running" | "failed" | "succeeded" | "stopped";
336
336
  provider: string;
337
+ createdAt: string;
337
338
  updatedAt: string;
338
339
  modeId: string | null;
339
340
  model: string | null;
@@ -350,8 +351,8 @@ declare const LoopRecordSchema: z.ZodObject<{
350
351
  workerOutcome: "completed" | "failed" | "canceled" | null;
351
352
  failureReason: string | null;
352
353
  verifyChecks: {
353
- command: string;
354
354
  exitCode: number;
355
+ command: string;
355
356
  stdout: string;
356
357
  stderr: string;
357
358
  startedAt: string;
@@ -379,9 +380,9 @@ declare const LoopRecordSchema: z.ZodObject<{
379
380
  maxTimeMs: number | null;
380
381
  stopRequestedAt: string | null;
381
382
  logs: {
383
+ text: string;
382
384
  level: "error" | "info";
383
385
  source: "worker" | "loop" | "verifier" | "verify-check";
384
- text: string;
385
386
  timestamp: string;
386
387
  seq: number;
387
388
  iteration: number | null;
@@ -391,12 +392,12 @@ declare const LoopRecordSchema: z.ZodObject<{
391
392
  activeWorkerAgentId: string | null;
392
393
  activeVerifierAgentId: string | null;
393
394
  }, {
394
- status: "running" | "failed" | "succeeded" | "stopped";
395
395
  cwd: string;
396
396
  name: string | null;
397
- createdAt: string;
398
397
  id: string;
398
+ status: "running" | "failed" | "succeeded" | "stopped";
399
399
  provider: string;
400
+ createdAt: string;
400
401
  updatedAt: string;
401
402
  model: string | null;
402
403
  startedAt: string;
@@ -412,8 +413,8 @@ declare const LoopRecordSchema: z.ZodObject<{
412
413
  workerOutcome: "completed" | "failed" | "canceled" | null;
413
414
  failureReason: string | null;
414
415
  verifyChecks: {
415
- command: string;
416
416
  exitCode: number;
417
+ command: string;
417
418
  stdout: string;
418
419
  stderr: string;
419
420
  startedAt: string;
@@ -440,9 +441,9 @@ declare const LoopRecordSchema: z.ZodObject<{
440
441
  maxTimeMs: number | null;
441
442
  stopRequestedAt: string | null;
442
443
  logs: {
444
+ text: string;
443
445
  level: "error" | "info";
444
446
  source: "worker" | "loop" | "verifier" | "verify-check";
445
- text: string;
446
447
  timestamp: string;
447
448
  seq: number;
448
449
  iteration: number | null;
@@ -493,6 +494,7 @@ export interface LoopLogsResult {
493
494
  entries: LoopLogEntry[];
494
495
  nextCursor: number;
495
496
  }
497
+ type CreateConfigResolver = Pick<ProviderSnapshotManager, "resolveCreateConfig">;
496
498
  export declare class LoopService {
497
499
  private readonly options;
498
500
  private readonly storePath;
@@ -505,6 +507,7 @@ export declare class LoopService {
505
507
  paseoHome: string;
506
508
  agentManager: AgentManager;
507
509
  logger: Logger;
510
+ providerSnapshotManager: CreateConfigResolver;
508
511
  });
509
512
  initialize(): Promise<void>;
510
513
  runLoop(input: LoopRunOptions): Promise<LoopRecord>;
@@ -518,6 +521,7 @@ export declare class LoopService {
518
521
  private runVerification;
519
522
  private buildWorkerConfig;
520
523
  private buildVerifierConfig;
524
+ private resolveProviderCreateConfig;
521
525
  private resolveFinalText;
522
526
  private toPrompt;
523
527
  private finishLoop;
@@ -2,10 +2,10 @@ import { randomUUID } from "node:crypto";
2
2
  import { promises as fs } from "node:fs";
3
3
  import path from "node:path";
4
4
  import { z } from "zod";
5
+ import { writeJsonFileAtomic } from "./atomic-file.js";
5
6
  import { curateAgentActivity } from "./agent/activity-curator.js";
6
7
  import { getStructuredAgentResponse } from "./agent/agent-response-loop.js";
7
8
  import { execCommand, platformShell } from "../utils/spawn.js";
8
- import { getUnattendedModeId } from "@getpaseo/protocol/provider-manifest";
9
9
  const LOOP_ID_LENGTH = 8;
10
10
  const DEFAULT_LOOP_PROVIDER = "claude";
11
11
  const MAX_VERIFY_OUTPUT_BYTES = 64 * 1024;
@@ -494,7 +494,7 @@ export class LoopService {
494
494
  await this.persist();
495
495
  }
496
496
  async runWorkerIteration(loop, iteration, signal) {
497
- const agent = await this.options.agentManager.createAgent(this.buildWorkerConfig(loop, iteration));
497
+ const agent = await this.options.agentManager.createAgent(await this.buildWorkerConfig(loop, iteration));
498
498
  iteration.workerAgentId = agent.id;
499
499
  loop.activeWorkerAgentId = agent.id;
500
500
  loop.updatedAt = nowIso();
@@ -591,7 +591,7 @@ export class LoopService {
591
591
  return true;
592
592
  }
593
593
  const startedAt = nowIso();
594
- const verifierAgent = await this.options.agentManager.createAgent(this.buildVerifierConfig(loop, iteration));
594
+ const verifierAgent = await this.options.agentManager.createAgent(await this.buildVerifierConfig(loop, iteration));
595
595
  iteration.verifierAgentId = verifierAgent.id;
596
596
  loop.activeVerifierAgentId = verifierAgent.id;
597
597
  loop.updatedAt = nowIso();
@@ -659,28 +659,47 @@ export class LoopService {
659
659
  }
660
660
  }
661
661
  }
662
- buildWorkerConfig(loop, iteration) {
662
+ async buildWorkerConfig(loop, iteration) {
663
663
  const provider = loop.workerProvider ?? loop.provider;
664
+ const resolvedUnattendedConfig = loop.modeId
665
+ ? { modeId: loop.modeId, featureValues: undefined }
666
+ : await this.resolveProviderCreateConfig({ provider, cwd: loop.cwd });
664
667
  return {
665
668
  provider,
666
669
  cwd: loop.cwd,
667
670
  model: loop.workerModel ?? loop.model ?? undefined,
668
- modeId: loop.modeId ?? getUnattendedModeId(provider),
671
+ modeId: resolvedUnattendedConfig.modeId,
672
+ featureValues: resolvedUnattendedConfig.featureValues,
669
673
  title: buildWorkerTitle(loop, iteration.index),
670
674
  internal: true,
671
675
  };
672
676
  }
673
- buildVerifierConfig(loop, iteration) {
677
+ async buildVerifierConfig(loop, iteration) {
674
678
  const provider = loop.verifierProvider ?? loop.provider;
679
+ const explicitModeId = loop.verifierModeId ?? loop.modeId;
680
+ const resolvedUnattendedConfig = explicitModeId
681
+ ? { modeId: explicitModeId, featureValues: undefined }
682
+ : await this.resolveProviderCreateConfig({ provider, cwd: loop.cwd });
675
683
  return {
676
684
  provider,
677
685
  cwd: loop.cwd,
678
686
  model: loop.verifierModel ?? loop.model ?? undefined,
679
- modeId: loop.verifierModeId ?? loop.modeId ?? getUnattendedModeId(provider),
687
+ modeId: resolvedUnattendedConfig.modeId,
688
+ featureValues: resolvedUnattendedConfig.featureValues,
680
689
  title: buildVerifierTitle(loop, iteration.index),
681
690
  internal: true,
682
691
  };
683
692
  }
693
+ resolveProviderCreateConfig(input) {
694
+ return this.options.providerSnapshotManager.resolveCreateConfig({
695
+ provider: input.provider,
696
+ cwd: input.cwd,
697
+ requestedMode: undefined,
698
+ featureValues: undefined,
699
+ parent: null,
700
+ unattended: true,
701
+ });
702
+ }
684
703
  resolveFinalText(timeline, finalText) {
685
704
  if (finalText.trim()) {
686
705
  return finalText;
@@ -739,9 +758,8 @@ export class LoopService {
739
758
  }
740
759
  async persist() {
741
760
  const nextPersist = this.persistQueue.then(async () => {
742
- await fs.mkdir(path.dirname(this.storePath), { recursive: true });
743
761
  const records = Array.from(this.loops.values()).sort((left, right) => left.createdAt.localeCompare(right.createdAt));
744
- await fs.writeFile(this.storePath, JSON.stringify(records, null, 2), "utf8");
762
+ await writeJsonFileAtomic(this.storePath, records);
745
763
  return;
746
764
  });
747
765
  this.persistQueue = nextPersist.catch(() => { });
@@ -7,11 +7,11 @@ export declare const packageJsonSchema: z.ZodObject<{
7
7
  name: z.ZodOptional<z.ZodString>;
8
8
  version: z.ZodOptional<z.ZodString>;
9
9
  }, "strip", z.ZodTypeAny, {
10
- version?: string | undefined;
11
10
  name?: string | undefined;
12
- }, {
13
11
  version?: string | undefined;
12
+ }, {
14
13
  name?: string | undefined;
14
+ version?: string | undefined;
15
15
  }>;
16
16
  export type PackageJson = z.infer<typeof packageJsonSchema>;
17
17
  export declare class PackageVersionResolutionError extends Error {
@@ -6,6 +6,7 @@ import type { GitHubService } from "../services/github-service.js";
6
6
  import type { TerminalManager } from "../terminal/terminal-manager.js";
7
7
  export interface ArchivePaseoWorktreeDependencies {
8
8
  paseoHome?: string;
9
+ worktreesRoot?: string;
9
10
  github: GitHubService;
10
11
  workspaceGitService: Pick<WorkspaceGitService, "getSnapshot">;
11
12
  agentManager: Pick<AgentManager, "listAgents" | "archiveAgent" | "archiveSnapshot">;
@@ -33,6 +34,7 @@ export declare function archivePaseoWorktree(dependencies: ArchivePaseoWorktreeD
33
34
  targetPath: string;
34
35
  repoRoot: string | null;
35
36
  worktreesRoot?: string;
37
+ worktreesBaseRoot?: string;
36
38
  requestId: string;
37
39
  }): Promise<string[]>;
38
40
  export declare function killTerminalsUnderPath(dependencies: KillTerminalsUnderPathDependencies, rootPath: string): Promise<void>;
@@ -1,9 +1,10 @@
1
1
  import { normalizeWorkspaceId as normalizePersistedWorkspaceId } from "./workspace-registry-model.js";
2
- import { deletePaseoWorktree, resolvePaseoWorktreeRootForCwd } from "../utils/worktree.js";
2
+ import { deletePaseoWorktree, resolvePaseoWorktreeRootForCwd, WorktreeTeardownError, } from "../utils/worktree.js";
3
3
  export async function archivePaseoWorktree(dependencies, options) {
4
4
  let targetPath = options.targetPath;
5
5
  const resolvedWorktree = await resolvePaseoWorktreeRootForCwd(targetPath, {
6
6
  paseoHome: dependencies.paseoHome,
7
+ worktreesRoot: options.worktreesBaseRoot ?? dependencies.worktreesRoot,
7
8
  });
8
9
  if (resolvedWorktree) {
9
10
  targetPath = resolvedWorktree.worktreePath;
@@ -50,13 +51,26 @@ export async function archivePaseoWorktree(dependencies, options) {
50
51
  dependencies.sessionLogger?.warn({ err: result.reason, targetPath }, "Worktree archive teardown step failed; continuing");
51
52
  }
52
53
  }
53
- await deletePaseoWorktree({
54
- cwd: options.repoRoot,
55
- worktreePath: targetPath,
56
- worktreesRoot: options.worktreesRoot,
57
- paseoHome: dependencies.paseoHome,
58
- });
59
- if (options.repoRoot) {
54
+ let teardownError = null;
55
+ try {
56
+ await deletePaseoWorktree({
57
+ cwd: options.repoRoot,
58
+ worktreePath: targetPath,
59
+ worktreesRoot: options.worktreesRoot,
60
+ paseoHome: dependencies.paseoHome,
61
+ worktreesBaseRoot: options.worktreesBaseRoot ?? dependencies.worktreesRoot,
62
+ });
63
+ }
64
+ catch (error) {
65
+ if (error instanceof WorktreeTeardownError) {
66
+ teardownError = error;
67
+ dependencies.sessionLogger?.warn({ err: error, targetPath }, "Worktree teardown failed during archive; archiving workspace record anyway");
68
+ }
69
+ else {
70
+ throw error;
71
+ }
72
+ }
73
+ if (!teardownError && options.repoRoot) {
60
74
  try {
61
75
  await dependencies.workspaceGitService.getSnapshot(options.repoRoot, {
62
76
  force: true,
@@ -75,9 +89,14 @@ export async function archivePaseoWorktree(dependencies, options) {
75
89
  await dependencies.archiveWorkspaceRecord(workspaceId);
76
90
  }
77
91
  catch (error) {
78
- dependencies.sessionLogger?.warn({ err: error, workspaceId }, "Failed to archive workspace record; worktree FS already removed");
92
+ dependencies.sessionLogger?.warn({ err: error, workspaceId }, teardownError
93
+ ? "Failed to archive workspace record after teardown failed"
94
+ : "Failed to archive workspace record; worktree FS already removed");
79
95
  }
80
96
  }));
97
+ if (teardownError) {
98
+ throw teardownError;
99
+ }
81
100
  }
82
101
  finally {
83
102
  dependencies.clearWorkspaceArchiving(affectedWorkspaceIdList);
@@ -46,6 +46,19 @@ export declare const PersistedConfigSchema: z.ZodObject<{
46
46
  useTls?: boolean | undefined;
47
47
  publicUseTls?: boolean | undefined;
48
48
  }>>;
49
+ serviceProxy: z.ZodOptional<z.ZodObject<{
50
+ enabled: z.ZodOptional<z.ZodBoolean>;
51
+ listen: z.ZodOptional<z.ZodString>;
52
+ publicBaseUrl: z.ZodOptional<z.ZodString>;
53
+ }, "strict", z.ZodTypeAny, {
54
+ publicBaseUrl?: string | undefined;
55
+ enabled?: boolean | undefined;
56
+ listen?: string | undefined;
57
+ }, {
58
+ publicBaseUrl?: string | undefined;
59
+ enabled?: boolean | undefined;
60
+ listen?: string | undefined;
61
+ }>>;
49
62
  auth: z.ZodOptional<z.ZodObject<{
50
63
  password: z.ZodOptional<z.ZodString>;
51
64
  }, "strict", z.ZodTypeAny, {
@@ -76,6 +89,11 @@ export declare const PersistedConfigSchema: z.ZodObject<{
76
89
  useTls?: boolean | undefined;
77
90
  publicUseTls?: boolean | undefined;
78
91
  } | undefined;
92
+ serviceProxy?: {
93
+ publicBaseUrl?: string | undefined;
94
+ enabled?: boolean | undefined;
95
+ listen?: string | undefined;
96
+ } | undefined;
79
97
  }, {
80
98
  auth?: {
81
99
  password?: string | undefined;
@@ -99,6 +117,11 @@ export declare const PersistedConfigSchema: z.ZodObject<{
99
117
  useTls?: boolean | undefined;
100
118
  publicUseTls?: boolean | undefined;
101
119
  } | undefined;
120
+ serviceProxy?: {
121
+ publicBaseUrl?: string | undefined;
122
+ enabled?: boolean | undefined;
123
+ listen?: string | undefined;
124
+ } | undefined;
102
125
  }>, {
103
126
  auth?: {
104
127
  password?: string | undefined;
@@ -121,6 +144,11 @@ export declare const PersistedConfigSchema: z.ZodObject<{
121
144
  useTls?: boolean | undefined;
122
145
  publicUseTls?: boolean | undefined;
123
146
  } | undefined;
147
+ serviceProxy?: {
148
+ publicBaseUrl?: string | undefined;
149
+ enabled?: boolean | undefined;
150
+ listen?: string | undefined;
151
+ } | undefined;
124
152
  }, {
125
153
  auth?: {
126
154
  password?: string | undefined;
@@ -144,6 +172,11 @@ export declare const PersistedConfigSchema: z.ZodObject<{
144
172
  useTls?: boolean | undefined;
145
173
  publicUseTls?: boolean | undefined;
146
174
  } | undefined;
175
+ serviceProxy?: {
176
+ publicBaseUrl?: string | undefined;
177
+ enabled?: boolean | undefined;
178
+ listen?: string | undefined;
179
+ } | undefined;
147
180
  }>>;
148
181
  app: z.ZodOptional<z.ZodObject<{
149
182
  baseUrl: z.ZodOptional<z.ZodString>;
@@ -182,6 +215,13 @@ export declare const PersistedConfigSchema: z.ZodObject<{
182
215
  apiKey?: string | undefined;
183
216
  } | undefined;
184
217
  }>>;
218
+ worktrees: z.ZodOptional<z.ZodObject<{
219
+ root: z.ZodOptional<z.ZodString>;
220
+ }, "strict", z.ZodTypeAny, {
221
+ root?: string | undefined;
222
+ }, {
223
+ root?: string | undefined;
224
+ }>>;
185
225
  agents: z.ZodOptional<z.ZodObject<{
186
226
  providers: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodObject<{
187
227
  extends: z.ZodOptional<z.ZodString>;
@@ -793,7 +833,34 @@ export declare const PersistedConfigSchema: z.ZodObject<{
793
833
  format?: "json" | "pretty" | undefined;
794
834
  }>>;
795
835
  }, "strict", z.ZodTypeAny, {
796
- version?: 1 | undefined;
836
+ daemon?: {
837
+ auth?: {
838
+ password?: string | undefined;
839
+ } | undefined;
840
+ mcp?: z.objectOutputType<{
841
+ enabled: z.ZodOptional<z.ZodBoolean>;
842
+ injectIntoAgents: z.ZodOptional<z.ZodBoolean>;
843
+ }, z.ZodTypeAny, "passthrough"> | undefined;
844
+ listen?: string | undefined;
845
+ hostnames?: true | string[] | undefined;
846
+ autoArchiveAfterMerge?: boolean | undefined;
847
+ appendSystemPrompt?: string | undefined;
848
+ cors?: {
849
+ allowedOrigins?: string[] | undefined;
850
+ } | undefined;
851
+ relay?: {
852
+ enabled?: boolean | undefined;
853
+ endpoint?: string | undefined;
854
+ publicEndpoint?: string | undefined;
855
+ useTls?: boolean | undefined;
856
+ publicUseTls?: boolean | undefined;
857
+ } | undefined;
858
+ serviceProxy?: {
859
+ publicBaseUrl?: string | undefined;
860
+ enabled?: boolean | undefined;
861
+ listen?: string | undefined;
862
+ } | undefined;
863
+ } | undefined;
797
864
  features?: {
798
865
  dictation?: {
799
866
  enabled?: boolean | undefined;
@@ -827,6 +894,10 @@ export declare const PersistedConfigSchema: z.ZodObject<{
827
894
  } | undefined;
828
895
  } | undefined;
829
896
  } | undefined;
897
+ version?: 1 | undefined;
898
+ worktrees?: {
899
+ root?: string | undefined;
900
+ } | undefined;
830
901
  log?: {
831
902
  level?: "error" | "fatal" | "warn" | "info" | "debug" | "trace" | undefined;
832
903
  console?: {
@@ -897,16 +968,18 @@ export declare const PersistedConfigSchema: z.ZodObject<{
897
968
  apiKey?: string | undefined;
898
969
  } | undefined;
899
970
  } | undefined;
971
+ }, {
900
972
  daemon?: {
901
973
  auth?: {
902
974
  password?: string | undefined;
903
975
  } | undefined;
904
- mcp?: z.objectOutputType<{
976
+ mcp?: z.objectInputType<{
905
977
  enabled: z.ZodOptional<z.ZodBoolean>;
906
978
  injectIntoAgents: z.ZodOptional<z.ZodBoolean>;
907
979
  }, z.ZodTypeAny, "passthrough"> | undefined;
908
980
  listen?: string | undefined;
909
981
  hostnames?: true | string[] | undefined;
982
+ allowedHosts?: true | string[] | undefined;
910
983
  autoArchiveAfterMerge?: boolean | undefined;
911
984
  appendSystemPrompt?: string | undefined;
912
985
  cors?: {
@@ -919,9 +992,12 @@ export declare const PersistedConfigSchema: z.ZodObject<{
919
992
  useTls?: boolean | undefined;
920
993
  publicUseTls?: boolean | undefined;
921
994
  } | undefined;
995
+ serviceProxy?: {
996
+ publicBaseUrl?: string | undefined;
997
+ enabled?: boolean | undefined;
998
+ listen?: string | undefined;
999
+ } | undefined;
922
1000
  } | undefined;
923
- }, {
924
- version?: 1 | undefined;
925
1001
  features?: {
926
1002
  dictation?: {
927
1003
  enabled?: boolean | undefined;
@@ -955,6 +1031,10 @@ export declare const PersistedConfigSchema: z.ZodObject<{
955
1031
  } | undefined;
956
1032
  } | undefined;
957
1033
  } | undefined;
1034
+ version?: 1 | undefined;
1035
+ worktrees?: {
1036
+ root?: string | undefined;
1037
+ } | undefined;
958
1038
  log?: {
959
1039
  level?: "error" | "fatal" | "warn" | "info" | "debug" | "trace" | undefined;
960
1040
  console?: {
@@ -992,30 +1072,6 @@ export declare const PersistedConfigSchema: z.ZodObject<{
992
1072
  apiKey?: string | undefined;
993
1073
  } | undefined;
994
1074
  } | undefined;
995
- daemon?: {
996
- auth?: {
997
- password?: string | undefined;
998
- } | undefined;
999
- mcp?: z.objectInputType<{
1000
- enabled: z.ZodOptional<z.ZodBoolean>;
1001
- injectIntoAgents: z.ZodOptional<z.ZodBoolean>;
1002
- }, z.ZodTypeAny, "passthrough"> | undefined;
1003
- listen?: string | undefined;
1004
- hostnames?: true | string[] | undefined;
1005
- allowedHosts?: true | string[] | undefined;
1006
- autoArchiveAfterMerge?: boolean | undefined;
1007
- appendSystemPrompt?: string | undefined;
1008
- cors?: {
1009
- allowedOrigins?: string[] | undefined;
1010
- } | undefined;
1011
- relay?: {
1012
- enabled?: boolean | undefined;
1013
- endpoint?: string | undefined;
1014
- publicEndpoint?: string | undefined;
1015
- useTls?: boolean | undefined;
1016
- publicUseTls?: boolean | undefined;
1017
- } | undefined;
1018
- } | undefined;
1019
1075
  }>;
1020
1076
  type PersistedConfigSchemaOutput = z.infer<typeof PersistedConfigSchema>;
1021
1077
  export type PersistedConfig = Omit<PersistedConfigSchemaOutput, "agents"> & {
@@ -2,7 +2,7 @@ import { existsSync, readFileSync } from "node:fs";
2
2
  import path from "node:path";
3
3
  import { z } from "zod";
4
4
  import { AgentProviderRuntimeSettingsMapSchema, migrateProviderSettings, ProviderOverridesSchema, } from "./agent/provider-launch-config.js";
5
- import { ensurePrivateFile, writePrivateFileSync } from "./private-files.js";
5
+ import { ensurePrivateFile, writePrivateFileAtomicSync } from "./private-files.js";
6
6
  export const LogLevelSchema = z.enum(["trace", "debug", "info", "warn", "error", "fatal"]);
7
7
  export const LogFormatSchema = z.enum(["pretty", "json"]);
8
8
  const LogConfigSchema = z
@@ -49,6 +49,11 @@ const ProvidersSchema = z
49
49
  local: LocalSpeechProviderSchema.optional(),
50
50
  })
51
51
  .strict();
52
+ const WorktreesConfigSchema = z
53
+ .object({
54
+ root: z.string().min(1).optional(),
55
+ })
56
+ .strict();
52
57
  const BcryptHashSchema = z.string().regex(/^\$2[aby]\$\d{2}\$[./A-Za-z0-9]{53}$/, {
53
58
  message: "Expected a bcrypt hash",
54
59
  });
@@ -197,6 +202,17 @@ export const PersistedConfigSchema = z
197
202
  })
198
203
  .strict()
199
204
  .optional(),
205
+ serviceProxy: z
206
+ .object({
207
+ // COMPAT(serviceProxyEnabled): added 2026-06-02, remove after 2026-12-02.
208
+ // Parsed only to suppress optional public/listen layers for old configs;
209
+ // localhost service proxying remains always enabled.
210
+ enabled: z.boolean().optional(),
211
+ listen: z.string().optional(),
212
+ publicBaseUrl: z.string().url().optional(),
213
+ })
214
+ .strict()
215
+ .optional(),
200
216
  auth: DaemonAuthSchema.optional(),
201
217
  })
202
218
  .strict()
@@ -212,6 +228,7 @@ export const PersistedConfigSchema = z
212
228
  .strict()
213
229
  .optional(),
214
230
  providers: ProvidersSchema.optional(),
231
+ worktrees: WorktreesConfigSchema.optional(),
215
232
  agents: z
216
233
  .object({
217
234
  providers: z.preprocess(normalizeAgentProviders, ProviderOverridesSchema).optional(),
@@ -279,7 +296,7 @@ export function loadPersistedConfig(paseoHome, logger) {
279
296
  const configPath = getConfigPath(paseoHome);
280
297
  if (!existsSync(configPath)) {
281
298
  try {
282
- writePrivateFileSync(configPath, JSON.stringify(DEFAULT_PERSISTED_CONFIG, null, 2) + "\n");
299
+ writePrivateFileAtomicSync(configPath, JSON.stringify(DEFAULT_PERSISTED_CONFIG, null, 2) + "\n");
283
300
  log?.info(`Initialized config file at ${configPath}`);
284
301
  }
285
302
  catch (err) {
@@ -330,7 +347,7 @@ export function savePersistedConfig(paseoHome, config, logger) {
330
347
  throw new Error(`[Config] Invalid config to save:\n${issues}`);
331
348
  }
332
349
  try {
333
- writePrivateFileSync(configPath, JSON.stringify(result.data, null, 2) + "\n");
350
+ writePrivateFileAtomicSync(configPath, JSON.stringify(result.data, null, 2) + "\n");
334
351
  log?.info(`Saved to ${configPath}`);
335
352
  }
336
353
  catch (err) {