@camerontaylor/paseo-cli 0.8.0-fork.1 → 0.9.0-beta.2.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.
Files changed (125) hide show
  1. package/dist/cli.js +44 -37
  2. package/dist/commands/agent/archive.js +2 -15
  3. package/dist/commands/agent/attach.d.ts +1 -0
  4. package/dist/commands/agent/attach.js +8 -12
  5. package/dist/commands/agent/delete.js +4 -15
  6. package/dist/commands/agent/detach.js +2 -13
  7. package/dist/commands/agent/import.js +2 -16
  8. package/dist/commands/agent/inspect.js +2 -15
  9. package/dist/commands/agent/logs.js +13 -13
  10. package/dist/commands/agent/ls.js +2 -23
  11. package/dist/commands/agent/mode.js +2 -2
  12. package/dist/commands/agent/open.js +2 -8
  13. package/dist/commands/agent/reload.js +2 -15
  14. package/dist/commands/agent/run.js +12 -17
  15. package/dist/commands/agent/send.js +6 -15
  16. package/dist/commands/agent/stop.js +2 -15
  17. package/dist/commands/agent/update.js +2 -15
  18. package/dist/commands/agent/wait.js +4 -15
  19. package/dist/commands/clone.js +2 -8
  20. package/dist/commands/daemon/config.d.ts +3 -0
  21. package/dist/commands/daemon/config.js +103 -0
  22. package/dist/commands/daemon/index.js +20 -52
  23. package/dist/commands/daemon/local-daemon.d.ts +10 -75
  24. package/dist/commands/daemon/local-daemon.js +61 -503
  25. package/dist/commands/daemon/pair.d.ts +3 -8
  26. package/dist/commands/daemon/pair.js +33 -61
  27. package/dist/commands/daemon/reload.d.ts +3 -1
  28. package/dist/commands/daemon/reload.js +10 -2
  29. package/dist/commands/daemon/restart.d.ts +19 -11
  30. package/dist/commands/daemon/restart.js +102 -88
  31. package/dist/commands/daemon/runtime-toolchain.js +1 -1
  32. package/dist/commands/daemon/set-password.js +8 -7
  33. package/dist/commands/daemon/start.d.ts +17 -3
  34. package/dist/commands/daemon/start.js +47 -52
  35. package/dist/commands/daemon/status.d.ts +12 -20
  36. package/dist/commands/daemon/status.js +91 -342
  37. package/dist/commands/daemon/stop.d.ts +19 -14
  38. package/dist/commands/daemon/stop.js +53 -55
  39. package/dist/commands/heartbeat/index.js +3 -3
  40. package/dist/commands/hub/connect.d.ts +1 -0
  41. package/dist/commands/hub/connect.js +1 -1
  42. package/dist/commands/hub/daemon-client.d.ts +3 -2
  43. package/dist/commands/hub/daemon-client.js +3 -3
  44. package/dist/commands/hub/disconnect.d.ts +1 -0
  45. package/dist/commands/hub/disconnect.js +1 -1
  46. package/dist/commands/hub/index.js +2 -2
  47. package/dist/commands/hub/init.d.ts +3 -1
  48. package/dist/commands/hub/init.js +13 -12
  49. package/dist/commands/hub/login.d.ts +4 -4
  50. package/dist/commands/hub/login.js +1 -1
  51. package/dist/commands/hub/logout.d.ts +1 -0
  52. package/dist/commands/hub/logout.js +2 -2
  53. package/dist/commands/hub/permissions.d.ts +1 -0
  54. package/dist/commands/hub/permissions.js +2 -2
  55. package/dist/commands/onboard.d.ts +7 -2
  56. package/dist/commands/onboard.js +59 -210
  57. package/dist/commands/open.js +3 -1
  58. package/dist/commands/permit/allow.js +2 -15
  59. package/dist/commands/permit/deny.js +2 -15
  60. package/dist/commands/permit/ls.js +2 -15
  61. package/dist/commands/plugin/index.d.ts +6 -0
  62. package/dist/commands/plugin/index.js +62 -46
  63. package/dist/commands/plugin/scaffold.js +10 -0
  64. package/dist/commands/plugin/shared.d.ts +5 -3
  65. package/dist/commands/plugin/shared.js +13 -9
  66. package/dist/commands/plugin/update.d.ts +37 -0
  67. package/dist/commands/plugin/update.js +58 -0
  68. package/dist/commands/project/create.js +5 -3
  69. package/dist/commands/project/delete.js +4 -2
  70. package/dist/commands/project/ls.js +2 -2
  71. package/dist/commands/project/rename.js +4 -2
  72. package/dist/commands/provider/add.js +2 -2
  73. package/dist/commands/provider/diagnostic.js +1 -1
  74. package/dist/commands/provider/ls.js +2 -30
  75. package/dist/commands/provider/models.js +1 -1
  76. package/dist/commands/provider/rm.js +2 -2
  77. package/dist/commands/schedule/create.js +2 -2
  78. package/dist/commands/schedule/delete.js +1 -1
  79. package/dist/commands/schedule/inspect.js +1 -1
  80. package/dist/commands/schedule/logs.js +1 -1
  81. package/dist/commands/schedule/ls.js +1 -1
  82. package/dist/commands/schedule/pause.js +1 -1
  83. package/dist/commands/schedule/resume.js +1 -1
  84. package/dist/commands/schedule/run-once.js +1 -1
  85. package/dist/commands/schedule/shared.d.ts +3 -1
  86. package/dist/commands/schedule/shared.js +7 -5
  87. package/dist/commands/schedule/update.js +1 -1
  88. package/dist/commands/script/ls.js +1 -1
  89. package/dist/commands/script/shared.d.ts +2 -1
  90. package/dist/commands/script/shared.js +3 -3
  91. package/dist/commands/script/start.js +1 -1
  92. package/dist/commands/script/stop.js +1 -1
  93. package/dist/commands/terminal/capture.d.ts +1 -1
  94. package/dist/commands/terminal/capture.js +2 -3
  95. package/dist/commands/terminal/create.js +1 -1
  96. package/dist/commands/terminal/kill.js +1 -1
  97. package/dist/commands/terminal/ls.js +1 -1
  98. package/dist/commands/terminal/send-keys.d.ts +1 -1
  99. package/dist/commands/terminal/send-keys.js +2 -3
  100. package/dist/commands/terminal/shared.d.ts +2 -1
  101. package/dist/commands/terminal/shared.js +5 -3
  102. package/dist/commands/workspace/archive.d.ts +1 -0
  103. package/dist/commands/workspace/archive.js +4 -2
  104. package/dist/commands/workspace/create.js +4 -2
  105. package/dist/commands/workspace/ls.d.ts +1 -0
  106. package/dist/commands/workspace/ls.js +2 -2
  107. package/dist/commands/workspace/rename.d.ts +1 -0
  108. package/dist/commands/workspace/rename.js +4 -2
  109. package/dist/commands/workspace/setup.d.ts +1 -0
  110. package/dist/commands/workspace/setup.js +2 -2
  111. package/dist/commands/worktree/archive.js +4 -2
  112. package/dist/commands/worktree/create.js +2 -10
  113. package/dist/commands/worktree/ls.d.ts +0 -2
  114. package/dist/commands/worktree/ls.js +4 -30
  115. package/dist/output/with-output.d.ts +2 -0
  116. package/dist/run.js +11 -1
  117. package/dist/utils/client-id.d.ts +1 -1
  118. package/dist/utils/client-id.js +8 -14
  119. package/dist/utils/client.d.ts +16 -21
  120. package/dist/utils/client.js +57 -109
  121. package/dist/utils/command-options.d.ts +1 -0
  122. package/dist/utils/command-options.js +26 -2
  123. package/dist/utils/daemon-target.d.ts +13 -0
  124. package/dist/utils/daemon-target.js +51 -0
  125. package/package.json +8 -4
