@parhelia/core 0.1.12479 → 0.1.12496

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.
Files changed (207) hide show
  1. package/dist/agents-view/AgentCard.js +2 -1
  2. package/dist/agents-view/AgentCard.js.map +1 -1
  3. package/dist/agents-view/AgentsView.js +2 -1
  4. package/dist/agents-view/AgentsView.js.map +1 -1
  5. package/dist/agents-view/AgentsWorkspaceView.js +12 -5
  6. package/dist/agents-view/AgentsWorkspaceView.js.map +1 -1
  7. package/dist/agents-view/ProfileAgentsGroup.js +2 -1
  8. package/dist/agents-view/ProfileAgentsGroup.js.map +1 -1
  9. package/dist/components/ui/input.js +1 -1
  10. package/dist/components/ui/input.js.map +1 -1
  11. package/dist/components/ui/tabs.d.ts +1 -1
  12. package/dist/components/ui/tabs.js +4 -11
  13. package/dist/components/ui/tabs.js.map +1 -1
  14. package/dist/config/config.js +33 -8
  15. package/dist/config/config.js.map +1 -1
  16. package/dist/config/types.d.ts +7 -0
  17. package/dist/config/types.js.map +1 -1
  18. package/dist/editor/FieldHistory.js +49 -31
  19. package/dist/editor/FieldHistory.js.map +1 -1
  20. package/dist/editor/ai/AgentDocumentList.js +32 -14
  21. package/dist/editor/ai/AgentDocumentList.js.map +1 -1
  22. package/dist/editor/ai/AgentGreeting.js +3 -2
  23. package/dist/editor/ai/AgentGreeting.js.map +1 -1
  24. package/dist/editor/ai/AgentProfileSelector.js +2 -1
  25. package/dist/editor/ai/AgentProfileSelector.js.map +1 -1
  26. package/dist/editor/ai/AgentTerminal.js +544 -169
  27. package/dist/editor/ai/AgentTerminal.js.map +1 -1
  28. package/dist/editor/ai/Agents.js +26 -26
  29. package/dist/editor/ai/Agents.js.map +1 -1
  30. package/dist/editor/ai/AiResponseMessage.js +3 -4
  31. package/dist/editor/ai/AiResponseMessage.js.map +1 -1
  32. package/dist/editor/ai/GuidanceOverlay.js +17 -11
  33. package/dist/editor/ai/GuidanceOverlay.js.map +1 -1
  34. package/dist/editor/ai/InlineAiDialog.js +3 -2
  35. package/dist/editor/ai/InlineAiDialog.js.map +1 -1
  36. package/dist/editor/ai/MediaImage.js +40 -8
  37. package/dist/editor/ai/MediaImage.js.map +1 -1
  38. package/dist/editor/ai/SpawnedAgentsPanel.js +10 -12
  39. package/dist/editor/ai/SpawnedAgentsPanel.js.map +1 -1
  40. package/dist/editor/ai/ToolCallDisplay.js +4 -1
  41. package/dist/editor/ai/ToolCallDisplay.js.map +1 -1
  42. package/dist/editor/ai/agentDiagnostics.js +1 -3
  43. package/dist/editor/ai/agentDiagnostics.js.map +1 -1
  44. package/dist/editor/ai/dialogs/AgentDialogHandler.d.ts +1 -8
  45. package/dist/editor/ai/dialogs/AgentDialogHandler.js +89 -12
  46. package/dist/editor/ai/dialogs/AgentDialogHandler.js.map +1 -1
  47. package/dist/editor/ai/dialogs/agentDialogTypes.d.ts +62 -0
  48. package/dist/editor/ai/dialogs/agentDialogTypes.js +2 -0
  49. package/dist/editor/ai/dialogs/agentDialogTypes.js.map +1 -1
  50. package/dist/editor/ai/dialogs/browserBoundCapture.d.ts +29 -0
  51. package/dist/editor/ai/dialogs/browserBoundCapture.js +117 -0
  52. package/dist/editor/ai/dialogs/browserBoundCapture.js.map +1 -0
  53. package/dist/editor/ai/dialogs/capturePageDom.d.ts +3 -0
  54. package/dist/editor/ai/dialogs/capturePageDom.js +64 -0
  55. package/dist/editor/ai/dialogs/capturePageDom.js.map +1 -0
  56. package/dist/editor/ai/dialogs/capturePageScreenshot.d.ts +3 -0
  57. package/dist/editor/ai/dialogs/capturePageScreenshot.js +446 -0
  58. package/dist/editor/ai/dialogs/capturePageScreenshot.js.map +1 -0
  59. package/dist/editor/ai/useAgentStatus.js +11 -0
  60. package/dist/editor/ai/useAgentStatus.js.map +1 -1
  61. package/dist/editor/client/EditorShell.js +39 -41
  62. package/dist/editor/client/EditorShell.js.map +1 -1
  63. package/dist/editor/client/editContext.d.ts +5 -1
  64. package/dist/editor/client/editContext.js.map +1 -1
  65. package/dist/editor/client/hooks/useEditorWebSocket.js +56 -44
  66. package/dist/editor/client/hooks/useEditorWebSocket.js.map +1 -1
  67. package/dist/editor/client/itemsRepository.js +10 -6
  68. package/dist/editor/client/itemsRepository.js.map +1 -1
  69. package/dist/editor/client/pageModelBuilder.js +1 -1
  70. package/dist/editor/client/pageModelBuilder.js.map +1 -1
  71. package/dist/editor/commands/componentCommands.js +3 -49
  72. package/dist/editor/commands/componentCommands.js.map +1 -1
  73. package/dist/editor/commands/customCommandConverter.js +2 -1
  74. package/dist/editor/commands/customCommandConverter.js.map +1 -1
  75. package/dist/editor/commands/handlers/agentHandler.js +2 -1
  76. package/dist/editor/commands/handlers/agentHandler.js.map +1 -1
  77. package/dist/editor/page-editor-chrome/FrameMenu.js +1 -1
  78. package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
  79. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +11 -11
  80. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
  81. package/dist/editor/page-viewer/PageViewerFrame.js +21 -8
  82. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
  83. package/dist/editor/page-viewer/pageModelSkeletonBuilder.js +107 -49
  84. package/dist/editor/page-viewer/pageModelSkeletonBuilder.js.map +1 -1
  85. package/dist/editor/page-viewer/pageViewContext.d.ts +1 -0
  86. package/dist/editor/page-viewer/pageViewContext.js +51 -14
  87. package/dist/editor/page-viewer/pageViewContext.js.map +1 -1
  88. package/dist/editor/reviews/CreateReviewDialog.js +1 -1
  89. package/dist/editor/reviews/CreateReviewDialog.js.map +1 -1
  90. package/dist/editor/reviews/DiffView.js +7 -14
  91. package/dist/editor/reviews/DiffView.js.map +1 -1
  92. package/dist/editor/reviews/useMultiReview.js +2 -2
  93. package/dist/editor/reviews/useMultiReview.js.map +1 -1
  94. package/dist/editor/services/agentService.d.ts +31 -1
  95. package/dist/editor/services/agentService.js +107 -72
  96. package/dist/editor/services/agentService.js.map +1 -1
  97. package/dist/editor/services/aiService.d.ts +3 -1
  98. package/dist/editor/services/aiService.js.map +1 -1
  99. package/dist/editor/services/indexService.js +1 -1
  100. package/dist/editor/services/indexService.js.map +1 -1
  101. package/dist/editor/settings/SettingsView.js +18 -16
  102. package/dist/editor/settings/SettingsView.js.map +1 -1
  103. package/dist/editor/settings/Status.js +5 -4
  104. package/dist/editor/settings/Status.js.map +1 -1
  105. package/dist/editor/settings/index/useIndexStatus.js +19 -21
  106. package/dist/editor/settings/index/useIndexStatus.js.map +1 -1
  107. package/dist/editor/settings/panels/CreateJavaScriptToolDialog.d.ts +7 -0
  108. package/dist/editor/settings/panels/CreateJavaScriptToolDialog.js +48 -0
  109. package/dist/editor/settings/panels/CreateJavaScriptToolDialog.js.map +1 -0
  110. package/dist/editor/settings/panels/GroupedFieldConfigPanel.d.ts +2 -1
  111. package/dist/editor/settings/panels/GroupedFieldConfigPanel.js +2 -2
  112. package/dist/editor/settings/panels/GroupedFieldConfigPanel.js.map +1 -1
  113. package/dist/editor/settings/panels/JavaScriptToolAgentPanel.d.ts +12 -0
  114. package/dist/editor/settings/panels/JavaScriptToolAgentPanel.js +46 -0
  115. package/dist/editor/settings/panels/JavaScriptToolAgentPanel.js.map +1 -0
  116. package/dist/editor/settings/panels/JavaScriptToolConfigPanel.d.ts +9 -0
  117. package/dist/editor/settings/panels/JavaScriptToolConfigPanel.js +34 -0
  118. package/dist/editor/settings/panels/JavaScriptToolConfigPanel.js.map +1 -0
  119. package/dist/editor/settings/panels/JavaScriptToolsPanel.d.ts +2 -0
  120. package/dist/editor/settings/panels/JavaScriptToolsPanel.js +285 -0
  121. package/dist/editor/settings/panels/JavaScriptToolsPanel.js.map +1 -0
  122. package/dist/editor/settings/panels/ModelConfigPanel.d.ts +2 -1
  123. package/dist/editor/settings/panels/ModelConfigPanel.js +88 -7
  124. package/dist/editor/settings/panels/ModelConfigPanel.js.map +1 -1
  125. package/dist/editor/settings/panels/ModelsPanel.js +129 -70
  126. package/dist/editor/settings/panels/ModelsPanel.js.map +1 -1
  127. package/dist/editor/settings/panels/ProjectTemplateAgentPanel.d.ts +1 -4
  128. package/dist/editor/settings/panels/ProjectTemplateAgentPanel.js +3 -3
  129. package/dist/editor/settings/panels/ProjectTemplateAgentPanel.js.map +1 -1
  130. package/dist/editor/settings/panels/ProjectTemplatesPanel.js +78 -22
  131. package/dist/editor/settings/panels/ProjectTemplatesPanel.js.map +1 -1
  132. package/dist/editor/settings/panels/ProvidersPanel.d.ts +1 -1
  133. package/dist/editor/settings/panels/ProvidersPanel.js +40 -55
  134. package/dist/editor/settings/panels/ProvidersPanel.js.map +1 -1
  135. package/dist/editor/settings/panels/index.d.ts +1 -0
  136. package/dist/editor/settings/panels/index.js +1 -0
  137. package/dist/editor/settings/panels/index.js.map +1 -1
  138. package/dist/editor/settings/status/coreStatusChecks.js +28 -17
  139. package/dist/editor/settings/status/coreStatusChecks.js.map +1 -1
  140. package/dist/editor/sidebar/ComponentPalette.js +2 -1
  141. package/dist/editor/sidebar/ComponentPalette.js.map +1 -1
  142. package/dist/editor/sidebar/ComponentTree.js +9 -9
  143. package/dist/editor/sidebar/ComponentTree.js.map +1 -1
  144. package/dist/editor/sidebar/EditHistory.js +3 -38
  145. package/dist/editor/sidebar/EditHistory.js.map +1 -1
  146. package/dist/editor/sidebar/MainContentTree.js +1 -1
  147. package/dist/editor/sidebar/MainContentTree.js.map +1 -1
  148. package/dist/editor/sidebar/NavigationPanelItem.js +2 -5
  149. package/dist/editor/sidebar/NavigationPanelItem.js.map +1 -1
  150. package/dist/editor/tree-indicators/GutterColumns.d.ts +3 -1
  151. package/dist/editor/tree-indicators/GutterColumns.js +4 -3
  152. package/dist/editor/tree-indicators/GutterColumns.js.map +1 -1
  153. package/dist/editor/tree-indicators/types.d.ts +1 -0
  154. package/dist/editor/views/CompareView.js +3 -1
  155. package/dist/editor/views/CompareView.js.map +1 -1
  156. package/dist/editor/views/EditorSlot.js +2 -2
  157. package/dist/editor/views/EditorSlot.js.map +1 -1
  158. package/dist/editor/views/ParheliaView.js +5 -6
  159. package/dist/editor/views/ParheliaView.js.map +1 -1
  160. package/dist/editor/views/SingleEditView.js +2 -0
  161. package/dist/editor/views/SingleEditView.js.map +1 -1
  162. package/dist/editor/views/editorSlotContext.js +35 -6
  163. package/dist/editor/views/editorSlotContext.js.map +1 -1
  164. package/dist/index.d.ts +4 -1
  165. package/dist/index.js +1 -0
  166. package/dist/index.js.map +1 -1
  167. package/dist/lib/sanitize.d.ts +10 -0
  168. package/dist/lib/sanitize.js +40 -0
  169. package/dist/lib/sanitize.js.map +1 -0
  170. package/dist/revision.d.ts +2 -2
  171. package/dist/revision.js +2 -2
  172. package/dist/setup/services/setupWizardService.d.ts +28 -0
  173. package/dist/setup/services/setupWizardService.js +34 -0
  174. package/dist/setup/services/setupWizardService.js.map +1 -1
  175. package/dist/setup/wizard/steps/AddModelDialog.js +9 -1
  176. package/dist/setup/wizard/steps/AddModelDialog.js.map +1 -1
  177. package/dist/setup/wizard/steps/ImportModelDialog.js +3 -1
  178. package/dist/setup/wizard/steps/ImportModelDialog.js.map +1 -1
  179. package/dist/splash-screen/NewPage.js +24 -24
  180. package/dist/splash-screen/NewPage.js.map +1 -1
  181. package/dist/task-board/TaskBoardWorkspace.js +29 -10
  182. package/dist/task-board/TaskBoardWorkspace.js.map +1 -1
  183. package/dist/task-board/components/ItemCollectionEditorDialog.js +5 -12
  184. package/dist/task-board/components/ItemCollectionEditorDialog.js.map +1 -1
  185. package/dist/task-board/components/ProjectAgentsPanel.js +1 -1
  186. package/dist/task-board/components/ProjectAgentsPanel.js.map +1 -1
  187. package/dist/task-board/components/ProjectOverviewContent.js +2 -2
  188. package/dist/task-board/components/ProjectOverviewContent.js.map +1 -1
  189. package/dist/task-board/components/ProjectPropertiesPanel.js +1 -1
  190. package/dist/task-board/components/ProjectPropertiesPanel.js.map +1 -1
  191. package/dist/task-board/components/TaskDetailPanel.js +1 -1
  192. package/dist/task-board/components/TaskDetailPanel.js.map +1 -1
  193. package/dist/task-board/components/TaskboardPersistentLogPanel.js +3 -1
  194. package/dist/task-board/components/TaskboardPersistentLogPanel.js.map +1 -1
  195. package/dist/task-board/taskAgentLink.js +1 -3
  196. package/dist/task-board/taskAgentLink.js.map +1 -1
  197. package/dist/task-board/views/DependencyGraphView.js +19 -1
  198. package/dist/task-board/views/DependencyGraphView.js.map +1 -1
  199. package/dist/tour/Tour.js +63 -4
  200. package/dist/tour/Tour.js.map +1 -1
  201. package/dist/tour/default-tour.js +51 -11
  202. package/dist/tour/default-tour.js.map +1 -1
  203. package/dist/types.d.ts +2 -0
  204. package/package.json +4 -1
  205. package/dist/editor/ComponentInfo.d.ts +0 -4
  206. package/dist/editor/ComponentInfo.js +0 -41
  207. package/dist/editor/ComponentInfo.js.map +0 -1
