@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/cli/index.js +2 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +116 -1
- package/dist/index.js +120 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
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
|