@camerontaylor/paseo-cli 0.8.0-fork.1 → 0.8.0-fork.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 +25 -37
- package/dist/commands/agent/archive.js +2 -15
- package/dist/commands/agent/attach.d.ts +1 -0
- package/dist/commands/agent/attach.js +8 -12
- package/dist/commands/agent/delete.js +4 -15
- package/dist/commands/agent/detach.js +2 -13
- package/dist/commands/agent/import.js +2 -16
- package/dist/commands/agent/inspect.js +2 -15
- package/dist/commands/agent/logs.js +12 -12
- package/dist/commands/agent/ls.js +2 -23
- package/dist/commands/agent/mode.js +2 -2
- package/dist/commands/agent/open.js +2 -8
- package/dist/commands/agent/reload.js +2 -15
- package/dist/commands/agent/run.js +11 -16
- package/dist/commands/agent/send.js +6 -15
- package/dist/commands/agent/stop.js +2 -15
- package/dist/commands/agent/update.js +2 -15
- package/dist/commands/agent/wait.js +4 -15
- package/dist/commands/clone.js +2 -8
- package/dist/commands/daemon/config.d.ts +3 -0
- package/dist/commands/daemon/config.js +102 -0
- package/dist/commands/daemon/index.js +20 -52
- package/dist/commands/daemon/local-daemon.d.ts +10 -75
- package/dist/commands/daemon/local-daemon.js +61 -503
- package/dist/commands/daemon/pair.d.ts +3 -8
- package/dist/commands/daemon/pair.js +31 -61
- package/dist/commands/daemon/reload.d.ts +3 -1
- package/dist/commands/daemon/reload.js +10 -2
- package/dist/commands/daemon/restart.d.ts +19 -11
- package/dist/commands/daemon/restart.js +102 -88
- package/dist/commands/daemon/set-password.js +6 -7
- package/dist/commands/daemon/start.d.ts +17 -3
- package/dist/commands/daemon/start.js +47 -52
- package/dist/commands/daemon/status.d.ts +12 -20
- package/dist/commands/daemon/status.js +90 -342
- package/dist/commands/daemon/stop.d.ts +19 -14
- package/dist/commands/daemon/stop.js +53 -55
- package/dist/commands/heartbeat/index.js +3 -3
- package/dist/commands/hub/connect.d.ts +1 -0
- package/dist/commands/hub/connect.js +1 -1
- package/dist/commands/hub/daemon-client.d.ts +3 -2
- package/dist/commands/hub/daemon-client.js +3 -3
- package/dist/commands/hub/disconnect.d.ts +1 -0
- package/dist/commands/hub/disconnect.js +1 -1
- package/dist/commands/hub/index.js +2 -2
- package/dist/commands/hub/init.d.ts +3 -1
- package/dist/commands/hub/init.js +13 -12
- package/dist/commands/hub/login.d.ts +4 -4
- package/dist/commands/hub/login.js +1 -1
- package/dist/commands/hub/logout.d.ts +1 -0
- package/dist/commands/hub/logout.js +2 -2
- package/dist/commands/hub/permissions.d.ts +1 -0
- package/dist/commands/hub/permissions.js +2 -2
- package/dist/commands/onboard.d.ts +7 -2
- package/dist/commands/onboard.js +58 -210
- package/dist/commands/open.js +2 -0
- package/dist/commands/permit/allow.js +2 -15
- package/dist/commands/permit/deny.js +2 -15
- package/dist/commands/permit/ls.js +2 -15
- package/dist/commands/plugin/index.js +7 -7
- package/dist/commands/plugin/shared.d.ts +4 -3
- package/dist/commands/plugin/shared.js +8 -8
- package/dist/commands/project/create.js +5 -3
- package/dist/commands/project/delete.js +4 -2
- package/dist/commands/project/ls.js +2 -2
- package/dist/commands/project/rename.js +4 -2
- package/dist/commands/provider/add.js +2 -2
- package/dist/commands/provider/diagnostic.js +1 -1
- package/dist/commands/provider/ls.js +2 -30
- package/dist/commands/provider/models.js +1 -1
- package/dist/commands/provider/rm.js +2 -2
- package/dist/commands/schedule/create.js +2 -2
- package/dist/commands/schedule/delete.js +1 -1
- package/dist/commands/schedule/inspect.js +1 -1
- package/dist/commands/schedule/logs.js +1 -1
- package/dist/commands/schedule/ls.js +1 -1
- package/dist/commands/schedule/pause.js +1 -1
- package/dist/commands/schedule/resume.js +1 -1
- package/dist/commands/schedule/run-once.js +1 -1
- package/dist/commands/schedule/shared.d.ts +3 -1
- package/dist/commands/schedule/shared.js +7 -5
- package/dist/commands/schedule/update.js +1 -1
- package/dist/commands/script/ls.js +1 -1
- package/dist/commands/script/shared.d.ts +2 -1
- package/dist/commands/script/shared.js +3 -3
- package/dist/commands/script/start.js +1 -1
- package/dist/commands/script/stop.js +1 -1
- package/dist/commands/terminal/capture.d.ts +1 -1
- package/dist/commands/terminal/capture.js +2 -3
- package/dist/commands/terminal/create.js +1 -1
- package/dist/commands/terminal/kill.js +1 -1
- package/dist/commands/terminal/ls.js +1 -1
- package/dist/commands/terminal/send-keys.d.ts +1 -1
- package/dist/commands/terminal/send-keys.js +2 -3
- package/dist/commands/terminal/shared.d.ts +2 -1
- package/dist/commands/terminal/shared.js +5 -3
- package/dist/commands/workspace/archive.d.ts +1 -0
- package/dist/commands/workspace/archive.js +4 -2
- package/dist/commands/workspace/create.js +4 -2
- package/dist/commands/workspace/ls.d.ts +1 -0
- package/dist/commands/workspace/ls.js +2 -2
- package/dist/commands/workspace/rename.d.ts +1 -0
- package/dist/commands/workspace/rename.js +4 -2
- package/dist/commands/workspace/setup.d.ts +1 -0
- package/dist/commands/workspace/setup.js +2 -2
- package/dist/commands/worktree/archive.js +4 -2
- package/dist/commands/worktree/create.js +2 -10
- package/dist/commands/worktree/ls.d.ts +0 -2
- package/dist/commands/worktree/ls.js +4 -30
- package/dist/output/with-output.d.ts +2 -0
- package/dist/run.js +11 -1
- package/dist/utils/client-id.d.ts +1 -1
- package/dist/utils/client-id.js +8 -14
- package/dist/utils/client.d.ts +16 -21
- package/dist/utils/client.js +57 -109
- package/dist/utils/command-options.d.ts +1 -0
- package/dist/utils/command-options.js +24 -2
- package/dist/utils/daemon-target.d.ts +13 -0
- package/dist/utils/daemon-target.js +51 -0
- package/package.json +8 -4
package/dist/cli.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { pairCommand } from "./commands/daemon/pair.js";
|
|
1
2
|
import { Command, Option } from "commander";
|
|
2
3
|
import { createAgentCommand } from "./commands/agent/index.js";
|
|
3
4
|
import { createDaemonCommand } from "./commands/daemon/index.js";
|
|
@@ -15,9 +16,9 @@ import { createHeartbeatCommand } from "./commands/heartbeat/index.js";
|
|
|
15
16
|
import { createHubCommand } from "./commands/hub/index.js";
|
|
16
17
|
import { createHooksCommand } from "./commands/hooks.js";
|
|
17
18
|
import { startCommand as daemonStartCommand } from "./commands/daemon/start.js";
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
19
|
+
import { daemonStatusCommand } from "./commands/daemon/status.js";
|
|
20
|
+
import { daemonRestartCommand } from "./commands/daemon/restart.js";
|
|
21
|
+
import { daemonReloadCommand } from "./commands/daemon/reload.js";
|
|
21
22
|
import { addLsOptions, runLsCommand } from "./commands/agent/ls.js";
|
|
22
23
|
import { addRunOptions, runRunCommand } from "./commands/agent/run.js";
|
|
23
24
|
import { addLogsOptions, runLogsCommand } from "./commands/agent/logs.js";
|
|
@@ -32,16 +33,9 @@ import { addImportOptions, runImportCommand } from "./commands/agent/import.js";
|
|
|
32
33
|
import { withOutput } from "./output/index.js";
|
|
33
34
|
import { runCloneCommand } from "./commands/clone.js";
|
|
34
35
|
import { onboardCommand } from "./commands/onboard.js";
|
|
35
|
-
import { addDaemonHostOption, addJsonAndDaemonHostOptions,
|
|
36
|
+
import { addDaemonHostOption, addJsonAndDaemonHostOptions, withGlobalOptions, } from "./utils/command-options.js";
|
|
36
37
|
import { resolveCliVersion } from "./version.js";
|
|
37
38
|
const VERSION = resolveCliVersion();
|
|
38
|
-
function resolveHostnamesOption(hostnames, allowedHosts) {
|
|
39
|
-
if (typeof hostnames === "string")
|
|
40
|
-
return hostnames;
|
|
41
|
-
if (typeof allowedHosts === "string")
|
|
42
|
-
return allowedHosts;
|
|
43
|
-
return undefined;
|
|
44
|
-
}
|
|
45
39
|
export function createCli() {
|
|
46
40
|
const program = new Command();
|
|
47
41
|
program
|
|
@@ -78,32 +72,10 @@ export function createCli() {
|
|
|
78
72
|
program.addCommand(onboardCommand());
|
|
79
73
|
program.addCommand(daemonStartCommand());
|
|
80
74
|
program.addCommand(createHooksCommand());
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
.action(withOutput(runDaemonStatusCommand));
|
|
86
|
-
addJsonAndDaemonHostOptions(program.command("reload").description('Reload daemon config (alias for "paseo daemon reload")')).action(withOutput(runDaemonReloadCommand));
|
|
87
|
-
addJsonOption(program
|
|
88
|
-
.command("restart")
|
|
89
|
-
.description('Restart local daemon (alias for "paseo daemon restart")'))
|
|
90
|
-
.option("--home <path>", "Paseo home directory (default: ~/.paseo)")
|
|
91
|
-
.option("--timeout <seconds>", "Wait timeout before force step (default: 15)")
|
|
92
|
-
.option("--force", "Send SIGKILL if graceful stop times out")
|
|
93
|
-
.option("--listen <listen>", "Listen target for restarted daemon (host:port, port, or unix socket)")
|
|
94
|
-
.option("--port <port>", "Port for restarted daemon listen target")
|
|
95
|
-
.option("--relay", "Enable relay on restarted daemon")
|
|
96
|
-
.option("--no-relay", "Disable relay on restarted daemon")
|
|
97
|
-
.option("--no-mcp", "Disable Agent MCP on restarted daemon")
|
|
98
|
-
.option("--hostnames <hosts>", 'Daemon hostnames (comma-separated, e.g. "myhost,.example.com" or "true" for any)')
|
|
99
|
-
.addOption(new Option("--allowed-hosts <hosts>").hideHelp())
|
|
100
|
-
.action(withOutput((...args) => {
|
|
101
|
-
const [options, command] = args.slice(-2);
|
|
102
|
-
return runDaemonRestartCommand({
|
|
103
|
-
...options,
|
|
104
|
-
hostnames: resolveHostnamesOption(options.hostnames, options.allowedHosts),
|
|
105
|
-
}, command);
|
|
106
|
-
}));
|
|
75
|
+
program.addCommand(daemonStatusCommand());
|
|
76
|
+
program.addCommand(daemonRestartCommand());
|
|
77
|
+
program.addCommand(daemonReloadCommand());
|
|
78
|
+
program.addCommand(pairCommand());
|
|
107
79
|
// Advanced agent commands (less common operations)
|
|
108
80
|
program.addCommand(createAgentCommand());
|
|
109
81
|
// Daemon commands
|
|
@@ -130,6 +102,22 @@ export function createCli() {
|
|
|
130
102
|
// COMPAT(worktreeCli): legacy command alias added before workspace was the product unit.
|
|
131
103
|
// Added in v0.2.0; remove after 2027-01-17.
|
|
132
104
|
program.addCommand(createWorktreeCommand(), { hidden: true });
|
|
105
|
+
const enforceSelectorDuplicates = (command) => {
|
|
106
|
+
for (const option of command.options) {
|
|
107
|
+
if (option.long !== "--home" && option.long !== "--host")
|
|
108
|
+
continue;
|
|
109
|
+
option.argParser((value, previous) => {
|
|
110
|
+
if (previous !== undefined && previous !== value)
|
|
111
|
+
throw {
|
|
112
|
+
code: "TARGET_AMBIGUOUS",
|
|
113
|
+
message: `Conflicting duplicate ${option.long} selectors.`,
|
|
114
|
+
};
|
|
115
|
+
return value;
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
command.commands.forEach(enforceSelectorDuplicates);
|
|
119
|
+
};
|
|
120
|
+
enforceSelectorDuplicates(program);
|
|
133
121
|
return program;
|
|
134
122
|
}
|
|
135
123
|
//# sourceMappingURL=cli.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { connectToDaemon,
|
|
1
|
+
import { connectToDaemon, resolveAgentId } from "../../utils/client.js";
|
|
2
2
|
/** Schema for archive command output */
|
|
3
3
|
export const archiveSchema = {
|
|
4
4
|
idField: "agentId",
|
|
@@ -15,7 +15,6 @@ export function addArchiveOptions(cmd) {
|
|
|
15
15
|
.option("--force", "Force archive running agent (interrupts active run first)");
|
|
16
16
|
}
|
|
17
17
|
export async function runArchiveCommand(agentIdArg, options, _command) {
|
|
18
|
-
const host = getDaemonHost({ host: options.host });
|
|
19
18
|
// Validate arguments
|
|
20
19
|
if (!agentIdArg || agentIdArg.trim().length === 0) {
|
|
21
20
|
const error = {
|
|
@@ -25,19 +24,7 @@ export async function runArchiveCommand(agentIdArg, options, _command) {
|
|
|
25
24
|
};
|
|
26
25
|
throw error;
|
|
27
26
|
}
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
client = await connectToDaemon({ host: options.host });
|
|
31
|
-
}
|
|
32
|
-
catch (err) {
|
|
33
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
34
|
-
const error = {
|
|
35
|
-
code: "DAEMON_NOT_RUNNING",
|
|
36
|
-
message: `Cannot connect to daemon at ${host}: ${message}`,
|
|
37
|
-
details: "Start the daemon with: paseo daemon start",
|
|
38
|
-
};
|
|
39
|
-
throw error;
|
|
40
|
-
}
|
|
27
|
+
const client = await connectToDaemon({ target: options.daemonTarget });
|
|
41
28
|
try {
|
|
42
29
|
const agentsPayload = await client.fetchAgents({ filter: { includeArchived: true } });
|
|
43
30
|
const agents = agentsPayload.entries.map((entry) => entry.agent);
|
|
@@ -2,6 +2,7 @@ import type { Command } from "commander";
|
|
|
2
2
|
export declare function addAttachOptions(cmd: Command): Command;
|
|
3
3
|
export interface AgentAttachOptions {
|
|
4
4
|
host?: string;
|
|
5
|
+
daemonTarget: import("../../utils/daemon-target.js").DaemonTarget;
|
|
5
6
|
[key: string]: unknown;
|
|
6
7
|
}
|
|
7
8
|
/**
|
|
@@ -3,7 +3,7 @@ export function addAttachOptions(cmd) {
|
|
|
3
3
|
.description("Attach to a running agent's output stream")
|
|
4
4
|
.argument("<id>", "Agent ID (or prefix)");
|
|
5
5
|
}
|
|
6
|
-
import { connectToDaemon
|
|
6
|
+
import { connectToDaemon } from "../../utils/client.js";
|
|
7
7
|
import { fetchProjectedTimelineItems, LIVE_HISTORY_FETCH_TIMEOUT_MS, } from "../../utils/timeline.js";
|
|
8
8
|
/**
|
|
9
9
|
* Format and print a timeline item to the terminal
|
|
@@ -74,22 +74,12 @@ function printStreamEvent(event) {
|
|
|
74
74
|
* Attach to a running agent's output stream
|
|
75
75
|
*/
|
|
76
76
|
export async function runAttachCommand(id, options, _command) {
|
|
77
|
-
const host = getDaemonHost({ host: options.host });
|
|
78
77
|
if (!id) {
|
|
79
78
|
console.error("Error: Agent ID required");
|
|
80
79
|
console.error("Usage: paseo attach <id>");
|
|
81
80
|
process.exit(1);
|
|
82
81
|
}
|
|
83
|
-
|
|
84
|
-
try {
|
|
85
|
-
client = await connectToDaemon({ host: options.host });
|
|
86
|
-
}
|
|
87
|
-
catch (err) {
|
|
88
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
89
|
-
console.error(`Error: Cannot connect to daemon at ${host}: ${message}`);
|
|
90
|
-
console.error("Start the daemon with: paseo daemon start");
|
|
91
|
-
process.exit(1);
|
|
92
|
-
}
|
|
82
|
+
const client = await connectToDaemon({ target: options.daemonTarget });
|
|
93
83
|
try {
|
|
94
84
|
const fetchResult = await client.fetchAgent({ agentId: id });
|
|
95
85
|
if (!fetchResult) {
|
|
@@ -121,6 +111,12 @@ export async function runAttachCommand(id, options, _command) {
|
|
|
121
111
|
if (message.type === "agent.timeline.replacement") {
|
|
122
112
|
console.log("\n[Timeline replaced; earlier output is no longer current]");
|
|
123
113
|
}
|
|
114
|
+
else if (message.type === "agent.timeline.subscription_restored") {
|
|
115
|
+
console.log("\n[Reconnected; live output resumed. Events may have been missed.]");
|
|
116
|
+
}
|
|
117
|
+
else if (message.type === "agent.timeline.error") {
|
|
118
|
+
console.error(`Timeline observation stopped: ${message.payload.error}`);
|
|
119
|
+
}
|
|
124
120
|
else {
|
|
125
121
|
printStreamEvent(message.payload.event);
|
|
126
122
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { connectToDaemon
|
|
1
|
+
import { connectToDaemon } from "../../utils/client.js";
|
|
2
2
|
import { isSameOrDescendantPath } from "../../utils/paths.js";
|
|
3
3
|
export function addDeleteOptions(cmd) {
|
|
4
4
|
return cmd
|
|
@@ -12,7 +12,6 @@ export const deleteSchema = {
|
|
|
12
12
|
columns: [{ header: "DELETED", field: "deletedCount" }],
|
|
13
13
|
};
|
|
14
14
|
export async function runDeleteCommand(id, options, _command) {
|
|
15
|
-
const host = getDaemonHost({ host: options.host });
|
|
16
15
|
if (!id && !options.all && !options.cwd) {
|
|
17
16
|
const error = {
|
|
18
17
|
code: "MISSING_ARGUMENT",
|
|
@@ -21,19 +20,7 @@ export async function runDeleteCommand(id, options, _command) {
|
|
|
21
20
|
};
|
|
22
21
|
throw error;
|
|
23
22
|
}
|
|
24
|
-
|
|
25
|
-
try {
|
|
26
|
-
client = await connectToDaemon({ host: options.host });
|
|
27
|
-
}
|
|
28
|
-
catch (err) {
|
|
29
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
30
|
-
const error = {
|
|
31
|
-
code: "DAEMON_NOT_RUNNING",
|
|
32
|
-
message: `Cannot connect to daemon at ${host}: ${message}`,
|
|
33
|
-
details: "Start the daemon with: paseo daemon start",
|
|
34
|
-
};
|
|
35
|
-
throw error;
|
|
36
|
-
}
|
|
23
|
+
const client = await connectToDaemon({ target: options.daemonTarget });
|
|
37
24
|
try {
|
|
38
25
|
const fetchPayload = await client.fetchAgents({ filter: { includeArchived: true } });
|
|
39
26
|
let agents = fetchPayload.entries.map((entry) => entry.agent);
|
|
@@ -69,6 +56,8 @@ export async function runDeleteCommand(id, options, _command) {
|
|
|
69
56
|
return { ok: true, id: agent.id };
|
|
70
57
|
}
|
|
71
58
|
catch (err) {
|
|
59
|
+
if (err && typeof err === "object" && "code" in err)
|
|
60
|
+
throw err;
|
|
72
61
|
const message = err instanceof Error ? err.message : String(err);
|
|
73
62
|
return { ok: false, id: agent.id, message };
|
|
74
63
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { connectToDaemon,
|
|
1
|
+
import { connectToDaemon, resolveAgentId } from "../../utils/client.js";
|
|
2
2
|
const detachSchema = {
|
|
3
3
|
idField: "agentId",
|
|
4
4
|
columns: [
|
|
@@ -7,18 +7,7 @@ const detachSchema = {
|
|
|
7
7
|
],
|
|
8
8
|
};
|
|
9
9
|
export async function runDetachCommand(agentIdArg, options, _command) {
|
|
10
|
-
const
|
|
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
|
-
}
|
|
10
|
+
const client = await connectToDaemon({ target: options.daemonTarget });
|
|
22
11
|
try {
|
|
23
12
|
const payload = await client.fetchAgents({ filter: { includeArchived: true } });
|
|
24
13
|
const agentId = resolveAgentId(agentIdArg, payload.entries.map((entry) => entry.agent));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { connectToDaemon
|
|
1
|
+
import { connectToDaemon } from "../../utils/client.js";
|
|
2
2
|
import { collectMultiple } from "../../utils/command-options.js";
|
|
3
3
|
import { agentRunSchema } from "./run.js";
|
|
4
4
|
export function addImportOptions(cmd) {
|
|
@@ -66,21 +66,7 @@ export function resolveImportCwd(explicitCwd, defaultCwd) {
|
|
|
66
66
|
}
|
|
67
67
|
return cwd;
|
|
68
68
|
}
|
|
69
|
-
async function connectToDaemonOrThrow(hostOption, host) {
|
|
70
|
-
try {
|
|
71
|
-
return await connectToDaemon({ host: hostOption });
|
|
72
|
-
}
|
|
73
|
-
catch (err) {
|
|
74
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
75
|
-
throw {
|
|
76
|
-
code: "DAEMON_NOT_RUNNING",
|
|
77
|
-
message: `Cannot connect to daemon at ${host}: ${message}`,
|
|
78
|
-
details: "Start the daemon with: paseo daemon start",
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
69
|
export async function runImportCommand(sessionIdArg, options, _command) {
|
|
83
|
-
const host = getDaemonHost({ host: options.host });
|
|
84
70
|
const sessionId = sessionIdArg.trim();
|
|
85
71
|
if (!sessionId) {
|
|
86
72
|
throw {
|
|
@@ -92,7 +78,7 @@ export async function runImportCommand(sessionIdArg, options, _command) {
|
|
|
92
78
|
const provider = parseImportProvider(options.provider);
|
|
93
79
|
const cwd = resolveImportCwd(options.cwd, process.cwd());
|
|
94
80
|
const labels = parseImportLabels(options.label);
|
|
95
|
-
const client = await
|
|
81
|
+
const client = await connectToDaemon({ target: options.daemonTarget });
|
|
96
82
|
try {
|
|
97
83
|
const agent = await client.importAgent({
|
|
98
84
|
provider,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PARENT_AGENT_ID_LABEL } from "@camerontaylor/paseo-protocol/agent-labels";
|
|
2
|
-
import { connectToDaemon
|
|
2
|
+
import { connectToDaemon } from "../../utils/client.js";
|
|
3
3
|
export function addInspectOptions(cmd) {
|
|
4
4
|
return cmd
|
|
5
5
|
.description("Show detailed information about an agent")
|
|
@@ -151,7 +151,6 @@ function toInspectRows(agent) {
|
|
|
151
151
|
return rows;
|
|
152
152
|
}
|
|
153
153
|
export async function runInspectCommand(agentIdArg, options, _command) {
|
|
154
|
-
const host = getDaemonHost({ host: options.host });
|
|
155
154
|
// Validate arguments
|
|
156
155
|
if (!agentIdArg || agentIdArg.trim().length === 0) {
|
|
157
156
|
const error = {
|
|
@@ -161,19 +160,7 @@ export async function runInspectCommand(agentIdArg, options, _command) {
|
|
|
161
160
|
};
|
|
162
161
|
throw error;
|
|
163
162
|
}
|
|
164
|
-
|
|
165
|
-
try {
|
|
166
|
-
client = await connectToDaemon({ host: options.host });
|
|
167
|
-
}
|
|
168
|
-
catch (err) {
|
|
169
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
170
|
-
const error = {
|
|
171
|
-
code: "DAEMON_NOT_RUNNING",
|
|
172
|
-
message: `Cannot connect to daemon at ${host}: ${message}`,
|
|
173
|
-
details: "Start the daemon with: paseo daemon start",
|
|
174
|
-
};
|
|
175
|
-
throw error;
|
|
176
|
-
}
|
|
163
|
+
const client = await connectToDaemon({ target: options.daemonTarget });
|
|
177
164
|
try {
|
|
178
165
|
const fetchResult = await client.fetchAgent({ agentId: agentIdArg });
|
|
179
166
|
if (!fetchResult) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { connectToDaemon
|
|
1
|
+
import { connectToDaemon } from "../../utils/client.js";
|
|
2
2
|
import { fetchProjectedTimelineItems, LIVE_HISTORY_FETCH_TIMEOUT_MS, } from "../../utils/timeline.js";
|
|
3
3
|
import { curateAgentActivity } from "@camerontaylor/paseo-server";
|
|
4
4
|
export function addLogsOptions(cmd) {
|
|
@@ -53,22 +53,12 @@ function matchesFilter(item, filter) {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
export async function runLogsCommand(id, options, _command) {
|
|
56
|
-
const host = getDaemonHost({ host: options.host });
|
|
57
56
|
if (!id) {
|
|
58
57
|
console.error("Error: Agent ID required");
|
|
59
58
|
console.error("Usage: paseo agent logs <id>");
|
|
60
59
|
process.exit(1);
|
|
61
60
|
}
|
|
62
|
-
|
|
63
|
-
try {
|
|
64
|
-
client = await connectToDaemon({ host: options.host });
|
|
65
|
-
}
|
|
66
|
-
catch (err) {
|
|
67
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
68
|
-
console.error(`Error: Cannot connect to daemon at ${host}: ${message}`);
|
|
69
|
-
console.error("Start the daemon with: paseo daemon start");
|
|
70
|
-
process.exit(1);
|
|
71
|
-
}
|
|
61
|
+
const client = await connectToDaemon({ target: options.daemonTarget });
|
|
72
62
|
try {
|
|
73
63
|
const fetchResult = await client.fetchAgent({ agentId: id });
|
|
74
64
|
if (!fetchResult) {
|
|
@@ -111,6 +101,8 @@ export async function runLogsCommand(id, options, _command) {
|
|
|
111
101
|
console.log(transcript);
|
|
112
102
|
}
|
|
113
103
|
catch (err) {
|
|
104
|
+
if (err && typeof err === "object" && "code" in err)
|
|
105
|
+
throw err;
|
|
114
106
|
const message = err instanceof Error ? err.message : String(err);
|
|
115
107
|
console.error(`Error: Failed to get logs: ${message}`);
|
|
116
108
|
await client.close().catch(() => { });
|
|
@@ -151,6 +143,14 @@ async function runFollowMode(client, agentId, options) {
|
|
|
151
143
|
console.log("\n[Timeline replaced; earlier output is no longer current]");
|
|
152
144
|
return;
|
|
153
145
|
}
|
|
146
|
+
if (message.type === "agent.timeline.error") {
|
|
147
|
+
console.error(`Timeline observation stopped: ${message.payload.error}`);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (message.type === "agent.timeline.subscription_restored") {
|
|
151
|
+
console.log("\n[Reconnected; live output resumed. Events may have been missed.]");
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
154
|
if (message.payload.event.type === "timeline") {
|
|
155
155
|
const item = message.payload.event.item;
|
|
156
156
|
// Apply filter
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { connectToDaemon
|
|
1
|
+
import { connectToDaemon } from "../../utils/client.js";
|
|
2
2
|
import { collectMultiple } from "../../utils/command-options.js";
|
|
3
3
|
import { isSameOrDescendantPath } from "../../utils/paths.js";
|
|
4
4
|
export function addLsOptions(cmd) {
|
|
@@ -78,20 +78,6 @@ function toListItem(agent) {
|
|
|
78
78
|
created: relativeTime(agent.createdAt),
|
|
79
79
|
};
|
|
80
80
|
}
|
|
81
|
-
function daemonConnectionFailure(host, cause) {
|
|
82
|
-
const reason = cause instanceof Error ? cause.message : String(cause);
|
|
83
|
-
const isSsh = host.trim().startsWith("ssh://");
|
|
84
|
-
return {
|
|
85
|
-
code: "DAEMON_NOT_RUNNING",
|
|
86
|
-
message: `Cannot reach the daemon at ${host}: ${reason}`,
|
|
87
|
-
details: isSsh
|
|
88
|
-
? "Start the Paseo daemon on the SSH host; SSH transport does not install or start it."
|
|
89
|
-
: [
|
|
90
|
-
"Start a local daemon with: paseo daemon start",
|
|
91
|
-
"To use another daemon, pass --host <host:port> or set PASEO_HOST.",
|
|
92
|
-
].join("\n"),
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
81
|
function parseLabelFilters(labels) {
|
|
96
82
|
const labelFilters = {};
|
|
97
83
|
for (const labelStr of labels ?? []) {
|
|
@@ -134,14 +120,7 @@ export function buildAgentLsFetchOptions(options) {
|
|
|
134
120
|
* - `paseo agent ls -ag` → global agents, including archived
|
|
135
121
|
*/
|
|
136
122
|
export async function runLsCommand(options, _command) {
|
|
137
|
-
const
|
|
138
|
-
let client;
|
|
139
|
-
try {
|
|
140
|
-
client = await connectToDaemon({ host: options.host });
|
|
141
|
-
}
|
|
142
|
-
catch (err) {
|
|
143
|
-
throw daemonConnectionFailure(host, err);
|
|
144
|
-
}
|
|
123
|
+
const client = await connectToDaemon({ target: options.daemonTarget });
|
|
145
124
|
try {
|
|
146
125
|
const normalizedThinkingOptionId = options.thinking?.trim();
|
|
147
126
|
if (options.thinking !== undefined && !normalizedThinkingOptionId) {
|
|
@@ -23,14 +23,14 @@ const missingModeError = () => ({
|
|
|
23
23
|
});
|
|
24
24
|
export async function runModeCommand(id, mode, options, _command) {
|
|
25
25
|
const normalizedMode = mode?.trim();
|
|
26
|
-
const host = getDaemonHost({
|
|
26
|
+
const host = getDaemonHost({ target: options.daemonTarget });
|
|
27
27
|
// Validate arguments
|
|
28
28
|
if (!options.list && !normalizedMode) {
|
|
29
29
|
throw missingModeError();
|
|
30
30
|
}
|
|
31
31
|
let client;
|
|
32
32
|
try {
|
|
33
|
-
client = await connectToDaemon({
|
|
33
|
+
client = await connectToDaemon({ target: options.daemonTarget });
|
|
34
34
|
const fetchResult = await client.fetchAgent({ agentId: id });
|
|
35
35
|
if (!fetchResult) {
|
|
36
36
|
const error = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { connectToDaemon } from "../../utils/client.js";
|
|
2
2
|
import { openDesktopWithAgent } from "../open.js";
|
|
3
3
|
const openAgentSchema = {
|
|
4
4
|
idField: "agentId",
|
|
@@ -19,13 +19,7 @@ async function resolveServerId(options) {
|
|
|
19
19
|
if (explicitServerId) {
|
|
20
20
|
return explicitServerId;
|
|
21
21
|
}
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
client = await connectToDaemon({ host: options.host });
|
|
25
|
-
}
|
|
26
|
-
catch (error) {
|
|
27
|
-
throw buildDaemonConnectionCommandError({ host: options.host, error });
|
|
28
|
-
}
|
|
22
|
+
const client = await connectToDaemon({ target: options.daemonTarget });
|
|
29
23
|
try {
|
|
30
24
|
const serverId = client.getLastServerInfoMessage()?.serverId.trim();
|
|
31
25
|
if (!serverId) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { connectToDaemon,
|
|
1
|
+
import { connectToDaemon, resolveAgentId } from "../../utils/client.js";
|
|
2
2
|
export const reloadSchema = {
|
|
3
3
|
idField: "agentId",
|
|
4
4
|
columns: [
|
|
@@ -13,7 +13,6 @@ export function addReloadOptions(cmd) {
|
|
|
13
13
|
.argument("<id>", "Agent ID, prefix, or name");
|
|
14
14
|
}
|
|
15
15
|
export async function runReloadCommand(agentIdArg, options, _command) {
|
|
16
|
-
const host = getDaemonHost({ host: options.host });
|
|
17
16
|
if (!agentIdArg || agentIdArg.trim().length === 0) {
|
|
18
17
|
const error = {
|
|
19
18
|
code: "MISSING_AGENT_ID",
|
|
@@ -22,19 +21,7 @@ export async function runReloadCommand(agentIdArg, options, _command) {
|
|
|
22
21
|
};
|
|
23
22
|
throw error;
|
|
24
23
|
}
|
|
25
|
-
|
|
26
|
-
try {
|
|
27
|
-
client = await connectToDaemon({ host: options.host });
|
|
28
|
-
}
|
|
29
|
-
catch (err) {
|
|
30
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
31
|
-
const error = {
|
|
32
|
-
code: "DAEMON_NOT_RUNNING",
|
|
33
|
-
message: `Cannot connect to daemon at ${host}: ${message}`,
|
|
34
|
-
details: "Start the daemon with: paseo daemon start",
|
|
35
|
-
};
|
|
36
|
-
throw error;
|
|
37
|
-
}
|
|
24
|
+
const client = await connectToDaemon({ target: options.daemonTarget });
|
|
38
25
|
try {
|
|
39
26
|
const agentsPayload = await client.fetchAgents({ filter: { includeArchived: true } });
|
|
40
27
|
const agents = agentsPayload.entries.map((entry) => entry.agent);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Option } from "commander";
|
|
2
2
|
import { getStructuredAgentResponse, StructuredAgentResponseError } from "@camerontaylor/paseo-server";
|
|
3
|
-
import { connectToDaemon
|
|
3
|
+
import { connectToDaemon } from "../../utils/client.js";
|
|
4
4
|
import { readFileSync } from "node:fs";
|
|
5
5
|
import { resolve } from "node:path";
|
|
6
6
|
import { lookup } from "mime-types";
|
|
@@ -57,6 +57,7 @@ function resolveNewWorkspaceKind(options) {
|
|
|
57
57
|
function buildRunWorkspaceSource(options, cwd) {
|
|
58
58
|
const newWorkspace = resolveNewWorkspaceKind(options) ?? "local";
|
|
59
59
|
return buildWorkspaceSource({
|
|
60
|
+
daemonTarget: options.daemonTarget,
|
|
60
61
|
isolation: newWorkspace,
|
|
61
62
|
path: cwd,
|
|
62
63
|
mode: options.worktreeMode,
|
|
@@ -93,6 +94,8 @@ function loadOutputSchema(value) {
|
|
|
93
94
|
source = readFileSync(resolve(trimmed), "utf8");
|
|
94
95
|
}
|
|
95
96
|
catch (err) {
|
|
97
|
+
if (err && typeof err === "object" && "code" in err)
|
|
98
|
+
throw err;
|
|
96
99
|
const message = err instanceof Error ? err.message : String(err);
|
|
97
100
|
const error = {
|
|
98
101
|
code: "INVALID_OUTPUT_SCHEMA",
|
|
@@ -107,6 +110,8 @@ function loadOutputSchema(value) {
|
|
|
107
110
|
parsed = JSON.parse(source);
|
|
108
111
|
}
|
|
109
112
|
catch (err) {
|
|
113
|
+
if (err && typeof err === "object" && "code" in err)
|
|
114
|
+
throw err;
|
|
110
115
|
const message = err instanceof Error ? err.message : String(err);
|
|
111
116
|
const error = {
|
|
112
117
|
code: "INVALID_OUTPUT_SCHEMA",
|
|
@@ -285,6 +290,8 @@ function parseWaitTimeoutOption(waitTimeout) {
|
|
|
285
290
|
return ms;
|
|
286
291
|
}
|
|
287
292
|
catch (err) {
|
|
293
|
+
if (err && typeof err === "object" && "code" in err)
|
|
294
|
+
throw err;
|
|
288
295
|
const message = err instanceof Error ? err.message : String(err);
|
|
289
296
|
throw {
|
|
290
297
|
code: "INVALID_TIMEOUT",
|
|
@@ -310,6 +317,8 @@ function loadRunImages(imagePaths) {
|
|
|
310
317
|
};
|
|
311
318
|
}
|
|
312
319
|
catch (err) {
|
|
320
|
+
if (err && typeof err === "object" && "code" in err)
|
|
321
|
+
throw err;
|
|
313
322
|
const message = err instanceof Error ? err.message : String(err);
|
|
314
323
|
throw new Error(`Failed to read image ${imagePath}: ${message}`, { cause: err });
|
|
315
324
|
}
|
|
@@ -349,19 +358,6 @@ function parseKeyValueFlags(flags, options) {
|
|
|
349
358
|
}
|
|
350
359
|
return labels;
|
|
351
360
|
}
|
|
352
|
-
async function connectToDaemonOrThrow(hostOption, host) {
|
|
353
|
-
try {
|
|
354
|
-
return await connectToDaemon({ host: hostOption });
|
|
355
|
-
}
|
|
356
|
-
catch (err) {
|
|
357
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
358
|
-
throw {
|
|
359
|
-
code: "DAEMON_NOT_RUNNING",
|
|
360
|
-
message: `Cannot connect to daemon at ${host}: ${message}`,
|
|
361
|
-
details: "Start the daemon with: paseo daemon start",
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
361
|
export async function resolveExistingRunWorkspace(client, workspaceId) {
|
|
366
362
|
const result = await client.fetchWorkspaces({
|
|
367
363
|
filter: { query: workspaceId },
|
|
@@ -416,13 +412,12 @@ async function resolveRunWorkspace(client, options, cwd) {
|
|
|
416
412
|
return { id: result.workspace.id, cwd: result.workspace.workspaceDirectory ?? cwd };
|
|
417
413
|
}
|
|
418
414
|
export async function runRunCommand(prompt, options, _command) {
|
|
419
|
-
const host = getDaemonHost({ host: options.host });
|
|
420
415
|
const outputSchema = options.outputSchema ? loadOutputSchema(options.outputSchema) : undefined;
|
|
421
416
|
validateRunOptions(prompt, options, outputSchema);
|
|
422
417
|
const waitTimeoutMs = parseWaitTimeoutOption(options.waitTimeout);
|
|
423
418
|
const resolvedProviderModel = resolveProviderAndModel(options);
|
|
424
419
|
const resolvedTitle = options.title ?? options.name;
|
|
425
|
-
const client = await
|
|
420
|
+
const client = await connectToDaemon({ target: options.daemonTarget });
|
|
426
421
|
try {
|
|
427
422
|
// Resolve working directory
|
|
428
423
|
const cwd = options.cwd ?? process.cwd();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { collectMultiple } from "../../utils/command-options.js";
|
|
2
|
-
import { connectToDaemon
|
|
2
|
+
import { connectToDaemon } from "../../utils/client.js";
|
|
3
3
|
import { readFile } from "node:fs/promises";
|
|
4
4
|
import { extname, resolve } from "node:path";
|
|
5
5
|
/** Schema for agent send output */
|
|
@@ -50,6 +50,8 @@ async function readImageFiles(imagePaths) {
|
|
|
50
50
|
return { data: buffer.toString("base64"), mimeType };
|
|
51
51
|
}
|
|
52
52
|
catch (err) {
|
|
53
|
+
if (err && typeof err === "object" && "code" in err)
|
|
54
|
+
throw err;
|
|
53
55
|
const message = err instanceof Error ? err.message : String(err);
|
|
54
56
|
throw {
|
|
55
57
|
code: "IMAGE_READ_ERROR",
|
|
@@ -89,6 +91,8 @@ async function resolvePromptInput(options) {
|
|
|
89
91
|
return await readFile(resolve(promptFilePath), "utf8");
|
|
90
92
|
}
|
|
91
93
|
catch (err) {
|
|
94
|
+
if (err && typeof err === "object" && "code" in err)
|
|
95
|
+
throw err;
|
|
92
96
|
const message = err instanceof Error ? err.message : String(err);
|
|
93
97
|
const error = {
|
|
94
98
|
code: "PROMPT_FILE_READ_ERROR",
|
|
@@ -116,7 +120,6 @@ function buildSendResult(agentIdArg, state) {
|
|
|
116
120
|
return { agentId, status: "completed", message: "Agent completed processing the message" };
|
|
117
121
|
}
|
|
118
122
|
export async function runSendCommand(agentIdArg, prompt, options, _command) {
|
|
119
|
-
const host = getDaemonHost({ host: options.host });
|
|
120
123
|
// Validate arguments
|
|
121
124
|
if (!agentIdArg || agentIdArg.trim().length === 0) {
|
|
122
125
|
const error = {
|
|
@@ -131,19 +134,7 @@ export async function runSendCommand(agentIdArg, prompt, options, _command) {
|
|
|
131
134
|
promptOption: options.prompt,
|
|
132
135
|
promptFile: options.promptFile,
|
|
133
136
|
});
|
|
134
|
-
|
|
135
|
-
try {
|
|
136
|
-
client = await connectToDaemon({ host: options.host });
|
|
137
|
-
}
|
|
138
|
-
catch (err) {
|
|
139
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
140
|
-
const error = {
|
|
141
|
-
code: "DAEMON_NOT_RUNNING",
|
|
142
|
-
message: `Cannot connect to daemon at ${host}: ${message}`,
|
|
143
|
-
details: "Start the daemon with: paseo daemon start",
|
|
144
|
-
};
|
|
145
|
-
throw error;
|
|
146
|
-
}
|
|
137
|
+
const client = await connectToDaemon({ target: options.daemonTarget });
|
|
147
138
|
try {
|
|
148
139
|
// Read image files if provided
|
|
149
140
|
const images = options.image && options.image.length > 0 ? await readImageFiles(options.image) : undefined;
|