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,19 @@
|
|
|
1
|
+
export { isExcludedDirectoryName, isSensitiveProjectPath } from "./pathPolicy.js";
|
|
2
|
+
export type ProjectFileChangeKind = "add" | "change" | "remove";
|
|
3
|
+
export interface ProjectFileChange {
|
|
4
|
+
readonly absolutePath: string;
|
|
5
|
+
readonly kind: ProjectFileChangeKind;
|
|
6
|
+
}
|
|
7
|
+
export interface ProjectFileWatcherOptions {
|
|
8
|
+
readonly rootDirectory: string;
|
|
9
|
+
readonly debounceMs?: number;
|
|
10
|
+
readonly onSettled: (changes: readonly ProjectFileChange[]) => void | Promise<void>;
|
|
11
|
+
readonly onError?: (error: unknown) => void;
|
|
12
|
+
}
|
|
13
|
+
export interface ProjectFileWatcher {
|
|
14
|
+
/** Starts watching and resolves after the initial directory walk is ready. */
|
|
15
|
+
start(): Promise<void>;
|
|
16
|
+
close(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
/** Creates a watcher that starts and stops explicitly with the server. */
|
|
19
|
+
export declare function createProjectFileWatcher(options: ProjectFileWatcherOptions): ProjectFileWatcher;
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node's recursive `fs.watch` is not available on every supported platform, so
|
|
3
|
+
* this watches each directory and adds watches for ones created later. The
|
|
4
|
+
* public surface is lifecycle and settled batches; debounce and symlink
|
|
5
|
+
* confinement stay internal.
|
|
6
|
+
*/
|
|
7
|
+
import { watch } from "node:fs";
|
|
8
|
+
import { readdir } from "node:fs/promises";
|
|
9
|
+
import { realpathSync, statSync } from "node:fs";
|
|
10
|
+
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
11
|
+
import { isExcludedDirectoryName, isSensitiveProjectPath } from "./pathPolicy.js";
|
|
12
|
+
export { isExcludedDirectoryName, isSensitiveProjectPath } from "./pathPolicy.js";
|
|
13
|
+
/** Creates a watcher that starts and stops explicitly with the server. */
|
|
14
|
+
export function createProjectFileWatcher(options) {
|
|
15
|
+
const rootDirectory = realpathSync(resolve(options.rootDirectory));
|
|
16
|
+
const debounceMs = Math.max(0, options.debounceMs ?? 60);
|
|
17
|
+
const watches = new Map();
|
|
18
|
+
const pending = new Map();
|
|
19
|
+
let timer = null;
|
|
20
|
+
let scanQueue = Promise.resolve();
|
|
21
|
+
let pendingScans = 0;
|
|
22
|
+
let readyPromise = null;
|
|
23
|
+
let resolveReady = null;
|
|
24
|
+
let closed = false;
|
|
25
|
+
const reportError = (error) => {
|
|
26
|
+
options.onError?.(error);
|
|
27
|
+
};
|
|
28
|
+
const schedule = (absolutePath, wasRenamed = false) => {
|
|
29
|
+
if (closed || !isProjectPath(rootDirectory, absolutePath))
|
|
30
|
+
return;
|
|
31
|
+
const kind = classifyChange(absolutePath, wasRenamed);
|
|
32
|
+
const existing = pending.get(absolutePath);
|
|
33
|
+
pending.set(absolutePath, mergeChangeKind(existing, kind));
|
|
34
|
+
if (timer)
|
|
35
|
+
clearTimeout(timer);
|
|
36
|
+
timer = setTimeout(flush, debounceMs);
|
|
37
|
+
};
|
|
38
|
+
const flush = () => {
|
|
39
|
+
timer = null;
|
|
40
|
+
if (closed || pending.size === 0)
|
|
41
|
+
return;
|
|
42
|
+
const changes = [...pending.entries()]
|
|
43
|
+
.sort(([a], [b]) => comparePosixStrings(a, b))
|
|
44
|
+
.map(([absolutePath, kind]) => ({ absolutePath, kind }));
|
|
45
|
+
pending.clear();
|
|
46
|
+
void Promise.resolve(options.onSettled(changes)).catch(reportError);
|
|
47
|
+
};
|
|
48
|
+
const closeDirectory = (directory) => {
|
|
49
|
+
const entry = watches.get(directory);
|
|
50
|
+
if (!entry)
|
|
51
|
+
return;
|
|
52
|
+
watches.delete(directory);
|
|
53
|
+
entry.watcher.close();
|
|
54
|
+
};
|
|
55
|
+
const closeDescendants = (directory) => {
|
|
56
|
+
for (const watchedDirectory of [...watches.keys()]) {
|
|
57
|
+
if (watchedDirectory === directory || watchedDirectory.startsWith(`${directory}${sep}`)) {
|
|
58
|
+
closeDirectory(watchedDirectory);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const watchDirectory = (directory) => {
|
|
63
|
+
if (closed || !isProjectDirectory(rootDirectory, directory))
|
|
64
|
+
return;
|
|
65
|
+
const canonicalDirectory = canonicalProjectPath(rootDirectory, directory);
|
|
66
|
+
if (!canonicalDirectory || [...watches.values()].some((entry) => entry.canonicalDirectory === canonicalDirectory))
|
|
67
|
+
return;
|
|
68
|
+
let directoryWatcher;
|
|
69
|
+
try {
|
|
70
|
+
directoryWatcher = watch(directory, { persistent: true }, (eventType, filename) => {
|
|
71
|
+
const changedName = filename?.toString();
|
|
72
|
+
const changedPath = changedName ? join(directory, changedName) : directory;
|
|
73
|
+
if (!isProjectPath(rootDirectory, changedPath))
|
|
74
|
+
return;
|
|
75
|
+
if (isProjectDirectory(rootDirectory, changedPath))
|
|
76
|
+
watchDirectory(changedPath);
|
|
77
|
+
else if (!exists(changedPath))
|
|
78
|
+
closeDescendants(changedPath);
|
|
79
|
+
schedule(changedPath, eventType === "rename");
|
|
80
|
+
});
|
|
81
|
+
directoryWatcher.on("error", reportError);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
reportError(error);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
watches.set(directory, { directory, canonicalDirectory, watcher: directoryWatcher });
|
|
88
|
+
// Watch before scanning so events during the async walk are not missed. Scans
|
|
89
|
+
// run serially and re-check `closed` after every await, so none leak past close().
|
|
90
|
+
pendingScans += 1;
|
|
91
|
+
scanQueue = scanQueue
|
|
92
|
+
.then(() => scanSubdirectories(directory))
|
|
93
|
+
.catch(reportError)
|
|
94
|
+
.finally(() => {
|
|
95
|
+
pendingScans -= 1;
|
|
96
|
+
if (pendingScans === 0)
|
|
97
|
+
resolveReady?.();
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
const scanSubdirectories = async (directory) => {
|
|
101
|
+
let entries;
|
|
102
|
+
try {
|
|
103
|
+
entries = await readdir(directory, { withFileTypes: true });
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
entries.sort((a, b) => comparePosixStrings(a.name, b.name));
|
|
109
|
+
for (const entry of entries) {
|
|
110
|
+
if (closed)
|
|
111
|
+
return;
|
|
112
|
+
if (!entry.isDirectory() || isExcludedDirectoryName(entry.name))
|
|
113
|
+
continue;
|
|
114
|
+
const child = join(directory, entry.name);
|
|
115
|
+
if (!isProjectPath(rootDirectory, child))
|
|
116
|
+
continue;
|
|
117
|
+
watchDirectory(child);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
return {
|
|
121
|
+
start: () => {
|
|
122
|
+
if (readyPromise)
|
|
123
|
+
return readyPromise;
|
|
124
|
+
if (closed)
|
|
125
|
+
return Promise.resolve();
|
|
126
|
+
readyPromise = new Promise((resolveReadyPromise) => {
|
|
127
|
+
resolveReady = resolveReadyPromise;
|
|
128
|
+
});
|
|
129
|
+
watchDirectory(rootDirectory);
|
|
130
|
+
if (pendingScans === 0)
|
|
131
|
+
resolveReady?.();
|
|
132
|
+
return readyPromise;
|
|
133
|
+
},
|
|
134
|
+
close: async () => {
|
|
135
|
+
if (closed)
|
|
136
|
+
return;
|
|
137
|
+
closed = true;
|
|
138
|
+
if (timer) {
|
|
139
|
+
clearTimeout(timer);
|
|
140
|
+
timer = null;
|
|
141
|
+
}
|
|
142
|
+
pending.clear();
|
|
143
|
+
for (const directory of [...watches.keys()])
|
|
144
|
+
closeDirectory(directory);
|
|
145
|
+
// Waiting on the serial queue keeps close() deterministic.
|
|
146
|
+
await scanQueue;
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function mergeChangeKind(previous, next) {
|
|
151
|
+
if (!previous)
|
|
152
|
+
return next;
|
|
153
|
+
if (next === "remove")
|
|
154
|
+
return "remove";
|
|
155
|
+
if (next === "add")
|
|
156
|
+
return previous === "remove" ? "add" : previous;
|
|
157
|
+
if (previous === "remove")
|
|
158
|
+
return "change";
|
|
159
|
+
return "change";
|
|
160
|
+
}
|
|
161
|
+
function classifyChange(absolutePath, wasRenamed) {
|
|
162
|
+
if (!exists(absolutePath))
|
|
163
|
+
return "remove";
|
|
164
|
+
return wasRenamed ? "add" : "change";
|
|
165
|
+
}
|
|
166
|
+
function exists(path) {
|
|
167
|
+
try {
|
|
168
|
+
return statSync(path).isFile() || statSync(path).isDirectory();
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function isProjectDirectory(rootDirectory, path) {
|
|
175
|
+
if (!isProjectPath(rootDirectory, path) || isExcludedDirectory(rootDirectory, path))
|
|
176
|
+
return false;
|
|
177
|
+
try {
|
|
178
|
+
return statSync(path).isDirectory();
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function isProjectPath(rootDirectory, path) {
|
|
185
|
+
if (!isWithin(rootDirectory, resolve(path)) || isExcludedDirectory(rootDirectory, path))
|
|
186
|
+
return false;
|
|
187
|
+
return canonicalProjectPath(rootDirectory, path) !== null;
|
|
188
|
+
}
|
|
189
|
+
function canonicalProjectPath(rootDirectory, path) {
|
|
190
|
+
try {
|
|
191
|
+
const canonical = realpathSync(path);
|
|
192
|
+
return isWithin(rootDirectory, canonical)
|
|
193
|
+
&& !isSensitiveProjectPath(relative(rootDirectory, canonical).split(sep).join("/"))
|
|
194
|
+
? canonical
|
|
195
|
+
: null;
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
const parent = dirname(path);
|
|
199
|
+
if (parent === path)
|
|
200
|
+
return null;
|
|
201
|
+
try {
|
|
202
|
+
const canonicalParent = realpathSync(parent);
|
|
203
|
+
return isWithin(rootDirectory, canonicalParent)
|
|
204
|
+
&& !isSensitiveProjectPath(relative(rootDirectory, canonicalParent).split(sep).join("/"))
|
|
205
|
+
? canonicalParent
|
|
206
|
+
: null;
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function isExcludedDirectory(rootDirectory, path) {
|
|
214
|
+
return relative(rootDirectory, resolve(path)).split(sep).some((segment) => isExcludedDirectoryName(segment));
|
|
215
|
+
}
|
|
216
|
+
function isWithin(rootDirectory, candidate) {
|
|
217
|
+
const pathFromRoot = relative(rootDirectory, candidate);
|
|
218
|
+
return pathFromRoot === ""
|
|
219
|
+
|| (!pathFromRoot.startsWith(`..${sep}`)
|
|
220
|
+
&& pathFromRoot !== ".."
|
|
221
|
+
&& !isAbsolute(pathFromRoot));
|
|
222
|
+
}
|
|
223
|
+
/** Compares UTF-8 path bytes so ordering does not depend on the host locale. */
|
|
224
|
+
function comparePosixStrings(a, b) {
|
|
225
|
+
return Buffer.from(a, "utf8").compare(Buffer.from(b, "utf8"));
|
|
226
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Names a project deterministically across restarts. The root is canonicalized
|
|
3
|
+
* first, so a symlinked working directory resolves to the same project — and
|
|
4
|
+
* therefore the same durable session — as its real path.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createProjectId(host: string, root: string): string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { realpathSync } from "node:fs";
|
|
3
|
+
const PROJECT_DIGEST_LENGTH = 24;
|
|
4
|
+
/**
|
|
5
|
+
* Names a project deterministically across restarts. The root is canonicalized
|
|
6
|
+
* first, so a symlinked working directory resolves to the same project — and
|
|
7
|
+
* therefore the same durable session — as its real path.
|
|
8
|
+
*/
|
|
9
|
+
export function createProjectId(host, root) {
|
|
10
|
+
let canonical = root;
|
|
11
|
+
try {
|
|
12
|
+
canonical = realpathSync(root);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
/* an unresolvable root keeps its textual form */
|
|
16
|
+
}
|
|
17
|
+
const digest = createHash("sha256").update(canonical).digest("hex").slice(0, PROJECT_DIGEST_LENGTH);
|
|
18
|
+
return `${host}:${digest}`;
|
|
19
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dot-prefixed segments commonly hold credentials, source-control metadata, or
|
|
3
|
+
* local tool state. Treating the whole segment as sensitive keeps one policy
|
|
4
|
+
* across direct requests, symlink targets, token discovery, and file watching.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isSensitiveProjectPath(projectPath: string): boolean;
|
|
7
|
+
/** Returns whether a directory name is outside the standalone project view. */
|
|
8
|
+
export declare function isExcludedDirectoryName(name: string): boolean;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dot-prefixed segments commonly hold credentials, source-control metadata, or
|
|
3
|
+
* local tool state. Treating the whole segment as sensitive keeps one policy
|
|
4
|
+
* across direct requests, symlink targets, token discovery, and file watching.
|
|
5
|
+
*/
|
|
6
|
+
export function isSensitiveProjectPath(projectPath) {
|
|
7
|
+
return projectPath.split(/[\\/]/).some((segment) => segment.startsWith("."));
|
|
8
|
+
}
|
|
9
|
+
/** Returns whether a directory name is outside the standalone project view. */
|
|
10
|
+
export function isExcludedDirectoryName(name) {
|
|
11
|
+
return name.startsWith(".") || name === "build" || name === "dist" || name === "node_modules";
|
|
12
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { TokenCatalogDiagnostic, TokenDefinition, TokenEntry } from "../css/model/index.js";
|
|
2
|
+
/** The serializable token knowledge published by the standalone manifest. */
|
|
3
|
+
export interface ProjectTokenSnapshot {
|
|
4
|
+
readonly tokenCatalog: readonly TokenDefinition[];
|
|
5
|
+
readonly tokens: readonly TokenEntry[];
|
|
6
|
+
readonly tokenDiagnostics: readonly TokenCatalogDiagnostic[];
|
|
7
|
+
readonly tokenGeneration: string;
|
|
8
|
+
}
|
|
9
|
+
/** The placeholder used before and in place of a successful project scan. */
|
|
10
|
+
export declare const EMPTY_PROJECT_TOKEN_SNAPSHOT: ProjectTokenSnapshot;
|
|
11
|
+
/** A CSS file discovered below the project root before inventory parsing. */
|
|
12
|
+
export interface ProjectCssArtifact {
|
|
13
|
+
readonly absolutePath: string;
|
|
14
|
+
readonly projectPath: string;
|
|
15
|
+
readonly content?: string;
|
|
16
|
+
readonly readError?: string;
|
|
17
|
+
}
|
|
18
|
+
/** Injectable so unreadable-file handling stays testable. */
|
|
19
|
+
export type ProjectCssFileReader = (absolutePath: string) => string | Promise<string>;
|
|
20
|
+
/** Options for the deterministic project CSS scan. */
|
|
21
|
+
export interface ProjectTokenSnapshotOptions {
|
|
22
|
+
readonly rootDirectory: string;
|
|
23
|
+
/** Additional authored roots to include in the same deterministic inventory. */
|
|
24
|
+
readonly additionalRootDirectories?: readonly string[];
|
|
25
|
+
readonly readFile?: ProjectCssFileReader;
|
|
26
|
+
/** Prefixed to the digest so two hosts scanning one project publish distinct generations. */
|
|
27
|
+
readonly generationLabel: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Files are sorted by project-relative POSIX path before receiving
|
|
31
|
+
* discoveryOrder. Symlinks are followed only when their canonical target stays
|
|
32
|
+
* below rootDirectory. Read and parse failures become diagnostics, never rejections.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createProjectTokenSnapshot(options: ProjectTokenSnapshotOptions): Promise<ProjectTokenSnapshot>;
|
|
35
|
+
/** Exported as a seam so provenance and symlink confinement are testable without PostCSS. */
|
|
36
|
+
export declare function discoverProjectCssArtifacts(rootDirectory: string, readFile?: ProjectCssFileReader): Promise<readonly ProjectCssArtifact[]>;
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node-only CSS token discovery for the static HTML host. Reports directory
|
|
3
|
+
* order as discovery evidence only: a directory walk cannot prove the order in
|
|
4
|
+
* which a browser applies stylesheets. Every filesystem operation is async so a
|
|
5
|
+
* large tree never blocks the server's event loop.
|
|
6
|
+
*/
|
|
7
|
+
import { createHash } from "node:crypto";
|
|
8
|
+
import { readFile as readUtf8File, readdir, realpath, stat, } from "node:fs/promises";
|
|
9
|
+
import { extname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
10
|
+
import { createTokenInventory, } from "../css/token-inventory/index.js";
|
|
11
|
+
import { isExcludedDirectoryName, isSensitiveProjectPath } from "./pathPolicy.js";
|
|
12
|
+
/** The placeholder used before and in place of a successful project scan. */
|
|
13
|
+
export const EMPTY_PROJECT_TOKEN_SNAPSHOT = {
|
|
14
|
+
tokenCatalog: [],
|
|
15
|
+
tokens: [],
|
|
16
|
+
tokenDiagnostics: [],
|
|
17
|
+
tokenGeneration: "empty",
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Files are sorted by project-relative POSIX path before receiving
|
|
21
|
+
* discoveryOrder. Symlinks are followed only when their canonical target stays
|
|
22
|
+
* below rootDirectory. Read and parse failures become diagnostics, never rejections.
|
|
23
|
+
*/
|
|
24
|
+
export async function createProjectTokenSnapshot(options) {
|
|
25
|
+
const rootDirectory = await canonicalRoot(options.rootDirectory);
|
|
26
|
+
const additionalRoots = (await Promise.all((options.additionalRootDirectories ?? []).map((directory) => canonicalOptionalRoot(directory)))).filter((root) => root !== null);
|
|
27
|
+
const scanRoots = [rootDirectory, ...additionalRoots.filter((root) => root !== rootDirectory)];
|
|
28
|
+
const discovered = await Promise.all(scanRoots.map((root) => discoverProjectCssArtifacts(root, options.readFile)));
|
|
29
|
+
const artifacts = [];
|
|
30
|
+
const seenFiles = new Set();
|
|
31
|
+
for (let index = 0; index < discovered.length; index += 1) {
|
|
32
|
+
for (const artifact of discovered[index] ?? []) {
|
|
33
|
+
const canonicalPath = await realpath(artifact.absolutePath).catch(() => artifact.absolutePath);
|
|
34
|
+
if (seenFiles.has(canonicalPath))
|
|
35
|
+
continue;
|
|
36
|
+
seenFiles.add(canonicalPath);
|
|
37
|
+
// Additional roots are expressed relative to the primary one so a single
|
|
38
|
+
// inventory can merge their declarations without losing provenance.
|
|
39
|
+
artifacts.push({
|
|
40
|
+
...artifact,
|
|
41
|
+
projectPath: index === 0
|
|
42
|
+
? artifact.projectPath
|
|
43
|
+
: relative(rootDirectory, artifact.absolutePath).split(sep).join("/"),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
artifacts.sort((a, b) => comparePosixStrings(a.projectPath, b.projectPath));
|
|
48
|
+
const inventory = createTokenInventory();
|
|
49
|
+
for (const [discoveryOrder, artifact] of artifacts.entries()) {
|
|
50
|
+
const inventoryArtifact = {
|
|
51
|
+
buildTool: "static-html",
|
|
52
|
+
id: artifact.projectPath,
|
|
53
|
+
stage: "authored",
|
|
54
|
+
provenance: "project",
|
|
55
|
+
discoveryOrder,
|
|
56
|
+
...(artifact.content !== undefined ? { content: artifact.content } : {}),
|
|
57
|
+
...(artifact.readError ? {
|
|
58
|
+
diagnostics: [{
|
|
59
|
+
code: "stylesheet-unreadable",
|
|
60
|
+
message: `Stylesheet "${artifact.projectPath}" could not be read: ${artifact.readError}`,
|
|
61
|
+
module: artifact.projectPath,
|
|
62
|
+
}],
|
|
63
|
+
} : {}),
|
|
64
|
+
};
|
|
65
|
+
inventory.apply(inventoryArtifact);
|
|
66
|
+
}
|
|
67
|
+
const snapshot = inventory.snapshot();
|
|
68
|
+
const tokenGeneration = artifacts.length === 0
|
|
69
|
+
? "empty"
|
|
70
|
+
: deterministicGeneration(artifacts, snapshot.generation, options.generationLabel);
|
|
71
|
+
return {
|
|
72
|
+
tokenCatalog: snapshot.definitions.map((definition) => ({
|
|
73
|
+
...definition,
|
|
74
|
+
declarations: definition.declarations.map((declaration) => ({
|
|
75
|
+
id: declaration.id,
|
|
76
|
+
order: declaration.order,
|
|
77
|
+
value: declaration.value,
|
|
78
|
+
source: declaration.source,
|
|
79
|
+
important: declaration.important,
|
|
80
|
+
context: declaration.context,
|
|
81
|
+
})),
|
|
82
|
+
})),
|
|
83
|
+
tokens: snapshot.tokens,
|
|
84
|
+
tokenDiagnostics: snapshot.diagnostics.map(mapDiagnostic),
|
|
85
|
+
tokenGeneration,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/** Exported as a seam so provenance and symlink confinement are testable without PostCSS. */
|
|
89
|
+
export async function discoverProjectCssArtifacts(rootDirectory, readFile = (absolutePath) => readUtf8File(absolutePath, "utf8")) {
|
|
90
|
+
const root = await canonicalRoot(rootDirectory);
|
|
91
|
+
const artifacts = [];
|
|
92
|
+
const visitedDirectories = new Set();
|
|
93
|
+
const visitedFiles = new Set();
|
|
94
|
+
await walkDirectory(root, root, visitedDirectories, visitedFiles, artifacts, readFile);
|
|
95
|
+
artifacts.sort((a, b) => comparePosixStrings(a.projectPath, b.projectPath));
|
|
96
|
+
return artifacts;
|
|
97
|
+
}
|
|
98
|
+
async function walkDirectory(rootDirectory, directory, visitedDirectories, visitedFiles, artifacts, readFile) {
|
|
99
|
+
const canonicalDirectoryPath = await canonicalWithinRoot(rootDirectory, directory);
|
|
100
|
+
if (!canonicalDirectoryPath || visitedDirectories.has(canonicalDirectoryPath))
|
|
101
|
+
return;
|
|
102
|
+
const projectDirectoryPath = relative(rootDirectory, directory).split(sep).join("/");
|
|
103
|
+
const canonicalProjectDirectoryPath = relative(rootDirectory, canonicalDirectoryPath)
|
|
104
|
+
.split(sep)
|
|
105
|
+
.join("/");
|
|
106
|
+
if (isSensitiveProjectPath(projectDirectoryPath)
|
|
107
|
+
|| isSensitiveProjectPath(canonicalProjectDirectoryPath))
|
|
108
|
+
return;
|
|
109
|
+
visitedDirectories.add(canonicalDirectoryPath);
|
|
110
|
+
let entries;
|
|
111
|
+
try {
|
|
112
|
+
entries = await readdir(directory, { withFileTypes: true });
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
entries.sort((a, b) => comparePosixStrings(a.name, b.name));
|
|
118
|
+
for (const entry of entries) {
|
|
119
|
+
if (entry.isDirectory() && isExcludedDirectoryName(entry.name))
|
|
120
|
+
continue;
|
|
121
|
+
const absolutePath = join(directory, entry.name);
|
|
122
|
+
const canonicalPath = await canonicalWithinRoot(rootDirectory, absolutePath);
|
|
123
|
+
if (!canonicalPath)
|
|
124
|
+
continue;
|
|
125
|
+
let stats;
|
|
126
|
+
try {
|
|
127
|
+
stats = await stat(absolutePath);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (stats.isDirectory()) {
|
|
133
|
+
if (isExcludedDirectoryName(entry.name))
|
|
134
|
+
continue;
|
|
135
|
+
await walkDirectory(rootDirectory, absolutePath, visitedDirectories, visitedFiles, artifacts, readFile);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (!stats.isFile() || extname(entry.name).toLowerCase() !== ".css")
|
|
139
|
+
continue;
|
|
140
|
+
if (visitedFiles.has(canonicalPath))
|
|
141
|
+
continue;
|
|
142
|
+
visitedFiles.add(canonicalPath);
|
|
143
|
+
const projectPath = relative(rootDirectory, absolutePath).split(sep).join("/");
|
|
144
|
+
const canonicalProjectPath = relative(rootDirectory, canonicalPath).split(sep).join("/");
|
|
145
|
+
if (isSensitiveProjectPath(projectPath) || isSensitiveProjectPath(canonicalProjectPath)) {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
const content = await readFile(absolutePath);
|
|
150
|
+
artifacts.push({ absolutePath, projectPath, content });
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
artifacts.push({
|
|
154
|
+
absolutePath,
|
|
155
|
+
projectPath,
|
|
156
|
+
readError: readErrorMessage(error),
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
async function canonicalRoot(rootDirectory) {
|
|
162
|
+
const root = await realpath(resolve(rootDirectory));
|
|
163
|
+
if (!(await stat(root)).isDirectory()) {
|
|
164
|
+
throw new Error(`Standalone root is not a directory: ${rootDirectory}`);
|
|
165
|
+
}
|
|
166
|
+
return root;
|
|
167
|
+
}
|
|
168
|
+
async function canonicalOptionalRoot(rootDirectory) {
|
|
169
|
+
try {
|
|
170
|
+
return await canonicalRoot(rootDirectory);
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
async function canonicalWithinRoot(rootDirectory, candidate) {
|
|
177
|
+
try {
|
|
178
|
+
const canonical = await realpath(candidate);
|
|
179
|
+
const pathFromRoot = relative(rootDirectory, canonical);
|
|
180
|
+
if (pathFromRoot === ""
|
|
181
|
+
|| (!pathFromRoot.startsWith(`..${sep}`)
|
|
182
|
+
&& pathFromRoot !== ".."
|
|
183
|
+
&& !isAbsolute(pathFromRoot))) {
|
|
184
|
+
return canonical;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// A disappearing file is absent from this scan; read failures are handled above.
|
|
189
|
+
}
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
function readErrorMessage(error) {
|
|
193
|
+
if (typeof error === "object" && error !== null && "code" in error) {
|
|
194
|
+
const code = error.code;
|
|
195
|
+
if (typeof code === "string")
|
|
196
|
+
return code;
|
|
197
|
+
}
|
|
198
|
+
return "read failed";
|
|
199
|
+
}
|
|
200
|
+
function mapDiagnostic(diagnostic) {
|
|
201
|
+
return {
|
|
202
|
+
code: diagnostic.code,
|
|
203
|
+
message: diagnostic.message,
|
|
204
|
+
module: diagnostic.module ?? diagnostic.artifact ?? "standalone-css",
|
|
205
|
+
...(diagnostic.exportName !== undefined ? { exportName: diagnostic.exportName } : {}),
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
function deterministicGeneration(artifacts, inventoryGeneration, label) {
|
|
209
|
+
const facts = artifacts.map((artifact) => JSON.stringify({
|
|
210
|
+
path: artifact.projectPath,
|
|
211
|
+
content: artifact.content,
|
|
212
|
+
readError: artifact.readError,
|
|
213
|
+
}));
|
|
214
|
+
const digest = createHash("sha256")
|
|
215
|
+
.update(`${facts.join("\n")}\n${inventoryGeneration}`)
|
|
216
|
+
.digest("hex")
|
|
217
|
+
.slice(0, 24);
|
|
218
|
+
return `${label}:${digest}`;
|
|
219
|
+
}
|
|
220
|
+
/** Compares UTF-8 path bytes so discovery is independent of the host locale. */
|
|
221
|
+
function comparePosixStrings(a, b) {
|
|
222
|
+
return Buffer.from(a, "utf8").compare(Buffer.from(b, "utf8"));
|
|
223
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The wire contract between any host and the browser client. Must stay
|
|
3
|
+
* browser-safe: the inspector's mount components import these routes directly.
|
|
4
|
+
* Anything needing Node belongs in `project/`.
|
|
5
|
+
*/
|
|
6
|
+
export * from "./routes.js";
|
|
7
|
+
/** Envelope version understood by the browser client. */
|
|
8
|
+
export declare const NUDGE_UI_MANIFEST_VERSION = 1;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The wire contract between any host and the browser client. Must stay
|
|
3
|
+
* browser-safe: the inspector's mount components import these routes directly.
|
|
4
|
+
* Anything needing Node belongs in `project/`.
|
|
5
|
+
*/
|
|
6
|
+
export * from "./routes.js";
|
|
7
|
+
/** Envelope version understood by the browser client. */
|
|
8
|
+
export const NUDGE_UI_MANIFEST_VERSION = 1;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The reserved URL namespace every host serves the inspector through. Hosts
|
|
3
|
+
* own their own middleware and reload policy, but the paths are one contract:
|
|
4
|
+
* the browser client is built once and requests the same URLs everywhere.
|
|
5
|
+
*/
|
|
6
|
+
/** A host must not serve project files here. */
|
|
7
|
+
export declare const NUDGE_UI_ROUTE_PREFIX = "/__nudge_ui__/";
|
|
8
|
+
export declare const NUDGE_UI_MANIFEST_PATH = "/__nudge_ui__/manifest";
|
|
9
|
+
export declare const NUDGE_UI_CLIENT_PATH = "/__nudge_ui__/client.mjs";
|
|
10
|
+
/** Server-sent events announcing settled project changes. */
|
|
11
|
+
export declare const NUDGE_UI_RELOAD_PATH = "/__nudge_ui__/reload";
|
|
12
|
+
export declare const NUDGE_UI_MOUNT_ID = "nudge-ui-root";
|
|
13
|
+
export declare function isReservedNudgeUiRoute(pathname: string): boolean;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The reserved URL namespace every host serves the inspector through. Hosts
|
|
3
|
+
* own their own middleware and reload policy, but the paths are one contract:
|
|
4
|
+
* the browser client is built once and requests the same URLs everywhere.
|
|
5
|
+
*/
|
|
6
|
+
/** A host must not serve project files here. */
|
|
7
|
+
export const NUDGE_UI_ROUTE_PREFIX = "/__nudge_ui__/";
|
|
8
|
+
export const NUDGE_UI_MANIFEST_PATH = `${NUDGE_UI_ROUTE_PREFIX}manifest`;
|
|
9
|
+
export const NUDGE_UI_CLIENT_PATH = `${NUDGE_UI_ROUTE_PREFIX}client.mjs`;
|
|
10
|
+
/** Server-sent events announcing settled project changes. */
|
|
11
|
+
export const NUDGE_UI_RELOAD_PATH = `${NUDGE_UI_ROUTE_PREFIX}reload`;
|
|
12
|
+
export const NUDGE_UI_MOUNT_ID = "nudge-ui-root";
|
|
13
|
+
export function isReservedNudgeUiRoute(pathname) {
|
|
14
|
+
return pathname === NUDGE_UI_ROUTE_PREFIX.slice(0, -1)
|
|
15
|
+
|| pathname.startsWith(NUDGE_UI_ROUTE_PREFIX);
|
|
16
|
+
}
|