@getpaseo/server 0.1.97 → 0.1.98

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 (69) hide show
  1. package/dist/server/server/agent/agent-manager.d.ts +11 -3
  2. package/dist/server/server/agent/agent-manager.js +94 -22
  3. package/dist/server/server/agent/agent-prompt.d.ts +1 -1
  4. package/dist/server/server/agent/agent-prompt.js +3 -10
  5. package/dist/server/server/agent/agent-sdk-types.d.ts +9 -3
  6. package/dist/server/server/agent/create-agent/create.d.ts +2 -0
  7. package/dist/server/server/agent/create-agent/create.js +8 -7
  8. package/dist/server/server/agent/lifecycle-command.d.ts +15 -1
  9. package/dist/server/server/agent/lifecycle-command.js +9 -2
  10. package/dist/server/server/agent/mcp-server.js +254 -115
  11. package/dist/server/server/agent/provider-notices.d.ts +3 -0
  12. package/dist/server/server/agent/provider-notices.js +5 -0
  13. package/dist/server/server/agent/provider-registry.d.ts +2 -0
  14. package/dist/server/server/agent/provider-registry.js +10 -3
  15. package/dist/server/server/agent/provider-snapshot-manager.d.ts +3 -0
  16. package/dist/server/server/agent/provider-snapshot-manager.js +11 -2
  17. package/dist/server/server/agent/providers/claude/agent.js +257 -143
  18. package/dist/server/server/agent/providers/claude/models.js +7 -3
  19. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +4 -3
  20. package/dist/server/server/agent/providers/codex-app-server-agent.js +43 -1
  21. package/dist/server/server/agent/providers/copilot-acp-agent.js +4 -1
  22. package/dist/server/server/agent/providers/diagnostic-utils.d.ts +9 -0
  23. package/dist/server/server/agent/providers/diagnostic-utils.js +188 -0
  24. package/dist/server/server/agent/providers/mock-slow-provider.js +1 -1
  25. package/dist/server/server/agent/providers/opencode/server-manager.d.ts +29 -2
  26. package/dist/server/server/agent/providers/opencode/server-manager.js +83 -17
  27. package/dist/server/server/agent/providers/opencode-agent.d.ts +2 -0
  28. package/dist/server/server/agent/providers/opencode-agent.js +14 -9
  29. package/dist/server/server/agent/providers/pi/agent.js +27 -14
  30. package/dist/server/server/bootstrap.d.ts +2 -0
  31. package/dist/server/server/bootstrap.js +32 -2
  32. package/dist/server/server/managed-processes/managed-processes.d.ts +76 -0
  33. package/dist/server/server/managed-processes/managed-processes.js +326 -0
  34. package/dist/server/server/resolve-worktree-creation-intent.d.ts +3 -0
  35. package/dist/server/server/resolve-worktree-creation-intent.js +3 -3
  36. package/dist/server/server/session.d.ts +12 -1
  37. package/dist/server/server/session.js +230 -40
  38. package/dist/server/server/speech/providers/openai/runtime.js +3 -4
  39. package/dist/server/server/websocket-server.d.ts +1 -0
  40. package/dist/server/server/websocket-server.js +11 -0
  41. package/dist/server/server/workspace-archive-service.js +2 -3
  42. package/dist/server/server/workspace-directory.js +5 -5
  43. package/dist/server/server/workspace-reconciliation-service.js +2 -2
  44. package/dist/server/server/worktree-core.d.ts +1 -0
  45. package/dist/server/server/worktree-core.js +5 -1
  46. package/dist/server/services/quota-fetcher/manifest.d.ts +4 -0
  47. package/dist/server/services/quota-fetcher/manifest.js +47 -0
  48. package/dist/server/services/quota-fetcher/provider.d.ts +17 -0
  49. package/dist/server/services/quota-fetcher/provider.js +2 -0
  50. package/dist/server/services/quota-fetcher/providers/claude.d.ts +26 -0
  51. package/dist/server/services/quota-fetcher/providers/claude.js +217 -0
  52. package/dist/server/services/quota-fetcher/providers/codex.d.ts +23 -0
  53. package/dist/server/services/quota-fetcher/providers/codex.js +211 -0
  54. package/dist/server/services/quota-fetcher/providers/copilot.d.ts +17 -0
  55. package/dist/server/services/quota-fetcher/providers/copilot.js +75 -0
  56. package/dist/server/services/quota-fetcher/providers/cursor.d.ts +17 -0
  57. package/dist/server/services/quota-fetcher/providers/cursor.js +123 -0
  58. package/dist/server/services/quota-fetcher/providers/grok.d.ts +18 -0
  59. package/dist/server/services/quota-fetcher/providers/grok.js +89 -0
  60. package/dist/server/services/quota-fetcher/providers/kimi.d.ts +20 -0
  61. package/dist/server/services/quota-fetcher/providers/kimi.js +89 -0
  62. package/dist/server/services/quota-fetcher/providers/zai.d.ts +17 -0
  63. package/dist/server/services/quota-fetcher/providers/zai.js +58 -0
  64. package/dist/server/services/quota-fetcher/service.d.ts +28 -0
  65. package/dist/server/services/quota-fetcher/service.js +58 -0
  66. package/dist/server/services/quota-fetcher/usage.d.ts +22 -0
  67. package/dist/server/services/quota-fetcher/usage.js +49 -0
  68. package/dist/server/utils/directory-suggestions.js +98 -2
  69. package/package.json +5 -5