@@ -1,14 +1,13 @@
1
+ import { type DaemonInstance } from "@camerontaylor/paseo-server/daemon-control";
2
+ import { type DaemonTarget } from "./daemon-target.js";
3
+ export type { DaemonTarget } from "./daemon-target.js";
1
4
  import { DaemonClient } from "@camerontaylor/paseo-client/internal/daemon-client";
2
5
  export interface ConnectOptions {
3
- host?: string;
6
+ target: DaemonTarget;
4
7
  timeout?: number;
8
+ instance?: DaemonInstance;
5
9
  }
6
- export interface DaemonConnectionCommandError {
7
- code: "DAEMON_NOT_RUNNING";
8
- message: string;
9
- details: string;
10
- }
11
- type DaemonTarget = {
10
+ type TransportTarget = {
12
11
  type: "tcp";
13
12
  url: string;
14
13
  } | {
@@ -16,25 +15,22 @@ type DaemonTarget = {
16
15
  url: string;
17
16
  socketPath: string;
18
17
  };
19
- /**
20
- * Get the daemon host from environment or options
21
- */
22
- export declare function getDaemonHost(options?: ConnectOptions): string;
23
- export declare function buildDaemonConnectionCommandError(options: {
24
- host?: string;
18
+ export declare function getDaemonHost(options: ConnectOptions): string;
19
+ export declare function buildDaemonConnectionCommandError(options: ConnectOptions & {
25
20
  error: unknown;
26
- }): DaemonConnectionCommandError;
21
+ }): {
22
+ code: string;
23
+ message: string;
24
+ details: string;
25
+ };
27
26
  export declare function normalizeDaemonHost(raw: string): string | null;
28
- export declare function resolveDefaultDaemonHost(env?: NodeJS.ProcessEnv): string;
29
- export declare function resolveDefaultDaemonHosts(env?: NodeJS.ProcessEnv): string[];
30
- export declare function getExplicitDaemonHost(host: string | undefined, env?: NodeJS.ProcessEnv): string | undefined;
31
- export declare function resolveDaemonTarget(host: string): DaemonTarget;
27
+ export declare function resolveDaemonTarget(host: string): TransportTarget;
32
28
  export declare function resolveDaemonPassword(host: string): string | undefined;
33
- export declare function connectToDaemon(options?: ConnectOptions): Promise<DaemonClient>;
29
+ export declare function connectToDaemon(options: ConnectOptions): Promise<DaemonClient>;
34
30
  /**
35
31
  * Try to connect to the daemon, returns null if connection fails
36
32
  */
37
- export declare function tryConnectToDaemon(options?: ConnectOptions): Promise<DaemonClient | null>;
33
+ export declare function tryConnectToDaemon(options: ConnectOptions): Promise<DaemonClient | null>;
38
34
  /** Minimal agent type for ID resolution */
39
35
  interface AgentLike {
40
36
  id: string;
@@ -50,5 +46,4 @@ interface AgentLike {
50
46
  * Returns the full agent ID if found, null otherwise.
51
47
  */
52
48
  export declare function resolveAgentId(idOrName: string, agents: AgentLike[]): string | null;
53
- export {};
54
49
  //# sourceMappingURL=client.d.ts.map
@@ -1,32 +1,39 @@
1
- import { existsSync, readFileSync } from "node:fs";
2
- import { loadConfig, resolvePaseoHome } from "@camerontaylor/paseo-server";
1
+ import { waitForDaemonReady, resolvePaseoHome, } from "@camerontaylor/paseo-server/daemon-control";
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";
5
5
  import { parseSshTransportUri } from "@camerontaylor/paseo-protocol/ssh-transport";
6
6
  import { DaemonClient } from "@camerontaylor/paseo-client/internal/daemon-client";
7
- import path from "node:path";
8
7
  import { WebSocket } from "ws";
9
8
  import { getOrCreateCliClientId } from "./client-id.js";
10
9
  import { resolveCliVersion } from "../version.js";
11
10
  import { createSshTunnel } from "../ssh/ssh-tunnel.js";
12
- const DEFAULT_HOST = "localhost:6767";
13
11
  const DEFAULT_TIMEOUT = 15000;
14
- const PID_FILENAME = "paseo.pid";
15
- /**
16
- * Get the daemon host from environment or options
17
- */
18
12
  export function getDaemonHost(options) {
19
- return resolveDaemonHostCandidates(options)[0] ?? DEFAULT_HOST;
13
+ return describeDaemonTarget(options.target);
20
14
  }
21
15
  export function buildDaemonConnectionCommandError(options) {
22
- const host = getDaemonHost({ host: options.host });
23
- const message = options.error instanceof Error ? options.error.message : String(options.error);
16
+ const error = options.error;
17
+ let message = error instanceof Error ? error.message : String(error);
18
+ if (error && typeof error === "object" && "message" in error)
19
+ message = String(error.message);
20
+ if (options.target.kind === "endpoint")
21
+ message = message.replaceAll(options.target.host, describeDaemonTarget(options.target));
22
+ if (message.startsWith("Cannot connect to daemon at "))
23
+ return error;
24
+ let code = "DAEMON_UNREACHABLE";
25
+ if (typeof error === "object" && error !== null && "code" in error)
26
+ code = String(error.code);
27
+ else if (message === "Password required")
28
+ code = "AUTH_REQUIRED";
29
+ else if (message === "Incorrect password")
30
+ code = "AUTH_FAILED";
24
31
  return {
25
- code: "DAEMON_NOT_RUNNING",
26
- message: `Cannot connect to daemon at ${host}: ${message}`,
27
- details: host.trim().startsWith("ssh://")
28
- ? "Start the Paseo daemon on the SSH host; SSH transport does not install or start it."
29
- : "Start the daemon with: paseo daemon start",
32
+ code,
33
+ 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.",
30
37
  };
31
38
  }
32
39
  export function normalizeDaemonHost(raw) {
@@ -70,77 +77,6 @@ export function normalizeDaemonHost(raw) {
70
77
  }
71
78
  return trimmed.includes(":") ? trimmed : null;
72
79
  }
73
- export function resolveDefaultDaemonHost(env = process.env) {
74
- return resolveDefaultDaemonHosts(env)[0] ?? DEFAULT_HOST;
75
- }
76
- function isIpcDaemonHost(host) {
77
- return host !== null && (host.startsWith("unix://") || host.startsWith("pipe://"));
78
- }
79
- function isTcpDaemonHost(host) {
80
- return host !== null && !isIpcDaemonHost(host);
81
- }
82
- function readPidSocketTarget(paseoHome) {
83
- const pidPath = path.join(paseoHome, PID_FILENAME);
84
- if (!existsSync(pidPath)) {
85
- return null;
86
- }
87
- try {
88
- const parsed = JSON.parse(readFileSync(pidPath, "utf-8"));
89
- if (typeof parsed.listen === "string")
90
- return parsed.listen;
91
- if (typeof parsed.sockPath === "string")
92
- return parsed.sockPath;
93
- return null;
94
- }
95
- catch {
96
- return null;
97
- }
98
- }
99
- function resolveConfiguredIpcDaemonHost(env, paseoHome) {
100
- const directEnvHost = normalizeDaemonHost(env.PASEO_LISTEN ?? "");
101
- if (isIpcDaemonHost(directEnvHost)) {
102
- return directEnvHost;
103
- }
104
- const pidHost = normalizeDaemonHost(readPidSocketTarget(paseoHome) ?? "");
105
- if (isIpcDaemonHost(pidHost)) {
106
- return pidHost;
107
- }
108
- const config = loadConfig(paseoHome, { env });
109
- const configuredHost = normalizeDaemonHost(config.listen);
110
- return isIpcDaemonHost(configuredHost) ? configuredHost : null;
111
- }
112
- function resolveConfiguredTcpDaemonHost(env, paseoHome) {
113
- const configuredHost = normalizeDaemonHost(loadConfig(paseoHome, { env }).listen);
114
- if (!isTcpDaemonHost(configuredHost)) {
115
- return null;
116
- }
117
- return configuredHost === "127.0.0.1:6767" ? null : configuredHost;
118
- }
119
- export function resolveDefaultDaemonHosts(env = process.env) {
120
- const paseoHome = resolvePaseoHome(env);
121
- const candidates = [];
122
- const configuredIpcHost = resolveConfiguredIpcDaemonHost(env, paseoHome);
123
- if (configuredIpcHost) {
124
- candidates.push(configuredIpcHost);
125
- }
126
- const configuredTcpHost = resolveConfiguredTcpDaemonHost(env, paseoHome);
127
- if (configuredTcpHost) {
128
- candidates.push(configuredTcpHost);
129
- }
130
- candidates.push(DEFAULT_HOST);
131
- return Array.from(new Set(candidates));
132
- }
133
- function resolveDaemonHostCandidates(options) {
134
- const explicitHost = getExplicitDaemonHost(options?.host);
135
- if (explicitHost) {
136
- return [explicitHost];
137
- }
138
- return resolveDefaultDaemonHosts();
139
- }
140
- export function getExplicitDaemonHost(host, env = process.env) {
141
- const explicitHost = host ?? env.PASEO_HOST;
142
- return explicitHost?.trim() ? explicitHost : undefined;
143
- }
144
80
  function stripIpcPrefix(trimmed) {
145
81
  if (trimmed.startsWith("unix://"))
146
82
  return trimmed.slice("unix://".length).trim();
@@ -269,18 +205,34 @@ function parseHostOfferOrNull(host) {
269
205
  throw new Error(`Invalid pairing offer URL: ${message}`, { cause: error });
270
206
  }
271
207
  }
272
- export async function connectToDaemon(options) {
273
- const timeout = options?.timeout ?? DEFAULT_TIMEOUT;
274
- const clientId = await getOrCreateCliClientId();
208
+ async function connectSelectedDaemon(options) {
209
+ const timeout = options.timeout ?? DEFAULT_TIMEOUT;
210
+ const deadline = Date.now() + timeout;
211
+ const explicitHost = options.target.kind === "endpoint"
212
+ ? options.target.host
213
+ : (await waitForDaemonReady(options.target.home, {
214
+ timeoutMs: timeout,
215
+ instance: options.instance,
216
+ })).listen;
217
+ const clientId = await getOrCreateCliClientId(resolvePaseoHome({}));
275
218
  const nodeWebSocketFactory = createNodeWebSocketFactory();
276
- const explicitHost = getExplicitDaemonHost(options?.host);
277
219
  if (explicitHost?.trim().startsWith("ssh://")) {
278
220
  const target = parseSshTransportUri(explicitHost.trim());
279
221
  const tunnel = await createSshTunnel(target);
280
222
  const password = resolveDaemonPassword(explicitHost);
281
- const result = await tryConnectHost(tunnel.endpoint, password, clientId, timeout, nodeWebSocketFactory);
282
- if ("client" in result)
223
+ const result = await tryConnectHost(tunnel.endpoint, password, clientId, Math.max(1, deadline - Date.now()), nodeWebSocketFactory);
224
+ if ("client" in result) {
225
+ const close = result.client.close.bind(result.client);
226
+ result.client.close = async () => {
227
+ try {
228
+ await close();
229
+ }
230
+ finally {
231
+ tunnel.close();
232
+ }
233
+ };
283
234
  return result.client;
235
+ }
284
236
  const failure = tunnel.failureDetail();
285
237
  tunnel.close();
286
238
  if (failure)
@@ -289,24 +241,20 @@ export async function connectToDaemon(options) {
289
241
  }
290
242
  const offer = parseHostOfferOrNull(explicitHost);
291
243
  if (offer) {
292
- return connectViaRelayOffer(offer, clientId, timeout, nodeWebSocketFactory);
244
+ return connectViaRelayOffer(offer, clientId, Math.max(1, deadline - Date.now()), nodeWebSocketFactory);
293
245
  }
294
- const hosts = resolveDaemonHostCandidates(options);
295
- async function tryNext(index, lastError) {
296
- if (index >= hosts.length) {
297
- if (lastError instanceof Error)
298
- throw lastError;
299
- throw new Error(`Unable to connect to Paseo daemon via ${hosts.join(", ")}`);
300
- }
301
- const host = hosts[index];
302
- const password = resolveDaemonPassword(host);
303
- const result = await tryConnectHost(host, password, clientId, timeout, nodeWebSocketFactory);
304
- if ("client" in result) {
305
- return result.client;
306
- }
307
- return tryNext(index + 1, result.error);
246
+ const result = await tryConnectHost(explicitHost, resolveDaemonPassword(explicitHost), clientId, Math.max(1, deadline - Date.now()), nodeWebSocketFactory);
247
+ if ("client" in result)
248
+ return result.client;
249
+ throw result.error;
250
+ }
251
+ export async function connectToDaemon(options) {
252
+ try {
253
+ return await connectSelectedDaemon(options);
254
+ }
255
+ catch (error) {
256
+ throw buildDaemonConnectionCommandError({ ...options, error });
308
257
  }
309
- return tryNext(0, null);
310
258
  }
311
259
  /**
312
260
  * Try to connect to the daemon, returns null if connection fails
@@ -1,4 +1,5 @@
1
1
  import type { Command } from "commander";
2
+ export declare function addLocalDaemonOptions<T extends Command>(command: T): T;
2
3
  export declare function collectMultiple(value: string, previous: string[]): string[];
3
4
  export declare function addJsonOption<T extends Command>(command: T): T;
4
5
  export declare function addDaemonHostOption<T extends Command>(command: T): T;
@@ -1,5 +1,12 @@
1
+ import { selectDaemonTarget } from "./daemon-target.js";
1
2
  const JSON_OPTION_DESCRIPTION = "Output in JSON format";
2
- const DAEMON_HOST_OPTION_DESCRIPTION = "Daemon host target: host:port, tcp://host:port, or ssh://user@host (default: local socket/pipe, then localhost:6767)";
3
+ const DAEMON_HOST_OPTION_DESCRIPTION = "Explicit daemon endpoint: host:port, TCP, socket, SSH, or pairing URL (default: local home)";
4
+ const localCommands = new WeakSet();
5
+ export function addLocalDaemonOptions(command) {
6
+ localCommands.add(command);
7
+ command.option("--home <path>", "Local daemon home (default: ~/.paseo)");
8
+ return command;
9
+ }
3
10
  export function collectMultiple(value, previous) {
4
11
  return previous.concat([value]);
5
12
  }
@@ -9,6 +16,8 @@ export function addJsonOption(command) {
9
16
  }
10
17
  export function addDaemonHostOption(command) {
11
18
  command.option("--host <host>", DAEMON_HOST_OPTION_DESCRIPTION);
19
+ if (!command.options.some((option) => option.long === "--home"))
20
+ command.option("--home <path>", "Select a local daemon home (default: ~/.paseo)");
12
21
  return command;
13
22
  }
14
23
  export function addJsonAndDaemonHostOptions(command) {
@@ -18,7 +27,22 @@ export function withGlobalOptions(handler) {
18
27
  return (...args) => {
19
28
  const command = args.at(-1);
20
29
  const mergedArgs = [...args];
21
- mergedArgs[mergedArgs.length - 2] = command.optsWithGlobals();
30
+ const options = command.optsWithGlobals();
31
+ const selectors = { home: new Set(), host: new Set() };
32
+ for (let current = command; current; current = current.parent) {
33
+ for (const key of ["home", "host"]) {
34
+ const value = current.opts()[key];
35
+ if (typeof value === "string")
36
+ selectors[key].add(value);
37
+ }
38
+ }
39
+ for (const key of ["home", "host"]) {
40
+ if (selectors[key].size > 1)
41
+ throw { code: "TARGET_AMBIGUOUS", message: `Conflicting duplicate --${key} selectors.` };
42
+ }
43
+ const localOnly = localCommands.has(command);
44
+ options.daemonTarget = selectDaemonTarget(options, process.env, localOnly);
45
+ mergedArgs[mergedArgs.length - 2] = options;
22
46
  return handler(...mergedArgs);
23
47
  };
24
48
  }
@@ -0,0 +1,13 @@
1
+ export type DaemonTarget = {
2
+ kind: "instance";
3
+ home: string;
4
+ } | {
5
+ kind: "endpoint";
6
+ host: string;
7
+ };
8
+ export declare function selectDaemonTarget(options: {
9
+ home?: string;
10
+ host?: string;
11
+ }, env?: NodeJS.ProcessEnv, localOnly?: boolean): DaemonTarget;
12
+ export declare function describeDaemonTarget(target: DaemonTarget): string;
13
+ //# sourceMappingURL=daemon-target.d.ts.map
@@ -0,0 +1,51 @@
1
+ import { resolvePaseoHome } from "@camerontaylor/paseo-server/daemon-control";
2
+ export function selectDaemonTarget(options, env = process.env, localOnly = false) {
3
+ for (const key of ["home", "host"]) {
4
+ if (options[key] !== undefined && !options[key].trim())
5
+ throw { code: "TARGET_INVALID", message: `--${key} requires a non-empty value.` };
6
+ }
7
+ if (options.home !== undefined && options.host !== undefined)
8
+ throw { code: "TARGET_AMBIGUOUS", message: "Choose either --home or --host, not both." };
9
+ if (localOnly) {
10
+ if (options.host !== undefined)
11
+ throw {
12
+ code: "LOCAL_OPERATION",
13
+ message: "This is a local operation; use --home. --host is not supported.",
14
+ };
15
+ return {
16
+ kind: "instance",
17
+ home: resolvePaseoHome({ PASEO_HOME: options.home ?? env.PASEO_HOME }),
18
+ };
19
+ }
20
+ if (options.home !== undefined)
21
+ return { kind: "instance", home: resolvePaseoHome({ PASEO_HOME: options.home }) };
22
+ if (options.host !== undefined)
23
+ return { kind: "endpoint", host: options.host };
24
+ if (env.PASEO_HOME && env.PASEO_HOST)
25
+ throw {
26
+ code: "TARGET_AMBIGUOUS",
27
+ message: "PASEO_HOME and PASEO_HOST are both set. Choose --home or --host explicitly.",
28
+ };
29
+ if (env.PASEO_HOST)
30
+ return { kind: "endpoint", host: env.PASEO_HOST };
31
+ return { kind: "instance", home: resolvePaseoHome({ PASEO_HOME: env.PASEO_HOME }) };
32
+ }
33
+ export function describeDaemonTarget(target) {
34
+ if (target.kind === "instance")
35
+ return `home ${target.home}`;
36
+ try {
37
+ const url = new URL(target.host);
38
+ if (url.password)
39
+ url.password = "REDACTED";
40
+ for (const key of url.searchParams.keys())
41
+ if (/password|token|secret/i.test(key))
42
+ url.searchParams.set(key, "REDACTED");
43
+ if (url.hash)
44
+ url.hash = "REDACTED";
45
+ return url.toString();
46
+ }
47
+ catch {
48
+ return target.host.replace(/([?&](?:password|token|secret)=)[^&]*/gi, "$1REDACTED");
49
+ }
50
+ }
51
+ //# sourceMappingURL=daemon-target.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camerontaylor/paseo-cli",
3
- "version": "0.8.0-fork.1",
3
+ "version": "0.9.0-beta.2.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.8.0-fork.1",
32
- "@camerontaylor/paseo-protocol": "0.8.0-fork.1",
33
- "@camerontaylor/paseo-server": "0.8.0-fork.1",
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",
34
34
  "chalk": "^5.3.0",
35
35
  "commander": "^12.0.0",
36
36
  "mime-types": "^2.1.35",
@@ -46,5 +46,9 @@
46
46
  "typescript": "^5.2.2",
47
47
  "vitest": "^4.1.6",
48
48
  "zx": "^8.8.5"
49
+ },
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "https://github.com/camerontaylor/paseo"
49
53
  }
50
54
  }