vigthoria-cli 1.13.31 → 1.13.42
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 +11 -56
- package/SECURITY_HARDENING.md +2 -4
- package/dist/commands/auth.js +16 -14
- package/dist/commands/cancel.d.ts +1 -0
- package/dist/commands/cancel.js +21 -4
- package/dist/commands/chat.d.ts +13 -0
- package/dist/commands/chat.js +170 -14
- package/dist/commands/fork.js +8 -3
- package/dist/commands/history.js +8 -3
- package/dist/commands/legion.js +1 -1
- package/dist/commands/replay.js +8 -3
- package/dist/commands/update-registration.js +63 -206
- package/dist/commands/v4-menu.d.ts +0 -1
- package/dist/commands/v4-menu.js +8 -6
- package/dist/commands/v4-registration.js +0 -2
- package/dist/commands/v4.js +9 -4
- package/dist/commands/wallet.d.ts +1 -1
- package/dist/commands/wallet.js +3 -3
- package/dist/index.js +2 -3
- package/dist/utils/agent-stream-state.d.ts +7 -0
- package/dist/utils/agent-stream-state.js +31 -0
- package/dist/utils/agentRunOutcome.js +5 -1
- package/dist/utils/api.d.ts +21 -3
- package/dist/utils/api.js +379 -550
- package/dist/utils/frontend-preview-service.d.ts +12 -2
- package/dist/utils/frontend-preview-service.js +214 -24
- package/dist/utils/javascript-syntax.d.ts +19 -0
- package/dist/utils/javascript-syntax.js +35 -0
- package/dist/utils/localTestMode.js +1 -1
- package/dist/utils/mutation-journal.d.ts +10 -0
- package/dist/utils/mutation-journal.js +104 -76
- package/dist/utils/network-policy.js +7 -10
- package/dist/utils/preview-screenshot-adapter.d.ts +111 -1
- package/dist/utils/preview-screenshot-adapter.js +990 -7
- package/dist/utils/release-install.d.ts +0 -1
- package/dist/utils/release-install.js +44 -7
- package/dist/utils/requestIntent.d.ts +1 -1
- package/dist/utils/requestIntent.js +17 -3
- package/dist/utils/tools.js +21 -15
- package/dist/utils/update-policy.d.ts +0 -4
- package/dist/utils/update-policy.js +5 -9
- package/dist/utils/v3-agent-client.js +25 -11
- package/install.ps1 +30 -50
- package/install.sh +12 -23
- package/package.json +4 -2
- package/release-policy.json +1 -5
- package/scripts/release/LOCAL_MACHINE_USER_VERIFICATION.md +6 -7
- package/scripts/release/install-release.mjs +5 -4
- package/scripts/release/publish-cli-release.mjs +21 -8
- package/scripts/release/test-balanced-model-live.sh +4 -1
- package/scripts/release/validate-live-service-gates.sh +27 -5
|
@@ -6,6 +6,7 @@ const IGNORE_NAMES = new Set(['.git', 'node_modules', '.vigthoria']);
|
|
|
6
6
|
const DEFAULT_MAX_BACKUP_BYTES = 128 * 1024 * 1024;
|
|
7
7
|
const DEFAULT_MAX_FILE_BYTES = 16 * 1024 * 1024;
|
|
8
8
|
const DEFAULT_MAX_FILES = 20_000;
|
|
9
|
+
const ACTIVE_MUTATION_JOURNALS = new Set();
|
|
9
10
|
function hashFile(filePath) {
|
|
10
11
|
const hash = createHash('sha256');
|
|
11
12
|
const descriptor = fs.openSync(filePath, 'r');
|
|
@@ -52,6 +53,7 @@ export class MutationJournal {
|
|
|
52
53
|
this.manifestPath = path.join(this.journalDirectory, 'journal.json');
|
|
53
54
|
this.captureBaseline();
|
|
54
55
|
this.persist('open', [], [], false);
|
|
56
|
+
ACTIVE_MUTATION_JOURNALS.add(this);
|
|
55
57
|
}
|
|
56
58
|
listWorkspaceDirectories() {
|
|
57
59
|
const directories = [];
|
|
@@ -284,104 +286,130 @@ export class MutationJournal {
|
|
|
284
286
|
};
|
|
285
287
|
}
|
|
286
288
|
commit() {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
289
|
+
try {
|
|
290
|
+
const affectedPaths = this.changedPaths();
|
|
291
|
+
this.persist('committed', affectedPaths, [], false);
|
|
292
|
+
fs.rmSync(this.backupDirectory, { recursive: true, force: true });
|
|
293
|
+
return this.report(affectedPaths, [], false);
|
|
294
|
+
}
|
|
295
|
+
finally {
|
|
296
|
+
ACTIVE_MUTATION_JOURNALS.delete(this);
|
|
297
|
+
}
|
|
291
298
|
}
|
|
292
299
|
rollback() {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
const safe = assertSafeRelativePath(relativePath);
|
|
298
|
-
const absolute = path.resolve(this.rootPath, ...safe.split('/'));
|
|
299
|
-
const relative = path.relative(this.rootPath, absolute);
|
|
300
|
-
if (relative.startsWith('..') || path.isAbsolute(relative))
|
|
301
|
-
throw new Error('path escaped workspace');
|
|
300
|
+
try {
|
|
301
|
+
const affectedPaths = this.changedPaths();
|
|
302
|
+
const failures = [];
|
|
303
|
+
for (const relativePath of affectedPaths.filter((entry) => !this.baseline.has(entry))) {
|
|
302
304
|
try {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
+
const safe = assertSafeRelativePath(relativePath);
|
|
306
|
+
const absolute = path.resolve(this.rootPath, ...safe.split('/'));
|
|
307
|
+
const relative = path.relative(this.rootPath, absolute);
|
|
308
|
+
if (relative.startsWith('..') || path.isAbsolute(relative))
|
|
309
|
+
throw new Error('path escaped workspace');
|
|
310
|
+
try {
|
|
311
|
+
fs.lstatSync(absolute);
|
|
312
|
+
fs.unlinkSync(absolute);
|
|
313
|
+
}
|
|
314
|
+
catch (error) {
|
|
315
|
+
if (error?.code !== 'ENOENT')
|
|
316
|
+
throw error;
|
|
317
|
+
}
|
|
305
318
|
}
|
|
306
319
|
catch (error) {
|
|
307
|
-
|
|
308
|
-
throw error;
|
|
320
|
+
failures.push(`${relativePath}: could not remove created file: ${error.message}`);
|
|
309
321
|
}
|
|
310
322
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
const baseline = this.baseline.get(relativePath);
|
|
317
|
-
if (baseline.kind === 'file' && (!baseline.backupPath || !fs.existsSync(baseline.backupPath))) {
|
|
318
|
-
failures.push(`${relativePath}: rollback backup unavailable`);
|
|
319
|
-
continue;
|
|
320
|
-
}
|
|
321
|
-
try {
|
|
322
|
-
const destination = this.resolveRollbackDestination(relativePath);
|
|
323
|
-
this.removeRollbackDestination(destination);
|
|
324
|
-
if (baseline.kind === 'symlink') {
|
|
325
|
-
if (baseline.linkTarget === undefined)
|
|
326
|
-
throw new Error('rollback link target unavailable');
|
|
327
|
-
fs.symlinkSync(baseline.linkTarget, destination, baseline.linkType);
|
|
323
|
+
for (const relativePath of affectedPaths.filter((entry) => this.baseline.has(entry))) {
|
|
324
|
+
const baseline = this.baseline.get(relativePath);
|
|
325
|
+
if (baseline.kind === 'file' && (!baseline.backupPath || !fs.existsSync(baseline.backupPath))) {
|
|
326
|
+
failures.push(`${relativePath}: rollback backup unavailable`);
|
|
327
|
+
continue;
|
|
328
328
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
fs.
|
|
336
|
-
fs.renameSync(temporary, destination);
|
|
329
|
+
try {
|
|
330
|
+
const destination = this.resolveRollbackDestination(relativePath);
|
|
331
|
+
this.removeRollbackDestination(destination);
|
|
332
|
+
if (baseline.kind === 'symlink') {
|
|
333
|
+
if (baseline.linkTarget === undefined)
|
|
334
|
+
throw new Error('rollback link target unavailable');
|
|
335
|
+
fs.symlinkSync(baseline.linkTarget, destination, baseline.linkType);
|
|
337
336
|
}
|
|
338
|
-
|
|
337
|
+
else {
|
|
338
|
+
if (!baseline.backupPath || !fs.existsSync(baseline.backupPath))
|
|
339
|
+
throw new Error('rollback backup unavailable');
|
|
340
|
+
const temporary = `${destination}.rollback-${randomUUID()}`;
|
|
339
341
|
try {
|
|
340
|
-
fs.
|
|
342
|
+
fs.copyFileSync(baseline.backupPath, temporary, fs.constants.COPYFILE_EXCL);
|
|
343
|
+
fs.chmodSync(temporary, baseline.mode ?? 0o600);
|
|
344
|
+
fs.renameSync(temporary, destination);
|
|
341
345
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
346
|
+
finally {
|
|
347
|
+
try {
|
|
348
|
+
fs.unlinkSync(temporary);
|
|
349
|
+
}
|
|
350
|
+
catch (error) {
|
|
351
|
+
if (error?.code !== 'ENOENT')
|
|
352
|
+
throw error;
|
|
353
|
+
}
|
|
345
354
|
}
|
|
346
355
|
}
|
|
347
356
|
}
|
|
357
|
+
catch (error) {
|
|
358
|
+
failures.push(`${relativePath}: restore failed: ${error.message}`);
|
|
359
|
+
}
|
|
348
360
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
catch (error) {
|
|
358
|
-
failures.push(`${relativePath}: directory restore failed: ${error.message}`);
|
|
361
|
+
for (const relativePath of [...this.baselineDirectories].sort((a, b) => a.length - b.length)) {
|
|
362
|
+
try {
|
|
363
|
+
fs.mkdirSync(resolveWorkspacePath(this.rootPath, relativePath, { allowMissing: true }), { recursive: true });
|
|
364
|
+
}
|
|
365
|
+
catch (error) {
|
|
366
|
+
failures.push(`${relativePath}: directory restore failed: ${error.message}`);
|
|
367
|
+
}
|
|
359
368
|
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
369
|
+
for (const relativePath of this.listWorkspaceDirectories().sort((a, b) => b.length - a.length)) {
|
|
370
|
+
if (this.baselineDirectories.has(relativePath))
|
|
371
|
+
continue;
|
|
372
|
+
try {
|
|
373
|
+
const directory = resolveWorkspacePath(this.rootPath, relativePath);
|
|
374
|
+
if (fs.readdirSync(directory).length === 0)
|
|
375
|
+
fs.rmdirSync(directory);
|
|
376
|
+
}
|
|
377
|
+
catch (error) {
|
|
378
|
+
failures.push(`${relativePath}: created directory remains: ${error.message}`);
|
|
379
|
+
}
|
|
368
380
|
}
|
|
369
|
-
|
|
370
|
-
|
|
381
|
+
const residual = this.changedPaths();
|
|
382
|
+
for (const relativePath of residual) {
|
|
383
|
+
if (!failures.some((failure) => failure.startsWith(`${relativePath}:`))) {
|
|
384
|
+
failures.push(`${relativePath}: mutation remains after rollback`);
|
|
385
|
+
}
|
|
371
386
|
}
|
|
387
|
+
const partial = failures.length > 0;
|
|
388
|
+
this.persist(partial ? 'partial_mutation' : 'rolled_back', affectedPaths, failures, !partial);
|
|
389
|
+
fs.rmSync(this.backupDirectory, { recursive: true, force: true });
|
|
390
|
+
return this.report(affectedPaths, failures, !partial);
|
|
372
391
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
if (!failures.some((failure) => failure.startsWith(`${relativePath}:`))) {
|
|
376
|
-
failures.push(`${relativePath}: mutation remains after rollback`);
|
|
377
|
-
}
|
|
392
|
+
finally {
|
|
393
|
+
ACTIVE_MUTATION_JOURNALS.delete(this);
|
|
378
394
|
}
|
|
379
|
-
const partial = failures.length > 0;
|
|
380
|
-
this.persist(partial ? 'partial_mutation' : 'rolled_back', affectedPaths, failures, !partial);
|
|
381
|
-
fs.rmSync(this.backupDirectory, { recursive: true, force: true });
|
|
382
|
-
return this.report(affectedPaths, failures, !partial);
|
|
383
395
|
}
|
|
384
396
|
}
|
|
397
|
+
/**
|
|
398
|
+
* Last-resort synchronous rollback for process signals.
|
|
399
|
+
*
|
|
400
|
+
* APIClient normally owns the foreground journal, but command teardown or a
|
|
401
|
+
* second lifecycle wrapper must never be able to detach an open transaction
|
|
402
|
+
* from SIGINT/SIGTERM protection. Journals register at construction and
|
|
403
|
+
* unregister only after commit/rollback, so this fallback closes every still
|
|
404
|
+
* open workspace transaction before the original signal is re-raised.
|
|
405
|
+
*/
|
|
406
|
+
export function rollbackActiveMutationJournals() {
|
|
407
|
+
const reports = [];
|
|
408
|
+
for (const journal of [...ACTIVE_MUTATION_JOURNALS]) {
|
|
409
|
+
reports.push(journal.rollback());
|
|
410
|
+
}
|
|
411
|
+
return reports;
|
|
412
|
+
}
|
|
385
413
|
export function finalizeMutationTransaction(journal, proofSucceeded) {
|
|
386
414
|
return proofSucceeded ? journal.commit() : journal.rollback();
|
|
387
415
|
}
|
|
@@ -14,14 +14,7 @@ const AUDIENCE_HOSTS = {
|
|
|
14
14
|
hyperloop: new Set(['coder.vigthoria.io', 'hyperloop.vigthoria.io']),
|
|
15
15
|
vigflow: new Set(['coder.vigthoria.io', 'workflow.vigthoria.io']),
|
|
16
16
|
bridge: new Set(['bridge.vigthoria.io', 'devtools.vigthoria.io']),
|
|
17
|
-
release: new Set([
|
|
18
|
-
'extension.vigthoria.io',
|
|
19
|
-
'landing.vigthoria.io',
|
|
20
|
-
'cli.vigthoria.io',
|
|
21
|
-
'coder.vigthoria.io',
|
|
22
|
-
'market.vigthoria.io',
|
|
23
|
-
'registry.npmjs.org',
|
|
24
|
-
]),
|
|
17
|
+
release: new Set(['extension.vigthoria.io']),
|
|
25
18
|
};
|
|
26
19
|
// `auto` exists only as a compatibility guard for legacy calls to the primary
|
|
27
20
|
// Coder origin. It must never mean "any Vigthoria host": doing so allows a
|
|
@@ -30,9 +23,13 @@ const AUDIENCE_HOSTS = {
|
|
|
30
23
|
// its audience explicitly.
|
|
31
24
|
const AUTO_CREDENTIAL_HOSTS = AUDIENCE_HOSTS.coder;
|
|
32
25
|
const LOOPBACK_HOSTS = new Set(['localhost', '127.0.0.1', '::1']);
|
|
33
|
-
|
|
26
|
+
// 18032/18041 are the isolated CLI-lane candidate ports used by OS TestFarm.
|
|
27
|
+
// They remain unreachable unless the caller also opts into loopback services.
|
|
28
|
+
const LOOPBACK_PORTS = new Set(['4008', '4009', '4011', '4016', '49160', '8032', '18032', '18041', '8020', '5060', '5050', '8016', '9000']);
|
|
34
29
|
const TESTFARM_BRIDGE_HOSTS = new Set(['host.lan']);
|
|
35
|
-
|
|
30
|
+
// Remote TestFarm CLI guests reach the CLI-exclusive V3 runtime through
|
|
31
|
+
// 18032. Port 18030 is deliberately absent because it belongs to Desktop/IDE.
|
|
32
|
+
const TESTFARM_BRIDGE_PORTS = new Set(['14009', '18020', '18032', '4011']);
|
|
36
33
|
const SENSITIVE_HEADER_NAMES = new Set(['authorization', 'cookie', 'proxy-authorization', 'x-api-key', 'x-service-key']);
|
|
37
34
|
export const DEFAULT_NETWORK_TIMEOUT_MS = 30_000;
|
|
38
35
|
export class NetworkPolicyError extends Error {
|
|
@@ -1,17 +1,124 @@
|
|
|
1
|
+
import WebSocket from 'ws';
|
|
2
|
+
export type PreviewRuntimeInteractionOptions = {
|
|
3
|
+
key?: string;
|
|
4
|
+
expectText?: string;
|
|
5
|
+
requireStateChange?: boolean;
|
|
6
|
+
waitMs?: number;
|
|
7
|
+
timeoutMs?: number;
|
|
8
|
+
steps?: PreviewRuntimeStep[];
|
|
9
|
+
workspaceRoot?: string;
|
|
10
|
+
};
|
|
11
|
+
export type PreviewRuntimeStep = {
|
|
12
|
+
action: 'assert' | 'click' | 'fill' | 'select' | 'press' | 'focus' | 'wait' | 'reload';
|
|
13
|
+
selector?: string;
|
|
14
|
+
value?: string;
|
|
15
|
+
wait_ms?: number;
|
|
16
|
+
offset_x_ratio?: number;
|
|
17
|
+
offset_y_ratio?: number;
|
|
18
|
+
expect_selector?: string;
|
|
19
|
+
expect_count?: number;
|
|
20
|
+
expect_text?: string;
|
|
21
|
+
expect_text_not?: string;
|
|
22
|
+
expect_canvas_nonblank?: boolean;
|
|
23
|
+
expect_value?: string;
|
|
24
|
+
expect_visible?: boolean;
|
|
25
|
+
expect_hidden?: boolean;
|
|
26
|
+
expect_attribute?: string;
|
|
27
|
+
expect_attribute_value?: string;
|
|
28
|
+
expect_attribute_absent?: string;
|
|
29
|
+
expect_attribute_token?: string;
|
|
30
|
+
expect_attribute_token_absent?: string;
|
|
31
|
+
expect_focused?: boolean;
|
|
32
|
+
expect_focus_within?: string;
|
|
33
|
+
};
|
|
1
34
|
export type PreviewScreenshotResult = {
|
|
2
35
|
captured: boolean;
|
|
3
36
|
error?: string;
|
|
4
37
|
};
|
|
38
|
+
export type PreviewRuntimeInteractionResult = PreviewScreenshotResult & {
|
|
39
|
+
passed: boolean;
|
|
40
|
+
action?: string;
|
|
41
|
+
initialBodyText?: string;
|
|
42
|
+
finalBodyText?: string;
|
|
43
|
+
bodyChanged?: boolean;
|
|
44
|
+
visualChanged?: boolean;
|
|
45
|
+
runtimeErrors?: string[];
|
|
46
|
+
interactionStepsRequested?: number;
|
|
47
|
+
interactionStepsPassed?: number;
|
|
48
|
+
interactionFailures?: string[];
|
|
49
|
+
};
|
|
5
50
|
export interface PreviewScreenshotPort {
|
|
6
51
|
capture(entryAbsolutePath: string, screenshotPath: string): Promise<PreviewScreenshotResult>;
|
|
52
|
+
captureRuntime?(entryAbsolutePath: string, screenshotPath: string, options: PreviewRuntimeInteractionOptions): Promise<PreviewRuntimeInteractionResult>;
|
|
7
53
|
}
|
|
8
54
|
export type PreviewBrowserResolution = {
|
|
9
55
|
executablePath: string;
|
|
10
56
|
source: 'system';
|
|
11
57
|
};
|
|
12
58
|
export type PreviewBrowserRunner = (executablePath: string, args: readonly string[], platform: NodeJS.Platform, environment?: NodeJS.ProcessEnv) => Promise<void>;
|
|
59
|
+
type PreviewRuntimeBrowserObservation = {
|
|
60
|
+
action?: string;
|
|
61
|
+
initialBodyText: string;
|
|
62
|
+
finalBodyText: string;
|
|
63
|
+
bodyChanged: boolean;
|
|
64
|
+
visualChanged: boolean;
|
|
65
|
+
runtimeErrors: string[];
|
|
66
|
+
interactionStepsRequested?: number;
|
|
67
|
+
interactionStepsPassed?: number;
|
|
68
|
+
interactionFailures?: string[];
|
|
69
|
+
};
|
|
70
|
+
export type PreviewRuntimeBrowserRunner = (executablePath: string, args: readonly string[], platform: NodeJS.Platform, environment: NodeJS.ProcessEnv, screenshotPath: string, options: PreviewRuntimeInteractionOptions) => Promise<PreviewRuntimeBrowserObservation>;
|
|
71
|
+
export declare function assertPreviewBrowserSandboxUser(platform?: NodeJS.Platform, effectiveUserId?: number | undefined): void;
|
|
13
72
|
export declare function resolvePreviewBrowserExecutable(environment?: NodeJS.ProcessEnv, platform?: NodeJS.Platform, exists?: (candidate: string) => boolean): PreviewBrowserResolution | null;
|
|
14
73
|
export declare const runPreviewBrowser: PreviewBrowserRunner;
|
|
74
|
+
type CdpResponse = {
|
|
75
|
+
id?: number;
|
|
76
|
+
method?: string;
|
|
77
|
+
params?: Record<string, any>;
|
|
78
|
+
result?: Record<string, any>;
|
|
79
|
+
error?: {
|
|
80
|
+
message?: string;
|
|
81
|
+
};
|
|
82
|
+
sessionId?: string;
|
|
83
|
+
};
|
|
84
|
+
declare class PreviewCdpClient {
|
|
85
|
+
private readonly socket;
|
|
86
|
+
private nextId;
|
|
87
|
+
private readonly pending;
|
|
88
|
+
private readonly eventListeners;
|
|
89
|
+
constructor(socket: WebSocket);
|
|
90
|
+
onEvent(listener: (event: CdpResponse) => void): () => void;
|
|
91
|
+
send(method: string, params?: Record<string, any>, sessionId?: string): Promise<Record<string, any>>;
|
|
92
|
+
close(): void;
|
|
93
|
+
private rejectPending;
|
|
94
|
+
}
|
|
95
|
+
type RuntimeKeyDefinition = {
|
|
96
|
+
key: string;
|
|
97
|
+
code: string;
|
|
98
|
+
virtualKeyCode: number;
|
|
99
|
+
text?: string;
|
|
100
|
+
};
|
|
101
|
+
type RuntimeModifierDefinition = RuntimeKeyDefinition & {
|
|
102
|
+
bit: number;
|
|
103
|
+
};
|
|
104
|
+
export declare function runtimeKeyChordDefinition(rawKey?: string): {
|
|
105
|
+
key: RuntimeKeyDefinition;
|
|
106
|
+
modifiers: RuntimeModifierDefinition[];
|
|
107
|
+
modifierMask: number;
|
|
108
|
+
} | null;
|
|
109
|
+
export declare function applyRuntimeStepAction(client: PreviewCdpClient, sessionId: string, step: PreviewRuntimeStep): Promise<void>;
|
|
110
|
+
export declare function waitForRuntimeActionTarget(client: PreviewCdpClient, sessionId: string, selector: string, scenarioDeadline: number): Promise<void>;
|
|
111
|
+
export declare function runtimeAttributeExpectationFailures(step: Pick<PreviewRuntimeStep, 'expect_attribute' | 'expect_attribute_value' | 'expect_attribute_absent' | 'expect_attribute_token' | 'expect_attribute_token_absent'>, snapshot: {
|
|
112
|
+
attributeValue: string | null;
|
|
113
|
+
absentAttributeValue: string | null;
|
|
114
|
+
}): string[];
|
|
115
|
+
export declare function runtimeVisibilityExpectationFailures(step: Pick<PreviewRuntimeStep, 'expect_visible' | 'expect_hidden'>, snapshot: {
|
|
116
|
+
visible: boolean;
|
|
117
|
+
hiddenAttribute: boolean;
|
|
118
|
+
hiddenProperty: boolean;
|
|
119
|
+
computedDisplay: string;
|
|
120
|
+
}): string[];
|
|
121
|
+
export declare const runPreviewRuntimeBrowser: PreviewRuntimeBrowserRunner;
|
|
15
122
|
/** Dependency-free system-browser adapter. No browser download or archive
|
|
16
123
|
* extractor is shipped, and only fixed operating-system installation paths
|
|
17
124
|
* are eligible.
|
|
@@ -23,8 +130,11 @@ export declare class SystemBrowserScreenshotAdapter implements PreviewScreenshot
|
|
|
23
130
|
private readonly platform;
|
|
24
131
|
private readonly exists;
|
|
25
132
|
private readonly runner;
|
|
26
|
-
|
|
133
|
+
private readonly runtimeRunner;
|
|
134
|
+
constructor(environment?: NodeJS.ProcessEnv, allocateTemp?: (prefix: string, requestedMaxBytes?: number) => string, releaseTemp?: (directory: string) => void, platform?: NodeJS.Platform, exists?: (candidate: string) => boolean, runner?: PreviewBrowserRunner, runtimeRunner?: PreviewRuntimeBrowserRunner);
|
|
27
135
|
capture(entryAbsolutePath: string, screenshotPath: string): Promise<PreviewScreenshotResult>;
|
|
136
|
+
captureRuntime(entryAbsolutePath: string, screenshotPath: string, options: PreviewRuntimeInteractionOptions): Promise<PreviewRuntimeInteractionResult>;
|
|
137
|
+
private captureRuntimeOnce;
|
|
28
138
|
private captureOnce;
|
|
29
139
|
}
|
|
30
140
|
/** @deprecated Internal compatibility alias retained for older deep imports. */
|