@getpaseo/cli 0.3.1 → 0.4.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.
- package/dist/cli.js +0 -5
- package/dist/commands/hub/connect.d.ts +1 -1
- package/dist/commands/hub/deploy-bundle.d.ts +16 -0
- package/dist/commands/hub/deploy-bundle.js +248 -0
- package/dist/commands/hub/deploy.d.ts +3 -2
- package/dist/commands/hub/deploy.js +17 -10
- package/dist/commands/hub/hub-client/index.d.ts +18 -0
- package/dist/commands/hub/hub-client/index.js +88 -0
- package/dist/commands/hub/{client.d.ts → hub-client/internal/contracts.d.ts} +16 -22
- package/dist/commands/hub/hub-client/internal/contracts.js +47 -0
- package/dist/commands/hub/hub-client/internal/problem.d.ts +3 -0
- package/dist/commands/hub/hub-client/internal/problem.js +72 -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 +1 -1
- package/dist/commands/hub/index.js +1 -1
- package/dist/commands/hub/login-flow.d.ts +1 -1
- package/dist/commands/hub/projects.d.ts +1 -1
- package/dist/commands/provider/diagnostic.d.ts +12 -0
- package/dist/commands/provider/diagnostic.js +31 -0
- package/dist/commands/provider/index.js +5 -0
- package/dist/commands/workspace/index.js +10 -0
- package/dist/commands/workspace/rename.d.ts +22 -0
- package/dist/commands/workspace/rename.js +61 -0
- package/package.json +4 -4
- package/dist/commands/chat/create.d.ts +0 -9
- package/dist/commands/chat/create.js +0 -23
- package/dist/commands/chat/delete.d.ts +0 -6
- package/dist/commands/chat/delete.js +0 -20
- package/dist/commands/chat/index.d.ts +0 -3
- package/dist/commands/chat/index.js +0 -47
- package/dist/commands/chat/inspect.d.ts +0 -6
- package/dist/commands/chat/inspect.js +0 -20
- package/dist/commands/chat/ls.d.ts +0 -6
- package/dist/commands/chat/ls.js +0 -20
- package/dist/commands/chat/post.d.ts +0 -9
- package/dist/commands/chat/post.js +0 -28
- package/dist/commands/chat/read.d.ts +0 -11
- package/dist/commands/chat/read.js +0 -40
- package/dist/commands/chat/schema.d.ts +0 -36
- package/dist/commands/chat/schema.js +0 -81
- package/dist/commands/chat/shared.d.ts +0 -19
- package/dist/commands/chat/shared.js +0 -118
- package/dist/commands/chat/wait.d.ts +0 -9
- package/dist/commands/chat/wait.js +0 -45
- package/dist/commands/hub/client.js +0 -234
- package/dist/commands/hub/deploy-input.d.ts +0 -17
- package/dist/commands/hub/deploy-input.js +0 -264
- package/dist/commands/loop/index.d.ts +0 -3
- package/dist/commands/loop/index.js +0 -18
- package/dist/commands/loop/inspect.d.ts +0 -13
- package/dist/commands/loop/inspect.js +0 -100
- package/dist/commands/loop/logs.d.ts +0 -8
- package/dist/commands/loop/logs.js +0 -69
- package/dist/commands/loop/ls.d.ts +0 -18
- package/dist/commands/loop/ls.js +0 -62
- package/dist/commands/loop/run.d.ts +0 -30
- package/dist/commands/loop/run.js +0 -162
- package/dist/commands/loop/stop.d.ts +0 -15
- package/dist/commands/loop/stop.js +0 -56
- package/dist/commands/loop/types.d.ts +0 -138
- package/dist/commands/loop/types.js +0 -2
|
@@ -1,264 +0,0 @@
|
|
|
1
|
-
import { lstat, readFile } from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import YAML from "yaml";
|
|
4
|
-
import { HubCommandError } from "./error.js";
|
|
5
|
-
const DEFAULT_CONFIGURATION_PATH = ".paseo/hub.yml";
|
|
6
|
-
const PROMPT_PARTIAL_ROOT = ".paseo/partials";
|
|
7
|
-
const PROMPT_PARTIAL_ROOT_PREFIX = `${PROMPT_PARTIAL_ROOT}/`;
|
|
8
|
-
const PROJECT_SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
|
|
9
|
-
const MAX_CONFIGURATION_LENGTH = 1000000;
|
|
10
|
-
const MAX_PROMPT_PARTIAL_COUNT = 100;
|
|
11
|
-
const MAX_PROMPT_PARTIAL_PATH_LENGTH = 512;
|
|
12
|
-
const MAX_PROMPT_PARTIAL_CONTENT_BYTES = 1000000;
|
|
13
|
-
const MAX_PROMPT_PARTIAL_BUNDLE_BYTES = 5000000;
|
|
14
|
-
export async function resolveHubDeployInput(input) {
|
|
15
|
-
const file = input.file ?? DEFAULT_CONFIGURATION_PATH;
|
|
16
|
-
const projectRoot = path.resolve(input.cwd);
|
|
17
|
-
const configurationPath = resolveConfigurationPath(projectRoot, file);
|
|
18
|
-
const yaml = await readConfiguration(projectRoot, configurationPath, file);
|
|
19
|
-
const configuration = parseConfiguration(yaml);
|
|
20
|
-
const projectSlug = input.project ?? projectFromConfiguration(configuration);
|
|
21
|
-
if (projectSlug === undefined) {
|
|
22
|
-
throw new HubCommandError("HUB_PROJECT_REQUIRED", "Project is required. Pass --project <slug> or add top-level project to the YAML.");
|
|
23
|
-
}
|
|
24
|
-
if (!PROJECT_SLUG_PATTERN.test(projectSlug)) {
|
|
25
|
-
throw new HubCommandError("HUB_INVALID_PROJECT", "Project must be a bare slug such as my-project.");
|
|
26
|
-
}
|
|
27
|
-
const partials = await resolvePromptPartials(projectRoot, configuration);
|
|
28
|
-
return {
|
|
29
|
-
projectSlug,
|
|
30
|
-
yaml,
|
|
31
|
-
...(partials.length === 0 ? {} : { partials }),
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
function resolveConfigurationPath(cwd, file) {
|
|
35
|
-
if (file.length === 0 || file.includes("\0")) {
|
|
36
|
-
throw invalidConfigurationPath();
|
|
37
|
-
}
|
|
38
|
-
const segments = file.replaceAll("\\", "/").split("/");
|
|
39
|
-
if (segments.some((segment) => segment === "..")) {
|
|
40
|
-
throw invalidConfigurationPath();
|
|
41
|
-
}
|
|
42
|
-
const resolved = path.resolve(cwd, file);
|
|
43
|
-
const relative = path.relative(cwd, resolved);
|
|
44
|
-
if (relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
|
|
45
|
-
throw invalidConfigurationPath();
|
|
46
|
-
}
|
|
47
|
-
return resolved;
|
|
48
|
-
}
|
|
49
|
-
async function readConfiguration(projectRoot, configurationPath, displayPath) {
|
|
50
|
-
const unsafePath = () => new HubCommandError("HUB_CONFIGURATION_UNSAFE_PATH", `Hub configuration at ${displayPath} must not use a symlink.`);
|
|
51
|
-
await rejectSymlinkComponents(projectRoot, configurationPath, unsafePath);
|
|
52
|
-
let stats;
|
|
53
|
-
try {
|
|
54
|
-
stats = await lstat(configurationPath);
|
|
55
|
-
}
|
|
56
|
-
catch (error) {
|
|
57
|
-
throw configurationReadError(displayPath, error);
|
|
58
|
-
}
|
|
59
|
-
if (stats.isSymbolicLink()) {
|
|
60
|
-
throw unsafePath();
|
|
61
|
-
}
|
|
62
|
-
if (!stats.isFile()) {
|
|
63
|
-
throw new HubCommandError("HUB_CONFIGURATION_NOT_FILE", `Hub configuration at ${displayPath} must be a regular file.`);
|
|
64
|
-
}
|
|
65
|
-
if (!hasReadPermission(stats.mode)) {
|
|
66
|
-
throw new HubCommandError("HUB_CONFIGURATION_UNREADABLE", `Could not read Hub configuration at ${displayPath}. Check file permissions.`);
|
|
67
|
-
}
|
|
68
|
-
let bytes;
|
|
69
|
-
try {
|
|
70
|
-
bytes = await readFile(configurationPath);
|
|
71
|
-
}
|
|
72
|
-
catch (error) {
|
|
73
|
-
throw configurationReadError(displayPath, error);
|
|
74
|
-
}
|
|
75
|
-
const yaml = bytes.toString("utf8");
|
|
76
|
-
if (yaml.length > MAX_CONFIGURATION_LENGTH) {
|
|
77
|
-
throw new HubCommandError("HUB_CONFIGURATION_TOO_LARGE", `Hub configuration at ${displayPath} exceeds the ${MAX_CONFIGURATION_LENGTH}-character limit.`);
|
|
78
|
-
}
|
|
79
|
-
return yaml;
|
|
80
|
-
}
|
|
81
|
-
function parseConfiguration(yaml) {
|
|
82
|
-
let configuration;
|
|
83
|
-
try {
|
|
84
|
-
configuration = YAML.parse(yaml);
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
throw new HubCommandError("HUB_INVALID_CONFIGURATION", "Hub configuration is not valid YAML.");
|
|
88
|
-
}
|
|
89
|
-
if (!isRecord(configuration)) {
|
|
90
|
-
throw new HubCommandError("HUB_INVALID_CONFIGURATION", "Hub configuration must be a YAML mapping.");
|
|
91
|
-
}
|
|
92
|
-
return configuration;
|
|
93
|
-
}
|
|
94
|
-
function projectFromConfiguration(configuration) {
|
|
95
|
-
const project = configuration["project"];
|
|
96
|
-
if (project === undefined)
|
|
97
|
-
return undefined;
|
|
98
|
-
if (typeof project !== "string") {
|
|
99
|
-
throw new HubCommandError("HUB_INVALID_PROJECT", "Top-level project must be a bare project slug.");
|
|
100
|
-
}
|
|
101
|
-
return project;
|
|
102
|
-
}
|
|
103
|
-
async function resolvePromptPartials(projectRoot, configuration) {
|
|
104
|
-
const references = collectPromptPartialReferences(configuration);
|
|
105
|
-
if (references.length > MAX_PROMPT_PARTIAL_COUNT) {
|
|
106
|
-
throw new HubCommandError("HUB_PARTIAL_LIMIT_EXCEEDED", `Hub configuration references ${references.length} partials; the limit is ${MAX_PROMPT_PARTIAL_COUNT}.`);
|
|
107
|
-
}
|
|
108
|
-
const partials = [];
|
|
109
|
-
let bundleBytes = 0;
|
|
110
|
-
for (const reference of references) {
|
|
111
|
-
const partialPath = path.resolve(projectRoot, PROMPT_PARTIAL_ROOT, ...reference.path.split("/"));
|
|
112
|
-
const content = await readPartial(projectRoot, partialPath, reference.path);
|
|
113
|
-
const contentBytes = Buffer.byteLength(content, "utf8");
|
|
114
|
-
if (contentBytes > MAX_PROMPT_PARTIAL_CONTENT_BYTES) {
|
|
115
|
-
throw new HubCommandError("HUB_PARTIAL_TOO_LARGE", `Referenced Hub partial ${reference.path} exceeds the ${MAX_PROMPT_PARTIAL_CONTENT_BYTES}-byte limit.`);
|
|
116
|
-
}
|
|
117
|
-
bundleBytes += contentBytes;
|
|
118
|
-
if (bundleBytes > MAX_PROMPT_PARTIAL_BUNDLE_BYTES) {
|
|
119
|
-
throw new HubCommandError("HUB_PARTIAL_BUNDLE_TOO_LARGE", `Referenced Hub partials exceed the ${MAX_PROMPT_PARTIAL_BUNDLE_BYTES}-byte combined limit.`);
|
|
120
|
-
}
|
|
121
|
-
partials.push({ path: reference.path, content });
|
|
122
|
-
}
|
|
123
|
-
return partials;
|
|
124
|
-
}
|
|
125
|
-
function collectPromptPartialReferences(configuration) {
|
|
126
|
-
const references = [];
|
|
127
|
-
const seen = new Set();
|
|
128
|
-
const triggers = configuration["triggers"];
|
|
129
|
-
if (!Array.isArray(triggers))
|
|
130
|
-
return references;
|
|
131
|
-
for (const trigger of triggers) {
|
|
132
|
-
if (!isRecord(trigger) || !Array.isArray(trigger["steps"]))
|
|
133
|
-
continue;
|
|
134
|
-
for (const step of trigger["steps"]) {
|
|
135
|
-
if (!isRecord(step) || !Array.isArray(step["prompt"]))
|
|
136
|
-
continue;
|
|
137
|
-
for (const block of step["prompt"]) {
|
|
138
|
-
if (!isRecord(block) || !Object.hasOwn(block, "include"))
|
|
139
|
-
continue;
|
|
140
|
-
const include = block["include"];
|
|
141
|
-
if (typeof include !== "string") {
|
|
142
|
-
throw new HubCommandError("HUB_PARTIAL_PATH_INVALID", "Hub partial include path must be a string.");
|
|
143
|
-
}
|
|
144
|
-
const normalizedPath = normalizePromptPartialPath(include);
|
|
145
|
-
if (seen.has(normalizedPath)) {
|
|
146
|
-
throw new HubCommandError("HUB_PARTIAL_DUPLICATE", `Hub partial ${normalizedPath} is referenced more than once. Remove the duplicate include.`);
|
|
147
|
-
}
|
|
148
|
-
seen.add(normalizedPath);
|
|
149
|
-
references.push({ path: normalizedPath });
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return references;
|
|
154
|
-
}
|
|
155
|
-
function normalizePromptPartialPath(value) {
|
|
156
|
-
const decoded = decodePromptPartialPath(value);
|
|
157
|
-
if (decoded.length === 0)
|
|
158
|
-
throw invalidPromptPartialPath(value);
|
|
159
|
-
if (/^(?:[a-zA-Z]:[\\/]|[\\/]{1,2})/u.test(decoded)) {
|
|
160
|
-
throw invalidPromptPartialPath(value);
|
|
161
|
-
}
|
|
162
|
-
const segments = decoded.replaceAll("\\", "/").split("/");
|
|
163
|
-
if (segments.some((segment) => segment.length === 0 || segment === "." || segment === "..")) {
|
|
164
|
-
throw invalidPromptPartialPath(value);
|
|
165
|
-
}
|
|
166
|
-
const canonical = `${PROMPT_PARTIAL_ROOT}/${segments.join("/")}`;
|
|
167
|
-
if (!canonical.startsWith(PROMPT_PARTIAL_ROOT_PREFIX)) {
|
|
168
|
-
throw invalidPromptPartialPath(value);
|
|
169
|
-
}
|
|
170
|
-
if (canonical.length > MAX_PROMPT_PARTIAL_PATH_LENGTH) {
|
|
171
|
-
throw new HubCommandError("HUB_PARTIAL_PATH_TOO_LONG", `Hub partial path ${value} exceeds the ${MAX_PROMPT_PARTIAL_PATH_LENGTH}-character limit.`);
|
|
172
|
-
}
|
|
173
|
-
return canonical.slice(PROMPT_PARTIAL_ROOT_PREFIX.length);
|
|
174
|
-
}
|
|
175
|
-
function decodePromptPartialPath(value) {
|
|
176
|
-
let decoded = value;
|
|
177
|
-
for (let attempt = 0; attempt < 8; attempt += 1) {
|
|
178
|
-
let next;
|
|
179
|
-
try {
|
|
180
|
-
next = decodeURIComponent(decoded);
|
|
181
|
-
}
|
|
182
|
-
catch {
|
|
183
|
-
throw invalidPromptPartialPath(value);
|
|
184
|
-
}
|
|
185
|
-
if (next === decoded)
|
|
186
|
-
break;
|
|
187
|
-
decoded = next;
|
|
188
|
-
}
|
|
189
|
-
if (decoded.includes("\0") || /%[0-9a-f]{2}/iu.test(decoded)) {
|
|
190
|
-
throw invalidPromptPartialPath(value);
|
|
191
|
-
}
|
|
192
|
-
return decoded;
|
|
193
|
-
}
|
|
194
|
-
async function readPartial(projectRoot, partialPath, displayPath) {
|
|
195
|
-
await rejectSymlinkComponents(projectRoot, partialPath, () => new HubCommandError("HUB_PARTIAL_UNSAFE_PATH", `Referenced Hub partial ${displayPath} must not use a symlink.`));
|
|
196
|
-
let stats;
|
|
197
|
-
try {
|
|
198
|
-
stats = await lstat(partialPath);
|
|
199
|
-
}
|
|
200
|
-
catch (error) {
|
|
201
|
-
if (errorCode(error) === "ENOENT") {
|
|
202
|
-
throw new HubCommandError("HUB_PARTIAL_MISSING", `Referenced Hub partial ${displayPath} does not exist.`);
|
|
203
|
-
}
|
|
204
|
-
throw new HubCommandError("HUB_PARTIAL_UNREADABLE", `Could not read referenced Hub partial ${displayPath}. Check the file and permissions.`);
|
|
205
|
-
}
|
|
206
|
-
if (stats.isSymbolicLink()) {
|
|
207
|
-
throw new HubCommandError("HUB_PARTIAL_UNSAFE_PATH", `Referenced Hub partial ${displayPath} must not be a symlink.`);
|
|
208
|
-
}
|
|
209
|
-
if (!stats.isFile()) {
|
|
210
|
-
throw new HubCommandError("HUB_PARTIAL_NOT_FILE", `Referenced Hub partial ${displayPath} must be a regular file.`);
|
|
211
|
-
}
|
|
212
|
-
if (!hasReadPermission(stats.mode)) {
|
|
213
|
-
throw new HubCommandError("HUB_PARTIAL_UNREADABLE", `Could not read referenced Hub partial ${displayPath}. Check the file and permissions.`);
|
|
214
|
-
}
|
|
215
|
-
try {
|
|
216
|
-
return (await readFile(partialPath)).toString("utf8");
|
|
217
|
-
}
|
|
218
|
-
catch {
|
|
219
|
-
throw new HubCommandError("HUB_PARTIAL_UNREADABLE", `Could not read referenced Hub partial ${displayPath}. Check the file and permissions.`);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
async function rejectSymlinkComponents(root, target, error) {
|
|
223
|
-
const relative = path.relative(root, target);
|
|
224
|
-
let current = root;
|
|
225
|
-
for (const segment of relative.split(path.sep).filter(Boolean)) {
|
|
226
|
-
current = path.join(current, segment);
|
|
227
|
-
try {
|
|
228
|
-
if ((await lstat(current)).isSymbolicLink())
|
|
229
|
-
throw error();
|
|
230
|
-
}
|
|
231
|
-
catch (failure) {
|
|
232
|
-
if (failure instanceof HubCommandError)
|
|
233
|
-
throw failure;
|
|
234
|
-
if (errorCode(failure) === "ENOENT")
|
|
235
|
-
return;
|
|
236
|
-
throw error();
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
function configurationReadError(displayPath, error) {
|
|
241
|
-
if (errorCode(error) === "ENOENT") {
|
|
242
|
-
return new HubCommandError("HUB_CONFIGURATION_UNREADABLE", `Could not read Hub configuration at ${displayPath}. Pass an existing YAML file.`);
|
|
243
|
-
}
|
|
244
|
-
return new HubCommandError("HUB_CONFIGURATION_UNREADABLE", `Could not read Hub configuration at ${displayPath}. Check the file and permissions.`);
|
|
245
|
-
}
|
|
246
|
-
function invalidConfigurationPath() {
|
|
247
|
-
return new HubCommandError("HUB_CONFIGURATION_PATH_INVALID", "Hub configuration path must stay within the current project root; parent-directory paths are not allowed.");
|
|
248
|
-
}
|
|
249
|
-
function invalidPromptPartialPath(value) {
|
|
250
|
-
return new HubCommandError("HUB_PARTIAL_PATH_INVALID", `Hub partial path must be a safe relative path under .paseo/partials/: ${value}`);
|
|
251
|
-
}
|
|
252
|
-
function hasReadPermission(mode) {
|
|
253
|
-
return (mode & 0o444) !== 0;
|
|
254
|
-
}
|
|
255
|
-
function errorCode(error) {
|
|
256
|
-
if (typeof error !== "object" || error === null)
|
|
257
|
-
return undefined;
|
|
258
|
-
const code = Reflect.get(error, "code");
|
|
259
|
-
return typeof code === "string" ? code : undefined;
|
|
260
|
-
}
|
|
261
|
-
function isRecord(value) {
|
|
262
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
263
|
-
}
|
|
264
|
-
//# sourceMappingURL=deploy-input.js.map
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import { withOutput } from "../../output/index.js";
|
|
3
|
-
import { addJsonAndDaemonHostOptions, addDaemonHostOption } from "../../utils/command-options.js";
|
|
4
|
-
import { addLoopRunOptions, runLoopRunCommand } from "./run.js";
|
|
5
|
-
import { addLoopLsOptions, runLoopLsCommand } from "./ls.js";
|
|
6
|
-
import { addLoopInspectOptions, runLoopInspectCommand } from "./inspect.js";
|
|
7
|
-
import { addLoopLogsOptions, runLoopLogsCommand } from "./logs.js";
|
|
8
|
-
import { addLoopStopOptions, runLoopStopCommand } from "./stop.js";
|
|
9
|
-
export function createLoopCommand() {
|
|
10
|
-
const loop = new Command("loop").description("Run iterative worker loops");
|
|
11
|
-
addJsonAndDaemonHostOptions(addLoopRunOptions(loop.command("run"))).action(withOutput(runLoopRunCommand));
|
|
12
|
-
addJsonAndDaemonHostOptions(addLoopLsOptions(loop.command("ls"))).action(withOutput(runLoopLsCommand));
|
|
13
|
-
addJsonAndDaemonHostOptions(addLoopInspectOptions(loop.command("inspect"))).action(withOutput(runLoopInspectCommand));
|
|
14
|
-
addDaemonHostOption(addLoopLogsOptions(loop.command("logs"))).action(runLoopLogsCommand);
|
|
15
|
-
addJsonAndDaemonHostOptions(addLoopStopOptions(loop.command("stop"))).action(withOutput(runLoopStopCommand));
|
|
16
|
-
return loop;
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import type { CommandOptions, ListResult } from "../../output/index.js";
|
|
3
|
-
interface InspectRow {
|
|
4
|
-
key: string;
|
|
5
|
-
value: string;
|
|
6
|
-
}
|
|
7
|
-
export interface LoopInspectOptions extends CommandOptions {
|
|
8
|
-
}
|
|
9
|
-
export declare function addLoopInspectOptions(command: Command): Command;
|
|
10
|
-
export type LoopInspectResult = ListResult<InspectRow>;
|
|
11
|
-
export declare function runLoopInspectCommand(id: string, options: LoopInspectOptions, _command: Command): Promise<LoopInspectResult>;
|
|
12
|
-
export {};
|
|
13
|
-
//# sourceMappingURL=inspect.d.ts.map
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { connectToDaemon, getDaemonHost } from "../../utils/client.js";
|
|
2
|
-
export function addLoopInspectOptions(command) {
|
|
3
|
-
return command.description("Show loop details and iteration history").argument("<id>", "Loop ID");
|
|
4
|
-
}
|
|
5
|
-
function createInspectSchema(loop) {
|
|
6
|
-
return {
|
|
7
|
-
idField: "key",
|
|
8
|
-
columns: [
|
|
9
|
-
{ header: "KEY", field: "key", width: 18 },
|
|
10
|
-
{ header: "VALUE", field: "value", width: 80 },
|
|
11
|
-
],
|
|
12
|
-
serialize: () => loop,
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
function toRows(loop) {
|
|
16
|
-
return [
|
|
17
|
-
{ key: "Id", value: loop.id },
|
|
18
|
-
{ key: "Name", value: loop.name ?? "null" },
|
|
19
|
-
{ key: "Status", value: loop.status },
|
|
20
|
-
{ key: "Cwd", value: loop.cwd },
|
|
21
|
-
{ key: "Provider", value: loop.provider },
|
|
22
|
-
{ key: "Model", value: loop.model ?? "null" },
|
|
23
|
-
{ key: "WorkerProvider", value: loop.workerProvider ?? "null" },
|
|
24
|
-
{ key: "WorkerModel", value: loop.workerModel ?? "null" },
|
|
25
|
-
{ key: "VerifierProvider", value: loop.verifierProvider ?? "null" },
|
|
26
|
-
{ key: "VerifierModel", value: loop.verifierModel ?? "null" },
|
|
27
|
-
{ key: "Prompt", value: loop.prompt },
|
|
28
|
-
{ key: "VerifyPrompt", value: loop.verifyPrompt ?? "null" },
|
|
29
|
-
{
|
|
30
|
-
key: "VerifyChecks",
|
|
31
|
-
value: loop.verifyChecks.length > 0 ? loop.verifyChecks.join(" | ") : "[]",
|
|
32
|
-
},
|
|
33
|
-
{ key: "Archive", value: String(loop.archive) },
|
|
34
|
-
{ key: "SleepMs", value: String(loop.sleepMs) },
|
|
35
|
-
{
|
|
36
|
-
key: "MaxIterations",
|
|
37
|
-
value: loop.maxIterations === null ? "null" : String(loop.maxIterations),
|
|
38
|
-
},
|
|
39
|
-
{ key: "MaxTimeMs", value: loop.maxTimeMs === null ? "null" : String(loop.maxTimeMs) },
|
|
40
|
-
{ key: "CreatedAt", value: loop.createdAt },
|
|
41
|
-
{ key: "UpdatedAt", value: loop.updatedAt },
|
|
42
|
-
{ key: "CompletedAt", value: loop.completedAt ?? "null" },
|
|
43
|
-
{
|
|
44
|
-
key: "Iterations",
|
|
45
|
-
value: loop.iterations.length === 0
|
|
46
|
-
? "[]"
|
|
47
|
-
: loop.iterations
|
|
48
|
-
.map((iteration) => {
|
|
49
|
-
const summary = [
|
|
50
|
-
`#${iteration.index}`,
|
|
51
|
-
iteration.status,
|
|
52
|
-
iteration.workerAgentId ? `worker=${iteration.workerAgentId}` : null,
|
|
53
|
-
iteration.verifierAgentId ? `verifier=${iteration.verifierAgentId}` : null,
|
|
54
|
-
iteration.failureReason ? `reason=${iteration.failureReason}` : null,
|
|
55
|
-
]
|
|
56
|
-
.filter(Boolean)
|
|
57
|
-
.join(" ");
|
|
58
|
-
return summary;
|
|
59
|
-
})
|
|
60
|
-
.join(" | "),
|
|
61
|
-
},
|
|
62
|
-
];
|
|
63
|
-
}
|
|
64
|
-
export async function runLoopInspectCommand(id, options, _command) {
|
|
65
|
-
const host = getDaemonHost({ host: options.host });
|
|
66
|
-
let client;
|
|
67
|
-
try {
|
|
68
|
-
client = (await connectToDaemon({
|
|
69
|
-
host: options.host,
|
|
70
|
-
}));
|
|
71
|
-
}
|
|
72
|
-
catch (error) {
|
|
73
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
74
|
-
throw {
|
|
75
|
-
code: "DAEMON_NOT_RUNNING",
|
|
76
|
-
message: `Cannot connect to daemon at ${host}: ${message}`,
|
|
77
|
-
details: "Start the daemon with: paseo daemon start",
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
try {
|
|
81
|
-
const payload = await client.loopInspect(id);
|
|
82
|
-
await client.close();
|
|
83
|
-
if (payload.error || !payload.loop) {
|
|
84
|
-
throw new Error(payload.error ?? `Loop not found: ${id}`);
|
|
85
|
-
}
|
|
86
|
-
return {
|
|
87
|
-
type: "list",
|
|
88
|
-
data: toRows(payload.loop),
|
|
89
|
-
schema: createInspectSchema(payload.loop),
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
catch (error) {
|
|
93
|
-
await client.close().catch(() => { });
|
|
94
|
-
throw {
|
|
95
|
-
code: "LOOP_INSPECT_FAILED",
|
|
96
|
-
message: error instanceof Error ? error.message : String(error),
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
//# sourceMappingURL=inspect.js.map
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import type { CommandOptions } from "../../output/index.js";
|
|
3
|
-
export interface LoopLogsOptions extends CommandOptions {
|
|
4
|
-
pollInterval?: string;
|
|
5
|
-
}
|
|
6
|
-
export declare function addLoopLogsOptions(command: Command): Command;
|
|
7
|
-
export declare function runLoopLogsCommand(id: string, options: LoopLogsOptions, _command: Command): Promise<void>;
|
|
8
|
-
//# sourceMappingURL=logs.d.ts.map
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { connectToDaemon, getDaemonHost } from "../../utils/client.js";
|
|
2
|
-
export function addLoopLogsOptions(command) {
|
|
3
|
-
return command
|
|
4
|
-
.description("Stream loop logs")
|
|
5
|
-
.argument("<id>", "Loop ID")
|
|
6
|
-
.option("--poll-interval <ms>", "Polling interval in milliseconds", "1000");
|
|
7
|
-
}
|
|
8
|
-
function parsePollInterval(value) {
|
|
9
|
-
const parsed = Number.parseInt(value, 10);
|
|
10
|
-
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
11
|
-
throw {
|
|
12
|
-
code: "INVALID_POLL_INTERVAL",
|
|
13
|
-
message: "--poll-interval must be a positive integer",
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
return parsed;
|
|
17
|
-
}
|
|
18
|
-
function renderLogEntry(entry) {
|
|
19
|
-
const prefix = [
|
|
20
|
-
entry.timestamp,
|
|
21
|
-
entry.source,
|
|
22
|
-
entry.iteration === null ? null : `iteration=${entry.iteration}`,
|
|
23
|
-
entry.level === "error" ? "ERROR" : null,
|
|
24
|
-
]
|
|
25
|
-
.filter(Boolean)
|
|
26
|
-
.join(" ");
|
|
27
|
-
return `${prefix}\n${entry.text}`;
|
|
28
|
-
}
|
|
29
|
-
export async function runLoopLogsCommand(id, options, _command) {
|
|
30
|
-
const host = getDaemonHost({ host: options.host });
|
|
31
|
-
const pollInterval = parsePollInterval(options.pollInterval ?? "1000");
|
|
32
|
-
let client;
|
|
33
|
-
try {
|
|
34
|
-
client = (await connectToDaemon({
|
|
35
|
-
host: options.host,
|
|
36
|
-
}));
|
|
37
|
-
}
|
|
38
|
-
catch (error) {
|
|
39
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
40
|
-
console.error(`Error: Cannot connect to daemon at ${host}: ${message}`);
|
|
41
|
-
console.error("Start the daemon with: paseo daemon start");
|
|
42
|
-
process.exit(1);
|
|
43
|
-
}
|
|
44
|
-
async function streamLogs(cursor) {
|
|
45
|
-
const payload = await client.loopLogs(id, cursor);
|
|
46
|
-
if (payload.error || !payload.loop) {
|
|
47
|
-
throw new Error(payload.error ?? `Loop not found: ${id}`);
|
|
48
|
-
}
|
|
49
|
-
for (const entry of payload.entries) {
|
|
50
|
-
console.log(renderLogEntry(entry));
|
|
51
|
-
}
|
|
52
|
-
if (payload.loop.status !== "running") {
|
|
53
|
-
await client.close();
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
57
|
-
return streamLogs(payload.nextCursor);
|
|
58
|
-
}
|
|
59
|
-
try {
|
|
60
|
-
await streamLogs(0);
|
|
61
|
-
}
|
|
62
|
-
catch (error) {
|
|
63
|
-
await client.close().catch(() => { });
|
|
64
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
65
|
-
console.error(`Error: Failed to stream loop logs: ${message}`);
|
|
66
|
-
process.exit(1);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
//# sourceMappingURL=logs.js.map
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import type { CommandOptions, OutputSchema, ListResult } from "../../output/index.js";
|
|
3
|
-
interface LoopListRow {
|
|
4
|
-
id: string;
|
|
5
|
-
name: string | null;
|
|
6
|
-
status: string;
|
|
7
|
-
cwd: string;
|
|
8
|
-
updated: string;
|
|
9
|
-
activeIteration: string;
|
|
10
|
-
}
|
|
11
|
-
export interface LoopLsOptions extends CommandOptions {
|
|
12
|
-
}
|
|
13
|
-
export declare const loopLsSchema: OutputSchema<LoopListRow>;
|
|
14
|
-
export declare function addLoopLsOptions(command: Command): Command;
|
|
15
|
-
export type LoopLsResult = ListResult<LoopListRow>;
|
|
16
|
-
export declare function runLoopLsCommand(options: LoopLsOptions, _command: Command): Promise<LoopLsResult>;
|
|
17
|
-
export {};
|
|
18
|
-
//# sourceMappingURL=ls.d.ts.map
|
package/dist/commands/loop/ls.js
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { connectToDaemon, getDaemonHost } from "../../utils/client.js";
|
|
2
|
-
export const loopLsSchema = {
|
|
3
|
-
idField: "id",
|
|
4
|
-
columns: [
|
|
5
|
-
{ header: "LOOP ID", field: "id", width: 10 },
|
|
6
|
-
{ header: "NAME", field: "name", width: 20 },
|
|
7
|
-
{ header: "STATUS", field: "status", width: 10 },
|
|
8
|
-
{ header: "ITER", field: "activeIteration", width: 8 },
|
|
9
|
-
{ header: "CWD", field: "cwd", width: 40 },
|
|
10
|
-
{ header: "UPDATED", field: "updated", width: 24 },
|
|
11
|
-
],
|
|
12
|
-
};
|
|
13
|
-
export function addLoopLsOptions(command) {
|
|
14
|
-
return command.description("List loops");
|
|
15
|
-
}
|
|
16
|
-
function toRow(loop) {
|
|
17
|
-
return {
|
|
18
|
-
id: loop.id,
|
|
19
|
-
name: loop.name,
|
|
20
|
-
status: loop.status,
|
|
21
|
-
cwd: loop.cwd,
|
|
22
|
-
updated: loop.updatedAt,
|
|
23
|
-
activeIteration: loop.activeIteration === null ? "-" : String(loop.activeIteration),
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
export async function runLoopLsCommand(options, _command) {
|
|
27
|
-
const host = getDaemonHost({ host: options.host });
|
|
28
|
-
let client;
|
|
29
|
-
try {
|
|
30
|
-
client = (await connectToDaemon({
|
|
31
|
-
host: options.host,
|
|
32
|
-
}));
|
|
33
|
-
}
|
|
34
|
-
catch (error) {
|
|
35
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
36
|
-
throw {
|
|
37
|
-
code: "DAEMON_NOT_RUNNING",
|
|
38
|
-
message: `Cannot connect to daemon at ${host}: ${message}`,
|
|
39
|
-
details: "Start the daemon with: paseo daemon start",
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
try {
|
|
43
|
-
const payload = await client.loopList();
|
|
44
|
-
await client.close();
|
|
45
|
-
if (payload.error) {
|
|
46
|
-
throw new Error(payload.error);
|
|
47
|
-
}
|
|
48
|
-
return {
|
|
49
|
-
type: "list",
|
|
50
|
-
data: payload.loops.map(toRow),
|
|
51
|
-
schema: loopLsSchema,
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
catch (error) {
|
|
55
|
-
await client.close().catch(() => { });
|
|
56
|
-
throw {
|
|
57
|
-
code: "LOOP_LIST_FAILED",
|
|
58
|
-
message: error instanceof Error ? error.message : String(error),
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
//# sourceMappingURL=ls.js.map
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import type { CommandOptions, OutputSchema, SingleResult } from "../../output/index.js";
|
|
3
|
-
import type { LoopRunInput } from "./types.js";
|
|
4
|
-
export interface LoopRunRow {
|
|
5
|
-
id: string;
|
|
6
|
-
status: string;
|
|
7
|
-
name: string | null;
|
|
8
|
-
cwd: string;
|
|
9
|
-
}
|
|
10
|
-
export interface LoopRunOptions extends CommandOptions {
|
|
11
|
-
provider?: string;
|
|
12
|
-
model?: string;
|
|
13
|
-
mode?: string;
|
|
14
|
-
verifyProvider?: string;
|
|
15
|
-
verifyModel?: string;
|
|
16
|
-
verifyMode?: string;
|
|
17
|
-
verify?: string;
|
|
18
|
-
verifyCheck?: string[];
|
|
19
|
-
archive?: boolean;
|
|
20
|
-
name?: string;
|
|
21
|
-
sleep?: string;
|
|
22
|
-
maxIterations?: string;
|
|
23
|
-
maxTime?: string;
|
|
24
|
-
}
|
|
25
|
-
export declare const loopRunSchema: OutputSchema<LoopRunRow>;
|
|
26
|
-
export declare function addLoopRunOptions(command: Command): Command;
|
|
27
|
-
export declare function buildLoopRunInput(prompt: string, options: LoopRunOptions): LoopRunInput;
|
|
28
|
-
export type LoopRunResult = SingleResult<LoopRunRow>;
|
|
29
|
-
export declare function runLoopRunCommand(prompt: string, options: LoopRunOptions, _command: Command): Promise<LoopRunResult>;
|
|
30
|
-
//# sourceMappingURL=run.d.ts.map
|