@spotpatch/runtime 1.12.0 → 1.13.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-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/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 +1192 -274
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1160 -351
- package/dist/index.js.map +1 -1
- package/dist/motion.cjs +1251 -0
- package/dist/motion.cjs.map +1 -0
- package/dist/motion.d.cts +79 -0
- package/dist/motion.d.ts +79 -0
- package/dist/motion.js +1092 -0
- package/dist/motion.js.map +1 -0
- package/package.json +17 -2
- package/dist/chunk-7ES63LA7.js.map +0 -1
- package/dist/chunk-BXRMVHNT.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1138,6 +1138,15 @@ var UI_Z_INDEX = Object.freeze({
|
|
|
1138
1138
|
highlight: 2147483646,
|
|
1139
1139
|
controls: 2147483647
|
|
1140
1140
|
});
|
|
1141
|
+
var FLOATING_SURFACE_LAYOUT = Object.freeze({
|
|
1142
|
+
compactInset: 8,
|
|
1143
|
+
compactViewportWidth: 520,
|
|
1144
|
+
desktopInset: 24,
|
|
1145
|
+
dragActivationDistance: 6,
|
|
1146
|
+
edgeSnapDistance: 20,
|
|
1147
|
+
workbenchMaxHeight: 620,
|
|
1148
|
+
workbenchMaxWidth: 460
|
|
1149
|
+
});
|
|
1141
1150
|
|
|
1142
1151
|
// src/picker/hit-test.ts
|
|
1143
1152
|
function isInsideSpotPatchUI(element2) {
|
|
@@ -1986,6 +1995,7 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1986
1995
|
root.hidden = !ai.enabled;
|
|
1987
1996
|
const header = createMarkedElement(document, "div");
|
|
1988
1997
|
header.className = "spotpatch-agent-head";
|
|
1998
|
+
header.setAttribute("data-spotpatch-agent-identity", "");
|
|
1989
1999
|
const title = createMarkedElement(document, "span");
|
|
1990
2000
|
title.className = "spotpatch-agent-title";
|
|
1991
2001
|
const badge = createMarkedElement(document, "span");
|
|
@@ -2492,7 +2502,27 @@ function svgElement(document, tagName, attributes) {
|
|
|
2492
2502
|
}
|
|
2493
2503
|
return element2;
|
|
2494
2504
|
}
|
|
2495
|
-
function
|
|
2505
|
+
function namespaceSvgIds(svg, prefix) {
|
|
2506
|
+
const safePrefix = prefix.replace(/[^a-zA-Z0-9_-]/gu, "-");
|
|
2507
|
+
const ids = /* @__PURE__ */ new Map();
|
|
2508
|
+
for (const element2 of svg.querySelectorAll("[id]")) {
|
|
2509
|
+
const id = element2.id;
|
|
2510
|
+
const namespacedId = `${safePrefix}-${id}`;
|
|
2511
|
+
ids.set(id, namespacedId);
|
|
2512
|
+
element2.id = namespacedId;
|
|
2513
|
+
}
|
|
2514
|
+
for (const element2 of [svg, ...svg.querySelectorAll("*")]) {
|
|
2515
|
+
for (const attribute of [...element2.attributes]) {
|
|
2516
|
+
let value = attribute.value;
|
|
2517
|
+
for (const [id, namespacedId] of ids) {
|
|
2518
|
+
value = value.replaceAll(`url(#${id})`, `url(#${namespacedId})`);
|
|
2519
|
+
if (value === `#${id}`) value = `#${namespacedId}`;
|
|
2520
|
+
}
|
|
2521
|
+
if (value !== attribute.value) element2.setAttribute(attribute.name, value);
|
|
2522
|
+
}
|
|
2523
|
+
}
|
|
2524
|
+
}
|
|
2525
|
+
function createBrandMark(document, content, idPrefix) {
|
|
2496
2526
|
const resolved = resolveBrandMarkContent(content);
|
|
2497
2527
|
const svg = svgElement(document, "svg", {
|
|
2498
2528
|
xmlns: SVG_NAMESPACE,
|
|
@@ -2502,6 +2532,7 @@ function createBrandMark(document, content) {
|
|
|
2502
2532
|
focusable: "false"
|
|
2503
2533
|
});
|
|
2504
2534
|
svg.innerHTML = resolved.content;
|
|
2535
|
+
if (idPrefix !== void 0) namespaceSvgIds(svg, idPrefix);
|
|
2505
2536
|
return svg;
|
|
2506
2537
|
}
|
|
2507
2538
|
|
|
@@ -2511,79 +2542,18 @@ function getDataFlowExtension(target2 = globalThis) {
|
|
|
2511
2542
|
return target2[DATA_FLOW_EXTENSION_KEY];
|
|
2512
2543
|
}
|
|
2513
2544
|
|
|
2514
|
-
// src/ui/dialog-placement.ts
|
|
2515
|
-
var VIEWPORT_MARGIN = 16;
|
|
2516
|
-
var TARGET_GAP = 14;
|
|
2517
|
-
var TARGET_INSET = 24;
|
|
2518
|
-
var ANCHOR_INSET = 22;
|
|
2519
|
-
function clamp(value, minimum, maximum) {
|
|
2520
|
-
return Math.min(Math.max(value, minimum), Math.max(minimum, maximum));
|
|
2521
|
-
}
|
|
2522
|
-
function calculateDialogPlacement({
|
|
2523
|
-
dialogHeight,
|
|
2524
|
-
dialogWidth,
|
|
2525
|
-
target: target2,
|
|
2526
|
-
viewportHeight,
|
|
2527
|
-
viewportWidth
|
|
2528
|
-
}) {
|
|
2529
|
-
const maxLeft = viewportWidth - dialogWidth - VIEWPORT_MARGIN;
|
|
2530
|
-
const maxTop = viewportHeight - dialogHeight - VIEWPORT_MARGIN;
|
|
2531
|
-
const viewportLeft = clamp(
|
|
2532
|
-
(viewportWidth - dialogWidth) / 2,
|
|
2533
|
-
VIEWPORT_MARGIN,
|
|
2534
|
-
maxLeft
|
|
2535
|
-
);
|
|
2536
|
-
const viewportTop = clamp(
|
|
2537
|
-
(viewportHeight - dialogHeight) / 2,
|
|
2538
|
-
VIEWPORT_MARGIN,
|
|
2539
|
-
maxTop
|
|
2540
|
-
);
|
|
2541
|
-
if (target2 === void 0) {
|
|
2542
|
-
return Object.freeze({
|
|
2543
|
-
anchorX: clamp(dialogWidth / 2, ANCHOR_INSET, dialogWidth - ANCHOR_INSET),
|
|
2544
|
-
anchorY: clamp(dialogHeight / 2, ANCHOR_INSET, dialogHeight - ANCHOR_INSET),
|
|
2545
|
-
left: viewportLeft,
|
|
2546
|
-
mode: "viewport",
|
|
2547
|
-
top: viewportTop
|
|
2548
|
-
});
|
|
2549
|
-
}
|
|
2550
|
-
const targetCenterX = target2.x + target2.width / 2;
|
|
2551
|
-
const targetCenterY = target2.y + target2.height / 2;
|
|
2552
|
-
const centeredLeft = clamp(targetCenterX - dialogWidth / 2, VIEWPORT_MARGIN, maxLeft);
|
|
2553
|
-
const centeredTop = clamp(targetCenterY - dialogHeight / 2, VIEWPORT_MARGIN, maxTop);
|
|
2554
|
-
let left = centeredLeft;
|
|
2555
|
-
let top = centeredTop;
|
|
2556
|
-
let mode = "viewport";
|
|
2557
|
-
if (target2.width >= dialogWidth + TARGET_INSET * 2 && target2.height >= dialogHeight + TARGET_INSET * 2) {
|
|
2558
|
-
mode = "center";
|
|
2559
|
-
} else if (target2.y - dialogHeight - TARGET_GAP >= VIEWPORT_MARGIN) {
|
|
2560
|
-
top = target2.y - dialogHeight - TARGET_GAP;
|
|
2561
|
-
mode = "above";
|
|
2562
|
-
} else if (target2.y + target2.height + TARGET_GAP + dialogHeight <= viewportHeight - VIEWPORT_MARGIN) {
|
|
2563
|
-
top = target2.y + target2.height + TARGET_GAP;
|
|
2564
|
-
mode = "below";
|
|
2565
|
-
} else if (target2.x + target2.width + TARGET_GAP + dialogWidth <= viewportWidth - VIEWPORT_MARGIN) {
|
|
2566
|
-
left = target2.x + target2.width + TARGET_GAP;
|
|
2567
|
-
mode = "right";
|
|
2568
|
-
} else if (target2.x - dialogWidth - TARGET_GAP >= VIEWPORT_MARGIN) {
|
|
2569
|
-
left = target2.x - dialogWidth - TARGET_GAP;
|
|
2570
|
-
mode = "left";
|
|
2571
|
-
}
|
|
2572
|
-
return Object.freeze({
|
|
2573
|
-
anchorX: clamp(targetCenterX - left, ANCHOR_INSET, dialogWidth - ANCHOR_INSET),
|
|
2574
|
-
anchorY: clamp(targetCenterY - top, ANCHOR_INSET, dialogHeight - ANCHOR_INSET),
|
|
2575
|
-
left,
|
|
2576
|
-
mode,
|
|
2577
|
-
top
|
|
2578
|
-
});
|
|
2579
|
-
}
|
|
2580
|
-
|
|
2581
2545
|
// src/ui/external-handoff-contract.ts
|
|
2582
2546
|
var EXTERNAL_HANDOFF_EXTENSION_KEY = /* @__PURE__ */ Symbol.for("spotpatch.external-handoff.v1");
|
|
2583
2547
|
function getExternalHandoffExtension() {
|
|
2584
2548
|
return globalThis[EXTERNAL_HANDOFF_EXTENSION_KEY];
|
|
2585
2549
|
}
|
|
2586
2550
|
|
|
2551
|
+
// src/ui/motion-extension-contract.ts
|
|
2552
|
+
var MOTION_EXTENSION_KEY = /* @__PURE__ */ Symbol.for("spotpatch.motion.v1");
|
|
2553
|
+
function getFloatingSurfaceMotionExtension() {
|
|
2554
|
+
return globalThis[MOTION_EXTENSION_KEY];
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2587
2557
|
// src/ui/localization.ts
|
|
2588
2558
|
var import_shared6 = require("@spotpatch/shared");
|
|
2589
2559
|
var STATUS_EN = Object.freeze({
|
|
@@ -2616,6 +2586,51 @@ var STATUS_ZH = Object.freeze({
|
|
|
2616
2586
|
reverted: "\u5DF2\u64A4\u9500",
|
|
2617
2587
|
failed: "\u5931\u8D25"
|
|
2618
2588
|
});
|
|
2589
|
+
var EXECUTION_ACTIVITY_EN = Object.freeze({
|
|
2590
|
+
prepare: "Preparing context",
|
|
2591
|
+
dispatch: "Dispatching context",
|
|
2592
|
+
discover: "Discovering project files",
|
|
2593
|
+
search: "Searching source",
|
|
2594
|
+
read: "Reading",
|
|
2595
|
+
patch: "Generating a minimal patch",
|
|
2596
|
+
check: "Running",
|
|
2597
|
+
audit: "Auditing proposed changes",
|
|
2598
|
+
apply: "Applying verified changes",
|
|
2599
|
+
sync: "Returning results to SpotPatch",
|
|
2600
|
+
unknown: "Processing the current task"
|
|
2601
|
+
});
|
|
2602
|
+
var EXECUTION_ACTIVITY_ZH = Object.freeze({
|
|
2603
|
+
prepare: "\u6B63\u5728\u51C6\u5907\u4E0A\u4E0B\u6587",
|
|
2604
|
+
dispatch: "\u6B63\u5728\u6D3E\u53D1\u4E0A\u4E0B\u6587",
|
|
2605
|
+
discover: "\u6B63\u5728\u67E5\u627E\u9879\u76EE\u6587\u4EF6",
|
|
2606
|
+
search: "\u6B63\u5728\u641C\u7D22\u6E90\u7801",
|
|
2607
|
+
read: "\u6B63\u5728\u8BFB\u53D6",
|
|
2608
|
+
patch: "\u6B63\u5728\u751F\u6210\u6700\u5C0F\u4FEE\u6539\u8865\u4E01",
|
|
2609
|
+
check: "\u6B63\u5728\u8FD0\u884C",
|
|
2610
|
+
audit: "\u6B63\u5728\u5BA1\u8BA1\u5019\u9009\u4FEE\u6539",
|
|
2611
|
+
apply: "\u6B63\u5728\u5E94\u7528\u5DF2\u9A8C\u8BC1\u4FEE\u6539",
|
|
2612
|
+
sync: "\u6B63\u5728\u5C06\u7ED3\u679C\u56DE\u6D41 SpotPatch",
|
|
2613
|
+
unknown: "\u6B63\u5728\u5904\u7406\u5F53\u524D\u4EFB\u52A1"
|
|
2614
|
+
});
|
|
2615
|
+
var EXECUTION_LANE_LABELS = Object.freeze({
|
|
2616
|
+
prepare: "prepare",
|
|
2617
|
+
dispatch: "dispatch",
|
|
2618
|
+
discover: "list",
|
|
2619
|
+
search: "search",
|
|
2620
|
+
read: "read",
|
|
2621
|
+
patch: "patch",
|
|
2622
|
+
check: "check",
|
|
2623
|
+
audit: "audit",
|
|
2624
|
+
apply: "apply",
|
|
2625
|
+
sync: "sync",
|
|
2626
|
+
unknown: "agent"
|
|
2627
|
+
});
|
|
2628
|
+
function executionActivityAction(labels, kind, detail) {
|
|
2629
|
+
return detail === void 0 || detail.length === 0 ? labels[kind] : `${labels[kind]} ${detail}`;
|
|
2630
|
+
}
|
|
2631
|
+
function executionActivityLane(kind, detail) {
|
|
2632
|
+
return detail === void 0 || detail.length === 0 ? EXECUTION_LANE_LABELS[kind] : `${EXECUTION_LANE_LABELS[kind]} \xB7 ${detail}`;
|
|
2633
|
+
}
|
|
2619
2634
|
var EXTERNAL_HANDOFF_ERROR_EN = "The external Agent handoff request failed.";
|
|
2620
2635
|
var EXTERNAL_HANDOFF_ERROR_ZH = "\u5916\u90E8 Agent \u4EA4\u63A5\u8BF7\u6C42\u5931\u8D25\u3002";
|
|
2621
2636
|
var ERROR_MESSAGES_EN = Object.freeze({
|
|
@@ -2833,6 +2848,11 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2833
2848
|
previewTitle: "Review the request",
|
|
2834
2849
|
previewSubtitle: "Verify the complete context before it leaves the browser."
|
|
2835
2850
|
}),
|
|
2851
|
+
floatingSurface: Object.freeze({
|
|
2852
|
+
dragHandle: "Drag to move the SpotPatch workbench",
|
|
2853
|
+
resetPosition: "Reset workbench position",
|
|
2854
|
+
positionReset: "SpotPatch position reset to the lower-right corner."
|
|
2855
|
+
}),
|
|
2836
2856
|
context: Object.freeze({
|
|
2837
2857
|
collecting: "Collecting context",
|
|
2838
2858
|
ready: "Context ready",
|
|
@@ -2919,6 +2939,27 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2919
2939
|
noOutput: "No output.",
|
|
2920
2940
|
status: (status) => STATUS_EN[status]
|
|
2921
2941
|
}),
|
|
2942
|
+
execution: Object.freeze({
|
|
2943
|
+
claude: "Claude",
|
|
2944
|
+
codex: "Codex",
|
|
2945
|
+
receivingTitle: "Receiving context",
|
|
2946
|
+
dispatchingTitle: (identity) => `Handing off to ${identity}`,
|
|
2947
|
+
runningTitle: (target2) => `Modifying ${target2}`,
|
|
2948
|
+
expandedRunningTitle: (identity) => `${identity} is making changes`,
|
|
2949
|
+
completedTitle: "Change complete",
|
|
2950
|
+
expandedCompletedTitle: "Changes complete",
|
|
2951
|
+
failedTitle: "Execution failed",
|
|
2952
|
+
receivingStatus: "Receiving",
|
|
2953
|
+
dispatchingStatus: "Dispatching",
|
|
2954
|
+
runningStatus: "Running",
|
|
2955
|
+
checkingStatus: "Checking",
|
|
2956
|
+
completedStatus: "Done",
|
|
2957
|
+
failedStatus: "Failed",
|
|
2958
|
+
resultReturned: "The result is back in SpotPatch",
|
|
2959
|
+
resultSummary: (files) => `${String(files)} ${files === 1 ? "file" : "files"}`,
|
|
2960
|
+
activityAction: (kind, detail) => executionActivityAction(EXECUTION_ACTIVITY_EN, kind, detail),
|
|
2961
|
+
activityLane: executionActivityLane
|
|
2962
|
+
}),
|
|
2922
2963
|
announcements: Object.freeze({
|
|
2923
2964
|
adapterDisabled: "React inspection was disabled after an adapter failure.",
|
|
2924
2965
|
selectionEnabled: "Element selection enabled.",
|
|
@@ -2971,6 +3012,11 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2971
3012
|
previewTitle: "\u5BA1\u9605\u4FEE\u6539\u8BF7\u6C42",
|
|
2972
3013
|
previewSubtitle: "\u53D1\u9001\u7ED9 AI \u524D\uFF0C\u8BF7\u6838\u5BF9\u5B8C\u6574\u4E0A\u4E0B\u6587\u4E0E\u6BCF\u9879\u76EE\u6807\u8BF4\u660E\u3002"
|
|
2973
3014
|
}),
|
|
3015
|
+
floatingSurface: Object.freeze({
|
|
3016
|
+
dragHandle: "\u62D6\u62FD\u4EE5\u79FB\u52A8 SpotPatch \u5DE5\u4F5C\u53F0",
|
|
3017
|
+
resetPosition: "\u91CD\u7F6E\u5DE5\u4F5C\u53F0\u4F4D\u7F6E",
|
|
3018
|
+
positionReset: "SpotPatch \u5DF2\u6062\u590D\u5230\u53F3\u4E0B\u89D2\u3002"
|
|
3019
|
+
}),
|
|
2974
3020
|
context: Object.freeze({
|
|
2975
3021
|
collecting: "\u6B63\u5728\u91C7\u96C6\u4E0A\u4E0B\u6587",
|
|
2976
3022
|
ready: "\u4E0A\u4E0B\u6587\u5DF2\u5C31\u7EEA",
|
|
@@ -3057,6 +3103,27 @@ var UI_MESSAGES = Object.freeze({
|
|
|
3057
3103
|
noOutput: "\u6CA1\u6709\u8F93\u51FA\u3002",
|
|
3058
3104
|
status: (status) => STATUS_ZH[status]
|
|
3059
3105
|
}),
|
|
3106
|
+
execution: Object.freeze({
|
|
3107
|
+
claude: "Claude",
|
|
3108
|
+
codex: "Codex",
|
|
3109
|
+
receivingTitle: "\u6B63\u5728\u63A5\u6536\u4E0A\u4E0B\u6587",
|
|
3110
|
+
dispatchingTitle: (identity) => `\u6B63\u5728\u4EA4\u63A5\u7ED9 ${identity}`,
|
|
3111
|
+
runningTitle: (target2) => `\u6B63\u5728\u4FEE\u6539 ${target2}`,
|
|
3112
|
+
expandedRunningTitle: (identity) => `${identity} \u6B63\u5728\u6267\u884C\u4FEE\u6539`,
|
|
3113
|
+
completedTitle: "\u4FEE\u6539\u5B8C\u6210",
|
|
3114
|
+
expandedCompletedTitle: "\u4FEE\u6539\u5DF2\u5B8C\u6210",
|
|
3115
|
+
failedTitle: "\u6267\u884C\u5931\u8D25",
|
|
3116
|
+
receivingStatus: "\u63A5\u6536\u4E2D",
|
|
3117
|
+
dispatchingStatus: "\u6D3E\u53D1\u4E2D",
|
|
3118
|
+
runningStatus: "\u6267\u884C\u4E2D",
|
|
3119
|
+
checkingStatus: "\u68C0\u67E5\u4E2D",
|
|
3120
|
+
completedStatus: "\u5B8C\u6210",
|
|
3121
|
+
failedStatus: "\u5931\u8D25",
|
|
3122
|
+
resultReturned: "\u7ED3\u679C\u5DF2\u56DE\u6D41 SpotPatch",
|
|
3123
|
+
resultSummary: (files) => `${String(files)} \u4E2A\u6587\u4EF6`,
|
|
3124
|
+
activityAction: (kind, detail) => executionActivityAction(EXECUTION_ACTIVITY_ZH, kind, detail),
|
|
3125
|
+
activityLane: executionActivityLane
|
|
3126
|
+
}),
|
|
3060
3127
|
announcements: Object.freeze({
|
|
3061
3128
|
adapterDisabled: "React \u9002\u914D\u5668\u5F02\u5E38\uFF0C\u672C\u6B21\u4F1A\u8BDD\u5DF2\u505C\u7528 React \u68C0\u67E5\u3002",
|
|
3062
3129
|
selectionEnabled: "\u5143\u7D20\u9009\u62E9\u5DF2\u542F\u7528\u3002",
|
|
@@ -3130,13 +3197,500 @@ function createUiLocalizer(document, preference = "auto") {
|
|
|
3130
3197
|
});
|
|
3131
3198
|
}
|
|
3132
3199
|
|
|
3133
|
-
// src/
|
|
3134
|
-
var
|
|
3135
|
-
var
|
|
3136
|
-
var
|
|
3137
|
-
|
|
3138
|
-
|
|
3200
|
+
// src/state/floating-surface-session.ts
|
|
3201
|
+
var STORAGE_PREFIX2 = "spotpatch:floating-surface:";
|
|
3202
|
+
var SNAPSHOT_VERSION2 = 1;
|
|
3203
|
+
var MAX_SNAPSHOT_CHARACTERS2 = 1024;
|
|
3204
|
+
function record2(value) {
|
|
3205
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
3206
|
+
}
|
|
3207
|
+
function finiteRatio(value) {
|
|
3208
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 1;
|
|
3209
|
+
}
|
|
3210
|
+
function alignment(value) {
|
|
3211
|
+
return value === "start" || value === "end";
|
|
3212
|
+
}
|
|
3213
|
+
function parseSnapshot2(value) {
|
|
3214
|
+
const snapshot = record2(value);
|
|
3215
|
+
if (snapshot?.version !== SNAPSHOT_VERSION2 || !alignment(snapshot.horizontal) || !alignment(snapshot.vertical) || !finiteRatio(snapshot.xRatio) || !finiteRatio(snapshot.yRatio)) {
|
|
3216
|
+
return void 0;
|
|
3217
|
+
}
|
|
3218
|
+
return Object.freeze({
|
|
3219
|
+
horizontal: snapshot.horizontal,
|
|
3220
|
+
vertical: snapshot.vertical,
|
|
3221
|
+
xRatio: snapshot.xRatio,
|
|
3222
|
+
yRatio: snapshot.yRatio
|
|
3223
|
+
});
|
|
3224
|
+
}
|
|
3225
|
+
function createFloatingSurfaceSession(window, sessionId) {
|
|
3226
|
+
const key = `${STORAGE_PREFIX2}${sessionId}`;
|
|
3227
|
+
let storage;
|
|
3228
|
+
try {
|
|
3229
|
+
storage = window.sessionStorage;
|
|
3230
|
+
} catch {
|
|
3231
|
+
storage = void 0;
|
|
3232
|
+
}
|
|
3233
|
+
return Object.freeze({
|
|
3234
|
+
clear() {
|
|
3235
|
+
try {
|
|
3236
|
+
storage?.removeItem(key);
|
|
3237
|
+
} catch {
|
|
3238
|
+
}
|
|
3239
|
+
},
|
|
3240
|
+
load() {
|
|
3241
|
+
let serialized;
|
|
3242
|
+
try {
|
|
3243
|
+
serialized = storage?.getItem(key) ?? null;
|
|
3244
|
+
} catch {
|
|
3245
|
+
return void 0;
|
|
3246
|
+
}
|
|
3247
|
+
if (serialized === null || serialized.length > MAX_SNAPSHOT_CHARACTERS2) {
|
|
3248
|
+
return void 0;
|
|
3249
|
+
}
|
|
3250
|
+
try {
|
|
3251
|
+
return parseSnapshot2(JSON.parse(serialized));
|
|
3252
|
+
} catch {
|
|
3253
|
+
return void 0;
|
|
3254
|
+
}
|
|
3255
|
+
},
|
|
3256
|
+
save(position) {
|
|
3257
|
+
try {
|
|
3258
|
+
storage?.setItem(
|
|
3259
|
+
key,
|
|
3260
|
+
JSON.stringify({ version: SNAPSHOT_VERSION2, ...position })
|
|
3261
|
+
);
|
|
3262
|
+
} catch {
|
|
3263
|
+
}
|
|
3264
|
+
}
|
|
3265
|
+
});
|
|
3266
|
+
}
|
|
3267
|
+
|
|
3268
|
+
// src/ui/floating-surface-position.ts
|
|
3269
|
+
var DEFAULT_FLOATING_SURFACE_POSITION = Object.freeze({
|
|
3270
|
+
horizontal: "end",
|
|
3271
|
+
vertical: "end",
|
|
3272
|
+
xRatio: 1,
|
|
3273
|
+
yRatio: 1
|
|
3139
3274
|
});
|
|
3275
|
+
function clamp(value, minimum, maximum) {
|
|
3276
|
+
return Math.min(Math.max(value, minimum), maximum);
|
|
3277
|
+
}
|
|
3278
|
+
function finiteNonNegative(value) {
|
|
3279
|
+
return Number.isFinite(value) ? Math.max(0, value) : 0;
|
|
3280
|
+
}
|
|
3281
|
+
function boundedRatio(value) {
|
|
3282
|
+
return Number.isFinite(value) ? clamp(value, 0, 1) : 0.5;
|
|
3283
|
+
}
|
|
3284
|
+
function normalizedViewport(viewport) {
|
|
3285
|
+
return Object.freeze({
|
|
3286
|
+
height: finiteNonNegative(viewport.height),
|
|
3287
|
+
left: Number.isFinite(viewport.left) ? viewport.left : 0,
|
|
3288
|
+
top: Number.isFinite(viewport.top) ? viewport.top : 0,
|
|
3289
|
+
width: finiteNonNegative(viewport.width)
|
|
3290
|
+
});
|
|
3291
|
+
}
|
|
3292
|
+
function horizontalAnchor(rect, alignment2) {
|
|
3293
|
+
return alignment2 === "end" ? rect.left + rect.width : rect.left;
|
|
3294
|
+
}
|
|
3295
|
+
function verticalAnchor(rect, alignment2) {
|
|
3296
|
+
return alignment2 === "end" ? rect.top + rect.height : rect.top;
|
|
3297
|
+
}
|
|
3298
|
+
function normalizedCoordinate(coordinate, origin, length) {
|
|
3299
|
+
if (length <= 0) {
|
|
3300
|
+
return 0.5;
|
|
3301
|
+
}
|
|
3302
|
+
return boundedRatio((coordinate - origin) / length);
|
|
3303
|
+
}
|
|
3304
|
+
function positionFromAnchor(anchor, viewport, horizontal, vertical) {
|
|
3305
|
+
return Object.freeze({
|
|
3306
|
+
horizontal,
|
|
3307
|
+
vertical,
|
|
3308
|
+
xRatio: normalizedCoordinate(anchor.x, viewport.left, viewport.width),
|
|
3309
|
+
yRatio: normalizedCoordinate(anchor.y, viewport.top, viewport.height)
|
|
3310
|
+
});
|
|
3311
|
+
}
|
|
3312
|
+
function resolveFloatingSurfaceRect(position, size, viewport) {
|
|
3313
|
+
const width = finiteNonNegative(size.width);
|
|
3314
|
+
const height = finiteNonNegative(size.height);
|
|
3315
|
+
const normalized = normalizedViewport(viewport);
|
|
3316
|
+
const viewportWidth = normalized.width;
|
|
3317
|
+
const viewportHeight = normalized.height;
|
|
3318
|
+
const leftBoundary = normalized.left;
|
|
3319
|
+
const topBoundary = normalized.top;
|
|
3320
|
+
const rightBoundary = leftBoundary + viewportWidth;
|
|
3321
|
+
const bottomBoundary = topBoundary + viewportHeight;
|
|
3322
|
+
const anchorX = leftBoundary + boundedRatio(position.xRatio) * viewportWidth;
|
|
3323
|
+
const anchorY = topBoundary + boundedRatio(position.yRatio) * viewportHeight;
|
|
3324
|
+
const requestedLeft = position.horizontal === "end" ? anchorX - width : anchorX;
|
|
3325
|
+
const requestedTop = position.vertical === "end" ? anchorY - height : anchorY;
|
|
3326
|
+
const maximumLeft = Math.max(leftBoundary, rightBoundary - width);
|
|
3327
|
+
const maximumTop = Math.max(topBoundary, bottomBoundary - height);
|
|
3328
|
+
return Object.freeze({
|
|
3329
|
+
height,
|
|
3330
|
+
left: clamp(requestedLeft, leftBoundary, maximumLeft),
|
|
3331
|
+
top: clamp(requestedTop, topBoundary, maximumTop),
|
|
3332
|
+
width
|
|
3333
|
+
});
|
|
3334
|
+
}
|
|
3335
|
+
function snapFloatingSurfaceRect(rect, viewport, snapDistance) {
|
|
3336
|
+
const distance = finiteNonNegative(snapDistance);
|
|
3337
|
+
const width = finiteNonNegative(rect.width);
|
|
3338
|
+
const height = finiteNonNegative(rect.height);
|
|
3339
|
+
const normalized = normalizedViewport(viewport);
|
|
3340
|
+
const viewportRight = normalized.left + normalized.width;
|
|
3341
|
+
const viewportBottom = normalized.top + normalized.height;
|
|
3342
|
+
const maximumLeft = Math.max(normalized.left, viewportRight - width);
|
|
3343
|
+
const maximumTop = Math.max(normalized.top, viewportBottom - height);
|
|
3344
|
+
const requestedLeft = clamp(rect.left, normalized.left, maximumLeft);
|
|
3345
|
+
const requestedTop = clamp(rect.top, normalized.top, maximumTop);
|
|
3346
|
+
const leftDistance = Math.abs(requestedLeft - normalized.left);
|
|
3347
|
+
const rightDistance = Math.abs(viewportRight - (requestedLeft + width));
|
|
3348
|
+
const topDistance = Math.abs(requestedTop - normalized.top);
|
|
3349
|
+
const bottomDistance = Math.abs(viewportBottom - (requestedTop + height));
|
|
3350
|
+
const left = Math.min(leftDistance, rightDistance) <= distance ? leftDistance <= rightDistance ? normalized.left : viewportRight - width : requestedLeft;
|
|
3351
|
+
const top = Math.min(topDistance, bottomDistance) <= distance ? topDistance <= bottomDistance ? normalized.top : viewportBottom - height : requestedTop;
|
|
3352
|
+
return Object.freeze({ height, left, top, width });
|
|
3353
|
+
}
|
|
3354
|
+
function positionFromFloatingSurfaceRect(rect, viewport, previous) {
|
|
3355
|
+
const bounded = snapFloatingSurfaceRect(rect, viewport, 0);
|
|
3356
|
+
const centerX = bounded.left + bounded.width / 2;
|
|
3357
|
+
const centerY = bounded.top + bounded.height / 2;
|
|
3358
|
+
const viewportCenterX = viewport.left + finiteNonNegative(viewport.width) / 2;
|
|
3359
|
+
const viewportCenterY = viewport.top + finiteNonNegative(viewport.height) / 2;
|
|
3360
|
+
const horizontal = centerX === viewportCenterX ? previous.horizontal : centerX < viewportCenterX ? "start" : "end";
|
|
3361
|
+
const vertical = centerY === viewportCenterY ? previous.vertical : centerY < viewportCenterY ? "start" : "end";
|
|
3362
|
+
return positionFromAnchor(
|
|
3363
|
+
{
|
|
3364
|
+
x: horizontalAnchor(bounded, horizontal),
|
|
3365
|
+
y: verticalAnchor(bounded, vertical)
|
|
3366
|
+
},
|
|
3367
|
+
viewport,
|
|
3368
|
+
horizontal,
|
|
3369
|
+
vertical
|
|
3370
|
+
);
|
|
3371
|
+
}
|
|
3372
|
+
|
|
3373
|
+
// src/ui/floating-surface-controller.ts
|
|
3374
|
+
function finite(value, fallback = 0) {
|
|
3375
|
+
return Number.isFinite(value) ? value : fallback;
|
|
3376
|
+
}
|
|
3377
|
+
function distanceBetween(first, second) {
|
|
3378
|
+
return Math.hypot(first.x - second.x, first.y - second.y);
|
|
3379
|
+
}
|
|
3380
|
+
function isPrimaryPointer(event) {
|
|
3381
|
+
return event.button === 0 && event.isPrimary;
|
|
3382
|
+
}
|
|
3383
|
+
function surfaceSize(surface) {
|
|
3384
|
+
const rect = surface.getBoundingClientRect();
|
|
3385
|
+
return Object.freeze({
|
|
3386
|
+
height: Math.max(0, finite(rect.height)),
|
|
3387
|
+
width: Math.max(0, finite(rect.width))
|
|
3388
|
+
});
|
|
3389
|
+
}
|
|
3390
|
+
function requestFrame(window, callback) {
|
|
3391
|
+
if (typeof window.requestAnimationFrame === "function") {
|
|
3392
|
+
return window.requestAnimationFrame(callback);
|
|
3393
|
+
}
|
|
3394
|
+
return window.setTimeout(() => {
|
|
3395
|
+
callback(Date.now());
|
|
3396
|
+
}, 0);
|
|
3397
|
+
}
|
|
3398
|
+
function cancelFrame(window, frame) {
|
|
3399
|
+
if (typeof window.cancelAnimationFrame === "function") {
|
|
3400
|
+
window.cancelAnimationFrame(frame);
|
|
3401
|
+
return;
|
|
3402
|
+
}
|
|
3403
|
+
window.clearTimeout(frame);
|
|
3404
|
+
}
|
|
3405
|
+
function createFloatingSurfaceController(window, session, layout) {
|
|
3406
|
+
let position = session.load() ?? DEFAULT_FLOATING_SURFACE_POSITION;
|
|
3407
|
+
let drag;
|
|
3408
|
+
let frame;
|
|
3409
|
+
let suppressClickFor;
|
|
3410
|
+
let suppressClickTimer;
|
|
3411
|
+
let disposed = false;
|
|
3412
|
+
const surfaces = /* @__PURE__ */ new Set();
|
|
3413
|
+
const cleanup = /* @__PURE__ */ new Set();
|
|
3414
|
+
function viewport() {
|
|
3415
|
+
const visualViewport = window.visualViewport;
|
|
3416
|
+
const width = Math.max(0, finite(visualViewport?.width ?? window.innerWidth));
|
|
3417
|
+
const height = Math.max(0, finite(visualViewport?.height ?? window.innerHeight));
|
|
3418
|
+
const inset = width <= layout.compactViewportWidth ? layout.compactInset : layout.desktopInset;
|
|
3419
|
+
return Object.freeze({
|
|
3420
|
+
height: Math.max(0, height - inset * 2),
|
|
3421
|
+
left: finite(visualViewport?.offsetLeft ?? 0) + inset,
|
|
3422
|
+
top: finite(visualViewport?.offsetTop ?? 0) + inset,
|
|
3423
|
+
width: Math.max(0, width - inset * 2)
|
|
3424
|
+
});
|
|
3425
|
+
}
|
|
3426
|
+
function isCompact() {
|
|
3427
|
+
return viewport().width + layout.compactInset * 2 <= layout.compactViewportWidth;
|
|
3428
|
+
}
|
|
3429
|
+
function apply(surface) {
|
|
3430
|
+
if (surface.hidden) {
|
|
3431
|
+
return void 0;
|
|
3432
|
+
}
|
|
3433
|
+
if (surface.dataset.motionMorphing === "true" && surface.dataset.floatingPositioned === "true") {
|
|
3434
|
+
return void 0;
|
|
3435
|
+
}
|
|
3436
|
+
const size = surfaceSize(surface);
|
|
3437
|
+
if (size.width === 0 || size.height === 0) {
|
|
3438
|
+
return void 0;
|
|
3439
|
+
}
|
|
3440
|
+
const rect = resolveFloatingSurfaceRect(position, size, viewport());
|
|
3441
|
+
surface.style.left = `${String(rect.left)}px`;
|
|
3442
|
+
surface.style.top = `${String(rect.top)}px`;
|
|
3443
|
+
surface.style.right = "auto";
|
|
3444
|
+
surface.style.bottom = "auto";
|
|
3445
|
+
surface.dataset.floatingPositioned = "true";
|
|
3446
|
+
return rect;
|
|
3447
|
+
}
|
|
3448
|
+
function reconcile() {
|
|
3449
|
+
if (disposed) {
|
|
3450
|
+
return;
|
|
3451
|
+
}
|
|
3452
|
+
if (frame !== void 0) {
|
|
3453
|
+
cancelFrame(window, frame);
|
|
3454
|
+
frame = void 0;
|
|
3455
|
+
}
|
|
3456
|
+
for (const surface of surfaces) {
|
|
3457
|
+
apply(surface);
|
|
3458
|
+
}
|
|
3459
|
+
}
|
|
3460
|
+
function requestReconcile() {
|
|
3461
|
+
if (disposed || frame !== void 0) {
|
|
3462
|
+
return;
|
|
3463
|
+
}
|
|
3464
|
+
frame = requestFrame(window, () => {
|
|
3465
|
+
frame = void 0;
|
|
3466
|
+
reconcile();
|
|
3467
|
+
});
|
|
3468
|
+
}
|
|
3469
|
+
function commit(nextPosition) {
|
|
3470
|
+
position = nextPosition;
|
|
3471
|
+
session.save(position);
|
|
3472
|
+
}
|
|
3473
|
+
function finishDrag(commitPosition) {
|
|
3474
|
+
const current = drag;
|
|
3475
|
+
if (current === void 0) {
|
|
3476
|
+
return;
|
|
3477
|
+
}
|
|
3478
|
+
drag = void 0;
|
|
3479
|
+
current.handle.dataset.dragging = "false";
|
|
3480
|
+
current.surface.dataset.dragging = "false";
|
|
3481
|
+
try {
|
|
3482
|
+
if (current.handle.hasPointerCapture(current.pointerId)) {
|
|
3483
|
+
current.handle.releasePointerCapture(current.pointerId);
|
|
3484
|
+
}
|
|
3485
|
+
} catch {
|
|
3486
|
+
}
|
|
3487
|
+
if (commitPosition) {
|
|
3488
|
+
const rect = apply(current.surface);
|
|
3489
|
+
if (rect !== void 0) {
|
|
3490
|
+
const snapped = snapFloatingSurfaceRect(
|
|
3491
|
+
rect,
|
|
3492
|
+
viewport(),
|
|
3493
|
+
layout.edgeSnapDistance
|
|
3494
|
+
);
|
|
3495
|
+
commit(positionFromFloatingSurfaceRect(snapped, viewport(), position));
|
|
3496
|
+
apply(current.surface);
|
|
3497
|
+
}
|
|
3498
|
+
} else {
|
|
3499
|
+
position = session.load() ?? DEFAULT_FLOATING_SURFACE_POSITION;
|
|
3500
|
+
reconcile();
|
|
3501
|
+
}
|
|
3502
|
+
}
|
|
3503
|
+
function updateDrag(event) {
|
|
3504
|
+
const current = drag;
|
|
3505
|
+
if (current === void 0) {
|
|
3506
|
+
return;
|
|
3507
|
+
}
|
|
3508
|
+
if (event.pointerId !== current.pointerId) {
|
|
3509
|
+
return;
|
|
3510
|
+
}
|
|
3511
|
+
const pointer = Object.freeze({ x: event.clientX, y: event.clientY });
|
|
3512
|
+
const start = Object.freeze({ x: current.startX, y: current.startY });
|
|
3513
|
+
if (current.handle.dataset.dragging !== "true" && distanceBetween(pointer, start) < layout.dragActivationDistance) {
|
|
3514
|
+
return;
|
|
3515
|
+
}
|
|
3516
|
+
if (current.handle.dataset.dragging !== "true") {
|
|
3517
|
+
current.onDragStart?.();
|
|
3518
|
+
}
|
|
3519
|
+
current.handle.dataset.dragging = "true";
|
|
3520
|
+
current.surface.dataset.dragging = "true";
|
|
3521
|
+
position = positionFromAnchor(
|
|
3522
|
+
{
|
|
3523
|
+
x: pointer.x + current.anchorOffsetX,
|
|
3524
|
+
y: pointer.y + current.anchorOffsetY
|
|
3525
|
+
},
|
|
3526
|
+
viewport(),
|
|
3527
|
+
position.horizontal,
|
|
3528
|
+
position.vertical
|
|
3529
|
+
);
|
|
3530
|
+
requestReconcile();
|
|
3531
|
+
event.preventDefault();
|
|
3532
|
+
}
|
|
3533
|
+
function addListener(target2, type, listener, options) {
|
|
3534
|
+
target2.addEventListener(type, listener, options);
|
|
3535
|
+
cleanup.add(() => {
|
|
3536
|
+
target2.removeEventListener(type, listener, options);
|
|
3537
|
+
});
|
|
3538
|
+
}
|
|
3539
|
+
function attachDraggable(handle, surface, options = {}) {
|
|
3540
|
+
const onPointerDown = (event) => {
|
|
3541
|
+
if (disposed || drag !== void 0 || !isPrimaryPointer(event) || options.canStartDrag?.(event) === false) {
|
|
3542
|
+
return;
|
|
3543
|
+
}
|
|
3544
|
+
const rect = apply(surface) ?? surface.getBoundingClientRect();
|
|
3545
|
+
const anchorX = position.horizontal === "end" ? rect.left + rect.width : rect.left;
|
|
3546
|
+
const anchorY = position.vertical === "end" ? rect.top + rect.height : rect.top;
|
|
3547
|
+
drag = Object.freeze({
|
|
3548
|
+
anchorOffsetX: anchorX - event.clientX,
|
|
3549
|
+
anchorOffsetY: anchorY - event.clientY,
|
|
3550
|
+
handle,
|
|
3551
|
+
...options.onDragStart === void 0 ? {} : { onDragStart: options.onDragStart },
|
|
3552
|
+
pointerId: event.pointerId,
|
|
3553
|
+
startX: event.clientX,
|
|
3554
|
+
startY: event.clientY,
|
|
3555
|
+
suppressClickOnDrag: options.suppressClickOnDrag ?? false,
|
|
3556
|
+
surface
|
|
3557
|
+
});
|
|
3558
|
+
try {
|
|
3559
|
+
handle.setPointerCapture(event.pointerId);
|
|
3560
|
+
} catch {
|
|
3561
|
+
}
|
|
3562
|
+
};
|
|
3563
|
+
const onLostPointerCapture = (event) => {
|
|
3564
|
+
if (drag?.pointerId === event.pointerId) {
|
|
3565
|
+
finishDrag(handle.dataset.dragging === "true");
|
|
3566
|
+
}
|
|
3567
|
+
};
|
|
3568
|
+
const onClickCapture = (event) => {
|
|
3569
|
+
if (suppressClickFor !== handle) {
|
|
3570
|
+
return;
|
|
3571
|
+
}
|
|
3572
|
+
suppressClickFor = void 0;
|
|
3573
|
+
if (suppressClickTimer !== void 0) {
|
|
3574
|
+
window.clearTimeout(suppressClickTimer);
|
|
3575
|
+
suppressClickTimer = void 0;
|
|
3576
|
+
}
|
|
3577
|
+
event.preventDefault();
|
|
3578
|
+
event.stopImmediatePropagation();
|
|
3579
|
+
};
|
|
3580
|
+
addListener(handle, "pointerdown", (event) => {
|
|
3581
|
+
onPointerDown(event);
|
|
3582
|
+
});
|
|
3583
|
+
addListener(handle, "lostpointercapture", (event) => {
|
|
3584
|
+
onLostPointerCapture(event);
|
|
3585
|
+
});
|
|
3586
|
+
addListener(
|
|
3587
|
+
handle,
|
|
3588
|
+
"click",
|
|
3589
|
+
(event) => {
|
|
3590
|
+
onClickCapture(event);
|
|
3591
|
+
},
|
|
3592
|
+
true
|
|
3593
|
+
);
|
|
3594
|
+
}
|
|
3595
|
+
function reset() {
|
|
3596
|
+
finishDrag(false);
|
|
3597
|
+
position = DEFAULT_FLOATING_SURFACE_POSITION;
|
|
3598
|
+
session.clear();
|
|
3599
|
+
reconcile();
|
|
3600
|
+
}
|
|
3601
|
+
function cancelOnWindowBlur() {
|
|
3602
|
+
finishDrag(false);
|
|
3603
|
+
}
|
|
3604
|
+
function cancelOnEscape(event) {
|
|
3605
|
+
if (event.key !== "Escape" || drag === void 0) {
|
|
3606
|
+
return;
|
|
3607
|
+
}
|
|
3608
|
+
finishDrag(false);
|
|
3609
|
+
event.preventDefault();
|
|
3610
|
+
event.stopImmediatePropagation();
|
|
3611
|
+
}
|
|
3612
|
+
function endPointer(event) {
|
|
3613
|
+
if (drag?.pointerId !== event.pointerId) {
|
|
3614
|
+
return;
|
|
3615
|
+
}
|
|
3616
|
+
const current = drag;
|
|
3617
|
+
const moved = current.handle.dataset.dragging === "true";
|
|
3618
|
+
finishDrag(moved);
|
|
3619
|
+
if (moved && current.suppressClickOnDrag) {
|
|
3620
|
+
suppressClickFor = current.handle;
|
|
3621
|
+
suppressClickTimer = window.setTimeout(() => {
|
|
3622
|
+
suppressClickFor = void 0;
|
|
3623
|
+
suppressClickTimer = void 0;
|
|
3624
|
+
}, 0);
|
|
3625
|
+
}
|
|
3626
|
+
}
|
|
3627
|
+
function cancelPointer(event) {
|
|
3628
|
+
if (drag?.pointerId === event.pointerId) {
|
|
3629
|
+
finishDrag(false);
|
|
3630
|
+
}
|
|
3631
|
+
}
|
|
3632
|
+
addListener(window, "pointermove", (event) => {
|
|
3633
|
+
updateDrag(event);
|
|
3634
|
+
});
|
|
3635
|
+
addListener(window, "pointerup", (event) => {
|
|
3636
|
+
endPointer(event);
|
|
3637
|
+
});
|
|
3638
|
+
addListener(window, "pointercancel", (event) => {
|
|
3639
|
+
cancelPointer(event);
|
|
3640
|
+
});
|
|
3641
|
+
addListener(window, "resize", requestReconcile);
|
|
3642
|
+
addListener(window, "blur", cancelOnWindowBlur);
|
|
3643
|
+
addListener(
|
|
3644
|
+
window,
|
|
3645
|
+
"keydown",
|
|
3646
|
+
(event) => {
|
|
3647
|
+
cancelOnEscape(event);
|
|
3648
|
+
},
|
|
3649
|
+
true
|
|
3650
|
+
);
|
|
3651
|
+
window.visualViewport?.addEventListener("resize", requestReconcile);
|
|
3652
|
+
window.visualViewport?.addEventListener("scroll", requestReconcile);
|
|
3653
|
+
cleanup.add(
|
|
3654
|
+
() => window.visualViewport?.removeEventListener("resize", requestReconcile)
|
|
3655
|
+
);
|
|
3656
|
+
cleanup.add(
|
|
3657
|
+
() => window.visualViewport?.removeEventListener("scroll", requestReconcile)
|
|
3658
|
+
);
|
|
3659
|
+
return Object.freeze({
|
|
3660
|
+
attachDraggable,
|
|
3661
|
+
dispose() {
|
|
3662
|
+
if (disposed) {
|
|
3663
|
+
return;
|
|
3664
|
+
}
|
|
3665
|
+
disposed = true;
|
|
3666
|
+
finishDrag(false);
|
|
3667
|
+
if (frame !== void 0) {
|
|
3668
|
+
cancelFrame(window, frame);
|
|
3669
|
+
frame = void 0;
|
|
3670
|
+
}
|
|
3671
|
+
if (suppressClickTimer !== void 0) {
|
|
3672
|
+
window.clearTimeout(suppressClickTimer);
|
|
3673
|
+
suppressClickTimer = void 0;
|
|
3674
|
+
}
|
|
3675
|
+
suppressClickFor = void 0;
|
|
3676
|
+
for (const disposeListener of cleanup) {
|
|
3677
|
+
disposeListener();
|
|
3678
|
+
}
|
|
3679
|
+
cleanup.clear();
|
|
3680
|
+
surfaces.clear();
|
|
3681
|
+
},
|
|
3682
|
+
isCompact,
|
|
3683
|
+
reconcile,
|
|
3684
|
+
registerSurface(surface) {
|
|
3685
|
+
surfaces.add(surface);
|
|
3686
|
+
},
|
|
3687
|
+
requestReconcile,
|
|
3688
|
+
reset
|
|
3689
|
+
});
|
|
3690
|
+
}
|
|
3691
|
+
|
|
3692
|
+
// src/ui/runtime-view.ts
|
|
3693
|
+
var SUCCESS_SETTLE_MS = 1500;
|
|
3140
3694
|
function resolveStyleNonce(document) {
|
|
3141
3695
|
const nonces = new Set(
|
|
3142
3696
|
[...document.querySelectorAll("script[nonce]")].map((script) => script.nonce?.trim() ?? "").filter(Boolean)
|
|
@@ -3167,53 +3721,20 @@ function createStyles(document) {
|
|
|
3167
3721
|
--spotpatch-success: #34d399;
|
|
3168
3722
|
--spotpatch-warning: #f59e0b;
|
|
3169
3723
|
--spotpatch-text-on-accent: #0b0b12;
|
|
3170
|
-
--spotpatch-radius-panel: 16px;
|
|
3171
3724
|
--spotpatch-radius-card: 10px;
|
|
3172
|
-
--spotpatch-shadow-panel: 0 30px 60px -20px rgb(0 0 0 / 70%);
|
|
3173
|
-
color-scheme: dark;
|
|
3174
3725
|
color: var(--spotpatch-text);
|
|
3175
3726
|
font-family: Inter, "SF Pro Display", "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
3176
3727
|
font-size: 14px;
|
|
3177
3728
|
line-height: 1.5;
|
|
3178
|
-
text-rendering: optimizeLegibility;
|
|
3179
|
-
-webkit-font-smoothing: antialiased;
|
|
3180
3729
|
}
|
|
3181
3730
|
[hidden] { display: none !important; }
|
|
3182
3731
|
button, textarea, select { font: inherit; }
|
|
3183
|
-
|
|
3184
|
-
.spotpatch-trigger {
|
|
3732
|
+
.spotpatch-floating-surface {
|
|
3185
3733
|
position: fixed;
|
|
3186
|
-
right:
|
|
3187
|
-
bottom:
|
|
3734
|
+
right: ${String(FLOATING_SURFACE_LAYOUT.desktopInset)}px;
|
|
3735
|
+
bottom: ${String(FLOATING_SURFACE_LAYOUT.desktopInset)}px;
|
|
3188
3736
|
z-index: ${String(UI_Z_INDEX.controls)};
|
|
3189
|
-
|
|
3190
|
-
align-items: center;
|
|
3191
|
-
gap: 10px;
|
|
3192
|
-
min-height: 44px;
|
|
3193
|
-
border: 1px solid rgb(255 255 255 / 12%);
|
|
3194
|
-
border-radius: 999px;
|
|
3195
|
-
padding: 10px 17px;
|
|
3196
|
-
color: #f8fafc;
|
|
3197
|
-
background: #171b23;
|
|
3198
|
-
box-shadow: 0 12px 34px rgb(0 0 0 / 25%), inset 0 1px rgb(255 255 255 / 5%);
|
|
3199
|
-
cursor: pointer;
|
|
3200
|
-
font-size: 14px;
|
|
3201
|
-
font-weight: 650;
|
|
3202
|
-
transition: border-color 160ms ease, box-shadow 160ms ease, transform 160ms ease;
|
|
3203
|
-
}
|
|
3204
|
-
.spotpatch-trigger::before {
|
|
3205
|
-
width: 9px;
|
|
3206
|
-
height: 9px;
|
|
3207
|
-
border-radius: 999px;
|
|
3208
|
-
background: var(--spotpatch-accent);
|
|
3209
|
-
box-shadow: 0 0 0 4px rgb(99 102 241 / 10%);
|
|
3210
|
-
content: "";
|
|
3211
|
-
}
|
|
3212
|
-
.spotpatch-trigger:hover { transform: translateY(-1px); border-color: rgb(129 140 248 / 52%); }
|
|
3213
|
-
.spotpatch-trigger[aria-pressed="true"] {
|
|
3214
|
-
border-color: rgb(124 58 237 / 55%);
|
|
3215
|
-
background: #24203b;
|
|
3216
|
-
box-shadow: 0 14px 42px rgb(76 29 149 / 24%), inset 0 1px rgb(255 255 255 / 10%);
|
|
3737
|
+
isolation: isolate;
|
|
3217
3738
|
}
|
|
3218
3739
|
.spotpatch-highlight {
|
|
3219
3740
|
position: fixed;
|
|
@@ -3282,82 +3803,28 @@ function createStyles(document) {
|
|
|
3282
3803
|
background: #5546dc;
|
|
3283
3804
|
}
|
|
3284
3805
|
.spotpatch-dialog {
|
|
3285
|
-
|
|
3286
|
-
--spotpatch-anchor-y: 50%;
|
|
3287
|
-
position: fixed;
|
|
3288
|
-
top: 16px;
|
|
3289
|
-
left: 16px;
|
|
3290
|
-
z-index: ${String(UI_Z_INDEX.controls)};
|
|
3806
|
+
position: relative;
|
|
3291
3807
|
box-sizing: border-box;
|
|
3292
|
-
width: min(${String(
|
|
3293
|
-
color: #edf0f7;
|
|
3808
|
+
width: min(${String(FLOATING_SURFACE_LAYOUT.workbenchMaxWidth)}px, calc(100vw - ${String(FLOATING_SURFACE_LAYOUT.desktopInset * 2)}px));
|
|
3294
3809
|
outline: none;
|
|
3295
|
-
filter: drop-shadow(var(--spotpatch-shadow-panel));
|
|
3296
3810
|
}
|
|
3297
|
-
.spotpatch-anchor {
|
|
3298
|
-
position: absolute;
|
|
3299
|
-
z-index: 0;
|
|
3300
|
-
width: 14px;
|
|
3301
|
-
height: 14px;
|
|
3302
|
-
border: 1px solid rgb(255 255 255 / 12%);
|
|
3303
|
-
background: var(--spotpatch-bg);
|
|
3304
|
-
transform: rotate(45deg);
|
|
3305
|
-
}
|
|
3306
|
-
.spotpatch-dialog[data-placement="above"] .spotpatch-anchor {
|
|
3307
|
-
bottom: -6px;
|
|
3308
|
-
left: calc(var(--spotpatch-anchor-x) - 7px);
|
|
3309
|
-
border-top: 0;
|
|
3310
|
-
border-left: 0;
|
|
3311
|
-
}
|
|
3312
|
-
.spotpatch-dialog[data-placement="below"] .spotpatch-anchor {
|
|
3313
|
-
top: -6px;
|
|
3314
|
-
left: calc(var(--spotpatch-anchor-x) - 7px);
|
|
3315
|
-
border-right: 0;
|
|
3316
|
-
border-bottom: 0;
|
|
3317
|
-
}
|
|
3318
|
-
.spotpatch-dialog[data-placement="left"] .spotpatch-anchor {
|
|
3319
|
-
top: calc(var(--spotpatch-anchor-y) - 7px);
|
|
3320
|
-
right: -6px;
|
|
3321
|
-
border-bottom: 0;
|
|
3322
|
-
border-left: 0;
|
|
3323
|
-
}
|
|
3324
|
-
.spotpatch-dialog[data-placement="right"] .spotpatch-anchor {
|
|
3325
|
-
top: calc(var(--spotpatch-anchor-y) - 7px);
|
|
3326
|
-
left: -6px;
|
|
3327
|
-
border-top: 0;
|
|
3328
|
-
border-right: 0;
|
|
3329
|
-
}
|
|
3330
|
-
.spotpatch-dialog[data-placement="center"] .spotpatch-anchor,
|
|
3331
|
-
.spotpatch-dialog[data-placement="viewport"] .spotpatch-anchor { display: none; }
|
|
3332
3811
|
.spotpatch-shell {
|
|
3333
3812
|
position: relative;
|
|
3334
3813
|
z-index: 1;
|
|
3335
3814
|
display: flex;
|
|
3336
3815
|
box-sizing: border-box;
|
|
3337
|
-
max-height: min(${String(
|
|
3816
|
+
max-height: min(${String(FLOATING_SURFACE_LAYOUT.workbenchMaxHeight)}px, calc(100vh - ${String(FLOATING_SURFACE_LAYOUT.desktopInset * 2)}px));
|
|
3338
3817
|
overflow: hidden;
|
|
3339
3818
|
flex-direction: column;
|
|
3340
|
-
border: 1px solid var(--spotpatch-border);
|
|
3341
|
-
border-radius: var(--spotpatch-radius-panel);
|
|
3342
|
-
background: var(--spotpatch-bg);
|
|
3343
|
-
box-shadow: inset 0 1px rgb(255 255 255 / 5%), 0 0 60px -32px rgb(139 123 255 / 20%);
|
|
3344
|
-
}
|
|
3345
|
-
.spotpatch-shell::before {
|
|
3346
|
-
position: absolute;
|
|
3347
|
-
z-index: 2;
|
|
3348
|
-
top: 0;
|
|
3349
|
-
right: 20%;
|
|
3350
|
-
left: 20%;
|
|
3351
|
-
height: 1px;
|
|
3352
|
-
background: linear-gradient(90deg, transparent, var(--spotpatch-accent), var(--spotpatch-accent-cyan), transparent);
|
|
3353
|
-
content: "";
|
|
3354
|
-
opacity: .65;
|
|
3355
|
-
pointer-events: none;
|
|
3356
3819
|
}
|
|
3357
3820
|
.spotpatch-header {
|
|
3358
3821
|
position: relative;
|
|
3359
3822
|
padding: 0 18px 14px;
|
|
3360
3823
|
}
|
|
3824
|
+
.spotpatch-header[data-spotpatch-drag-handle] { cursor: grab; touch-action: none; user-select: none; }
|
|
3825
|
+
.spotpatch-header[data-dragging="true"] { cursor: grabbing; }
|
|
3826
|
+
.spotpatch-header button,
|
|
3827
|
+
.spotpatch-header a { cursor: pointer; user-select: auto; }
|
|
3361
3828
|
.spotpatch-brand-row {
|
|
3362
3829
|
display: flex;
|
|
3363
3830
|
align-items: center;
|
|
@@ -3381,18 +3848,6 @@ function createStyles(document) {
|
|
|
3381
3848
|
filter: drop-shadow(0 6px 12px rgb(76 29 149 / 22%));
|
|
3382
3849
|
}
|
|
3383
3850
|
.spotpatch-brand-copy { display: grid; min-width: 0; gap: 1px; }
|
|
3384
|
-
.spotpatch-brand-name {
|
|
3385
|
-
color: #fff;
|
|
3386
|
-
font-size: 13.5px;
|
|
3387
|
-
font-weight: 680;
|
|
3388
|
-
letter-spacing: -.01em;
|
|
3389
|
-
}
|
|
3390
|
-
.spotpatch-brand-context {
|
|
3391
|
-
color: #8e98aa;
|
|
3392
|
-
font-size: 10.5px;
|
|
3393
|
-
font-weight: 560;
|
|
3394
|
-
letter-spacing: .02em;
|
|
3395
|
-
}
|
|
3396
3851
|
.spotpatch-header-controls {
|
|
3397
3852
|
display: inline-flex;
|
|
3398
3853
|
align-items: center;
|
|
@@ -3401,6 +3856,7 @@ function createStyles(document) {
|
|
|
3401
3856
|
}
|
|
3402
3857
|
.spotpatch-repository,
|
|
3403
3858
|
.spotpatch-locale,
|
|
3859
|
+
.spotpatch-reset-position,
|
|
3404
3860
|
.spotpatch-close {
|
|
3405
3861
|
height: 27px;
|
|
3406
3862
|
border: 1px solid rgb(255 255 255 / 11%);
|
|
@@ -3424,6 +3880,16 @@ function createStyles(document) {
|
|
|
3424
3880
|
font-size: 12px;
|
|
3425
3881
|
font-weight: 650;
|
|
3426
3882
|
}
|
|
3883
|
+
.spotpatch-reset-position {
|
|
3884
|
+
display: inline-grid;
|
|
3885
|
+
width: 27px;
|
|
3886
|
+
padding: 0;
|
|
3887
|
+
place-items: center;
|
|
3888
|
+
color: #c5cad5;
|
|
3889
|
+
cursor: pointer;
|
|
3890
|
+
font-size: 15px;
|
|
3891
|
+
line-height: 1;
|
|
3892
|
+
}
|
|
3427
3893
|
.spotpatch-close {
|
|
3428
3894
|
display: inline-grid;
|
|
3429
3895
|
width: 27px;
|
|
@@ -3437,21 +3903,8 @@ function createStyles(document) {
|
|
|
3437
3903
|
}
|
|
3438
3904
|
.spotpatch-close:hover,
|
|
3439
3905
|
.spotpatch-locale:hover,
|
|
3906
|
+
.spotpatch-reset-position:hover,
|
|
3440
3907
|
.spotpatch-repository:hover { border-color: rgb(129 112 247 / 45%); color: #fff; background: rgb(109 93 246 / 10%); }
|
|
3441
|
-
.spotpatch-title {
|
|
3442
|
-
margin: 0;
|
|
3443
|
-
color: #fff;
|
|
3444
|
-
font-size: 18px;
|
|
3445
|
-
font-weight: 680;
|
|
3446
|
-
letter-spacing: -.015em;
|
|
3447
|
-
}
|
|
3448
|
-
.spotpatch-subtitle {
|
|
3449
|
-
max-width: 390px;
|
|
3450
|
-
margin: 4px 0 0;
|
|
3451
|
-
color: var(--spotpatch-text-secondary);
|
|
3452
|
-
font-size: 12.5px;
|
|
3453
|
-
line-height: 1.5;
|
|
3454
|
-
}
|
|
3455
3908
|
.spotpatch-target-row {
|
|
3456
3909
|
display: flex;
|
|
3457
3910
|
align-items: center;
|
|
@@ -3815,6 +4268,7 @@ function createStyles(document) {
|
|
|
3815
4268
|
.spotpatch-target-open:focus-visible,
|
|
3816
4269
|
.spotpatch-target-remove:focus-visible,
|
|
3817
4270
|
.spotpatch-close:focus-visible,
|
|
4271
|
+
.spotpatch-reset-position:focus-visible,
|
|
3818
4272
|
.spotpatch-trigger:focus-visible,
|
|
3819
4273
|
.spotpatch-target-select:focus-visible,
|
|
3820
4274
|
.spotpatch-target-editor textarea:focus-visible,
|
|
@@ -3839,8 +4293,8 @@ function createStyles(document) {
|
|
|
3839
4293
|
.spotpatch-diagnostics > summary::before { transition: none; }
|
|
3840
4294
|
}
|
|
3841
4295
|
@media (max-width: 520px) {
|
|
3842
|
-
.spotpatch-dialog {
|
|
3843
|
-
.spotpatch-shell { max-height: calc(
|
|
4296
|
+
.spotpatch-dialog { width: calc(100vw - 16px); }
|
|
4297
|
+
.spotpatch-shell { max-height: calc(100dvh - 16px); }
|
|
3844
4298
|
.spotpatch-header, .spotpatch-body { padding-left: 14px; padding-right: 14px; }
|
|
3845
4299
|
.spotpatch-brand-row { margin-right: -14px; margin-left: -14px; padding-right: 14px; padding-left: 14px; }
|
|
3846
4300
|
.spotpatch-actions { padding-right: 14px; padding-left: 14px; }
|
|
@@ -3856,6 +4310,38 @@ function summaryLine(summary, prefix) {
|
|
|
3856
4310
|
const line = summary.split("\n").find((candidate) => candidate.startsWith(`${prefix}: `));
|
|
3857
4311
|
return line?.slice(prefix.length + 2).trim();
|
|
3858
4312
|
}
|
|
4313
|
+
function startsOnInteractiveControl(event) {
|
|
4314
|
+
const target2 = event.target;
|
|
4315
|
+
return target2 instanceof Element && target2.closest(
|
|
4316
|
+
"a, button, input, select, textarea, summary, [contenteditable='true']"
|
|
4317
|
+
) !== null;
|
|
4318
|
+
}
|
|
4319
|
+
function createFallbackExecutionIsland(document) {
|
|
4320
|
+
const root = createButton(document, "", "spotpatch-execution-island");
|
|
4321
|
+
root.hidden = true;
|
|
4322
|
+
root.setAttribute("aria-hidden", "true");
|
|
4323
|
+
const logo = createBrandMark(
|
|
4324
|
+
document,
|
|
4325
|
+
void 0,
|
|
4326
|
+
"spotpatch-fallback-execution-island"
|
|
4327
|
+
);
|
|
4328
|
+
logo.classList.add("spotpatch-execution-logo");
|
|
4329
|
+
const copy = createMarkedElement(document, "span");
|
|
4330
|
+
root.append(logo, copy);
|
|
4331
|
+
return Object.freeze({
|
|
4332
|
+
canExpand: () => false,
|
|
4333
|
+
isExpanded: () => false,
|
|
4334
|
+
root,
|
|
4335
|
+
setExpanded: () => void 0,
|
|
4336
|
+
render(projection) {
|
|
4337
|
+
const text2 = [projection.headline, projection.action, projection.meta].filter((value) => value.length > 0).join(" \xB7 ");
|
|
4338
|
+
copy.textContent = text2;
|
|
4339
|
+
root.setAttribute("aria-label", text2);
|
|
4340
|
+
},
|
|
4341
|
+
dispose() {
|
|
4342
|
+
}
|
|
4343
|
+
});
|
|
4344
|
+
}
|
|
3859
4345
|
function createUnavailableDataFlowPanel(document, changesRoot, diagnosticsRoot) {
|
|
3860
4346
|
changesRoot.append(diagnosticsRoot);
|
|
3861
4347
|
return Object.freeze({
|
|
@@ -3869,10 +4355,33 @@ function createUnavailableDataFlowPanel(document, changesRoot, diagnosticsRoot)
|
|
|
3869
4355
|
}
|
|
3870
4356
|
function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: false }), localePreference = "auto", dataFlowEnabled = false, externalAgentEnabled = false, framework = "vite", sessionId = "") {
|
|
3871
4357
|
const localizer = createUiLocalizer(document, localePreference);
|
|
4358
|
+
const associatedWindow = document.defaultView;
|
|
4359
|
+
if (associatedWindow === null) {
|
|
4360
|
+
throw new Error("SpotPatch requires a document with an associated window.");
|
|
4361
|
+
}
|
|
4362
|
+
const runtimeWindow = associatedWindow;
|
|
4363
|
+
const floatingSurface = createFloatingSurfaceController(
|
|
4364
|
+
runtimeWindow,
|
|
4365
|
+
createFloatingSurfaceSession(runtimeWindow, sessionId),
|
|
4366
|
+
FLOATING_SURFACE_LAYOUT
|
|
4367
|
+
);
|
|
3872
4368
|
let messages = localizer.messages();
|
|
4369
|
+
let currentStatus = "idle";
|
|
4370
|
+
let plannerVisible = false;
|
|
4371
|
+
let executionSuppressed = false;
|
|
4372
|
+
let executionProjection;
|
|
4373
|
+
let pendingAgentMotion;
|
|
4374
|
+
let successSettleKey;
|
|
4375
|
+
let settledSuccessKey;
|
|
4376
|
+
let successSettleTimer;
|
|
4377
|
+
let observedExecutionStartedAt;
|
|
3873
4378
|
const host = document.createElement("spotpatch-root");
|
|
3874
4379
|
host.setAttribute(UI_MARKER_ATTRIBUTE, "");
|
|
3875
4380
|
const shadowRoot = host.attachShadow({ mode: "open" });
|
|
4381
|
+
const floatingSurfaceRoot = createMarkedElement(document, "div");
|
|
4382
|
+
floatingSurfaceRoot.className = "spotpatch-floating-surface";
|
|
4383
|
+
floatingSurfaceRoot.dataset.scene = "pill";
|
|
4384
|
+
floatingSurfaceRoot.dataset.tone = "neutral";
|
|
3876
4385
|
const triggerButton = createButton(
|
|
3877
4386
|
document,
|
|
3878
4387
|
messages.trigger.select,
|
|
@@ -3880,6 +4389,10 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3880
4389
|
);
|
|
3881
4390
|
triggerButton.title = messages.trigger.title(shortcut);
|
|
3882
4391
|
triggerButton.setAttribute("aria-pressed", "false");
|
|
4392
|
+
const motionExtension = getFloatingSurfaceMotionExtension();
|
|
4393
|
+
const motionExecutionIsland = motionExtension?.createExecutionIsland(document);
|
|
4394
|
+
const executionIslandView = motionExecutionIsland ?? createFallbackExecutionIsland(document);
|
|
4395
|
+
const executionIsland = executionIslandView.root;
|
|
3883
4396
|
const highlight = createMarkedElement(document, "div");
|
|
3884
4397
|
highlight.className = "spotpatch-highlight";
|
|
3885
4398
|
highlight.hidden = true;
|
|
@@ -3893,16 +4406,13 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3893
4406
|
dialog.className = "spotpatch-dialog";
|
|
3894
4407
|
dialog.hidden = true;
|
|
3895
4408
|
dialog.tabIndex = -1;
|
|
3896
|
-
dialog.dataset.placement = "viewport";
|
|
3897
4409
|
dialog.setAttribute("role", "dialog");
|
|
3898
4410
|
dialog.setAttribute("aria-labelledby", "spotpatch-selection-title");
|
|
3899
|
-
const anchor = createMarkedElement(document, "span");
|
|
3900
|
-
anchor.className = "spotpatch-anchor";
|
|
3901
|
-
anchor.setAttribute("aria-hidden", "true");
|
|
3902
4411
|
const shell = createMarkedElement(document, "div");
|
|
3903
4412
|
shell.className = "spotpatch-shell";
|
|
3904
4413
|
const header = createMarkedElement(document, "header");
|
|
3905
4414
|
header.className = "spotpatch-header";
|
|
4415
|
+
header.setAttribute("data-spotpatch-drag-handle", "");
|
|
3906
4416
|
const brandRow = createMarkedElement(document, "div");
|
|
3907
4417
|
brandRow.className = "spotpatch-brand-row";
|
|
3908
4418
|
const brand = createMarkedElement(document, "div");
|
|
@@ -3923,8 +4433,9 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3923
4433
|
repositoryLink.target = "_blank";
|
|
3924
4434
|
repositoryLink.rel = "noopener noreferrer";
|
|
3925
4435
|
const localeButton = createButton(document, "", "spotpatch-locale");
|
|
4436
|
+
const resetPositionButton = createButton(document, "\u2316", "spotpatch-reset-position");
|
|
3926
4437
|
const closeButton = createButton(document, "\xD7", "spotpatch-close");
|
|
3927
|
-
headerControls.append(repositoryLink, localeButton, closeButton);
|
|
4438
|
+
headerControls.append(repositoryLink, localeButton, resetPositionButton, closeButton);
|
|
3928
4439
|
brandRow.append(brand, headerControls);
|
|
3929
4440
|
const title = createMarkedElement(document, "h2");
|
|
3930
4441
|
title.id = "spotpatch-selection-title";
|
|
@@ -3984,13 +4495,20 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3984
4495
|
diagnostics.append(diagnosticsLabel, summary);
|
|
3985
4496
|
const agentPanel = createAgentPanel(document, ai, localizer);
|
|
3986
4497
|
const changesPanel = createMarkedElement(document, "div");
|
|
4498
|
+
function requestFloatingSurfaceLayout() {
|
|
4499
|
+
if (plannerVisible) {
|
|
4500
|
+
floatingSurface.requestReconcile();
|
|
4501
|
+
}
|
|
4502
|
+
}
|
|
3987
4503
|
const externalHandoffPanel = externalAgentEnabled ? getExternalHandoffExtension()?.createPanel(
|
|
3988
4504
|
document,
|
|
3989
4505
|
framework,
|
|
3990
4506
|
localizer.locale,
|
|
3991
4507
|
sessionId,
|
|
3992
4508
|
localizer.subscribe,
|
|
3993
|
-
|
|
4509
|
+
requestFloatingSurfaceLayout,
|
|
4510
|
+
renderExternalDispatch,
|
|
4511
|
+
renderExternalControl
|
|
3994
4512
|
) : void 0;
|
|
3995
4513
|
changesPanel.append(
|
|
3996
4514
|
targetsPanel,
|
|
@@ -4003,7 +4521,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4003
4521
|
localizer.locale,
|
|
4004
4522
|
changesPanel,
|
|
4005
4523
|
diagnostics,
|
|
4006
|
-
|
|
4524
|
+
requestFloatingSurfaceLayout
|
|
4007
4525
|
) ?? createUnavailableDataFlowPanel(document, changesPanel, diagnostics);
|
|
4008
4526
|
selectionPanel.append(dataFlowPanel.root);
|
|
4009
4527
|
const previewPanel = createMarkedElement(document, "div");
|
|
@@ -4059,13 +4577,14 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4059
4577
|
);
|
|
4060
4578
|
actions.append(editorFeedback, secondaryActions, primaryActions);
|
|
4061
4579
|
shell.append(header, body, actions);
|
|
4062
|
-
dialog.append(
|
|
4580
|
+
dialog.append(shell);
|
|
4063
4581
|
const liveRegion = createMarkedElement(document, "div");
|
|
4064
4582
|
liveRegion.className = "spotpatch-live";
|
|
4065
4583
|
liveRegion.setAttribute("aria-live", "polite");
|
|
4066
4584
|
liveRegion.setAttribute("aria-atomic", "true");
|
|
4067
4585
|
const styles2 = [
|
|
4068
4586
|
createStyles(document),
|
|
4587
|
+
...motionExtension === void 0 ? [] : [motionExtension.createStyles(document)],
|
|
4069
4588
|
dataFlowPanel.styles,
|
|
4070
4589
|
...externalHandoffPanel === void 0 ? [] : [externalHandoffPanel.styles]
|
|
4071
4590
|
];
|
|
@@ -4079,14 +4598,38 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4079
4598
|
...styles2,
|
|
4080
4599
|
selectionHighlights,
|
|
4081
4600
|
highlight,
|
|
4082
|
-
|
|
4083
|
-
triggerButton,
|
|
4601
|
+
floatingSurfaceRoot,
|
|
4084
4602
|
liveRegion
|
|
4085
4603
|
);
|
|
4604
|
+
floatingSurfaceRoot.append(triggerButton, dialog, executionIsland);
|
|
4086
4605
|
document.documentElement.append(host);
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4606
|
+
floatingSurface.registerSurface(floatingSurfaceRoot);
|
|
4607
|
+
const motionController = motionExtension === void 0 || motionExecutionIsland === void 0 ? void 0 : motionExtension.createController(
|
|
4608
|
+
document,
|
|
4609
|
+
Object.freeze({
|
|
4610
|
+
execution: motionExecutionIsland.elements,
|
|
4611
|
+
pill: triggerButton,
|
|
4612
|
+
planner: dialog,
|
|
4613
|
+
surface: floatingSurfaceRoot
|
|
4614
|
+
}),
|
|
4615
|
+
floatingSurface.reconcile
|
|
4616
|
+
);
|
|
4617
|
+
const cancelMotionOnDrag = () => {
|
|
4618
|
+
motionController?.cancel();
|
|
4619
|
+
};
|
|
4620
|
+
floatingSurface.attachDraggable(triggerButton, floatingSurfaceRoot, {
|
|
4621
|
+
onDragStart: cancelMotionOnDrag,
|
|
4622
|
+
suppressClickOnDrag: true
|
|
4623
|
+
});
|
|
4624
|
+
floatingSurface.attachDraggable(header, floatingSurfaceRoot, {
|
|
4625
|
+
canStartDrag: (event) => !floatingSurface.isCompact() && !startsOnInteractiveControl(event),
|
|
4626
|
+
onDragStart: cancelMotionOnDrag
|
|
4627
|
+
});
|
|
4628
|
+
floatingSurface.attachDraggable(executionIsland, floatingSurfaceRoot, {
|
|
4629
|
+
onDragStart: cancelMotionOnDrag,
|
|
4630
|
+
suppressClickOnDrag: true
|
|
4631
|
+
});
|
|
4632
|
+
floatingSurface.reconcile();
|
|
4090
4633
|
let currentCanOpenEditor = false;
|
|
4091
4634
|
let currentCanPreview = false;
|
|
4092
4635
|
let currentSummaryText = "";
|
|
@@ -4101,12 +4644,274 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4101
4644
|
page: Object.freeze({ status: dataFlowEnabled ? "idle" : "disabled" }),
|
|
4102
4645
|
observationCount: 0
|
|
4103
4646
|
});
|
|
4647
|
+
function currentTargetSummary() {
|
|
4648
|
+
const target2 = currentTargets.find((candidate) => candidate.active);
|
|
4649
|
+
return target2 === void 0 ? Object.freeze({
|
|
4650
|
+
label: messages.context.selectedElement,
|
|
4651
|
+
source: ""
|
|
4652
|
+
}) : Object.freeze({ label: target2.label, source: target2.source });
|
|
4653
|
+
}
|
|
4654
|
+
function currentTargetContext() {
|
|
4655
|
+
const target2 = currentTargetSummary();
|
|
4656
|
+
return target2.source.length === 0 ? target2.label : `${target2.label} \xB7 ${target2.source}`;
|
|
4657
|
+
}
|
|
4658
|
+
function beginObservedExecution() {
|
|
4659
|
+
observedExecutionStartedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4660
|
+
return observedExecutionStartedAt;
|
|
4661
|
+
}
|
|
4662
|
+
function observedExecutionStart() {
|
|
4663
|
+
return observedExecutionStartedAt ?? beginObservedExecution();
|
|
4664
|
+
}
|
|
4665
|
+
function clearSuccessSettle(resetKeys) {
|
|
4666
|
+
if (successSettleTimer !== void 0) {
|
|
4667
|
+
runtimeWindow.clearTimeout(successSettleTimer);
|
|
4668
|
+
successSettleTimer = void 0;
|
|
4669
|
+
}
|
|
4670
|
+
if (resetKeys) {
|
|
4671
|
+
successSettleKey = void 0;
|
|
4672
|
+
settledSuccessKey = void 0;
|
|
4673
|
+
}
|
|
4674
|
+
}
|
|
4675
|
+
function showSuccessUntilSettled(key) {
|
|
4676
|
+
if (settledSuccessKey === key) return false;
|
|
4677
|
+
if (successSettleKey === key) return true;
|
|
4678
|
+
clearSuccessSettle(false);
|
|
4679
|
+
successSettleKey = key;
|
|
4680
|
+
successSettleTimer = runtimeWindow.setTimeout(() => {
|
|
4681
|
+
successSettleTimer = void 0;
|
|
4682
|
+
if (!host.isConnected) return;
|
|
4683
|
+
settledSuccessKey = key;
|
|
4684
|
+
executionProjection = void 0;
|
|
4685
|
+
observedExecutionStartedAt = void 0;
|
|
4686
|
+
executionSuppressed = false;
|
|
4687
|
+
plannerVisible = false;
|
|
4688
|
+
renderFloatingSurfaceMotion();
|
|
4689
|
+
}, SUCCESS_SETTLE_MS);
|
|
4690
|
+
return true;
|
|
4691
|
+
}
|
|
4692
|
+
function externalAgentIdentity(kind) {
|
|
4693
|
+
return kind.startsWith("claude") ? messages.execution.claude : kind.startsWith("codex") ? messages.execution.codex : kind;
|
|
4694
|
+
}
|
|
4695
|
+
function projectAgentActivity(item) {
|
|
4696
|
+
return Object.freeze({
|
|
4697
|
+
...item.detail === void 0 ? {} : { detail: item.detail },
|
|
4698
|
+
key: item.key,
|
|
4699
|
+
kind: item.kind,
|
|
4700
|
+
label: messages.execution.activityLane(item.kind, item.detail),
|
|
4701
|
+
state: item.state
|
|
4702
|
+
});
|
|
4703
|
+
}
|
|
4704
|
+
function motionActivity(key, kind, detail, state = "active") {
|
|
4705
|
+
return Object.freeze({
|
|
4706
|
+
...detail === void 0 ? {} : { detail },
|
|
4707
|
+
key,
|
|
4708
|
+
kind,
|
|
4709
|
+
label: messages.execution.activityLane(kind, detail),
|
|
4710
|
+
state
|
|
4711
|
+
});
|
|
4712
|
+
}
|
|
4713
|
+
function renderFloatingSurfaceMotion() {
|
|
4714
|
+
const capturing = currentStatus === "inspecting";
|
|
4715
|
+
const pillActive = !plannerVisible || capturing;
|
|
4716
|
+
const projection = pillActive ? {
|
|
4717
|
+
scene: capturing ? "capturing" : "pill",
|
|
4718
|
+
tone: capturing ? "capturing" : "neutral",
|
|
4719
|
+
headline: triggerButton.textContent,
|
|
4720
|
+
action: "",
|
|
4721
|
+
meta: "",
|
|
4722
|
+
recentActivities: Object.freeze([])
|
|
4723
|
+
} : !executionSuppressed && executionProjection !== void 0 ? executionProjection : {
|
|
4724
|
+
scene: "planner",
|
|
4725
|
+
tone: "ready",
|
|
4726
|
+
headline: messages.dialog.editTitle,
|
|
4727
|
+
action: messages.dialog.editSubtitle,
|
|
4728
|
+
meta: messages.context.ready,
|
|
4729
|
+
recentActivities: Object.freeze([])
|
|
4730
|
+
};
|
|
4731
|
+
if (motionController !== void 0) {
|
|
4732
|
+
motionController.render(projection, () => {
|
|
4733
|
+
executionIslandView.render(projection);
|
|
4734
|
+
});
|
|
4735
|
+
return;
|
|
4736
|
+
}
|
|
4737
|
+
executionIslandView.render(projection);
|
|
4738
|
+
floatingSurfaceRoot.dataset.scene = projection.scene;
|
|
4739
|
+
floatingSurfaceRoot.dataset.tone = projection.tone;
|
|
4740
|
+
const plannerActive = projection.scene === "planner";
|
|
4741
|
+
triggerButton.hidden = !pillActive;
|
|
4742
|
+
triggerButton.inert = !pillActive;
|
|
4743
|
+
dialog.hidden = !plannerActive;
|
|
4744
|
+
dialog.inert = !plannerActive;
|
|
4745
|
+
dialog.setAttribute("aria-hidden", String(!plannerActive));
|
|
4746
|
+
executionIsland.hidden = pillActive || plannerActive;
|
|
4747
|
+
executionIsland.inert = pillActive || plannerActive;
|
|
4748
|
+
executionIsland.setAttribute("aria-hidden", String(pillActive || plannerActive));
|
|
4749
|
+
floatingSurface.reconcile();
|
|
4750
|
+
}
|
|
4751
|
+
function renderExternalDispatch(dispatch) {
|
|
4752
|
+
if (dispatch === null) {
|
|
4753
|
+
pendingAgentMotion = void 0;
|
|
4754
|
+
observedExecutionStartedAt = void 0;
|
|
4755
|
+
} else if (pendingAgentMotion !== void 0 && dispatch.phase !== "failed" && dispatch.phase !== "delivery-unknown") {
|
|
4756
|
+
startStagedAgentRequest();
|
|
4757
|
+
} else if (dispatch.phase === "failed" || dispatch.phase === "delivery-unknown") {
|
|
4758
|
+
pendingAgentMotion = void 0;
|
|
4759
|
+
}
|
|
4760
|
+
if (dispatch !== null && !executionSuppressed) {
|
|
4761
|
+
const failed = dispatch.phase === "failed" || dispatch.phase === "delivery-unknown";
|
|
4762
|
+
const completed = dispatch.phase === "completed";
|
|
4763
|
+
const startedAt = failed || completed ? void 0 : observedExecutionStart();
|
|
4764
|
+
if (failed || completed) observedExecutionStartedAt = void 0;
|
|
4765
|
+
const successKey = `dispatch:${String(dispatch.revision)}`;
|
|
4766
|
+
if (completed && !showSuccessUntilSettled(successKey)) {
|
|
4767
|
+
executionProjection = void 0;
|
|
4768
|
+
renderFloatingSurfaceMotion();
|
|
4769
|
+
return;
|
|
4770
|
+
}
|
|
4771
|
+
const identity = externalAgentIdentity(dispatch.adapterKind);
|
|
4772
|
+
const target2 = currentTargetSummary();
|
|
4773
|
+
const activityKind = dispatch.phase === "queued" || dispatch.phase === "dispatching" || dispatch.phase === "dispatched" ? "dispatch" : completed ? "sync" : "unknown";
|
|
4774
|
+
const activity = motionActivity(
|
|
4775
|
+
`dispatch:${String(dispatch.revision)}:${dispatch.phase}`,
|
|
4776
|
+
activityKind,
|
|
4777
|
+
dispatch.phase,
|
|
4778
|
+
failed ? "failure" : completed ? "success" : "active"
|
|
4779
|
+
);
|
|
4780
|
+
const scene = failed ? "failed" : completed ? "success" : dispatch.phase === "working" ? "running" : "handoff";
|
|
4781
|
+
executionProjection = {
|
|
4782
|
+
scene,
|
|
4783
|
+
tone: failed ? "danger" : completed ? "success" : "running",
|
|
4784
|
+
headline: completed ? messages.execution.completedTitle : failed ? messages.execution.failedTitle : scene === "running" ? messages.execution.runningTitle(target2.label) : messages.execution.dispatchingTitle(identity),
|
|
4785
|
+
action: completed ? messages.execution.resultReturned : target2.source,
|
|
4786
|
+
expandedHeadline: completed ? messages.execution.expandedCompletedTitle : failed ? messages.execution.failedTitle : scene === "running" ? messages.execution.expandedRunningTitle(identity) : messages.execution.dispatchingTitle(identity),
|
|
4787
|
+
expandedAction: completed ? messages.execution.resultReturned : currentTargetContext(),
|
|
4788
|
+
meta: failed ? messages.execution.failedStatus : completed ? messages.execution.completedStatus : scene === "running" ? messages.execution.runningStatus : messages.execution.dispatchingStatus,
|
|
4789
|
+
activity,
|
|
4790
|
+
recentActivities: Object.freeze([activity]),
|
|
4791
|
+
...startedAt === void 0 ? {} : { startedAt }
|
|
4792
|
+
};
|
|
4793
|
+
} else if (dispatch === null) {
|
|
4794
|
+
executionProjection = void 0;
|
|
4795
|
+
}
|
|
4796
|
+
renderFloatingSurfaceMotion();
|
|
4797
|
+
}
|
|
4798
|
+
function renderExternalControl(status) {
|
|
4799
|
+
const task = status?.task;
|
|
4800
|
+
if (status === void 0 || task === void 0 || executionSuppressed) return;
|
|
4801
|
+
const phase = task.managedPhase;
|
|
4802
|
+
const failed = phase === "failed" || phase === "cleanup-warning";
|
|
4803
|
+
const completed = phase === "completed" || phase === "review-required";
|
|
4804
|
+
const cancelled = phase === "cancelled";
|
|
4805
|
+
if (failed || cancelled) {
|
|
4806
|
+
pendingAgentMotion = void 0;
|
|
4807
|
+
} else if (pendingAgentMotion !== void 0) {
|
|
4808
|
+
startStagedAgentRequest();
|
|
4809
|
+
}
|
|
4810
|
+
if (cancelled) {
|
|
4811
|
+
executionProjection = void 0;
|
|
4812
|
+
observedExecutionStartedAt = void 0;
|
|
4813
|
+
renderFloatingSurfaceMotion();
|
|
4814
|
+
return;
|
|
4815
|
+
}
|
|
4816
|
+
const startedAt = failed || completed ? void 0 : observedExecutionStart();
|
|
4817
|
+
if (failed || completed) observedExecutionStartedAt = void 0;
|
|
4818
|
+
if (phase === "completed" && !showSuccessUntilSettled(`managed:${String(task.revision)}`)) {
|
|
4819
|
+
executionProjection = void 0;
|
|
4820
|
+
renderFloatingSurfaceMotion();
|
|
4821
|
+
return;
|
|
4822
|
+
}
|
|
4823
|
+
const scene = failed ? "failed" : completed ? "success" : phase === "preparing" ? "handoff" : "running";
|
|
4824
|
+
const tone = failed ? "danger" : completed ? "success" : "running";
|
|
4825
|
+
const identity = messages.execution.codex;
|
|
4826
|
+
const target2 = currentTargetSummary();
|
|
4827
|
+
const activityKind = phase === "preparing" ? "prepare" : phase === "auditing" ? "audit" : phase === "validating" ? "check" : phase === "applying" ? "apply" : completed ? "sync" : "unknown";
|
|
4828
|
+
const latestCheck = task.checks.at(-1);
|
|
4829
|
+
const latestFile = task.files.at(-1);
|
|
4830
|
+
const activityDetail = phase === "validating" ? latestCheck?.id : phase === "auditing" || phase === "applying" ? latestFile?.path : void 0;
|
|
4831
|
+
const activity = motionActivity(
|
|
4832
|
+
`managed:${String(task.revision)}:${phase}:${activityDetail ?? ""}`,
|
|
4833
|
+
activityKind,
|
|
4834
|
+
activityDetail,
|
|
4835
|
+
failed ? "failure" : completed ? "success" : "active"
|
|
4836
|
+
);
|
|
4837
|
+
const recentActivities = Object.freeze([
|
|
4838
|
+
...task.files.slice(-2).map(
|
|
4839
|
+
(file) => motionActivity(
|
|
4840
|
+
`managed-file:${String(task.revision)}:${file.path}`,
|
|
4841
|
+
"patch",
|
|
4842
|
+
file.path,
|
|
4843
|
+
"success"
|
|
4844
|
+
)
|
|
4845
|
+
),
|
|
4846
|
+
...task.checks.slice(-2).map(
|
|
4847
|
+
(check) => motionActivity(
|
|
4848
|
+
`managed-check:${String(task.revision)}:${check.id}`,
|
|
4849
|
+
"check",
|
|
4850
|
+
check.id,
|
|
4851
|
+
check.outcome === "passed" ? "success" : "failure"
|
|
4852
|
+
)
|
|
4853
|
+
),
|
|
4854
|
+
activity
|
|
4855
|
+
]);
|
|
4856
|
+
executionProjection = {
|
|
4857
|
+
scene,
|
|
4858
|
+
tone,
|
|
4859
|
+
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),
|
|
4860
|
+
action: completed ? task.files.length === 0 ? messages.execution.resultReturned : messages.execution.resultSummary(task.files.length) : target2.source,
|
|
4861
|
+
expandedHeadline: completed ? messages.execution.expandedCompletedTitle : failed ? messages.execution.failedTitle : scene === "handoff" ? messages.execution.dispatchingTitle(identity) : messages.execution.expandedRunningTitle(identity),
|
|
4862
|
+
expandedAction: completed ? messages.execution.resultReturned : currentTargetContext(),
|
|
4863
|
+
meta: failed ? messages.execution.failedStatus : completed ? messages.execution.completedStatus : phase === "validating" ? messages.execution.checkingStatus : scene === "handoff" ? messages.execution.dispatchingStatus : messages.execution.runningStatus,
|
|
4864
|
+
activity,
|
|
4865
|
+
recentActivities,
|
|
4866
|
+
...startedAt === void 0 ? {} : { startedAt }
|
|
4867
|
+
};
|
|
4868
|
+
renderFloatingSurfaceMotion();
|
|
4869
|
+
}
|
|
4870
|
+
function beginAgentRequest(target2, agentCard) {
|
|
4871
|
+
if (!plannerVisible) {
|
|
4872
|
+
return;
|
|
4873
|
+
}
|
|
4874
|
+
clearSuccessSettle(true);
|
|
4875
|
+
const startedAt = beginObservedExecution();
|
|
4876
|
+
executionSuppressed = false;
|
|
4877
|
+
const activity = motionActivity(
|
|
4878
|
+
`dispatch-start:${currentTargetContext()}`,
|
|
4879
|
+
"dispatch",
|
|
4880
|
+
currentTargetContext()
|
|
4881
|
+
);
|
|
4882
|
+
executionProjection = {
|
|
4883
|
+
scene: "agent-charging",
|
|
4884
|
+
tone: "running",
|
|
4885
|
+
headline: messages.execution.receivingTitle,
|
|
4886
|
+
action: currentTargetContext(),
|
|
4887
|
+
expandedHeadline: messages.execution.receivingTitle,
|
|
4888
|
+
expandedAction: currentTargetContext(),
|
|
4889
|
+
meta: messages.execution.receivingStatus,
|
|
4890
|
+
activity,
|
|
4891
|
+
recentActivities: Object.freeze([activity]),
|
|
4892
|
+
startedAt
|
|
4893
|
+
};
|
|
4894
|
+
renderFloatingSurfaceMotion();
|
|
4895
|
+
motionController?.dispatch(target2, agentCard);
|
|
4896
|
+
}
|
|
4897
|
+
function stageAgentRequest(source2, target2) {
|
|
4898
|
+
if (!plannerVisible || source2.disabled) return;
|
|
4899
|
+
pendingAgentMotion = Object.freeze({ source: source2, target: target2 });
|
|
4900
|
+
}
|
|
4901
|
+
function startStagedAgentRequest() {
|
|
4902
|
+
const pending = pendingAgentMotion;
|
|
4903
|
+
pendingAgentMotion = void 0;
|
|
4904
|
+
if (pending === void 0 || !pending.source.isConnected || !pending.target.isConnected) {
|
|
4905
|
+
return;
|
|
4906
|
+
}
|
|
4907
|
+
beginAgentRequest(pending.source, pending.target);
|
|
4908
|
+
}
|
|
4104
4909
|
function renderEditorStatus(state) {
|
|
4105
4910
|
currentEditorFeedbackState = state;
|
|
4106
4911
|
editorFeedback.dataset.state = state;
|
|
4107
4912
|
editorFeedback.hidden = state === "idle";
|
|
4108
4913
|
editorFeedback.textContent = state === "opening" ? messages.announcements.editorOpening : state === "success" ? messages.announcements.editorOpened : state === "error" ? messages.announcements.editorFailed : "";
|
|
4109
|
-
|
|
4914
|
+
requestFloatingSurfaceLayout();
|
|
4110
4915
|
}
|
|
4111
4916
|
function statusText(target2) {
|
|
4112
4917
|
if (target2.status === "ready") {
|
|
@@ -4241,6 +5046,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4241
5046
|
replacement?.setSelectionRange(selectionStart, selectionEnd);
|
|
4242
5047
|
}
|
|
4243
5048
|
}
|
|
5049
|
+
requestFloatingSurfaceLayout();
|
|
4244
5050
|
}
|
|
4245
5051
|
function updateTargetInstruction(targetId, instruction) {
|
|
4246
5052
|
currentTargets = currentTargets.map(
|
|
@@ -4289,8 +5095,6 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4289
5095
|
}
|
|
4290
5096
|
function showSelectionHighlights(targets) {
|
|
4291
5097
|
selectionHighlights.replaceChildren();
|
|
4292
|
-
activeSelectionRect = targets.find((target2) => target2.active)?.rect;
|
|
4293
|
-
currentRect = activeSelectionRect;
|
|
4294
5098
|
for (const [index, target2] of targets.entries()) {
|
|
4295
5099
|
const box = createMarkedElement(document, "div");
|
|
4296
5100
|
box.className = "spotpatch-selection-highlight";
|
|
@@ -4304,31 +5108,6 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4304
5108
|
box.append(label);
|
|
4305
5109
|
selectionHighlights.append(box);
|
|
4306
5110
|
}
|
|
4307
|
-
placeDialog();
|
|
4308
|
-
}
|
|
4309
|
-
function placeDialog() {
|
|
4310
|
-
if (dialog.hidden) {
|
|
4311
|
-
return;
|
|
4312
|
-
}
|
|
4313
|
-
const view = document.defaultView;
|
|
4314
|
-
const viewportWidth = view?.innerWidth ?? document.documentElement.clientWidth;
|
|
4315
|
-
const viewportHeight = view?.innerHeight ?? document.documentElement.clientHeight;
|
|
4316
|
-
const measured = dialog.getBoundingClientRect();
|
|
4317
|
-
const status = currentStatus === "previewing" ? "previewing" : "selected";
|
|
4318
|
-
const dialogWidth = measured.width > 0 ? measured.width : Math.min(DIALOG_MAX_WIDTH, viewportWidth - 32);
|
|
4319
|
-
const dialogHeight = measured.height > 0 ? measured.height : Math.min(DIALOG_FALLBACK_HEIGHT[status], viewportHeight - 32);
|
|
4320
|
-
const placement = calculateDialogPlacement({
|
|
4321
|
-
dialogWidth,
|
|
4322
|
-
dialogHeight,
|
|
4323
|
-
viewportWidth,
|
|
4324
|
-
viewportHeight,
|
|
4325
|
-
...currentRect === void 0 ? {} : { target: currentRect }
|
|
4326
|
-
});
|
|
4327
|
-
dialog.style.left = `${String(placement.left)}px`;
|
|
4328
|
-
dialog.style.top = `${String(placement.top)}px`;
|
|
4329
|
-
dialog.style.setProperty("--spotpatch-anchor-x", `${String(placement.anchorX)}px`);
|
|
4330
|
-
dialog.style.setProperty("--spotpatch-anchor-y", `${String(placement.anchorY)}px`);
|
|
4331
|
-
dialog.dataset.placement = placement.mode;
|
|
4332
5111
|
}
|
|
4333
5112
|
function updateContextOverview(summaryText) {
|
|
4334
5113
|
const summaryMessages = messages.summary;
|
|
@@ -4360,13 +5139,12 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4360
5139
|
agentPanel.setContextReady(canPreview);
|
|
4361
5140
|
externalHandoffPanel?.setContextReady(canPreview);
|
|
4362
5141
|
updateContextOverview(summaryText);
|
|
4363
|
-
|
|
5142
|
+
requestFloatingSurfaceLayout();
|
|
4364
5143
|
}
|
|
4365
5144
|
function renderPanelStatus(status) {
|
|
4366
5145
|
currentStatus = status;
|
|
4367
5146
|
const selected = status === "selected";
|
|
4368
5147
|
const previewing = status === "previewing";
|
|
4369
|
-
triggerButton.hidden = selected || previewing;
|
|
4370
5148
|
selectionPanel.hidden = !selected;
|
|
4371
5149
|
previewPanel.hidden = !previewing;
|
|
4372
5150
|
reselectButton.hidden = !selected;
|
|
@@ -4380,7 +5158,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4380
5158
|
backButton.hidden = !previewing;
|
|
4381
5159
|
title.textContent = previewing ? messages.dialog.previewTitle : messages.dialog.editTitle;
|
|
4382
5160
|
subtitle.textContent = previewing ? messages.dialog.previewSubtitle : messages.dialog.editSubtitle;
|
|
4383
|
-
|
|
5161
|
+
renderFloatingSurfaceMotion();
|
|
4384
5162
|
}
|
|
4385
5163
|
function applyMessages() {
|
|
4386
5164
|
messages = localizer.messages();
|
|
@@ -4392,8 +5170,14 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4392
5170
|
localeButton.textContent = messages.alternateLocaleName;
|
|
4393
5171
|
localeButton.title = messages.switchLocale;
|
|
4394
5172
|
localeButton.setAttribute("aria-label", messages.switchLocale);
|
|
5173
|
+
resetPositionButton.title = messages.floatingSurface.resetPosition;
|
|
5174
|
+
resetPositionButton.setAttribute(
|
|
5175
|
+
"aria-label",
|
|
5176
|
+
messages.floatingSurface.resetPosition
|
|
5177
|
+
);
|
|
4395
5178
|
closeButton.setAttribute("aria-label", messages.dialog.close);
|
|
4396
5179
|
closeButton.title = messages.dialog.close;
|
|
5180
|
+
header.title = messages.floatingSurface.dragHandle;
|
|
4397
5181
|
targetsPanel.setAttribute("aria-label", messages.targets.ariaLabel);
|
|
4398
5182
|
targetsTitle.textContent = messages.targets.title;
|
|
4399
5183
|
diagnosticsTitle.textContent = messages.diagnostics.title;
|
|
@@ -4429,8 +5213,58 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4429
5213
|
contextState.textContent = messages.context.collecting;
|
|
4430
5214
|
}
|
|
4431
5215
|
}
|
|
4432
|
-
|
|
5216
|
+
function announce(message) {
|
|
5217
|
+
liveRegion.textContent = "";
|
|
5218
|
+
liveRegion.textContent = message;
|
|
5219
|
+
}
|
|
5220
|
+
function resetFloatingSurfacePosition() {
|
|
5221
|
+
floatingSurface.reset();
|
|
5222
|
+
announce(messages.floatingSurface.positionReset);
|
|
5223
|
+
}
|
|
5224
|
+
diagnostics.addEventListener("toggle", requestFloatingSurfaceLayout);
|
|
4433
5225
|
localeButton.addEventListener("click", localizer.toggle);
|
|
5226
|
+
resetPositionButton.addEventListener("click", resetFloatingSurfacePosition);
|
|
5227
|
+
const onAgentRun = () => {
|
|
5228
|
+
stageAgentRequest(agentPanel.runButton, agentPanel.root);
|
|
5229
|
+
};
|
|
5230
|
+
const onExternalSend = () => {
|
|
5231
|
+
if (externalHandoffPanel !== void 0) {
|
|
5232
|
+
stageAgentRequest(externalHandoffPanel.sendButton, externalHandoffPanel.root);
|
|
5233
|
+
}
|
|
5234
|
+
};
|
|
5235
|
+
const onExecutionOpen = () => {
|
|
5236
|
+
if (executionIslandView.canExpand() && !executionIslandView.isExpanded()) {
|
|
5237
|
+
if (motionController === void 0) {
|
|
5238
|
+
executionIslandView.setExpanded(true);
|
|
5239
|
+
floatingSurface.reconcile();
|
|
5240
|
+
} else {
|
|
5241
|
+
motionController.updateLayout(() => {
|
|
5242
|
+
executionIslandView.setExpanded(true);
|
|
5243
|
+
});
|
|
5244
|
+
}
|
|
5245
|
+
return;
|
|
5246
|
+
}
|
|
5247
|
+
clearSuccessSettle(false);
|
|
5248
|
+
executionSuppressed = true;
|
|
5249
|
+
renderFloatingSurfaceMotion();
|
|
5250
|
+
};
|
|
5251
|
+
const onExecutionKeyDown = (event) => {
|
|
5252
|
+
if (event.key !== "Escape" || !executionIslandView.isExpanded()) return;
|
|
5253
|
+
event.preventDefault();
|
|
5254
|
+
event.stopPropagation();
|
|
5255
|
+
if (motionController === void 0) {
|
|
5256
|
+
executionIslandView.setExpanded(false);
|
|
5257
|
+
floatingSurface.reconcile();
|
|
5258
|
+
} else {
|
|
5259
|
+
motionController.updateLayout(() => {
|
|
5260
|
+
executionIslandView.setExpanded(false);
|
|
5261
|
+
});
|
|
5262
|
+
}
|
|
5263
|
+
};
|
|
5264
|
+
agentPanel.runButton.addEventListener("click", onAgentRun);
|
|
5265
|
+
externalHandoffPanel?.sendButton.addEventListener("click", onExternalSend);
|
|
5266
|
+
executionIsland.addEventListener("click", onExecutionOpen);
|
|
5267
|
+
executionIsland.addEventListener("keydown", onExecutionKeyDown);
|
|
4434
5268
|
const unsubscribeLocale = localizer.subscribe(applyMessages);
|
|
4435
5269
|
applyMessages();
|
|
4436
5270
|
return Object.freeze({
|
|
@@ -4460,6 +5294,11 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4460
5294
|
...externalHandoffPanel === void 0 ? {} : { externalHandoffPanel },
|
|
4461
5295
|
renderStatus(status) {
|
|
4462
5296
|
const inspecting = status === "inspecting";
|
|
5297
|
+
if (status === "idle" || inspecting) {
|
|
5298
|
+
plannerVisible = false;
|
|
5299
|
+
} else {
|
|
5300
|
+
plannerVisible = true;
|
|
5301
|
+
}
|
|
4463
5302
|
triggerButton.setAttribute("aria-pressed", String(inspecting));
|
|
4464
5303
|
triggerButton.textContent = inspecting ? messages.trigger.stop : messages.trigger.select;
|
|
4465
5304
|
renderPanelStatus(status);
|
|
@@ -4468,36 +5307,28 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4468
5307
|
renderDataFlow(state) {
|
|
4469
5308
|
currentDataFlowState = state;
|
|
4470
5309
|
dataFlowPanel.render(state);
|
|
4471
|
-
|
|
5310
|
+
requestFloatingSurfaceLayout();
|
|
4472
5311
|
},
|
|
4473
5312
|
showHighlight(rect, label) {
|
|
4474
|
-
currentRect = rect;
|
|
4475
5313
|
highlight.hidden = false;
|
|
4476
5314
|
highlight.style.transform = `translate(${String(rect.x)}px, ${String(rect.y)}px)`;
|
|
4477
5315
|
highlight.style.width = `${String(rect.width)}px`;
|
|
4478
5316
|
highlight.style.height = `${String(rect.height)}px`;
|
|
4479
5317
|
highlightLabel.textContent = label;
|
|
4480
5318
|
targetLabel.textContent = label;
|
|
4481
|
-
placeDialog();
|
|
4482
5319
|
},
|
|
4483
5320
|
hideHighlight() {
|
|
4484
|
-
currentRect = activeSelectionRect;
|
|
4485
5321
|
highlight.hidden = true;
|
|
4486
5322
|
highlightLabel.textContent = "";
|
|
4487
|
-
placeDialog();
|
|
4488
5323
|
},
|
|
4489
5324
|
showSelectionHighlights,
|
|
4490
5325
|
hideSelectionHighlights() {
|
|
4491
5326
|
selectionHighlights.replaceChildren();
|
|
4492
|
-
activeSelectionRect = void 0;
|
|
4493
|
-
currentRect = void 0;
|
|
4494
|
-
placeDialog();
|
|
4495
5327
|
},
|
|
4496
5328
|
showSelection(summaryText, canOpenEditor, canPreview) {
|
|
4497
5329
|
updateSelection(summaryText, canOpenEditor, canPreview);
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
placeDialog();
|
|
5330
|
+
plannerVisible = true;
|
|
5331
|
+
renderPanelStatus(currentStatus === "previewing" ? "previewing" : "selected");
|
|
4501
5332
|
},
|
|
4502
5333
|
updateSelection,
|
|
4503
5334
|
renderTargets,
|
|
@@ -4509,8 +5340,9 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4509
5340
|
externalHandoffPanel?.setContextReady(enabled);
|
|
4510
5341
|
},
|
|
4511
5342
|
hideSelection() {
|
|
4512
|
-
|
|
4513
|
-
|
|
5343
|
+
plannerVisible = false;
|
|
5344
|
+
executionSuppressed = false;
|
|
5345
|
+
executionProjection = void 0;
|
|
4514
5346
|
targetList.replaceChildren();
|
|
4515
5347
|
currentTargets = [];
|
|
4516
5348
|
currentMaximum = 0;
|
|
@@ -4536,14 +5368,17 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4536
5368
|
agentPanel.setEditingEnabled(true);
|
|
4537
5369
|
agentPanel.resetJob();
|
|
4538
5370
|
dataFlowPanel.resetView();
|
|
5371
|
+
renderFloatingSurfaceMotion();
|
|
4539
5372
|
},
|
|
4540
5373
|
hideSelectionTemporarily() {
|
|
4541
|
-
|
|
4542
|
-
|
|
5374
|
+
plannerVisible = false;
|
|
5375
|
+
executionSuppressed = false;
|
|
5376
|
+
executionProjection = void 0;
|
|
5377
|
+
renderFloatingSurfaceMotion();
|
|
4543
5378
|
},
|
|
4544
5379
|
showPreview(prompt) {
|
|
4545
5380
|
promptOutput.textContent = prompt;
|
|
4546
|
-
|
|
5381
|
+
requestFloatingSurfaceLayout();
|
|
4547
5382
|
},
|
|
4548
5383
|
readAgentSelection() {
|
|
4549
5384
|
return agentPanel.readSelection();
|
|
@@ -4567,25 +5402,86 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4567
5402
|
previewButton.disabled = !enabled || !currentCanPreview;
|
|
4568
5403
|
externalHandoffPanel?.setContextReady(enabled && currentCanPreview);
|
|
4569
5404
|
agentPanel.setEditingEnabled(enabled);
|
|
4570
|
-
|
|
5405
|
+
requestFloatingSurfaceLayout();
|
|
4571
5406
|
},
|
|
4572
5407
|
renderAgentCapability(state, message, capabilitySnapshot, errorCode) {
|
|
4573
5408
|
agentPanel.renderCapability(state, message, capabilitySnapshot, errorCode);
|
|
5409
|
+
if (state === "error") {
|
|
5410
|
+
pendingAgentMotion = void 0;
|
|
5411
|
+
renderFloatingSurfaceMotion();
|
|
5412
|
+
}
|
|
4574
5413
|
const agentReady = state === "ready" && capabilitySnapshot?.state === "agent-ready";
|
|
4575
5414
|
previewButton.classList.toggle("spotpatch-primary", !agentReady);
|
|
4576
|
-
|
|
5415
|
+
requestFloatingSurfaceLayout();
|
|
4577
5416
|
},
|
|
4578
5417
|
renderAgentWorkspaceHealth(state, snapshot, errorCode) {
|
|
4579
5418
|
agentPanel.renderWorkspaceHealth(state, snapshot, errorCode);
|
|
4580
|
-
|
|
5419
|
+
if (state === "blocked") {
|
|
5420
|
+
pendingAgentMotion = void 0;
|
|
5421
|
+
renderFloatingSurfaceMotion();
|
|
5422
|
+
}
|
|
5423
|
+
requestFloatingSurfaceLayout();
|
|
4581
5424
|
},
|
|
4582
5425
|
renderAgentJob(snapshot, result, activities, errorCode) {
|
|
4583
5426
|
agentPanel.renderJob(snapshot, result, activities, errorCode);
|
|
4584
|
-
|
|
5427
|
+
if (pendingAgentMotion !== void 0 && snapshot.status !== "failed" && snapshot.status !== "cancelled") {
|
|
5428
|
+
startStagedAgentRequest();
|
|
5429
|
+
}
|
|
5430
|
+
if (snapshot.status === "failed" || snapshot.status === "cancelled") {
|
|
5431
|
+
pendingAgentMotion = void 0;
|
|
5432
|
+
}
|
|
5433
|
+
const successful = snapshot.status === "awaiting-review" || snapshot.status === "applied" || snapshot.status === "completed" || snapshot.status === "reverted";
|
|
5434
|
+
const failed = snapshot.status === "failed";
|
|
5435
|
+
const cancelled = snapshot.status === "cancelled";
|
|
5436
|
+
const terminalSuccess = snapshot.status === "applied" || snapshot.status === "completed" || snapshot.status === "reverted";
|
|
5437
|
+
const scene = successful ? "success" : failed ? "failed" : snapshot.status === "queued" || snapshot.status === "preparing" ? "handoff" : "running";
|
|
5438
|
+
if (!executionSuppressed) {
|
|
5439
|
+
if (terminalSuccess && !showSuccessUntilSettled(`job:${snapshot.jobId}:${snapshot.status}`)) {
|
|
5440
|
+
executionProjection = void 0;
|
|
5441
|
+
renderFloatingSurfaceMotion();
|
|
5442
|
+
requestFloatingSurfaceLayout();
|
|
5443
|
+
return;
|
|
5444
|
+
}
|
|
5445
|
+
const identity = snapshot.providerLabel;
|
|
5446
|
+
const target2 = currentTargetSummary();
|
|
5447
|
+
const projectedActivities = Object.freeze(activities.map(projectAgentActivity));
|
|
5448
|
+
const latestActivity = activities.at(-1);
|
|
5449
|
+
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";
|
|
5450
|
+
const phaseActivity = motionActivity(
|
|
5451
|
+
`job-phase:${snapshot.jobId}:${snapshot.status}:${snapshot.updatedAt}`,
|
|
5452
|
+
phaseKind,
|
|
5453
|
+
void 0,
|
|
5454
|
+
successful ? "success" : failed ? "failure" : "active"
|
|
5455
|
+
);
|
|
5456
|
+
const activity = snapshot.status === "running" && latestActivity !== void 0 ? projectAgentActivity(latestActivity) : phaseActivity;
|
|
5457
|
+
executionProjection = cancelled ? void 0 : {
|
|
5458
|
+
scene,
|
|
5459
|
+
tone: successful ? "success" : failed ? "danger" : "running",
|
|
5460
|
+
headline: successful ? messages.execution.completedTitle : failed ? messages.execution.failedTitle : scene === "handoff" ? messages.execution.dispatchingTitle(identity) : snapshot.status === "validating" ? messages.execution.activityAction(
|
|
5461
|
+
"check",
|
|
5462
|
+
latestActivity?.detail
|
|
5463
|
+
) : snapshot.status === "applying" || snapshot.status === "reverting" ? messages.execution.activityAction(phaseKind) : messages.execution.runningTitle(target2.label),
|
|
5464
|
+
action: successful ? result === void 0 || result.files.length === 0 ? messages.execution.resultReturned : messages.execution.resultSummary(result.files.length) : latestActivity?.detail ?? target2.source,
|
|
5465
|
+
expandedHeadline: successful ? messages.execution.expandedCompletedTitle : failed ? messages.execution.failedTitle : scene === "handoff" ? messages.execution.dispatchingTitle(identity) : messages.execution.expandedRunningTitle(identity),
|
|
5466
|
+
expandedAction: successful ? result === void 0 || result.files.length === 0 ? messages.execution.resultReturned : messages.execution.resultSummary(result.files.length) : currentTargetContext(),
|
|
5467
|
+
meta: successful ? messages.execution.completedStatus : failed ? messages.execution.failedStatus : snapshot.status === "validating" ? messages.execution.checkingStatus : scene === "handoff" ? messages.execution.dispatchingStatus : messages.execution.runningStatus,
|
|
5468
|
+
activity,
|
|
5469
|
+
recentActivities: projectedActivities.length === 0 ? Object.freeze([phaseActivity]) : projectedActivities,
|
|
5470
|
+
startedAt: snapshot.createdAt
|
|
5471
|
+
};
|
|
5472
|
+
}
|
|
5473
|
+
renderFloatingSurfaceMotion();
|
|
5474
|
+
requestFloatingSurfaceLayout();
|
|
4585
5475
|
},
|
|
4586
5476
|
resetAgentJob() {
|
|
4587
5477
|
agentPanel.resetJob();
|
|
4588
|
-
|
|
5478
|
+
observedExecutionStartedAt = void 0;
|
|
5479
|
+
if (executionProjection !== void 0) {
|
|
5480
|
+
executionProjection = void 0;
|
|
5481
|
+
executionSuppressed = false;
|
|
5482
|
+
renderFloatingSurfaceMotion();
|
|
5483
|
+
}
|
|
5484
|
+
requestFloatingSurfaceLayout();
|
|
4589
5485
|
},
|
|
4590
5486
|
focusTargetInstruction(targetId) {
|
|
4591
5487
|
instructionInput(targetId)?.focus({ preventScroll: true });
|
|
@@ -4593,21 +5489,27 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4593
5489
|
focusPrompt() {
|
|
4594
5490
|
promptOutput.focus({ preventScroll: true });
|
|
4595
5491
|
},
|
|
4596
|
-
announce
|
|
4597
|
-
liveRegion.textContent = "";
|
|
4598
|
-
liveRegion.textContent = message;
|
|
4599
|
-
},
|
|
5492
|
+
announce,
|
|
4600
5493
|
locale: localizer.locale,
|
|
4601
5494
|
messages: localizer.messages,
|
|
4602
5495
|
agentWorkspaceConsentGranted: agentPanel.workspaceConsentGranted,
|
|
4603
5496
|
subscribeLocale: localizer.subscribe,
|
|
4604
5497
|
dispose() {
|
|
4605
|
-
diagnostics.removeEventListener("toggle",
|
|
5498
|
+
diagnostics.removeEventListener("toggle", requestFloatingSurfaceLayout);
|
|
4606
5499
|
localeButton.removeEventListener("click", localizer.toggle);
|
|
5500
|
+
resetPositionButton.removeEventListener("click", resetFloatingSurfacePosition);
|
|
5501
|
+
agentPanel.runButton.removeEventListener("click", onAgentRun);
|
|
5502
|
+
externalHandoffPanel?.sendButton.removeEventListener("click", onExternalSend);
|
|
5503
|
+
executionIsland.removeEventListener("click", onExecutionOpen);
|
|
5504
|
+
executionIsland.removeEventListener("keydown", onExecutionKeyDown);
|
|
4607
5505
|
unsubscribeLocale();
|
|
4608
5506
|
dataFlowPanel.dispose();
|
|
4609
5507
|
externalHandoffPanel?.dispose();
|
|
4610
5508
|
agentPanel.dispose();
|
|
5509
|
+
motionController?.dispose();
|
|
5510
|
+
executionIslandView.dispose();
|
|
5511
|
+
clearSuccessSettle(true);
|
|
5512
|
+
floatingSurface.dispose();
|
|
4611
5513
|
host.remove();
|
|
4612
5514
|
}
|
|
4613
5515
|
});
|
|
@@ -4674,17 +5576,33 @@ var import_shared8 = require("@spotpatch/shared");
|
|
|
4674
5576
|
function capabilityKey(providerProfileId, modelProfileId) {
|
|
4675
5577
|
return `${providerProfileId}:${modelProfileId}`;
|
|
4676
5578
|
}
|
|
5579
|
+
var TOOL_ACTIVITY_KIND = Object.freeze({
|
|
5580
|
+
list_files: "discover",
|
|
5581
|
+
search_text: "search",
|
|
5582
|
+
read_file: "read",
|
|
5583
|
+
replace_text: "patch",
|
|
5584
|
+
apply_patch: "patch",
|
|
5585
|
+
run_check: "check"
|
|
5586
|
+
});
|
|
5587
|
+
function toolActivityKind(toolName) {
|
|
5588
|
+
return TOOL_ACTIVITY_KIND[toolName] ?? "unknown";
|
|
5589
|
+
}
|
|
4677
5590
|
function activityFromEvent(event) {
|
|
4678
5591
|
if (event.type === "tool") {
|
|
5592
|
+
const detail = event.data.relativePath ?? event.data.checkLabel;
|
|
4679
5593
|
return Object.freeze({
|
|
4680
5594
|
key: `tool:${String(event.data.turn)}:${event.data.toolCallId}`,
|
|
4681
|
-
|
|
5595
|
+
kind: toolActivityKind(event.data.toolName),
|
|
5596
|
+
...detail === void 0 ? {} : { detail },
|
|
5597
|
+
label: `${event.data.toolName}${detail === void 0 ? "" : ` \xB7 ${detail}`} \xB7 ${event.data.state}`,
|
|
4682
5598
|
state: event.data.state === "started" ? "active" : event.data.state === "succeeded" ? "success" : "failure"
|
|
4683
5599
|
});
|
|
4684
5600
|
}
|
|
4685
5601
|
if (event.type === "check") {
|
|
4686
5602
|
return Object.freeze({
|
|
4687
5603
|
key: `check:${event.data.result.checkId}:${String(event.sequence)}`,
|
|
5604
|
+
kind: "check",
|
|
5605
|
+
detail: event.data.result.label,
|
|
4688
5606
|
label: `${event.data.result.label} \xB7 ${event.data.result.status}`,
|
|
4689
5607
|
state: event.data.result.status === "passed" ? "success" : event.data.result.status === "failed" || event.data.result.status === "timed-out" ? "failure" : "info"
|
|
4690
5608
|
});
|
|
@@ -6258,9 +7176,9 @@ function installWritableDataProperty(target2, key, replacement, original = ownPr
|
|
|
6258
7176
|
}
|
|
6259
7177
|
};
|
|
6260
7178
|
}
|
|
6261
|
-
function recordWithoutAffectingHost(
|
|
7179
|
+
function recordWithoutAffectingHost(record3) {
|
|
6262
7180
|
try {
|
|
6263
|
-
|
|
7181
|
+
record3();
|
|
6264
7182
|
} catch {
|
|
6265
7183
|
}
|
|
6266
7184
|
}
|