nudge-ui 0.2.3 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/dist/cli/agentCommand.js +4 -28
  2. package/dist/client.mjs +870 -212
  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 +5 -7
  16. package/dist/inspector/agent/verification.js +67 -20
  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 +23 -12
  22. package/dist/inspector/canvas/CanvasElementOverlay.js +97 -128
  23. package/dist/inspector/canvas/CanvasToolbar.js +2 -1
  24. package/dist/inspector/canvas/CanvasWorkspace.js +119 -162
  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/frameScrollbarStyles.d.ts +3 -0
  49. package/dist/inspector/canvas/frameScrollbarStyles.js +21 -0
  50. package/dist/inspector/canvas/pageSurface.d.ts +11 -0
  51. package/dist/inspector/canvas/pageSurface.js +34 -0
  52. package/dist/inspector/canvas/projection.d.ts +19 -9
  53. package/dist/inspector/canvas/projection.js +58 -31
  54. package/dist/inspector/canvas/rendererBootstrap.js +4 -1
  55. package/dist/inspector/canvas/rendererElementSelector.js +9 -1
  56. package/dist/inspector/canvas/rendererMessageRouter.d.ts +4 -5
  57. package/dist/inspector/canvas/rendererMessageRouter.js +12 -16
  58. package/dist/inspector/canvas/rendererSelectionProxy.d.ts +7 -1
  59. package/dist/inspector/canvas/rendererSelectionProxy.js +8 -36
  60. package/dist/inspector/canvas/rendererStylesheet.js +15 -0
  61. package/dist/inspector/canvas/sessionStore.d.ts +2 -2
  62. package/dist/inspector/canvas/sessionStore.js +12 -9
  63. package/dist/inspector/canvas/staleChangeDetector.d.ts +1 -1
  64. package/dist/inspector/canvas/staleChangeDetector.js +10 -22
  65. package/dist/inspector/changes/codecs.d.ts +2 -0
  66. package/dist/inspector/changes/codecs.js +27 -3
  67. package/dist/inspector/changes/draftPreview.d.ts +12 -0
  68. package/dist/inspector/changes/draftPreview.js +133 -0
  69. package/dist/inspector/changes/editModel.d.ts +18 -0
  70. package/dist/inspector/changes/editModel.js +16 -3
  71. package/dist/inspector/changes/managedStyleProjection.js +2 -1
  72. package/dist/inspector/changes/previewDiagnostics.js +1 -1
  73. package/dist/inspector/changes/types.d.ts +18 -1
  74. package/dist/inspector/comments/CommentsOverlay.js +18 -16
  75. package/dist/inspector/comments/element.js +10 -3
  76. package/dist/inspector/comments/store.js +3 -2
  77. package/dist/inspector/comments/verification.js +1 -1
  78. package/dist/inspector/componentSemantics/ComponentPropsSection.js +2 -1
  79. package/dist/inspector/componentSemantics/adapterRegistry.d.ts +6 -1
  80. package/dist/inspector/componentSemantics/adapterRegistry.js +23 -1
  81. package/dist/inspector/componentSemantics/changeAction.js +1 -1
  82. package/dist/inspector/componentSemantics/reactRuntime.d.ts +2 -1
  83. package/dist/inspector/componentSemantics/reactRuntime.js +38 -0
  84. package/dist/inspector/componentSemantics/runtimeBridge.d.ts +4 -2
  85. package/dist/inspector/componentSemantics/runtimeBridge.js +17 -0
  86. package/dist/inspector/componentSemantics/textBinding.d.ts +1 -2
  87. package/dist/inspector/componentSemantics/textBinding.js +4 -45
  88. package/dist/inspector/componentSemantics/types.d.ts +11 -0
  89. package/dist/inspector/drafts/draftStore.d.ts +109 -0
  90. package/dist/inspector/drafts/draftStore.js +451 -0
  91. package/dist/inspector/drafts/model.d.ts +9 -1
  92. package/dist/inspector/drafts/model.js +5 -1
  93. package/dist/inspector/drafts/store.d.ts +53 -15
  94. package/dist/inspector/drafts/store.js +143 -169
  95. package/dist/inspector/index.d.ts +2 -4
  96. package/dist/inspector/index.js +2 -264
  97. package/dist/inspector/inline-text/inlineTextEditor.d.ts +1 -1
  98. package/dist/inspector/inline-text/inlineTextEditor.js +1 -2
  99. package/dist/inspector/inline-text/textEditChange.d.ts +1 -1
  100. package/dist/inspector/inspection/bridge.d.ts +1 -1
  101. package/dist/inspector/inspection/bridge.js +2 -1
  102. package/dist/inspector/inspection/browserCssInspection.d.ts +8 -0
  103. package/dist/inspector/inspection/browserCssInspection.js +28 -6
  104. package/dist/inspector/inspection/inspectionSnapshot.d.ts +6 -0
  105. package/dist/inspector/inspection/inspectionSnapshot.js +10 -0
  106. package/dist/inspector/inspection/performanceDiagnostics.d.ts +18 -0
  107. package/dist/inspector/inspection/performanceDiagnostics.js +31 -0
  108. package/dist/inspector/inspection/useBrowserCssInspection.js +17 -38
  109. package/dist/inspector/iterations/capture.d.ts +2 -1
  110. package/dist/inspector/iterations/capture.js +2 -1
  111. package/dist/inspector/iterations/client.d.ts +2 -1
  112. package/dist/inspector/iterations/coordinator.d.ts +4 -3
  113. package/dist/inspector/iterations/coordinator.js +5 -3
  114. package/dist/inspector/iterations/prompt.js +9 -8
  115. package/dist/inspector/overlay/interactionStyles.js +17 -0
  116. package/dist/inspector/pageInspector.d.ts +42 -0
  117. package/dist/inspector/pageInspector.js +342 -0
  118. package/dist/inspector/projection/draftProjection.d.ts +10 -2
  119. package/dist/inspector/projection/draftProjection.js +9 -1
  120. package/dist/inspector/projection/managedStylesheet.js +24 -4
  121. package/dist/inspector/projection/renderedInstance.d.ts +15 -2
  122. package/dist/inspector/projection/renderedInstance.js +60 -7
  123. package/dist/inspector/projection/structuralProjection.d.ts +0 -9
  124. package/dist/inspector/projection/structuralProjection.js +16 -46
  125. package/dist/inspector/projection/textProjection.d.ts +8 -2
  126. package/dist/inspector/projection/textProjection.js +77 -24
  127. package/dist/inspector/prompt/clipboardHandoff.d.ts +14 -0
  128. package/dist/inspector/prompt/clipboardHandoff.js +47 -16
  129. package/dist/inspector/prompt/generatePrompt.d.ts +1 -1
  130. package/dist/inspector/prompt/generatePrompt.js +248 -148
  131. package/dist/inspector/prompt/promptDocument.d.ts +3 -0
  132. package/dist/inspector/prompt/promptDocument.js +8 -0
  133. package/dist/inspector/prompt/promptSettings.js +7 -5
  134. package/dist/inspector/runtime/inspectorStorage.d.ts +17 -0
  135. package/dist/inspector/runtime/inspectorStorage.js +42 -0
  136. package/dist/inspector/runtime/ownedStylesheets.d.ts +20 -0
  137. package/dist/inspector/runtime/ownedStylesheets.js +72 -0
  138. package/dist/inspector/runtime/runtimeConfig.d.ts +4 -0
  139. package/dist/inspector/runtime/runtimeConfig.js +10 -1
  140. package/dist/inspector/runtime/runtimeIdentityClaims.d.ts +29 -0
  141. package/dist/inspector/runtime/runtimeIdentityClaims.js +188 -0
  142. package/dist/inspector/runtime/staticHtmlRuntimeIdentity.d.ts +15 -0
  143. package/dist/inspector/runtime/staticHtmlRuntimeIdentity.js +113 -29
  144. package/dist/inspector/selection/editScope.d.ts +1 -0
  145. package/dist/inspector/selection/editScope.js +13 -2
  146. package/dist/inspector/selection/sourceSite.d.ts +12 -0
  147. package/dist/inspector/selection/sourceSite.js +28 -0
  148. package/dist/inspector/shell/AgentStatusButton.js +2 -2
  149. package/dist/inspector/shell/AppShell.js +6 -2
  150. package/dist/inspector/shell/ChangesLog.js +27 -9
  151. package/dist/inspector/shell/CopyPromptButton.js +74 -26
  152. package/dist/inspector/shell/EmptyState.js +3 -3
  153. package/dist/inspector/shell/InspectorShell.d.ts +0 -3
  154. package/dist/inspector/shell/InspectorShell.js +21 -13
  155. package/dist/inspector/shell/PeekOriginalButton.js +3 -3
  156. package/dist/inspector/shell/interactionStatePreview.d.ts +9 -0
  157. package/dist/inspector/shell/interactionStatePreview.js +112 -0
  158. package/dist/inspector/shell/originalPreview.d.ts +3 -2
  159. package/dist/inspector/shell/originalPreview.js +10 -37
  160. package/dist/inspector/shell/stateValue.js +2 -3
  161. package/dist/inspector/sketch/SketchEditor.js +5 -4
  162. package/dist/inspector/sketch/SketchFrameOverlay.d.ts +2 -1
  163. package/dist/inspector/sketch/SketchFrameOverlay.js +5 -4
  164. package/dist/inspector/sketch/SketchOverlay.d.ts +3 -5
  165. package/dist/inspector/sketch/SketchOverlay.js +139 -263
  166. package/dist/inspector/sketch/SketchPromptPanel.d.ts +1 -1
  167. package/dist/inspector/sketch/SketchPromptPanel.js +8 -1
  168. package/dist/inspector/sketch/SketchThumbnail.d.ts +5 -0
  169. package/dist/inspector/sketch/SketchThumbnail.js +18 -0
  170. package/dist/inspector/sketch/SketchWorkspace.d.ts +1 -2
  171. package/dist/inspector/sketch/SketchWorkspace.js +69 -34
  172. package/dist/inspector/sketch/capture.js +19 -3
  173. package/dist/inspector/sketch/copySketch.d.ts +10 -0
  174. package/dist/inspector/sketch/copySketch.js +52 -0
  175. package/dist/inspector/sketch/drawingTools.d.ts +17 -0
  176. package/dist/inspector/sketch/drawingTools.js +47 -0
  177. package/dist/inspector/sketch/frameHeading.d.ts +9 -0
  178. package/dist/inspector/sketch/frameHeading.js +30 -0
  179. package/dist/inspector/sketch/freehand.js +3 -3
  180. package/dist/inspector/sketch/geometry.d.ts +6 -0
  181. package/dist/inspector/sketch/geometry.js +19 -0
  182. package/dist/inspector/sketch/history.d.ts +30 -0
  183. package/dist/inspector/sketch/history.js +58 -0
  184. package/dist/inspector/sketch/interaction.d.ts +1 -3
  185. package/dist/inspector/sketch/interaction.js +6 -9
  186. package/dist/inspector/sketch/model.d.ts +35 -1
  187. package/dist/inspector/sketch/model.js +116 -61
  188. package/dist/inspector/sketch/persistence.d.ts +14 -0
  189. package/dist/inspector/sketch/persistence.js +63 -7
  190. package/dist/inspector/sketch/raster.d.ts +6 -2
  191. package/dist/inspector/sketch/raster.js +43 -17
  192. package/dist/inspector/sketch/store.d.ts +1 -1
  193. package/dist/inspector/sketch/store.js +1 -1
  194. package/dist/inspector/sketch/videoFrames.d.ts +6 -0
  195. package/dist/inspector/sketch/videoFrames.js +81 -0
  196. package/dist/inspector/styleEditors/BackgroundEditor.js +3 -2
  197. package/dist/inspector/styleEditors/BorderEditor.js +30 -130
  198. package/dist/inspector/styleEditors/BorderRadiusEditor.js +8 -3
  199. package/dist/inspector/styleEditors/ImageBackgroundEditor.js +1 -1
  200. package/dist/inspector/styleEditors/LayoutSection.js +2 -2
  201. package/dist/inspector/styleEditors/borderModel.d.ts +42 -0
  202. package/dist/inspector/styleEditors/borderModel.js +114 -0
  203. package/dist/inspector/styleEditors/layoutValue.js +2 -3
  204. package/dist/inspector/tokens/TokenField.js +40 -7
  205. package/dist/inspector/tokens/TokensPanel.js +2 -1
  206. package/dist/inspector/tokens/editActions.d.ts +3 -3
  207. package/dist/inspector/tokens/editActions.js +15 -3
  208. package/dist/inspector/tokens/resolution/containerQueryEvaluator.d.ts +15 -0
  209. package/dist/inspector/tokens/resolution/containerQueryEvaluator.js +86 -0
  210. package/dist/inspector/tokens/resolution/cssomCollector.js +44 -9
  211. package/dist/inspector/tokens/resolution/nestedSelectors.d.ts +6 -0
  212. package/dist/inspector/tokens/resolution/nestedSelectors.js +67 -0
  213. package/dist/inspector/tokens/resolution/ruleMatching.js +23 -4
  214. package/dist/inspector/tokens/resolution.d.ts +6 -3
  215. package/dist/inspector/tokens/resolution.js +91 -112
  216. package/dist/inspector/tokens/tokenEdits.d.ts +1 -1
  217. package/dist/inspector/tokens/tokenEdits.js +1 -1
  218. package/dist/inspector/ui/InlineStyleWarning.js +2 -2
  219. package/dist/inspector/ui/InspectorStyle.d.ts +8 -0
  220. package/dist/inspector/ui/InspectorStyle.js +26 -0
  221. package/dist/inspector/ui/PopoverListbox.d.ts +2 -1
  222. package/dist/inspector/ui/PopoverListbox.js +3 -3
  223. package/dist/inspector/ui/Toast.d.ts +14 -0
  224. package/dist/inspector/ui/Toast.js +30 -0
  225. package/dist/inspector/ui/assets/canvasIllustration.d.ts +2 -0
  226. package/dist/inspector/ui/assets/canvasIllustration.js +21 -0
  227. package/dist/inspector/ui/assets/gridIllustration.d.ts +2 -0
  228. package/dist/inspector/ui/assets/{grid.svg → gridIllustration.js} +3 -2
  229. package/dist/inspector/ui/customCursors.d.ts +5 -0
  230. package/dist/inspector/ui/customCursors.js +32 -6
  231. package/dist/inspector/ui/styles.js +12 -10
  232. package/dist/inspector/workspace/commands.js +1 -2
  233. package/dist/inspector/workspace/controller.js +1 -2
  234. package/dist/inspector/workspace/handoff.js +3 -2
  235. package/dist/inspector/workspace/sentItems.d.ts +16 -0
  236. package/dist/inspector/workspace/sentItems.js +33 -0
  237. package/dist/inspector/workspace/timeline.d.ts +24 -10
  238. package/dist/inspector/workspace/timeline.js +118 -96
  239. package/dist/internal/agent-protocol.d.ts +50 -13
  240. package/dist/internal/agent-protocol.js +145 -19
  241. package/dist/nudge-ui.mjs +81 -65
  242. package/dist/project/mcpPackage.d.ts +8 -0
  243. package/dist/project/mcpPackage.js +60 -0
  244. package/package.json +13 -3
  245. package/dist/inspector/canvas/measurementProjection.d.ts +0 -8
  246. package/dist/inspector/canvas/measurementProjection.js +0 -16
  247. package/dist/inspector/changes/changesLog.d.ts +0 -47
  248. package/dist/inspector/changes/changesLog.js +0 -247
  249. package/dist/inspector/changes/draftChanges.d.ts +0 -56
  250. package/dist/inspector/changes/draftChanges.js +0 -300
  251. package/dist/inspector/conformance/projection.d.ts +0 -2
  252. package/dist/inspector/conformance/projection.js +0 -3
  253. package/dist/inspector/inline-text/textChangeBoundary.d.ts +0 -6
  254. package/dist/inspector/inline-text/textChangeBoundary.js +0 -1
  255. package/dist/inspector/overlay/InspectorOverlay.d.ts +0 -5
  256. package/dist/inspector/overlay/InspectorOverlay.js +0 -332
  257. package/dist/inspector/overlay/elementSelector.d.ts +0 -1
  258. package/dist/inspector/overlay/elementSelector.js +0 -111
  259. package/dist/inspector/sketch/SketchChanges.d.ts +0 -2
  260. package/dist/inspector/sketch/SketchChanges.js +0 -72
  261. package/dist/inspector/sketch/SketchEntryButton.d.ts +0 -4
  262. package/dist/inspector/sketch/SketchEntryButton.js +0 -11
  263. package/dist/inspector/sketch/SketchLayersPanel.d.ts +0 -2
  264. package/dist/inspector/sketch/SketchLayersPanel.js +0 -71
