@spotpatch/runtime 1.12.0 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-BXRMVHNT.js → chunk-ASRUAKA5.js} +1 -1
- package/dist/chunk-ASRUAKA5.js.map +1 -0
- package/dist/chunk-KIDHJQRG.js +14 -0
- package/dist/chunk-KIDHJQRG.js.map +1 -0
- package/dist/{chunk-7ES63LA7.js → chunk-P6X75LO5.js} +11 -1
- package/dist/chunk-P6X75LO5.js.map +1 -0
- package/dist/chunk-P7W3F4UA.js +115 -0
- package/dist/chunk-P7W3F4UA.js.map +1 -0
- package/dist/contextual-ask-panel.cjs +1637 -0
- package/dist/contextual-ask-panel.cjs.map +1 -0
- package/dist/contextual-ask-panel.d.cts +163 -0
- package/dist/contextual-ask-panel.d.ts +163 -0
- package/dist/contextual-ask-panel.js +1593 -0
- package/dist/contextual-ask-panel.js.map +1 -0
- package/dist/data-flow-panel.cjs +9 -0
- package/dist/data-flow-panel.cjs.map +1 -1
- package/dist/data-flow-panel.js +1 -1
- package/dist/external-handoff-panel.cjs +29 -9
- package/dist/external-handoff-panel.cjs.map +1 -1
- package/dist/external-handoff-panel.d.cts +3 -3
- package/dist/external-handoff-panel.d.ts +3 -3
- package/dist/external-handoff-panel.js +22 -11
- package/dist/external-handoff-panel.js.map +1 -1
- package/dist/index.cjs +1285 -279
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1250 -356
- package/dist/index.js.map +1 -1
- package/dist/motion-extension-contract-B3m26CML.d.cts +72 -0
- package/dist/motion-extension-contract-B3m26CML.d.ts +72 -0
- package/dist/motion.cjs +1251 -0
- package/dist/motion.cjs.map +1 -0
- package/dist/motion.d.cts +11 -0
- package/dist/motion.d.ts +11 -0
- package/dist/motion.js +1092 -0
- package/dist/motion.js.map +1 -0
- package/package.json +31 -3
- package/dist/chunk-7ES63LA7.js.map +0 -1
- package/dist/chunk-BXRMVHNT.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getContextualAskExtension
|
|
3
|
+
} from "./chunk-KIDHJQRG.js";
|
|
1
4
|
import {
|
|
2
5
|
getDataFlowExtension
|
|
3
6
|
} from "./chunk-NII5OBAN.js";
|
|
@@ -10,13 +13,18 @@ import {
|
|
|
10
13
|
} from "./chunk-2WA6XVA4.js";
|
|
11
14
|
import {
|
|
12
15
|
getExternalHandoffExtension
|
|
13
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-ASRUAKA5.js";
|
|
17
|
+
import {
|
|
18
|
+
createBrandMark,
|
|
19
|
+
getFloatingSurfaceMotionExtension
|
|
20
|
+
} from "./chunk-P7W3F4UA.js";
|
|
14
21
|
import {
|
|
22
|
+
FLOATING_SURFACE_LAYOUT,
|
|
15
23
|
UI_MARKER_ATTRIBUTE,
|
|
16
24
|
UI_Z_INDEX,
|
|
17
25
|
createButton,
|
|
18
26
|
createMarkedElement
|
|
19
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-P6X75LO5.js";
|
|
20
28
|
|
|
21
29
|
// src/controller/runtime-controller.ts
|
|
22
30
|
import { createReact18Adapter } from "@spotpatch/react-adapter";
|
|
@@ -430,7 +438,7 @@ function omitBrowserCodeContext(request) {
|
|
|
430
438
|
};
|
|
431
439
|
}
|
|
432
440
|
function runtimeApiErrorCode(error) {
|
|
433
|
-
return error instanceof RuntimeApiError ? error.code : void 0;
|
|
441
|
+
return error instanceof RuntimeApiError && isAgentErrorCode(error.code) ? error.code : void 0;
|
|
434
442
|
}
|
|
435
443
|
function createRuntimeApi(options) {
|
|
436
444
|
const pendingRequests = /* @__PURE__ */ new Set();
|
|
@@ -1978,6 +1986,7 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1978
1986
|
root.hidden = !ai.enabled;
|
|
1979
1987
|
const header = createMarkedElement(document, "div");
|
|
1980
1988
|
header.className = "spotpatch-agent-head";
|
|
1989
|
+
header.setAttribute("data-spotpatch-agent-identity", "");
|
|
1981
1990
|
const title = createMarkedElement(document, "span");
|
|
1982
1991
|
title.className = "spotpatch-agent-title";
|
|
1983
1992
|
const badge = createMarkedElement(document, "span");
|
|
@@ -2419,151 +2428,6 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
2419
2428
|
});
|
|
2420
2429
|
}
|
|
2421
2430
|
|
|
2422
|
-
// src/ui/brand-mark-content.ts
|
|
2423
|
-
var BRAND_MARK_CONTENT = `
|
|
2424
|
-
<defs>
|
|
2425
|
-
<linearGradient id="locator-gradient" x1="76" y1="92" x2="436" y2="374" gradientUnits="userSpaceOnUse">
|
|
2426
|
-
<stop offset="0" stop-color="#B61CFF" />
|
|
2427
|
-
<stop offset="0.38" stop-color="#6D35FF" />
|
|
2428
|
-
<stop offset="0.72" stop-color="#168EFF" />
|
|
2429
|
-
<stop offset="1" stop-color="#00D9E9" />
|
|
2430
|
-
</linearGradient>
|
|
2431
|
-
<linearGradient id="left-code-gradient" x1="165" y1="166" x2="236" y2="258" gradientUnits="userSpaceOnUse">
|
|
2432
|
-
<stop stop-color="#A51EFF" />
|
|
2433
|
-
<stop offset="1" stop-color="#653BFF" />
|
|
2434
|
-
</linearGradient>
|
|
2435
|
-
<linearGradient id="right-code-gradient" x1="276" y1="166" x2="347" y2="258" gradientUnits="userSpaceOnUse">
|
|
2436
|
-
<stop stop-color="#158DFF" />
|
|
2437
|
-
<stop offset="1" stop-color="#00D8E9" />
|
|
2438
|
-
</linearGradient>
|
|
2439
|
-
<linearGradient id="bolt-gradient" x1="270" y1="111" x2="252" y2="365" gradientUnits="userSpaceOnUse">
|
|
2440
|
-
<stop stop-color="#6840FF" />
|
|
2441
|
-
<stop offset="0.48" stop-color="#257BFF" />
|
|
2442
|
-
<stop offset="1" stop-color="#00CBEF" />
|
|
2443
|
-
</linearGradient>
|
|
2444
|
-
</defs>
|
|
2445
|
-
<path
|
|
2446
|
-
fill="url(#locator-gradient)"
|
|
2447
|
-
fill-rule="evenodd"
|
|
2448
|
-
clip-rule="evenodd"
|
|
2449
|
-
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"
|
|
2450
|
-
/>
|
|
2451
|
-
<rect x="238" y="20" width="36" height="84" rx="4" fill="url(#locator-gradient)" />
|
|
2452
|
-
<rect x="62" y="196" width="84" height="36" rx="4" fill="url(#locator-gradient)" />
|
|
2453
|
-
<rect x="366" y="196" width="84" height="36" rx="4" fill="url(#locator-gradient)" />
|
|
2454
|
-
<path
|
|
2455
|
-
d="M213.5 160L158 211.5L213.5 263L238 236.5L211 211.5L238 186.5L213.5 160Z"
|
|
2456
|
-
fill="url(#left-code-gradient)"
|
|
2457
|
-
/>
|
|
2458
|
-
<path
|
|
2459
|
-
d="M298.5 160L354 211.5L298.5 263L274 236.5L301 211.5L274 186.5L298.5 160Z"
|
|
2460
|
-
fill="url(#right-code-gradient)"
|
|
2461
|
-
/>
|
|
2462
|
-
<path
|
|
2463
|
-
d="M283 108L232 212L266 253L238 369L302 237L267 198L283 108Z"
|
|
2464
|
-
fill="url(#bolt-gradient)"
|
|
2465
|
-
/>
|
|
2466
|
-
`;
|
|
2467
|
-
|
|
2468
|
-
// src/ui/brand-mark.ts
|
|
2469
|
-
var SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
2470
|
-
function resolveBrandMarkContent(override) {
|
|
2471
|
-
if (override !== void 0) {
|
|
2472
|
-
return { content: override, viewBox: "0 0 512 512" };
|
|
2473
|
-
}
|
|
2474
|
-
const injected = typeof __SPOTPATCH_BRAND_MARK_CONTENT__ === "string" ? __SPOTPATCH_BRAND_MARK_CONTENT__ : void 0;
|
|
2475
|
-
if (typeof injected === "string") {
|
|
2476
|
-
return { content: injected, viewBox: "0 0 512 512" };
|
|
2477
|
-
}
|
|
2478
|
-
return true ? { content: BRAND_MARK_CONTENT, viewBox: "0 0 512 512" } : { content: FALLBACK_BRAND_MARK_CONTENT, viewBox: "0 0 1 1" };
|
|
2479
|
-
}
|
|
2480
|
-
function svgElement(document, tagName, attributes) {
|
|
2481
|
-
const element2 = document.createElementNS(SVG_NAMESPACE, tagName);
|
|
2482
|
-
for (const [name, value] of Object.entries(attributes)) {
|
|
2483
|
-
element2.setAttribute(name, value);
|
|
2484
|
-
}
|
|
2485
|
-
return element2;
|
|
2486
|
-
}
|
|
2487
|
-
function createBrandMark(document, content) {
|
|
2488
|
-
const resolved = resolveBrandMarkContent(content);
|
|
2489
|
-
const svg = svgElement(document, "svg", {
|
|
2490
|
-
xmlns: SVG_NAMESPACE,
|
|
2491
|
-
class: "spotpatch-brand-mark",
|
|
2492
|
-
viewBox: resolved.viewBox,
|
|
2493
|
-
"aria-hidden": "true",
|
|
2494
|
-
focusable: "false"
|
|
2495
|
-
});
|
|
2496
|
-
svg.innerHTML = resolved.content;
|
|
2497
|
-
return svg;
|
|
2498
|
-
}
|
|
2499
|
-
|
|
2500
|
-
// src/ui/dialog-placement.ts
|
|
2501
|
-
var VIEWPORT_MARGIN = 16;
|
|
2502
|
-
var TARGET_GAP = 14;
|
|
2503
|
-
var TARGET_INSET = 24;
|
|
2504
|
-
var ANCHOR_INSET = 22;
|
|
2505
|
-
function clamp(value, minimum, maximum) {
|
|
2506
|
-
return Math.min(Math.max(value, minimum), Math.max(minimum, maximum));
|
|
2507
|
-
}
|
|
2508
|
-
function calculateDialogPlacement({
|
|
2509
|
-
dialogHeight,
|
|
2510
|
-
dialogWidth,
|
|
2511
|
-
target: target2,
|
|
2512
|
-
viewportHeight,
|
|
2513
|
-
viewportWidth
|
|
2514
|
-
}) {
|
|
2515
|
-
const maxLeft = viewportWidth - dialogWidth - VIEWPORT_MARGIN;
|
|
2516
|
-
const maxTop = viewportHeight - dialogHeight - VIEWPORT_MARGIN;
|
|
2517
|
-
const viewportLeft = clamp(
|
|
2518
|
-
(viewportWidth - dialogWidth) / 2,
|
|
2519
|
-
VIEWPORT_MARGIN,
|
|
2520
|
-
maxLeft
|
|
2521
|
-
);
|
|
2522
|
-
const viewportTop = clamp(
|
|
2523
|
-
(viewportHeight - dialogHeight) / 2,
|
|
2524
|
-
VIEWPORT_MARGIN,
|
|
2525
|
-
maxTop
|
|
2526
|
-
);
|
|
2527
|
-
if (target2 === void 0) {
|
|
2528
|
-
return Object.freeze({
|
|
2529
|
-
anchorX: clamp(dialogWidth / 2, ANCHOR_INSET, dialogWidth - ANCHOR_INSET),
|
|
2530
|
-
anchorY: clamp(dialogHeight / 2, ANCHOR_INSET, dialogHeight - ANCHOR_INSET),
|
|
2531
|
-
left: viewportLeft,
|
|
2532
|
-
mode: "viewport",
|
|
2533
|
-
top: viewportTop
|
|
2534
|
-
});
|
|
2535
|
-
}
|
|
2536
|
-
const targetCenterX = target2.x + target2.width / 2;
|
|
2537
|
-
const targetCenterY = target2.y + target2.height / 2;
|
|
2538
|
-
const centeredLeft = clamp(targetCenterX - dialogWidth / 2, VIEWPORT_MARGIN, maxLeft);
|
|
2539
|
-
const centeredTop = clamp(targetCenterY - dialogHeight / 2, VIEWPORT_MARGIN, maxTop);
|
|
2540
|
-
let left = centeredLeft;
|
|
2541
|
-
let top = centeredTop;
|
|
2542
|
-
let mode = "viewport";
|
|
2543
|
-
if (target2.width >= dialogWidth + TARGET_INSET * 2 && target2.height >= dialogHeight + TARGET_INSET * 2) {
|
|
2544
|
-
mode = "center";
|
|
2545
|
-
} else if (target2.y - dialogHeight - TARGET_GAP >= VIEWPORT_MARGIN) {
|
|
2546
|
-
top = target2.y - dialogHeight - TARGET_GAP;
|
|
2547
|
-
mode = "above";
|
|
2548
|
-
} else if (target2.y + target2.height + TARGET_GAP + dialogHeight <= viewportHeight - VIEWPORT_MARGIN) {
|
|
2549
|
-
top = target2.y + target2.height + TARGET_GAP;
|
|
2550
|
-
mode = "below";
|
|
2551
|
-
} else if (target2.x + target2.width + TARGET_GAP + dialogWidth <= viewportWidth - VIEWPORT_MARGIN) {
|
|
2552
|
-
left = target2.x + target2.width + TARGET_GAP;
|
|
2553
|
-
mode = "right";
|
|
2554
|
-
} else if (target2.x - dialogWidth - TARGET_GAP >= VIEWPORT_MARGIN) {
|
|
2555
|
-
left = target2.x - dialogWidth - TARGET_GAP;
|
|
2556
|
-
mode = "left";
|
|
2557
|
-
}
|
|
2558
|
-
return Object.freeze({
|
|
2559
|
-
anchorX: clamp(targetCenterX - left, ANCHOR_INSET, dialogWidth - ANCHOR_INSET),
|
|
2560
|
-
anchorY: clamp(targetCenterY - top, ANCHOR_INSET, dialogHeight - ANCHOR_INSET),
|
|
2561
|
-
left,
|
|
2562
|
-
mode,
|
|
2563
|
-
top
|
|
2564
|
-
});
|
|
2565
|
-
}
|
|
2566
|
-
|
|
2567
2431
|
// src/ui/localization.ts
|
|
2568
2432
|
import {
|
|
2569
2433
|
ERROR_CODES as ERROR_CODES2
|
|
@@ -2598,6 +2462,51 @@ var STATUS_ZH = Object.freeze({
|
|
|
2598
2462
|
reverted: "\u5DF2\u64A4\u9500",
|
|
2599
2463
|
failed: "\u5931\u8D25"
|
|
2600
2464
|
});
|
|
2465
|
+
var EXECUTION_ACTIVITY_EN = Object.freeze({
|
|
2466
|
+
prepare: "Preparing context",
|
|
2467
|
+
dispatch: "Dispatching context",
|
|
2468
|
+
discover: "Discovering project files",
|
|
2469
|
+
search: "Searching source",
|
|
2470
|
+
read: "Reading",
|
|
2471
|
+
patch: "Generating a minimal patch",
|
|
2472
|
+
check: "Running",
|
|
2473
|
+
audit: "Auditing proposed changes",
|
|
2474
|
+
apply: "Applying verified changes",
|
|
2475
|
+
sync: "Returning results to SpotPatch",
|
|
2476
|
+
unknown: "Processing the current task"
|
|
2477
|
+
});
|
|
2478
|
+
var EXECUTION_ACTIVITY_ZH = Object.freeze({
|
|
2479
|
+
prepare: "\u6B63\u5728\u51C6\u5907\u4E0A\u4E0B\u6587",
|
|
2480
|
+
dispatch: "\u6B63\u5728\u6D3E\u53D1\u4E0A\u4E0B\u6587",
|
|
2481
|
+
discover: "\u6B63\u5728\u67E5\u627E\u9879\u76EE\u6587\u4EF6",
|
|
2482
|
+
search: "\u6B63\u5728\u641C\u7D22\u6E90\u7801",
|
|
2483
|
+
read: "\u6B63\u5728\u8BFB\u53D6",
|
|
2484
|
+
patch: "\u6B63\u5728\u751F\u6210\u6700\u5C0F\u4FEE\u6539\u8865\u4E01",
|
|
2485
|
+
check: "\u6B63\u5728\u8FD0\u884C",
|
|
2486
|
+
audit: "\u6B63\u5728\u5BA1\u8BA1\u5019\u9009\u4FEE\u6539",
|
|
2487
|
+
apply: "\u6B63\u5728\u5E94\u7528\u5DF2\u9A8C\u8BC1\u4FEE\u6539",
|
|
2488
|
+
sync: "\u6B63\u5728\u5C06\u7ED3\u679C\u56DE\u6D41 SpotPatch",
|
|
2489
|
+
unknown: "\u6B63\u5728\u5904\u7406\u5F53\u524D\u4EFB\u52A1"
|
|
2490
|
+
});
|
|
2491
|
+
var EXECUTION_LANE_LABELS = Object.freeze({
|
|
2492
|
+
prepare: "prepare",
|
|
2493
|
+
dispatch: "dispatch",
|
|
2494
|
+
discover: "list",
|
|
2495
|
+
search: "search",
|
|
2496
|
+
read: "read",
|
|
2497
|
+
patch: "patch",
|
|
2498
|
+
check: "check",
|
|
2499
|
+
audit: "audit",
|
|
2500
|
+
apply: "apply",
|
|
2501
|
+
sync: "sync",
|
|
2502
|
+
unknown: "agent"
|
|
2503
|
+
});
|
|
2504
|
+
function executionActivityAction(labels, kind, detail) {
|
|
2505
|
+
return detail === void 0 || detail.length === 0 ? labels[kind] : `${labels[kind]} ${detail}`;
|
|
2506
|
+
}
|
|
2507
|
+
function executionActivityLane(kind, detail) {
|
|
2508
|
+
return detail === void 0 || detail.length === 0 ? EXECUTION_LANE_LABELS[kind] : `${EXECUTION_LANE_LABELS[kind]} \xB7 ${detail}`;
|
|
2509
|
+
}
|
|
2601
2510
|
var EXTERNAL_HANDOFF_ERROR_EN = "The external Agent handoff request failed.";
|
|
2602
2511
|
var EXTERNAL_HANDOFF_ERROR_ZH = "\u5916\u90E8 Agent \u4EA4\u63A5\u8BF7\u6C42\u5931\u8D25\u3002";
|
|
2603
2512
|
var ERROR_MESSAGES_EN = Object.freeze({
|
|
@@ -2815,6 +2724,11 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2815
2724
|
previewTitle: "Review the request",
|
|
2816
2725
|
previewSubtitle: "Verify the complete context before it leaves the browser."
|
|
2817
2726
|
}),
|
|
2727
|
+
floatingSurface: Object.freeze({
|
|
2728
|
+
dragHandle: "Drag to move the SpotPatch workbench",
|
|
2729
|
+
resetPosition: "Reset workbench position",
|
|
2730
|
+
positionReset: "SpotPatch position reset to the lower-right corner."
|
|
2731
|
+
}),
|
|
2818
2732
|
context: Object.freeze({
|
|
2819
2733
|
collecting: "Collecting context",
|
|
2820
2734
|
ready: "Context ready",
|
|
@@ -2901,6 +2815,27 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2901
2815
|
noOutput: "No output.",
|
|
2902
2816
|
status: (status) => STATUS_EN[status]
|
|
2903
2817
|
}),
|
|
2818
|
+
execution: Object.freeze({
|
|
2819
|
+
claude: "Claude",
|
|
2820
|
+
codex: "Codex",
|
|
2821
|
+
receivingTitle: "Receiving context",
|
|
2822
|
+
dispatchingTitle: (identity) => `Handing off to ${identity}`,
|
|
2823
|
+
runningTitle: (target2) => `Modifying ${target2}`,
|
|
2824
|
+
expandedRunningTitle: (identity) => `${identity} is making changes`,
|
|
2825
|
+
completedTitle: "Change complete",
|
|
2826
|
+
expandedCompletedTitle: "Changes complete",
|
|
2827
|
+
failedTitle: "Execution failed",
|
|
2828
|
+
receivingStatus: "Receiving",
|
|
2829
|
+
dispatchingStatus: "Dispatching",
|
|
2830
|
+
runningStatus: "Running",
|
|
2831
|
+
checkingStatus: "Checking",
|
|
2832
|
+
completedStatus: "Done",
|
|
2833
|
+
failedStatus: "Failed",
|
|
2834
|
+
resultReturned: "The result is back in SpotPatch",
|
|
2835
|
+
resultSummary: (files) => `${String(files)} ${files === 1 ? "file" : "files"}`,
|
|
2836
|
+
activityAction: (kind, detail) => executionActivityAction(EXECUTION_ACTIVITY_EN, kind, detail),
|
|
2837
|
+
activityLane: executionActivityLane
|
|
2838
|
+
}),
|
|
2904
2839
|
announcements: Object.freeze({
|
|
2905
2840
|
adapterDisabled: "React inspection was disabled after an adapter failure.",
|
|
2906
2841
|
selectionEnabled: "Element selection enabled.",
|
|
@@ -2953,6 +2888,11 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2953
2888
|
previewTitle: "\u5BA1\u9605\u4FEE\u6539\u8BF7\u6C42",
|
|
2954
2889
|
previewSubtitle: "\u53D1\u9001\u7ED9 AI \u524D\uFF0C\u8BF7\u6838\u5BF9\u5B8C\u6574\u4E0A\u4E0B\u6587\u4E0E\u6BCF\u9879\u76EE\u6807\u8BF4\u660E\u3002"
|
|
2955
2890
|
}),
|
|
2891
|
+
floatingSurface: Object.freeze({
|
|
2892
|
+
dragHandle: "\u62D6\u62FD\u4EE5\u79FB\u52A8 SpotPatch \u5DE5\u4F5C\u53F0",
|
|
2893
|
+
resetPosition: "\u91CD\u7F6E\u5DE5\u4F5C\u53F0\u4F4D\u7F6E",
|
|
2894
|
+
positionReset: "SpotPatch \u5DF2\u6062\u590D\u5230\u53F3\u4E0B\u89D2\u3002"
|
|
2895
|
+
}),
|
|
2956
2896
|
context: Object.freeze({
|
|
2957
2897
|
collecting: "\u6B63\u5728\u91C7\u96C6\u4E0A\u4E0B\u6587",
|
|
2958
2898
|
ready: "\u4E0A\u4E0B\u6587\u5DF2\u5C31\u7EEA",
|
|
@@ -3039,6 +2979,27 @@ var UI_MESSAGES = Object.freeze({
|
|
|
3039
2979
|
noOutput: "\u6CA1\u6709\u8F93\u51FA\u3002",
|
|
3040
2980
|
status: (status) => STATUS_ZH[status]
|
|
3041
2981
|
}),
|
|
2982
|
+
execution: Object.freeze({
|
|
2983
|
+
claude: "Claude",
|
|
2984
|
+
codex: "Codex",
|
|
2985
|
+
receivingTitle: "\u6B63\u5728\u63A5\u6536\u4E0A\u4E0B\u6587",
|
|
2986
|
+
dispatchingTitle: (identity) => `\u6B63\u5728\u4EA4\u63A5\u7ED9 ${identity}`,
|
|
2987
|
+
runningTitle: (target2) => `\u6B63\u5728\u4FEE\u6539 ${target2}`,
|
|
2988
|
+
expandedRunningTitle: (identity) => `${identity} \u6B63\u5728\u6267\u884C\u4FEE\u6539`,
|
|
2989
|
+
completedTitle: "\u4FEE\u6539\u5B8C\u6210",
|
|
2990
|
+
expandedCompletedTitle: "\u4FEE\u6539\u5DF2\u5B8C\u6210",
|
|
2991
|
+
failedTitle: "\u6267\u884C\u5931\u8D25",
|
|
2992
|
+
receivingStatus: "\u63A5\u6536\u4E2D",
|
|
2993
|
+
dispatchingStatus: "\u6D3E\u53D1\u4E2D",
|
|
2994
|
+
runningStatus: "\u6267\u884C\u4E2D",
|
|
2995
|
+
checkingStatus: "\u68C0\u67E5\u4E2D",
|
|
2996
|
+
completedStatus: "\u5B8C\u6210",
|
|
2997
|
+
failedStatus: "\u5931\u8D25",
|
|
2998
|
+
resultReturned: "\u7ED3\u679C\u5DF2\u56DE\u6D41 SpotPatch",
|
|
2999
|
+
resultSummary: (files) => `${String(files)} \u4E2A\u6587\u4EF6`,
|
|
3000
|
+
activityAction: (kind, detail) => executionActivityAction(EXECUTION_ACTIVITY_ZH, kind, detail),
|
|
3001
|
+
activityLane: executionActivityLane
|
|
3002
|
+
}),
|
|
3042
3003
|
announcements: Object.freeze({
|
|
3043
3004
|
adapterDisabled: "React \u9002\u914D\u5668\u5F02\u5E38\uFF0C\u672C\u6B21\u4F1A\u8BDD\u5DF2\u505C\u7528 React \u68C0\u67E5\u3002",
|
|
3044
3005
|
selectionEnabled: "\u5143\u7D20\u9009\u62E9\u5DF2\u542F\u7528\u3002",
|
|
@@ -3112,13 +3073,500 @@ function createUiLocalizer(document, preference = "auto") {
|
|
|
3112
3073
|
});
|
|
3113
3074
|
}
|
|
3114
3075
|
|
|
3115
|
-
// src/
|
|
3116
|
-
var
|
|
3117
|
-
var
|
|
3118
|
-
var
|
|
3119
|
-
|
|
3120
|
-
|
|
3076
|
+
// src/state/floating-surface-session.ts
|
|
3077
|
+
var STORAGE_PREFIX2 = "spotpatch:floating-surface:";
|
|
3078
|
+
var SNAPSHOT_VERSION2 = 1;
|
|
3079
|
+
var MAX_SNAPSHOT_CHARACTERS2 = 1024;
|
|
3080
|
+
function record2(value) {
|
|
3081
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
3082
|
+
}
|
|
3083
|
+
function finiteRatio(value) {
|
|
3084
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 1;
|
|
3085
|
+
}
|
|
3086
|
+
function alignment(value) {
|
|
3087
|
+
return value === "start" || value === "end";
|
|
3088
|
+
}
|
|
3089
|
+
function parseSnapshot2(value) {
|
|
3090
|
+
const snapshot = record2(value);
|
|
3091
|
+
if (snapshot?.version !== SNAPSHOT_VERSION2 || !alignment(snapshot.horizontal) || !alignment(snapshot.vertical) || !finiteRatio(snapshot.xRatio) || !finiteRatio(snapshot.yRatio)) {
|
|
3092
|
+
return void 0;
|
|
3093
|
+
}
|
|
3094
|
+
return Object.freeze({
|
|
3095
|
+
horizontal: snapshot.horizontal,
|
|
3096
|
+
vertical: snapshot.vertical,
|
|
3097
|
+
xRatio: snapshot.xRatio,
|
|
3098
|
+
yRatio: snapshot.yRatio
|
|
3099
|
+
});
|
|
3100
|
+
}
|
|
3101
|
+
function createFloatingSurfaceSession(window, sessionId) {
|
|
3102
|
+
const key = `${STORAGE_PREFIX2}${sessionId}`;
|
|
3103
|
+
let storage;
|
|
3104
|
+
try {
|
|
3105
|
+
storage = window.sessionStorage;
|
|
3106
|
+
} catch {
|
|
3107
|
+
storage = void 0;
|
|
3108
|
+
}
|
|
3109
|
+
return Object.freeze({
|
|
3110
|
+
clear() {
|
|
3111
|
+
try {
|
|
3112
|
+
storage?.removeItem(key);
|
|
3113
|
+
} catch {
|
|
3114
|
+
}
|
|
3115
|
+
},
|
|
3116
|
+
load() {
|
|
3117
|
+
let serialized;
|
|
3118
|
+
try {
|
|
3119
|
+
serialized = storage?.getItem(key) ?? null;
|
|
3120
|
+
} catch {
|
|
3121
|
+
return void 0;
|
|
3122
|
+
}
|
|
3123
|
+
if (serialized === null || serialized.length > MAX_SNAPSHOT_CHARACTERS2) {
|
|
3124
|
+
return void 0;
|
|
3125
|
+
}
|
|
3126
|
+
try {
|
|
3127
|
+
return parseSnapshot2(JSON.parse(serialized));
|
|
3128
|
+
} catch {
|
|
3129
|
+
return void 0;
|
|
3130
|
+
}
|
|
3131
|
+
},
|
|
3132
|
+
save(position) {
|
|
3133
|
+
try {
|
|
3134
|
+
storage?.setItem(
|
|
3135
|
+
key,
|
|
3136
|
+
JSON.stringify({ version: SNAPSHOT_VERSION2, ...position })
|
|
3137
|
+
);
|
|
3138
|
+
} catch {
|
|
3139
|
+
}
|
|
3140
|
+
}
|
|
3141
|
+
});
|
|
3142
|
+
}
|
|
3143
|
+
|
|
3144
|
+
// src/ui/floating-surface-position.ts
|
|
3145
|
+
var DEFAULT_FLOATING_SURFACE_POSITION = Object.freeze({
|
|
3146
|
+
horizontal: "end",
|
|
3147
|
+
vertical: "end",
|
|
3148
|
+
xRatio: 1,
|
|
3149
|
+
yRatio: 1
|
|
3121
3150
|
});
|
|
3151
|
+
function clamp(value, minimum, maximum) {
|
|
3152
|
+
return Math.min(Math.max(value, minimum), maximum);
|
|
3153
|
+
}
|
|
3154
|
+
function finiteNonNegative(value) {
|
|
3155
|
+
return Number.isFinite(value) ? Math.max(0, value) : 0;
|
|
3156
|
+
}
|
|
3157
|
+
function boundedRatio(value) {
|
|
3158
|
+
return Number.isFinite(value) ? clamp(value, 0, 1) : 0.5;
|
|
3159
|
+
}
|
|
3160
|
+
function normalizedViewport(viewport) {
|
|
3161
|
+
return Object.freeze({
|
|
3162
|
+
height: finiteNonNegative(viewport.height),
|
|
3163
|
+
left: Number.isFinite(viewport.left) ? viewport.left : 0,
|
|
3164
|
+
top: Number.isFinite(viewport.top) ? viewport.top : 0,
|
|
3165
|
+
width: finiteNonNegative(viewport.width)
|
|
3166
|
+
});
|
|
3167
|
+
}
|
|
3168
|
+
function horizontalAnchor(rect, alignment2) {
|
|
3169
|
+
return alignment2 === "end" ? rect.left + rect.width : rect.left;
|
|
3170
|
+
}
|
|
3171
|
+
function verticalAnchor(rect, alignment2) {
|
|
3172
|
+
return alignment2 === "end" ? rect.top + rect.height : rect.top;
|
|
3173
|
+
}
|
|
3174
|
+
function normalizedCoordinate(coordinate, origin, length) {
|
|
3175
|
+
if (length <= 0) {
|
|
3176
|
+
return 0.5;
|
|
3177
|
+
}
|
|
3178
|
+
return boundedRatio((coordinate - origin) / length);
|
|
3179
|
+
}
|
|
3180
|
+
function positionFromAnchor(anchor, viewport, horizontal, vertical) {
|
|
3181
|
+
return Object.freeze({
|
|
3182
|
+
horizontal,
|
|
3183
|
+
vertical,
|
|
3184
|
+
xRatio: normalizedCoordinate(anchor.x, viewport.left, viewport.width),
|
|
3185
|
+
yRatio: normalizedCoordinate(anchor.y, viewport.top, viewport.height)
|
|
3186
|
+
});
|
|
3187
|
+
}
|
|
3188
|
+
function resolveFloatingSurfaceRect(position, size, viewport) {
|
|
3189
|
+
const width = finiteNonNegative(size.width);
|
|
3190
|
+
const height = finiteNonNegative(size.height);
|
|
3191
|
+
const normalized = normalizedViewport(viewport);
|
|
3192
|
+
const viewportWidth = normalized.width;
|
|
3193
|
+
const viewportHeight = normalized.height;
|
|
3194
|
+
const leftBoundary = normalized.left;
|
|
3195
|
+
const topBoundary = normalized.top;
|
|
3196
|
+
const rightBoundary = leftBoundary + viewportWidth;
|
|
3197
|
+
const bottomBoundary = topBoundary + viewportHeight;
|
|
3198
|
+
const anchorX = leftBoundary + boundedRatio(position.xRatio) * viewportWidth;
|
|
3199
|
+
const anchorY = topBoundary + boundedRatio(position.yRatio) * viewportHeight;
|
|
3200
|
+
const requestedLeft = position.horizontal === "end" ? anchorX - width : anchorX;
|
|
3201
|
+
const requestedTop = position.vertical === "end" ? anchorY - height : anchorY;
|
|
3202
|
+
const maximumLeft = Math.max(leftBoundary, rightBoundary - width);
|
|
3203
|
+
const maximumTop = Math.max(topBoundary, bottomBoundary - height);
|
|
3204
|
+
return Object.freeze({
|
|
3205
|
+
height,
|
|
3206
|
+
left: clamp(requestedLeft, leftBoundary, maximumLeft),
|
|
3207
|
+
top: clamp(requestedTop, topBoundary, maximumTop),
|
|
3208
|
+
width
|
|
3209
|
+
});
|
|
3210
|
+
}
|
|
3211
|
+
function snapFloatingSurfaceRect(rect, viewport, snapDistance) {
|
|
3212
|
+
const distance = finiteNonNegative(snapDistance);
|
|
3213
|
+
const width = finiteNonNegative(rect.width);
|
|
3214
|
+
const height = finiteNonNegative(rect.height);
|
|
3215
|
+
const normalized = normalizedViewport(viewport);
|
|
3216
|
+
const viewportRight = normalized.left + normalized.width;
|
|
3217
|
+
const viewportBottom = normalized.top + normalized.height;
|
|
3218
|
+
const maximumLeft = Math.max(normalized.left, viewportRight - width);
|
|
3219
|
+
const maximumTop = Math.max(normalized.top, viewportBottom - height);
|
|
3220
|
+
const requestedLeft = clamp(rect.left, normalized.left, maximumLeft);
|
|
3221
|
+
const requestedTop = clamp(rect.top, normalized.top, maximumTop);
|
|
3222
|
+
const leftDistance = Math.abs(requestedLeft - normalized.left);
|
|
3223
|
+
const rightDistance = Math.abs(viewportRight - (requestedLeft + width));
|
|
3224
|
+
const topDistance = Math.abs(requestedTop - normalized.top);
|
|
3225
|
+
const bottomDistance = Math.abs(viewportBottom - (requestedTop + height));
|
|
3226
|
+
const left = Math.min(leftDistance, rightDistance) <= distance ? leftDistance <= rightDistance ? normalized.left : viewportRight - width : requestedLeft;
|
|
3227
|
+
const top = Math.min(topDistance, bottomDistance) <= distance ? topDistance <= bottomDistance ? normalized.top : viewportBottom - height : requestedTop;
|
|
3228
|
+
return Object.freeze({ height, left, top, width });
|
|
3229
|
+
}
|
|
3230
|
+
function positionFromFloatingSurfaceRect(rect, viewport, previous) {
|
|
3231
|
+
const bounded = snapFloatingSurfaceRect(rect, viewport, 0);
|
|
3232
|
+
const centerX = bounded.left + bounded.width / 2;
|
|
3233
|
+
const centerY = bounded.top + bounded.height / 2;
|
|
3234
|
+
const viewportCenterX = viewport.left + finiteNonNegative(viewport.width) / 2;
|
|
3235
|
+
const viewportCenterY = viewport.top + finiteNonNegative(viewport.height) / 2;
|
|
3236
|
+
const horizontal = centerX === viewportCenterX ? previous.horizontal : centerX < viewportCenterX ? "start" : "end";
|
|
3237
|
+
const vertical = centerY === viewportCenterY ? previous.vertical : centerY < viewportCenterY ? "start" : "end";
|
|
3238
|
+
return positionFromAnchor(
|
|
3239
|
+
{
|
|
3240
|
+
x: horizontalAnchor(bounded, horizontal),
|
|
3241
|
+
y: verticalAnchor(bounded, vertical)
|
|
3242
|
+
},
|
|
3243
|
+
viewport,
|
|
3244
|
+
horizontal,
|
|
3245
|
+
vertical
|
|
3246
|
+
);
|
|
3247
|
+
}
|
|
3248
|
+
|
|
3249
|
+
// src/ui/floating-surface-controller.ts
|
|
3250
|
+
function finite(value, fallback = 0) {
|
|
3251
|
+
return Number.isFinite(value) ? value : fallback;
|
|
3252
|
+
}
|
|
3253
|
+
function distanceBetween(first, second) {
|
|
3254
|
+
return Math.hypot(first.x - second.x, first.y - second.y);
|
|
3255
|
+
}
|
|
3256
|
+
function isPrimaryPointer(event) {
|
|
3257
|
+
return event.button === 0 && event.isPrimary;
|
|
3258
|
+
}
|
|
3259
|
+
function surfaceSize(surface) {
|
|
3260
|
+
const rect = surface.getBoundingClientRect();
|
|
3261
|
+
return Object.freeze({
|
|
3262
|
+
height: Math.max(0, finite(rect.height)),
|
|
3263
|
+
width: Math.max(0, finite(rect.width))
|
|
3264
|
+
});
|
|
3265
|
+
}
|
|
3266
|
+
function requestFrame(window, callback) {
|
|
3267
|
+
if (typeof window.requestAnimationFrame === "function") {
|
|
3268
|
+
return window.requestAnimationFrame(callback);
|
|
3269
|
+
}
|
|
3270
|
+
return window.setTimeout(() => {
|
|
3271
|
+
callback(Date.now());
|
|
3272
|
+
}, 0);
|
|
3273
|
+
}
|
|
3274
|
+
function cancelFrame(window, frame) {
|
|
3275
|
+
if (typeof window.cancelAnimationFrame === "function") {
|
|
3276
|
+
window.cancelAnimationFrame(frame);
|
|
3277
|
+
return;
|
|
3278
|
+
}
|
|
3279
|
+
window.clearTimeout(frame);
|
|
3280
|
+
}
|
|
3281
|
+
function createFloatingSurfaceController(window, session, layout) {
|
|
3282
|
+
let position = session.load() ?? DEFAULT_FLOATING_SURFACE_POSITION;
|
|
3283
|
+
let drag;
|
|
3284
|
+
let frame;
|
|
3285
|
+
let suppressClickFor;
|
|
3286
|
+
let suppressClickTimer;
|
|
3287
|
+
let disposed = false;
|
|
3288
|
+
const surfaces = /* @__PURE__ */ new Set();
|
|
3289
|
+
const cleanup = /* @__PURE__ */ new Set();
|
|
3290
|
+
function viewport() {
|
|
3291
|
+
const visualViewport = window.visualViewport;
|
|
3292
|
+
const width = Math.max(0, finite(visualViewport?.width ?? window.innerWidth));
|
|
3293
|
+
const height = Math.max(0, finite(visualViewport?.height ?? window.innerHeight));
|
|
3294
|
+
const inset = width <= layout.compactViewportWidth ? layout.compactInset : layout.desktopInset;
|
|
3295
|
+
return Object.freeze({
|
|
3296
|
+
height: Math.max(0, height - inset * 2),
|
|
3297
|
+
left: finite(visualViewport?.offsetLeft ?? 0) + inset,
|
|
3298
|
+
top: finite(visualViewport?.offsetTop ?? 0) + inset,
|
|
3299
|
+
width: Math.max(0, width - inset * 2)
|
|
3300
|
+
});
|
|
3301
|
+
}
|
|
3302
|
+
function isCompact() {
|
|
3303
|
+
return viewport().width + layout.compactInset * 2 <= layout.compactViewportWidth;
|
|
3304
|
+
}
|
|
3305
|
+
function apply(surface) {
|
|
3306
|
+
if (surface.hidden) {
|
|
3307
|
+
return void 0;
|
|
3308
|
+
}
|
|
3309
|
+
if (surface.dataset.motionMorphing === "true" && surface.dataset.floatingPositioned === "true") {
|
|
3310
|
+
return void 0;
|
|
3311
|
+
}
|
|
3312
|
+
const size = surfaceSize(surface);
|
|
3313
|
+
if (size.width === 0 || size.height === 0) {
|
|
3314
|
+
return void 0;
|
|
3315
|
+
}
|
|
3316
|
+
const rect = resolveFloatingSurfaceRect(position, size, viewport());
|
|
3317
|
+
surface.style.left = `${String(rect.left)}px`;
|
|
3318
|
+
surface.style.top = `${String(rect.top)}px`;
|
|
3319
|
+
surface.style.right = "auto";
|
|
3320
|
+
surface.style.bottom = "auto";
|
|
3321
|
+
surface.dataset.floatingPositioned = "true";
|
|
3322
|
+
return rect;
|
|
3323
|
+
}
|
|
3324
|
+
function reconcile() {
|
|
3325
|
+
if (disposed) {
|
|
3326
|
+
return;
|
|
3327
|
+
}
|
|
3328
|
+
if (frame !== void 0) {
|
|
3329
|
+
cancelFrame(window, frame);
|
|
3330
|
+
frame = void 0;
|
|
3331
|
+
}
|
|
3332
|
+
for (const surface of surfaces) {
|
|
3333
|
+
apply(surface);
|
|
3334
|
+
}
|
|
3335
|
+
}
|
|
3336
|
+
function requestReconcile() {
|
|
3337
|
+
if (disposed || frame !== void 0) {
|
|
3338
|
+
return;
|
|
3339
|
+
}
|
|
3340
|
+
frame = requestFrame(window, () => {
|
|
3341
|
+
frame = void 0;
|
|
3342
|
+
reconcile();
|
|
3343
|
+
});
|
|
3344
|
+
}
|
|
3345
|
+
function commit(nextPosition) {
|
|
3346
|
+
position = nextPosition;
|
|
3347
|
+
session.save(position);
|
|
3348
|
+
}
|
|
3349
|
+
function finishDrag(commitPosition) {
|
|
3350
|
+
const current = drag;
|
|
3351
|
+
if (current === void 0) {
|
|
3352
|
+
return;
|
|
3353
|
+
}
|
|
3354
|
+
drag = void 0;
|
|
3355
|
+
current.handle.dataset.dragging = "false";
|
|
3356
|
+
current.surface.dataset.dragging = "false";
|
|
3357
|
+
try {
|
|
3358
|
+
if (current.handle.hasPointerCapture(current.pointerId)) {
|
|
3359
|
+
current.handle.releasePointerCapture(current.pointerId);
|
|
3360
|
+
}
|
|
3361
|
+
} catch {
|
|
3362
|
+
}
|
|
3363
|
+
if (commitPosition) {
|
|
3364
|
+
const rect = apply(current.surface);
|
|
3365
|
+
if (rect !== void 0) {
|
|
3366
|
+
const snapped = snapFloatingSurfaceRect(
|
|
3367
|
+
rect,
|
|
3368
|
+
viewport(),
|
|
3369
|
+
layout.edgeSnapDistance
|
|
3370
|
+
);
|
|
3371
|
+
commit(positionFromFloatingSurfaceRect(snapped, viewport(), position));
|
|
3372
|
+
apply(current.surface);
|
|
3373
|
+
}
|
|
3374
|
+
} else {
|
|
3375
|
+
position = session.load() ?? DEFAULT_FLOATING_SURFACE_POSITION;
|
|
3376
|
+
reconcile();
|
|
3377
|
+
}
|
|
3378
|
+
}
|
|
3379
|
+
function updateDrag(event) {
|
|
3380
|
+
const current = drag;
|
|
3381
|
+
if (current === void 0) {
|
|
3382
|
+
return;
|
|
3383
|
+
}
|
|
3384
|
+
if (event.pointerId !== current.pointerId) {
|
|
3385
|
+
return;
|
|
3386
|
+
}
|
|
3387
|
+
const pointer = Object.freeze({ x: event.clientX, y: event.clientY });
|
|
3388
|
+
const start = Object.freeze({ x: current.startX, y: current.startY });
|
|
3389
|
+
if (current.handle.dataset.dragging !== "true" && distanceBetween(pointer, start) < layout.dragActivationDistance) {
|
|
3390
|
+
return;
|
|
3391
|
+
}
|
|
3392
|
+
if (current.handle.dataset.dragging !== "true") {
|
|
3393
|
+
current.onDragStart?.();
|
|
3394
|
+
}
|
|
3395
|
+
current.handle.dataset.dragging = "true";
|
|
3396
|
+
current.surface.dataset.dragging = "true";
|
|
3397
|
+
position = positionFromAnchor(
|
|
3398
|
+
{
|
|
3399
|
+
x: pointer.x + current.anchorOffsetX,
|
|
3400
|
+
y: pointer.y + current.anchorOffsetY
|
|
3401
|
+
},
|
|
3402
|
+
viewport(),
|
|
3403
|
+
position.horizontal,
|
|
3404
|
+
position.vertical
|
|
3405
|
+
);
|
|
3406
|
+
requestReconcile();
|
|
3407
|
+
event.preventDefault();
|
|
3408
|
+
}
|
|
3409
|
+
function addListener(target2, type, listener, options) {
|
|
3410
|
+
target2.addEventListener(type, listener, options);
|
|
3411
|
+
cleanup.add(() => {
|
|
3412
|
+
target2.removeEventListener(type, listener, options);
|
|
3413
|
+
});
|
|
3414
|
+
}
|
|
3415
|
+
function attachDraggable(handle, surface, options = {}) {
|
|
3416
|
+
const onPointerDown = (event) => {
|
|
3417
|
+
if (disposed || drag !== void 0 || !isPrimaryPointer(event) || options.canStartDrag?.(event) === false) {
|
|
3418
|
+
return;
|
|
3419
|
+
}
|
|
3420
|
+
const rect = apply(surface) ?? surface.getBoundingClientRect();
|
|
3421
|
+
const anchorX = position.horizontal === "end" ? rect.left + rect.width : rect.left;
|
|
3422
|
+
const anchorY = position.vertical === "end" ? rect.top + rect.height : rect.top;
|
|
3423
|
+
drag = Object.freeze({
|
|
3424
|
+
anchorOffsetX: anchorX - event.clientX,
|
|
3425
|
+
anchorOffsetY: anchorY - event.clientY,
|
|
3426
|
+
handle,
|
|
3427
|
+
...options.onDragStart === void 0 ? {} : { onDragStart: options.onDragStart },
|
|
3428
|
+
pointerId: event.pointerId,
|
|
3429
|
+
startX: event.clientX,
|
|
3430
|
+
startY: event.clientY,
|
|
3431
|
+
suppressClickOnDrag: options.suppressClickOnDrag ?? false,
|
|
3432
|
+
surface
|
|
3433
|
+
});
|
|
3434
|
+
try {
|
|
3435
|
+
handle.setPointerCapture(event.pointerId);
|
|
3436
|
+
} catch {
|
|
3437
|
+
}
|
|
3438
|
+
};
|
|
3439
|
+
const onLostPointerCapture = (event) => {
|
|
3440
|
+
if (drag?.pointerId === event.pointerId) {
|
|
3441
|
+
finishDrag(handle.dataset.dragging === "true");
|
|
3442
|
+
}
|
|
3443
|
+
};
|
|
3444
|
+
const onClickCapture = (event) => {
|
|
3445
|
+
if (suppressClickFor !== handle) {
|
|
3446
|
+
return;
|
|
3447
|
+
}
|
|
3448
|
+
suppressClickFor = void 0;
|
|
3449
|
+
if (suppressClickTimer !== void 0) {
|
|
3450
|
+
window.clearTimeout(suppressClickTimer);
|
|
3451
|
+
suppressClickTimer = void 0;
|
|
3452
|
+
}
|
|
3453
|
+
event.preventDefault();
|
|
3454
|
+
event.stopImmediatePropagation();
|
|
3455
|
+
};
|
|
3456
|
+
addListener(handle, "pointerdown", (event) => {
|
|
3457
|
+
onPointerDown(event);
|
|
3458
|
+
});
|
|
3459
|
+
addListener(handle, "lostpointercapture", (event) => {
|
|
3460
|
+
onLostPointerCapture(event);
|
|
3461
|
+
});
|
|
3462
|
+
addListener(
|
|
3463
|
+
handle,
|
|
3464
|
+
"click",
|
|
3465
|
+
(event) => {
|
|
3466
|
+
onClickCapture(event);
|
|
3467
|
+
},
|
|
3468
|
+
true
|
|
3469
|
+
);
|
|
3470
|
+
}
|
|
3471
|
+
function reset() {
|
|
3472
|
+
finishDrag(false);
|
|
3473
|
+
position = DEFAULT_FLOATING_SURFACE_POSITION;
|
|
3474
|
+
session.clear();
|
|
3475
|
+
reconcile();
|
|
3476
|
+
}
|
|
3477
|
+
function cancelOnWindowBlur() {
|
|
3478
|
+
finishDrag(false);
|
|
3479
|
+
}
|
|
3480
|
+
function cancelOnEscape(event) {
|
|
3481
|
+
if (event.key !== "Escape" || drag === void 0) {
|
|
3482
|
+
return;
|
|
3483
|
+
}
|
|
3484
|
+
finishDrag(false);
|
|
3485
|
+
event.preventDefault();
|
|
3486
|
+
event.stopImmediatePropagation();
|
|
3487
|
+
}
|
|
3488
|
+
function endPointer(event) {
|
|
3489
|
+
if (drag?.pointerId !== event.pointerId) {
|
|
3490
|
+
return;
|
|
3491
|
+
}
|
|
3492
|
+
const current = drag;
|
|
3493
|
+
const moved = current.handle.dataset.dragging === "true";
|
|
3494
|
+
finishDrag(moved);
|
|
3495
|
+
if (moved && current.suppressClickOnDrag) {
|
|
3496
|
+
suppressClickFor = current.handle;
|
|
3497
|
+
suppressClickTimer = window.setTimeout(() => {
|
|
3498
|
+
suppressClickFor = void 0;
|
|
3499
|
+
suppressClickTimer = void 0;
|
|
3500
|
+
}, 0);
|
|
3501
|
+
}
|
|
3502
|
+
}
|
|
3503
|
+
function cancelPointer(event) {
|
|
3504
|
+
if (drag?.pointerId === event.pointerId) {
|
|
3505
|
+
finishDrag(false);
|
|
3506
|
+
}
|
|
3507
|
+
}
|
|
3508
|
+
addListener(window, "pointermove", (event) => {
|
|
3509
|
+
updateDrag(event);
|
|
3510
|
+
});
|
|
3511
|
+
addListener(window, "pointerup", (event) => {
|
|
3512
|
+
endPointer(event);
|
|
3513
|
+
});
|
|
3514
|
+
addListener(window, "pointercancel", (event) => {
|
|
3515
|
+
cancelPointer(event);
|
|
3516
|
+
});
|
|
3517
|
+
addListener(window, "resize", requestReconcile);
|
|
3518
|
+
addListener(window, "blur", cancelOnWindowBlur);
|
|
3519
|
+
addListener(
|
|
3520
|
+
window,
|
|
3521
|
+
"keydown",
|
|
3522
|
+
(event) => {
|
|
3523
|
+
cancelOnEscape(event);
|
|
3524
|
+
},
|
|
3525
|
+
true
|
|
3526
|
+
);
|
|
3527
|
+
window.visualViewport?.addEventListener("resize", requestReconcile);
|
|
3528
|
+
window.visualViewport?.addEventListener("scroll", requestReconcile);
|
|
3529
|
+
cleanup.add(
|
|
3530
|
+
() => window.visualViewport?.removeEventListener("resize", requestReconcile)
|
|
3531
|
+
);
|
|
3532
|
+
cleanup.add(
|
|
3533
|
+
() => window.visualViewport?.removeEventListener("scroll", requestReconcile)
|
|
3534
|
+
);
|
|
3535
|
+
return Object.freeze({
|
|
3536
|
+
attachDraggable,
|
|
3537
|
+
dispose() {
|
|
3538
|
+
if (disposed) {
|
|
3539
|
+
return;
|
|
3540
|
+
}
|
|
3541
|
+
disposed = true;
|
|
3542
|
+
finishDrag(false);
|
|
3543
|
+
if (frame !== void 0) {
|
|
3544
|
+
cancelFrame(window, frame);
|
|
3545
|
+
frame = void 0;
|
|
3546
|
+
}
|
|
3547
|
+
if (suppressClickTimer !== void 0) {
|
|
3548
|
+
window.clearTimeout(suppressClickTimer);
|
|
3549
|
+
suppressClickTimer = void 0;
|
|
3550
|
+
}
|
|
3551
|
+
suppressClickFor = void 0;
|
|
3552
|
+
for (const disposeListener of cleanup) {
|
|
3553
|
+
disposeListener();
|
|
3554
|
+
}
|
|
3555
|
+
cleanup.clear();
|
|
3556
|
+
surfaces.clear();
|
|
3557
|
+
},
|
|
3558
|
+
isCompact,
|
|
3559
|
+
reconcile,
|
|
3560
|
+
registerSurface(surface) {
|
|
3561
|
+
surfaces.add(surface);
|
|
3562
|
+
},
|
|
3563
|
+
requestReconcile,
|
|
3564
|
+
reset
|
|
3565
|
+
});
|
|
3566
|
+
}
|
|
3567
|
+
|
|
3568
|
+
// src/ui/runtime-view.ts
|
|
3569
|
+
var SUCCESS_SETTLE_MS = 1500;
|
|
3122
3570
|
function resolveStyleNonce(document) {
|
|
3123
3571
|
const nonces = new Set(
|
|
3124
3572
|
[...document.querySelectorAll("script[nonce]")].map((script) => script.nonce?.trim() ?? "").filter(Boolean)
|
|
@@ -3149,53 +3597,20 @@ function createStyles(document) {
|
|
|
3149
3597
|
--spotpatch-success: #34d399;
|
|
3150
3598
|
--spotpatch-warning: #f59e0b;
|
|
3151
3599
|
--spotpatch-text-on-accent: #0b0b12;
|
|
3152
|
-
--spotpatch-radius-panel: 16px;
|
|
3153
3600
|
--spotpatch-radius-card: 10px;
|
|
3154
|
-
--spotpatch-shadow-panel: 0 30px 60px -20px rgb(0 0 0 / 70%);
|
|
3155
|
-
color-scheme: dark;
|
|
3156
3601
|
color: var(--spotpatch-text);
|
|
3157
3602
|
font-family: Inter, "SF Pro Display", "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
3158
3603
|
font-size: 14px;
|
|
3159
3604
|
line-height: 1.5;
|
|
3160
|
-
text-rendering: optimizeLegibility;
|
|
3161
|
-
-webkit-font-smoothing: antialiased;
|
|
3162
3605
|
}
|
|
3163
3606
|
[hidden] { display: none !important; }
|
|
3164
3607
|
button, textarea, select { font: inherit; }
|
|
3165
|
-
|
|
3166
|
-
.spotpatch-trigger {
|
|
3608
|
+
.spotpatch-floating-surface {
|
|
3167
3609
|
position: fixed;
|
|
3168
|
-
right:
|
|
3169
|
-
bottom:
|
|
3610
|
+
right: ${String(FLOATING_SURFACE_LAYOUT.desktopInset)}px;
|
|
3611
|
+
bottom: ${String(FLOATING_SURFACE_LAYOUT.desktopInset)}px;
|
|
3170
3612
|
z-index: ${String(UI_Z_INDEX.controls)};
|
|
3171
|
-
|
|
3172
|
-
align-items: center;
|
|
3173
|
-
gap: 10px;
|
|
3174
|
-
min-height: 44px;
|
|
3175
|
-
border: 1px solid rgb(255 255 255 / 12%);
|
|
3176
|
-
border-radius: 999px;
|
|
3177
|
-
padding: 10px 17px;
|
|
3178
|
-
color: #f8fafc;
|
|
3179
|
-
background: #171b23;
|
|
3180
|
-
box-shadow: 0 12px 34px rgb(0 0 0 / 25%), inset 0 1px rgb(255 255 255 / 5%);
|
|
3181
|
-
cursor: pointer;
|
|
3182
|
-
font-size: 14px;
|
|
3183
|
-
font-weight: 650;
|
|
3184
|
-
transition: border-color 160ms ease, box-shadow 160ms ease, transform 160ms ease;
|
|
3185
|
-
}
|
|
3186
|
-
.spotpatch-trigger::before {
|
|
3187
|
-
width: 9px;
|
|
3188
|
-
height: 9px;
|
|
3189
|
-
border-radius: 999px;
|
|
3190
|
-
background: var(--spotpatch-accent);
|
|
3191
|
-
box-shadow: 0 0 0 4px rgb(99 102 241 / 10%);
|
|
3192
|
-
content: "";
|
|
3193
|
-
}
|
|
3194
|
-
.spotpatch-trigger:hover { transform: translateY(-1px); border-color: rgb(129 140 248 / 52%); }
|
|
3195
|
-
.spotpatch-trigger[aria-pressed="true"] {
|
|
3196
|
-
border-color: rgb(124 58 237 / 55%);
|
|
3197
|
-
background: #24203b;
|
|
3198
|
-
box-shadow: 0 14px 42px rgb(76 29 149 / 24%), inset 0 1px rgb(255 255 255 / 10%);
|
|
3613
|
+
isolation: isolate;
|
|
3199
3614
|
}
|
|
3200
3615
|
.spotpatch-highlight {
|
|
3201
3616
|
position: fixed;
|
|
@@ -3264,82 +3679,28 @@ function createStyles(document) {
|
|
|
3264
3679
|
background: #5546dc;
|
|
3265
3680
|
}
|
|
3266
3681
|
.spotpatch-dialog {
|
|
3267
|
-
|
|
3268
|
-
--spotpatch-anchor-y: 50%;
|
|
3269
|
-
position: fixed;
|
|
3270
|
-
top: 16px;
|
|
3271
|
-
left: 16px;
|
|
3272
|
-
z-index: ${String(UI_Z_INDEX.controls)};
|
|
3682
|
+
position: relative;
|
|
3273
3683
|
box-sizing: border-box;
|
|
3274
|
-
width: min(${String(
|
|
3275
|
-
color: #edf0f7;
|
|
3684
|
+
width: min(${String(FLOATING_SURFACE_LAYOUT.workbenchMaxWidth)}px, calc(100vw - ${String(FLOATING_SURFACE_LAYOUT.desktopInset * 2)}px));
|
|
3276
3685
|
outline: none;
|
|
3277
|
-
filter: drop-shadow(var(--spotpatch-shadow-panel));
|
|
3278
3686
|
}
|
|
3279
|
-
.spotpatch-anchor {
|
|
3280
|
-
position: absolute;
|
|
3281
|
-
z-index: 0;
|
|
3282
|
-
width: 14px;
|
|
3283
|
-
height: 14px;
|
|
3284
|
-
border: 1px solid rgb(255 255 255 / 12%);
|
|
3285
|
-
background: var(--spotpatch-bg);
|
|
3286
|
-
transform: rotate(45deg);
|
|
3287
|
-
}
|
|
3288
|
-
.spotpatch-dialog[data-placement="above"] .spotpatch-anchor {
|
|
3289
|
-
bottom: -6px;
|
|
3290
|
-
left: calc(var(--spotpatch-anchor-x) - 7px);
|
|
3291
|
-
border-top: 0;
|
|
3292
|
-
border-left: 0;
|
|
3293
|
-
}
|
|
3294
|
-
.spotpatch-dialog[data-placement="below"] .spotpatch-anchor {
|
|
3295
|
-
top: -6px;
|
|
3296
|
-
left: calc(var(--spotpatch-anchor-x) - 7px);
|
|
3297
|
-
border-right: 0;
|
|
3298
|
-
border-bottom: 0;
|
|
3299
|
-
}
|
|
3300
|
-
.spotpatch-dialog[data-placement="left"] .spotpatch-anchor {
|
|
3301
|
-
top: calc(var(--spotpatch-anchor-y) - 7px);
|
|
3302
|
-
right: -6px;
|
|
3303
|
-
border-bottom: 0;
|
|
3304
|
-
border-left: 0;
|
|
3305
|
-
}
|
|
3306
|
-
.spotpatch-dialog[data-placement="right"] .spotpatch-anchor {
|
|
3307
|
-
top: calc(var(--spotpatch-anchor-y) - 7px);
|
|
3308
|
-
left: -6px;
|
|
3309
|
-
border-top: 0;
|
|
3310
|
-
border-right: 0;
|
|
3311
|
-
}
|
|
3312
|
-
.spotpatch-dialog[data-placement="center"] .spotpatch-anchor,
|
|
3313
|
-
.spotpatch-dialog[data-placement="viewport"] .spotpatch-anchor { display: none; }
|
|
3314
3687
|
.spotpatch-shell {
|
|
3315
3688
|
position: relative;
|
|
3316
3689
|
z-index: 1;
|
|
3317
3690
|
display: flex;
|
|
3318
3691
|
box-sizing: border-box;
|
|
3319
|
-
max-height: min(${String(
|
|
3692
|
+
max-height: min(${String(FLOATING_SURFACE_LAYOUT.workbenchMaxHeight)}px, calc(100vh - ${String(FLOATING_SURFACE_LAYOUT.desktopInset * 2)}px));
|
|
3320
3693
|
overflow: hidden;
|
|
3321
3694
|
flex-direction: column;
|
|
3322
|
-
border: 1px solid var(--spotpatch-border);
|
|
3323
|
-
border-radius: var(--spotpatch-radius-panel);
|
|
3324
|
-
background: var(--spotpatch-bg);
|
|
3325
|
-
box-shadow: inset 0 1px rgb(255 255 255 / 5%), 0 0 60px -32px rgb(139 123 255 / 20%);
|
|
3326
|
-
}
|
|
3327
|
-
.spotpatch-shell::before {
|
|
3328
|
-
position: absolute;
|
|
3329
|
-
z-index: 2;
|
|
3330
|
-
top: 0;
|
|
3331
|
-
right: 20%;
|
|
3332
|
-
left: 20%;
|
|
3333
|
-
height: 1px;
|
|
3334
|
-
background: linear-gradient(90deg, transparent, var(--spotpatch-accent), var(--spotpatch-accent-cyan), transparent);
|
|
3335
|
-
content: "";
|
|
3336
|
-
opacity: .65;
|
|
3337
|
-
pointer-events: none;
|
|
3338
3695
|
}
|
|
3339
3696
|
.spotpatch-header {
|
|
3340
3697
|
position: relative;
|
|
3341
3698
|
padding: 0 18px 14px;
|
|
3342
3699
|
}
|
|
3700
|
+
.spotpatch-header[data-spotpatch-drag-handle] { cursor: grab; touch-action: none; user-select: none; }
|
|
3701
|
+
.spotpatch-header[data-dragging="true"] { cursor: grabbing; }
|
|
3702
|
+
.spotpatch-header button,
|
|
3703
|
+
.spotpatch-header a { cursor: pointer; user-select: auto; }
|
|
3343
3704
|
.spotpatch-brand-row {
|
|
3344
3705
|
display: flex;
|
|
3345
3706
|
align-items: center;
|
|
@@ -3363,18 +3724,6 @@ function createStyles(document) {
|
|
|
3363
3724
|
filter: drop-shadow(0 6px 12px rgb(76 29 149 / 22%));
|
|
3364
3725
|
}
|
|
3365
3726
|
.spotpatch-brand-copy { display: grid; min-width: 0; gap: 1px; }
|
|
3366
|
-
.spotpatch-brand-name {
|
|
3367
|
-
color: #fff;
|
|
3368
|
-
font-size: 13.5px;
|
|
3369
|
-
font-weight: 680;
|
|
3370
|
-
letter-spacing: -.01em;
|
|
3371
|
-
}
|
|
3372
|
-
.spotpatch-brand-context {
|
|
3373
|
-
color: #8e98aa;
|
|
3374
|
-
font-size: 10.5px;
|
|
3375
|
-
font-weight: 560;
|
|
3376
|
-
letter-spacing: .02em;
|
|
3377
|
-
}
|
|
3378
3727
|
.spotpatch-header-controls {
|
|
3379
3728
|
display: inline-flex;
|
|
3380
3729
|
align-items: center;
|
|
@@ -3383,6 +3732,7 @@ function createStyles(document) {
|
|
|
3383
3732
|
}
|
|
3384
3733
|
.spotpatch-repository,
|
|
3385
3734
|
.spotpatch-locale,
|
|
3735
|
+
.spotpatch-reset-position,
|
|
3386
3736
|
.spotpatch-close {
|
|
3387
3737
|
height: 27px;
|
|
3388
3738
|
border: 1px solid rgb(255 255 255 / 11%);
|
|
@@ -3406,6 +3756,16 @@ function createStyles(document) {
|
|
|
3406
3756
|
font-size: 12px;
|
|
3407
3757
|
font-weight: 650;
|
|
3408
3758
|
}
|
|
3759
|
+
.spotpatch-reset-position {
|
|
3760
|
+
display: inline-grid;
|
|
3761
|
+
width: 27px;
|
|
3762
|
+
padding: 0;
|
|
3763
|
+
place-items: center;
|
|
3764
|
+
color: #c5cad5;
|
|
3765
|
+
cursor: pointer;
|
|
3766
|
+
font-size: 15px;
|
|
3767
|
+
line-height: 1;
|
|
3768
|
+
}
|
|
3409
3769
|
.spotpatch-close {
|
|
3410
3770
|
display: inline-grid;
|
|
3411
3771
|
width: 27px;
|
|
@@ -3419,21 +3779,8 @@ function createStyles(document) {
|
|
|
3419
3779
|
}
|
|
3420
3780
|
.spotpatch-close:hover,
|
|
3421
3781
|
.spotpatch-locale:hover,
|
|
3782
|
+
.spotpatch-reset-position:hover,
|
|
3422
3783
|
.spotpatch-repository:hover { border-color: rgb(129 112 247 / 45%); color: #fff; background: rgb(109 93 246 / 10%); }
|
|
3423
|
-
.spotpatch-title {
|
|
3424
|
-
margin: 0;
|
|
3425
|
-
color: #fff;
|
|
3426
|
-
font-size: 18px;
|
|
3427
|
-
font-weight: 680;
|
|
3428
|
-
letter-spacing: -.015em;
|
|
3429
|
-
}
|
|
3430
|
-
.spotpatch-subtitle {
|
|
3431
|
-
max-width: 390px;
|
|
3432
|
-
margin: 4px 0 0;
|
|
3433
|
-
color: var(--spotpatch-text-secondary);
|
|
3434
|
-
font-size: 12.5px;
|
|
3435
|
-
line-height: 1.5;
|
|
3436
|
-
}
|
|
3437
3784
|
.spotpatch-target-row {
|
|
3438
3785
|
display: flex;
|
|
3439
3786
|
align-items: center;
|
|
@@ -3797,6 +4144,7 @@ function createStyles(document) {
|
|
|
3797
4144
|
.spotpatch-target-open:focus-visible,
|
|
3798
4145
|
.spotpatch-target-remove:focus-visible,
|
|
3799
4146
|
.spotpatch-close:focus-visible,
|
|
4147
|
+
.spotpatch-reset-position:focus-visible,
|
|
3800
4148
|
.spotpatch-trigger:focus-visible,
|
|
3801
4149
|
.spotpatch-target-select:focus-visible,
|
|
3802
4150
|
.spotpatch-target-editor textarea:focus-visible,
|
|
@@ -3821,8 +4169,8 @@ function createStyles(document) {
|
|
|
3821
4169
|
.spotpatch-diagnostics > summary::before { transition: none; }
|
|
3822
4170
|
}
|
|
3823
4171
|
@media (max-width: 520px) {
|
|
3824
|
-
.spotpatch-dialog {
|
|
3825
|
-
.spotpatch-shell { max-height: calc(
|
|
4172
|
+
.spotpatch-dialog { width: calc(100vw - 16px); }
|
|
4173
|
+
.spotpatch-shell { max-height: calc(100dvh - 16px); }
|
|
3826
4174
|
.spotpatch-header, .spotpatch-body { padding-left: 14px; padding-right: 14px; }
|
|
3827
4175
|
.spotpatch-brand-row { margin-right: -14px; margin-left: -14px; padding-right: 14px; padding-left: 14px; }
|
|
3828
4176
|
.spotpatch-actions { padding-right: 14px; padding-left: 14px; }
|
|
@@ -3838,6 +4186,38 @@ function summaryLine(summary, prefix) {
|
|
|
3838
4186
|
const line = summary.split("\n").find((candidate) => candidate.startsWith(`${prefix}: `));
|
|
3839
4187
|
return line?.slice(prefix.length + 2).trim();
|
|
3840
4188
|
}
|
|
4189
|
+
function startsOnInteractiveControl(event) {
|
|
4190
|
+
const target2 = event.target;
|
|
4191
|
+
return target2 instanceof Element && target2.closest(
|
|
4192
|
+
"a, button, input, select, textarea, summary, [contenteditable='true']"
|
|
4193
|
+
) !== null;
|
|
4194
|
+
}
|
|
4195
|
+
function createFallbackExecutionIsland(document) {
|
|
4196
|
+
const root = createButton(document, "", "spotpatch-execution-island");
|
|
4197
|
+
root.hidden = true;
|
|
4198
|
+
root.setAttribute("aria-hidden", "true");
|
|
4199
|
+
const logo = createBrandMark(
|
|
4200
|
+
document,
|
|
4201
|
+
void 0,
|
|
4202
|
+
"spotpatch-fallback-execution-island"
|
|
4203
|
+
);
|
|
4204
|
+
logo.classList.add("spotpatch-execution-logo");
|
|
4205
|
+
const copy = createMarkedElement(document, "span");
|
|
4206
|
+
root.append(logo, copy);
|
|
4207
|
+
return Object.freeze({
|
|
4208
|
+
canExpand: () => false,
|
|
4209
|
+
isExpanded: () => false,
|
|
4210
|
+
root,
|
|
4211
|
+
setExpanded: () => void 0,
|
|
4212
|
+
render(projection) {
|
|
4213
|
+
const text2 = [projection.headline, projection.action, projection.meta].filter((value) => value.length > 0).join(" \xB7 ");
|
|
4214
|
+
copy.textContent = text2;
|
|
4215
|
+
root.setAttribute("aria-label", text2);
|
|
4216
|
+
},
|
|
4217
|
+
dispose() {
|
|
4218
|
+
}
|
|
4219
|
+
});
|
|
4220
|
+
}
|
|
3841
4221
|
function createUnavailableDataFlowPanel(document, changesRoot, diagnosticsRoot) {
|
|
3842
4222
|
changesRoot.append(diagnosticsRoot);
|
|
3843
4223
|
return Object.freeze({
|
|
@@ -3849,12 +4229,38 @@ function createUnavailableDataFlowPanel(document, changesRoot, diagnosticsRoot)
|
|
|
3849
4229
|
resetView: () => void 0
|
|
3850
4230
|
});
|
|
3851
4231
|
}
|
|
3852
|
-
function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: false }), localePreference = "auto", dataFlowEnabled = false, externalAgentEnabled = false, framework = "vite", sessionId = "") {
|
|
4232
|
+
function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: false }), localePreference = "auto", dataFlowEnabled = false, externalAgentEnabled = false, framework = "vite", sessionId = "", contextualAskEnabled = false) {
|
|
3853
4233
|
const localizer = createUiLocalizer(document, localePreference);
|
|
4234
|
+
const associatedWindow = document.defaultView;
|
|
4235
|
+
if (associatedWindow === null) {
|
|
4236
|
+
throw new Error("SpotPatch requires a document with an associated window.");
|
|
4237
|
+
}
|
|
4238
|
+
const runtimeWindow = associatedWindow;
|
|
4239
|
+
const floatingSurface = createFloatingSurfaceController(
|
|
4240
|
+
runtimeWindow,
|
|
4241
|
+
createFloatingSurfaceSession(runtimeWindow, sessionId),
|
|
4242
|
+
FLOATING_SURFACE_LAYOUT
|
|
4243
|
+
);
|
|
3854
4244
|
let messages = localizer.messages();
|
|
4245
|
+
let currentStatus = "idle";
|
|
4246
|
+
let contextualAskMode = "change";
|
|
4247
|
+
let contextualAskTitle = "";
|
|
4248
|
+
let contextualAskSubtitle = "";
|
|
4249
|
+
let plannerVisible = false;
|
|
4250
|
+
let executionSuppressed = false;
|
|
4251
|
+
let executionProjection;
|
|
4252
|
+
let pendingAgentMotion;
|
|
4253
|
+
let successSettleKey;
|
|
4254
|
+
let settledSuccessKey;
|
|
4255
|
+
let successSettleTimer;
|
|
4256
|
+
let observedExecutionStartedAt;
|
|
3855
4257
|
const host = document.createElement("spotpatch-root");
|
|
3856
4258
|
host.setAttribute(UI_MARKER_ATTRIBUTE, "");
|
|
3857
4259
|
const shadowRoot = host.attachShadow({ mode: "open" });
|
|
4260
|
+
const floatingSurfaceRoot = createMarkedElement(document, "div");
|
|
4261
|
+
floatingSurfaceRoot.className = "spotpatch-floating-surface";
|
|
4262
|
+
floatingSurfaceRoot.dataset.scene = "pill";
|
|
4263
|
+
floatingSurfaceRoot.dataset.tone = "neutral";
|
|
3858
4264
|
const triggerButton = createButton(
|
|
3859
4265
|
document,
|
|
3860
4266
|
messages.trigger.select,
|
|
@@ -3862,6 +4268,10 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3862
4268
|
);
|
|
3863
4269
|
triggerButton.title = messages.trigger.title(shortcut);
|
|
3864
4270
|
triggerButton.setAttribute("aria-pressed", "false");
|
|
4271
|
+
const motionExtension = getFloatingSurfaceMotionExtension();
|
|
4272
|
+
const motionExecutionIsland = motionExtension?.createExecutionIsland(document);
|
|
4273
|
+
const executionIslandView = motionExecutionIsland ?? createFallbackExecutionIsland(document);
|
|
4274
|
+
const executionIsland = executionIslandView.root;
|
|
3865
4275
|
const highlight = createMarkedElement(document, "div");
|
|
3866
4276
|
highlight.className = "spotpatch-highlight";
|
|
3867
4277
|
highlight.hidden = true;
|
|
@@ -3875,16 +4285,13 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3875
4285
|
dialog.className = "spotpatch-dialog";
|
|
3876
4286
|
dialog.hidden = true;
|
|
3877
4287
|
dialog.tabIndex = -1;
|
|
3878
|
-
dialog.dataset.placement = "viewport";
|
|
3879
4288
|
dialog.setAttribute("role", "dialog");
|
|
3880
4289
|
dialog.setAttribute("aria-labelledby", "spotpatch-selection-title");
|
|
3881
|
-
const anchor = createMarkedElement(document, "span");
|
|
3882
|
-
anchor.className = "spotpatch-anchor";
|
|
3883
|
-
anchor.setAttribute("aria-hidden", "true");
|
|
3884
4290
|
const shell = createMarkedElement(document, "div");
|
|
3885
4291
|
shell.className = "spotpatch-shell";
|
|
3886
4292
|
const header = createMarkedElement(document, "header");
|
|
3887
4293
|
header.className = "spotpatch-header";
|
|
4294
|
+
header.setAttribute("data-spotpatch-drag-handle", "");
|
|
3888
4295
|
const brandRow = createMarkedElement(document, "div");
|
|
3889
4296
|
brandRow.className = "spotpatch-brand-row";
|
|
3890
4297
|
const brand = createMarkedElement(document, "div");
|
|
@@ -3905,8 +4312,9 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3905
4312
|
repositoryLink.target = "_blank";
|
|
3906
4313
|
repositoryLink.rel = "noopener noreferrer";
|
|
3907
4314
|
const localeButton = createButton(document, "", "spotpatch-locale");
|
|
4315
|
+
const resetPositionButton = createButton(document, "\u2316", "spotpatch-reset-position");
|
|
3908
4316
|
const closeButton = createButton(document, "\xD7", "spotpatch-close");
|
|
3909
|
-
headerControls.append(repositoryLink, localeButton, closeButton);
|
|
4317
|
+
headerControls.append(repositoryLink, localeButton, resetPositionButton, closeButton);
|
|
3910
4318
|
brandRow.append(brand, headerControls);
|
|
3911
4319
|
const title = createMarkedElement(document, "h2");
|
|
3912
4320
|
title.id = "spotpatch-selection-title";
|
|
@@ -3966,13 +4374,20 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3966
4374
|
diagnostics.append(diagnosticsLabel, summary);
|
|
3967
4375
|
const agentPanel = createAgentPanel(document, ai, localizer);
|
|
3968
4376
|
const changesPanel = createMarkedElement(document, "div");
|
|
4377
|
+
function requestFloatingSurfaceLayout() {
|
|
4378
|
+
if (plannerVisible) {
|
|
4379
|
+
floatingSurface.requestReconcile();
|
|
4380
|
+
}
|
|
4381
|
+
}
|
|
3969
4382
|
const externalHandoffPanel = externalAgentEnabled ? getExternalHandoffExtension()?.createPanel(
|
|
3970
4383
|
document,
|
|
3971
4384
|
framework,
|
|
3972
4385
|
localizer.locale,
|
|
3973
4386
|
sessionId,
|
|
3974
4387
|
localizer.subscribe,
|
|
3975
|
-
|
|
4388
|
+
requestFloatingSurfaceLayout,
|
|
4389
|
+
renderExternalDispatch,
|
|
4390
|
+
renderExternalControl
|
|
3976
4391
|
) : void 0;
|
|
3977
4392
|
changesPanel.append(
|
|
3978
4393
|
targetsPanel,
|
|
@@ -3985,7 +4400,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3985
4400
|
localizer.locale,
|
|
3986
4401
|
changesPanel,
|
|
3987
4402
|
diagnostics,
|
|
3988
|
-
|
|
4403
|
+
requestFloatingSurfaceLayout
|
|
3989
4404
|
) ?? createUnavailableDataFlowPanel(document, changesPanel, diagnostics);
|
|
3990
4405
|
selectionPanel.append(dataFlowPanel.root);
|
|
3991
4406
|
const previewPanel = createMarkedElement(document, "div");
|
|
@@ -4040,15 +4455,40 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4040
4455
|
backButton
|
|
4041
4456
|
);
|
|
4042
4457
|
actions.append(editorFeedback, secondaryActions, primaryActions);
|
|
4458
|
+
const contextualAskPanel = contextualAskEnabled ? getContextualAskExtension()?.createPanel({
|
|
4459
|
+
document,
|
|
4460
|
+
locale: localizer.locale,
|
|
4461
|
+
subscribeLocale: localizer.subscribe,
|
|
4462
|
+
changeRoot: dataFlowPanel.root,
|
|
4463
|
+
changeActions: actions,
|
|
4464
|
+
announce,
|
|
4465
|
+
onModeChange(mode, askTitle, askSubtitle) {
|
|
4466
|
+
contextualAskMode = mode;
|
|
4467
|
+
contextualAskTitle = askTitle;
|
|
4468
|
+
contextualAskSubtitle = askSubtitle;
|
|
4469
|
+
if (host.isConnected) renderPanelStatus(currentStatus);
|
|
4470
|
+
},
|
|
4471
|
+
onExecutionChange(projection) {
|
|
4472
|
+
executionProjection = projection;
|
|
4473
|
+
executionSuppressed = false;
|
|
4474
|
+
renderFloatingSurfaceMotion();
|
|
4475
|
+
},
|
|
4476
|
+
onViewChange: requestFloatingSurfaceLayout
|
|
4477
|
+
}) : void 0;
|
|
4478
|
+
if (contextualAskPanel !== void 0) {
|
|
4479
|
+
selectionPanel.prepend(contextualAskPanel.root);
|
|
4480
|
+
}
|
|
4043
4481
|
shell.append(header, body, actions);
|
|
4044
|
-
dialog.append(
|
|
4482
|
+
dialog.append(shell);
|
|
4045
4483
|
const liveRegion = createMarkedElement(document, "div");
|
|
4046
4484
|
liveRegion.className = "spotpatch-live";
|
|
4047
4485
|
liveRegion.setAttribute("aria-live", "polite");
|
|
4048
4486
|
liveRegion.setAttribute("aria-atomic", "true");
|
|
4049
4487
|
const styles2 = [
|
|
4050
4488
|
createStyles(document),
|
|
4489
|
+
...motionExtension === void 0 ? [] : [motionExtension.createStyles(document)],
|
|
4051
4490
|
dataFlowPanel.styles,
|
|
4491
|
+
...contextualAskPanel === void 0 ? [] : [contextualAskPanel.styles],
|
|
4052
4492
|
...externalHandoffPanel === void 0 ? [] : [externalHandoffPanel.styles]
|
|
4053
4493
|
];
|
|
4054
4494
|
const styleNonce = resolveStyleNonce(document);
|
|
@@ -4061,14 +4501,38 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4061
4501
|
...styles2,
|
|
4062
4502
|
selectionHighlights,
|
|
4063
4503
|
highlight,
|
|
4064
|
-
|
|
4065
|
-
triggerButton,
|
|
4504
|
+
floatingSurfaceRoot,
|
|
4066
4505
|
liveRegion
|
|
4067
4506
|
);
|
|
4507
|
+
floatingSurfaceRoot.append(triggerButton, dialog, executionIsland);
|
|
4068
4508
|
document.documentElement.append(host);
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4509
|
+
floatingSurface.registerSurface(floatingSurfaceRoot);
|
|
4510
|
+
const motionController = motionExtension === void 0 || motionExecutionIsland === void 0 ? void 0 : motionExtension.createController(
|
|
4511
|
+
document,
|
|
4512
|
+
Object.freeze({
|
|
4513
|
+
execution: motionExecutionIsland.elements,
|
|
4514
|
+
pill: triggerButton,
|
|
4515
|
+
planner: dialog,
|
|
4516
|
+
surface: floatingSurfaceRoot
|
|
4517
|
+
}),
|
|
4518
|
+
floatingSurface.reconcile
|
|
4519
|
+
);
|
|
4520
|
+
const cancelMotionOnDrag = () => {
|
|
4521
|
+
motionController?.cancel();
|
|
4522
|
+
};
|
|
4523
|
+
floatingSurface.attachDraggable(triggerButton, floatingSurfaceRoot, {
|
|
4524
|
+
onDragStart: cancelMotionOnDrag,
|
|
4525
|
+
suppressClickOnDrag: true
|
|
4526
|
+
});
|
|
4527
|
+
floatingSurface.attachDraggable(header, floatingSurfaceRoot, {
|
|
4528
|
+
canStartDrag: (event) => !floatingSurface.isCompact() && !startsOnInteractiveControl(event),
|
|
4529
|
+
onDragStart: cancelMotionOnDrag
|
|
4530
|
+
});
|
|
4531
|
+
floatingSurface.attachDraggable(executionIsland, floatingSurfaceRoot, {
|
|
4532
|
+
onDragStart: cancelMotionOnDrag,
|
|
4533
|
+
suppressClickOnDrag: true
|
|
4534
|
+
});
|
|
4535
|
+
floatingSurface.reconcile();
|
|
4072
4536
|
let currentCanOpenEditor = false;
|
|
4073
4537
|
let currentCanPreview = false;
|
|
4074
4538
|
let currentSummaryText = "";
|
|
@@ -4083,12 +4547,274 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4083
4547
|
page: Object.freeze({ status: dataFlowEnabled ? "idle" : "disabled" }),
|
|
4084
4548
|
observationCount: 0
|
|
4085
4549
|
});
|
|
4550
|
+
function currentTargetSummary() {
|
|
4551
|
+
const target2 = currentTargets.find((candidate) => candidate.active);
|
|
4552
|
+
return target2 === void 0 ? Object.freeze({
|
|
4553
|
+
label: messages.context.selectedElement,
|
|
4554
|
+
source: ""
|
|
4555
|
+
}) : Object.freeze({ label: target2.label, source: target2.source });
|
|
4556
|
+
}
|
|
4557
|
+
function currentTargetContext() {
|
|
4558
|
+
const target2 = currentTargetSummary();
|
|
4559
|
+
return target2.source.length === 0 ? target2.label : `${target2.label} \xB7 ${target2.source}`;
|
|
4560
|
+
}
|
|
4561
|
+
function beginObservedExecution() {
|
|
4562
|
+
observedExecutionStartedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4563
|
+
return observedExecutionStartedAt;
|
|
4564
|
+
}
|
|
4565
|
+
function observedExecutionStart() {
|
|
4566
|
+
return observedExecutionStartedAt ?? beginObservedExecution();
|
|
4567
|
+
}
|
|
4568
|
+
function clearSuccessSettle(resetKeys) {
|
|
4569
|
+
if (successSettleTimer !== void 0) {
|
|
4570
|
+
runtimeWindow.clearTimeout(successSettleTimer);
|
|
4571
|
+
successSettleTimer = void 0;
|
|
4572
|
+
}
|
|
4573
|
+
if (resetKeys) {
|
|
4574
|
+
successSettleKey = void 0;
|
|
4575
|
+
settledSuccessKey = void 0;
|
|
4576
|
+
}
|
|
4577
|
+
}
|
|
4578
|
+
function showSuccessUntilSettled(key) {
|
|
4579
|
+
if (settledSuccessKey === key) return false;
|
|
4580
|
+
if (successSettleKey === key) return true;
|
|
4581
|
+
clearSuccessSettle(false);
|
|
4582
|
+
successSettleKey = key;
|
|
4583
|
+
successSettleTimer = runtimeWindow.setTimeout(() => {
|
|
4584
|
+
successSettleTimer = void 0;
|
|
4585
|
+
if (!host.isConnected) return;
|
|
4586
|
+
settledSuccessKey = key;
|
|
4587
|
+
executionProjection = void 0;
|
|
4588
|
+
observedExecutionStartedAt = void 0;
|
|
4589
|
+
executionSuppressed = false;
|
|
4590
|
+
plannerVisible = false;
|
|
4591
|
+
renderFloatingSurfaceMotion();
|
|
4592
|
+
}, SUCCESS_SETTLE_MS);
|
|
4593
|
+
return true;
|
|
4594
|
+
}
|
|
4595
|
+
function externalAgentIdentity(kind) {
|
|
4596
|
+
return kind.startsWith("claude") ? messages.execution.claude : kind.startsWith("codex") ? messages.execution.codex : kind;
|
|
4597
|
+
}
|
|
4598
|
+
function projectAgentActivity(item) {
|
|
4599
|
+
return Object.freeze({
|
|
4600
|
+
...item.detail === void 0 ? {} : { detail: item.detail },
|
|
4601
|
+
key: item.key,
|
|
4602
|
+
kind: item.kind,
|
|
4603
|
+
label: messages.execution.activityLane(item.kind, item.detail),
|
|
4604
|
+
state: item.state
|
|
4605
|
+
});
|
|
4606
|
+
}
|
|
4607
|
+
function motionActivity(key, kind, detail, state = "active") {
|
|
4608
|
+
return Object.freeze({
|
|
4609
|
+
...detail === void 0 ? {} : { detail },
|
|
4610
|
+
key,
|
|
4611
|
+
kind,
|
|
4612
|
+
label: messages.execution.activityLane(kind, detail),
|
|
4613
|
+
state
|
|
4614
|
+
});
|
|
4615
|
+
}
|
|
4616
|
+
function renderFloatingSurfaceMotion() {
|
|
4617
|
+
const capturing = currentStatus === "inspecting";
|
|
4618
|
+
const pillActive = !plannerVisible || capturing;
|
|
4619
|
+
const projection = pillActive ? {
|
|
4620
|
+
scene: capturing ? "capturing" : "pill",
|
|
4621
|
+
tone: capturing ? "capturing" : "neutral",
|
|
4622
|
+
headline: triggerButton.textContent,
|
|
4623
|
+
action: "",
|
|
4624
|
+
meta: "",
|
|
4625
|
+
recentActivities: Object.freeze([])
|
|
4626
|
+
} : !executionSuppressed && executionProjection !== void 0 ? executionProjection : {
|
|
4627
|
+
scene: "planner",
|
|
4628
|
+
tone: "ready",
|
|
4629
|
+
headline: messages.dialog.editTitle,
|
|
4630
|
+
action: messages.dialog.editSubtitle,
|
|
4631
|
+
meta: messages.context.ready,
|
|
4632
|
+
recentActivities: Object.freeze([])
|
|
4633
|
+
};
|
|
4634
|
+
if (motionController !== void 0) {
|
|
4635
|
+
motionController.render(projection, () => {
|
|
4636
|
+
executionIslandView.render(projection);
|
|
4637
|
+
});
|
|
4638
|
+
return;
|
|
4639
|
+
}
|
|
4640
|
+
executionIslandView.render(projection);
|
|
4641
|
+
floatingSurfaceRoot.dataset.scene = projection.scene;
|
|
4642
|
+
floatingSurfaceRoot.dataset.tone = projection.tone;
|
|
4643
|
+
const plannerActive = projection.scene === "planner";
|
|
4644
|
+
triggerButton.hidden = !pillActive;
|
|
4645
|
+
triggerButton.inert = !pillActive;
|
|
4646
|
+
dialog.hidden = !plannerActive;
|
|
4647
|
+
dialog.inert = !plannerActive;
|
|
4648
|
+
dialog.setAttribute("aria-hidden", String(!plannerActive));
|
|
4649
|
+
executionIsland.hidden = pillActive || plannerActive;
|
|
4650
|
+
executionIsland.inert = pillActive || plannerActive;
|
|
4651
|
+
executionIsland.setAttribute("aria-hidden", String(pillActive || plannerActive));
|
|
4652
|
+
floatingSurface.reconcile();
|
|
4653
|
+
}
|
|
4654
|
+
function renderExternalDispatch(dispatch) {
|
|
4655
|
+
if (dispatch === null) {
|
|
4656
|
+
pendingAgentMotion = void 0;
|
|
4657
|
+
observedExecutionStartedAt = void 0;
|
|
4658
|
+
} else if (pendingAgentMotion !== void 0 && dispatch.phase !== "failed" && dispatch.phase !== "delivery-unknown") {
|
|
4659
|
+
startStagedAgentRequest();
|
|
4660
|
+
} else if (dispatch.phase === "failed" || dispatch.phase === "delivery-unknown") {
|
|
4661
|
+
pendingAgentMotion = void 0;
|
|
4662
|
+
}
|
|
4663
|
+
if (dispatch !== null && !executionSuppressed) {
|
|
4664
|
+
const failed = dispatch.phase === "failed" || dispatch.phase === "delivery-unknown";
|
|
4665
|
+
const completed = dispatch.phase === "completed";
|
|
4666
|
+
const startedAt = failed || completed ? void 0 : observedExecutionStart();
|
|
4667
|
+
if (failed || completed) observedExecutionStartedAt = void 0;
|
|
4668
|
+
const successKey = `dispatch:${String(dispatch.revision)}`;
|
|
4669
|
+
if (completed && !showSuccessUntilSettled(successKey)) {
|
|
4670
|
+
executionProjection = void 0;
|
|
4671
|
+
renderFloatingSurfaceMotion();
|
|
4672
|
+
return;
|
|
4673
|
+
}
|
|
4674
|
+
const identity = externalAgentIdentity(dispatch.adapterKind);
|
|
4675
|
+
const target2 = currentTargetSummary();
|
|
4676
|
+
const activityKind = dispatch.phase === "queued" || dispatch.phase === "dispatching" || dispatch.phase === "dispatched" ? "dispatch" : completed ? "sync" : "unknown";
|
|
4677
|
+
const activity = motionActivity(
|
|
4678
|
+
`dispatch:${String(dispatch.revision)}:${dispatch.phase}`,
|
|
4679
|
+
activityKind,
|
|
4680
|
+
dispatch.phase,
|
|
4681
|
+
failed ? "failure" : completed ? "success" : "active"
|
|
4682
|
+
);
|
|
4683
|
+
const scene = failed ? "failed" : completed ? "success" : dispatch.phase === "working" ? "running" : "handoff";
|
|
4684
|
+
executionProjection = {
|
|
4685
|
+
scene,
|
|
4686
|
+
tone: failed ? "danger" : completed ? "success" : "running",
|
|
4687
|
+
headline: completed ? messages.execution.completedTitle : failed ? messages.execution.failedTitle : scene === "running" ? messages.execution.runningTitle(target2.label) : messages.execution.dispatchingTitle(identity),
|
|
4688
|
+
action: completed ? messages.execution.resultReturned : target2.source,
|
|
4689
|
+
expandedHeadline: completed ? messages.execution.expandedCompletedTitle : failed ? messages.execution.failedTitle : scene === "running" ? messages.execution.expandedRunningTitle(identity) : messages.execution.dispatchingTitle(identity),
|
|
4690
|
+
expandedAction: completed ? messages.execution.resultReturned : currentTargetContext(),
|
|
4691
|
+
meta: failed ? messages.execution.failedStatus : completed ? messages.execution.completedStatus : scene === "running" ? messages.execution.runningStatus : messages.execution.dispatchingStatus,
|
|
4692
|
+
activity,
|
|
4693
|
+
recentActivities: Object.freeze([activity]),
|
|
4694
|
+
...startedAt === void 0 ? {} : { startedAt }
|
|
4695
|
+
};
|
|
4696
|
+
} else if (dispatch === null) {
|
|
4697
|
+
executionProjection = void 0;
|
|
4698
|
+
}
|
|
4699
|
+
renderFloatingSurfaceMotion();
|
|
4700
|
+
}
|
|
4701
|
+
function renderExternalControl(status) {
|
|
4702
|
+
const task = status?.task;
|
|
4703
|
+
if (status === void 0 || task === void 0 || executionSuppressed) return;
|
|
4704
|
+
const phase = task.managedPhase;
|
|
4705
|
+
const failed = phase === "failed" || phase === "cleanup-warning";
|
|
4706
|
+
const completed = phase === "completed" || phase === "review-required";
|
|
4707
|
+
const cancelled = phase === "cancelled";
|
|
4708
|
+
if (failed || cancelled) {
|
|
4709
|
+
pendingAgentMotion = void 0;
|
|
4710
|
+
} else if (pendingAgentMotion !== void 0) {
|
|
4711
|
+
startStagedAgentRequest();
|
|
4712
|
+
}
|
|
4713
|
+
if (cancelled) {
|
|
4714
|
+
executionProjection = void 0;
|
|
4715
|
+
observedExecutionStartedAt = void 0;
|
|
4716
|
+
renderFloatingSurfaceMotion();
|
|
4717
|
+
return;
|
|
4718
|
+
}
|
|
4719
|
+
const startedAt = failed || completed ? void 0 : observedExecutionStart();
|
|
4720
|
+
if (failed || completed) observedExecutionStartedAt = void 0;
|
|
4721
|
+
if (phase === "completed" && !showSuccessUntilSettled(`managed:${String(task.revision)}`)) {
|
|
4722
|
+
executionProjection = void 0;
|
|
4723
|
+
renderFloatingSurfaceMotion();
|
|
4724
|
+
return;
|
|
4725
|
+
}
|
|
4726
|
+
const scene = failed ? "failed" : completed ? "success" : phase === "preparing" ? "handoff" : "running";
|
|
4727
|
+
const tone = failed ? "danger" : completed ? "success" : "running";
|
|
4728
|
+
const identity = messages.execution.codex;
|
|
4729
|
+
const target2 = currentTargetSummary();
|
|
4730
|
+
const activityKind = phase === "preparing" ? "prepare" : phase === "auditing" ? "audit" : phase === "validating" ? "check" : phase === "applying" ? "apply" : completed ? "sync" : "unknown";
|
|
4731
|
+
const latestCheck = task.checks.at(-1);
|
|
4732
|
+
const latestFile = task.files.at(-1);
|
|
4733
|
+
const activityDetail = phase === "validating" ? latestCheck?.id : phase === "auditing" || phase === "applying" ? latestFile?.path : void 0;
|
|
4734
|
+
const activity = motionActivity(
|
|
4735
|
+
`managed:${String(task.revision)}:${phase}:${activityDetail ?? ""}`,
|
|
4736
|
+
activityKind,
|
|
4737
|
+
activityDetail,
|
|
4738
|
+
failed ? "failure" : completed ? "success" : "active"
|
|
4739
|
+
);
|
|
4740
|
+
const recentActivities = Object.freeze([
|
|
4741
|
+
...task.files.slice(-2).map(
|
|
4742
|
+
(file) => motionActivity(
|
|
4743
|
+
`managed-file:${String(task.revision)}:${file.path}`,
|
|
4744
|
+
"patch",
|
|
4745
|
+
file.path,
|
|
4746
|
+
"success"
|
|
4747
|
+
)
|
|
4748
|
+
),
|
|
4749
|
+
...task.checks.slice(-2).map(
|
|
4750
|
+
(check) => motionActivity(
|
|
4751
|
+
`managed-check:${String(task.revision)}:${check.id}`,
|
|
4752
|
+
"check",
|
|
4753
|
+
check.id,
|
|
4754
|
+
check.outcome === "passed" ? "success" : "failure"
|
|
4755
|
+
)
|
|
4756
|
+
),
|
|
4757
|
+
activity
|
|
4758
|
+
]);
|
|
4759
|
+
executionProjection = {
|
|
4760
|
+
scene,
|
|
4761
|
+
tone,
|
|
4762
|
+
headline: completed ? messages.execution.completedTitle : failed ? messages.execution.failedTitle : scene === "handoff" ? messages.execution.dispatchingTitle(identity) : phase === "validating" ? messages.execution.activityAction("check", activityDetail) : messages.execution.runningTitle(target2.label),
|
|
4763
|
+
action: completed ? task.files.length === 0 ? messages.execution.resultReturned : messages.execution.resultSummary(task.files.length) : target2.source,
|
|
4764
|
+
expandedHeadline: completed ? messages.execution.expandedCompletedTitle : failed ? messages.execution.failedTitle : scene === "handoff" ? messages.execution.dispatchingTitle(identity) : messages.execution.expandedRunningTitle(identity),
|
|
4765
|
+
expandedAction: completed ? messages.execution.resultReturned : currentTargetContext(),
|
|
4766
|
+
meta: failed ? messages.execution.failedStatus : completed ? messages.execution.completedStatus : phase === "validating" ? messages.execution.checkingStatus : scene === "handoff" ? messages.execution.dispatchingStatus : messages.execution.runningStatus,
|
|
4767
|
+
activity,
|
|
4768
|
+
recentActivities,
|
|
4769
|
+
...startedAt === void 0 ? {} : { startedAt }
|
|
4770
|
+
};
|
|
4771
|
+
renderFloatingSurfaceMotion();
|
|
4772
|
+
}
|
|
4773
|
+
function beginAgentRequest(target2, agentCard) {
|
|
4774
|
+
if (!plannerVisible) {
|
|
4775
|
+
return;
|
|
4776
|
+
}
|
|
4777
|
+
clearSuccessSettle(true);
|
|
4778
|
+
const startedAt = beginObservedExecution();
|
|
4779
|
+
executionSuppressed = false;
|
|
4780
|
+
const activity = motionActivity(
|
|
4781
|
+
`dispatch-start:${currentTargetContext()}`,
|
|
4782
|
+
"dispatch",
|
|
4783
|
+
currentTargetContext()
|
|
4784
|
+
);
|
|
4785
|
+
executionProjection = {
|
|
4786
|
+
scene: "agent-charging",
|
|
4787
|
+
tone: "running",
|
|
4788
|
+
headline: messages.execution.receivingTitle,
|
|
4789
|
+
action: currentTargetContext(),
|
|
4790
|
+
expandedHeadline: messages.execution.receivingTitle,
|
|
4791
|
+
expandedAction: currentTargetContext(),
|
|
4792
|
+
meta: messages.execution.receivingStatus,
|
|
4793
|
+
activity,
|
|
4794
|
+
recentActivities: Object.freeze([activity]),
|
|
4795
|
+
startedAt
|
|
4796
|
+
};
|
|
4797
|
+
renderFloatingSurfaceMotion();
|
|
4798
|
+
motionController?.dispatch(target2, agentCard);
|
|
4799
|
+
}
|
|
4800
|
+
function stageAgentRequest(source2, target2) {
|
|
4801
|
+
if (!plannerVisible || source2.disabled) return;
|
|
4802
|
+
pendingAgentMotion = Object.freeze({ source: source2, target: target2 });
|
|
4803
|
+
}
|
|
4804
|
+
function startStagedAgentRequest() {
|
|
4805
|
+
const pending = pendingAgentMotion;
|
|
4806
|
+
pendingAgentMotion = void 0;
|
|
4807
|
+
if (pending === void 0 || !pending.source.isConnected || !pending.target.isConnected) {
|
|
4808
|
+
return;
|
|
4809
|
+
}
|
|
4810
|
+
beginAgentRequest(pending.source, pending.target);
|
|
4811
|
+
}
|
|
4086
4812
|
function renderEditorStatus(state) {
|
|
4087
4813
|
currentEditorFeedbackState = state;
|
|
4088
4814
|
editorFeedback.dataset.state = state;
|
|
4089
4815
|
editorFeedback.hidden = state === "idle";
|
|
4090
4816
|
editorFeedback.textContent = state === "opening" ? messages.announcements.editorOpening : state === "success" ? messages.announcements.editorOpened : state === "error" ? messages.announcements.editorFailed : "";
|
|
4091
|
-
|
|
4817
|
+
requestFloatingSurfaceLayout();
|
|
4092
4818
|
}
|
|
4093
4819
|
function statusText(target2) {
|
|
4094
4820
|
if (target2.status === "ready") {
|
|
@@ -4223,6 +4949,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4223
4949
|
replacement?.setSelectionRange(selectionStart, selectionEnd);
|
|
4224
4950
|
}
|
|
4225
4951
|
}
|
|
4952
|
+
requestFloatingSurfaceLayout();
|
|
4226
4953
|
}
|
|
4227
4954
|
function updateTargetInstruction(targetId, instruction) {
|
|
4228
4955
|
currentTargets = currentTargets.map(
|
|
@@ -4271,8 +4998,6 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4271
4998
|
}
|
|
4272
4999
|
function showSelectionHighlights(targets) {
|
|
4273
5000
|
selectionHighlights.replaceChildren();
|
|
4274
|
-
activeSelectionRect = targets.find((target2) => target2.active)?.rect;
|
|
4275
|
-
currentRect = activeSelectionRect;
|
|
4276
5001
|
for (const [index, target2] of targets.entries()) {
|
|
4277
5002
|
const box = createMarkedElement(document, "div");
|
|
4278
5003
|
box.className = "spotpatch-selection-highlight";
|
|
@@ -4286,31 +5011,6 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4286
5011
|
box.append(label);
|
|
4287
5012
|
selectionHighlights.append(box);
|
|
4288
5013
|
}
|
|
4289
|
-
placeDialog();
|
|
4290
|
-
}
|
|
4291
|
-
function placeDialog() {
|
|
4292
|
-
if (dialog.hidden) {
|
|
4293
|
-
return;
|
|
4294
|
-
}
|
|
4295
|
-
const view = document.defaultView;
|
|
4296
|
-
const viewportWidth = view?.innerWidth ?? document.documentElement.clientWidth;
|
|
4297
|
-
const viewportHeight = view?.innerHeight ?? document.documentElement.clientHeight;
|
|
4298
|
-
const measured = dialog.getBoundingClientRect();
|
|
4299
|
-
const status = currentStatus === "previewing" ? "previewing" : "selected";
|
|
4300
|
-
const dialogWidth = measured.width > 0 ? measured.width : Math.min(DIALOG_MAX_WIDTH, viewportWidth - 32);
|
|
4301
|
-
const dialogHeight = measured.height > 0 ? measured.height : Math.min(DIALOG_FALLBACK_HEIGHT[status], viewportHeight - 32);
|
|
4302
|
-
const placement = calculateDialogPlacement({
|
|
4303
|
-
dialogWidth,
|
|
4304
|
-
dialogHeight,
|
|
4305
|
-
viewportWidth,
|
|
4306
|
-
viewportHeight,
|
|
4307
|
-
...currentRect === void 0 ? {} : { target: currentRect }
|
|
4308
|
-
});
|
|
4309
|
-
dialog.style.left = `${String(placement.left)}px`;
|
|
4310
|
-
dialog.style.top = `${String(placement.top)}px`;
|
|
4311
|
-
dialog.style.setProperty("--spotpatch-anchor-x", `${String(placement.anchorX)}px`);
|
|
4312
|
-
dialog.style.setProperty("--spotpatch-anchor-y", `${String(placement.anchorY)}px`);
|
|
4313
|
-
dialog.dataset.placement = placement.mode;
|
|
4314
5014
|
}
|
|
4315
5015
|
function updateContextOverview(summaryText) {
|
|
4316
5016
|
const summaryMessages = messages.summary;
|
|
@@ -4341,14 +5041,18 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4341
5041
|
previewButton.disabled = !canPreview;
|
|
4342
5042
|
agentPanel.setContextReady(canPreview);
|
|
4343
5043
|
externalHandoffPanel?.setContextReady(canPreview);
|
|
5044
|
+
contextualAskPanel?.setSelectionPreview({
|
|
5045
|
+
contextReady: currentTargets.every((target2) => target2.status !== "loading"),
|
|
5046
|
+
targetCount: currentTargets.length,
|
|
5047
|
+
sourceCount: currentTargets.filter((target2) => target2.canOpenEditor).length
|
|
5048
|
+
});
|
|
4344
5049
|
updateContextOverview(summaryText);
|
|
4345
|
-
|
|
5050
|
+
requestFloatingSurfaceLayout();
|
|
4346
5051
|
}
|
|
4347
5052
|
function renderPanelStatus(status) {
|
|
4348
5053
|
currentStatus = status;
|
|
4349
5054
|
const selected = status === "selected";
|
|
4350
5055
|
const previewing = status === "previewing";
|
|
4351
|
-
triggerButton.hidden = selected || previewing;
|
|
4352
5056
|
selectionPanel.hidden = !selected;
|
|
4353
5057
|
previewPanel.hidden = !previewing;
|
|
4354
5058
|
reselectButton.hidden = !selected;
|
|
@@ -4358,11 +5062,12 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4358
5062
|
secondaryActions.hidden = !selected;
|
|
4359
5063
|
agentPanel.setSelectionVisible(selected);
|
|
4360
5064
|
externalHandoffPanel?.setSelectionVisible(selected);
|
|
5065
|
+
contextualAskPanel?.setSelectionVisible(selected);
|
|
4361
5066
|
copyButton.hidden = !previewing;
|
|
4362
5067
|
backButton.hidden = !previewing;
|
|
4363
|
-
title.textContent = previewing ? messages.dialog.previewTitle : messages.dialog.editTitle;
|
|
4364
|
-
subtitle.textContent = previewing ? messages.dialog.previewSubtitle : messages.dialog.editSubtitle;
|
|
4365
|
-
|
|
5068
|
+
title.textContent = previewing ? messages.dialog.previewTitle : contextualAskMode === "ask" && contextualAskTitle.length > 0 ? contextualAskTitle : messages.dialog.editTitle;
|
|
5069
|
+
subtitle.textContent = previewing ? messages.dialog.previewSubtitle : contextualAskMode === "ask" && contextualAskSubtitle.length > 0 ? contextualAskSubtitle : messages.dialog.editSubtitle;
|
|
5070
|
+
renderFloatingSurfaceMotion();
|
|
4366
5071
|
}
|
|
4367
5072
|
function applyMessages() {
|
|
4368
5073
|
messages = localizer.messages();
|
|
@@ -4374,8 +5079,14 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4374
5079
|
localeButton.textContent = messages.alternateLocaleName;
|
|
4375
5080
|
localeButton.title = messages.switchLocale;
|
|
4376
5081
|
localeButton.setAttribute("aria-label", messages.switchLocale);
|
|
5082
|
+
resetPositionButton.title = messages.floatingSurface.resetPosition;
|
|
5083
|
+
resetPositionButton.setAttribute(
|
|
5084
|
+
"aria-label",
|
|
5085
|
+
messages.floatingSurface.resetPosition
|
|
5086
|
+
);
|
|
4377
5087
|
closeButton.setAttribute("aria-label", messages.dialog.close);
|
|
4378
5088
|
closeButton.title = messages.dialog.close;
|
|
5089
|
+
header.title = messages.floatingSurface.dragHandle;
|
|
4379
5090
|
targetsPanel.setAttribute("aria-label", messages.targets.ariaLabel);
|
|
4380
5091
|
targetsTitle.textContent = messages.targets.title;
|
|
4381
5092
|
diagnosticsTitle.textContent = messages.diagnostics.title;
|
|
@@ -4411,8 +5122,58 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4411
5122
|
contextState.textContent = messages.context.collecting;
|
|
4412
5123
|
}
|
|
4413
5124
|
}
|
|
4414
|
-
|
|
5125
|
+
function announce(message) {
|
|
5126
|
+
liveRegion.textContent = "";
|
|
5127
|
+
liveRegion.textContent = message;
|
|
5128
|
+
}
|
|
5129
|
+
function resetFloatingSurfacePosition() {
|
|
5130
|
+
floatingSurface.reset();
|
|
5131
|
+
announce(messages.floatingSurface.positionReset);
|
|
5132
|
+
}
|
|
5133
|
+
diagnostics.addEventListener("toggle", requestFloatingSurfaceLayout);
|
|
4415
5134
|
localeButton.addEventListener("click", localizer.toggle);
|
|
5135
|
+
resetPositionButton.addEventListener("click", resetFloatingSurfacePosition);
|
|
5136
|
+
const onAgentRun = () => {
|
|
5137
|
+
stageAgentRequest(agentPanel.runButton, agentPanel.root);
|
|
5138
|
+
};
|
|
5139
|
+
const onExternalSend = () => {
|
|
5140
|
+
if (externalHandoffPanel !== void 0) {
|
|
5141
|
+
stageAgentRequest(externalHandoffPanel.sendButton, externalHandoffPanel.root);
|
|
5142
|
+
}
|
|
5143
|
+
};
|
|
5144
|
+
const onExecutionOpen = () => {
|
|
5145
|
+
if (executionIslandView.canExpand() && !executionIslandView.isExpanded()) {
|
|
5146
|
+
if (motionController === void 0) {
|
|
5147
|
+
executionIslandView.setExpanded(true);
|
|
5148
|
+
floatingSurface.reconcile();
|
|
5149
|
+
} else {
|
|
5150
|
+
motionController.updateLayout(() => {
|
|
5151
|
+
executionIslandView.setExpanded(true);
|
|
5152
|
+
});
|
|
5153
|
+
}
|
|
5154
|
+
return;
|
|
5155
|
+
}
|
|
5156
|
+
clearSuccessSettle(false);
|
|
5157
|
+
executionSuppressed = true;
|
|
5158
|
+
renderFloatingSurfaceMotion();
|
|
5159
|
+
};
|
|
5160
|
+
const onExecutionKeyDown = (event) => {
|
|
5161
|
+
if (event.key !== "Escape" || !executionIslandView.isExpanded()) return;
|
|
5162
|
+
event.preventDefault();
|
|
5163
|
+
event.stopPropagation();
|
|
5164
|
+
if (motionController === void 0) {
|
|
5165
|
+
executionIslandView.setExpanded(false);
|
|
5166
|
+
floatingSurface.reconcile();
|
|
5167
|
+
} else {
|
|
5168
|
+
motionController.updateLayout(() => {
|
|
5169
|
+
executionIslandView.setExpanded(false);
|
|
5170
|
+
});
|
|
5171
|
+
}
|
|
5172
|
+
};
|
|
5173
|
+
agentPanel.runButton.addEventListener("click", onAgentRun);
|
|
5174
|
+
externalHandoffPanel?.sendButton.addEventListener("click", onExternalSend);
|
|
5175
|
+
executionIsland.addEventListener("click", onExecutionOpen);
|
|
5176
|
+
executionIsland.addEventListener("keydown", onExecutionKeyDown);
|
|
4416
5177
|
const unsubscribeLocale = localizer.subscribe(applyMessages);
|
|
4417
5178
|
applyMessages();
|
|
4418
5179
|
return Object.freeze({
|
|
@@ -4440,8 +5201,14 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4440
5201
|
agentRevertButton: agentPanel.revertButton,
|
|
4441
5202
|
agentResetButton: agentPanel.resetButton,
|
|
4442
5203
|
...externalHandoffPanel === void 0 ? {} : { externalHandoffPanel },
|
|
5204
|
+
...contextualAskPanel === void 0 ? {} : { contextualAskPanel },
|
|
4443
5205
|
renderStatus(status) {
|
|
4444
5206
|
const inspecting = status === "inspecting";
|
|
5207
|
+
if (status === "idle" || inspecting) {
|
|
5208
|
+
plannerVisible = false;
|
|
5209
|
+
} else {
|
|
5210
|
+
plannerVisible = true;
|
|
5211
|
+
}
|
|
4445
5212
|
triggerButton.setAttribute("aria-pressed", String(inspecting));
|
|
4446
5213
|
triggerButton.textContent = inspecting ? messages.trigger.stop : messages.trigger.select;
|
|
4447
5214
|
renderPanelStatus(status);
|
|
@@ -4450,36 +5217,28 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4450
5217
|
renderDataFlow(state) {
|
|
4451
5218
|
currentDataFlowState = state;
|
|
4452
5219
|
dataFlowPanel.render(state);
|
|
4453
|
-
|
|
5220
|
+
requestFloatingSurfaceLayout();
|
|
4454
5221
|
},
|
|
4455
5222
|
showHighlight(rect, label) {
|
|
4456
|
-
currentRect = rect;
|
|
4457
5223
|
highlight.hidden = false;
|
|
4458
5224
|
highlight.style.transform = `translate(${String(rect.x)}px, ${String(rect.y)}px)`;
|
|
4459
5225
|
highlight.style.width = `${String(rect.width)}px`;
|
|
4460
5226
|
highlight.style.height = `${String(rect.height)}px`;
|
|
4461
5227
|
highlightLabel.textContent = label;
|
|
4462
5228
|
targetLabel.textContent = label;
|
|
4463
|
-
placeDialog();
|
|
4464
5229
|
},
|
|
4465
5230
|
hideHighlight() {
|
|
4466
|
-
currentRect = activeSelectionRect;
|
|
4467
5231
|
highlight.hidden = true;
|
|
4468
5232
|
highlightLabel.textContent = "";
|
|
4469
|
-
placeDialog();
|
|
4470
5233
|
},
|
|
4471
5234
|
showSelectionHighlights,
|
|
4472
5235
|
hideSelectionHighlights() {
|
|
4473
5236
|
selectionHighlights.replaceChildren();
|
|
4474
|
-
activeSelectionRect = void 0;
|
|
4475
|
-
currentRect = void 0;
|
|
4476
|
-
placeDialog();
|
|
4477
5237
|
},
|
|
4478
5238
|
showSelection(summaryText, canOpenEditor, canPreview) {
|
|
4479
5239
|
updateSelection(summaryText, canOpenEditor, canPreview);
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
placeDialog();
|
|
5240
|
+
plannerVisible = true;
|
|
5241
|
+
renderPanelStatus(currentStatus === "previewing" ? "previewing" : "selected");
|
|
4483
5242
|
},
|
|
4484
5243
|
updateSelection,
|
|
4485
5244
|
renderTargets,
|
|
@@ -4491,8 +5250,9 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4491
5250
|
externalHandoffPanel?.setContextReady(enabled);
|
|
4492
5251
|
},
|
|
4493
5252
|
hideSelection() {
|
|
4494
|
-
|
|
4495
|
-
|
|
5253
|
+
plannerVisible = false;
|
|
5254
|
+
executionSuppressed = false;
|
|
5255
|
+
executionProjection = void 0;
|
|
4496
5256
|
targetList.replaceChildren();
|
|
4497
5257
|
currentTargets = [];
|
|
4498
5258
|
currentMaximum = 0;
|
|
@@ -4515,17 +5275,21 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4515
5275
|
agentPanel.setSelectionVisible(false);
|
|
4516
5276
|
externalHandoffPanel?.setContextReady(false);
|
|
4517
5277
|
externalHandoffPanel?.setSelectionVisible(false);
|
|
5278
|
+
contextualAskPanel?.setSelectionVisible(false);
|
|
4518
5279
|
agentPanel.setEditingEnabled(true);
|
|
4519
5280
|
agentPanel.resetJob();
|
|
4520
5281
|
dataFlowPanel.resetView();
|
|
5282
|
+
renderFloatingSurfaceMotion();
|
|
4521
5283
|
},
|
|
4522
5284
|
hideSelectionTemporarily() {
|
|
4523
|
-
|
|
4524
|
-
|
|
5285
|
+
plannerVisible = false;
|
|
5286
|
+
executionSuppressed = false;
|
|
5287
|
+
executionProjection = void 0;
|
|
5288
|
+
renderFloatingSurfaceMotion();
|
|
4525
5289
|
},
|
|
4526
5290
|
showPreview(prompt) {
|
|
4527
5291
|
promptOutput.textContent = prompt;
|
|
4528
|
-
|
|
5292
|
+
requestFloatingSurfaceLayout();
|
|
4529
5293
|
},
|
|
4530
5294
|
readAgentSelection() {
|
|
4531
5295
|
return agentPanel.readSelection();
|
|
@@ -4549,25 +5313,86 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4549
5313
|
previewButton.disabled = !enabled || !currentCanPreview;
|
|
4550
5314
|
externalHandoffPanel?.setContextReady(enabled && currentCanPreview);
|
|
4551
5315
|
agentPanel.setEditingEnabled(enabled);
|
|
4552
|
-
|
|
5316
|
+
requestFloatingSurfaceLayout();
|
|
4553
5317
|
},
|
|
4554
5318
|
renderAgentCapability(state, message, capabilitySnapshot, errorCode) {
|
|
4555
5319
|
agentPanel.renderCapability(state, message, capabilitySnapshot, errorCode);
|
|
5320
|
+
if (state === "error") {
|
|
5321
|
+
pendingAgentMotion = void 0;
|
|
5322
|
+
renderFloatingSurfaceMotion();
|
|
5323
|
+
}
|
|
4556
5324
|
const agentReady = state === "ready" && capabilitySnapshot?.state === "agent-ready";
|
|
4557
5325
|
previewButton.classList.toggle("spotpatch-primary", !agentReady);
|
|
4558
|
-
|
|
5326
|
+
requestFloatingSurfaceLayout();
|
|
4559
5327
|
},
|
|
4560
5328
|
renderAgentWorkspaceHealth(state, snapshot, errorCode) {
|
|
4561
5329
|
agentPanel.renderWorkspaceHealth(state, snapshot, errorCode);
|
|
4562
|
-
|
|
5330
|
+
if (state === "blocked") {
|
|
5331
|
+
pendingAgentMotion = void 0;
|
|
5332
|
+
renderFloatingSurfaceMotion();
|
|
5333
|
+
}
|
|
5334
|
+
requestFloatingSurfaceLayout();
|
|
4563
5335
|
},
|
|
4564
5336
|
renderAgentJob(snapshot, result, activities, errorCode) {
|
|
4565
5337
|
agentPanel.renderJob(snapshot, result, activities, errorCode);
|
|
4566
|
-
|
|
5338
|
+
if (pendingAgentMotion !== void 0 && snapshot.status !== "failed" && snapshot.status !== "cancelled") {
|
|
5339
|
+
startStagedAgentRequest();
|
|
5340
|
+
}
|
|
5341
|
+
if (snapshot.status === "failed" || snapshot.status === "cancelled") {
|
|
5342
|
+
pendingAgentMotion = void 0;
|
|
5343
|
+
}
|
|
5344
|
+
const successful = snapshot.status === "awaiting-review" || snapshot.status === "applied" || snapshot.status === "completed" || snapshot.status === "reverted";
|
|
5345
|
+
const failed = snapshot.status === "failed";
|
|
5346
|
+
const cancelled = snapshot.status === "cancelled";
|
|
5347
|
+
const terminalSuccess = snapshot.status === "applied" || snapshot.status === "completed" || snapshot.status === "reverted";
|
|
5348
|
+
const scene = successful ? "success" : failed ? "failed" : snapshot.status === "queued" || snapshot.status === "preparing" ? "handoff" : "running";
|
|
5349
|
+
if (!executionSuppressed) {
|
|
5350
|
+
if (terminalSuccess && !showSuccessUntilSettled(`job:${snapshot.jobId}:${snapshot.status}`)) {
|
|
5351
|
+
executionProjection = void 0;
|
|
5352
|
+
renderFloatingSurfaceMotion();
|
|
5353
|
+
requestFloatingSurfaceLayout();
|
|
5354
|
+
return;
|
|
5355
|
+
}
|
|
5356
|
+
const identity = snapshot.providerLabel;
|
|
5357
|
+
const target2 = currentTargetSummary();
|
|
5358
|
+
const projectedActivities = Object.freeze(activities.map(projectAgentActivity));
|
|
5359
|
+
const latestActivity = activities.at(-1);
|
|
5360
|
+
const phaseKind = snapshot.status === "queued" || snapshot.status === "preparing" ? "prepare" : snapshot.status === "validating" ? "check" : snapshot.status === "applying" || snapshot.status === "reverting" ? "apply" : snapshot.status === "awaiting-review" || successful ? "sync" : "unknown";
|
|
5361
|
+
const phaseActivity = motionActivity(
|
|
5362
|
+
`job-phase:${snapshot.jobId}:${snapshot.status}:${snapshot.updatedAt}`,
|
|
5363
|
+
phaseKind,
|
|
5364
|
+
void 0,
|
|
5365
|
+
successful ? "success" : failed ? "failure" : "active"
|
|
5366
|
+
);
|
|
5367
|
+
const activity = snapshot.status === "running" && latestActivity !== void 0 ? projectAgentActivity(latestActivity) : phaseActivity;
|
|
5368
|
+
executionProjection = cancelled ? void 0 : {
|
|
5369
|
+
scene,
|
|
5370
|
+
tone: successful ? "success" : failed ? "danger" : "running",
|
|
5371
|
+
headline: successful ? messages.execution.completedTitle : failed ? messages.execution.failedTitle : scene === "handoff" ? messages.execution.dispatchingTitle(identity) : snapshot.status === "validating" ? messages.execution.activityAction(
|
|
5372
|
+
"check",
|
|
5373
|
+
latestActivity?.detail
|
|
5374
|
+
) : snapshot.status === "applying" || snapshot.status === "reverting" ? messages.execution.activityAction(phaseKind) : messages.execution.runningTitle(target2.label),
|
|
5375
|
+
action: successful ? result === void 0 || result.files.length === 0 ? messages.execution.resultReturned : messages.execution.resultSummary(result.files.length) : latestActivity?.detail ?? target2.source,
|
|
5376
|
+
expandedHeadline: successful ? messages.execution.expandedCompletedTitle : failed ? messages.execution.failedTitle : scene === "handoff" ? messages.execution.dispatchingTitle(identity) : messages.execution.expandedRunningTitle(identity),
|
|
5377
|
+
expandedAction: successful ? result === void 0 || result.files.length === 0 ? messages.execution.resultReturned : messages.execution.resultSummary(result.files.length) : currentTargetContext(),
|
|
5378
|
+
meta: successful ? messages.execution.completedStatus : failed ? messages.execution.failedStatus : snapshot.status === "validating" ? messages.execution.checkingStatus : scene === "handoff" ? messages.execution.dispatchingStatus : messages.execution.runningStatus,
|
|
5379
|
+
activity,
|
|
5380
|
+
recentActivities: projectedActivities.length === 0 ? Object.freeze([phaseActivity]) : projectedActivities,
|
|
5381
|
+
startedAt: snapshot.createdAt
|
|
5382
|
+
};
|
|
5383
|
+
}
|
|
5384
|
+
renderFloatingSurfaceMotion();
|
|
5385
|
+
requestFloatingSurfaceLayout();
|
|
4567
5386
|
},
|
|
4568
5387
|
resetAgentJob() {
|
|
4569
5388
|
agentPanel.resetJob();
|
|
4570
|
-
|
|
5389
|
+
observedExecutionStartedAt = void 0;
|
|
5390
|
+
if (executionProjection !== void 0) {
|
|
5391
|
+
executionProjection = void 0;
|
|
5392
|
+
executionSuppressed = false;
|
|
5393
|
+
renderFloatingSurfaceMotion();
|
|
5394
|
+
}
|
|
5395
|
+
requestFloatingSurfaceLayout();
|
|
4571
5396
|
},
|
|
4572
5397
|
focusTargetInstruction(targetId) {
|
|
4573
5398
|
instructionInput(targetId)?.focus({ preventScroll: true });
|
|
@@ -4575,21 +5400,28 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4575
5400
|
focusPrompt() {
|
|
4576
5401
|
promptOutput.focus({ preventScroll: true });
|
|
4577
5402
|
},
|
|
4578
|
-
announce
|
|
4579
|
-
liveRegion.textContent = "";
|
|
4580
|
-
liveRegion.textContent = message;
|
|
4581
|
-
},
|
|
5403
|
+
announce,
|
|
4582
5404
|
locale: localizer.locale,
|
|
4583
5405
|
messages: localizer.messages,
|
|
4584
5406
|
agentWorkspaceConsentGranted: agentPanel.workspaceConsentGranted,
|
|
4585
5407
|
subscribeLocale: localizer.subscribe,
|
|
4586
5408
|
dispose() {
|
|
4587
|
-
diagnostics.removeEventListener("toggle",
|
|
5409
|
+
diagnostics.removeEventListener("toggle", requestFloatingSurfaceLayout);
|
|
4588
5410
|
localeButton.removeEventListener("click", localizer.toggle);
|
|
5411
|
+
resetPositionButton.removeEventListener("click", resetFloatingSurfacePosition);
|
|
5412
|
+
agentPanel.runButton.removeEventListener("click", onAgentRun);
|
|
5413
|
+
externalHandoffPanel?.sendButton.removeEventListener("click", onExternalSend);
|
|
5414
|
+
executionIsland.removeEventListener("click", onExecutionOpen);
|
|
5415
|
+
executionIsland.removeEventListener("keydown", onExecutionKeyDown);
|
|
4589
5416
|
unsubscribeLocale();
|
|
4590
5417
|
dataFlowPanel.dispose();
|
|
4591
5418
|
externalHandoffPanel?.dispose();
|
|
5419
|
+
contextualAskPanel?.dispose();
|
|
4592
5420
|
agentPanel.dispose();
|
|
5421
|
+
motionController?.dispose();
|
|
5422
|
+
executionIslandView.dispose();
|
|
5423
|
+
clearSuccessSettle(true);
|
|
5424
|
+
floatingSurface.dispose();
|
|
4593
5425
|
host.remove();
|
|
4594
5426
|
}
|
|
4595
5427
|
});
|
|
@@ -4658,17 +5490,33 @@ import {
|
|
|
4658
5490
|
function capabilityKey(providerProfileId, modelProfileId) {
|
|
4659
5491
|
return `${providerProfileId}:${modelProfileId}`;
|
|
4660
5492
|
}
|
|
5493
|
+
var TOOL_ACTIVITY_KIND = Object.freeze({
|
|
5494
|
+
list_files: "discover",
|
|
5495
|
+
search_text: "search",
|
|
5496
|
+
read_file: "read",
|
|
5497
|
+
replace_text: "patch",
|
|
5498
|
+
apply_patch: "patch",
|
|
5499
|
+
run_check: "check"
|
|
5500
|
+
});
|
|
5501
|
+
function toolActivityKind(toolName) {
|
|
5502
|
+
return TOOL_ACTIVITY_KIND[toolName] ?? "unknown";
|
|
5503
|
+
}
|
|
4661
5504
|
function activityFromEvent(event) {
|
|
4662
5505
|
if (event.type === "tool") {
|
|
5506
|
+
const detail = event.data.relativePath ?? event.data.checkLabel;
|
|
4663
5507
|
return Object.freeze({
|
|
4664
5508
|
key: `tool:${String(event.data.turn)}:${event.data.toolCallId}`,
|
|
4665
|
-
|
|
5509
|
+
kind: toolActivityKind(event.data.toolName),
|
|
5510
|
+
...detail === void 0 ? {} : { detail },
|
|
5511
|
+
label: `${event.data.toolName}${detail === void 0 ? "" : ` \xB7 ${detail}`} \xB7 ${event.data.state}`,
|
|
4666
5512
|
state: event.data.state === "started" ? "active" : event.data.state === "succeeded" ? "success" : "failure"
|
|
4667
5513
|
});
|
|
4668
5514
|
}
|
|
4669
5515
|
if (event.type === "check") {
|
|
4670
5516
|
return Object.freeze({
|
|
4671
5517
|
key: `check:${event.data.result.checkId}:${String(event.sequence)}`,
|
|
5518
|
+
kind: "check",
|
|
5519
|
+
detail: event.data.result.label,
|
|
4672
5520
|
label: `${event.data.result.label} \xB7 ${event.data.result.status}`,
|
|
4673
5521
|
state: event.data.result.status === "passed" ? "success" : event.data.result.status === "failed" || event.data.result.status === "timed-out" ? "failure" : "info"
|
|
4674
5522
|
});
|
|
@@ -5089,7 +5937,8 @@ function createController(config, dependencies = {}) {
|
|
|
5089
5937
|
config.dataFlow.enabled,
|
|
5090
5938
|
config.externalAgent.enabled,
|
|
5091
5939
|
config.framework,
|
|
5092
|
-
config.sessionId
|
|
5940
|
+
config.sessionId,
|
|
5941
|
+
config.contextualAsk.enabled
|
|
5093
5942
|
);
|
|
5094
5943
|
const api = dependencies.api ?? createRuntimeApi({
|
|
5095
5944
|
apiBase: config.apiBase,
|
|
@@ -5292,6 +6141,19 @@ function createController(config, dependencies = {}) {
|
|
|
5292
6141
|
(target2) => target2.instruction.trim().length > 0 && target2.elementContext !== void 0 && target2.styles !== void 0 && target2.apiStatus !== "loading"
|
|
5293
6142
|
);
|
|
5294
6143
|
}
|
|
6144
|
+
function selectedAskSelection() {
|
|
6145
|
+
const snapshots = targets.flatMap((target2) => {
|
|
6146
|
+
const snapshot = snapshotTarget(target2);
|
|
6147
|
+
return snapshot === void 0 ? [] : [snapshot];
|
|
6148
|
+
});
|
|
6149
|
+
if (snapshots.length === 0 || snapshots.length !== targets.length) {
|
|
6150
|
+
return void 0;
|
|
6151
|
+
}
|
|
6152
|
+
return Object.freeze({
|
|
6153
|
+
locale: view.locale(),
|
|
6154
|
+
targets: snapshots
|
|
6155
|
+
});
|
|
6156
|
+
}
|
|
5295
6157
|
function selectionSummary() {
|
|
5296
6158
|
const messages = view.messages().summary;
|
|
5297
6159
|
return targets.map((target2, index) => {
|
|
@@ -5413,6 +6275,7 @@ ${summary}`;
|
|
|
5413
6275
|
api.cancelPending();
|
|
5414
6276
|
agentWorkflow.disposeSelection();
|
|
5415
6277
|
externalHandoffWorkflow?.cancelPending();
|
|
6278
|
+
contextualAskWorkflow?.cancelPending();
|
|
5416
6279
|
clearCollectionTimers();
|
|
5417
6280
|
resizeObserver?.disconnect();
|
|
5418
6281
|
targets = [];
|
|
@@ -5538,6 +6401,27 @@ ${summary}`;
|
|
|
5538
6401
|
config.sessionToken,
|
|
5539
6402
|
browser.window
|
|
5540
6403
|
) : void 0;
|
|
6404
|
+
const contextualAskWorkflow = config.contextualAsk.enabled && view.contextualAskPanel !== void 0 ? getContextualAskExtension()?.createWorkflow({
|
|
6405
|
+
...clipboard === void 0 ? {} : { clipboard },
|
|
6406
|
+
createId,
|
|
6407
|
+
fetch: browser.window.fetch.bind(browser.window),
|
|
6408
|
+
getSelection: selectedAskSelection,
|
|
6409
|
+
onBusyChange(busy) {
|
|
6410
|
+
view.setAgentEditingEnabled(!busy);
|
|
6411
|
+
},
|
|
6412
|
+
onConvert() {
|
|
6413
|
+
view.focusTargetInstruction(activeTargetId);
|
|
6414
|
+
},
|
|
6415
|
+
async onOpenSource(source2) {
|
|
6416
|
+
await api.openEditor({
|
|
6417
|
+
fileId: source2.fileId,
|
|
6418
|
+
line: source2.startLine,
|
|
6419
|
+
column: 1
|
|
6420
|
+
});
|
|
6421
|
+
},
|
|
6422
|
+
panel: view.contextualAskPanel,
|
|
6423
|
+
sessionToken: config.sessionToken
|
|
6424
|
+
}) : void 0;
|
|
5541
6425
|
async function loadSourceContext(target2, revision) {
|
|
5542
6426
|
const marker = target2.marker;
|
|
5543
6427
|
if (marker === void 0) {
|
|
@@ -5651,6 +6535,7 @@ ${summary}`;
|
|
|
5651
6535
|
previewPrompt = "";
|
|
5652
6536
|
agentWorkflow.beginSelection();
|
|
5653
6537
|
workflowSelectionActive = true;
|
|
6538
|
+
contextualAskWorkflow?.beginSelection();
|
|
5654
6539
|
}
|
|
5655
6540
|
targetSequence += 1;
|
|
5656
6541
|
const target2 = {
|
|
@@ -5669,6 +6554,9 @@ ${summary}`;
|
|
|
5669
6554
|
dataFlowStatus: "idle"
|
|
5670
6555
|
};
|
|
5671
6556
|
targets.push(target2);
|
|
6557
|
+
if (!initialSelection) {
|
|
6558
|
+
contextualAskWorkflow?.selectionChanged();
|
|
6559
|
+
}
|
|
5672
6560
|
activeTargetId = target2.id;
|
|
5673
6561
|
addingTarget = false;
|
|
5674
6562
|
const revision = sessionRevision;
|
|
@@ -5785,10 +6673,12 @@ ${summary}`;
|
|
|
5785
6673
|
pageDataFlowStatus = "idle";
|
|
5786
6674
|
renderDataFlowView();
|
|
5787
6675
|
selectionSession.clear();
|
|
6676
|
+
contextualAskWorkflow?.selectionChanged();
|
|
5788
6677
|
view.announce(view.messages().announcements.allTargetsRemoved);
|
|
5789
6678
|
return;
|
|
5790
6679
|
}
|
|
5791
6680
|
refreshSelectionView();
|
|
6681
|
+
contextualAskWorkflow?.selectionChanged();
|
|
5792
6682
|
void loadDataFlowReports();
|
|
5793
6683
|
persistSelection();
|
|
5794
6684
|
view.announce(view.messages().announcements.targetRemoved);
|
|
@@ -5967,6 +6857,7 @@ ${summary}`;
|
|
|
5967
6857
|
}
|
|
5968
6858
|
mounted = true;
|
|
5969
6859
|
externalHandoffWorkflow?.mount();
|
|
6860
|
+
contextualAskWorkflow?.mount();
|
|
5970
6861
|
view.renderStatus(state.status);
|
|
5971
6862
|
browser.document.addEventListener("pointermove", handlePointerMove, true);
|
|
5972
6863
|
browser.document.addEventListener("click", handleClick, true);
|
|
@@ -6018,6 +6909,7 @@ ${summary}`;
|
|
|
6018
6909
|
if (selectionOpen && targets.length > 0) {
|
|
6019
6910
|
transition({ type: "RESTORE" });
|
|
6020
6911
|
agentWorkflow.beginSelection();
|
|
6912
|
+
contextualAskWorkflow?.beginSelection();
|
|
6021
6913
|
workflowSelectionActive = true;
|
|
6022
6914
|
refreshSelectionView(true);
|
|
6023
6915
|
}
|
|
@@ -6034,6 +6926,7 @@ ${summary}`;
|
|
|
6034
6926
|
api.dispose();
|
|
6035
6927
|
agentWorkflow.disposeSelection();
|
|
6036
6928
|
externalHandoffWorkflow?.dispose();
|
|
6929
|
+
contextualAskWorkflow?.dispose();
|
|
6037
6930
|
sourceResolver.dispose();
|
|
6038
6931
|
return;
|
|
6039
6932
|
}
|
|
@@ -6098,6 +6991,7 @@ ${summary}`;
|
|
|
6098
6991
|
api.dispose();
|
|
6099
6992
|
agentWorkflow.disposeSelection();
|
|
6100
6993
|
externalHandoffWorkflow?.dispose();
|
|
6994
|
+
contextualAskWorkflow?.dispose();
|
|
6101
6995
|
sourceResolver.dispose();
|
|
6102
6996
|
view.dispose();
|
|
6103
6997
|
state = INITIAL_RUNTIME_STATE;
|