@@ -501,11 +501,103 @@ export async function createAgentMcpServer(options) {
501
501
  .describe("Draft provider feature values."),
502
502
  })
503
503
  .strict();
504
- const agentToAgentInputSchema = {
505
- cwd: z
506
- .string()
507
- .optional()
508
- .describe("Optional working directory. Defaults to your current working directory."),
504
+ const AgentRelationshipInputSchema = z.discriminatedUnion("kind", [
505
+ z
506
+ .object({ kind: z.literal("subagent") })
507
+ .strict()
508
+ .describe("Create a child agent under this agent's subagent track."),
509
+ z
510
+ .object({ kind: z.literal("detached") })
511
+ .strict()
512
+ .describe("Create a root agent that does not appear in this agent's subagent track."),
513
+ ]);
514
+ const AgentCreateWorktreeTargetInputSchema = z.discriminatedUnion("kind", [
515
+ z
516
+ .object({
517
+ kind: z.literal("branch-off"),
518
+ worktreeSlug: z
519
+ .string()
520
+ .min(1)
521
+ .optional()
522
+ .describe("Optional worktree slug/path label. Omit to let Paseo generate one."),
523
+ branchName: z
524
+ .string()
525
+ .min(1)
526
+ .optional()
527
+ .describe("Optional git branch name. Defaults to the worktree slug."),
528
+ baseBranch: z
529
+ .string()
530
+ .min(1)
531
+ .optional()
532
+ .describe("Optional base branch. Defaults to the repository default branch."),
533
+ })
534
+ .strict()
535
+ .describe("Create a new branch in a new Paseo worktree."),
536
+ z
537
+ .object({
538
+ kind: z.literal("checkout-branch"),
539
+ branch: z.string().min(1).describe("Existing branch to check out."),
540
+ })
541
+ .strict()
542
+ .describe("Check out an existing branch in a new Paseo worktree."),
543
+ z
544
+ .object({
545
+ kind: z.literal("checkout-pr"),
546
+ githubPrNumber: z.number().int().positive().describe("GitHub pull request number."),
547
+ })
548
+ .strict()
549
+ .describe("Check out a GitHub pull request in a new Paseo worktree."),
550
+ ]);
551
+ const AgentWorkspaceInputSchema = z.discriminatedUnion("kind", [
552
+ z
553
+ .object({
554
+ kind: z.literal("current"),
555
+ cwd: z.string().optional().describe("Optional runtime cwd. Defaults to the caller's cwd."),
556
+ })
557
+ .strict()
558
+ .describe("Use the caller's current workspace."),
559
+ z
560
+ .object({
561
+ kind: z.literal("existing"),
562
+ workspaceId: z.string().min(1).describe("Existing workspace id to attach the agent to."),
563
+ cwd: z
564
+ .string()
565
+ .optional()
566
+ .describe("Optional runtime cwd. Defaults to the existing workspace cwd."),
567
+ })
568
+ .strict()
569
+ .describe("Attach the agent to an existing workspace."),
570
+ z
571
+ .object({
572
+ kind: z.literal("create"),
573
+ source: z.discriminatedUnion("kind", [
574
+ z
575
+ .object({
576
+ kind: z.literal("directory"),
577
+ path: z
578
+ .string()
579
+ .optional()
580
+ .describe("Optional directory path. Defaults to the caller's cwd."),
581
+ })
582
+ .strict(),
583
+ z
584
+ .object({
585
+ kind: z.literal("worktree"),
586
+ cwd: z
587
+ .string()
588
+ .optional()
589
+ .describe("Optional source repository. Defaults to the caller's cwd."),
590
+ target: AgentCreateWorktreeTargetInputSchema,
591
+ })
592
+ .strict(),
593
+ ]),
594
+ })
595
+ .strict()
596
+ .describe("Create a new workspace for the agent."),
597
+ ]);
598
+ const commonCreateAgentInputSchema = {
599
+ relationship: AgentRelationshipInputSchema.describe("Whether the created agent is a subagent under you or a detached root agent."),
600
+ workspace: AgentWorkspaceInputSchema.describe("Workspace ownership/location for the created agent."),
509
601
  title: z
510
602
  .string()
511
603
  .trim()
@@ -520,11 +612,9 @@ export async function createAgentMcpServer(options) {
520
612
  .trim()
521
613
  .min(1, "initialPrompt is required")
522
614
  .describe("Required first task to run immediately after creation."),
523
- detached: z
524
- .boolean()
525
- .optional()
526
- .default(false)
527
- .describe("If true, the created agent stands on its own: it does not appear in your subagent track and is not archived with you."),
615
+ };
616
+ const agentToAgentInputSchema = {
617
+ ...commonCreateAgentInputSchema,
528
618
  notifyOnFinish: z
529
619
  .boolean()
530
620
  .optional()
@@ -532,42 +622,7 @@ export async function createAgentMcpServer(options) {
532
622
  .describe("Get notified when the created agent finishes, errors, or needs permission. Set false only for truly fire-and-forget agents."),
533
623
  };
534
624
  const topLevelInputSchema = {
535
- cwd: z
536
- .string()
537
- .describe("Required working directory for the agent (absolute, relative, or ~)."),
538
- title: z
539
- .string()
540
- .trim()
541
- .min(1, "Title is required")
542
- .max(60, "Title must be 60 characters or fewer")
543
- .describe("Short descriptive title (<= 60 chars) summarizing the agent's focus."),
544
- provider: ProviderModelInputSchema.describe("Required provider/model pair, for example codex/gpt-5.4."),
545
- labels: z.record(z.string(), z.string()).optional().describe("Labels to set on the agent"),
546
- settings: CreateAgentSettingsInputSchema.optional().describe("Initial runtime settings for the new agent."),
547
- initialPrompt: z
548
- .string()
549
- .trim()
550
- .min(1, "initialPrompt is required")
551
- .describe("Required first task to run immediately after creation."),
552
- worktreeName: z
553
- .string()
554
- .optional()
555
- .describe("Optional git worktree branch name (lowercase alphanumerics + hyphen)."),
556
- baseBranch: z
557
- .string()
558
- .optional()
559
- .describe("Required when worktreeName is set: the base branch to diff/merge against."),
560
- refName: z.string().min(1).optional().describe("Optional source ref for worktree creation."),
561
- action: z
562
- .enum(["branch-off", "checkout"])
563
- .optional()
564
- .describe("Optional worktree creation action."),
565
- githubPrNumber: z
566
- .number()
567
- .int()
568
- .positive()
569
- .optional()
570
- .describe("Optional GitHub pull request number to checkout."),
625
+ ...commonCreateAgentInputSchema,
571
626
  background: z
572
627
  .boolean()
573
628
  .optional()
@@ -582,6 +637,40 @@ export async function createAgentMcpServer(options) {
582
637
  const createAgentInputSchema = callerAgentId ? agentToAgentInputSchema : topLevelInputSchema;
583
638
  const agentToAgentCreateAgentArgsSchema = z.object(agentToAgentInputSchema).strict();
584
639
  const topLevelCreateAgentArgsSchema = z.object(topLevelInputSchema).strict();
640
+ const commonSendAgentPromptInputSchema = {
641
+ agentId: z.string(),
642
+ prompt: z.string(),
643
+ sessionMode: z.string().optional().describe("Optional mode to set before running the prompt."),
644
+ };
645
+ const agentToAgentSendAgentPromptInputSchema = {
646
+ ...commonSendAgentPromptInputSchema,
647
+ background: z
648
+ .boolean()
649
+ .optional()
650
+ .default(true)
651
+ .describe("Run agent in background. Agent-scoped default is true so you can continue until the finish notification arrives. Set false only when you need a blocking response."),
652
+ notifyOnFinish: z
653
+ .boolean()
654
+ .optional()
655
+ .default(true)
656
+ .describe("Get notified when the prompted agent finishes, errors, or needs permission. Set false only for truly fire-and-forget prompts."),
657
+ };
658
+ const topLevelSendAgentPromptInputSchema = {
659
+ ...commonSendAgentPromptInputSchema,
660
+ background: z
661
+ .boolean()
662
+ .optional()
663
+ .default(false)
664
+ .describe("Run agent in background. If false (default), waits for completion or permission request. If true, returns immediately."),
665
+ notifyOnFinish: z
666
+ .boolean()
667
+ .optional()
668
+ .default(false)
669
+ .describe("Agent-scoped only: get notified when the prompted agent finishes, errors, or needs permission."),
670
+ };
671
+ const sendAgentPromptInputSchema = callerAgentId
672
+ ? agentToAgentSendAgentPromptInputSchema
673
+ : topLevelSendAgentPromptInputSchema;
585
674
  const inspectProviderInputSchema = {
586
675
  provider: ProviderOrProviderModelInputSchema.describe("Provider ID, optionally with a model ID (for example codex or codex/gpt-5.4)."),
587
676
  cwd: z
@@ -628,13 +717,14 @@ export async function createAgentMcpServer(options) {
628
717
  }
629
718
  registerTool("create_agent", {
630
719
  title: "Create agent",
631
- description: "Create an agent tied to a working directory. Requires provider/model, for example codex/gpt-5.4. Do not guess; call list_providers and list_models first if uncertain. Optionally run an initial prompt immediately or create a git worktree for the agent.",
720
+ description: "Create an agent. Requires relationship, workspace, provider/model (for example codex/gpt-5.4), and an initial prompt. Do not guess; call list_providers and list_models first if uncertain.",
632
721
  inputSchema: createAgentInputSchema,
633
722
  outputSchema: {
634
723
  agentId: z.string(),
635
724
  type: AgentProviderEnum,
636
725
  status: AgentStatusEnum,
637
726
  cwd: z.string(),
727
+ workspaceId: z.string().optional(),
638
728
  currentModeId: z.string().nullable(),
639
729
  availableModes: z.array(ProviderModeSchema),
640
730
  lastMessage: z.string().nullable().optional(),
@@ -642,20 +732,20 @@ export async function createAgentMcpServer(options) {
642
732
  guidance: z.string().optional(),
643
733
  },
644
734
  }, async (args) => {
645
- const resolvedArgs = resolveCreateAgentToolArgs(args);
735
+ const resolvedArgs = await resolveCreateAgentToolArgs(args);
646
736
  const { parsedArgs, worktree } = resolvedArgs;
647
737
  let requestedBackground;
648
738
  let notifyOnFinish;
649
739
  let detached;
650
740
  if (resolvedArgs.kind === "agent-scoped") {
651
741
  requestedBackground = true;
652
- notifyOnFinish = resolvedArgs.parsedArgs.notifyOnFinish;
653
- detached = resolvedArgs.parsedArgs.detached;
742
+ notifyOnFinish = parsedArgs.notifyOnFinish;
743
+ detached = resolvedArgs.relationship.kind === "detached";
654
744
  }
655
745
  else {
656
746
  requestedBackground = resolvedArgs.parsedArgs.background;
657
747
  notifyOnFinish = resolvedArgs.parsedArgs.notifyOnFinish ?? false;
658
- detached = false;
748
+ detached = resolvedArgs.parsedArgs.relationship.kind === "detached";
659
749
  }
660
750
  const { snapshot, background: createdInBackground, initialPromptStarted, } = await createAgentCommand({
661
751
  agentManager,
@@ -674,7 +764,8 @@ export async function createAgentMcpServer(options) {
674
764
  provider: parsedArgs.provider,
675
765
  title: parsedArgs.title,
676
766
  initialPrompt: parsedArgs.initialPrompt,
677
- cwd: parsedArgs.cwd,
767
+ cwd: resolvedArgs.cwd,
768
+ workspaceId: resolvedArgs.workspaceId,
678
769
  thinking: parsedArgs.settings?.thinkingOptionId,
679
770
  features: parsedArgs.settings?.features,
680
771
  labels: parsedArgs.labels,
@@ -697,6 +788,7 @@ export async function createAgentMcpServer(options) {
697
788
  type: snapshot.provider,
698
789
  status: result.status,
699
790
  cwd: liveSnapshot.cwd,
791
+ ...(liveSnapshot.workspaceId ? { workspaceId: liveSnapshot.workspaceId } : {}),
700
792
  currentModeId: liveSnapshot.currentModeId,
701
793
  availableModes: liveSnapshot.availableModes,
702
794
  lastMessage: result.lastMessage,
@@ -726,6 +818,7 @@ export async function createAgentMcpServer(options) {
726
818
  type: snapshot.provider,
727
819
  status: currentSnapshot.lifecycle,
728
820
  cwd: currentSnapshot.cwd,
821
+ ...(currentSnapshot.workspaceId ? { workspaceId: currentSnapshot.workspaceId } : {}),
729
822
  currentModeId: currentSnapshot.currentModeId,
730
823
  availableModes: currentSnapshot.availableModes,
731
824
  lastMessage: null,
@@ -735,30 +828,109 @@ export async function createAgentMcpServer(options) {
735
828
  };
736
829
  return response;
737
830
  });
738
- function resolveCreateAgentToolArgs(args) {
831
+ async function resolveCreateAgentToolArgs(args) {
739
832
  if (callerAgentId) {
833
+ const parsed = agentToAgentCreateAgentArgsSchema.parse(args);
834
+ const { cwd, workspaceId, worktree } = await resolveCreateAgentWorkspace(parsed.workspace);
740
835
  return {
741
836
  kind: "agent-scoped",
742
- parsedArgs: agentToAgentCreateAgentArgsSchema.parse(args),
743
- worktree: undefined,
837
+ parsedArgs: parsed,
838
+ relationship: parsed.relationship,
839
+ cwd,
840
+ workspaceId,
841
+ worktree,
744
842
  };
745
843
  }
746
844
  const parsedArgs = topLevelCreateAgentArgsSchema.parse(args);
845
+ if (parsedArgs.relationship.kind === "subagent") {
846
+ throw new Error("relationship subagent requires an agent-scoped MCP session");
847
+ }
848
+ const { cwd, workspaceId, worktree } = await resolveCreateAgentWorkspace(parsedArgs.workspace);
747
849
  return {
748
850
  kind: "top-level",
749
851
  parsedArgs,
750
- worktree: resolveTopLevelCreateAgentWorktree(parsedArgs),
852
+ cwd,
853
+ workspaceId,
854
+ worktree,
751
855
  };
752
856
  }
753
- function resolveTopLevelCreateAgentWorktree(args) {
857
+ async function resolveCreateAgentWorkspace(workspace) {
858
+ if (workspace.kind === "current") {
859
+ if (!callerAgentId) {
860
+ throw new Error("workspace current requires an agent-scoped MCP session");
861
+ }
862
+ const callerAgent = resolveCallerAgent();
863
+ if (!callerAgent?.workspaceId) {
864
+ throw new Error(`Caller agent ${callerAgentId} has no current workspace`);
865
+ }
866
+ return {
867
+ cwd: workspace.cwd,
868
+ workspaceId: callerAgent.workspaceId,
869
+ worktree: undefined,
870
+ };
871
+ }
872
+ if (workspace.kind === "existing") {
873
+ if (!options.listActiveWorkspaces) {
874
+ throw new Error("Workspace lookup is not configured");
875
+ }
876
+ const existingWorkspace = (await options.listActiveWorkspaces()).find((candidate) => candidate.workspaceId === workspace.workspaceId);
877
+ if (!existingWorkspace) {
878
+ throw new Error(`Workspace ${workspace.workspaceId} not found`);
879
+ }
880
+ const cwd = workspace.cwd
881
+ ? resolveScopedCwd(workspace.cwd, { required: true })
882
+ : existingWorkspace.cwd;
883
+ const lockedCwd = callerContext?.lockedCwd?.trim();
884
+ if (lockedCwd && !isSameOrDescendantPath(expandUserPath(lockedCwd), cwd)) {
885
+ throw new Error(`Workspace ${workspace.workspaceId} is outside the allowed cwd`);
886
+ }
887
+ return {
888
+ cwd,
889
+ workspaceId: workspace.workspaceId,
890
+ worktree: undefined,
891
+ };
892
+ }
893
+ if (workspace.source.kind === "directory") {
894
+ const cwd = resolveScopedCwd(workspace.source.path, { required: true });
895
+ if (!options.ensureWorkspaceForCreate) {
896
+ throw new Error("Workspace creation is not configured");
897
+ }
898
+ return {
899
+ cwd,
900
+ workspaceId: await options.ensureWorkspaceForCreate(cwd),
901
+ worktree: undefined,
902
+ };
903
+ }
904
+ const cwd = resolveScopedCwd(workspace.source.cwd, { required: true });
754
905
  return {
755
- worktreeName: args.worktreeName,
756
- baseBranch: args.baseBranch,
757
- refName: args.refName,
758
- action: args.action,
759
- githubPrNumber: args.githubPrNumber,
906
+ cwd,
907
+ workspaceId: undefined,
908
+ worktree: resolveCreateAgentWorktree(workspace.source.target),
760
909
  };
761
910
  }
911
+ function resolveCreateAgentWorktree(target) {
912
+ switch (target.kind) {
913
+ case "branch-off":
914
+ return {
915
+ action: "branch-off",
916
+ worktreeName: target.worktreeSlug,
917
+ branchName: target.branchName,
918
+ baseBranch: target.baseBranch,
919
+ };
920
+ case "checkout-branch":
921
+ return {
922
+ action: "checkout",
923
+ refName: target.branch,
924
+ };
925
+ case "checkout-pr":
926
+ return {
927
+ action: "checkout",
928
+ githubPrNumber: target.githubPrNumber,
929
+ };
930
+ default:
931
+ throw new Error("unreachable");
932
+ }
933
+ }
762
934
  registerTool("wait_for_agent", {
763
935
  title: "Wait for agent",
764
936
  description: "Block until the agent requests permission or the current run completes. Returns the pending permission (if any) and recent activity summary.",
@@ -828,35 +1000,20 @@ export async function createAgentMcpServer(options) {
828
1000
  });
829
1001
  registerTool("send_agent_prompt", {
830
1002
  title: "Send agent prompt",
831
- description: "Send a task to a running agent. Returns immediately after the agent begins processing.",
832
- inputSchema: {
833
- agentId: z.string(),
834
- prompt: z.string(),
835
- sessionMode: z
836
- .string()
837
- .optional()
838
- .describe("Optional mode to set before running the prompt."),
839
- background: z
840
- .boolean()
841
- .optional()
842
- .default(false)
843
- .describe("Run agent in background. If false (default), waits for completion or permission request. If true, returns immediately."),
844
- notifyOnFinish: z
845
- .boolean()
846
- .optional()
847
- .default(false)
848
- .describe("Agent-scoped only: get notified when this run finishes, errors, or needs permission."),
849
- },
1003
+ description: "Send a task to a running agent. Agent-scoped callers run in background by default; top-level callers wait by default.",
1004
+ inputSchema: sendAgentPromptInputSchema,
850
1005
  outputSchema: {
851
1006
  success: z.boolean(),
852
1007
  status: AgentStatusEnum,
853
1008
  lastMessage: z.string().nullable().optional(),
854
1009
  permission: AgentPermissionRequestPayloadSchema.nullable().optional(),
1010
+ guidance: z.string().optional(),
855
1011
  },
856
- }, async ({ agentId, prompt, sessionMode, background = false, notifyOnFinish = false }) => {
1012
+ }, async ({ agentId, prompt, sessionMode, background = Boolean(callerAgentId), notifyOnFinish = Boolean(callerAgentId), }) => {
857
1013
  if (agentManager.hasInFlightRun(agentId)) {
858
1014
  waitTracker.cancel(agentId, "Agent run interrupted by new prompt");
859
1015
  }
1016
+ const shouldNotifyOnFinish = Boolean(callerAgentId && notifyOnFinish && background);
860
1017
  await sendPromptToAgent({
861
1018
  agentManager,
862
1019
  agentStorage,
@@ -865,7 +1022,7 @@ export async function createAgentMcpServer(options) {
865
1022
  sessionMode,
866
1023
  logger: childLogger,
867
1024
  });
868
- if (notifyOnFinish && callerAgentId) {
1025
+ if (shouldNotifyOnFinish && callerAgentId) {
869
1026
  setupFinishNotification({
870
1027
  agentManager,
871
1028
  agentStorage,
@@ -900,6 +1057,11 @@ export async function createAgentMcpServer(options) {
900
1057
  status: currentSnapshot?.lifecycle ?? "idle",
901
1058
  lastMessage: null,
902
1059
  permission: null,
1060
+ ...(shouldNotifyOnFinish
1061
+ ? {
1062
+ guidance: "You will get notified when the prompted agent finishes, errors, or needs permission. Do not call wait_for_agent or poll for status; continue with other work until the notification arrives.",
1063
+ }
1064
+ : {}),
903
1065
  };
904
1066
  const validJson = ensureValidJson(responseData);
905
1067
  const response = {
@@ -1607,37 +1769,12 @@ export async function createAgentMcpServer(options) {
1607
1769
  description: "Create a Paseo-managed git worktree. Branch off a new branch, check out an existing branch, or check out a GitHub PR.",
1608
1770
  inputSchema: {
1609
1771
  cwd: z.string().optional().describe("Repository directory. Defaults to the agent's cwd."),
1610
- target: z
1611
- .discriminatedUnion("mode", [
1612
- z
1613
- .object({
1614
- mode: z.literal("branch-off"),
1615
- newBranch: z.string().min(1).describe("Name for the new branch."),
1616
- base: z
1617
- .string()
1618
- .min(1)
1619
- .optional()
1620
- .describe("Base ref. Defaults to the repo's default branch."),
1621
- })
1622
- .describe("Create a new branch off a base."),
1623
- z
1624
- .object({
1625
- mode: z.literal("checkout-branch"),
1626
- branch: z.string().min(1).describe("Existing branch to check out."),
1627
- })
1628
- .describe("Check out an existing branch."),
1629
- z
1630
- .object({
1631
- mode: z.literal("checkout-pr"),
1632
- prNumber: z.number().int().positive().describe("Pull request number."),
1633
- })
1634
- .describe("Check out a GitHub pull request."),
1635
- ])
1636
- .describe("What the worktree should contain."),
1772
+ target: AgentCreateWorktreeTargetInputSchema.describe("What the worktree should contain."),
1637
1773
  },
1638
1774
  outputSchema: {
1639
1775
  branchName: z.string(),
1640
1776
  worktreePath: z.string(),
1777
+ workspaceId: z.string(),
1641
1778
  },
1642
1779
  }, async ({ cwd, target }) => {
1643
1780
  const repoRoot = resolveScopedCwd(cwd, { required: true });
@@ -1649,7 +1786,7 @@ export async function createAgentMcpServer(options) {
1649
1786
  if (!commandResult.ok) {
1650
1787
  throw new WorktreeRequestError(commandResult.error);
1651
1788
  }
1652
- const { worktree } = commandResult.createdWorktree;
1789
+ const { worktree, workspace } = commandResult.createdWorktree;
1653
1790
  await options.workspaceGitService?.listWorktrees?.(repoRoot, {
1654
1791
  force: true,
1655
1792
  reason: "mcp:create-worktree",
@@ -1659,6 +1796,7 @@ export async function createAgentMcpServer(options) {
1659
1796
  structuredContent: ensureValidJson({
1660
1797
  branchName: worktree.branchName,
1661
1798
  worktreePath: worktree.worktreePath,
1799
+ workspaceId: workspace.workspaceId,
1662
1800
  }),
1663
1801
  };
1664
1802
  });
@@ -1873,18 +2011,19 @@ function archiveWorktreeDependencies(options, context) {
1873
2011
  }
1874
2012
  function createMcpWorktreeCommandInput(repoRoot, target) {
1875
2013
  const base = { cwd: repoRoot };
1876
- switch (target.mode) {
2014
+ switch (target.kind) {
1877
2015
  case "branch-off":
1878
2016
  return {
1879
2017
  ...base,
1880
- worktreeSlug: target.newBranch,
2018
+ worktreeSlug: target.worktreeSlug,
2019
+ branchName: target.branchName,
1881
2020
  action: "branch-off",
1882
- ...(target.base ? { refName: target.base } : {}),
2021
+ ...(target.baseBranch ? { refName: target.baseBranch } : {}),
1883
2022
  };
1884
2023
  case "checkout-branch":
1885
2024
  return { ...base, action: "checkout", refName: target.branch };
1886
2025
  case "checkout-pr":
1887
- return { ...base, action: "checkout", githubPrNumber: target.prNumber };
2026
+ return { ...base, action: "checkout", githubPrNumber: target.githubPrNumber };
1888
2027
  default:
1889
2028
  throw new Error("unreachable");
1890
2029
  }
@@ -0,0 +1,3 @@
1
+ import type { AgentProviderNotice } from "./agent-sdk-types.js";
2
+ export declare const SETTING_APPLIES_NEXT_TURN_NOTICE: AgentProviderNotice;
3
+ //# sourceMappingURL=provider-notices.d.ts.map
@@ -0,0 +1,5 @@
1
+ export const SETTING_APPLIES_NEXT_TURN_NOTICE = {
2
+ type: "info",
3
+ message: "This change applies next turn.",
4
+ };
5
+ //# sourceMappingURL=provider-notices.js.map
@@ -1,6 +1,7 @@
1
1
  import type { Logger } from "pino";
2
2
  import type { AgentClient, AgentCreateConfigUnattendedInput, AgentMode, AgentModelDefinition, AgentProvider, AgentSession, ListModelsOptions, ListModesOptions, ResolveAgentCreateConfigInput, ResolveAgentCreateConfigResult } from "./agent-sdk-types.js";
3
3
  import type { WorkspaceGitService } from "../workspace-git-service.js";
4
+ import type { ManagedProcessRegistry } from "../managed-processes/managed-processes.js";
4
5
  import type { AgentProviderRuntimeSettingsMap, ProviderOverride } from "./provider-launch-config.js";
5
6
  import { AGENT_PROVIDER_DEFINITIONS, getAgentProviderDefinition, type AgentProviderDefinition } from "@getpaseo/protocol/provider-manifest";
6
7
  export type { AgentProviderDefinition };
@@ -23,6 +24,7 @@ export interface BuildProviderRegistryOptions {
23
24
  runtimeSettings?: AgentProviderRuntimeSettingsMap;
24
25
  providerOverrides?: Record<string, ProviderOverride>;
25
26
  workspaceGitService?: Pick<WorkspaceGitService, "resolveRepoRoot">;
27
+ managedProcesses?: ManagedProcessRegistry;
26
28
  isDev?: boolean;
27
29
  }
28
30
  export declare function wrapSessionProvider(provider: AgentProvider, inner: AgentSession): AgentSession;
@@ -32,7 +32,9 @@ const PROVIDER_CLIENT_FACTORIES = {
32
32
  command: getCursorACPCommand(runtimeSettings),
33
33
  env: runtimeSettings?.env,
34
34
  }),
35
- opencode: (logger, runtimeSettings) => new OpenCodeAgentClient(logger, runtimeSettings),
35
+ opencode: (logger, runtimeSettings, options) => new OpenCodeAgentClient(logger, runtimeSettings, {
36
+ managedProcesses: options?.managedProcesses,
37
+ }),
36
38
  pi: (logger, runtimeSettings, options) => new PiRpcAgentClient({
37
39
  logger,
38
40
  runtimeSettings,
@@ -329,13 +331,14 @@ function buildResolvedBuiltinProviders(providerOverrides, runtimeSettings, optio
329
331
  providerParams: override?.params,
330
332
  createBaseClient: (logger) => factory(logger, mergedRuntimeSettings, {
331
333
  workspaceGitService: options.workspaceGitService,
334
+ managedProcesses: options.managedProcesses,
332
335
  providerParams: override?.params,
333
336
  }),
334
337
  });
335
338
  }
336
339
  return resolvedProviders;
337
340
  }
338
- function addDerivedProviders(resolvedProviders, providerOverrides) {
341
+ function addDerivedProviders(resolvedProviders, providerOverrides, options) {
339
342
  for (const [providerId, override] of Object.entries(providerOverrides)) {
340
343
  if (resolvedProviders.has(providerId) || BUILTIN_PROVIDER_IDS.includes(providerId)) {
341
344
  continue;
@@ -403,6 +406,7 @@ function addDerivedProviders(resolvedProviders, providerOverrides) {
403
406
  derivedFromProviderId: baseProviderId,
404
407
  providerParams,
405
408
  createBaseClient: (logger) => baseFactory(logger, mergedRuntimeSettings, {
409
+ managedProcesses: options.managedProcesses,
406
410
  providerParams,
407
411
  customProvider: {
408
412
  id: providerId,
@@ -418,8 +422,11 @@ export function buildProviderRegistry(logger, options) {
418
422
  const providerOverrides = options?.providerOverrides ?? {};
419
423
  const resolvedProviders = buildResolvedBuiltinProviders(providerOverrides, runtimeSettings, {
420
424
  workspaceGitService: options?.workspaceGitService,
425
+ managedProcesses: options?.managedProcesses,
421
426
  }, options?.isDev === true);
422
- addDerivedProviders(resolvedProviders, providerOverrides);
427
+ addDerivedProviders(resolvedProviders, providerOverrides, {
428
+ managedProcesses: options?.managedProcesses,
429
+ });
423
430
  return Object.fromEntries([...resolvedProviders.entries()].map(([provider, resolved]) => [
424
431
  provider,
425
432
  createRegistryEntry(logger, provider, resolved),
@@ -2,6 +2,7 @@ import type { Logger } from "pino";
2
2
  import type { AgentClient, AgentMode, AgentModelDefinition, AgentProvider, ProviderSnapshotEntry } from "./agent-sdk-types.js";
3
3
  import type { ManagedAgent } from "./agent-manager.js";
4
4
  import type { WorkspaceGitService } from "../workspace-git-service.js";
5
+ import type { ManagedProcessRegistry } from "../managed-processes/managed-processes.js";
5
6
  import type { AgentProviderRuntimeSettingsMap, ProviderOverride } from "./provider-launch-config.js";
6
7
  import type { MutableDaemonConfig } from "../daemon-config-store.js";
7
8
  type ProviderSnapshotChangeListener = (entries: ProviderSnapshotEntry[], cwd: string) => void;
@@ -10,6 +11,7 @@ export interface ProviderSnapshotManagerOptions {
10
11
  runtimeSettings?: AgentProviderRuntimeSettingsMap;
11
12
  providerOverrides?: Record<string, ProviderOverride>;
12
13
  workspaceGitService?: Pick<WorkspaceGitService, "resolveRepoRoot">;
14
+ managedProcesses?: ManagedProcessRegistry;
13
15
  isDev?: boolean;
14
16
  extraClients?: Partial<Record<AgentProvider, AgentClient>>;
15
17
  refreshTimeoutMs?: number;
@@ -64,6 +66,7 @@ export declare class ProviderSnapshotManager {
64
66
  private readonly refreshTimeoutMs;
65
67
  private readonly logger;
66
68
  private readonly workspaceGitService?;
69
+ private readonly managedProcesses?;
67
70
  private readonly isDev;
68
71
  private readonly extraClients;
69
72
  private runtimeSettings;
@@ -32,6 +32,7 @@ export class ProviderSnapshotManager {
32
32
  this.destroyed = false;
33
33
  this.logger = options.logger;
34
34
  this.workspaceGitService = options.workspaceGitService;
35
+ this.managedProcesses = options.managedProcesses;
35
36
  this.isDev = options.isDev === true;
36
37
  this.extraClients = options.extraClients ?? {};
37
38
  this.runtimeSettings = options.runtimeSettings;
@@ -225,6 +226,7 @@ export class ProviderSnapshotManager {
225
226
  runtimeSettings: this.runtimeSettings,
226
227
  providerOverrides: this.providerOverrides,
227
228
  workspaceGitService: this.workspaceGitService,
229
+ managedProcesses: this.managedProcesses,
228
230
  isDev: this.isDev,
229
231
  });
230
232
  for (const [provider, client] of Object.entries(this.extraClients)) {
@@ -549,8 +551,15 @@ export function resolveSnapshotCwd(cwd) {
549
551
  if (!trimmed) {
550
552
  return homedir();
551
553
  }
552
- const expanded = trimmed === "~" || trimmed.startsWith("~/") ? `${homedir()}${trimmed.slice(1)}` : trimmed;
553
- return resolve(expanded);
554
+ let expanded = trimmed === "~" || trimmed.startsWith("~/") ? `${homedir()}${trimmed.slice(1)}` : trimmed;
555
+ if (process.platform === "win32" && /^[A-Za-z]:$/.test(expanded)) {
556
+ expanded = `${expanded}\\`;
557
+ }
558
+ let resolved = resolve(expanded);
559
+ if (process.platform === "win32" && /^[A-Za-z]:$/.test(resolved)) {
560
+ resolved = `${resolved}\\`;
561
+ }
562
+ return resolved;
554
563
  }
555
564
  function entriesToArray(entries) {
556
565
  return Array.from(entries.values(), cloneEntry);