@@ -138,13 +138,7 @@ function instrumentConfig(config, options) {
138
138
  });
139
139
  const nextConfig = { ...source };
140
140
  // --- transpilePackages -------------------------------------------------
141
- // Workspace Nudge UI packages ship raw TypeScript that SWC refuses to
142
- // compile from node_modules unless listed (see feature-plan appendix).
143
- const nudgeUiPackages = [
144
- "nudge-ui",
145
- "../../inspector/index.ts",
146
- "../../css/index.ts",
147
- ];
141
+ const nudgeUiPackages = ["nudge-ui"];
148
142
  const userTranspile = Array.isArray(source.transpilePackages)
149
143
  ? source.transpilePackages
150
144
  : [];
@@ -6,10 +6,10 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
6
6
  }
7
7
  return path;
8
8
  };
9
- import { existsSync } from "node:fs";
10
9
  import { createRequire } from "node:module";
11
- import { dirname, join, parse } from "node:path";
10
+ import { join } from "node:path";
12
11
  import { pathToFileURL } from "node:url";
12
+ import { findProjectMcpRoot } from "../project/mcpPackage.js";
13
13
  const runningBridges = new Map();
14
14
  /** Starts the optional project bridge installed beside the host application. */
15
15
  export async function startOptionalProjectBridge(input) {
@@ -28,7 +28,7 @@ export async function startOptionalProjectBridge(input) {
28
28
  async function launchOptionalProjectBridge(input, key) {
29
29
  let modulePath;
30
30
  try {
31
- if (!isPnpRuntime() && !hasProjectInstalledMcp(input.appRoot)) {
31
+ if (findProjectMcpRoot(input.appRoot) === null) {
32
32
  runningBridges.delete(key);
33
33
  return null;
34
34
  }
@@ -73,20 +73,6 @@ async function launchOptionalProjectBridge(input, key) {
73
73
  return null;
74
74
  }
75
75
  }
76
- function isPnpRuntime() {
77
- return typeof process.versions.pnp === "string";
78
- }
79
- function hasProjectInstalledMcp(appRoot) {
80
- let directory = appRoot;
81
- const root = parse(directory).root;
82
- for (;;) {
83
- if (existsSync(join(directory, "node_modules", "@nudge-ui", "mcp", "package.json")))
84
- return true;
85
- if (directory === root)
86
- return false;
87
- directory = dirname(directory);
88
- }
89
- }
90
76
  /** Returns the browser origin for a loopback HTTP server address. */
91
77
  export function loopbackOrigin(address, protocol = "http") {
92
78
  const host = address.address === "::" || address.address === "::1"
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { useMemo, useRef, useState } from "react";
3
3
  import { Dialog } from "@base-ui/react/dialog";
4
4
  import { IconCheck, IconCopy, IconPlugConnected, IconRefresh, IconUnlink, IconX, } from "@tabler/icons-react";
5
- import { getAgentConnectionStatus } from "./connectionStatus.js";
5
+ import { useAgentConnectionStatus } from "./connectionStatus.js";
6
6
  import { copyToClipboard } from "../prompt/copyToClipboard.js";
7
7
  import { Button } from "../ui/Button.js";
8
8
  import { Disclosure } from "../ui/Disclosure.js";
@@ -35,20 +35,24 @@ export function McpConnectionContent({ projectId, origin, snapshot, onConnect, o
35
35
  "Start the application normally. Reload the agent if needed, then listen to Nudge.",
36
36
  ].join("\n"), [setupCommand]);
37
37
  const doctorCommand = "nudge-ui agent doctor";
38
- const status = getAgentConnectionStatus(snapshot);
38
+ const status = useAgentConnectionStatus(snapshot);
39
39
  const showConnectionStatus = status.kind !== "not-found"
40
40
  || Boolean(snapshot.error || checkError || snapshot.request?.summary || snapshot.request?.error);
41
41
  const canConnect = snapshot.companionReachable
42
42
  && !snapshot.paired
43
43
  && !snapshot.pairedElsewhere
44
44
  && snapshot.state !== "pairing"
45
+ && snapshot.state !== "delivered"
45
46
  && snapshot.state !== "working"
47
+ && snapshot.request?.status !== "delivered"
46
48
  && snapshot.request?.status !== "working";
47
- const canDisconnect = snapshot.paired || snapshot.request?.status === "working";
49
+ const canDisconnect = snapshot.paired || snapshot.request?.status === "working" || snapshot.request?.status === "delivered";
48
50
  const canTakeOver = snapshot.companionReachable
49
51
  && snapshot.pairedElsewhere
50
52
  && snapshot.state !== "pairing"
53
+ && snapshot.state !== "delivered"
51
54
  && snapshot.state !== "working"
55
+ && snapshot.request?.status !== "delivered"
52
56
  && snapshot.request?.status !== "working";
53
57
  async function handleCheckAgain() {
54
58
  if (checking)
@@ -12,7 +12,7 @@ export interface AgentActivitySnapshot {
12
12
  /** Pins submitted frames before dispatch. Activity never selects or edits a draft. */
13
13
  export declare function beginActivityDispatch(projectId: string, dispatchId: string, targets: readonly string[], target?: DraftTarget): void;
14
14
  /** Dispatch and status are the only authority for the layer's lifetime. */
15
- export declare function synchronizeAgentActivity(projectId: string, requestId: string | undefined, working: boolean, dispatchId?: string): void;
15
+ export declare function synchronizeAgentActivity(projectId: string, requestId: string | undefined, working: boolean, dispatchId?: string, awaitingAcknowledgment?: boolean): void;
16
16
  export declare function reportAgentActivity(projectId: string, activity: AgentActivity): void;
17
17
  export declare function getAgentActivity(projectId: string): AgentActivitySnapshot;
18
18
  export declare function useAgentActivity(projectId: string): AgentActivitySnapshot;
@@ -19,13 +19,14 @@ export function beginActivityDispatch(projectId, dispatchId, targets, target) {
19
19
  project(projectId).dispatch = { id: dispatchId, targets: [...targets], target };
20
20
  }
21
21
  /** Dispatch and status are the only authority for the layer's lifetime. */
22
- export function synchronizeAgentActivity(projectId, requestId, working, dispatchId) {
22
+ export function synchronizeAgentActivity(projectId, requestId, working, dispatchId, awaitingAcknowledgment = false) {
23
23
  const state = project(projectId);
24
24
  if (!working || !requestId) {
25
25
  if (state.timer)
26
26
  clearTimeout(state.timer);
27
27
  state.timer = undefined;
28
- state.dispatch = undefined;
28
+ if (!awaitingAcknowledgment)
29
+ state.dispatch = undefined;
29
30
  if (state.snapshot !== EMPTY)
30
31
  publish(state, EMPTY);
31
32
  return;
@@ -1,5 +1,5 @@
1
1
  import { type AgentBridgeTransport, type AgentClientOptions, type AgentSketchAttachment, type AgentSketchMetadata, type AgentRequestStatus, type AgentStatusSnapshot, type PromptDispatchResponse } from "./protocol.js";
2
- export type AgentClientState = "disabled" | "disconnected" | "available" | "pairing" | "connected" | "working" | "completed" | "failed" | "interrupted";
2
+ export type AgentClientState = "disabled" | "disconnected" | "available" | "pairing" | "connected" | "delivered" | "working" | "completed" | "failed" | "interrupted";
3
3
  export interface AgentRequestSnapshot {
4
4
  readonly requestId: string;
5
5
  readonly changeRevision?: number;
@@ -80,7 +80,7 @@ export declare class AgentClient {
80
80
  private pairWith;
81
81
  private openEvents;
82
82
  /**
83
- * Dispatches one immutable prompt revision. The request enters `working`
83
+ * Dispatches one immutable prompt revision. The request enters `delivered`
84
84
  * synchronously, before the transport promise resolves, so the UI cannot
85
85
  * issue a second prompt while the first one is in flight.
86
86
  */
@@ -3,7 +3,7 @@ import { useEffect, useMemo, useSyncExternalStore } from "react";
3
3
  import { isNudgeUiDev } from "../runtime/devFlag.js";
4
4
  import { isDemoRuntime } from "../runtime/runtimeConfig.js";
5
5
  import { AgentBridgeHttpError, HttpAgentBridgeTransport, shouldAutoConnectAgentBridge, } from "./httpTransport.js";
6
- import { AGENT_PROTOCOL_VERSION, } from "./protocol.js";
6
+ import { AGENT_PROTOCOL_VERSION, deriveConnectionState, } from "./protocol.js";
7
7
  const DISABLED_SNAPSHOT = Object.freeze({
8
8
  state: "disabled",
9
9
  connection: "offline",
@@ -96,15 +96,6 @@ function setAutoConnectDisabled(projectId, disabled) {
96
96
  // the explicit disconnect preference in memory.
97
97
  }
98
98
  }
99
- function statusForConnection(status) {
100
- if (status.connection === "working" || status.request?.status === "working")
101
- return "working";
102
- if (status.paired)
103
- return "paired";
104
- if (status.listenerActive)
105
- return "listening";
106
- return "offline";
107
- }
108
99
  function hashRevision(value) {
109
100
  // FNV-1a is sufficient here: the revision is an opaque, bounded identity
110
101
  // used to prevent a later browser edit from being mistaken for the sent
@@ -316,7 +307,7 @@ export class AgentClient {
316
307
  return false;
317
308
  this.autoConnectSuppressed = false;
318
309
  setAutoConnectDisabled(this.projectId, false);
319
- if (this.connection === "working" || this.activeRequest?.status === "working")
310
+ if (this.connection === "working" || this.connection === "delivered" || this.activeRequest?.status === "working" || this.activeRequest?.status === "delivered")
320
311
  return false;
321
312
  const idleListenerActive = this.listenerActive;
322
313
  const idleCompanionReachable = this.companionReachable;
@@ -398,14 +389,14 @@ export class AgentClient {
398
389
  }
399
390
  }
400
391
  /**
401
- * Dispatches one immutable prompt revision. The request enters `working`
392
+ * Dispatches one immutable prompt revision. The request enters `delivered`
402
393
  * synchronously, before the transport promise resolves, so the UI cannot
403
394
  * issue a second prompt while the first one is in flight.
404
395
  */
405
396
  async dispatchPrompt(prompt, changeRevision, options = {}) {
406
397
  if (!this.enabled || !this.started || !this.paired || !this.listenerActive || !this.sessionToken)
407
398
  return null;
408
- if (!prompt || this.activeRequest?.status === "working")
399
+ if (!prompt || this.activeRequest?.status === "working" || this.activeRequest?.status === "delivered")
409
400
  return null;
410
401
  const localRequestId = randomId("request");
411
402
  const request = {
@@ -424,9 +415,9 @@ export class AgentClient {
424
415
  ...(changeRevision === undefined ? {} : { changeRevision }),
425
416
  ...(options.clientDispatchId === undefined ? {} : { clientDispatchId: options.clientDispatchId }),
426
417
  ...(sketches === undefined ? {} : { sketches }),
427
- status: "working",
418
+ status: "delivered",
428
419
  };
429
- this.connection = "working";
420
+ this.connection = "delivered";
430
421
  this.lastError = undefined;
431
422
  this.publish();
432
423
  const abortController = new AbortController();
@@ -445,8 +436,9 @@ export class AgentClient {
445
436
  }
446
437
  : this.activeRequest;
447
438
  }
448
- if (response?.status && response.status !== "working") {
439
+ if (response?.status) {
449
440
  this.applyRequestStatus(response.status, response.request.requestId);
441
+ this.publish();
450
442
  }
451
443
  return response ?? null;
452
444
  }
@@ -471,7 +463,7 @@ export class AgentClient {
471
463
  setAutoConnectDisabled(this.projectId, true);
472
464
  const token = this.sessionToken;
473
465
  const active = this.activeRequest;
474
- if (active?.status === "working") {
466
+ if (active?.status === "working" || active?.status === "delivered") {
475
467
  this.activeRequest = { ...active, status: "interrupted", error: reason };
476
468
  }
477
469
  this.dispatchAbort?.abort();
@@ -518,7 +510,7 @@ export class AgentClient {
518
510
  }
519
511
  else {
520
512
  this.companionReachable = true;
521
- if (this.connection !== "paired" && this.connection !== "working" && !this.pairingAbort) {
513
+ if (this.connection !== "paired" && this.connection !== "working" && this.connection !== "delivered" && !this.pairingAbort) {
522
514
  // Discovery is unauthenticated. Another browser tab can own the
523
515
  // pairing, so do not adopt `paired` until this tab restores the
524
516
  // shared token. The next poll runs restore first in case a sibling
@@ -538,7 +530,7 @@ export class AgentClient {
538
530
  }
539
531
  }
540
532
  }
541
- else if (this.connection !== "paired" && this.connection !== "working" && !this.pairingAbort) {
533
+ else if (this.connection !== "paired" && this.connection !== "working" && this.connection !== "delivered" && !this.pairingAbort) {
542
534
  this.connection = "offline";
543
535
  this.listenerActive = false;
544
536
  this.companionReachable = false;
@@ -549,7 +541,7 @@ export class AgentClient {
549
541
  }
550
542
  }
551
543
  catch (error) {
552
- if (!abortController.signal.aborted && this.started && this.connection !== "paired" && this.connection !== "working" && !this.pairingAbort) {
544
+ if (!abortController.signal.aborted && this.started && this.connection !== "paired" && this.connection !== "working" && this.connection !== "delivered" && !this.pairingAbort) {
553
545
  this.connection = "offline";
554
546
  this.listenerActive = false;
555
547
  this.companionReachable = false;
@@ -658,7 +650,7 @@ export class AgentClient {
658
650
  this.agentClientName = status.agentClientName;
659
651
  this.paired = status.paired;
660
652
  this.pairedElsewhere = pairedElsewhere;
661
- this.connection = statusForConnection(status);
653
+ this.connection = deriveConnectionState(status);
662
654
  if (status.paired && this.discoveryTimer !== null) {
663
655
  clearTimeout(this.discoveryTimer);
664
656
  this.discoveryTimer = null;
@@ -666,16 +658,16 @@ export class AgentClient {
666
658
  if (status.request) {
667
659
  this.applyRequestStatus(status.request.status, status.request.requestId, status.request.summary, status.request.error, status.request.changeRevision, status.request.clientDispatchId, status.request.sketches);
668
660
  }
669
- else if (status.listenerActive && status.paired && this.activeRequest?.status !== "working") {
661
+ else if (status.listenerActive && status.paired && this.activeRequest?.status !== "working" && this.activeRequest?.status !== "delivered") {
670
662
  // A re-armed MCP listen call is the lifecycle boundary for the previous
671
663
  // terminal request. Drop only that terminal status; newer edits remain
672
664
  // in the inspector's canonical change log.
673
665
  this.activeRequest = null;
674
666
  }
675
- else if (this.activeRequest?.status === "working" && status.connection !== "working") {
667
+ else if ((this.activeRequest?.status === "working" || this.activeRequest?.status === "delivered") && status.connection !== this.activeRequest.status) {
676
668
  // The bridge may omit a request during a brief re-arm transition. Do
677
669
  // not mark a local request interrupted until the stream disconnects.
678
- this.connection = "working";
670
+ this.connection = this.activeRequest.status;
679
671
  }
680
672
  if (!status.paired && this.sessionToken) {
681
673
  this.handleDisconnect("The agent bridge pairing expired.");
@@ -695,10 +687,15 @@ export class AgentClient {
695
687
  }
696
688
  applyRequestStatus(status, requestId, summary, error, changeRevision, clientDispatchId, sketches) {
697
689
  const active = this.activeRequest;
690
+ // A dispatch response can arrive after an SSE acknowledgment or outcome.
691
+ if (status === "delivered" && active && active.status !== "delivered") {
692
+ this.connection = active.status === "working" ? "working" : this.paired ? "paired" : "offline";
693
+ return;
694
+ }
698
695
  if (active && active.requestId !== requestId && active.localRequestId !== requestId) {
699
696
  // A fresh server id can arrive before the POST response. Associate it
700
- // with the one local request that was just marked working.
701
- if (active.status !== "working")
697
+ // with the one local request awaiting acknowledgment.
698
+ if (active.status !== "working" && active.status !== "delivered")
702
699
  return;
703
700
  this.activeRequest = { ...active, requestId };
704
701
  }
@@ -727,8 +724,8 @@ export class AgentClient {
727
724
  ...(error === undefined ? {} : { error }),
728
725
  };
729
726
  }
730
- if (status === "working")
731
- this.connection = "working";
727
+ if (status === "working" || status === "delivered")
728
+ this.connection = status;
732
729
  else if (this.paired)
733
730
  this.connection = "paired";
734
731
  }
@@ -784,6 +781,8 @@ export class AgentClient {
784
781
  return "disconnected";
785
782
  if (this.connection === "listening")
786
783
  return "available";
784
+ if (this.connection === "delivered" || this.activeRequest?.status === "delivered")
785
+ return "delivered";
787
786
  if (this.connection === "working" || this.activeRequest?.status === "working")
788
787
  return "working";
789
788
  if (this.activeRequest?.status === "completed")
@@ -796,7 +795,7 @@ export class AgentClient {
796
795
  }
797
796
  publish(stateOverride) {
798
797
  this.snapshot = Object.freeze(this.makeSnapshot(stateOverride));
799
- synchronizeAgentActivity(this.projectId, this.snapshot.request?.requestId, this.snapshot.paired && this.snapshot.request?.status === "working", this.snapshot.request?.clientDispatchId);
798
+ synchronizeAgentActivity(this.projectId, this.snapshot.request?.requestId, this.snapshot.paired && this.snapshot.request?.status === "working", this.snapshot.request?.clientDispatchId, this.snapshot.paired && this.snapshot.request?.status === "delivered");
800
799
  for (const listener of this.listeners)
801
800
  listener();
802
801
  }
@@ -1,5 +1,5 @@
1
1
  import type { AgentClientSnapshot } from "./client.js";
2
- export type AgentConnectionStatusKind = "unavailable" | "connecting" | "working-disconnected" | "working" | "paired-elsewhere" | "not-found" | "ready-to-connect" | "connected-not-listening" | "listening";
2
+ export type AgentConnectionStatusKind = "unavailable" | "connecting" | "delivered" | "delivered-disconnected" | "working-disconnected" | "working" | "paired-elsewhere" | "not-found" | "ready-to-connect" | "connected" | "connected-not-listening" | "listening";
3
3
  export interface AgentConnectionStatus {
4
4
  readonly kind: AgentConnectionStatusKind;
5
5
  readonly label: string;
@@ -11,3 +11,5 @@ export interface AgentConnectionStatus {
11
11
  }
12
12
  /** Returns the user-facing connection state shared by the prompt UI and MCP panel. */
13
13
  export declare function getAgentConnectionStatus(snapshot: AgentClientSnapshot): AgentConnectionStatus;
14
+ /** Gives the agent time to rearm after completing a request before showing a reminder. */
15
+ export declare function useAgentConnectionStatus(snapshot: AgentClientSnapshot): AgentConnectionStatus;
@@ -1,3 +1,4 @@
1
+ import { useEffect, useState } from "react";
1
2
  /** Returns the user-facing connection state shared by the prompt UI and MCP panel. */
2
3
  export function getAgentConnectionStatus(snapshot) {
3
4
  if (snapshot.state === "disabled") {
@@ -14,6 +15,11 @@ export function getAgentConnectionStatus(snapshot) {
14
15
  action: { kind: "takeover", label: "Take over" },
15
16
  };
16
17
  }
18
+ if (snapshot.state === "delivered" || snapshot.request?.status === "delivered") {
19
+ return snapshot.paired
20
+ ? { kind: "delivered", label: "Connected · Awaiting agent acknowledgment", tone: "accent" }
21
+ : { kind: "delivered-disconnected", label: "Disconnected · Agent acknowledgment unknown", tone: "warning" };
22
+ }
17
23
  if (!snapshot.paired && (snapshot.state === "working" || snapshot.request?.status === "working")) {
18
24
  return { kind: "working-disconnected", label: "Disconnected · Last work status unknown", tone: "warning" };
19
25
  }
@@ -40,3 +46,22 @@ export function getAgentConnectionStatus(snapshot) {
40
46
  action: { kind: "connect", label: "Connect" },
41
47
  };
42
48
  }
49
+ /** Gives the agent time to rearm after completing a request before showing a reminder. */
50
+ export function useAgentConnectionStatus(snapshot) {
51
+ const status = getAgentConnectionStatus(snapshot);
52
+ const completedRequestId = status.kind === "connected-not-listening" && snapshot.request?.status === "completed"
53
+ ? snapshot.request.requestId
54
+ : undefined;
55
+ const [reminderRequestId, setReminderRequestId] = useState();
56
+ useEffect(() => {
57
+ setReminderRequestId(undefined);
58
+ if (!completedRequestId)
59
+ return;
60
+ const timeout = setTimeout(() => setReminderRequestId(completedRequestId), 5_000);
61
+ return () => clearTimeout(timeout);
62
+ }, [completedRequestId]);
63
+ if (completedRequestId && reminderRequestId !== completedRequestId) {
64
+ return { kind: "connected", label: "MCP connected", tone: "accent" };
65
+ }
66
+ return status;
67
+ }