@sightmap/sightmap 0.5.1 → 0.6.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.ts CHANGED
@@ -51,4 +51,119 @@ interface CanonicalizeOptions {
51
51
  }
52
52
  declare function canonicalize(input: string, opts: CanonicalizeOptions): CanonicalizeResult;
53
53
 
54
- export { type CanonicalizeOptions, type CanonicalizeResult, Diagnostic, type FormatInput, Sightmap, ValidateResult, canonicalize, format, lint, loadDirectory, validate };
54
+ interface BoundingRect {
55
+ x: number;
56
+ y: number;
57
+ width: number;
58
+ height: number;
59
+ }
60
+ /**
61
+ * What an engine adapter's in-page evaluate returns for each sightmap
62
+ * component. matchCount is the number of DOM elements matched (after
63
+ * dedup); samplePosition is the bounding rect of the first match.
64
+ *
65
+ * Engine adapters produce this shape from their own browser-evaluate
66
+ * mechanism; the kernel does not care how.
67
+ */
68
+ interface InPageSightmapMatch {
69
+ name: string;
70
+ selector: string[];
71
+ matchCount: number;
72
+ samplePosition?: BoundingRect | undefined;
73
+ }
74
+ interface EnrichSnapshotInput {
75
+ sightmap: Sightmap;
76
+ currentUrl: string;
77
+ inPageMatches: InPageSightmapMatch[];
78
+ }
79
+ interface SightmapSnapshotComponent {
80
+ name: string;
81
+ selector: string[];
82
+ memory: string[];
83
+ scope: "global" | "view-scoped";
84
+ matchCount: number;
85
+ samplePosition?: BoundingRect | undefined;
86
+ }
87
+ interface EnrichedSnapshot {
88
+ view: {
89
+ name: string;
90
+ route: string;
91
+ memory: string[];
92
+ } | null;
93
+ components: SightmapSnapshotComponent[];
94
+ memory: string[];
95
+ }
96
+ /**
97
+ * Pure function: combines a sightmap, the agent's current URL, and the
98
+ * in-page sightmap match results into an engine-agnostic enriched snapshot.
99
+ *
100
+ * Engine adapters typically wrap this and add their own passthrough fields
101
+ * (e.g. @sightmap/mcp adds ariaSnapshot for the Playwright MCP a11y text).
102
+ * The kernel never touches engine-specific text formats.
103
+ */
104
+ declare function enrichSnapshot(input: EnrichSnapshotInput): EnrichedSnapshot;
105
+
106
+ interface ResolveSightmapActInput {
107
+ componentName: string;
108
+ }
109
+ type ResolveSightmapActResult = {
110
+ kind: "ok";
111
+ componentName: string;
112
+ selector: string;
113
+ allSelectors: string[];
114
+ } | {
115
+ kind: "error";
116
+ message: string;
117
+ };
118
+ /**
119
+ * Resolve a sightmap component by name to a CSS selector that an engine
120
+ * adapter's action verb (click/type/hover/...) can use as the target.
121
+ *
122
+ * Lookup order:
123
+ * 1. Global components (sightmap.globalComponents)
124
+ * 2. View-scoped components, walking each view's components list
125
+ *
126
+ * The first selector in the matching component's selector array is
127
+ * returned; additional selectors are exposed in allSelectors so callers
128
+ * can fall back if the engine's first-selector resolution fails.
129
+ */
130
+ declare function resolveSightmapAct(sightmap: Sightmap, input: ResolveSightmapActInput): ResolveSightmapActResult;
131
+
132
+ interface ParsedNetworkRequest {
133
+ method: string;
134
+ url: string;
135
+ status: number;
136
+ statusText: string;
137
+ }
138
+ interface AnnotatedNetworkRequest extends ParsedNetworkRequest {
139
+ sightmapName?: string;
140
+ sightmapMemory?: string[];
141
+ }
142
+ /**
143
+ * Cross-reference each captured network request with sightmap's `requests:`
144
+ * declarations. When a match is found, attaches the sightmap name + memory
145
+ * to the response. Unmatched requests are returned unchanged.
146
+ *
147
+ * The `requests` input is already normalized; this function does not parse
148
+ * any engine-specific text format. Engine adapters do their own parsing.
149
+ */
150
+ declare function annotateNetworkRequests(sightmap: Sightmap, requests: ParsedNetworkRequest[]): AnnotatedNetworkRequest[];
151
+
152
+ /**
153
+ * Build the in-page evaluate function body. Embeds the component selectors
154
+ * inline; the page only needs to query the DOM. No sightmap-js dependency
155
+ * in the page context.
156
+ *
157
+ * Engine adapters serialize this string and pass it to their browser's
158
+ * `evaluate` primitive (Playwright MCP's `browser_evaluate`, Playwright
159
+ * CLI's `playwright-cli eval`, etc.). The output shape is
160
+ * `{ url: string, matches: InPageSightmapMatch[] }` — adapters do their
161
+ * own parsing of the engine's wrapping (e.g. Playwright MCP's
162
+ * `### Result` framing).
163
+ */
164
+ declare function buildInPageEvalFunction(components: Array<{
165
+ name: string;
166
+ selector: string[];
167
+ }>): string;
168
+
169
+ export { type AnnotatedNetworkRequest, type BoundingRect, type CanonicalizeOptions, type CanonicalizeResult, Diagnostic, type EnrichSnapshotInput, type EnrichedSnapshot, type FormatInput, type InPageSightmapMatch, type ParsedNetworkRequest, type ResolveSightmapActInput, type ResolveSightmapActResult, Sightmap, type SightmapSnapshotComponent, ValidateResult, annotateNetworkRequests, buildInPageEvalFunction, canonicalize, enrichSnapshot, format, lint, loadDirectory, resolveSightmapAct, validate };
package/dist/index.js CHANGED
@@ -968,6 +968,122 @@ function serialize(doc) {
968
968
  });
