@camerontaylor/paseo-cli 0.9.0-beta.2.fork.1 → 0.10.1-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.
@@ -72,7 +72,16 @@ export interface RunWorkspaceLookupClient {
72
72
  }
73
73
  export declare function resolveExistingRunWorkspace(client: RunWorkspaceLookupClient, workspaceId: string): Promise<RunWorkspace>;
74
74
  export declare function runRunCommand(prompt: string, options: AgentRunOptions, _command: Command): Promise<SingleResult<AgentRunResult>>;
75
- export declare function resolveRunCallerAgentId(env?: {
75
+ export interface RunCallerLookupClient {
76
+ fetchAgent(options: {
77
+ agentId: string;
78
+ }): Promise<{
79
+ agent: {
80
+ id: string;
81
+ };
82
+ } | null>;
83
+ }
84
+ export declare function resolveRunCallerAgentId(client: RunCallerLookupClient, env?: {
76
85
  PASEO_AGENT_ID?: string;
77
- }): string | undefined;
86
+ }): Promise<string | undefined>;
78
87
  //# sourceMappingURL=run.d.ts.map
@@ -1,5 +1,6 @@
1
1
  import { Option } from "commander";
2
2
  import { getStructuredAgentResponse, StructuredAgentResponseError, } from "@camerontaylor/paseo-server/agent-response";
3
+ import { DaemonConnectionError } from "@camerontaylor/paseo-client/internal/daemon-client";
3
4
  import { connectToDaemon } from "../../utils/client.js";
4
5
  import { readFileSync } from "node:fs";
5
6
  import { resolve } from "node:path";
@@ -374,18 +375,18 @@ export async function resolveExistingRunWorkspace(client, workspaceId) {
374
375
  }
375
376
  // Workspace policy for `paseo run`. Precedence:
376
377
  // 1. --workspace <id> -> run in that existing workspace
377
- // 2. $PASEO_AGENT_ID -> daemon resolves the caller's workspace
378
+ // 2. caller agent -> daemon resolves the caller's workspace
378
379
  // 3. $PASEO_WORKSPACE_ID -> exported by workspace terminals
379
380
  // 4. --new-workspace <kind> -> mint a new workspace explicitly
380
381
  // 5. bare run -> mint a new local-backed workspace for cwd
