nudge-ui 0.2.4 → 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.
Files changed (250) hide show
  1. package/dist/cli/agentCommand.js +4 -28
  2. package/dist/client.mjs +863 -213
  3. package/dist/hosts/next/wrapper.js +1 -7
  4. package/dist/hosts/projectBridge.js +3 -17
  5. package/dist/inspector/agent/McpConnectionDialog.js +7 -3
  6. package/dist/inspector/agent/activity.d.ts +1 -1
  7. package/dist/inspector/agent/activity.js +3 -2
  8. package/dist/inspector/agent/client.d.ts +2 -2
  9. package/dist/inspector/agent/client.js +28 -29
  10. package/dist/inspector/agent/connectionStatus.d.ts +3 -1
  11. package/dist/inspector/agent/connectionStatus.js +25 -0
  12. package/dist/inspector/agent/httpTransport.js +31 -147
  13. package/dist/inspector/agent/protocol.d.ts +1 -1
  14. package/dist/inspector/agent/protocol.js +1 -1
  15. package/dist/inspector/agent/verification.d.ts +1 -1
  16. package/dist/inspector/agent/verification.js +7 -4
  17. package/dist/inspector/boot.d.ts +3 -0
  18. package/dist/inspector/boot.js +297 -0
  19. package/dist/inspector/canvas/AgentActivityOverlay.d.ts +2 -1
  20. package/dist/inspector/canvas/AgentActivityOverlay.js +6 -3
  21. package/dist/inspector/canvas/CanvasCard.js +21 -12
  22. package/dist/inspector/canvas/CanvasElementOverlay.js +82 -127
  23. package/dist/inspector/canvas/CanvasToolbar.js +2 -1
  24. package/dist/inspector/canvas/CanvasWorkspace.js +74 -97
  25. package/dist/inspector/canvas/LockedWorkspaceNotice.d.ts +3 -2
  26. package/dist/inspector/canvas/LockedWorkspaceNotice.js +10 -6
  27. package/dist/inspector/canvas/PageCard.d.ts +10 -0
  28. package/dist/inspector/canvas/PageCard.js +51 -0
  29. package/dist/inspector/canvas/SketchToolOptions.d.ts +5 -0
  30. package/dist/inspector/canvas/SketchToolOptions.js +86 -0
  31. package/dist/inspector/canvas/StaleChangeIndicator.d.ts +1 -1
  32. package/dist/inspector/canvas/StaleChangeIndicator.js +1 -1
  33. package/dist/inspector/canvas/ToolOptionsDrawer.d.ts +21 -0
  34. package/dist/inspector/canvas/ToolOptionsDrawer.js +77 -0
  35. package/dist/inspector/canvas/activeCanvasDocument.d.ts +3 -2
  36. package/dist/inspector/canvas/assets/eraser.svg +28 -0
  37. package/dist/inspector/canvas/assets/pen.svg +25 -0
  38. package/dist/inspector/canvas/canvasFrame.d.ts +16 -0
  39. package/dist/inspector/canvas/canvasFrame.js +10 -0
  40. package/dist/inspector/canvas/canvasGestures.d.ts +0 -1
  41. package/dist/inspector/canvas/canvasGestures.js +0 -6
  42. package/dist/inspector/canvas/canvasStore.d.ts +6 -0
  43. package/dist/inspector/canvas/canvasStore.js +36 -1
  44. package/dist/inspector/canvas/frameConnection.d.ts +48 -0
  45. package/dist/inspector/canvas/frameConnection.js +73 -0
  46. package/dist/inspector/canvas/frameProtocol.d.ts +18 -1
  47. package/dist/inspector/canvas/frameProtocol.js +36 -0
  48. package/dist/inspector/canvas/pageSurface.d.ts +11 -0
  49. package/dist/inspector/canvas/pageSurface.js +34 -0
  50. package/dist/inspector/canvas/projection.d.ts +19 -9
  51. package/dist/inspector/canvas/projection.js +58 -31
  52. package/dist/inspector/canvas/rendererBootstrap.js +4 -1
  53. package/dist/inspector/canvas/rendererElementSelector.js +9 -1
  54. package/dist/inspector/canvas/rendererMessageRouter.d.ts +4 -5
  55. package/dist/inspector/canvas/rendererMessageRouter.js +12 -16
  56. package/dist/inspector/canvas/rendererSelectionProxy.d.ts +7 -1
  57. package/dist/inspector/canvas/rendererSelectionProxy.js +8 -36
  58. package/dist/inspector/canvas/rendererStylesheet.js +15 -0
  59. package/dist/inspector/canvas/sessionStore.d.ts +2 -2
  60. package/dist/inspector/canvas/sessionStore.js +12 -9
  61. package/dist/inspector/canvas/staleChangeDetector.d.ts +1 -1
  62. package/dist/inspector/canvas/staleChangeDetector.js +10 -22
  63. package/dist/inspector/changes/codecs.d.ts +1 -0
  64. package/dist/inspector/changes/codecs.js +20 -5
  65. package/dist/inspector/changes/draftPreview.d.ts +12 -0
  66. package/dist/inspector/changes/draftPreview.js +133 -0
  67. package/dist/inspector/changes/editModel.d.ts +8 -0
  68. package/dist/inspector/changes/editModel.js +8 -2
  69. package/dist/inspector/changes/managedStyleProjection.js +2 -1
  70. package/dist/inspector/changes/previewDiagnostics.js +1 -1
  71. package/dist/inspector/changes/types.d.ts +11 -1
  72. package/dist/inspector/comments/CommentsOverlay.js +18 -16
  73. package/dist/inspector/comments/store.js +3 -2
  74. package/dist/inspector/comments/verification.js +1 -1
  75. package/dist/inspector/componentSemantics/ComponentPropsSection.js +2 -1
  76. package/dist/inspector/componentSemantics/changeAction.js +1 -1
  77. package/dist/inspector/componentSemantics/textBinding.d.ts +1 -2
  78. package/dist/inspector/componentSemantics/textBinding.js +4 -45
  79. package/dist/inspector/drafts/draftStore.d.ts +109 -0
  80. package/dist/inspector/drafts/draftStore.js +451 -0
  81. package/dist/inspector/drafts/model.d.ts +9 -1
  82. package/dist/inspector/drafts/model.js +5 -1
  83. package/dist/inspector/drafts/store.d.ts +53 -15
  84. package/dist/inspector/drafts/store.js +143 -169
  85. package/dist/inspector/index.d.ts +2 -4
  86. package/dist/inspector/index.js +2 -264
  87. package/dist/inspector/inline-text/inlineTextEditor.d.ts +1 -1
  88. package/dist/inspector/inline-text/inlineTextEditor.js +1 -2
  89. package/dist/inspector/inline-text/textEditChange.d.ts +1 -1
  90. package/dist/inspector/inspection/bridge.d.ts +1 -1
  91. package/dist/inspector/inspection/bridge.js +2 -1
  92. package/dist/inspector/inspection/browserCssInspection.d.ts +8 -0
  93. package/dist/inspector/inspection/browserCssInspection.js +28 -6
  94. package/dist/inspector/inspection/inspectionSnapshot.d.ts +6 -0
  95. package/dist/inspector/inspection/inspectionSnapshot.js +10 -0
  96. package/dist/inspector/inspection/performanceDiagnostics.d.ts +18 -0
  97. package/dist/inspector/inspection/performanceDiagnostics.js +31 -0
  98. package/dist/inspector/inspection/useBrowserCssInspection.js +17 -38
  99. package/dist/inspector/iterations/capture.d.ts +2 -1
  100. package/dist/inspector/iterations/client.d.ts +2 -1
  101. package/dist/inspector/iterations/coordinator.d.ts +4 -3
  102. package/dist/inspector/iterations/coordinator.js +5 -3
  103. package/dist/inspector/iterations/prompt.js +9 -8
  104. package/dist/inspector/overlay/interactionStyles.js +17 -0
  105. package/dist/inspector/pageInspector.d.ts +42 -0
  106. package/dist/inspector/pageInspector.js +342 -0
  107. package/dist/inspector/projection/draftProjection.d.ts +10 -2
  108. package/dist/inspector/projection/draftProjection.js +9 -1
  109. package/dist/inspector/projection/managedStylesheet.js +24 -4
  110. package/dist/inspector/projection/renderedInstance.js +7 -1
  111. package/dist/inspector/projection/structuralProjection.d.ts +0 -9
  112. package/dist/inspector/projection/structuralProjection.js +14 -44
  113. package/dist/inspector/projection/textProjection.d.ts +8 -2
  114. package/dist/inspector/projection/textProjection.js +21 -13
  115. package/dist/inspector/prompt/clipboardHandoff.d.ts +9 -0
  116. package/dist/inspector/prompt/clipboardHandoff.js +42 -16
  117. package/dist/inspector/prompt/generatePrompt.d.ts +1 -1
  118. package/dist/inspector/prompt/generatePrompt.js +243 -147
  119. package/dist/inspector/prompt/promptDocument.d.ts +3 -0
  120. package/dist/inspector/prompt/promptDocument.js +8 -0
  121. package/dist/inspector/prompt/promptSettings.js +7 -5
  122. package/dist/inspector/runtime/inspectorStorage.d.ts +17 -0
  123. package/dist/inspector/runtime/inspectorStorage.js +42 -0
  124. package/dist/inspector/runtime/ownedStylesheets.d.ts +20 -0
  125. package/dist/inspector/runtime/ownedStylesheets.js +72 -0
  126. package/dist/inspector/runtime/runtimeConfig.d.ts +4 -0
  127. package/dist/inspector/runtime/runtimeConfig.js +10 -1
  128. package/dist/inspector/runtime/runtimeIdentityClaims.d.ts +29 -0
  129. package/dist/inspector/runtime/runtimeIdentityClaims.js +188 -0
  130. package/dist/inspector/runtime/staticHtmlRuntimeIdentity.d.ts +15 -0
  131. package/dist/inspector/runtime/staticHtmlRuntimeIdentity.js +113 -29
  132. package/dist/inspector/selection/editScope.d.ts +1 -0
  133. package/dist/inspector/selection/editScope.js +13 -2
  134. package/dist/inspector/shell/AgentStatusButton.js +2 -2
  135. package/dist/inspector/shell/AppShell.js +6 -2
  136. package/dist/inspector/shell/ChangesLog.js +27 -9
  137. package/dist/inspector/shell/CopyPromptButton.js +60 -54
  138. package/dist/inspector/shell/EmptyState.js +3 -3
  139. package/dist/inspector/shell/InspectorShell.d.ts +0 -3
  140. package/dist/inspector/shell/InspectorShell.js +21 -13
  141. package/dist/inspector/shell/PeekOriginalButton.js +3 -3
  142. package/dist/inspector/shell/interactionStatePreview.d.ts +9 -0
  143. package/dist/inspector/shell/interactionStatePreview.js +112 -0
  144. package/dist/inspector/shell/originalPreview.d.ts +3 -2
  145. package/dist/inspector/shell/originalPreview.js +10 -37
  146. package/dist/inspector/shell/stateValue.js +2 -3
  147. package/dist/inspector/sketch/SketchEditor.js +5 -4
  148. package/dist/inspector/sketch/SketchFrameOverlay.d.ts +2 -1
  149. package/dist/inspector/sketch/SketchFrameOverlay.js +5 -4
  150. package/dist/inspector/sketch/SketchOverlay.d.ts +3 -5
  151. package/dist/inspector/sketch/SketchOverlay.js +139 -263
  152. package/dist/inspector/sketch/SketchPromptPanel.d.ts +1 -1
  153. package/dist/inspector/sketch/SketchPromptPanel.js +8 -1
  154. package/dist/inspector/sketch/SketchThumbnail.d.ts +5 -0
  155. package/dist/inspector/sketch/SketchThumbnail.js +18 -0
  156. package/dist/inspector/sketch/SketchWorkspace.d.ts +1 -2
  157. package/dist/inspector/sketch/SketchWorkspace.js +69 -34
  158. package/dist/inspector/sketch/capture.js +19 -3
  159. package/dist/inspector/sketch/copySketch.d.ts +10 -0
  160. package/dist/inspector/sketch/copySketch.js +52 -0
  161. package/dist/inspector/sketch/drawingTools.d.ts +17 -0
  162. package/dist/inspector/sketch/drawingTools.js +47 -0
  163. package/dist/inspector/sketch/frameHeading.d.ts +9 -0
  164. package/dist/inspector/sketch/frameHeading.js +30 -0
  165. package/dist/inspector/sketch/freehand.js +3 -3
  166. package/dist/inspector/sketch/geometry.d.ts +6 -0
  167. package/dist/inspector/sketch/geometry.js +19 -0
  168. package/dist/inspector/sketch/history.d.ts +30 -0
  169. package/dist/inspector/sketch/history.js +58 -0
  170. package/dist/inspector/sketch/interaction.d.ts +1 -3
  171. package/dist/inspector/sketch/interaction.js +6 -9
  172. package/dist/inspector/sketch/model.d.ts +35 -1
  173. package/dist/inspector/sketch/model.js +116 -61
  174. package/dist/inspector/sketch/persistence.d.ts +14 -0
  175. package/dist/inspector/sketch/persistence.js +63 -7
  176. package/dist/inspector/sketch/raster.d.ts +6 -2
  177. package/dist/inspector/sketch/raster.js +43 -17
  178. package/dist/inspector/sketch/store.d.ts +1 -1
  179. package/dist/inspector/sketch/store.js +1 -1
  180. package/dist/inspector/sketch/videoFrames.d.ts +6 -0
  181. package/dist/inspector/sketch/videoFrames.js +81 -0
  182. package/dist/inspector/styleEditors/BackgroundEditor.js +2 -1
  183. package/dist/inspector/styleEditors/BorderEditor.js +30 -130
  184. package/dist/inspector/styleEditors/BorderRadiusEditor.js +8 -3
  185. package/dist/inspector/styleEditors/ImageBackgroundEditor.js +1 -1
  186. package/dist/inspector/styleEditors/LayoutSection.js +2 -2
  187. package/dist/inspector/styleEditors/borderModel.d.ts +42 -0
  188. package/dist/inspector/styleEditors/borderModel.js +114 -0
  189. package/dist/inspector/styleEditors/layoutValue.js +2 -3
  190. package/dist/inspector/tokens/TokenField.js +34 -3
  191. package/dist/inspector/tokens/TokensPanel.js +2 -1
  192. package/dist/inspector/tokens/editActions.d.ts +3 -3
  193. package/dist/inspector/tokens/editActions.js +9 -3
  194. package/dist/inspector/tokens/resolution/containerQueryEvaluator.d.ts +15 -0
  195. package/dist/inspector/tokens/resolution/containerQueryEvaluator.js +86 -0
  196. package/dist/inspector/tokens/resolution/cssomCollector.js +44 -9
  197. package/dist/inspector/tokens/resolution/nestedSelectors.d.ts +6 -0
  198. package/dist/inspector/tokens/resolution/nestedSelectors.js +67 -0
  199. package/dist/inspector/tokens/resolution/ruleMatching.js +23 -4
  200. package/dist/inspector/tokens/resolution.d.ts +6 -3
  201. package/dist/inspector/tokens/resolution.js +91 -112
  202. package/dist/inspector/tokens/tokenEdits.d.ts +1 -1
  203. package/dist/inspector/tokens/tokenEdits.js +1 -1
  204. package/dist/inspector/ui/InlineStyleWarning.js +2 -2
  205. package/dist/inspector/ui/InspectorStyle.d.ts +8 -0
  206. package/dist/inspector/ui/InspectorStyle.js +26 -0
  207. package/dist/inspector/ui/PopoverListbox.d.ts +2 -1
  208. package/dist/inspector/ui/PopoverListbox.js +3 -3
  209. package/dist/inspector/ui/Toast.d.ts +14 -0
  210. package/dist/inspector/ui/Toast.js +30 -0
  211. package/dist/inspector/ui/assets/canvasIllustration.d.ts +2 -0
  212. package/dist/inspector/ui/assets/canvasIllustration.js +21 -0
  213. package/dist/inspector/ui/assets/gridIllustration.d.ts +2 -0
  214. package/dist/inspector/ui/assets/{grid.svg → gridIllustration.js} +3 -2
  215. package/dist/inspector/ui/customCursors.d.ts +5 -0
  216. package/dist/inspector/ui/customCursors.js +32 -6
  217. package/dist/inspector/ui/styles.js +12 -10
  218. package/dist/inspector/workspace/commands.js +1 -2
  219. package/dist/inspector/workspace/controller.js +1 -2
  220. package/dist/inspector/workspace/handoff.js +3 -2
  221. package/dist/inspector/workspace/sentItems.d.ts +3 -6
  222. package/dist/inspector/workspace/sentItems.js +6 -24
  223. package/dist/inspector/workspace/timeline.d.ts +24 -10
  224. package/dist/inspector/workspace/timeline.js +118 -96
  225. package/dist/internal/agent-protocol.d.ts +50 -13
  226. package/dist/internal/agent-protocol.js +145 -19
  227. package/dist/nudge-ui.mjs +81 -65
  228. package/dist/project/mcpPackage.d.ts +8 -0
  229. package/dist/project/mcpPackage.js +60 -0
  230. package/package.json +12 -2
  231. package/dist/inspector/canvas/measurementProjection.d.ts +0 -8
  232. package/dist/inspector/canvas/measurementProjection.js +0 -16
  233. package/dist/inspector/changes/changesLog.d.ts +0 -49
  234. package/dist/inspector/changes/changesLog.js +0 -255
  235. package/dist/inspector/changes/draftChanges.d.ts +0 -58
  236. package/dist/inspector/changes/draftChanges.js +0 -304
  237. package/dist/inspector/conformance/projection.d.ts +0 -2
  238. package/dist/inspector/conformance/projection.js +0 -3
  239. package/dist/inspector/inline-text/textChangeBoundary.d.ts +0 -6
  240. package/dist/inspector/inline-text/textChangeBoundary.js +0 -1
  241. package/dist/inspector/overlay/InspectorOverlay.d.ts +0 -5
  242. package/dist/inspector/overlay/InspectorOverlay.js +0 -332
  243. package/dist/inspector/overlay/elementSelector.d.ts +0 -1
  244. package/dist/inspector/overlay/elementSelector.js +0 -111
  245. package/dist/inspector/sketch/SketchChanges.d.ts +0 -2
  246. package/dist/inspector/sketch/SketchChanges.js +0 -72
  247. package/dist/inspector/sketch/SketchEntryButton.d.ts +0 -4
  248. package/dist/inspector/sketch/SketchEntryButton.js +0 -11
  249. package/dist/inspector/sketch/SketchLayersPanel.d.ts +0 -2
  250. package/dist/inspector/sketch/SketchLayersPanel.js +0 -71
