Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions packages/agentic-components/storybook/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ src/storybook.requires.js
# Metro bundle output
*.jsbundle

# Generated native project + build output (react-native-test-app regenerates these).
# Generated native projects + build output (react-native-test-app regenerates these).
# The hand-written macos/Podfile is kept under version control.
macos/Pods/
macos/build/
Expand All @@ -14,6 +14,21 @@ macos/Podfile.lock
macos/.xcode.env
macos/*.xcodeproj/
macos/*.xcworkspace/
windows/.vs/
windows/ARM64/
windows/AppPackages/
windows/Debug/
windows/Release/
windows/build/
windows/ReactApp.Package/
windows/x64/
windows/x86/
windows/packages/
windows/*.binlog
windows/*.err
windows/*.hprof
windows/*.sln
windows/*.wrn
windows/ExperimentalFeatures.props
windows/NuGet.Config
dist/


46 changes: 43 additions & 3 deletions packages/agentic-components/storybook/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Agentic Components Storybook (react-native-macos)
# Agentic Components Storybook

On-device [Storybook](https://storybook.js.org/) app (Storybook for React Native v10) for
`@fluentui-react-native/agentic-components`. It loads every `*.stories.(ts|tsx)` file from the
Expand Down Expand Up @@ -62,12 +62,52 @@ Requires Xcode + CocoaPods.
> therefore not installed; `metro.config.js` aliases the import to a JS-only stub in
> `.storybook-mocks/`, so no native module is needed.

## Running on Windows

The Windows app also uses `react-native-test-app`. Its generated Win32 project uses React Native
Windows' New Architecture and Fabric renderer.

```powershell
# from this directory
# 1. Generate the Fabric Windows solution
yarn windows:generate

# 2. Start Metro (also generates storybook.requires)
yarn start

# 3. In another terminal, build and launch the Windows app
yarn windows
```

Requires Visual Studio 2022 with the React Native Windows build prerequisites. The generated
solution, `ExperimentalFeatures.props`, and build outputs are git-ignored and can be regenerated
with `yarn windows:generate`.

The Debug app always loads from Metro; `react-native-test-app` does not automatically fall back
to an embedded bundle in Debug builds. To bundle, build, and launch a Release app that runs
without Metro:

```powershell
yarn windows:offline
```

The Release package embeds `dist/index.windows.bundle`. Storybook's optional color-picker image
is intentionally not packaged because the Yarn pnpm asset path exceeds Windows' deployment path
limit; controls and stories otherwise run from the embedded bundle. The command replaces this
app's current Debug registration with its Release layout; running `yarn windows` later deploys
the Debug app again.

Storybook's development bundle intentionally contains separate `pretty-format` and `react-is`
versions used by its internal tooling. They are excluded from the duplicate-module enforcement;
React, React Native, and application dependencies remain checked.

## Bundling (no native toolchain required)

You can produce the JS bundle without Xcode. This also generates `storybook.requires` first:

```sh
yarn bundle:macos # -> writes index.macos.jsbundle
yarn bundle:macos # -> writes dist/index.macos.jsbundle
yarn bundle:windows # -> writes dist/index.windows.bundle
```

## Agent interaction (WebSocket channel + MCP)
Expand All @@ -79,7 +119,7 @@ The running app can be driven by external agents through a standalone Storybook
yarn storybook-server # WebSocket: ws://127.0.0.1:7007/ MCP: http://127.0.0.1:7007/mcp
```

Run it alongside `yarn start` + `yarn macos`. The on-device app connects to it automatically
Run it alongside `yarn start` + `yarn macos` or `yarn windows`. The on-device app connects to it automatically
(`.rnstorybook/index.tsx` calls `getStorybookUI({ enableWebsockets: true, host, port })`).

- **WebSocket channel** (`ws://127.0.0.1:7007/`): agents connect and emit Storybook channel events
Expand Down
3 changes: 2 additions & 1 deletion packages/agentic-components/storybook/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
}
],
"resources": {
"macos": ["dist/assets", "dist/index.macos.jsbundle"]
"macos": ["dist/assets", "dist/index.macos.jsbundle"],
"windows": ["dist/index.windows.bundle"]
}
}
19 changes: 18 additions & 1 deletion packages/agentic-components/storybook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@fluentui-react-native/agentic-components-storybook",
"version": "0.1.0",
"private": true,
"description": "On-device Storybook (react-native-macos) app for @fluentui-react-native/agentic-components",
"description": "On-device Storybook app for @fluentui-react-native/agentic-components",
"license": "MIT",
"author": "",
"repository": {
Expand All @@ -13,7 +13,11 @@
"scripts": {
"start": "rnx-cli start",
"macos": "rnx-cli run --platform macos",
"windows": "react-native run-windows --arch x64 --sln windows/AgenticStorybook.sln",
"windows:offline": "yarn bundle:windows && yarn windows:generate && yarn windows --release --no-packager --no-deploy --no-launch --msbuildprops UseBundle=false && pwsh -NoProfile -File scripts/run-windows-offline.ps1",
"windows:generate": "install-windows-test-app --use-fabric",
"bundle:macos": "yarn prebuild && rnx-cli bundle --dev false --platform macos",
"bundle:windows": "yarn prebuild && rnx-cli bundle --dev false --platform windows",
"prebuild": "sb-rn-get-stories --config-path src",
"storybook-server": "node storybook-server.cjs",
"lint": "fluentui-scripts lint",
Expand All @@ -35,6 +39,7 @@
"@react-native-community/cli-platform-ios": "^20.0.0",
"@react-native-community/datetimepicker": "^9.1.0",
"@react-native-community/slider": "^5.0.0",
"@react-native-windows/cli": "^0.81.0",
"@react-native/babel-preset": "^0.81.0",
"@react-native/metro-babel-transformer": "^0.81.0",
"@react-native/metro-config": "^0.81.0",
Expand Down Expand Up @@ -74,6 +79,18 @@
"macos",
"windows"
],
"plugins": [
[
"@rnx-kit/metro-plugin-duplicates-checker",
{
"throwOnError": true,
"ignoredModules": [
"pretty-format",
"react-is"
]
}
]
],
"platforms": {
"macos": {
"bundleOutput": "dist/index.macos.jsbundle",
Expand Down
18 changes: 18 additions & 0 deletions packages/agentic-components/storybook/react-native.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,30 @@ const project = (() => {
macos: {
sourceDir: 'macos',
},
windows: {
sourceDir: 'windows',
solutionFile: 'windows/AgenticStorybook.sln',
},
});
} catch (_) {
return undefined;
}
})();

module.exports = {
dependencies: {
// These optional Storybook control dependencies only provide legacy UWP projects. Linking
// them into the WinUI 3 Fabric app fails, while liteMode does not require their native views.
'@react-native-community/datetimepicker': {
platforms: {
windows: null,
},
},
'@react-native-community/slider': {
platforms: {
windows: null,
},
},
},
...(project ? { project } : undefined),
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
param(
[switch]$NoLaunch
)

$ErrorActionPreference = 'Stop'

$packageRoot = Split-Path -Parent $PSScriptRoot
$manifestPath = Join-Path $packageRoot 'windows\ReactApp.Package\bin\x64\Release\AppxManifest.xml'

if (-not (Test-Path -LiteralPath $manifestPath)) {
throw "Release manifest not found at '$manifestPath'. Build the Windows Release app first."
}

[xml]$manifest = Get-Content -LiteralPath $manifestPath
$identityName = [string]$manifest.Package.Identity.Name
$appId = [string]$manifest.Package.Applications.Application.Id

$installedPackage = Get-AppxPackage -Name $identityName
if ($installedPackage) {
Remove-AppxPackage -Package $installedPackage.PackageFullName
}

Add-AppxPackage -Register $manifestPath

if (-not $NoLaunch) {
$registeredPackage = Get-AppxPackage -Name $identityName
$target = "shell:AppsFolder\$($registeredPackage.PackageFamilyName)!$appId"
Start-Process explorer.exe $target
}
1 change: 1 addition & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2598,6 +2598,7 @@ __metadata:
"@react-native-community/cli-platform-ios": "npm:^20.0.0"
"@react-native-community/datetimepicker": "npm:^9.1.0"
"@react-native-community/slider": "npm:^5.0.0"
"@react-native-windows/cli": "npm:^0.81.0"
"@react-native/babel-preset": "npm:^0.81.0"
"@react-native/metro-babel-transformer": "npm:^0.81.0"
"@react-native/metro-config": "npm:^0.81.0"
Expand Down
Loading