autokap 1.0.6 → 1.0.8
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/assets/chrome/ios-statusbar-comparison-reference.jpg +0 -0
- package/assets/chrome/ios-statusbar-dark-reference.jpg +0 -0
- package/assets/chrome/ios-statusbar-light-reference.jpg +0 -0
- package/assets/cursors/macos.svg +4 -0
- package/assets/cursors/windows.svg +15 -0
- package/assets/devices/ipad-pro-11-m4.json +52 -0
- package/assets/devices/iphone-16-pro.json +53 -0
- package/assets/devices/macbook-air-13.json +45 -0
- package/assets/frames/MacBook Air 13.svg +242 -0
- package/assets/frames/Status bar - iPhone.png +0 -0
- Menu bar- iPad.png +0 -0
- package/assets/frames/iPad Pro M4 11_.png +0 -0
- package/assets/frames/iPhone 16 Pro.png +0 -0
- package/assets/icons/Cellular Connection.svg +3 -0
- package/assets/icons/Union.svg +6 -0
- package/assets/icons/Wifi.svg +3 -0
- package/assets/icons/battery.svg +5 -0
- package/assets/icons/battery_charging.svg +8 -0
- package/assets/skill/OPCODE-REFERENCE.md +607 -0
- package/assets/skill/README.md +39 -0
- package/assets/skill/SKILL.md +453 -468
- package/assets/skill/STUDIO-SKILL.md +476 -0
- package/assets/skill/references/examples.md +104 -0
- package/assets/skill/references/interactive-demo.md +225 -0
- package/assets/skill/references/mock-data.md +178 -0
- package/dist/abort.d.ts +5 -0
- package/dist/abort.js +44 -0
- package/dist/action-verifier.d.ts +29 -0
- package/dist/action-verifier.js +133 -0
- package/dist/agent-action-recovery.d.ts +45 -0
- package/dist/agent-action-recovery.js +370 -0
- package/dist/agent-message-utils.d.ts +21 -0
- package/dist/agent-message-utils.js +77 -0
- package/dist/agent-url-utils.d.ts +30 -0
- package/dist/agent-url-utils.js +138 -0
- package/dist/agent.d.ts +226 -0
- package/dist/agent.js +6666 -0
- package/dist/ak-tree.d.ts +39 -0
- package/dist/ak-tree.js +368 -0
- package/dist/alt-text.d.ts +26 -0
- package/dist/alt-text.js +55 -0
- package/dist/auth-capture.d.ts +17 -0
- package/dist/auth-capture.js +164 -0
- package/dist/benchmark.d.ts +59 -0
- package/dist/benchmark.js +135 -0
- package/dist/billing-operation-logging.d.ts +38 -0
- package/dist/billing-operation-logging.js +248 -0
- package/dist/browser-bar.d.ts +48 -0
- package/dist/browser-bar.js +284 -0
- package/dist/browser-pool.d.ts +7 -0
- package/dist/browser-pool.js +15 -5
- package/dist/browser-utils.d.ts +31 -0
- package/dist/browser-utils.js +97 -0
- package/dist/browser.d.ts +76 -1
- package/dist/browser.js +1657 -39
- package/dist/capture-alt-text.d.ts +12 -0
- package/dist/capture-alt-text.js +52 -0
- package/dist/capture-encryption.d.ts +10 -0
- package/dist/capture-encryption.js +41 -0
- package/dist/capture-language-preflight.d.ts +41 -0
- package/dist/capture-language-preflight.js +300 -0
- package/dist/capture-llm-page-identity.d.ts +15 -0
- package/dist/capture-llm-page-identity.js +128 -0
- package/dist/capture-model-resolution.d.ts +9 -0
- package/dist/capture-model-resolution.js +21 -0
- package/dist/capture-page-identity.d.ts +7 -0
- package/dist/capture-page-identity.js +352 -0
- package/dist/capture-preset-credentials.d.ts +62 -0
- package/dist/capture-preset-credentials.js +184 -0
- package/dist/capture-request-plan.d.ts +58 -0
- package/dist/capture-request-plan.js +264 -0
- package/dist/capture-run-optimizer.d.ts +139 -0
- package/dist/capture-run-optimizer.js +863 -0
- package/dist/capture-selector-memory.d.ts +31 -0
- package/dist/capture-selector-memory.js +345 -0
- package/dist/capture-session-profile-encryption.d.ts +2 -0
- package/dist/capture-session-profile-encryption.js +22 -0
- package/dist/capture-step-timeout.d.ts +10 -0
- package/dist/capture-step-timeout.js +30 -0
- package/dist/capture-strategy.d.ts +36 -0
- package/dist/capture-strategy.js +95 -0
- package/dist/capture-studio-sync.d.ts +23 -0
- package/dist/capture-studio-sync.js +172 -0
- package/dist/capture-surface-contract.d.ts +36 -0
- package/dist/capture-surface-contract.js +299 -0
- package/dist/capture-transition-engine.d.ts +28 -0
- package/dist/capture-transition-engine.js +292 -0
- package/dist/capture-variant-state.d.ts +56 -0
- package/dist/capture-variant-state.js +182 -0
- package/dist/capture-verification.d.ts +35 -0
- package/dist/capture-verification.js +95 -0
- package/dist/capture-viewport-lock.d.ts +48 -0
- package/dist/capture-viewport-lock.js +74 -0
- package/dist/circuit-breaker.d.ts +42 -0
- package/dist/circuit-breaker.js +119 -0
- package/dist/cli-config.d.ts +8 -1
- package/dist/cli-config.js +62 -6
- package/dist/cli-contract.d.ts +15 -0
- package/dist/cli-contract.js +167 -0
- package/dist/cli-runner-local.d.ts +12 -0
- package/dist/cli-runner-local.js +102 -0
- package/dist/cli-runner.d.ts +34 -0
- package/dist/cli-runner.js +433 -0
- package/dist/cli-utils.d.ts +0 -1
- package/dist/cli-utils.js +2 -5
- package/dist/cli.js +1005 -252
- package/dist/clip-orchestrator.d.ts +148 -0
- package/dist/clip-orchestrator.js +957 -0
- package/dist/clip-postprocess.d.ts +42 -0
- package/dist/clip-postprocess.js +201 -0
- package/dist/cookie-dismiss.d.ts +2 -0
- package/dist/cookie-dismiss.js +48 -13
- package/dist/cost-logging.d.ts +35 -0
- package/dist/cost-logging.js +242 -0
- package/dist/cost-resolution-monitor.d.ts +16 -0
- package/dist/cost-resolution-monitor.js +34 -0
- package/dist/credential-templates.d.ts +5 -0
- package/dist/credential-templates.js +60 -0
- package/dist/cursor-overlay-script.d.ts +6 -0
- package/dist/cursor-overlay-script.js +169 -0
- package/dist/dom-css-purger.d.ts +65 -0
- package/dist/dom-css-purger.js +333 -0
- package/dist/dom-font-inliner.d.ts +45 -0
- package/dist/dom-font-inliner.js +148 -0
- package/dist/dom-patch-resolver.d.ts +52 -0
- package/dist/dom-patch-resolver.js +242 -0
- package/dist/dom-serializer.d.ts +82 -0
- package/dist/dom-serializer.js +378 -0
- package/dist/element-capture.d.ts +13 -0
- package/dist/element-capture.js +522 -0
- package/dist/env-validation.d.ts +5 -0
- package/dist/env-validation.js +29 -0
- package/dist/execution-schema.d.ts +4423 -0
- package/dist/execution-schema.js +507 -0
- package/dist/execution-types.d.ts +886 -0
- package/dist/execution-types.js +65 -0
- package/dist/fonts-loader.d.ts +14 -0
- package/dist/fonts-loader.js +55 -0
- package/dist/hybrid-navigator.d.ts +138 -0
- package/dist/hybrid-navigator.js +468 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +17 -0
- package/dist/legacy/agent-action-recovery.d.ts +45 -0
- package/dist/legacy/agent-action-recovery.js +370 -0
- package/dist/legacy/agent-message-utils.d.ts +21 -0
- package/dist/legacy/agent-message-utils.js +77 -0
- package/dist/legacy/agent-url-utils.d.ts +30 -0
- package/dist/legacy/agent-url-utils.js +138 -0
- package/dist/legacy/agent.d.ts +226 -0
- package/dist/legacy/agent.js +6666 -0
- package/dist/legacy/clip-orchestrator.d.ts +148 -0
- package/dist/legacy/clip-orchestrator.js +957 -0
- package/dist/legacy/credential-templates.d.ts +5 -0
- package/dist/legacy/credential-templates.js +60 -0
- package/dist/legacy/hybrid-navigator.d.ts +138 -0
- package/dist/legacy/hybrid-navigator.js +468 -0
- package/dist/legacy/llm-usage.d.ts +17 -0
- package/dist/legacy/llm-usage.js +45 -0
- package/dist/legacy/prompt-cache.d.ts +10 -0
- package/dist/legacy/prompt-cache.js +24 -0
- package/dist/legacy/prompts.d.ts +175 -0
- package/dist/legacy/prompts.js +1038 -0
- package/dist/legacy/tools.d.ts +4 -0
- package/dist/legacy/tools.js +216 -0
- package/dist/legacy/video-agent.d.ts +143 -0
- package/dist/legacy/video-agent.js +4788 -0
- package/dist/legacy/video-observation.d.ts +36 -0
- package/dist/legacy/video-observation.js +192 -0
- package/dist/legacy/video-planner.d.ts +12 -0
- package/dist/legacy/video-planner.js +501 -0
- package/dist/legacy/video-prompts.d.ts +37 -0
- package/dist/legacy/video-prompts.js +569 -0
- package/dist/legacy/video-tools.d.ts +3 -0
- package/dist/legacy/video-tools.js +59 -0
- package/dist/legacy/video-variant-state.d.ts +29 -0
- package/dist/legacy/video-variant-state.js +80 -0
- package/dist/legacy/vision-model.d.ts +17 -0
- package/dist/legacy/vision-model.js +74 -0
- package/dist/llm-healer.d.ts +63 -0
- package/dist/llm-healer.js +166 -0
- package/dist/llm-provider.d.ts +29 -0
- package/dist/llm-provider.js +80 -0
- package/dist/llm-usage.d.ts +17 -0
- package/dist/llm-usage.js +45 -0
- package/dist/logger.d.ts +6 -2
- package/dist/logger.js +15 -1
- package/dist/mockup-html.d.ts +119 -0
- package/dist/mockup-html.js +263 -0
- package/dist/mockup.d.ts +187 -0
- package/dist/mockup.js +869 -0
- package/dist/mouse-animation.d.ts +46 -0
- package/dist/mouse-animation.js +114 -0
- package/dist/opcode-actions.d.ts +42 -0
- package/dist/opcode-actions.js +511 -0
- package/dist/opcode-runner.d.ts +51 -0
- package/dist/opcode-runner.js +770 -0
- package/dist/openrouter-client.d.ts +40 -0
- package/dist/openrouter-client.js +16 -0
- package/dist/overlay-engine.d.ts +24 -0
- package/dist/overlay-engine.js +176 -0
- package/dist/overlay-utils.d.ts +14 -0
- package/dist/overlay-utils.js +13 -0
- package/dist/postcondition.d.ts +16 -0
- package/dist/postcondition.js +269 -0
- package/dist/posthog.d.ts +4 -0
- package/dist/posthog.js +26 -0
- package/dist/program-patcher.d.ts +25 -0
- package/dist/program-patcher.js +44 -0
- package/dist/prompt-cache.d.ts +10 -0
- package/dist/prompt-cache.js +24 -0
- package/dist/prompts.d.ts +175 -0
- package/dist/prompts.js +1038 -0
- package/dist/provider-config.d.ts +12 -0
- package/dist/provider-config.js +15 -0
- package/dist/recovery-chain.d.ts +37 -0
- package/dist/recovery-chain.js +350 -0
- package/dist/remote-browser.d.ts +215 -0
- package/dist/remote-browser.js +360 -0
- package/dist/safari-browser-bar.d.ts +15 -0
- package/dist/safari-browser-bar.js +95 -0
- package/dist/safari-toolbar-asset.d.ts +15 -0
- package/dist/safari-toolbar-asset.js +12 -0
- package/dist/security.d.ts +21 -0
- package/dist/security.js +608 -0
- package/dist/selector-resolver.d.ts +34 -0
- package/dist/selector-resolver.js +181 -0
- package/dist/semantic-resolver.d.ts +35 -0
- package/dist/semantic-resolver.js +161 -0
- package/dist/server-capture-runtime.d.ts +125 -0
- package/dist/server-capture-runtime.js +585 -0
- package/dist/server-credit-usage.d.ts +12 -0
- package/dist/server-credit-usage.js +41 -0
- package/dist/server-posthog.d.ts +2 -0
- package/dist/server-posthog.js +16 -0
- package/dist/server-project-webhooks.d.ts +59 -0
- package/dist/server-project-webhooks.js +123 -0
- package/dist/server-screenshot-watermark.d.ts +7 -0
- package/dist/server-screenshot-watermark.js +60 -0
- package/dist/session-profile.d.ts +86 -0
- package/dist/session-profile.js +1536 -0
- package/dist/sf-pro-fonts.d.ts +4 -0
- package/dist/sf-pro-fonts.js +7 -0
- package/dist/sf-pro-symbols.d.ts +1 -0
- package/dist/sf-pro-symbols.js +55 -0
- package/dist/skill-packaging.d.ts +28 -0
- package/dist/skill-packaging.js +169 -0
- package/dist/smart-wait.d.ts +27 -0
- package/dist/smart-wait.js +81 -0
- package/dist/status-bar-l10n.d.ts +14 -0
- package/dist/status-bar-l10n.js +177 -0
- package/dist/status-bar-render.d.ts +20 -0
- package/dist/status-bar-render.js +410 -0
- package/dist/status-bar.d.ts +53 -0
- package/dist/status-bar.js +620 -0
- package/dist/svg-browser-bar.d.ts +33 -0
- package/dist/svg-browser-bar.js +206 -0
- package/dist/svg-status-bar.d.ts +36 -0
- package/dist/svg-status-bar.js +597 -0
- package/dist/svg-text.d.ts +61 -0
- package/dist/svg-text.js +118 -0
- package/dist/tools.d.ts +4 -0
- package/dist/tools.js +216 -0
- package/dist/types.d.ts +240 -5
- package/dist/types.js +23 -1
- package/dist/v2/action-verifier.d.ts +29 -0
- package/dist/v2/action-verifier.js +133 -0
- package/dist/v2/alt-text.d.ts +26 -0
- package/dist/v2/alt-text.js +55 -0
- package/dist/v2/benchmark.d.ts +59 -0
- package/dist/v2/benchmark.js +135 -0
- package/dist/v2/capture-strategy.d.ts +30 -0
- package/dist/v2/capture-strategy.js +67 -0
- package/dist/v2/capture-verification.d.ts +35 -0
- package/dist/v2/capture-verification.js +95 -0
- package/dist/v2/circuit-breaker.d.ts +42 -0
- package/dist/v2/circuit-breaker.js +119 -0
- package/dist/v2/cli-runner-local.d.ts +11 -0
- package/dist/v2/cli-runner-local.js +91 -0
- package/dist/v2/cli-runner.d.ts +34 -0
- package/dist/v2/cli-runner.js +300 -0
- package/dist/v2/compiler-prompts.d.ts +27 -0
- package/dist/v2/compiler-prompts.js +123 -0
- package/dist/v2/compiler.d.ts +37 -0
- package/dist/v2/compiler.js +147 -0
- package/dist/v2/explorer.d.ts +41 -0
- package/dist/v2/explorer.js +56 -0
- package/dist/v2/index.d.ts +37 -0
- package/dist/v2/index.js +31 -0
- package/dist/v2/llm-healer.d.ts +62 -0
- package/dist/v2/llm-healer.js +166 -0
- package/dist/v2/llm-provider.d.ts +29 -0
- package/dist/v2/llm-provider.js +80 -0
- package/dist/v2/opcode-runner.d.ts +47 -0
- package/dist/v2/opcode-runner.js +634 -0
- package/dist/v2/overlay-engine.d.ts +24 -0
- package/dist/v2/overlay-engine.js +150 -0
- package/dist/v2/postcondition.d.ts +16 -0
- package/dist/v2/postcondition.js +249 -0
- package/dist/v2/program-patcher.d.ts +25 -0
- package/dist/v2/program-patcher.js +44 -0
- package/dist/v2/recovery-chain.d.ts +30 -0
- package/dist/v2/recovery-chain.js +368 -0
- package/dist/v2/schema.d.ts +2580 -0
- package/dist/v2/schema.js +295 -0
- package/dist/v2/selector-resolver.d.ts +34 -0
- package/dist/v2/selector-resolver.js +181 -0
- package/dist/v2/semantic-resolver.d.ts +35 -0
- package/dist/v2/semantic-resolver.js +161 -0
- package/dist/v2/smart-wait.d.ts +27 -0
- package/dist/v2/smart-wait.js +81 -0
- package/dist/v2/types.d.ts +444 -0
- package/dist/v2/types.js +19 -0
- package/dist/v2/web-playwright-local.d.ts +69 -0
- package/dist/v2/web-playwright-local.js +392 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +5 -0
- package/dist/video-agent.d.ts +143 -0
- package/dist/video-agent.js +4788 -0
- package/dist/video-observation.d.ts +36 -0
- package/dist/video-observation.js +192 -0
- package/dist/video-planner.d.ts +12 -0
- package/dist/video-planner.js +501 -0
- package/dist/video-prompts.d.ts +37 -0
- package/dist/video-prompts.js +554 -0
- package/dist/video-tools.d.ts +3 -0
- package/dist/video-tools.js +59 -0
- package/dist/video-variant-state.d.ts +29 -0
- package/dist/video-variant-state.js +80 -0
- package/dist/vision-model.d.ts +17 -0
- package/dist/vision-model.js +74 -0
- package/dist/web-playwright-local.d.ts +126 -0
- package/dist/web-playwright-local.js +819 -0
- package/dist/ws-auth.d.ts +20 -0
- package/dist/ws-auth.js +70 -0
- package/dist/ws-broadcast.d.ts +34 -0
- package/dist/ws-broadcast.js +85 -0
- package/dist/ws-connection-limits.d.ts +12 -0
- package/dist/ws-connection-limits.js +44 -0
- package/dist/ws-handler-utils.d.ts +32 -0
- package/dist/ws-handler-utils.js +139 -0
- package/dist/ws-handler.d.ts +10 -0
- package/dist/ws-handler.js +1793 -0
- package/dist/ws-metrics-server.d.ts +9 -0
- package/dist/ws-metrics-server.js +31 -0
- package/dist/ws-server.d.ts +9 -0
- package/dist/ws-server.js +92 -0
- package/package.json +142 -71
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
2
|
+
export interface ScreenshotSelectorMemoryUpdate {
|
|
3
|
+
stepSignature: string;
|
|
4
|
+
selector: string;
|
|
5
|
+
source: 'agent' | 'deterministic' | 'manual';
|
|
6
|
+
success: boolean;
|
|
7
|
+
}
|
|
8
|
+
/** Map a viewport width to a device category for selector memory scoping. */
|
|
9
|
+
export declare function getViewportCategory(width: number): 'mobile' | 'tablet' | 'desktop';
|
|
10
|
+
export declare function loadScreenshotSelectorMemory(supabase: SupabaseClient, params: {
|
|
11
|
+
projectId: string | null;
|
|
12
|
+
presetId?: string | null;
|
|
13
|
+
domain: string;
|
|
14
|
+
lang: string;
|
|
15
|
+
theme: 'light' | 'dark';
|
|
16
|
+
/** Optional viewport width — when provided, filters selectors by viewport category. */
|
|
17
|
+
viewportWidth?: number | null;
|
|
18
|
+
}): Promise<Record<string, string[]>>;
|
|
19
|
+
export declare function persistScreenshotSelectorMemoryUpdates(supabase: SupabaseClient, params: {
|
|
20
|
+
projectId: string | null;
|
|
21
|
+
presetId?: string | null;
|
|
22
|
+
domain: string;
|
|
23
|
+
lang: string;
|
|
24
|
+
theme: 'light' | 'dark';
|
|
25
|
+
viewportWidth?: number | null;
|
|
26
|
+
}, updates: ScreenshotSelectorMemoryUpdate[]): Promise<void>;
|
|
27
|
+
export declare function extractSelectorUpdates(actions: Array<{
|
|
28
|
+
action: string;
|
|
29
|
+
params: Record<string, unknown>;
|
|
30
|
+
success: boolean;
|
|
31
|
+
}>): ScreenshotSelectorMemoryUpdate[];
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
const GENERIC_NAV_TOKENS = new Set([
|
|
2
|
+
'page',
|
|
3
|
+
'pages',
|
|
4
|
+
'open',
|
|
5
|
+
'view',
|
|
6
|
+
'link',
|
|
7
|
+
'button',
|
|
8
|
+
'click',
|
|
9
|
+
'menu',
|
|
10
|
+
'nav',
|
|
11
|
+
'navigation',
|
|
12
|
+
'section',
|
|
13
|
+
'screen',
|
|
14
|
+
'capture',
|
|
15
|
+
'prepare',
|
|
16
|
+
'show',
|
|
17
|
+
'the',
|
|
18
|
+
'and',
|
|
19
|
+
'for',
|
|
20
|
+
'with',
|
|
21
|
+
]);
|
|
22
|
+
const INTERNAL_AUTOMATION_SELECTOR_RE = /\[data-ak-[^\]]+\]|data-ak-interactive-index/i;
|
|
23
|
+
function containsInternalAutomationSelector(selector) {
|
|
24
|
+
return !!selector && INTERNAL_AUTOMATION_SELECTOR_RE.test(selector);
|
|
25
|
+
}
|
|
26
|
+
function uniqueInOrder(values) {
|
|
27
|
+
const seen = new Set();
|
|
28
|
+
const result = [];
|
|
29
|
+
for (const value of values) {
|
|
30
|
+
if (seen.has(value))
|
|
31
|
+
continue;
|
|
32
|
+
seen.add(value);
|
|
33
|
+
result.push(value);
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
function normalizeNavigationTokens(values) {
|
|
38
|
+
const tokens = [];
|
|
39
|
+
for (const value of values) {
|
|
40
|
+
if (!value)
|
|
41
|
+
continue;
|
|
42
|
+
const parts = value
|
|
43
|
+
.toLowerCase()
|
|
44
|
+
.split(/[^a-z0-9]+/i)
|
|
45
|
+
.map((part) => part.trim())
|
|
46
|
+
.filter((part) => part.length >= 3 && part.length <= 32 && !GENERIC_NAV_TOKENS.has(part));
|
|
47
|
+
tokens.push(...parts);
|
|
48
|
+
}
|
|
49
|
+
return uniqueInOrder(tokens).slice(0, 8);
|
|
50
|
+
}
|
|
51
|
+
function extractPathTokens(rawUrl) {
|
|
52
|
+
if (!rawUrl)
|
|
53
|
+
return [];
|
|
54
|
+
try {
|
|
55
|
+
const url = new URL(rawUrl);
|
|
56
|
+
return normalizeNavigationTokens(url.pathname.split('/'));
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return normalizeNavigationTokens(rawUrl.split('/'));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** Map a viewport width to a device category for selector memory scoping. */
|
|
63
|
+
export function getViewportCategory(width) {
|
|
64
|
+
if (width < 768)
|
|
65
|
+
return 'mobile';
|
|
66
|
+
if (width < 1024)
|
|
67
|
+
return 'tablet';
|
|
68
|
+
return 'desktop';
|
|
69
|
+
}
|
|
70
|
+
export async function loadScreenshotSelectorMemory(supabase, params) {
|
|
71
|
+
const selectFields = 'step_signature, selector, confidence, last_success_at';
|
|
72
|
+
const grouped = {};
|
|
73
|
+
const appendRows = (rows) => {
|
|
74
|
+
for (const row of rows) {
|
|
75
|
+
const signature = String(row.step_signature ?? '').trim();
|
|
76
|
+
const selector = String(row.selector ?? '').trim();
|
|
77
|
+
if (!signature || !selector)
|
|
78
|
+
continue;
|
|
79
|
+
if (!grouped[signature])
|
|
80
|
+
grouped[signature] = [];
|
|
81
|
+
if (!grouped[signature].includes(selector)) {
|
|
82
|
+
grouped[signature].push(selector);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const viewportCategory = params.viewportWidth
|
|
87
|
+
? getViewportCategory(params.viewportWidth)
|
|
88
|
+
: null;
|
|
89
|
+
if (params.presetId) {
|
|
90
|
+
let query = supabase
|
|
91
|
+
.from('screenshot_step_memory')
|
|
92
|
+
.select(selectFields)
|
|
93
|
+
.eq('domain', params.domain)
|
|
94
|
+
.eq('preset_id', params.presetId)
|
|
95
|
+
.eq('lang', params.lang)
|
|
96
|
+
.eq('theme', params.theme)
|
|
97
|
+
.order('confidence', { ascending: false })
|
|
98
|
+
.order('last_success_at', { ascending: false })
|
|
99
|
+
.limit(200);
|
|
100
|
+
if (params.projectId) {
|
|
101
|
+
query = query.eq('project_id', params.projectId);
|
|
102
|
+
}
|
|
103
|
+
if (viewportCategory) {
|
|
104
|
+
query = query.or(`viewport_category.eq.${viewportCategory},viewport_category.is.null`);
|
|
105
|
+
}
|
|
106
|
+
const { data } = await query;
|
|
107
|
+
if (data && data.length > 0) {
|
|
108
|
+
appendRows(data);
|
|
109
|
+
return grouped;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
let fallbackQuery = supabase
|
|
113
|
+
.from('screenshot_step_memory')
|
|
114
|
+
.select(selectFields)
|
|
115
|
+
.eq('domain', params.domain)
|
|
116
|
+
.order('confidence', { ascending: false })
|
|
117
|
+
.order('last_success_at', { ascending: false })
|
|
118
|
+
.limit(200);
|
|
119
|
+
if (params.projectId) {
|
|
120
|
+
fallbackQuery = fallbackQuery.eq('project_id', params.projectId);
|
|
121
|
+
}
|
|
122
|
+
if (viewportCategory) {
|
|
123
|
+
fallbackQuery = fallbackQuery.or(`viewport_category.eq.${viewportCategory},viewport_category.is.null`);
|
|
124
|
+
}
|
|
125
|
+
const { data: fallbackData } = await fallbackQuery;
|
|
126
|
+
if (fallbackData) {
|
|
127
|
+
appendRows(fallbackData);
|
|
128
|
+
}
|
|
129
|
+
return grouped;
|
|
130
|
+
}
|
|
131
|
+
export async function persistScreenshotSelectorMemoryUpdates(supabase, params, updates) {
|
|
132
|
+
const nowIso = new Date().toISOString();
|
|
133
|
+
const uniqueUpdates = new Map();
|
|
134
|
+
for (const update of updates) {
|
|
135
|
+
if (!update.stepSignature || !update.selector)
|
|
136
|
+
continue;
|
|
137
|
+
const key = `${update.stepSignature}|${update.selector}|${update.source}`;
|
|
138
|
+
uniqueUpdates.set(key, update);
|
|
139
|
+
}
|
|
140
|
+
for (const update of uniqueUpdates.values()) {
|
|
141
|
+
const baseQuery = supabase
|
|
142
|
+
.from('screenshot_step_memory')
|
|
143
|
+
.select('id, success_count, fail_count, confidence')
|
|
144
|
+
.eq('domain', params.domain)
|
|
145
|
+
.eq('step_signature', update.stepSignature)
|
|
146
|
+
.eq('selector', update.selector)
|
|
147
|
+
.eq('lang', params.lang)
|
|
148
|
+
.eq('theme', params.theme)
|
|
149
|
+
.limit(1);
|
|
150
|
+
const scopedQuery = params.presetId
|
|
151
|
+
? baseQuery.eq('preset_id', params.presetId)
|
|
152
|
+
: baseQuery.is('preset_id', null);
|
|
153
|
+
const projectScopedQuery = params.projectId
|
|
154
|
+
? scopedQuery.eq('project_id', params.projectId)
|
|
155
|
+
: scopedQuery.is('project_id', null);
|
|
156
|
+
const { data: existingRows } = await projectScopedQuery;
|
|
157
|
+
const existing = existingRows?.[0];
|
|
158
|
+
if (!existing) {
|
|
159
|
+
await supabase.from('screenshot_step_memory').insert({
|
|
160
|
+
project_id: params.projectId,
|
|
161
|
+
preset_id: params.presetId ?? null,
|
|
162
|
+
domain: params.domain,
|
|
163
|
+
lang: params.lang,
|
|
164
|
+
theme: params.theme,
|
|
165
|
+
viewport_category: params.viewportWidth ? getViewportCategory(params.viewportWidth) : null,
|
|
166
|
+
step_signature: update.stepSignature,
|
|
167
|
+
selector: update.selector,
|
|
168
|
+
source: update.source,
|
|
169
|
+
success_count: update.success ? 1 : 0,
|
|
170
|
+
fail_count: update.success ? 0 : 1,
|
|
171
|
+
confidence: update.success ? 0.65 : 0.35,
|
|
172
|
+
last_success_at: update.success ? nowIso : null,
|
|
173
|
+
last_failure_at: update.success ? null : nowIso,
|
|
174
|
+
});
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
const successCount = (existing.success_count ?? 0) + (update.success ? 1 : 0);
|
|
178
|
+
const failCount = (existing.fail_count ?? 0) + (update.success ? 0 : 1);
|
|
179
|
+
const currentConfidence = existing.confidence ?? 0.5;
|
|
180
|
+
const confidence = update.success
|
|
181
|
+
? Math.min(0.98, currentConfidence + 0.08)
|
|
182
|
+
: Math.max(0.05, currentConfidence - 0.12);
|
|
183
|
+
await supabase
|
|
184
|
+
.from('screenshot_step_memory')
|
|
185
|
+
.update({
|
|
186
|
+
success_count: successCount,
|
|
187
|
+
fail_count: failCount,
|
|
188
|
+
confidence,
|
|
189
|
+
last_success_at: update.success ? nowIso : undefined,
|
|
190
|
+
last_failure_at: update.success ? undefined : nowIso,
|
|
191
|
+
})
|
|
192
|
+
.eq('id', existing.id);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
export function extractSelectorUpdates(actions) {
|
|
196
|
+
const updates = [];
|
|
197
|
+
const languageAliases = {
|
|
198
|
+
en: ['en', 'english'],
|
|
199
|
+
fr: ['fr', 'french', 'francais', 'français'],
|
|
200
|
+
de: ['de', 'german', 'deutsch'],
|
|
201
|
+
es: ['es', 'spanish', 'espanol', 'español'],
|
|
202
|
+
it: ['it', 'italian', 'italiano'],
|
|
203
|
+
pt: ['pt', 'portuguese', 'portugues', 'português'],
|
|
204
|
+
};
|
|
205
|
+
for (const action of actions) {
|
|
206
|
+
if (action.action !== 'click'
|
|
207
|
+
&& action.action !== 'type_text'
|
|
208
|
+
&& action.action !== 'safe_expand'
|
|
209
|
+
&& action.action !== 'select_option') {
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
const selector = action.params.selector
|
|
213
|
+
?? action.params.resolvedSelector
|
|
214
|
+
?? (action.params.index !== undefined ? `[index:${action.params.index}]` : null);
|
|
215
|
+
if (!selector || selector.startsWith('[index:') || containsInternalAutomationSelector(selector)) {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
const text = String(action.params.text ?? '').toLowerCase();
|
|
219
|
+
const label = String(action.params.elementLabel ?? '').toLowerCase();
|
|
220
|
+
const optionLabel = String(action.params.optionLabel ?? '').toLowerCase();
|
|
221
|
+
const optionValue = String(action.params.optionValue ?? '').toLowerCase();
|
|
222
|
+
const href = String(action.params.href ?? '').toLowerCase();
|
|
223
|
+
const selectorLower = selector.toLowerCase();
|
|
224
|
+
const combined = `${selectorLower} ${text} ${label} ${optionLabel} ${optionValue} ${href}`;
|
|
225
|
+
if (combined.includes('login')
|
|
226
|
+
|| combined.includes('sign in')
|
|
227
|
+
|| combined.includes('signin')
|
|
228
|
+
|| combined.includes('password')
|
|
229
|
+
|| combined.includes('email')
|
|
230
|
+
|| combined.includes('auth')) {
|
|
231
|
+
updates.push({
|
|
232
|
+
stepSignature: action.action === 'type_text'
|
|
233
|
+
? combined.includes('password')
|
|
234
|
+
? 'login:password_field'
|
|
235
|
+
: 'login:email_field'
|
|
236
|
+
: 'login:submit',
|
|
237
|
+
selector,
|
|
238
|
+
source: 'agent',
|
|
239
|
+
success: action.success,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
if (action.action === 'type_text'
|
|
243
|
+
&& (combined.includes('search') || combined.includes('query'))) {
|
|
244
|
+
updates.push({
|
|
245
|
+
stepSignature: 'search:field',
|
|
246
|
+
selector,
|
|
247
|
+
source: 'agent',
|
|
248
|
+
success: action.success,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
if ((action.action === 'click' || action.action === 'safe_expand')
|
|
252
|
+
&& (combined.includes('menu') || combined.includes('navigation') || combined.includes('hamburger') || combined.includes('drawer'))) {
|
|
253
|
+
updates.push({
|
|
254
|
+
stepSignature: 'menu:primary',
|
|
255
|
+
selector,
|
|
256
|
+
source: 'agent',
|
|
257
|
+
success: action.success,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
if ((action.action === 'click' || action.action === 'safe_expand')
|
|
261
|
+
&& (combined.includes('account') || combined.includes('profile') || combined.includes('avatar') || combined.includes('user'))) {
|
|
262
|
+
updates.push({
|
|
263
|
+
stepSignature: 'account:menu',
|
|
264
|
+
selector,
|
|
265
|
+
source: 'agent',
|
|
266
|
+
success: action.success,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
const languageLike = combined.includes('lang')
|
|
270
|
+
|| combined.includes('locale')
|
|
271
|
+
|| combined.includes('language')
|
|
272
|
+
|| Object.values(languageAliases).some((aliases) => aliases.some((alias) => combined.includes(alias)));
|
|
273
|
+
if (languageLike) {
|
|
274
|
+
updates.push({
|
|
275
|
+
stepSignature: 'lang:switcher',
|
|
276
|
+
selector,
|
|
277
|
+
source: 'agent',
|
|
278
|
+
success: action.success,
|
|
279
|
+
});
|
|
280
|
+
for (const [langCode, aliases] of Object.entries(languageAliases)) {
|
|
281
|
+
if (aliases.some((alias) => combined.includes(alias))) {
|
|
282
|
+
updates.push({
|
|
283
|
+
stepSignature: `lang:option:${langCode}`,
|
|
284
|
+
selector,
|
|
285
|
+
source: 'agent',
|
|
286
|
+
success: action.success,
|
|
287
|
+
});
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
if (action.action === 'click' || action.action === 'safe_expand' || action.action === 'select_option') {
|
|
293
|
+
for (const token of extractPathTokens(String(action.params.href ?? '')).slice(0, 4)) {
|
|
294
|
+
updates.push({
|
|
295
|
+
stepSignature: `nav:path:${token}`,
|
|
296
|
+
selector,
|
|
297
|
+
source: 'agent',
|
|
298
|
+
success: action.success,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
for (const token of normalizeNavigationTokens([
|
|
302
|
+
action.params.elementLabel,
|
|
303
|
+
action.params.optionLabel,
|
|
304
|
+
]).slice(0, 4)) {
|
|
305
|
+
updates.push({
|
|
306
|
+
stepSignature: `nav:label:${token}`,
|
|
307
|
+
selector,
|
|
308
|
+
source: 'agent',
|
|
309
|
+
success: action.success,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
const themeLike = combined.includes('theme')
|
|
314
|
+
|| combined.includes('appearance')
|
|
315
|
+
|| combined.includes('dark')
|
|
316
|
+
|| combined.includes('light')
|
|
317
|
+
|| combined.includes('mode');
|
|
318
|
+
if (themeLike) {
|
|
319
|
+
updates.push({
|
|
320
|
+
stepSignature: 'theme:toggle',
|
|
321
|
+
selector,
|
|
322
|
+
source: 'agent',
|
|
323
|
+
success: action.success,
|
|
324
|
+
});
|
|
325
|
+
if (combined.includes('dark')) {
|
|
326
|
+
updates.push({
|
|
327
|
+
stepSignature: 'theme:option:dark',
|
|
328
|
+
selector,
|
|
329
|
+
source: 'agent',
|
|
330
|
+
success: action.success,
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
if (combined.includes('light')) {
|
|
334
|
+
updates.push({
|
|
335
|
+
stepSignature: 'theme:option:light',
|
|
336
|
+
selector,
|
|
337
|
+
source: 'agent',
|
|
338
|
+
success: action.success,
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return updates;
|
|
344
|
+
}
|
|
345
|
+
//# sourceMappingURL=capture-selector-memory.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { decrypt, encrypt, isEncryptedEnvelope } from './capture-encryption.js';
|
|
2
|
+
function getSecret() {
|
|
3
|
+
const secret = process.env.SESSION_PROFILE_ENCRYPTION_SECRET;
|
|
4
|
+
if (!secret) {
|
|
5
|
+
throw new Error('Missing SESSION_PROFILE_ENCRYPTION_SECRET for session profile encryption');
|
|
6
|
+
}
|
|
7
|
+
return secret;
|
|
8
|
+
}
|
|
9
|
+
export function encryptSessionField(value) {
|
|
10
|
+
if (!value)
|
|
11
|
+
return value;
|
|
12
|
+
return encrypt(JSON.stringify(value), getSecret());
|
|
13
|
+
}
|
|
14
|
+
export function decryptSessionField(value) {
|
|
15
|
+
if (!value)
|
|
16
|
+
return undefined;
|
|
17
|
+
if (isEncryptedEnvelope(value)) {
|
|
18
|
+
return JSON.parse(decrypt(value, getSecret()));
|
|
19
|
+
}
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=capture-session-profile-encryption.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare class CaptureStepTimeoutError extends Error {
|
|
2
|
+
readonly timeoutMs: number;
|
|
3
|
+
readonly stepLabel: string;
|
|
4
|
+
constructor(stepLabel: string, timeoutMs: number);
|
|
5
|
+
}
|
|
6
|
+
export declare function isCaptureStepTimeoutError(error: unknown): error is CaptureStepTimeoutError;
|
|
7
|
+
export declare function withCaptureStepTimeout<T>(work: () => Promise<T>, params: {
|
|
8
|
+
stepLabel: string;
|
|
9
|
+
timeoutMs: number;
|
|
10
|
+
}): Promise<T>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export class CaptureStepTimeoutError extends Error {
|
|
2
|
+
timeoutMs;
|
|
3
|
+
stepLabel;
|
|
4
|
+
constructor(stepLabel, timeoutMs) {
|
|
5
|
+
super(`Timed out after ${timeoutMs}ms while ${stepLabel}.`);
|
|
6
|
+
this.name = "CaptureStepTimeoutError";
|
|
7
|
+
this.stepLabel = stepLabel;
|
|
8
|
+
this.timeoutMs = timeoutMs;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function isCaptureStepTimeoutError(error) {
|
|
12
|
+
return error instanceof CaptureStepTimeoutError;
|
|
13
|
+
}
|
|
14
|
+
export async function withCaptureStepTimeout(work, params) {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
const timer = setTimeout(() => {
|
|
17
|
+
reject(new CaptureStepTimeoutError(params.stepLabel, params.timeoutMs));
|
|
18
|
+
}, params.timeoutMs);
|
|
19
|
+
void work()
|
|
20
|
+
.then((result) => {
|
|
21
|
+
clearTimeout(timer);
|
|
22
|
+
resolve(result);
|
|
23
|
+
})
|
|
24
|
+
.catch((error) => {
|
|
25
|
+
clearTimeout(timer);
|
|
26
|
+
reject(error);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=capture-step-timeout.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capture Agent — Capture Strategy
|
|
3
|
+
*
|
|
4
|
+
* Abstraction over the supported media modes: screenshot and clip.
|
|
5
|
+
* The opcode runner is identical for all three — only the capture
|
|
6
|
+
* opcodes dispatch to different strategies.
|
|
7
|
+
*/
|
|
8
|
+
import type { ArtifactSpec, ArtifactResult, RuntimeAdapter, MediaMode } from './execution-types.js';
|
|
9
|
+
export interface CaptureStrategy {
|
|
10
|
+
readonly mediaMode: MediaMode;
|
|
11
|
+
/** Prepare the adapter for capture (e.g. lock viewport, inject cursor overlay) */
|
|
12
|
+
prepare(adapter: RuntimeAdapter, spec: ArtifactSpec): Promise<void>;
|
|
13
|
+
/** Perform the capture and return the raw artifact */
|
|
14
|
+
capture(adapter: RuntimeAdapter, spec: ArtifactSpec): Promise<ArtifactResult>;
|
|
15
|
+
/** Post-process the artifact (mockup frame, status bar, format conversion) */
|
|
16
|
+
postProcess(artifact: ArtifactResult, spec: ArtifactSpec): Promise<ArtifactResult>;
|
|
17
|
+
}
|
|
18
|
+
export declare class ScreenshotStrategy implements CaptureStrategy {
|
|
19
|
+
readonly mediaMode: "screenshot";
|
|
20
|
+
prepare(_adapter: RuntimeAdapter, _spec: ArtifactSpec): Promise<void>;
|
|
21
|
+
capture(adapter: RuntimeAdapter, _spec: ArtifactSpec): Promise<ArtifactResult>;
|
|
22
|
+
postProcess(artifact: ArtifactResult, spec: ArtifactSpec): Promise<ArtifactResult>;
|
|
23
|
+
}
|
|
24
|
+
export declare class ClipStrategy implements CaptureStrategy {
|
|
25
|
+
readonly mediaMode: "clip";
|
|
26
|
+
prepare(adapter: RuntimeAdapter, _spec: ArtifactSpec): Promise<void>;
|
|
27
|
+
capture(adapter: RuntimeAdapter, _spec: ArtifactSpec): Promise<ArtifactResult>;
|
|
28
|
+
postProcess(artifact: ArtifactResult, spec: ArtifactSpec): Promise<ArtifactResult>;
|
|
29
|
+
}
|
|
30
|
+
export declare class DomStrategy implements CaptureStrategy {
|
|
31
|
+
readonly mediaMode: "dom";
|
|
32
|
+
prepare(_adapter: RuntimeAdapter, _spec: ArtifactSpec): Promise<void>;
|
|
33
|
+
capture(adapter: RuntimeAdapter, _spec: ArtifactSpec): Promise<ArtifactResult>;
|
|
34
|
+
postProcess(artifact: ArtifactResult, _spec: ArtifactSpec): Promise<ArtifactResult>;
|
|
35
|
+
}
|
|
36
|
+
export declare function createCaptureStrategy(mediaMode: MediaMode): CaptureStrategy;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capture Agent — Capture Strategy
|
|
3
|
+
*
|
|
4
|
+
* Abstraction over the supported media modes: screenshot and clip.
|
|
5
|
+
* The opcode runner is identical for all three — only the capture
|
|
6
|
+
* opcodes dispatch to different strategies.
|
|
7
|
+
*/
|
|
8
|
+
// ── Screenshot strategy ─────────────────────────────────────────────
|
|
9
|
+
export class ScreenshotStrategy {
|
|
10
|
+
mediaMode = 'screenshot';
|
|
11
|
+
async prepare(_adapter, _spec) {
|
|
12
|
+
// Viewport locking is handled externally by the CLI runner
|
|
13
|
+
// when creating the browser context per variant.
|
|
14
|
+
}
|
|
15
|
+
async capture(adapter, _spec) {
|
|
16
|
+
const buffer = await adapter.takeScreenshot();
|
|
17
|
+
return {
|
|
18
|
+
mediaMode: 'screenshot',
|
|
19
|
+
buffer,
|
|
20
|
+
mimeType: 'image/png',
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
async postProcess(artifact, spec) {
|
|
24
|
+
// Post-processing (mockup frame, status bar) will be applied
|
|
25
|
+
// by the CLI runner using existing utilities:
|
|
26
|
+
// - applyDeviceFrame() from src/mockup.ts
|
|
27
|
+
// - generateStatusBarHtml() from src/status-bar.ts
|
|
28
|
+
// For now, return as-is. Phase 4 CLI runner handles the orchestration.
|
|
29
|
+
return artifact;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// ── Clip strategy ───────────────────────────────────────────────────
|
|
33
|
+
export class ClipStrategy {
|
|
34
|
+
mediaMode = 'clip';
|
|
35
|
+
async prepare(adapter, _spec) {
|
|
36
|
+
// Clip recording preparation:
|
|
37
|
+
// - The browser context is created with video recording enabled
|
|
38
|
+
// - Cursor overlay is injected by Browser.forVideoRecording()
|
|
39
|
+
}
|
|
40
|
+
async capture(adapter, _spec) {
|
|
41
|
+
// Clip capture is bounded by BEGIN_CLIP / END_CLIP opcodes.
|
|
42
|
+
// The opcode runner calls adapter.beginRecording() and adapter.endRecording().
|
|
43
|
+
// This method is called for the final artifact assembly.
|
|
44
|
+
const recording = await adapter.endRecording();
|
|
45
|
+
return {
|
|
46
|
+
mediaMode: 'clip',
|
|
47
|
+
buffer: recording.buffer,
|
|
48
|
+
mimeType: recording.mimeType,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
async postProcess(artifact, spec) {
|
|
52
|
+
// Post-processing for clips:
|
|
53
|
+
// - Convert WebM to GIF/MP4 via src/clip-postprocess.ts (if it exists)
|
|
54
|
+
// - Trim start/end
|
|
55
|
+
// - Apply cursor theme
|
|
56
|
+
// Handled by CLI runner using existing video processing utilities.
|
|
57
|
+
return artifact;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// ── DOM strategy (Interactive Demos — AUT-121) ──────────────────────
|
|
61
|
+
export class DomStrategy {
|
|
62
|
+
mediaMode = 'dom';
|
|
63
|
+
async prepare(_adapter, _spec) {
|
|
64
|
+
// Nothing to prepare — DOM serialization happens inline in the
|
|
65
|
+
// CAPTURE_DOM opcode handler in opcode-runner.ts.
|
|
66
|
+
}
|
|
67
|
+
async capture(adapter, _spec) {
|
|
68
|
+
if (!adapter.serializeDom) {
|
|
69
|
+
throw new Error('DOM capture requires an adapter that implements serializeDom()');
|
|
70
|
+
}
|
|
71
|
+
const result = await adapter.serializeDom();
|
|
72
|
+
return {
|
|
73
|
+
mediaMode: 'dom',
|
|
74
|
+
buffer: Buffer.from(result.html, 'utf8'),
|
|
75
|
+
mimeType: 'text/html; charset=utf-8',
|
|
76
|
+
domHtml: result.html,
|
|
77
|
+
domAssetUrls: result.assetUrls,
|
|
78
|
+
domHtmlBytes: result.html.length,
|
|
79
|
+
dimensions: result.viewport,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
async postProcess(artifact, _spec) {
|
|
83
|
+
// Phase 3 will add asset extraction (CAS), PurgeCSS and Brotli here.
|
|
84
|
+
return artifact;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// ── Factory ─────────────────────────────────────────────────────────
|
|
88
|
+
export function createCaptureStrategy(mediaMode) {
|
|
89
|
+
switch (mediaMode) {
|
|
90
|
+
case 'screenshot': return new ScreenshotStrategy();
|
|
91
|
+
case 'clip': return new ClipStrategy();
|
|
92
|
+
case 'dom': return new DomStrategy();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=capture-strategy.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
2
|
+
type StudioBrowserBarConfig = {
|
|
3
|
+
url?: string;
|
|
4
|
+
pageTitle?: string;
|
|
5
|
+
tabIconUrl?: string;
|
|
6
|
+
} | null | undefined;
|
|
7
|
+
export declare function syncStudioVariantAfterCapture(params: {
|
|
8
|
+
supabase: SupabaseClient;
|
|
9
|
+
projectId: string;
|
|
10
|
+
presetId: string;
|
|
11
|
+
targetId?: string | null;
|
|
12
|
+
lang: string;
|
|
13
|
+
theme: string;
|
|
14
|
+
elementName: string | null;
|
|
15
|
+
captureId: string;
|
|
16
|
+
screenshotUrl: string | null;
|
|
17
|
+
rawScreenshotUrl?: string | null;
|
|
18
|
+
deviceFrame?: string | null;
|
|
19
|
+
orientation?: 'portrait' | 'landscape' | null;
|
|
20
|
+
browserBar?: StudioBrowserBarConfig;
|
|
21
|
+
matchTargetId?: boolean;
|
|
22
|
+
}): Promise<void>;
|
|
23
|
+
export {};
|