@getpaseo/cli 0.2.0-beta.1 → 0.2.0-beta.3
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/cli.js +10 -2
- package/dist/commands/agent/detach.d.ts +9 -0
- package/dist/commands/agent/detach.js +38 -0
- package/dist/commands/agent/index.js +7 -0
- package/dist/commands/agent/open.d.ts +11 -0
- package/dist/commands/agent/open.js +61 -0
- package/dist/commands/agent/run.d.ts +34 -0
- package/dist/commands/agent/run.js +133 -45
- package/dist/commands/heartbeat/index.d.ts +3 -0
- package/dist/commands/heartbeat/index.js +139 -0
- package/dist/commands/hub/index.d.ts +3 -0
- package/dist/commands/hub/index.js +65 -0
- package/dist/commands/open.d.ts +2 -0
- package/dist/commands/open.js +22 -17
- package/dist/commands/schedule/index.js +5 -6
- package/dist/commands/schedule/inspect.js +3 -0
- package/dist/commands/schedule/logs.js +2 -1
- package/dist/commands/schedule/ls.js +3 -1
- package/dist/commands/schedule/pause.js +2 -1
- package/dist/commands/schedule/resume.js +2 -1
- package/dist/commands/schedule/run-once.js +2 -1
- package/dist/commands/schedule/shared.d.ts +2 -0
- package/dist/commands/schedule/shared.js +25 -21
- package/dist/commands/schedule/update.js +2 -1
- package/dist/commands/workspace/archive.d.ts +12 -0
- package/dist/commands/workspace/archive.js +41 -0
- package/dist/commands/workspace/create.d.ts +49 -0
- package/dist/commands/workspace/create.js +114 -0
- package/dist/commands/workspace/index.d.ts +3 -0
- package/dist/commands/workspace/index.js +30 -0
- package/dist/commands/workspace/ls.d.ts +7 -0
- package/dist/commands/workspace/ls.js +28 -0
- package/dist/commands/workspace/shared.d.ts +12 -0
- package/dist/commands/workspace/shared.js +20 -0
- package/dist/utils/duration.d.ts +1 -1
- package/dist/utils/duration.js +8 -7
- package/package.json +4 -4
package/dist/cli.js
CHANGED
|
@@ -9,6 +9,9 @@ import { createScheduleCommand } from "./commands/schedule/index.js";
|
|
|
9
9
|
import { createSpeechCommand } from "./commands/speech/index.js";
|
|
10
10
|
import { createTerminalCommand } from "./commands/terminal/index.js";
|
|
11
11
|
import { createWorktreeCommand } from "./commands/worktree/index.js";
|
|
12
|
+
import { createWorkspaceCommand } from "./commands/workspace/index.js";
|
|
13
|
+
import { createHeartbeatCommand } from "./commands/heartbeat/index.js";
|
|
14
|
+
import { createHubCommand } from "./commands/hub/index.js";
|
|
12
15
|
import { createHooksCommand } from "./commands/hooks.js";
|
|
13
16
|
import { startCommand as daemonStartCommand } from "./commands/daemon/start.js";
|
|
14
17
|
import { runStatusCommand as runDaemonStatusCommand } from "./commands/daemon/status.js";
|
|
@@ -100,6 +103,7 @@ export function createCli() {
|
|
|
100
103
|
program.addCommand(createAgentCommand());
|
|
101
104
|
// Daemon commands
|
|
102
105
|
program.addCommand(createDaemonCommand());
|
|
106
|
+
program.addCommand(createHubCommand());
|
|
103
107
|
// Chat commands
|
|
104
108
|
program.addCommand(createChatCommand());
|
|
105
109
|
// Terminal commands
|
|
@@ -108,14 +112,18 @@ export function createCli() {
|
|
|
108
112
|
program.addCommand(createLoopCommand());
|
|
109
113
|
// Schedule commands
|
|
110
114
|
program.addCommand(createScheduleCommand());
|
|
115
|
+
program.addCommand(createHeartbeatCommand());
|
|
111
116
|
// Permission commands
|
|
112
117
|
program.addCommand(createPermitCommand());
|
|
113
118
|
// Provider commands
|
|
114
119
|
program.addCommand(createProviderCommand());
|
|
115
120
|
// Speech model commands
|
|
116
121
|
program.addCommand(createSpeechCommand());
|
|
117
|
-
//
|
|
118
|
-
program.addCommand(
|
|
122
|
+
// Workspace commands
|
|
123
|
+
program.addCommand(createWorkspaceCommand());
|
|
124
|
+
// COMPAT(worktreeCli): legacy command alias added before workspace was the product unit.
|
|
125
|
+
// Added in v0.2.0; remove after 2027-01-17.
|
|
126
|
+
program.addCommand(createWorktreeCommand(), { hidden: true });
|
|
119
127
|
return program;
|
|
120
128
|
}
|
|
121
129
|
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { CommandOptions, SingleResult } from "../../output/index.js";
|
|
3
|
+
interface AgentDetachResult {
|
|
4
|
+
agentId: string;
|
|
5
|
+
status: "detached";
|
|
6
|
+
}
|
|
7
|
+
export declare function runDetachCommand(agentIdArg: string, options: CommandOptions, _command: Command): Promise<SingleResult<AgentDetachResult>>;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=detach.d.ts.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { connectToDaemon, getDaemonHost, resolveAgentId } from "../../utils/client.js";
|
|
2
|
+
const detachSchema = {
|
|
3
|
+
idField: "agentId",
|
|
4
|
+
columns: [
|
|
5
|
+
{ header: "AGENT ID", field: "agentId" },
|
|
6
|
+
{ header: "STATUS", field: "status" },
|
|
7
|
+
],
|
|
8
|
+
};
|
|
9
|
+
export async function runDetachCommand(agentIdArg, options, _command) {
|
|
10
|
+
const host = getDaemonHost({ host: options.host });
|
|
11
|
+
let client;
|
|
12
|
+
try {
|
|
13
|
+
client = await connectToDaemon({ host: options.host });
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
17
|
+
throw {
|
|
18
|
+
code: "DAEMON_NOT_RUNNING",
|
|
19
|
+
message: `Cannot connect to daemon at ${host}: ${message}`,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const payload = await client.fetchAgents({ filter: { includeArchived: true } });
|
|
24
|
+
const agentId = resolveAgentId(agentIdArg, payload.entries.map((entry) => entry.agent));
|
|
25
|
+
if (!agentId) {
|
|
26
|
+
throw {
|
|
27
|
+
code: "AGENT_NOT_FOUND",
|
|
28
|
+
message: `Agent not found: ${agentIdArg}`,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
await client.detachAgent(agentId);
|
|
32
|
+
return { type: "single", data: { agentId, status: "detached" }, schema: detachSchema };
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
await client.close().catch(() => undefined);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=detach.js.map
|
|
@@ -13,6 +13,8 @@ import { addAttachOptions, runAttachCommand } from "./attach.js";
|
|
|
13
13
|
import { addReloadOptions, runReloadCommand } from "./reload.js";
|
|
14
14
|
import { addImportOptions, runImportCommand } from "./import.js";
|
|
15
15
|
import { runUpdateCommand } from "./update.js";
|
|
16
|
+
import { runDetachCommand } from "./detach.js";
|
|
17
|
+
import { addOpenOptions, runOpenCommand } from "./open.js";
|
|
16
18
|
import { withOutput } from "../../output/index.js";
|
|
17
19
|
import { addDaemonHostOption, addJsonAndDaemonHostOptions, collectMultiple, } from "../../utils/command-options.js";
|
|
18
20
|
export function createAgentCommand() {
|
|
@@ -23,6 +25,7 @@ export function createAgentCommand() {
|
|
|
23
25
|
addJsonAndDaemonHostOptions(addImportOptions(agent.command("import"))).action(withOutput(runImportCommand));
|
|
24
26
|
addDaemonHostOption(addAttachOptions(agent.command("attach"))).action(runAttachCommand);
|
|
25
27
|
addDaemonHostOption(addLogsOptions(agent.command("logs"))).action(runLogsCommand);
|
|
28
|
+
addJsonAndDaemonHostOptions(addOpenOptions(agent.command("open"))).action(withOutput(runOpenCommand));
|
|
26
29
|
addJsonAndDaemonHostOptions(addStopOptions(agent.command("stop"))).action(withOutput(runStopCommand));
|
|
27
30
|
addJsonAndDaemonHostOptions(addDeleteOptions(agent.command("delete"))).action(withOutput(runDeleteCommand));
|
|
28
31
|
addJsonAndDaemonHostOptions(addSendOptions(agent.command("send"))).action(withOutput(runSendCommand));
|
|
@@ -37,6 +40,10 @@ export function createAgentCommand() {
|
|
|
37
40
|
.option("--list", "List available modes for this agent")).action(withOutput(runModeCommand));
|
|
38
41
|
addJsonAndDaemonHostOptions(addArchiveOptions(agent.command("archive"))).action(withOutput(runArchiveCommand));
|
|
39
42
|
addJsonAndDaemonHostOptions(addReloadOptions(agent.command("reload"))).action(withOutput(runReloadCommand));
|
|
43
|
+
addJsonAndDaemonHostOptions(agent
|
|
44
|
+
.command("detach")
|
|
45
|
+
.description("Make a subagent independent without stopping or moving it")
|
|
46
|
+
.argument("<id>", "Agent ID, prefix, or name")).action(withOutput(runDetachCommand));
|
|
40
47
|
addJsonAndDaemonHostOptions(agent
|
|
41
48
|
.command("update")
|
|
42
49
|
.description("Update an agent's metadata")
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { CommandOptions, SingleResult } from "../../output/index.js";
|
|
3
|
+
interface OpenAgentResult {
|
|
4
|
+
agentId: string;
|
|
5
|
+
serverId: string;
|
|
6
|
+
status: "opened";
|
|
7
|
+
}
|
|
8
|
+
export declare function addOpenOptions(command: Command): Command;
|
|
9
|
+
export declare function runOpenCommand(agentIdArg: string, options: CommandOptions, _command: Command): Promise<SingleResult<OpenAgentResult>>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=open.d.ts.map
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { buildDaemonConnectionCommandError, connectToDaemon } from "../../utils/client.js";
|
|
2
|
+
import { openDesktopWithAgent } from "../open.js";
|
|
3
|
+
const openAgentSchema = {
|
|
4
|
+
idField: "agentId",
|
|
5
|
+
columns: [
|
|
6
|
+
{ header: "AGENT ID", field: "agentId" },
|
|
7
|
+
{ header: "SERVER ID", field: "serverId" },
|
|
8
|
+
{ header: "STATUS", field: "status" },
|
|
9
|
+
],
|
|
10
|
+
};
|
|
11
|
+
export function addOpenOptions(command) {
|
|
12
|
+
return command
|
|
13
|
+
.description("Open an existing agent in Paseo Desktop")
|
|
14
|
+
.argument("<agent-id>", "Existing agent ID")
|
|
15
|
+
.option("--server <server-id>", "Server ID (defaults to the local daemon)");
|
|
16
|
+
}
|
|
17
|
+
async function resolveServerId(options) {
|
|
18
|
+
const explicitServerId = typeof options.server === "string" ? options.server.trim() : "";
|
|
19
|
+
if (explicitServerId) {
|
|
20
|
+
return explicitServerId;
|
|
21
|
+
}
|
|
22
|
+
let client;
|
|
23
|
+
try {
|
|
24
|
+
client = await connectToDaemon({ host: options.host });
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
throw buildDaemonConnectionCommandError({ host: options.host, error });
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const serverId = client.getLastServerInfoMessage()?.serverId.trim();
|
|
31
|
+
if (!serverId) {
|
|
32
|
+
const error = {
|
|
33
|
+
code: "SERVER_ID_UNAVAILABLE",
|
|
34
|
+
message: "The daemon did not report a server ID.",
|
|
35
|
+
};
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
return serverId;
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
await client.close().catch(() => { });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export async function runOpenCommand(agentIdArg, options, _command) {
|
|
45
|
+
const agentId = agentIdArg.trim();
|
|
46
|
+
if (!agentId) {
|
|
47
|
+
const error = {
|
|
48
|
+
code: "MISSING_AGENT_ID",
|
|
49
|
+
message: "Agent ID is required.",
|
|
50
|
+
};
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
const serverId = await resolveServerId(options);
|
|
54
|
+
await openDesktopWithAgent({ serverId, agentId });
|
|
55
|
+
return {
|
|
56
|
+
type: "single",
|
|
57
|
+
data: { agentId, serverId, status: "opened" },
|
|
58
|
+
schema: openAgentSchema,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=open.js.map
|
|
@@ -14,6 +14,7 @@ export interface AgentRunResult {
|
|
|
14
14
|
/** Schema for agent run output */
|
|
15
15
|
export declare const agentRunSchema: OutputSchema<AgentRunResult>;
|
|
16
16
|
export interface AgentRunOptions extends CommandOptions {
|
|
17
|
+
background?: boolean;
|
|
17
18
|
detach?: boolean;
|
|
18
19
|
title?: string;
|
|
19
20
|
name?: string;
|
|
@@ -21,8 +22,15 @@ export interface AgentRunOptions extends CommandOptions {
|
|
|
21
22
|
model?: string;
|
|
22
23
|
thinking?: string;
|
|
23
24
|
mode?: string;
|
|
25
|
+
newWorkspace?: string;
|
|
24
26
|
worktree?: string;
|
|
27
|
+
worktreeMode?: string;
|
|
28
|
+
worktreeSlug?: string;
|
|
29
|
+
newBranch?: string;
|
|
25
30
|
base?: string;
|
|
31
|
+
branch?: string;
|
|
32
|
+
prNumber?: string;
|
|
33
|
+
forge?: string;
|
|
26
34
|
workspace?: string;
|
|
27
35
|
image?: string[];
|
|
28
36
|
cwd?: string;
|
|
@@ -40,5 +48,31 @@ export declare function resolveStructuredResponseMessage(options: {
|
|
|
40
48
|
agentId: string;
|
|
41
49
|
lastMessage: string | null;
|
|
42
50
|
}): Promise<string | null>;
|
|
51
|
+
interface RunWorkspace {
|
|
52
|
+
id?: string;
|
|
53
|
+
cwd: string;
|
|
54
|
+
}
|
|
55
|
+
export interface RunWorkspaceLookupClient {
|
|
56
|
+
fetchWorkspaces(options: {
|
|
57
|
+
filter: {
|
|
58
|
+
query: string;
|
|
59
|
+
};
|
|
60
|
+
page: {
|
|
61
|
+
limit: number;
|
|
62
|
+
};
|
|
63
|
+
}): Promise<{
|
|
64
|
+
entries: Array<{
|
|
65
|
+
id: string;
|
|
66
|
+
workspaceDirectory: string;
|
|
67
|
+
}>;
|
|
68
|
+
pageInfo: {
|
|
69
|
+
nextCursor: string | null;
|
|
70
|
+
};
|
|
71
|
+
}>;
|
|
72
|
+
}
|
|
73
|
+
export declare function resolveExistingRunWorkspace(client: RunWorkspaceLookupClient, workspaceId: string): Promise<RunWorkspace>;
|
|
43
74
|
export declare function runRunCommand(prompt: string, options: AgentRunOptions, _command: Command): Promise<SingleResult<AgentRunResult>>;
|
|
75
|
+
export declare function resolveRunCallerAgentId(env?: {
|
|
76
|
+
PASEO_AGENT_ID?: string;
|
|
77
|
+
}): string | undefined;
|
|
44
78
|
//# sourceMappingURL=run.d.ts.map
|
|
@@ -7,27 +7,38 @@ import { lookup } from "mime-types";
|
|
|
7
7
|
import { parseDuration } from "../../utils/duration.js";
|
|
8
8
|
import { collectMultiple } from "../../utils/command-options.js";
|
|
9
9
|
import { resolveProviderAndModel } from "../../utils/provider-model.js";
|
|
10
|
+
import { buildWorkspaceSource } from "../workspace/create.js";
|
|
10
11
|
export { resolveProviderAndModel } from "../../utils/provider-model.js";
|
|
11
12
|
export function addRunOptions(cmd) {
|
|
12
|
-
return cmd
|
|
13
|
+
return (cmd
|
|
13
14
|
.description("Create and start an agent with a task")
|
|
14
15
|
.argument("<prompt>", "The task/prompt for the agent")
|
|
15
|
-
.option("-d, --
|
|
16
|
+
.option("-d, --background", "Run in background")
|
|
17
|
+
// COMPAT(detachRunFlag): --detach used to mean background execution, not
|
|
18
|
+
// ownership transfer. Added in v0.2.0; remove after 2027-01-17.
|
|
19
|
+
.addOption(new Option("--detach", "Legacy alias for --background").hideHelp())
|
|
16
20
|
.option("--title <title>", "Assign a title to the agent")
|
|
17
21
|
.addOption(new Option("--name <name>", "Hidden alias for --title").hideHelp())
|
|
18
22
|
.option("--provider <provider>", "Agent provider, or provider/model (e.g. codex or codex/gpt-5.4)")
|
|
19
23
|
.option("--model <model>", "Model to use (e.g., claude-sonnet-4-20250514, claude-3-5-haiku-20241022)")
|
|
20
24
|
.option("--thinking <id>", "Thinking option ID to use for this run")
|
|
21
25
|
.option("--mode <mode>", "Provider-specific mode (e.g., plan, default, bypass)")
|
|
22
|
-
.option("--
|
|
23
|
-
.
|
|
24
|
-
.option("--
|
|
26
|
+
.option("--new-workspace <local|worktree>", "Create a separate local or worktree workspace")
|
|
27
|
+
.addOption(new Option("--worktree <name>", "Legacy workspace isolation alias").hideHelp())
|
|
28
|
+
.option("--worktree-mode <mode>", "Worktree mode: branch-off, checkout-branch, or checkout-pr")
|
|
29
|
+
.option("--worktree-slug <slug>", "Managed worktree path slug")
|
|
30
|
+
.option("--new-branch <name>", "New branch name for branch-off mode")
|
|
31
|
+
.option("--base <ref>", "Base ref for branch-off mode")
|
|
32
|
+
.option("--branch <name>", "Existing branch for checkout-branch mode")
|
|
33
|
+
.option("--pr-number <n>", "Pull request or change request number for checkout-pr mode")
|
|
34
|
+
.option("--forge <forge>", "Forge for checkout-pr mode")
|
|
35
|
+
.option("--workspace <id>", "Run in an existing workspace (defaults to the caller workspace when agent-scoped)")
|
|
25
36
|
.option("--image <path>", "Attach image(s) to the initial prompt (can be used multiple times)", collectMultiple, [])
|
|
26
37
|
.option("--cwd <path>", "Working directory (default: current)")
|
|
27
38
|
.option("--env <key=value>", "Set environment variable(s) for the agent process (can be used multiple times)", collectMultiple, [])
|
|
28
39
|
.option("--label <key=value>", "Add label(s) to the agent (can be used multiple times)", collectMultiple, [])
|
|
29
40
|
.option("--wait-timeout <duration>", "Maximum time to wait for agent to finish (e.g., 30s, 5m, 1h). Default: no limit")
|
|
30
|
-
.option("--output-schema <schema>", "Output JSON matching the provided schema file path or inline JSON schema");
|
|
41
|
+
.option("--output-schema <schema>", "Output JSON matching the provided schema file path or inline JSON schema"));
|
|
31
42
|
}
|
|
32
43
|
/** Schema for agent run output */
|
|
33
44
|
export const agentRunSchema = {
|
|
@@ -40,6 +51,23 @@ export const agentRunSchema = {
|
|
|
40
51
|
{ header: "TITLE", field: "title", width: 20 },
|
|
41
52
|
],
|
|
42
53
|
};
|
|
54
|
+
function resolveNewWorkspaceKind(options) {
|
|
55
|
+
return options.newWorkspace ?? (options.worktree ? "worktree" : undefined);
|
|
56
|
+
}
|
|
57
|
+
function buildRunWorkspaceSource(options, cwd) {
|
|
58
|
+
const newWorkspace = resolveNewWorkspaceKind(options) ?? "local";
|
|
59
|
+
return buildWorkspaceSource({
|
|
60
|
+
isolation: newWorkspace,
|
|
61
|
+
path: cwd,
|
|
62
|
+
mode: options.worktreeMode,
|
|
63
|
+
worktreeSlug: options.worktreeSlug ?? options.worktree,
|
|
64
|
+
newBranch: options.newBranch,
|
|
65
|
+
base: options.base,
|
|
66
|
+
branch: options.branch,
|
|
67
|
+
prNumber: options.prNumber,
|
|
68
|
+
forge: options.forge,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
43
71
|
function toRunResult(agent, statusOverride) {
|
|
44
72
|
return {
|
|
45
73
|
agentId: agent.id,
|
|
@@ -164,43 +192,88 @@ function structuredRunSchema(output) {
|
|
|
164
192
|
serialize: () => output,
|
|
165
193
|
};
|
|
166
194
|
}
|
|
167
|
-
function
|
|
168
|
-
|
|
195
|
+
function validateRunWorkspaceOptions(options) {
|
|
196
|
+
const newWorkspace = resolveNewWorkspaceKind(options);
|
|
197
|
+
if (options.newWorkspace &&
|
|
198
|
+
options.newWorkspace !== "local" &&
|
|
199
|
+
options.newWorkspace !== "worktree") {
|
|
169
200
|
throw {
|
|
170
|
-
code: "
|
|
171
|
-
message:
|
|
172
|
-
details: "
|
|
201
|
+
code: "INVALID_OPTIONS",
|
|
202
|
+
message: `Unsupported new workspace kind: ${options.newWorkspace}`,
|
|
203
|
+
details: "Use --new-workspace local or --new-workspace worktree",
|
|
173
204
|
};
|
|
174
205
|
}
|
|
175
|
-
if (options.
|
|
206
|
+
if (options.newWorkspace && options.worktree) {
|
|
207
|
+
throw {
|
|
208
|
+
code: "INVALID_OPTIONS",
|
|
209
|
+
message: "--new-workspace and --worktree cannot be combined",
|
|
210
|
+
details: "Use --new-workspace worktree and the supported worktree options",
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
const hasWorktreeCreationOptions = [
|
|
214
|
+
options.worktreeMode,
|
|
215
|
+
options.worktreeSlug,
|
|
216
|
+
options.newBranch,
|
|
217
|
+
options.base,
|
|
218
|
+
options.branch,
|
|
219
|
+
options.prNumber,
|
|
220
|
+
options.forge,
|
|
221
|
+
].some((value) => value !== undefined);
|
|
222
|
+
if (hasWorktreeCreationOptions && newWorkspace !== "worktree") {
|
|
223
|
+
throw {
|
|
224
|
+
code: "INVALID_OPTIONS",
|
|
225
|
+
message: "Worktree options require --new-workspace worktree",
|
|
226
|
+
details: "Usage: paseo run --new-workspace worktree [worktree options] <prompt>",
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
if (newWorkspace === "worktree") {
|
|
230
|
+
try {
|
|
231
|
+
buildRunWorkspaceSource(options, options.cwd ?? process.cwd());
|
|
232
|
+
}
|
|
233
|
+
catch (error) {
|
|
234
|
+
throw {
|
|
235
|
+
code: "INVALID_OPTIONS",
|
|
236
|
+
message: error instanceof Error ? error.message : String(error),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if (options.newWorkspace && options.workspace) {
|
|
176
241
|
throw {
|
|
177
242
|
code: "INVALID_OPTIONS",
|
|
178
|
-
message: "--
|
|
179
|
-
details: "
|
|
243
|
+
message: "--new-workspace and --workspace cannot be combined",
|
|
244
|
+
details: "Select an existing workspace or explicitly create a new one",
|
|
180
245
|
};
|
|
181
246
|
}
|
|
247
|
+
// COMPAT(worktreeRunFlag): --worktree implies a new worktree-isolated workspace.
|
|
248
|
+
// Added in v0.2.0; remove after 2027-01-17.
|
|
182
249
|
if (options.worktree && options.workspace) {
|
|
183
250
|
throw {
|
|
184
251
|
code: "INVALID_OPTIONS",
|
|
185
252
|
message: "--worktree and --workspace cannot be combined",
|
|
186
|
-
details: "--workspace
|
|
253
|
+
details: "Use --new-workspace worktree instead of the legacy --worktree flag",
|
|
187
254
|
};
|
|
188
255
|
}
|
|
189
|
-
|
|
256
|
+
}
|
|
257
|
+
function validateRunOptions(prompt, options, outputSchema) {
|
|
258
|
+
if (!prompt || prompt.trim().length === 0) {
|
|
190
259
|
throw {
|
|
191
|
-
code: "
|
|
192
|
-
message: "
|
|
193
|
-
details: "
|
|
260
|
+
code: "MISSING_PROMPT",
|
|
261
|
+
message: "A prompt is required",
|
|
262
|
+
details: "Usage: paseo agent run [options] <prompt>",
|
|
194
263
|
};
|
|
195
264
|
}
|
|
196
|
-
|
|
265
|
+
validateRunWorkspaceOptions(options);
|
|
266
|
+
if (outputSchema && runsInBackground(options)) {
|
|
197
267
|
throw {
|
|
198
268
|
code: "INVALID_OPTIONS",
|
|
199
|
-
message: "--output-schema cannot be used with --
|
|
269
|
+
message: "--output-schema cannot be used with --background",
|
|
200
270
|
details: "Structured output requires waiting for the agent to finish",
|
|
201
271
|
};
|
|
202
272
|
}
|
|
203
273
|
}
|
|
274
|
+
function runsInBackground(options) {
|
|
275
|
+
return Boolean(options.background || options.detach);
|
|
276
|
+
}
|
|
204
277
|
function parseWaitTimeoutOption(waitTimeout) {
|
|
205
278
|
if (!waitTimeout)
|
|
206
279
|
return 0;
|
|
@@ -289,36 +362,45 @@ async function connectToDaemonOrThrow(hostOption, host) {
|
|
|
289
362
|
};
|
|
290
363
|
}
|
|
291
364
|
}
|
|
365
|
+
export async function resolveExistingRunWorkspace(client, workspaceId) {
|
|
366
|
+
const result = await client.fetchWorkspaces({
|
|
367
|
+
filter: { query: workspaceId },
|
|
368
|
+
page: { limit: 200 },
|
|
369
|
+
});
|
|
370
|
+
const workspace = result.entries.find((entry) => entry.id === workspaceId);
|
|
371
|
+
if (workspace) {
|
|
372
|
+
return { id: workspace.id, cwd: workspace.workspaceDirectory };
|
|
373
|
+
}
|
|
374
|
+
throw {
|
|
375
|
+
code: "WORKSPACE_NOT_FOUND",
|
|
376
|
+
message: `Workspace not found: ${workspaceId}`,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
292
379
|
// Workspace policy for `paseo run`. Precedence:
|
|
293
380
|
// 1. --workspace <id> -> run in that existing workspace
|
|
294
|
-
// 2. $
|
|
295
|
-
// 3.
|
|
296
|
-
// 4.
|
|
297
|
-
//
|
|
298
|
-
// $PASEO_WORKSPACE_ID (validateRunOptions), so worktree resolution here never
|
|
299
|
-
// races an existing-workspace selection.
|
|
381
|
+
// 2. $PASEO_AGENT_ID -> daemon resolves the caller's workspace
|
|
382
|
+
// 3. $PASEO_WORKSPACE_ID -> exported by workspace terminals
|
|
383
|
+
// 4. --new-workspace <kind> -> mint a new workspace explicitly
|
|
384
|
+
// 5. bare run -> mint a new local-backed workspace for cwd
|
|
300
385
|
async function resolveRunWorkspace(client, options, cwd) {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
const explicit = options.worktree
|
|
304
|
-
? undefined
|
|
305
|
-
: options.workspace?.trim() || process.env.PASEO_WORKSPACE_ID?.trim();
|
|
386
|
+
const newWorkspace = resolveNewWorkspaceKind(options);
|
|
387
|
+
const explicit = newWorkspace ? undefined : options.workspace?.trim();
|
|
306
388
|
if (explicit) {
|
|
307
389
|
console.error(`Using workspace ${explicit}`);
|
|
308
|
-
return
|
|
390
|
+
return resolveExistingRunWorkspace(client, explicit);
|
|
391
|
+
}
|
|
392
|
+
if (!newWorkspace && resolveRunCallerAgentId()) {
|
|
393
|
+
return { cwd };
|
|
394
|
+
}
|
|
395
|
+
const ambientWorkspaceId = newWorkspace ? undefined : process.env.PASEO_WORKSPACE_ID?.trim();
|
|
396
|
+
if (ambientWorkspaceId) {
|
|
397
|
+
console.error(`Using workspace ${ambientWorkspaceId}`);
|
|
398
|
+
return resolveExistingRunWorkspace(client, ambientWorkspaceId);
|
|
309
399
|
}
|
|
310
400
|
// TODO: thread the run `prompt` as firstAgentContext so workspace-level
|
|
311
401
|
// title/branch generation picks up the task description (U8/U6 deferred).
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
source: {
|
|
315
|
-
kind: "worktree",
|
|
316
|
-
cwd,
|
|
317
|
-
worktreeSlug: options.worktree,
|
|
318
|
-
baseBranch: options.base,
|
|
319
|
-
},
|
|
320
|
-
})
|
|
321
|
-
: await client.createWorkspace({ source: { kind: "directory", path: cwd } });
|
|
402
|
+
const source = buildRunWorkspaceSource(options, cwd);
|
|
403
|
+
const result = await client.createWorkspace({ source });
|
|
322
404
|
if (!result.workspace) {
|
|
323
405
|
throw {
|
|
324
406
|
code: "WORKSPACE_CREATE_FAILED",
|
|
@@ -357,6 +439,7 @@ export async function runRunCommand(prompt, options, _command) {
|
|
|
357
439
|
const requestEnv = Object.keys(env).length > 0 ? env : undefined;
|
|
358
440
|
const workspace = await resolveRunWorkspace(client, options, cwd);
|
|
359
441
|
const workspaceId = workspace.id;
|
|
442
|
+
const callerAgentId = resolveRunCallerAgentId();
|
|
360
443
|
const runCwd = workspace.cwd;
|
|
361
444
|
if (outputSchema) {
|
|
362
445
|
let structuredAgent = null;
|
|
@@ -366,6 +449,7 @@ export async function runRunCommand(prompt, options, _command) {
|
|
|
366
449
|
provider: resolvedProviderModel.provider,
|
|
367
450
|
cwd: runCwd,
|
|
368
451
|
workspaceId,
|
|
452
|
+
callerAgentId,
|
|
369
453
|
title: resolvedTitle,
|
|
370
454
|
modeId: options.mode,
|
|
371
455
|
model: resolvedProviderModel.model,
|
|
@@ -420,6 +504,7 @@ export async function runRunCommand(prompt, options, _command) {
|
|
|
420
504
|
provider: resolvedProviderModel.provider,
|
|
421
505
|
cwd: runCwd,
|
|
422
506
|
workspaceId,
|
|
507
|
+
callerAgentId,
|
|
423
508
|
title: resolvedTitle,
|
|
424
509
|
modeId: options.mode,
|
|
425
510
|
model: resolvedProviderModel.model,
|
|
@@ -429,8 +514,8 @@ export async function runRunCommand(prompt, options, _command) {
|
|
|
429
514
|
env: requestEnv,
|
|
430
515
|
labels: Object.keys(labels).length > 0 ? labels : undefined,
|
|
431
516
|
});
|
|
432
|
-
// Default run behavior is foreground: wait for completion unless
|
|
433
|
-
if (!options
|
|
517
|
+
// Default run behavior is foreground: wait for completion unless background execution is set.
|
|
518
|
+
if (!runsInBackground(options)) {
|
|
434
519
|
const state = await client.waitForFinish(agent.id, waitTimeoutMs);
|
|
435
520
|
await client.close();
|
|
436
521
|
const finalAgent = state.final ?? agent;
|
|
@@ -461,4 +546,7 @@ export async function runRunCommand(prompt, options, _command) {
|
|
|
461
546
|
throw error;
|
|
462
547
|
}
|
|
463
548
|
}
|
|
549
|
+
export function resolveRunCallerAgentId(env = process.env) {
|
|
550
|
+
return env.PASEO_AGENT_ID?.trim() || undefined;
|
|
551
|
+
}
|
|
464
552
|
//# sourceMappingURL=run.js.map
|