381
- async function resolveRunWorkspace(client, options, cwd) {
382
+ async function resolveRunWorkspace(client, options, cwd, callerAgentId) {
382
383
  const newWorkspace = resolveNewWorkspaceKind(options);
383
384
  const explicit = newWorkspace ? undefined : options.workspace?.trim();
384
385
  if (explicit) {
385
386
  console.error(`Using workspace ${explicit}`);
386
387
  return resolveExistingRunWorkspace(client, explicit);
387
388
  }
388
- if (!newWorkspace && resolveRunCallerAgentId()) {
389
+ if (!newWorkspace && callerAgentId) {
389
390
  return { cwd };
390
391
  }
391
392
  const ambientWorkspaceId = newWorkspace ? undefined : process.env.PASEO_WORKSPACE_ID?.trim();
@@ -434,9 +435,9 @@ export async function runRunCommand(prompt, options, _command) {
434
435
  const labels = parseRunLabels(options.label);
435
436
  const env = parseRunEnv(options.env);
436
437
  const requestEnv = Object.keys(env).length > 0 ? env : undefined;
437
- const workspace = await resolveRunWorkspace(client, options, cwd);
438
+ const callerAgentId = await resolveRunCallerAgentId(client);
439
+ const workspace = await resolveRunWorkspace(client, options, cwd, callerAgentId);
438
440
  const workspaceId = workspace.id;
439
- const callerAgentId = resolveRunCallerAgentId();
440
441
  const runCwd = workspace.cwd;
441
442
  if (outputSchema) {
442
443
  let structuredAgent = null;
@@ -543,7 +544,22 @@ export async function runRunCommand(prompt, options, _command) {
543
544
  throw error;
544
545
  }
545
546
  }
546
- export function resolveRunCallerAgentId(env = process.env) {
547
- return env.PASEO_AGENT_ID?.trim() || undefined;
547
+ // PASEO_AGENT_ID names an agent on the daemon that launched this shell. A run
548
+ // sent to another daemon (--host or --home) has no caller there, so it runs as
549
+ // a top-level agent instead of failing on an unknown caller.
550
+ export async function resolveRunCallerAgentId(client, env = process.env) {
551
+ const agentId = env.PASEO_AGENT_ID?.trim();
552
+ if (!agentId) {
553
+ return undefined;
554
+ }
555
+ const caller = await client.fetchAgent({ agentId }).catch((error) => {
556
+ // A daemon without this agent answers with an error. A lost or timed-out
557
+ // connection is not an answer, so it must not drop the caller.
558
+ if (error instanceof DaemonConnectionError) {
559
+ throw error;
560
+ }
561
+ return null;
562
+ });
563
+ return caller?.agent.id === agentId ? agentId : undefined;
548
564
  }
549
565
  //# sourceMappingURL=run.js.map
@@ -7,6 +7,8 @@ import { readPersistedConfig, editPersistedConfig, resolveConfigFromPersisted, }
7
7
  import { connectToDaemon } from "../../utils/client.js";
8
8
  import { addJsonAndDaemonHostOptions, withGlobalOptions } from "../../utils/command-options.js";
9
9
  import { formatPairingInstructions } from "../../output/pairing.js";
10
+ import { parseConnectionOfferFromUrl } from "@camerontaylor/paseo-protocol/connection-offer";
11
+ import { serializeRelayConnectionUri } from "@camerontaylor/paseo-protocol/daemon-endpoints";
10
12
  const PAIRING_DAEMON_RPC_TIMEOUT_MS = 1500;
11
13
  const RELAY_DOCS_URL = "https://paseo.sh/docs/security";
12
14
  function createProcessOutput() {
@@ -126,13 +128,16 @@ function outputPairingResult(pairing, options, output) {
126
128
  output.setExitCode(1);
127
129
  return;
128
130
  }
131
+ const offer = parseConnectionOfferFromUrl(pairing.url);
132
+ const connectionUri = offer ? serializeRelayConnectionUri({ offer }) : null;
129
133
  if (options.json) {
130
- output.writeStdout(`${JSON.stringify({ relayEnabled: pairing.relayEnabled, url: pairing.url, qr: pairing.qr }, null, 2)}\n`);
134
+ output.writeStdout(`${JSON.stringify({ relayEnabled: pairing.relayEnabled, url: pairing.url, qr: pairing.qr, connectionUri }, null, 2)}\n`);
131
135
  return;
132
136
  }
133
137
  output.writeStdout(formatPairingInstructions({
134
138
  url: pairing.url,
135
139
  qr: pairing.qr,
140
+ connectionUri,
136
141
  columns: output.columns,
137
142
  }));
138
143
  }
@@ -27,6 +27,12 @@ const setPasswordResultSchema = {
27
27
  function createCommandError(code, message, details) {
28
28
  return { code, message, ...(details ? { details } : {}) };
29
29
  }
30
+ function terminalPasswordPrompt() {
31
+ if (!process.stdin.isTTY) {
32
+ throw createCommandError("PASSWORD_TTY_REQUIRED", "paseo daemon set-password needs a terminal to read the password", "Run it in an interactive terminal, or set PASEO_PASSWORD in the daemon's environment instead.");
33
+ }
34
+ return (message) => passwordPrompt({ message });
35
+ }
30
36
  async function promptForPassword(promptPassword) {
31
37
  const first = await promptPassword("New daemon password");
32
38
  if (isCancel(first)) {
@@ -69,7 +75,7 @@ export async function setDaemonPasswordInConfig(newPassword, options = {}) {
69
75
  export async function runSetPasswordCommand(options, _command) {
70
76
  const promptPassword = typeof options.promptPassword === "function"
71
77
  ? options.promptPassword
72
- : (message) => passwordPrompt({ message });
78
+ : terminalPasswordPrompt();
73
79
  const newPassword = await promptForPassword(promptPassword);
74
80
  const result = await setDaemonPasswordInConfig(newPassword, {
75
81
  home: options.daemonTarget.kind === "instance" ? options.daemonTarget.home : undefined,
@@ -102,6 +102,7 @@ function localStatus(home, instance) {
102
102
  pid: instance?.pid ?? null,
103
103
  startedAt: instance?.startedAt ?? null,
104
104
  listen: instance?.listen ?? null,
105
+ serverId: instance?.serverId ?? undefined,
105
106
  hostname: instance?.hostname ?? null,
106
107
  configuredListen: config.listen,
107
108
  localDaemon,
@@ -1,4 +1,5 @@
1
1
  import type { Command } from "commander";
2
+ import type { AgentPermissionRequest } from "@camerontaylor/paseo-protocol/agent-types";
2
3
  import type { CommandOptions, ListResult, OutputSchema } from "../../output/index.js";
3
4
  /** Permission response item for display */
4
5
  export interface PermissionResponseItem {
@@ -10,6 +11,8 @@ export interface PermissionResponseItem {
10
11
  }
11
12
  /** Schema for permit allow/deny output */
12
13
  export declare const permitResponseSchema: OutputSchema<PermissionResponseItem>;
14
+ /** Transform a permission the agent answered to a response item */
15
+ export declare function toPermissionResponseItem(agentId: string, permission: AgentPermissionRequest, result: "allowed" | "denied"): PermissionResponseItem;
13
16
  export type PermitAllowResult = ListResult<PermissionResponseItem>;
14
17
  export interface PermitAllowOptions extends CommandOptions {
15
18
  all?: boolean;
@@ -3,7 +3,7 @@ import { connectToDaemon } from "../../utils/client.js";
3
3
  export const permitResponseSchema = {
4
4
  idField: "requestId",
5
5
  columns: [
6
- { header: "REQUEST ID", field: "requestId", width: 12 },
6
+ { header: "REQUEST ID", field: (item) => item.requestId.slice(0, 8), width: 12 },
7
7
  { header: "AGENT", field: "agentShortId", width: 10 },
8
8
  { header: "TOOL", field: "name", width: 20 },
9
9
  {
@@ -20,6 +20,16 @@ export const permitResponseSchema = {
20
20
  },
21
21
  ],
22
22
  };
23
+ /** Transform a permission the agent answered to a response item */
24
+ export function toPermissionResponseItem(agentId, permission, result) {
25
+ return {
26
+ requestId: permission.id,
27
+ agentId,
28
+ agentShortId: agentId.slice(0, 7),
29
+ name: permission.name,
30
+ result,
31
+ };
32
+ }
23
33
  export async function runAllowCommand(agentIdOrPrefix, reqId, options, _command) {
24
34
  // No validation needed - if no reqId provided, allow all by default
25
35
  // Parse input JSON if provided
@@ -88,13 +98,7 @@ export async function runAllowCommand(agentIdOrPrefix, reqId, options, _command)
88
98
  behavior: "allow",
89
99
  ...(updatedInput ? { updatedInput } : {}),
90
100
  });
91
- return {
92
- requestId: permission.id.slice(0, 8),
93
- agentId: resolvedAgentId,
94
- agentShortId: resolvedAgentId.slice(0, 7),
95
- name: permission.name,
96
- result: "allowed",
97
- };
101
+ return toPermissionResponseItem(resolvedAgentId, permission, "allowed");
98
102
  }));
99
103
  await client.close();
100
104
  return {
@@ -1,5 +1,5 @@
1
1
  import { connectToDaemon } from "../../utils/client.js";
2
- import { permitResponseSchema } from "./allow.js";
2
+ import { permitResponseSchema, toPermissionResponseItem, } from "./allow.js";
3
3
  export async function runDenyCommand(agentIdOrPrefix, reqId, options, _command) {
4
4
  // Validate arguments
5
5
  if (!options.all && !reqId) {
@@ -60,13 +60,7 @@ export async function runDenyCommand(agentIdOrPrefix, reqId, options, _command)
60
60
  ...(options.message ? { message: options.message } : {}),
61
61
  ...(options.interrupt ? { interrupt: true } : {}),
62
62
  });
63
- return {
64
- requestId: permission.id.slice(0, 8),
65
- agentId: resolvedAgentId,
66
- agentShortId: resolvedAgentId.slice(0, 7),
67
- name: permission.name,
68
- result: "denied",
69
- };
63
+ return toPermissionResponseItem(resolvedAgentId, permission, "denied");
70
64
  }));
71
65
  await client.close();
72
66
  return {
@@ -1,4 +1,5 @@
1
1
  import type { Command } from "commander";
2
+ import type { AgentSnapshotPayload } from "@camerontaylor/paseo-protocol/messages";
2
3
  import type { CommandOptions, ListResult, OutputSchema } from "../../output/index.js";
3
4
  /** Permission list item for display */
4
5
  export interface PermissionListItem {
@@ -11,6 +12,8 @@ export interface PermissionListItem {
11
12
  /** Schema for permit ls output */
12
13
  export declare const permitLsSchema: OutputSchema<PermissionListItem>;
13
14
  export type PermitLsResult = ListResult<PermissionListItem>;
15
+ /** Collect the pending permissions of every agent */
16
+ export declare function listPendingPermissions(agents: AgentSnapshotPayload[]): PermitLsResult;
14
17
  export interface PermitLsOptions extends CommandOptions {
15
18
  host?: string;
16
19
  }
@@ -4,7 +4,7 @@ export const permitLsSchema = {
4
4
  idField: "id",
5
5
  columns: [
6
6
  { header: "AGENT", field: "agentShortId", width: 12 },
7
- { header: "REQ_ID", field: "id", width: 12 },
7
+ { header: "REQ_ID", field: (item) => item.id.slice(0, 8), width: 12 },
8
8
  { header: "TOOL", field: "name", width: 20 },
9
9
  { header: "DESCRIPTION", field: "description", width: 50 },
10
10
  ],
@@ -12,33 +12,34 @@ export const permitLsSchema = {
12
12
  /** Transform agent snapshot + permission to list item */
13
13
  function toListItem(agent, permission) {
14
14
  return {
15
- id: permission.id.slice(0, 8),
15
+ id: permission.id,
16
16
  agentId: agent.id,
17
17
  agentShortId: agent.id.slice(0, 7),
18
18
  name: permission.name,
19
19
  description: permission.description ?? "-",
20
20
  };
21
21
  }
22
+ /** Collect the pending permissions of every agent */
23
+ export function listPendingPermissions(agents) {
24
+ const items = [];
25
+ for (const agent of agents) {
26
+ for (const permission of agent.pendingPermissions ?? []) {
27
+ items.push(toListItem(agent, permission));
28
+ }
29
+ }
30
+ return {
31
+ type: "list",
32
+ data: items,
33
+ schema: permitLsSchema,
34
+ };
35
+ }
22
36
  export async function runLsCommand(options, _command) {
23
37
  const client = await connectToDaemon({ target: options.daemonTarget });
24
38
  try {
25
39
  const agentsPayload = await client.fetchAgents({ filter: { includeArchived: true } });
26
40
  const agents = agentsPayload.entries.map((entry) => entry.agent);
27
41
  await client.close();
28
- // Collect all pending permissions from all agents
29
- const items = [];
30
- for (const agent of agents) {
31
- if (agent.pendingPermissions && agent.pendingPermissions.length > 0) {
32
- for (const permission of agent.pendingPermissions) {
33
- items.push(toListItem(agent, permission));
34
- }
35
- }
36
- }
37
- return {
38
- type: "list",
39
- data: items,
40
- schema: permitLsSchema,
41
- };
42
+ return listPendingPermissions(agents);
42
43
  }
43
44
  catch (err) {
44
45
  await client.close().catch(() => { });
@@ -1,8 +1,9 @@
1
1
  interface PairingInstructions {
2
2
  url: string;
3
3
  qr: string | null;
4
+ connectionUri?: string | null;
4
5
  columns?: number;
5
6
  }
6
- export declare function formatPairingInstructions({ url, qr, columns }: PairingInstructions): string;
7
+ export declare function formatPairingInstructions({ url, qr, columns, connectionUri, }: PairingInstructions): string;
7
8
  export {};
8
9
  //# sourceMappingURL=pairing.d.ts.map
@@ -18,7 +18,19 @@ function formatQr(qr, columns) {
18
18
  }
19
19
  return qr;
20
20
  }
21
- export function formatPairingInstructions({ url, qr, columns }) {
22
- return `\nScan to pair:\n${formatQr(qr, columns)}\n\nPairing link:\n${url}\n\nTreat this pairing link like a password. Anyone with it can access this daemon.\n`;
21
+ function redactConnectionUri(uri) {
22
+ try {
23
+ const parsed = new URL(uri);
24
+ if (parsed.searchParams.has("password")) {
25
+ parsed.searchParams.set("password", "[redacted]");
26
+ }
27
+ return parsed.toString();
28
+ }
29
+ catch {
30
+ return "Invalid connection URI";
31
+ }
32
+ }
33
+ export function formatPairingInstructions({ url, qr, columns, connectionUri, }) {
34
+ return `\nScan to pair:\n${formatQr(qr, columns)}\n\nPairing link:\n${url}${connectionUri ? `\n\nConnection URI:\n${redactConnectionUri(connectionUri)}` : ""}\n\nTreat this pairing link like a password. Anyone with it can access this daemon.\n`;
23
35
  }
24
36
  //# sourceMappingURL=pairing.js.map
@@ -7,6 +7,7 @@ export interface ConnectOptions {
7
7
  timeout?: number;
8
8
  instance?: DaemonInstance;
9
9
  }
10
+ export declare function resolveClientPaseoHome(target: DaemonTarget, env?: Readonly<Record<string, string | undefined>>): string;
10
11
  type TransportTarget = {
11
12
  type: "tcp";
12
13
  url: string;
@@ -26,6 +27,13 @@ export declare function buildDaemonConnectionCommandError(options: ConnectOption
26
27
  export declare function normalizeDaemonHost(raw: string): string | null;
27
28
  export declare function resolveDaemonTarget(host: string): TransportTarget;
28
29
  export declare function resolveDaemonPassword(host: string): string | undefined;
30
+ export declare function resolveDaemonCredential(host: string, home: string): {
31
+ kind: "password";
32
+ password: string;
33
+ } | {
34
+ kind: "localCredential";
35
+ token: string;
36
+ } | null;
29
37
  export declare function connectToDaemon(options: ConnectOptions): Promise<DaemonClient>;
30
38
  /**
31
39
  * Try to connect to the daemon, returns null if connection fails
@@ -1,4 +1,4 @@
1
- import { waitForDaemonReady, resolvePaseoHome, } from "@camerontaylor/paseo-server/daemon-control";
1
+ import { waitForDaemonReady, resolvePaseoHome, readLocalCredentialForTarget, } from "@camerontaylor/paseo-server/daemon-control";
2
2
  import { describeDaemonTarget } from "./daemon-target.js";
3
3
  import { buildDaemonWebSocketUrl, buildRelayWebSocketUrl, normalizeHostPort, parseConnectionUri, shouldUseTlsForDefaultHostedRelay, } from "@camerontaylor/paseo-protocol/daemon-endpoints";
4
4
  import { parseConnectionOfferFromUrl, } from "@camerontaylor/paseo-protocol/connection-offer";
@@ -8,6 +8,9 @@ import { WebSocket } from "ws";
8
8
  import { getOrCreateCliClientId } from "./client-id.js";
9
9
  import { resolveCliVersion } from "../version.js";
10
10
  import { createSshTunnel } from "../ssh/ssh-tunnel.js";
11
+ export function resolveClientPaseoHome(target, env = process.env) {
12
+ return target.kind === "instance" ? target.home : resolvePaseoHome(env);
13
+ }
11
14
  const DEFAULT_TIMEOUT = 15000;
12
15
  export function getDaemonHost(options) {
13
16
  return describeDaemonTarget(options.target);
@@ -31,11 +34,18 @@ export function buildDaemonConnectionCommandError(options) {
31
34
  return {
32
35
  code,
33
36
  message: `Cannot connect to daemon at ${describeDaemonTarget(options.target)}: ${message}`,
34
- details: options.target.kind === "instance"
35
- ? `Start with: paseo daemon start --home ${JSON.stringify(options.target.home)}`
36
- : "Check the selected endpoint and credentials. SSH transport does not install or start the daemon.",
37
+ details: describeConnectionRemedy(code, options.target),
37
38
  };
38
39
  }
40
+ function describeConnectionRemedy(code, target) {
41
+ if (code === "AUTH_REQUIRED")
42
+ return "The daemon requires a password. Set PASEO_PASSWORD and retry.";
43
+ if (code === "AUTH_FAILED")
44
+ return "The daemon rejected the password. Check PASEO_PASSWORD and retry.";
45
+ if (target.kind === "instance")
46
+ return `Start with: paseo daemon start --home ${JSON.stringify(target.home)}`;
47
+ return "Check the selected endpoint and credentials. SSH transport does not install or start the daemon.";
48
+ }
39
49
  export function normalizeDaemonHost(raw) {
40
50
  const trimmed = raw.trim();
41
51
  if (!trimmed) {
@@ -126,6 +136,13 @@ export function resolveDaemonPassword(host) {
126
136
  const fromEnv = process.env.PASEO_PASSWORD;
127
137
  return fromEnv && fromEnv.length > 0 ? fromEnv : undefined;
128
138
  }
139
+ export function resolveDaemonCredential(host, home) {
140
+ const password = resolveDaemonPassword(host);
141
+ if (password)
142
+ return { kind: "password", password };
143
+ const token = readLocalCredentialForTarget(home, host);
144
+ return token ? { kind: "localCredential", token } : null;
145
+ }
129
146
  /**
130
147
  * Create a WebSocket factory that works in Node.js
131
148
  */
@@ -141,14 +158,17 @@ function createNodeWebSocketFactory() {
141
158
  * Create and connect a daemon client
142
159
  * Returns the connected client or throws if connection fails
143
160
  */
144
- async function tryConnectHost(host, password, clientId, timeout, nodeWebSocketFactory) {
161
+ async function tryConnectHost(host, credential, home, clientId, timeout, nodeWebSocketFactory) {
145
162
  const target = resolveDaemonTarget(host);
146
163
  const client = new DaemonClient({
147
164
  url: target.url,
148
165
  clientId,
149
166
  clientType: "cli",
150
167
  appVersion: resolveCliVersion(),
151
- password,
168
+ ...(credential?.kind === "password" ? { password: credential.password } : {}),
169
+ ...(credential?.kind === "localCredential"
170
+ ? { localCredential: () => readLocalCredentialForTarget(home, host) ?? undefined }
171
+ : {}),
152
172
  connectTimeoutMs: timeout,
153
173
  webSocketFactory: (url, config) => nodeWebSocketFactory(url, {
154
174
  headers: config?.headers,
@@ -214,13 +234,14 @@ async function connectSelectedDaemon(options) {
214
234
  timeoutMs: timeout,
215
235
  instance: options.instance,
216
236
  })).listen;
217
- const clientId = await getOrCreateCliClientId(resolvePaseoHome({}));
237
+ const home = resolveClientPaseoHome(options.target);
238
+ const clientId = await getOrCreateCliClientId(home);
218
239
  const nodeWebSocketFactory = createNodeWebSocketFactory();
219
240
  if (explicitHost?.trim().startsWith("ssh://")) {
220
241
  const target = parseSshTransportUri(explicitHost.trim());
221
242
  const tunnel = await createSshTunnel(target);
222
243
  const password = resolveDaemonPassword(explicitHost);
223
- const result = await tryConnectHost(tunnel.endpoint, password, clientId, Math.max(1, deadline - Date.now()), nodeWebSocketFactory);
244
+ const result = await tryConnectHost(tunnel.endpoint, password ? { kind: "password", password } : null, home, clientId, Math.max(1, deadline - Date.now()), nodeWebSocketFactory);
224
245
  if ("client" in result) {
225
246
  const close = result.client.close.bind(result.client);
226
247
  result.client.close = async () => {
@@ -243,7 +264,7 @@ async function connectSelectedDaemon(options) {
243
264
  if (offer) {
244
265
  return connectViaRelayOffer(offer, clientId, Math.max(1, deadline - Date.now()), nodeWebSocketFactory);
245
266
  }
246
- const result = await tryConnectHost(explicitHost, resolveDaemonPassword(explicitHost), clientId, Math.max(1, deadline - Date.now()), nodeWebSocketFactory);
267
+ const result = await tryConnectHost(explicitHost, resolveDaemonCredential(explicitHost, home), home, clientId, Math.max(1, deadline - Date.now()), nodeWebSocketFactory);
247
268
  if ("client" in result)
248
269
  return result.client;
249
270
  throw result.error;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camerontaylor/paseo-cli",
3
- "version": "0.9.0-beta.2.fork.1",
3
+ "version": "0.10.1-fork.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
- "@camerontaylor/paseo-client": "0.9.0-beta.2.fork.1",
32
- "@camerontaylor/paseo-protocol": "0.9.0-beta.2.fork.1",
33
- "@camerontaylor/paseo-server": "0.9.0-beta.2.fork.1",
31
+ "@camerontaylor/paseo-client": "0.10.1-fork.1",
32
+ "@camerontaylor/paseo-protocol": "0.10.1-fork.1",
33
+ "@camerontaylor/paseo-server": "0.10.1-fork.1",
34
34
  "chalk": "^5.3.0",
35
35
  "commander": "^12.0.0",
36
36
  "mime-types": "^2.1.35",