@getpaseo/server 0.1.97-beta.3 → 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.
- package/dist/server/server/agent/agent-manager.d.ts +11 -3
- package/dist/server/server/agent/agent-manager.js +95 -23
- package/dist/server/server/agent/agent-prompt.d.ts +1 -1
- package/dist/server/server/agent/agent-prompt.js +3 -10
- package/dist/server/server/agent/agent-response-loop.js +9 -3
- package/dist/server/server/agent/agent-sdk-types.d.ts +9 -3
- package/dist/server/server/agent/agent-storage.d.ts +20 -240
- package/dist/server/server/agent/agent-storage.js +6 -6
- package/dist/server/server/agent/create-agent/create.d.ts +2 -0
- package/dist/server/server/agent/create-agent/create.js +8 -7
- package/dist/server/server/agent/lifecycle-command.d.ts +15 -1
- package/dist/server/server/agent/lifecycle-command.js +9 -2
- package/dist/server/server/agent/mcp-server.js +263 -119
- package/dist/server/server/agent/mcp-shared.d.ts +35 -179
- package/dist/server/server/agent/provider-notices.d.ts +3 -0
- package/dist/server/server/agent/provider-notices.js +5 -0
- package/dist/server/server/agent/provider-registry.d.ts +2 -0
- package/dist/server/server/agent/provider-registry.js +10 -3
- package/dist/server/server/agent/provider-snapshot-manager.d.ts +3 -0
- package/dist/server/server/agent/provider-snapshot-manager.js +11 -2
- package/dist/server/server/agent/providers/claude/agent.js +257 -143
- package/dist/server/server/agent/providers/claude/models.js +7 -3
- package/dist/server/server/agent/providers/claude/project-dir.js +9 -6
- package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts +2 -22
- package/dist/server/server/agent/providers/codex/app-server-transport.d.ts +8 -118
- package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +4 -3
- package/dist/server/server/agent/providers/codex-app-server-agent.js +43 -1
- package/dist/server/server/agent/providers/copilot-acp-agent.js +4 -1
- package/dist/server/server/agent/providers/diagnostic-utils.d.ts +9 -0
- package/dist/server/server/agent/providers/diagnostic-utils.js +188 -0
- package/dist/server/server/agent/providers/generic-acp-agent.d.ts +1 -5
- package/dist/server/server/agent/providers/mock-slow-provider.js +1 -1
- package/dist/server/server/agent/providers/opencode/server-manager.d.ts +29 -2
- package/dist/server/server/agent/providers/opencode/server-manager.js +83 -17
- package/dist/server/server/agent/providers/opencode-agent.d.ts +2 -0
- package/dist/server/server/agent/providers/opencode-agent.js +14 -9
- package/dist/server/server/agent/providers/pi/agent.d.ts +1 -5
- package/dist/server/server/agent/providers/pi/agent.js +27 -14
- package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts +391 -1261
- package/dist/server/server/agent/providers/tool-call-detail-primitives.js +26 -16
- package/dist/server/server/bootstrap.d.ts +2 -0
- package/dist/server/server/bootstrap.js +32 -2
- package/dist/server/server/loop-service.d.ts +60 -359
- package/dist/server/server/managed-processes/managed-processes.d.ts +76 -0
- package/dist/server/server/managed-processes/managed-processes.js +326 -0
- package/dist/server/server/migrations/backfill-workspace-id.migration.js +10 -6
- package/dist/server/server/package-version.d.ts +1 -7
- package/dist/server/server/paseo-worktree-service.js +15 -1
- package/dist/server/server/persisted-config.d.ts +138 -1009
- package/dist/server/server/persisted-config.js +1 -1
- package/dist/server/server/pid-lock.d.ts +1 -15
- package/dist/server/server/resolve-worktree-creation-intent.d.ts +3 -0
- package/dist/server/server/resolve-worktree-creation-intent.js +3 -3
- package/dist/server/server/session.d.ts +18 -1
- package/dist/server/server/session.js +424 -64
- package/dist/server/server/speech/providers/local/sherpa/model-catalog.d.ts +2 -2
- package/dist/server/server/speech/providers/openai/runtime.js +3 -4
- package/dist/server/server/speech/speech-types.d.ts +9 -11
- package/dist/server/server/websocket-server.d.ts +1 -0
- package/dist/server/server/websocket-server.js +15 -0
- package/dist/server/server/workspace-archive-service.js +2 -3
- package/dist/server/server/workspace-directory.js +5 -5
- package/dist/server/server/workspace-reconciliation-service.js +2 -2
- package/dist/server/server/workspace-registry.d.ts +17 -48
- package/dist/server/server/workspace-registry.js +9 -0
- package/dist/server/server/worktree-core.d.ts +1 -0
- package/dist/server/server/worktree-core.js +5 -1
- package/dist/server/services/quota-fetcher/manifest.d.ts +4 -0
- package/dist/server/services/quota-fetcher/manifest.js +47 -0
- package/dist/server/services/quota-fetcher/provider.d.ts +17 -0
- package/dist/server/services/quota-fetcher/provider.js +2 -0
- package/dist/server/services/quota-fetcher/providers/claude.d.ts +26 -0
- package/dist/server/services/quota-fetcher/providers/claude.js +217 -0
- package/dist/server/services/quota-fetcher/providers/codex.d.ts +23 -0
- package/dist/server/services/quota-fetcher/providers/codex.js +211 -0
- package/dist/server/services/quota-fetcher/providers/copilot.d.ts +17 -0
- package/dist/server/services/quota-fetcher/providers/copilot.js +75 -0
- package/dist/server/services/quota-fetcher/providers/cursor.d.ts +17 -0
- package/dist/server/services/quota-fetcher/providers/cursor.js +123 -0
- package/dist/server/services/quota-fetcher/providers/grok.d.ts +18 -0
- package/dist/server/services/quota-fetcher/providers/grok.js +89 -0
- package/dist/server/services/quota-fetcher/providers/kimi.d.ts +20 -0
- package/dist/server/services/quota-fetcher/providers/kimi.js +89 -0
- package/dist/server/services/quota-fetcher/providers/zai.d.ts +17 -0
- package/dist/server/services/quota-fetcher/providers/zai.js +58 -0
- package/dist/server/services/quota-fetcher/service.d.ts +28 -0
- package/dist/server/services/quota-fetcher/service.js +58 -0
- package/dist/server/services/quota-fetcher/usage.d.ts +22 -0
- package/dist/server/services/quota-fetcher/usage.js +49 -0
- package/dist/server/terminal/terminal-session-controller.d.ts +8 -0
- package/dist/server/terminal/terminal-session-controller.js +23 -3
- package/dist/server/utils/checkout-git.js +36 -76
- package/dist/server/utils/directory-suggestions.js +98 -2
- package/dist/server/utils/worktree-metadata.d.ts +7 -59
- package/dist/src/server/persisted-config.js +1 -1
- package/package.json +9 -9
|
@@ -59,7 +59,9 @@ function formatStructuredContentForModel(structuredContent) {
|
|
|
59
59
|
return summary.length > 0 ? `${summary.join("\n")}\n\n${json}` : json;
|
|
60
60
|
}
|
|
61
61
|
function isZodSchema(value) {
|
|
62
|
-
return (typeof value === "object" &&
|
|
62
|
+
return (typeof value === "object" &&
|
|
63
|
+
value !== null &&
|
|
64
|
+
typeof value.safeParseAsync === "function");
|
|
63
65
|
}
|
|
64
66
|
function relaxMcpOutputSchema(outputSchema) {
|
|
65
67
|
if (!outputSchema) {
|
|
@@ -468,7 +470,7 @@ export async function createAgentMcpServer(options) {
|
|
|
468
470
|
modeId: z.string().optional().describe("Session mode to configure before the first run."),
|
|
469
471
|
thinkingOptionId: z.string().optional().describe("Thinking option ID."),
|
|
470
472
|
features: z
|
|
471
|
-
.record(z.unknown())
|
|
473
|
+
.record(z.string(), z.unknown())
|
|
472
474
|
.optional()
|
|
473
475
|
.describe("Provider-specific feature values, for example { fast_mode: true } for Codex."),
|
|
474
476
|
})
|
|
@@ -483,7 +485,7 @@ export async function createAgentMcpServer(options) {
|
|
|
483
485
|
.optional()
|
|
484
486
|
.describe("Thinking option ID. Pass null to clear."),
|
|
485
487
|
features: z
|
|
486
|
-
.record(z.unknown())
|
|
488
|
+
.record(z.string(), z.unknown())
|
|
487
489
|
.optional()
|
|
488
490
|
.describe("Provider-specific feature values, for example { fast_mode: true } for Codex."),
|
|
489
491
|
})
|
|
@@ -493,14 +495,109 @@ export async function createAgentMcpServer(options) {
|
|
|
493
495
|
modeId: z.string().optional().describe("Draft session mode ID."),
|
|
494
496
|
model: z.string().optional().describe("Draft model ID."),
|
|
495
497
|
thinkingOptionId: z.string().optional().describe("Draft thinking option ID."),
|
|
496
|
-
features: z
|
|
498
|
+
features: z
|
|
499
|
+
.record(z.string(), z.unknown())
|
|
500
|
+
.optional()
|
|
501
|
+
.describe("Draft provider feature values."),
|
|
497
502
|
})
|
|
498
503
|
.strict();
|
|
499
|
-
const
|
|
500
|
-
|
|
501
|
-
.
|
|
502
|
-
.
|
|
503
|
-
.describe("
|
|
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."),
|
|
504
601
|
title: z
|
|
505
602
|
.string()
|
|
506
603
|
.trim()
|
|
@@ -515,11 +612,9 @@ export async function createAgentMcpServer(options) {
|
|
|
515
612
|
.trim()
|
|
516
613
|
.min(1, "initialPrompt is required")
|
|
517
614
|
.describe("Required first task to run immediately after creation."),
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
.default(false)
|
|
522
|
-
.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,
|
|
523
618
|
notifyOnFinish: z
|
|
524
619
|
.boolean()
|
|
525
620
|
.optional()
|
|
@@ -527,42 +622,7 @@ export async function createAgentMcpServer(options) {
|
|
|
527
622
|
.describe("Get notified when the created agent finishes, errors, or needs permission. Set false only for truly fire-and-forget agents."),
|
|
528
623
|
};
|
|
529
624
|
const topLevelInputSchema = {
|
|
530
|
-
|
|
531
|
-
.string()
|
|
532
|
-
.describe("Required working directory for the agent (absolute, relative, or ~)."),
|
|
533
|
-
title: z
|
|
534
|
-
.string()
|
|
535
|
-
.trim()
|
|
536
|
-
.min(1, "Title is required")
|
|
537
|
-
.max(60, "Title must be 60 characters or fewer")
|
|
538
|
-
.describe("Short descriptive title (<= 60 chars) summarizing the agent's focus."),
|
|
539
|
-
provider: ProviderModelInputSchema.describe("Required provider/model pair, for example codex/gpt-5.4."),
|
|
540
|
-
labels: z.record(z.string(), z.string()).optional().describe("Labels to set on the agent"),
|
|
541
|
-
settings: CreateAgentSettingsInputSchema.optional().describe("Initial runtime settings for the new agent."),
|
|
542
|
-
initialPrompt: z
|
|
543
|
-
.string()
|
|
544
|
-
.trim()
|
|
545
|
-
.min(1, "initialPrompt is required")
|
|
546
|
-
.describe("Required first task to run immediately after creation."),
|
|
547
|
-
worktreeName: z
|
|
548
|
-
.string()
|
|
549
|
-
.optional()
|
|
550
|
-
.describe("Optional git worktree branch name (lowercase alphanumerics + hyphen)."),
|
|
551
|
-
baseBranch: z
|
|
552
|
-
.string()
|
|
553
|
-
.optional()
|
|
554
|
-
.describe("Required when worktreeName is set: the base branch to diff/merge against."),
|
|
555
|
-
refName: z.string().min(1).optional().describe("Optional source ref for worktree creation."),
|
|
556
|
-
action: z
|
|
557
|
-
.enum(["branch-off", "checkout"])
|
|
558
|
-
.optional()
|
|
559
|
-
.describe("Optional worktree creation action."),
|
|
560
|
-
githubPrNumber: z
|
|
561
|
-
.number()
|
|
562
|
-
.int()
|
|
563
|
-
.positive()
|
|
564
|
-
.optional()
|
|
565
|
-
.describe("Optional GitHub pull request number to checkout."),
|
|
625
|
+
...commonCreateAgentInputSchema,
|
|
566
626
|
background: z
|
|
567
627
|
.boolean()
|
|
568
628
|
.optional()
|
|
@@ -577,6 +637,40 @@ export async function createAgentMcpServer(options) {
|
|
|
577
637
|
const createAgentInputSchema = callerAgentId ? agentToAgentInputSchema : topLevelInputSchema;
|
|
578
638
|
const agentToAgentCreateAgentArgsSchema = z.object(agentToAgentInputSchema).strict();
|
|
579
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;
|
|
580
674
|
const inspectProviderInputSchema = {
|
|
581
675
|
provider: ProviderOrProviderModelInputSchema.describe("Provider ID, optionally with a model ID (for example codex or codex/gpt-5.4)."),
|
|
582
676
|
cwd: z
|
|
@@ -623,13 +717,14 @@ export async function createAgentMcpServer(options) {
|
|
|
623
717
|
}
|
|
624
718
|
registerTool("create_agent", {
|
|
625
719
|
title: "Create agent",
|
|
626
|
-
description: "Create an 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.",
|
|
627
721
|
inputSchema: createAgentInputSchema,
|
|
628
722
|
outputSchema: {
|
|
629
723
|
agentId: z.string(),
|
|
630
724
|
type: AgentProviderEnum,
|
|
631
725
|
status: AgentStatusEnum,
|
|
632
726
|
cwd: z.string(),
|
|
727
|
+
workspaceId: z.string().optional(),
|
|
633
728
|
currentModeId: z.string().nullable(),
|
|
634
729
|
availableModes: z.array(ProviderModeSchema),
|
|
635
730
|
lastMessage: z.string().nullable().optional(),
|
|
@@ -637,20 +732,20 @@ export async function createAgentMcpServer(options) {
|
|
|
637
732
|
guidance: z.string().optional(),
|
|
638
733
|
},
|
|
639
734
|
}, async (args) => {
|
|
640
|
-
const resolvedArgs = resolveCreateAgentToolArgs(args);
|
|
735
|
+
const resolvedArgs = await resolveCreateAgentToolArgs(args);
|
|
641
736
|
const { parsedArgs, worktree } = resolvedArgs;
|
|
642
737
|
let requestedBackground;
|
|
643
738
|
let notifyOnFinish;
|
|
644
739
|
let detached;
|
|
645
740
|
if (resolvedArgs.kind === "agent-scoped") {
|
|
646
741
|
requestedBackground = true;
|
|
647
|
-
notifyOnFinish =
|
|
648
|
-
detached = resolvedArgs.
|
|
742
|
+
notifyOnFinish = parsedArgs.notifyOnFinish;
|
|
743
|
+
detached = resolvedArgs.relationship.kind === "detached";
|
|
649
744
|
}
|
|
650
745
|
else {
|
|
651
746
|
requestedBackground = resolvedArgs.parsedArgs.background;
|
|
652
747
|
notifyOnFinish = resolvedArgs.parsedArgs.notifyOnFinish ?? false;
|
|
653
|
-
detached =
|
|
748
|
+
detached = resolvedArgs.parsedArgs.relationship.kind === "detached";
|
|
654
749
|
}
|
|
655
750
|
const { snapshot, background: createdInBackground, initialPromptStarted, } = await createAgentCommand({
|
|
656
751
|
agentManager,
|
|
@@ -669,7 +764,8 @@ export async function createAgentMcpServer(options) {
|
|
|
669
764
|
provider: parsedArgs.provider,
|
|
670
765
|
title: parsedArgs.title,
|
|
671
766
|
initialPrompt: parsedArgs.initialPrompt,
|
|
672
|
-
cwd:
|
|
767
|
+
cwd: resolvedArgs.cwd,
|
|
768
|
+
workspaceId: resolvedArgs.workspaceId,
|
|
673
769
|
thinking: parsedArgs.settings?.thinkingOptionId,
|
|
674
770
|
features: parsedArgs.settings?.features,
|
|
675
771
|
labels: parsedArgs.labels,
|
|
@@ -692,6 +788,7 @@ export async function createAgentMcpServer(options) {
|
|
|
692
788
|
type: snapshot.provider,
|
|
693
789
|
status: result.status,
|
|
694
790
|
cwd: liveSnapshot.cwd,
|
|
791
|
+
...(liveSnapshot.workspaceId ? { workspaceId: liveSnapshot.workspaceId } : {}),
|
|
695
792
|
currentModeId: liveSnapshot.currentModeId,
|
|
696
793
|
availableModes: liveSnapshot.availableModes,
|
|
697
794
|
lastMessage: result.lastMessage,
|
|
@@ -721,6 +818,7 @@ export async function createAgentMcpServer(options) {
|
|
|
721
818
|
type: snapshot.provider,
|
|
722
819
|
status: currentSnapshot.lifecycle,
|
|
723
820
|
cwd: currentSnapshot.cwd,
|
|
821
|
+
...(currentSnapshot.workspaceId ? { workspaceId: currentSnapshot.workspaceId } : {}),
|
|
724
822
|
currentModeId: currentSnapshot.currentModeId,
|
|
725
823
|
availableModes: currentSnapshot.availableModes,
|
|
726
824
|
lastMessage: null,
|
|
@@ -730,30 +828,109 @@ export async function createAgentMcpServer(options) {
|
|
|
730
828
|
};
|
|
731
829
|
return response;
|
|
732
830
|
});
|
|
733
|
-
function resolveCreateAgentToolArgs(args) {
|
|
831
|
+
async function resolveCreateAgentToolArgs(args) {
|
|
734
832
|
if (callerAgentId) {
|
|
833
|
+
const parsed = agentToAgentCreateAgentArgsSchema.parse(args);
|
|
834
|
+
const { cwd, workspaceId, worktree } = await resolveCreateAgentWorkspace(parsed.workspace);
|
|
735
835
|
return {
|
|
736
836
|
kind: "agent-scoped",
|
|
737
|
-
parsedArgs:
|
|
738
|
-
|
|
837
|
+
parsedArgs: parsed,
|
|
838
|
+
relationship: parsed.relationship,
|
|
839
|
+
cwd,
|
|
840
|
+
workspaceId,
|
|
841
|
+
worktree,
|
|
739
842
|
};
|
|
740
843
|
}
|
|
741
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);
|
|
742
849
|
return {
|
|
743
850
|
kind: "top-level",
|
|
744
851
|
parsedArgs,
|
|
745
|
-
|
|
852
|
+
cwd,
|
|
853
|
+
workspaceId,
|
|
854
|
+
worktree,
|
|
746
855
|
};
|
|
747
856
|
}
|
|
748
|
-
function
|
|
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 });
|
|
749
905
|
return {
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
action: args.action,
|
|
754
|
-
githubPrNumber: args.githubPrNumber,
|
|
906
|
+
cwd,
|
|
907
|
+
workspaceId: undefined,
|
|
908
|
+
worktree: resolveCreateAgentWorktree(workspace.source.target),
|
|
755
909
|
};
|
|
756
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
|
+
}
|
|
757
934
|
registerTool("wait_for_agent", {
|
|
758
935
|
title: "Wait for agent",
|
|
759
936
|
description: "Block until the agent requests permission or the current run completes. Returns the pending permission (if any) and recent activity summary.",
|
|
@@ -823,35 +1000,20 @@ export async function createAgentMcpServer(options) {
|
|
|
823
1000
|
});
|
|
824
1001
|
registerTool("send_agent_prompt", {
|
|
825
1002
|
title: "Send agent prompt",
|
|
826
|
-
description: "Send a task to a running agent.
|
|
827
|
-
inputSchema:
|
|
828
|
-
agentId: z.string(),
|
|
829
|
-
prompt: z.string(),
|
|
830
|
-
sessionMode: z
|
|
831
|
-
.string()
|
|
832
|
-
.optional()
|
|
833
|
-
.describe("Optional mode to set before running the prompt."),
|
|
834
|
-
background: z
|
|
835
|
-
.boolean()
|
|
836
|
-
.optional()
|
|
837
|
-
.default(false)
|
|
838
|
-
.describe("Run agent in background. If false (default), waits for completion or permission request. If true, returns immediately."),
|
|
839
|
-
notifyOnFinish: z
|
|
840
|
-
.boolean()
|
|
841
|
-
.optional()
|
|
842
|
-
.default(false)
|
|
843
|
-
.describe("Agent-scoped only: get notified when this run finishes, errors, or needs permission."),
|
|
844
|
-
},
|
|
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,
|
|
845
1005
|
outputSchema: {
|
|
846
1006
|
success: z.boolean(),
|
|
847
1007
|
status: AgentStatusEnum,
|
|
848
1008
|
lastMessage: z.string().nullable().optional(),
|
|
849
1009
|
permission: AgentPermissionRequestPayloadSchema.nullable().optional(),
|
|
1010
|
+
guidance: z.string().optional(),
|
|
850
1011
|
},
|
|
851
|
-
}, async ({ agentId, prompt, sessionMode, background =
|
|
1012
|
+
}, async ({ agentId, prompt, sessionMode, background = Boolean(callerAgentId), notifyOnFinish = Boolean(callerAgentId), }) => {
|
|
852
1013
|
if (agentManager.hasInFlightRun(agentId)) {
|
|
853
1014
|
waitTracker.cancel(agentId, "Agent run interrupted by new prompt");
|
|
854
1015
|
}
|
|
1016
|
+
const shouldNotifyOnFinish = Boolean(callerAgentId && notifyOnFinish && background);
|
|
855
1017
|
await sendPromptToAgent({
|
|
856
1018
|
agentManager,
|
|
857
1019
|
agentStorage,
|
|
@@ -860,7 +1022,7 @@ export async function createAgentMcpServer(options) {
|
|
|
860
1022
|
sessionMode,
|
|
861
1023
|
logger: childLogger,
|
|
862
1024
|
});
|
|
863
|
-
if (
|
|
1025
|
+
if (shouldNotifyOnFinish && callerAgentId) {
|
|
864
1026
|
setupFinishNotification({
|
|
865
1027
|
agentManager,
|
|
866
1028
|
agentStorage,
|
|
@@ -895,6 +1057,11 @@ export async function createAgentMcpServer(options) {
|
|
|
895
1057
|
status: currentSnapshot?.lifecycle ?? "idle",
|
|
896
1058
|
lastMessage: null,
|
|
897
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
|
+
: {}),
|
|
898
1065
|
};
|
|
899
1066
|
const validJson = ensureValidJson(responseData);
|
|
900
1067
|
const response = {
|
|
@@ -1602,37 +1769,12 @@ export async function createAgentMcpServer(options) {
|
|
|
1602
1769
|
description: "Create a Paseo-managed git worktree. Branch off a new branch, check out an existing branch, or check out a GitHub PR.",
|
|
1603
1770
|
inputSchema: {
|
|
1604
1771
|
cwd: z.string().optional().describe("Repository directory. Defaults to the agent's cwd."),
|
|
1605
|
-
target:
|
|
1606
|
-
.discriminatedUnion("mode", [
|
|
1607
|
-
z
|
|
1608
|
-
.object({
|
|
1609
|
-
mode: z.literal("branch-off"),
|
|
1610
|
-
newBranch: z.string().min(1).describe("Name for the new branch."),
|
|
1611
|
-
base: z
|
|
1612
|
-
.string()
|
|
1613
|
-
.min(1)
|
|
1614
|
-
.optional()
|
|
1615
|
-
.describe("Base ref. Defaults to the repo's default branch."),
|
|
1616
|
-
})
|
|
1617
|
-
.describe("Create a new branch off a base."),
|
|
1618
|
-
z
|
|
1619
|
-
.object({
|
|
1620
|
-
mode: z.literal("checkout-branch"),
|
|
1621
|
-
branch: z.string().min(1).describe("Existing branch to check out."),
|
|
1622
|
-
})
|
|
1623
|
-
.describe("Check out an existing branch."),
|
|
1624
|
-
z
|
|
1625
|
-
.object({
|
|
1626
|
-
mode: z.literal("checkout-pr"),
|
|
1627
|
-
prNumber: z.number().int().positive().describe("Pull request number."),
|
|
1628
|
-
})
|
|
1629
|
-
.describe("Check out a GitHub pull request."),
|
|
1630
|
-
])
|
|
1631
|
-
.describe("What the worktree should contain."),
|
|
1772
|
+
target: AgentCreateWorktreeTargetInputSchema.describe("What the worktree should contain."),
|
|
1632
1773
|
},
|
|
1633
1774
|
outputSchema: {
|
|
1634
1775
|
branchName: z.string(),
|
|
1635
1776
|
worktreePath: z.string(),
|
|
1777
|
+
workspaceId: z.string(),
|
|
1636
1778
|
},
|
|
1637
1779
|
}, async ({ cwd, target }) => {
|
|
1638
1780
|
const repoRoot = resolveScopedCwd(cwd, { required: true });
|
|
@@ -1644,7 +1786,7 @@ export async function createAgentMcpServer(options) {
|
|
|
1644
1786
|
if (!commandResult.ok) {
|
|
1645
1787
|
throw new WorktreeRequestError(commandResult.error);
|
|
1646
1788
|
}
|
|
1647
|
-
const { worktree } = commandResult.createdWorktree;
|
|
1789
|
+
const { worktree, workspace } = commandResult.createdWorktree;
|
|
1648
1790
|
await options.workspaceGitService?.listWorktrees?.(repoRoot, {
|
|
1649
1791
|
force: true,
|
|
1650
1792
|
reason: "mcp:create-worktree",
|
|
@@ -1654,6 +1796,7 @@ export async function createAgentMcpServer(options) {
|
|
|
1654
1796
|
structuredContent: ensureValidJson({
|
|
1655
1797
|
branchName: worktree.branchName,
|
|
1656
1798
|
worktreePath: worktree.worktreePath,
|
|
1799
|
+
workspaceId: workspace.workspaceId,
|
|
1657
1800
|
}),
|
|
1658
1801
|
};
|
|
1659
1802
|
});
|
|
@@ -1868,18 +2011,19 @@ function archiveWorktreeDependencies(options, context) {
|
|
|
1868
2011
|
}
|
|
1869
2012
|
function createMcpWorktreeCommandInput(repoRoot, target) {
|
|
1870
2013
|
const base = { cwd: repoRoot };
|
|
1871
|
-
switch (target.
|
|
2014
|
+
switch (target.kind) {
|
|
1872
2015
|
case "branch-off":
|
|
1873
2016
|
return {
|
|
1874
2017
|
...base,
|
|
1875
|
-
worktreeSlug: target.
|
|
2018
|
+
worktreeSlug: target.worktreeSlug,
|
|
2019
|
+
branchName: target.branchName,
|
|
1876
2020
|
action: "branch-off",
|
|
1877
|
-
...(target.
|
|
2021
|
+
...(target.baseBranch ? { refName: target.baseBranch } : {}),
|
|
1878
2022
|
};
|
|
1879
2023
|
case "checkout-branch":
|
|
1880
2024
|
return { ...base, action: "checkout", refName: target.branch };
|
|
1881
2025
|
case "checkout-pr":
|
|
1882
|
-
return { ...base, action: "checkout", githubPrNumber: target.
|
|
2026
|
+
return { ...base, action: "checkout", githubPrNumber: target.githubPrNumber };
|
|
1883
2027
|
default:
|
|
1884
2028
|
throw new Error("unreachable");
|
|
1885
2029
|
}
|