969
969
  return out.endsWith("\n") ? out : out + "\n";
970
970
  }
971
+
972
+ // src/enrich/snapshot.ts
973
+ function enrichSnapshot(input) {
974
+ const { sightmap, currentUrl, inPageMatches } = input;
975
+ const result = match(sightmap, { url: currentUrl });
976
+ const inPageByName = /* @__PURE__ */ new Map();
977
+ for (const m of inPageMatches) inPageByName.set(m.name, m);
978
+ const components = result.components.map((c) => {
979
+ const inPage = inPageByName.get(c.name);
980
+ return {
981
+ name: c.name,
982
+ selector: c.selector,
983
+ memory: c.memory ?? [],
984
+ scope: c.scope,
985
+ matchCount: inPage?.matchCount ?? 0,
986
+ ...inPage?.samplePosition !== void 0 ? { samplePosition: inPage.samplePosition } : {}
987
+ };
988
+ });
989
+ return {
990
+ view: result.view ? {
991
+ name: result.view.name,
992
+ route: result.view.route,
993
+ memory: result.view.memory ?? []
994
+ } : null,
995
+ components,
996
+ memory: result.memory ?? []
997
+ };
998
+ }
999
+
1000
+ // src/enrich/act.ts
1001
+ function resolveSightmapAct(sightmap, input) {
1002
+ const found = findComponentByName(sightmap, input.componentName);
1003
+ if (found === null) {
1004
+ return {
1005
+ kind: "error",
1006
+ message: `Component "${input.componentName}" not found in the loaded sightmap.`
1007
+ };
1008
+ }
1009
+ const selectors = Array.isArray(found.selector) ? found.selector : [];
1010
+ if (selectors.length === 0) {
1011
+ return {
1012
+ kind: "error",
1013
+ message: `Component "${input.componentName}" has no selector \u2014 cannot dispatch an action.`
1014
+ };
1015
+ }
1016
+ return {
1017
+ kind: "ok",
1018
+ componentName: input.componentName,
1019
+ selector: selectors[0],
1020
+ allSelectors: selectors
1021
+ };
1022
+ }
1023
+ function findComponentByName(sightmap, name) {
1024
+ for (const c of sightmap.globalComponents) {
1025
+ if (c.name === name) return c;
1026
+ }
1027
+ for (const v of sightmap.views) {
1028
+ for (const c of v.components ?? []) {
1029
+ if (c.name === name) return c;
1030
+ }
1031
+ }
1032
+ return null;
1033
+ }
1034
+
1035
+ // src/enrich/network.ts
1036
+ function annotateNetworkRequests(sightmap, requests) {
1037
+ return requests.map((req) => {
1038
+ const result = match(sightmap, { url: req.url, method: req.method });
1039
+ const first = result.requests[0];
1040
+ if (first === void 0) return req;
1041
+ const annotated = { ...req, sightmapName: first.name };
1042
+ if (first.memory && first.memory.length > 0) {
1043
+ annotated.sightmapMemory = first.memory;
1044
+ }
1045
+ return annotated;
1046
+ });
1047
+ }
1048
+
1049
+ // src/enrich/in-page.ts
1050
+ function buildInPageEvalFunction(components) {
1051
+ const componentsJson = JSON.stringify(components);
1052
+ return `() => {
1053
+ const components = ${componentsJson};
1054
+ const matches = components.map((c) => {
1055
+ const selectors = c.selector || [];
1056
+ const seen = new Set();
1057
+ const elements = [];
1058
+ for (const sel of selectors) {
1059
+ try {
1060
+ const found = document.querySelectorAll(sel);
1061
+ for (const el of Array.from(found)) {
1062
+ if (!seen.has(el)) {
1063
+ seen.add(el);
1064
+ elements.push(el);
1065
+ }
1066
+ }
1067
+ } catch {
1068
+ // Invalid selector \u2014 skip silently.
1069
+ }
1070
+ }
1071
+ const first = elements[0];
1072
+ let samplePosition;
1073
+ if (first && typeof first.getBoundingClientRect === "function") {
1074
+ const r = first.getBoundingClientRect();
1075
+ samplePosition = { x: r.x, y: r.y, width: r.width, height: r.height };
1076
+ }
1077
+ return {
1078
+ name: c.name,
1079
+ selector: selectors,
1080
+ matchCount: elements.length,
1081
+ samplePosition,
1082
+ };
1083
+ });
1084
+ return { url: window.location.href, matches };
1085
+ }`;
1086
+ }
971
1087
  export {
972
1088
  DUPLICATE_ROUTE,
973
1089
  DUPLICATE_VIEW_NAME,
@@ -982,7 +1098,10 @@ export {
982
1098
  SELECTOR_SYNTAX,
983
1099
  UNKNOWN_SOURCE,
984
1100
  UNKNOWN_VERSION,
1101
+ annotateNetworkRequests,
1102
+ buildInPageEvalFunction,
985
1103
  canonicalize,
1104
+ enrichSnapshot,
986
1105
  explain,
987
1106
  format,
988
1107
  lint,
@@ -990,6 +1109,7 @@ export {
990
1109
  match,
991
1110
  merge,
992
1111
  parse,
1112
+ resolveSightmapAct,
993
1113
  validate
994
1114
  };
995
1115
  //# sourceMappingURL=index.js.map