@@ -1,15 +1,37 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { assignSketchToDraft } from "../drafts/store.js";
3
- import { getActiveDraftChanges } from "../changes/draftChanges.js";
2
+ import { canvasFrameHost } from "../canvas/canvasFrame.js";
3
+ import { getRegisteredFrames } from "../canvas/projection.js";
4
+ import { setSelectedElement } from "../selection/selectionStore.js";
5
+ import { selectCard } from "../canvas/canvasStore.js";
6
+ import { activateDraftForCard, assignSketchToDraft, getActiveDraftChanges } from "../drafts/store.js";
4
7
  import { useEffect, useState } from "react";
5
8
  import { renderAnnotatedPng } from "./raster.js";
9
+ import { sketchFrameHeading } from "./frameHeading.js";
6
10
  import { closeSketchEditor, completeSketchCapture, beginSketchCapture, cancelSketchInteraction, openSketchEditor, useSketchInteraction } from "./interaction.js";
7
- import { initializeSketchStore, saveSketch, useSketchStore } from "./store.js";
11
+ import { recordCanvasChange } from "../workspace/timeline.js";
12
+ import { getSketch, initializeSketchStore, removeSketch, saveSketch, useSketchStore } from "./store.js";
8
13
  import { clearSketchClipboardHandoff } from "./handoff.js";
