libretto 0.6.31 → 0.6.32
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/commands/cloud-credentials.js +5 -17
- package/dist/cli/commands/cloud-jobs.js +118 -0
- package/dist/cli/commands/cloud-schedules.js +128 -0
- package/dist/cli/commands/cloud-settings.js +75 -0
- package/dist/cli/commands/cloud-sharing.js +13 -27
- package/dist/cli/commands/deploy.js +7 -16
- package/dist/cli/commands/profiles.js +8 -21
- package/dist/cli/commands/shared.js +17 -0
- package/dist/cli/core/daemon/ipc.js +23 -16
- package/dist/cli/router.js +6 -0
- package/package.json +1 -1
- package/skills/libretto/SKILL.md +1 -1
- package/skills/libretto-readonly/SKILL.md +1 -1
- package/src/cli/commands/cloud-credentials.ts +6 -18
- package/src/cli/commands/cloud-jobs.ts +149 -0
- package/src/cli/commands/cloud-schedules.ts +164 -0
- package/src/cli/commands/cloud-settings.ts +101 -0
- package/src/cli/commands/cloud-sharing.ts +20 -28
- package/src/cli/commands/deploy.ts +8 -19
- package/src/cli/commands/profiles.ts +10 -22
- package/src/cli/commands/shared.ts +29 -0
- package/src/cli/core/daemon/ipc.ts +27 -18
- package/src/cli/router.ts +6 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { SimpleCLI } from "affordance";
|
|
3
|
-
import { orpcCall
|
|
3
|
+
import { orpcCall } from "../core/auth-fetch.js";
|
|
4
4
|
import { normalizeProfileName } from "../core/profiles.js";
|
|
5
|
+
import { withCloudApiKey } from "./shared.js";
|
|
5
6
|
|
|
6
7
|
type ListProfilesResponse = {
|
|
7
8
|
profiles: Array<{
|
|
@@ -17,30 +18,17 @@ type DeleteProfileResponse = {
|
|
|
17
18
|
deleted_count: number;
|
|
18
19
|
};
|
|
19
20
|
|
|
20
|
-
function requireApiKeyCredential() {
|
|
21
|
-
const apiKey = process.env.LIBRETTO_API_KEY?.trim();
|
|
22
|
-
if (!apiKey) {
|
|
23
|
-
throw new Error(
|
|
24
|
-
"LIBRETTO_API_KEY is required to manage Libretto Cloud profiles. Issue one with `libretto cloud auth api-key issue --label <label>`.",
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
return {
|
|
28
|
-
apiUrl: resolveApiUrl(null),
|
|
29
|
-
credential: { source: "env-api-key" as const, apiKey },
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
|
|
33
21
|
export const listProfilesCommand = SimpleCLI.command({
|
|
34
22
|
description: "List Libretto Cloud auth profiles",
|
|
35
23
|
})
|
|
36
24
|
.input(SimpleCLI.input({ positionals: [], named: {} }))
|
|
37
|
-
.
|
|
38
|
-
|
|
25
|
+
.use(withCloudApiKey("manage Libretto Cloud profiles"))
|
|
26
|
+
.handle(async ({ ctx }) => {
|
|
39
27
|
const response = await orpcCall<ListProfilesResponse>({
|
|
40
|
-
apiUrl,
|
|
28
|
+
apiUrl: ctx.apiUrl,
|
|
41
29
|
path: "/v1/browserProfiles/list",
|
|
42
30
|
input: {},
|
|
43
|
-
credential,
|
|
31
|
+
credential: ctx.credential,
|
|
44
32
|
});
|
|
45
33
|
if (response.profiles.length === 0) {
|
|
46
34
|
console.log("No cloud profiles found.");
|
|
@@ -65,14 +53,14 @@ export const deleteProfileCommand = SimpleCLI.command({
|
|
|
65
53
|
],
|
|
66
54
|
named: {},
|
|
67
55
|
}))
|
|
68
|
-
.
|
|
56
|
+
.use(withCloudApiKey("manage Libretto Cloud profiles"))
|
|
57
|
+
.handle(async ({ input, ctx }) => {
|
|
69
58
|
const profileName = normalizeProfileName(input.profileName);
|
|
70
|
-
const { apiUrl, credential } = requireApiKeyCredential();
|
|
71
59
|
const response = await orpcCall<DeleteProfileResponse>({
|
|
72
|
-
apiUrl,
|
|
60
|
+
apiUrl: ctx.apiUrl,
|
|
73
61
|
path: "/v1/browserProfiles/delete",
|
|
74
62
|
input: { name: profileName },
|
|
75
|
-
credential,
|
|
63
|
+
credential: ctx.credential,
|
|
76
64
|
});
|
|
77
65
|
if (!response.success || response.deleted_count === 0) {
|
|
78
66
|
console.log(`No cloud profile found for ${profileName}.`);
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
type SessionState,
|
|
10
10
|
validateSessionName,
|
|
11
11
|
} from "../core/session.js";
|
|
12
|
+
import { resolveApiUrl } from "../core/auth-fetch.js";
|
|
12
13
|
import {
|
|
13
14
|
SimpleCLI,
|
|
14
15
|
type SimpleCLIContext,
|
|
@@ -40,6 +41,11 @@ export type ExperimentsContext = {
|
|
|
40
41
|
experiments: Experiments;
|
|
41
42
|
};
|
|
42
43
|
|
|
44
|
+
export type CloudApiKeyContext = {
|
|
45
|
+
apiUrl: string;
|
|
46
|
+
credential: { source: "env-api-key"; apiKey: string };
|
|
47
|
+
};
|
|
48
|
+
|
|
43
49
|
export function withExperiments<
|
|
44
50
|
TContext extends SimpleCLIContext,
|
|
45
51
|
>(): SimpleCLIMiddleware<unknown, TContext, TContext & ExperimentsContext> {
|
|
@@ -49,6 +55,29 @@ export function withExperiments<
|
|
|
49
55
|
});
|
|
50
56
|
}
|
|
51
57
|
|
|
58
|
+
export function withCloudApiKey<
|
|
59
|
+
TContext extends SimpleCLIContext,
|
|
60
|
+
>(
|
|
61
|
+
action: string,
|
|
62
|
+
formatMissingMessage?: () => string | Promise<string>,
|
|
63
|
+
): SimpleCLIMiddleware<unknown, TContext, TContext & CloudApiKeyContext> {
|
|
64
|
+
return async ({ ctx }) => {
|
|
65
|
+
const apiKey = process.env.LIBRETTO_API_KEY?.trim();
|
|
66
|
+
if (!apiKey) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
formatMissingMessage
|
|
69
|
+
? await formatMissingMessage()
|
|
70
|
+
: `LIBRETTO_API_KEY is required to ${action}. Issue one with \`libretto cloud auth api-key issue --label <label>\`.`,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
...ctx,
|
|
75
|
+
apiUrl: resolveApiUrl(null),
|
|
76
|
+
credential: { source: "env-api-key", apiKey },
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
52
81
|
export function withRequiredSession(): SimpleCLIMiddleware<
|
|
53
82
|
{ session?: string },
|
|
54
83
|
{},
|
|
@@ -2,7 +2,7 @@ import { createHash } from "node:crypto";
|
|
|
2
2
|
import type { ChildProcess } from "node:child_process";
|
|
3
3
|
import { spawn } from "node:child_process";
|
|
4
4
|
import { openSync, closeSync } from "node:fs";
|
|
5
|
-
import
|
|
5
|
+
import * as moduleBuiltin from "node:module";
|
|
6
6
|
import { homedir, userInfo } from "node:os";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
import { createIpcPeer, type IpcPeer } from "../../../shared/ipc/ipc.js";
|
|
@@ -246,25 +246,34 @@ export class DaemonClient {
|
|
|
246
246
|
const daemonEntryPath = fileURLToPath(
|
|
247
247
|
new URL("./daemon.js", import.meta.url),
|
|
248
248
|
);
|
|
249
|
-
const
|
|
250
|
-
const
|
|
249
|
+
const childArgs = [daemonEntryPath, JSON.stringify(config)];
|
|
250
|
+
const childEnv: NodeJS.ProcessEnv = { ...process.env };
|
|
251
|
+
|
|
252
|
+
if (config.workflow) {
|
|
253
|
+
const tsxPreflightPath = fileURLToPath(
|
|
254
|
+
import.meta.resolve("tsx/preflight"),
|
|
255
|
+
);
|
|
256
|
+
const tsxLoaderFlag =
|
|
257
|
+
typeof moduleBuiltin.register === "function" ? "--import" : "--loader";
|
|
258
|
+
|
|
259
|
+
childArgs.unshift(
|
|
260
|
+
"--require",
|
|
261
|
+
tsxPreflightPath,
|
|
262
|
+
tsxLoaderFlag,
|
|
263
|
+
import.meta.resolve("tsx"),
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
if (config.workflow.tsconfigPath) {
|
|
267
|
+
childEnv.TSX_TSCONFIG_PATH = config.workflow.tsconfigPath;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
251
270
|
|
|
252
271
|
const childStderrFd = openSync(logPath, "a");
|
|
253
|
-
const child = spawn(
|
|
254
|
-
|
|
255
|
-
[
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
? ["--tsconfig", config.workflow.tsconfigPath]
|
|
259
|
-
: []),
|
|
260
|
-
daemonEntryPath,
|
|
261
|
-
JSON.stringify(config),
|
|
262
|
-
],
|
|
263
|
-
{
|
|
264
|
-
detached: true,
|
|
265
|
-
stdio: ["ignore", "ignore", childStderrFd, "ipc"],
|
|
266
|
-
},
|
|
267
|
-
);
|
|
272
|
+
const child = spawn(process.execPath, childArgs, {
|
|
273
|
+
detached: true,
|
|
274
|
+
stdio: ["ignore", "ignore", childStderrFd, "ipc"],
|
|
275
|
+
env: childEnv,
|
|
276
|
+
});
|
|
268
277
|
closeSync(childStderrFd);
|
|
269
278
|
|
|
270
279
|
const pid = child.pid!;
|
package/src/cli/router.ts
CHANGED
|
@@ -2,6 +2,9 @@ import { authCommands } from "./commands/auth.js";
|
|
|
2
2
|
import { billingCommands } from "./commands/billing.js";
|
|
3
3
|
import { browserCommands } from "./commands/browser.js";
|
|
4
4
|
import { cloudCredentialCommands } from "./commands/cloud-credentials.js";
|
|
5
|
+
import { cloudJobCommands } from "./commands/cloud-jobs.js";
|
|
6
|
+
import { cloudScheduleCommands } from "./commands/cloud-schedules.js";
|
|
7
|
+
import { settingsCommands } from "./commands/cloud-settings.js";
|
|
5
8
|
import { codeSharingCommands, shareWorkflowCommand } from "./commands/cloud-sharing.js";
|
|
6
9
|
import { deployCommand } from "./commands/deploy.js";
|
|
7
10
|
import { executionCommands } from "./commands/execution.js";
|
|
@@ -25,7 +28,10 @@ export const cliRoutes = {
|
|
|
25
28
|
auth: authCommands,
|
|
26
29
|
billing: billingCommands,
|
|
27
30
|
credentials: cloudCredentialCommands,
|
|
31
|
+
jobs: cloudJobCommands,
|
|
28
32
|
profiles: profileCommands,
|
|
33
|
+
schedules: cloudScheduleCommands,
|
|
34
|
+
settings: settingsCommands,
|
|
29
35
|
share: shareWorkflowCommand,
|
|
30
36
|
sharing: codeSharingCommands,
|
|
31
37
|
},
|