@@ -0,0 +1,117 @@
1
+ export const CAPTURE_ERROR_CODES = {
2
+ BROWSER_CLAIM_MISMATCH: "browser_claim_mismatch",
3
+ BROWSER_CONTEXT_MISSING: "browser_context_missing",
4
+ PAGE_VIEWER_NOT_OPEN: "page_viewer_not_open",
5
+ };
6
+ function normalize(value) {
7
+ return value?.trim().toLowerCase() || "";
8
+ }
9
+ export function getBrowserCaptureClaim(metadata) {
10
+ const raw = metadata?.additionalData?.browserCaptureClaim ||
11
+ metadata
12
+ ?.browserCaptureClaim;
13
+ if (!raw || typeof raw !== "object") {
14
+ return null;
15
+ }
16
+ return raw;
17
+ }
18
+ export function setBrowserCaptureClaim(metadata, claim) {
19
+ const nextAdditionalData = { ...(metadata?.additionalData || {}) };
20
+ const nextMetadata = {
21
+ ...(metadata || {}),
22
+ additionalData: nextAdditionalData,
23
+ };
24
+ if (claim) {
25
+ nextAdditionalData.browserCaptureClaim = claim;
26
+ nextMetadata.browserCaptureClaim = claim;
27
+ }
28
+ else {
29
+ delete nextAdditionalData.browserCaptureClaim;
30
+ delete nextMetadata.browserCaptureClaim;
31
+ }
32
+ return nextMetadata;
33
+ }
34
+ export function buildOpenCaptureContext(editContext) {
35
+ const currentItem = editContext?.currentItemDescriptor;
36
+ if (!currentItem && !editContext?.workspaceId) {
37
+ return undefined;
38
+ }
39
+ return {
40
+ itemId: currentItem?.id,
41
+ itemName: editContext?.item?.name,
42
+ itemPath: currentItem?.path,
43
+ language: currentItem?.language,
44
+ version: currentItem?.version,
45
+ activeWorkspace: editContext?.workspaceId,
46
+ };
47
+ }
48
+ export function validateBrowserBoundCaptureRequest(params) {
49
+ const { request, editContext, scope } = params;
50
+ const requiredContext = request.parameters?.targetContext ||
51
+ undefined;
52
+ const currentContext = buildOpenCaptureContext(editContext);
53
+ if (request.targetSessionId &&
54
+ editContext?.sessionId &&
55
+ normalize(request.targetSessionId) !== normalize(editContext.sessionId)) {
56
+ return buildCaptureFailure({
57
+ scope,
58
+ errorCode: CAPTURE_ERROR_CODES.BROWSER_CLAIM_MISMATCH,
59
+ error: "This browser is not the claimed browser for the capture request.",
60
+ currentContext,
61
+ requiredContext,
62
+ recommendedAction: "Attach this agent to the current browser or switch back to the claimed browser, then retry capture.",
63
+ });
64
+ }
65
+ if (scope === "editor-ui") {
66
+ return null;
67
+ }
68
+ if (!requiredContext?.itemId) {
69
+ return buildCaptureFailure({
70
+ scope,
71
+ errorCode: CAPTURE_ERROR_CODES.BROWSER_CONTEXT_MISSING,
72
+ error: "The capture request is missing a concrete page target, so it cannot safely run against the currently open page.",
73
+ currentContext,
74
+ requiredContext,
75
+ recommendedAction: "Refresh the agent context or load the intended item first, then retry capture.",
76
+ });
77
+ }
78
+ return null;
79
+ }
80
+ export function buildPageViewerNotOpenFailure(params) {
81
+ const requiredContext = params.request.parameters?.targetContext || undefined;
82
+ return buildCaptureFailure({
83
+ scope: params.scope,
84
+ errorCode: CAPTURE_ERROR_CODES.PAGE_VIEWER_NOT_OPEN,
85
+ error: "No page viewer or editor surface is open in the claimed browser, so capture cannot run.",
86
+ currentContext: buildOpenCaptureContext(params.editContext),
87
+ requiredContext,
88
+ recommendedAction: buildLoadItemAction(requiredContext),
89
+ });
90
+ }
91
+ function buildLoadItemAction(targetContext) {
92
+ if (!targetContext?.itemId) {
93
+ return "Open the intended page in the page editor or viewer, then retry capture.";
94
+ }
95
+ const parts = [`Call load-item with itemId "${targetContext.itemId}"`];
96
+ if (targetContext.language) {
97
+ parts.push(`language "${targetContext.language}"`);
98
+ }
99
+ if (targetContext.version != null) {
100
+ parts.push(`version ${targetContext.version}`);
101
+ }
102
+ return `${parts.join(", ")}, then retry capture.`;
103
+ }
104
+ function buildCaptureFailure(params) {
105
+ return {
106
+ success: false,
107
+ scope: params.scope,
108
+ errorCode: params.errorCode,
109
+ error: params.recommendedAction
110
+ ? `${params.error} ${params.recommendedAction}`
111
+ : params.error,
112
+ requiredContext: params.requiredContext,
113
+ currentContext: params.currentContext,
114
+ recommendedAction: params.recommendedAction,
115
+ };
116
+ }
117
+ //# sourceMappingURL=browserBoundCapture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browserBoundCapture.js","sourceRoot":"","sources":["../../../../src/editor/ai/dialogs/browserBoundCapture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { EditContextType } from "../../client/editContext";
2
+ import type { AgentDialogRequest, CapturePageDomParameters, CapturePageDomResult } from "./agentDialogTypes";
3
+ export declare function capturePageDom(request: AgentDialogRequest, _params: CapturePageDomParameters, editContext: EditContextType | undefined): Promise<CapturePageDomResult>;
@@ -0,0 +1,64 @@
1
+ import { buildPageViewerNotOpenFailure, validateBrowserBoundCaptureRequest, } from "./browserBoundCapture";
2
+ function getActiveEditorIframe(editContext) {
3
+ return editContext.getActiveSlotContext?.()?.primaryPageViewContext.editorIframe;
4
+ }
5
+ export async function capturePageDom(request, _params, editContext) {
6
+ if (!editContext) {
7
+ return buildPageViewerNotOpenFailure({
8
+ request,
9
+ editContext,
10
+ scope: "page",
11
+ });
12
+ }
13
+ const iframe = getActiveEditorIframe(editContext);
14
+ if (!iframe) {
15
+ return buildPageViewerNotOpenFailure({
16
+ request,
17
+ editContext,
18
+ scope: "page",
19
+ });
20
+ }
21
+ const validationFailure = validateBrowserBoundCaptureRequest({
22
+ request,
23
+ editContext,
24
+ scope: "page",
25
+ });
26
+ if (validationFailure) {
27
+ return validationFailure;
28
+ }
29
+ let iframeDocument = null;
30
+ let html = "";
31
+ try {
32
+ iframeDocument = iframe.contentDocument;
33
+ html = iframeDocument?.documentElement?.outerHTML ?? "";
34
+ }
35
+ catch {
36
+ return {
37
+ success: false,
38
+ scope: "page",
39
+ error: "The current page iframe is not accessible from the editor, so DOM capture is unavailable.",
40
+ };
41
+ }
42
+ if (!iframeDocument?.documentElement) {
43
+ return {
44
+ success: false,
45
+ scope: "page",
46
+ error: "The current page has not finished loading inside the editor iframe.",
47
+ };
48
+ }
49
+ if (!html.trim()) {
50
+ return {
51
+ success: false,
52
+ scope: "page",
53
+ error: "The current page DOM is empty.",
54
+ };
55
+ }
56
+ return {
57
+ success: true,
58
+ scope: "page",
59
+ html,
60
+ length: html.length,
61
+ documentTitle: iframeDocument.title || undefined,
62
+ };
63
+ }
64
+ //# sourceMappingURL=capturePageDom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capturePageDom.js","sourceRoot":"","sources":["../../../../src/editor/ai/dialogs/capturePageDom.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,6BAA6B,EAC7B,kCAAkC,GACnC,MAAM,uBAAuB,CAAC;AAE/B,SAAS,qBAAqB,CAAC,WAA4B;IACzD,OAAO,WAAW,CAAC,oBAAoB,EAAE,EAAE,EAAE,sBAAsB,CAAC,YAAY,CAAC;AACnF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAA2B,EAC3B,OAAiC,EACjC,WAAwC;IAExC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,6BAA6B,CAAC;YACnC,OAAO;YACP,WAAW;YACX,KAAK,EAAE,MAAM;SACd,CAAyB,CAAC;IAC7B,CAAC;IAED,MAAM,MAAM,GAAG,qBAAqB,CAAC,WAAW,CAAC,CAAC;IAClD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,6BAA6B,CAAC;YACnC,OAAO;YACP,WAAW;YACX,KAAK,EAAE,MAAM;SACd,CAAyB,CAAC;IAC7B,CAAC;IAED,MAAM,iBAAiB,GAAG,kCAAkC,CAAC;QAC3D,OAAO;QACP,WAAW;QACX,KAAK,EAAE,MAAM;KACd,CAAC,CAAC;IACH,IAAI,iBAAiB,EAAE,CAAC;QACtB,OAAO,iBAAyC,CAAC;IACnD,CAAC;IAED,IAAI,cAAc,GAAoB,IAAI,CAAC;IAC3C,IAAI,IAAI,GAAG,EAAE,CAAC;IAEd,IAAI,CAAC;QACH,cAAc,GAAG,MAAM,CAAC,eAAe,CAAC;QACxC,IAAI,GAAG,cAAc,EAAE,eAAe,EAAE,SAAS,IAAI,EAAE,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,MAAM;YACb,KAAK,EACH,2FAA2F;SAC9F,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,cAAc,EAAE,eAAe,EAAE,CAAC;QACrC,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,qEAAqE;SAC7E,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACjB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,gCAAgC;SACxC,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,MAAM;QACb,IAAI;QACJ,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,aAAa,EAAE,cAAc,CAAC,KAAK,IAAI,SAAS;KACjD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { EditContextType } from "../../client/editContext";
2
+ import type { AgentDialogRequest, CapturePageScreenshotParameters, CapturePageScreenshotResult } from "./agentDialogTypes";
3
+ export declare function capturePageScreenshot(request: AgentDialogRequest, params: CapturePageScreenshotParameters, editContext: EditContextType | undefined): Promise<CapturePageScreenshotResult>;
@@ -0,0 +1,446 @@
1
+ import html2canvas from "html2canvas-pro";
2
+ import { getComponentById } from "../../componentTreeHelper";
3
+ import { findComponentRect, getAbsolutePosition } from "../../utils";
4
+ import { buildPageViewerNotOpenFailure, validateBrowserBoundCaptureRequest, } from "./browserBoundCapture";
5
+ const MAX_TOOL_RESULT_IMAGE_DIMENSION = 1280;
6
+ const PNG_SIZE_FALLBACK_THRESHOLD = 2_500_000;
7
+ const JPEG_QUALITY = 0.9;
8
+ function normalizeScope(scope) {
9
+ switch (scope) {
10
+ case "editor-ui":
11
+ case "selection":
12
+ case "component":
13
+ case "component-range":
14
+ case "page":
15
+ return scope;
16
+ case "viewport":
17
+ default:
18
+ return "viewport";
19
+ }
20
+ }
21
+ function getPageDimensions(doc) {
22
+ const body = doc.body;
23
+ const root = doc.documentElement;
24
+ return {
25
+ width: Math.max(root?.scrollWidth ?? 0, root?.clientWidth ?? 0, body?.scrollWidth ?? 0, body?.clientWidth ?? 0),
26
+ height: Math.max(root?.scrollHeight ?? 0, root?.clientHeight ?? 0, body?.scrollHeight ?? 0, body?.clientHeight ?? 0),
27
+ };
28
+ }
29
+ function getWindowViewportBounds(targetWindow, zoom = 1, viewportWidth = targetWindow.innerWidth, viewportHeight = targetWindow.innerHeight) {
30
+ const safeZoom = zoom > 0 ? zoom : 1;
31
+ return {
32
+ x: Math.floor(targetWindow.scrollX ?? 0),
33
+ y: Math.floor(targetWindow.scrollY ?? 0),
34
+ width: Math.max(1, Math.ceil(viewportWidth / safeZoom)),
35
+ height: Math.max(1, Math.ceil(viewportHeight / safeZoom)),
36
+ };
37
+ }
38
+ function clampBounds(bounds, pageSize, padding = 0) {
39
+ const x = Math.max(0, Math.floor(bounds.x - padding));
40
+ const y = Math.max(0, Math.floor(bounds.y - padding));
41
+ const right = Math.min(pageSize.width, Math.ceil(bounds.x + bounds.width + padding));
42
+ const bottom = Math.min(pageSize.height, Math.ceil(bounds.y + bounds.height + padding));
43
+ return {
44
+ x,
45
+ y,
46
+ width: Math.max(1, right - x),
47
+ height: Math.max(1, bottom - y),
48
+ };
49
+ }
50
+ function unionBounds(boundsList) {
51
+ const minX = Math.min(...boundsList.map((bounds) => bounds.x));
52
+ const minY = Math.min(...boundsList.map((bounds) => bounds.y));
53
+ const maxRight = Math.max(...boundsList.map((bounds) => bounds.x + bounds.width));
54
+ const maxBottom = Math.max(...boundsList.map((bounds) => bounds.y + bounds.height));
55
+ return {
56
+ x: minX,
57
+ y: minY,
58
+ width: maxRight - minX,
59
+ height: maxBottom - minY,
60
+ };
61
+ }
62
+ function normalizeComponentIdentifier(value) {
63
+ return value?.trim().replace(/[{}]/g, "").toLowerCase() ?? "";
64
+ }
65
+ function matchesComponentIdentifier(candidate, target) {
66
+ const normalizedCandidate = normalizeComponentIdentifier(candidate);
67
+ const normalizedTarget = normalizeComponentIdentifier(target);
68
+ return !!normalizedCandidate && normalizedCandidate === normalizedTarget;
69
+ }
70
+ function findExactComponentById(page, componentId) {
71
+ const targetId = normalizeComponentIdentifier(componentId);
72
+ if (!targetId) {
73
+ return null;
74
+ }
75
+ const queue = [...(page.rootComponent.placeholders ?? [])];
76
+ while (queue.length > 0) {
77
+ const placeholder = queue.shift();
78
+ if (!placeholder) {
79
+ continue;
80
+ }
81
+ for (const component of placeholder.components) {
82
+ if (matchesComponentIdentifier(component.id, targetId)) {
83
+ return component;
84
+ }
85
+ if (component.placeholders?.length) {
86
+ queue.push(...component.placeholders);
87
+ }
88
+ }
89
+ }
90
+ return null;
91
+ }
92
+ function getElementBounds(iframe, element) {
93
+ const rect = getAbsolutePosition(element, iframe);
94
+ if (rect.width <= 0 || rect.height <= 0) {
95
+ return null;
96
+ }
97
+ return {
98
+ x: Math.floor(rect.x),
99
+ y: Math.floor(rect.y),
100
+ width: Math.ceil(rect.width),
101
+ height: Math.ceil(rect.height),
102
+ };
103
+ }
104
+ function getComponentBoundsFromLiveDom(iframe, componentId) {
105
+ const doc = iframe.contentDocument;
106
+ if (!doc?.body) {
107
+ return null;
108
+ }
109
+ const matchingElements = Array.from(doc.querySelectorAll("[data-component-id]")).filter((element) => {
110
+ return (element instanceof HTMLElement &&
111
+ matchesComponentIdentifier(element.getAttribute("data-component-id"), componentId));
112
+ });
113
+ const bounds = matchingElements
114
+ .map((element) => getElementBounds(iframe, element))
115
+ .filter((item) => !!item && item.width > 0 && item.height > 0);
116
+ if (bounds.length === 0) {
117
+ return null;
118
+ }
119
+ return unionBounds(bounds);
120
+ }
121
+ function getComponentBounds(iframe, page, componentId) {
122
+ const exactComponent = findExactComponentById(page, componentId);
123
+ const component = exactComponent ?? getComponentById(componentId, page);
124
+ const candidateIds = [
125
+ componentId,
126
+ component?.id,
127
+ component?.datasourceItem?.id,
128
+ ].filter((value, index, values) => {
129
+ return (!!value &&
130
+ values.findIndex((other) => matchesComponentIdentifier(other, value)) ===
131
+ index);
132
+ });
133
+ if (component) {
134
+ const componentRect = findComponentRect(iframe, component, true)?.rect;
135
+ if (componentRect) {
136
+ return {
137
+ x: Math.floor(componentRect.x),
138
+ y: Math.floor(componentRect.y),
139
+ width: Math.ceil(componentRect.width),
140
+ height: Math.ceil(componentRect.height),
141
+ };
142
+ }
143
+ }
144
+ for (const candidateId of candidateIds) {
145
+ const liveDomBounds = getComponentBoundsFromLiveDom(iframe, candidateId);
146
+ if (liveDomBounds) {
147
+ return liveDomBounds;
148
+ }
149
+ }
150
+ return null;
151
+ }
152
+ function getViewportBounds(iframe, zoom) {
153
+ const iframeWindow = iframe.contentWindow;
154
+ return getWindowViewportBounds(iframeWindow ?? window, zoom, iframe.clientWidth, iframe.clientHeight);
155
+ }
156
+ function resolveCaptureArea(iframe, page, selection, zoom, params, pageSize) {
157
+ const scope = normalizeScope(params.scope);
158
+ const padding = Math.max(0, params.padding ?? 0);
159
+ if (scope === "page") {
160
+ return {
161
+ scope,
162
+ bounds: clampBounds({
163
+ x: 0,
164
+ y: 0,
165
+ width: pageSize.width,
166
+ height: pageSize.height,
167
+ }, pageSize, padding),
168
+ };
169
+ }
170
+ if (!page) {
171
+ if (scope === "viewport") {
172
+ return {
173
+ scope,
174
+ bounds: clampBounds(getViewportBounds(iframe, zoom), pageSize, padding),
175
+ };
176
+ }
177
+ throw new Error("No page model is loaded, so component-based capture is unavailable.");
178
+ }
179
+ const fromComponentId = params.fromComponentId?.trim();
180
+ const toComponentId = params.toComponentId?.trim();
181
+ if (scope === "selection") {
182
+ const bounds = selection
183
+ .map((componentId) => getComponentBounds(iframe, page, componentId))
184
+ .filter((item) => !!item && item.width > 0 && item.height > 0);
185
+ if (!bounds.length) {
186
+ throw new Error("There are no selected components to capture.");
187
+ }
188
+ return {
189
+ scope,
190
+ bounds: clampBounds(unionBounds(bounds), pageSize, padding),
191
+ };
192
+ }
193
+ if (fromComponentId && toComponentId) {
194
+ const bounds = [fromComponentId, toComponentId]
195
+ .map((componentId) => getComponentBounds(iframe, page, componentId))
196
+ .filter((item) => !!item && item.width > 0 && item.height > 0);
197
+ if (bounds.length !== 2) {
198
+ throw new Error("Could not resolve both component boundaries for the requested capture range.");
199
+ }
200
+ return {
201
+ scope: "component-range",
202
+ bounds: clampBounds(unionBounds(bounds), pageSize, padding),
203
+ };
204
+ }
205
+ if (fromComponentId) {
206
+ const bounds = getComponentBounds(iframe, page, fromComponentId);
207
+ if (!bounds) {
208
+ throw new Error(`Could not resolve a visible component for '${fromComponentId}'.`);
209
+ }
210
+ return {
211
+ scope: "component",
212
+ bounds: clampBounds(bounds, pageSize, padding),
213
+ };
214
+ }
215
+ if (scope === "component" || scope === "component-range") {
216
+ return {
217
+ scope: "viewport",
218
+ bounds: clampBounds(getViewportBounds(iframe, zoom), pageSize, padding),
219
+ };
220
+ }
221
+ return {
222
+ scope: "viewport",
223
+ bounds: clampBounds(getViewportBounds(iframe, zoom), pageSize, padding),
224
+ };
225
+ }
226
+ async function canvasToBlob(canvas, contentType, quality) {
227
+ const blob = await new Promise((resolve, reject) => {
228
+ canvas.toBlob((value) => {
229
+ if (value) {
230
+ resolve(value);
231
+ }
232
+ else {
233
+ reject(new Error("Failed to convert screenshot canvas into an image."));
234
+ }
235
+ }, contentType, quality);
236
+ });
237
+ return blob;
238
+ }
239
+ async function blobToDataUrl(blob) {
240
+ return await new Promise((resolve, reject) => {
241
+ const reader = new FileReader();
242
+ reader.onload = () => {
243
+ const value = reader.result;
244
+ if (typeof value === "string" && value.length > 0) {
245
+ resolve(value);
246
+ return;
247
+ }
248
+ reject(new Error("Failed to encode screenshot image data."));
249
+ };
250
+ reader.onerror = () => {
251
+ reject(reader.error ?? new Error("Failed to encode screenshot image data."));
252
+ };
253
+ reader.readAsDataURL(blob);
254
+ });
255
+ }
256
+ function buildFileName(scope, extension = "png") {
257
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
258
+ return `page-screenshot-${scope}-${timestamp}.${extension}`;
259
+ }
260
+ function scaleCanvasForToolResult(canvas) {
261
+ const maxDimension = Math.max(canvas.width, canvas.height);
262
+ if (maxDimension <= MAX_TOOL_RESULT_IMAGE_DIMENSION) {
263
+ return canvas;
264
+ }
265
+ const scale = MAX_TOOL_RESULT_IMAGE_DIMENSION / maxDimension;
266
+ const scaledCanvas = document.createElement("canvas");
267
+ scaledCanvas.width = Math.max(1, Math.round(canvas.width * scale));
268
+ scaledCanvas.height = Math.max(1, Math.round(canvas.height * scale));
269
+ const context = scaledCanvas.getContext("2d");
270
+ if (!context) {
271
+ throw new Error("Failed to prepare the screenshot for the tool result.");
272
+ }
273
+ context.drawImage(canvas, 0, 0, scaledCanvas.width, scaledCanvas.height);
274
+ return scaledCanvas;
275
+ }
276
+ function replaceFileExtension(fileName, extension) {
277
+ return fileName.replace(/\.[^.]+$/, "") + `.${extension}`;
278
+ }
279
+ async function canvasToResultImage(canvas, scope) {
280
+ const processedCanvas = scaleCanvasForToolResult(canvas);
281
+ let contentType = "image/png";
282
+ let fileName = buildFileName(scope, "png");
283
+ let blob = await canvasToBlob(processedCanvas, contentType);
284
+ if (blob.size > PNG_SIZE_FALLBACK_THRESHOLD) {
285
+ contentType = "image/jpeg";
286
+ fileName = replaceFileExtension(fileName, "jpg");
287
+ blob = await canvasToBlob(processedCanvas, contentType, JPEG_QUALITY);
288
+ }
289
+ return {
290
+ image: {
291
+ dataUrl: await blobToDataUrl(blob),
292
+ fileName,
293
+ fileSize: blob.size,
294
+ contentType,
295
+ },
296
+ width: processedCanvas.width,
297
+ height: processedCanvas.height,
298
+ };
299
+ }
300
+ function getActiveEditorIframe(editContext) {
301
+ return editContext.getActiveSlotContext?.()?.primaryPageViewContext.editorIframe;
302
+ }
303
+ export async function capturePageScreenshot(request, params, editContext) {
304
+ const normalizedScope = normalizeScope(params.scope);
305
+ const captureEditorUi = normalizedScope === "editor-ui";
306
+ if (!editContext) {
307
+ return buildPageViewerNotOpenFailure({
308
+ request,
309
+ editContext,
310
+ scope: normalizedScope,
311
+ });
312
+ }
313
+ const validationFailure = validateBrowserBoundCaptureRequest({
314
+ request,
315
+ editContext,
316
+ scope: normalizedScope,
317
+ });
318
+ if (validationFailure) {
319
+ return validationFailure;
320
+ }
321
+ let targetElement;
322
+ let pageSize;
323
+ let captureArea;
324
+ const activeSlotContext = editContext.getActiveSlotContext?.();
325
+ if (captureEditorUi) {
326
+ if (!document.documentElement || !document.body) {
327
+ return {
328
+ success: false,
329
+ scope: normalizedScope,
330
+ error: "The Parhelia UI has not finished loading yet.",
331
+ };
332
+ }
333
+ targetElement = document.documentElement;
334
+ pageSize = getPageDimensions(document);
335
+ const padding = Math.max(0, params.padding ?? 0);
336
+ captureArea = {
337
+ scope: "editor-ui",
338
+ bounds: clampBounds(getWindowViewportBounds(window), pageSize, padding),
339
+ };
340
+ }
341
+ else {
342
+ const iframe = getActiveEditorIframe(editContext);
343
+ if (!iframe) {
344
+ return buildPageViewerNotOpenFailure({
345
+ request,
346
+ editContext,
347
+ scope: normalizedScope,
348
+ });
349
+ }
350
+ let iframeDocument = null;
351
+ let iframeWindow = null;
352
+ try {
353
+ iframeWindow = iframe.contentWindow;
354
+ iframeDocument = iframe.contentDocument;
355
+ void iframeWindow?.document?.body;
356
+ }
357
+ catch {
358
+ return {
359
+ success: false,
360
+ scope: normalizedScope,
361
+ error: "The current page iframe is not accessible from the editor, so screenshot capture is unavailable.",
362
+ };
363
+ }
364
+ if (!iframeDocument?.documentElement || !iframeDocument.body || !iframeWindow) {
365
+ return {
366
+ success: false,
367
+ scope: normalizedScope,
368
+ error: "The current page has not finished loading inside the editor iframe.",
369
+ };
370
+ }
371
+ targetElement = iframeDocument.documentElement;
372
+ pageSize = getPageDimensions(iframeDocument);
373
+ const zoom = activeSlotContext?.primaryPageViewContext.zoom ?? 1;
374
+ try {
375
+ captureArea = resolveCaptureArea(iframe, editContext?.page, editContext?.selection ?? [], zoom, params, pageSize);
376
+ }
377
+ catch (error) {
378
+ return {
379
+ success: false,
380
+ scope: normalizedScope,
381
+ error: error instanceof Error ? error.message : "Failed to resolve capture bounds.",
382
+ };
383
+ }
384
+ }
385
+ const rootStyle = targetElement.style;
386
+ const previousTransform = rootStyle.transform;
387
+ const previousTransformOrigin = rootStyle.transformOrigin;
388
+ const previousOverflow = rootStyle.overflow;
389
+ let canvas;
390
+ try {
391
+ rootStyle.transform = "none";
392
+ rootStyle.transformOrigin = "";
393
+ rootStyle.overflow = previousOverflow || "auto";
394
+ await new Promise((resolve) => requestAnimationFrame(() => resolve(undefined)));
395
+ canvas = await html2canvas(targetElement, {
396
+ backgroundColor: "#ffffff",
397
+ logging: false,
398
+ removeContainer: true,
399
+ scale: Math.min(globalThis.devicePixelRatio || 1, 2),
400
+ useCORS: true,
401
+ windowWidth: pageSize.width,
402
+ windowHeight: pageSize.height,
403
+ scrollX: 0,
404
+ scrollY: 0,
405
+ x: captureArea.bounds.x,
406
+ y: captureArea.bounds.y,
407
+ width: captureArea.bounds.width,
408
+ height: captureArea.bounds.height,
409
+ });
410
+ }
411
+ catch (error) {
412
+ return {
413
+ success: false,
414
+ scope: captureArea.scope,
415
+ error: error instanceof Error
416
+ ? error.message
417
+ : "Failed to render the requested screenshot.",
418
+ };
419
+ }
420
+ finally {
421
+ rootStyle.transform = previousTransform;
422
+ rootStyle.transformOrigin = previousTransformOrigin;
423
+ rootStyle.overflow = previousOverflow;
424
+ }
425
+ try {
426
+ const resultImage = await canvasToResultImage(canvas, captureArea.scope);
427
+ return {
428
+ success: true,
429
+ scope: captureArea.scope,
430
+ image: resultImage.image,
431
+ bounds: captureArea.bounds,
432
+ imageWidth: resultImage.width,
433
+ imageHeight: resultImage.height,
434
+ };
435
+ }
436
+ catch (error) {
437
+ return {
438
+ success: false,
439
+ scope: captureArea.scope,
440
+ error: error instanceof Error
441
+ ? error.message
442
+ : "Failed to encode the screenshot for the tool result.",
443
+ };
444
+ }
445
+ }
446
+ //# sourceMappingURL=capturePageScreenshot.js.map