nudge-ui 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -0
- package/bin/nudge-ui.mjs +7 -0
- package/dist/LICENSE +21 -0
- package/dist/client.mjs +261 -0
- package/dist/compiler/ast.d.ts +18 -0
- package/dist/compiler/ast.js +75 -0
- package/dist/compiler/componentContractTypes.d.ts +19 -0
- package/dist/compiler/componentContractTypes.js +1 -0
- package/dist/compiler/componentContracts.d.ts +2 -0
- package/dist/compiler/componentContracts.js +260 -0
- package/dist/compiler/componentInstrumentation.d.ts +32 -0
- package/dist/compiler/componentInstrumentation.js +140 -0
- package/dist/compiler/componentPolicyResolution.d.ts +71 -0
- package/dist/compiler/componentPolicyResolution.js +388 -0
- package/dist/compiler/index.d.ts +9 -0
- package/dist/compiler/index.js +9 -0
- package/dist/compiler/packageComponentContracts.d.ts +32 -0
- package/dist/compiler/packageComponentContracts.js +308 -0
- package/dist/compiler/reactComponentProtocols.d.ts +145 -0
- package/dist/compiler/reactComponentProtocols.js +47 -0
- package/dist/compiler/reactIdentity.d.ts +15 -0
- package/dist/compiler/reactIdentity.js +339 -0
- package/dist/compiler/sourcePaths.d.ts +12 -0
- package/dist/compiler/sourcePaths.js +27 -0
- package/dist/css/dialects/index.d.ts +62 -0
- package/dist/css/dialects/index.js +103 -0
- package/dist/css/dialects/tailwind.d.ts +46 -0
- package/dist/css/dialects/tailwind.js +119 -0
- package/dist/css/dialects/vanillaExtract.d.ts +20 -0
- package/dist/css/dialects/vanillaExtract.js +32 -0
- package/dist/css/index.d.ts +10 -0
- package/dist/css/index.js +10 -0
- package/dist/css/model/index.d.ts +190 -0
- package/dist/css/model/index.js +10 -0
- package/dist/css/token-inventory/index.d.ts +26 -0
- package/dist/css/token-inventory/index.js +24 -0
- package/dist/css/token-inventory/inventory.d.ts +8 -0
- package/dist/css/token-inventory/inventory.js +421 -0
- package/dist/css/token-inventory/parseStylesheet.d.ts +16 -0
- package/dist/css/token-inventory/parseStylesheet.js +155 -0
- package/dist/css/token-inventory/policy.d.ts +47 -0
- package/dist/css/token-inventory/policy.js +50 -0
- package/dist/css/token-inventory/types.d.ts +97 -0
- package/dist/css/token-inventory/types.js +1 -0
- package/dist/css/value-semantics/borderSemantics.d.ts +28 -0
- package/dist/css/value-semantics/borderSemantics.js +91 -0
- package/dist/css/value-semantics/boxSemantics.d.ts +37 -0
- package/dist/css/value-semantics/boxSemantics.js +71 -0
- package/dist/css/value-semantics/colorSemantics.d.ts +99 -0
- package/dist/css/value-semantics/colorSemantics.js +526 -0
- package/dist/css/value-semantics/cssSyntax.d.ts +19 -0
- package/dist/css/value-semantics/cssSyntax.js +111 -0
- package/dist/css/value-semantics/fontSemantics.d.ts +35 -0
- package/dist/css/value-semantics/fontSemantics.js +131 -0
- package/dist/css/value-semantics/index.d.ts +20 -0
- package/dist/css/value-semantics/index.js +15 -0
- package/dist/css/value-semantics/propertyPolicy.d.ts +118 -0
- package/dist/css/value-semantics/propertyPolicy.js +356 -0
- package/dist/css/value-semantics/stringMaps.d.ts +2 -0
- package/dist/css/value-semantics/stringMaps.js +1 -0
- package/dist/css/value-semantics/structuredValues.d.ts +64 -0
- package/dist/css/value-semantics/structuredValues.js +250 -0
- package/dist/css/value-semantics/tokenInterpretation.d.ts +90 -0
- package/dist/css/value-semantics/tokenInterpretation.js +193 -0
- package/dist/css/virtual-design-tokens.d.ts +17 -0
- package/dist/hosts/astro/astroRuntimeConfig.d.ts +12 -0
- package/dist/hosts/astro/astroRuntimeConfig.js +26 -0
- package/dist/hosts/astro/clientAsset.d.ts +12 -0
- package/dist/hosts/astro/clientAsset.js +51 -0
- package/dist/hosts/astro/clientTransport.d.ts +3 -0
- package/dist/hosts/astro/clientTransport.js +57 -0
- package/dist/hosts/astro/index.d.ts +3 -0
- package/dist/hosts/astro/index.js +2 -0
- package/dist/hosts/astro/integration.d.ts +35 -0
- package/dist/hosts/astro/integration.js +96 -0
- package/dist/hosts/astro/middleware.d.ts +13 -0
- package/dist/hosts/astro/middleware.js +22 -0
- package/dist/hosts/astro/projectContext.d.ts +11 -0
- package/dist/hosts/astro/projectContext.js +34 -0
- package/dist/hosts/astro/responseInstrumentation.d.ts +41 -0
- package/dist/hosts/astro/responseInstrumentation.js +80 -0
- package/dist/hosts/next/index.d.ts +4 -0
- package/dist/hosts/next/index.js +7 -0
- package/dist/hosts/next/loader.d.ts +66 -0
- package/dist/hosts/next/loader.js +346 -0
- package/dist/hosts/next/loaders/identity-loader.cjs +228257 -0
- package/dist/hosts/next/loaders/loader-plugin.cjs +228257 -0
- package/dist/hosts/next/manifest.d.ts +38 -0
- package/dist/hosts/next/manifest.js +30 -0
- package/dist/hosts/next/mount.d.ts +12 -0
- package/dist/hosts/next/mount.js +23 -0
- package/dist/hosts/next/repositoryScope.d.ts +20 -0
- package/dist/hosts/next/repositoryScope.js +33 -0
- package/dist/hosts/next/sidecar.d.ts +27 -0
- package/dist/hosts/next/sidecar.js +526 -0
- package/dist/hosts/next/wrapper.d.ts +67 -0
- package/dist/hosts/next/wrapper.js +310 -0
- package/dist/hosts/static/cli.d.ts +12 -0
- package/dist/hosts/static/cli.js +77 -0
- package/dist/hosts/static/html/bootstrap.d.ts +27 -0
- package/dist/hosts/static/html/bootstrap.js +93 -0
- package/dist/hosts/static/index.d.ts +4 -0
- package/dist/hosts/static/index.js +4 -0
- package/dist/hosts/static/manifest.d.ts +18 -0
- package/dist/hosts/static/manifest.js +51 -0
- package/dist/hosts/static/server.d.ts +72 -0
- package/dist/hosts/static/server.js +554 -0
- package/dist/hosts/vite/index.d.ts +20 -0
- package/dist/hosts/vite/index.js +48 -0
- package/dist/hosts/vite/react.d.ts +67 -0
- package/dist/hosts/vite/react.js +231 -0
- package/dist/hosts/vite/tokens/activeStylesheets.d.ts +28 -0
- package/dist/hosts/vite/tokens/activeStylesheets.js +70 -0
- package/dist/hosts/vite/tokens/fileMap.d.ts +2 -0
- package/dist/hosts/vite/tokens/fileMap.js +1 -0
- package/dist/hosts/vite/tokens/viteStylesheetArtifacts.d.ts +46 -0
- package/dist/hosts/vite/tokens/viteStylesheetArtifacts.js +104 -0
- package/dist/hosts/vite/virtual/design-tokens.d.ts +9 -0
- package/dist/hosts/vite/virtual/design-tokens.js +7 -0
- package/dist/hosts/vite/virtual-design-tokens.d.ts +1 -0
- package/dist/hosts/vite/vite.d.ts +62 -0
- package/dist/hosts/vite/vite.js +854 -0
- package/dist/html/dom.d.ts +13 -0
- package/dist/html/dom.js +46 -0
- package/dist/html/identity.d.ts +40 -0
- package/dist/html/identity.js +196 -0
- package/dist/html/insertions.d.ts +26 -0
- package/dist/html/insertions.js +59 -0
- package/dist/inspector/agent/McpConnectionDialog.d.ts +26 -0
- package/dist/inspector/agent/McpConnectionDialog.js +135 -0
- package/dist/inspector/agent/client.d.ts +98 -0
- package/dist/inspector/agent/client.js +728 -0
- package/dist/inspector/agent/connectionStatus.d.ts +13 -0
- package/dist/inspector/agent/connectionStatus.js +35 -0
- package/dist/inspector/agent/httpTransport.d.ts +21 -0
- package/dist/inspector/agent/httpTransport.js +347 -0
- package/dist/inspector/agent/protocol.d.ts +95 -0
- package/dist/inspector/agent/protocol.js +9 -0
- package/dist/inspector/agent/verification.d.ts +39 -0
- package/dist/inspector/agent/verification.js +207 -0
- package/dist/inspector/canvas/CanvasCard.d.ts +10 -0
- package/dist/inspector/canvas/CanvasCard.js +275 -0
- package/dist/inspector/canvas/CanvasElementOverlay.d.ts +2 -0
- package/dist/inspector/canvas/CanvasElementOverlay.js +301 -0
- package/dist/inspector/canvas/CanvasWorkspace.d.ts +2 -0
- package/dist/inspector/canvas/CanvasWorkspace.js +301 -0
- package/dist/inspector/canvas/LockedWorkspaceNotice.d.ts +6 -0
- package/dist/inspector/canvas/LockedWorkspaceNotice.js +17 -0
- package/dist/inspector/canvas/StaleChangeIndicator.d.ts +7 -0
- package/dist/inspector/canvas/StaleChangeIndicator.js +43 -0
- package/dist/inspector/canvas/agentPresentation.d.ts +87 -0
- package/dist/inspector/canvas/agentPresentation.js +421 -0
- package/dist/inspector/canvas/canvasGestures.d.ts +12 -0
- package/dist/inspector/canvas/canvasGestures.js +21 -0
- package/dist/inspector/canvas/canvasStore.d.ts +108 -0
- package/dist/inspector/canvas/canvasStore.js +448 -0
- package/dist/inspector/canvas/frameProtocol.d.ts +231 -0
- package/dist/inspector/canvas/frameProtocol.js +165 -0
- package/dist/inspector/canvas/linkEligibility.d.ts +8 -0
- package/dist/inspector/canvas/linkEligibility.js +68 -0
- package/dist/inspector/canvas/measurementProjection.d.ts +8 -0
- package/dist/inspector/canvas/measurementProjection.js +16 -0
- package/dist/inspector/canvas/normalizeUrl.d.ts +7 -0
- package/dist/inspector/canvas/normalizeUrl.js +27 -0
- package/dist/inspector/canvas/projection.d.ts +41 -0
- package/dist/inspector/canvas/projection.js +232 -0
- package/dist/inspector/canvas/rendererBootstrap.d.ts +4 -0
- package/dist/inspector/canvas/rendererBootstrap.js +410 -0
- package/dist/inspector/canvas/rendererCidIndex.d.ts +11 -0
- package/dist/inspector/canvas/rendererCidIndex.js +21 -0
- package/dist/inspector/canvas/rendererElementSelector.d.ts +2 -0
- package/dist/inspector/canvas/rendererElementSelector.js +378 -0
- package/dist/inspector/canvas/rendererSelectionProxy.d.ts +2 -0
- package/dist/inspector/canvas/rendererSelectionProxy.js +61 -0
- package/dist/inspector/canvas/rendererStylesheet.d.ts +16 -0
- package/dist/inspector/canvas/rendererStylesheet.js +221 -0
- package/dist/inspector/canvas/resizeHandleScale.d.ts +13 -0
- package/dist/inspector/canvas/resizeHandleScale.js +20 -0
- package/dist/inspector/canvas/roleDetection.d.ts +5 -0
- package/dist/inspector/canvas/roleDetection.js +21 -0
- package/dist/inspector/canvas/sessionStore.d.ts +71 -0
- package/dist/inspector/canvas/sessionStore.js +453 -0
- package/dist/inspector/canvas/staleChangeDetector.d.ts +11 -0
- package/dist/inspector/canvas/staleChangeDetector.js +217 -0
- package/dist/inspector/canvas/toolbarScale.d.ts +7 -0
- package/dist/inspector/canvas/toolbarScale.js +11 -0
- package/dist/inspector/canvas/workspaceLease.d.ts +26 -0
- package/dist/inspector/canvas/workspaceLease.js +214 -0
- package/dist/inspector/changes/changesLog.d.ts +46 -0
- package/dist/inspector/changes/changesLog.js +209 -0
- package/dist/inspector/changes/codecs.d.ts +98 -0
- package/dist/inspector/changes/codecs.js +389 -0
- package/dist/inspector/changes/editModel.d.ts +74 -0
- package/dist/inspector/changes/editModel.js +120 -0
- package/dist/inspector/changes/managedStyleProjection.d.ts +6 -0
- package/dist/inspector/changes/managedStyleProjection.js +109 -0
- package/dist/inspector/changes/model.d.ts +13 -0
- package/dist/inspector/changes/model.js +163 -0
- package/dist/inspector/changes/presentation.d.ts +14 -0
- package/dist/inspector/changes/presentation.js +81 -0
- package/dist/inspector/changes/previewDiagnostics.d.ts +39 -0
- package/dist/inspector/changes/previewDiagnostics.js +172 -0
- package/dist/inspector/changes/structuralTypes.d.ts +35 -0
- package/dist/inspector/changes/structuralTypes.js +1 -0
- package/dist/inspector/changes/types.d.ts +76 -0
- package/dist/inspector/changes/types.js +16 -0
- package/dist/inspector/changes/workspaceChanges.d.ts +43 -0
- package/dist/inspector/changes/workspaceChanges.js +239 -0
- package/dist/inspector/clientManifest.d.ts +24 -0
- package/dist/inspector/clientManifest.js +69 -0
- package/dist/inspector/componentSemantics/ComponentPropsSection.d.ts +5 -0
- package/dist/inspector/componentSemantics/ComponentPropsSection.js +44 -0
- package/dist/inspector/componentSemantics/adapterRegistry.d.ts +11 -0
- package/dist/inspector/componentSemantics/adapterRegistry.js +75 -0
- package/dist/inspector/componentSemantics/boundaries.d.ts +2 -0
- package/dist/inspector/componentSemantics/boundaries.js +10 -0
- package/dist/inspector/componentSemantics/changeAction.d.ts +3 -0
- package/dist/inspector/componentSemantics/changeAction.js +6 -0
- package/dist/inspector/componentSemantics/changeModel.d.ts +8 -0
- package/dist/inspector/componentSemantics/changeModel.js +60 -0
- package/dist/inspector/componentSemantics/index.d.ts +4 -0
- package/dist/inspector/componentSemantics/index.js +2 -0
- package/dist/inspector/componentSemantics/reactRuntime.d.ts +10 -0
- package/dist/inspector/componentSemantics/reactRuntime.js +186 -0
- package/dist/inspector/componentSemantics/runtimeBridge.d.ts +25 -0
- package/dist/inspector/componentSemantics/runtimeBridge.js +161 -0
- package/dist/inspector/componentSemantics/runtimeTypes.d.ts +2 -0
- package/dist/inspector/componentSemantics/runtimeTypes.js +1 -0
- package/dist/inspector/componentSemantics/textBinding.d.ts +69 -0
- package/dist/inspector/componentSemantics/textBinding.js +514 -0
- package/dist/inspector/componentSemantics/types.d.ts +96 -0
- package/dist/inspector/componentSemantics/types.js +5 -0
- package/dist/inspector/conformance/borderCases.d.ts +7 -0
- package/dist/inspector/conformance/borderCases.js +428 -0
- package/dist/inspector/conformance/colorCases.d.ts +8 -0
- package/dist/inspector/conformance/colorCases.js +470 -0
- package/dist/inspector/conformance/fixture.d.ts +68 -0
- package/dist/inspector/conformance/fixture.js +153 -0
- package/dist/inspector/conformance/projection.d.ts +2 -0
- package/dist/inspector/conformance/projection.js +3 -0
- package/dist/inspector/conformance/spacingCases.d.ts +6 -0
- package/dist/inspector/conformance/spacingCases.js +417 -0
- package/dist/inspector/conformance/typographyCases.d.ts +7 -0
- package/dist/inspector/conformance/typographyCases.js +174 -0
- package/dist/inspector/editScope.d.ts +4 -0
- package/dist/inspector/editScope.js +5 -0
- package/dist/inspector/index.d.ts +20 -0
- package/dist/inspector/index.js +236 -0
- package/dist/inspector/inline-text/inlineTextEditor.d.ts +74 -0
- package/dist/inspector/inline-text/inlineTextEditor.js +1207 -0
- package/dist/inspector/inline-text/inlineTextLifecycle.d.ts +2 -0
- package/dist/inspector/inline-text/inlineTextLifecycle.js +17 -0
- package/dist/inspector/inline-text/textChangeBoundary.d.ts +6 -0
- package/dist/inspector/inline-text/textChangeBoundary.js +1 -0
- package/dist/inspector/inspection/bridge.d.ts +72 -0
- package/dist/inspector/inspection/bridge.js +134 -0
- package/dist/inspector/inspection/browserCssInspection.d.ts +74 -0
- package/dist/inspector/inspection/browserCssInspection.js +317 -0
- package/dist/inspector/inspection/browserCssInspectionRegistry.d.ts +12 -0
- package/dist/inspector/inspection/browserCssInspectionRegistry.js +66 -0
- package/dist/inspector/inspection/selectionProperty.d.ts +32 -0
- package/dist/inspector/inspection/selectionProperty.js +33 -0
- package/dist/inspector/inspection/useBrowserCssInspection.d.ts +20 -0
- package/dist/inspector/inspection/useBrowserCssInspection.js +159 -0
- package/dist/inspector/overlay/DropGuideOverlay.d.ts +17 -0
- package/dist/inspector/overlay/DropGuideOverlay.js +17 -0
- package/dist/inspector/overlay/InspectorOverlay.d.ts +5 -0
- package/dist/inspector/overlay/InspectorOverlay.js +328 -0
- package/dist/inspector/overlay/MeasurementGuideOverlay.d.ts +19 -0
- package/dist/inspector/overlay/MeasurementGuideOverlay.js +40 -0
- package/dist/inspector/overlay/clickPolicy.d.ts +7 -0
- package/dist/inspector/overlay/clickPolicy.js +13 -0
- package/dist/inspector/overlay/dropGuide.d.ts +22 -0
- package/dist/inspector/overlay/dropGuide.js +48 -0
- package/dist/inspector/overlay/elementSelector.d.ts +1 -0
- package/dist/inspector/overlay/elementSelector.js +100 -0
- package/dist/inspector/overlay/frameThrottle.d.ts +10 -0
- package/dist/inspector/overlay/frameThrottle.js +38 -0
- package/dist/inspector/overlay/interactionStyles.d.ts +3 -0
- package/dist/inspector/overlay/interactionStyles.js +70 -0
- package/dist/inspector/overlay/measurementGeometry.d.ts +25 -0
- package/dist/inspector/overlay/measurementGeometry.js +104 -0
- package/dist/inspector/overlay/overlayGeometry.d.ts +40 -0
- package/dist/inspector/overlay/overlayGeometry.js +59 -0
- package/dist/inspector/overlay/selectedGeometry.d.ts +7 -0
- package/dist/inspector/overlay/selectedGeometry.js +51 -0
- package/dist/inspector/overlay/structuralGestures.d.ts +28 -0
- package/dist/inspector/overlay/structuralGestures.js +180 -0
- package/dist/inspector/projection/cssEscapes.d.ts +3 -0
- package/dist/inspector/projection/cssEscapes.js +20 -0
- package/dist/inspector/projection/managedStylesheet.d.ts +33 -0
- package/dist/inspector/projection/managedStylesheet.js +240 -0
- package/dist/inspector/projection/renderedInstance.d.ts +56 -0
- package/dist/inspector/projection/renderedInstance.js +306 -0
- package/dist/inspector/projection/structuralProjection.d.ts +93 -0
- package/dist/inspector/projection/structuralProjection.js +560 -0
- package/dist/inspector/projection/structuralProjectionBoundary.d.ts +5 -0
- package/dist/inspector/projection/structuralProjectionBoundary.js +65 -0
- package/dist/inspector/projection/textProjection.d.ts +53 -0
- package/dist/inspector/projection/textProjection.js +705 -0
- package/dist/inspector/projection/workspaceProjection.d.ts +43 -0
- package/dist/inspector/projection/workspaceProjection.js +58 -0
- package/dist/inspector/prompt/PromptSettingsDialog.d.ts +15 -0
- package/dist/inspector/prompt/PromptSettingsDialog.js +17 -0
- package/dist/inspector/prompt/clipboardHandoff.d.ts +34 -0
- package/dist/inspector/prompt/clipboardHandoff.js +212 -0
- package/dist/inspector/prompt/copyToClipboard.d.ts +1 -0
- package/dist/inspector/prompt/copyToClipboard.js +34 -0
- package/dist/inspector/prompt/detectFramework.d.ts +6 -0
- package/dist/inspector/prompt/detectFramework.js +4 -0
- package/dist/inspector/prompt/generatePrompt.d.ts +7 -0
- package/dist/inspector/prompt/generatePrompt.js +391 -0
- package/dist/inspector/prompt/promptSettings.d.ts +8 -0
- package/dist/inspector/prompt/promptSettings.js +28 -0
- package/dist/inspector/runtime/devFlag.d.ts +28 -0
- package/dist/inspector/runtime/devFlag.js +50 -0
- package/dist/inspector/runtime/documentStylesheetOrder.d.ts +19 -0
- package/dist/inspector/runtime/documentStylesheetOrder.js +89 -0
- package/dist/inspector/runtime/domRealm.d.ts +4 -0
- package/dist/inspector/runtime/domRealm.js +11 -0
- package/dist/inspector/runtime/runtimeConfig.d.ts +119 -0
- package/dist/inspector/runtime/runtimeConfig.js +276 -0
- package/dist/inspector/runtime/staticHtmlRuntimeIdentity.d.ts +32 -0
- package/dist/inspector/runtime/staticHtmlRuntimeIdentity.js +149 -0
- package/dist/inspector/runtime/useRuntimeConfig.d.ts +10 -0
- package/dist/inspector/runtime/useRuntimeConfig.js +13 -0
- package/dist/inspector/selection/editScope.d.ts +32 -0
- package/dist/inspector/selection/editScope.js +140 -0
- package/dist/inspector/selection/editTarget.d.ts +8 -0
- package/dist/inspector/selection/editTarget.js +11 -0
- package/dist/inspector/selection/hierarchy.d.ts +7 -0
- package/dist/inspector/selection/hierarchy.js +42 -0
- package/dist/inspector/selection/resolveSelection.d.ts +10 -0
- package/dist/inspector/selection/resolveSelection.js +60 -0
- package/dist/inspector/selection/selectionStore.d.ts +41 -0
- package/dist/inspector/selection/selectionStore.js +262 -0
- package/dist/inspector/selection/selectionTarget.d.ts +5 -0
- package/dist/inspector/selection/selectionTarget.js +50 -0
- package/dist/inspector/selection/sourceSite.d.ts +2 -0
- package/dist/inspector/selection/sourceSite.js +12 -0
- package/dist/inspector/selection/styleSelection.d.ts +22 -0
- package/dist/inspector/selection/styleSelection.js +104 -0
- package/dist/inspector/session/index.d.ts +3 -0
- package/dist/inspector/session/index.js +2 -0
- package/dist/inspector/session/lifecycle.d.ts +22 -0
- package/dist/inspector/session/lifecycle.js +63 -0
- package/dist/inspector/session/sessionContext.d.ts +21 -0
- package/dist/inspector/session/sessionContext.js +28 -0
- package/dist/inspector/session/sessionFactory.d.ts +29 -0
- package/dist/inspector/session/sessionFactory.js +73 -0
- package/dist/inspector/settings/SettingsDialog.d.ts +12 -0
- package/dist/inspector/settings/SettingsDialog.js +46 -0
- package/dist/inspector/shell/AppShell.d.ts +2 -0
- package/dist/inspector/shell/AppShell.js +9 -0
- package/dist/inspector/shell/ChangesLog.d.ts +6 -0
- package/dist/inspector/shell/ChangesLog.js +92 -0
- package/dist/inspector/shell/CopyPromptButton.d.ts +9 -0
- package/dist/inspector/shell/CopyPromptButton.js +159 -0
- package/dist/inspector/shell/DomNavigation.d.ts +8 -0
- package/dist/inspector/shell/DomNavigation.js +30 -0
- package/dist/inspector/shell/EmptyState.d.ts +2 -0
- package/dist/inspector/shell/EmptyState.js +15 -0
- package/dist/inspector/shell/InspectorShell.d.ts +11 -0
- package/dist/inspector/shell/InspectorShell.js +268 -0
- package/dist/inspector/shell/openStore.d.ts +6 -0
- package/dist/inspector/shell/openStore.js +29 -0
- package/dist/inspector/shell/panelLayout.d.ts +2 -0
- package/dist/inspector/shell/panelLayout.js +29 -0
- package/dist/inspector/shell/shortcuts.d.ts +3 -0
- package/dist/inspector/shell/shortcuts.js +25 -0
- package/dist/inspector/shell/stateValue.d.ts +3 -0
- package/dist/inspector/shell/stateValue.js +34 -0
- package/dist/inspector/shell/styleState.d.ts +7 -0
- package/dist/inspector/shell/styleState.js +13 -0
- package/dist/inspector/spacing/projection.d.ts +43 -0
- package/dist/inspector/spacing/projection.js +136 -0
- package/dist/inspector/styleEditors/AppearanceSection.d.ts +13 -0
- package/dist/inspector/styleEditors/AppearanceSection.js +6 -0
- package/dist/inspector/styleEditors/AspectRatioField.d.ts +17 -0
- package/dist/inspector/styleEditors/AspectRatioField.js +10 -0
- package/dist/inspector/styleEditors/BorderEditor.d.ts +13 -0
- package/dist/inspector/styleEditors/BorderEditor.js +295 -0
- package/dist/inspector/styleEditors/BorderRadiusEditor.d.ts +14 -0
- package/dist/inspector/styleEditors/BorderRadiusEditor.js +108 -0
- package/dist/inspector/styleEditors/BoxShadowEditor.d.ts +13 -0
- package/dist/inspector/styleEditors/BoxShadowEditor.js +13 -0
- package/dist/inspector/styleEditors/ColorPicker.d.ts +15 -0
- package/dist/inspector/styleEditors/ColorPicker.js +73 -0
- package/dist/inspector/styleEditors/GapField.d.ts +17 -0
- package/dist/inspector/styleEditors/GapField.js +12 -0
- package/dist/inspector/styleEditors/GridChildSection.d.ts +14 -0
- package/dist/inspector/styleEditors/GridChildSection.js +91 -0
- package/dist/inspector/styleEditors/GridPicker.d.ts +13 -0
- package/dist/inspector/styleEditors/GridPicker.js +179 -0
- package/dist/inspector/styleEditors/GridSection.d.ts +17 -0
- package/dist/inspector/styleEditors/GridSection.js +27 -0
- package/dist/inspector/styleEditors/GridValueField.d.ts +17 -0
- package/dist/inspector/styleEditors/GridValueField.js +70 -0
- package/dist/inspector/styleEditors/InsetSection.d.ts +15 -0
- package/dist/inspector/styleEditors/InsetSection.js +15 -0
- package/dist/inspector/styleEditors/LayoutBlockedIndicator.d.ts +6 -0
- package/dist/inspector/styleEditors/LayoutBlockedIndicator.js +6 -0
- package/dist/inspector/styleEditors/LayoutComboField.d.ts +18 -0
- package/dist/inspector/styleEditors/LayoutComboField.js +138 -0
- package/dist/inspector/styleEditors/LayoutDropdown.d.ts +14 -0
- package/dist/inspector/styleEditors/LayoutDropdown.js +34 -0
- package/dist/inspector/styleEditors/LayoutSection.d.ts +13 -0
- package/dist/inspector/styleEditors/LayoutSection.js +342 -0
- package/dist/inspector/styleEditors/OpacityEditor.d.ts +13 -0
- package/dist/inspector/styleEditors/OpacityEditor.js +34 -0
- package/dist/inspector/styleEditors/PositionInsets.d.ts +15 -0
- package/dist/inspector/styleEditors/PositionInsets.js +12 -0
- package/dist/inspector/styleEditors/SpacingBox.d.ts +29 -0
- package/dist/inspector/styleEditors/SpacingBox.js +189 -0
- package/dist/inspector/styleEditors/Typography.d.ts +13 -0
- package/dist/inspector/styleEditors/Typography.js +137 -0
- package/dist/inspector/styleEditors/completeCssValue.d.ts +8 -0
- package/dist/inspector/styleEditors/completeCssValue.js +34 -0
- package/dist/inspector/styleEditors/gridChildModel.d.ts +74 -0
- package/dist/inspector/styleEditors/gridChildModel.js +138 -0
- package/dist/inspector/styleEditors/layoutValue.d.ts +24 -0
- package/dist/inspector/styleEditors/layoutValue.js +103 -0
- package/dist/inspector/styleEditors/nudgeValue.d.ts +8 -0
- package/dist/inspector/styleEditors/nudgeValue.js +71 -0
- package/dist/inspector/styleEditors/rowLookup.d.ts +11 -0
- package/dist/inspector/styleEditors/rowLookup.js +13 -0
- package/dist/inspector/styleEditors/stringRecord.d.ts +4 -0
- package/dist/inspector/styleEditors/stringRecord.js +1 -0
- package/dist/inspector/styleEditors/valuePolicy.d.ts +20 -0
- package/dist/inspector/styleEditors/valuePolicy.js +82 -0
- package/dist/inspector/testing.d.ts +10 -0
- package/dist/inspector/testing.js +9 -0
- package/dist/inspector/tokens/TokenChip.d.ts +24 -0
- package/dist/inspector/tokens/TokenChip.js +23 -0
- package/dist/inspector/tokens/TokenDropdown.d.ts +13 -0
- package/dist/inspector/tokens/TokenDropdown.js +59 -0
- package/dist/inspector/tokens/TokenField.d.ts +68 -0
- package/dist/inspector/tokens/TokenField.js +485 -0
- package/dist/inspector/tokens/TokenLabel.d.ts +7 -0
- package/dist/inspector/tokens/TokenLabel.js +23 -0
- package/dist/inspector/tokens/TokensPanel.d.ts +5 -0
- package/dist/inspector/tokens/TokensPanel.js +47 -0
- package/dist/inspector/tokens/catalog.d.ts +51 -0
- package/dist/inspector/tokens/catalog.js +184 -0
- package/dist/inspector/tokens/editActions.d.ts +35 -0
- package/dist/inspector/tokens/editActions.js +164 -0
- package/dist/inspector/tokens/resolution/cascade.d.ts +14 -0
- package/dist/inspector/tokens/resolution/cascade.js +31 -0
- package/dist/inspector/tokens/resolution/cssomCollector.d.ts +43 -0
- package/dist/inspector/tokens/resolution/cssomCollector.js +528 -0
- package/dist/inspector/tokens/resolution/selectorSemantics.d.ts +12 -0
- package/dist/inspector/tokens/resolution/selectorSemantics.js +106 -0
- package/dist/inspector/tokens/resolution.d.ts +56 -0
- package/dist/inspector/tokens/resolution.js +1401 -0
- package/dist/inspector/tokens/tokenEdits.d.ts +3 -0
- package/dist/inspector/tokens/tokenEdits.js +22 -0
- package/dist/inspector/tokens/valueSemanticsAdapter.d.ts +6 -0
- package/dist/inspector/tokens/valueSemanticsAdapter.js +68 -0
- package/dist/inspector/ui/AtRuleContext.d.ts +18 -0
- package/dist/inspector/ui/AtRuleContext.js +54 -0
- package/dist/inspector/ui/Button.d.ts +9 -0
- package/dist/inspector/ui/Button.js +4 -0
- package/dist/inspector/ui/ColorSwatch.d.ts +7 -0
- package/dist/inspector/ui/ColorSwatch.js +6 -0
- package/dist/inspector/ui/ControlSurface.d.ts +14 -0
- package/dist/inspector/ui/ControlSurface.js +10 -0
- package/dist/inspector/ui/FieldRow.d.ts +14 -0
- package/dist/inspector/ui/FieldRow.js +15 -0
- package/dist/inspector/ui/IconButton.d.ts +14 -0
- package/dist/inspector/ui/IconButton.js +5 -0
- package/dist/inspector/ui/InspectorPopover.d.ts +17 -0
- package/dist/inspector/ui/InspectorPopover.js +13 -0
- package/dist/inspector/ui/PopoverListbox.d.ts +37 -0
- package/dist/inspector/ui/PopoverListbox.js +21 -0
- package/dist/inspector/ui/SegmentedControl.d.ts +24 -0
- package/dist/inspector/ui/SegmentedControl.js +16 -0
- package/dist/inspector/ui/Select.d.ts +25 -0
- package/dist/inspector/ui/Select.js +56 -0
- package/dist/inspector/ui/SideValuesField.d.ts +44 -0
- package/dist/inspector/ui/SideValuesField.js +76 -0
- package/dist/inspector/ui/StatusCallout.d.ts +9 -0
- package/dist/inspector/ui/StatusCallout.js +4 -0
- package/dist/inspector/ui/TextInput.d.ts +12 -0
- package/dist/inspector/ui/TextInput.js +5 -0
- package/dist/inspector/ui/ToggleButton.d.ts +11 -0
- package/dist/inspector/ui/ToggleButton.js +6 -0
- package/dist/inspector/ui/assets/grid.svg +14 -0
- package/dist/inspector/ui/css.d.ts +9 -0
- package/dist/inspector/ui/labels.d.ts +1 -0
- package/dist/inspector/ui/labels.js +7 -0
- package/dist/inspector/ui/styles.d.ts +1 -0
- package/dist/inspector/ui/styles.js +68 -0
- package/dist/inspector/virtual-modules.d.ts +7 -0
- package/dist/inspector/vite-env.d.ts +10 -0
- package/dist/internal/agent-protocol.d.ts +232 -0
- package/dist/internal/agent-protocol.js +237 -0
- package/dist/nudge-ui.mjs +15722 -0
- package/dist/project/files.d.ts +19 -0
- package/dist/project/files.js +226 -0
- package/dist/project/identity.d.ts +6 -0
- package/dist/project/identity.js +19 -0
- package/dist/project/pathPolicy.d.ts +8 -0
- package/dist/project/pathPolicy.js +12 -0
- package/dist/project/tokens.d.ts +36 -0
- package/dist/project/tokens.js +223 -0
- package/dist/transport/index.d.ts +8 -0
- package/dist/transport/index.js +8 -0
- package/dist/transport/routes.d.ts +13 -0
- package/dist/transport/routes.js +16 -0
- package/package.json +137 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DefaultTreeAdapterTypes } from "parse5";
|
|
2
|
+
export declare const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
|
|
3
|
+
/** Elements that never carry identity: they render nothing a user can select. */
|
|
4
|
+
export declare const EXCLUDED_TAG_NAMES: Set<string>;
|
|
5
|
+
export type HtmlElement = DefaultTreeAdapterTypes.Element;
|
|
6
|
+
export type ElementLocation = NonNullable<HtmlElement["sourceCodeLocation"]>;
|
|
7
|
+
export type StartTagLocation = NonNullable<ElementLocation["startTag"]>;
|
|
8
|
+
export declare function isElement(node: DefaultTreeAdapterTypes.ChildNode): node is HtmlElement;
|
|
9
|
+
export declare function hasAttribute(element: HtmlElement, name: string, value?: string): boolean;
|
|
10
|
+
export declare function getAttributeValue(element: HtmlElement, name: string): string | undefined;
|
|
11
|
+
/** Every `<body>` in the document, skipping inert `<template>` content. */
|
|
12
|
+
export declare function findBodyElements(document: DefaultTreeAdapterTypes.Document): HtmlElement[];
|
|
13
|
+
export declare function escapeAttributeValue(value: string): string;
|
package/dist/html/dom.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
|
|
2
|
+
/** Elements that never carry identity: they render nothing a user can select. */
|
|
3
|
+
export const EXCLUDED_TAG_NAMES = new Set([
|
|
4
|
+
"html",
|
|
5
|
+
"head",
|
|
6
|
+
"body",
|
|
7
|
+
"script",
|
|
8
|
+
"style",
|
|
9
|
+
"template",
|
|
10
|
+
"noscript",
|
|
11
|
+
]);
|
|
12
|
+
export function isElement(node) {
|
|
13
|
+
return "tagName" in node && typeof node.tagName === "string";
|
|
14
|
+
}
|
|
15
|
+
export function hasAttribute(element, name, value) {
|
|
16
|
+
const attribute = element.attrs.find((candidate) => candidate.name === name);
|
|
17
|
+
return attribute !== undefined && (value === undefined || attribute.value === value);
|
|
18
|
+
}
|
|
19
|
+
export function getAttributeValue(element, name) {
|
|
20
|
+
return element.attrs.find((candidate) => candidate.name === name)?.value;
|
|
21
|
+
}
|
|
22
|
+
/** Every `<body>` in the document, skipping inert `<template>` content. */
|
|
23
|
+
export function findBodyElements(document) {
|
|
24
|
+
const bodies = [];
|
|
25
|
+
const visit = (parent) => {
|
|
26
|
+
for (const child of parent.childNodes) {
|
|
27
|
+
if (!isElement(child))
|
|
28
|
+
continue;
|
|
29
|
+
if (child.tagName.toLowerCase() === "template")
|
|
30
|
+
continue;
|
|
31
|
+
if (child.tagName === "body" && child.namespaceURI === HTML_NAMESPACE) {
|
|
32
|
+
bodies.push(child);
|
|
33
|
+
}
|
|
34
|
+
visit(child);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
visit(document);
|
|
38
|
+
return bodies;
|
|
39
|
+
}
|
|
40
|
+
export function escapeAttributeValue(value) {
|
|
41
|
+
return value
|
|
42
|
+
.replaceAll("&", "&")
|
|
43
|
+
.replaceAll('"', """)
|
|
44
|
+
.replaceAll("<", "<")
|
|
45
|
+
.replaceAll(">", ">");
|
|
46
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adds source identity to HTML without reserializing it. The two hosts differ
|
|
3
|
+
* only in where identity comes from: the static-HTML host owns the file and
|
|
4
|
+
* uses parser offsets, Astro does not own the response and reads its
|
|
5
|
+
* compiler's annotations. Both share the traversal below.
|
|
6
|
+
*
|
|
7
|
+
* Attributes are inserted only where missing, at the end of the opening tag,
|
|
8
|
+
* so everything outside those insertions stays byte-for-byte unchanged.
|
|
9
|
+
*/
|
|
10
|
+
export interface HtmlIdentityDiagnostic {
|
|
11
|
+
readonly code: HtmlIdentityDiagnosticCode;
|
|
12
|
+
readonly severity: "warning";
|
|
13
|
+
readonly message: string;
|
|
14
|
+
readonly file?: string;
|
|
15
|
+
/** One-based. */
|
|
16
|
+
readonly line?: number;
|
|
17
|
+
/** One-based. */
|
|
18
|
+
readonly column?: number;
|
|
19
|
+
/** Zero-based. */
|
|
20
|
+
readonly offset?: number;
|
|
21
|
+
}
|
|
22
|
+
export type HtmlIdentityDiagnosticCode = "html-parse-error" | "missing-source-location" | "invalid-source-location" | "astro-source-annotations-absent";
|
|
23
|
+
export interface HtmlIdentityResult {
|
|
24
|
+
readonly html: string;
|
|
25
|
+
/** In source order, document-level last. */
|
|
26
|
+
readonly diagnostics: readonly HtmlIdentityDiagnostic[];
|
|
27
|
+
readonly insertedAttributeCount: number;
|
|
28
|
+
}
|
|
29
|
+
/** Instruments an HTML file the host owns on disk, using parser offsets for position. */
|
|
30
|
+
export declare function instrumentSourceHtml(source: string, file: string): HtmlIdentityResult;
|
|
31
|
+
export interface RenderedHtmlIdentityOptions {
|
|
32
|
+
/** Relativizes absolute annotation paths. Omit to forward them unchanged. */
|
|
33
|
+
readonly projectRoot?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Instruments a rendered Astro dev response from Astro's own compiler
|
|
37
|
+
* annotations. Elements without them degrade to an `astro:<Tag>` label and no
|
|
38
|
+
* position, because a guessed `data-src` would be worse than none.
|
|
39
|
+
*/
|
|
40
|
+
export declare function instrumentRenderedHtml(html: string, options?: RenderedHtmlIdentityOptions): HtmlIdentityResult;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { parse } from "parse5";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { EXCLUDED_TAG_NAMES, HTML_NAMESPACE, escapeAttributeValue, findBodyElements, getAttributeValue, hasAttribute, isElement, } from "./dom.js";
|
|
4
|
+
import { applyInsertions, createSourcePositionIndex, insertionOffsetFor, positionAt, } from "./insertions.js";
|
|
5
|
+
import { NUDGE_UI_MOUNT_ID } from "../transport/routes.js";
|
|
6
|
+
function runIdentityPass(source, pass) {
|
|
7
|
+
const diagnostics = [];
|
|
8
|
+
const report = (code, message, position) => {
|
|
9
|
+
diagnostics.push({
|
|
10
|
+
code,
|
|
11
|
+
severity: "warning",
|
|
12
|
+
message,
|
|
13
|
+
...(pass.file === undefined ? {} : { file: pass.file }),
|
|
14
|
+
...(position?.line === undefined ? {} : { line: position.line }),
|
|
15
|
+
...(position?.column === undefined ? {} : { column: position.column }),
|
|
16
|
+
...(position?.offset === undefined ? {} : { offset: position.offset }),
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
const parseErrors = [];
|
|
20
|
+
const document = parse(source, {
|
|
21
|
+
sourceCodeLocationInfo: true,
|
|
22
|
+
onParseError: (error) => parseErrors.push(error),
|
|
23
|
+
});
|
|
24
|
+
for (const error of parseErrors) {
|
|
25
|
+
// Affects neither source locations nor DOM identity, and ordinary fragments have none.
|
|
26
|
+
if (error.code === "missing-doctype")
|
|
27
|
+
continue;
|
|
28
|
+
report("html-parse-error", `HTML parser reported ${error.code}.`, {
|
|
29
|
+
line: error.startLine,
|
|
30
|
+
column: error.startCol,
|
|
31
|
+
offset: error.startOffset,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
const positions = createSourcePositionIndex(source);
|
|
35
|
+
const insertions = [];
|
|
36
|
+
const visit = (element) => {
|
|
37
|
+
if (element.namespaceURI !== HTML_NAMESPACE)
|
|
38
|
+
return;
|
|
39
|
+
const tagName = element.tagName.toLowerCase();
|
|
40
|
+
if (EXCLUDED_TAG_NAMES.has(tagName))
|
|
41
|
+
return;
|
|
42
|
+
if (hasAttribute(element, "id", NUDGE_UI_MOUNT_ID))
|
|
43
|
+
return;
|
|
44
|
+
pass.observe?.(element);
|
|
45
|
+
const location = element.sourceCodeLocation;
|
|
46
|
+
const startTag = location?.startTag;
|
|
47
|
+
if (!startTag) {
|
|
48
|
+
report("missing-source-location", `Skipped <${tagName}> because the parser did not provide an opening-tag location.`, { line: location?.startLine, column: location?.startCol, offset: location?.startOffset });
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
const startOffset = location?.startOffset ?? startTag.startOffset;
|
|
52
|
+
const { line, column } = positionAt(positions, startOffset);
|
|
53
|
+
const offset = insertionOffsetFor(source, startTag);
|
|
54
|
+
if (offset === null) {
|
|
55
|
+
report("invalid-source-location", `Skipped <${tagName}> because its opening-tag location does not end at a tag boundary.`, { line, column, offset: startOffset });
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
const attributes = pass.attributesFor({ element, tagName, line, column, offset: startOffset }, report);
|
|
59
|
+
if (attributes.length > 0) {
|
|
60
|
+
insertions.push({
|
|
61
|
+
offset,
|
|
62
|
+
text: ` ${attributes.join(" ")}`,
|
|
63
|
+
attributeCount: attributes.length,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (pass.stopsDescent?.(tagName))
|
|
69
|
+
return;
|
|
70
|
+
for (const child of element.childNodes) {
|
|
71
|
+
if (isElement(child))
|
|
72
|
+
visit(child);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
for (const body of findBodyElements(document)) {
|
|
76
|
+
for (const child of body.childNodes) {
|
|
77
|
+
if (isElement(child))
|
|
78
|
+
visit(child);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
html: insertions.length === 0 ? source : applyInsertions(source, insertions),
|
|
83
|
+
diagnostics,
|
|
84
|
+
insertedAttributeCount: insertions.reduce((count, i) => count + i.attributeCount, 0),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/** Instruments an HTML file the host owns on disk, using parser offsets for position. */
|
|
88
|
+
export function instrumentSourceHtml(source, file) {
|
|
89
|
+
return runIdentityPass(source, {
|
|
90
|
+
file,
|
|
91
|
+
attributesFor({ element, line, column }) {
|
|
92
|
+
const attributes = [];
|
|
93
|
+
if (!hasAttribute(element, "data-cid")) {
|
|
94
|
+
attributes.push(`data-cid="${escapeAttributeValue(`html:${element.tagName}`)}"`);
|
|
95
|
+
}
|
|
96
|
+
if (!hasAttribute(element, "data-src")) {
|
|
97
|
+
attributes.push(`data-src="${escapeAttributeValue(`${file}:${line}:${column}`)}"`);
|
|
98
|
+
}
|
|
99
|
+
return attributes;
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
/** Astro's hydration host; its subtree receives framework-side identity later. */
|
|
104
|
+
const ASTRO_ISLAND_TAG_NAME = "astro-island";
|
|
105
|
+
const ASTRO_SOURCE_FILE_ATTRIBUTE = "data-astro-source-file";
|
|
106
|
+
const ASTRO_SOURCE_LOC_ATTRIBUTE = "data-astro-source-loc";
|
|
107
|
+
/**
|
|
108
|
+
* Instruments a rendered Astro dev response from Astro's own compiler
|
|
109
|
+
* annotations. Elements without them degrade to an `astro:<Tag>` label and no
|
|
110
|
+
* position, because a guessed `data-src` would be worse than none.
|
|
111
|
+
*/
|
|
112
|
+
export function instrumentRenderedHtml(html, options = {}) {
|
|
113
|
+
let sawSourceAnnotation = false;
|
|
114
|
+
const result = runIdentityPass(html, {
|
|
115
|
+
stopsDescent: (tagName) => tagName === ASTRO_ISLAND_TAG_NAME,
|
|
116
|
+
observe(element) {
|
|
117
|
+
if (hasAttribute(element, ASTRO_SOURCE_FILE_ATTRIBUTE))
|
|
118
|
+
sawSourceAnnotation = true;
|
|
119
|
+
},
|
|
120
|
+
attributesFor({ element, tagName, line, column, offset }, report) {
|
|
121
|
+
const attributes = [];
|
|
122
|
+
if (!hasAttribute(element, "data-cid")) {
|
|
123
|
+
attributes.push(`data-cid="${escapeAttributeValue(astroLabel(tagName))}"`);
|
|
124
|
+
}
|
|
125
|
+
if (!hasAttribute(element, "data-src")) {
|
|
126
|
+
const identity = readAstroSourceIdentity(element, options.projectRoot, report, {
|
|
127
|
+
line,
|
|
128
|
+
column,
|
|
129
|
+
offset,
|
|
130
|
+
});
|
|
131
|
+
if (identity !== null)
|
|
132
|
+
attributes.push(`data-src="${escapeAttributeValue(identity)}"`);
|
|
133
|
+
}
|
|
134
|
+
return attributes;
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
if (result.insertedAttributeCount === 0 || sawSourceAnnotation)
|
|
138
|
+
return result;
|
|
139
|
+
return {
|
|
140
|
+
...result,
|
|
141
|
+
diagnostics: [...result.diagnostics, {
|
|
142
|
+
code: "astro-source-annotations-absent",
|
|
143
|
+
severity: "warning",
|
|
144
|
+
message: "No eligible element carried Astro dev source annotations, so identity is degraded to generated astro:<Tag> labels without data-src. Enable the Astro dev toolbar to restore exact source identity.",
|
|
145
|
+
}],
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/** Returns null rather than a bare file path, which consumers would misparse. */
|
|
149
|
+
function readAstroSourceIdentity(element, projectRoot, report, position) {
|
|
150
|
+
const fileValue = getAttributeValue(element, ASTRO_SOURCE_FILE_ATTRIBUTE);
|
|
151
|
+
if (fileValue === undefined)
|
|
152
|
+
return null;
|
|
153
|
+
const tagName = element.tagName.toLowerCase();
|
|
154
|
+
const trimmedFile = fileValue.trim();
|
|
155
|
+
if (trimmedFile === "") {
|
|
156
|
+
report("invalid-source-location", `Ignored empty Astro source file annotation on <${tagName}>.`, position);
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
const locValue = getAttributeValue(element, ASTRO_SOURCE_LOC_ATTRIBUTE);
|
|
160
|
+
if (locValue === undefined)
|
|
161
|
+
return null;
|
|
162
|
+
const loc = parseAstroSourceLoc(locValue);
|
|
163
|
+
if (loc === null) {
|
|
164
|
+
report("invalid-source-location", `Ignored unreadable Astro source location "${locValue}" on <${tagName}>.`, position);
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
const file = projectRelativePath(trimmedFile, projectRoot);
|
|
168
|
+
return loc.column === undefined ? `${file}:${loc.line}` : `${file}:${loc.line}:${loc.column}`;
|
|
169
|
+
}
|
|
170
|
+
/** Parses "line:column". A bare integer is accepted as a line with no column. */
|
|
171
|
+
function parseAstroSourceLoc(value) {
|
|
172
|
+
const match = /^\s*(\d+)(?:\s*:\s*(\d+))?\s*$/.exec(value);
|
|
173
|
+
const lineText = match?.[1];
|
|
174
|
+
if (lineText === undefined)
|
|
175
|
+
return null;
|
|
176
|
+
const columnText = match?.[2];
|
|
177
|
+
const line = Number(lineText);
|
|
178
|
+
if (columnText === undefined)
|
|
179
|
+
return line >= 1 ? { line } : null;
|
|
180
|
+
const column = Number(columnText);
|
|
181
|
+
return line >= 1 && column >= 1 ? { line, column } : null;
|
|
182
|
+
}
|
|
183
|
+
/** Separators are normalized to forward slashes so values stay portable. */
|
|
184
|
+
function projectRelativePath(filePath, projectRoot) {
|
|
185
|
+
const normalized = filePath.replaceAll("\\", "/");
|
|
186
|
+
if (projectRoot === undefined || !path.isAbsolute(normalized))
|
|
187
|
+
return normalized;
|
|
188
|
+
const relative = path.relative(projectRoot, normalized).replaceAll("\\", "/");
|
|
189
|
+
return relative === "" ? "." : relative;
|
|
190
|
+
}
|
|
191
|
+
/** h1 -> astro:H1. The island gets `astro:Island`, not `astro:Astro-island`. */
|
|
192
|
+
function astroLabel(tagName) {
|
|
193
|
+
if (tagName === ASTRO_ISLAND_TAG_NAME)
|
|
194
|
+
return "astro:Island";
|
|
195
|
+
return `astro:${tagName.charAt(0).toUpperCase()}${tagName.slice(1)}`;
|
|
196
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { StartTagLocation } from "./dom.js";
|
|
2
|
+
/** Attribute text to splice into the original source at one byte offset. */
|
|
3
|
+
export interface Insertion {
|
|
4
|
+
readonly offset: number;
|
|
5
|
+
readonly text: string;
|
|
6
|
+
readonly attributeCount: number;
|
|
7
|
+
}
|
|
8
|
+
/** Offset just inside the opening tag's `>`, or null if it is not a tag boundary. */
|
|
9
|
+
export declare function insertionOffsetFor(source: string, startTag: StartTagLocation): number | null;
|
|
10
|
+
/** Splices insertions into the source, leaving every other byte untouched. */
|
|
11
|
+
export declare function applyInsertions(source: string, insertions: readonly Insertion[]): string;
|
|
12
|
+
/**
|
|
13
|
+
* One-based positions computed from the original source, not from parse5,
|
|
14
|
+
* which normalizes `\r\n` and lone `\r` to `\n` and would drift from the bytes
|
|
15
|
+
* these operations preserve. Columns count UTF-16 code units, so a tab is one
|
|
16
|
+
* column, matching grep-style tooling rather than editor tab stops.
|
|
17
|
+
*/
|
|
18
|
+
export interface SourcePositionIndex {
|
|
19
|
+
readonly lineStarts: readonly number[];
|
|
20
|
+
}
|
|
21
|
+
export declare function createSourcePositionIndex(source: string): SourcePositionIndex;
|
|
22
|
+
export interface SourcePosition {
|
|
23
|
+
readonly line: number;
|
|
24
|
+
readonly column: number;
|
|
25
|
+
}
|
|
26
|
+
export declare function positionAt(positions: SourcePositionIndex, offset: number): SourcePosition;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** Offset just inside the opening tag's `>`, or null if it is not a tag boundary. */
|
|
2
|
+
export function insertionOffsetFor(source, startTag) {
|
|
3
|
+
const { startOffset, endOffset } = startTag;
|
|
4
|
+
if (startOffset < 0
|
|
5
|
+
|| endOffset <= startOffset
|
|
6
|
+
|| endOffset > source.length
|
|
7
|
+
|| source[endOffset - 1] !== ">") {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
// Insert before a self-closing slash: `<input data-cid="..." />`.
|
|
11
|
+
return source[endOffset - 2] === "/" ? endOffset - 2 : endOffset - 1;
|
|
12
|
+
}
|
|
13
|
+
/** Splices insertions into the source, leaving every other byte untouched. */
|
|
14
|
+
export function applyInsertions(source, insertions) {
|
|
15
|
+
const byOffset = new Map();
|
|
16
|
+
for (const insertion of insertions) {
|
|
17
|
+
const texts = byOffset.get(insertion.offset) ?? [];
|
|
18
|
+
texts.push(insertion.text);
|
|
19
|
+
byOffset.set(insertion.offset, texts);
|
|
20
|
+
}
|
|
21
|
+
let result = "";
|
|
22
|
+
let cursor = 0;
|
|
23
|
+
for (const offset of [...byOffset.keys()].sort((a, b) => a - b)) {
|
|
24
|
+
result += source.slice(cursor, offset);
|
|
25
|
+
result += byOffset.get(offset).join("");
|
|
26
|
+
cursor = offset;
|
|
27
|
+
}
|
|
28
|
+
return result + source.slice(cursor);
|
|
29
|
+
}
|
|
30
|
+
export function createSourcePositionIndex(source) {
|
|
31
|
+
const lineStarts = [0];
|
|
32
|
+
for (let offset = 0; offset < source.length; offset += 1) {
|
|
33
|
+
const character = source[offset];
|
|
34
|
+
if (character === "\r") {
|
|
35
|
+
// `\r\n` is one break, so skip its `\n`.
|
|
36
|
+
const next = source[offset + 1];
|
|
37
|
+
lineStarts.push(next === "\n" ? offset + 2 : offset + 1);
|
|
38
|
+
if (next === "\n")
|
|
39
|
+
offset += 1;
|
|
40
|
+
}
|
|
41
|
+
else if (character === "\n") {
|
|
42
|
+
lineStarts.push(offset + 1);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return { lineStarts };
|
|
46
|
+
}
|
|
47
|
+
export function positionAt(positions, offset) {
|
|
48
|
+
const { lineStarts } = positions;
|
|
49
|
+
let low = 0;
|
|
50
|
+
let high = lineStarts.length - 1;
|
|
51
|
+
while (low < high) {
|
|
52
|
+
const middle = Math.ceil((low + high) / 2);
|
|
53
|
+
if (lineStarts[middle] <= offset)
|
|
54
|
+
low = middle;
|
|
55
|
+
else
|
|
56
|
+
high = middle - 1;
|
|
57
|
+
}
|
|
58
|
+
return { line: low + 1, column: offset - lineStarts[low] + 1 };
|
|
59
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import type { AgentClientSnapshot } from "./client.js";
|
|
3
|
+
export declare const MCP_DOCS_URL = "https://github.com/charlessmart/nudge-ui#connect-a-coding-agent";
|
|
4
|
+
/** Builds the project-local add-mcp command shown by the connection panel. */
|
|
5
|
+
export declare function createMcpSetupCommand(projectId: string, origin: string): string;
|
|
6
|
+
export interface McpConnectionContentProps {
|
|
7
|
+
readonly projectId: string;
|
|
8
|
+
readonly origin: string;
|
|
9
|
+
readonly snapshot: AgentClientSnapshot;
|
|
10
|
+
readonly onConnect: () => Promise<boolean> | boolean | void;
|
|
11
|
+
readonly onDisconnect: () => void;
|
|
12
|
+
readonly onCheckAgain: () => Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export interface McpConnectionDialogProps extends McpConnectionContentProps {
|
|
15
|
+
readonly open: boolean;
|
|
16
|
+
readonly onOpenChange: (open: boolean) => void;
|
|
17
|
+
}
|
|
18
|
+
/** Renders the MCP setup and pairing flow without owning a dialog surface. */
|
|
19
|
+
export declare function McpConnectionContent({ projectId, origin, snapshot, onConnect, onDisconnect, onCheckAgain, }: McpConnectionContentProps): ReactElement;
|
|
20
|
+
/**
|
|
21
|
+
* Explains and controls the project-scoped MCP companion connection.
|
|
22
|
+
*
|
|
23
|
+
* This compatibility wrapper keeps the existing standalone MCP surface while
|
|
24
|
+
* the shared content is also embedded in the general settings modal.
|
|
25
|
+
*/
|
|
26
|
+
export declare function McpConnectionDialog({ open, projectId, origin, snapshot, onOpenChange, onConnect, onDisconnect, onCheckAgain, }: McpConnectionDialogProps): ReactElement;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useRef, useState } from "react";
|
|
3
|
+
import { Dialog } from "@base-ui/react/dialog";
|
|
4
|
+
import { IconCheck, IconClipboard, IconExternalLink, IconPlugConnected, IconRefresh, IconUnlink, IconX, } from "@tabler/icons-react";
|
|
5
|
+
import { getAgentConnectionStatus } from "./connectionStatus.js";
|
|
6
|
+
import { copyToClipboard } from "../prompt/copyToClipboard.js";
|
|
7
|
+
import { Button } from "../ui/Button.js";
|
|
8
|
+
import { SegmentedControl } from "../ui/SegmentedControl.js";
|
|
9
|
+
import { StatusCallout } from "../ui/StatusCallout.js";
|
|
10
|
+
export const MCP_DOCS_URL = "https://github.com/charlessmart/nudge-ui#connect-a-coding-agent";
|
|
11
|
+
/** Quotes one value for a POSIX shell command. */
|
|
12
|
+
function shellQuote(value) {
|
|
13
|
+
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
14
|
+
}
|
|
15
|
+
function shellArgument(value) {
|
|
16
|
+
// Keep the usual command readable while quoting values that could be
|
|
17
|
+
// interpreted as shell syntax when add-mcp runs the nested command.
|
|
18
|
+
return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value) ? value : shellQuote(value);
|
|
19
|
+
}
|
|
20
|
+
/** Builds the project-local add-mcp command shown by the connection panel. */
|
|
21
|
+
export function createMcpSetupCommand(projectId, origin) {
|
|
22
|
+
const serverCommand = [
|
|
23
|
+
"npx -y @nudge-ui/mcp@latest",
|
|
24
|
+
"--project-id",
|
|
25
|
+
shellArgument(projectId),
|
|
26
|
+
"--origin",
|
|
27
|
+
shellArgument(origin),
|
|
28
|
+
"--workspace-root .",
|
|
29
|
+
].join(" ");
|
|
30
|
+
return `npx add-mcp ${shellQuote(serverCommand)} --name nudge_ui`;
|
|
31
|
+
}
|
|
32
|
+
function formatMcpSetupCommand(command) {
|
|
33
|
+
return command
|
|
34
|
+
.replace(" --project-id ", "\n --project-id ")
|
|
35
|
+
.replace(" --origin ", "\n --origin ")
|
|
36
|
+
.replace(" --workspace-root ", "\n --workspace-root ");
|
|
37
|
+
}
|
|
38
|
+
function portalContainer() {
|
|
39
|
+
return typeof document !== "undefined"
|
|
40
|
+
? document.getElementById("nudge-ui-root")?.shadowRoot ?? document.body
|
|
41
|
+
: null;
|
|
42
|
+
}
|
|
43
|
+
function TimelineStep({ number, complete, title, children, }) {
|
|
44
|
+
return (_jsxs("li", { className: `mcp-connection__timeline-step${complete ? " mcp-connection__timeline-step--complete" : ""}`, "data-test": `mcp-step-${number}`, "data-complete": complete ? "true" : "false", children: [_jsx("div", { className: "mcp-connection__timeline-marker", "aria-hidden": "true", children: complete ? _jsx(IconCheck, { size: "var(--icon-size-small)", stroke: 2 }) : number }), _jsxs("section", { className: "mcp-connection__timeline-content", children: [_jsx("h3", { className: "mcp-connection__section-title", children: title }), children] })] }));
|
|
45
|
+
}
|
|
46
|
+
/** Renders the MCP setup and pairing flow without owning a dialog surface. */
|
|
47
|
+
export function McpConnectionContent({ projectId, origin, snapshot, onConnect, onDisconnect, onCheckAgain, }) {
|
|
48
|
+
const [checking, setChecking] = useState(false);
|
|
49
|
+
const [setupMethod, setSetupMethod] = useState("ai");
|
|
50
|
+
const [copiedCommand, setCopiedCommand] = useState(false);
|
|
51
|
+
const [copiedPrompt, setCopiedPrompt] = useState(false);
|
|
52
|
+
const [copiedListener, setCopiedListener] = useState(false);
|
|
53
|
+
const [copyError, setCopyError] = useState();
|
|
54
|
+
const [checkError, setCheckError] = useState();
|
|
55
|
+
const setupCommand = useMemo(() => createMcpSetupCommand(projectId, origin), [origin, projectId]);
|
|
56
|
+
const displaySetupCommand = useMemo(() => formatMcpSetupCommand(setupCommand), [setupCommand]);
|
|
57
|
+
const setupPrompt = useMemo(() => [
|
|
58
|
+
"Please configure the Nudge MCP companion for this project.",
|
|
59
|
+
"",
|
|
60
|
+
"Run this command from the project root:",
|
|
61
|
+
setupCommand,
|
|
62
|
+
"",
|
|
63
|
+
"Then restart or refresh the MCP server so Nudge can connect.",
|
|
64
|
+
].join("\n"), [setupCommand]);
|
|
65
|
+
const listenerInstruction = "Call nudge_listen now and wait for my Nudge UI prompt. After applying it, call nudge_report_status and listen again.";
|
|
66
|
+
const status = getAgentConnectionStatus(snapshot);
|
|
67
|
+
const canConnect = snapshot.companionReachable
|
|
68
|
+
&& !snapshot.paired
|
|
69
|
+
&& snapshot.state !== "pairing"
|
|
70
|
+
&& snapshot.state !== "working"
|
|
71
|
+
&& snapshot.request?.status !== "working";
|
|
72
|
+
const canDisconnect = snapshot.paired || snapshot.request?.status === "working";
|
|
73
|
+
async function handleCheckAgain() {
|
|
74
|
+
if (checking)
|
|
75
|
+
return;
|
|
76
|
+
setChecking(true);
|
|
77
|
+
setCheckError(undefined);
|
|
78
|
+
try {
|
|
79
|
+
await onCheckAgain();
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
setCheckError("The connection could not be checked. Try again.");
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
setChecking(false);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async function handleCopyCommand() {
|
|
89
|
+
setCopyError(undefined);
|
|
90
|
+
try {
|
|
91
|
+
await copyToClipboard(setupCommand);
|
|
92
|
+
setCopiedCommand(true);
|
|
93
|
+
window.setTimeout(() => setCopiedCommand(false), 1500);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
setCopyError("The setup command could not be copied. Select it and copy it manually.");
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async function handleCopyPrompt() {
|
|
100
|
+
setCopyError(undefined);
|
|
101
|
+
try {
|
|
102
|
+
await copyToClipboard(setupPrompt);
|
|
103
|
+
setCopiedPrompt(true);
|
|
104
|
+
window.setTimeout(() => setCopiedPrompt(false), 1500);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
setCopyError("The AI setup prompt could not be copied. Select it and copy it manually.");
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async function handleCopyListener() {
|
|
111
|
+
setCopyError(undefined);
|
|
112
|
+
try {
|
|
113
|
+
await copyToClipboard(listenerInstruction);
|
|
114
|
+
setCopiedListener(true);
|
|
115
|
+
window.setTimeout(() => setCopiedListener(false), 1500);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
setCopyError("The listener instruction could not be copied. Select it and copy it manually.");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return (_jsxs(_Fragment, { children: [_jsxs(StatusCallout, { className: "mcp-connection__status", tone: status.tone, "data-test": "mcp-connection-status", children: [_jsx("span", { className: "mcp-connection__status-label", role: "status", children: status.label }), snapshot.error ? (_jsx("span", { className: "mcp-connection__status-detail", children: snapshot.error })) : null, checkError ? _jsx("span", { role: "alert", children: checkError }) : null, snapshot.request?.summary ? (_jsx("span", { className: "mcp-connection__status-detail", children: snapshot.request.summary })) : null, snapshot.request?.error ? (_jsx("span", { className: "mcp-connection__status-detail", children: snapshot.request.error })) : null] }), _jsxs("ol", { className: "mcp-connection__timeline", "data-test": "mcp-connection-timeline", children: [_jsxs(TimelineStep, { number: 1, complete: snapshot.companionReachable, title: "Configure the MCP host", children: [_jsx(SegmentedControl, { "aria-label": "MCP setup method", className: "mcp-connection__setup-tabs", "data-test": "mcp-setup-tabs", value: setupMethod, options: [
|
|
122
|
+
{ value: "ai", label: "AI instructions", testId: "mcp-setup-tab-ai" },
|
|
123
|
+
{ value: "terminal", label: "Terminal command", testId: "mcp-setup-tab-terminal" },
|
|
124
|
+
], onChange: setSetupMethod }), setupMethod === "terminal" ? (_jsxs(_Fragment, { children: [_jsx("p", { className: "mcp-connection__copy", children: "Run this command from your project root." }), _jsx("pre", { className: "mcp-connection__command", children: _jsx("code", { "data-test": "mcp-setup-command", children: displaySetupCommand }) }), _jsx("div", { className: "mcp-connection__command-actions", children: _jsxs(Button, { variant: "secondary", "data-test": "mcp-copy-command", type: "button", onClick: () => void handleCopyCommand(), children: [copiedCommand ? _jsx(IconCheck, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" }) : _jsx(IconClipboard, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" }), copiedCommand ? "Copied" : "Copy command"] }) })] })) : (_jsxs(_Fragment, { children: [_jsx("p", { className: "mcp-connection__copy", children: "Copy this prompt into your coding agent to configure Nudge MCP." }), _jsx("pre", { className: "mcp-connection__command", children: _jsx("code", { "data-test": "mcp-setup-prompt", children: setupPrompt }) }), _jsx("div", { className: "mcp-connection__command-actions", children: _jsxs(Button, { variant: "secondary", "data-test": "mcp-copy-setup-prompt", type: "button", onClick: () => void handleCopyPrompt(), children: [copiedPrompt ? _jsx(IconCheck, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" }) : _jsx(IconClipboard, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" }), copiedPrompt ? "Copied" : "Copy prompt"] }) })] }))] }), _jsxs(TimelineStep, { number: 2, complete: snapshot.paired, title: "Connect this page", children: [_jsxs("dl", { className: "mcp-connection__diagnostics", "data-test": "mcp-connection-diagnostics", children: [_jsxs("div", { className: "mcp-connection__diagnostic", children: [_jsx("dt", { children: "Project ID" }), _jsx("dd", { "data-test": "mcp-project-id", children: _jsx("code", { children: projectId }) })] }), _jsxs("div", { className: "mcp-connection__diagnostic", children: [_jsx("dt", { children: "Origin" }), _jsx("dd", { "data-test": "mcp-origin", children: _jsx("code", { children: origin }) })] })] }), _jsxs("div", { className: "mcp-connection__actions", children: [canConnect ? (_jsxs(Button, { variant: "primary", "data-test": "mcp-connect", type: "button", onClick: () => void onConnect(), children: [_jsx(IconPlugConnected, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" }), "Connect"] })) : null, _jsxs(Button, { variant: "quiet", "data-test": "mcp-check-again", type: "button", disabled: checking || snapshot.state === "disabled" || snapshot.state === "pairing", onClick: () => void handleCheckAgain(), children: [_jsx(IconRefresh, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" }), checking ? "Checking…" : "Check again"] }), canDisconnect ? (_jsxs(Button, { variant: "danger", "data-test": "mcp-disconnect", type: "button", onClick: onDisconnect, children: [_jsx(IconUnlink, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" }), snapshot.paired ? "Disconnect" : "Forget connection"] })) : null] })] }), _jsxs(TimelineStep, { number: 3, complete: snapshot.listenerActive, title: "Start the agent listener", children: [_jsxs("p", { className: "mcp-connection__copy", children: ["Ask your coding agent to call ", _jsx("code", { children: "nudge_listen" }), " and keep it active."] }), _jsx("div", { className: "mcp-connection__command-actions", children: _jsxs(Button, { variant: "secondary", "data-test": "mcp-copy-listener", type: "button", onClick: () => void handleCopyListener(), children: [copiedListener ? _jsx(IconCheck, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" }) : _jsx(IconClipboard, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" }), copiedListener ? "Copied" : "Copy listener instruction"] }) })] })] }), copyError ? _jsx("p", { className: "mcp-connection__error", role: "alert", children: copyError }) : null, _jsxs("a", { className: "mcp-connection__docs", "data-test": "mcp-docs-link", href: MCP_DOCS_URL, target: "_blank", rel: "noreferrer", children: [_jsx(IconExternalLink, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" }), "Read the MCP connection guide"] })] }));
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Explains and controls the project-scoped MCP companion connection.
|
|
128
|
+
*
|
|
129
|
+
* This compatibility wrapper keeps the existing standalone MCP surface while
|
|
130
|
+
* the shared content is also embedded in the general settings modal.
|
|
131
|
+
*/
|
|
132
|
+
export function McpConnectionDialog({ open, projectId, origin, snapshot, onOpenChange, onConnect, onDisconnect, onCheckAgain, }) {
|
|
133
|
+
const closeRef = useRef(null);
|
|
134
|
+
return (_jsx(Dialog.Root, { open: open, onOpenChange: onOpenChange, children: _jsxs(Dialog.Portal, { container: portalContainer(), children: [_jsx(Dialog.Backdrop, { className: "mcp-connection__backdrop", "data-test": "mcp-connection-backdrop" }), _jsxs(Dialog.Popup, { className: "mcp-connection__popup", "data-test": "mcp-connection-dialog", initialFocus: closeRef, children: [_jsxs("div", { className: "mcp-connection__header", children: [_jsxs("div", { children: [_jsx(Dialog.Title, { className: "mcp-connection__title", children: "Connect MCP" }), _jsx(Dialog.Description, { className: "mcp-connection__description", children: "Pair this page with your coding agent. You can connect before the agent starts listening." })] }), _jsx(Dialog.Close, { ref: closeRef, className: "icon-button icon-button--quiet mcp-connection__close", "aria-label": "Close MCP connection", "data-test": "mcp-connection-close", type: "button", children: _jsx(IconX, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" }) })] }), _jsx(McpConnectionContent, { projectId: projectId, origin: origin, snapshot: snapshot, onConnect: onConnect, onDisconnect: onDisconnect, onCheckAgain: onCheckAgain })] })] }) }));
|
|
135
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { type AgentBridgeTransport, type AgentClientOptions, type AgentRequestStatus, type AgentStatusSnapshot, type PromptDispatchResponse } from "./protocol.js";
|
|
2
|
+
export type AgentClientState = "disabled" | "disconnected" | "available" | "pairing" | "connected" | "working" | "completed" | "failed" | "interrupted";
|
|
3
|
+
export interface AgentRequestSnapshot {
|
|
4
|
+
readonly requestId: string;
|
|
5
|
+
readonly changeRevision?: number;
|
|
6
|
+
readonly status: AgentRequestStatus;
|
|
7
|
+
readonly summary?: string;
|
|
8
|
+
readonly error?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface AgentClientSnapshot {
|
|
11
|
+
/** Composite state used by the handoff control. */
|
|
12
|
+
readonly state: AgentClientState;
|
|
13
|
+
/** Companion state, using the shared protocol vocabulary. */
|
|
14
|
+
readonly connection: AgentStatusSnapshot["connection"];
|
|
15
|
+
readonly listenerActive: boolean;
|
|
16
|
+
/** Whether the last valid discovery response came from the local companion. */
|
|
17
|
+
readonly companionReachable: boolean;
|
|
18
|
+
readonly paired: boolean;
|
|
19
|
+
readonly request: AgentRequestSnapshot | null;
|
|
20
|
+
readonly error?: string;
|
|
21
|
+
}
|
|
22
|
+
/** Creates a stable numeric revision for one prompt snapshot. */
|
|
23
|
+
export declare function createPromptRevision(changes: readonly unknown[], structuralChanges?: readonly unknown[]): number;
|
|
24
|
+
/**
|
|
25
|
+
* Browser-side companion client.
|
|
26
|
+
*
|
|
27
|
+
* Discovery is deliberately started by `start()`, which is guarded by the
|
|
28
|
+
* dev-only flag. Constructing this class never opens a socket or performs a
|
|
29
|
+
* network request, so importing the inspector remains inert in production.
|
|
30
|
+
*/
|
|
31
|
+
export declare class AgentClient {
|
|
32
|
+
readonly projectId: string;
|
|
33
|
+
readonly origin: string;
|
|
34
|
+
private readonly transport;
|
|
35
|
+
private readonly discoveryIntervalMs;
|
|
36
|
+
private readonly enabled;
|
|
37
|
+
private canvasCommandHandler;
|
|
38
|
+
private readonly listeners;
|
|
39
|
+
private snapshot;
|
|
40
|
+
private sessionToken;
|
|
41
|
+
private activeRequest;
|
|
42
|
+
private discoveryTimer;
|
|
43
|
+
private discoveryAbort;
|
|
44
|
+
private pairingAbort;
|
|
45
|
+
private dispatchAbort;
|
|
46
|
+
private eventSubscription;
|
|
47
|
+
private started;
|
|
48
|
+
private connection;
|
|
49
|
+
private listenerActive;
|
|
50
|
+
private companionReachable;
|
|
51
|
+
private paired;
|
|
52
|
+
private lastError;
|
|
53
|
+
constructor(options: AgentClientOptions);
|
|
54
|
+
/** Installs the controller callback used to acknowledge Canvas commands. */
|
|
55
|
+
setCanvasCommandHandler(handler: AgentClientOptions["canvasCommandHandler"]): void;
|
|
56
|
+
getSnapshot: () => AgentClientSnapshot;
|
|
57
|
+
subscribe: (listener: () => void) => (() => void);
|
|
58
|
+
/** Starts loopback discovery. Calling it repeatedly is idempotent. */
|
|
59
|
+
start(): void;
|
|
60
|
+
/** Stops discovery and closes the browser event stream. */
|
|
61
|
+
stop(): void;
|
|
62
|
+
private restoreOrDiscover;
|
|
63
|
+
/** Runs an immediate authenticated restore or companion discovery probe. */
|
|
64
|
+
checkConnection(): Promise<void>;
|
|
65
|
+
/** Triggers a new discovery probe after a connection loss. */
|
|
66
|
+
reconnect(): void;
|
|
67
|
+
/** Pairs the browser with a reachable companion, including an idle agent. */
|
|
68
|
+
connect(): Promise<boolean>;
|
|
69
|
+
private openEvents;
|
|
70
|
+
/**
|
|
71
|
+
* Dispatches one immutable prompt revision. The request enters `working`
|
|
72
|
+
* synchronously, before the transport promise resolves, so the UI cannot
|
|
73
|
+
* issue a second prompt while the first one is in flight.
|
|
74
|
+
*/
|
|
75
|
+
dispatchPrompt(prompt: string, changeRevision?: number): Promise<PromptDispatchResponse | null>;
|
|
76
|
+
/** Interrupts local request state and asks the companion to revoke pairing. */
|
|
77
|
+
disconnect(reason?: string): void;
|
|
78
|
+
private discover;
|
|
79
|
+
private scheduleDiscovery;
|
|
80
|
+
private scheduleReconnect;
|
|
81
|
+
private handleEvent;
|
|
82
|
+
private acknowledgeCanvasCommand;
|
|
83
|
+
private applyStatus;
|
|
84
|
+
private resetForDiscovery;
|
|
85
|
+
private applyRequestStatus;
|
|
86
|
+
private handleDisconnect;
|
|
87
|
+
private makeSnapshot;
|
|
88
|
+
private deriveState;
|
|
89
|
+
private publish;
|
|
90
|
+
}
|
|
91
|
+
/** Sets a host/test transport for subsequently created project clients. */
|
|
92
|
+
export declare function configureAgentBridgeTransport(transport: AgentBridgeTransport | undefined): void;
|
|
93
|
+
/** Clears cached clients and their active streams. */
|
|
94
|
+
export declare function resetAgentClients(): void;
|
|
95
|
+
export declare function createAgentClient(options: AgentClientOptions): AgentClient;
|
|
96
|
+
export declare function getAgentClient(projectId: string, options?: Omit<AgentClientOptions, "projectId">): AgentClient;
|
|
97
|
+
/** React hook used by the inspector handoff control. */
|
|
98
|
+
export declare function useAgentClient(projectId: string, suppliedClient?: AgentClient): AgentClientSnapshot;
|