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
|
@@ -13,15 +13,20 @@ import { parseViewportArg } from "./browser.js";
|
|
|
13
13
|
import { getPauseSignalPaths } from "../core/pause-signals.js";
|
|
14
14
|
import {
|
|
15
15
|
assertSessionAvailableForStart,
|
|
16
|
+
assertSessionAllowsCommand,
|
|
16
17
|
clearSessionState,
|
|
17
18
|
readSessionState,
|
|
18
19
|
setSessionStatus
|
|
19
20
|
} from "../core/session.js";
|
|
21
|
+
import { warnIfInstalledSkillOutOfDate } from "../core/skill-version.js";
|
|
20
22
|
import {
|
|
21
23
|
readActionLog,
|
|
22
24
|
readNetworkLog,
|
|
23
25
|
wrapPageForActionLogging
|
|
24
26
|
} from "../core/telemetry.js";
|
|
27
|
+
import { readLibrettoConfig } from "../core/config.js";
|
|
28
|
+
import { resolveProviderName, getCloudProviderApi } from "../core/providers/index.js";
|
|
29
|
+
import { createReadonlyExecHelpers } from "../core/readonly-exec.js";
|
|
25
30
|
import { SimpleCLI } from "../framework/simple-cli.js";
|
|
26
31
|
import {
|
|
27
32
|
pageOption,
|
|
@@ -135,12 +140,15 @@ function stripEmptyCatchHandlers(code) {
|
|
|
135
140
|
}
|
|
136
141
|
return { cleaned: result, strippedCount };
|
|
137
142
|
}
|
|
138
|
-
async function runExec(code, session, logger,
|
|
143
|
+
async function runExec(code, session, logger, options = {}) {
|
|
144
|
+
const visualize = options.visualize ?? false;
|
|
145
|
+
const pageId = options.pageId;
|
|
146
|
+
const mode = options.mode ?? "exec";
|
|
139
147
|
const { cleaned: cleanedCode, strippedCount } = stripEmptyCatchHandlers(code);
|
|
140
148
|
if (strippedCount > 0) {
|
|
141
149
|
console.log("(Stripped `.catch(() => {})` \u2014 letting errors bubble up)");
|
|
142
150
|
}
|
|
143
|
-
logger.info(
|
|
151
|
+
logger.info(`${mode}-start`, {
|
|
144
152
|
session,
|
|
145
153
|
codeLength: cleanedCode.length,
|
|
146
154
|
codePreview: cleanedCode.slice(0, 200),
|
|
@@ -164,57 +172,61 @@ async function runExec(code, session, logger, visualize = false, pageId) {
|
|
|
164
172
|
const stallInterval = setInterval(() => {
|
|
165
173
|
const silenceMs = Date.now() - lastActivityTs;
|
|
166
174
|
if (silenceMs >= STALL_THRESHOLD_MS) {
|
|
167
|
-
logger.warn(
|
|
175
|
+
logger.warn(`${mode}-stall-warning`, {
|
|
168
176
|
session,
|
|
169
177
|
silenceMs,
|
|
170
178
|
codePreview: cleanedCode.slice(0, 200)
|
|
171
179
|
});
|
|
172
180
|
console.warn(
|
|
173
|
-
`[stall-warning] No Playwright activity for ${Math.round(silenceMs / 1e3)}s \u2014
|
|
181
|
+
`[stall-warning] No Playwright activity for ${Math.round(silenceMs / 1e3)}s \u2014 ${mode} may be hung (code: ${cleanedCode.slice(0, 100)}...)`
|
|
174
182
|
);
|
|
175
183
|
}
|
|
176
184
|
}, STALL_THRESHOLD_MS);
|
|
177
185
|
const execStartTs = Date.now();
|
|
178
186
|
const sigintHandler = () => {
|
|
179
|
-
logger.info(
|
|
187
|
+
logger.info(`${mode}-interrupted`, {
|
|
180
188
|
session,
|
|
181
189
|
duration: Date.now() - execStartTs,
|
|
182
190
|
codePreview: cleanedCode.slice(0, 200)
|
|
183
191
|
});
|
|
184
192
|
};
|
|
185
193
|
process.on("SIGINT", sigintHandler);
|
|
186
|
-
|
|
187
|
-
|
|
194
|
+
if (mode === "exec") {
|
|
195
|
+
wrapPageForActionLogging(page, session, resolvedPageId, onActivity);
|
|
196
|
+
}
|
|
197
|
+
if (visualize && mode === "exec") {
|
|
188
198
|
await installInstrumentation(page, { visualize: true, logger });
|
|
189
199
|
}
|
|
190
200
|
try {
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
201
|
+
const helpers = mode === "readonly-exec" ? createReadonlyExecHelpers(page, { onActivity }) : (() => {
|
|
202
|
+
const execState = {};
|
|
203
|
+
const networkLog = (opts = {}) => {
|
|
204
|
+
return readNetworkLog(session, opts);
|
|
205
|
+
};
|
|
206
|
+
const actionLog = (opts = {}) => {
|
|
207
|
+
return readActionLog(session, opts);
|
|
208
|
+
};
|
|
209
|
+
return {
|
|
210
|
+
page,
|
|
211
|
+
context,
|
|
212
|
+
state: execState,
|
|
213
|
+
browser,
|
|
214
|
+
networkLog,
|
|
215
|
+
actionLog,
|
|
216
|
+
console,
|
|
217
|
+
setTimeout,
|
|
218
|
+
setInterval,
|
|
219
|
+
clearTimeout,
|
|
220
|
+
clearInterval,
|
|
221
|
+
fetch,
|
|
222
|
+
URL,
|
|
223
|
+
Buffer
|
|
224
|
+
};
|
|
225
|
+
})();
|
|
214
226
|
const helperNames = Object.keys(helpers);
|
|
215
227
|
const fn = compileExecFunction(cleanedCode, helperNames);
|
|
216
228
|
const result = await fn(...Object.values(helpers));
|
|
217
|
-
logger.info(
|
|
229
|
+
logger.info(`${mode}-success`, { session, hasResult: result !== void 0 });
|
|
218
230
|
if (result !== void 0) {
|
|
219
231
|
console.log(
|
|
220
232
|
typeof result === "string" ? result : JSON.stringify(result, null, 2)
|
|
@@ -223,7 +235,7 @@ async function runExec(code, session, logger, visualize = false, pageId) {
|
|
|
223
235
|
console.log("Executed successfully");
|
|
224
236
|
}
|
|
225
237
|
} catch (err) {
|
|
226
|
-
logger.error(
|
|
238
|
+
logger.error(`${mode}-error`, {
|
|
227
239
|
error: err,
|
|
228
240
|
session,
|
|
229
241
|
codePreview: cleanedCode.slice(0, 200)
|
|
@@ -445,13 +457,15 @@ async function runIntegrationFromFile(args, logger) {
|
|
|
445
457
|
);
|
|
446
458
|
const payload = JSON.stringify({
|
|
447
459
|
integrationPath: args.integrationPath,
|
|
448
|
-
workflowName: args.workflowName,
|
|
449
460
|
session: args.session,
|
|
450
461
|
params: args.params,
|
|
451
462
|
headless: args.headless,
|
|
452
463
|
visualize: args.visualize,
|
|
453
464
|
authProfileDomain: args.authProfileDomain,
|
|
454
|
-
viewport: args.viewport
|
|
465
|
+
viewport: args.viewport,
|
|
466
|
+
accessMode: args.accessMode,
|
|
467
|
+
cdpEndpoint: args.cdpEndpoint,
|
|
468
|
+
provider: args.provider
|
|
455
469
|
});
|
|
456
470
|
const worker = spawn(
|
|
457
471
|
process.execPath,
|
|
@@ -526,6 +540,7 @@ const execInput = SimpleCLI.input({
|
|
|
526
540
|
const execCommand = SimpleCLI.command({
|
|
527
541
|
description: "Execute Playwright TypeScript code"
|
|
528
542
|
}).input(execInput).use(withRequiredSession()).handle(async ({ input, ctx }) => {
|
|
543
|
+
assertSessionAllowsCommand(ctx.sessionState, "exec", ["write-access"]);
|
|
529
544
|
const code = input.code;
|
|
530
545
|
const codeFromArgsOrStdin = code === "-" ? readStdinSync() : code;
|
|
531
546
|
if (codeFromArgsOrStdin === null) {
|
|
@@ -537,18 +552,48 @@ const execCommand = SimpleCLI.command({
|
|
|
537
552
|
codeFromArgsOrStdin,
|
|
538
553
|
ctx.session,
|
|
539
554
|
ctx.logger,
|
|
540
|
-
|
|
541
|
-
|
|
555
|
+
{
|
|
556
|
+
visualize: input.visualize,
|
|
557
|
+
pageId: input.page,
|
|
558
|
+
mode: "exec"
|
|
559
|
+
}
|
|
542
560
|
);
|
|
543
561
|
});
|
|
544
|
-
const
|
|
562
|
+
const readonlyExecInput = SimpleCLI.input({
|
|
563
|
+
positionals: [
|
|
564
|
+
SimpleCLI.positional("code", z.string().optional(), {
|
|
565
|
+
help: "Read-only Playwright TypeScript code to execute"
|
|
566
|
+
})
|
|
567
|
+
],
|
|
568
|
+
named: {
|
|
569
|
+
session: sessionOption(),
|
|
570
|
+
page: pageOption()
|
|
571
|
+
}
|
|
572
|
+
}).refine(
|
|
573
|
+
(input) => input.code !== void 0,
|
|
574
|
+
`Usage: libretto readonly-exec <code|-> [--session <name>] [--page <id>]
|
|
575
|
+
echo '<code>' | libretto readonly-exec - [--session <name>] [--page <id>]`
|
|
576
|
+
);
|
|
577
|
+
const readonlyExecCommand = SimpleCLI.command({
|
|
578
|
+
description: "Execute read-only Playwright inspection code"
|
|
579
|
+
}).input(readonlyExecInput).use(withRequiredSession()).handle(async ({ input, ctx }) => {
|
|
580
|
+
const code = input.code;
|
|
581
|
+
const codeFromArgsOrStdin = code === "-" ? readStdinSync() : code;
|
|
582
|
+
if (codeFromArgsOrStdin === null) {
|
|
583
|
+
throw new Error(
|
|
584
|
+
"Missing stdin input for `readonly-exec -`. Pipe inspection code into stdin."
|
|
585
|
+
);
|
|
586
|
+
}
|
|
587
|
+
await runExec(codeFromArgsOrStdin, ctx.session, ctx.logger, {
|
|
588
|
+
pageId: input.page,
|
|
589
|
+
mode: "readonly-exec"
|
|
590
|
+
});
|
|
591
|
+
});
|
|
592
|
+
const runUsage = `Usage: libretto run <integrationFile> [--params <json> | --params-file <path>] [--tsconfig <path>] [--headed|--headless] [--read-only|--write-access] [--no-visualize] [--viewport WxH]`;
|
|
545
593
|
const runInput = SimpleCLI.input({
|
|
546
594
|
positionals: [
|
|
547
595
|
SimpleCLI.positional("integrationFile", z.string().optional(), {
|
|
548
596
|
help: "Path to the integration file"
|
|
549
|
-
}),
|
|
550
|
-
SimpleCLI.positional("workflowName", z.string().optional(), {
|
|
551
|
-
help: "Workflow name to run (from workflow(name, handler))"
|
|
552
597
|
})
|
|
553
598
|
],
|
|
554
599
|
named: {
|
|
@@ -565,6 +610,14 @@ const runInput = SimpleCLI.input({
|
|
|
565
610
|
}),
|
|
566
611
|
headed: SimpleCLI.flag({ help: "Run in headed mode" }),
|
|
567
612
|
headless: SimpleCLI.flag({ help: "Run in headless mode" }),
|
|
613
|
+
readOnly: SimpleCLI.flag({
|
|
614
|
+
name: "read-only",
|
|
615
|
+
help: "Create the session in read-only mode"
|
|
616
|
+
}),
|
|
617
|
+
writeAccess: SimpleCLI.flag({
|
|
618
|
+
name: "write-access",
|
|
619
|
+
help: "Create the session in write-access mode (overrides config default)"
|
|
620
|
+
}),
|
|
568
621
|
noVisualize: SimpleCLI.flag({
|
|
569
622
|
name: "no-visualize",
|
|
570
623
|
help: "Disable ghost cursor + highlight visualization in headed mode"
|
|
@@ -575,10 +628,14 @@ const runInput = SimpleCLI.input({
|
|
|
575
628
|
}),
|
|
576
629
|
viewport: SimpleCLI.option(z.string().optional(), {
|
|
577
630
|
help: "Viewport size as WIDTHxHEIGHT (e.g. 1920x1080)"
|
|
631
|
+
}),
|
|
632
|
+
provider: SimpleCLI.option(z.string().optional(), {
|
|
633
|
+
help: "Browser provider (local, kernel, browserbase)",
|
|
634
|
+
aliases: ["-p"]
|
|
578
635
|
})
|
|
579
636
|
}
|
|
580
637
|
}).refine(
|
|
581
|
-
(input) => Boolean(input.integrationFile
|
|
638
|
+
(input) => Boolean(input.integrationFile),
|
|
582
639
|
runUsage
|
|
583
640
|
).refine(
|
|
584
641
|
(input) => !(input.params && input.paramsFile),
|
|
@@ -586,6 +643,9 @@ const runInput = SimpleCLI.input({
|
|
|
586
643
|
).refine(
|
|
587
644
|
(input) => !(input.headed && input.headless),
|
|
588
645
|
"Cannot pass both --headed and --headless."
|
|
646
|
+
).refine(
|
|
647
|
+
(input) => !(input.readOnly && input.writeAccess),
|
|
648
|
+
"Cannot pass both --read-only and --write-access."
|
|
589
649
|
);
|
|
590
650
|
function resolveRunParams(rawInlineParams, paramsFile) {
|
|
591
651
|
if (paramsFile) {
|
|
@@ -605,8 +665,9 @@ function resolveRunParams(rawInlineParams, paramsFile) {
|
|
|
605
665
|
return {};
|
|
606
666
|
}
|
|
607
667
|
const runCommand = SimpleCLI.command({
|
|
608
|
-
description: "Run
|
|
668
|
+
description: "Run the default-exported Libretto workflow from a file"
|
|
609
669
|
}).input(runInput).use(withAutoSession()).handle(async ({ input, ctx }) => {
|
|
670
|
+
warnIfInstalledSkillOutOfDate();
|
|
610
671
|
await stopExistingFailedRunSession(ctx.session, ctx.logger);
|
|
611
672
|
assertSessionAvailableForStart(ctx.session, ctx.logger);
|
|
612
673
|
const params = resolveRunParams(input.params, input.paramsFile);
|
|
@@ -616,20 +677,52 @@ const runCommand = SimpleCLI.command({
|
|
|
616
677
|
parseViewportArg(input.viewport),
|
|
617
678
|
ctx.logger
|
|
618
679
|
);
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
680
|
+
const providerName = resolveProviderName(input.provider);
|
|
681
|
+
let cdpEndpoint;
|
|
682
|
+
let providerInfo;
|
|
683
|
+
let provider;
|
|
684
|
+
if (providerName !== "local") {
|
|
685
|
+
provider = getCloudProviderApi(providerName);
|
|
686
|
+
console.log(
|
|
687
|
+
`Creating ${providerName} browser session (session: ${ctx.session})...`
|
|
688
|
+
);
|
|
689
|
+
const providerSession = await provider.createSession();
|
|
690
|
+
console.log(`Connecting to ${providerName} browser...`);
|
|
691
|
+
cdpEndpoint = providerSession.cdpEndpoint;
|
|
692
|
+
providerInfo = {
|
|
693
|
+
name: providerName,
|
|
694
|
+
sessionId: providerSession.sessionId
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
try {
|
|
698
|
+
await runIntegrationFromFile(
|
|
699
|
+
{
|
|
700
|
+
integrationPath: input.integrationFile,
|
|
701
|
+
session: ctx.session,
|
|
702
|
+
params,
|
|
703
|
+
tsconfigPath: input.tsconfig,
|
|
704
|
+
headless: cdpEndpoint ? true : headlessMode ?? false,
|
|
705
|
+
visualize,
|
|
706
|
+
authProfileDomain: input.authProfile,
|
|
707
|
+
viewport,
|
|
708
|
+
accessMode: input.readOnly ? "read-only" : input.writeAccess ? "write-access" : readLibrettoConfig().sessionMode ?? "write-access",
|
|
709
|
+
cdpEndpoint,
|
|
710
|
+
provider: providerInfo
|
|
711
|
+
},
|
|
712
|
+
ctx.logger
|
|
713
|
+
);
|
|
714
|
+
} finally {
|
|
715
|
+
if (provider && providerInfo) {
|
|
716
|
+
try {
|
|
717
|
+
await provider.closeSession(providerInfo.sessionId);
|
|
718
|
+
} catch (cleanupErr) {
|
|
719
|
+
console.error(
|
|
720
|
+
`Failed to clean up ${providerInfo.name} session ${providerInfo.sessionId}:`,
|
|
721
|
+
cleanupErr instanceof Error ? cleanupErr.message : cleanupErr
|
|
722
|
+
);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
633
726
|
});
|
|
634
727
|
const resumeInput = SimpleCLI.input({
|
|
635
728
|
positionals: [],
|
|
@@ -644,6 +737,7 @@ const resumeCommand = SimpleCLI.command({
|
|
|
644
737
|
});
|
|
645
738
|
const executionCommands = {
|
|
646
739
|
exec: execCommand,
|
|
740
|
+
"readonly-exec": readonlyExecCommand,
|
|
647
741
|
run: runCommand,
|
|
648
742
|
resume: resumeCommand
|
|
649
743
|
};
|
|
@@ -651,6 +745,8 @@ export {
|
|
|
651
745
|
execCommand,
|
|
652
746
|
execInput,
|
|
653
747
|
executionCommands,
|
|
748
|
+
readonlyExecCommand,
|
|
749
|
+
readonlyExecInput,
|
|
654
750
|
resumeCommand,
|
|
655
751
|
resumeInput,
|
|
656
752
|
runCommand,
|