@spotpatch/runtime 1.4.0 → 1.5.1
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/README.md +3 -7
- package/dist/index.cjs +892 -546
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +890 -544
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -3,9 +3,9 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (
|
|
6
|
+
var __export = (target2, all) => {
|
|
7
7
|
for (var name in all)
|
|
8
|
-
__defProp(
|
|
8
|
+
__defProp(target2, name, { get: all[name], enumerable: true });
|
|
9
9
|
};
|
|
10
10
|
var __copyProps = (to, from, except, desc) => {
|
|
11
11
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
@@ -31,45 +31,46 @@ var import_shared9 = require("@spotpatch/shared");
|
|
|
31
31
|
|
|
32
32
|
// src/annotation/create-annotation.ts
|
|
33
33
|
var import_shared = require("@spotpatch/shared");
|
|
34
|
-
function freezeSource(
|
|
34
|
+
function freezeSource(source2, code2) {
|
|
35
35
|
return Object.freeze({
|
|
36
|
-
...
|
|
37
|
-
...
|
|
36
|
+
...source2,
|
|
37
|
+
...source2.relativePath === void 0 && code2 !== void 0 ? { relativePath: code2.relativePath } : {}
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
|
-
function freezeReact(
|
|
40
|
+
function freezeReact(react2) {
|
|
41
41
|
return Object.freeze({
|
|
42
|
-
...
|
|
43
|
-
componentStack: Object.freeze([...
|
|
44
|
-
...
|
|
42
|
+
...react2,
|
|
43
|
+
componentStack: Object.freeze([...react2.componentStack]),
|
|
44
|
+
...react2.source === void 0 ? {} : { source: freezeSource(react2.source) }
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
|
-
function freezeElement(
|
|
47
|
+
function freezeElement(element2) {
|
|
48
48
|
return Object.freeze({
|
|
49
|
-
...
|
|
50
|
-
rect: Object.freeze({ ...
|
|
49
|
+
...element2,
|
|
50
|
+
rect: Object.freeze({ ...element2.rect })
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
|
-
function freezeStyles(
|
|
53
|
+
function freezeStyles(styles2) {
|
|
54
54
|
return Object.freeze({
|
|
55
|
-
...
|
|
56
|
-
classNames: Object.freeze([...
|
|
55
|
+
...styles2,
|
|
56
|
+
classNames: Object.freeze([...styles2.classNames]),
|
|
57
57
|
matchedRules: Object.freeze(
|
|
58
|
-
|
|
58
|
+
styles2.matchedRules.map((rule) => Object.freeze({ ...rule }))
|
|
59
59
|
),
|
|
60
|
-
computed: Object.freeze({ ...
|
|
61
|
-
warnings: Object.freeze([...
|
|
60
|
+
computed: Object.freeze({ ...styles2.computed }),
|
|
61
|
+
warnings: Object.freeze([...styles2.warnings])
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
|
-
function freezeTarget(
|
|
64
|
+
function freezeTarget(target2) {
|
|
65
65
|
return Object.freeze({
|
|
66
|
-
instruction:
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
instruction: target2.instruction.trim(),
|
|
67
|
+
...target2.page === void 0 ? {} : { page: Object.freeze({ ...target2.page }) },
|
|
68
|
+
source: freezeSource(target2.source, target2.code),
|
|
69
|
+
react: freezeReact(target2.react),
|
|
70
|
+
element: freezeElement(target2.element),
|
|
71
|
+
styles: freezeStyles(target2.styles),
|
|
72
|
+
...target2.code === void 0 ? {} : { code: Object.freeze({ ...target2.code }) },
|
|
73
|
+
warnings: Object.freeze([...target2.warnings])
|
|
73
74
|
});
|
|
74
75
|
}
|
|
75
76
|
function createAnnotation(input) {
|
|
@@ -78,7 +79,7 @@ function createAnnotation(input) {
|
|
|
78
79
|
`SpotPatch annotations require between 1 and ${String(import_shared.MAX_ANNOTATION_TARGETS)} targets.`
|
|
79
80
|
);
|
|
80
81
|
}
|
|
81
|
-
const instructions = input.targets.map((
|
|
82
|
+
const instructions = input.targets.map((target2) => target2.instruction.trim());
|
|
82
83
|
if (instructions.some(
|
|
83
84
|
(instruction) => instruction.length === 0 || instruction.length > import_shared.MAX_TARGET_INSTRUCTION_CHARACTERS
|
|
84
85
|
) || instructions.reduce((total, instruction) => total + instruction.length, 0) > import_shared.MAX_ANNOTATION_INSTRUCTION_CHARACTERS) {
|
|
@@ -265,10 +266,10 @@ var MAX_EVENT_LINE_BYTES = 1e5;
|
|
|
265
266
|
var MAX_EVENT_STREAM_BYTES = 4e6;
|
|
266
267
|
var RuntimeApiError = class extends Error {
|
|
267
268
|
code;
|
|
268
|
-
constructor(
|
|
269
|
+
constructor(code2) {
|
|
269
270
|
super("SpotPatch local API request failed.");
|
|
270
271
|
this.name = "RuntimeApiError";
|
|
271
|
-
this.code =
|
|
272
|
+
this.code = code2;
|
|
272
273
|
}
|
|
273
274
|
};
|
|
274
275
|
function isRecord2(value) {
|
|
@@ -340,9 +341,9 @@ async function readBoundedText(response, maximumBytes) {
|
|
|
340
341
|
reader.releaseLock();
|
|
341
342
|
}
|
|
342
343
|
}
|
|
343
|
-
function parseJson(
|
|
344
|
+
function parseJson(text2) {
|
|
344
345
|
try {
|
|
345
|
-
return JSON.parse(
|
|
346
|
+
return JSON.parse(text2);
|
|
346
347
|
} catch {
|
|
347
348
|
throw new RuntimeApiError();
|
|
348
349
|
}
|
|
@@ -385,13 +386,13 @@ function omitBrowserCodeContext(request) {
|
|
|
385
386
|
...request,
|
|
386
387
|
annotation: {
|
|
387
388
|
...request.annotation,
|
|
388
|
-
targets: request.annotation.targets.map((
|
|
389
|
-
instruction:
|
|
390
|
-
source:
|
|
391
|
-
react:
|
|
392
|
-
element:
|
|
393
|
-
styles:
|
|
394
|
-
warnings:
|
|
389
|
+
targets: request.annotation.targets.map((target2) => ({
|
|
390
|
+
instruction: target2.instruction,
|
|
391
|
+
source: target2.source,
|
|
392
|
+
react: target2.react,
|
|
393
|
+
element: target2.element,
|
|
394
|
+
styles: target2.styles,
|
|
395
|
+
warnings: target2.warnings
|
|
395
396
|
}))
|
|
396
397
|
}
|
|
397
398
|
};
|
|
@@ -682,12 +683,12 @@ function contextCharacterCount(classNames, inlineStyle, rules, computed, warning
|
|
|
682
683
|
function stylesheetSource(sheet, baseUrl) {
|
|
683
684
|
return sheet.href === null ? void 0 : (0, import_shared4.sanitizeUrl)(sheet.href, baseUrl);
|
|
684
685
|
}
|
|
685
|
-
function collectMatchedRules(
|
|
686
|
+
function collectMatchedRules(element2, rules, source2, inheritedConditions, output, warnings) {
|
|
686
687
|
for (const rule of rules) {
|
|
687
688
|
if (isStyleRule(rule)) {
|
|
688
689
|
let matches = false;
|
|
689
690
|
try {
|
|
690
|
-
matches =
|
|
691
|
+
matches = element2.matches(rule.selectorText);
|
|
691
692
|
} catch {
|
|
692
693
|
warnings.add(CSS_COLLECTION_WARNINGS.selector);
|
|
693
694
|
continue;
|
|
@@ -697,7 +698,7 @@ function collectMatchedRules(element, rules, source, inheritedConditions, output
|
|
|
697
698
|
Object.freeze({
|
|
698
699
|
selector: sanitizeCssText(rule.selectorText),
|
|
699
700
|
declarations: sanitizeCssText(rule.style.cssText),
|
|
700
|
-
...
|
|
701
|
+
...source2 === void 0 ? {} : { source: source2 },
|
|
701
702
|
...inheritedConditions.length === 0 ? {} : { media: inheritedConditions.join(" and ") }
|
|
702
703
|
})
|
|
703
704
|
);
|
|
@@ -707,9 +708,9 @@ function collectMatchedRules(element, rules, source, inheritedConditions, output
|
|
|
707
708
|
if (isGroupingRule(rule)) {
|
|
708
709
|
const condition = groupingCondition(rule);
|
|
709
710
|
collectMatchedRules(
|
|
710
|
-
|
|
711
|
+
element2,
|
|
711
712
|
rule.cssRules,
|
|
712
|
-
|
|
713
|
+
source2,
|
|
713
714
|
condition === void 0 ? inheritedConditions : [...inheritedConditions, condition],
|
|
714
715
|
output,
|
|
715
716
|
warnings
|
|
@@ -717,11 +718,11 @@ function collectMatchedRules(element, rules, source, inheritedConditions, output
|
|
|
717
718
|
}
|
|
718
719
|
}
|
|
719
720
|
}
|
|
720
|
-
function collectComputedStyle(
|
|
721
|
+
function collectComputedStyle(element2, getComputedStyle) {
|
|
721
722
|
if (getComputedStyle === void 0) {
|
|
722
723
|
return {};
|
|
723
724
|
}
|
|
724
|
-
const declaration = getComputedStyle(
|
|
725
|
+
const declaration = getComputedStyle(element2);
|
|
725
726
|
const computed = {};
|
|
726
727
|
for (const property of COMPUTED_STYLE_PROPERTIES) {
|
|
727
728
|
const value = sanitizeCssText(declaration.getPropertyValue(property).trim());
|
|
@@ -859,11 +860,11 @@ function escapeHtml(value) {
|
|
|
859
860
|
function isPreservedAttribute(name) {
|
|
860
861
|
return SAFE_ATTRIBUTE_NAMES.has(name) || name.startsWith("aria-") || name === "data-testid";
|
|
861
862
|
}
|
|
862
|
-
function openingTag(
|
|
863
|
-
const tagName =
|
|
863
|
+
function openingTag(element2) {
|
|
864
|
+
const tagName = element2.tagName.toLowerCase();
|
|
864
865
|
const attributes = [];
|
|
865
|
-
const baseUrl =
|
|
866
|
-
for (const attribute of
|
|
866
|
+
const baseUrl = element2.ownerDocument.baseURI;
|
|
867
|
+
for (const attribute of element2.attributes) {
|
|
867
868
|
const name = attribute.name.toLowerCase();
|
|
868
869
|
if (!isPreservedAttribute(name)) {
|
|
869
870
|
continue;
|
|
@@ -878,28 +879,28 @@ function openingTag(element) {
|
|
|
878
879
|
function normalizedText(value) {
|
|
879
880
|
return (0, import_shared4.redactSensitiveText)(value).replaceAll(/\s+/gu, " ").trim();
|
|
880
881
|
}
|
|
881
|
-
function serializeElement(
|
|
882
|
+
function serializeElement(element2, depth, state, lines) {
|
|
882
883
|
if (state.nodeCount >= DOM_COLLECTION_LIMITS.maxNodes) {
|
|
883
884
|
state.truncated = true;
|
|
884
885
|
return;
|
|
885
886
|
}
|
|
886
887
|
state.nodeCount += 1;
|
|
887
888
|
const indent = " ".repeat(depth);
|
|
888
|
-
const tagName =
|
|
889
|
-
lines.push(`${indent}${openingTag(
|
|
889
|
+
const tagName = element2.tagName.toLowerCase();
|
|
890
|
+
lines.push(`${indent}${openingTag(element2)}`);
|
|
890
891
|
if (VOID_ELEMENT_NAMES.has(tagName)) {
|
|
891
892
|
return;
|
|
892
893
|
}
|
|
893
|
-
for (const child of
|
|
894
|
+
for (const child of element2.childNodes) {
|
|
894
895
|
if (state.nodeCount >= DOM_COLLECTION_LIMITS.maxNodes) {
|
|
895
896
|
state.truncated = true;
|
|
896
897
|
break;
|
|
897
898
|
}
|
|
898
899
|
if (child.nodeType === 3) {
|
|
899
|
-
const
|
|
900
|
-
if (
|
|
900
|
+
const text2 = normalizedText(child.textContent ?? "");
|
|
901
|
+
if (text2.length > 0) {
|
|
901
902
|
state.nodeCount += 1;
|
|
902
|
-
const truncated =
|
|
903
|
+
const truncated = text2.length <= DOM_COLLECTION_LIMITS.maxTextCharacters ? text2 : `${text2.slice(0, DOM_COLLECTION_LIMITS.maxTextCharacters)}\u2026`;
|
|
903
904
|
lines.push(`${" ".repeat(depth + 1)}${escapeHtml(truncated)}`);
|
|
904
905
|
}
|
|
905
906
|
continue;
|
|
@@ -918,9 +919,9 @@ function serializeElement(element, depth, state, lines) {
|
|
|
918
919
|
}
|
|
919
920
|
lines.push(`${indent}</${tagName}>`);
|
|
920
921
|
}
|
|
921
|
-
function parentContext(
|
|
922
|
+
function parentContext(element2) {
|
|
922
923
|
const parents = [];
|
|
923
|
-
let parent =
|
|
924
|
+
let parent = element2.parentElement;
|
|
924
925
|
while (parent !== null && parents.length < DOM_COLLECTION_LIMITS.maxParentDepth) {
|
|
925
926
|
parents.push(openingTag(parent));
|
|
926
927
|
parent = parent.parentElement;
|
|
@@ -941,26 +942,26 @@ function escapeCssIdentifier(value) {
|
|
|
941
942
|
function escapeCssAttribute(value) {
|
|
942
943
|
return value.replaceAll("\\", "\\\\").replaceAll('"', '\\"');
|
|
943
944
|
}
|
|
944
|
-
function selectorSegment(
|
|
945
|
-
const tagName =
|
|
946
|
-
if (
|
|
947
|
-
return `${tagName}#${escapeCssIdentifier(
|
|
945
|
+
function selectorSegment(element2) {
|
|
946
|
+
const tagName = element2.tagName.toLowerCase();
|
|
947
|
+
if (element2.id.length > 0) {
|
|
948
|
+
return `${tagName}#${escapeCssIdentifier(element2.id)}`;
|
|
948
949
|
}
|
|
949
|
-
const testId =
|
|
950
|
+
const testId = element2.getAttribute("data-testid");
|
|
950
951
|
if (testId !== null && testId.length > 0) {
|
|
951
952
|
return `${tagName}[data-testid="${escapeCssAttribute(testId)}"]`;
|
|
952
953
|
}
|
|
953
|
-
const classes = Array.from(
|
|
954
|
-
const sameTagSiblings =
|
|
955
|
-
(sibling) => sibling.tagName ===
|
|
954
|
+
const classes = Array.from(element2.classList).slice(0, 2).map((name) => `.${escapeCssIdentifier(name)}`).join("");
|
|
955
|
+
const sameTagSiblings = element2.parentElement === null ? [] : Array.from(element2.parentElement.children).filter(
|
|
956
|
+
(sibling) => sibling.tagName === element2.tagName
|
|
956
957
|
);
|
|
957
|
-
const position = sameTagSiblings.indexOf(
|
|
958
|
+
const position = sameTagSiblings.indexOf(element2);
|
|
958
959
|
const nth = sameTagSiblings.length > 1 && position >= 0 ? `:nth-of-type(${String(position + 1)})` : "";
|
|
959
960
|
return `${tagName}${classes}${nth}`;
|
|
960
961
|
}
|
|
961
|
-
function createSelector(
|
|
962
|
+
function createSelector(element2) {
|
|
962
963
|
const segments = [];
|
|
963
|
-
let current =
|
|
964
|
+
let current = element2;
|
|
964
965
|
while (current !== null && segments.length < 5) {
|
|
965
966
|
const segment = selectorSegment(current);
|
|
966
967
|
segments.unshift(segment);
|
|
@@ -979,15 +980,15 @@ function collectElementContext(options) {
|
|
|
979
980
|
if (parents.length > 0) {
|
|
980
981
|
lines.push("<!-- Parent context: nearest first -->", ...parents);
|
|
981
982
|
}
|
|
982
|
-
const
|
|
983
|
+
const text2 = normalizedText(options.element.textContent);
|
|
983
984
|
const rect = options.element.getBoundingClientRect();
|
|
984
985
|
const role = options.element.getAttribute("role");
|
|
985
986
|
return Object.freeze({
|
|
986
987
|
tagName: options.element.tagName.toLowerCase(),
|
|
987
988
|
selector: createSelector(options.element),
|
|
988
989
|
sanitizedHtml: truncateContext(lines.join("\n"), options.maxCharacters),
|
|
989
|
-
...
|
|
990
|
-
textPreview:
|
|
990
|
+
...text2.length === 0 ? {} : {
|
|
991
|
+
textPreview: text2.length <= DOM_COLLECTION_LIMITS.maxTextCharacters ? text2 : `${text2.slice(0, DOM_COLLECTION_LIMITS.maxTextCharacters)}\u2026`
|
|
991
992
|
},
|
|
992
993
|
...role === null ? {} : { role },
|
|
993
994
|
rect: Object.freeze({
|
|
@@ -1006,11 +1007,11 @@ function isApplePlatform(platform) {
|
|
|
1006
1007
|
function normalizedKey(key) {
|
|
1007
1008
|
return key.toLowerCase();
|
|
1008
1009
|
}
|
|
1009
|
-
function isTextEntryTarget(
|
|
1010
|
-
if (!(
|
|
1010
|
+
function isTextEntryTarget(target2) {
|
|
1011
|
+
if (!(target2 instanceof Element)) {
|
|
1011
1012
|
return false;
|
|
1012
1013
|
}
|
|
1013
|
-
return
|
|
1014
|
+
return target2 instanceof HTMLInputElement || target2 instanceof HTMLTextAreaElement || target2 instanceof HTMLSelectElement || target2.closest("[contenteditable]:not([contenteditable='false'])") !== null;
|
|
1014
1015
|
}
|
|
1015
1016
|
function matchesShortcut(event, shortcut, platform) {
|
|
1016
1017
|
const tokens = shortcut.split("+").map((token) => token.trim().toLowerCase()).filter((token) => token.length > 0);
|
|
@@ -1060,15 +1061,25 @@ function unionRects(rects) {
|
|
|
1060
1061
|
height: bottom - top
|
|
1061
1062
|
});
|
|
1062
1063
|
}
|
|
1063
|
-
function
|
|
1064
|
-
const display = view.getComputedStyle(element).display;
|
|
1064
|
+
function measureElementRect(element2, display) {
|
|
1065
1065
|
if (display.startsWith("inline")) {
|
|
1066
|
-
const lineBoxRect = unionRects(Array.from(
|
|
1066
|
+
const lineBoxRect = unionRects(Array.from(element2.getClientRects()));
|
|
1067
1067
|
if (lineBoxRect !== void 0) {
|
|
1068
1068
|
return lineBoxRect;
|
|
1069
1069
|
}
|
|
1070
1070
|
}
|
|
1071
|
-
return toElementRect(
|
|
1071
|
+
return toElementRect(element2.getBoundingClientRect());
|
|
1072
|
+
}
|
|
1073
|
+
function getElementRect(element2, view) {
|
|
1074
|
+
return measureElementRect(element2, view.getComputedStyle(element2).display);
|
|
1075
|
+
}
|
|
1076
|
+
function getVisibleElementRect(element2, view) {
|
|
1077
|
+
const style = view.getComputedStyle(element2);
|
|
1078
|
+
if (style.display === "none" || style.visibility === "hidden") {
|
|
1079
|
+
return void 0;
|
|
1080
|
+
}
|
|
1081
|
+
const rect = measureElementRect(element2, style.display);
|
|
1082
|
+
return rect.width > 0 && rect.height > 0 ? rect : void 0;
|
|
1072
1083
|
}
|
|
1073
1084
|
|
|
1074
1085
|
// src/ui/ui-constants.ts
|
|
@@ -1079,32 +1090,27 @@ var UI_Z_INDEX = Object.freeze({
|
|
|
1079
1090
|
});
|
|
1080
1091
|
|
|
1081
1092
|
// src/picker/hit-test.ts
|
|
1082
|
-
function isInsideSpotPatchUI(
|
|
1083
|
-
if (
|
|
1093
|
+
function isInsideSpotPatchUI(element2) {
|
|
1094
|
+
if (element2.closest(`[${UI_MARKER_ATTRIBUTE}]`) !== null) {
|
|
1084
1095
|
return true;
|
|
1085
1096
|
}
|
|
1086
|
-
const root =
|
|
1097
|
+
const root = element2.getRootNode();
|
|
1087
1098
|
return root instanceof ShadowRoot && root.host.hasAttribute(UI_MARKER_ATTRIBUTE);
|
|
1088
1099
|
}
|
|
1089
|
-
function hasVisibleArea(
|
|
1090
|
-
|
|
1091
|
-
if (style.display === "none" || style.visibility === "hidden") {
|
|
1092
|
-
return false;
|
|
1093
|
-
}
|
|
1094
|
-
const rect = element.getBoundingClientRect();
|
|
1095
|
-
return rect.width > 0 && rect.height > 0;
|
|
1100
|
+
function hasVisibleArea(element2, view) {
|
|
1101
|
+
return getVisibleElementRect(element2, view) !== void 0;
|
|
1096
1102
|
}
|
|
1097
|
-
function isDocumentRoot(
|
|
1098
|
-
return
|
|
1103
|
+
function isDocumentRoot(element2) {
|
|
1104
|
+
return element2.tagName === "HTML" || element2.tagName === "BODY";
|
|
1099
1105
|
}
|
|
1100
1106
|
function pickElementAt(document, view, clientX, clientY) {
|
|
1101
1107
|
const visibleCandidates = document.elementsFromPoint(clientX, clientY).filter(
|
|
1102
|
-
(
|
|
1108
|
+
(element2) => !isInsideSpotPatchUI(element2) && hasVisibleArea(element2, view)
|
|
1103
1109
|
);
|
|
1104
|
-
return visibleCandidates.find((
|
|
1110
|
+
return visibleCandidates.find((element2) => !isDocumentRoot(element2)) ?? visibleCandidates[0];
|
|
1105
1111
|
}
|
|
1106
|
-
function isSpotPatchUIEventTarget(
|
|
1107
|
-
return
|
|
1112
|
+
function isSpotPatchUIEventTarget(target2) {
|
|
1113
|
+
return target2 instanceof Element && isInsideSpotPatchUI(target2);
|
|
1108
1114
|
}
|
|
1109
1115
|
|
|
1110
1116
|
// src/prompt/prompt-composer.ts
|
|
@@ -1183,10 +1189,10 @@ function fenced(language, value) {
|
|
|
1183
1189
|
${value}
|
|
1184
1190
|
${fence}`;
|
|
1185
1191
|
}
|
|
1186
|
-
function sourceLocation(
|
|
1187
|
-
const path =
|
|
1188
|
-
const line =
|
|
1189
|
-
const column =
|
|
1192
|
+
function sourceLocation(target2, messages) {
|
|
1193
|
+
const path = target2.code?.relativePath ?? target2.source.relativePath;
|
|
1194
|
+
const line = target2.source.line;
|
|
1195
|
+
const column = target2.source.column;
|
|
1190
1196
|
if (path === void 0) {
|
|
1191
1197
|
return messages.unavailable;
|
|
1192
1198
|
}
|
|
@@ -1205,10 +1211,10 @@ function renderRule(rule) {
|
|
|
1205
1211
|
}`;
|
|
1206
1212
|
return [...metadata, body].join("\n");
|
|
1207
1213
|
}
|
|
1208
|
-
function renderStyles(
|
|
1214
|
+
function renderStyles(target2, rules, messages) {
|
|
1209
1215
|
const metadata = [
|
|
1210
|
-
|
|
1211
|
-
|
|
1216
|
+
target2.styles.classNames.length === 0 ? void 0 : `/* classes: ${target2.styles.classNames.map(sanitizeCssText).join(" ")} */`,
|
|
1217
|
+
target2.styles.inlineStyle === void 0 ? void 0 : `/* inline: ${sanitizeCssText(target2.styles.inlineStyle)} */`
|
|
1212
1218
|
].filter((line) => line !== void 0);
|
|
1213
1219
|
const blocks = [...metadata, ...rules.map(renderRule)];
|
|
1214
1220
|
return blocks.length === 0 ? messages.unavailable : fenced("css", blocks.join("\n\n"));
|
|
@@ -1221,41 +1227,47 @@ function renderComputed(entries, messages) {
|
|
|
1221
1227
|
).join("\n")
|
|
1222
1228
|
);
|
|
1223
1229
|
}
|
|
1224
|
-
function renderTarget(
|
|
1230
|
+
function renderTarget(target2, draft, index, messages) {
|
|
1225
1231
|
const reactLines = [
|
|
1226
|
-
`- ${messages.adapter}: ${
|
|
1227
|
-
...
|
|
1228
|
-
...
|
|
1229
|
-
`- ${messages.component}: ${(0, import_shared4.redactSensitiveText)(
|
|
1232
|
+
`- ${messages.adapter}: ${target2.react.supported ? messages.supported : messages.unsupported}`,
|
|
1233
|
+
...target2.react.version === void 0 ? [] : [`- ${messages.reactVersion}: ${(0, import_shared4.redactSensitiveText)(target2.react.version)}`],
|
|
1234
|
+
...target2.react.componentName === void 0 ? [] : [
|
|
1235
|
+
`- ${messages.component}: ${(0, import_shared4.redactSensitiveText)(target2.react.componentName)}`
|
|
1230
1236
|
],
|
|
1231
1237
|
...draft.reactStack.length === 0 ? [] : [
|
|
1232
1238
|
`- ${messages.stack}: ${draft.reactStack.map(import_shared4.redactSensitiveText).join(" > ")}`
|
|
1233
1239
|
]
|
|
1234
1240
|
];
|
|
1235
|
-
const
|
|
1241
|
+
const code2 = target2.code === void 0 || draft.codeLines.length === 0 ? messages.unavailable : `- ${messages.boundary}: ${target2.code.boundary}
|
|
1236
1242
|
|
|
1237
1243
|
${fenced(
|
|
1238
|
-
|
|
1244
|
+
target2.code.language,
|
|
1239
1245
|
(0, import_shared4.redactSensitiveText)(draft.codeLines.join("\n"))
|
|
1240
1246
|
)}`;
|
|
1241
1247
|
return [
|
|
1242
1248
|
`### ${messages.target(index + 1)}`,
|
|
1243
1249
|
`#### ${messages.requestedChange}`,
|
|
1244
1250
|
draft.instruction,
|
|
1251
|
+
...target2.page === void 0 ? [] : [
|
|
1252
|
+
`#### ${messages.pageEnvironment}`,
|
|
1253
|
+
`- ${messages.url}: <${(0, import_shared4.sanitizeUrl)(target2.page.url, target2.page.url)}>
|
|
1254
|
+
- ${messages.pathname}: ${(0, import_shared4.redactSensitiveText)(target2.page.pathname)}
|
|
1255
|
+
- ${messages.title}: ${(0, import_shared4.redactSensitiveText)(target2.page.title) || messages.unavailable}`
|
|
1256
|
+
],
|
|
1245
1257
|
`#### ${messages.reactContext}`,
|
|
1246
1258
|
reactLines.join("\n"),
|
|
1247
1259
|
`#### ${messages.source}`,
|
|
1248
|
-
`- ${messages.file}: ${sourceLocation(
|
|
1249
|
-
- ${messages.origin}: ${
|
|
1250
|
-
- ${messages.confidence}: ${
|
|
1260
|
+
`- ${messages.file}: ${sourceLocation(target2, messages)}
|
|
1261
|
+
- ${messages.origin}: ${target2.source.origin}
|
|
1262
|
+
- ${messages.confidence}: ${target2.source.confidence}`,
|
|
1251
1263
|
`#### ${messages.element}`,
|
|
1252
1264
|
fenced("html", (0, import_shared4.redactSensitiveText)(draft.dom)),
|
|
1253
1265
|
`#### ${messages.styles}`,
|
|
1254
|
-
renderStyles(
|
|
1266
|
+
renderStyles(target2, draft.matchedRules, messages),
|
|
1255
1267
|
`#### ${messages.computedStyles}`,
|
|
1256
1268
|
renderComputed(draft.computedEntries, messages),
|
|
1257
1269
|
`#### ${messages.code}`,
|
|
1258
|
-
|
|
1270
|
+
code2,
|
|
1259
1271
|
`#### ${messages.warnings}`,
|
|
1260
1272
|
draft.warnings.length === 0 ? `- ${messages.none}` : draft.warnings.map((warning) => `- ${(0, import_shared4.redactSensitiveText)(warning)}`).join("\n")
|
|
1261
1273
|
].join("\n\n");
|
|
@@ -1271,19 +1283,19 @@ function renderPrompt(annotation, draft) {
|
|
|
1271
1283
|
- ${messages.viewport}: ${String(annotation.page.viewportWidth)} \xD7 ${String(annotation.page.viewportHeight)}
|
|
1272
1284
|
- ${messages.devicePixelRatio}: ${String(annotation.page.devicePixelRatio)}`,
|
|
1273
1285
|
`## ${messages.selectedTargets(annotation.targets.length)}`,
|
|
1274
|
-
annotation.targets.map((
|
|
1286
|
+
annotation.targets.map((target2, index) => {
|
|
1275
1287
|
const targetDraft = draft.targets[index];
|
|
1276
1288
|
if (targetDraft === void 0) {
|
|
1277
1289
|
throw new RangeError("Prompt target draft is missing.");
|
|
1278
1290
|
}
|
|
1279
|
-
return renderTarget(
|
|
1291
|
+
return renderTarget(target2, targetDraft, index, messages);
|
|
1280
1292
|
}).join("\n\n"),
|
|
1281
1293
|
`## ${messages.modificationRequirements}`,
|
|
1282
1294
|
messages.modificationConstraint
|
|
1283
1295
|
].join("\n\n");
|
|
1284
1296
|
}
|
|
1285
|
-
function shrinkCode(
|
|
1286
|
-
if (draft.codeLines.length === 0 ||
|
|
1297
|
+
function shrinkCode(target2, draft) {
|
|
1298
|
+
if (draft.codeLines.length === 0 || target2.code === void 0) {
|
|
1287
1299
|
return false;
|
|
1288
1300
|
}
|
|
1289
1301
|
if (draft.codeLines.length === 1) {
|
|
@@ -1295,9 +1307,9 @@ function shrinkCode(target, draft) {
|
|
|
1295
1307
|
}
|
|
1296
1308
|
return true;
|
|
1297
1309
|
}
|
|
1298
|
-
const selectedLine =
|
|
1299
|
-
const firstDistance = Math.abs(
|
|
1300
|
-
const lastLine =
|
|
1310
|
+
const selectedLine = target2.source.line ?? target2.code.startLine;
|
|
1311
|
+
const firstDistance = Math.abs(target2.code.startLine - selectedLine);
|
|
1312
|
+
const lastLine = target2.code.startLine + draft.codeLines.length - 1;
|
|
1301
1313
|
const lastDistance = Math.abs(lastLine - selectedLine);
|
|
1302
1314
|
if (lastDistance >= firstDistance) {
|
|
1303
1315
|
draft.codeLines.pop();
|
|
@@ -1306,15 +1318,15 @@ function shrinkCode(target, draft) {
|
|
|
1306
1318
|
}
|
|
1307
1319
|
return true;
|
|
1308
1320
|
}
|
|
1309
|
-
function createTargetDraft(
|
|
1321
|
+
function createTargetDraft(target2) {
|
|
1310
1322
|
return {
|
|
1311
|
-
instruction: (0, import_shared4.redactSensitiveText)(
|
|
1312
|
-
reactStack: [...
|
|
1313
|
-
dom:
|
|
1314
|
-
matchedRules: [...
|
|
1315
|
-
computedEntries: Object.entries(
|
|
1316
|
-
codeLines:
|
|
1317
|
-
warnings: Array.from(/* @__PURE__ */ new Set([...
|
|
1323
|
+
instruction: (0, import_shared4.redactSensitiveText)(target2.instruction.trim()),
|
|
1324
|
+
reactStack: [...target2.react.componentStack],
|
|
1325
|
+
dom: target2.element.sanitizedHtml,
|
|
1326
|
+
matchedRules: [...target2.styles.matchedRules],
|
|
1327
|
+
computedEntries: Object.entries(target2.styles.computed),
|
|
1328
|
+
codeLines: target2.code?.excerpt.split(/\r?\n/u) ?? [],
|
|
1329
|
+
warnings: Array.from(/* @__PURE__ */ new Set([...target2.styles.warnings, ...target2.warnings]))
|
|
1318
1330
|
};
|
|
1319
1331
|
}
|
|
1320
1332
|
function createDraft(annotation) {
|
|
@@ -1343,9 +1355,9 @@ function shrinkTargetsFairly(annotation, draft, cursor) {
|
|
|
1343
1355
|
for (const operation of operations) {
|
|
1344
1356
|
for (let offset = 0; offset < annotation.targets.length; offset += 1) {
|
|
1345
1357
|
const index = (cursor + offset) % annotation.targets.length;
|
|
1346
|
-
const
|
|
1358
|
+
const target2 = annotation.targets[index];
|
|
1347
1359
|
const targetDraft = draft.targets[index];
|
|
1348
|
-
if (
|
|
1360
|
+
if (target2 !== void 0 && targetDraft !== void 0 && operation(target2, targetDraft)) {
|
|
1349
1361
|
return (index + 1) % annotation.targets.length;
|
|
1350
1362
|
}
|
|
1351
1363
|
}
|
|
@@ -1354,15 +1366,15 @@ function shrinkTargetsFairly(annotation, draft, cursor) {
|
|
|
1354
1366
|
}
|
|
1355
1367
|
function renderCompactPrompt(annotation, draft) {
|
|
1356
1368
|
const messages = PROMPT_MESSAGES[annotation.locale];
|
|
1357
|
-
const targets = annotation.targets.map((
|
|
1369
|
+
const targets = annotation.targets.map((target2, index) => {
|
|
1358
1370
|
const targetDraft = draft.targets[index];
|
|
1359
|
-
const component =
|
|
1371
|
+
const component = target2.react.componentName;
|
|
1360
1372
|
return [
|
|
1361
1373
|
`### ${messages.target(index + 1)}`,
|
|
1362
|
-
`- ${messages.requestedChange}: ${targetDraft?.instruction ?? (0, import_shared4.redactSensitiveText)(
|
|
1363
|
-
`- ${messages.file}: ${sourceLocation(
|
|
1374
|
+
`- ${messages.requestedChange}: ${targetDraft?.instruction ?? (0, import_shared4.redactSensitiveText)(target2.instruction)}`,
|
|
1375
|
+
`- ${messages.file}: ${sourceLocation(target2, messages)}`,
|
|
1364
1376
|
...component === void 0 ? [] : [`- ${messages.component}: ${(0, import_shared4.redactSensitiveText)(component)}`],
|
|
1365
|
-
`- ${messages.element}: ${(0, import_shared4.redactSensitiveText)(openingTag2(targetDraft?.dom ??
|
|
1377
|
+
`- ${messages.element}: ${(0, import_shared4.redactSensitiveText)(openingTag2(targetDraft?.dom ?? target2.element.sanitizedHtml, messages.unavailable))}`
|
|
1366
1378
|
].join("\n");
|
|
1367
1379
|
});
|
|
1368
1380
|
return [
|
|
@@ -1420,7 +1432,10 @@ var STATES = Object.freeze({
|
|
|
1420
1432
|
});
|
|
1421
1433
|
var INITIAL_RUNTIME_STATE = STATES.idle;
|
|
1422
1434
|
function reduceIdle(event) {
|
|
1423
|
-
|
|
1435
|
+
if (event.type === "ACTIVATE") {
|
|
1436
|
+
return STATES.inspecting;
|
|
1437
|
+
}
|
|
1438
|
+
return event.type === "RESTORE" ? STATES.selected : STATES.idle;
|
|
1424
1439
|
}
|
|
1425
1440
|
function reduceInspecting(event) {
|
|
1426
1441
|
switch (event.type) {
|
|
@@ -1472,17 +1487,132 @@ function reduceRuntimeState(state, event) {
|
|
|
1472
1487
|
}
|
|
1473
1488
|
}
|
|
1474
1489
|
|
|
1490
|
+
// src/state/selection-session.ts
|
|
1491
|
+
var STORAGE_PREFIX = "spotpatch:selection:";
|
|
1492
|
+
var SNAPSHOT_VERSION = 1;
|
|
1493
|
+
var MAX_SNAPSHOT_CHARACTERS = 1e6;
|
|
1494
|
+
function record(value) {
|
|
1495
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
1496
|
+
}
|
|
1497
|
+
function text(value) {
|
|
1498
|
+
return typeof value === "string";
|
|
1499
|
+
}
|
|
1500
|
+
function optionalText(value) {
|
|
1501
|
+
return value === void 0 || text(value);
|
|
1502
|
+
}
|
|
1503
|
+
function strings(value) {
|
|
1504
|
+
return Array.isArray(value) && value.length <= 256 && value.every(text);
|
|
1505
|
+
}
|
|
1506
|
+
function finiteNumber(value) {
|
|
1507
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
1508
|
+
}
|
|
1509
|
+
function optionalNumber(value) {
|
|
1510
|
+
return value === void 0 || finiteNumber(value);
|
|
1511
|
+
}
|
|
1512
|
+
function source(value) {
|
|
1513
|
+
const item = record(value);
|
|
1514
|
+
return item !== void 0 && text(item.origin) && text(item.confidence) && optionalText(item.fileId) && optionalText(item.relativePath) && optionalNumber(item.line) && optionalNumber(item.column);
|
|
1515
|
+
}
|
|
1516
|
+
function react(value) {
|
|
1517
|
+
const item = record(value);
|
|
1518
|
+
return item !== void 0 && typeof item.supported === "boolean" && optionalText(item.version) && optionalText(item.componentName) && strings(item.componentStack) && (item.source === void 0 || source(item.source));
|
|
1519
|
+
}
|
|
1520
|
+
function page(value) {
|
|
1521
|
+
const item = record(value);
|
|
1522
|
+
return item !== void 0 && text(item.url) && text(item.pathname) && text(item.title) && finiteNumber(item.viewportWidth) && finiteNumber(item.viewportHeight) && finiteNumber(item.devicePixelRatio);
|
|
1523
|
+
}
|
|
1524
|
+
function element(value) {
|
|
1525
|
+
const item = record(value);
|
|
1526
|
+
const rect = record(item?.rect);
|
|
1527
|
+
return item !== void 0 && text(item.tagName) && text(item.selector) && text(item.sanitizedHtml) && optionalText(item.textPreview) && optionalText(item.role) && rect !== void 0 && finiteNumber(rect.x) && finiteNumber(rect.y) && finiteNumber(rect.width) && finiteNumber(rect.height);
|
|
1528
|
+
}
|
|
1529
|
+
function styles(value) {
|
|
1530
|
+
const item = record(value);
|
|
1531
|
+
const computed = record(item?.computed);
|
|
1532
|
+
return item !== void 0 && strings(item.classNames) && optionalText(item.inlineStyle) && Array.isArray(item.matchedRules) && item.matchedRules.length <= 256 && item.matchedRules.every((value2) => {
|
|
1533
|
+
const rule = record(value2);
|
|
1534
|
+
return rule !== void 0 && text(rule.selector) && text(rule.declarations) && optionalText(rule.source) && optionalText(rule.media);
|
|
1535
|
+
}) && computed !== void 0 && Object.values(computed).every(text) && strings(item.warnings);
|
|
1536
|
+
}
|
|
1537
|
+
function code(value) {
|
|
1538
|
+
const item = record(value);
|
|
1539
|
+
return item !== void 0 && text(item.relativePath) && text(item.language) && finiteNumber(item.startLine) && finiteNumber(item.endLine) && text(item.excerpt) && text(item.boundary);
|
|
1540
|
+
}
|
|
1541
|
+
function target(value) {
|
|
1542
|
+
const item = record(value);
|
|
1543
|
+
return item !== void 0 && text(item.id) && text(item.instruction) && page(item.page) && source(item.source) && react(item.react) && element(item.element) && styles(item.styles) && (item.code === void 0 || code(item.code));
|
|
1544
|
+
}
|
|
1545
|
+
function parseSnapshot(value, maximumTargets) {
|
|
1546
|
+
const item = record(value);
|
|
1547
|
+
if (item?.version !== SNAPSHOT_VERSION || typeof item.open !== "boolean" || !Number.isSafeInteger(item.sequence) || Number(item.sequence) < 0 || item.activeTargetId !== void 0 && typeof item.activeTargetId !== "string" || !Array.isArray(item.targets) || item.targets.length === 0 || item.targets.length > maximumTargets || !item.targets.every(target)) {
|
|
1548
|
+
return void 0;
|
|
1549
|
+
}
|
|
1550
|
+
const targets = item.targets;
|
|
1551
|
+
const ids = targets.map(({ id }) => id);
|
|
1552
|
+
if (new Set(ids).size !== ids.length || item.activeTargetId !== void 0 && !ids.includes(item.activeTargetId)) {
|
|
1553
|
+
return void 0;
|
|
1554
|
+
}
|
|
1555
|
+
return {
|
|
1556
|
+
...item.activeTargetId === void 0 ? {} : { activeTargetId: item.activeTargetId },
|
|
1557
|
+
open: item.open,
|
|
1558
|
+
sequence: Number(item.sequence),
|
|
1559
|
+
targets
|
|
1560
|
+
};
|
|
1561
|
+
}
|
|
1562
|
+
function createSelectionSession(window, sessionId, maximumTargets) {
|
|
1563
|
+
const key = `${STORAGE_PREFIX}${sessionId}`;
|
|
1564
|
+
let storage;
|
|
1565
|
+
try {
|
|
1566
|
+
storage = window.sessionStorage;
|
|
1567
|
+
} catch {
|
|
1568
|
+
storage = void 0;
|
|
1569
|
+
}
|
|
1570
|
+
return Object.freeze({
|
|
1571
|
+
clear() {
|
|
1572
|
+
try {
|
|
1573
|
+
storage?.removeItem(key);
|
|
1574
|
+
} catch {
|
|
1575
|
+
}
|
|
1576
|
+
},
|
|
1577
|
+
load() {
|
|
1578
|
+
let serialized;
|
|
1579
|
+
try {
|
|
1580
|
+
serialized = storage?.getItem(key) ?? null;
|
|
1581
|
+
} catch {
|
|
1582
|
+
return void 0;
|
|
1583
|
+
}
|
|
1584
|
+
if (serialized === null || serialized.length > MAX_SNAPSHOT_CHARACTERS) {
|
|
1585
|
+
return void 0;
|
|
1586
|
+
}
|
|
1587
|
+
try {
|
|
1588
|
+
return parseSnapshot(JSON.parse(serialized), maximumTargets);
|
|
1589
|
+
} catch {
|
|
1590
|
+
return void 0;
|
|
1591
|
+
}
|
|
1592
|
+
},
|
|
1593
|
+
save(snapshot) {
|
|
1594
|
+
try {
|
|
1595
|
+
storage?.setItem(
|
|
1596
|
+
key,
|
|
1597
|
+
JSON.stringify({ version: SNAPSHOT_VERSION, ...snapshot })
|
|
1598
|
+
);
|
|
1599
|
+
} catch {
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
});
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1475
1605
|
// src/source/source-resolver.ts
|
|
1476
1606
|
var import_shared5 = require("@spotpatch/shared");
|
|
1477
1607
|
var EMPTY_REACT_CONTEXT = Object.freeze({
|
|
1478
1608
|
supported: false,
|
|
1479
1609
|
componentStack: Object.freeze([])
|
|
1480
1610
|
});
|
|
1481
|
-
function directMarker(
|
|
1482
|
-
return (0, import_shared5.parseSourceMarker)(
|
|
1611
|
+
function directMarker(element2) {
|
|
1612
|
+
return (0, import_shared5.parseSourceMarker)(element2.getAttribute(import_shared5.SOURCE_MARKER_ATTRIBUTE));
|
|
1483
1613
|
}
|
|
1484
|
-
function ancestorMarker(
|
|
1485
|
-
let ancestor =
|
|
1614
|
+
function ancestorMarker(element2) {
|
|
1615
|
+
let ancestor = element2.parentElement;
|
|
1486
1616
|
while (ancestor !== null) {
|
|
1487
1617
|
const marker = directMarker(ancestor);
|
|
1488
1618
|
if (marker !== void 0) {
|
|
@@ -1504,21 +1634,21 @@ function markerSource(marker, origin, confidence) {
|
|
|
1504
1634
|
function unknownSource() {
|
|
1505
1635
|
return Object.freeze({ origin: "none", confidence: "unknown" });
|
|
1506
1636
|
}
|
|
1507
|
-
function sourceRefToMarker(
|
|
1508
|
-
return
|
|
1509
|
-
fileId:
|
|
1510
|
-
line:
|
|
1511
|
-
column:
|
|
1637
|
+
function sourceRefToMarker(source2) {
|
|
1638
|
+
return source2.fileId === void 0 || source2.line === void 0 || source2.column === void 0 ? void 0 : Object.freeze({
|
|
1639
|
+
fileId: source2.fileId,
|
|
1640
|
+
line: source2.line,
|
|
1641
|
+
column: source2.column
|
|
1512
1642
|
});
|
|
1513
1643
|
}
|
|
1514
1644
|
function createSourceResolver(options) {
|
|
1515
1645
|
let adapterEnabled = true;
|
|
1516
|
-
function inspectReact(
|
|
1646
|
+
function inspectReact(element2) {
|
|
1517
1647
|
if (!adapterEnabled) {
|
|
1518
1648
|
return EMPTY_REACT_CONTEXT;
|
|
1519
1649
|
}
|
|
1520
1650
|
try {
|
|
1521
|
-
return options.adapter.inspect(
|
|
1651
|
+
return options.adapter.inspect(element2);
|
|
1522
1652
|
} catch {
|
|
1523
1653
|
adapterEnabled = false;
|
|
1524
1654
|
options.onAdapterError?.();
|
|
@@ -1526,26 +1656,26 @@ function createSourceResolver(options) {
|
|
|
1526
1656
|
}
|
|
1527
1657
|
}
|
|
1528
1658
|
return Object.freeze({
|
|
1529
|
-
resolve(
|
|
1530
|
-
const marker = directMarker(
|
|
1531
|
-
const
|
|
1659
|
+
resolve(element2) {
|
|
1660
|
+
const marker = directMarker(element2);
|
|
1661
|
+
const react2 = inspectReact(element2);
|
|
1532
1662
|
if (marker !== void 0) {
|
|
1533
1663
|
return Object.freeze({
|
|
1534
|
-
react,
|
|
1664
|
+
react: react2,
|
|
1535
1665
|
source: markerSource(marker, "jsx-host", "exact")
|
|
1536
1666
|
});
|
|
1537
1667
|
}
|
|
1538
|
-
if (
|
|
1539
|
-
return Object.freeze({ react, source:
|
|
1668
|
+
if (react2.source !== void 0) {
|
|
1669
|
+
return Object.freeze({ react: react2, source: react2.source });
|
|
1540
1670
|
}
|
|
1541
|
-
const nearestAncestor = ancestorMarker(
|
|
1671
|
+
const nearestAncestor = ancestorMarker(element2);
|
|
1542
1672
|
if (nearestAncestor !== void 0) {
|
|
1543
1673
|
return Object.freeze({
|
|
1544
|
-
react,
|
|
1674
|
+
react: react2,
|
|
1545
1675
|
source: markerSource(nearestAncestor, "dom-ancestor", "approximate")
|
|
1546
1676
|
});
|
|
1547
1677
|
}
|
|
1548
|
-
return Object.freeze({ react, source: unknownSource() });
|
|
1678
|
+
return Object.freeze({ react: react2, source: unknownSource() });
|
|
1549
1679
|
},
|
|
1550
1680
|
dispose() {
|
|
1551
1681
|
adapterEnabled = false;
|
|
@@ -1559,9 +1689,9 @@ var import_shared7 = require("@spotpatch/shared");
|
|
|
1559
1689
|
|
|
1560
1690
|
// src/ui/dom.ts
|
|
1561
1691
|
function createMarkedElement(document, tagName) {
|
|
1562
|
-
const
|
|
1563
|
-
|
|
1564
|
-
return
|
|
1692
|
+
const element2 = document.createElement(tagName);
|
|
1693
|
+
element2.setAttribute(UI_MARKER_ATTRIBUTE, "");
|
|
1694
|
+
return element2;
|
|
1565
1695
|
}
|
|
1566
1696
|
function createButton(document, label, className = "") {
|
|
1567
1697
|
const button = createMarkedElement(document, "button");
|
|
@@ -1574,7 +1704,7 @@ function createButton(document, label, className = "") {
|
|
|
1574
1704
|
// src/ui/agent-panel.ts
|
|
1575
1705
|
var AGENT_PANEL_STYLES = `
|
|
1576
1706
|
.spotpatch-agent {
|
|
1577
|
-
margin-top:
|
|
1707
|
+
margin-top: 10px;
|
|
1578
1708
|
overflow: hidden;
|
|
1579
1709
|
border: 1px solid var(--spotpatch-border-subtle);
|
|
1580
1710
|
border-radius: var(--spotpatch-radius-card);
|
|
@@ -1584,36 +1714,36 @@ var AGENT_PANEL_STYLES = `
|
|
|
1584
1714
|
display: flex;
|
|
1585
1715
|
align-items: center;
|
|
1586
1716
|
justify-content: space-between;
|
|
1587
|
-
gap:
|
|
1588
|
-
padding:
|
|
1717
|
+
gap: 10px;
|
|
1718
|
+
padding: 10px 12px;
|
|
1589
1719
|
border-bottom: 1px solid rgb(255 255 255 / 7%);
|
|
1590
1720
|
}
|
|
1591
|
-
.spotpatch-agent-title { color: #eef0f5; font-size:
|
|
1721
|
+
.spotpatch-agent-title { color: #eef0f5; font-size: 13px; font-weight: 650; }
|
|
1592
1722
|
.spotpatch-agent-badge {
|
|
1593
1723
|
border: 1px solid rgb(129 112 247 / 24%);
|
|
1594
1724
|
border-radius: 999px;
|
|
1595
1725
|
padding: 3px 7px;
|
|
1596
1726
|
color: #c5cafa;
|
|
1597
1727
|
background: rgb(109 93 246 / 9%);
|
|
1598
|
-
font-size:
|
|
1728
|
+
font-size: 10px;
|
|
1599
1729
|
font-weight: 650;
|
|
1600
1730
|
}
|
|
1601
|
-
.spotpatch-agent-setup { padding:
|
|
1602
|
-
.spotpatch-agent-selectors { display: grid; grid-template-columns: 1fr; gap:
|
|
1603
|
-
.spotpatch-agent-selectors label { min-width: 0; color: var(--spotpatch-text-secondary); font-size:
|
|
1731
|
+
.spotpatch-agent-setup { padding: 12px; }
|
|
1732
|
+
.spotpatch-agent-selectors { display: grid; grid-template-columns: 1fr; gap: 10px; }
|
|
1733
|
+
.spotpatch-agent-selectors label { min-width: 0; color: var(--spotpatch-text-secondary); font-size: 11.5px; font-weight: 580; }
|
|
1604
1734
|
.spotpatch-agent select {
|
|
1605
1735
|
box-sizing: border-box;
|
|
1606
1736
|
width: 100%;
|
|
1607
1737
|
min-width: 0;
|
|
1608
|
-
min-height:
|
|
1609
|
-
margin-top:
|
|
1738
|
+
min-height: 34px;
|
|
1739
|
+
margin-top: 4px;
|
|
1610
1740
|
border: 1px solid var(--spotpatch-border);
|
|
1611
|
-
border-radius:
|
|
1612
|
-
padding:
|
|
1741
|
+
border-radius: 8px;
|
|
1742
|
+
padding: 7px 32px 7px 9px;
|
|
1613
1743
|
color: #e8ebf2;
|
|
1614
1744
|
color-scheme: dark;
|
|
1615
1745
|
background: linear-gradient(180deg, rgb(255 255 255 / 4%), rgb(255 255 255 / 2%));
|
|
1616
|
-
font-size:
|
|
1746
|
+
font-size: 12px;
|
|
1617
1747
|
font-weight: 560;
|
|
1618
1748
|
line-height: 1.35;
|
|
1619
1749
|
outline: none;
|
|
@@ -1625,7 +1755,7 @@ var AGENT_PANEL_STYLES = `
|
|
|
1625
1755
|
@supports (appearance: base-select) {
|
|
1626
1756
|
.spotpatch-agent select,
|
|
1627
1757
|
::picker(select) { appearance: base-select; }
|
|
1628
|
-
.spotpatch-agent select { padding:
|
|
1758
|
+
.spotpatch-agent select { padding: 7px 9px; }
|
|
1629
1759
|
.spotpatch-agent select::picker-icon {
|
|
1630
1760
|
color: #9da6b5;
|
|
1631
1761
|
transition: rotate 180ms cubic-bezier(.2, .8, .2, 1);
|
|
@@ -1672,24 +1802,24 @@ var AGENT_PANEL_STYLES = `
|
|
|
1672
1802
|
.spotpatch-consent {
|
|
1673
1803
|
display: flex;
|
|
1674
1804
|
align-items: flex-start;
|
|
1675
|
-
gap:
|
|
1676
|
-
margin-top:
|
|
1805
|
+
gap: 8px;
|
|
1806
|
+
margin-top: 10px;
|
|
1677
1807
|
color: var(--spotpatch-text-secondary);
|
|
1678
1808
|
cursor: pointer;
|
|
1679
|
-
font-size:
|
|
1680
|
-
line-height: 1.
|
|
1809
|
+
font-size: 11.5px;
|
|
1810
|
+
line-height: 1.5;
|
|
1681
1811
|
}
|
|
1682
|
-
.spotpatch-consent input { width:
|
|
1812
|
+
.spotpatch-consent input { width: 14px; height: 14px; flex: none; margin: 2px 0 0; accent-color: var(--spotpatch-accent); }
|
|
1683
1813
|
.spotpatch-workspace-consent {
|
|
1684
|
-
margin-top:
|
|
1814
|
+
margin-top: 9px;
|
|
1685
1815
|
border: 1px solid rgb(251 191 36 / 18%);
|
|
1686
1816
|
border-radius: 10px;
|
|
1687
|
-
padding:
|
|
1817
|
+
padding: 9px 10px;
|
|
1688
1818
|
background: rgb(120 53 15 / 9%);
|
|
1689
1819
|
}
|
|
1690
|
-
.spotpatch-workspace-consent strong { display: block; color: #fde68a; font-size:
|
|
1691
|
-
.spotpatch-workspace-consent small { display: block; margin-top: 2px; color: #aeb6c4; font-size:
|
|
1692
|
-
.spotpatch-agent-health-list { display: grid; gap:
|
|
1820
|
+
.spotpatch-workspace-consent strong { display: block; color: #fde68a; font-size: 11.5px; font-weight: 620; }
|
|
1821
|
+
.spotpatch-workspace-consent small { display: block; margin-top: 2px; color: #aeb6c4; font-size: 10.5px; line-height: 1.45; }
|
|
1822
|
+
.spotpatch-agent-health-list { display: grid; gap: 6px; margin-top: 10px; }
|
|
1693
1823
|
.spotpatch-agent-workspace,
|
|
1694
1824
|
.spotpatch-agent-capability {
|
|
1695
1825
|
display: flex;
|
|
@@ -1697,7 +1827,7 @@ var AGENT_PANEL_STYLES = `
|
|
|
1697
1827
|
gap: 8px;
|
|
1698
1828
|
margin: 0;
|
|
1699
1829
|
color: #929bab;
|
|
1700
|
-
font-size:
|
|
1830
|
+
font-size: 11px;
|
|
1701
1831
|
}
|
|
1702
1832
|
.spotpatch-agent-capability::before {
|
|
1703
1833
|
width: 6px;
|
|
@@ -1727,7 +1857,7 @@ var AGENT_PANEL_STYLES = `
|
|
|
1727
1857
|
.spotpatch-agent-workspace[data-state="consent-required"]::before { background: #fbbf24; }
|
|
1728
1858
|
.spotpatch-agent-workspace[data-state="blocked"] { color: #fecaca; }
|
|
1729
1859
|
.spotpatch-agent-workspace[data-state="blocked"]::before { background: var(--spotpatch-danger); }
|
|
1730
|
-
.spotpatch-agent-job { padding:
|
|
1860
|
+
.spotpatch-agent-job { padding: 12px; }
|
|
1731
1861
|
.spotpatch-agent-job-meta { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
|
|
1732
1862
|
.spotpatch-agent-model { min-width: 0; overflow: hidden; color: #d6dafe; font-size: 13px; text-overflow: ellipsis; white-space: nowrap; }
|
|
1733
1863
|
.spotpatch-agent-status {
|
|
@@ -2178,68 +2308,81 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
2178
2308
|
});
|
|
2179
2309
|
}
|
|
2180
2310
|
|
|
2311
|
+
// src/ui/brand-mark-content.ts
|
|
2312
|
+
var BRAND_MARK_CONTENT = `
|
|
2313
|
+
<defs>
|
|
2314
|
+
<linearGradient id="locator-gradient" x1="76" y1="92" x2="436" y2="374" gradientUnits="userSpaceOnUse">
|
|
2315
|
+
<stop offset="0" stop-color="#B61CFF" />
|
|
2316
|
+
<stop offset="0.38" stop-color="#6D35FF" />
|
|
2317
|
+
<stop offset="0.72" stop-color="#168EFF" />
|
|
2318
|
+
<stop offset="1" stop-color="#00D9E9" />
|
|
2319
|
+
</linearGradient>
|
|
2320
|
+
<linearGradient id="left-code-gradient" x1="165" y1="166" x2="236" y2="258" gradientUnits="userSpaceOnUse">
|
|
2321
|
+
<stop stop-color="#A51EFF" />
|
|
2322
|
+
<stop offset="1" stop-color="#653BFF" />
|
|
2323
|
+
</linearGradient>
|
|
2324
|
+
<linearGradient id="right-code-gradient" x1="276" y1="166" x2="347" y2="258" gradientUnits="userSpaceOnUse">
|
|
2325
|
+
<stop stop-color="#158DFF" />
|
|
2326
|
+
<stop offset="1" stop-color="#00D8E9" />
|
|
2327
|
+
</linearGradient>
|
|
2328
|
+
<linearGradient id="bolt-gradient" x1="270" y1="111" x2="252" y2="365" gradientUnits="userSpaceOnUse">
|
|
2329
|
+
<stop stop-color="#6840FF" />
|
|
2330
|
+
<stop offset="0.48" stop-color="#257BFF" />
|
|
2331
|
+
<stop offset="1" stop-color="#00CBEF" />
|
|
2332
|
+
</linearGradient>
|
|
2333
|
+
</defs>
|
|
2334
|
+
<path
|
|
2335
|
+
fill="url(#locator-gradient)"
|
|
2336
|
+
fill-rule="evenodd"
|
|
2337
|
+
clip-rule="evenodd"
|
|
2338
|
+
d="M256 52C345.47 52 418 124.53 418 214C418 267.55 391.98 316.24 354.04 348.02L256 468L157.96 348.02C120.02 316.24 94 267.55 94 214C94 124.53 166.53 52 256 52ZM256 88C186.41 88 130 144.41 130 214C130 258.2 152.76 297.08 187.2 319.57L256 403.8L324.8 319.57C359.24 297.08 382 258.2 382 214C382 144.41 325.59 88 256 88Z"
|
|
2339
|
+
/>
|
|
2340
|
+
<rect x="238" y="20" width="36" height="84" rx="4" fill="url(#locator-gradient)" />
|
|
2341
|
+
<rect x="62" y="196" width="84" height="36" rx="4" fill="url(#locator-gradient)" />
|
|
2342
|
+
<rect x="366" y="196" width="84" height="36" rx="4" fill="url(#locator-gradient)" />
|
|
2343
|
+
<path
|
|
2344
|
+
d="M213.5 160L158 211.5L213.5 263L238 236.5L211 211.5L238 186.5L213.5 160Z"
|
|
2345
|
+
fill="url(#left-code-gradient)"
|
|
2346
|
+
/>
|
|
2347
|
+
<path
|
|
2348
|
+
d="M298.5 160L354 211.5L298.5 263L274 236.5L301 211.5L274 186.5L298.5 160Z"
|
|
2349
|
+
fill="url(#right-code-gradient)"
|
|
2350
|
+
/>
|
|
2351
|
+
<path
|
|
2352
|
+
d="M283 108L232 212L266 253L238 369L302 237L267 198L283 108Z"
|
|
2353
|
+
fill="url(#bolt-gradient)"
|
|
2354
|
+
/>
|
|
2355
|
+
`;
|
|
2356
|
+
|
|
2181
2357
|
// src/ui/brand-mark.ts
|
|
2182
2358
|
var SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
2359
|
+
function resolveBrandMarkContent(override) {
|
|
2360
|
+
if (override !== void 0) {
|
|
2361
|
+
return { content: override, viewBox: "0 0 512 512" };
|
|
2362
|
+
}
|
|
2363
|
+
const injected = typeof __SPOTPATCH_BRAND_MARK_CONTENT__ === "string" ? __SPOTPATCH_BRAND_MARK_CONTENT__ : void 0;
|
|
2364
|
+
if (typeof injected === "string") {
|
|
2365
|
+
return { content: injected, viewBox: "0 0 512 512" };
|
|
2366
|
+
}
|
|
2367
|
+
return true ? { content: BRAND_MARK_CONTENT, viewBox: "0 0 512 512" } : { content: FALLBACK_BRAND_MARK_CONTENT, viewBox: "0 0 1 1" };
|
|
2368
|
+
}
|
|
2183
2369
|
function svgElement(document, tagName, attributes) {
|
|
2184
|
-
const
|
|
2370
|
+
const element2 = document.createElementNS(SVG_NAMESPACE, tagName);
|
|
2185
2371
|
for (const [name, value] of Object.entries(attributes)) {
|
|
2186
|
-
|
|
2372
|
+
element2.setAttribute(name, value);
|
|
2187
2373
|
}
|
|
2188
|
-
return
|
|
2374
|
+
return element2;
|
|
2189
2375
|
}
|
|
2190
|
-
function createBrandMark(document) {
|
|
2376
|
+
function createBrandMark(document, content) {
|
|
2377
|
+
const resolved = resolveBrandMarkContent(content);
|
|
2191
2378
|
const svg = svgElement(document, "svg", {
|
|
2379
|
+
xmlns: SVG_NAMESPACE,
|
|
2192
2380
|
class: "spotpatch-brand-mark",
|
|
2193
|
-
viewBox:
|
|
2381
|
+
viewBox: resolved.viewBox,
|
|
2194
2382
|
"aria-hidden": "true",
|
|
2195
2383
|
focusable: "false"
|
|
2196
2384
|
});
|
|
2197
|
-
|
|
2198
|
-
const gradient = svgElement(document, "linearGradient", {
|
|
2199
|
-
id: "spotpatch-brand-gradient",
|
|
2200
|
-
x1: "35",
|
|
2201
|
-
y1: "42",
|
|
2202
|
-
x2: "184",
|
|
2203
|
-
y2: "176",
|
|
2204
|
-
gradientUnits: "userSpaceOnUse"
|
|
2205
|
-
});
|
|
2206
|
-
gradient.append(
|
|
2207
|
-
svgElement(document, "stop", { offset: "0", "stop-color": "#7c22ff" }),
|
|
2208
|
-
svgElement(document, "stop", { offset: ".52", "stop-color": "#4a69ff" }),
|
|
2209
|
-
svgElement(document, "stop", { offset: "1", "stop-color": "#06d9ef" })
|
|
2210
|
-
);
|
|
2211
|
-
definitions.append(gradient);
|
|
2212
|
-
const commonStroke = {
|
|
2213
|
-
fill: "none",
|
|
2214
|
-
stroke: "url(#spotpatch-brand-gradient)",
|
|
2215
|
-
"stroke-linecap": "square",
|
|
2216
|
-
"stroke-linejoin": "miter"
|
|
2217
|
-
};
|
|
2218
|
-
const outer = svgElement(document, "path", {
|
|
2219
|
-
d: "M106 42C67 42 43 68 43 105c0 36 24 61 63 96 39-35 63-60 63-96 0-37-24-63-63-63Z",
|
|
2220
|
-
...commonStroke,
|
|
2221
|
-
"stroke-width": "14"
|
|
2222
|
-
});
|
|
2223
|
-
const topStem = svgElement(document, "path", {
|
|
2224
|
-
d: "M106 25v42",
|
|
2225
|
-
...commonStroke,
|
|
2226
|
-
"stroke-width": "14"
|
|
2227
|
-
});
|
|
2228
|
-
const sideStems = svgElement(document, "path", {
|
|
2229
|
-
d: "M35 109h20m102 0h38",
|
|
2230
|
-
...commonStroke,
|
|
2231
|
-
"stroke-width": "13"
|
|
2232
|
-
});
|
|
2233
|
-
const brackets = svgElement(document, "path", {
|
|
2234
|
-
d: "m94 89-18 19 18 17m39-36 18 19-18 17",
|
|
2235
|
-
...commonStroke,
|
|
2236
|
-
"stroke-width": "9"
|
|
2237
|
-
});
|
|
2238
|
-
const bolt = svgElement(document, "path", {
|
|
2239
|
-
d: "m119 61-20 45 15 11-13 47 30-56-16-12 4-35Z",
|
|
2240
|
-
fill: "url(#spotpatch-brand-gradient)"
|
|
2241
|
-
});
|
|
2242
|
-
svg.append(definitions, outer, topStem, sideStems, brackets, bolt);
|
|
2385
|
+
svg.innerHTML = resolved.content;
|
|
2243
2386
|
return svg;
|
|
2244
2387
|
}
|
|
2245
2388
|
|
|
@@ -2254,32 +2397,51 @@ function clamp(value, minimum, maximum) {
|
|
|
2254
2397
|
function calculateDialogPlacement({
|
|
2255
2398
|
dialogHeight,
|
|
2256
2399
|
dialogWidth,
|
|
2257
|
-
target,
|
|
2400
|
+
target: target2,
|
|
2258
2401
|
viewportHeight,
|
|
2259
2402
|
viewportWidth
|
|
2260
2403
|
}) {
|
|
2261
2404
|
const maxLeft = viewportWidth - dialogWidth - VIEWPORT_MARGIN;
|
|
2262
2405
|
const maxTop = viewportHeight - dialogHeight - VIEWPORT_MARGIN;
|
|
2263
|
-
const
|
|
2264
|
-
|
|
2406
|
+
const viewportLeft = clamp(
|
|
2407
|
+
(viewportWidth - dialogWidth) / 2,
|
|
2408
|
+
VIEWPORT_MARGIN,
|
|
2409
|
+
maxLeft
|
|
2410
|
+
);
|
|
2411
|
+
const viewportTop = clamp(
|
|
2412
|
+
(viewportHeight - dialogHeight) / 2,
|
|
2413
|
+
VIEWPORT_MARGIN,
|
|
2414
|
+
maxTop
|
|
2415
|
+
);
|
|
2416
|
+
if (target2 === void 0) {
|
|
2417
|
+
return Object.freeze({
|
|
2418
|
+
anchorX: clamp(dialogWidth / 2, ANCHOR_INSET, dialogWidth - ANCHOR_INSET),
|
|
2419
|
+
anchorY: clamp(dialogHeight / 2, ANCHOR_INSET, dialogHeight - ANCHOR_INSET),
|
|
2420
|
+
left: viewportLeft,
|
|
2421
|
+
mode: "viewport",
|
|
2422
|
+
top: viewportTop
|
|
2423
|
+
});
|
|
2424
|
+
}
|
|
2425
|
+
const targetCenterX = target2.x + target2.width / 2;
|
|
2426
|
+
const targetCenterY = target2.y + target2.height / 2;
|
|
2265
2427
|
const centeredLeft = clamp(targetCenterX - dialogWidth / 2, VIEWPORT_MARGIN, maxLeft);
|
|
2266
2428
|
const centeredTop = clamp(targetCenterY - dialogHeight / 2, VIEWPORT_MARGIN, maxTop);
|
|
2267
2429
|
let left = centeredLeft;
|
|
2268
2430
|
let top = centeredTop;
|
|
2269
2431
|
let mode = "viewport";
|
|
2270
|
-
if (
|
|
2432
|
+
if (target2.width >= dialogWidth + TARGET_INSET * 2 && target2.height >= dialogHeight + TARGET_INSET * 2) {
|
|
2271
2433
|
mode = "center";
|
|
2272
|
-
} else if (
|
|
2273
|
-
top =
|
|
2434
|
+
} else if (target2.y - dialogHeight - TARGET_GAP >= VIEWPORT_MARGIN) {
|
|
2435
|
+
top = target2.y - dialogHeight - TARGET_GAP;
|
|
2274
2436
|
mode = "above";
|
|
2275
|
-
} else if (
|
|
2276
|
-
top =
|
|
2437
|
+
} else if (target2.y + target2.height + TARGET_GAP + dialogHeight <= viewportHeight - VIEWPORT_MARGIN) {
|
|
2438
|
+
top = target2.y + target2.height + TARGET_GAP;
|
|
2277
2439
|
mode = "below";
|
|
2278
|
-
} else if (
|
|
2279
|
-
left =
|
|
2440
|
+
} else if (target2.x + target2.width + TARGET_GAP + dialogWidth <= viewportWidth - VIEWPORT_MARGIN) {
|
|
2441
|
+
left = target2.x + target2.width + TARGET_GAP;
|
|
2280
2442
|
mode = "right";
|
|
2281
|
-
} else if (
|
|
2282
|
-
left =
|
|
2443
|
+
} else if (target2.x - dialogWidth - TARGET_GAP >= VIEWPORT_MARGIN) {
|
|
2444
|
+
left = target2.x - dialogWidth - TARGET_GAP;
|
|
2283
2445
|
mode = "left";
|
|
2284
2446
|
}
|
|
2285
2447
|
return Object.freeze({
|
|
@@ -2596,7 +2758,7 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2596
2758
|
noSelectable: "No selectable element was found.",
|
|
2597
2759
|
allTargetsRemoved: "All targets were removed. Choose an element to continue.",
|
|
2598
2760
|
targetRemoved: "Selected target removed.",
|
|
2599
|
-
|
|
2761
|
+
detachedTargetPreserved: "The page element was unloaded; its collected context remains selected.",
|
|
2600
2762
|
contextWarning: "Browser context collection completed with a warning.",
|
|
2601
2763
|
contextCollected: "Browser context collected.",
|
|
2602
2764
|
editorOpening: "Opening source\u2026",
|
|
@@ -2732,7 +2894,7 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2732
2894
|
noSelectable: "\u5F53\u524D\u4F4D\u7F6E\u6CA1\u6709\u53EF\u9009\u62E9\u7684\u5143\u7D20\u3002",
|
|
2733
2895
|
allTargetsRemoved: "\u5DF2\u79FB\u9664\u5168\u90E8\u76EE\u6807\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u5143\u7D20\u3002",
|
|
2734
2896
|
targetRemoved: "\u5DF2\u79FB\u9664\u9009\u4E2D\u76EE\u6807\u3002",
|
|
2735
|
-
|
|
2897
|
+
detachedTargetPreserved: "\u9875\u9762\u5143\u7D20\u5DF2\u5378\u8F7D\uFF0C\u5DF2\u91C7\u96C6\u7684\u4E0A\u4E0B\u6587\u4ECD\u4FDD\u7559\u5728\u9009\u62E9\u4E2D\u3002",
|
|
2736
2898
|
contextWarning: "\u6D4F\u89C8\u5668\u4E0A\u4E0B\u6587\u91C7\u96C6\u5B8C\u6210\uFF0C\u4F46\u5B58\u5728\u8B66\u544A\u3002",
|
|
2737
2899
|
contextCollected: "\u6D4F\u89C8\u5668\u4E0A\u4E0B\u6587\u91C7\u96C6\u5B8C\u6210\u3002",
|
|
2738
2900
|
editorOpening: "\u6B63\u5728\u6253\u5F00\u6E90\u7801\u2026\u2026",
|
|
@@ -2790,33 +2952,36 @@ function createUiLocalizer(document, preference = "auto") {
|
|
|
2790
2952
|
}
|
|
2791
2953
|
|
|
2792
2954
|
// src/ui/runtime-view.ts
|
|
2793
|
-
var
|
|
2955
|
+
var DIALOG_MAX_WIDTH = 460;
|
|
2956
|
+
var DIALOG_MAX_HEIGHT = 620;
|
|
2794
2957
|
var DIALOG_FALLBACK_HEIGHT = Object.freeze({
|
|
2795
|
-
previewing:
|
|
2796
|
-
selected:
|
|
2958
|
+
previewing: 560,
|
|
2959
|
+
selected: DIALOG_MAX_HEIGHT
|
|
2797
2960
|
});
|
|
2798
2961
|
function createStyles(document) {
|
|
2799
2962
|
const style = document.createElement("style");
|
|
2800
2963
|
style.textContent = `
|
|
2801
2964
|
:host {
|
|
2802
2965
|
all: initial;
|
|
2803
|
-
--spotpatch-bg: #
|
|
2804
|
-
--spotpatch-bg-raised: #
|
|
2805
|
-
--spotpatch-bg-
|
|
2806
|
-
--spotpatch-
|
|
2807
|
-
--spotpatch-border
|
|
2808
|
-
--spotpatch-
|
|
2809
|
-
--spotpatch-text
|
|
2810
|
-
--spotpatch-text-
|
|
2811
|
-
--spotpatch-
|
|
2812
|
-
--spotpatch-accent
|
|
2813
|
-
--spotpatch-accent-
|
|
2966
|
+
--spotpatch-bg: #0e0e12;
|
|
2967
|
+
--spotpatch-bg-raised: #17171c;
|
|
2968
|
+
--spotpatch-bg-active: #1c1c22;
|
|
2969
|
+
--spotpatch-bg-input: #0b0b0f;
|
|
2970
|
+
--spotpatch-border: #2a2a32;
|
|
2971
|
+
--spotpatch-border-subtle: #232329;
|
|
2972
|
+
--spotpatch-text: #f2f2f5;
|
|
2973
|
+
--spotpatch-text-secondary: #96969f;
|
|
2974
|
+
--spotpatch-text-muted: #686872;
|
|
2975
|
+
--spotpatch-accent: #8b7bff;
|
|
2976
|
+
--spotpatch-accent-strong: #6a5ce8;
|
|
2977
|
+
--spotpatch-accent-cyan: #52a8ff;
|
|
2814
2978
|
--spotpatch-danger: #fb7185;
|
|
2815
2979
|
--spotpatch-success: #34d399;
|
|
2816
2980
|
--spotpatch-warning: #f59e0b;
|
|
2817
|
-
--spotpatch-
|
|
2818
|
-
--spotpatch-radius-
|
|
2819
|
-
--spotpatch-
|
|
2981
|
+
--spotpatch-text-on-accent: #0b0b12;
|
|
2982
|
+
--spotpatch-radius-panel: 16px;
|
|
2983
|
+
--spotpatch-radius-card: 10px;
|
|
2984
|
+
--spotpatch-shadow-panel: 0 30px 60px -20px rgb(0 0 0 / 70%);
|
|
2820
2985
|
color-scheme: dark;
|
|
2821
2986
|
color: var(--spotpatch-text);
|
|
2822
2987
|
font-family: Inter, "SF Pro Display", "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
@@ -2936,7 +3101,7 @@ function createStyles(document) {
|
|
|
2936
3101
|
left: 16px;
|
|
2937
3102
|
z-index: ${String(UI_Z_INDEX.controls)};
|
|
2938
3103
|
box-sizing: border-box;
|
|
2939
|
-
width: min(
|
|
3104
|
+
width: min(${String(DIALOG_MAX_WIDTH)}px, calc(100vw - 32px));
|
|
2940
3105
|
color: #edf0f7;
|
|
2941
3106
|
outline: none;
|
|
2942
3107
|
filter: drop-shadow(var(--spotpatch-shadow-panel));
|
|
@@ -2980,78 +3145,92 @@ function createStyles(document) {
|
|
|
2980
3145
|
position: relative;
|
|
2981
3146
|
z-index: 1;
|
|
2982
3147
|
display: flex;
|
|
2983
|
-
|
|
3148
|
+
box-sizing: border-box;
|
|
3149
|
+
max-height: min(${String(DIALOG_MAX_HEIGHT)}px, calc(100vh - 32px));
|
|
2984
3150
|
overflow: hidden;
|
|
2985
3151
|
flex-direction: column;
|
|
2986
3152
|
border: 1px solid var(--spotpatch-border);
|
|
2987
3153
|
border-radius: var(--spotpatch-radius-panel);
|
|
2988
3154
|
background: var(--spotpatch-bg);
|
|
2989
|
-
box-shadow: inset 0 1px rgb(255 255 255 /
|
|
3155
|
+
box-shadow: inset 0 1px rgb(255 255 255 / 5%), 0 0 60px -32px rgb(139 123 255 / 20%);
|
|
3156
|
+
}
|
|
3157
|
+
.spotpatch-shell::before {
|
|
3158
|
+
position: absolute;
|
|
3159
|
+
z-index: 2;
|
|
3160
|
+
top: 0;
|
|
3161
|
+
right: 20%;
|
|
3162
|
+
left: 20%;
|
|
3163
|
+
height: 1px;
|
|
3164
|
+
background: linear-gradient(90deg, transparent, var(--spotpatch-accent), var(--spotpatch-accent-cyan), transparent);
|
|
3165
|
+
content: "";
|
|
3166
|
+
opacity: .65;
|
|
3167
|
+
pointer-events: none;
|
|
2990
3168
|
}
|
|
2991
3169
|
.spotpatch-header {
|
|
2992
3170
|
position: relative;
|
|
2993
|
-
padding:
|
|
2994
|
-
border-bottom: 1px solid rgb(255 255 255 / 8%);
|
|
3171
|
+
padding: 0 18px 14px;
|
|
2995
3172
|
}
|
|
2996
3173
|
.spotpatch-brand-row {
|
|
2997
3174
|
display: flex;
|
|
2998
3175
|
align-items: center;
|
|
2999
3176
|
justify-content: space-between;
|
|
3000
|
-
gap:
|
|
3001
|
-
margin
|
|
3177
|
+
gap: 12px;
|
|
3178
|
+
margin: 0 -18px 18px;
|
|
3179
|
+
padding: 14px 18px 13px;
|
|
3180
|
+
border-bottom: 1px solid var(--spotpatch-border-subtle);
|
|
3002
3181
|
}
|
|
3003
3182
|
.spotpatch-brand {
|
|
3004
3183
|
display: inline-flex;
|
|
3005
3184
|
align-items: center;
|
|
3006
|
-
gap:
|
|
3185
|
+
gap: 10px;
|
|
3007
3186
|
min-width: 0;
|
|
3008
3187
|
color: #f8fafc;
|
|
3009
3188
|
}
|
|
3010
3189
|
.spotpatch-brand-mark {
|
|
3011
|
-
width:
|
|
3012
|
-
height:
|
|
3190
|
+
width: 30px;
|
|
3191
|
+
height: 30px;
|
|
3013
3192
|
flex: none;
|
|
3014
3193
|
filter: drop-shadow(0 6px 12px rgb(76 29 149 / 22%));
|
|
3015
3194
|
}
|
|
3016
3195
|
.spotpatch-brand-copy { display: grid; min-width: 0; gap: 1px; }
|
|
3017
3196
|
.spotpatch-brand-name {
|
|
3018
3197
|
color: #fff;
|
|
3019
|
-
font-size:
|
|
3020
|
-
font-weight:
|
|
3198
|
+
font-size: 13.5px;
|
|
3199
|
+
font-weight: 680;
|
|
3021
3200
|
letter-spacing: -.01em;
|
|
3022
3201
|
}
|
|
3023
3202
|
.spotpatch-brand-context {
|
|
3024
3203
|
color: #8e98aa;
|
|
3025
|
-
font-size:
|
|
3204
|
+
font-size: 10.5px;
|
|
3026
3205
|
font-weight: 560;
|
|
3027
3206
|
letter-spacing: .02em;
|
|
3028
3207
|
}
|
|
3029
3208
|
.spotpatch-header-controls {
|
|
3030
3209
|
display: inline-flex;
|
|
3031
3210
|
align-items: center;
|
|
3032
|
-
gap:
|
|
3211
|
+
gap: 6px;
|
|
3033
3212
|
flex: none;
|
|
3034
3213
|
}
|
|
3035
3214
|
.spotpatch-repository,
|
|
3036
3215
|
.spotpatch-locale,
|
|
3037
3216
|
.spotpatch-close {
|
|
3038
|
-
height:
|
|
3217
|
+
height: 27px;
|
|
3039
3218
|
border: 1px solid rgb(255 255 255 / 11%);
|
|
3040
|
-
border-radius:
|
|
3041
|
-
background:
|
|
3219
|
+
border-radius: 7px;
|
|
3220
|
+
background: transparent;
|
|
3042
3221
|
}
|
|
3043
3222
|
.spotpatch-repository {
|
|
3044
3223
|
display: inline-flex;
|
|
3045
3224
|
align-items: center;
|
|
3046
|
-
padding: 0
|
|
3047
|
-
color:
|
|
3225
|
+
padding: 0 9px;
|
|
3226
|
+
color: var(--spotpatch-text-secondary);
|
|
3048
3227
|
font-size: 11px;
|
|
3049
3228
|
font-weight: 680;
|
|
3050
3229
|
text-decoration: none;
|
|
3051
3230
|
}
|
|
3052
3231
|
.spotpatch-locale {
|
|
3053
|
-
min-width:
|
|
3054
|
-
padding: 0
|
|
3232
|
+
min-width: 34px;
|
|
3233
|
+
padding: 0 8px;
|
|
3055
3234
|
color: #c5cad5;
|
|
3056
3235
|
cursor: pointer;
|
|
3057
3236
|
font-size: 12px;
|
|
@@ -3059,12 +3238,12 @@ function createStyles(document) {
|
|
|
3059
3238
|
}
|
|
3060
3239
|
.spotpatch-close {
|
|
3061
3240
|
display: inline-grid;
|
|
3062
|
-
width:
|
|
3241
|
+
width: 27px;
|
|
3063
3242
|
padding: 0;
|
|
3064
3243
|
place-items: center;
|
|
3065
3244
|
color: #9da5b4;
|
|
3066
3245
|
cursor: pointer;
|
|
3067
|
-
font-size:
|
|
3246
|
+
font-size: 15px;
|
|
3068
3247
|
line-height: 1;
|
|
3069
3248
|
transition: border-color 150ms ease, color 150ms ease, background 150ms ease;
|
|
3070
3249
|
}
|
|
@@ -3074,30 +3253,30 @@ function createStyles(document) {
|
|
|
3074
3253
|
.spotpatch-title {
|
|
3075
3254
|
margin: 0;
|
|
3076
3255
|
color: #fff;
|
|
3077
|
-
font-size:
|
|
3078
|
-
font-weight:
|
|
3079
|
-
letter-spacing: -.
|
|
3256
|
+
font-size: 18px;
|
|
3257
|
+
font-weight: 680;
|
|
3258
|
+
letter-spacing: -.015em;
|
|
3080
3259
|
}
|
|
3081
3260
|
.spotpatch-subtitle {
|
|
3082
|
-
max-width:
|
|
3083
|
-
margin:
|
|
3084
|
-
color:
|
|
3085
|
-
font-size:
|
|
3086
|
-
line-height: 1.
|
|
3261
|
+
max-width: 390px;
|
|
3262
|
+
margin: 4px 0 0;
|
|
3263
|
+
color: var(--spotpatch-text-secondary);
|
|
3264
|
+
font-size: 12.5px;
|
|
3265
|
+
line-height: 1.5;
|
|
3087
3266
|
}
|
|
3088
3267
|
.spotpatch-target-row {
|
|
3089
3268
|
display: flex;
|
|
3090
3269
|
align-items: center;
|
|
3091
3270
|
gap: 8px;
|
|
3092
3271
|
min-width: 0;
|
|
3093
|
-
margin-top:
|
|
3272
|
+
margin-top: 14px;
|
|
3094
3273
|
}
|
|
3095
3274
|
.spotpatch-target-label {
|
|
3096
3275
|
min-width: 0;
|
|
3097
3276
|
overflow: hidden;
|
|
3098
3277
|
border: 1px solid rgb(129 112 247 / 24%);
|
|
3099
3278
|
border-radius: 999px;
|
|
3100
|
-
padding:
|
|
3279
|
+
padding: 4px 10px;
|
|
3101
3280
|
color: #cdd2ff;
|
|
3102
3281
|
background: rgb(109 93 246 / 10%);
|
|
3103
3282
|
font: 600 11px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
@@ -3110,7 +3289,7 @@ function createStyles(document) {
|
|
|
3110
3289
|
gap: 6px;
|
|
3111
3290
|
flex: none;
|
|
3112
3291
|
color: #a5adba;
|
|
3113
|
-
font-size:
|
|
3292
|
+
font-size: 11px;
|
|
3114
3293
|
white-space: nowrap;
|
|
3115
3294
|
}
|
|
3116
3295
|
.spotpatch-context-state::before {
|
|
@@ -3131,7 +3310,7 @@ function createStyles(document) {
|
|
|
3131
3310
|
.spotpatch-body {
|
|
3132
3311
|
min-height: 0;
|
|
3133
3312
|
overflow: auto;
|
|
3134
|
-
padding:
|
|
3313
|
+
padding: 0 18px 14px;
|
|
3135
3314
|
scrollbar-color: rgb(100 116 139 / 50%) transparent;
|
|
3136
3315
|
scrollbar-width: thin;
|
|
3137
3316
|
}
|
|
@@ -3142,36 +3321,54 @@ function createStyles(document) {
|
|
|
3142
3321
|
display: flex;
|
|
3143
3322
|
align-items: center;
|
|
3144
3323
|
justify-content: space-between;
|
|
3145
|
-
gap:
|
|
3146
|
-
margin-bottom:
|
|
3147
|
-
color:
|
|
3148
|
-
font-size:
|
|
3149
|
-
font-weight:
|
|
3324
|
+
gap: 10px;
|
|
3325
|
+
margin-bottom: 8px;
|
|
3326
|
+
color: var(--spotpatch-text-secondary);
|
|
3327
|
+
font-size: 11px;
|
|
3328
|
+
font-weight: 650;
|
|
3329
|
+
letter-spacing: .04em;
|
|
3330
|
+
text-transform: uppercase;
|
|
3150
3331
|
}
|
|
3151
3332
|
.spotpatch-targets-meta {
|
|
3152
3333
|
display: flex;
|
|
3153
3334
|
align-items: center;
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3335
|
+
gap: 8px;
|
|
3336
|
+
min-width: 0;
|
|
3337
|
+
letter-spacing: 0;
|
|
3338
|
+
text-transform: none;
|
|
3157
3339
|
}
|
|
3158
|
-
.spotpatch-target-complete { color: var(--spotpatch-text-
|
|
3340
|
+
.spotpatch-target-complete { color: var(--spotpatch-text-muted); font-size: 11px; font-weight: 560; }
|
|
3159
3341
|
.spotpatch-target-budget {
|
|
3160
3342
|
color: var(--spotpatch-text-muted);
|
|
3161
|
-
font: 550
|
|
3343
|
+
font: 550 10.5px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
3162
3344
|
}
|
|
3345
|
+
.spotpatch-target-budget[data-state="ready"] { display: none; }
|
|
3163
3346
|
.spotpatch-target-budget[data-state="over"] { color: #fda4af; }
|
|
3164
3347
|
.spotpatch-target-count {
|
|
3348
|
+
margin-left: auto;
|
|
3165
3349
|
border-radius: 999px;
|
|
3166
3350
|
padding: 3px 8px;
|
|
3167
|
-
color:
|
|
3168
|
-
|
|
3169
|
-
|
|
3351
|
+
color: var(--spotpatch-text-muted);
|
|
3352
|
+
font: 600 10.5px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
3353
|
+
}
|
|
3354
|
+
.spotpatch-target-progress {
|
|
3355
|
+
height: 3px;
|
|
3356
|
+
margin-bottom: 13px;
|
|
3357
|
+
overflow: hidden;
|
|
3358
|
+
border-radius: 999px;
|
|
3359
|
+
background: var(--spotpatch-border-subtle);
|
|
3360
|
+
}
|
|
3361
|
+
.spotpatch-target-progress-fill {
|
|
3362
|
+
width: 0;
|
|
3363
|
+
height: 100%;
|
|
3364
|
+
border-radius: inherit;
|
|
3365
|
+
background: linear-gradient(90deg, var(--spotpatch-accent), var(--spotpatch-accent-cyan));
|
|
3366
|
+
transition: width 180ms ease;
|
|
3170
3367
|
}
|
|
3171
3368
|
.spotpatch-target-list {
|
|
3172
3369
|
display: grid;
|
|
3173
|
-
gap:
|
|
3174
|
-
max-height: min(
|
|
3370
|
+
gap: 8px;
|
|
3371
|
+
max-height: min(340px, 48vh);
|
|
3175
3372
|
overflow: auto;
|
|
3176
3373
|
padding-right: 2px;
|
|
3177
3374
|
}
|
|
@@ -3179,30 +3376,30 @@ function createStyles(document) {
|
|
|
3179
3376
|
overflow: hidden;
|
|
3180
3377
|
border: 1px solid var(--spotpatch-border-subtle);
|
|
3181
3378
|
border-radius: var(--spotpatch-radius-card);
|
|
3182
|
-
background:
|
|
3379
|
+
background: var(--spotpatch-bg-raised);
|
|
3183
3380
|
transition: border-color 150ms ease, background 150ms ease;
|
|
3184
3381
|
}
|
|
3185
3382
|
.spotpatch-target-item[data-active="true"] {
|
|
3186
|
-
border-color: rgb(
|
|
3187
|
-
background:
|
|
3188
|
-
box-shadow:
|
|
3383
|
+
border-color: rgb(139 123 255 / 34%);
|
|
3384
|
+
background: var(--spotpatch-bg-active);
|
|
3385
|
+
box-shadow: 0 0 0 3px rgb(139 123 255 / 10%);
|
|
3189
3386
|
}
|
|
3190
3387
|
.spotpatch-target-summary {
|
|
3191
3388
|
display: grid;
|
|
3192
|
-
grid-template-columns: minmax(0, 1fr)
|
|
3389
|
+
grid-template-columns: minmax(0, 1fr) 28px 28px;
|
|
3193
3390
|
align-items: stretch;
|
|
3194
|
-
gap:
|
|
3195
|
-
padding:
|
|
3391
|
+
gap: 2px;
|
|
3392
|
+
padding: 4px;
|
|
3196
3393
|
}
|
|
3197
3394
|
.spotpatch-target-select {
|
|
3198
3395
|
display: grid;
|
|
3199
|
-
grid-template-columns:
|
|
3396
|
+
grid-template-columns: 24px minmax(0, 1fr) auto;
|
|
3200
3397
|
align-items: center;
|
|
3201
|
-
gap:
|
|
3398
|
+
gap: 9px;
|
|
3202
3399
|
min-width: 0;
|
|
3203
3400
|
border: 0;
|
|
3204
|
-
border-radius:
|
|
3205
|
-
padding:
|
|
3401
|
+
border-radius: 8px;
|
|
3402
|
+
padding: 8px;
|
|
3206
3403
|
color: inherit;
|
|
3207
3404
|
background: transparent;
|
|
3208
3405
|
cursor: pointer;
|
|
@@ -3211,14 +3408,14 @@ function createStyles(document) {
|
|
|
3211
3408
|
.spotpatch-target-select:hover { background: rgb(255 255 255 / 3.5%); }
|
|
3212
3409
|
.spotpatch-target-index {
|
|
3213
3410
|
display: inline-grid;
|
|
3214
|
-
width:
|
|
3215
|
-
height:
|
|
3411
|
+
width: 22px;
|
|
3412
|
+
height: 22px;
|
|
3216
3413
|
place-items: center;
|
|
3217
3414
|
border: 1px solid rgb(68 202 224 / 25%);
|
|
3218
|
-
border-radius:
|
|
3219
|
-
color:
|
|
3220
|
-
background:
|
|
3221
|
-
font:
|
|
3415
|
+
border-radius: 6px;
|
|
3416
|
+
color: var(--spotpatch-text-secondary);
|
|
3417
|
+
background: var(--spotpatch-bg);
|
|
3418
|
+
font: 650 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
3222
3419
|
}
|
|
3223
3420
|
.spotpatch-target-copy { min-width: 0; }
|
|
3224
3421
|
.spotpatch-target-name,
|
|
@@ -3228,14 +3425,14 @@ function createStyles(document) {
|
|
|
3228
3425
|
text-overflow: ellipsis;
|
|
3229
3426
|
white-space: nowrap;
|
|
3230
3427
|
}
|
|
3231
|
-
.spotpatch-target-name { color: #
|
|
3232
|
-
.spotpatch-target-source { margin-top:
|
|
3428
|
+
.spotpatch-target-name { color: #f2f2f5; font-size: 13px; font-weight: 650; }
|
|
3429
|
+
.spotpatch-target-source { margin-top: 1px; color: var(--spotpatch-text-muted); font: 500 10.5px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; }
|
|
3233
3430
|
.spotpatch-target-state {
|
|
3234
3431
|
border-radius: 999px;
|
|
3235
|
-
padding:
|
|
3432
|
+
padding: 3px 8px;
|
|
3236
3433
|
color: #a7f3d0;
|
|
3237
3434
|
background: rgb(16 185 129 / 9%);
|
|
3238
|
-
font-size:
|
|
3435
|
+
font-size: 10.5px;
|
|
3239
3436
|
font-weight: 650;
|
|
3240
3437
|
white-space: nowrap;
|
|
3241
3438
|
}
|
|
@@ -3243,13 +3440,13 @@ function createStyles(document) {
|
|
|
3243
3440
|
.spotpatch-target-open,
|
|
3244
3441
|
.spotpatch-target-remove {
|
|
3245
3442
|
display: inline-grid;
|
|
3246
|
-
width:
|
|
3443
|
+
width: 28px;
|
|
3247
3444
|
height: 100%;
|
|
3248
|
-
min-height:
|
|
3445
|
+
min-height: 34px;
|
|
3249
3446
|
padding: 0;
|
|
3250
3447
|
place-items: center;
|
|
3251
3448
|
border: 1px solid transparent;
|
|
3252
|
-
border-radius:
|
|
3449
|
+
border-radius: 7px;
|
|
3253
3450
|
color: #7f899a;
|
|
3254
3451
|
background: transparent;
|
|
3255
3452
|
cursor: pointer;
|
|
@@ -3258,31 +3455,30 @@ function createStyles(document) {
|
|
|
3258
3455
|
.spotpatch-target-open:hover:not(:disabled) { border-color: rgb(68 202 224 / 30%); color: #c8f7ff; background: rgb(8 145 178 / 11%); }
|
|
3259
3456
|
.spotpatch-target-remove:hover:not(:disabled) { border-color: rgb(251 113 133 / 24%); color: #fda4af; background: rgb(127 29 29 / 12%); }
|
|
3260
3457
|
.spotpatch-target-editor {
|
|
3261
|
-
|
|
3262
|
-
padding: 18px;
|
|
3458
|
+
padding: 0 12px 12px;
|
|
3263
3459
|
}
|
|
3264
3460
|
.spotpatch-target-editor-head {
|
|
3265
3461
|
display: flex;
|
|
3266
3462
|
align-items: baseline;
|
|
3267
3463
|
justify-content: space-between;
|
|
3268
3464
|
gap: 12px;
|
|
3269
|
-
margin-bottom:
|
|
3465
|
+
margin-bottom: 6px;
|
|
3270
3466
|
}
|
|
3271
|
-
.spotpatch-target-editor-label { color:
|
|
3272
|
-
.spotpatch-target-editor-count { color: var(--spotpatch-text-muted); font: 500
|
|
3467
|
+
.spotpatch-target-editor-label { color: var(--spotpatch-text-secondary); font-size: 11px; font-weight: 650; }
|
|
3468
|
+
.spotpatch-target-editor-count { color: var(--spotpatch-text-muted); font: 500 10.5px/1.3 ui-monospace, SFMono-Regular, Menlo, monospace; }
|
|
3273
3469
|
.spotpatch-target-editor textarea {
|
|
3274
3470
|
box-sizing: border-box;
|
|
3275
3471
|
width: 100%;
|
|
3276
|
-
min-height:
|
|
3472
|
+
min-height: 74px;
|
|
3277
3473
|
resize: vertical;
|
|
3278
3474
|
border: 1px solid var(--spotpatch-border);
|
|
3279
|
-
border-radius:
|
|
3280
|
-
padding:
|
|
3475
|
+
border-radius: 7px;
|
|
3476
|
+
padding: 9px 10px;
|
|
3281
3477
|
color: #f8fafc;
|
|
3282
3478
|
caret-color: #8b7cf7;
|
|
3283
3479
|
background: var(--spotpatch-bg-input);
|
|
3284
|
-
font-size:
|
|
3285
|
-
line-height: 1.
|
|
3480
|
+
font-size: 12.5px;
|
|
3481
|
+
line-height: 1.55;
|
|
3286
3482
|
outline: none;
|
|
3287
3483
|
transition: border-color 150ms ease, box-shadow 150ms ease, background 150ms ease;
|
|
3288
3484
|
}
|
|
@@ -3291,23 +3487,23 @@ function createStyles(document) {
|
|
|
3291
3487
|
.spotpatch-target-editor textarea:focus {
|
|
3292
3488
|
border-color: rgb(139 124 247 / 68%);
|
|
3293
3489
|
background: rgb(3 7 18 / 65%);
|
|
3294
|
-
box-shadow: 0 0 0
|
|
3490
|
+
box-shadow: 0 0 0 2px rgb(109 93 246 / 10%);
|
|
3295
3491
|
}
|
|
3296
3492
|
.spotpatch-diagnostics {
|
|
3297
|
-
margin-top:
|
|
3493
|
+
margin-top: 10px;
|
|
3298
3494
|
overflow: hidden;
|
|
3299
3495
|
border: 1px solid rgb(255 255 255 / 8%);
|
|
3300
|
-
border-radius:
|
|
3496
|
+
border-radius: 9px;
|
|
3301
3497
|
background: rgb(255 255 255 / 2.5%);
|
|
3302
3498
|
}
|
|
3303
3499
|
.spotpatch-diagnostics > summary {
|
|
3304
3500
|
display: flex;
|
|
3305
3501
|
align-items: center;
|
|
3306
3502
|
gap: 8px;
|
|
3307
|
-
padding: 11px
|
|
3503
|
+
padding: 9px 11px;
|
|
3308
3504
|
color: #bfc5d0;
|
|
3309
3505
|
cursor: pointer;
|
|
3310
|
-
font-size:
|
|
3506
|
+
font-size: 11px;
|
|
3311
3507
|
font-weight: 650;
|
|
3312
3508
|
list-style: none;
|
|
3313
3509
|
user-select: none;
|
|
@@ -3336,9 +3532,9 @@ function createStyles(document) {
|
|
|
3336
3532
|
margin: 0;
|
|
3337
3533
|
overflow: auto;
|
|
3338
3534
|
border-top: 1px solid rgb(255 255 255 / 7%);
|
|
3339
|
-
padding:
|
|
3535
|
+
padding: 10px 11px 11px;
|
|
3340
3536
|
color: #9ca5b5;
|
|
3341
|
-
font:
|
|
3537
|
+
font: 10.5px/1.55 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
3342
3538
|
overflow-wrap: anywhere;
|
|
3343
3539
|
white-space: pre-wrap;
|
|
3344
3540
|
user-select: text;
|
|
@@ -3348,39 +3544,44 @@ function createStyles(document) {
|
|
|
3348
3544
|
margin: 0;
|
|
3349
3545
|
overflow: auto;
|
|
3350
3546
|
border: 1px solid rgb(255 255 255 / 9%);
|
|
3351
|
-
border-radius:
|
|
3352
|
-
padding:
|
|
3547
|
+
border-radius: 9px;
|
|
3548
|
+
padding: 11px;
|
|
3353
3549
|
color: #d8ddeb;
|
|
3354
3550
|
background: rgb(3 7 18 / 55%);
|
|
3355
|
-
font:
|
|
3551
|
+
font: 11px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
3356
3552
|
overflow-wrap: anywhere;
|
|
3357
3553
|
white-space: pre-wrap;
|
|
3358
3554
|
user-select: text;
|
|
3359
3555
|
}
|
|
3360
3556
|
.spotpatch-actions {
|
|
3361
|
-
display:
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
padding: 14px 22px 18px;
|
|
3557
|
+
display: grid;
|
|
3558
|
+
gap: 8px;
|
|
3559
|
+
padding: 10px 18px 14px;
|
|
3365
3560
|
border-top: 1px solid rgb(255 255 255 / 8%);
|
|
3366
|
-
background: rgb(8 12
|
|
3561
|
+
background: rgb(8 8 12 / 86%);
|
|
3367
3562
|
}
|
|
3368
3563
|
.spotpatch-editor-feedback {
|
|
3369
|
-
flex-basis: 100%;
|
|
3370
3564
|
white-space: normal;
|
|
3371
3565
|
}
|
|
3566
|
+
.spotpatch-secondary-actions,
|
|
3567
|
+
.spotpatch-primary-actions {
|
|
3568
|
+
display: flex;
|
|
3569
|
+
align-items: center;
|
|
3570
|
+
gap: 7px;
|
|
3571
|
+
}
|
|
3572
|
+
.spotpatch-secondary-actions { min-height: 30px; }
|
|
3372
3573
|
.spotpatch-actions button {
|
|
3373
3574
|
display: inline-flex;
|
|
3374
|
-
min-height:
|
|
3575
|
+
min-height: 34px;
|
|
3375
3576
|
align-items: center;
|
|
3376
3577
|
justify-content: center;
|
|
3377
3578
|
border: 1px solid rgb(255 255 255 / 10%);
|
|
3378
|
-
border-radius:
|
|
3379
|
-
padding:
|
|
3380
|
-
color:
|
|
3579
|
+
border-radius: 9px;
|
|
3580
|
+
padding: 7px 11px;
|
|
3581
|
+
color: var(--spotpatch-text-secondary);
|
|
3381
3582
|
background: rgb(255 255 255 / 4%);
|
|
3382
3583
|
cursor: pointer;
|
|
3383
|
-
font-size:
|
|
3584
|
+
font-size: 12px;
|
|
3384
3585
|
font-weight: 650;
|
|
3385
3586
|
transition: border-color 150ms ease, box-shadow 150ms ease, color 150ms ease, transform 150ms ease;
|
|
3386
3587
|
}
|
|
@@ -3390,14 +3591,36 @@ function createStyles(document) {
|
|
|
3390
3591
|
transform: translateY(-1px);
|
|
3391
3592
|
}
|
|
3392
3593
|
.spotpatch-actions .spotpatch-primary {
|
|
3393
|
-
min-width:
|
|
3594
|
+
min-width: 138px;
|
|
3394
3595
|
flex: 1;
|
|
3395
|
-
border-color:
|
|
3396
|
-
color:
|
|
3397
|
-
background: var(--spotpatch-accent-strong);
|
|
3398
|
-
box-shadow: 0
|
|
3596
|
+
border-color: transparent;
|
|
3597
|
+
color: var(--spotpatch-text-on-accent);
|
|
3598
|
+
background: linear-gradient(135deg, var(--spotpatch-accent), var(--spotpatch-accent-strong));
|
|
3599
|
+
box-shadow: 0 8px 20px -8px rgb(139 123 255 / 55%);
|
|
3399
3600
|
}
|
|
3601
|
+
.spotpatch-actions .spotpatch-primary:hover:not(:disabled) { color: var(--spotpatch-text-on-accent); filter: brightness(1.08); }
|
|
3400
3602
|
.spotpatch-actions .spotpatch-primary::after { margin-left: 8px; content: "\u2197"; font-size: 12px; }
|
|
3603
|
+
.spotpatch-actions .spotpatch-secondary-action {
|
|
3604
|
+
min-height: 30px;
|
|
3605
|
+
border-style: dashed;
|
|
3606
|
+
padding: 5px 10px;
|
|
3607
|
+
color: var(--spotpatch-text-muted);
|
|
3608
|
+
background: transparent;
|
|
3609
|
+
font-size: 11px;
|
|
3610
|
+
}
|
|
3611
|
+
.spotpatch-actions .spotpatch-icon-action {
|
|
3612
|
+
width: 34px;
|
|
3613
|
+
min-width: 34px;
|
|
3614
|
+
padding: 0;
|
|
3615
|
+
font-size: 0;
|
|
3616
|
+
}
|
|
3617
|
+
.spotpatch-actions .spotpatch-icon-action::before {
|
|
3618
|
+
color: var(--spotpatch-text-secondary);
|
|
3619
|
+
content: attr(data-compact-icon);
|
|
3620
|
+
font-size: 18px;
|
|
3621
|
+
font-weight: 400;
|
|
3622
|
+
line-height: 1;
|
|
3623
|
+
}
|
|
3401
3624
|
.spotpatch-actions button:disabled { cursor: not-allowed; opacity: .4; transform: none; }
|
|
3402
3625
|
.spotpatch-actions button:focus-visible,
|
|
3403
3626
|
.spotpatch-repository:focus-visible,
|
|
@@ -3429,11 +3652,13 @@ function createStyles(document) {
|
|
|
3429
3652
|
}
|
|
3430
3653
|
@media (max-width: 520px) {
|
|
3431
3654
|
.spotpatch-dialog { top: 8px; left: 8px; width: calc(100vw - 16px); }
|
|
3432
|
-
.spotpatch-shell { max-height: calc(100vh - 16px); border-radius:
|
|
3433
|
-
.spotpatch-header, .spotpatch-body { padding-left:
|
|
3434
|
-
.spotpatch-
|
|
3435
|
-
.spotpatch-
|
|
3655
|
+
.spotpatch-shell { max-height: calc(100vh - 16px); border-radius: 14px; }
|
|
3656
|
+
.spotpatch-header, .spotpatch-body { padding-left: 14px; padding-right: 14px; }
|
|
3657
|
+
.spotpatch-brand-row { margin-right: -14px; margin-left: -14px; padding-right: 14px; padding-left: 14px; }
|
|
3658
|
+
.spotpatch-actions { padding-right: 14px; padding-left: 14px; }
|
|
3659
|
+
.spotpatch-target-select { grid-template-columns: 24px minmax(0, 1fr); }
|
|
3436
3660
|
.spotpatch-target-state { display: none; }
|
|
3661
|
+
.spotpatch-repository { display: none; }
|
|
3437
3662
|
}
|
|
3438
3663
|
${AGENT_PANEL_STYLES}
|
|
3439
3664
|
`;
|
|
@@ -3536,10 +3761,17 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3536
3761
|
const targetCount = createMarkedElement(document, "span");
|
|
3537
3762
|
targetCount.className = "spotpatch-target-count";
|
|
3538
3763
|
targetsMeta.append(targetComplete, targetBudget);
|
|
3539
|
-
|
|
3764
|
+
targetRow.append(targetCount);
|
|
3765
|
+
targetsHeading.append(targetsTitle, targetsMeta);
|
|
3766
|
+
const targetProgress = createMarkedElement(document, "div");
|
|
3767
|
+
targetProgress.className = "spotpatch-target-progress";
|
|
3768
|
+
targetProgress.setAttribute("aria-hidden", "true");
|
|
3769
|
+
const targetProgressFill = createMarkedElement(document, "div");
|
|
3770
|
+
targetProgressFill.className = "spotpatch-target-progress-fill";
|
|
3771
|
+
targetProgress.append(targetProgressFill);
|
|
3540
3772
|
const targetList = createMarkedElement(document, "div");
|
|
3541
3773
|
targetList.className = "spotpatch-target-list";
|
|
3542
|
-
targetsPanel.append(targetsHeading,
|
|
3774
|
+
targetsPanel.append(targetsHeading, targetProgress, targetList);
|
|
3543
3775
|
const diagnostics = createMarkedElement(document, "details");
|
|
3544
3776
|
diagnostics.className = "spotpatch-diagnostics";
|
|
3545
3777
|
const diagnosticsLabel = createMarkedElement(document, "summary");
|
|
@@ -3580,21 +3812,30 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3580
3812
|
);
|
|
3581
3813
|
const copyButton = createButton(document, messages.actions.copy, "spotpatch-primary");
|
|
3582
3814
|
const backButton = createButton(document, messages.actions.back);
|
|
3583
|
-
|
|
3584
|
-
|
|
3815
|
+
const secondaryActions = createMarkedElement(document, "div");
|
|
3816
|
+
secondaryActions.className = "spotpatch-secondary-actions";
|
|
3817
|
+
const primaryActions = createMarkedElement(document, "div");
|
|
3818
|
+
primaryActions.className = "spotpatch-primary-actions";
|
|
3819
|
+
addTargetButton.classList.add("spotpatch-icon-action");
|
|
3820
|
+
addTargetButton.dataset.compactIcon = "+";
|
|
3821
|
+
agentPanel.testButton.classList.add("spotpatch-icon-action");
|
|
3822
|
+
agentPanel.testButton.dataset.compactIcon = "\u2713";
|
|
3823
|
+
openEditorButton.classList.add("spotpatch-secondary-action");
|
|
3824
|
+
reselectButton.classList.add("spotpatch-secondary-action");
|
|
3825
|
+
secondaryActions.append(openEditorButton, reselectButton);
|
|
3826
|
+
primaryActions.append(
|
|
3827
|
+
agentPanel.testButton,
|
|
3828
|
+
addTargetButton,
|
|
3585
3829
|
agentPanel.runButton,
|
|
3586
3830
|
previewButton,
|
|
3587
|
-
agentPanel.testButton,
|
|
3588
3831
|
agentPanel.cancelButton,
|
|
3589
3832
|
agentPanel.applyButton,
|
|
3590
3833
|
agentPanel.revertButton,
|
|
3591
3834
|
agentPanel.resetButton,
|
|
3592
|
-
addTargetButton,
|
|
3593
|
-
openEditorButton,
|
|
3594
|
-
reselectButton,
|
|
3595
3835
|
copyButton,
|
|
3596
3836
|
backButton
|
|
3597
3837
|
);
|
|
3838
|
+
actions.append(editorFeedback, secondaryActions, primaryActions);
|
|
3598
3839
|
shell.append(header, body, actions);
|
|
3599
3840
|
dialog.append(anchor, shell);
|
|
3600
3841
|
const liveRegion = createMarkedElement(document, "div");
|
|
@@ -3627,11 +3868,15 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3627
3868
|
editorFeedback.textContent = state === "opening" ? messages.announcements.editorOpening : state === "success" ? messages.announcements.editorOpened : state === "error" ? messages.announcements.editorFailed : "";
|
|
3628
3869
|
placeDialog();
|
|
3629
3870
|
}
|
|
3630
|
-
function statusText(
|
|
3631
|
-
if (
|
|
3871
|
+
function statusText(target2) {
|
|
3872
|
+
if (target2.status === "ready") {
|
|
3632
3873
|
return messages.targets.statusReady;
|
|
3633
3874
|
}
|
|
3634
|
-
return
|
|
3875
|
+
return target2.status === "warning" ? messages.targets.statusPartial : messages.targets.statusCollecting;
|
|
3876
|
+
}
|
|
3877
|
+
function renderTargetProgress(complete, total) {
|
|
3878
|
+
const ratio = total === 0 ? 0 : complete / total;
|
|
3879
|
+
targetProgressFill.style.width = `${String(ratio * 100)}%`;
|
|
3635
3880
|
}
|
|
3636
3881
|
function instructionInput(targetId) {
|
|
3637
3882
|
const inputs = targetList.querySelectorAll(
|
|
@@ -3648,16 +3893,17 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3648
3893
|
const focusedTargetId = focusedInstruction?.dataset.targetInstructionId;
|
|
3649
3894
|
const selectionStart = focusedInstruction?.selectionStart;
|
|
3650
3895
|
const selectionEnd = focusedInstruction?.selectionEnd;
|
|
3651
|
-
currentTargets = targets.map((
|
|
3896
|
+
currentTargets = targets.map((target2) => Object.freeze({ ...target2 }));
|
|
3652
3897
|
currentMaximum = maximum;
|
|
3653
3898
|
targetList.replaceChildren();
|
|
3654
3899
|
const completeCount = targets.filter(
|
|
3655
|
-
(
|
|
3900
|
+
(target2) => target2.instruction.trim().length > 0
|
|
3656
3901
|
).length;
|
|
3657
3902
|
const instructionCharacters = targets.reduce(
|
|
3658
|
-
(total,
|
|
3903
|
+
(total, target2) => total + target2.instruction.trim().length,
|
|
3659
3904
|
0
|
|
3660
3905
|
);
|
|
3906
|
+
renderTargetProgress(completeCount, targets.length);
|
|
3661
3907
|
targetCount.textContent = messages.targets.count(targets.length, maximum);
|
|
3662
3908
|
targetComplete.textContent = messages.targets.complete(
|
|
3663
3909
|
completeCount,
|
|
@@ -3675,18 +3921,18 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3675
3921
|
addTargetButton.disabled = !editingEnabled || targets.length >= maximum;
|
|
3676
3922
|
addTargetButton.title = targets.length >= maximum ? messages.targets.limitTitle(maximum) : messages.targets.addTitle;
|
|
3677
3923
|
targetLabel.textContent = targets.length === 1 ? targets[0]?.label ?? messages.context.selectedElement : messages.context.selectedCount(targets.length);
|
|
3678
|
-
for (const [index,
|
|
3924
|
+
for (const [index, target2] of targets.entries()) {
|
|
3679
3925
|
const item = createMarkedElement(document, "div");
|
|
3680
3926
|
item.className = "spotpatch-target-item";
|
|
3681
|
-
item.dataset.active = String(
|
|
3682
|
-
item.dataset.status =
|
|
3683
|
-
item.dataset.targetId =
|
|
3927
|
+
item.dataset.active = String(target2.active);
|
|
3928
|
+
item.dataset.status = target2.status;
|
|
3929
|
+
item.dataset.targetId = target2.id;
|
|
3684
3930
|
const targetSummary = createMarkedElement(document, "div");
|
|
3685
3931
|
targetSummary.className = "spotpatch-target-summary";
|
|
3686
3932
|
const select = createButton(document, "", "spotpatch-target-select");
|
|
3687
|
-
select.dataset.activateTargetId =
|
|
3933
|
+
select.dataset.activateTargetId = target2.id;
|
|
3688
3934
|
select.setAttribute("aria-label", messages.targets.activate(index + 1));
|
|
3689
|
-
select.setAttribute("aria-expanded", String(
|
|
3935
|
+
select.setAttribute("aria-expanded", String(target2.active));
|
|
3690
3936
|
const number = createMarkedElement(document, "span");
|
|
3691
3937
|
number.className = "spotpatch-target-index";
|
|
3692
3938
|
number.textContent = String(index + 1);
|
|
@@ -3694,54 +3940,54 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3694
3940
|
copy.className = "spotpatch-target-copy";
|
|
3695
3941
|
const name = createMarkedElement(document, "span");
|
|
3696
3942
|
name.className = "spotpatch-target-name";
|
|
3697
|
-
name.textContent =
|
|
3698
|
-
const
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
copy.append(name,
|
|
3702
|
-
const instructionComplete =
|
|
3943
|
+
name.textContent = target2.label;
|
|
3944
|
+
const source2 = createMarkedElement(document, "span");
|
|
3945
|
+
source2.className = "spotpatch-target-source";
|
|
3946
|
+
source2.textContent = `${statusText(target2)} \xB7 ${target2.source}`;
|
|
3947
|
+
copy.append(name, source2);
|
|
3948
|
+
const instructionComplete = target2.instruction.trim().length > 0;
|
|
3703
3949
|
const state = createMarkedElement(document, "span");
|
|
3704
3950
|
state.className = "spotpatch-target-state";
|
|
3705
3951
|
state.dataset.complete = String(instructionComplete);
|
|
3706
3952
|
state.textContent = instructionComplete ? messages.targets.instructionReady : messages.targets.instructionMissing;
|
|
3707
3953
|
select.append(number, copy, state);
|
|
3708
3954
|
const open = createButton(document, "\u2197", "spotpatch-target-open");
|
|
3709
|
-
open.dataset.openTargetId =
|
|
3710
|
-
open.disabled = !
|
|
3955
|
+
open.dataset.openTargetId = target2.id;
|
|
3956
|
+
open.disabled = !target2.canOpenEditor;
|
|
3711
3957
|
open.setAttribute("aria-label", messages.actions.openTarget(index + 1));
|
|
3712
3958
|
open.title = messages.actions.openTarget(index + 1);
|
|
3713
3959
|
const remove = createButton(document, "\xD7", "spotpatch-target-remove");
|
|
3714
|
-
remove.dataset.removeTargetId =
|
|
3960
|
+
remove.dataset.removeTargetId = target2.id;
|
|
3715
3961
|
remove.disabled = !editingEnabled;
|
|
3716
3962
|
remove.setAttribute("aria-label", messages.targets.remove(index + 1));
|
|
3717
3963
|
remove.title = messages.targets.removeTitle;
|
|
3718
3964
|
targetSummary.append(select, open, remove);
|
|
3719
3965
|
item.append(targetSummary);
|
|
3720
|
-
if (
|
|
3966
|
+
if (target2.active) {
|
|
3721
3967
|
const editor = createMarkedElement(document, "label");
|
|
3722
3968
|
editor.className = "spotpatch-target-editor";
|
|
3723
3969
|
const editorHead = createMarkedElement(document, "span");
|
|
3724
3970
|
editorHead.className = "spotpatch-target-editor-head";
|
|
3725
3971
|
const editorLabel = createMarkedElement(document, "span");
|
|
3726
3972
|
editorLabel.className = "spotpatch-target-editor-label";
|
|
3727
|
-
editorLabel.textContent = messages.targets.instructionLabel(
|
|
3973
|
+
editorLabel.textContent = messages.targets.instructionLabel(target2.label);
|
|
3728
3974
|
const characterCount = createMarkedElement(document, "span");
|
|
3729
3975
|
characterCount.className = "spotpatch-target-editor-count";
|
|
3730
3976
|
characterCount.textContent = messages.targets.instructionCount(
|
|
3731
|
-
|
|
3977
|
+
target2.instruction.length,
|
|
3732
3978
|
import_shared7.MAX_TARGET_INSTRUCTION_CHARACTERS
|
|
3733
3979
|
);
|
|
3734
3980
|
editorHead.append(editorLabel, characterCount);
|
|
3735
3981
|
const input = createMarkedElement(document, "textarea");
|
|
3736
3982
|
input.rows = 4;
|
|
3737
3983
|
input.maxLength = import_shared7.MAX_TARGET_INSTRUCTION_CHARACTERS;
|
|
3738
|
-
input.value =
|
|
3984
|
+
input.value = target2.instruction;
|
|
3739
3985
|
input.placeholder = messages.targets.instructionPlaceholder;
|
|
3740
3986
|
input.disabled = !editingEnabled;
|
|
3741
|
-
input.dataset.targetInstructionId =
|
|
3987
|
+
input.dataset.targetInstructionId = target2.id;
|
|
3742
3988
|
input.setAttribute(
|
|
3743
3989
|
"aria-label",
|
|
3744
|
-
messages.targets.instructionLabel(
|
|
3990
|
+
messages.targets.instructionLabel(target2.label)
|
|
3745
3991
|
);
|
|
3746
3992
|
editor.append(editorHead, input);
|
|
3747
3993
|
item.append(editor);
|
|
@@ -3758,7 +4004,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3758
4004
|
}
|
|
3759
4005
|
function updateTargetInstruction(targetId, instruction) {
|
|
3760
4006
|
currentTargets = currentTargets.map(
|
|
3761
|
-
(
|
|
4007
|
+
(target2) => target2.id === targetId ? Object.freeze({ ...target2, instruction }) : target2
|
|
3762
4008
|
);
|
|
3763
4009
|
const item = Array.from(
|
|
3764
4010
|
targetList.querySelectorAll(".spotpatch-target-item")
|
|
@@ -3779,12 +4025,16 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3779
4025
|
import_shared7.MAX_TARGET_INSTRUCTION_CHARACTERS
|
|
3780
4026
|
);
|
|
3781
4027
|
}
|
|
4028
|
+
const completeCount = currentTargets.filter(
|
|
4029
|
+
(target2) => target2.instruction.trim().length > 0
|
|
4030
|
+
).length;
|
|
3782
4031
|
targetComplete.textContent = messages.targets.complete(
|
|
3783
|
-
|
|
4032
|
+
completeCount,
|
|
3784
4033
|
currentTargets.length
|
|
3785
4034
|
);
|
|
4035
|
+
renderTargetProgress(completeCount, currentTargets.length);
|
|
3786
4036
|
const instructionCharacters = currentTargets.reduce(
|
|
3787
|
-
(total,
|
|
4037
|
+
(total, target2) => total + target2.instruction.trim().length,
|
|
3788
4038
|
0
|
|
3789
4039
|
);
|
|
3790
4040
|
const instructionLimitExceeded = instructionCharacters > import_shared7.MAX_ANNOTATION_INSTRUCTION_CHARACTERS;
|
|
@@ -3799,25 +4049,25 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3799
4049
|
}
|
|
3800
4050
|
function showSelectionHighlights(targets) {
|
|
3801
4051
|
selectionHighlights.replaceChildren();
|
|
3802
|
-
activeSelectionRect = targets.find((
|
|
4052
|
+
activeSelectionRect = targets.find((target2) => target2.active)?.rect;
|
|
3803
4053
|
currentRect = activeSelectionRect;
|
|
3804
|
-
for (const [index,
|
|
4054
|
+
for (const [index, target2] of targets.entries()) {
|
|
3805
4055
|
const box = createMarkedElement(document, "div");
|
|
3806
4056
|
box.className = "spotpatch-selection-highlight";
|
|
3807
|
-
box.dataset.targetId =
|
|
3808
|
-
box.dataset.active = String(
|
|
3809
|
-
box.style.transform = `translate(${String(
|
|
3810
|
-
box.style.width = `${String(
|
|
3811
|
-
box.style.height = `${String(
|
|
4057
|
+
box.dataset.targetId = target2.id;
|
|
4058
|
+
box.dataset.active = String(target2.active);
|
|
4059
|
+
box.style.transform = `translate(${String(target2.rect.x)}px, ${String(target2.rect.y)}px)`;
|
|
4060
|
+
box.style.width = `${String(target2.rect.width)}px`;
|
|
4061
|
+
box.style.height = `${String(target2.rect.height)}px`;
|
|
3812
4062
|
const label = createMarkedElement(document, "span");
|
|
3813
|
-
label.textContent = `${String(index + 1)} \xB7 ${
|
|
4063
|
+
label.textContent = `${String(index + 1)} \xB7 ${target2.label}`;
|
|
3814
4064
|
box.append(label);
|
|
3815
4065
|
selectionHighlights.append(box);
|
|
3816
4066
|
}
|
|
3817
4067
|
placeDialog();
|
|
3818
4068
|
}
|
|
3819
4069
|
function placeDialog() {
|
|
3820
|
-
if (dialog.hidden
|
|
4070
|
+
if (dialog.hidden) {
|
|
3821
4071
|
return;
|
|
3822
4072
|
}
|
|
3823
4073
|
const view = document.defaultView;
|
|
@@ -3825,14 +4075,14 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3825
4075
|
const viewportHeight = view?.innerHeight ?? document.documentElement.clientHeight;
|
|
3826
4076
|
const measured = dialog.getBoundingClientRect();
|
|
3827
4077
|
const status = currentStatus === "previewing" ? "previewing" : "selected";
|
|
3828
|
-
const dialogWidth = measured.width > 0 ? measured.width : Math.min(
|
|
4078
|
+
const dialogWidth = measured.width > 0 ? measured.width : Math.min(DIALOG_MAX_WIDTH, viewportWidth - 32);
|
|
3829
4079
|
const dialogHeight = measured.height > 0 ? measured.height : Math.min(DIALOG_FALLBACK_HEIGHT[status], viewportHeight - 32);
|
|
3830
4080
|
const placement = calculateDialogPlacement({
|
|
3831
|
-
target: currentRect,
|
|
3832
4081
|
dialogWidth,
|
|
3833
4082
|
dialogHeight,
|
|
3834
4083
|
viewportWidth,
|
|
3835
|
-
viewportHeight
|
|
4084
|
+
viewportHeight,
|
|
4085
|
+
...currentRect === void 0 ? {} : { target: currentRect }
|
|
3836
4086
|
});
|
|
3837
4087
|
dialog.style.left = `${String(placement.left)}px`;
|
|
3838
4088
|
dialog.style.top = `${String(placement.top)}px`;
|
|
@@ -3842,8 +4092,8 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3842
4092
|
}
|
|
3843
4093
|
function updateContextOverview(summaryText) {
|
|
3844
4094
|
const summaryMessages = messages.summary;
|
|
3845
|
-
const
|
|
3846
|
-
sourcePeek.textContent =
|
|
4095
|
+
const source2 = summaryLine(summaryText, summaryMessages.source);
|
|
4096
|
+
sourcePeek.textContent = source2 ?? messages.diagnostics.noExactSource;
|
|
3847
4097
|
const browserReady = `${summaryMessages.browserContext}: ${summaryMessages.collectionStatuses.ready}`;
|
|
3848
4098
|
const browserLoading = `${summaryMessages.browserContext}: ${summaryMessages.collectionStatuses.loading}`;
|
|
3849
4099
|
const browserFailed = `${summaryMessages.browserContext}: ${summaryMessages.collectionStatuses.failed}`;
|
|
@@ -3882,6 +4132,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3882
4132
|
addTargetButton.hidden = !selected;
|
|
3883
4133
|
openEditorButton.hidden = !selected;
|
|
3884
4134
|
previewButton.hidden = !selected;
|
|
4135
|
+
secondaryActions.hidden = !selected;
|
|
3885
4136
|
agentPanel.setSelectionVisible(selected);
|
|
3886
4137
|
copyButton.hidden = !previewing;
|
|
3887
4138
|
backButton.hidden = !previewing;
|
|
@@ -3920,6 +4171,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3920
4171
|
} else {
|
|
3921
4172
|
targetCount.textContent = messages.targets.count(0, currentMaximum);
|
|
3922
4173
|
targetComplete.textContent = messages.targets.complete(0, 0);
|
|
4174
|
+
renderTargetProgress(0, 0);
|
|
3923
4175
|
targetBudget.dataset.state = "ready";
|
|
3924
4176
|
targetBudget.textContent = messages.targets.instructionBudget(
|
|
3925
4177
|
0,
|
|
@@ -3988,6 +4240,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3988
4240
|
selectionHighlights.replaceChildren();
|
|
3989
4241
|
activeSelectionRect = void 0;
|
|
3990
4242
|
currentRect = void 0;
|
|
4243
|
+
placeDialog();
|
|
3991
4244
|
},
|
|
3992
4245
|
showSelection(summaryText, canOpenEditor, canPreview) {
|
|
3993
4246
|
updateSelection(summaryText, canOpenEditor, canPreview);
|
|
@@ -4013,6 +4266,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4013
4266
|
renderEditorStatus("idle");
|
|
4014
4267
|
targetCount.textContent = messages.targets.count(0, 0);
|
|
4015
4268
|
targetComplete.textContent = messages.targets.complete(0, 0);
|
|
4269
|
+
renderTargetProgress(0, 0);
|
|
4016
4270
|
targetLabel.textContent = messages.context.selectedElement;
|
|
4017
4271
|
summary.textContent = "";
|
|
4018
4272
|
promptOutput.textContent = "";
|
|
@@ -4552,25 +4806,25 @@ var EMPTY_STYLE_CONTEXT = Object.freeze({
|
|
|
4552
4806
|
computed: Object.freeze({}),
|
|
4553
4807
|
warnings: Object.freeze(["CSS context collection failed."])
|
|
4554
4808
|
});
|
|
4555
|
-
function elementLabel(
|
|
4556
|
-
const id =
|
|
4557
|
-
const className = Array.from(
|
|
4558
|
-
return `<${
|
|
4559
|
-
}
|
|
4560
|
-
function sourceLabel(
|
|
4561
|
-
const path =
|
|
4562
|
-
const line =
|
|
4563
|
-
const column =
|
|
4809
|
+
function elementLabel(element2) {
|
|
4810
|
+
const id = element2.id.length > 0 ? `#${element2.id}` : "";
|
|
4811
|
+
const className = Array.from(element2.classList).slice(0, 2).map((name) => `.${name}`).join("");
|
|
4812
|
+
return `<${element2.tagName.toLowerCase()}${id}${className}>`;
|
|
4813
|
+
}
|
|
4814
|
+
function sourceLabel(target2, unavailable) {
|
|
4815
|
+
const path = target2.code?.relativePath ?? target2.resolution.source.relativePath;
|
|
4816
|
+
const line = target2.resolution.source.line;
|
|
4817
|
+
const column = target2.resolution.source.column;
|
|
4564
4818
|
if (path === void 0) {
|
|
4565
4819
|
return unavailable;
|
|
4566
4820
|
}
|
|
4567
4821
|
return `${path}${line === void 0 ? "" : `:${String(line)}`}${column === void 0 ? "" : `:${String(column)}`}`;
|
|
4568
4822
|
}
|
|
4569
|
-
function targetStatus(
|
|
4570
|
-
if (
|
|
4823
|
+
function targetStatus(target2) {
|
|
4824
|
+
if (target2.apiStatus === "failed" || target2.collectionStatus === "failed") {
|
|
4571
4825
|
return "warning";
|
|
4572
4826
|
}
|
|
4573
|
-
if (
|
|
4827
|
+
if (target2.apiStatus === "loading" || target2.collectionStatus === "loading") {
|
|
4574
4828
|
return "loading";
|
|
4575
4829
|
}
|
|
4576
4830
|
return "ready";
|
|
@@ -4597,6 +4851,8 @@ function createController(config, dependencies = {}) {
|
|
|
4597
4851
|
const clipboard = dependencies.clipboard ?? resolveClipboardWriter(browser.window.navigator);
|
|
4598
4852
|
const createId = dependencies.createId ?? (() => createBrowserAnnotationId(browser.window));
|
|
4599
4853
|
const now = dependencies.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
4854
|
+
const selectionSession = dependencies.selectionSession ?? createSelectionSession(browser.window, config.sessionId, config.maxTargets);
|
|
4855
|
+
const restoredSelection = selectionSession.load();
|
|
4600
4856
|
const sourceResolver = createSourceResolver({
|
|
4601
4857
|
adapter: dependencies.reactAdapter ?? (0, import_react_adapter.createReact18Adapter)({
|
|
4602
4858
|
maxComponentDepth: config.budget.maxComponentDepth
|
|
@@ -4614,9 +4870,26 @@ function createController(config, dependencies = {}) {
|
|
|
4614
4870
|
let mounted = false;
|
|
4615
4871
|
let animationFrame;
|
|
4616
4872
|
let lastPointer;
|
|
4617
|
-
let targets =
|
|
4618
|
-
|
|
4619
|
-
|
|
4873
|
+
let targets = restoredSelection?.targets.map((target2) => {
|
|
4874
|
+
const marker = sourceRefToMarker(target2.source);
|
|
4875
|
+
return {
|
|
4876
|
+
id: target2.id,
|
|
4877
|
+
resolution: Object.freeze({ source: target2.source, react: target2.react }),
|
|
4878
|
+
apiStatus: marker === void 0 ? "not-required" : target2.code === void 0 ? "failed" : "connected",
|
|
4879
|
+
code: target2.code,
|
|
4880
|
+
collectionStatus: "ready",
|
|
4881
|
+
element: void 0,
|
|
4882
|
+
elementContext: target2.element,
|
|
4883
|
+
instruction: target2.instruction,
|
|
4884
|
+
marker,
|
|
4885
|
+
page: target2.page,
|
|
4886
|
+
styles: target2.styles
|
|
4887
|
+
};
|
|
4888
|
+
}) ?? [];
|
|
4889
|
+
let activeTargetId = restoredSelection?.activeTargetId;
|
|
4890
|
+
let targetSequence = restoredSelection?.sequence ?? 0;
|
|
4891
|
+
let selectionOpen = restoredSelection?.open ?? false;
|
|
4892
|
+
let workflowSelectionActive = false;
|
|
4620
4893
|
let sessionRevision = 0;
|
|
4621
4894
|
let editorRequestRevision = 0;
|
|
4622
4895
|
let addingTarget = false;
|
|
@@ -4631,51 +4904,87 @@ function createController(config, dependencies = {}) {
|
|
|
4631
4904
|
view.renderStatus(state.status);
|
|
4632
4905
|
}
|
|
4633
4906
|
function activeTarget() {
|
|
4634
|
-
return targets.find((
|
|
4907
|
+
return targets.find((target2) => target2.id === activeTargetId) ?? targets.at(-1);
|
|
4908
|
+
}
|
|
4909
|
+
function snapshotTarget(target2) {
|
|
4910
|
+
if (target2.elementContext === void 0 || target2.styles === void 0) {
|
|
4911
|
+
return void 0;
|
|
4912
|
+
}
|
|
4913
|
+
return {
|
|
4914
|
+
id: target2.id,
|
|
4915
|
+
instruction: target2.instruction,
|
|
4916
|
+
page: target2.page,
|
|
4917
|
+
source: target2.resolution.source,
|
|
4918
|
+
react: target2.resolution.react,
|
|
4919
|
+
element: target2.elementContext,
|
|
4920
|
+
styles: target2.styles,
|
|
4921
|
+
...target2.code === void 0 ? {} : { code: target2.code }
|
|
4922
|
+
};
|
|
4635
4923
|
}
|
|
4636
|
-
function
|
|
4637
|
-
|
|
4924
|
+
function persistSelection() {
|
|
4925
|
+
const persistedTargets = targets.flatMap((target2) => {
|
|
4926
|
+
const snapshot = snapshotTarget(target2);
|
|
4927
|
+
return snapshot === void 0 ? [] : [snapshot];
|
|
4928
|
+
});
|
|
4929
|
+
if (persistedTargets.length === 0) {
|
|
4930
|
+
selectionSession.clear();
|
|
4931
|
+
return;
|
|
4932
|
+
}
|
|
4933
|
+
const persistedIds = new Set(persistedTargets.map(({ id }) => id));
|
|
4934
|
+
selectionSession.save({
|
|
4935
|
+
...activeTargetId !== void 0 && persistedIds.has(activeTargetId) ? { activeTargetId } : {},
|
|
4936
|
+
open: selectionOpen,
|
|
4937
|
+
sequence: targetSequence,
|
|
4938
|
+
targets: persistedTargets
|
|
4939
|
+
});
|
|
4940
|
+
}
|
|
4941
|
+
function targetIsCurrent(target2, revision) {
|
|
4942
|
+
return mounted && revision === sessionRevision && state.status !== "idle" && targets.includes(target2);
|
|
4638
4943
|
}
|
|
4639
4944
|
function canPreview() {
|
|
4640
4945
|
const instructionCharacters = targets.reduce(
|
|
4641
|
-
(total,
|
|
4946
|
+
(total, target2) => total + target2.instruction.trim().length,
|
|
4642
4947
|
0
|
|
4643
4948
|
);
|
|
4644
4949
|
return targets.length > 0 && instructionCharacters <= import_shared9.MAX_ANNOTATION_INSTRUCTION_CHARACTERS && targets.every(
|
|
4645
|
-
(
|
|
4950
|
+
(target2) => target2.instruction.trim().length > 0 && target2.elementContext !== void 0 && target2.styles !== void 0 && target2.apiStatus !== "loading"
|
|
4646
4951
|
);
|
|
4647
4952
|
}
|
|
4648
4953
|
function selectionSummary() {
|
|
4649
4954
|
const messages = view.messages().summary;
|
|
4650
|
-
return targets.map((
|
|
4955
|
+
return targets.map((target2, index) => {
|
|
4651
4956
|
const summary = createSelectionSummary(
|
|
4652
4957
|
{
|
|
4653
|
-
resolution:
|
|
4654
|
-
...
|
|
4655
|
-
...
|
|
4656
|
-
apiStatus:
|
|
4657
|
-
collectionStatus:
|
|
4958
|
+
resolution: target2.resolution,
|
|
4959
|
+
...target2.code === void 0 ? {} : { code: target2.code },
|
|
4960
|
+
...target2.styles === void 0 ? {} : { styles: target2.styles },
|
|
4961
|
+
apiStatus: target2.apiStatus,
|
|
4962
|
+
collectionStatus: target2.collectionStatus,
|
|
4658
4963
|
framework: config.framework,
|
|
4659
4964
|
frameworkVersion: config.frameworkVersion,
|
|
4660
4965
|
spotPatchVersion: config.spotPatchVersion
|
|
4661
4966
|
},
|
|
4662
4967
|
messages
|
|
4663
4968
|
);
|
|
4664
|
-
return `${messages.target(index + 1,
|
|
4969
|
+
return `${messages.target(index + 1, target2.id === activeTargetId)}
|
|
4665
4970
|
${summary}`;
|
|
4666
4971
|
}).join("\n\n");
|
|
4667
4972
|
}
|
|
4668
4973
|
function refreshHighlights() {
|
|
4669
|
-
const highlights = targets.flatMap((
|
|
4670
|
-
if (!
|
|
4974
|
+
const highlights = targets.flatMap((target2) => {
|
|
4975
|
+
if (!target2.element?.isConnected) {
|
|
4976
|
+
return [];
|
|
4977
|
+
}
|
|
4978
|
+
const rect = getVisibleElementRect(target2.element, browser.window);
|
|
4979
|
+
if (rect === void 0) {
|
|
4671
4980
|
return [];
|
|
4672
4981
|
}
|
|
4673
4982
|
return [
|
|
4674
4983
|
{
|
|
4675
|
-
id:
|
|
4676
|
-
label: elementLabel(
|
|
4677
|
-
rect
|
|
4678
|
-
active:
|
|
4984
|
+
id: target2.id,
|
|
4985
|
+
label: elementLabel(target2.element),
|
|
4986
|
+
rect,
|
|
4987
|
+
active: target2.id === activeTargetId
|
|
4679
4988
|
}
|
|
4680
4989
|
];
|
|
4681
4990
|
});
|
|
@@ -4690,14 +4999,14 @@ ${summary}`;
|
|
|
4690
4999
|
return;
|
|
4691
5000
|
}
|
|
4692
5001
|
view.renderTargets(
|
|
4693
|
-
targets.map((
|
|
4694
|
-
id:
|
|
4695
|
-
label:
|
|
4696
|
-
source: sourceLabel(
|
|
4697
|
-
canOpenEditor:
|
|
4698
|
-
status: targetStatus(
|
|
4699
|
-
active:
|
|
4700
|
-
instruction:
|
|
5002
|
+
targets.map((target2) => ({
|
|
5003
|
+
id: target2.id,
|
|
5004
|
+
label: target2.resolution.react.componentName ?? (target2.element === void 0 ? target2.elementContext?.tagName ?? "Element" : elementLabel(target2.element)),
|
|
5005
|
+
source: sourceLabel(target2, view.messages().context.sourceUnavailable),
|
|
5006
|
+
canOpenEditor: target2.marker !== void 0,
|
|
5007
|
+
status: targetStatus(target2),
|
|
5008
|
+
active: target2.id === activeTargetId,
|
|
5009
|
+
instruction: target2.instruction
|
|
4701
5010
|
})),
|
|
4702
5011
|
config.maxTargets
|
|
4703
5012
|
);
|
|
@@ -4715,21 +5024,22 @@ ${summary}`;
|
|
|
4715
5024
|
if (!canPreview()) {
|
|
4716
5025
|
return void 0;
|
|
4717
5026
|
}
|
|
4718
|
-
const annotationTargets = targets.map((
|
|
4719
|
-
if (
|
|
5027
|
+
const annotationTargets = targets.map((target2) => {
|
|
5028
|
+
if (target2.elementContext === void 0 || target2.styles === void 0) {
|
|
4720
5029
|
throw new Error("SpotPatch attempted to compose an incomplete target.");
|
|
4721
5030
|
}
|
|
4722
5031
|
const warnings = [
|
|
4723
|
-
...
|
|
4724
|
-
...
|
|
5032
|
+
...target2.apiStatus === "failed" ? ["Source context could not be loaded."] : [],
|
|
5033
|
+
...target2.collectionStatus === "failed" ? ["Part of the browser context could not be collected."] : []
|
|
4725
5034
|
];
|
|
4726
5035
|
return {
|
|
4727
|
-
instruction:
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
5036
|
+
instruction: target2.instruction.trim(),
|
|
5037
|
+
page: target2.page,
|
|
5038
|
+
source: target2.resolution.source,
|
|
5039
|
+
react: target2.resolution.react,
|
|
5040
|
+
element: target2.elementContext,
|
|
5041
|
+
styles: target2.styles,
|
|
5042
|
+
...target2.code === void 0 ? {} : { code: target2.code },
|
|
4733
5043
|
warnings
|
|
4734
5044
|
};
|
|
4735
5045
|
});
|
|
@@ -4741,8 +5051,8 @@ ${summary}`;
|
|
|
4741
5051
|
targets: annotationTargets
|
|
4742
5052
|
});
|
|
4743
5053
|
}
|
|
4744
|
-
function showElementHighlight(
|
|
4745
|
-
view.showHighlight(getElementRect(
|
|
5054
|
+
function showElementHighlight(element2) {
|
|
5055
|
+
view.showHighlight(getElementRect(element2, browser.window), elementLabel(element2));
|
|
4746
5056
|
}
|
|
4747
5057
|
function restoreFocus() {
|
|
4748
5058
|
if (previousFocus?.isConnected === true) {
|
|
@@ -4764,10 +5074,13 @@ ${summary}`;
|
|
|
4764
5074
|
resizeObserver?.disconnect();
|
|
4765
5075
|
targets = [];
|
|
4766
5076
|
activeTargetId = void 0;
|
|
5077
|
+
selectionOpen = false;
|
|
5078
|
+
workflowSelectionActive = false;
|
|
4767
5079
|
addingTarget = false;
|
|
4768
5080
|
previewPrompt = "";
|
|
4769
5081
|
view.hideSelection();
|
|
4770
5082
|
view.hideSelectionHighlights();
|
|
5083
|
+
selectionSession.clear();
|
|
4771
5084
|
restoreFocus();
|
|
4772
5085
|
}
|
|
4773
5086
|
function close() {
|
|
@@ -4779,7 +5092,11 @@ ${summary}`;
|
|
|
4779
5092
|
transition({ type: "BACK" });
|
|
4780
5093
|
transition({ type: "CLOSE" });
|
|
4781
5094
|
}
|
|
4782
|
-
|
|
5095
|
+
selectionOpen = false;
|
|
5096
|
+
persistSelection();
|
|
5097
|
+
view.hideSelection();
|
|
5098
|
+
view.hideSelectionHighlights();
|
|
5099
|
+
restoreFocus();
|
|
4783
5100
|
view.hideHighlight();
|
|
4784
5101
|
}
|
|
4785
5102
|
function cancelAddTarget() {
|
|
@@ -4803,6 +5120,18 @@ ${summary}`;
|
|
|
4803
5120
|
close();
|
|
4804
5121
|
return;
|
|
4805
5122
|
}
|
|
5123
|
+
if (targets.length > 0) {
|
|
5124
|
+
selectionOpen = true;
|
|
5125
|
+
transition({ type: "RESTORE" });
|
|
5126
|
+
if (!workflowSelectionActive) {
|
|
5127
|
+
agentWorkflow.beginSelection();
|
|
5128
|
+
workflowSelectionActive = true;
|
|
5129
|
+
}
|
|
5130
|
+
refreshSelectionView(true);
|
|
5131
|
+
view.focusTargetInstruction(activeTargetId);
|
|
5132
|
+
persistSelection();
|
|
5133
|
+
return;
|
|
5134
|
+
}
|
|
4806
5135
|
transition({ type: "ACTIVATE" });
|
|
4807
5136
|
view.hideSelection();
|
|
4808
5137
|
view.announce(view.messages().announcements.selectionEnabled);
|
|
@@ -4836,12 +5165,13 @@ ${summary}`;
|
|
|
4836
5165
|
sessionRevision += 1;
|
|
4837
5166
|
clearCollectionTimers();
|
|
4838
5167
|
resizeObserver?.disconnect();
|
|
4839
|
-
for (const
|
|
4840
|
-
|
|
5168
|
+
for (const target2 of targets) {
|
|
5169
|
+
target2.element = void 0;
|
|
4841
5170
|
}
|
|
4842
5171
|
view.hideHighlight();
|
|
4843
5172
|
view.hideSelectionHighlights();
|
|
4844
5173
|
refreshSelectionView();
|
|
5174
|
+
selectionSession.clear();
|
|
4845
5175
|
view.announce(view.messages().announcements.appliedTargetsDetached);
|
|
4846
5176
|
}
|
|
4847
5177
|
const agentWorkflow = createAgentWorkflow({
|
|
@@ -4854,8 +5184,8 @@ ${summary}`;
|
|
|
4854
5184
|
},
|
|
4855
5185
|
view
|
|
4856
5186
|
});
|
|
4857
|
-
async function loadSourceContext(
|
|
4858
|
-
const marker =
|
|
5187
|
+
async function loadSourceContext(target2, revision) {
|
|
5188
|
+
const marker = target2.marker;
|
|
4859
5189
|
if (marker === void 0) {
|
|
4860
5190
|
return;
|
|
4861
5191
|
}
|
|
@@ -4866,16 +5196,18 @@ ${summary}`;
|
|
|
4866
5196
|
column: marker.column,
|
|
4867
5197
|
maxLines: config.budget.maxCodeLines
|
|
4868
5198
|
});
|
|
4869
|
-
if (targetIsCurrent(
|
|
4870
|
-
|
|
4871
|
-
|
|
5199
|
+
if (targetIsCurrent(target2, revision)) {
|
|
5200
|
+
target2.code = context;
|
|
5201
|
+
target2.apiStatus = "connected";
|
|
5202
|
+
persistSelection();
|
|
4872
5203
|
refreshSelectionView();
|
|
4873
5204
|
view.announce(view.messages().announcements.sourceLoaded);
|
|
4874
5205
|
}
|
|
4875
5206
|
} catch (error) {
|
|
4876
|
-
if (targetIsCurrent(
|
|
4877
|
-
|
|
4878
|
-
|
|
5207
|
+
if (targetIsCurrent(target2, revision)) {
|
|
5208
|
+
target2.code = void 0;
|
|
5209
|
+
target2.apiStatus = "failed";
|
|
5210
|
+
persistSelection();
|
|
4879
5211
|
refreshSelectionView();
|
|
4880
5212
|
view.announce(view.messages().announcements.sourceFailed);
|
|
4881
5213
|
if (config.debug && !(error instanceof DOMException && error.name === "AbortError")) {
|
|
@@ -4884,61 +5216,62 @@ ${summary}`;
|
|
|
4884
5216
|
}
|
|
4885
5217
|
}
|
|
4886
5218
|
}
|
|
4887
|
-
function scheduleBrowserContextCollection(
|
|
4888
|
-
const
|
|
4889
|
-
if (
|
|
5219
|
+
function scheduleBrowserContextCollection(target2, revision) {
|
|
5220
|
+
const element2 = target2.element;
|
|
5221
|
+
if (element2 === void 0) {
|
|
4890
5222
|
return;
|
|
4891
5223
|
}
|
|
4892
5224
|
const timer = browser.window.setTimeout(() => {
|
|
4893
|
-
collectionTimers.delete(
|
|
4894
|
-
if (!targetIsCurrent(
|
|
5225
|
+
collectionTimers.delete(target2.id);
|
|
5226
|
+
if (!targetIsCurrent(target2, revision)) {
|
|
4895
5227
|
return;
|
|
4896
5228
|
}
|
|
4897
5229
|
let failed = false;
|
|
4898
5230
|
try {
|
|
4899
|
-
|
|
4900
|
-
element,
|
|
5231
|
+
target2.elementContext = collectElementContext({
|
|
5232
|
+
element: element2,
|
|
4901
5233
|
maxCharacters: config.budget.domCharacters
|
|
4902
5234
|
});
|
|
4903
5235
|
} catch {
|
|
4904
|
-
|
|
5236
|
+
target2.elementContext = void 0;
|
|
4905
5237
|
failed = true;
|
|
4906
5238
|
}
|
|
4907
5239
|
try {
|
|
4908
|
-
|
|
5240
|
+
target2.styles = collectStyleContext({
|
|
4909
5241
|
document: browser.document,
|
|
4910
|
-
element,
|
|
5242
|
+
element: element2,
|
|
4911
5243
|
maxCharacters: config.budget.cssCharacters
|
|
4912
5244
|
});
|
|
4913
5245
|
} catch {
|
|
4914
|
-
|
|
5246
|
+
target2.styles = EMPTY_STYLE_CONTEXT;
|
|
4915
5247
|
failed = true;
|
|
4916
5248
|
}
|
|
4917
|
-
|
|
5249
|
+
target2.collectionStatus = failed ? "failed" : "ready";
|
|
5250
|
+
persistSelection();
|
|
4918
5251
|
refreshSelectionView();
|
|
4919
5252
|
view.announce(
|
|
4920
5253
|
failed ? view.messages().announcements.contextWarning : view.messages().announcements.contextCollected
|
|
4921
5254
|
);
|
|
4922
|
-
if (config.debug &&
|
|
5255
|
+
if (config.debug && target2.styles.warnings.length > 0) {
|
|
4923
5256
|
console.warn(
|
|
4924
|
-
`[spotpatch:runtime] CSS collection completed with ${String(
|
|
5257
|
+
`[spotpatch:runtime] CSS collection completed with ${String(target2.styles.warnings.length)} warning(s).`
|
|
4925
5258
|
);
|
|
4926
5259
|
}
|
|
4927
5260
|
}, 0);
|
|
4928
|
-
collectionTimers.set(
|
|
5261
|
+
collectionTimers.set(target2.id, timer);
|
|
4929
5262
|
}
|
|
4930
|
-
function duplicateTarget(
|
|
5263
|
+
function duplicateTarget(element2, marker) {
|
|
4931
5264
|
if (marker !== void 0) {
|
|
4932
5265
|
return targets.find(
|
|
4933
|
-
(
|
|
5266
|
+
(target2) => target2.marker?.fileId === marker.fileId && target2.marker.line === marker.line && target2.marker.column === marker.column
|
|
4934
5267
|
);
|
|
4935
5268
|
}
|
|
4936
|
-
return targets.find((
|
|
5269
|
+
return targets.find((target2) => target2.element === element2);
|
|
4937
5270
|
}
|
|
4938
|
-
function selectElement(
|
|
4939
|
-
const resolution = sourceResolver.resolve(
|
|
5271
|
+
function selectElement(element2) {
|
|
5272
|
+
const resolution = sourceResolver.resolve(element2);
|
|
4940
5273
|
const marker = sourceRefToMarker(resolution.source);
|
|
4941
|
-
const duplicate = duplicateTarget(
|
|
5274
|
+
const duplicate = duplicateTarget(element2, marker);
|
|
4942
5275
|
if (duplicate !== void 0) {
|
|
4943
5276
|
activeTargetId = duplicate.id;
|
|
4944
5277
|
addingTarget = false;
|
|
@@ -4962,13 +5295,15 @@ ${summary}`;
|
|
|
4962
5295
|
previousFocus = browser.document.activeElement instanceof HTMLElement ? browser.document.activeElement : void 0;
|
|
4963
5296
|
previewPrompt = "";
|
|
4964
5297
|
agentWorkflow.beginSelection();
|
|
5298
|
+
workflowSelectionActive = true;
|
|
4965
5299
|
}
|
|
4966
5300
|
targetSequence += 1;
|
|
4967
|
-
const
|
|
5301
|
+
const target2 = {
|
|
4968
5302
|
id: `target-${String(targetSequence)}`,
|
|
4969
|
-
element,
|
|
5303
|
+
element: element2,
|
|
4970
5304
|
resolution,
|
|
4971
5305
|
marker,
|
|
5306
|
+
page: collectPageContext(browser.document, browser.window),
|
|
4972
5307
|
code: void 0,
|
|
4973
5308
|
elementContext: void 0,
|
|
4974
5309
|
styles: void 0,
|
|
@@ -4976,18 +5311,19 @@ ${summary}`;
|
|
|
4976
5311
|
apiStatus: marker === void 0 ? "not-required" : "loading",
|
|
4977
5312
|
collectionStatus: "loading"
|
|
4978
5313
|
};
|
|
4979
|
-
targets.push(
|
|
4980
|
-
activeTargetId =
|
|
5314
|
+
targets.push(target2);
|
|
5315
|
+
activeTargetId = target2.id;
|
|
4981
5316
|
addingTarget = false;
|
|
4982
5317
|
const revision = sessionRevision;
|
|
4983
5318
|
transition({ type: "SELECT" });
|
|
4984
5319
|
view.hideHighlight();
|
|
4985
|
-
resizeObserver?.observe(
|
|
5320
|
+
resizeObserver?.observe(element2);
|
|
4986
5321
|
refreshSelectionView(true);
|
|
4987
|
-
|
|
4988
|
-
|
|
5322
|
+
selectionOpen = true;
|
|
5323
|
+
view.focusTargetInstruction(target2.id);
|
|
5324
|
+
scheduleBrowserContextCollection(target2, revision);
|
|
4989
5325
|
if (marker !== void 0) {
|
|
4990
|
-
void loadSourceContext(
|
|
5326
|
+
void loadSourceContext(target2, revision);
|
|
4991
5327
|
} else {
|
|
4992
5328
|
view.announce(
|
|
4993
5329
|
resolution.source.confidence === "probable" ? view.messages().announcements.sourceProbable : view.messages().announcements.sourceMissing
|
|
@@ -5061,7 +5397,7 @@ ${summary}`;
|
|
|
5061
5397
|
if (state.status !== "selected" && state.status !== "inspecting") {
|
|
5062
5398
|
return;
|
|
5063
5399
|
}
|
|
5064
|
-
const index = targets.findIndex((
|
|
5400
|
+
const index = targets.findIndex((target2) => target2.id === targetId);
|
|
5065
5401
|
if (index < 0) {
|
|
5066
5402
|
return;
|
|
5067
5403
|
}
|
|
@@ -5087,10 +5423,12 @@ ${summary}`;
|
|
|
5087
5423
|
}
|
|
5088
5424
|
view.hideSelectionTemporarily();
|
|
5089
5425
|
view.hideSelectionHighlights();
|
|
5426
|
+
selectionSession.clear();
|
|
5090
5427
|
view.announce(view.messages().announcements.allTargetsRemoved);
|
|
5091
5428
|
return;
|
|
5092
5429
|
}
|
|
5093
5430
|
refreshSelectionView();
|
|
5431
|
+
persistSelection();
|
|
5094
5432
|
view.announce(view.messages().announcements.targetRemoved);
|
|
5095
5433
|
}
|
|
5096
5434
|
function refreshSelectedGeometry() {
|
|
@@ -5098,24 +5436,24 @@ ${summary}`;
|
|
|
5098
5436
|
return;
|
|
5099
5437
|
}
|
|
5100
5438
|
const disconnected = targets.filter(
|
|
5101
|
-
(
|
|
5439
|
+
(target2) => target2.element !== void 0 && !target2.element.isConnected
|
|
5102
5440
|
);
|
|
5103
5441
|
if (disconnected.length > 0) {
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
}
|
|
5110
|
-
if (targets.length > 0) {
|
|
5111
|
-
view.announce(view.messages().announcements.detachedTargetRemoved);
|
|
5442
|
+
for (const target2 of disconnected) {
|
|
5443
|
+
if (target2.element !== void 0) {
|
|
5444
|
+
resizeObserver?.unobserve(target2.element);
|
|
5445
|
+
target2.element = void 0;
|
|
5446
|
+
}
|
|
5112
5447
|
}
|
|
5448
|
+
refreshSelectionView();
|
|
5449
|
+
persistSelection();
|
|
5450
|
+
view.announce(view.messages().announcements.detachedTargetPreserved);
|
|
5113
5451
|
return;
|
|
5114
5452
|
}
|
|
5115
5453
|
refreshHighlights();
|
|
5116
5454
|
}
|
|
5117
5455
|
function handleOpenEditor(targetId) {
|
|
5118
|
-
const current = targetId === void 0 ? activeTarget() : targets.find((
|
|
5456
|
+
const current = targetId === void 0 ? activeTarget() : targets.find((target2) => target2.id === targetId);
|
|
5119
5457
|
if (state.status !== "selected" || current?.marker === void 0) {
|
|
5120
5458
|
return;
|
|
5121
5459
|
}
|
|
@@ -5147,13 +5485,14 @@ ${summary}`;
|
|
|
5147
5485
|
return;
|
|
5148
5486
|
}
|
|
5149
5487
|
const targetId = event.target.dataset.targetInstructionId;
|
|
5150
|
-
const
|
|
5151
|
-
if (
|
|
5488
|
+
const target2 = targets.find((candidate) => candidate.id === targetId);
|
|
5489
|
+
if (target2 === void 0) {
|
|
5152
5490
|
return;
|
|
5153
5491
|
}
|
|
5154
|
-
|
|
5155
|
-
view.updateTargetInstruction(
|
|
5492
|
+
target2.instruction = event.target.value;
|
|
5493
|
+
view.updateTargetInstruction(target2.id, target2.instruction);
|
|
5156
5494
|
view.setPreviewEnabled(canPreview());
|
|
5495
|
+
persistSelection();
|
|
5157
5496
|
}
|
|
5158
5497
|
function handleOpenEditorButtonClick() {
|
|
5159
5498
|
handleOpenEditor();
|
|
@@ -5246,7 +5585,7 @@ ${summary}`;
|
|
|
5246
5585
|
"button[data-activate-target-id]"
|
|
5247
5586
|
);
|
|
5248
5587
|
const targetId = activateButton?.dataset.activateTargetId;
|
|
5249
|
-
if (state.status !== "selected" || targetId === void 0 || !targets.some((
|
|
5588
|
+
if (state.status !== "selected" || targetId === void 0 || !targets.some((target2) => target2.id === targetId)) {
|
|
5250
5589
|
return;
|
|
5251
5590
|
}
|
|
5252
5591
|
activeTargetId = targetId;
|
|
@@ -5304,6 +5643,12 @@ ${summary}`;
|
|
|
5304
5643
|
subtree: true
|
|
5305
5644
|
});
|
|
5306
5645
|
}
|
|
5646
|
+
if (selectionOpen && targets.length > 0) {
|
|
5647
|
+
transition({ type: "RESTORE" });
|
|
5648
|
+
agentWorkflow.beginSelection();
|
|
5649
|
+
workflowSelectionActive = true;
|
|
5650
|
+
refreshSelectionView(true);
|
|
5651
|
+
}
|
|
5307
5652
|
if (config.debug) {
|
|
5308
5653
|
console.info(`[spotpatch:runtime] Mounted. Shortcut: ${config.shortcut}.`);
|
|
5309
5654
|
}
|
|
@@ -5361,6 +5706,7 @@ ${summary}`;
|
|
|
5361
5706
|
animationFrame = void 0;
|
|
5362
5707
|
}
|
|
5363
5708
|
clearCollectionTimers();
|
|
5709
|
+
persistSelection();
|
|
5364
5710
|
resizeObserver?.disconnect();
|
|
5365
5711
|
mutationObserver?.disconnect();
|
|
5366
5712
|
resizeObserver = void 0;
|
|
@@ -5383,10 +5729,10 @@ ${summary}`;
|
|
|
5383
5729
|
// src/controller/bootstrap.ts
|
|
5384
5730
|
var RUNTIME_INSTANCE_KEY = "__spotpatchRuntime__";
|
|
5385
5731
|
function bootstrapSpotPatch(config) {
|
|
5386
|
-
const
|
|
5387
|
-
|
|
5732
|
+
const target2 = globalThis;
|
|
5733
|
+
target2[RUNTIME_INSTANCE_KEY]?.dispose();
|
|
5388
5734
|
const controller = createController(config);
|
|
5389
|
-
|
|
5735
|
+
target2[RUNTIME_INSTANCE_KEY] = controller;
|
|
5390
5736
|
controller.mount();
|
|
5391
5737
|
}
|
|
5392
5738
|
// Annotate the CommonJS export names for ESM import in node:
|