@spotpatch/runtime 1.5.0 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +306 -195
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +306 -195
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1061,8 +1061,7 @@ function unionRects(rects) {
|
|
|
1061
1061
|
height: bottom - top
|
|
1062
1062
|
});
|
|
1063
1063
|
}
|
|
1064
|
-
function
|
|
1065
|
-
const display = view.getComputedStyle(element2).display;
|
|
1064
|
+
function measureElementRect(element2, display) {
|
|
1066
1065
|
if (display.startsWith("inline")) {
|
|
1067
1066
|
const lineBoxRect = unionRects(Array.from(element2.getClientRects()));
|
|
1068
1067
|
if (lineBoxRect !== void 0) {
|
|
@@ -1071,6 +1070,17 @@ function getElementRect(element2, view) {
|
|
|
1071
1070
|
}
|
|
1072
1071
|
return toElementRect(element2.getBoundingClientRect());
|
|
1073
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;
|
|
1083
|
+
}
|
|
1074
1084
|
|
|
1075
1085
|
// src/ui/ui-constants.ts
|
|
1076
1086
|
var UI_MARKER_ATTRIBUTE = "data-spotpatch-ui";
|
|
@@ -1088,12 +1098,7 @@ function isInsideSpotPatchUI(element2) {
|
|
|
1088
1098
|
return root instanceof ShadowRoot && root.host.hasAttribute(UI_MARKER_ATTRIBUTE);
|
|
1089
1099
|
}
|
|
1090
1100
|
function hasVisibleArea(element2, view) {
|
|
1091
|
-
|
|
1092
|
-
if (style.display === "none" || style.visibility === "hidden") {
|
|
1093
|
-
return false;
|
|
1094
|
-
}
|
|
1095
|
-
const rect = element2.getBoundingClientRect();
|
|
1096
|
-
return rect.width > 0 && rect.height > 0;
|
|
1101
|
+
return getVisibleElementRect(element2, view) !== void 0;
|
|
1097
1102
|
}
|
|
1098
1103
|
function isDocumentRoot(element2) {
|
|
1099
1104
|
return element2.tagName === "HTML" || element2.tagName === "BODY";
|
|
@@ -1699,7 +1704,7 @@ function createButton(document, label, className = "") {
|
|
|
1699
1704
|
// src/ui/agent-panel.ts
|
|
1700
1705
|
var AGENT_PANEL_STYLES = `
|
|
1701
1706
|
.spotpatch-agent {
|
|
1702
|
-
margin-top:
|
|
1707
|
+
margin-top: 10px;
|
|
1703
1708
|
overflow: hidden;
|
|
1704
1709
|
border: 1px solid var(--spotpatch-border-subtle);
|
|
1705
1710
|
border-radius: var(--spotpatch-radius-card);
|
|
@@ -1709,36 +1714,36 @@ var AGENT_PANEL_STYLES = `
|
|
|
1709
1714
|
display: flex;
|
|
1710
1715
|
align-items: center;
|
|
1711
1716
|
justify-content: space-between;
|
|
1712
|
-
gap:
|
|
1713
|
-
padding:
|
|
1717
|
+
gap: 10px;
|
|
1718
|
+
padding: 10px 12px;
|
|
1714
1719
|
border-bottom: 1px solid rgb(255 255 255 / 7%);
|
|
1715
1720
|
}
|
|
1716
|
-
.spotpatch-agent-title { color: #eef0f5; font-size:
|
|
1721
|
+
.spotpatch-agent-title { color: #eef0f5; font-size: 13px; font-weight: 650; }
|
|
1717
1722
|
.spotpatch-agent-badge {
|
|
1718
1723
|
border: 1px solid rgb(129 112 247 / 24%);
|
|
1719
1724
|
border-radius: 999px;
|
|
1720
1725
|
padding: 3px 7px;
|
|
1721
1726
|
color: #c5cafa;
|
|
1722
1727
|
background: rgb(109 93 246 / 9%);
|
|
1723
|
-
font-size:
|
|
1728
|
+
font-size: 10px;
|
|
1724
1729
|
font-weight: 650;
|
|
1725
1730
|
}
|
|
1726
|
-
.spotpatch-agent-setup { padding:
|
|
1727
|
-
.spotpatch-agent-selectors { display: grid; grid-template-columns: 1fr; gap:
|
|
1728
|
-
.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; }
|
|
1729
1734
|
.spotpatch-agent select {
|
|
1730
1735
|
box-sizing: border-box;
|
|
1731
1736
|
width: 100%;
|
|
1732
1737
|
min-width: 0;
|
|
1733
|
-
min-height:
|
|
1734
|
-
margin-top:
|
|
1738
|
+
min-height: 34px;
|
|
1739
|
+
margin-top: 4px;
|
|
1735
1740
|
border: 1px solid var(--spotpatch-border);
|
|
1736
|
-
border-radius:
|
|
1737
|
-
padding:
|
|
1741
|
+
border-radius: 8px;
|
|
1742
|
+
padding: 7px 32px 7px 9px;
|
|
1738
1743
|
color: #e8ebf2;
|
|
1739
1744
|
color-scheme: dark;
|
|
1740
1745
|
background: linear-gradient(180deg, rgb(255 255 255 / 4%), rgb(255 255 255 / 2%));
|
|
1741
|
-
font-size:
|
|
1746
|
+
font-size: 12px;
|
|
1742
1747
|
font-weight: 560;
|
|
1743
1748
|
line-height: 1.35;
|
|
1744
1749
|
outline: none;
|
|
@@ -1750,7 +1755,7 @@ var AGENT_PANEL_STYLES = `
|
|
|
1750
1755
|
@supports (appearance: base-select) {
|
|
1751
1756
|
.spotpatch-agent select,
|
|
1752
1757
|
::picker(select) { appearance: base-select; }
|
|
1753
|
-
.spotpatch-agent select { padding:
|
|
1758
|
+
.spotpatch-agent select { padding: 7px 9px; }
|
|
1754
1759
|
.spotpatch-agent select::picker-icon {
|
|
1755
1760
|
color: #9da6b5;
|
|
1756
1761
|
transition: rotate 180ms cubic-bezier(.2, .8, .2, 1);
|
|
@@ -1797,24 +1802,24 @@ var AGENT_PANEL_STYLES = `
|
|
|
1797
1802
|
.spotpatch-consent {
|
|
1798
1803
|
display: flex;
|
|
1799
1804
|
align-items: flex-start;
|
|
1800
|
-
gap:
|
|
1801
|
-
margin-top:
|
|
1805
|
+
gap: 8px;
|
|
1806
|
+
margin-top: 10px;
|
|
1802
1807
|
color: var(--spotpatch-text-secondary);
|
|
1803
1808
|
cursor: pointer;
|
|
1804
|
-
font-size:
|
|
1805
|
-
line-height: 1.
|
|
1809
|
+
font-size: 11.5px;
|
|
1810
|
+
line-height: 1.5;
|
|
1806
1811
|
}
|
|
1807
|
-
.spotpatch-consent input { width:
|
|
1812
|
+
.spotpatch-consent input { width: 14px; height: 14px; flex: none; margin: 2px 0 0; accent-color: var(--spotpatch-accent); }
|
|
1808
1813
|
.spotpatch-workspace-consent {
|
|
1809
|
-
margin-top:
|
|
1814
|
+
margin-top: 9px;
|
|
1810
1815
|
border: 1px solid rgb(251 191 36 / 18%);
|
|
1811
1816
|
border-radius: 10px;
|
|
1812
|
-
padding:
|
|
1817
|
+
padding: 9px 10px;
|
|
1813
1818
|
background: rgb(120 53 15 / 9%);
|
|
1814
1819
|
}
|
|
1815
|
-
.spotpatch-workspace-consent strong { display: block; color: #fde68a; font-size:
|
|
1816
|
-
.spotpatch-workspace-consent small { display: block; margin-top: 2px; color: #aeb6c4; font-size:
|
|
1817
|
-
.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; }
|
|
1818
1823
|
.spotpatch-agent-workspace,
|
|
1819
1824
|
.spotpatch-agent-capability {
|
|
1820
1825
|
display: flex;
|
|
@@ -1822,7 +1827,7 @@ var AGENT_PANEL_STYLES = `
|
|
|
1822
1827
|
gap: 8px;
|
|
1823
1828
|
margin: 0;
|
|
1824
1829
|
color: #929bab;
|
|
1825
|
-
font-size:
|
|
1830
|
+
font-size: 11px;
|
|
1826
1831
|
}
|
|
1827
1832
|
.spotpatch-agent-capability::before {
|
|
1828
1833
|
width: 6px;
|
|
@@ -1852,7 +1857,7 @@ var AGENT_PANEL_STYLES = `
|
|
|
1852
1857
|
.spotpatch-agent-workspace[data-state="consent-required"]::before { background: #fbbf24; }
|
|
1853
1858
|
.spotpatch-agent-workspace[data-state="blocked"] { color: #fecaca; }
|
|
1854
1859
|
.spotpatch-agent-workspace[data-state="blocked"]::before { background: var(--spotpatch-danger); }
|
|
1855
|
-
.spotpatch-agent-job { padding:
|
|
1860
|
+
.spotpatch-agent-job { padding: 12px; }
|
|
1856
1861
|
.spotpatch-agent-job-meta { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
|
|
1857
1862
|
.spotpatch-agent-model { min-width: 0; overflow: hidden; color: #d6dafe; font-size: 13px; text-overflow: ellipsis; white-space: nowrap; }
|
|
1858
1863
|
.spotpatch-agent-status {
|
|
@@ -1994,11 +1999,7 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1994
1999
|
job.append(jobMeta, phase, error, activity, resultPanel);
|
|
1995
2000
|
root.append(header, setup, job);
|
|
1996
2001
|
const testButton = createButton(document, messages.agent.testConnection);
|
|
1997
|
-
const runButton = createButton(
|
|
1998
|
-
document,
|
|
1999
|
-
messages.agent.verifyAndRun,
|
|
2000
|
-
"spotpatch-run"
|
|
2001
|
-
);
|
|
2002
|
+
const runButton = createButton(document, messages.agent.run, "spotpatch-run");
|
|
2002
2003
|
const cancelButton = createButton(document, messages.agent.cancel);
|
|
2003
2004
|
const applyButton = createButton(document, messages.agent.apply, "spotpatch-primary");
|
|
2004
2005
|
const revertButton = createButton(document, messages.agent.revert);
|
|
@@ -2043,7 +2044,7 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
2043
2044
|
};
|
|
2044
2045
|
const refreshActions = () => {
|
|
2045
2046
|
const setupVisible = ai.enabled && selectionVisible && !jobPresented;
|
|
2046
|
-
runButton.textContent = capabilityProbing ? messages.agent.verifying :
|
|
2047
|
+
runButton.textContent = capabilityProbing ? messages.agent.verifying : messages.agent.run;
|
|
2047
2048
|
runButton.classList.toggle("spotpatch-primary", capabilityReady);
|
|
2048
2049
|
testButton.hidden = !setupVisible;
|
|
2049
2050
|
runButton.hidden = !setupVisible;
|
|
@@ -2398,6 +2399,25 @@ function calculateDialogPlacement({
|
|
|
2398
2399
|
}) {
|
|
2399
2400
|
const maxLeft = viewportWidth - dialogWidth - VIEWPORT_MARGIN;
|
|
2400
2401
|
const maxTop = viewportHeight - dialogHeight - VIEWPORT_MARGIN;
|
|
2402
|
+
const viewportLeft = clamp(
|
|
2403
|
+
(viewportWidth - dialogWidth) / 2,
|
|
2404
|
+
VIEWPORT_MARGIN,
|
|
2405
|
+
maxLeft
|
|
2406
|
+
);
|
|
2407
|
+
const viewportTop = clamp(
|
|
2408
|
+
(viewportHeight - dialogHeight) / 2,
|
|
2409
|
+
VIEWPORT_MARGIN,
|
|
2410
|
+
maxTop
|
|
2411
|
+
);
|
|
2412
|
+
if (target2 === void 0) {
|
|
2413
|
+
return Object.freeze({
|
|
2414
|
+
anchorX: clamp(dialogWidth / 2, ANCHOR_INSET, dialogWidth - ANCHOR_INSET),
|
|
2415
|
+
anchorY: clamp(dialogHeight / 2, ANCHOR_INSET, dialogHeight - ANCHOR_INSET),
|
|
2416
|
+
left: viewportLeft,
|
|
2417
|
+
mode: "viewport",
|
|
2418
|
+
top: viewportTop
|
|
2419
|
+
});
|
|
2420
|
+
}
|
|
2401
2421
|
const targetCenterX = target2.x + target2.width / 2;
|
|
2402
2422
|
const targetCenterY = target2.y + target2.height / 2;
|
|
2403
2423
|
const centeredLeft = clamp(targetCenterX - dialogWidth / 2, VIEWPORT_MARGIN, maxLeft);
|
|
@@ -2474,7 +2494,7 @@ var ERROR_MESSAGES_EN = Object.freeze({
|
|
|
2474
2494
|
[import_shared6.ERROR_CODES.PROVIDER_AUTH_FAILED]: "The provider rejected authentication. Check the server-side Key.",
|
|
2475
2495
|
[import_shared6.ERROR_CODES.PROVIDER_PROTOCOL_UNSUPPORTED]: "The relay does not match the configured OpenAI-compatible protocol.",
|
|
2476
2496
|
[import_shared6.ERROR_CODES.MODEL_NOT_ALLOWED]: "The selected model profile is not allowed.",
|
|
2477
|
-
[import_shared6.ERROR_CODES.MODEL_TOOL_CALL_UNSUPPORTED]: "The selected model did not
|
|
2497
|
+
[import_shared6.ERROR_CODES.MODEL_TOOL_CALL_UNSUPPORTED]: "The selected model did not start or continue the required tool call.",
|
|
2478
2498
|
[import_shared6.ERROR_CODES.PROVIDER_RATE_LIMITED]: "The provider is rate limited. Wait and try again.",
|
|
2479
2499
|
[import_shared6.ERROR_CODES.AGENT_BUSY]: "Another write Agent job is still active.",
|
|
2480
2500
|
[import_shared6.ERROR_CODES.AGENT_LIMIT_EXCEEDED]: "The Agent stopped at a configured time, turn, output, or size limit.",
|
|
@@ -2509,7 +2529,7 @@ var ERROR_MESSAGES_ZH = Object.freeze({
|
|
|
2509
2529
|
[import_shared6.ERROR_CODES.PROVIDER_AUTH_FAILED]: "\u6A21\u578B\u670D\u52A1\u9274\u6743\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u670D\u52A1\u7AEF Key\u3002",
|
|
2510
2530
|
[import_shared6.ERROR_CODES.PROVIDER_PROTOCOL_UNSUPPORTED]: "\u4E2D\u8F6C\u670D\u52A1\u4E0E\u914D\u7F6E\u7684 OpenAI \u517C\u5BB9\u534F\u8BAE\u4E0D\u4E00\u81F4\u3002",
|
|
2511
2531
|
[import_shared6.ERROR_CODES.MODEL_NOT_ALLOWED]: "\u5F53\u524D\u6A21\u578B\u914D\u7F6E\u672A\u83B7\u6388\u6743\u3002",
|
|
2512
|
-
[import_shared6.ERROR_CODES.MODEL_TOOL_CALL_UNSUPPORTED]: "\u5F53\u524D\u6A21\u578B\u672A\
|
|
2532
|
+
[import_shared6.ERROR_CODES.MODEL_TOOL_CALL_UNSUPPORTED]: "\u5F53\u524D\u6A21\u578B\u672A\u5B8C\u6210\u5FC5\u8981\u7684\u5DE5\u5177\u8C03\u7528\u6216\u7ED3\u679C\u7EED\u63A5\u3002",
|
|
2513
2533
|
[import_shared6.ERROR_CODES.PROVIDER_RATE_LIMITED]: "\u6A21\u578B\u670D\u52A1\u6B63\u5728\u9650\u6D41\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
|
|
2514
2534
|
[import_shared6.ERROR_CODES.AGENT_BUSY]: "\u5F53\u524D\u9879\u76EE\u5DF2\u6709\u4E00\u4E2A\u5199\u5165\u4EFB\u52A1\u6B63\u5728\u8FD0\u884C\u3002",
|
|
2515
2535
|
[import_shared6.ERROR_CODES.AGENT_LIMIT_EXCEEDED]: "Agent \u8FBE\u5230\u65F6\u95F4\u3001\u8F6E\u6B21\u3001\u8F93\u51FA\u6216\u53D8\u66F4\u89C4\u6A21\u9650\u5236\u3002",
|
|
@@ -2689,7 +2709,7 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2689
2709
|
modelAriaLabel: "AI model",
|
|
2690
2710
|
providerUnavailable: "Provider configuration is unavailable.",
|
|
2691
2711
|
consent: (provider) => `I understand selected context and allowed source may be sent to ${provider}; its data policy is my responsibility.`,
|
|
2692
|
-
connectionNotTested: "
|
|
2712
|
+
connectionNotTested: "Optional connection check not run",
|
|
2693
2713
|
workspaceNotChecked: "Local workspace not checked",
|
|
2694
2714
|
checkingWorkspace: "Checking Git workspace and isolated execution\u2026",
|
|
2695
2715
|
workspaceReady: "Local workspace is ready for isolated execution",
|
|
@@ -2706,7 +2726,6 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2706
2726
|
consentRequired: "Confirm remote provider data transmission before running AI.",
|
|
2707
2727
|
toolsReady: "tools and streaming ready",
|
|
2708
2728
|
testConnection: "Check environment",
|
|
2709
|
-
verifyAndRun: "Verify & run",
|
|
2710
2729
|
verifying: "Verifying\u2026",
|
|
2711
2730
|
run: "Run AI",
|
|
2712
2731
|
cancel: "Cancel agent",
|
|
@@ -2825,7 +2844,7 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2825
2844
|
modelAriaLabel: "AI \u6A21\u578B",
|
|
2826
2845
|
providerUnavailable: "\u6A21\u578B\u670D\u52A1\u914D\u7F6E\u4E0D\u53EF\u7528\u3002",
|
|
2827
2846
|
consent: (provider) => `\u6211\u4E86\u89E3\u9009\u4E2D\u4E0A\u4E0B\u6587\u4E0E\u83B7\u51C6\u6E90\u7801\u53EF\u80FD\u53D1\u9001\u5230 ${provider}\uFF0C\u5E76\u81EA\u884C\u8D1F\u8D23\u5176\u6570\u636E\u7B56\u7565\u3002`,
|
|
2828
|
-
connectionNotTested: "\u5C1A\u672A\
|
|
2847
|
+
connectionNotTested: "\u5C1A\u672A\u6267\u884C\u53EF\u9009\u8FDE\u63A5\u68C0\u67E5",
|
|
2829
2848
|
workspaceNotChecked: "\u5C1A\u672A\u68C0\u67E5\u672C\u5730\u5DE5\u4F5C\u533A",
|
|
2830
2849
|
checkingWorkspace: "\u6B63\u5728\u68C0\u67E5 Git \u5DE5\u4F5C\u533A\u4E0E\u9694\u79BB\u6267\u884C\u73AF\u5883\u2026\u2026",
|
|
2831
2850
|
workspaceReady: "\u672C\u5730\u5DE5\u4F5C\u533A\u5DF2\u6EE1\u8DB3\u9694\u79BB\u6267\u884C\u6761\u4EF6",
|
|
@@ -2842,7 +2861,6 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2842
2861
|
consentRequired: "\u8FD0\u884C AI \u524D\uFF0C\u8BF7\u5148\u786E\u8BA4\u5141\u8BB8\u5411\u8FDC\u7A0B\u6A21\u578B\u670D\u52A1\u4F20\u8F93\u6570\u636E\u3002",
|
|
2843
2862
|
toolsReady: "\u5DE5\u5177\u8C03\u7528\u4E0E\u6D41\u5F0F\u54CD\u5E94\u5DF2\u5C31\u7EEA",
|
|
2844
2863
|
testConnection: "\u68C0\u67E5\u8FD0\u884C\u73AF\u5883",
|
|
2845
|
-
verifyAndRun: "\u9A8C\u8BC1\u5E76\u8FD0\u884C",
|
|
2846
2864
|
verifying: "\u9A8C\u8BC1\u4E2D\u2026\u2026",
|
|
2847
2865
|
run: "\u8FD0\u884C AI",
|
|
2848
2866
|
cancel: "\u53D6\u6D88 Agent",
|
|
@@ -2928,33 +2946,36 @@ function createUiLocalizer(document, preference = "auto") {
|
|
|
2928
2946
|
}
|
|
2929
2947
|
|
|
2930
2948
|
// src/ui/runtime-view.ts
|
|
2931
|
-
var
|
|
2949
|
+
var DIALOG_MAX_WIDTH = 460;
|
|
2950
|
+
var DIALOG_MAX_HEIGHT = 620;
|
|
2932
2951
|
var DIALOG_FALLBACK_HEIGHT = Object.freeze({
|
|
2933
|
-
previewing:
|
|
2934
|
-
selected:
|
|
2952
|
+
previewing: 560,
|
|
2953
|
+
selected: DIALOG_MAX_HEIGHT
|
|
2935
2954
|
});
|
|
2936
2955
|
function createStyles(document) {
|
|
2937
2956
|
const style = document.createElement("style");
|
|
2938
2957
|
style.textContent = `
|
|
2939
2958
|
:host {
|
|
2940
2959
|
all: initial;
|
|
2941
|
-
--spotpatch-bg: #
|
|
2942
|
-
--spotpatch-bg-raised: #
|
|
2943
|
-
--spotpatch-bg-
|
|
2944
|
-
--spotpatch-
|
|
2945
|
-
--spotpatch-border
|
|
2946
|
-
--spotpatch-
|
|
2947
|
-
--spotpatch-text
|
|
2948
|
-
--spotpatch-text-
|
|
2949
|
-
--spotpatch-
|
|
2950
|
-
--spotpatch-accent
|
|
2951
|
-
--spotpatch-accent-
|
|
2960
|
+
--spotpatch-bg: #0e0e12;
|
|
2961
|
+
--spotpatch-bg-raised: #17171c;
|
|
2962
|
+
--spotpatch-bg-active: #1c1c22;
|
|
2963
|
+
--spotpatch-bg-input: #0b0b0f;
|
|
2964
|
+
--spotpatch-border: #2a2a32;
|
|
2965
|
+
--spotpatch-border-subtle: #232329;
|
|
2966
|
+
--spotpatch-text: #f2f2f5;
|
|
2967
|
+
--spotpatch-text-secondary: #96969f;
|
|
2968
|
+
--spotpatch-text-muted: #686872;
|
|
2969
|
+
--spotpatch-accent: #8b7bff;
|
|
2970
|
+
--spotpatch-accent-strong: #6a5ce8;
|
|
2971
|
+
--spotpatch-accent-cyan: #52a8ff;
|
|
2952
2972
|
--spotpatch-danger: #fb7185;
|
|
2953
2973
|
--spotpatch-success: #34d399;
|
|
2954
2974
|
--spotpatch-warning: #f59e0b;
|
|
2955
|
-
--spotpatch-
|
|
2956
|
-
--spotpatch-radius-
|
|
2957
|
-
--spotpatch-
|
|
2975
|
+
--spotpatch-text-on-accent: #0b0b12;
|
|
2976
|
+
--spotpatch-radius-panel: 16px;
|
|
2977
|
+
--spotpatch-radius-card: 10px;
|
|
2978
|
+
--spotpatch-shadow-panel: 0 30px 60px -20px rgb(0 0 0 / 70%);
|
|
2958
2979
|
color-scheme: dark;
|
|
2959
2980
|
color: var(--spotpatch-text);
|
|
2960
2981
|
font-family: Inter, "SF Pro Display", "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
@@ -3074,7 +3095,7 @@ function createStyles(document) {
|
|
|
3074
3095
|
left: 16px;
|
|
3075
3096
|
z-index: ${String(UI_Z_INDEX.controls)};
|
|
3076
3097
|
box-sizing: border-box;
|
|
3077
|
-
width: min(
|
|
3098
|
+
width: min(${String(DIALOG_MAX_WIDTH)}px, calc(100vw - 32px));
|
|
3078
3099
|
color: #edf0f7;
|
|
3079
3100
|
outline: none;
|
|
3080
3101
|
filter: drop-shadow(var(--spotpatch-shadow-panel));
|
|
@@ -3118,78 +3139,92 @@ function createStyles(document) {
|
|
|
3118
3139
|
position: relative;
|
|
3119
3140
|
z-index: 1;
|
|
3120
3141
|
display: flex;
|
|
3121
|
-
|
|
3142
|
+
box-sizing: border-box;
|
|
3143
|
+
max-height: min(${String(DIALOG_MAX_HEIGHT)}px, calc(100vh - 32px));
|
|
3122
3144
|
overflow: hidden;
|
|
3123
3145
|
flex-direction: column;
|
|
3124
3146
|
border: 1px solid var(--spotpatch-border);
|
|
3125
3147
|
border-radius: var(--spotpatch-radius-panel);
|
|
3126
3148
|
background: var(--spotpatch-bg);
|
|
3127
|
-
box-shadow: inset 0 1px rgb(255 255 255 /
|
|
3149
|
+
box-shadow: inset 0 1px rgb(255 255 255 / 5%), 0 0 60px -32px rgb(139 123 255 / 20%);
|
|
3150
|
+
}
|
|
3151
|
+
.spotpatch-shell::before {
|
|
3152
|
+
position: absolute;
|
|
3153
|
+
z-index: 2;
|
|
3154
|
+
top: 0;
|
|
3155
|
+
right: 20%;
|
|
3156
|
+
left: 20%;
|
|
3157
|
+
height: 1px;
|
|
3158
|
+
background: linear-gradient(90deg, transparent, var(--spotpatch-accent), var(--spotpatch-accent-cyan), transparent);
|
|
3159
|
+
content: "";
|
|
3160
|
+
opacity: .65;
|
|
3161
|
+
pointer-events: none;
|
|
3128
3162
|
}
|
|
3129
3163
|
.spotpatch-header {
|
|
3130
3164
|
position: relative;
|
|
3131
|
-
padding:
|
|
3132
|
-
border-bottom: 1px solid rgb(255 255 255 / 8%);
|
|
3165
|
+
padding: 0 18px 14px;
|
|
3133
3166
|
}
|
|
3134
3167
|
.spotpatch-brand-row {
|
|
3135
3168
|
display: flex;
|
|
3136
3169
|
align-items: center;
|
|
3137
3170
|
justify-content: space-between;
|
|
3138
|
-
gap:
|
|
3139
|
-
margin
|
|
3171
|
+
gap: 12px;
|
|
3172
|
+
margin: 0 -18px 18px;
|
|
3173
|
+
padding: 14px 18px 13px;
|
|
3174
|
+
border-bottom: 1px solid var(--spotpatch-border-subtle);
|
|
3140
3175
|
}
|
|
3141
3176
|
.spotpatch-brand {
|
|
3142
3177
|
display: inline-flex;
|
|
3143
3178
|
align-items: center;
|
|
3144
|
-
gap:
|
|
3179
|
+
gap: 10px;
|
|
3145
3180
|
min-width: 0;
|
|
3146
3181
|
color: #f8fafc;
|
|
3147
3182
|
}
|
|
3148
3183
|
.spotpatch-brand-mark {
|
|
3149
|
-
width:
|
|
3150
|
-
height:
|
|
3184
|
+
width: 30px;
|
|
3185
|
+
height: 30px;
|
|
3151
3186
|
flex: none;
|
|
3152
3187
|
filter: drop-shadow(0 6px 12px rgb(76 29 149 / 22%));
|
|
3153
3188
|
}
|
|
3154
3189
|
.spotpatch-brand-copy { display: grid; min-width: 0; gap: 1px; }
|
|
3155
3190
|
.spotpatch-brand-name {
|
|
3156
3191
|
color: #fff;
|
|
3157
|
-
font-size:
|
|
3158
|
-
font-weight:
|
|
3192
|
+
font-size: 13.5px;
|
|
3193
|
+
font-weight: 680;
|
|
3159
3194
|
letter-spacing: -.01em;
|
|
3160
3195
|
}
|
|
3161
3196
|
.spotpatch-brand-context {
|
|
3162
3197
|
color: #8e98aa;
|
|
3163
|
-
font-size:
|
|
3198
|
+
font-size: 10.5px;
|
|
3164
3199
|
font-weight: 560;
|
|
3165
3200
|
letter-spacing: .02em;
|
|
3166
3201
|
}
|
|
3167
3202
|
.spotpatch-header-controls {
|
|
3168
3203
|
display: inline-flex;
|
|
3169
3204
|
align-items: center;
|
|
3170
|
-
gap:
|
|
3205
|
+
gap: 6px;
|
|
3171
3206
|
flex: none;
|
|
3172
3207
|
}
|
|
3173
3208
|
.spotpatch-repository,
|
|
3174
3209
|
.spotpatch-locale,
|
|
3175
3210
|
.spotpatch-close {
|
|
3176
|
-
height:
|
|
3211
|
+
height: 27px;
|
|
3177
3212
|
border: 1px solid rgb(255 255 255 / 11%);
|
|
3178
|
-
border-radius:
|
|
3179
|
-
background:
|
|
3213
|
+
border-radius: 7px;
|
|
3214
|
+
background: transparent;
|
|
3180
3215
|
}
|
|
3181
3216
|
.spotpatch-repository {
|
|
3182
3217
|
display: inline-flex;
|
|
3183
3218
|
align-items: center;
|
|
3184
|
-
padding: 0
|
|
3185
|
-
color:
|
|
3219
|
+
padding: 0 9px;
|
|
3220
|
+
color: var(--spotpatch-text-secondary);
|
|
3186
3221
|
font-size: 11px;
|
|
3187
3222
|
font-weight: 680;
|
|
3188
3223
|
text-decoration: none;
|
|
3189
3224
|
}
|
|
3190
3225
|
.spotpatch-locale {
|
|
3191
|
-
min-width:
|
|
3192
|
-
padding: 0
|
|
3226
|
+
min-width: 34px;
|
|
3227
|
+
padding: 0 8px;
|
|
3193
3228
|
color: #c5cad5;
|
|
3194
3229
|
cursor: pointer;
|
|
3195
3230
|
font-size: 12px;
|
|
@@ -3197,12 +3232,12 @@ function createStyles(document) {
|
|
|
3197
3232
|
}
|
|
3198
3233
|
.spotpatch-close {
|
|
3199
3234
|
display: inline-grid;
|
|
3200
|
-
width:
|
|
3235
|
+
width: 27px;
|
|
3201
3236
|
padding: 0;
|
|
3202
3237
|
place-items: center;
|
|
3203
3238
|
color: #9da5b4;
|
|
3204
3239
|
cursor: pointer;
|
|
3205
|
-
font-size:
|
|
3240
|
+
font-size: 15px;
|
|
3206
3241
|
line-height: 1;
|
|
3207
3242
|
transition: border-color 150ms ease, color 150ms ease, background 150ms ease;
|
|
3208
3243
|
}
|
|
@@ -3212,30 +3247,30 @@ function createStyles(document) {
|
|
|
3212
3247
|
.spotpatch-title {
|
|
3213
3248
|
margin: 0;
|
|
3214
3249
|
color: #fff;
|
|
3215
|
-
font-size:
|
|
3216
|
-
font-weight:
|
|
3217
|
-
letter-spacing: -.
|
|
3250
|
+
font-size: 18px;
|
|
3251
|
+
font-weight: 680;
|
|
3252
|
+
letter-spacing: -.015em;
|
|
3218
3253
|
}
|
|
3219
3254
|
.spotpatch-subtitle {
|
|
3220
|
-
max-width:
|
|
3221
|
-
margin:
|
|
3222
|
-
color:
|
|
3223
|
-
font-size:
|
|
3224
|
-
line-height: 1.
|
|
3255
|
+
max-width: 390px;
|
|
3256
|
+
margin: 4px 0 0;
|
|
3257
|
+
color: var(--spotpatch-text-secondary);
|
|
3258
|
+
font-size: 12.5px;
|
|
3259
|
+
line-height: 1.5;
|
|
3225
3260
|
}
|
|
3226
3261
|
.spotpatch-target-row {
|
|
3227
3262
|
display: flex;
|
|
3228
3263
|
align-items: center;
|
|
3229
3264
|
gap: 8px;
|
|
3230
3265
|
min-width: 0;
|
|
3231
|
-
margin-top:
|
|
3266
|
+
margin-top: 14px;
|
|
3232
3267
|
}
|
|
3233
3268
|
.spotpatch-target-label {
|
|
3234
3269
|
min-width: 0;
|
|
3235
3270
|
overflow: hidden;
|
|
3236
3271
|
border: 1px solid rgb(129 112 247 / 24%);
|
|
3237
3272
|
border-radius: 999px;
|
|
3238
|
-
padding:
|
|
3273
|
+
padding: 4px 10px;
|
|
3239
3274
|
color: #cdd2ff;
|
|
3240
3275
|
background: rgb(109 93 246 / 10%);
|
|
3241
3276
|
font: 600 11px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
@@ -3248,7 +3283,7 @@ function createStyles(document) {
|
|
|
3248
3283
|
gap: 6px;
|
|
3249
3284
|
flex: none;
|
|
3250
3285
|
color: #a5adba;
|
|
3251
|
-
font-size:
|
|
3286
|
+
font-size: 11px;
|
|
3252
3287
|
white-space: nowrap;
|
|
3253
3288
|
}
|
|
3254
3289
|
.spotpatch-context-state::before {
|
|
@@ -3269,7 +3304,7 @@ function createStyles(document) {
|
|
|
3269
3304
|
.spotpatch-body {
|
|
3270
3305
|
min-height: 0;
|
|
3271
3306
|
overflow: auto;
|
|
3272
|
-
padding:
|
|
3307
|
+
padding: 0 18px 14px;
|
|
3273
3308
|
scrollbar-color: rgb(100 116 139 / 50%) transparent;
|
|
3274
3309
|
scrollbar-width: thin;
|
|
3275
3310
|
}
|
|
@@ -3280,36 +3315,54 @@ function createStyles(document) {
|
|
|
3280
3315
|
display: flex;
|
|
3281
3316
|
align-items: center;
|
|
3282
3317
|
justify-content: space-between;
|
|
3283
|
-
gap:
|
|
3284
|
-
margin-bottom:
|
|
3285
|
-
color:
|
|
3286
|
-
font-size:
|
|
3287
|
-
font-weight:
|
|
3318
|
+
gap: 10px;
|
|
3319
|
+
margin-bottom: 8px;
|
|
3320
|
+
color: var(--spotpatch-text-secondary);
|
|
3321
|
+
font-size: 11px;
|
|
3322
|
+
font-weight: 650;
|
|
3323
|
+
letter-spacing: .04em;
|
|
3324
|
+
text-transform: uppercase;
|
|
3288
3325
|
}
|
|
3289
3326
|
.spotpatch-targets-meta {
|
|
3290
3327
|
display: flex;
|
|
3291
3328
|
align-items: center;
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3329
|
+
gap: 8px;
|
|
3330
|
+
min-width: 0;
|
|
3331
|
+
letter-spacing: 0;
|
|
3332
|
+
text-transform: none;
|
|
3295
3333
|
}
|
|
3296
|
-
.spotpatch-target-complete { color: var(--spotpatch-text-
|
|
3334
|
+
.spotpatch-target-complete { color: var(--spotpatch-text-muted); font-size: 11px; font-weight: 560; }
|
|
3297
3335
|
.spotpatch-target-budget {
|
|
3298
3336
|
color: var(--spotpatch-text-muted);
|
|
3299
|
-
font: 550
|
|
3337
|
+
font: 550 10.5px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
3300
3338
|
}
|
|
3339
|
+
.spotpatch-target-budget[data-state="ready"] { display: none; }
|
|
3301
3340
|
.spotpatch-target-budget[data-state="over"] { color: #fda4af; }
|
|
3302
3341
|
.spotpatch-target-count {
|
|
3342
|
+
margin-left: auto;
|
|
3303
3343
|
border-radius: 999px;
|
|
3304
3344
|
padding: 3px 8px;
|
|
3305
|
-
color:
|
|
3306
|
-
|
|
3307
|
-
|
|
3345
|
+
color: var(--spotpatch-text-muted);
|
|
3346
|
+
font: 600 10.5px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
3347
|
+
}
|
|
3348
|
+
.spotpatch-target-progress {
|
|
3349
|
+
height: 3px;
|
|
3350
|
+
margin-bottom: 13px;
|
|
3351
|
+
overflow: hidden;
|
|
3352
|
+
border-radius: 999px;
|
|
3353
|
+
background: var(--spotpatch-border-subtle);
|
|
3354
|
+
}
|
|
3355
|
+
.spotpatch-target-progress-fill {
|
|
3356
|
+
width: 0;
|
|
3357
|
+
height: 100%;
|
|
3358
|
+
border-radius: inherit;
|
|
3359
|
+
background: linear-gradient(90deg, var(--spotpatch-accent), var(--spotpatch-accent-cyan));
|
|
3360
|
+
transition: width 180ms ease;
|
|
3308
3361
|
}
|
|
3309
3362
|
.spotpatch-target-list {
|
|
3310
3363
|
display: grid;
|
|
3311
|
-
gap:
|
|
3312
|
-
max-height: min(
|
|
3364
|
+
gap: 8px;
|
|
3365
|
+
max-height: min(340px, 48vh);
|
|
3313
3366
|
overflow: auto;
|
|
3314
3367
|
padding-right: 2px;
|
|
3315
3368
|
}
|
|
@@ -3317,30 +3370,30 @@ function createStyles(document) {
|
|
|
3317
3370
|
overflow: hidden;
|
|
3318
3371
|
border: 1px solid var(--spotpatch-border-subtle);
|
|
3319
3372
|
border-radius: var(--spotpatch-radius-card);
|
|
3320
|
-
background:
|
|
3373
|
+
background: var(--spotpatch-bg-raised);
|
|
3321
3374
|
transition: border-color 150ms ease, background 150ms ease;
|
|
3322
3375
|
}
|
|
3323
3376
|
.spotpatch-target-item[data-active="true"] {
|
|
3324
|
-
border-color: rgb(
|
|
3325
|
-
background:
|
|
3326
|
-
box-shadow:
|
|
3377
|
+
border-color: rgb(139 123 255 / 34%);
|
|
3378
|
+
background: var(--spotpatch-bg-active);
|
|
3379
|
+
box-shadow: 0 0 0 3px rgb(139 123 255 / 10%);
|
|
3327
3380
|
}
|
|
3328
3381
|
.spotpatch-target-summary {
|
|
3329
3382
|
display: grid;
|
|
3330
|
-
grid-template-columns: minmax(0, 1fr)
|
|
3383
|
+
grid-template-columns: minmax(0, 1fr) 28px 28px;
|
|
3331
3384
|
align-items: stretch;
|
|
3332
|
-
gap:
|
|
3333
|
-
padding:
|
|
3385
|
+
gap: 2px;
|
|
3386
|
+
padding: 4px;
|
|
3334
3387
|
}
|
|
3335
3388
|
.spotpatch-target-select {
|
|
3336
3389
|
display: grid;
|
|
3337
|
-
grid-template-columns:
|
|
3390
|
+
grid-template-columns: 24px minmax(0, 1fr) auto;
|
|
3338
3391
|
align-items: center;
|
|
3339
|
-
gap:
|
|
3392
|
+
gap: 9px;
|
|
3340
3393
|
min-width: 0;
|
|
3341
3394
|
border: 0;
|
|
3342
|
-
border-radius:
|
|
3343
|
-
padding:
|
|
3395
|
+
border-radius: 8px;
|
|
3396
|
+
padding: 8px;
|
|
3344
3397
|
color: inherit;
|
|
3345
3398
|
background: transparent;
|
|
3346
3399
|
cursor: pointer;
|
|
@@ -3349,14 +3402,14 @@ function createStyles(document) {
|
|
|
3349
3402
|
.spotpatch-target-select:hover { background: rgb(255 255 255 / 3.5%); }
|
|
3350
3403
|
.spotpatch-target-index {
|
|
3351
3404
|
display: inline-grid;
|
|
3352
|
-
width:
|
|
3353
|
-
height:
|
|
3405
|
+
width: 22px;
|
|
3406
|
+
height: 22px;
|
|
3354
3407
|
place-items: center;
|
|
3355
3408
|
border: 1px solid rgb(68 202 224 / 25%);
|
|
3356
|
-
border-radius:
|
|
3357
|
-
color:
|
|
3358
|
-
background:
|
|
3359
|
-
font:
|
|
3409
|
+
border-radius: 6px;
|
|
3410
|
+
color: var(--spotpatch-text-secondary);
|
|
3411
|
+
background: var(--spotpatch-bg);
|
|
3412
|
+
font: 650 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
3360
3413
|
}
|
|
3361
3414
|
.spotpatch-target-copy { min-width: 0; }
|
|
3362
3415
|
.spotpatch-target-name,
|
|
@@ -3366,14 +3419,14 @@ function createStyles(document) {
|
|
|
3366
3419
|
text-overflow: ellipsis;
|
|
3367
3420
|
white-space: nowrap;
|
|
3368
3421
|
}
|
|
3369
|
-
.spotpatch-target-name { color: #
|
|
3370
|
-
.spotpatch-target-source { margin-top:
|
|
3422
|
+
.spotpatch-target-name { color: #f2f2f5; font-size: 13px; font-weight: 650; }
|
|
3423
|
+
.spotpatch-target-source { margin-top: 1px; color: var(--spotpatch-text-muted); font: 500 10.5px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; }
|
|
3371
3424
|
.spotpatch-target-state {
|
|
3372
3425
|
border-radius: 999px;
|
|
3373
|
-
padding:
|
|
3426
|
+
padding: 3px 8px;
|
|
3374
3427
|
color: #a7f3d0;
|
|
3375
3428
|
background: rgb(16 185 129 / 9%);
|
|
3376
|
-
font-size:
|
|
3429
|
+
font-size: 10.5px;
|
|
3377
3430
|
font-weight: 650;
|
|
3378
3431
|
white-space: nowrap;
|
|
3379
3432
|
}
|
|
@@ -3381,13 +3434,13 @@ function createStyles(document) {
|
|
|
3381
3434
|
.spotpatch-target-open,
|
|
3382
3435
|
.spotpatch-target-remove {
|
|
3383
3436
|
display: inline-grid;
|
|
3384
|
-
width:
|
|
3437
|
+
width: 28px;
|
|
3385
3438
|
height: 100%;
|
|
3386
|
-
min-height:
|
|
3439
|
+
min-height: 34px;
|
|
3387
3440
|
padding: 0;
|
|
3388
3441
|
place-items: center;
|
|
3389
3442
|
border: 1px solid transparent;
|
|
3390
|
-
border-radius:
|
|
3443
|
+
border-radius: 7px;
|
|
3391
3444
|
color: #7f899a;
|
|
3392
3445
|
background: transparent;
|
|
3393
3446
|
cursor: pointer;
|
|
@@ -3396,31 +3449,30 @@ function createStyles(document) {
|
|
|
3396
3449
|
.spotpatch-target-open:hover:not(:disabled) { border-color: rgb(68 202 224 / 30%); color: #c8f7ff; background: rgb(8 145 178 / 11%); }
|
|
3397
3450
|
.spotpatch-target-remove:hover:not(:disabled) { border-color: rgb(251 113 133 / 24%); color: #fda4af; background: rgb(127 29 29 / 12%); }
|
|
3398
3451
|
.spotpatch-target-editor {
|
|
3399
|
-
|
|
3400
|
-
padding: 18px;
|
|
3452
|
+
padding: 0 12px 12px;
|
|
3401
3453
|
}
|
|
3402
3454
|
.spotpatch-target-editor-head {
|
|
3403
3455
|
display: flex;
|
|
3404
3456
|
align-items: baseline;
|
|
3405
3457
|
justify-content: space-between;
|
|
3406
3458
|
gap: 12px;
|
|
3407
|
-
margin-bottom:
|
|
3459
|
+
margin-bottom: 6px;
|
|
3408
3460
|
}
|
|
3409
|
-
.spotpatch-target-editor-label { color:
|
|
3410
|
-
.spotpatch-target-editor-count { color: var(--spotpatch-text-muted); font: 500
|
|
3461
|
+
.spotpatch-target-editor-label { color: var(--spotpatch-text-secondary); font-size: 11px; font-weight: 650; }
|
|
3462
|
+
.spotpatch-target-editor-count { color: var(--spotpatch-text-muted); font: 500 10.5px/1.3 ui-monospace, SFMono-Regular, Menlo, monospace; }
|
|
3411
3463
|
.spotpatch-target-editor textarea {
|
|
3412
3464
|
box-sizing: border-box;
|
|
3413
3465
|
width: 100%;
|
|
3414
|
-
min-height:
|
|
3466
|
+
min-height: 74px;
|
|
3415
3467
|
resize: vertical;
|
|
3416
3468
|
border: 1px solid var(--spotpatch-border);
|
|
3417
|
-
border-radius:
|
|
3418
|
-
padding:
|
|
3469
|
+
border-radius: 7px;
|
|
3470
|
+
padding: 9px 10px;
|
|
3419
3471
|
color: #f8fafc;
|
|
3420
3472
|
caret-color: #8b7cf7;
|
|
3421
3473
|
background: var(--spotpatch-bg-input);
|
|
3422
|
-
font-size:
|
|
3423
|
-
line-height: 1.
|
|
3474
|
+
font-size: 12.5px;
|
|
3475
|
+
line-height: 1.55;
|
|
3424
3476
|
outline: none;
|
|
3425
3477
|
transition: border-color 150ms ease, box-shadow 150ms ease, background 150ms ease;
|
|
3426
3478
|
}
|
|
@@ -3429,23 +3481,23 @@ function createStyles(document) {
|
|
|
3429
3481
|
.spotpatch-target-editor textarea:focus {
|
|
3430
3482
|
border-color: rgb(139 124 247 / 68%);
|
|
3431
3483
|
background: rgb(3 7 18 / 65%);
|
|
3432
|
-
box-shadow: 0 0 0
|
|
3484
|
+
box-shadow: 0 0 0 2px rgb(109 93 246 / 10%);
|
|
3433
3485
|
}
|
|
3434
3486
|
.spotpatch-diagnostics {
|
|
3435
|
-
margin-top:
|
|
3487
|
+
margin-top: 10px;
|
|
3436
3488
|
overflow: hidden;
|
|
3437
3489
|
border: 1px solid rgb(255 255 255 / 8%);
|
|
3438
|
-
border-radius:
|
|
3490
|
+
border-radius: 9px;
|
|
3439
3491
|
background: rgb(255 255 255 / 2.5%);
|
|
3440
3492
|
}
|
|
3441
3493
|
.spotpatch-diagnostics > summary {
|
|
3442
3494
|
display: flex;
|
|
3443
3495
|
align-items: center;
|
|
3444
3496
|
gap: 8px;
|
|
3445
|
-
padding: 11px
|
|
3497
|
+
padding: 9px 11px;
|
|
3446
3498
|
color: #bfc5d0;
|
|
3447
3499
|
cursor: pointer;
|
|
3448
|
-
font-size:
|
|
3500
|
+
font-size: 11px;
|
|
3449
3501
|
font-weight: 650;
|
|
3450
3502
|
list-style: none;
|
|
3451
3503
|
user-select: none;
|
|
@@ -3474,9 +3526,9 @@ function createStyles(document) {
|
|
|
3474
3526
|
margin: 0;
|
|
3475
3527
|
overflow: auto;
|
|
3476
3528
|
border-top: 1px solid rgb(255 255 255 / 7%);
|
|
3477
|
-
padding:
|
|
3529
|
+
padding: 10px 11px 11px;
|
|
3478
3530
|
color: #9ca5b5;
|
|
3479
|
-
font:
|
|
3531
|
+
font: 10.5px/1.55 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
3480
3532
|
overflow-wrap: anywhere;
|
|
3481
3533
|
white-space: pre-wrap;
|
|
3482
3534
|
user-select: text;
|
|
@@ -3486,39 +3538,44 @@ function createStyles(document) {
|
|
|
3486
3538
|
margin: 0;
|
|
3487
3539
|
overflow: auto;
|
|
3488
3540
|
border: 1px solid rgb(255 255 255 / 9%);
|
|
3489
|
-
border-radius:
|
|
3490
|
-
padding:
|
|
3541
|
+
border-radius: 9px;
|
|
3542
|
+
padding: 11px;
|
|
3491
3543
|
color: #d8ddeb;
|
|
3492
3544
|
background: rgb(3 7 18 / 55%);
|
|
3493
|
-
font:
|
|
3545
|
+
font: 11px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
3494
3546
|
overflow-wrap: anywhere;
|
|
3495
3547
|
white-space: pre-wrap;
|
|
3496
3548
|
user-select: text;
|
|
3497
3549
|
}
|
|
3498
3550
|
.spotpatch-actions {
|
|
3499
|
-
display:
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
padding: 14px 22px 18px;
|
|
3551
|
+
display: grid;
|
|
3552
|
+
gap: 8px;
|
|
3553
|
+
padding: 10px 18px 14px;
|
|
3503
3554
|
border-top: 1px solid rgb(255 255 255 / 8%);
|
|
3504
|
-
background: rgb(8 12
|
|
3555
|
+
background: rgb(8 8 12 / 86%);
|
|
3505
3556
|
}
|
|
3506
3557
|
.spotpatch-editor-feedback {
|
|
3507
|
-
flex-basis: 100%;
|
|
3508
3558
|
white-space: normal;
|
|
3509
3559
|
}
|
|
3560
|
+
.spotpatch-secondary-actions,
|
|
3561
|
+
.spotpatch-primary-actions {
|
|
3562
|
+
display: flex;
|
|
3563
|
+
align-items: center;
|
|
3564
|
+
gap: 7px;
|
|
3565
|
+
}
|
|
3566
|
+
.spotpatch-secondary-actions { min-height: 30px; }
|
|
3510
3567
|
.spotpatch-actions button {
|
|
3511
3568
|
display: inline-flex;
|
|
3512
|
-
min-height:
|
|
3569
|
+
min-height: 34px;
|
|
3513
3570
|
align-items: center;
|
|
3514
3571
|
justify-content: center;
|
|
3515
3572
|
border: 1px solid rgb(255 255 255 / 10%);
|
|
3516
|
-
border-radius:
|
|
3517
|
-
padding:
|
|
3518
|
-
color:
|
|
3573
|
+
border-radius: 9px;
|
|
3574
|
+
padding: 7px 11px;
|
|
3575
|
+
color: var(--spotpatch-text-secondary);
|
|
3519
3576
|
background: rgb(255 255 255 / 4%);
|
|
3520
3577
|
cursor: pointer;
|
|
3521
|
-
font-size:
|
|
3578
|
+
font-size: 12px;
|
|
3522
3579
|
font-weight: 650;
|
|
3523
3580
|
transition: border-color 150ms ease, box-shadow 150ms ease, color 150ms ease, transform 150ms ease;
|
|
3524
3581
|
}
|
|
@@ -3528,14 +3585,36 @@ function createStyles(document) {
|
|
|
3528
3585
|
transform: translateY(-1px);
|
|
3529
3586
|
}
|
|
3530
3587
|
.spotpatch-actions .spotpatch-primary {
|
|
3531
|
-
min-width:
|
|
3588
|
+
min-width: 138px;
|
|
3532
3589
|
flex: 1;
|
|
3533
|
-
border-color:
|
|
3534
|
-
color:
|
|
3535
|
-
background: var(--spotpatch-accent-strong);
|
|
3536
|
-
box-shadow: 0
|
|
3590
|
+
border-color: transparent;
|
|
3591
|
+
color: var(--spotpatch-text-on-accent);
|
|
3592
|
+
background: linear-gradient(135deg, var(--spotpatch-accent), var(--spotpatch-accent-strong));
|
|
3593
|
+
box-shadow: 0 8px 20px -8px rgb(139 123 255 / 55%);
|
|
3537
3594
|
}
|
|
3595
|
+
.spotpatch-actions .spotpatch-primary:hover:not(:disabled) { color: var(--spotpatch-text-on-accent); filter: brightness(1.08); }
|
|
3538
3596
|
.spotpatch-actions .spotpatch-primary::after { margin-left: 8px; content: "\u2197"; font-size: 12px; }
|
|
3597
|
+
.spotpatch-actions .spotpatch-secondary-action {
|
|
3598
|
+
min-height: 30px;
|
|
3599
|
+
border-style: dashed;
|
|
3600
|
+
padding: 5px 10px;
|
|
3601
|
+
color: var(--spotpatch-text-muted);
|
|
3602
|
+
background: transparent;
|
|
3603
|
+
font-size: 11px;
|
|
3604
|
+
}
|
|
3605
|
+
.spotpatch-actions .spotpatch-icon-action {
|
|
3606
|
+
width: 34px;
|
|
3607
|
+
min-width: 34px;
|
|
3608
|
+
padding: 0;
|
|
3609
|
+
font-size: 0;
|
|
3610
|
+
}
|
|
3611
|
+
.spotpatch-actions .spotpatch-icon-action::before {
|
|
3612
|
+
color: var(--spotpatch-text-secondary);
|
|
3613
|
+
content: attr(data-compact-icon);
|
|
3614
|
+
font-size: 18px;
|
|
3615
|
+
font-weight: 400;
|
|
3616
|
+
line-height: 1;
|
|
3617
|
+
}
|
|
3539
3618
|
.spotpatch-actions button:disabled { cursor: not-allowed; opacity: .4; transform: none; }
|
|
3540
3619
|
.spotpatch-actions button:focus-visible,
|
|
3541
3620
|
.spotpatch-repository:focus-visible,
|
|
@@ -3567,11 +3646,13 @@ function createStyles(document) {
|
|
|
3567
3646
|
}
|
|
3568
3647
|
@media (max-width: 520px) {
|
|
3569
3648
|
.spotpatch-dialog { top: 8px; left: 8px; width: calc(100vw - 16px); }
|
|
3570
|
-
.spotpatch-shell { max-height: calc(100vh - 16px); border-radius:
|
|
3571
|
-
.spotpatch-header, .spotpatch-body { padding-left:
|
|
3572
|
-
.spotpatch-
|
|
3573
|
-
.spotpatch-
|
|
3649
|
+
.spotpatch-shell { max-height: calc(100vh - 16px); border-radius: 14px; }
|
|
3650
|
+
.spotpatch-header, .spotpatch-body { padding-left: 14px; padding-right: 14px; }
|
|
3651
|
+
.spotpatch-brand-row { margin-right: -14px; margin-left: -14px; padding-right: 14px; padding-left: 14px; }
|
|
3652
|
+
.spotpatch-actions { padding-right: 14px; padding-left: 14px; }
|
|
3653
|
+
.spotpatch-target-select { grid-template-columns: 24px minmax(0, 1fr); }
|
|
3574
3654
|
.spotpatch-target-state { display: none; }
|
|
3655
|
+
.spotpatch-repository { display: none; }
|
|
3575
3656
|
}
|
|
3576
3657
|
${AGENT_PANEL_STYLES}
|
|
3577
3658
|
`;
|
|
@@ -3674,10 +3755,17 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3674
3755
|
const targetCount = createMarkedElement(document, "span");
|
|
3675
3756
|
targetCount.className = "spotpatch-target-count";
|
|
3676
3757
|
targetsMeta.append(targetComplete, targetBudget);
|
|
3677
|
-
|
|
3758
|
+
targetRow.append(targetCount);
|
|
3759
|
+
targetsHeading.append(targetsTitle, targetsMeta);
|
|
3760
|
+
const targetProgress = createMarkedElement(document, "div");
|
|
3761
|
+
targetProgress.className = "spotpatch-target-progress";
|
|
3762
|
+
targetProgress.setAttribute("aria-hidden", "true");
|
|
3763
|
+
const targetProgressFill = createMarkedElement(document, "div");
|
|
3764
|
+
targetProgressFill.className = "spotpatch-target-progress-fill";
|
|
3765
|
+
targetProgress.append(targetProgressFill);
|
|
3678
3766
|
const targetList = createMarkedElement(document, "div");
|
|
3679
3767
|
targetList.className = "spotpatch-target-list";
|
|
3680
|
-
targetsPanel.append(targetsHeading,
|
|
3768
|
+
targetsPanel.append(targetsHeading, targetProgress, targetList);
|
|
3681
3769
|
const diagnostics = createMarkedElement(document, "details");
|
|
3682
3770
|
diagnostics.className = "spotpatch-diagnostics";
|
|
3683
3771
|
const diagnosticsLabel = createMarkedElement(document, "summary");
|
|
@@ -3718,21 +3806,30 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3718
3806
|
);
|
|
3719
3807
|
const copyButton = createButton(document, messages.actions.copy, "spotpatch-primary");
|
|
3720
3808
|
const backButton = createButton(document, messages.actions.back);
|
|
3721
|
-
|
|
3722
|
-
|
|
3809
|
+
const secondaryActions = createMarkedElement(document, "div");
|
|
3810
|
+
secondaryActions.className = "spotpatch-secondary-actions";
|
|
3811
|
+
const primaryActions = createMarkedElement(document, "div");
|
|
3812
|
+
primaryActions.className = "spotpatch-primary-actions";
|
|
3813
|
+
addTargetButton.classList.add("spotpatch-icon-action");
|
|
3814
|
+
addTargetButton.dataset.compactIcon = "+";
|
|
3815
|
+
agentPanel.testButton.classList.add("spotpatch-icon-action");
|
|
3816
|
+
agentPanel.testButton.dataset.compactIcon = "\u2713";
|
|
3817
|
+
openEditorButton.classList.add("spotpatch-secondary-action");
|
|
3818
|
+
reselectButton.classList.add("spotpatch-secondary-action");
|
|
3819
|
+
secondaryActions.append(openEditorButton, reselectButton);
|
|
3820
|
+
primaryActions.append(
|
|
3821
|
+
agentPanel.testButton,
|
|
3822
|
+
addTargetButton,
|
|
3723
3823
|
agentPanel.runButton,
|
|
3724
3824
|
previewButton,
|
|
3725
|
-
agentPanel.testButton,
|
|
3726
3825
|
agentPanel.cancelButton,
|
|
3727
3826
|
agentPanel.applyButton,
|
|
3728
3827
|
agentPanel.revertButton,
|
|
3729
3828
|
agentPanel.resetButton,
|
|
3730
|
-
addTargetButton,
|
|
3731
|
-
openEditorButton,
|
|
3732
|
-
reselectButton,
|
|
3733
3829
|
copyButton,
|
|
3734
3830
|
backButton
|
|
3735
3831
|
);
|
|
3832
|
+
actions.append(editorFeedback, secondaryActions, primaryActions);
|
|
3736
3833
|
shell.append(header, body, actions);
|
|
3737
3834
|
dialog.append(anchor, shell);
|
|
3738
3835
|
const liveRegion = createMarkedElement(document, "div");
|
|
@@ -3771,6 +3868,10 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3771
3868
|
}
|
|
3772
3869
|
return target2.status === "warning" ? messages.targets.statusPartial : messages.targets.statusCollecting;
|
|
3773
3870
|
}
|
|
3871
|
+
function renderTargetProgress(complete, total) {
|
|
3872
|
+
const ratio = total === 0 ? 0 : complete / total;
|
|
3873
|
+
targetProgressFill.style.width = `${String(ratio * 100)}%`;
|
|
3874
|
+
}
|
|
3774
3875
|
function instructionInput(targetId) {
|
|
3775
3876
|
const inputs = targetList.querySelectorAll(
|
|
3776
3877
|
"textarea[data-target-instruction-id]"
|
|
@@ -3796,6 +3897,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3796
3897
|
(total, target2) => total + target2.instruction.trim().length,
|
|
3797
3898
|
0
|
|
3798
3899
|
);
|
|
3900
|
+
renderTargetProgress(completeCount, targets.length);
|
|
3799
3901
|
targetCount.textContent = messages.targets.count(targets.length, maximum);
|
|
3800
3902
|
targetComplete.textContent = messages.targets.complete(
|
|
3801
3903
|
completeCount,
|
|
@@ -3917,10 +4019,14 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3917
4019
|
import_shared7.MAX_TARGET_INSTRUCTION_CHARACTERS
|
|
3918
4020
|
);
|
|
3919
4021
|
}
|
|
4022
|
+
const completeCount = currentTargets.filter(
|
|
4023
|
+
(target2) => target2.instruction.trim().length > 0
|
|
4024
|
+
).length;
|
|
3920
4025
|
targetComplete.textContent = messages.targets.complete(
|
|
3921
|
-
|
|
4026
|
+
completeCount,
|
|
3922
4027
|
currentTargets.length
|
|
3923
4028
|
);
|
|
4029
|
+
renderTargetProgress(completeCount, currentTargets.length);
|
|
3924
4030
|
const instructionCharacters = currentTargets.reduce(
|
|
3925
4031
|
(total, target2) => total + target2.instruction.trim().length,
|
|
3926
4032
|
0
|
|
@@ -3955,7 +4061,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3955
4061
|
placeDialog();
|
|
3956
4062
|
}
|
|
3957
4063
|
function placeDialog() {
|
|
3958
|
-
if (dialog.hidden
|
|
4064
|
+
if (dialog.hidden) {
|
|
3959
4065
|
return;
|
|
3960
4066
|
}
|
|
3961
4067
|
const view = document.defaultView;
|
|
@@ -3963,14 +4069,14 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3963
4069
|
const viewportHeight = view?.innerHeight ?? document.documentElement.clientHeight;
|
|
3964
4070
|
const measured = dialog.getBoundingClientRect();
|
|
3965
4071
|
const status = currentStatus === "previewing" ? "previewing" : "selected";
|
|
3966
|
-
const dialogWidth = measured.width > 0 ? measured.width : Math.min(
|
|
4072
|
+
const dialogWidth = measured.width > 0 ? measured.width : Math.min(DIALOG_MAX_WIDTH, viewportWidth - 32);
|
|
3967
4073
|
const dialogHeight = measured.height > 0 ? measured.height : Math.min(DIALOG_FALLBACK_HEIGHT[status], viewportHeight - 32);
|
|
3968
4074
|
const placement = calculateDialogPlacement({
|
|
3969
|
-
target: currentRect,
|
|
3970
4075
|
dialogWidth,
|
|
3971
4076
|
dialogHeight,
|
|
3972
4077
|
viewportWidth,
|
|
3973
|
-
viewportHeight
|
|
4078
|
+
viewportHeight,
|
|
4079
|
+
...currentRect === void 0 ? {} : { target: currentRect }
|
|
3974
4080
|
});
|
|
3975
4081
|
dialog.style.left = `${String(placement.left)}px`;
|
|
3976
4082
|
dialog.style.top = `${String(placement.top)}px`;
|
|
@@ -4020,6 +4126,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4020
4126
|
addTargetButton.hidden = !selected;
|
|
4021
4127
|
openEditorButton.hidden = !selected;
|
|
4022
4128
|
previewButton.hidden = !selected;
|
|
4129
|
+
secondaryActions.hidden = !selected;
|
|
4023
4130
|
agentPanel.setSelectionVisible(selected);
|
|
4024
4131
|
copyButton.hidden = !previewing;
|
|
4025
4132
|
backButton.hidden = !previewing;
|
|
@@ -4058,6 +4165,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4058
4165
|
} else {
|
|
4059
4166
|
targetCount.textContent = messages.targets.count(0, currentMaximum);
|
|
4060
4167
|
targetComplete.textContent = messages.targets.complete(0, 0);
|
|
4168
|
+
renderTargetProgress(0, 0);
|
|
4061
4169
|
targetBudget.dataset.state = "ready";
|
|
4062
4170
|
targetBudget.textContent = messages.targets.instructionBudget(
|
|
4063
4171
|
0,
|
|
@@ -4126,6 +4234,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4126
4234
|
selectionHighlights.replaceChildren();
|
|
4127
4235
|
activeSelectionRect = void 0;
|
|
4128
4236
|
currentRect = void 0;
|
|
4237
|
+
placeDialog();
|
|
4129
4238
|
},
|
|
4130
4239
|
showSelection(summaryText, canOpenEditor, canPreview) {
|
|
4131
4240
|
updateSelection(summaryText, canOpenEditor, canPreview);
|
|
@@ -4151,6 +4260,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4151
4260
|
renderEditorStatus("idle");
|
|
4152
4261
|
targetCount.textContent = messages.targets.count(0, 0);
|
|
4153
4262
|
targetComplete.textContent = messages.targets.complete(0, 0);
|
|
4263
|
+
renderTargetProgress(0, 0);
|
|
4154
4264
|
targetLabel.textContent = messages.context.selectedElement;
|
|
4155
4265
|
summary.textContent = "";
|
|
4156
4266
|
promptOutput.textContent = "";
|
|
@@ -4593,10 +4703,7 @@ function createAgentWorkflow(options) {
|
|
|
4593
4703
|
providerConsents.add(selection.providerProfileId);
|
|
4594
4704
|
const workflowRevision = ++revision;
|
|
4595
4705
|
options.view.setAgentEditingEnabled(false);
|
|
4596
|
-
void
|
|
4597
|
-
probe(workflowRevision),
|
|
4598
|
-
refreshWorkspaceHealth(workflowRevision)
|
|
4599
|
-
]).then(async ([, health]) => {
|
|
4706
|
+
void refreshWorkspaceHealth(workflowRevision).then(async (health) => {
|
|
4600
4707
|
if (workflowRevision !== revision) {
|
|
4601
4708
|
return;
|
|
4602
4709
|
}
|
|
@@ -4859,11 +4966,15 @@ ${summary}`;
|
|
|
4859
4966
|
if (!target2.element?.isConnected) {
|
|
4860
4967
|
return [];
|
|
4861
4968
|
}
|
|
4969
|
+
const rect = getVisibleElementRect(target2.element, browser.window);
|
|
4970
|
+
if (rect === void 0) {
|
|
4971
|
+
return [];
|
|
4972
|
+
}
|
|
4862
4973
|
return [
|
|
4863
4974
|
{
|
|
4864
4975
|
id: target2.id,
|
|
4865
4976
|
label: elementLabel(target2.element),
|
|
4866
|
-
rect
|
|
4977
|
+
rect,
|
|
4867
4978
|
active: target2.id === activeTargetId
|
|
4868
4979
|
}
|
|
4869
4980
|
];
|