@thinkingos/vsl-sdk 0.1.1 → 0.2.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 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;
@@ -1055,7 +1098,7 @@ declare const ACTION_TOOL_SCHEMA: {
1055
1098
  action: {
1056
1099
  type: string;
1057
1100
  description: string;
1058
- enum: ("select" | "click" | "close" | "type" | "check" | "uncheck" | "clear" | "scroll" | "hover" | "focus" | "blur" | "drag" | "drop" | "submit" | "reset" | "open" | "expand" | "collapse" | "wait" | "navigate" | "go_back" | "go_forward" | "refresh" | "download")[];
1101
+ 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
1102
  };
1060
1103
  target_id: {
1061
1104
  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;
@@ -1055,7 +1098,7 @@ declare const ACTION_TOOL_SCHEMA: {
1055
1098
  action: {
1056
1099
  type: string;
1057
1100
  description: string;
1058
- enum: ("select" | "click" | "close" | "type" | "check" | "uncheck" | "clear" | "scroll" | "hover" | "focus" | "blur" | "drag" | "drop" | "submit" | "reset" | "open" | "expand" | "collapse" | "wait" | "navigate" | "go_back" | "go_forward" | "refresh" | "download")[];
1101
+ 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
1102
  };
1060
1103
  target_id: {
1061
1104
  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) {