autokap 1.0.7 → 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/cursors/macos.svg +4 -0
- package/assets/cursors/windows.svg +15 -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/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 +92 -8
- package/dist/agent.js +2936 -781
- 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/browser-bar.d.ts +14 -6
- package/dist/browser-bar.js +145 -8
- 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 +51 -1
- package/dist/browser.js +1481 -31
- package/dist/capture-alt-text.js +2 -1
- package/dist/capture-language-preflight.js +14 -0
- package/dist/capture-llm-page-identity.js +22 -10
- package/dist/capture-page-identity.d.ts +5 -7
- package/dist/capture-page-identity.js +211 -78
- package/dist/capture-preset-credentials.d.ts +50 -0
- package/dist/capture-preset-credentials.js +127 -0
- package/dist/capture-request-plan.d.ts +2 -2
- package/dist/capture-request-plan.js +64 -16
- package/dist/capture-run-optimizer.js +48 -33
- package/dist/capture-selector-memory.d.ts +5 -0
- package/dist/capture-selector-memory.js +18 -0
- package/dist/capture-strategy.d.ts +36 -0
- package/dist/capture-strategy.js +95 -0
- package/dist/capture-studio-sync.d.ts +1 -0
- package/dist/capture-studio-sync.js +9 -3
- 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 +2 -0
- package/dist/capture-variant-state.js +26 -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 -267
- package/dist/clip-orchestrator.js +9 -2
- package/dist/clip-postprocess.js +25 -16
- package/dist/cookie-dismiss.d.ts +2 -0
- package/dist/cookie-dismiss.js +48 -13
- package/dist/cost-logging.d.ts +8 -0
- package/dist/cost-logging.js +160 -46
- package/dist/cost-resolution-monitor.d.ts +16 -0
- package/dist/cost-resolution-monitor.js +34 -0
- package/dist/credential-templates.js +2 -2
- 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 +1 -41
- package/dist/element-capture.js +202 -446
- 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.js +12 -12
- package/dist/index.d.ts +9 -6
- package/dist/index.js +10 -4
- 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/logger.d.ts +6 -2
- package/dist/logger.js +15 -1
- package/dist/mockup-html.js +35 -25
- package/dist/mockup.d.ts +95 -2
- package/dist/mockup.js +427 -166
- package/dist/mouse-animation.d.ts +2 -2
- package/dist/mouse-animation.js +34 -20
- 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/postcondition.d.ts +16 -0
- package/dist/postcondition.js +269 -0
- package/dist/program-patcher.d.ts +25 -0
- package/dist/program-patcher.js +44 -0
- package/dist/prompts.d.ts +13 -5
- package/dist/prompts.js +224 -351
- 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 +28 -4
- package/dist/remote-browser.js +60 -5
- 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 +2 -1
- package/dist/security.js +49 -10
- 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 +5 -3
- package/dist/server-capture-runtime.js +42 -95
- package/dist/server-credit-usage.d.ts +2 -2
- package/dist/server-project-webhooks.d.ts +15 -1
- package/dist/server-project-webhooks.js +34 -8
- package/dist/server-screenshot-watermark.js +27 -5
- package/dist/session-profile.js +164 -1
- 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-render.d.ts +20 -0
- package/dist/status-bar-render.js +410 -0
- package/dist/status-bar.d.ts +9 -0
- package/dist/status-bar.js +298 -14
- 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.js +89 -451
- 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.js +18 -13
- package/dist/video-planner.js +2 -1
- package/dist/video-prompts.js +3 -3
- package/dist/web-playwright-local.d.ts +126 -0
- package/dist/web-playwright-local.js +819 -0
- package/dist/ws-auth.js +4 -1
- 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.js +294 -164
- package/dist/ws-metrics-server.d.ts +9 -0
- package/dist/ws-metrics-server.js +31 -0
- package/dist/ws-server.js +41 -1
- package/package.json +51 -34
package/dist/session-profile.js
CHANGED
|
@@ -29,6 +29,10 @@ const LANGUAGE_ALIASES = {
|
|
|
29
29
|
tr: ['tr', 'turkish', 'turkce', 'türkçe'],
|
|
30
30
|
zh: ['zh', 'chinese', '中文'],
|
|
31
31
|
};
|
|
32
|
+
const THEME_ALIASES = {
|
|
33
|
+
light: ['light', 'clair', 'claro', 'chiaro'],
|
|
34
|
+
dark: ['dark', 'sombre', 'oscuro', 'scuro'],
|
|
35
|
+
};
|
|
32
36
|
function makeDiagnostic(outcome, confidence, reasons) {
|
|
33
37
|
return {
|
|
34
38
|
outcome,
|
|
@@ -965,6 +969,44 @@ function languageTerms(requestedLang) {
|
|
|
965
969
|
return [];
|
|
966
970
|
return LANGUAGE_ALIASES[normalized] ?? [normalized];
|
|
967
971
|
}
|
|
972
|
+
function themeTerms(requestedTheme) {
|
|
973
|
+
const normalized = requestedTheme.toLowerCase();
|
|
974
|
+
if (normalized === 'light' || normalized === 'dark') {
|
|
975
|
+
return THEME_ALIASES[normalized];
|
|
976
|
+
}
|
|
977
|
+
return [requestedTheme];
|
|
978
|
+
}
|
|
979
|
+
function variantTerms(kind, target) {
|
|
980
|
+
return kind === 'locale' ? languageTerms(target) : themeTerms(target);
|
|
981
|
+
}
|
|
982
|
+
function normalizeSearchToken(value) {
|
|
983
|
+
return value
|
|
984
|
+
.normalize('NFKD')
|
|
985
|
+
.replace(/\p{Diacritic}/gu, '')
|
|
986
|
+
.replace(/\s+/g, ' ')
|
|
987
|
+
.trim()
|
|
988
|
+
.toLowerCase();
|
|
989
|
+
}
|
|
990
|
+
function buildVariantSearchQueries(kind, target) {
|
|
991
|
+
const seen = new Set();
|
|
992
|
+
return variantTerms(kind, target)
|
|
993
|
+
.map((term) => term.trim())
|
|
994
|
+
.filter(Boolean)
|
|
995
|
+
.sort((left, right) => {
|
|
996
|
+
const leftShort = normalizeSearchToken(left).length <= 2 ? 1 : 0;
|
|
997
|
+
const rightShort = normalizeSearchToken(right).length <= 2 ? 1 : 0;
|
|
998
|
+
if (leftShort !== rightShort)
|
|
999
|
+
return leftShort - rightShort;
|
|
1000
|
+
return right.length - left.length;
|
|
1001
|
+
})
|
|
1002
|
+
.filter((term) => {
|
|
1003
|
+
const normalized = normalizeSearchToken(term);
|
|
1004
|
+
if (!normalized || seen.has(normalized))
|
|
1005
|
+
return false;
|
|
1006
|
+
seen.add(normalized);
|
|
1007
|
+
return true;
|
|
1008
|
+
});
|
|
1009
|
+
}
|
|
968
1010
|
function controlMatchesVariant(control, kind, target) {
|
|
969
1011
|
if (control.kind !== kind)
|
|
970
1012
|
return false;
|
|
@@ -983,6 +1025,17 @@ async function applyVariantSelector(browser, selector, params) {
|
|
|
983
1025
|
const probe = await probeSelector(browser, selector);
|
|
984
1026
|
if (!probe)
|
|
985
1027
|
return false;
|
|
1028
|
+
const probeControl = {
|
|
1029
|
+
kind: params.kind,
|
|
1030
|
+
mechanism: 'button',
|
|
1031
|
+
selector,
|
|
1032
|
+
label: probe.label,
|
|
1033
|
+
value: null,
|
|
1034
|
+
href: probe.href,
|
|
1035
|
+
tag: probe.tag,
|
|
1036
|
+
role: probe.role,
|
|
1037
|
+
};
|
|
1038
|
+
const isDirectTarget = controlMatchesVariant(probeControl, params.kind, params.target);
|
|
986
1039
|
if (probe.tag === 'select') {
|
|
987
1040
|
const optionLabel = params.kind === 'locale'
|
|
988
1041
|
? languageTerms(params.target)[0] ?? params.target
|
|
@@ -1010,7 +1063,8 @@ async function applyVariantSelector(browser, selector, params) {
|
|
|
1010
1063
|
await browser.clickBySelector(selector);
|
|
1011
1064
|
return true;
|
|
1012
1065
|
}
|
|
1013
|
-
if (
|
|
1066
|
+
if (!isDirectTarget
|
|
1067
|
+
&& (LANG_CONTROL_RE.test(`${probe.label} ${selector}`) || THEME_CONTROL_RE.test(`${probe.label} ${selector}`))) {
|
|
1014
1068
|
await browser.safeExpand({ selector });
|
|
1015
1069
|
return true;
|
|
1016
1070
|
}
|
|
@@ -1057,6 +1111,87 @@ async function trySelectorSet(browser, selectors, action, params) {
|
|
|
1057
1111
|
}
|
|
1058
1112
|
return { success: false, validation, updates };
|
|
1059
1113
|
}
|
|
1114
|
+
function scoreVariantSearchResult(result, kind, query) {
|
|
1115
|
+
const normalizedQuery = normalizeSearchToken(query);
|
|
1116
|
+
const normalizedText = normalizeSearchToken(result.text || '');
|
|
1117
|
+
const selector = (result.selector || '').toLowerCase();
|
|
1118
|
+
const tag = (result.tag || '').toLowerCase();
|
|
1119
|
+
const role = (result.role || '').toLowerCase();
|
|
1120
|
+
let score = 0;
|
|
1121
|
+
if (normalizedText === normalizedQuery)
|
|
1122
|
+
score += 10;
|
|
1123
|
+
else if (normalizedText.includes(normalizedQuery))
|
|
1124
|
+
score += 7;
|
|
1125
|
+
else
|
|
1126
|
+
score += 3;
|
|
1127
|
+
if (result.clickable)
|
|
1128
|
+
score += 5;
|
|
1129
|
+
if (result.visibilityState === 'full')
|
|
1130
|
+
score += 4;
|
|
1131
|
+
else if (result.visibilityState === 'partial')
|
|
1132
|
+
score += 3;
|
|
1133
|
+
else if (result.visibilityState === 'offscreen')
|
|
1134
|
+
score += 2;
|
|
1135
|
+
if (['label', 'button', 'input', 'a', 'option'].includes(tag))
|
|
1136
|
+
score += 4;
|
|
1137
|
+
if (['button', 'radio', 'switch', 'link', 'menuitem', 'option'].includes(role))
|
|
1138
|
+
score += 3;
|
|
1139
|
+
if (kind === 'locale' && /\b(lang|locale|language|hreflang)\b/.test(selector))
|
|
1140
|
+
score += 2;
|
|
1141
|
+
if (kind === 'theme' && /\b(theme|appearance|color-scheme|mode)\b/.test(selector))
|
|
1142
|
+
score += 2;
|
|
1143
|
+
return score;
|
|
1144
|
+
}
|
|
1145
|
+
async function trySearchBasedVariantSet(browser, params) {
|
|
1146
|
+
let validation = await revalidate(browser, params.validationParams);
|
|
1147
|
+
const updates = [];
|
|
1148
|
+
const attemptedSelectors = new Set();
|
|
1149
|
+
for (const query of buildVariantSearchQueries(params.kind, params.target).slice(0, 6)) {
|
|
1150
|
+
let results = [];
|
|
1151
|
+
try {
|
|
1152
|
+
results = await browser.searchText(query);
|
|
1153
|
+
}
|
|
1154
|
+
catch {
|
|
1155
|
+
continue;
|
|
1156
|
+
}
|
|
1157
|
+
const candidates = results
|
|
1158
|
+
.map((result) => ({ result, score: scoreVariantSearchResult(result, params.kind, query) }))
|
|
1159
|
+
.sort((left, right) => right.score - left.score)
|
|
1160
|
+
.slice(0, 5);
|
|
1161
|
+
for (const candidate of candidates) {
|
|
1162
|
+
const selector = candidate.result.selector;
|
|
1163
|
+
if (!selector || attemptedSelectors.has(selector))
|
|
1164
|
+
continue;
|
|
1165
|
+
attemptedSelectors.add(selector);
|
|
1166
|
+
try {
|
|
1167
|
+
await applyVariantSelector(browser, selector, {
|
|
1168
|
+
kind: params.kind,
|
|
1169
|
+
target: params.target,
|
|
1170
|
+
});
|
|
1171
|
+
await browser.wait(350);
|
|
1172
|
+
validation = await revalidate(browser, params.validationParams);
|
|
1173
|
+
updates.push({
|
|
1174
|
+
stepSignature: params.signature,
|
|
1175
|
+
selector,
|
|
1176
|
+
source: 'deterministic',
|
|
1177
|
+
success: validation.validationStatus !== 'invalid',
|
|
1178
|
+
});
|
|
1179
|
+
if (validation.validationStatus === 'valid') {
|
|
1180
|
+
return { success: true, validation, updates };
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
catch {
|
|
1184
|
+
updates.push({
|
|
1185
|
+
stepSignature: params.signature,
|
|
1186
|
+
selector,
|
|
1187
|
+
source: 'deterministic',
|
|
1188
|
+
success: false,
|
|
1189
|
+
});
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
return { success: false, validation, updates };
|
|
1194
|
+
}
|
|
1060
1195
|
function needsHardLangRepair(validation) {
|
|
1061
1196
|
return validation.langDiagnostic.outcome === 'mismatch';
|
|
1062
1197
|
}
|
|
@@ -1166,6 +1301,20 @@ export async function performDeterministicSessionRepair(browser, params) {
|
|
|
1166
1301
|
}
|
|
1167
1302
|
}
|
|
1168
1303
|
}
|
|
1304
|
+
const langSearchAttempt = await trySearchBasedVariantSet(browser, {
|
|
1305
|
+
kind: 'locale',
|
|
1306
|
+
target: params.requestedLang,
|
|
1307
|
+
signature: `lang:option:${requestedLang}`,
|
|
1308
|
+
validationParams: params,
|
|
1309
|
+
});
|
|
1310
|
+
remember(langSearchAttempt.updates);
|
|
1311
|
+
validation = langSearchAttempt.validation;
|
|
1312
|
+
if (langSearchAttempt.updates.length > 0) {
|
|
1313
|
+
signals = await refreshSignals(signals);
|
|
1314
|
+
}
|
|
1315
|
+
if (validation.validationStatus === 'valid') {
|
|
1316
|
+
return { repaired: true, validation, pathUsed: 'lang_search', updates };
|
|
1317
|
+
}
|
|
1169
1318
|
}
|
|
1170
1319
|
// Recapture signals before theme repair — lang repair may have changed the DOM structure,
|
|
1171
1320
|
// opened/closed menus, or navigated to different settings. Theme variant controls detected
|
|
@@ -1222,6 +1371,20 @@ export async function performDeterministicSessionRepair(browser, params) {
|
|
|
1222
1371
|
}
|
|
1223
1372
|
}
|
|
1224
1373
|
}
|
|
1374
|
+
const themeSearchAttempt = await trySearchBasedVariantSet(browser, {
|
|
1375
|
+
kind: 'theme',
|
|
1376
|
+
target: params.requestedTheme,
|
|
1377
|
+
signature: `theme:option:${params.requestedTheme}`,
|
|
1378
|
+
validationParams: params,
|
|
1379
|
+
});
|
|
1380
|
+
remember(themeSearchAttempt.updates);
|
|
1381
|
+
validation = themeSearchAttempt.validation;
|
|
1382
|
+
if (themeSearchAttempt.updates.length > 0) {
|
|
1383
|
+
signals = await refreshSignals(signals);
|
|
1384
|
+
}
|
|
1385
|
+
if (validation.validationStatus === 'valid') {
|
|
1386
|
+
return { repaired: true, validation, pathUsed: 'theme_search', updates };
|
|
1387
|
+
}
|
|
1225
1388
|
}
|
|
1226
1389
|
if (signals
|
|
1227
1390
|
&& ((params.requestedLang && validation.langMatches !== true)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SF_PRO_SYMBOLS: string;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Auto-generated — SF Pro symbol subset as base64 data URI
|
|
2
|
+
// Source: /Library/Fonts/SF-Pro.ttf (subset to required macOS menu bar glyphs)
|
|
3
|
+
export const SF_PRO_SYMBOLS = 'data:font/woff2;base64,d09GMgABAAAAAA8MABIAAAAAJ0gAAA6gAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGyAcNj9IVkFSg' +
|
|
4
|
+
'Q4/TVZBUoYNBmA/U1RBVIZMJzoAfC+FVAqHCIY0MI1WATYCJAMcCxAABCAFn0QHIBuqJRPueNg4YFjjHTcaGTVZLUKK/yohGzKkN' +
|
|
5
|
+
'19DhKi7ucMVMRiKiSEKTVQqjzlLvmzbB/eVf93jHBohySwPD+ue79w7M2++6ARxhfQF901qP+0muUEJCnH9/off5t8HVmAj8yjy/' +
|
|
6
|
+
'QyjsBYGRjUomMgUMZpYVri1i8SKfPAN7vF1VVcg/OHLbAAyhBVAAMXkVqmeYYRfgNf/t9Yq/xaNHxpJ7ez14ULakgnpr8wd6mkRl' +
|
|
7
|
+
'SEd8UKxEmmD+WDRIkRSxaqhs7mJQmJcqUL/uSiq8umb6qEL2xVqr9Ca8UgQJkJiJBaMQij4h//7fjxdsrZ/wK/YML1P4/KyKMtmO' +
|
|
8
|
+
'+rN3Aoso+B/M9GnpT0sjAxnXPjkPFPLxuSgj68SomAZs2SLVlYo9cWHBVrpgy7I/IV+YSCjhGYTUOVPwhqJ/0B4irhsMHi5rEww+' +
|
|
9
|
+
'DB4HDCwhazH0AVwVgV7IAGzYeEVa4GnYKV9LXnb29bNRgPhdWYiXtsNEQq/0CyrAIyQArfvok5tqKkbGCkJCNBCZcqXx90AiCiQO' +
|
|
10
|
+
'5T7dzCL9bAwfujlVN5g/6MDGLIfyBdh9f35YQdoWO+N789Vqm97U6iKTDa9CO0WoAFQBgCAQFNZ/ba3AQCAFc4ANgCAU7hR8jTWh' +
|
|
11
|
+
'NwF4MZR5sSpAwKXYeXUgannQIqobr8ZA0uCFBmy5ChSogxHhSo16rTgaSNYRafQkCLTlgdX0PnlroXhlRFkGSuPkQAsLHUYUnBAw' +
|
|
12
|
+
'JIkTYY8Bc/m5Z4Gzcsfas+++cFKXqpuGUuSpnyfWRhBA7MCQRCE3nVTkv65JGEsS30xOd+/gsGswE47m7x8guLtBSkvhRBqvNQ3W' +
|
|
13
|
+
'bsoKbFEoiUn9qrIKxkFLMtmxJMKk23s53cClKyYszrID2h/osfq0/+rgvHtMYKAskN1AQOQEFILJbpgAJgC5uDzvDQkB+zclVuMc' +
|
|
14
|
+
'CEHX0rjIbkw/0/79QgP1mJxsm30yBve9qU//IvgwiDWhF/Qgxdb42TcjQ9RF0MJ2SUpaZ9ByczC3Jln82F+yaYcKySglMR+GP3+X' +
|
|
15
|
+
'yigIgfWHnpsVTm4TiiFyqG1x6kcrpU6cqS0XY6W5irHahUpcrzUd9+JxrWT2inttHZGO6ud085rF7SLcmntjjePy+W1qqsvypXS3' +
|
|
16
|
+
'v5VSiv9a5QC5HrppdwoxWk3tVv33V5s7Y52V7un3dceaA/5qfno+ACF4jWooSrt+eyVj3/+eGsqvnaIkvu8t0QfsALbYbVCHxR2A' +
|
|
17
|
+
'Fbq+hM9KSd0UFZ5UOigG+UpdbDc7TSUBgBKpeBNwZbEGgPxDtpYvA00qL4F3Aq6gOeBB4ggvx2sAhVAn5MBMfytYQgQwmEtxE4xI' +
|
|
18
|
+
'gyB8Upz9eLCKIzLJuOahClMxjULc5iMiwlhCZPxMSmsAFf0U8IG/iycFnYAoXhRPyPWwh84K+ZeH65NtO/AQsdOLKR1ZqFLVxa6d' +
|
|
19
|
+
'WehR08WevVmoU9fFvr1Zx8DBnKYPRs3aDBMxg0ZCpPxEzYcsFIYMRK0Afqo0fCyMGYs6OL0ceOhDxMmhtcm0jPCW0hMmsyGzCw2T' +
|
|
20
|
+
'JnKhmnT2TBjJhuyZ7Eh4o7YwJ7DXQDq+2iHtkQvEO8UeV+pkLKJSqkad4KaKk5ffbpUZSU7qqvDD34Xi8G37IfGQXGYWCy3vaYmW' +
|
|
21
|
+
'dmmiJoGRFBbK6+Sk7dHvvzVr3n48OYMp/c9DwFxifjxpDtatTtvp706nLsyju3rPiDWugSN9fr67vQw1qFb4O4Xue3PjVLsKzpqG' +
|
|
22
|
+
'iL51c8yUosIal5Ajrhoe0cPuasXujfUdbVF7OisbaSvoabjvblNXAfqq9sLsNpsVhmyTa642k+XIYczR9cSqUxVbCksp6r1JClaU' +
|
|
23
|
+
'xR+yEl9l2a6YjnNyodk7eRhzvaNsO8hKAjyasdhLTbZBVt4ZBcE2rjqeuo6rA/Q89Cz8M7KXRvkkphw/e0jOd/vp9GtookB+kS94' +
|
|
24
|
+
'P9YJEw5J8/RRn4fRk/W3ipbYl+F8z4TVXvTbIjnO8ZETZXNuyQxFlymy6KjjPFeT3YRY588JcY+3oX3vtqcCMefjbkGGcCMvXKCS' +
|
|
25
|
+
'acfLyqszJgbJ5JA6bndl0qIjY3EkkuXEkHN+y9ti5j2S+4bRFvi9T86kvBncYNDDPfBQKFKdv2ikN5x80YHQygM58YNRkcQzo2bH' +
|
|
26
|
+
'XSItps3BTn4jBv9yzmtpXU6598/HC18zqkgCF6s0xKu+3vtrpWov19kdfeuyLq/r2m4m7BPZF1ntSUkUDMhqs4p/7F1a6ISIXr/k' +
|
|
27
|
+
'Mze4sj7yN1+YVtjY538SGSSRbi6cdY7Z3h6OqcT4fYfJOpTNwrepnCflpQk8oiCVUmqf5TqW0jzyPX39+DR50v1IcmzLiARHwXMM' +
|
|
28
|
+
'JAEapgQAdIBgMf/18jckPoJCPiOlzWEdPYEwH8Tko+RxnCwoT8AeBv4CQp8ABEBYPCP7XL48a/iRXRJWmZxrLu+oWtsbHJmdnZ6Y' +
|
|
29
|
+
'mxksH9KhsagTaCvoSKNsZJyaho4WVlcjoyUorpapipOuQ2nuv1ODZEL6oQaoWFyB89cH9QE7Eidf2dc0UyUhGqi9rgzJ48dOXr0+' +
|
|
30
|
+
'Kkz5y9dwbl0AWgnCwT6izLGHpQ0llnU1l7plq1oE758/vrzx/dff+2eX99//Pz+RQT8vsgEYL5paEKgnQ4aNpLGUQiVADiIsVNAg' +
|
|
31
|
+
'5wrVraCkANDaJWBKkMbESGI0CrFb1KiY2gjIoQQbFX47IZaZ/toszUps0M1WxeacOvbuTabD8fRSps8PxwGDhEhiA1rlYEqQzURI' +
|
|
32
|
+
'YhIq3RVtp7f38DH1MOB03zAnOXT4FqK2r7Tm2AHHsrhyNmnq5mOquc39rmj5SjvbmEqGq/64sF1v/5FXf+Msk7l+9fPqzpmwBktY' +
|
|
33
|
+
'yNuy9Hbzz81jcyiNNL06fnto1toaBkfrp+2JshPtIjtmpYJeQJeHf/ifdMg2tfUcsiEQjbdLcLVkKA819vs1junTCDb+0e9wt+eL' +
|
|
34
|
+
'BJIKP3vEc32gJ0uuo+FtTAr4xSTg5rr9MeLzmgS6suXUrSP9vhfCVzhBzJ44USbnCia5mwXirOatKgcFzjhhR98yBEoto6rGtmZi' +
|
|
35
|
+
'pHqeOsSxcoFhuEvHKhzXWe/mnv7vDPqijJUN7sduPG9dVafFnoWTX+29dNJN7QUzcB0KXLyk2iZIAZSrys+EffNCgmzfeKq19dPH' +
|
|
36
|
+
'nC3k9dfV9VPy2qcIjtdX/Xs9DYXtDwpSGw7/QwOnF5tZ2emJw/T7X+rUPjbPg3y/c3sHj2qrB4D3Gian11LM8bBWHXlIxHWa62ev' +
|
|
37
|
+
'FBS2r7WK4rrBpvtSxs3t+VGeVnK9NX6mX0yll50D9jmquegMrQt6LDystVPn76vHQflkQ5eoeBgqAzjte+fcrl0Zzz0vzm723acf' +
|
|
38
|
+
'dMP+Dl07pTgO4zflh/WTwolJ+s/PbmwzQUtu3MMt114suz70Doeba0fat+z0ztpO/2sbzu2ibpjwxlcwJuwAL8wWCUePq80LK56c' +
|
|
39
|
+
'G3PRqU91x4cvfXoczVTnx/dOrpnNhuz74iFe4CGlgmczhcZ4GCsSTzdmsYAN8TE5HX9n9o+3oUbzFVg9M/r589/DKGdqO42QVWD4' +
|
|
40
|
+
'R/tBltbE3UYElexULtKPATqY151fyjVMgUKA82U9OXRqZY/IoyfibxQS97EjxrKqzA3XijVj0qcaz66nCPWReK8Ls4dDlkWicttu' +
|
|
41
|
+
'cssL9uVjyuqHgzPr0BvUqCtmhCvZhto4c2usBm2t4WvLQk7dosl2fom2H5RlCdAhUASQdRt/FnusMXxu9e2VCx/G3UEcYUzZ6vtr' +
|
|
42
|
+
'dsVbjEmnP69G2x3xl57CVon+9loy3GjbevPdI/j2qrJ/MyUyZ9/+GkQi70e/PTw/L89TkvpuXmv//uj03xXlLv5E0n+qYff++dEg' +
|
|
43
|
+
'AAB6k0M/0Rl+2kZrAwAftWXbsw+ObV9yXlhetUu+ZIPwVPbyV8nyz5fK4fPIcfll/uf1S0yW/B8td9TjSj8lgketOToyf4vBypQx' +
|
|
44
|
+
'yJKLKE4/K6UOFK9VohSFtgICkIbG6V2nlWYQXZLpcoArh409OLLHYRMzk+wGp4hFAohwZBR4BixjnWM6QaHCUrsZIoYDyezGGLmD' +
|
|
45
|
+
'GKFBTORWCIpCJWJuKyQdZo1C31gQ1dTbFFSlR1irrOGUcZYi5gbp3XbcXFaz/jJHjVnONApCkfkcuNEtzLQUGorZ6S6y4VJ/eWKW' +
|
|
46
|
+
'CvcGLUudwbtxYNZs3nS6eO8kPsxb7rdxAelF/jSHRI/lKHxpz5pAhCnVCCZxskpSBwXBZNrPBVCc94JpeTZhgVHOIVGnQj46RIJN' +
|
|
47
|
+
'0ui6FhBNJmaIoa6LcSSq93E0XTAFB+DuZMwOBKRvRGdha9jILhBEgNPSaazeEzktcZC3BgpjLZYKt29KA1l30lH2gEZTE5BJsKtw' +
|
|
48
|
+
'WZwIbLoXD4O8u3f2TCe7mQPcXM6cZ47n4tHoeVC87qy+WhB97Ww41rUZS3urJZ0U0s7qGVd0/JOaUV3lN8RFXRBhcGvKOzdGPBuC' +
|
|
49
|
+
'nU3B7lbwtutge22kHZ7MLsjjN0ZwO4KXXcHrXvC1b2B6r4QdX9weiAsPRiQHgpFDwehR1a/2PDoik9+1QCoWGCJDaa5UL9GxFm2b' +
|
|
50
|
+
'GwsRLxxJDOr1XthT+JKlyoNT26pzyrC+v98LExmhPJAJAjXBiFYUuVhY+DWh+sb2LbELE3BFNZ4fVNVqlg2W9uzJmKQnVzpxwqn6' +
|
|
51
|
+
'd65vMt02K9FSsfEkyZQNp50yRhTkdB+cRxFYk3qoqsNsmRPbJiLy0TCsfFwzR09Detb+TI+xEeFSZOO4wt1wOtp/Np7jF9TvIg5T' +
|
|
52
|
+
'7ZE0tA/66erj8pyJUOEEipZ/SSlz/aMr2mKeD+Fi+fDXbz6XryPIV+RQB+RaRfsrSXLBFr4XBxMLJwAwxgntClCmL4PmBHQkRxh8' +
|
|
53
|
+
'QlVnjD4hCZPmKKELk6owaAPmBHQFzADMBVFV+WGDJVAfCChtSQJr5KpcJcfFX9hbyD+kt0A590VysZYwHTnki1EUgZJQvQ8wLiAJ' +
|
|
54
|
+
'CmSwSFr4iS9SVIkSRaXrALjXqDvAcYF9AQMgtn3vtuXf5QMC/z/FQ7ZAwAA';
|
|
55
|
+
//# sourceMappingURL=sf-pro-symbols.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type SkillType = 'preset' | 'studio';
|
|
2
|
+
export type SkillAgent = 'claude' | 'codex' | 'cursor' | 'windsurf' | 'copilot';
|
|
3
|
+
export interface SkillPlaceholderOptions {
|
|
4
|
+
projectUrl?: string;
|
|
5
|
+
projectId?: string;
|
|
6
|
+
apiBaseUrl?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface SkillExportResult {
|
|
9
|
+
mode: 'single-file' | 'bundle';
|
|
10
|
+
writtenPaths: string[];
|
|
11
|
+
}
|
|
12
|
+
export declare function resolveSkillAssetDir(): Promise<string>;
|
|
13
|
+
export declare function shouldInstallSkillBundle(params: {
|
|
14
|
+
agent?: string;
|
|
15
|
+
outputPath?: string;
|
|
16
|
+
type: SkillType;
|
|
17
|
+
}): boolean;
|
|
18
|
+
export declare function renderSkillSingleFile(params: {
|
|
19
|
+
type: SkillType;
|
|
20
|
+
agent?: string;
|
|
21
|
+
placeholders: SkillPlaceholderOptions;
|
|
22
|
+
}): Promise<string>;
|
|
23
|
+
export declare function writeSkillExport(params: {
|
|
24
|
+
type: SkillType;
|
|
25
|
+
agent?: string;
|
|
26
|
+
outputPath: string;
|
|
27
|
+
placeholders: SkillPlaceholderOptions;
|
|
28
|
+
}): Promise<SkillExportResult>;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
function replaceSkillPlaceholders(content, opts) {
|
|
4
|
+
let result = content;
|
|
5
|
+
if (opts.projectUrl) {
|
|
6
|
+
result = result.replace(/\[AUTOKAP_PROJECT_URL\]/g, opts.projectUrl);
|
|
7
|
+
}
|
|
8
|
+
if (opts.projectId) {
|
|
9
|
+
result = result.replace(/\[AUTOKAP_PROJECT_ID\]/g, opts.projectId);
|
|
10
|
+
}
|
|
11
|
+
if (opts.apiBaseUrl) {
|
|
12
|
+
result = result.replace(/https:\/\/autokap\.app/g, opts.apiBaseUrl);
|
|
13
|
+
}
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
const PRESET_SKILL_SOURCE = {
|
|
17
|
+
coreFile: 'SKILL.md',
|
|
18
|
+
references: [
|
|
19
|
+
{ relativePath: 'OPCODE-REFERENCE.md', title: 'Opcode Reference', anchor: 'reference-opcode-reference' },
|
|
20
|
+
{ relativePath: 'references/interactive-demo.md', title: 'Interactive Demo Workflow', anchor: 'reference-interactive-demo-workflow' },
|
|
21
|
+
{ relativePath: 'references/mock-data.md', title: 'Mock Data Injection', anchor: 'reference-mock-data-injection' },
|
|
22
|
+
{ relativePath: 'references/examples.md', title: 'Complete Examples', anchor: 'reference-complete-examples' },
|
|
23
|
+
],
|
|
24
|
+
};
|
|
25
|
+
const STUDIO_SKILL_SOURCE = {
|
|
26
|
+
coreFile: 'STUDIO-SKILL.md',
|
|
27
|
+
references: [],
|
|
28
|
+
};
|
|
29
|
+
function getSkillSourceSpec(type) {
|
|
30
|
+
return type === 'studio' ? STUDIO_SKILL_SOURCE : PRESET_SKILL_SOURCE;
|
|
31
|
+
}
|
|
32
|
+
async function pathExists(candidate) {
|
|
33
|
+
try {
|
|
34
|
+
await fs.access(candidate);
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function getModuleAssetCandidates() {
|
|
42
|
+
const url = new URL(import.meta.url);
|
|
43
|
+
const dir = process.platform === 'win32'
|
|
44
|
+
? path.dirname(url.pathname.replace(/^\/([A-Za-z]:)/, '$1'))
|
|
45
|
+
: path.dirname(url.pathname);
|
|
46
|
+
return [
|
|
47
|
+
path.resolve(dir, '..', 'assets', 'skill'),
|
|
48
|
+
path.resolve(dir, '..', '..', 'assets', 'skill'),
|
|
49
|
+
];
|
|
50
|
+
}
|
|
51
|
+
export async function resolveSkillAssetDir() {
|
|
52
|
+
const candidates = [
|
|
53
|
+
...getModuleAssetCandidates(),
|
|
54
|
+
path.join(process.cwd(), 'assets', 'skill'),
|
|
55
|
+
path.join(process.cwd(), '..', 'assets', 'skill'),
|
|
56
|
+
path.join(process.cwd(), '..', '..', 'assets', 'skill'),
|
|
57
|
+
];
|
|
58
|
+
for (const candidate of candidates) {
|
|
59
|
+
if (await pathExists(candidate)) {
|
|
60
|
+
return candidate;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
throw new Error('Could not find assets/skill. Make sure the autokap package is installed correctly.');
|
|
64
|
+
}
|
|
65
|
+
function inferBundleInstall(outputPath) {
|
|
66
|
+
if (!outputPath)
|
|
67
|
+
return false;
|
|
68
|
+
const normalized = path.normalize(outputPath);
|
|
69
|
+
const parts = normalized.split(path.sep).filter(Boolean);
|
|
70
|
+
for (let index = 0; index < parts.length - 1; index += 1) {
|
|
71
|
+
if (parts[index] === '.agents' && parts[index + 1] === 'skills') {
|
|
72
|
+
return path.basename(normalized) === 'SKILL.md';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
export function shouldInstallSkillBundle(params) {
|
|
78
|
+
if (params.type === 'studio')
|
|
79
|
+
return false;
|
|
80
|
+
if (params.agent?.toLowerCase() === 'codex')
|
|
81
|
+
return true;
|
|
82
|
+
return inferBundleInstall(params.outputPath);
|
|
83
|
+
}
|
|
84
|
+
async function readSkillFile(rootDir, relativePath, placeholders) {
|
|
85
|
+
const absolutePath = path.join(rootDir, relativePath);
|
|
86
|
+
const raw = await fs.readFile(absolutePath, 'utf-8');
|
|
87
|
+
return replaceSkillPlaceholders(raw, placeholders);
|
|
88
|
+
}
|
|
89
|
+
function insertAfterFrontmatter(content, inserted) {
|
|
90
|
+
if (!content.startsWith('---\n')) {
|
|
91
|
+
return `${inserted.trim()}\n\n${content}`;
|
|
92
|
+
}
|
|
93
|
+
const secondFence = content.indexOf('\n---\n', 4);
|
|
94
|
+
if (secondFence === -1) {
|
|
95
|
+
return `${inserted.trim()}\n\n${content}`;
|
|
96
|
+
}
|
|
97
|
+
const frontmatter = content.slice(0, secondFence + 5);
|
|
98
|
+
const rest = content.slice(secondFence + 5).replace(/^\n+/, '');
|
|
99
|
+
return `${frontmatter}\n${inserted.trim()}\n\n${rest}`;
|
|
100
|
+
}
|
|
101
|
+
function stripLeadingTitle(content) {
|
|
102
|
+
return content.replace(/^# .*\n+/, '').trim();
|
|
103
|
+
}
|
|
104
|
+
function rewriteLinksForSingleFile(content, spec) {
|
|
105
|
+
let rewritten = content.replace(/\(SKILL\.md\)/g, '(#autokap-preset-creation-skill)');
|
|
106
|
+
for (const reference of spec.references) {
|
|
107
|
+
const escapedPath = reference.relativePath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
108
|
+
rewritten = rewritten.replace(new RegExp(`\\(${escapedPath}\\)`, 'g'), `(#${reference.anchor})`);
|
|
109
|
+
}
|
|
110
|
+
return rewritten;
|
|
111
|
+
}
|
|
112
|
+
export async function renderSkillSingleFile(params) {
|
|
113
|
+
const rootDir = await resolveSkillAssetDir();
|
|
114
|
+
const spec = getSkillSourceSpec(params.type);
|
|
115
|
+
let core = await readSkillFile(rootDir, spec.coreFile, params.placeholders);
|
|
116
|
+
if (params.type === 'studio') {
|
|
117
|
+
return core;
|
|
118
|
+
}
|
|
119
|
+
core = rewriteLinksForSingleFile(core, spec);
|
|
120
|
+
core = insertAfterFrontmatter(core, '> Packaging note: the canonical AutoKap preset skill is a modular bundle for Codex (`SKILL.md` + companion reference files). This single-file export is generated from that same source so all agents stay in parity.');
|
|
121
|
+
const bundledReferences = [];
|
|
122
|
+
for (const reference of spec.references) {
|
|
123
|
+
const content = await readSkillFile(rootDir, reference.relativePath, params.placeholders);
|
|
124
|
+
bundledReferences.push([
|
|
125
|
+
'---',
|
|
126
|
+
'',
|
|
127
|
+
`## Reference: ${reference.title}`,
|
|
128
|
+
`Source path in the Codex bundle: \`${reference.relativePath}\``,
|
|
129
|
+
'',
|
|
130
|
+
rewriteLinksForSingleFile(stripLeadingTitle(content), spec),
|
|
131
|
+
].join('\n'));
|
|
132
|
+
}
|
|
133
|
+
return [core, ...bundledReferences].join('\n\n');
|
|
134
|
+
}
|
|
135
|
+
export async function writeSkillExport(params) {
|
|
136
|
+
const rootDir = await resolveSkillAssetDir();
|
|
137
|
+
const spec = getSkillSourceSpec(params.type);
|
|
138
|
+
if (shouldInstallSkillBundle({
|
|
139
|
+
agent: params.agent,
|
|
140
|
+
outputPath: params.outputPath,
|
|
141
|
+
type: params.type,
|
|
142
|
+
})) {
|
|
143
|
+
const destinationDir = path.dirname(params.outputPath);
|
|
144
|
+
const writtenPaths = [];
|
|
145
|
+
for (const relativePath of [spec.coreFile, ...spec.references.map((reference) => reference.relativePath)]) {
|
|
146
|
+
const absolutePath = path.join(destinationDir, relativePath);
|
|
147
|
+
const content = await readSkillFile(rootDir, relativePath, params.placeholders);
|
|
148
|
+
await fs.mkdir(path.dirname(absolutePath), { recursive: true });
|
|
149
|
+
await fs.writeFile(absolutePath, content, 'utf-8');
|
|
150
|
+
writtenPaths.push(absolutePath);
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
mode: 'bundle',
|
|
154
|
+
writtenPaths,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
const content = await renderSkillSingleFile({
|
|
158
|
+
type: params.type,
|
|
159
|
+
agent: params.agent,
|
|
160
|
+
placeholders: params.placeholders,
|
|
161
|
+
});
|
|
162
|
+
await fs.mkdir(path.dirname(params.outputPath), { recursive: true });
|
|
163
|
+
await fs.writeFile(params.outputPath, content, 'utf-8');
|
|
164
|
+
return {
|
|
165
|
+
mode: 'single-file',
|
|
166
|
+
writtenPaths: [params.outputPath],
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=skill-packaging.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capture Agent — Smart Wait
|
|
3
|
+
*
|
|
4
|
+
* Detects if the page is still loading before capture.
|
|
5
|
+
* Uses Playwright-native checks (no LLM) to wait for:
|
|
6
|
+
* - Network idle
|
|
7
|
+
* - No visible spinners/skeletons
|
|
8
|
+
* - DOM stability
|
|
9
|
+
*/
|
|
10
|
+
import type { RuntimeAdapter } from './execution-types.js';
|
|
11
|
+
export interface SmartWaitResult {
|
|
12
|
+
/** Whether the page appears stable */
|
|
13
|
+
stable: boolean;
|
|
14
|
+
/** What we waited for */
|
|
15
|
+
waitedFor: string[];
|
|
16
|
+
/** Total time spent waiting (ms) */
|
|
17
|
+
waitedMs: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Waits for the page to be visually stable before capture.
|
|
21
|
+
* Checks for common loading patterns and waits for them to resolve.
|
|
22
|
+
*
|
|
23
|
+
* This runs BEFORE CAPTURE_SCREENSHOT — deterministic, no LLM.
|
|
24
|
+
*/
|
|
25
|
+
export declare function smartWaitForStability(adapter: RuntimeAdapter, options?: {
|
|
26
|
+
maxWaitMs?: number;
|
|
27
|
+
}): Promise<SmartWaitResult>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capture Agent — Smart Wait
|
|
3
|
+
*
|
|
4
|
+
* Detects if the page is still loading before capture.
|
|
5
|
+
* Uses Playwright-native checks (no LLM) to wait for:
|
|
6
|
+
* - Network idle
|
|
7
|
+
* - No visible spinners/skeletons
|
|
8
|
+
* - DOM stability
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Waits for the page to be visually stable before capture.
|
|
12
|
+
* Checks for common loading patterns and waits for them to resolve.
|
|
13
|
+
*
|
|
14
|
+
* This runs BEFORE CAPTURE_SCREENSHOT — deterministic, no LLM.
|
|
15
|
+
*/
|
|
16
|
+
export async function smartWaitForStability(adapter, options) {
|
|
17
|
+
const maxWait = options?.maxWaitMs ?? 10000;
|
|
18
|
+
const startTime = Date.now();
|
|
19
|
+
const waitedFor = [];
|
|
20
|
+
// 1. Wait for no visible spinners/skeletons
|
|
21
|
+
const spinnerSelectors = [
|
|
22
|
+
'[class*="spinner"]',
|
|
23
|
+
'[class*="loading"]',
|
|
24
|
+
'[class*="skeleton"]',
|
|
25
|
+
'[class*="shimmer"]',
|
|
26
|
+
'[role="progressbar"]',
|
|
27
|
+
'[aria-busy="true"]',
|
|
28
|
+
'.animate-spin',
|
|
29
|
+
'.animate-pulse',
|
|
30
|
+
];
|
|
31
|
+
for (const selector of spinnerSelectors) {
|
|
32
|
+
const elapsed = Date.now() - startTime;
|
|
33
|
+
if (elapsed >= maxWait)
|
|
34
|
+
break;
|
|
35
|
+
try {
|
|
36
|
+
// Check if spinner exists and is visible
|
|
37
|
+
const visible = await adapter.waitFor({
|
|
38
|
+
selector,
|
|
39
|
+
state: 'visible',
|
|
40
|
+
timeoutMs: 200, // Quick check
|
|
41
|
+
});
|
|
42
|
+
if (visible) {
|
|
43
|
+
// Spinner found — wait for it to disappear
|
|
44
|
+
waitedFor.push(selector);
|
|
45
|
+
const remaining = maxWait - (Date.now() - startTime);
|
|
46
|
+
if (remaining > 0) {
|
|
47
|
+
// Poll until spinner disappears
|
|
48
|
+
const deadline = Date.now() + Math.min(remaining, 5000);
|
|
49
|
+
while (Date.now() < deadline) {
|
|
50
|
+
const stillVisible = await adapter.waitFor({
|
|
51
|
+
selector,
|
|
52
|
+
state: 'visible',
|
|
53
|
+
timeoutMs: 300,
|
|
54
|
+
});
|
|
55
|
+
if (!stillVisible)
|
|
56
|
+
break;
|
|
57
|
+
await sleep(300);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Selector check failed — skip
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// 2. Brief stability pause (let animations settle)
|
|
67
|
+
const elapsed = Date.now() - startTime;
|
|
68
|
+
if (elapsed < maxWait) {
|
|
69
|
+
await sleep(Math.min(500, maxWait - elapsed));
|
|
70
|
+
waitedFor.push('stability-pause');
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
stable: true,
|
|
74
|
+
waitedFor,
|
|
75
|
+
waitedMs: Date.now() - startTime,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function sleep(ms) {
|
|
79
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=smart-wait.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status bar PNG renderer — uses satori (CSS flexbox engine) + resvg for
|
|
3
|
+
* pixel-perfect parity with the HTML status bar used on the client.
|
|
4
|
+
*
|
|
5
|
+
* The layout code mirrors generateStatusBarHtml() from status-bar.ts exactly:
|
|
6
|
+
* same flex containers, gaps, font sizes, and icon dimensions. satori measures
|
|
7
|
+
* text widths using the actual SF Pro font metrics (via opentype.js), so
|
|
8
|
+
* spacing is identical to what a browser produces.
|
|
9
|
+
*
|
|
10
|
+
* Fonts are decompressed from woff2 → TTF on first use (wawoff2) and cached.
|
|
11
|
+
*/
|
|
12
|
+
import type { StatusBarRenderOptions } from './status-bar.js';
|
|
13
|
+
/**
|
|
14
|
+
* Render the status bar to a PNG buffer using satori (CSS flexbox) + resvg.
|
|
15
|
+
* Produces pixel-perfect output matching the HTML status bar on the client.
|
|
16
|
+
*
|
|
17
|
+
* @param options Same options as generateStatusBarHtml()
|
|
18
|
+
* @param targetWidth Physical pixel width for the output PNG (e.g. logical × outputScale)
|
|
19
|
+
*/
|
|
20
|
+
export declare function renderStatusBarBuffer(options: StatusBarRenderOptions, targetWidth: number): Promise<Buffer>;
|