libretto 0.5.5 → 0.6.0
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/README.md +23 -10
- package/README.template.md +23 -10
- package/dist/cli/cli.js +10 -0
- package/dist/cli/commands/ai.js +77 -2
- package/dist/cli/commands/browser.js +98 -8
- package/dist/cli/commands/execution.js +152 -56
- package/dist/cli/commands/setup.js +390 -0
- package/dist/cli/commands/snapshot.js +2 -2
- package/dist/cli/commands/status.js +62 -0
- package/dist/cli/core/{snapshot-api-config.js → ai-model.js} +81 -7
- package/dist/cli/core/api-snapshot-analyzer.js +7 -5
- package/dist/cli/core/browser.js +202 -36
- package/dist/cli/core/{ai-config.js → config.js} +14 -79
- package/dist/cli/core/context.js +1 -25
- package/dist/cli/core/deploy-artifact.js +121 -61
- package/dist/cli/core/providers/browserbase.js +53 -0
- package/dist/cli/core/providers/index.js +48 -0
- package/dist/cli/core/providers/kernel.js +46 -0
- package/dist/cli/core/providers/libretto-cloud.js +58 -0
- package/dist/cli/core/readonly-exec.js +231 -0
- package/dist/{shared/llm/client.js → cli/core/resolve-model.js} +4 -68
- package/dist/cli/core/session.js +53 -0
- package/dist/cli/core/skill-version.js +73 -0
- package/dist/cli/core/telemetry.js +1 -54
- package/dist/cli/index.js +1 -7
- package/dist/cli/router.js +4 -4
- package/dist/cli/workers/run-integration-runtime.js +19 -13
- package/dist/cli/workers/run-integration-worker-protocol.js +5 -2
- package/dist/index.d.ts +2 -4
- package/dist/index.js +2 -2
- package/dist/runtime/extract/extract.d.ts +2 -2
- package/dist/runtime/extract/extract.js +4 -2
- package/dist/runtime/extract/index.d.ts +1 -1
- package/dist/runtime/recovery/agent.d.ts +2 -3
- package/dist/runtime/recovery/agent.js +5 -3
- package/dist/runtime/recovery/errors.d.ts +2 -3
- package/dist/runtime/recovery/errors.js +4 -2
- package/dist/runtime/recovery/index.d.ts +1 -2
- package/dist/runtime/recovery/recovery.d.ts +2 -3
- package/dist/runtime/recovery/recovery.js +3 -3
- package/dist/shared/debug/pause.js +4 -21
- package/dist/shared/run/api.d.ts +2 -0
- package/dist/shared/run/browser.d.ts +9 -1
- package/dist/shared/run/browser.js +43 -3
- package/dist/shared/state/index.d.ts +1 -1
- package/dist/shared/state/index.js +2 -0
- package/dist/shared/state/session-state.d.ts +20 -1
- package/dist/shared/state/session-state.js +12 -2
- package/dist/shared/workflow/workflow.d.ts +2 -1
- package/dist/shared/workflow/workflow.js +16 -9
- package/package.json +17 -16
- package/scripts/postinstall.mjs +13 -11
- package/scripts/skills-libretto.mjs +14 -4
- package/skills/AGENTS.md +11 -0
- package/skills/libretto/SKILL.md +30 -9
- package/skills/libretto/references/auth-profiles.md +1 -1
- package/skills/libretto/references/code-generation-rules.md +3 -3
- package/skills/libretto/references/configuration-file-reference.md +11 -6
- package/skills/libretto-readonly/SKILL.md +95 -0
- package/src/cli/cli.ts +10 -0
- package/src/cli/commands/ai.ts +111 -1
- package/src/cli/commands/browser.ts +111 -9
- package/src/cli/commands/execution.ts +181 -74
- package/src/cli/commands/setup.ts +516 -0
- package/src/cli/commands/snapshot.ts +2 -2
- package/src/cli/commands/status.ts +79 -0
- package/src/cli/core/{snapshot-api-config.ts → ai-model.ts} +154 -14
- package/src/cli/core/api-snapshot-analyzer.ts +7 -5
- package/src/cli/core/browser.ts +242 -35
- package/src/cli/core/{ai-config.ts → config.ts} +14 -108
- package/src/cli/core/context.ts +1 -45
- package/src/cli/core/deploy-artifact.ts +141 -71
- package/src/cli/core/providers/browserbase.ts +57 -0
- package/src/cli/core/providers/index.ts +62 -0
- package/src/cli/core/providers/kernel.ts +49 -0
- package/src/cli/core/providers/libretto-cloud.ts +61 -0
- package/src/cli/core/providers/types.ts +9 -0
- package/src/cli/core/readonly-exec.ts +284 -0
- package/src/{shared/llm/client.ts → cli/core/resolve-model.ts} +3 -85
- package/src/cli/core/session.ts +75 -2
- package/src/cli/core/skill-version.ts +93 -0
- package/src/cli/core/telemetry.ts +0 -52
- package/src/cli/index.ts +0 -6
- package/src/cli/router.ts +4 -4
- package/src/cli/workers/run-integration-runtime.ts +18 -16
- package/src/cli/workers/run-integration-worker-protocol.ts +4 -1
- package/src/index.ts +1 -7
- package/src/runtime/extract/extract.ts +6 -5
- package/src/runtime/recovery/agent.ts +5 -4
- package/src/runtime/recovery/errors.ts +4 -3
- package/src/runtime/recovery/recovery.ts +4 -4
- package/src/shared/debug/pause.ts +4 -23
- package/src/shared/run/browser.ts +50 -1
- package/src/shared/state/index.ts +2 -0
- package/src/shared/state/session-state.ts +10 -0
- package/src/shared/workflow/workflow.ts +24 -13
- package/dist/cli/commands/init.js +0 -286
- package/dist/cli/commands/logs.js +0 -117
- package/dist/shared/llm/ai-sdk-adapter.d.ts +0 -22
- package/dist/shared/llm/ai-sdk-adapter.js +0 -49
- package/dist/shared/llm/client.d.ts +0 -13
- package/dist/shared/llm/index.d.ts +0 -5
- package/dist/shared/llm/index.js +0 -6
- package/dist/shared/llm/types.d.ts +0 -67
- package/src/cli/commands/init.ts +0 -331
- package/src/cli/commands/logs.ts +0 -128
- package/src/shared/llm/ai-sdk-adapter.ts +0 -81
- package/src/shared/llm/index.ts +0 -3
- package/src/shared/llm/types.ts +0 -63
- /package/dist/{shared/llm → cli/core/providers}/types.js +0 -0
|
@@ -14,16 +14,21 @@ import { parseViewportArg } from "./browser.js";
|
|
|
14
14
|
import { getPauseSignalPaths } from "../core/pause-signals.js";
|
|
15
15
|
import {
|
|
16
16
|
assertSessionAvailableForStart,
|
|
17
|
+
assertSessionAllowsCommand,
|
|
17
18
|
clearSessionState,
|
|
18
19
|
readSessionState,
|
|
19
20
|
setSessionStatus,
|
|
20
21
|
type SessionState,
|
|
21
22
|
} from "../core/session.js";
|
|
23
|
+
import { warnIfInstalledSkillOutOfDate } from "../core/skill-version.js";
|
|
22
24
|
import {
|
|
23
25
|
readActionLog,
|
|
24
26
|
readNetworkLog,
|
|
25
27
|
wrapPageForActionLogging,
|
|
26
28
|
} from "../core/telemetry.js";
|
|
29
|
+
import { readLibrettoConfig } from "../core/config.js";
|
|
30
|
+
import { resolveProviderName, getCloudProviderApi } from "../core/providers/index.js";
|
|
31
|
+
import { createReadonlyExecHelpers } from "../core/readonly-exec.js";
|
|
27
32
|
import type { RunIntegrationWorkerRequest } from "../workers/run-integration-worker-protocol.js";
|
|
28
33
|
import { SimpleCLI } from "../framework/simple-cli.js";
|
|
29
34
|
import {
|
|
@@ -37,6 +42,7 @@ type ExecFunction = (...args: unknown[]) => Promise<unknown>;
|
|
|
37
42
|
type RunIntegrationCommandRequest = RunIntegrationWorkerRequest & {
|
|
38
43
|
tsconfigPath?: string;
|
|
39
44
|
};
|
|
45
|
+
type ExecMode = "exec" | "readonly-exec";
|
|
40
46
|
|
|
41
47
|
type StripTypeScriptTypesFn = (
|
|
42
48
|
code: string,
|
|
@@ -202,14 +208,20 @@ async function runExec(
|
|
|
202
208
|
code: string,
|
|
203
209
|
session: string,
|
|
204
210
|
logger: LoggerApi,
|
|
205
|
-
|
|
206
|
-
|
|
211
|
+
options: {
|
|
212
|
+
visualize?: boolean;
|
|
213
|
+
pageId?: string;
|
|
214
|
+
mode?: ExecMode;
|
|
215
|
+
} = {},
|
|
207
216
|
): Promise<void> {
|
|
217
|
+
const visualize = options.visualize ?? false;
|
|
218
|
+
const pageId = options.pageId;
|
|
219
|
+
const mode = options.mode ?? "exec";
|
|
208
220
|
const { cleaned: cleanedCode, strippedCount } = stripEmptyCatchHandlers(code);
|
|
209
221
|
if (strippedCount > 0) {
|
|
210
222
|
console.log("(Stripped `.catch(() => {})` — letting errors bubble up)");
|
|
211
223
|
}
|
|
212
|
-
logger.info(
|
|
224
|
+
logger.info(`${mode}-start`, {
|
|
213
225
|
session,
|
|
214
226
|
codeLength: cleanedCode.length,
|
|
215
227
|
codePreview: cleanedCode.slice(0, 200),
|
|
@@ -235,20 +247,20 @@ async function runExec(
|
|
|
235
247
|
const stallInterval = setInterval(() => {
|
|
236
248
|
const silenceMs = Date.now() - lastActivityTs;
|
|
237
249
|
if (silenceMs >= STALL_THRESHOLD_MS) {
|
|
238
|
-
logger.warn(
|
|
250
|
+
logger.warn(`${mode}-stall-warning`, {
|
|
239
251
|
session,
|
|
240
252
|
silenceMs,
|
|
241
253
|
codePreview: cleanedCode.slice(0, 200),
|
|
242
254
|
});
|
|
243
255
|
console.warn(
|
|
244
|
-
`[stall-warning] No Playwright activity for ${Math.round(silenceMs / 1000)}s —
|
|
256
|
+
`[stall-warning] No Playwright activity for ${Math.round(silenceMs / 1000)}s — ${mode} may be hung (code: ${cleanedCode.slice(0, 100)}...)`,
|
|
245
257
|
);
|
|
246
258
|
}
|
|
247
259
|
}, STALL_THRESHOLD_MS);
|
|
248
260
|
|
|
249
261
|
const execStartTs = Date.now();
|
|
250
262
|
const sigintHandler = () => {
|
|
251
|
-
logger.info(
|
|
263
|
+
logger.info(`${mode}-interrupted`, {
|
|
252
264
|
session,
|
|
253
265
|
duration: Date.now() - execStartTs,
|
|
254
266
|
codePreview: cleanedCode.slice(0, 200),
|
|
@@ -256,60 +268,67 @@ async function runExec(
|
|
|
256
268
|
};
|
|
257
269
|
process.on("SIGINT", sigintHandler);
|
|
258
270
|
|
|
259
|
-
|
|
271
|
+
if (mode === "exec") {
|
|
272
|
+
wrapPageForActionLogging(page, session, resolvedPageId, onActivity);
|
|
273
|
+
}
|
|
260
274
|
|
|
261
|
-
if (visualize) {
|
|
275
|
+
if (visualize && mode === "exec") {
|
|
262
276
|
await installInstrumentation(page, { visualize: true, logger });
|
|
263
277
|
}
|
|
264
278
|
|
|
265
279
|
try {
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
280
|
+
const helpers =
|
|
281
|
+
mode === "readonly-exec"
|
|
282
|
+
? createReadonlyExecHelpers(page, { onActivity })
|
|
283
|
+
: (() => {
|
|
284
|
+
const execState: Record<string, unknown> = {};
|
|
285
|
+
|
|
286
|
+
const networkLog = (
|
|
287
|
+
opts: {
|
|
288
|
+
last?: number;
|
|
289
|
+
filter?: string;
|
|
290
|
+
method?: string;
|
|
291
|
+
pageId?: string;
|
|
292
|
+
} = {},
|
|
293
|
+
) => {
|
|
294
|
+
return readNetworkLog(session, opts);
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
const actionLog = (
|
|
298
|
+
opts: {
|
|
299
|
+
last?: number;
|
|
300
|
+
filter?: string;
|
|
301
|
+
action?: string;
|
|
302
|
+
source?: string;
|
|
303
|
+
pageId?: string;
|
|
304
|
+
} = {},
|
|
305
|
+
) => {
|
|
306
|
+
return readActionLog(session, opts);
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
return {
|
|
310
|
+
page,
|
|
311
|
+
context,
|
|
312
|
+
state: execState,
|
|
313
|
+
browser,
|
|
314
|
+
networkLog,
|
|
315
|
+
actionLog,
|
|
316
|
+
console,
|
|
317
|
+
setTimeout,
|
|
318
|
+
setInterval,
|
|
319
|
+
clearTimeout,
|
|
320
|
+
clearInterval,
|
|
321
|
+
fetch,
|
|
322
|
+
URL,
|
|
323
|
+
Buffer,
|
|
324
|
+
};
|
|
325
|
+
})();
|
|
307
326
|
|
|
308
327
|
const helperNames = Object.keys(helpers);
|
|
309
328
|
const fn = compileExecFunction(cleanedCode, helperNames);
|
|
310
329
|
|
|
311
330
|
const result = await fn(...Object.values(helpers));
|
|
312
|
-
logger.info(
|
|
331
|
+
logger.info(`${mode}-success`, { session, hasResult: result !== undefined });
|
|
313
332
|
if (result !== undefined) {
|
|
314
333
|
console.log(
|
|
315
334
|
typeof result === "string" ? result : JSON.stringify(result, null, 2),
|
|
@@ -318,7 +337,7 @@ async function runExec(
|
|
|
318
337
|
console.log("Executed successfully");
|
|
319
338
|
}
|
|
320
339
|
} catch (err) {
|
|
321
|
-
logger.error(
|
|
340
|
+
logger.error(`${mode}-error`, {
|
|
322
341
|
error: err,
|
|
323
342
|
session,
|
|
324
343
|
codePreview: cleanedCode.slice(0, 200),
|
|
@@ -605,13 +624,15 @@ async function runIntegrationFromFile(
|
|
|
605
624
|
);
|
|
606
625
|
const payload = JSON.stringify({
|
|
607
626
|
integrationPath: args.integrationPath,
|
|
608
|
-
workflowName: args.workflowName,
|
|
609
627
|
session: args.session,
|
|
610
628
|
params: args.params,
|
|
611
629
|
headless: args.headless,
|
|
612
630
|
visualize: args.visualize,
|
|
613
631
|
authProfileDomain: args.authProfileDomain,
|
|
614
632
|
viewport: args.viewport,
|
|
633
|
+
accessMode: args.accessMode,
|
|
634
|
+
cdpEndpoint: args.cdpEndpoint,
|
|
635
|
+
provider: args.provider,
|
|
615
636
|
} satisfies RunIntegrationWorkerRequest);
|
|
616
637
|
const worker = spawn(
|
|
617
638
|
process.execPath,
|
|
@@ -690,6 +711,7 @@ export const execCommand = SimpleCLI.command({
|
|
|
690
711
|
.input(execInput)
|
|
691
712
|
.use(withRequiredSession())
|
|
692
713
|
.handle(async ({ input, ctx }) => {
|
|
714
|
+
assertSessionAllowsCommand(ctx.sessionState, "exec", ["write-access"]);
|
|
693
715
|
const code = input.code!;
|
|
694
716
|
const codeFromArgsOrStdin = code === "-" ? readStdinSync() : code;
|
|
695
717
|
if (codeFromArgsOrStdin === null) {
|
|
@@ -701,21 +723,55 @@ export const execCommand = SimpleCLI.command({
|
|
|
701
723
|
codeFromArgsOrStdin,
|
|
702
724
|
ctx.session,
|
|
703
725
|
ctx.logger,
|
|
704
|
-
|
|
705
|
-
|
|
726
|
+
{
|
|
727
|
+
visualize: input.visualize,
|
|
728
|
+
pageId: input.page,
|
|
729
|
+
mode: "exec",
|
|
730
|
+
},
|
|
706
731
|
);
|
|
707
732
|
});
|
|
708
733
|
|
|
709
|
-
const
|
|
734
|
+
export const readonlyExecInput = SimpleCLI.input({
|
|
735
|
+
positionals: [
|
|
736
|
+
SimpleCLI.positional("code", z.string().optional(), {
|
|
737
|
+
help: "Read-only Playwright TypeScript code to execute",
|
|
738
|
+
}),
|
|
739
|
+
],
|
|
740
|
+
named: {
|
|
741
|
+
session: sessionOption(),
|
|
742
|
+
page: pageOption(),
|
|
743
|
+
},
|
|
744
|
+
}).refine(
|
|
745
|
+
(input) => input.code !== undefined,
|
|
746
|
+
`Usage: libretto readonly-exec <code|-> [--session <name>] [--page <id>]\n echo '<code>' | libretto readonly-exec - [--session <name>] [--page <id>]`,
|
|
747
|
+
);
|
|
748
|
+
|
|
749
|
+
export const readonlyExecCommand = SimpleCLI.command({
|
|
750
|
+
description: "Execute read-only Playwright inspection code",
|
|
751
|
+
})
|
|
752
|
+
.input(readonlyExecInput)
|
|
753
|
+
.use(withRequiredSession())
|
|
754
|
+
.handle(async ({ input, ctx }) => {
|
|
755
|
+
const code = input.code!;
|
|
756
|
+
const codeFromArgsOrStdin = code === "-" ? readStdinSync() : code;
|
|
757
|
+
if (codeFromArgsOrStdin === null) {
|
|
758
|
+
throw new Error(
|
|
759
|
+
"Missing stdin input for `readonly-exec -`. Pipe inspection code into stdin.",
|
|
760
|
+
);
|
|
761
|
+
}
|
|
762
|
+
await runExec(codeFromArgsOrStdin, ctx.session, ctx.logger, {
|
|
763
|
+
pageId: input.page,
|
|
764
|
+
mode: "readonly-exec",
|
|
765
|
+
});
|
|
766
|
+
});
|
|
767
|
+
|
|
768
|
+
const runUsage = `Usage: libretto run <integrationFile> [--params <json> | --params-file <path>] [--tsconfig <path>] [--headed|--headless] [--read-only|--write-access] [--no-visualize] [--viewport WxH]`;
|
|
710
769
|
|
|
711
770
|
export const runInput = SimpleCLI.input({
|
|
712
771
|
positionals: [
|
|
713
772
|
SimpleCLI.positional("integrationFile", z.string().optional(), {
|
|
714
773
|
help: "Path to the integration file",
|
|
715
774
|
}),
|
|
716
|
-
SimpleCLI.positional("workflowName", z.string().optional(), {
|
|
717
|
-
help: "Workflow name to run (from workflow(name, handler))",
|
|
718
|
-
}),
|
|
719
775
|
],
|
|
720
776
|
named: {
|
|
721
777
|
session: sessionOption(),
|
|
@@ -731,6 +787,14 @@ export const runInput = SimpleCLI.input({
|
|
|
731
787
|
}),
|
|
732
788
|
headed: SimpleCLI.flag({ help: "Run in headed mode" }),
|
|
733
789
|
headless: SimpleCLI.flag({ help: "Run in headless mode" }),
|
|
790
|
+
readOnly: SimpleCLI.flag({
|
|
791
|
+
name: "read-only",
|
|
792
|
+
help: "Create the session in read-only mode",
|
|
793
|
+
}),
|
|
794
|
+
writeAccess: SimpleCLI.flag({
|
|
795
|
+
name: "write-access",
|
|
796
|
+
help: "Create the session in write-access mode (overrides config default)",
|
|
797
|
+
}),
|
|
734
798
|
noVisualize: SimpleCLI.flag({
|
|
735
799
|
name: "no-visualize",
|
|
736
800
|
help: "Disable ghost cursor + highlight visualization in headed mode",
|
|
@@ -742,10 +806,14 @@ export const runInput = SimpleCLI.input({
|
|
|
742
806
|
viewport: SimpleCLI.option(z.string().optional(), {
|
|
743
807
|
help: "Viewport size as WIDTHxHEIGHT (e.g. 1920x1080)",
|
|
744
808
|
}),
|
|
809
|
+
provider: SimpleCLI.option(z.string().optional(), {
|
|
810
|
+
help: "Browser provider (local, kernel, browserbase)",
|
|
811
|
+
aliases: ["-p"],
|
|
812
|
+
}),
|
|
745
813
|
},
|
|
746
814
|
})
|
|
747
815
|
.refine(
|
|
748
|
-
(input) => Boolean(input.integrationFile
|
|
816
|
+
(input) => Boolean(input.integrationFile),
|
|
749
817
|
runUsage,
|
|
750
818
|
)
|
|
751
819
|
.refine(
|
|
@@ -755,6 +823,10 @@ export const runInput = SimpleCLI.input({
|
|
|
755
823
|
.refine(
|
|
756
824
|
(input) => !(input.headed && input.headless),
|
|
757
825
|
"Cannot pass both --headed and --headless.",
|
|
826
|
+
)
|
|
827
|
+
.refine(
|
|
828
|
+
(input) => !(input.readOnly && input.writeAccess),
|
|
829
|
+
"Cannot pass both --read-only and --write-access.",
|
|
758
830
|
);
|
|
759
831
|
|
|
760
832
|
function resolveRunParams(
|
|
@@ -779,11 +851,12 @@ function resolveRunParams(
|
|
|
779
851
|
}
|
|
780
852
|
|
|
781
853
|
export const runCommand = SimpleCLI.command({
|
|
782
|
-
description: "Run
|
|
854
|
+
description: "Run the default-exported Libretto workflow from a file",
|
|
783
855
|
})
|
|
784
856
|
.input(runInput)
|
|
785
857
|
.use(withAutoSession())
|
|
786
858
|
.handle(async ({ input, ctx }) => {
|
|
859
|
+
warnIfInstalledSkillOutOfDate();
|
|
787
860
|
await stopExistingFailedRunSession(ctx.session, ctx.logger);
|
|
788
861
|
assertSessionAvailableForStart(ctx.session, ctx.logger);
|
|
789
862
|
|
|
@@ -799,20 +872,53 @@ export const runCommand = SimpleCLI.command({
|
|
|
799
872
|
ctx.logger,
|
|
800
873
|
);
|
|
801
874
|
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
875
|
+
const providerName = resolveProviderName(input.provider);
|
|
876
|
+
let cdpEndpoint: string | undefined;
|
|
877
|
+
let providerInfo: { name: string; sessionId: string } | undefined;
|
|
878
|
+
let provider: ReturnType<typeof getCloudProviderApi> | undefined;
|
|
879
|
+
if (providerName !== "local") {
|
|
880
|
+
provider = getCloudProviderApi(providerName);
|
|
881
|
+
console.log(
|
|
882
|
+
`Creating ${providerName} browser session (session: ${ctx.session})...`,
|
|
883
|
+
);
|
|
884
|
+
const providerSession = await provider.createSession();
|
|
885
|
+
console.log(`Connecting to ${providerName} browser...`);
|
|
886
|
+
cdpEndpoint = providerSession.cdpEndpoint;
|
|
887
|
+
providerInfo = {
|
|
888
|
+
name: providerName,
|
|
889
|
+
sessionId: providerSession.sessionId,
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
try {
|
|
894
|
+
await runIntegrationFromFile(
|
|
895
|
+
{
|
|
896
|
+
integrationPath: input.integrationFile!,
|
|
897
|
+
session: ctx.session,
|
|
898
|
+
params,
|
|
899
|
+
tsconfigPath: input.tsconfig,
|
|
900
|
+
headless: cdpEndpoint ? true : (headlessMode ?? false),
|
|
901
|
+
visualize,
|
|
902
|
+
authProfileDomain: input.authProfile,
|
|
903
|
+
viewport,
|
|
904
|
+
accessMode: input.readOnly ? "read-only" : input.writeAccess ? "write-access" : (readLibrettoConfig().sessionMode ?? "write-access"),
|
|
905
|
+
cdpEndpoint,
|
|
906
|
+
provider: providerInfo,
|
|
907
|
+
},
|
|
908
|
+
ctx.logger,
|
|
909
|
+
);
|
|
910
|
+
} finally {
|
|
911
|
+
if (provider && providerInfo) {
|
|
912
|
+
try {
|
|
913
|
+
await provider.closeSession(providerInfo.sessionId);
|
|
914
|
+
} catch (cleanupErr) {
|
|
915
|
+
console.error(
|
|
916
|
+
`Failed to clean up ${providerInfo.name} session ${providerInfo.sessionId}:`,
|
|
917
|
+
cleanupErr instanceof Error ? cleanupErr.message : cleanupErr,
|
|
918
|
+
);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
}
|
|
816
922
|
});
|
|
817
923
|
|
|
818
924
|
export const resumeInput = SimpleCLI.input({
|
|
@@ -833,6 +939,7 @@ export const resumeCommand = SimpleCLI.command({
|
|
|
833
939
|
|
|
834
940
|
export const executionCommands = {
|
|
835
941
|
exec: execCommand,
|
|
942
|
+
"readonly-exec": readonlyExecCommand,
|
|
836
943
|
run: runCommand,
|
|
837
944
|
resume: resumeCommand,
|
|
838
945
|
};
|