14
+ import { copySketchImage, saveAndCopySketch } from "./copySketch.js";
9
15
  import { SketchEditor } from "./SketchEditor.js";
10
16
  import { SketchOverlay } from "./SketchOverlay.js";
11
17
  import { closeSketchNote, useSketchNote } from "./sketchNote.js";
12
18
  import { SketchPromptPanel } from "./SketchPromptPanel.js";
19
+ /** Makes saving a new sketch one step in the session undo history. */
20
+ function recordSketchCreation(document, owner) {
21
+ let snapshot = document;
22
+ recordCanvasChange({
23
+ cardIds: [],
24
+ undo: () => {
25
+ snapshot = getSketch(document.id)?.document ?? snapshot;
26
+ void removeSketch(document.id);
27
+ },
28
+ redo: () => {
29
+ void saveSketch({ ...snapshot, annotations: snapshot.annotations ?? [] })
30
+ .then((saved) => assignSketchToDraft(owner, saved.id));
31
+ },
32
+ dispose: () => undefined,
33
+ });
34
+ }
13
35
  function clamp(value, maximum) {
14
36
  return Math.max(0, Math.min(maximum, value));
15
37
  }
@@ -37,26 +59,6 @@ export function projectLiveStrokes(draft, captured) {
37
59
  }];
