@camerontaylor/paseo-cli 0.8.0-fork.1
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/bin/paseo +3 -0
- package/dist/classify.d.ts +19 -0
- package/dist/classify.js +49 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +135 -0
- package/dist/commands/agent/archive.d.ts +18 -0
- package/dist/commands/agent/archive.js +102 -0
- package/dist/commands/agent/attach.d.ts +11 -0
- package/dist/commands/agent/attach.js +161 -0
- package/dist/commands/agent/delete.d.ts +15 -0
- package/dist/commands/agent/delete.js +107 -0
- package/dist/commands/agent/detach.d.ts +9 -0
- package/dist/commands/agent/detach.js +38 -0
- package/dist/commands/agent/import.d.ts +14 -0
- package/dist/commands/agent/import.js +122 -0
- package/dist/commands/agent/index.d.ts +3 -0
- package/dist/commands/agent/index.js +56 -0
- package/dist/commands/agent/inspect.d.ts +15 -0
- package/dist/commands/agent/inspect.js +209 -0
- package/dist/commands/agent/logs.d.ts +19 -0
- package/dist/commands/agent/logs.js +180 -0
- package/dist/commands/agent/ls.d.ts +44 -0
- package/dist/commands/agent/ls.js +212 -0
- package/dist/commands/agent/mode.d.ts +18 -0
- package/dist/commands/agent/mode.js +100 -0
- package/dist/commands/agent/open.d.ts +11 -0
- package/dist/commands/agent/open.js +61 -0
- package/dist/commands/agent/reload.d.ts +15 -0
- package/dist/commands/agent/reload.js +75 -0
- package/dist/commands/agent/run.d.ts +78 -0
- package/dist/commands/agent/run.js +554 -0
- package/dist/commands/agent/send.d.ts +19 -0
- package/dist/commands/agent/send.js +187 -0
- package/dist/commands/agent/stop.d.ts +17 -0
- package/dist/commands/agent/stop.js +115 -0
- package/dist/commands/agent/update.d.ts +51 -0
- package/dist/commands/agent/update.js +186 -0
- package/dist/commands/agent/wait.d.ts +17 -0
- package/dist/commands/agent/wait.js +158 -0
- package/dist/commands/clone.d.ts +17 -0
- package/dist/commands/clone.js +65 -0
- package/dist/commands/daemon/index.d.ts +3 -0
- package/dist/commands/daemon/index.js +60 -0
- package/dist/commands/daemon/local-daemon.d.ts +78 -0
- package/dist/commands/daemon/local-daemon.js +547 -0
- package/dist/commands/daemon/pair.d.ts +35 -0
- package/dist/commands/daemon/pair.js +167 -0
- package/dist/commands/daemon/reload.d.ts +10 -0
- package/dist/commands/daemon/reload.js +36 -0
- package/dist/commands/daemon/restart.d.ts +12 -0
- package/dist/commands/daemon/restart.js +99 -0
- package/dist/commands/daemon/runtime-toolchain.d.ts +6 -0
- package/dist/commands/daemon/runtime-toolchain.js +87 -0
- package/dist/commands/daemon/set-password.d.ts +17 -0
- package/dist/commands/daemon/set-password.js +82 -0
- package/dist/commands/daemon/start.d.ts +6 -0
- package/dist/commands/daemon/start.js +57 -0
- package/dist/commands/daemon/status.d.ts +21 -0
- package/dist/commands/daemon/status.js +363 -0
- package/dist/commands/daemon/stop.d.ts +15 -0
- package/dist/commands/daemon/stop.js +60 -0
- package/dist/commands/heartbeat/index.d.ts +3 -0
- package/dist/commands/heartbeat/index.js +139 -0
- package/dist/commands/hooks.d.ts +19 -0
- package/dist/commands/hooks.js +89 -0
- package/dist/commands/hub/authority.d.ts +17 -0
- package/dist/commands/hub/authority.js +18 -0
- package/dist/commands/hub/connect.d.ts +23 -0
- package/dist/commands/hub/connect.js +44 -0
- package/dist/commands/hub/credentials.d.ts +21 -0
- package/dist/commands/hub/credentials.js +143 -0
- package/dist/commands/hub/daemon-client.d.ts +40 -0
- package/dist/commands/hub/daemon-client.js +14 -0
- package/dist/commands/hub/deploy-bundle.d.ts +16 -0
- package/dist/commands/hub/deploy-bundle.js +248 -0
- package/dist/commands/hub/deploy-triggers.d.ts +6 -0
- package/dist/commands/hub/deploy-triggers.js +116 -0
- package/dist/commands/hub/deploy.d.ts +50 -0
- package/dist/commands/hub/deploy.js +159 -0
- package/dist/commands/hub/disconnect.d.ts +16 -0
- package/dist/commands/hub/disconnect.js +24 -0
- package/dist/commands/hub/error.d.ts +6 -0
- package/dist/commands/hub/error.js +9 -0
- package/dist/commands/hub/export.d.ts +28 -0
- package/dist/commands/hub/export.js +80 -0
- package/dist/commands/hub/help.d.ts +3 -0
- package/dist/commands/hub/help.js +5 -0
- package/dist/commands/hub/hub-client/index.d.ts +22 -0
- package/dist/commands/hub/hub-client/index.js +135 -0
- package/dist/commands/hub/hub-client/internal/contracts.d.ts +126 -0
- package/dist/commands/hub/hub-client/internal/contracts.js +85 -0
- package/dist/commands/hub/hub-client/internal/problem.d.ts +3 -0
- package/dist/commands/hub/hub-client/internal/problem.js +85 -0
- package/dist/commands/hub/hub-client/internal/transport.d.ts +15 -0
- package/dist/commands/hub/hub-client/internal/transport.js +30 -0
- package/dist/commands/hub/index.d.ts +20 -0
- package/dist/commands/hub/index.js +94 -0
- package/dist/commands/hub/init-plan.d.ts +33 -0
- package/dist/commands/hub/init-plan.js +94 -0
- package/dist/commands/hub/init.d.ts +35 -0
- package/dist/commands/hub/init.js +524 -0
- package/dist/commands/hub/login-flow.d.ts +34 -0
- package/dist/commands/hub/login-flow.js +78 -0
- package/dist/commands/hub/login.d.ts +23 -0
- package/dist/commands/hub/login.js +40 -0
- package/dist/commands/hub/logout.d.ts +32 -0
- package/dist/commands/hub/logout.js +71 -0
- package/dist/commands/hub/origin.d.ts +2 -0
- package/dist/commands/hub/origin.js +27 -0
- package/dist/commands/hub/permissions.d.ts +21 -0
- package/dist/commands/hub/permissions.js +61 -0
- package/dist/commands/hub/projects.d.ts +24 -0
- package/dist/commands/hub/projects.js +49 -0
- package/dist/commands/hub/reporter.d.ts +10 -0
- package/dist/commands/hub/reporter.js +11 -0
- package/dist/commands/hub/starter-agent-runtime.d.ts +37 -0
- package/dist/commands/hub/starter-agent-runtime.js +49 -0
- package/dist/commands/hub/starter-trigger.d.ts +10 -0
- package/dist/commands/hub/starter-trigger.js +30 -0
- package/dist/commands/hub/status-output.d.ts +13 -0
- package/dist/commands/hub/status-output.js +30 -0
- package/dist/commands/onboard.d.ts +10 -0
- package/dist/commands/onboard.js +400 -0
- package/dist/commands/open.d.ts +4 -0
- package/dist/commands/open.js +89 -0
- package/dist/commands/permit/allow.d.ts +20 -0
- package/dist/commands/permit/allow.js +133 -0
- package/dist/commands/permit/deny.d.ts +12 -0
- package/dist/commands/permit/deny.js +105 -0
- package/dist/commands/permit/index.d.ts +3 -0
- package/dist/commands/permit/index.js +27 -0
- package/dist/commands/permit/ls.d.ts +18 -0
- package/dist/commands/permit/ls.js +66 -0
- package/dist/commands/plugin/index.d.ts +17 -0
- package/dist/commands/plugin/index.js +138 -0
- package/dist/commands/plugin/scaffold.d.ts +6 -0
- package/dist/commands/plugin/scaffold.js +162 -0
- package/dist/commands/plugin/shared.d.ts +5 -0
- package/dist/commands/plugin/shared.js +30 -0
- package/dist/commands/project/create.d.ts +10 -0
- package/dist/commands/project/create.js +41 -0
- package/dist/commands/project/delete.d.ts +9 -0
- package/dist/commands/project/delete.js +33 -0
- package/dist/commands/project/index.d.ts +3 -0
- package/dist/commands/project/index.js +28 -0
- package/dist/commands/project/ls.d.ts +5 -0
- package/dist/commands/project/ls.js +19 -0
- package/dist/commands/project/rename.d.ts +15 -0
- package/dist/commands/project/rename.js +50 -0
- package/dist/commands/project/shared.d.ts +11 -0
- package/dist/commands/project/shared.js +18 -0
- package/dist/commands/provider/add.d.ts +30 -0
- package/dist/commands/provider/add.js +123 -0
- package/dist/commands/provider/diagnostic.d.ts +12 -0
- package/dist/commands/provider/diagnostic.js +31 -0
- package/dist/commands/provider/index.d.ts +3 -0
- package/dist/commands/provider/index.js +38 -0
- package/dist/commands/provider/ls.d.ts +20 -0
- package/dist/commands/provider/ls.js +76 -0
- package/dist/commands/provider/models.d.ts +20 -0
- package/dist/commands/provider/models.js +53 -0
- package/dist/commands/provider/rm.d.ts +10 -0
- package/dist/commands/provider/rm.js +45 -0
- package/dist/commands/provider/shared.d.ts +7 -0
- package/dist/commands/provider/shared.js +10 -0
- package/dist/commands/schedule/create.d.ts +19 -0
- package/dist/commands/schedule/create.js +41 -0
- package/dist/commands/schedule/delete.d.ts +10 -0
- package/dist/commands/schedule/delete.js +32 -0
- package/dist/commands/schedule/index.d.ts +3 -0
- package/dist/commands/schedule/index.js +66 -0
- package/dist/commands/schedule/inspect.d.ts +6 -0
- package/dist/commands/schedule/inspect.js +27 -0
- package/dist/commands/schedule/logs.d.ts +6 -0
- package/dist/commands/schedule/logs.js +24 -0
- package/dist/commands/schedule/ls.d.ts +5 -0
- package/dist/commands/schedule/ls.js +25 -0
- package/dist/commands/schedule/pause.d.ts +5 -0
- package/dist/commands/schedule/pause.js +24 -0
- package/dist/commands/schedule/resume.d.ts +5 -0
- package/dist/commands/schedule/resume.js +24 -0
- package/dist/commands/schedule/run-once.d.ts +5 -0
- package/dist/commands/schedule/run-once.js +24 -0
- package/dist/commands/schedule/schema.d.ts +21 -0
- package/dist/commands/schedule/schema.js +67 -0
- package/dist/commands/schedule/shared.d.ts +59 -0
- package/dist/commands/schedule/shared.js +358 -0
- package/dist/commands/schedule/types.d.ts +165 -0
- package/dist/commands/schedule/types.js +2 -0
- package/dist/commands/schedule/update.d.ts +21 -0
- package/dist/commands/schedule/update.js +40 -0
- package/dist/commands/script/index.d.ts +3 -0
- package/dist/commands/script/index.js +19 -0
- package/dist/commands/script/ls.d.ts +6 -0
- package/dist/commands/script/ls.js +20 -0
- package/dist/commands/script/schema.d.ts +5 -0
- package/dist/commands/script/schema.js +13 -0
- package/dist/commands/script/shared.d.ts +11 -0
- package/dist/commands/script/shared.js +59 -0
- package/dist/commands/script/start.d.ts +6 -0
- package/dist/commands/script/start.js +23 -0
- package/dist/commands/script/stop.d.ts +6 -0
- package/dist/commands/script/stop.js +23 -0
- package/dist/commands/speech/index.d.ts +3 -0
- package/dist/commands/speech/index.js +5 -0
- package/dist/commands/terminal/capture.d.ts +10 -0
- package/dist/commands/terminal/capture.js +68 -0
- package/dist/commands/terminal/create.d.ts +11 -0
- package/dist/commands/terminal/create.js +29 -0
- package/dist/commands/terminal/index.d.ts +3 -0
- package/dist/commands/terminal/index.js +45 -0
- package/dist/commands/terminal/kill.d.ts +6 -0
- package/dist/commands/terminal/kill.js +36 -0
- package/dist/commands/terminal/ls.d.ts +11 -0
- package/dist/commands/terminal/ls.js +21 -0
- package/dist/commands/terminal/schema.d.ts +10 -0
- package/dist/commands/terminal/schema.js +17 -0
- package/dist/commands/terminal/send-keys.d.ts +7 -0
- package/dist/commands/terminal/send-keys.js +45 -0
- package/dist/commands/terminal/shared.d.ts +12 -0
- package/dist/commands/terminal/shared.js +62 -0
- 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 +45 -0
- package/dist/commands/workspace/ls.d.ts +7 -0
- package/dist/commands/workspace/ls.js +28 -0
- package/dist/commands/workspace/rename.d.ts +22 -0
- package/dist/commands/workspace/rename.js +61 -0
- package/dist/commands/workspace/setup.d.ts +11 -0
- package/dist/commands/workspace/setup.js +41 -0
- package/dist/commands/workspace/shared.d.ts +12 -0
- package/dist/commands/workspace/shared.js +20 -0
- package/dist/commands/worktree/archive.d.ts +20 -0
- package/dist/commands/worktree/archive.js +104 -0
- package/dist/commands/worktree/create-input.d.ts +15 -0
- package/dist/commands/worktree/create-input.js +56 -0
- package/dist/commands/worktree/create.d.ts +11 -0
- package/dist/commands/worktree/create.js +58 -0
- package/dist/commands/worktree/index.d.ts +3 -0
- package/dist/commands/worktree/index.js +25 -0
- package/dist/commands/worktree/ls.d.ts +19 -0
- package/dist/commands/worktree/ls.js +97 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +6 -0
- package/dist/output/index.d.ts +45 -0
- package/dist/output/index.js +47 -0
- package/dist/output/json.d.ts +11 -0
- package/dist/output/json.js +37 -0
- package/dist/output/pairing.d.ts +8 -0
- package/dist/output/pairing.js +24 -0
- package/dist/output/quiet.d.ts +9 -0
- package/dist/output/quiet.js +22 -0
- package/dist/output/render.d.ts +15 -0
- package/dist/output/render.js +84 -0
- package/dist/output/table.d.ts +13 -0
- package/dist/output/table.js +135 -0
- package/dist/output/types.d.ts +73 -0
- package/dist/output/types.js +8 -0
- package/dist/output/with-output.d.ts +41 -0
- package/dist/output/with-output.js +85 -0
- package/dist/output/yaml.d.ts +11 -0
- package/dist/output/yaml.js +38 -0
- package/dist/run.d.ts +14 -0
- package/dist/run.js +40 -0
- package/dist/ssh/ssh-tunnel.d.ts +9 -0
- package/dist/ssh/ssh-tunnel.js +79 -0
- package/dist/utils/client-id.d.ts +2 -0
- package/dist/utils/client-id.js +37 -0
- package/dist/utils/client.d.ts +54 -0
- package/dist/utils/client.js +363 -0
- package/dist/utils/command-options.d.ts +7 -0
- package/dist/utils/command-options.js +25 -0
- package/dist/utils/duration.d.ts +7 -0
- package/dist/utils/duration.js +39 -0
- package/dist/utils/errors.d.ts +5 -0
- package/dist/utils/errors.js +10 -0
- package/dist/utils/paths.d.ts +12 -0
- package/dist/utils/paths.js +22 -0
- package/dist/utils/provider-model.d.ts +11 -0
- package/dist/utils/provider-model.js +49 -0
- package/dist/utils/timeline.d.ts +11 -0
- package/dist/utils/timeline.js +11 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +10 -0
- package/package.json +50 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { collectMultiple } from "../../utils/command-options.js";
|
|
2
|
+
import { connectToDaemon, getDaemonHost } from "../../utils/client.js";
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
|
+
import { extname, resolve } from "node:path";
|
|
5
|
+
/** Schema for agent send output */
|
|
6
|
+
export const agentSendSchema = {
|
|
7
|
+
idField: "agentId",
|
|
8
|
+
columns: [
|
|
9
|
+
{ header: "AGENT ID", field: "agentId", width: 12 },
|
|
10
|
+
{ header: "STATUS", field: "status", width: 12 },
|
|
11
|
+
{ header: "MESSAGE", field: "message", width: 40 },
|
|
12
|
+
],
|
|
13
|
+
};
|
|
14
|
+
export function addSendOptions(cmd) {
|
|
15
|
+
return cmd
|
|
16
|
+
.description("Send a message/task to an existing agent")
|
|
17
|
+
.argument("<id>", "Agent ID (or prefix)")
|
|
18
|
+
.argument("[prompt]", "The message to send")
|
|
19
|
+
.option("--prompt <text>", "Provide the message inline as a flag")
|
|
20
|
+
.option("--prompt-file <path>", "Read the message from a UTF-8 text file")
|
|
21
|
+
.option("--image <path>", "Attach image(s) to the message", collectMultiple, [])
|
|
22
|
+
.option("--no-wait", "Return immediately without waiting for completion");
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Read image files and convert them to base64 data URIs
|
|
26
|
+
*/
|
|
27
|
+
async function readImageFiles(imagePaths) {
|
|
28
|
+
return Promise.all(imagePaths.map(async (path) => {
|
|
29
|
+
try {
|
|
30
|
+
const buffer = await readFile(path);
|
|
31
|
+
const ext = extname(path).toLowerCase();
|
|
32
|
+
let mimeType = "image/jpeg";
|
|
33
|
+
switch (ext) {
|
|
34
|
+
case ".png":
|
|
35
|
+
mimeType = "image/png";
|
|
36
|
+
break;
|
|
37
|
+
case ".jpg":
|
|
38
|
+
case ".jpeg":
|
|
39
|
+
mimeType = "image/jpeg";
|
|
40
|
+
break;
|
|
41
|
+
case ".gif":
|
|
42
|
+
mimeType = "image/gif";
|
|
43
|
+
break;
|
|
44
|
+
case ".webp":
|
|
45
|
+
mimeType = "image/webp";
|
|
46
|
+
break;
|
|
47
|
+
default:
|
|
48
|
+
mimeType = "image/jpeg";
|
|
49
|
+
}
|
|
50
|
+
return { data: buffer.toString("base64"), mimeType };
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
54
|
+
throw {
|
|
55
|
+
code: "IMAGE_READ_ERROR",
|
|
56
|
+
message: `Failed to read image file: ${path}`,
|
|
57
|
+
details: message,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
async function resolvePromptInput(options) {
|
|
63
|
+
const promptText = options.promptArgument?.trim();
|
|
64
|
+
const promptOptionText = options.promptOption?.trim();
|
|
65
|
+
const promptFilePath = options.promptFile?.trim();
|
|
66
|
+
const providedSourceCount = [promptText, promptOptionText, promptFilePath].filter(Boolean).length;
|
|
67
|
+
if (providedSourceCount > 1) {
|
|
68
|
+
const error = {
|
|
69
|
+
code: "CONFLICTING_PROMPT_INPUT",
|
|
70
|
+
message: "Provide exactly one of prompt argument, --prompt, or --prompt-file",
|
|
71
|
+
};
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
if (promptText) {
|
|
75
|
+
return options.promptArgument;
|
|
76
|
+
}
|
|
77
|
+
if (promptOptionText) {
|
|
78
|
+
return options.promptOption;
|
|
79
|
+
}
|
|
80
|
+
if (!promptFilePath) {
|
|
81
|
+
const error = {
|
|
82
|
+
code: "MISSING_PROMPT",
|
|
83
|
+
message: "A prompt is required",
|
|
84
|
+
details: "Usage: paseo agent send [options] <id> [prompt] | --prompt <text> | --prompt-file <path>",
|
|
85
|
+
};
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
return await readFile(resolve(promptFilePath), "utf8");
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
93
|
+
const error = {
|
|
94
|
+
code: "PROMPT_FILE_READ_ERROR",
|
|
95
|
+
message: `Failed to read prompt file: ${promptFilePath}`,
|
|
96
|
+
details: message,
|
|
97
|
+
};
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function buildSendResult(agentIdArg, state) {
|
|
102
|
+
const agentId = state.final?.id ?? agentIdArg;
|
|
103
|
+
if (state.status === "timeout") {
|
|
104
|
+
return { agentId, status: "timeout", message: "Timed out waiting for agent to finish" };
|
|
105
|
+
}
|
|
106
|
+
if (state.status === "permission") {
|
|
107
|
+
return { agentId, status: "permission", message: "Agent is waiting for permission" };
|
|
108
|
+
}
|
|
109
|
+
if (state.status === "error") {
|
|
110
|
+
return {
|
|
111
|
+
agentId,
|
|
112
|
+
status: "error",
|
|
113
|
+
message: state.error ?? "Agent finished with error",
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
return { agentId, status: "completed", message: "Agent completed processing the message" };
|
|
117
|
+
}
|
|
118
|
+
export async function runSendCommand(agentIdArg, prompt, options, _command) {
|
|
119
|
+
const host = getDaemonHost({ host: options.host });
|
|
120
|
+
// Validate arguments
|
|
121
|
+
if (!agentIdArg || agentIdArg.trim().length === 0) {
|
|
122
|
+
const error = {
|
|
123
|
+
code: "MISSING_AGENT_ID",
|
|
124
|
+
message: "Agent ID is required",
|
|
125
|
+
details: "Usage: paseo agent send [options] <id> [prompt]",
|
|
126
|
+
};
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
const promptInput = await resolvePromptInput({
|
|
130
|
+
promptArgument: prompt,
|
|
131
|
+
promptOption: options.prompt,
|
|
132
|
+
promptFile: options.promptFile,
|
|
133
|
+
});
|
|
134
|
+
let client;
|
|
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
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
// Read image files if provided
|
|
149
|
+
const images = options.image && options.image.length > 0 ? await readImageFiles(options.image) : undefined;
|
|
150
|
+
// Send the message
|
|
151
|
+
await client.sendAgentMessage(agentIdArg, promptInput, { images });
|
|
152
|
+
// If --no-wait, return immediately
|
|
153
|
+
if (options.wait === false) {
|
|
154
|
+
await client.close();
|
|
155
|
+
return {
|
|
156
|
+
type: "single",
|
|
157
|
+
data: {
|
|
158
|
+
agentId: agentIdArg,
|
|
159
|
+
status: "sent",
|
|
160
|
+
message: "Message sent, not waiting for completion",
|
|
161
|
+
},
|
|
162
|
+
schema: agentSendSchema,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
const state = await client.waitForFinish(agentIdArg, 600000); // 10 minute timeout
|
|
166
|
+
await client.close();
|
|
167
|
+
return {
|
|
168
|
+
type: "single",
|
|
169
|
+
data: buildSendResult(agentIdArg, state),
|
|
170
|
+
schema: agentSendSchema,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
await client.close().catch(() => { });
|
|
175
|
+
// Re-throw CommandError as-is
|
|
176
|
+
if (err && typeof err === "object" && "code" in err) {
|
|
177
|
+
throw err;
|
|
178
|
+
}
|
|
179
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
180
|
+
const error = {
|
|
181
|
+
code: "SEND_FAILED",
|
|
182
|
+
message: `Failed to send message: ${message}`,
|
|
183
|
+
};
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=send.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import type { CommandOptions, SingleResult, OutputSchema } from "../../output/index.js";
|
|
3
|
+
/** Result type for agent stop command */
|
|
4
|
+
export interface StopResult {
|
|
5
|
+
stoppedCount: number;
|
|
6
|
+
agentIds: string[];
|
|
7
|
+
}
|
|
8
|
+
/** Schema for stop command output */
|
|
9
|
+
export declare const stopSchema: OutputSchema<StopResult>;
|
|
10
|
+
export declare function addStopOptions(cmd: Command): Command;
|
|
11
|
+
export interface AgentStopOptions extends CommandOptions {
|
|
12
|
+
all?: boolean;
|
|
13
|
+
cwd?: string;
|
|
14
|
+
}
|
|
15
|
+
export type AgentStopResult = SingleResult<StopResult>;
|
|
16
|
+
export declare function runStopCommand(id: string | undefined, options: AgentStopOptions, _command: Command): Promise<AgentStopResult>;
|
|
17
|
+
//# sourceMappingURL=stop.d.ts.map
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { connectToDaemon, getDaemonHost } from "../../utils/client.js";
|
|
2
|
+
import { isSameOrDescendantPath } from "../../utils/paths.js";
|
|
3
|
+
/** Schema for stop command output */
|
|
4
|
+
export const stopSchema = {
|
|
5
|
+
// For quiet mode, output the stopped agent IDs (one per line)
|
|
6
|
+
idField: (item) => item.agentIds.join("\n"),
|
|
7
|
+
columns: [{ header: "INTERRUPTED", field: "stoppedCount" }],
|
|
8
|
+
};
|
|
9
|
+
export function addStopOptions(cmd) {
|
|
10
|
+
return cmd
|
|
11
|
+
.description("Interrupt an agent if it is running (no-op for idle agents)")
|
|
12
|
+
.argument("[id]", "Agent ID (or prefix) - optional if --all or --cwd specified")
|
|
13
|
+
.option("--all", "Stop all agents")
|
|
14
|
+
.option("--cwd <path>", "Stop all agents in directory");
|
|
15
|
+
}
|
|
16
|
+
export async function runStopCommand(id, options, _command) {
|
|
17
|
+
const host = getDaemonHost({ host: options.host });
|
|
18
|
+
// Validate arguments - need either an id, --all, or --cwd
|
|
19
|
+
if (!id && !options.all && !options.cwd) {
|
|
20
|
+
const error = {
|
|
21
|
+
code: "MISSING_ARGUMENT",
|
|
22
|
+
message: "Agent ID required unless --all or --cwd is specified",
|
|
23
|
+
details: "Usage: paseo agent stop <id> | --all | --cwd <path>",
|
|
24
|
+
};
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
let client;
|
|
28
|
+
try {
|
|
29
|
+
client = await connectToDaemon({ host: options.host });
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
33
|
+
const error = {
|
|
34
|
+
code: "DAEMON_NOT_RUNNING",
|
|
35
|
+
message: `Cannot connect to daemon at ${host}: ${message}`,
|
|
36
|
+
details: "Start the daemon with: paseo daemon start",
|
|
37
|
+
};
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const fetchPayload = await client.fetchAgents({ filter: { includeArchived: true } });
|
|
42
|
+
let agents = fetchPayload.entries.map((entry) => entry.agent);
|
|
43
|
+
const stoppedIds = [];
|
|
44
|
+
if (options.all) {
|
|
45
|
+
// Stop all agents (not archived)
|
|
46
|
+
agents = agents.filter((a) => !a.archivedAt);
|
|
47
|
+
}
|
|
48
|
+
else if (options.cwd) {
|
|
49
|
+
// Stop agents in directory
|
|
50
|
+
agents = agents.filter((a) => {
|
|
51
|
+
if (a.archivedAt)
|
|
52
|
+
return false;
|
|
53
|
+
return isSameOrDescendantPath(options.cwd, a.cwd);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
else if (id) {
|
|
57
|
+
// Stop specific agent
|
|
58
|
+
const fetchResult = await client.fetchAgent({ agentId: id });
|
|
59
|
+
if (!fetchResult) {
|
|
60
|
+
const error = {
|
|
61
|
+
code: "AGENT_NOT_FOUND",
|
|
62
|
+
message: `No agent found matching: ${id}`,
|
|
63
|
+
details: "Use `paseo ls` to list available agents",
|
|
64
|
+
};
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
agents = [fetchResult.agent];
|
|
68
|
+
}
|
|
69
|
+
// Interrupt each running agent. Idle agents are a no-op.
|
|
70
|
+
const stopResults = await Promise.all(agents.map(async (agent) => {
|
|
71
|
+
if (agent.status !== "running")
|
|
72
|
+
return { ok: true, id: agent.id, stopped: false };
|
|
73
|
+
try {
|
|
74
|
+
await client.cancelAgent(agent.id);
|
|
75
|
+
return { ok: true, id: agent.id, stopped: true };
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
79
|
+
return { ok: false, id: agent.id, message };
|
|
80
|
+
}
|
|
81
|
+
}));
|
|
82
|
+
for (const result of stopResults) {
|
|
83
|
+
if (!result.ok) {
|
|
84
|
+
console.error(`Warning: Failed to stop agent ${result.id.slice(0, 7)}: ${result.message}`);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (result.stopped) {
|
|
88
|
+
stoppedIds.push(result.id);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
await client.close();
|
|
92
|
+
return {
|
|
93
|
+
type: "single",
|
|
94
|
+
data: {
|
|
95
|
+
stoppedCount: stoppedIds.length,
|
|
96
|
+
agentIds: stoppedIds,
|
|
97
|
+
},
|
|
98
|
+
schema: stopSchema,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
await client.close().catch(() => { });
|
|
103
|
+
// Re-throw if it's already a CommandError
|
|
104
|
+
if (err && typeof err === "object" && "code" in err) {
|
|
105
|
+
throw err;
|
|
106
|
+
}
|
|
107
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
108
|
+
const error = {
|
|
109
|
+
code: "STOP_AGENT_FAILED",
|
|
110
|
+
message: `Failed to stop agent(s): ${message}`,
|
|
111
|
+
};
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=stop.js.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { AgentProviderNotice } from "@camerontaylor/paseo-protocol/agent-types";
|
|
3
|
+
import type { AgentSnapshotPayload } from "@camerontaylor/paseo-protocol/messages";
|
|
4
|
+
import type { CommandOptions, SingleResult, OutputSchema } from "../../output/index.js";
|
|
5
|
+
/** Result type for agent update command */
|
|
6
|
+
export interface AgentUpdateResult {
|
|
7
|
+
agentId: string;
|
|
8
|
+
name: string | null;
|
|
9
|
+
labels: string;
|
|
10
|
+
thinkingOptionId: string | null;
|
|
11
|
+
noticeType: AgentProviderNotice["type"] | null;
|
|
12
|
+
notice: string | null;
|
|
13
|
+
}
|
|
14
|
+
/** Schema for update command output */
|
|
15
|
+
export declare const updateSchema: OutputSchema<AgentUpdateResult>;
|
|
16
|
+
export interface AgentUpdateOptions extends CommandOptions {
|
|
17
|
+
name?: string;
|
|
18
|
+
label?: string[];
|
|
19
|
+
thinking?: string;
|
|
20
|
+
host?: string;
|
|
21
|
+
}
|
|
22
|
+
export type AgentUpdateCommandResult = SingleResult<AgentUpdateResult>;
|
|
23
|
+
export interface AgentMetadataChanges {
|
|
24
|
+
name?: string;
|
|
25
|
+
labels?: Record<string, string>;
|
|
26
|
+
}
|
|
27
|
+
interface AgentUpdateServerInfo {
|
|
28
|
+
features?: {
|
|
29
|
+
agentThinkingUpdate?: boolean;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export interface AgentUpdateClient {
|
|
33
|
+
getLastServerInfoMessage(): AgentUpdateServerInfo | null;
|
|
34
|
+
updateAgent(agentId: string, updates: AgentMetadataChanges): Promise<void>;
|
|
35
|
+
setAgentThinkingOption(agentId: string, thinkingOptionId: string): Promise<AgentProviderNotice | null>;
|
|
36
|
+
}
|
|
37
|
+
export type AgentChanges = {
|
|
38
|
+
type: "metadata";
|
|
39
|
+
updates: AgentMetadataChanges;
|
|
40
|
+
} | {
|
|
41
|
+
type: "thinking";
|
|
42
|
+
thinkingOptionId: string;
|
|
43
|
+
};
|
|
44
|
+
export interface AppliedAgentChanges {
|
|
45
|
+
notice: AgentProviderNotice | null;
|
|
46
|
+
}
|
|
47
|
+
export declare function toAgentUpdateResult(agent: Pick<AgentSnapshotPayload, "id" | "title" | "labels" | "effectiveThinkingOptionId">, appliedChanges: AppliedAgentChanges): AgentUpdateResult;
|
|
48
|
+
export declare function applyAgentChanges(client: AgentUpdateClient, agentId: string, changes: AgentChanges): Promise<AppliedAgentChanges>;
|
|
49
|
+
export declare function runUpdateCommand(agentIdArg: string, options: AgentUpdateOptions, _command: Command): Promise<AgentUpdateCommandResult>;
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=update.d.ts.map
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { connectToDaemon, getDaemonHost } from "../../utils/client.js";
|
|
2
|
+
/** Schema for update command output */
|
|
3
|
+
export const updateSchema = {
|
|
4
|
+
idField: "agentId",
|
|
5
|
+
columns: [
|
|
6
|
+
{ header: "AGENT ID", field: "agentId" },
|
|
7
|
+
{ header: "NAME", field: "name" },
|
|
8
|
+
{ header: "LABELS", field: "labels" },
|
|
9
|
+
{ header: "THINKING", field: "thinkingOptionId" },
|
|
10
|
+
{ header: "NOTICE", field: "notice" },
|
|
11
|
+
],
|
|
12
|
+
};
|
|
13
|
+
export function toAgentUpdateResult(agent, appliedChanges) {
|
|
14
|
+
return {
|
|
15
|
+
agentId: agent.id,
|
|
16
|
+
name: agent.title,
|
|
17
|
+
labels: formatLabels(agent.labels),
|
|
18
|
+
thinkingOptionId: agent.effectiveThinkingOptionId ?? null,
|
|
19
|
+
noticeType: appliedChanges.notice?.type ?? null,
|
|
20
|
+
notice: appliedChanges.notice?.message ?? null,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export async function applyAgentChanges(client, agentId, changes) {
|
|
24
|
+
if (changes.type === "thinking") {
|
|
25
|
+
// COMPAT(agentThinkingUpdate): added in v0.2.4, remove gate after 2027-01-28.
|
|
26
|
+
if (client.getLastServerInfoMessage()?.features?.agentThinkingUpdate !== true) {
|
|
27
|
+
throw {
|
|
28
|
+
code: "DAEMON_UPDATE_REQUIRED",
|
|
29
|
+
message: "Update the host to use agent thinking updates.",
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const notice = await client.setAgentThinkingOption(agentId, changes.thinkingOptionId);
|
|
33
|
+
return { notice };
|
|
34
|
+
}
|
|
35
|
+
await client.updateAgent(agentId, changes.updates);
|
|
36
|
+
return { notice: null };
|
|
37
|
+
}
|
|
38
|
+
function parseLabelOptions(labels) {
|
|
39
|
+
const parsed = {};
|
|
40
|
+
if (!labels) {
|
|
41
|
+
return parsed;
|
|
42
|
+
}
|
|
43
|
+
for (const rawLabel of labels) {
|
|
44
|
+
for (const segment of rawLabel.split(",")) {
|
|
45
|
+
const label = segment.trim();
|
|
46
|
+
if (!label) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const eqIndex = label.indexOf("=");
|
|
50
|
+
if (eqIndex === -1) {
|
|
51
|
+
const error = {
|
|
52
|
+
code: "INVALID_LABEL",
|
|
53
|
+
message: `Invalid label format: ${label}`,
|
|
54
|
+
details: "Labels must be in key=value format",
|
|
55
|
+
};
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
const key = label.slice(0, eqIndex).trim();
|
|
59
|
+
const value = label.slice(eqIndex + 1);
|
|
60
|
+
if (!key) {
|
|
61
|
+
const error = {
|
|
62
|
+
code: "INVALID_LABEL",
|
|
63
|
+
message: `Invalid label format: ${label}`,
|
|
64
|
+
details: "Labels must include a non-empty key in key=value format",
|
|
65
|
+
};
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
parsed[key] = value;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return parsed;
|
|
72
|
+
}
|
|
73
|
+
function formatLabels(labels) {
|
|
74
|
+
const entries = Object.entries(labels);
|
|
75
|
+
if (entries.length === 0) {
|
|
76
|
+
return "-";
|
|
77
|
+
}
|
|
78
|
+
return entries.map(([key, value]) => `${key}=${value}`).join(",");
|
|
79
|
+
}
|
|
80
|
+
function parseAgentChanges(options) {
|
|
81
|
+
const name = options.name?.trim();
|
|
82
|
+
if (options.name !== undefined && !name) {
|
|
83
|
+
throw {
|
|
84
|
+
code: "INVALID_NAME",
|
|
85
|
+
message: "Name cannot be empty",
|
|
86
|
+
details: "Use --name <name> with a non-empty value",
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const labels = parseLabelOptions(options.label);
|
|
90
|
+
const thinkingOptionId = options.thinking?.trim();
|
|
91
|
+
if (options.thinking !== undefined && !thinkingOptionId) {
|
|
92
|
+
throw {
|
|
93
|
+
code: "INVALID_THINKING_OPTION",
|
|
94
|
+
message: "--thinking cannot be empty",
|
|
95
|
+
details: 'Provide a thinking option ID. Use "paseo provider models <provider> --thinking" to list valid IDs.',
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
const hasMetadataUpdates = Boolean(name) || Object.keys(labels).length > 0;
|
|
99
|
+
if (hasMetadataUpdates && thinkingOptionId) {
|
|
100
|
+
throw {
|
|
101
|
+
code: "INVALID_OPTIONS",
|
|
102
|
+
message: "--thinking cannot be combined with --name or --label",
|
|
103
|
+
details: "Run separate agent update commands for runtime settings and metadata.",
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
if (!hasMetadataUpdates && !thinkingOptionId) {
|
|
107
|
+
throw {
|
|
108
|
+
code: "NO_CHANGES_PROVIDED",
|
|
109
|
+
message: "Nothing to update",
|
|
110
|
+
details: "Provide at least one of: --name <name>, --label <key=value>, --thinking <id>",
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
if (thinkingOptionId) {
|
|
114
|
+
return { type: "thinking", thinkingOptionId };
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
type: "metadata",
|
|
118
|
+
updates: {
|
|
119
|
+
...(name ? { name } : {}),
|
|
120
|
+
...(Object.keys(labels).length > 0 ? { labels } : {}),
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
export async function runUpdateCommand(agentIdArg, options, _command) {
|
|
125
|
+
const host = getDaemonHost({ host: options.host });
|
|
126
|
+
// Validate arguments
|
|
127
|
+
if (!agentIdArg || agentIdArg.trim().length === 0) {
|
|
128
|
+
const error = {
|
|
129
|
+
code: "MISSING_AGENT_ID",
|
|
130
|
+
message: "Agent ID is required",
|
|
131
|
+
details: "Usage: paseo agent update <id> [--name <name>] [--label <key=value>]",
|
|
132
|
+
};
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
const changes = parseAgentChanges(options);
|
|
136
|
+
let client;
|
|
137
|
+
try {
|
|
138
|
+
client = await connectToDaemon({ host: options.host });
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
142
|
+
const error = {
|
|
143
|
+
code: "DAEMON_NOT_RUNNING",
|
|
144
|
+
message: `Cannot connect to daemon at ${host}: ${message}`,
|
|
145
|
+
details: "Start the daemon with: paseo daemon start",
|
|
146
|
+
};
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
const fetchResult = await client.fetchAgent({ agentId: agentIdArg });
|
|
151
|
+
if (!fetchResult) {
|
|
152
|
+
const error = {
|
|
153
|
+
code: "AGENT_NOT_FOUND",
|
|
154
|
+
message: `Agent not found: ${agentIdArg}`,
|
|
155
|
+
details: 'Use "paseo ls" to list available agents',
|
|
156
|
+
};
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
const agentId = fetchResult.agent.id;
|
|
160
|
+
const appliedChanges = await applyAgentChanges(client, agentId, changes);
|
|
161
|
+
const updatedResult = await client.fetchAgent({ agentId });
|
|
162
|
+
if (!updatedResult) {
|
|
163
|
+
throw new Error(`Agent not found after update: ${agentId}`);
|
|
164
|
+
}
|
|
165
|
+
await client.close();
|
|
166
|
+
return {
|
|
167
|
+
type: "single",
|
|
168
|
+
data: toAgentUpdateResult(updatedResult.agent, appliedChanges),
|
|
169
|
+
schema: updateSchema,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
await client.close().catch(() => { });
|
|
174
|
+
// Re-throw CommandError as-is
|
|
175
|
+
if (err && typeof err === "object" && "code" in err) {
|
|
176
|
+
throw err;
|
|
177
|
+
}
|
|
178
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
179
|
+
const error = {
|
|
180
|
+
code: "UPDATE_FAILED",
|
|
181
|
+
message: `Failed to update agent: ${message}`,
|
|
182
|
+
};
|
|
183
|
+
throw error;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import type { CommandOptions, SingleResult, OutputSchema } from "../../output/index.js";
|
|
3
|
+
/** Result type for agent wait command */
|
|
4
|
+
export interface AgentWaitResult {
|
|
5
|
+
agentId: string;
|
|
6
|
+
status: "idle" | "timeout" | "permission" | "error";
|
|
7
|
+
message: string;
|
|
8
|
+
}
|
|
9
|
+
/** Schema for agent wait output */
|
|
10
|
+
export declare const agentWaitSchema: OutputSchema<AgentWaitResult>;
|
|
11
|
+
export interface AgentWaitOptions extends CommandOptions {
|
|
12
|
+
timeout?: string;
|
|
13
|
+
host?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function addWaitOptions(cmd: Command): Command;
|
|
16
|
+
export declare function runWaitCommand(agentIdArg: string, options: AgentWaitOptions, _command: Command): Promise<SingleResult<AgentWaitResult>>;
|
|
17
|
+
//# sourceMappingURL=wait.d.ts.map
|