nudge-ui 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/agentCommand.js +4 -28
- package/dist/client.mjs +870 -212
- package/dist/hosts/next/wrapper.js +1 -7
- package/dist/hosts/projectBridge.js +3 -17
- package/dist/inspector/agent/McpConnectionDialog.js +7 -3
- package/dist/inspector/agent/activity.d.ts +1 -1
- package/dist/inspector/agent/activity.js +3 -2
- package/dist/inspector/agent/client.d.ts +2 -2
- package/dist/inspector/agent/client.js +28 -29
- package/dist/inspector/agent/connectionStatus.d.ts +3 -1
- package/dist/inspector/agent/connectionStatus.js +25 -0
- package/dist/inspector/agent/httpTransport.js +31 -147
- package/dist/inspector/agent/protocol.d.ts +1 -1
- package/dist/inspector/agent/protocol.js +1 -1
- package/dist/inspector/agent/verification.d.ts +5 -7
- package/dist/inspector/agent/verification.js +67 -20
- package/dist/inspector/boot.d.ts +3 -0
- package/dist/inspector/boot.js +297 -0
- package/dist/inspector/canvas/AgentActivityOverlay.d.ts +2 -1
- package/dist/inspector/canvas/AgentActivityOverlay.js +6 -3
- package/dist/inspector/canvas/CanvasCard.js +23 -12
- package/dist/inspector/canvas/CanvasElementOverlay.js +97 -128
- package/dist/inspector/canvas/CanvasToolbar.js +2 -1
- package/dist/inspector/canvas/CanvasWorkspace.js +119 -162
- package/dist/inspector/canvas/LockedWorkspaceNotice.d.ts +3 -2
- package/dist/inspector/canvas/LockedWorkspaceNotice.js +10 -6
- package/dist/inspector/canvas/PageCard.d.ts +10 -0
- package/dist/inspector/canvas/PageCard.js +51 -0
- package/dist/inspector/canvas/SketchToolOptions.d.ts +5 -0
- package/dist/inspector/canvas/SketchToolOptions.js +86 -0
- package/dist/inspector/canvas/StaleChangeIndicator.d.ts +1 -1
- package/dist/inspector/canvas/StaleChangeIndicator.js +1 -1
- package/dist/inspector/canvas/ToolOptionsDrawer.d.ts +21 -0
- package/dist/inspector/canvas/ToolOptionsDrawer.js +77 -0
- package/dist/inspector/canvas/activeCanvasDocument.d.ts +3 -2
- package/dist/inspector/canvas/assets/eraser.svg +28 -0
- package/dist/inspector/canvas/assets/pen.svg +25 -0
- package/dist/inspector/canvas/canvasFrame.d.ts +16 -0
- package/dist/inspector/canvas/canvasFrame.js +10 -0
- package/dist/inspector/canvas/canvasGestures.d.ts +0 -1
- package/dist/inspector/canvas/canvasGestures.js +0 -6
- package/dist/inspector/canvas/canvasStore.d.ts +6 -0
- package/dist/inspector/canvas/canvasStore.js +36 -1
- package/dist/inspector/canvas/frameConnection.d.ts +48 -0
- package/dist/inspector/canvas/frameConnection.js +73 -0
- package/dist/inspector/canvas/frameProtocol.d.ts +18 -1
- package/dist/inspector/canvas/frameProtocol.js +36 -0
- package/dist/inspector/canvas/frameScrollbarStyles.d.ts +3 -0
- package/dist/inspector/canvas/frameScrollbarStyles.js +21 -0
- package/dist/inspector/canvas/pageSurface.d.ts +11 -0
- package/dist/inspector/canvas/pageSurface.js +34 -0
- package/dist/inspector/canvas/projection.d.ts +19 -9
- package/dist/inspector/canvas/projection.js +58 -31
- package/dist/inspector/canvas/rendererBootstrap.js +4 -1
- package/dist/inspector/canvas/rendererElementSelector.js +9 -1
- package/dist/inspector/canvas/rendererMessageRouter.d.ts +4 -5
- package/dist/inspector/canvas/rendererMessageRouter.js +12 -16
- package/dist/inspector/canvas/rendererSelectionProxy.d.ts +7 -1
- package/dist/inspector/canvas/rendererSelectionProxy.js +8 -36
- package/dist/inspector/canvas/rendererStylesheet.js +15 -0
- package/dist/inspector/canvas/sessionStore.d.ts +2 -2
- package/dist/inspector/canvas/sessionStore.js +12 -9
- package/dist/inspector/canvas/staleChangeDetector.d.ts +1 -1
- package/dist/inspector/canvas/staleChangeDetector.js +10 -22
- package/dist/inspector/changes/codecs.d.ts +2 -0
- package/dist/inspector/changes/codecs.js +27 -3
- package/dist/inspector/changes/draftPreview.d.ts +12 -0
- package/dist/inspector/changes/draftPreview.js +133 -0
- package/dist/inspector/changes/editModel.d.ts +18 -0
- package/dist/inspector/changes/editModel.js +16 -3
- package/dist/inspector/changes/managedStyleProjection.js +2 -1
- package/dist/inspector/changes/previewDiagnostics.js +1 -1
- package/dist/inspector/changes/types.d.ts +18 -1
- package/dist/inspector/comments/CommentsOverlay.js +18 -16
- package/dist/inspector/comments/element.js +10 -3
- package/dist/inspector/comments/store.js +3 -2
- package/dist/inspector/comments/verification.js +1 -1
- package/dist/inspector/componentSemantics/ComponentPropsSection.js +2 -1
- package/dist/inspector/componentSemantics/adapterRegistry.d.ts +6 -1
- package/dist/inspector/componentSemantics/adapterRegistry.js +23 -1
- package/dist/inspector/componentSemantics/changeAction.js +1 -1
- package/dist/inspector/componentSemantics/reactRuntime.d.ts +2 -1
- package/dist/inspector/componentSemantics/reactRuntime.js +38 -0
- package/dist/inspector/componentSemantics/runtimeBridge.d.ts +4 -2
- package/dist/inspector/componentSemantics/runtimeBridge.js +17 -0
- package/dist/inspector/componentSemantics/textBinding.d.ts +1 -2
- package/dist/inspector/componentSemantics/textBinding.js +4 -45
- package/dist/inspector/componentSemantics/types.d.ts +11 -0
- package/dist/inspector/drafts/draftStore.d.ts +109 -0
- package/dist/inspector/drafts/draftStore.js +451 -0
- package/dist/inspector/drafts/model.d.ts +9 -1
- package/dist/inspector/drafts/model.js +5 -1
- package/dist/inspector/drafts/store.d.ts +53 -15
- package/dist/inspector/drafts/store.js +143 -169
- package/dist/inspector/index.d.ts +2 -4
- package/dist/inspector/index.js +2 -264
- package/dist/inspector/inline-text/inlineTextEditor.d.ts +1 -1
- package/dist/inspector/inline-text/inlineTextEditor.js +1 -2
- package/dist/inspector/inline-text/textEditChange.d.ts +1 -1
- package/dist/inspector/inspection/bridge.d.ts +1 -1
- package/dist/inspector/inspection/bridge.js +2 -1
- package/dist/inspector/inspection/browserCssInspection.d.ts +8 -0
- package/dist/inspector/inspection/browserCssInspection.js +28 -6
- package/dist/inspector/inspection/inspectionSnapshot.d.ts +6 -0
- package/dist/inspector/inspection/inspectionSnapshot.js +10 -0
- package/dist/inspector/inspection/performanceDiagnostics.d.ts +18 -0
- package/dist/inspector/inspection/performanceDiagnostics.js +31 -0
- package/dist/inspector/inspection/useBrowserCssInspection.js +17 -38
- package/dist/inspector/iterations/capture.d.ts +2 -1
- package/dist/inspector/iterations/capture.js +2 -1
- package/dist/inspector/iterations/client.d.ts +2 -1
- package/dist/inspector/iterations/coordinator.d.ts +4 -3
- package/dist/inspector/iterations/coordinator.js +5 -3
- package/dist/inspector/iterations/prompt.js +9 -8
- package/dist/inspector/overlay/interactionStyles.js +17 -0
- package/dist/inspector/pageInspector.d.ts +42 -0
- package/dist/inspector/pageInspector.js +342 -0
- package/dist/inspector/projection/draftProjection.d.ts +10 -2
- package/dist/inspector/projection/draftProjection.js +9 -1
- package/dist/inspector/projection/managedStylesheet.js +24 -4
- package/dist/inspector/projection/renderedInstance.d.ts +15 -2
- package/dist/inspector/projection/renderedInstance.js +60 -7
- package/dist/inspector/projection/structuralProjection.d.ts +0 -9
- package/dist/inspector/projection/structuralProjection.js +16 -46
- package/dist/inspector/projection/textProjection.d.ts +8 -2
- package/dist/inspector/projection/textProjection.js +77 -24
- package/dist/inspector/prompt/clipboardHandoff.d.ts +14 -0
- package/dist/inspector/prompt/clipboardHandoff.js +47 -16
- package/dist/inspector/prompt/generatePrompt.d.ts +1 -1
- package/dist/inspector/prompt/generatePrompt.js +248 -148
- package/dist/inspector/prompt/promptDocument.d.ts +3 -0
- package/dist/inspector/prompt/promptDocument.js +8 -0
- package/dist/inspector/prompt/promptSettings.js +7 -5
- package/dist/inspector/runtime/inspectorStorage.d.ts +17 -0
- package/dist/inspector/runtime/inspectorStorage.js +42 -0
- package/dist/inspector/runtime/ownedStylesheets.d.ts +20 -0
- package/dist/inspector/runtime/ownedStylesheets.js +72 -0
- package/dist/inspector/runtime/runtimeConfig.d.ts +4 -0
- package/dist/inspector/runtime/runtimeConfig.js +10 -1
- package/dist/inspector/runtime/runtimeIdentityClaims.d.ts +29 -0
- package/dist/inspector/runtime/runtimeIdentityClaims.js +188 -0
- package/dist/inspector/runtime/staticHtmlRuntimeIdentity.d.ts +15 -0
- package/dist/inspector/runtime/staticHtmlRuntimeIdentity.js +113 -29
- package/dist/inspector/selection/editScope.d.ts +1 -0
- package/dist/inspector/selection/editScope.js +13 -2
- package/dist/inspector/selection/sourceSite.d.ts +12 -0
- package/dist/inspector/selection/sourceSite.js +28 -0
- package/dist/inspector/shell/AgentStatusButton.js +2 -2
- package/dist/inspector/shell/AppShell.js +6 -2
- package/dist/inspector/shell/ChangesLog.js +27 -9
- package/dist/inspector/shell/CopyPromptButton.js +74 -26
- package/dist/inspector/shell/EmptyState.js +3 -3
- package/dist/inspector/shell/InspectorShell.d.ts +0 -3
- package/dist/inspector/shell/InspectorShell.js +21 -13
- package/dist/inspector/shell/PeekOriginalButton.js +3 -3
- package/dist/inspector/shell/interactionStatePreview.d.ts +9 -0
- package/dist/inspector/shell/interactionStatePreview.js +112 -0
- package/dist/inspector/shell/originalPreview.d.ts +3 -2
- package/dist/inspector/shell/originalPreview.js +10 -37
- package/dist/inspector/shell/stateValue.js +2 -3
- package/dist/inspector/sketch/SketchEditor.js +5 -4
- package/dist/inspector/sketch/SketchFrameOverlay.d.ts +2 -1
- package/dist/inspector/sketch/SketchFrameOverlay.js +5 -4
- package/dist/inspector/sketch/SketchOverlay.d.ts +3 -5
- package/dist/inspector/sketch/SketchOverlay.js +139 -263
- package/dist/inspector/sketch/SketchPromptPanel.d.ts +1 -1
- package/dist/inspector/sketch/SketchPromptPanel.js +8 -1
- package/dist/inspector/sketch/SketchThumbnail.d.ts +5 -0
- package/dist/inspector/sketch/SketchThumbnail.js +18 -0
- package/dist/inspector/sketch/SketchWorkspace.d.ts +1 -2
- package/dist/inspector/sketch/SketchWorkspace.js +69 -34
- package/dist/inspector/sketch/capture.js +19 -3
- package/dist/inspector/sketch/copySketch.d.ts +10 -0
- package/dist/inspector/sketch/copySketch.js +52 -0
- package/dist/inspector/sketch/drawingTools.d.ts +17 -0
- package/dist/inspector/sketch/drawingTools.js +47 -0
- package/dist/inspector/sketch/frameHeading.d.ts +9 -0
- package/dist/inspector/sketch/frameHeading.js +30 -0
- package/dist/inspector/sketch/freehand.js +3 -3
- package/dist/inspector/sketch/geometry.d.ts +6 -0
- package/dist/inspector/sketch/geometry.js +19 -0
- package/dist/inspector/sketch/history.d.ts +30 -0
- package/dist/inspector/sketch/history.js +58 -0
- package/dist/inspector/sketch/interaction.d.ts +1 -3
- package/dist/inspector/sketch/interaction.js +6 -9
- package/dist/inspector/sketch/model.d.ts +35 -1
- package/dist/inspector/sketch/model.js +116 -61
- package/dist/inspector/sketch/persistence.d.ts +14 -0
- package/dist/inspector/sketch/persistence.js +63 -7
- package/dist/inspector/sketch/raster.d.ts +6 -2
- package/dist/inspector/sketch/raster.js +43 -17
- package/dist/inspector/sketch/store.d.ts +1 -1
- package/dist/inspector/sketch/store.js +1 -1
- package/dist/inspector/sketch/videoFrames.d.ts +6 -0
- package/dist/inspector/sketch/videoFrames.js +81 -0
- package/dist/inspector/styleEditors/BackgroundEditor.js +3 -2
- package/dist/inspector/styleEditors/BorderEditor.js +30 -130
- package/dist/inspector/styleEditors/BorderRadiusEditor.js +8 -3
- package/dist/inspector/styleEditors/ImageBackgroundEditor.js +1 -1
- package/dist/inspector/styleEditors/LayoutSection.js +2 -2
- package/dist/inspector/styleEditors/borderModel.d.ts +42 -0
- package/dist/inspector/styleEditors/borderModel.js +114 -0
- package/dist/inspector/styleEditors/layoutValue.js +2 -3
- package/dist/inspector/tokens/TokenField.js +40 -7
- package/dist/inspector/tokens/TokensPanel.js +2 -1
- package/dist/inspector/tokens/editActions.d.ts +3 -3
- package/dist/inspector/tokens/editActions.js +15 -3
- package/dist/inspector/tokens/resolution/containerQueryEvaluator.d.ts +15 -0
- package/dist/inspector/tokens/resolution/containerQueryEvaluator.js +86 -0
- package/dist/inspector/tokens/resolution/cssomCollector.js +44 -9
- package/dist/inspector/tokens/resolution/nestedSelectors.d.ts +6 -0
- package/dist/inspector/tokens/resolution/nestedSelectors.js +67 -0
- package/dist/inspector/tokens/resolution/ruleMatching.js +23 -4
- package/dist/inspector/tokens/resolution.d.ts +6 -3
- package/dist/inspector/tokens/resolution.js +91 -112
- package/dist/inspector/tokens/tokenEdits.d.ts +1 -1
- package/dist/inspector/tokens/tokenEdits.js +1 -1
- package/dist/inspector/ui/InlineStyleWarning.js +2 -2
- package/dist/inspector/ui/InspectorStyle.d.ts +8 -0
- package/dist/inspector/ui/InspectorStyle.js +26 -0
- package/dist/inspector/ui/PopoverListbox.d.ts +2 -1
- package/dist/inspector/ui/PopoverListbox.js +3 -3
- package/dist/inspector/ui/Toast.d.ts +14 -0
- package/dist/inspector/ui/Toast.js +30 -0
- package/dist/inspector/ui/assets/canvasIllustration.d.ts +2 -0
- package/dist/inspector/ui/assets/canvasIllustration.js +21 -0
- package/dist/inspector/ui/assets/gridIllustration.d.ts +2 -0
- package/dist/inspector/ui/assets/{grid.svg → gridIllustration.js} +3 -2
- package/dist/inspector/ui/customCursors.d.ts +5 -0
- package/dist/inspector/ui/customCursors.js +32 -6
- package/dist/inspector/ui/styles.js +12 -10
- package/dist/inspector/workspace/commands.js +1 -2
- package/dist/inspector/workspace/controller.js +1 -2
- package/dist/inspector/workspace/handoff.js +3 -2
- package/dist/inspector/workspace/sentItems.d.ts +16 -0
- package/dist/inspector/workspace/sentItems.js +33 -0
- package/dist/inspector/workspace/timeline.d.ts +24 -10
- package/dist/inspector/workspace/timeline.js +118 -96
- package/dist/internal/agent-protocol.d.ts +50 -13
- package/dist/internal/agent-protocol.js +145 -19
- package/dist/nudge-ui.mjs +81 -65
- package/dist/project/mcpPackage.d.ts +8 -0
- package/dist/project/mcpPackage.js +60 -0
- package/package.json +13 -3
- package/dist/inspector/canvas/measurementProjection.d.ts +0 -8
- package/dist/inspector/canvas/measurementProjection.js +0 -16
- package/dist/inspector/changes/changesLog.d.ts +0 -47
- package/dist/inspector/changes/changesLog.js +0 -247
- package/dist/inspector/changes/draftChanges.d.ts +0 -56
- package/dist/inspector/changes/draftChanges.js +0 -300
- package/dist/inspector/conformance/projection.d.ts +0 -2
- package/dist/inspector/conformance/projection.js +0 -3
- package/dist/inspector/inline-text/textChangeBoundary.d.ts +0 -6
- package/dist/inspector/inline-text/textChangeBoundary.js +0 -1
- package/dist/inspector/overlay/InspectorOverlay.d.ts +0 -5
- package/dist/inspector/overlay/InspectorOverlay.js +0 -332
- package/dist/inspector/overlay/elementSelector.d.ts +0 -1
- package/dist/inspector/overlay/elementSelector.js +0 -111
- package/dist/inspector/sketch/SketchChanges.d.ts +0 -2
- package/dist/inspector/sketch/SketchChanges.js +0 -72
- package/dist/inspector/sketch/SketchEntryButton.d.ts +0 -4
- package/dist/inspector/sketch/SketchEntryButton.js +0 -11
- package/dist/inspector/sketch/SketchLayersPanel.d.ts +0 -2
- package/dist/inspector/sketch/SketchLayersPanel.js +0 -71
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AGENT_PROTOCOL_VERSION,
|
|
1
|
+
import { AGENT_PROTOCOL_VERSION, decodeAgentStatusSnapshot, decodeBridgeEvent, decodePairingResponse, decodePromptDispatchResponse, } from "./protocol.js";
|
|
2
2
|
import { getActiveCanvasDocument } from "../canvas/activeCanvasDocument.js";
|
|
3
3
|
function isRecord(value) {
|
|
4
4
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -27,8 +27,7 @@ function configuredEndpointInDocument(doc) {
|
|
|
27
27
|
const target = doc.defaultView;
|
|
28
28
|
if (!target)
|
|
29
29
|
return undefined;
|
|
30
|
-
const globalConfig = endpointValue(target.__NUDGE_UI_AGENT_BRIDGE__)
|
|
31
|
-
?? endpointValue(target.__NUDGE_UI_AGENT__);
|
|
30
|
+
const globalConfig = endpointValue(target.__NUDGE_UI_AGENT_BRIDGE__);
|
|
32
31
|
if (globalConfig)
|
|
33
32
|
return globalConfig;
|
|
34
33
|
const meta = doc.querySelector('meta[name="nudge-ui-agent-bridge"]');
|
|
@@ -75,12 +74,12 @@ function safeUrl(value, origin) {
|
|
|
75
74
|
return null;
|
|
76
75
|
}
|
|
77
76
|
}
|
|
78
|
-
|
|
77
|
+
/** Null when the host published no endpoint; the browser never guesses a bridge port. */
|
|
78
|
+
function endpointUrl(config, key, fallbackPath, origin) {
|
|
79
79
|
const explicit = config[key];
|
|
80
80
|
if (explicit && key !== "baseUrl")
|
|
81
81
|
return safeUrl(explicit, origin);
|
|
82
|
-
const
|
|
83
|
-
const base = safeUrl(baseValue, origin);
|
|
82
|
+
const base = config.baseUrl ? safeUrl(config.baseUrl, origin) : null;
|
|
84
83
|
if (!base)
|
|
85
84
|
return null;
|
|
86
85
|
base.pathname = `${base.pathname.replace(/\/$/, "")}${fallbackPath}`;
|
|
@@ -123,83 +122,6 @@ async function readJson(response) {
|
|
|
123
122
|
}
|
|
124
123
|
return isRecord(payload) ? payload : {};
|
|
125
124
|
}
|
|
126
|
-
function statusPayload(value) {
|
|
127
|
-
if (!isRecord(value))
|
|
128
|
-
return null;
|
|
129
|
-
const status = isRecord(value.status) ? value.status : value;
|
|
130
|
-
if (typeof status.projectId !== "string"
|
|
131
|
-
|| (status.connection !== "offline"
|
|
132
|
-
&& status.connection !== "listening"
|
|
133
|
-
&& status.connection !== "paired"
|
|
134
|
-
&& status.connection !== "working")
|
|
135
|
-
|| typeof status.listenerActive !== "boolean"
|
|
136
|
-
|| typeof status.paired !== "boolean")
|
|
137
|
-
return null;
|
|
138
|
-
if (status.protocolVersion !== undefined && status.protocolVersion !== AGENT_PROTOCOL_VERSION)
|
|
139
|
-
return null;
|
|
140
|
-
const rawRequest = status.request;
|
|
141
|
-
let request = null;
|
|
142
|
-
if (rawRequest !== null && rawRequest !== undefined) {
|
|
143
|
-
if (!isRecord(rawRequest)
|
|
144
|
-
|| (rawRequest.status !== "working"
|
|
145
|
-
&& rawRequest.status !== "completed"
|
|
146
|
-
&& rawRequest.status !== "failed"
|
|
147
|
-
&& rawRequest.status !== "interrupted"))
|
|
148
|
-
return null;
|
|
149
|
-
const requestCandidate = {
|
|
150
|
-
requestId: rawRequest.requestId,
|
|
151
|
-
projectId: rawRequest.projectId,
|
|
152
|
-
prompt: rawRequest.prompt,
|
|
153
|
-
...(typeof rawRequest.changeRevision === "number" ? { changeRevision: rawRequest.changeRevision } : {}),
|
|
154
|
-
...(rawRequest.clientDispatchId === undefined ? {} : { clientDispatchId: rawRequest.clientDispatchId }),
|
|
155
|
-
...(rawRequest.sketches === undefined ? {} : { sketches: rawRequest.sketches }),
|
|
156
|
-
};
|
|
157
|
-
if (!isAgentPromptRequest(requestCandidate))
|
|
158
|
-
return null;
|
|
159
|
-
request = {
|
|
160
|
-
...requestCandidate,
|
|
161
|
-
status: rawRequest.status,
|
|
162
|
-
...(typeof rawRequest.summary === "string" ? { summary: rawRequest.summary } : {}),
|
|
163
|
-
...(typeof rawRequest.error === "string" ? { error: rawRequest.error } : {}),
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
return {
|
|
167
|
-
protocolVersion: AGENT_PROTOCOL_VERSION,
|
|
168
|
-
projectId: status.projectId,
|
|
169
|
-
connection: status.connection,
|
|
170
|
-
listenerActive: status.listenerActive,
|
|
171
|
-
...(typeof status.agentClientName === "string" ? { agentClientName: status.agentClientName.slice(0, 120) } : {}),
|
|
172
|
-
paired: status.paired,
|
|
173
|
-
request,
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
function eventPayload(value) {
|
|
177
|
-
if (!isRecord(value))
|
|
178
|
-
return null;
|
|
179
|
-
const envelope = value;
|
|
180
|
-
const event = isRecord(envelope.event) ? envelope.event : value;
|
|
181
|
-
const type = stringValue(event.type);
|
|
182
|
-
if (type === "status") {
|
|
183
|
-
const status = statusPayload(event.status);
|
|
184
|
-
return status ? { type: "status", status } : null;
|
|
185
|
-
}
|
|
186
|
-
if (type === "connected") {
|
|
187
|
-
const status = statusPayload(event.status);
|
|
188
|
-
return status ? { type: "connected", status } : null;
|
|
189
|
-
}
|
|
190
|
-
if (type === "disconnected") {
|
|
191
|
-
return { type: "disconnected", ...(stringValue(event.reason) ? { reason: stringValue(event.reason) } : {}) };
|
|
192
|
-
}
|
|
193
|
-
if (type === "activity" && isAgentActivity(event.activity))
|
|
194
|
-
return { type: "activity", activity: event.activity };
|
|
195
|
-
if (type === "canvas-command" && isRecord(event.command)) {
|
|
196
|
-
// The Canvas controller owns command validation. Preserve the shared
|
|
197
|
-
// shape here so the parent stage can consume this event without a second
|
|
198
|
-
// protocol vocabulary.
|
|
199
|
-
return { type: "canvas-command", command: event.command };
|
|
200
|
-
}
|
|
201
|
-
return null;
|
|
202
|
-
}
|
|
203
125
|
function eventData(event) {
|
|
204
126
|
if (typeof event.data !== "string")
|
|
205
127
|
return event.data;
|
|
@@ -223,7 +145,7 @@ export class HttpAgentBridgeTransport {
|
|
|
223
145
|
this.config = config;
|
|
224
146
|
}
|
|
225
147
|
async discover(request, signal) {
|
|
226
|
-
const url = endpointUrl(this.config,
|
|
148
|
+
const url = endpointUrl(this.config, "healthUrl", "/health", pageOrigin());
|
|
227
149
|
if (!url || typeof fetch !== "function")
|
|
228
150
|
return null;
|
|
229
151
|
const response = await fetch(withQuery(url, {
|
|
@@ -238,10 +160,10 @@ export class HttpAgentBridgeTransport {
|
|
|
238
160
|
|| payload.projectId !== request.projectId
|
|
239
161
|
|| (payload.origin !== undefined && payload.origin !== null && payload.origin !== request.origin))
|
|
240
162
|
return null;
|
|
241
|
-
return
|
|
163
|
+
return decodeAgentStatusSnapshot(payload.status);
|
|
242
164
|
}
|
|
243
165
|
async pair(request, signal) {
|
|
244
|
-
const url = endpointUrl(this.config,
|
|
166
|
+
const url = endpointUrl(this.config, "pairUrl", "/pair", pageOrigin());
|
|
245
167
|
if (!url || typeof fetch !== "function")
|
|
246
168
|
throw new Error("Agent bridge is unavailable.");
|
|
247
169
|
const response = await fetch(url, {
|
|
@@ -250,26 +172,13 @@ export class HttpAgentBridgeTransport {
|
|
|
250
172
|
body: JSON.stringify(request),
|
|
251
173
|
signal,
|
|
252
174
|
});
|
|
253
|
-
const
|
|
254
|
-
if (
|
|
255
|
-
|| payload.projectId !== request.projectId
|
|
256
|
-
|| payload.origin !== request.origin
|
|
257
|
-
|| typeof payload.sessionToken !== "string") {
|
|
175
|
+
const pairing = decodePairingResponse(await readJson(response), request);
|
|
176
|
+
if (!pairing)
|
|
258
177
|
throw new Error("Agent bridge returned an invalid pairing response.");
|
|
259
|
-
|
|
260
|
-
const status = statusPayload(payload.status);
|
|
261
|
-
if (!status)
|
|
262
|
-
throw new Error("Agent bridge returned an invalid status.");
|
|
263
|
-
return {
|
|
264
|
-
protocolVersion: AGENT_PROTOCOL_VERSION,
|
|
265
|
-
projectId: request.projectId,
|
|
266
|
-
origin: request.origin,
|
|
267
|
-
sessionToken: payload.sessionToken,
|
|
268
|
-
status,
|
|
269
|
-
};
|
|
178
|
+
return pairing;
|
|
270
179
|
}
|
|
271
180
|
async takeOver(request, signal) {
|
|
272
|
-
const url = endpointUrl(this.config,
|
|
181
|
+
const url = endpointUrl(this.config, "takeoverUrl", "/takeover", pageOrigin());
|
|
273
182
|
if (!url || typeof fetch !== "function")
|
|
274
183
|
throw new Error("Agent bridge is unavailable.");
|
|
275
184
|
const response = await fetch(url, {
|
|
@@ -278,42 +187,26 @@ export class HttpAgentBridgeTransport {
|
|
|
278
187
|
body: JSON.stringify(request),
|
|
279
188
|
signal,
|
|
280
189
|
});
|
|
281
|
-
const
|
|
282
|
-
if (
|
|
283
|
-
|| payload.projectId !== request.projectId
|
|
284
|
-
|| payload.origin !== request.origin
|
|
285
|
-
|| typeof payload.sessionToken !== "string") {
|
|
190
|
+
const pairing = decodePairingResponse(await readJson(response), request);
|
|
191
|
+
if (!pairing)
|
|
286
192
|
throw new Error("Agent bridge returned an invalid takeover response.");
|
|
287
|
-
|
|
288
|
-
const status = statusPayload(payload.status);
|
|
289
|
-
if (!status)
|
|
290
|
-
throw new Error("Agent bridge returned an invalid status.");
|
|
291
|
-
return {
|
|
292
|
-
protocolVersion: AGENT_PROTOCOL_VERSION,
|
|
293
|
-
projectId: request.projectId,
|
|
294
|
-
origin: request.origin,
|
|
295
|
-
sessionToken: payload.sessionToken,
|
|
296
|
-
status,
|
|
297
|
-
};
|
|
193
|
+
return pairing;
|
|
298
194
|
}
|
|
299
195
|
async restore(request, signal) {
|
|
300
|
-
const url = endpointUrl(this.config,
|
|
196
|
+
const url = endpointUrl(this.config, "statusUrl", "/status", pageOrigin());
|
|
301
197
|
if (!url || typeof fetch !== "function")
|
|
302
198
|
return null;
|
|
303
199
|
const response = await fetch(withQuery(url, {
|
|
304
200
|
projectId: request.projectId,
|
|
305
201
|
sessionToken: request.sessionToken,
|
|
306
202
|
}), { method: "GET", headers: headers(), signal });
|
|
307
|
-
const
|
|
308
|
-
if (
|
|
309
|
-
return null;
|
|
310
|
-
const status = statusPayload(payload);
|
|
311
|
-
if (!status || !status.paired)
|
|
203
|
+
const status = decodeAgentStatusSnapshot(await readJson(response));
|
|
204
|
+
if (!status || status.projectId !== request.projectId || !status.paired)
|
|
312
205
|
return null;
|
|
313
206
|
return status;
|
|
314
207
|
}
|
|
315
208
|
openEvents(request, handlers) {
|
|
316
|
-
const url = endpointUrl(this.config,
|
|
209
|
+
const url = endpointUrl(this.config, "eventsUrl", "/events", pageOrigin());
|
|
317
210
|
if (!url || typeof EventSource !== "function") {
|
|
318
211
|
queueMicrotask(() => handlers.onDisconnect("Agent event transport is unavailable."));
|
|
319
212
|
return { close: () => undefined };
|
|
@@ -325,10 +218,13 @@ export class HttpAgentBridgeTransport {
|
|
|
325
218
|
const source = new EventSource(eventUrl.href);
|
|
326
219
|
let closed = false;
|
|
327
220
|
const handleMessage = (event) => {
|
|
328
|
-
const
|
|
329
|
-
if (isRecord(
|
|
221
|
+
const envelope = eventData(event);
|
|
222
|
+
if (!isRecord(envelope)
|
|
223
|
+
|| envelope.protocolVersion !== AGENT_PROTOCOL_VERSION
|
|
224
|
+
|| envelope.projectId !== request.projectId
|
|
225
|
+
|| envelope.sessionToken !== request.sessionToken)
|
|
330
226
|
return;
|
|
331
|
-
const parsed =
|
|
227
|
+
const parsed = decodeBridgeEvent(envelope.event);
|
|
332
228
|
if (parsed)
|
|
333
229
|
handlers.onEvent(parsed);
|
|
334
230
|
};
|
|
@@ -355,7 +251,7 @@ export class HttpAgentBridgeTransport {
|
|
|
355
251
|
};
|
|
356
252
|
}
|
|
357
253
|
async dispatch(request, signal) {
|
|
358
|
-
const url = endpointUrl(this.config,
|
|
254
|
+
const url = endpointUrl(this.config, "promptUrl", "/prompt", pageOrigin());
|
|
359
255
|
if (!url || typeof fetch !== "function")
|
|
360
256
|
throw new Error("Agent bridge is unavailable.");
|
|
361
257
|
const response = await fetch(url, {
|
|
@@ -364,25 +260,13 @@ export class HttpAgentBridgeTransport {
|
|
|
364
260
|
body: JSON.stringify(request),
|
|
365
261
|
signal,
|
|
366
262
|
});
|
|
367
|
-
const
|
|
368
|
-
if (!
|
|
263
|
+
const dispatched = decodePromptDispatchResponse(await readJson(response), request.projectId);
|
|
264
|
+
if (!dispatched)
|
|
369
265
|
throw new Error("Agent bridge returned an invalid prompt response.");
|
|
370
|
-
|
|
371
|
-
const requestCandidate = {
|
|
372
|
-
requestId: payload.request.requestId,
|
|
373
|
-
projectId: payload.request.projectId,
|
|
374
|
-
prompt: payload.request.prompt,
|
|
375
|
-
...(typeof payload.request.changeRevision === "number" ? { changeRevision: payload.request.changeRevision } : {}),
|
|
376
|
-
...(payload.request.clientDispatchId === undefined ? {} : { clientDispatchId: payload.request.clientDispatchId }),
|
|
377
|
-
...(payload.request.sketches === undefined ? {} : { sketches: payload.request.sketches }),
|
|
378
|
-
};
|
|
379
|
-
if (!isAgentPromptRequest(requestCandidate) || requestCandidate.projectId !== request.projectId) {
|
|
380
|
-
throw new Error("Agent bridge returned an invalid prompt response.");
|
|
381
|
-
}
|
|
382
|
-
return { request: requestCandidate, status: "working" };
|
|
266
|
+
return dispatched;
|
|
383
267
|
}
|
|
384
268
|
async disconnect(request, signal) {
|
|
385
|
-
const url = endpointUrl(this.config,
|
|
269
|
+
const url = endpointUrl(this.config, "disconnectUrl", "/disconnect", pageOrigin());
|
|
386
270
|
if (!url || typeof fetch !== "function")
|
|
387
271
|
return;
|
|
388
272
|
await fetch(url, {
|
|
@@ -393,7 +277,7 @@ export class HttpAgentBridgeTransport {
|
|
|
393
277
|
});
|
|
394
278
|
}
|
|
395
279
|
async acknowledgeCanvasCommand(request, signal) {
|
|
396
|
-
const url = endpointUrl(this.config,
|
|
280
|
+
const url = endpointUrl(this.config, "canvasAckUrl", "/canvas/ack", pageOrigin());
|
|
397
281
|
if (!url || typeof fetch !== "function")
|
|
398
282
|
return;
|
|
399
283
|
await fetch(url, {
|
|
@@ -7,7 +7,7 @@ import type { AgentActivity, AgentStatusSnapshot, CanvasCommand, CanvasCommandAc
|
|
|
7
7
|
* boundary local lets inspector tests use a deterministic fake while the
|
|
8
8
|
* companion remains the owner of MCP and Node-specific code.
|
|
9
9
|
*/
|
|
10
|
-
export { AGENT_PROTOCOL_LIMITS, AGENT_PROTOCOL_VERSION,
|
|
10
|
+
export { AGENT_PROTOCOL_LIMITS, AGENT_PROTOCOL_VERSION, CANVAS_COMMAND_TYPES, canonicalOrigin, decodeAgentStatusSnapshot, decodeBridgeEvent, decodePairingResponse, decodePromptDispatchResponse, deriveConnectionState, isAgentPromptRequest, isAgentSketchAttachment, isAgentSketchAnnotation, isAgentSketchCaptureMetadata, isAgentSketchMetadata, isAgentStatusUpdate, isAgentActivity, isAllowedOrigin, isCanvasCommand, isCanvasGroup, isCanvasState, isCanonicalOrigin, isProjectIdentity, isSameOriginRoute, protocolError, validateSketchAttachments, validateRoutes, } from "../../internal/agent-protocol.js";
|
|
11
11
|
export type { AgentActivity, BridgeActivityEvent, AgentConnectionState, AgentProjectIdentity, AgentPromptRequest, AgentDeliveredPrompt, AgentSketchAttachment, AgentSketchAnnotation, AgentSketchCaptureMetadata, AgentSketchMetadata, AgentRequestOutcome, AgentRequestStatus, AgentRoute, AgentStatusSnapshot, AgentStatusUpdate, BridgeCanvasCommandEvent, BridgeConnectedEvent, BridgeDisconnectedEvent, BridgeEnvelope, BridgeEvent, BridgeEventType, BridgeStatusEvent, CanvasCommand, CanvasCommandAcknowledgement, CanvasCommandError, CanvasCommandResult, CanvasGroup, CanvasGroupOwner, CanvasState, FitCanvasCommand, FocusCanvasGroupCommand, PairingRequest, PairingResponse, PresentRoutesCommand, PromptDispatchRequest, PromptDispatchResponse, ReadCanvasStateCommand, RemoveCanvasGroupCommand, StatusEventRequest, AgentProtocolVersion, } from "../../internal/agent-protocol.js";
|
|
12
12
|
export interface AgentBridgeEndpointConfig {
|
|
13
13
|
readonly baseUrl?: string;
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
* boundary local lets inspector tests use a deterministic fake while the
|
|
7
7
|
* companion remains the owner of MCP and Node-specific code.
|
|
8
8
|
*/
|
|
9
|
-
export { AGENT_PROTOCOL_LIMITS, AGENT_PROTOCOL_VERSION,
|
|
9
|
+
export { AGENT_PROTOCOL_LIMITS, AGENT_PROTOCOL_VERSION, CANVAS_COMMAND_TYPES, canonicalOrigin, decodeAgentStatusSnapshot, decodeBridgeEvent, decodePairingResponse, decodePromptDispatchResponse, deriveConnectionState, isAgentPromptRequest, isAgentSketchAttachment, isAgentSketchAnnotation, isAgentSketchCaptureMetadata, isAgentSketchMetadata, isAgentStatusUpdate, isAgentActivity, isAllowedOrigin, isCanvasCommand, isCanvasGroup, isCanvasState, isCanonicalOrigin, isProjectIdentity, isSameOriginRoute, protocolError, validateSketchAttachments, validateRoutes, } from "../../internal/agent-protocol.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type DraftTarget } from "../drafts/model.js";
|
|
2
|
-
import { type ChangeRecord } from "../changes/
|
|
2
|
+
import { type ChangeRecord } from "../changes/types.js";
|
|
3
3
|
import { type StructuralChange } from "../projection/structuralProjection.js";
|
|
4
4
|
export interface HandoffOwner {
|
|
5
5
|
readonly draftId: string;
|
|
@@ -13,12 +13,6 @@ export interface HandoffSnapshot {
|
|
|
13
13
|
readonly changes: readonly ChangeRecord[];
|
|
14
14
|
readonly structuralChanges: readonly StructuralChange[];
|
|
15
15
|
}
|
|
16
|
-
/**
|
|
17
|
-
* User-facing agent completion state, named once.
|
|
18
|
-
* "completed" means the agent finished; "verified" means completed work was
|
|
19
|
-
* positively reconciled against source-rendered output.
|
|
20
|
-
*/
|
|
21
|
-
export type AgentCompletionStatus = "completed" | "verified";
|
|
22
16
|
/** Stable, preview-metadata-free identity for one prompt handoff record. */
|
|
23
17
|
export declare function handoffChangeFingerprint(change: ChangeRecord): string;
|
|
24
18
|
/** Stable identity for one structural record included in a prompt handoff. */
|
|
@@ -43,6 +37,10 @@ export declare function getAgentDispatchSize(revision: number): number;
|
|
|
43
37
|
*/
|
|
44
38
|
export declare function verifyAndReconcileHandoff(snapshot: HandoffSnapshot, doc?: Document | null): Promise<number>;
|
|
45
39
|
export declare function documentBelongsToHandoff(doc: Document, owner: HandoffOwner): boolean;
|
|
40
|
+
/** Returns the records captured for one dispatch until it is reconciled. */
|
|
41
|
+
export declare function getAgentDispatch(revision: number): HandoffSnapshot | null;
|
|
42
|
+
/** Records in the owner draft that still equal what a handoff sent. */
|
|
43
|
+
export declare function unchangedHandoffRecords(snapshot: HandoffSnapshot): Pick<HandoffSnapshot, "changes" | "structuralChanges">;
|
|
46
44
|
/** Reconciles the captured records for one completed connected-agent request. */
|
|
47
45
|
export declare function verifyAndReconcileAgentDispatch(revision: number): Promise<number>;
|
|
48
46
|
/** Test/session reset for in-memory dispatch snapshots. */
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { draftIdForCard } from "../drafts/store.js";
|
|
1
|
+
import { draftIdForCard, getActiveDraftChanges, getDraftChanges, reconcileDraftChanges } from "../drafts/store.js";
|
|
2
2
|
import { getCanvasCards } from "../canvas/canvasStore.js";
|
|
3
3
|
import { getRegisteredFrames, getCanvasCardIdForDocument } from "../canvas/projection.js";
|
|
4
4
|
import { applicationTarget, targetFromKey, targetKey } from "../drafts/model.js";
|
|
5
5
|
import { changeKey, tokenReference } from "../changes/model.js";
|
|
6
6
|
import { selectorForManagedChange } from "../changes/managedStyleProjection.js";
|
|
7
|
-
import {
|
|
8
|
-
import { isComponentChange, isTextContentChange, isTokenChange, } from "../changes/changesLog.js";
|
|
7
|
+
import { isComponentChange, isTextContentChange, isTokenChange, } from "../changes/types.js";
|
|
9
8
|
import { verifyPreview } from "../projection/managedStylesheet.js";
|
|
10
|
-
import {
|
|
9
|
+
import { resolveMovedRenderedInstance } from "../projection/renderedInstance.js";
|
|
10
|
+
import { relocateSourceSite, sourceSiteSelector } from "../selection/sourceSite.js";
|
|
11
|
+
import { boundRuntimeEvidence, normalizeRuntimeTag } from "../runtime/staticHtmlRuntimeIdentity.js";
|
|
11
12
|
import { documentStateKey, } from "../projection/structuralProjection.js";
|
|
12
13
|
import { resolveTextProjectionTarget, resolveTextProjectionTextNode, } from "../projection/textProjection.js";
|
|
13
14
|
import { applyHostDraftProjection, compileDraftProjection, } from "../projection/draftProjection.js";
|
|
@@ -48,32 +49,60 @@ function requestedStyleValue(change) {
|
|
|
48
49
|
return tokenReference(change.newToken);
|
|
49
50
|
return change.rawValue ?? "";
|
|
50
51
|
}
|
|
51
|
-
function
|
|
52
|
-
if (!isTokenChange(change) && (change.state ?? "base") !== "base")
|
|
53
|
-
return false;
|
|
54
|
-
const selector = selectorForManagedChange(change);
|
|
52
|
+
function queryTargets(doc, selector) {
|
|
55
53
|
if (!selector)
|
|
56
|
-
return
|
|
57
|
-
let targets;
|
|
54
|
+
return [];
|
|
58
55
|
try {
|
|
59
|
-
|
|
56
|
+
return Array.from(doc.querySelectorAll(selector));
|
|
60
57
|
}
|
|
61
58
|
catch {
|
|
62
|
-
return
|
|
59
|
+
return [];
|
|
63
60
|
}
|
|
61
|
+
}
|
|
62
|
+
/** Resolves current style targets, following a source site whose position shifted. */
|
|
63
|
+
function styleTargets(change, doc) {
|
|
64
|
+
if (isTokenChange(change))
|
|
65
|
+
return queryTargets(doc, change.selector);
|
|
66
|
+
// The projection marker is lifted for verification; evidence names the instance.
|
|
67
|
+
if (change.scope === "rendered-instance") {
|
|
68
|
+
const resolved = change.instanceOverride
|
|
69
|
+
? resolveMovedRenderedInstance(doc, change.instanceOverride.target)
|
|
70
|
+
: null;
|
|
71
|
+
return resolved?.status === "resolved" ? [resolved.element] : [];
|
|
72
|
+
}
|
|
73
|
+
const targets = queryTargets(doc, selectorForManagedChange(change));
|
|
74
|
+
const evidence = change.sourceEvidence;
|
|
75
|
+
if (targets.length > 0 || !evidence || change.column === undefined)
|
|
76
|
+
return targets;
|
|
77
|
+
const site = relocateSourceSite(doc, { cid: change.cid, src: `${change.file}:${change.line}:${change.column}` }, (element) => normalizeRuntimeTag(element.tagName) === evidence.tagName
|
|
78
|
+
&& boundRuntimeEvidence(element.getAttribute("data-cprops")) === evidence.props);
|
|
79
|
+
return site ? queryTargets(doc, sourceSiteSelector(site.cid, site.src)) : [];
|
|
80
|
+
}
|
|
81
|
+
function verifyStyle(change, doc) {
|
|
82
|
+
if (!isTokenChange(change) && (change.state ?? "base") !== "base")
|
|
83
|
+
return false;
|
|
84
|
+
const targets = styleTargets(change, doc);
|
|
64
85
|
const requested = requestedStyleValue(change);
|
|
65
86
|
return requested.length > 0
|
|
66
87
|
&& targets.length > 0
|
|
67
88
|
&& targets.every((target) => verifyPreview(target, change.property, requested).status === "applied");
|
|
68
89
|
}
|
|
69
90
|
function verifyText(change, doc) {
|
|
70
|
-
|
|
91
|
+
let target = change.target;
|
|
92
|
+
let resolved = resolveTextProjectionTarget(doc, target, change.after);
|
|
93
|
+
if (resolved.status === "missing") {
|
|
94
|
+
const sourceSite = relocateSourceSite(doc, target.sourceSite, (element) => element.getAttribute("data-cprops") === target.props && element.getAttribute("aria-label") === target.ariaLabel);
|
|
95
|
+
if (sourceSite) {
|
|
96
|
+
target = { ...target, sourceSite };
|
|
97
|
+
resolved = resolveTextProjectionTarget(doc, target, change.after);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
71
100
|
if (resolved.status !== "resolved")
|
|
72
101
|
return false;
|
|
73
|
-
const node = resolveTextProjectionTextNode(resolved.element,
|
|
102
|
+
const node = resolveTextProjectionTextNode(resolved.element, target, change.after);
|
|
74
103
|
if (node)
|
|
75
104
|
return node.nodeValue === change.after;
|
|
76
|
-
return
|
|
105
|
+
return target.textNodePath === undefined
|
|
77
106
|
&& change.after.length === 0
|
|
78
107
|
&& (resolved.element.textContent ?? "") === "";
|
|
79
108
|
}
|
|
@@ -97,7 +126,7 @@ function verifyStructuralDelete(change, doc) {
|
|
|
97
126
|
}
|
|
98
127
|
return currentRoute === change.route
|
|
99
128
|
&& documentStateKey(doc) === change.state
|
|
100
|
-
&&
|
|
129
|
+
&& resolveMovedRenderedInstance(doc, change.target).status === "missing";
|
|
101
130
|
}
|
|
102
131
|
/**
|
|
103
132
|
* A move verifies when the element sits at its recorded destination without
|
|
@@ -106,17 +135,17 @@ function verifyStructuralDelete(change, doc) {
|
|
|
106
135
|
* stay unverified instead of trusting rendered placement alone.
|
|
107
136
|
*/
|
|
108
137
|
function verifyStructuralMove(change, doc) {
|
|
109
|
-
const target =
|
|
138
|
+
const target = resolveMovedRenderedInstance(doc, change.target);
|
|
110
139
|
if (target.status !== "resolved")
|
|
111
140
|
return false;
|
|
112
|
-
const parent =
|
|
141
|
+
const parent = resolveMovedRenderedInstance(doc, change.destination.parent);
|
|
113
142
|
if (parent.status !== "resolved")
|
|
114
143
|
return false;
|
|
115
144
|
if (target.element.parentElement !== parent.element)
|
|
116
145
|
return false;
|
|
117
146
|
if (!change.destination.before)
|
|
118
147
|
return target.element.nextElementSibling === null;
|
|
119
|
-
const before =
|
|
148
|
+
const before = resolveMovedRenderedInstance(doc, change.destination.before);
|
|
120
149
|
return before.status === "resolved" && target.element.nextElementSibling === before.element;
|
|
121
150
|
}
|
|
122
151
|
function verifiedStructuralChangeIds(eligible, doc) {
|
|
@@ -253,10 +282,14 @@ export async function verifyAndReconcileHandoff(snapshot, doc = handoffDocument(
|
|
|
253
282
|
finally {
|
|
254
283
|
// Reconciliation reapplies the canonical set. If it was unable to write
|
|
255
284
|
// (for example, a read-only Canvas lease), restore the untouched set here.
|
|
285
|
+
// A Canvas restore settles on the renderer's acknowledgement: that
|
|
286
|
+
// acknowledgement invalidates the frame's stylesheet revision, and a
|
|
287
|
+
// caller still inside this verification must not mistake it for a source
|
|
288
|
+
// change and schedule another verification.
|
|
256
289
|
if (doc === document)
|
|
257
290
|
await applyProjection(getActiveDraftChanges());
|
|
258
291
|
else
|
|
259
|
-
restoreCanonicalFrameProjection(doc);
|
|
292
|
+
await restoreCanonicalFrameProjection(doc);
|
|
260
293
|
}
|
|
261
294
|
}
|
|
262
295
|
export function documentBelongsToHandoff(doc, owner) {
|
|
@@ -278,6 +311,20 @@ function handoffDocument(owner) {
|
|
|
278
311
|
}
|
|
279
312
|
return owner.target.kind === "application" && !isEditorShellDocument() ? document : null;
|
|
280
313
|
}
|
|
314
|
+
/** Returns the records captured for one dispatch until it is reconciled. */
|
|
315
|
+
export function getAgentDispatch(revision) {
|
|
316
|
+
return dispatches.get(revision) ?? null;
|
|
317
|
+
}
|
|
318
|
+
/** Records in the owner draft that still equal what a handoff sent. */
|
|
319
|
+
export function unchangedHandoffRecords(snapshot) {
|
|
320
|
+
const sent = new Set(snapshot.changes.map(handoffChangeFingerprint));
|
|
321
|
+
const sentStructural = new Set(snapshot.structuralChanges.map(handoffStructuralFingerprint));
|
|
322
|
+
const current = getDraftChanges(snapshot.owner.draftId);
|
|
323
|
+
return {
|
|
324
|
+
changes: current.changes.filter((change) => sent.has(handoffChangeFingerprint(change))),
|
|
325
|
+
structuralChanges: current.structuralChanges.filter((change) => sentStructural.has(handoffStructuralFingerprint(change))),
|
|
326
|
+
};
|
|
327
|
+
}
|
|
281
328
|
/** Reconciles the captured records for one completed connected-agent request. */
|
|
282
329
|
export async function verifyAndReconcileAgentDispatch(revision) {
|
|
283
330
|
const snapshot = dispatches.get(revision);
|