@getpaseo/cli 0.6.0 → 0.7.0-beta.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.
|
@@ -78,6 +78,17 @@ 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
|
+
return {
|
|
84
|
+
code: "DAEMON_NOT_RUNNING",
|
|
85
|
+
message: `Cannot reach the daemon at ${host}: ${reason}`,
|
|
86
|
+
details: [
|
|
87
|
+
"Start a local daemon with: paseo daemon start",
|
|
88
|
+
"To use another daemon, pass --host <host:port> or set PASEO_HOST.",
|
|
89
|
+
].join("\n"),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
81
92
|
function parseLabelFilters(labels) {
|
|
82
93
|
const labelFilters = {};
|
|
83
94
|
for (const labelStr of labels ?? []) {
|
|
@@ -126,13 +137,7 @@ export async function runLsCommand(options, _command) {
|
|
|
126
137
|
client = await connectToDaemon({ host: options.host });
|
|
127
138
|
}
|
|
128
139
|
catch (err) {
|
|
129
|
-
|
|
130
|
-
const error = {
|
|
131
|
-
code: "DAEMON_NOT_RUNNING",
|
|
132
|
-
message: `Cannot connect to daemon at ${host}: ${message}`,
|
|
133
|
-
details: "Start the daemon with: paseo daemon start\nFor a remote daemon, pass --host <host:port> or set PASEO_HOST.",
|
|
134
|
-
};
|
|
135
|
-
throw error;
|
|
140
|
+
throw daemonConnectionFailure(host, err);
|
|
136
141
|
}
|
|
137
142
|
try {
|
|
138
143
|
const normalizedThinkingOptionId = options.thinking?.trim();
|
|
@@ -5,6 +5,9 @@ import { type PluginScaffold } from "./scaffold.js";
|
|
|
5
5
|
interface PluginOptions extends CommandOptions {
|
|
6
6
|
host?: string;
|
|
7
7
|
id?: string;
|
|
8
|
+
ref?: string;
|
|
9
|
+
path?: string;
|
|
10
|
+
all?: boolean;
|
|
8
11
|
}
|
|
9
12
|
export declare function runPluginInitCommand(directory: string, options: PluginOptions, _command: Command): Promise<SingleResult<PluginScaffold>>;
|
|
10
13
|
export declare function runPluginListCommand(options: PluginOptions, _command: Command): Promise<ListResult<PluginListItem>>;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
import { withOutput } from "../../output/index.js";
|
|
3
4
|
import { addJsonAndDaemonHostOptions, addJsonOption } from "../../utils/command-options.js";
|
|
4
5
|
import { scaffoldPluginDirectory } from "./scaffold.js";
|
|
5
|
-
import { withPluginLogsClient, withPluginManagementClient } from "./shared.js";
|
|
6
|
+
import { withPluginLogsClient, withPluginManagementClient, withPluginSourceClient, } from "./shared.js";
|
|
6
7
|
const pluginSchema = {
|
|
7
8
|
idField: "id",
|
|
8
9
|
columns: [
|
|
@@ -28,6 +29,30 @@ const pluginLogsSchema = {
|
|
|
28
29
|
{ header: "MESSAGE", field: "message", width: 80 },
|
|
29
30
|
],
|
|
30
31
|
};
|
|
32
|
+
function shortCommit(commit) {
|
|
33
|
+
return commit?.slice(0, 12) ?? "-";
|
|
34
|
+
}
|
|
35
|
+
const pluginStatusSchema = {
|
|
36
|
+
idField: "id",
|
|
37
|
+
columns: [
|
|
38
|
+
{ header: "PLUGIN", field: "id", width: 20 },
|
|
39
|
+
{ header: "SOURCE", field: "source", width: 10 },
|
|
40
|
+
{ header: "CURRENT", field: (plugin) => shortCommit(plugin.currentCommit), width: 14 },
|
|
41
|
+
{ header: "LATEST", field: (plugin) => shortCommit(plugin.latestCommit), width: 14 },
|
|
42
|
+
{ header: "COMMITS", field: (plugin) => String(plugin.commitsBehind ?? 0), width: 8 },
|
|
43
|
+
{ header: "REF", field: (plugin) => plugin.ref ?? "-", width: 24 },
|
|
44
|
+
],
|
|
45
|
+
};
|
|
46
|
+
const pluginUpdateSchema = {
|
|
47
|
+
idField: "id",
|
|
48
|
+
columns: [
|
|
49
|
+
{ header: "PLUGIN", field: "id", width: 20 },
|
|
50
|
+
{ header: "PREVIOUS", field: (plugin) => shortCommit(plugin.previousCommit), width: 14 },
|
|
51
|
+
{ header: "CURRENT", field: (plugin) => shortCommit(plugin.currentCommit), width: 14 },
|
|
52
|
+
{ header: "COMMITS", field: (plugin) => String(plugin.commits), width: 8 },
|
|
53
|
+
{ header: "UPDATED", field: (plugin) => (plugin.updated ? "yes" : "no"), width: 8 },
|
|
54
|
+
],
|
|
55
|
+
};
|
|
31
56
|
export async function runPluginInitCommand(directory, options, _command) {
|
|
32
57
|
return {
|
|
33
58
|
type: "single",
|
|
@@ -43,10 +68,36 @@ export async function runPluginLogsCommand(pluginId, options, _command) {
|
|
|
43
68
|
const data = await withPluginLogsClient(options.host, (client) => client.getPluginLogs(pluginId));
|
|
44
69
|
return { type: "list", data, schema: pluginLogsSchema };
|
|
45
70
|
}
|
|
46
|
-
async function install(
|
|
47
|
-
const
|
|
71
|
+
async function install(source, options, _command) {
|
|
72
|
+
const isExplicitPath = path.isAbsolute(source) ||
|
|
73
|
+
source === "." ||
|
|
74
|
+
source === ".." ||
|
|
75
|
+
source.startsWith("./") ||
|
|
76
|
+
source.startsWith("../") ||
|
|
77
|
+
source.startsWith(".\\") ||
|
|
78
|
+
source.startsWith("..\\");
|
|
79
|
+
const canUseLegacyDirectoryInstall = isExplicitPath && !options.ref && !options.path;
|
|
80
|
+
const data = canUseLegacyDirectoryInstall
|
|
81
|
+
? await withPluginManagementClient(options.host, (client) => client.installDirectoryPlugin(source, options.id))
|
|
82
|
+
: await withPluginSourceClient(options.host, (client) => client.installPluginSource({
|
|
83
|
+
source,
|
|
84
|
+
...(options.id ? { id: options.id } : {}),
|
|
85
|
+
...(options.ref ? { ref: options.ref } : {}),
|
|
86
|
+
...(options.path ? { pluginPath: options.path } : {}),
|
|
87
|
+
}));
|
|
48
88
|
return { type: "single", data, schema: pluginSchema };
|
|
49
89
|
}
|
|
90
|
+
async function status(pluginId, options, _command) {
|
|
91
|
+
const data = await withPluginSourceClient(options.host, (client) => client.getPluginSourceStatus(pluginId));
|
|
92
|
+
return { type: "list", data, schema: pluginStatusSchema };
|
|
93
|
+
}
|
|
94
|
+
async function update(pluginId, options, _command) {
|
|
95
|
+
if ((pluginId === undefined) === (options.all !== true)) {
|
|
96
|
+
throw new Error("Choose one plugin ID or pass --all");
|
|
97
|
+
}
|
|
98
|
+
const data = await withPluginSourceClient(options.host, (client) => client.updatePluginSources(pluginId));
|
|
99
|
+
return { type: "list", data, schema: pluginUpdateSchema };
|
|
100
|
+
}
|
|
50
101
|
async function act(action, pluginId, options) {
|
|
51
102
|
const data = await withPluginManagementClient(options.host, (client) => client[`${action}Plugin`](pluginId));
|
|
52
103
|
return { type: "single", data, schema: pluginSchema };
|
|
@@ -62,7 +113,7 @@ async function remove(pluginId, options, _command) {
|
|
|
62
113
|
return { type: "single", data, schema: pluginSchema };
|
|
63
114
|
}
|
|
64
115
|
export function createPluginCommand() {
|
|
65
|
-
const plugin = new Command("plugin").description("Manage trusted
|
|
116
|
+
const plugin = new Command("plugin").description("Manage trusted plugins");
|
|
66
117
|
addJsonOption(plugin
|
|
67
118
|
.command("init")
|
|
68
119
|
.description("Create a typecheckable local plugin")
|
|
@@ -72,11 +123,20 @@ export function createPluginCommand() {
|
|
|
72
123
|
addJsonAndDaemonHostOptions(plugin.command("logs").description("Show recent plugin output").argument("<id>")).action(withOutput(runPluginLogsCommand));
|
|
73
124
|
addJsonAndDaemonHostOptions(plugin
|
|
74
125
|
.command("install")
|
|
75
|
-
.
|
|
76
|
-
.
|
|
77
|
-
.
|
|
126
|
+
.alias("add")
|
|
127
|
+
.description("Install a plugin from a directory or Git repository")
|
|
128
|
+
.argument("<source>", "Host directory, owner/repo shorthand, or Git URL")
|
|
129
|
+
.option("--id <id>", "Runtime plugin ID (defaults to paseo-plugin.json id)")
|
|
130
|
+
.option("--ref <ref>", "Git branch, tag, or commit")
|
|
131
|
+
.option("--path <path>", "Plugin directory within the repository")).action(withOutput(install));
|
|
132
|
+
addJsonAndDaemonHostOptions(plugin.command("status").description("Check plugin source updates").argument("[id]")).action(withOutput(status));
|
|
133
|
+
addJsonAndDaemonHostOptions(plugin
|
|
134
|
+
.command("update")
|
|
135
|
+
.description("Update a Git-managed plugin")
|
|
136
|
+
.argument("[id]")
|
|
137
|
+
.option("--all", "Update every Git-managed plugin")).action(withOutput(update));
|
|
78
138
|
for (const action of ["reload", "enable", "disable"]) {
|
|
79
|
-
addJsonAndDaemonHostOptions(plugin.command(action).description(`${action} a
|
|
139
|
+
addJsonAndDaemonHostOptions(plugin.command(action).description(`${action} a plugin`).argument("<id>")).action(withOutput((id, options, _command) => act(action, id, options)));
|
|
80
140
|
}
|
|
81
141
|
addJsonAndDaemonHostOptions(plugin.command("remove").description("Remove plugin configuration").argument("<id>")).action(withOutput(remove));
|
|
82
142
|
return plugin;
|
|
@@ -58,6 +58,7 @@ const SDK_DECLARATIONS = `declare module "@getpaseo/plugin/server" {
|
|
|
58
58
|
declare module "@getpaseo/plugin" {
|
|
59
59
|
import type { ComponentType } from "react";
|
|
60
60
|
import type { PaseoApi } from "@getpaseo/client";
|
|
61
|
+
import type { AgentTimelineItem } from "@getpaseo/protocol/agent-types";
|
|
61
62
|
import type { ZodType, input as ZodInput, output as ZodOutput } from "zod";
|
|
62
63
|
import type {
|
|
63
64
|
PluginAttachmentSourceContribution,
|
|
@@ -80,10 +81,15 @@ declare module "@getpaseo/plugin" {
|
|
|
80
81
|
export interface PluginTheme {
|
|
81
82
|
readonly colors: {
|
|
82
83
|
readonly surface0: string;
|
|
84
|
+
readonly surface1: string;
|
|
85
|
+
readonly surface2: string;
|
|
86
|
+
readonly border: string;
|
|
83
87
|
readonly foreground: string;
|
|
84
88
|
readonly foregroundMuted: string;
|
|
85
89
|
readonly accent: string;
|
|
86
90
|
readonly accentForeground: string;
|
|
91
|
+
readonly statusSuccess: string;
|
|
92
|
+
readonly statusWarning: string;
|
|
87
93
|
readonly statusDanger: string;
|
|
88
94
|
};
|
|
89
95
|
}
|
|
@@ -96,6 +102,12 @@ declare module "@getpaseo/plugin" {
|
|
|
96
102
|
|
|
97
103
|
export interface PluginSurfaceProps extends PluginHostProps {}
|
|
98
104
|
|
|
105
|
+
export interface PluginIconProps {
|
|
106
|
+
name: string;
|
|
107
|
+
size?: number;
|
|
108
|
+
color?: string;
|
|
109
|
+
}
|
|
110
|
+
|
|
99
111
|
export interface PluginWorkspaceSnapshot {
|
|
100
112
|
readonly id: string;
|
|
101
113
|
readonly projectId: string;
|
|
@@ -179,6 +191,29 @@ declare module "@getpaseo/plugin" {
|
|
|
179
191
|
Component: ComponentType<PluginSurfaceProps>;
|
|
180
192
|
}
|
|
181
193
|
|
|
194
|
+
export type PluginTimelineData = null | boolean | number | string | PluginTimelineData[] | { [key: string]: PluginTimelineData };
|
|
195
|
+
export interface PluginTimelineItem { type: "plugin"; kind: string; version: number; data: PluginTimelineData; }
|
|
196
|
+
export interface PluginTimelineTransformResult { items: PluginTimelineItem[]; }
|
|
197
|
+
export type PluginTimelineTransformerContribution<ItemType extends AgentTimelineItem["type"] = AgentTimelineItem["type"]> =
|
|
198
|
+
ItemType extends AgentTimelineItem["type"]
|
|
199
|
+
? {
|
|
200
|
+
id: string;
|
|
201
|
+
query: { itemType: ItemType };
|
|
202
|
+
transform(input: { item: Extract<AgentTimelineItem, { type: ItemType }> }): PluginTimelineTransformResult | undefined;
|
|
203
|
+
}
|
|
204
|
+
: never;
|
|
205
|
+
export interface PluginTimelineItemProps<Data = unknown> extends PluginHostProps {
|
|
206
|
+
agentId: string;
|
|
207
|
+
item: { type: "plugin"; kind: string; version: number; data: Data };
|
|
208
|
+
timestamp: Date;
|
|
209
|
+
}
|
|
210
|
+
export interface PluginTimelineRendererContribution<Schema extends ZodType = ZodType> {
|
|
211
|
+
kind: string;
|
|
212
|
+
version: number;
|
|
213
|
+
schema: Schema;
|
|
214
|
+
Component: ComponentType<PluginTimelineItemProps<ZodOutput<Schema>>>;
|
|
215
|
+
}
|
|
216
|
+
|
|
182
217
|
export interface PluginCommandCapabilities {
|
|
183
218
|
paseo: PaseoApi;
|
|
184
219
|
rpc<InputSchema extends ZodType, OutputSchema extends ZodType>(
|
|
@@ -224,11 +259,15 @@ declare module "@getpaseo/plugin" {
|
|
|
224
259
|
addCommandCenterItem(contribution: PluginCommandCenterItemContribution): void;
|
|
225
260
|
addAttachmentSource(contribution: PluginAttachmentSourceContribution): void;
|
|
226
261
|
addTheme(contribution: PluginThemeContribution): void;
|
|
262
|
+
addTimelineTransformer<ItemType extends AgentTimelineItem["type"]>(contribution: PluginTimelineTransformerContribution<ItemType>): void;
|
|
263
|
+
addTimelineRenderer<Schema extends ZodType>(contribution: PluginTimelineRendererContribution<Schema>): void;
|
|
227
264
|
}
|
|
228
265
|
|
|
229
266
|
export type PluginCleanup = () => void | Promise<void>;
|
|
230
267
|
export type PluginContribution = (plugin: PluginContext) => PluginCleanup;
|
|
231
268
|
|
|
269
|
+
export const Icon: ComponentType<PluginIconProps>;
|
|
270
|
+
|
|
232
271
|
export function useRpc<InputSchema extends ZodType, OutputSchema extends ZodType>(
|
|
233
272
|
contract: PluginRpcContract<InputSchema, OutputSchema>,
|
|
234
273
|
): (input: ZodInput<InputSchema>) => Promise<ZodOutput<OutputSchema>>;
|
|
@@ -307,6 +346,7 @@ export async function scaffoldPluginDirectory(targetDirectory, requestedId) {
|
|
|
307
346
|
scripts: { typecheck: "tsc --noEmit" },
|
|
308
347
|
devDependencies: {
|
|
309
348
|
"@getpaseo/client": "^0.4.0",
|
|
349
|
+
"@getpaseo/protocol": "^0.6.1",
|
|
310
350
|
"@tanstack/react-query": "^5.90.11",
|
|
311
351
|
"@types/react": "~19.2.0",
|
|
312
352
|
react: "19.1.0",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DaemonClient } from "@getpaseo/client/internal/daemon-client";
|
|
2
2
|
export declare function withPluginManagementClient<T>(host: string | undefined, run: (client: DaemonClient) => Promise<T>): Promise<T>;
|
|
3
3
|
export declare function withPluginLogsClient<T>(host: string | undefined, run: (client: DaemonClient) => Promise<T>): Promise<T>;
|
|
4
|
+
export declare function withPluginSourceClient<T>(host: string | undefined, run: (client: DaemonClient) => Promise<T>): Promise<T>;
|
|
4
5
|
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -23,4 +23,8 @@ export async function withPluginLogsClient(host, run) {
|
|
|
23
23
|
// COMPAT(pluginLogs): added in v0.4.0, remove gate after 2027-08-16.
|
|
24
24
|
return withPluginClient(host, "pluginLogs", "Update the host to view plugin logs.", run);
|
|
25
25
|
}
|
|
26
|
+
export async function withPluginSourceClient(host, run) {
|
|
27
|
+
// COMPAT(pluginGitManagement): added in v0.7.0, remove gate after 2027-08-26.
|
|
28
|
+
return withPluginClient(host, "pluginGitManagement", "Update the host to install and update Git plugins.", run);
|
|
29
|
+
}
|
|
26
30
|
//# sourceMappingURL=shared.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getpaseo/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0-beta.1",
|
|
4
4
|
"description": "Paseo CLI - control your AI coding agents from the command line",
|
|
5
5
|
"bin": {
|
|
6
6
|
"paseo": "bin/paseo"
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@clack/prompts": "^1.0.0",
|
|
31
|
-
"@getpaseo/client": "0.
|
|
32
|
-
"@getpaseo/protocol": "0.
|
|
33
|
-
"@getpaseo/server": "0.
|
|
31
|
+
"@getpaseo/client": "0.7.0-beta.1",
|
|
32
|
+
"@getpaseo/protocol": "0.7.0-beta.1",
|
|
33
|
+
"@getpaseo/server": "0.7.0-beta.1",
|
|
34
34
|
"chalk": "^5.3.0",
|
|
35
35
|
"commander": "^12.0.0",
|
|
36
36
|
"mime-types": "^2.1.35",
|