@thinkingos/vsl-sdk 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +70 -28
- package/dist/index.d.ts +70 -28
- package/dist/index.js +105 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +105 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -60,6 +60,18 @@ interface ElementCss {
|
|
|
60
60
|
pointerEvents?: string;
|
|
61
61
|
overflow?: string;
|
|
62
62
|
height?: string;
|
|
63
|
+
/** Background color (computed) — для sty.bg в VslObject. */
|
|
64
|
+
backgroundColor?: string;
|
|
65
|
+
/** Text/foreground color (computed) — для sty.fg в VslObject. */
|
|
66
|
+
color?: string;
|
|
67
|
+
/** Border shorthand (computed) — для sty.border в VslObject. */
|
|
68
|
+
border?: string;
|
|
69
|
+
/** Border radius (computed) — для sty.radius в VslObject. */
|
|
70
|
+
borderRadius?: string;
|
|
71
|
+
/** Box shadow (computed) — для sty.shadow в VslObject. */
|
|
72
|
+
boxShadow?: string;
|
|
73
|
+
/** Font family (computed) — для sty.font.family в VslObject. */
|
|
74
|
+
fontFamily?: string;
|
|
63
75
|
}
|
|
64
76
|
/** Собственный текст элемента: только прямые текстовые узлы, whitespace-нормализация. */
|
|
65
77
|
declare function ownText(el: Element): string;
|
|
@@ -76,7 +88,7 @@ declare function extractDomTree(root?: Element): ExtractedElement[];
|
|
|
76
88
|
* Семантический тип объекта VSL (поле `t`): L1-теги + L2-роли (T1.1.3/T1.1.4),
|
|
77
89
|
* L3-CSS (T1.5.1), L4-структурные (T1.5.2), L5-vision (T1.5.4).
|
|
78
90
|
*/
|
|
79
|
-
type VslType = 'button' | 'input' | 'link' | 'nav' | 'header' | 'main' | 'container' | 'image' | 'select' | 'textarea' | 'modal' | 'tab' | 'heading' | 'footer' | 'scrollable_container' | 'toolbar' | 'list' | 'grid' | 'form_field' | 'tab_bar' | 'layout' | 'icon' | 'chart' | 'custom_widget' | 'unknown';
|
|
91
|
+
type VslType = 'button' | 'input' | 'file_input' | 'link' | 'nav' | 'header' | 'main' | 'container' | 'image' | 'select' | 'textarea' | 'modal' | 'tab' | 'heading' | 'footer' | 'scrollable_container' | 'toolbar' | 'list' | 'grid' | 'form_field' | 'tab_bar' | 'layout' | 'icon' | 'chart' | 'custom_widget' | 'unknown';
|
|
80
92
|
/** Состояние объекта VSL (поле `st`) — из ARIA-атрибутов (T1.1.4). */
|
|
81
93
|
type VslState = 'checked' | 'expanded' | 'disabled';
|
|
82
94
|
/** Тип визуального фрагмента — выход классификации vision (§2.2.2 Шаг 2). */
|
|
@@ -89,6 +101,29 @@ interface VslFragmentMeta$1 {
|
|
|
89
101
|
hash?: string;
|
|
90
102
|
cached_at?: string;
|
|
91
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Визуальные стили объекта VSL (DESIGN_SYSTEM.md §4.3).
|
|
106
|
+
* Optional: только для визуально значимых элементов.
|
|
107
|
+
* Все значения — computed styles в момент snapshot.
|
|
108
|
+
*/
|
|
109
|
+
interface VslStyle {
|
|
110
|
+
/** Background color (computed). */
|
|
111
|
+
bg?: string;
|
|
112
|
+
/** Text/foreground color (computed). */
|
|
113
|
+
fg?: string;
|
|
114
|
+
/** Border shorthand (computed). */
|
|
115
|
+
border?: string;
|
|
116
|
+
/** Border radius (computed). */
|
|
117
|
+
radius?: string;
|
|
118
|
+
/** Box shadow (computed). */
|
|
119
|
+
shadow?: string;
|
|
120
|
+
/** Font properties. */
|
|
121
|
+
font?: {
|
|
122
|
+
family?: string;
|
|
123
|
+
size?: string;
|
|
124
|
+
weight?: string;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
92
127
|
/**
|
|
93
128
|
* Запись реестра visual_fragments документа (§2.2.2, ARCHITECTURE.md:L265-284).
|
|
94
129
|
* ТОЛЬКО метаданные: base64-данные изображений живут в VisualFragmentStore
|
|
@@ -148,6 +183,12 @@ interface VslObject {
|
|
|
148
183
|
vf?: string;
|
|
149
184
|
/** Метаданные фрагмента (§4.4). */
|
|
150
185
|
vf_meta?: VslFragmentMeta$1;
|
|
186
|
+
/** Визуальные стили (DESIGN_SYSTEM.md §4.3). Optional: только для визуально значимых элементов. */
|
|
187
|
+
sty?: VslStyle;
|
|
188
|
+
/** Accept attribute для file_input (например, '.pdf,.docx'). */
|
|
189
|
+
accept?: string;
|
|
190
|
+
/** Multiple attribute для file_input — разрешена загрузка нескольких файлов. */
|
|
191
|
+
multiple?: boolean;
|
|
151
192
|
}
|
|
152
193
|
interface VslDocument {
|
|
153
194
|
vsl_version: string;
|
|
@@ -250,6 +291,8 @@ interface SegmentedElement {
|
|
|
250
291
|
txt: string | null;
|
|
251
292
|
/** Состояние из ARIA (checked/expanded/disabled) или null. */
|
|
252
293
|
st: VslState | null;
|
|
294
|
+
/** CSS-подмножество для визуальных стилей (передаётся в Builder для sty). */
|
|
295
|
+
css?: ElementCss;
|
|
253
296
|
ch: SegmentedElement[];
|
|
254
297
|
/** Ссылка на визуальный фрагмент (заполняется enrichWithVision, T1.5.4). */
|
|
255
298
|
vf?: string;
|
|
@@ -802,32 +845,6 @@ interface EnrichWithVisionDeps {
|
|
|
802
845
|
extractor: FragmentExtractor;
|
|
803
846
|
}
|
|
804
847
|
|
|
805
|
-
/**
|
|
806
|
-
* VSL Snapshot Session (T1.2.4, ROADMAP.md M1.2; ARCHITECTURE.md §2.4/§5.2/§6.3).
|
|
807
|
-
*
|
|
808
|
-
* Stateful-фасад над пайплайном capture→segment→build→cache→diff:
|
|
809
|
-
* - первый вызов или смена URL → полный VslDocument; кэш очищается и
|
|
810
|
-
* заполняется объектами документа; счётчик версий сбрасывается в 1;
|
|
811
|
-
* - тот же URL → VslDiff последнего документа против нового (формат §6.2):
|
|
812
|
-
* diff_version = version + 1, base_version = version;
|
|
813
|
-
* - viewport изменился при том же URL → дополнительно
|
|
814
|
-
* store.invalidateCoordinates() — «сброс координат» §5.2, НЕ полный сброс.
|
|
815
|
-
*
|
|
816
|
-
* Состояние {lastUrl, lastViewport, lastDocument, version} — в памяти
|
|
817
|
-
* экземпляра; VslDocument (канон §4) версиями НЕ расширяется.
|
|
818
|
-
*
|
|
819
|
-
* Политика кэша — store отражает текущий документ: full → clear + заполнение;
|
|
820
|
-
* diff → удалённые invalidate, добавленные (поддеревья) и изменённые set из
|
|
821
|
-
* нового документа; неизменённые остаются кэшированными (после resize — с
|
|
822
|
-
* обнулённым coordHash: наблюдаемый эффект invalidateCoordinates).
|
|
823
|
-
*
|
|
824
|
-
* input.url/viewport/timestamp/background передаются в BuildOptions ЯВНО —
|
|
825
|
-
* дефолты builder (window.innerWidth/innerHeight/location.href/document.title)
|
|
826
|
-
* вычислялись бы от глобалов: недетерминированны в тестах и недоступны в Node;
|
|
827
|
-
* title — из input, иначе root.ownerDocument.title (портативный фолбэк — фикс
|
|
828
|
-
* packaging-smoke demo:cache-diff).
|
|
829
|
-
*/
|
|
830
|
-
|
|
831
848
|
/** Результат snapshot(): полный документ (1-й вызов / URL change) или дифф. */
|
|
832
849
|
type SnapshotResult = VslDocument | VslDiff;
|
|
833
850
|
/** Type guard: различение диффа и полного документа (контракт T1.2.4). */
|
|
@@ -866,11 +883,26 @@ declare class VslSnapshotSession {
|
|
|
866
883
|
private lastDocument;
|
|
867
884
|
private version;
|
|
868
885
|
constructor(store?: CacheStore);
|
|
886
|
+
/**
|
|
887
|
+
* Сбрасывает состояние сессии (URL, viewport, документ, версия).
|
|
888
|
+
* Следующий вызов snapshot() вернёт полный документ (как первый вызов).
|
|
889
|
+
*/
|
|
890
|
+
clear(): void;
|
|
891
|
+
/** Возвращает последний полный документ (не diff). */
|
|
892
|
+
getLastDocument(): VslDocument | null;
|
|
893
|
+
/** Текущая версия документа (инкрементируется при каждом diff). */
|
|
894
|
+
getVersion(): number;
|
|
869
895
|
/**
|
|
870
896
|
* Строит VSL из DOM поддерева root (extractDomTree → segmentTree →
|
|
871
897
|
* buildVslDocument) и возвращает полный документ либо дифф (см. шапку).
|
|
872
898
|
*/
|
|
873
899
|
snapshot(root: Element, input: SnapshotInput): SnapshotResult;
|
|
900
|
+
/**
|
|
901
|
+
* Вариант snapshot() для pre-extracted elements (MCP сервер, Node.js контекст).
|
|
902
|
+
* Принимает ExtractedElement[] напрямую (без DOM Element), проходит тот же
|
|
903
|
+
* pipeline: segmentTree → buildVslDocument → cache/diff.
|
|
904
|
+
*/
|
|
905
|
+
snapshotFromElements(extractedElements: readonly ExtractedElement[], input: SnapshotInput): SnapshotResult;
|
|
874
906
|
/**
|
|
875
907
|
* Vision-вариант конвейера (T1.5.5): segmentTree → enrichWithVision (Level 5
|
|
876
908
|
* fallback — аннотация t + vf/vf_meta на элементах ДО сборки) → buildVslDocument
|
|
@@ -879,8 +911,18 @@ declare class VslSnapshotSession {
|
|
|
879
911
|
* (base64) возвращаются ОТДЕЛЬНО — в документе только метаданные (DEC-015).
|
|
880
912
|
*/
|
|
881
913
|
snapshotWithVision(root: Element, input: SnapshotInput, vision: EnrichWithVisionDeps): Promise<VisionSnapshotResult>;
|
|
914
|
+
/**
|
|
915
|
+
* Vision-вариант для pre-extracted elements (MCP сервер, Node.js контекст).
|
|
916
|
+
* Полный pipeline: segmentTree → enrichWithVision → buildVslDocument → cache/diff.
|
|
917
|
+
*/
|
|
918
|
+
snapshotWithVisionFromElements(extractedElements: readonly ExtractedElement[], input: SnapshotInput, vision: EnrichWithVisionDeps): Promise<VisionSnapshotResult>;
|
|
882
919
|
/** BuildOptions из input + портативный title (логика бывшего snapshot()). */
|
|
883
920
|
private buildOptions;
|
|
921
|
+
/**
|
|
922
|
+
* BuildOptions из input без DOM Element (для snapshotFromElements).
|
|
923
|
+
* Title берётся только из input (нет фолбэка на root.ownerDocument.title).
|
|
924
|
+
*/
|
|
925
|
+
private buildOptionsFromInput;
|
|
884
926
|
/** Сборка документа + кэш/дифф (логика бывшего snapshot(), см. шапку модуля). */
|
|
885
927
|
private commit;
|
|
886
928
|
}
|
|
@@ -1055,7 +1097,7 @@ declare const ACTION_TOOL_SCHEMA: {
|
|
|
1055
1097
|
action: {
|
|
1056
1098
|
type: string;
|
|
1057
1099
|
description: string;
|
|
1058
|
-
enum: ("select" | "
|
|
1100
|
+
enum: ("select" | "type" | "click" | "close" | "check" | "uncheck" | "clear" | "scroll" | "hover" | "focus" | "blur" | "drag" | "drop" | "submit" | "reset" | "open" | "expand" | "collapse" | "wait" | "navigate" | "go_back" | "go_forward" | "refresh" | "download")[];
|
|
1059
1101
|
};
|
|
1060
1102
|
target_id: {
|
|
1061
1103
|
type: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -60,6 +60,18 @@ interface ElementCss {
|
|
|
60
60
|
pointerEvents?: string;
|
|
61
61
|
overflow?: string;
|
|
62
62
|
height?: string;
|
|
63
|
+
/** Background color (computed) — для sty.bg в VslObject. */
|
|
64
|
+
backgroundColor?: string;
|
|
65
|
+
/** Text/foreground color (computed) — для sty.fg в VslObject. */
|
|
66
|
+
color?: string;
|
|
67
|
+
/** Border shorthand (computed) — для sty.border в VslObject. */
|
|
68
|
+
border?: string;
|
|
69
|
+
/** Border radius (computed) — для sty.radius в VslObject. */
|
|
70
|
+
borderRadius?: string;
|
|
71
|
+
/** Box shadow (computed) — для sty.shadow в VslObject. */
|
|
72
|
+
boxShadow?: string;
|
|
73
|
+
/** Font family (computed) — для sty.font.family в VslObject. */
|
|
74
|
+
fontFamily?: string;
|
|
63
75
|
}
|
|
64
76
|
/** Собственный текст элемента: только прямые текстовые узлы, whitespace-нормализация. */
|
|
65
77
|
declare function ownText(el: Element): string;
|
|
@@ -76,7 +88,7 @@ declare function extractDomTree(root?: Element): ExtractedElement[];
|
|
|
76
88
|
* Семантический тип объекта VSL (поле `t`): L1-теги + L2-роли (T1.1.3/T1.1.4),
|
|
77
89
|
* L3-CSS (T1.5.1), L4-структурные (T1.5.2), L5-vision (T1.5.4).
|
|
78
90
|
*/
|
|
79
|
-
type VslType = 'button' | 'input' | 'link' | 'nav' | 'header' | 'main' | 'container' | 'image' | 'select' | 'textarea' | 'modal' | 'tab' | 'heading' | 'footer' | 'scrollable_container' | 'toolbar' | 'list' | 'grid' | 'form_field' | 'tab_bar' | 'layout' | 'icon' | 'chart' | 'custom_widget' | 'unknown';
|
|
91
|
+
type VslType = 'button' | 'input' | 'file_input' | 'link' | 'nav' | 'header' | 'main' | 'container' | 'image' | 'select' | 'textarea' | 'modal' | 'tab' | 'heading' | 'footer' | 'scrollable_container' | 'toolbar' | 'list' | 'grid' | 'form_field' | 'tab_bar' | 'layout' | 'icon' | 'chart' | 'custom_widget' | 'unknown';
|
|
80
92
|
/** Состояние объекта VSL (поле `st`) — из ARIA-атрибутов (T1.1.4). */
|
|
81
93
|
type VslState = 'checked' | 'expanded' | 'disabled';
|
|
82
94
|
/** Тип визуального фрагмента — выход классификации vision (§2.2.2 Шаг 2). */
|
|
@@ -89,6 +101,29 @@ interface VslFragmentMeta$1 {
|
|
|
89
101
|
hash?: string;
|
|
90
102
|
cached_at?: string;
|
|
91
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Визуальные стили объекта VSL (DESIGN_SYSTEM.md §4.3).
|
|
106
|
+
* Optional: только для визуально значимых элементов.
|
|
107
|
+
* Все значения — computed styles в момент snapshot.
|
|
108
|
+
*/
|
|
109
|
+
interface VslStyle {
|
|
110
|
+
/** Background color (computed). */
|
|
111
|
+
bg?: string;
|
|
112
|
+
/** Text/foreground color (computed). */
|
|
113
|
+
fg?: string;
|
|
114
|
+
/** Border shorthand (computed). */
|
|
115
|
+
border?: string;
|
|
116
|
+
/** Border radius (computed). */
|
|
117
|
+
radius?: string;
|
|
118
|
+
/** Box shadow (computed). */
|
|
119
|
+
shadow?: string;
|
|
120
|
+
/** Font properties. */
|
|
121
|
+
font?: {
|
|
122
|
+
family?: string;
|
|
123
|
+
size?: string;
|
|
124
|
+
weight?: string;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
92
127
|
/**
|
|
93
128
|
* Запись реестра visual_fragments документа (§2.2.2, ARCHITECTURE.md:L265-284).
|
|
94
129
|
* ТОЛЬКО метаданные: base64-данные изображений живут в VisualFragmentStore
|
|
@@ -148,6 +183,12 @@ interface VslObject {
|
|
|
148
183
|
vf?: string;
|
|
149
184
|
/** Метаданные фрагмента (§4.4). */
|
|
150
185
|
vf_meta?: VslFragmentMeta$1;
|
|
186
|
+
/** Визуальные стили (DESIGN_SYSTEM.md §4.3). Optional: только для визуально значимых элементов. */
|
|
187
|
+
sty?: VslStyle;
|
|
188
|
+
/** Accept attribute для file_input (например, '.pdf,.docx'). */
|
|
189
|
+
accept?: string;
|
|
190
|
+
/** Multiple attribute для file_input — разрешена загрузка нескольких файлов. */
|
|
191
|
+
multiple?: boolean;
|
|
151
192
|
}
|
|
152
193
|
interface VslDocument {
|
|
153
194
|
vsl_version: string;
|
|
@@ -250,6 +291,8 @@ interface SegmentedElement {
|
|
|
250
291
|
txt: string | null;
|
|
251
292
|
/** Состояние из ARIA (checked/expanded/disabled) или null. */
|
|
252
293
|
st: VslState | null;
|
|
294
|
+
/** CSS-подмножество для визуальных стилей (передаётся в Builder для sty). */
|
|
295
|
+
css?: ElementCss;
|
|
253
296
|
ch: SegmentedElement[];
|
|
254
297
|
/** Ссылка на визуальный фрагмент (заполняется enrichWithVision, T1.5.4). */
|
|
255
298
|
vf?: string;
|
|
@@ -802,32 +845,6 @@ interface EnrichWithVisionDeps {
|
|
|
802
845
|
extractor: FragmentExtractor;
|
|
803
846
|
}
|
|
804
847
|
|
|
805
|
-
/**
|
|
806
|
-
* VSL Snapshot Session (T1.2.4, ROADMAP.md M1.2; ARCHITECTURE.md §2.4/§5.2/§6.3).
|
|
807
|
-
*
|
|
808
|
-
* Stateful-фасад над пайплайном capture→segment→build→cache→diff:
|
|
809
|
-
* - первый вызов или смена URL → полный VslDocument; кэш очищается и
|
|
810
|
-
* заполняется объектами документа; счётчик версий сбрасывается в 1;
|
|
811
|
-
* - тот же URL → VslDiff последнего документа против нового (формат §6.2):
|
|
812
|
-
* diff_version = version + 1, base_version = version;
|
|
813
|
-
* - viewport изменился при том же URL → дополнительно
|
|
814
|
-
* store.invalidateCoordinates() — «сброс координат» §5.2, НЕ полный сброс.
|
|
815
|
-
*
|
|
816
|
-
* Состояние {lastUrl, lastViewport, lastDocument, version} — в памяти
|
|
817
|
-
* экземпляра; VslDocument (канон §4) версиями НЕ расширяется.
|
|
818
|
-
*
|
|
819
|
-
* Политика кэша — store отражает текущий документ: full → clear + заполнение;
|
|
820
|
-
* diff → удалённые invalidate, добавленные (поддеревья) и изменённые set из
|
|
821
|
-
* нового документа; неизменённые остаются кэшированными (после resize — с
|
|
822
|
-
* обнулённым coordHash: наблюдаемый эффект invalidateCoordinates).
|
|
823
|
-
*
|
|
824
|
-
* input.url/viewport/timestamp/background передаются в BuildOptions ЯВНО —
|
|
825
|
-
* дефолты builder (window.innerWidth/innerHeight/location.href/document.title)
|
|
826
|
-
* вычислялись бы от глобалов: недетерминированны в тестах и недоступны в Node;
|
|
827
|
-
* title — из input, иначе root.ownerDocument.title (портативный фолбэк — фикс
|
|
828
|
-
* packaging-smoke demo:cache-diff).
|
|
829
|
-
*/
|
|
830
|
-
|
|
831
848
|
/** Результат snapshot(): полный документ (1-й вызов / URL change) или дифф. */
|
|
832
849
|
type SnapshotResult = VslDocument | VslDiff;
|
|
833
850
|
/** Type guard: различение диффа и полного документа (контракт T1.2.4). */
|
|
@@ -866,11 +883,26 @@ declare class VslSnapshotSession {
|
|
|
866
883
|
private lastDocument;
|
|
867
884
|
private version;
|
|
868
885
|
constructor(store?: CacheStore);
|
|
886
|
+
/**
|
|
887
|
+
* Сбрасывает состояние сессии (URL, viewport, документ, версия).
|
|
888
|
+
* Следующий вызов snapshot() вернёт полный документ (как первый вызов).
|
|
889
|
+
*/
|
|
890
|
+
clear(): void;
|
|
891
|
+
/** Возвращает последний полный документ (не diff). */
|
|
892
|
+
getLastDocument(): VslDocument | null;
|
|
893
|
+
/** Текущая версия документа (инкрементируется при каждом diff). */
|
|
894
|
+
getVersion(): number;
|
|
869
895
|
/**
|
|
870
896
|
* Строит VSL из DOM поддерева root (extractDomTree → segmentTree →
|
|
871
897
|
* buildVslDocument) и возвращает полный документ либо дифф (см. шапку).
|
|
872
898
|
*/
|
|
873
899
|
snapshot(root: Element, input: SnapshotInput): SnapshotResult;
|
|
900
|
+
/**
|
|
901
|
+
* Вариант snapshot() для pre-extracted elements (MCP сервер, Node.js контекст).
|
|
902
|
+
* Принимает ExtractedElement[] напрямую (без DOM Element), проходит тот же
|
|
903
|
+
* pipeline: segmentTree → buildVslDocument → cache/diff.
|
|
904
|
+
*/
|
|
905
|
+
snapshotFromElements(extractedElements: readonly ExtractedElement[], input: SnapshotInput): SnapshotResult;
|
|
874
906
|
/**
|
|
875
907
|
* Vision-вариант конвейера (T1.5.5): segmentTree → enrichWithVision (Level 5
|
|
876
908
|
* fallback — аннотация t + vf/vf_meta на элементах ДО сборки) → buildVslDocument
|
|
@@ -879,8 +911,18 @@ declare class VslSnapshotSession {
|
|
|
879
911
|
* (base64) возвращаются ОТДЕЛЬНО — в документе только метаданные (DEC-015).
|
|
880
912
|
*/
|
|
881
913
|
snapshotWithVision(root: Element, input: SnapshotInput, vision: EnrichWithVisionDeps): Promise<VisionSnapshotResult>;
|
|
914
|
+
/**
|
|
915
|
+
* Vision-вариант для pre-extracted elements (MCP сервер, Node.js контекст).
|
|
916
|
+
* Полный pipeline: segmentTree → enrichWithVision → buildVslDocument → cache/diff.
|
|
917
|
+
*/
|
|
918
|
+
snapshotWithVisionFromElements(extractedElements: readonly ExtractedElement[], input: SnapshotInput, vision: EnrichWithVisionDeps): Promise<VisionSnapshotResult>;
|
|
882
919
|
/** BuildOptions из input + портативный title (логика бывшего snapshot()). */
|
|
883
920
|
private buildOptions;
|
|
921
|
+
/**
|
|
922
|
+
* BuildOptions из input без DOM Element (для snapshotFromElements).
|
|
923
|
+
* Title берётся только из input (нет фолбэка на root.ownerDocument.title).
|
|
924
|
+
*/
|
|
925
|
+
private buildOptionsFromInput;
|
|
884
926
|
/** Сборка документа + кэш/дифф (логика бывшего snapshot(), см. шапку модуля). */
|
|
885
927
|
private commit;
|
|
886
928
|
}
|
|
@@ -1055,7 +1097,7 @@ declare const ACTION_TOOL_SCHEMA: {
|
|
|
1055
1097
|
action: {
|
|
1056
1098
|
type: string;
|
|
1057
1099
|
description: string;
|
|
1058
|
-
enum: ("select" | "
|
|
1100
|
+
enum: ("select" | "type" | "click" | "close" | "check" | "uncheck" | "clear" | "scroll" | "hover" | "focus" | "blur" | "drag" | "drop" | "submit" | "reset" | "open" | "expand" | "collapse" | "wait" | "navigate" | "go_back" | "go_forward" | "refresh" | "download")[];
|
|
1059
1101
|
};
|
|
1060
1102
|
target_id: {
|
|
1061
1103
|
type: string;
|
package/dist/index.js
CHANGED
|
@@ -109,7 +109,13 @@ var CSS_PROPERTIES = [
|
|
|
109
109
|
["opacity", "opacity"],
|
|
110
110
|
["pointerEvents", "pointer-events"],
|
|
111
111
|
["overflow", "overflow"],
|
|
112
|
-
["height", "height"]
|
|
112
|
+
["height", "height"],
|
|
113
|
+
["backgroundColor", "background-color"],
|
|
114
|
+
["color", "color"],
|
|
115
|
+
["border", "border"],
|
|
116
|
+
["borderRadius", "border-radius"],
|
|
117
|
+
["boxShadow", "box-shadow"],
|
|
118
|
+
["fontFamily", "font-family"]
|
|
113
119
|
];
|
|
114
120
|
function captureCss(el) {
|
|
115
121
|
const view = viewOf(el);
|
|
@@ -319,14 +325,16 @@ function isAriaHidden(attributes) {
|
|
|
319
325
|
}
|
|
320
326
|
function segmentOne(el) {
|
|
321
327
|
const { attributes } = el;
|
|
328
|
+
const isFileInput = el.tag === "input" && attributes["type"] === "file";
|
|
322
329
|
return {
|
|
323
330
|
tag: el.tag,
|
|
324
331
|
indexPath: el.indexPath,
|
|
325
332
|
rect: el.rect,
|
|
326
333
|
attributes,
|
|
327
|
-
t: resolveLevel1Type(el.tag) ?? resolveAriaRoleType(attributes["role"]) ?? resolveLevel3Type(el.css, attributes),
|
|
334
|
+
t: isFileInput ? "file_input" : resolveLevel1Type(el.tag) ?? resolveAriaRoleType(attributes["role"]) ?? resolveLevel3Type(el.css, attributes),
|
|
328
335
|
txt: attributes["aria-label"] ?? el.text,
|
|
329
336
|
st: resolveSt(attributes),
|
|
337
|
+
css: el.css,
|
|
330
338
|
ch: []
|
|
331
339
|
};
|
|
332
340
|
}
|
|
@@ -379,6 +387,8 @@ function defaultActions(t, st, attributes) {
|
|
|
379
387
|
return ["click", "select"];
|
|
380
388
|
case "textarea":
|
|
381
389
|
return ["click", "type", "clear"];
|
|
390
|
+
case "file_input":
|
|
391
|
+
return ["click", "upload"];
|
|
382
392
|
default:
|
|
383
393
|
return void 0;
|
|
384
394
|
}
|
|
@@ -391,6 +401,39 @@ function baseSemanticScore(el) {
|
|
|
391
401
|
if (el.txt) score += 1;
|
|
392
402
|
return score;
|
|
393
403
|
}
|
|
404
|
+
function extractVisualStyles(css) {
|
|
405
|
+
if (!css) return void 0;
|
|
406
|
+
const style = {};
|
|
407
|
+
let hasContent = false;
|
|
408
|
+
if (css.backgroundColor && css.backgroundColor !== "transparent" && !css.backgroundColor.includes("rgba(0, 0, 0, 0)")) {
|
|
409
|
+
style.bg = css.backgroundColor;
|
|
410
|
+
hasContent = true;
|
|
411
|
+
}
|
|
412
|
+
if (css.color && css.color !== "rgb(0, 0, 0)") {
|
|
413
|
+
style.fg = css.color;
|
|
414
|
+
hasContent = true;
|
|
415
|
+
}
|
|
416
|
+
if (css.border && css.border !== "none" && !css.border.startsWith("0px")) {
|
|
417
|
+
style.border = css.border;
|
|
418
|
+
hasContent = true;
|
|
419
|
+
}
|
|
420
|
+
if (css.borderRadius && css.borderRadius !== "0px") {
|
|
421
|
+
style.radius = css.borderRadius;
|
|
422
|
+
hasContent = true;
|
|
423
|
+
}
|
|
424
|
+
if (css.boxShadow && css.boxShadow !== "none") {
|
|
425
|
+
style.shadow = css.boxShadow;
|
|
426
|
+
hasContent = true;
|
|
427
|
+
}
|
|
428
|
+
if (css.fontFamily || css.fontSize || css.fontWeight) {
|
|
429
|
+
style.font = {};
|
|
430
|
+
if (css.fontFamily) style.font.family = css.fontFamily;
|
|
431
|
+
if (css.fontSize) style.font.size = css.fontSize;
|
|
432
|
+
if (css.fontWeight) style.font.weight = css.fontWeight;
|
|
433
|
+
hasContent = true;
|
|
434
|
+
}
|
|
435
|
+
return hasContent ? style : void 0;
|
|
436
|
+
}
|
|
394
437
|
function toVslObject(el, viewport, includedChildren, textBlocks, counter) {
|
|
395
438
|
const t = el.t ?? "container";
|
|
396
439
|
const object = {
|
|
@@ -417,6 +460,12 @@ function toVslObject(el, viewport, includedChildren, textBlocks, counter) {
|
|
|
417
460
|
if (includedChildren.length > 0) object.ch = includedChildren;
|
|
418
461
|
if (el.vf !== void 0) object.vf = el.vf;
|
|
419
462
|
if (el.vf_meta !== void 0) object.vf_meta = el.vf_meta;
|
|
463
|
+
const sty = extractVisualStyles(el.css);
|
|
464
|
+
if (sty !== void 0) object.sty = sty;
|
|
465
|
+
if (t === "file_input") {
|
|
466
|
+
if (el.attributes["accept"] !== void 0) object.accept = el.attributes["accept"];
|
|
467
|
+
if (el.attributes["multiple"] !== void 0) object.multiple = true;
|
|
468
|
+
}
|
|
420
469
|
return object;
|
|
421
470
|
}
|
|
422
471
|
function convert(el, viewport, textBlocks, counter) {
|
|
@@ -603,6 +652,8 @@ function objectsEqual(a, b) {
|
|
|
603
652
|
return computeContentHash(a) === computeContentHash(b) && computeCoordHash(a) === computeCoordHash(b);
|
|
604
653
|
}
|
|
605
654
|
function tuple2Equal(a, b) {
|
|
655
|
+
if (a === null || a === void 0) return b === null || b === void 0;
|
|
656
|
+
if (b === null || b === void 0) return false;
|
|
606
657
|
return a[0] === b[0] && a[1] === b[1];
|
|
607
658
|
}
|
|
608
659
|
function stringArrayEqual(a, b) {
|
|
@@ -739,6 +790,25 @@ var VslSnapshotSession = class {
|
|
|
739
790
|
constructor(store = createCacheStore()) {
|
|
740
791
|
this.store = store;
|
|
741
792
|
}
|
|
793
|
+
/**
|
|
794
|
+
* Сбрасывает состояние сессии (URL, viewport, документ, версия).
|
|
795
|
+
* Следующий вызов snapshot() вернёт полный документ (как первый вызов).
|
|
796
|
+
*/
|
|
797
|
+
clear() {
|
|
798
|
+
this.store.clear();
|
|
799
|
+
this.lastUrl = null;
|
|
800
|
+
this.lastViewport = null;
|
|
801
|
+
this.lastDocument = null;
|
|
802
|
+
this.version = 0;
|
|
803
|
+
}
|
|
804
|
+
/** Возвращает последний полный документ (не diff). */
|
|
805
|
+
getLastDocument() {
|
|
806
|
+
return this.lastDocument;
|
|
807
|
+
}
|
|
808
|
+
/** Текущая версия документа (инкрементируется при каждом diff). */
|
|
809
|
+
getVersion() {
|
|
810
|
+
return this.version;
|
|
811
|
+
}
|
|
742
812
|
/**
|
|
743
813
|
* Строит VSL из DOM поддерева root (extractDomTree → segmentTree →
|
|
744
814
|
* buildVslDocument) и возвращает полный документ либо дифф (см. шапку).
|
|
@@ -747,6 +817,15 @@ var VslSnapshotSession = class {
|
|
|
747
817
|
const elements = segmentTree(extractDomTree(root));
|
|
748
818
|
return this.commit(elements, this.buildOptions(root, input), input);
|
|
749
819
|
}
|
|
820
|
+
/**
|
|
821
|
+
* Вариант snapshot() для pre-extracted elements (MCP сервер, Node.js контекст).
|
|
822
|
+
* Принимает ExtractedElement[] напрямую (без DOM Element), проходит тот же
|
|
823
|
+
* pipeline: segmentTree → buildVslDocument → cache/diff.
|
|
824
|
+
*/
|
|
825
|
+
snapshotFromElements(extractedElements, input) {
|
|
826
|
+
const elements = segmentTree(extractedElements);
|
|
827
|
+
return this.commit(elements, this.buildOptionsFromInput(input), input);
|
|
828
|
+
}
|
|
750
829
|
/**
|
|
751
830
|
* Vision-вариант конвейера (T1.5.5): segmentTree → enrichWithVision (Level 5
|
|
752
831
|
* fallback — аннотация t + vf/vf_meta на элементах ДО сборки) → buildVslDocument
|
|
@@ -760,6 +839,16 @@ var VslSnapshotSession = class {
|
|
|
760
839
|
const snapshot = this.commit(elements, this.buildOptions(root, input), input);
|
|
761
840
|
return { snapshot, fragments: visionResult.fragments };
|
|
762
841
|
}
|
|
842
|
+
/**
|
|
843
|
+
* Vision-вариант для pre-extracted elements (MCP сервер, Node.js контекст).
|
|
844
|
+
* Полный pipeline: segmentTree → enrichWithVision → buildVslDocument → cache/diff.
|
|
845
|
+
*/
|
|
846
|
+
async snapshotWithVisionFromElements(extractedElements, input, vision) {
|
|
847
|
+
const elements = segmentTree(extractedElements);
|
|
848
|
+
const visionResult = await enrichWithVision(elements, vision);
|
|
849
|
+
const snapshot = this.commit(elements, this.buildOptionsFromInput(input), input);
|
|
850
|
+
return { snapshot, fragments: visionResult.fragments };
|
|
851
|
+
}
|
|
763
852
|
/** BuildOptions из input + портативный title (логика бывшего snapshot()). */
|
|
764
853
|
buildOptions(root, input) {
|
|
765
854
|
const options = {
|
|
@@ -771,6 +860,20 @@ var VslSnapshotSession = class {
|
|
|
771
860
|
if (input.background !== void 0) options.background = input.background;
|
|
772
861
|
return options;
|
|
773
862
|
}
|
|
863
|
+
/**
|
|
864
|
+
* BuildOptions из input без DOM Element (для snapshotFromElements).
|
|
865
|
+
* Title берётся только из input (нет фолбэка на root.ownerDocument.title).
|
|
866
|
+
*/
|
|
867
|
+
buildOptionsFromInput(input) {
|
|
868
|
+
const options = {
|
|
869
|
+
viewport: { width: input.viewport.width, height: input.viewport.height },
|
|
870
|
+
url: input.url
|
|
871
|
+
};
|
|
872
|
+
if (input.title !== void 0) options.title = input.title;
|
|
873
|
+
if (input.timestamp !== void 0) options.timestamp = input.timestamp;
|
|
874
|
+
if (input.background !== void 0) options.background = input.background;
|
|
875
|
+
return options;
|
|
876
|
+
}
|
|
774
877
|
/** Сборка документа + кэш/дифф (логика бывшего snapshot(), см. шапку модуля). */
|
|
775
878
|
commit(elements, options, input) {
|
|
776
879
|
const nextDocument = buildVslDocument(elements, options);
|