@agent-native/core 0.106.0 → 0.106.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +6 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/application-state/index.ts +2 -0
- package/corpus/core/src/application-state/script-helpers.ts +12 -0
- package/corpus/core/src/application-state/store.ts +38 -0
- package/corpus/core/src/client/review/ReviewCommentComposer.tsx +10 -3
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +22 -0
- package/corpus/templates/design/AGENTS.md +16 -0
- package/corpus/templates/design/actions/cancel-node-rewrite-request.ts +54 -0
- package/corpus/templates/design/actions/propose-node-rewrite.ts +290 -0
- package/corpus/templates/design/actions/resolve-node-rewrite.ts +257 -0
- package/corpus/templates/design/actions/view-screen.ts +98 -2
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +71 -1
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +19 -0
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +33 -0
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +194 -0
- package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +21 -4
- package/corpus/templates/design/app/components/design/design-canvas/iframe-events.ts +18 -0
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +4 -0
- package/corpus/templates/design/app/components/visual-editor/NodeRewriteProposal.tsx +638 -0
- package/corpus/templates/design/app/components/visual-editor/ReviewCanvasPins.tsx +535 -54
- package/corpus/templates/design/app/components/visual-editor/index.ts +5 -1
- package/corpus/templates/design/app/components/visual-editor/review-canvas-state.ts +21 -3
- package/corpus/templates/design/app/i18n/ar-SA.ts +35 -0
- package/corpus/templates/design/app/i18n/de-DE.ts +35 -0
- package/corpus/templates/design/app/i18n/es-ES.ts +35 -0
- package/corpus/templates/design/app/i18n/fr-FR.ts +35 -0
- package/corpus/templates/design/app/i18n/hi-IN.ts +35 -0
- package/corpus/templates/design/app/i18n/ja-JP.ts +35 -0
- package/corpus/templates/design/app/i18n/ko-KR.ts +35 -0
- package/corpus/templates/design/app/i18n/pt-BR.ts +35 -0
- package/corpus/templates/design/app/i18n/zh-CN.ts +35 -0
- package/corpus/templates/design/app/i18n/zh-TW.ts +32 -0
- package/corpus/templates/design/app/i18n-data.ts +32 -0
- package/corpus/templates/design/app/lib/node-reprompt.ts +110 -0
- package/corpus/templates/design/changelog/2026-07-16-design-editing-and-review-are-now-more-predictable.md +6 -0
- package/corpus/templates/design/server/lib/reprompt-action-guard.ts +107 -0
- package/corpus/templates/design/server/plugins/agent-chat.ts +9 -1
- package/corpus/templates/design/shared/code-layer.ts +15 -0
- package/corpus/templates/design/shared/node-rewrite.ts +213 -0
- package/corpus/templates/design/shared/review-anchor.ts +26 -3
- package/dist/application-state/index.d.ts +2 -2
- package/dist/application-state/index.d.ts.map +1 -1
- package/dist/application-state/index.js +2 -2
- package/dist/application-state/index.js.map +1 -1
- package/dist/application-state/script-helpers.d.ts +1 -0
- package/dist/application-state/script-helpers.d.ts.map +1 -1
- package/dist/application-state/script-helpers.js +7 -1
- package/dist/application-state/script-helpers.js.map +1 -1
- package/dist/application-state/store.d.ts +1 -0
- package/dist/application-state/store.d.ts.map +1 -1
- package/dist/application-state/store.js +28 -0
- package/dist/application-state/store.js.map +1 -1
- package/dist/client/review/ReviewCommentComposer.d.ts +4 -1
- package/dist/client/review/ReviewCommentComposer.d.ts.map +1 -1
- package/dist/client/review/ReviewCommentComposer.js +3 -3
- package/dist/client/review/ReviewCommentComposer.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +5 -5
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/package.json +1 -1
|
@@ -2168,6 +2168,17 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
2168
2168
|
|
|
2169
2169
|
var selectedEl: Element | null = null;
|
|
2170
2170
|
var hoveredEl: Element | null = null;
|
|
2171
|
+
type NodeHtmlPreviewSession = {
|
|
2172
|
+
proposalId: string;
|
|
2173
|
+
originalElement: Element;
|
|
2174
|
+
originalOuterHTML: string;
|
|
2175
|
+
startMarker: Comment;
|
|
2176
|
+
endMarker: Comment;
|
|
2177
|
+
currentElement: Element;
|
|
2178
|
+
selectedWasInside: boolean;
|
|
2179
|
+
hoveredWasInside: boolean;
|
|
2180
|
+
};
|
|
2181
|
+
var activeNodeHtmlPreview: NodeHtmlPreviewSession | null = null;
|
|
2171
2182
|
// Last element an "element-hover" message was actually posted for. Lets
|
|
2172
2183
|
// the shield's pointermove handler skip getLightElementInfo's two
|
|
2173
2184
|
// getComputedStyle calls plus the postMessage on every one of the dozens
|
|
@@ -5120,6 +5131,178 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
5120
5131
|
return null;
|
|
5121
5132
|
}
|
|
5122
5133
|
|
|
5134
|
+
function parseNodeHtmlPreviewElement(html: string): Element | null {
|
|
5135
|
+
var trimmed = html.trim();
|
|
5136
|
+
if (/^<body(?:\s|>)/i.test(trimmed)) {
|
|
5137
|
+
var parsedDocument = new DOMParser().parseFromString(
|
|
5138
|
+
"<!doctype html><html><head></head>" + trimmed + "</html>", // i18n-ignore parser scaffold
|
|
5139
|
+
"text/html",
|
|
5140
|
+
);
|
|
5141
|
+
return parsedDocument.body;
|
|
5142
|
+
}
|
|
5143
|
+
var template = document.createElement("template");
|
|
5144
|
+
template.innerHTML = html;
|
|
5145
|
+
var element = template.content.firstElementChild;
|
|
5146
|
+
if (!element || template.content.childElementCount !== 1) return null;
|
|
5147
|
+
for (
|
|
5148
|
+
var child = template.content.firstChild;
|
|
5149
|
+
child;
|
|
5150
|
+
child = child.nextSibling
|
|
5151
|
+
) {
|
|
5152
|
+
if (child === element) continue;
|
|
5153
|
+
if (child.nodeType !== 3 || String(child.textContent || "").trim()) {
|
|
5154
|
+
return null;
|
|
5155
|
+
}
|
|
5156
|
+
}
|
|
5157
|
+
return element;
|
|
5158
|
+
}
|
|
5159
|
+
|
|
5160
|
+
function resolveNodeHtmlPreviewTarget(target: unknown): Element | null {
|
|
5161
|
+
if (!target || typeof target !== "object") return null;
|
|
5162
|
+
var nodeId = (target as { nodeId?: unknown }).nodeId;
|
|
5163
|
+
if (typeof nodeId === "string" && nodeId) {
|
|
5164
|
+
try {
|
|
5165
|
+
var nodeMatch = document.querySelector(
|
|
5166
|
+
'[data-agent-native-node-id="' + escapeAttribute(nodeId) + '"]',
|
|
5167
|
+
);
|
|
5168
|
+
if (nodeMatch && !isLayerInteractionBlocked(nodeMatch)) {
|
|
5169
|
+
return nodeMatch;
|
|
5170
|
+
}
|
|
5171
|
+
} catch (_err) {}
|
|
5172
|
+
}
|
|
5173
|
+
var selector = (target as { selector?: unknown }).selector;
|
|
5174
|
+
if (typeof selector !== "string" || !selector) return null;
|
|
5175
|
+
try {
|
|
5176
|
+
var selectorMatch = document.querySelector(selector);
|
|
5177
|
+
return selectorMatch && !isLayerInteractionBlocked(selectorMatch)
|
|
5178
|
+
? selectorMatch
|
|
5179
|
+
: null;
|
|
5180
|
+
} catch (_err) {
|
|
5181
|
+
return null;
|
|
5182
|
+
}
|
|
5183
|
+
}
|
|
5184
|
+
|
|
5185
|
+
function postNodeHtmlPreviewApplied(proposalId: string): void {
|
|
5186
|
+
(window.parent as Window).postMessage(
|
|
5187
|
+
{
|
|
5188
|
+
type: "agent-native:node-html-preview-applied",
|
|
5189
|
+
proposalId: proposalId,
|
|
5190
|
+
},
|
|
5191
|
+
"*",
|
|
5192
|
+
);
|
|
5193
|
+
}
|
|
5194
|
+
|
|
5195
|
+
function replaceNodeHtmlPreviewElement(
|
|
5196
|
+
session: NodeHtmlPreviewSession,
|
|
5197
|
+
nextElement: Element,
|
|
5198
|
+
): boolean {
|
|
5199
|
+
var parent = session.startMarker.parentNode;
|
|
5200
|
+
if (!parent || session.endMarker.parentNode !== parent) return false;
|
|
5201
|
+
var cursor = session.startMarker.nextSibling;
|
|
5202
|
+
while (cursor && cursor !== session.endMarker) {
|
|
5203
|
+
var next = cursor.nextSibling;
|
|
5204
|
+
parent.removeChild(cursor);
|
|
5205
|
+
cursor = next;
|
|
5206
|
+
}
|
|
5207
|
+
if (cursor !== session.endMarker) return false;
|
|
5208
|
+
nextElement.setAttribute(
|
|
5209
|
+
"data-agent-native-node-rewrite-proposal",
|
|
5210
|
+
session.proposalId,
|
|
5211
|
+
);
|
|
5212
|
+
parent.insertBefore(nextElement, session.endMarker);
|
|
5213
|
+
session.currentElement = nextElement;
|
|
5214
|
+
if (session.selectedWasInside) selectedEl = nextElement;
|
|
5215
|
+
if (session.hoveredWasInside) hoveredEl = nextElement;
|
|
5216
|
+
refreshOverlays();
|
|
5217
|
+
return true;
|
|
5218
|
+
}
|
|
5219
|
+
|
|
5220
|
+
function restoreActiveNodeHtmlPreview(proposalId?: string): boolean {
|
|
5221
|
+
var session = activeNodeHtmlPreview;
|
|
5222
|
+
if (!session || (proposalId && session.proposalId !== proposalId)) {
|
|
5223
|
+
return false;
|
|
5224
|
+
}
|
|
5225
|
+
activeNodeHtmlPreview = null;
|
|
5226
|
+
var parent = session.startMarker.parentNode;
|
|
5227
|
+
if (!parent || session.endMarker.parentNode !== parent) return false;
|
|
5228
|
+
var cursor = session.startMarker.nextSibling;
|
|
5229
|
+
while (cursor && cursor !== session.endMarker) {
|
|
5230
|
+
var next = cursor.nextSibling;
|
|
5231
|
+
parent.removeChild(cursor);
|
|
5232
|
+
cursor = next;
|
|
5233
|
+
}
|
|
5234
|
+
if (cursor !== session.endMarker) return false;
|
|
5235
|
+
parent.insertBefore(session.originalElement, session.endMarker);
|
|
5236
|
+
parent.removeChild(session.startMarker);
|
|
5237
|
+
parent.removeChild(session.endMarker);
|
|
5238
|
+
if (session.selectedWasInside) selectedEl = session.originalElement;
|
|
5239
|
+
if (session.hoveredWasInside) hoveredEl = session.originalElement;
|
|
5240
|
+
refreshOverlays();
|
|
5241
|
+
return session.originalElement.outerHTML === session.originalOuterHTML;
|
|
5242
|
+
}
|
|
5243
|
+
|
|
5244
|
+
function applyNodeHtmlPreview(data: {
|
|
5245
|
+
proposalId?: unknown;
|
|
5246
|
+
target?: unknown;
|
|
5247
|
+
html?: unknown;
|
|
5248
|
+
}): void {
|
|
5249
|
+
var proposalId = data.proposalId;
|
|
5250
|
+
if (
|
|
5251
|
+
typeof proposalId !== "string" ||
|
|
5252
|
+
!proposalId ||
|
|
5253
|
+
typeof data.html !== "string"
|
|
5254
|
+
) {
|
|
5255
|
+
return;
|
|
5256
|
+
}
|
|
5257
|
+
var nextElement = parseNodeHtmlPreviewElement(data.html);
|
|
5258
|
+
if (!nextElement) return;
|
|
5259
|
+
if (
|
|
5260
|
+
activeNodeHtmlPreview &&
|
|
5261
|
+
activeNodeHtmlPreview.proposalId === proposalId
|
|
5262
|
+
) {
|
|
5263
|
+
if (replaceNodeHtmlPreviewElement(activeNodeHtmlPreview, nextElement)) {
|
|
5264
|
+
postNodeHtmlPreviewApplied(proposalId);
|
|
5265
|
+
}
|
|
5266
|
+
return;
|
|
5267
|
+
}
|
|
5268
|
+
if (activeNodeHtmlPreview) restoreActiveNodeHtmlPreview();
|
|
5269
|
+
var target = resolveNodeHtmlPreviewTarget(data.target);
|
|
5270
|
+
if (!target || !target.parentNode || target === document.documentElement) {
|
|
5271
|
+
return;
|
|
5272
|
+
}
|
|
5273
|
+
var originalOuterHTML = target.outerHTML;
|
|
5274
|
+
nextElement.setAttribute(
|
|
5275
|
+
"data-agent-native-node-rewrite-proposal",
|
|
5276
|
+
proposalId,
|
|
5277
|
+
);
|
|
5278
|
+
var startMarker = document.createComment(
|
|
5279
|
+
"agent-native:node-html-preview:start",
|
|
5280
|
+
);
|
|
5281
|
+
var endMarker = document.createComment(
|
|
5282
|
+
"agent-native:node-html-preview:end",
|
|
5283
|
+
);
|
|
5284
|
+
var parent = target.parentNode;
|
|
5285
|
+
var selectedWasInside = !!selectedEl && target.contains(selectedEl);
|
|
5286
|
+
var hoveredWasInside = !!hoveredEl && target.contains(hoveredEl);
|
|
5287
|
+
parent.insertBefore(startMarker, target);
|
|
5288
|
+
parent.insertBefore(endMarker, target.nextSibling);
|
|
5289
|
+
parent.replaceChild(nextElement, target);
|
|
5290
|
+
activeNodeHtmlPreview = {
|
|
5291
|
+
proposalId: proposalId,
|
|
5292
|
+
originalElement: target,
|
|
5293
|
+
originalOuterHTML: originalOuterHTML,
|
|
5294
|
+
startMarker: startMarker,
|
|
5295
|
+
endMarker: endMarker,
|
|
5296
|
+
currentElement: nextElement,
|
|
5297
|
+
selectedWasInside: selectedWasInside,
|
|
5298
|
+
hoveredWasInside: hoveredWasInside,
|
|
5299
|
+
};
|
|
5300
|
+
if (selectedWasInside) selectedEl = nextElement;
|
|
5301
|
+
if (hoveredWasInside) hoveredEl = nextElement;
|
|
5302
|
+
refreshOverlays();
|
|
5303
|
+
postNodeHtmlPreviewApplied(proposalId);
|
|
5304
|
+
}
|
|
5305
|
+
|
|
5123
5306
|
// Host-driven Layers-panel moves must never inherit findRuntimeTarget's
|
|
5124
5307
|
// selected-element shortcut or first-match querySelector behavior. Runtime
|
|
5125
5308
|
// React trees routinely repeat classes and component markup, so a selector
|
|
@@ -11070,6 +11253,7 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
11070
11253
|
return;
|
|
11071
11254
|
}
|
|
11072
11255
|
if (e.data.type === "replace-document-content") {
|
|
11256
|
+
activeNodeHtmlPreview = null;
|
|
11073
11257
|
replaceRuntimeDocument(
|
|
11074
11258
|
e.data.content,
|
|
11075
11259
|
e.data.forceFullDocument ? "" : e.data.selectedSelector,
|
|
@@ -11079,6 +11263,16 @@ declare var __RUNTIME_LAYER_SNAPSHOT_ENABLED__: boolean;
|
|
|
11079
11263
|
);
|
|
11080
11264
|
return;
|
|
11081
11265
|
}
|
|
11266
|
+
if (e.data.type === "node-html-preview") {
|
|
11267
|
+
if (e.data.operation === "restore") {
|
|
11268
|
+
if (typeof e.data.proposalId === "string") {
|
|
11269
|
+
restoreActiveNodeHtmlPreview(e.data.proposalId);
|
|
11270
|
+
}
|
|
11271
|
+
} else if (e.data.operation === "preview") {
|
|
11272
|
+
applyNodeHtmlPreview(e.data);
|
|
11273
|
+
}
|
|
11274
|
+
return;
|
|
11275
|
+
}
|
|
11082
11276
|
if (e.data.type === "delete-element") {
|
|
11083
11277
|
removeRuntimeTarget(e.data.selector, e.data.selectorCandidates);
|
|
11084
11278
|
return;
|
|
@@ -739,9 +739,20 @@
|
|
|
739
739
|
): Element | null {
|
|
740
740
|
var element = elementFromEditorPoint(clientX, clientY);
|
|
741
741
|
if (!element) return null;
|
|
742
|
-
|
|
742
|
+
var identifiedAncestor = element.closest(
|
|
743
743
|
"[data-agent-native-node-id],[data-code-layer-id],[data-layer-id],[data-builder-id],[id]",
|
|
744
744
|
);
|
|
745
|
+
if (
|
|
746
|
+
identifiedAncestor &&
|
|
747
|
+
identifiedAncestor !== document.body &&
|
|
748
|
+
identifiedAncestor !== document.documentElement
|
|
749
|
+
) {
|
|
750
|
+
return identifiedAncestor;
|
|
751
|
+
}
|
|
752
|
+
if (element === document.body || element === document.documentElement) {
|
|
753
|
+
return null;
|
|
754
|
+
}
|
|
755
|
+
return element;
|
|
745
756
|
}
|
|
746
757
|
|
|
747
758
|
function reviewNodeElements(nodeIds: string[]): Record<string, Element> {
|
|
@@ -808,14 +819,20 @@
|
|
|
808
819
|
reviewPointX,
|
|
809
820
|
reviewPointY,
|
|
810
821
|
);
|
|
822
|
+
var reviewPointNodeId = reviewPointElement
|
|
823
|
+
? getNodeId(reviewPointElement)
|
|
824
|
+
: "";
|
|
825
|
+
var reviewPointSelector =
|
|
826
|
+
reviewPointElement && !reviewPointNodeId
|
|
827
|
+
? buildSourceEquivalentSelector(reviewPointElement)
|
|
828
|
+
: "";
|
|
811
829
|
try {
|
|
812
830
|
(window.parent as Window).postMessage(
|
|
813
831
|
{
|
|
814
832
|
type: "agent-native:review-anchor-at-point-result",
|
|
815
833
|
correlationId: reviewPointCorrelationId,
|
|
816
|
-
nodeId:
|
|
817
|
-
|
|
818
|
-
: undefined,
|
|
834
|
+
nodeId: reviewPointNodeId || undefined,
|
|
835
|
+
targetSelector: reviewPointSelector || undefined,
|
|
819
836
|
layerName:
|
|
820
837
|
reviewPointElement?.getAttribute(
|
|
821
838
|
"data-agent-native-layer-name",
|
|
@@ -23,3 +23,21 @@ export interface IframeContextMenuPayload {
|
|
|
23
23
|
info?: ElementInfo | null;
|
|
24
24
|
layerCandidates?: CanvasLayerHitCandidate[];
|
|
25
25
|
}
|
|
26
|
+
|
|
27
|
+
export interface IframeNodeHtmlPreviewTarget {
|
|
28
|
+
nodeId?: string;
|
|
29
|
+
selector?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface IframeNodeHtmlPreviewMessage {
|
|
33
|
+
type: "node-html-preview";
|
|
34
|
+
proposalId: string;
|
|
35
|
+
target: IframeNodeHtmlPreviewTarget;
|
|
36
|
+
operation: "preview" | "restore";
|
|
37
|
+
html?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface IframeNodeHtmlPreviewAppliedPayload {
|
|
41
|
+
type: "agent-native:node-html-preview-applied";
|
|
42
|
+
proposalId: string;
|
|
43
|
+
}
|
|
@@ -130,6 +130,10 @@ export interface MultiScreenCanvasProps {
|
|
|
130
130
|
* transformed directly from the overview canvas. */
|
|
131
131
|
lockedScreenIds?: ReadonlySet<string> | readonly string[];
|
|
132
132
|
fullViewScreenIds?: string[];
|
|
133
|
+
/** Screens with generated candidates waiting for explicit review. */
|
|
134
|
+
pendingReviewScreenIds?: ReadonlySet<string> | readonly string[];
|
|
135
|
+
/** Opens candidate review for one pending screen. */
|
|
136
|
+
onReviewPendingScreen?: (screenId: string) => void;
|
|
133
137
|
/** Lets every live frame receive native pointer interaction while the
|
|
134
138
|
* overview camera and frame chrome remain available. */
|
|
135
139
|
interactMode?: boolean;
|