38
60
  });
39
61
  }
40
- function projectLiveAnnotations(draft, captured) {
41
- const scaleX = captured.imageWidth / Math.max(1, draft.viewport.width);
42
- const scaleY = captured.imageHeight / Math.max(1, draft.viewport.height);
43
- const captureScrollX = captured.capture.scrollX;
44
- const captureScrollY = captured.capture.scrollY;
45
- const visibleRight = captureScrollX + draft.viewport.width;
46
- const visibleBottom = captureScrollY + draft.viewport.height;
47
- return draft.annotations
48
- .filter((annotation) => annotation.point.x >= captureScrollX
49
- && annotation.point.x <= visibleRight
50
- && annotation.point.y >= captureScrollY
51
- && annotation.point.y <= visibleBottom)
52
- .map((annotation) => ({
53
- ...annotation,
54
- point: {
55
- x: clamp((annotation.point.x - captureScrollX) * scaleX, captured.imageWidth),
56
- y: clamp((annotation.point.y - captureScrollY) * scaleY, captured.imageHeight),
57
- },
58
- }));
59
- }
60
62
  export function SketchWorkspace({ hostElement, projectId }) {
61
63
  const interaction = useSketchInteraction();
62
64
  const store = useSketchStore();
@@ -77,39 +79,71 @@ export function SketchWorkspace({ hostElement, projectId }) {
77
79
  const noteDocument = note.sketchId
78
80
  ? store.items.find((item) => item.document.id === note.sketchId)?.document ?? null
79
81
  : null;
82
+ function selectTarget(point, lockedTarget) {
83
+ for (const [cardId, frame] of getRegisteredFrames()) {
84
+ const target = canvasFrameHost(frame);
85
+ if (!target || !frame.isConnected || getComputedStyle(target).visibility === "hidden")
86
+ continue;
87
+ const bounds = frame.getBoundingClientRect();
88
+ if (bounds.width <= 0 || bounds.height <= 0)
89
+ continue;
90
+ if (point.x < bounds.left || point.x > bounds.right || point.y < bounds.top || point.y > bounds.bottom)
91
+ continue;
92
+ if (lockedTarget && target !== lockedTarget)
93
+ return null;
94
+ if (target !== hostElement) {
95
+ setSelectedElement(null);
96
+ selectCard(cardId);
97
+ activateDraftForCard(cardId);
98
+ beginSketchCapture();
99
+ }
100
+ return target;
101
+ }
102
+ return null;
103
+ }
80
104
  async function save(input) {
81
105
  const owner = interaction.draftId ?? getActiveDraftChanges().draftId;
82
106
  const saved = await saveSketch(input);
83
- if (!input.id)
107
+ if (!input.id) {
84
108
  assignSketchToDraft(owner, saved.id);
109
+ recordSketchCreation(saved, owner);
110
+ }
85
111
  closeSketchEditor();
112
+ void copySketchImage(input.annotatedImage);
113
+ }
114
+ function saveLive(draft) {
115
+ return saveAndCopySketch(() => saveLiveSketch(draft));
86
116
  }
87
- async function saveLive(draft) {
117
+ async function saveLiveSketch(draft) {
88
118
  if (!hostElement)
89
119
  throw new Error("The inspector is no longer available.");
90
120
  const owner = interaction.draftId ?? getActiveDraftChanges().draftId;
91
121
  const captured = await completeSketchCapture(hostElement);
92
122
  const strokes = projectLiveStrokes(draft, captured);
93
- const annotations = projectLiveAnnotations(draft, captured);
94
- const rendered = await renderAnnotatedPng(captured.originalImage, captured.imageWidth, captured.imageHeight, strokes, annotations, draft.description);
123
+ const rendered = await renderAnnotatedPng(captured.originalImage, captured.imageWidth, captured.imageHeight, strokes, [], draft.description, sketchFrameHeading(captured.capture.url));
95
124
  const saved = await saveSketch({
96
125
  capture: captured.capture,
97
126
  description: draft.description,
98
127
  strokes,
99
- annotations,
128
+ annotations: [],
100
129
  imageWidth: rendered.width,
101
130
  imageHeight: rendered.height,
102
131
  originalImage: captured.originalImage,
103
132
  annotatedImage: rendered.blob,
104
133
  });
105
134
  assignSketchToDraft(owner, saved.id);
135
+ recordSketchCreation(saved, owner);
106
136
  closeSketchEditor();
137
+ return rendered.blob;
107
138
  }
108
- async function saveNote(description) {
139
+ function saveNote(description) {
109
140
  if (!noteDocument)
110
- return;
141
+ return Promise.resolve();
142
+ return saveAndCopySketch(() => saveNoteSketch(noteDocument, description));
143
+ }
144
+ async function saveNoteSketch(noteDocument, description) {
111
145
  const nextDescription = description.trim();
112
- const rendered = await renderAnnotatedPng(noteDocument.originalImage, noteDocument.capture.imageWidth, noteDocument.capture.imageHeight, noteDocument.strokes, noteDocument.annotations ?? [], nextDescription);
146
+ const rendered = await renderAnnotatedPng(noteDocument.originalImage, noteDocument.capture.imageWidth, noteDocument.capture.imageHeight, noteDocument.strokes, noteDocument.annotations ?? [], nextDescription, sketchFrameHeading(noteDocument.capture.url));
113
147
  await saveSketch({
114
148
  id: noteDocument.id,
115
149
  capture: noteDocument.capture,
@@ -122,8 +156,9 @@ export function SketchWorkspace({ hostElement, projectId }) {
122
156
  annotatedImage: rendered.blob,
123
157
  });
124
158
  closeSketchNote();
159
+ return rendered.blob;
125
160
  }
126
- return (_jsxs(_Fragment, { children: [hostElement ? (_jsx(SketchOverlay, { open: liveOpen, hostElement: hostElement, initialTool: interaction.initialTool, onCancel: cancelSketchInteraction, onDone: saveLive })) : null, _jsx(SketchEditor, { open: editorOpen, document: editingDocument, captured: interaction.captured, onCancel: cancelSketchInteraction, onSave: save }), noteDocument ? (_jsx(SavedSketchNote, { document: noteDocument, onSave: saveNote, onCancel: closeSketchNote })) : null] }));
161
+ return (_jsxs(_Fragment, { children: [hostElement ? (_jsx(SketchOverlay, { open: liveOpen, hostElement: hostElement, selectTarget: selectTarget, onCancel: cancelSketchInteraction, onDone: saveLive })) : null, _jsx(SketchEditor, { open: editorOpen, document: editingDocument, captured: interaction.captured, onCancel: cancelSketchInteraction, onSave: save }), noteDocument ? (_jsx(SavedSketchNote, { document: noteDocument, onSave: saveNote, onCancel: closeSketchNote })) : null] }));
127
162
  }
128
163
  function SavedSketchNote({ document, onSave, onCancel, }) {
129
164
  const [description, setDescription] = useState(document.description);
@@ -148,10 +183,10 @@ function SavedSketchNote({ document, onSave, onCancel, }) {
148
183
  }
149
184
  return (_jsx(SketchPromptPanel, { dataTest: "sketch-note-prompt", className: "sketch__saved-note-panel", description: description, error: error, saving: saving, autoFocus: true, onDescriptionChange: setDescription, onDone: done, onCancel: onCancel }));
150
185
  }
151
- export function startSketchCapture(hostElement, initialTool = "pen") {
186
+ export function startSketchCapture(hostElement) {
152
187
  if (!hostElement)
153
188
  return;
154
- beginSketchCapture(initialTool);
189
+ beginSketchCapture();
155
190
  }
156
191
  export function editSketch(sketchId) {
157
192
  openSketchEditor(sketchId);
@@ -2,6 +2,7 @@ import { domToBlob } from "modern-screenshot";
2
2
  import { getNudgeUiRuntimeConfig } from "../runtime/runtimeConfig.js";
3
3
  import { SKETCH_LIMITS } from "./model.js";
4
4
  import { getPngDimensions } from "./raster.js";
5
+ import { prepareSketchVideoFrames } from "./videoFrames.js";
5
6
  const MEDIA_LOAD_TIMEOUT_MS = 500;
6
7
  const FONT_READY_TIMEOUT_MS = 2_000;
7
8
  const DEFAULT_PROCESSING_TIMEOUT_MS = 20_000;
@@ -258,7 +259,17 @@ async function captureDomFrame(options, signal) {
258
259
  let scale = viewport.scale;
259
260
  for (let attempt = 0; attempt < 7; attempt += 1) {
260
261
  assertNotAborted(signal);
262
+ const videoFrames = prepareSketchVideoFrames(surface.document);
261
263
  const restoreMedia = suspendOffscreenLazyImages(surface.document, viewport);
264
+ let restored = false;
265
+ const restore = () => {
266
+ if (restored)
267
+ return;
268
+ restored = true;
269
+ videoFrames.restore();
270
+ restoreMedia();
271
+ };
272
+ signal?.addEventListener("abort", restore, { once: true });
262
273
  let blob;
263
274
  try {
264
275
  blob = await domToBlob(surface.document.documentElement, {
@@ -272,18 +283,23 @@ async function captureDomFrame(options, signal) {
272
283
  height: `${viewport.height}px`,
273
284
  overflow: "hidden",
274
285
  },
275
- filter: (node) => node !== options.hostElement && !isGoogleFontStylesheet(node),
286
+ filter: (node) => node !== options.hostElement && !isGoogleFontStylesheet(node) && videoFrames.filter(node),
276
287
  features: { restoreScrollPosition: true },
277
288
  timeout: MEDIA_LOAD_TIMEOUT_MS,
278
289
  // Cross-origin Google CSS cannot be read by modern-screenshot. Skipping
279
290
  // its font embedding avoids waiting on a stylesheet that the renderer
280
291
  // cannot serialize anyway; computed font styles still remain inline.
281
292
  font: hasGoogleFontStylesheet(surface.document) ? false : undefined,
282
- onCloneEachNode: prepareDomClone,
293
+ onCloneEachNode: (node) => {
294
+ prepareDomClone(node);
295
+ videoFrames.prepareClone(node);
296
+ },
297
+ onCloneNode: restore,
283
298
  });
284
299
  }
285
300
  finally {
286
- restoreMedia();
301
+ signal?.removeEventListener("abort", restore);
302
+ restore();
287
303
  }
288
304
  assertNotAborted(signal);
289
305
  const dimensions = await getPngDimensions(blob);
@@ -0,0 +1,10 @@
1
+ /** Copies a saved sketch image automatically after an edit and reports the outcome as a toast. */
2
+ export declare function copySketchImage(image: Blob): Promise<void>;
3
+ /** Copies a sketch image the user asked for; only a failure needs a toast. */
4
+ export declare function copySketchImageOnRequest(image: Blob): Promise<void>;
5
+ /**
6
+ * Starts the clipboard write synchronously (inside the "Done" gesture) and
7
+ * fills it with the image that `save` renders. A failed save skips the toast
8
+ * and rethrows so the caller can show its own error.
9
+ */
10
+ export declare function saveAndCopySketch(save: () => Promise<Blob>): Promise<void>;
@@ -0,0 +1,52 @@
1
+ import { showToast } from "../ui/Toast.js";
2
+ import { copyImageToClipboard } from "./raster.js";
3
+ function reportCopyFailure(title, error) {
4
+ showToast({
5
+ tone: "error",
6
+ title,
7
+ description: error instanceof Error ? error.message : "The sketch image could not be copied.",
8
+ });
9
+ }
10
+ /**
11
+ * Reports a copy made automatically on save. The toast is the only sign the
12
+ * clipboard changed, so success is announced as well as failure.
13
+ */
14
+ function reportAutoCopy(copied) {
15
+ void copied.then(() => showToast({ title: "Copied to clipboard" }), (error) => reportCopyFailure("Sketch saved, but not copied", error));
16
+ }
17
+ /** Copies a saved sketch image automatically after an edit and reports the outcome as a toast. */
18
+ export function copySketchImage(image) {
19
+ const copied = copyImageToClipboard(image);
20
+ reportAutoCopy(copied);
21
+ return copied.catch(() => undefined);
22
+ }
23
+ /** Copies a sketch image the user asked for; only a failure needs a toast. */
24
+ export function copySketchImageOnRequest(image) {
25
+ const copied = copyImageToClipboard(image);
26
+ void copied.catch((error) => reportCopyFailure("Sketch not copied", error));
27
+ return copied.catch(() => undefined);
28
+ }
29
+ /**
30
+ * Starts the clipboard write synchronously (inside the "Done" gesture) and
31
+ * fills it with the image that `save` renders. A failed save skips the toast
32
+ * and rethrows so the caller can show its own error.
33
+ */
34
+ export async function saveAndCopySketch(save) {
35
+ let resolveImage = () => undefined;
36
+ let rejectImage = () => undefined;
37
+ const image = new Promise((resolve, reject) => {
38
+ resolveImage = resolve;
39
+ rejectImage = reject;
40
+ });
41
+ image.catch(() => undefined);
42
+ const copied = copyImageToClipboard(image);
43
+ copied.catch(() => undefined);
44
+ try {
45
+ resolveImage(await save());
46
+ }
47
+ catch (error) {
48
+ rejectImage(error);
49
+ throw error;
50
+ }
51
+ reportAutoCopy(copied);
52
+ }
@@ -0,0 +1,17 @@
1
+ import { type SketchPenColor } from "./model.js";
2
+ /** Drawing mode chosen from the canvas toolbar while the sketch tool is active. */
3
+ export type SketchDrawingTool = "pen" | "eraser" | "rectangle";
4
+ export interface SketchDrawingToolsSnapshot {
5
+ readonly tool: SketchDrawingTool;
6
+ readonly color: SketchPenColor;
7
+ }
8
+ export declare function getSketchDrawingTools(): SketchDrawingToolsSnapshot;
9
+ export declare function subscribeSketchDrawingTools(listener: () => void): () => void;
10
+ export declare function useSketchDrawingTools(): SketchDrawingToolsSnapshot;
11
+ export declare function setSketchDrawingTool(tool: SketchDrawingTool): void;
12
+ /** Choosing a color implies drawing with it, so the eraser hands back to the pen. */
13
+ export declare function setSketchStrokeColor(color: SketchPenColor): void;
14
+ /** Every sketch session starts with the pen; the chosen color is kept. */
15
+ export declare function resetSketchDrawingTool(): void;
16
+ /** Restores the default tool and color. */
17
+ export declare function restoreDefaultSketchDrawingTools(): void;
@@ -0,0 +1,47 @@
1
+ import { useSyncExternalStore } from "react";
2
+ import { SKETCH_PEN_COLORS, SKETCH_STROKE_COLOR } from "./model.js";
3
+ const DEFAULT_COLOR = SKETCH_PEN_COLORS.find((color) => color.value === SKETCH_STROKE_COLOR) ?? SKETCH_PEN_COLORS[0];
4
+ const DEFAULT_SNAPSHOT = {
5
+ tool: "pen",
6
+ color: DEFAULT_COLOR,
7
+ };
8
+ let snapshot = DEFAULT_SNAPSHOT;
9
+ const listeners = new Set();
10
+ function publish(next) {
11
+ if (next.tool === snapshot.tool && next.color === snapshot.color)
12
+ return;
13
+ snapshot = next;
14
+ for (const listener of listeners) {
15
+ try {
16
+ listener();
17
+ }
18
+ catch {
19
+ // A view subscriber must not stop the others from seeing the new tool.
20
+ }
21
+ }
22
+ }
23
+ export function getSketchDrawingTools() {
24
+ return snapshot;
25
+ }
26
+ export function subscribeSketchDrawingTools(listener) {
27
+ listeners.add(listener);
28
+ return () => listeners.delete(listener);
29
+ }
30
+ export function useSketchDrawingTools() {
31
+ return useSyncExternalStore(subscribeSketchDrawingTools, getSketchDrawingTools, getSketchDrawingTools);
32
+ }
33
+ export function setSketchDrawingTool(tool) {
34
+ publish({ ...snapshot, tool });
35
+ }
36
+ /** Choosing a color implies drawing with it, so the eraser hands back to the pen. */
37
+ export function setSketchStrokeColor(color) {
38
+ publish({ tool: snapshot.tool === "eraser" ? "pen" : snapshot.tool, color });
39
+ }
40
+ /** Every sketch session starts with the pen; the chosen color is kept. */
41
+ export function resetSketchDrawingTool() {
42
+ setSketchDrawingTool("pen");
43
+ }
44
+ /** Restores the default tool and color. */
45
+ export function restoreDefaultSketchDrawingTools() {
46
+ snapshot = DEFAULT_SNAPSHOT;
47
+ }
@@ -0,0 +1,9 @@
1
+ import { type CanvasCard } from "../canvas/canvasStore.js";
2
+ /**
3
+ * Names the frame an annotated sketch targets, so the PNG stays actionable when
4
+ * a user copies it to an agent without the handoff prompt. Iterations also name
5
+ * their artifact file: the folder ID is the only stable identity an agent can
6
+ * use to find the right iteration, since canvas iteration numbers are live
7
+ * labels that nothing persists.
8
+ */
9
+ export declare function sketchFrameHeading(captureUrl: string, frameCards?: readonly CanvasCard[]): string;
@@ -0,0 +1,30 @@
1
+ import { getCanvasCards } from "../canvas/canvasStore.js";
2
+ import { contentSourceUrl } from "../canvas/frameContent.js";
3
+ import { artifactIdFromUrl, htmlTarget } from "../drafts/model.js";
4
+ /** The page path shown in sketch headings; origin, query, and hash stay out. */
5
+ function routePath(url) {
6
+ try {
7
+ return new URL(url).pathname || "/";
8
+ }
9
+ catch {
10
+ return url;
11
+ }
12
+ }
13
+ /**
14
+ * Names the frame an annotated sketch targets, so the PNG stays actionable when
15
+ * a user copies it to an agent without the handoff prompt. Iterations also name
16
+ * their artifact file: the folder ID is the only stable identity an agent can
17
+ * use to find the right iteration, since canvas iteration numbers are live
18
+ * labels that nothing persists.
19
+ */
20
+ export function sketchFrameHeading(captureUrl, frameCards = getCanvasCards()) {
21
+ const artifactId = artifactIdFromUrl(captureUrl);
22
+ if (!artifactId)
23
+ return `Implement these changes for "${routePath(captureUrl)}"`;
24
+ const card = frameCards.find((candidate) => candidate.content.kind === "iteration"
25
+ && candidate.content.artifactId === artifactId);
26
+ const path = htmlTarget(artifactId).path;
27
+ return card
28
+ ? `Implement these changes for the HTML iteration "${routePath(contentSourceUrl(card.content))}" (${path})`
29
+ : `Implement these changes for the HTML iteration (${path})`;
30
+ }
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { getStroke } from "perfect-freehand";
3
- import { SKETCH_STROKE_COLOR, } from "./model.js";
3
+ import { SKETCH_ACCENT_COLOR, SKETCH_RECTANGLE_FILL_OPACITY, SKETCH_STROKE_COLOR, } from "./model.js";
4
4
  const FREEHAND_OPTIONS = {
5
5
  thinning: 0.45,
6
6
  smoothing: 0.5,
@@ -56,9 +56,9 @@ export function SketchSvgLayer({ strokes, annotations = [], annotationScale = 1,
56
56
  if (!path)
57
57
  return null;
58
58
  const rectangle = stroke.kind === "rectangle";
59
- return (_jsx("path", { d: path, fill: rectangle ? "none" : stroke.color || SKETCH_STROKE_COLOR, stroke: rectangle ? stroke.color || SKETCH_STROKE_COLOR : "none", strokeWidth: rectangle ? stroke.width : undefined, strokeLinecap: "round", strokeLinejoin: "round", pointerEvents: "none" }, stroke.id));
59
+ return (_jsx("path", { d: path, fill: stroke.color || SKETCH_STROKE_COLOR, fillOpacity: rectangle ? SKETCH_RECTANGLE_FILL_OPACITY : undefined, stroke: rectangle ? stroke.color || SKETCH_STROKE_COLOR : "none", strokeWidth: rectangle ? stroke.width : undefined, strokeLinecap: "round", strokeLinejoin: "round", pointerEvents: "none" }, stroke.id));
60
60
  }), annotations.map((annotation) => {
61
61
  const radius = 16 * annotationScale;
62
- return (_jsxs("g", { transform: `translate(${number(annotation.point.x)} ${number(annotation.point.y)})`, pointerEvents: "none", children: [_jsx("circle", { r: radius, fill: SKETCH_STROKE_COLOR }), _jsx("text", { x: "0", y: "0", fill: "#ffffff", fontFamily: "system-ui, sans-serif", fontSize: 12 * annotationScale, fontWeight: "600", textAnchor: "middle", dominantBaseline: "central", children: annotation.number })] }, annotation.id));
62
+ return (_jsxs("g", { transform: `translate(${number(annotation.point.x)} ${number(annotation.point.y)})`, pointerEvents: "none", children: [_jsx("circle", { r: radius, fill: SKETCH_ACCENT_COLOR }), _jsx("text", { x: "0", y: "0", fill: "#ffffff", fontFamily: "system-ui, sans-serif", fontSize: 12 * annotationScale, fontWeight: "600", textAnchor: "middle", dominantBaseline: "central", children: annotation.number })] }, annotation.id));
63
63
  })] }));
64
64
  }
@@ -15,3 +15,9 @@ export declare function distanceToSegment(point: SketchPoint, start: SketchPoint
15
15
  export declare function findSketchElementAt(point: SketchPoint, strokes: readonly SketchStroke[], annotations: readonly SketchAnnotation[]): SketchElementReference | null;
16
16
  export declare function translateSketchStroke(stroke: SketchStroke, delta: SketchPoint, bounds: SketchBounds): SketchStroke;
17
17
  export declare function translateSketchAnnotation(annotation: SketchAnnotation, delta: SketchPoint, bounds: SketchBounds): SketchAnnotation;
18
+ /**
19
+ * Returns the ids of strokes whose drawn line passes within `radius` of the
20
+ * eraser path from `start` to `end`. Rectangles are hit on their outline only,
21
+ * so erasing across the inside of a box leaves it in place.
22
+ */
23
+ export declare function findErasedSketchStrokeIds(start: SketchPoint, end: SketchPoint, strokes: readonly SketchStroke[], radius: number): string[];
@@ -96,3 +96,22 @@ export function translateSketchAnnotation(annotation, delta, bounds) {
96
96
  },
97
97
  };
98
98
  }
99
+ /**
100
+ * Returns the ids of strokes whose drawn line passes within `radius` of the
101
+ * eraser path from `start` to `end`. Rectangles are hit on their outline only,
102
+ * so erasing across the inside of a box leaves it in place.
103
+ */
104
+ export function findErasedSketchStrokeIds(start, end, strokes, radius) {
105
+ const steps = Math.max(1, Math.ceil(distance(start, end) / Math.max(1, radius / 2)));
106
+ const samples = [];
107
+ for (let step = 0; step <= steps; step += 1) {
108
+ const position = step / steps;
109
+ samples.push({ x: start.x + (end.x - start.x) * position, y: start.y + (end.y - start.y) * position });
110
+ }
111
+ return strokes
112
+ .filter((stroke) => {
113
+ const tolerance = radius + stroke.width / 2;
114
+ return samples.some((sample) => distanceToStroke(sample, stroke) <= tolerance);
115
+ })
116
+ .map((stroke) => stroke.id);
117
+ }
@@ -0,0 +1,30 @@
1
+ import type { SketchStroke } from "./model.js";
2
+ interface ErasedStroke {
3
+ readonly stroke: SketchStroke;
4
+ /** Position in the stroke list at the moment it was erased. */
5
+ readonly index: number;
6
+ }
7
+ type SketchHistoryEntry = {
8
+ readonly kind: "add";
9
+ readonly stroke: SketchStroke;
10
+ } | {
11
+ readonly kind: "erase";
12
+ readonly gesture: number;
13
+ readonly erased: readonly ErasedStroke[];
14
+ };
15
+ /** Strokes plus the undo and redo stacks of the edits that produced them. */
16
+ export interface SketchHistory {
17
+ readonly strokes: readonly SketchStroke[];
18
+ readonly undo: readonly SketchHistoryEntry[];
19
+ readonly redo: readonly SketchHistoryEntry[];
20
+ }
21
+ export declare const EMPTY_SKETCH_HISTORY: SketchHistory;
22
+ export declare function addSketchStroke(history: SketchHistory, stroke: SketchStroke): SketchHistory;
23
+ /**
24
+ * Erases strokes as one undoable edit. Strokes erased by the same `gesture`
25
+ * share an entry, so one eraser drag undoes in a single step.
26
+ */
27
+ export declare function eraseSketchStrokes(history: SketchHistory, ids: readonly string[], gesture: number): SketchHistory;
28
+ export declare function undoSketchEdit(history: SketchHistory): SketchHistory;
29
+ export declare function redoSketchEdit(history: SketchHistory): SketchHistory;
30
+ export {};
@@ -0,0 +1,58 @@
1
+ export const EMPTY_SKETCH_HISTORY = { strokes: [], undo: [], redo: [] };
2
+ export function addSketchStroke(history, stroke) {
3
+ return {
4
+ strokes: [...history.strokes, stroke],
5
+ undo: [...history.undo, { kind: "add", stroke }],
6
+ redo: [],
7
+ };
8
+ }
9
+ function removeStrokes(strokes, ids) {
10
+ const remaining = [];
11
+ const erased = [];
12
+ strokes.forEach((stroke, index) => {
13
+ if (ids.has(stroke.id))
14
+ erased.push({ stroke, index: index - erased.length });
15
+ else
16
+ remaining.push(stroke);
17
+ });
18
+ return { strokes: remaining, erased };
19
+ }
20
+ /**
21
+ * Erases strokes as one undoable edit. Strokes erased by the same `gesture`
22
+ * share an entry, so one eraser drag undoes in a single step.
23
+ */
24
+ export function eraseSketchStrokes(history, ids, gesture) {
25
+ const { strokes, erased } = removeStrokes(history.strokes, new Set(ids));
26
+ if (erased.length === 0)
27
+ return history;
28
+ const last = history.undo.at(-1);
29
+ const undo = last?.kind === "erase" && last.gesture === gesture
30
+ ? [...history.undo.slice(0, -1), { ...last, erased: [...last.erased, ...erased] }]
31
+ : [...history.undo, { kind: "erase", gesture, erased }];
32
+ return { strokes, undo, redo: [] };
33
+ }
34
+ function restoreErased(strokes, erased) {
35
+ const restored = [...strokes];
36
+ // Reinsert in reverse removal order so each recorded index is valid again.
37
+ for (const { stroke, index } of [...erased].reverse())
38
+ restored.splice(index, 0, stroke);
39
+ return restored;
40
+ }
41
+ export function undoSketchEdit(history) {
42
+ const entry = history.undo.at(-1);
43
+ if (!entry)
44
+ return history;
45
+ const strokes = entry.kind === "add"
46
+ ? history.strokes.filter((stroke) => stroke.id !== entry.stroke.id)
47
+ : restoreErased(history.strokes, entry.erased);
48
+ return { strokes, undo: history.undo.slice(0, -1), redo: [...history.redo, entry] };
49
+ }
50
+ export function redoSketchEdit(history) {
51
+ const entry = history.redo.at(-1);
52
+ if (!entry)
53
+ return history;
54
+ const strokes = entry.kind === "add"
55
+ ? [...history.strokes, entry.stroke]
56
+ : removeStrokes(history.strokes, new Set(entry.erased.map(({ stroke }) => stroke.id))).strokes;
57
+ return { strokes, undo: [...history.undo, entry], redo: history.redo.slice(0, -1) };
58
+ }
@@ -1,12 +1,10 @@
1
1
  import { type CapturedSketch } from "./capture.js";
2
2
  export type SketchCaptureState = "idle" | "sketching" | "capturing" | "ready" | "error";
3
- export type SketchEntryTool = "pen" | "annotate";
4
3
  export interface SketchInteractionSnapshot {
5
4
  readonly captureState: SketchCaptureState;
6
5
  readonly captured: CapturedSketch | null;
7
6
  readonly editingId: string | null;
8
7
  readonly error: string | null;
9
- readonly initialTool: SketchEntryTool;
10
8
  readonly draftId: string | null;
11
9
  }
12
10
  export declare function getSketchInteractionSnapshot(): SketchInteractionSnapshot;
@@ -14,7 +12,7 @@ export declare function subscribeSketchInteraction(listener: () => void): () =>
14
12
  export declare function useSketchInteraction(): SketchInteractionSnapshot;
15
13
  export declare function isSketchInteractionActive(): boolean;
16
14
  export declare function useSketchInteractionActive(): boolean;
17
- export declare function beginSketchCapture(initialTool?: SketchEntryTool): void;
15
+ export declare function beginSketchCapture(): void;
18
16
  export declare function completeSketchCapture(hostElement: HTMLElement): Promise<CapturedSketch>;
19
17
  export declare function cancelSketchInteraction(): void;
20
18
  export declare function openSketchEditor(sketchId: string): void;
@@ -1,4 +1,4 @@
1
- import { getActiveDraftChanges } from "../changes/draftChanges.js";
1
+ import { getActiveDraftChanges } from "../drafts/store.js";
2
2
  import { useSyncExternalStore } from "react";
3
3
  import { captureViewport, } from "./capture.js";
4
4
  const EMPTY_SNAPSHOT = {
@@ -6,7 +6,6 @@ const EMPTY_SNAPSHOT = {
6
6
  captured: null,
7
7
  editingId: null,
8
8
  error: null,
9
- initialTool: "pen",
10
9
  draftId: null,
11
10
  };
12
11
  let snapshot = EMPTY_SNAPSHOT;
@@ -40,25 +39,24 @@ export function useSketchInteractionActive() {
40
39
  const current = useSketchInteraction();
41
40
  return current.captureState !== "idle" || current.captured !== null || current.editingId !== null;
42
41
  }
43
- export function beginSketchCapture(initialTool = "pen") {
42
+ export function beginSketchCapture() {
44
43
  captureController?.abort();
45
44
  captureController = null;
46
- publish({ captureState: "sketching", captured: null, editingId: null, error: null, initialTool, draftId: getActiveDraftChanges().draftId });
45
+ publish({ captureState: "sketching", captured: null, editingId: null, error: null, draftId: getActiveDraftChanges().draftId });
47
46
  }
48
47
  export function completeSketchCapture(hostElement) {
49
48
  captureController?.abort();
50
49
  const controller = new AbortController();
51
50
  captureController = controller;
52
- const initialTool = snapshot.initialTool;
53
51
  const draftId = snapshot.draftId;
54
- publish({ captureState: "capturing", captured: null, editingId: null, error: null, initialTool, draftId });
52
+ publish({ captureState: "capturing", captured: null, editingId: null, error: null, draftId });
55
53
  const options = { hostElement, signal: controller.signal };
56
54
  return captureViewport(options)
57
55
  .then((captured) => {
58
56
  if (captureController !== controller)
59
57
  return captured;
60
58
  captureController = null;
61
- publish({ captureState: "ready", captured, editingId: null, error: null, initialTool, draftId });
59
+ publish({ captureState: "ready", captured, editingId: null, error: null, draftId });
62
60
  return captured;
63
61
  })
64
62
  .catch((error) => {
@@ -74,7 +72,6 @@ export function completeSketchCapture(hostElement) {
74
72
  captured: null,
75
73
  editingId: null,
76
74
  error: error instanceof Error ? error.message : "The viewport could not be captured.",
77
- initialTool,
78
75
  draftId,
79
76
  });
80
77
  throw error;
@@ -88,7 +85,7 @@ export function cancelSketchInteraction() {
88
85
  export function openSketchEditor(sketchId) {
89
86
  captureController?.abort();
90
87
  captureController = null;
91
- publish({ captureState: "idle", captured: null, editingId: sketchId, error: null, initialTool: "pen", draftId: null });
88
+ publish({ captureState: "idle", captured: null, editingId: sketchId, error: null, draftId: null });
92
89
  }
93
90
  export function closeSketchEditor() {
94
91
  if (snapshot.captureState !== "ready" && snapshot.editingId === null)