@portel/photon 1.4.1 → 1.6.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 +326 -1177
- package/dist/auto-ui/beam.d.ts +14 -0
- package/dist/auto-ui/beam.d.ts.map +1 -0
- package/dist/auto-ui/beam.js +3057 -0
- package/dist/auto-ui/beam.js.map +1 -0
- package/dist/auto-ui/bridge/index.d.ts +37 -0
- package/dist/auto-ui/bridge/index.d.ts.map +1 -0
- package/dist/auto-ui/bridge/index.js +555 -0
- package/dist/auto-ui/bridge/index.js.map +1 -0
- package/dist/auto-ui/bridge/openai-shim.d.ts +20 -0
- package/dist/auto-ui/bridge/openai-shim.d.ts.map +1 -0
- package/dist/auto-ui/bridge/openai-shim.js +231 -0
- package/dist/auto-ui/bridge/openai-shim.js.map +1 -0
- package/dist/auto-ui/bridge/photon-app.d.ts +162 -0
- package/dist/auto-ui/bridge/photon-app.d.ts.map +1 -0
- package/dist/auto-ui/bridge/photon-app.js +460 -0
- package/dist/auto-ui/bridge/photon-app.js.map +1 -0
- package/dist/auto-ui/bridge/types.d.ts +128 -0
- package/dist/auto-ui/bridge/types.d.ts.map +1 -0
- package/dist/auto-ui/bridge/types.js +7 -0
- package/dist/auto-ui/bridge/types.js.map +1 -0
- package/dist/auto-ui/components/card.d.ts +13 -0
- package/dist/auto-ui/components/card.d.ts.map +1 -0
- package/dist/auto-ui/components/card.js +64 -0
- package/dist/auto-ui/components/card.js.map +1 -0
- package/dist/auto-ui/components/form.d.ts +15 -0
- package/dist/auto-ui/components/form.d.ts.map +1 -0
- package/dist/auto-ui/components/form.js +72 -0
- package/dist/auto-ui/components/form.js.map +1 -0
- package/dist/auto-ui/components/list.d.ts +13 -0
- package/dist/auto-ui/components/list.d.ts.map +1 -0
- package/dist/auto-ui/components/list.js +58 -0
- package/dist/auto-ui/components/list.js.map +1 -0
- package/dist/auto-ui/components/progress.d.ts +18 -0
- package/dist/auto-ui/components/progress.d.ts.map +1 -0
- package/dist/auto-ui/components/progress.js +125 -0
- package/dist/auto-ui/components/progress.js.map +1 -0
- package/dist/auto-ui/components/table.d.ts +13 -0
- package/dist/auto-ui/components/table.d.ts.map +1 -0
- package/dist/auto-ui/components/table.js +82 -0
- package/dist/auto-ui/components/table.js.map +1 -0
- package/dist/auto-ui/components/tree.d.ts +13 -0
- package/dist/auto-ui/components/tree.d.ts.map +1 -0
- package/dist/auto-ui/components/tree.js +61 -0
- package/dist/auto-ui/components/tree.js.map +1 -0
- package/dist/auto-ui/daemon-tools.d.ts +45 -0
- package/dist/auto-ui/daemon-tools.d.ts.map +1 -0
- package/dist/auto-ui/daemon-tools.js +580 -0
- package/dist/auto-ui/daemon-tools.js.map +1 -0
- package/dist/auto-ui/design-system/index.d.ts +21 -0
- package/dist/auto-ui/design-system/index.d.ts.map +1 -0
- package/dist/auto-ui/design-system/index.js +27 -0
- package/dist/auto-ui/design-system/index.js.map +1 -0
- package/dist/auto-ui/design-system/tokens.d.ts +9 -0
- package/dist/auto-ui/design-system/tokens.d.ts.map +1 -0
- package/dist/auto-ui/design-system/tokens.js +27 -0
- package/dist/auto-ui/design-system/tokens.js.map +1 -0
- package/dist/auto-ui/design-system/transaction-ui.d.ts +70 -0
- package/dist/auto-ui/design-system/transaction-ui.d.ts.map +1 -0
- package/dist/auto-ui/design-system/transaction-ui.js +982 -0
- package/dist/auto-ui/design-system/transaction-ui.js.map +1 -0
- package/dist/auto-ui/frontend/index.html +84 -0
- package/dist/auto-ui/index.d.ts +23 -0
- package/dist/auto-ui/index.d.ts.map +1 -0
- package/dist/auto-ui/index.js +28 -0
- package/dist/auto-ui/index.js.map +1 -0
- package/dist/auto-ui/openapi-generator.d.ts +71 -0
- package/dist/auto-ui/openapi-generator.d.ts.map +1 -0
- package/dist/auto-ui/openapi-generator.js +223 -0
- package/dist/auto-ui/openapi-generator.js.map +1 -0
- package/dist/auto-ui/photon-bridge.d.ts +159 -0
- package/dist/auto-ui/photon-bridge.d.ts.map +1 -0
- package/dist/auto-ui/photon-bridge.js +262 -0
- package/dist/auto-ui/photon-bridge.js.map +1 -0
- package/dist/auto-ui/photon-host.d.ts +113 -0
- package/dist/auto-ui/photon-host.d.ts.map +1 -0
- package/dist/auto-ui/photon-host.js +284 -0
- package/dist/auto-ui/photon-host.js.map +1 -0
- package/dist/auto-ui/platform-compat.d.ts +71 -0
- package/dist/auto-ui/platform-compat.d.ts.map +1 -0
- package/dist/auto-ui/platform-compat.js +628 -0
- package/dist/auto-ui/platform-compat.js.map +1 -0
- package/dist/auto-ui/playground-html.d.ts +15 -0
- package/dist/auto-ui/playground-html.d.ts.map +1 -0
- package/dist/auto-ui/playground-html.js +1113 -0
- package/dist/auto-ui/playground-html.js.map +1 -0
- package/dist/auto-ui/playground-server.d.ts +7 -0
- package/dist/auto-ui/playground-server.d.ts.map +1 -0
- package/dist/auto-ui/playground-server.js +840 -0
- package/dist/auto-ui/playground-server.js.map +1 -0
- package/dist/auto-ui/registry.d.ts +13 -0
- package/dist/auto-ui/registry.d.ts.map +1 -0
- package/dist/auto-ui/registry.js +62 -0
- package/dist/auto-ui/registry.js.map +1 -0
- package/dist/auto-ui/renderer.d.ts +14 -0
- package/dist/auto-ui/renderer.d.ts.map +1 -0
- package/dist/auto-ui/renderer.js +88 -0
- package/dist/auto-ui/renderer.js.map +1 -0
- package/dist/auto-ui/rendering/components.d.ts +29 -0
- package/dist/auto-ui/rendering/components.d.ts.map +1 -0
- package/dist/auto-ui/rendering/components.js +773 -0
- package/dist/auto-ui/rendering/components.js.map +1 -0
- package/dist/auto-ui/rendering/field-analyzer.d.ts +48 -0
- package/dist/auto-ui/rendering/field-analyzer.d.ts.map +1 -0
- package/dist/auto-ui/rendering/field-analyzer.js +270 -0
- package/dist/auto-ui/rendering/field-analyzer.js.map +1 -0
- package/dist/auto-ui/rendering/field-renderers.d.ts +64 -0
- package/dist/auto-ui/rendering/field-renderers.d.ts.map +1 -0
- package/dist/auto-ui/rendering/field-renderers.js +317 -0
- package/dist/auto-ui/rendering/field-renderers.js.map +1 -0
- package/dist/auto-ui/rendering/index.d.ts +28 -0
- package/dist/auto-ui/rendering/index.d.ts.map +1 -0
- package/dist/auto-ui/rendering/index.js +60 -0
- package/dist/auto-ui/rendering/index.js.map +1 -0
- package/dist/auto-ui/rendering/layout-selector.d.ts +48 -0
- package/dist/auto-ui/rendering/layout-selector.d.ts.map +1 -0
- package/dist/auto-ui/rendering/layout-selector.js +352 -0
- package/dist/auto-ui/rendering/layout-selector.js.map +1 -0
- package/dist/auto-ui/rendering/template-engine.d.ts +41 -0
- package/dist/auto-ui/rendering/template-engine.d.ts.map +1 -0
- package/dist/auto-ui/rendering/template-engine.js +238 -0
- package/dist/auto-ui/rendering/template-engine.js.map +1 -0
- package/dist/auto-ui/streamable-http-transport.d.ts +103 -0
- package/dist/auto-ui/streamable-http-transport.d.ts.map +1 -0
- package/dist/auto-ui/streamable-http-transport.js +1875 -0
- package/dist/auto-ui/streamable-http-transport.js.map +1 -0
- package/dist/auto-ui/types.d.ts +384 -0
- package/dist/auto-ui/types.d.ts.map +1 -0
- package/dist/auto-ui/types.js +92 -0
- package/dist/auto-ui/types.js.map +1 -0
- package/dist/beam.bundle.js +63137 -0
- package/dist/beam.bundle.js.map +7 -0
- package/dist/claude-code-plugin.d.ts.map +1 -1
- package/dist/claude-code-plugin.js +30 -30
- package/dist/claude-code-plugin.js.map +1 -1
- package/dist/cli/commands/info.d.ts +11 -0
- package/dist/cli/commands/info.d.ts.map +1 -0
- package/dist/cli/commands/info.js +313 -0
- package/dist/cli/commands/info.js.map +1 -0
- package/dist/cli/commands/marketplace.d.ts +11 -0
- package/dist/cli/commands/marketplace.d.ts.map +1 -0
- package/dist/cli/commands/marketplace.js +198 -0
- package/dist/cli/commands/marketplace.js.map +1 -0
- package/dist/cli/commands/package-app.d.ts +9 -0
- package/dist/cli/commands/package-app.d.ts.map +1 -0
- package/dist/cli/commands/package-app.js +191 -0
- package/dist/cli/commands/package-app.js.map +1 -0
- package/dist/cli/commands/package.d.ts +11 -0
- package/dist/cli/commands/package.d.ts.map +1 -0
- package/dist/cli/commands/package.js +573 -0
- package/dist/cli/commands/package.js.map +1 -0
- package/dist/cli-alias.d.ts.map +1 -1
- package/dist/cli-alias.js +30 -28
- package/dist/cli-alias.js.map +1 -1
- package/dist/cli-formatter.d.ts +8 -24
- package/dist/cli-formatter.d.ts.map +1 -1
- package/dist/cli-formatter.js +8 -325
- package/dist/cli-formatter.js.map +1 -1
- package/dist/cli.d.ts +15 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1166 -1131
- package/dist/cli.js.map +1 -1
- package/dist/daemon/client.d.ts +84 -3
- package/dist/daemon/client.d.ts.map +1 -1
- package/dist/daemon/client.js +561 -11
- package/dist/daemon/client.js.map +1 -1
- package/dist/daemon/manager.d.ts +51 -12
- package/dist/daemon/manager.d.ts.map +1 -1
- package/dist/daemon/manager.js +122 -61
- package/dist/daemon/manager.js.map +1 -1
- package/dist/daemon/protocol.d.ts +62 -6
- package/dist/daemon/protocol.d.ts.map +1 -1
- package/dist/daemon/protocol.js +76 -1
- package/dist/daemon/protocol.js.map +1 -1
- package/dist/daemon/server.d.ts +6 -6
- package/dist/daemon/server.js +743 -133
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/session-manager.d.ts +8 -1
- package/dist/daemon/session-manager.d.ts.map +1 -1
- package/dist/daemon/session-manager.js +32 -9
- package/dist/daemon/session-manager.js.map +1 -1
- package/dist/deploy/cloudflare.d.ts +12 -0
- package/dist/deploy/cloudflare.d.ts.map +1 -0
- package/dist/deploy/cloudflare.js +216 -0
- package/dist/deploy/cloudflare.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +191 -21
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +1186 -319
- package/dist/loader.js.map +1 -1
- package/dist/markdown-utils.d.ts +8 -0
- package/dist/markdown-utils.d.ts.map +1 -0
- package/dist/markdown-utils.js +63 -0
- package/dist/markdown-utils.js.map +1 -0
- package/dist/marketplace-manager.d.ts +10 -0
- package/dist/marketplace-manager.d.ts.map +1 -1
- package/dist/marketplace-manager.js +112 -28
- package/dist/marketplace-manager.js.map +1 -1
- package/dist/mcp-client.d.ts +9 -0
- package/dist/mcp-client.d.ts.map +1 -0
- package/dist/mcp-client.js +11 -0
- package/dist/mcp-client.js.map +1 -0
- package/dist/mcp-elicitation.d.ts +32 -0
- package/dist/mcp-elicitation.d.ts.map +1 -0
- package/dist/mcp-elicitation.js +26 -0
- package/dist/mcp-elicitation.js.map +1 -0
- package/dist/path-resolver.d.ts +9 -12
- package/dist/path-resolver.d.ts.map +1 -1
- package/dist/path-resolver.js +13 -43
- package/dist/path-resolver.js.map +1 -1
- package/dist/photon-cli-runner.d.ts.map +1 -1
- package/dist/photon-cli-runner.js +204 -77
- package/dist/photon-cli-runner.js.map +1 -1
- package/dist/photon-doc-extractor.d.ts +89 -0
- package/dist/photon-doc-extractor.d.ts.map +1 -1
- package/dist/photon-doc-extractor.js +560 -32
- package/dist/photon-doc-extractor.js.map +1 -1
- package/dist/photons/maker.photon.d.ts +182 -0
- package/dist/photons/maker.photon.d.ts.map +1 -0
- package/dist/photons/maker.photon.js +504 -0
- package/dist/photons/maker.photon.js.map +1 -0
- package/dist/photons/maker.photon.ts +626 -0
- package/dist/photons/marketplace.photon.d.ts +110 -0
- package/dist/photons/marketplace.photon.d.ts.map +1 -0
- package/dist/photons/marketplace.photon.js +260 -0
- package/dist/photons/marketplace.photon.js.map +1 -0
- package/dist/photons/marketplace.photon.ts +378 -0
- package/dist/photons/tunnel.photon.d.ts +80 -0
- package/dist/photons/tunnel.photon.d.ts.map +1 -0
- package/dist/photons/tunnel.photon.js +269 -0
- package/dist/photons/tunnel.photon.js.map +1 -0
- package/dist/photons/tunnel.photon.ts +345 -0
- package/dist/security-scanner.d.ts.map +1 -1
- package/dist/security-scanner.js +18 -15
- package/dist/security-scanner.js.map +1 -1
- package/dist/serv/auth/jwt.d.ts +89 -0
- package/dist/serv/auth/jwt.d.ts.map +1 -0
- package/dist/serv/auth/jwt.js +239 -0
- package/dist/serv/auth/jwt.js.map +1 -0
- package/dist/serv/auth/oauth.d.ts +117 -0
- package/dist/serv/auth/oauth.d.ts.map +1 -0
- package/dist/serv/auth/oauth.js +395 -0
- package/dist/serv/auth/oauth.js.map +1 -0
- package/dist/serv/auth/well-known.d.ts +60 -0
- package/dist/serv/auth/well-known.d.ts.map +1 -0
- package/dist/serv/auth/well-known.js +154 -0
- package/dist/serv/auth/well-known.js.map +1 -0
- package/dist/serv/db/d1-client.d.ts +65 -0
- package/dist/serv/db/d1-client.d.ts.map +1 -0
- package/dist/serv/db/d1-client.js +137 -0
- package/dist/serv/db/d1-client.js.map +1 -0
- package/dist/serv/db/d1-stores.d.ts +62 -0
- package/dist/serv/db/d1-stores.d.ts.map +1 -0
- package/dist/serv/db/d1-stores.js +307 -0
- package/dist/serv/db/d1-stores.js.map +1 -0
- package/dist/serv/index.d.ts +114 -0
- package/dist/serv/index.d.ts.map +1 -0
- package/dist/serv/index.js +172 -0
- package/dist/serv/index.js.map +1 -0
- package/dist/serv/local.d.ts +118 -0
- package/dist/serv/local.d.ts.map +1 -0
- package/dist/serv/local.js +392 -0
- package/dist/serv/local.js.map +1 -0
- package/dist/serv/middleware/auth.d.ts +66 -0
- package/dist/serv/middleware/auth.d.ts.map +1 -0
- package/dist/serv/middleware/auth.js +178 -0
- package/dist/serv/middleware/auth.js.map +1 -0
- package/dist/serv/middleware/tenant.d.ts +94 -0
- package/dist/serv/middleware/tenant.d.ts.map +1 -0
- package/dist/serv/middleware/tenant.js +152 -0
- package/dist/serv/middleware/tenant.js.map +1 -0
- package/dist/serv/runtime/executor.d.ts +76 -0
- package/dist/serv/runtime/executor.d.ts.map +1 -0
- package/dist/serv/runtime/executor.js +105 -0
- package/dist/serv/runtime/executor.js.map +1 -0
- package/dist/serv/runtime/index.d.ts +8 -0
- package/dist/serv/runtime/index.d.ts.map +1 -0
- package/dist/serv/runtime/index.js +10 -0
- package/dist/serv/runtime/index.js.map +1 -0
- package/dist/serv/runtime/oauth-context.d.ts +121 -0
- package/dist/serv/runtime/oauth-context.d.ts.map +1 -0
- package/dist/serv/runtime/oauth-context.js +153 -0
- package/dist/serv/runtime/oauth-context.js.map +1 -0
- package/dist/serv/session/kv-store.d.ts +54 -0
- package/dist/serv/session/kv-store.d.ts.map +1 -0
- package/dist/serv/session/kv-store.js +149 -0
- package/dist/serv/session/kv-store.js.map +1 -0
- package/dist/serv/session/store.d.ts +113 -0
- package/dist/serv/session/store.d.ts.map +1 -0
- package/dist/serv/session/store.js +284 -0
- package/dist/serv/session/store.js.map +1 -0
- package/dist/serv/types/index.d.ts +147 -0
- package/dist/serv/types/index.d.ts.map +1 -0
- package/dist/serv/types/index.js +8 -0
- package/dist/serv/types/index.js.map +1 -0
- package/dist/serv/vault/token-vault.d.ts +102 -0
- package/dist/serv/vault/token-vault.d.ts.map +1 -0
- package/dist/serv/vault/token-vault.js +177 -0
- package/dist/serv/vault/token-vault.js.map +1 -0
- package/dist/server.d.ts +184 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1995 -86
- package/dist/server.js.map +1 -1
- package/dist/shared/cli-sections.d.ts +6 -0
- package/dist/shared/cli-sections.d.ts.map +1 -0
- package/dist/shared/cli-sections.js +16 -0
- package/dist/shared/cli-sections.js.map +1 -0
- package/dist/shared/cli-utils.d.ts +81 -0
- package/dist/shared/cli-utils.d.ts.map +1 -0
- package/dist/shared/cli-utils.js +174 -0
- package/dist/shared/cli-utils.js.map +1 -0
- package/dist/shared/config-docs.d.ts +6 -0
- package/dist/shared/config-docs.d.ts.map +1 -0
- package/dist/shared/config-docs.js +6 -0
- package/dist/shared/config-docs.js.map +1 -0
- package/dist/shared/error-handler.d.ts +128 -0
- package/dist/shared/error-handler.d.ts.map +1 -0
- package/dist/shared/error-handler.js +342 -0
- package/dist/shared/error-handler.js.map +1 -0
- package/dist/shared/logger.d.ts +42 -0
- package/dist/shared/logger.d.ts.map +1 -0
- package/dist/shared/logger.js +123 -0
- package/dist/shared/logger.js.map +1 -0
- package/dist/shared/performance.d.ts +65 -0
- package/dist/shared/performance.d.ts.map +1 -0
- package/dist/shared/performance.js +136 -0
- package/dist/shared/performance.js.map +1 -0
- package/dist/shared/task-runner.d.ts +2 -0
- package/dist/shared/task-runner.d.ts.map +1 -0
- package/dist/shared/task-runner.js +16 -0
- package/dist/shared/task-runner.js.map +1 -0
- package/dist/shared/validation.d.ts +6 -0
- package/dist/shared/validation.d.ts.map +1 -0
- package/dist/shared/validation.js +6 -0
- package/dist/shared/validation.js.map +1 -0
- package/dist/shared-utils.d.ts +63 -0
- package/dist/shared-utils.d.ts.map +1 -0
- package/dist/shared-utils.js +123 -0
- package/dist/shared-utils.js.map +1 -0
- package/dist/template-manager.d.ts +23 -2
- package/dist/template-manager.d.ts.map +1 -1
- package/dist/template-manager.js +176 -87
- package/dist/template-manager.js.map +1 -1
- package/dist/test-client.d.ts.map +1 -1
- package/dist/test-client.js +10 -8
- package/dist/test-client.js.map +1 -1
- package/dist/test-runner.d.ts +52 -0
- package/dist/test-runner.d.ts.map +1 -0
- package/dist/test-runner.js +785 -0
- package/dist/test-runner.js.map +1 -0
- package/dist/testing.d.ts +103 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +163 -0
- package/dist/testing.js.map +1 -0
- package/dist/version-checker.d.ts.map +1 -1
- package/dist/version-checker.js +2 -2
- package/dist/version-checker.js.map +1 -1
- package/dist/version.d.ts +10 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +21 -0
- package/dist/version.js.map +1 -0
- package/dist/watcher.d.ts +6 -3
- package/dist/watcher.d.ts.map +1 -1
- package/dist/watcher.js +49 -10
- package/dist/watcher.js.map +1 -1
- package/package.json +57 -7
- package/templates/cloudflare/worker.ts.template +381 -0
- package/templates/cloudflare/wrangler.toml.template +9 -0
- package/dist/base.d.ts +0 -58
- package/dist/base.d.ts.map +0 -1
- package/dist/base.js +0 -92
- package/dist/base.js.map +0 -1
- package/dist/dependency-manager.d.ts +0 -49
- package/dist/dependency-manager.d.ts.map +0 -1
- package/dist/dependency-manager.js +0 -165
- package/dist/dependency-manager.js.map +0 -1
- package/dist/registry-manager.d.ts +0 -76
- package/dist/registry-manager.d.ts.map +0 -1
- package/dist/registry-manager.js +0 -220
- package/dist/registry-manager.js.map +0 -1
- package/dist/schema-extractor.d.ts +0 -110
- package/dist/schema-extractor.d.ts.map +0 -1
- package/dist/schema-extractor.js +0 -727
- package/dist/schema-extractor.js.map +0 -1
- package/dist/test-marketplace-sources.d.ts +0 -5
- package/dist/test-marketplace-sources.d.ts.map +0 -1
- package/dist/test-marketplace-sources.js +0 -53
- package/dist/test-marketplace-sources.js.map +0 -1
- package/dist/types.d.ts +0 -109
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -12
- package/dist/types.js.map +0 -1
|
@@ -0,0 +1,628 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform Compatibility Layer
|
|
3
|
+
*
|
|
4
|
+
* Provides universal compatibility for custom UIs across:
|
|
5
|
+
* - MCP Apps Extension (SEP-1865) - Standard ui/initialize protocol
|
|
6
|
+
* - ChatGPT Apps SDK - window.openai API
|
|
7
|
+
* - Claude Artifacts - postMessage with theme class
|
|
8
|
+
*
|
|
9
|
+
* BEAM injects all these APIs so apps built for any platform work without modification.
|
|
10
|
+
*
|
|
11
|
+
* @see https://github.com/modelcontextprotocol/modelcontextprotocol/pull/1865
|
|
12
|
+
* @see https://developers.openai.com/apps-sdk/reference/
|
|
13
|
+
* @see https://www.reidbarber.com/blog/reverse-engineering-claude-artifacts
|
|
14
|
+
*/
|
|
15
|
+
import { getThemeTokens } from './design-system/tokens.js';
|
|
16
|
+
// Re-export MCP Apps standard types and helpers from core
|
|
17
|
+
export { createMcpAppsInitialize, createThemeChangeMessages, } from '@portel/photon-core';
|
|
18
|
+
// ════════════════════════════════════════════════════════════════════════════════
|
|
19
|
+
// PLATFORM BRIDGE SCRIPT GENERATOR
|
|
20
|
+
// ════════════════════════════════════════════════════════════════════════════════
|
|
21
|
+
/**
|
|
22
|
+
* Generate the script that injects all platform APIs into an iframe.
|
|
23
|
+
* This enables apps built for ChatGPT, Claude, or MCP Apps to work in BEAM.
|
|
24
|
+
*/
|
|
25
|
+
export function generatePlatformBridgeScript(context) {
|
|
26
|
+
const themeTokens = getThemeTokens(context.theme);
|
|
27
|
+
const themeTokensJson = JSON.stringify(themeTokens);
|
|
28
|
+
const contextJson = JSON.stringify(context);
|
|
29
|
+
return `
|
|
30
|
+
<script>
|
|
31
|
+
(function() {
|
|
32
|
+
'use strict';
|
|
33
|
+
|
|
34
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
35
|
+
// SHARED STATE
|
|
36
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
37
|
+
|
|
38
|
+
var ctx = ${contextJson};
|
|
39
|
+
var themeTokens = ${themeTokensJson};
|
|
40
|
+
var toolInput = {};
|
|
41
|
+
var toolOutput = null;
|
|
42
|
+
var widgetState = {};
|
|
43
|
+
var pendingCalls = {};
|
|
44
|
+
var callIdCounter = 0;
|
|
45
|
+
|
|
46
|
+
// Event listeners
|
|
47
|
+
var listeners = {
|
|
48
|
+
progress: [],
|
|
49
|
+
status: [],
|
|
50
|
+
stream: [],
|
|
51
|
+
emit: [],
|
|
52
|
+
toolInputPartial: [],
|
|
53
|
+
toolInput: [],
|
|
54
|
+
result: [],
|
|
55
|
+
error: [],
|
|
56
|
+
themeChange: []
|
|
57
|
+
};
|
|
58
|
+
var elicitationHandler = null;
|
|
59
|
+
var teardownHandler = null;
|
|
60
|
+
|
|
61
|
+
function subscribe(arr, cb) {
|
|
62
|
+
arr.push(cb);
|
|
63
|
+
return function() { var i = arr.indexOf(cb); if (i >= 0) arr.splice(i, 1); };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function postToHost(msg) {
|
|
67
|
+
window.parent.postMessage(msg, '*');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function generateCallId() {
|
|
71
|
+
return 'call_' + (++callIdCounter) + '_' + Math.random().toString(36).slice(2);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
75
|
+
// MESSAGE HANDLER (receives from host)
|
|
76
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
77
|
+
|
|
78
|
+
window.addEventListener('message', function(e) {
|
|
79
|
+
var m = e.data;
|
|
80
|
+
if (!m || typeof m !== 'object') return;
|
|
81
|
+
|
|
82
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
83
|
+
// MCP Apps Extension (JSON-RPC 2.0)
|
|
84
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
85
|
+
|
|
86
|
+
// Helper to extract data from MCP result format
|
|
87
|
+
function extractMcpResultData(result) {
|
|
88
|
+
if (!result) return result;
|
|
89
|
+
// Prefer structuredContent if available
|
|
90
|
+
if (result.structuredContent) return result.structuredContent;
|
|
91
|
+
// Extract from content array
|
|
92
|
+
if (Array.isArray(result.content)) {
|
|
93
|
+
var textItem = result.content.find(function(item) { return item.type === 'text'; });
|
|
94
|
+
if (textItem && textItem.text) {
|
|
95
|
+
try { return JSON.parse(textItem.text); } catch (e) { return textItem.text; }
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (m.jsonrpc === '2.0') {
|
|
102
|
+
// JSON-RPC response (from tools/call) - has id but no method
|
|
103
|
+
if (m.id && !m.method) {
|
|
104
|
+
var pending = pendingCalls[m.id];
|
|
105
|
+
if (pending) {
|
|
106
|
+
delete pendingCalls[m.id];
|
|
107
|
+
if (m.error) {
|
|
108
|
+
pending.reject(new Error(m.error.message || 'Tool call failed'));
|
|
109
|
+
} else if (m.result && m.result.isError) {
|
|
110
|
+
// Tool returned an error (isError flag in MCP result)
|
|
111
|
+
var errorData = extractMcpResultData(m.result);
|
|
112
|
+
var errorMsg = typeof errorData === 'string' ? errorData : JSON.stringify(errorData);
|
|
113
|
+
pending.reject(new Error(errorMsg || 'Tool returned an error'));
|
|
114
|
+
} else {
|
|
115
|
+
pending.resolve(extractMcpResultData(m.result));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (m.method === 'ui/initialize') {
|
|
121
|
+
// Standard: hostContext.styles.variables; Legacy: params.theme
|
|
122
|
+
var initTokens = (m.params.hostContext && m.params.hostContext.styles && m.params.hostContext.styles.variables) || m.params.theme;
|
|
123
|
+
if (initTokens) themeTokens = initTokens;
|
|
124
|
+
// Extract theme name from hostContext or fall back
|
|
125
|
+
if (m.params.hostContext && m.params.hostContext.theme) ctx.theme = m.params.hostContext.theme;
|
|
126
|
+
applyThemeTokens();
|
|
127
|
+
}
|
|
128
|
+
else if (m.method === 'ui/notifications/tool-input-partial') {
|
|
129
|
+
listeners.toolInputPartial.forEach(function(cb) { cb(m.params); });
|
|
130
|
+
}
|
|
131
|
+
else if (m.method === 'ui/notifications/tool-input') {
|
|
132
|
+
toolInput = m.params.input || {};
|
|
133
|
+
listeners.toolInput.forEach(function(cb) { cb(m.params); });
|
|
134
|
+
}
|
|
135
|
+
else if (m.method === 'ui/notifications/tool-result') {
|
|
136
|
+
toolOutput = m.params.result;
|
|
137
|
+
listeners.result.forEach(function(cb) { cb(m.params.result); });
|
|
138
|
+
}
|
|
139
|
+
else if (m.method === 'ui/resource-teardown' && m.id != null) {
|
|
140
|
+
var teardownResult = teardownHandler ? teardownHandler() : undefined;
|
|
141
|
+
var sendTeardownResponse = function() {
|
|
142
|
+
postToHost({ jsonrpc: '2.0', id: m.id, result: {} });
|
|
143
|
+
};
|
|
144
|
+
if (teardownResult && typeof teardownResult.then === 'function') {
|
|
145
|
+
teardownResult.then(sendTeardownResponse).catch(sendTeardownResponse);
|
|
146
|
+
} else {
|
|
147
|
+
sendTeardownResponse();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else if (m.method === 'ui/notifications/context' || m.method === 'ui/notifications/host-context-changed') {
|
|
151
|
+
// Standard spec: host-context-changed with styles.variables
|
|
152
|
+
var ctxParams = m.params || {};
|
|
153
|
+
if (ctxParams.styles && ctxParams.styles.variables) {
|
|
154
|
+
themeTokens = ctxParams.styles.variables;
|
|
155
|
+
applyThemeTokens();
|
|
156
|
+
}
|
|
157
|
+
if (ctxParams.theme) {
|
|
158
|
+
ctx.theme = ctxParams.theme;
|
|
159
|
+
applyThemeClass();
|
|
160
|
+
listeners.themeChange.forEach(function(cb) { cb(ctx.theme); });
|
|
161
|
+
}
|
|
162
|
+
// Legacy: flat merge
|
|
163
|
+
Object.assign(ctx, ctxParams);
|
|
164
|
+
}
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
169
|
+
// Photon Bridge Protocol (internal)
|
|
170
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
171
|
+
if (typeof m.type === 'string' && m.type.indexOf('photon:') === 0) {
|
|
172
|
+
if (m.type === 'photon:init') {
|
|
173
|
+
toolInput = m.toolInput || {};
|
|
174
|
+
Object.assign(ctx, m.context);
|
|
175
|
+
themeTokens = m.themeTokens || themeTokens;
|
|
176
|
+
applyThemeTokens();
|
|
177
|
+
}
|
|
178
|
+
else if (m.type === 'photon:emit') {
|
|
179
|
+
var ev = m.event;
|
|
180
|
+
listeners.emit.forEach(function(cb) { cb(ev); });
|
|
181
|
+
if (ev.emit === 'progress') listeners.progress.forEach(function(cb) { cb(ev); });
|
|
182
|
+
else if (ev.emit === 'status') listeners.status.forEach(function(cb) { cb(ev); });
|
|
183
|
+
else if (ev.emit === 'stream') listeners.stream.forEach(function(cb) { cb(ev); });
|
|
184
|
+
}
|
|
185
|
+
else if (m.type === 'photon:ask' && elicitationHandler) {
|
|
186
|
+
elicitationHandler(m.event).then(function(v) {
|
|
187
|
+
postToHost({ type: 'photon:ask-response', id: m.id, value: v });
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
else if (m.type === 'photon:result') {
|
|
191
|
+
toolOutput = m.data;
|
|
192
|
+
listeners.result.forEach(function(cb) { cb(m.data); });
|
|
193
|
+
}
|
|
194
|
+
else if (m.type === 'photon:error') {
|
|
195
|
+
listeners.error.forEach(function(cb) { cb(m.error); });
|
|
196
|
+
}
|
|
197
|
+
else if (m.type === 'photon:context') {
|
|
198
|
+
Object.assign(ctx, m.context);
|
|
199
|
+
if (m.themeTokens) {
|
|
200
|
+
themeTokens = m.themeTokens;
|
|
201
|
+
applyThemeTokens();
|
|
202
|
+
}
|
|
203
|
+
if (m.context.theme) {
|
|
204
|
+
listeners.themeChange.forEach(function(cb) { cb(ctx.theme); });
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
else if (m.type === 'photon:theme-change') {
|
|
208
|
+
// Theme change from BEAM
|
|
209
|
+
ctx.theme = m.theme || 'dark';
|
|
210
|
+
// Update theme tokens if provided
|
|
211
|
+
if (m.themeTokens) {
|
|
212
|
+
themeTokens = m.themeTokens;
|
|
213
|
+
applyThemeTokens();
|
|
214
|
+
}
|
|
215
|
+
applyThemeClass();
|
|
216
|
+
listeners.themeChange.forEach(function(cb) { cb(ctx.theme); });
|
|
217
|
+
}
|
|
218
|
+
else if (m.type === 'photon:upload-file-response') {
|
|
219
|
+
var pending = pendingCalls[m.callId];
|
|
220
|
+
if (pending) {
|
|
221
|
+
delete pendingCalls[m.callId];
|
|
222
|
+
if (m.error) pending.reject(new Error(m.error));
|
|
223
|
+
else pending.resolve({ fileId: m.fileId });
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
else if (m.type === 'photon:get-file-url-response') {
|
|
227
|
+
var pending = pendingCalls[m.callId];
|
|
228
|
+
if (pending) {
|
|
229
|
+
delete pendingCalls[m.callId];
|
|
230
|
+
if (m.error) pending.reject(new Error(m.error));
|
|
231
|
+
else pending.resolve(m.url);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
else if (m.type === 'photon:request-modal-response') {
|
|
235
|
+
var pending = pendingCalls[m.callId];
|
|
236
|
+
if (pending) {
|
|
237
|
+
delete pendingCalls[m.callId];
|
|
238
|
+
if (m.error) pending.reject(new Error(m.error));
|
|
239
|
+
else pending.resolve(m.result);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
else if (m.type === 'photon:init-state') {
|
|
243
|
+
// Restore persisted widget state from host
|
|
244
|
+
if (m.state !== null && m.state !== undefined) {
|
|
245
|
+
widgetState = m.state;
|
|
246
|
+
// Dispatch event for apps listening to state changes
|
|
247
|
+
window.dispatchEvent(new CustomEvent('photon:state-restored', { detail: m.state }));
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
254
|
+
// Claude Artifacts Protocol (simple postMessage)
|
|
255
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
256
|
+
if (m.type === 'theme') {
|
|
257
|
+
ctx.theme = m.theme || 'dark';
|
|
258
|
+
applyThemeClass();
|
|
259
|
+
listeners.themeChange.forEach(function(cb) { cb(ctx.theme); });
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
263
|
+
// OpenAI set_globals event
|
|
264
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
265
|
+
if (m.type === 'openai:set_globals') {
|
|
266
|
+
if (m.theme) ctx.theme = m.theme;
|
|
267
|
+
if (m.toolInput) toolInput = m.toolInput;
|
|
268
|
+
if (m.toolOutput) toolOutput = m.toolOutput;
|
|
269
|
+
if (m.widgetState) widgetState = m.widgetState;
|
|
270
|
+
applyThemeClass();
|
|
271
|
+
listeners.themeChange.forEach(function(cb) { cb(ctx.theme); });
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
276
|
+
// THEME APPLICATION
|
|
277
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
278
|
+
|
|
279
|
+
function applyThemeTokens() {
|
|
280
|
+
var root = document.documentElement;
|
|
281
|
+
for (var key in themeTokens) {
|
|
282
|
+
root.style.setProperty(key, themeTokens[key]);
|
|
283
|
+
}
|
|
284
|
+
// Set safe area inset CSS variables
|
|
285
|
+
var insets = ctx.safeAreaInsets || { top: 0, bottom: 0, left: 0, right: 0 };
|
|
286
|
+
root.style.setProperty('--safe-area-inset-top', insets.top + 'px');
|
|
287
|
+
root.style.setProperty('--safe-area-inset-bottom', insets.bottom + 'px');
|
|
288
|
+
root.style.setProperty('--safe-area-inset-left', insets.left + 'px');
|
|
289
|
+
root.style.setProperty('--safe-area-inset-right', insets.right + 'px');
|
|
290
|
+
applyThemeClass();
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function applyThemeClass() {
|
|
294
|
+
document.documentElement.classList.remove('light', 'dark', 'light-theme');
|
|
295
|
+
document.documentElement.classList.add(ctx.theme);
|
|
296
|
+
|
|
297
|
+
// Define colors for each theme (must match design-system/tokens.ts)
|
|
298
|
+
var lightBg = '#ffffff';
|
|
299
|
+
var lightText = '#1a1a1a';
|
|
300
|
+
var darkBg = '#0d0d0d';
|
|
301
|
+
var darkText = '#e6e6e6';
|
|
302
|
+
|
|
303
|
+
if (ctx.theme === 'light') {
|
|
304
|
+
document.documentElement.classList.add('light-theme');
|
|
305
|
+
document.documentElement.style.colorScheme = 'light';
|
|
306
|
+
document.documentElement.style.backgroundColor = lightBg;
|
|
307
|
+
if (document.body) {
|
|
308
|
+
document.body.style.backgroundColor = lightBg;
|
|
309
|
+
document.body.style.color = lightText;
|
|
310
|
+
}
|
|
311
|
+
} else {
|
|
312
|
+
document.documentElement.style.colorScheme = 'dark';
|
|
313
|
+
document.documentElement.style.backgroundColor = darkBg;
|
|
314
|
+
if (document.body) {
|
|
315
|
+
document.body.style.backgroundColor = darkBg;
|
|
316
|
+
document.body.style.color = darkText;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
document.documentElement.setAttribute('data-theme', ctx.theme);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
323
|
+
// CALL TOOL HELPER
|
|
324
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
325
|
+
|
|
326
|
+
function callTool(name, args) {
|
|
327
|
+
var callId = generateCallId();
|
|
328
|
+
return new Promise(function(resolve, reject) {
|
|
329
|
+
pendingCalls[callId] = { resolve: resolve, reject: reject };
|
|
330
|
+
|
|
331
|
+
// MCP Apps standard: JSON-RPC tools/call
|
|
332
|
+
postToHost({
|
|
333
|
+
jsonrpc: '2.0',
|
|
334
|
+
id: callId,
|
|
335
|
+
method: 'tools/call',
|
|
336
|
+
params: { name: name, arguments: args || {} }
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
// Timeout after 30s
|
|
340
|
+
setTimeout(function() {
|
|
341
|
+
if (pendingCalls[callId]) {
|
|
342
|
+
delete pendingCalls[callId];
|
|
343
|
+
reject(new Error('Tool call timeout'));
|
|
344
|
+
}
|
|
345
|
+
}, 30000);
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
350
|
+
// 1. WINDOW.PHOTON - Photon Bridge API
|
|
351
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
352
|
+
|
|
353
|
+
window.photon = {
|
|
354
|
+
get toolInput() { return toolInput; },
|
|
355
|
+
get toolOutput() { return toolOutput; },
|
|
356
|
+
get widgetState() { return widgetState; },
|
|
357
|
+
setWidgetState: function(s) {
|
|
358
|
+
widgetState = s;
|
|
359
|
+
postToHost({ type: 'photon:set-state', state: s });
|
|
360
|
+
},
|
|
361
|
+
|
|
362
|
+
onProgress: function(cb) { return subscribe(listeners.progress, cb); },
|
|
363
|
+
onStatus: function(cb) { return subscribe(listeners.status, cb); },
|
|
364
|
+
onStream: function(cb) { return subscribe(listeners.stream, cb); },
|
|
365
|
+
onEmit: function(cb) { return subscribe(listeners.emit, cb); },
|
|
366
|
+
onResult: function(cb) { return subscribe(listeners.result, cb); },
|
|
367
|
+
onError: function(cb) { return subscribe(listeners.error, cb); },
|
|
368
|
+
onThemeChange: function(cb) { return subscribe(listeners.themeChange, cb); },
|
|
369
|
+
onToolInputPartial: function(cb) { return subscribe(listeners.toolInputPartial, cb); },
|
|
370
|
+
onToolInput: function(cb) { return subscribe(listeners.toolInput, cb); },
|
|
371
|
+
onElicitation: function(h) { elicitationHandler = h; return function() { elicitationHandler = null; }; },
|
|
372
|
+
onTeardown: function(h) { teardownHandler = h; return function() { teardownHandler = null; }; },
|
|
373
|
+
|
|
374
|
+
updateModelContext: function(opts) {
|
|
375
|
+
var callId = generateCallId();
|
|
376
|
+
return new Promise(function(resolve, reject) {
|
|
377
|
+
pendingCalls[callId] = { resolve: resolve, reject: reject };
|
|
378
|
+
postToHost({
|
|
379
|
+
jsonrpc: '2.0',
|
|
380
|
+
id: callId,
|
|
381
|
+
method: 'ui/update-model-context',
|
|
382
|
+
params: { content: opts.content, structuredContent: opts.structuredContent }
|
|
383
|
+
});
|
|
384
|
+
setTimeout(function() {
|
|
385
|
+
if (pendingCalls[callId]) {
|
|
386
|
+
delete pendingCalls[callId];
|
|
387
|
+
reject(new Error('Model context update timeout'));
|
|
388
|
+
}
|
|
389
|
+
}, 10000);
|
|
390
|
+
});
|
|
391
|
+
},
|
|
392
|
+
|
|
393
|
+
get safeAreaInsets() {
|
|
394
|
+
return ctx.safeAreaInsets || { top: 0, bottom: 0, left: 0, right: 0 };
|
|
395
|
+
},
|
|
396
|
+
|
|
397
|
+
callTool: callTool,
|
|
398
|
+
invoke: callTool, // Alias for callTool - used by custom UI templates
|
|
399
|
+
sendFollowUpMessage: function(msg) {
|
|
400
|
+
postToHost({ type: 'photon:follow-up', message: msg });
|
|
401
|
+
},
|
|
402
|
+
|
|
403
|
+
get theme() { return ctx.theme; },
|
|
404
|
+
get locale() { return ctx.locale; },
|
|
405
|
+
get photon() { return ctx.photon; },
|
|
406
|
+
get method() { return ctx.method; },
|
|
407
|
+
get isChatGPT() { return typeof window.openai !== 'undefined'; }
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
411
|
+
// 2. WINDOW.OPENAI - ChatGPT Apps SDK Compatibility
|
|
412
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
413
|
+
|
|
414
|
+
window.openai = {
|
|
415
|
+
// Context properties (reactive via openai:set_globals)
|
|
416
|
+
get theme() { return ctx.theme; },
|
|
417
|
+
get displayMode() { return ctx.displayMode === 'fullscreen' ? 'fullscreen' : 'inline'; },
|
|
418
|
+
get locale() { return ctx.locale; },
|
|
419
|
+
get maxHeight() { return 600; },
|
|
420
|
+
get toolInput() { return toolInput; },
|
|
421
|
+
get toolOutput() { return toolOutput; },
|
|
422
|
+
get widgetState() { return widgetState; },
|
|
423
|
+
get toolResponseMetadata() { return {}; },
|
|
424
|
+
|
|
425
|
+
// Methods
|
|
426
|
+
setWidgetState: function(state) {
|
|
427
|
+
widgetState = state;
|
|
428
|
+
postToHost({ type: 'photon:set-state', state: state });
|
|
429
|
+
},
|
|
430
|
+
|
|
431
|
+
callTool: callTool,
|
|
432
|
+
|
|
433
|
+
sendFollowUpMessage: function(opts) {
|
|
434
|
+
postToHost({ type: 'photon:follow-up', message: opts.prompt });
|
|
435
|
+
return Promise.resolve();
|
|
436
|
+
},
|
|
437
|
+
|
|
438
|
+
uploadFile: function(file) {
|
|
439
|
+
var callId = generateCallId();
|
|
440
|
+
return new Promise(function(resolve, reject) {
|
|
441
|
+
pendingCalls[callId] = { resolve: resolve, reject: reject };
|
|
442
|
+
|
|
443
|
+
// Read file as base64
|
|
444
|
+
var reader = new FileReader();
|
|
445
|
+
reader.onload = function() {
|
|
446
|
+
var base64 = reader.result;
|
|
447
|
+
postToHost({
|
|
448
|
+
type: 'photon:upload-file',
|
|
449
|
+
callId: callId,
|
|
450
|
+
fileName: file.name,
|
|
451
|
+
fileType: file.type,
|
|
452
|
+
fileSize: file.size,
|
|
453
|
+
data: base64
|
|
454
|
+
});
|
|
455
|
+
};
|
|
456
|
+
reader.onerror = function() {
|
|
457
|
+
delete pendingCalls[callId];
|
|
458
|
+
reject(new Error('Failed to read file'));
|
|
459
|
+
};
|
|
460
|
+
reader.readAsDataURL(file);
|
|
461
|
+
|
|
462
|
+
// Timeout after 60s
|
|
463
|
+
setTimeout(function() {
|
|
464
|
+
if (pendingCalls[callId]) {
|
|
465
|
+
delete pendingCalls[callId];
|
|
466
|
+
reject(new Error('File upload timeout'));
|
|
467
|
+
}
|
|
468
|
+
}, 60000);
|
|
469
|
+
});
|
|
470
|
+
},
|
|
471
|
+
|
|
472
|
+
getFileDownloadUrl: function(opts) {
|
|
473
|
+
var callId = generateCallId();
|
|
474
|
+
return new Promise(function(resolve, reject) {
|
|
475
|
+
pendingCalls[callId] = { resolve: resolve, reject: reject };
|
|
476
|
+
|
|
477
|
+
postToHost({
|
|
478
|
+
type: 'photon:get-file-url',
|
|
479
|
+
callId: callId,
|
|
480
|
+
fileId: opts.fileId
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
// Timeout after 30s
|
|
484
|
+
setTimeout(function() {
|
|
485
|
+
if (pendingCalls[callId]) {
|
|
486
|
+
delete pendingCalls[callId];
|
|
487
|
+
reject(new Error('Get file URL timeout'));
|
|
488
|
+
}
|
|
489
|
+
}, 30000);
|
|
490
|
+
});
|
|
491
|
+
},
|
|
492
|
+
|
|
493
|
+
requestDisplayMode: function(mode) {
|
|
494
|
+
postToHost({ type: 'photon:request-display-mode', mode: mode });
|
|
495
|
+
return Promise.resolve();
|
|
496
|
+
},
|
|
497
|
+
|
|
498
|
+
requestModal: function(opts) {
|
|
499
|
+
var callId = generateCallId();
|
|
500
|
+
return new Promise(function(resolve, reject) {
|
|
501
|
+
pendingCalls[callId] = { resolve: resolve, reject: reject };
|
|
502
|
+
|
|
503
|
+
postToHost({
|
|
504
|
+
type: 'photon:request-modal',
|
|
505
|
+
callId: callId,
|
|
506
|
+
template: opts.template,
|
|
507
|
+
params: opts.params
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
// Timeout after 5 minutes (modals may take user input)
|
|
511
|
+
setTimeout(function() {
|
|
512
|
+
if (pendingCalls[callId]) {
|
|
513
|
+
delete pendingCalls[callId];
|
|
514
|
+
reject(new Error('Modal request timeout'));
|
|
515
|
+
}
|
|
516
|
+
}, 300000);
|
|
517
|
+
});
|
|
518
|
+
},
|
|
519
|
+
|
|
520
|
+
notifyIntrinsicHeight: function(height) {
|
|
521
|
+
postToHost({ type: 'photon:notify-height', height: height });
|
|
522
|
+
},
|
|
523
|
+
|
|
524
|
+
openExternal: function(opts) {
|
|
525
|
+
window.open(opts.href, '_blank', 'noopener,noreferrer');
|
|
526
|
+
},
|
|
527
|
+
|
|
528
|
+
setOpenInAppUrl: function(opts) {
|
|
529
|
+
postToHost({ type: 'photon:set-open-in-app-url', href: opts.href });
|
|
530
|
+
}
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
534
|
+
// 3. WINDOW.MCP - Generic MCP Bridge (superset)
|
|
535
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
536
|
+
|
|
537
|
+
window.mcp = {
|
|
538
|
+
// Inherits from photon
|
|
539
|
+
...window.photon,
|
|
540
|
+
|
|
541
|
+
// Additional MCP-specific context
|
|
542
|
+
get hostName() { return ctx.hostName; },
|
|
543
|
+
get hostVersion() { return ctx.hostVersion; },
|
|
544
|
+
|
|
545
|
+
// MCP Apps Extension methods
|
|
546
|
+
requestToolCall: callTool,
|
|
547
|
+
|
|
548
|
+
// Read a resource
|
|
549
|
+
readResource: function(uri) {
|
|
550
|
+
return callTool('resources/read', { uri: uri });
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
555
|
+
// 4. OPENAI GLOBAL HOOK - useOpenAiGlobal compatibility
|
|
556
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
557
|
+
|
|
558
|
+
// Dispatch custom event for useOpenAiGlobal hook subscribers
|
|
559
|
+
function dispatchGlobalsEvent() {
|
|
560
|
+
window.dispatchEvent(new CustomEvent('openai:set_globals', {
|
|
561
|
+
detail: {
|
|
562
|
+
theme: ctx.theme,
|
|
563
|
+
displayMode: ctx.displayMode,
|
|
564
|
+
locale: ctx.locale,
|
|
565
|
+
toolInput: toolInput,
|
|
566
|
+
toolOutput: toolOutput,
|
|
567
|
+
widgetState: widgetState
|
|
568
|
+
}
|
|
569
|
+
}));
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
573
|
+
// INITIALIZATION
|
|
574
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
575
|
+
|
|
576
|
+
// Apply initial theme
|
|
577
|
+
applyThemeTokens();
|
|
578
|
+
|
|
579
|
+
// Notify host that bridge is ready (Photon/BEAM protocol)
|
|
580
|
+
postToHost({ type: 'photon:ready' });
|
|
581
|
+
|
|
582
|
+
// Request persisted state from host
|
|
583
|
+
postToHost({ type: 'photon:get-state' });
|
|
584
|
+
|
|
585
|
+
// MCP Apps Extension: Send ui/initialize REQUEST and handle response
|
|
586
|
+
// This is the official handshake required by Claude Desktop and other MCP Apps hosts
|
|
587
|
+
var initCallId = generateCallId();
|
|
588
|
+
pendingCalls[initCallId] = {
|
|
589
|
+
resolve: function(result) {
|
|
590
|
+
// Store host context from response
|
|
591
|
+
if (result.hostContext) {
|
|
592
|
+
Object.assign(ctx, result.hostContext);
|
|
593
|
+
if (result.hostContext.theme) ctx.theme = result.hostContext.theme;
|
|
594
|
+
if (result.hostContext.styles && result.hostContext.styles.variables) {
|
|
595
|
+
themeTokens = result.hostContext.styles.variables;
|
|
596
|
+
}
|
|
597
|
+
applyThemeTokens();
|
|
598
|
+
}
|
|
599
|
+
// Send ui/notifications/initialized to complete handshake
|
|
600
|
+
postToHost({
|
|
601
|
+
jsonrpc: '2.0',
|
|
602
|
+
method: 'ui/notifications/initialized',
|
|
603
|
+
params: {}
|
|
604
|
+
});
|
|
605
|
+
},
|
|
606
|
+
reject: function(err) {
|
|
607
|
+
console.error('MCP Apps init failed:', err);
|
|
608
|
+
}
|
|
609
|
+
};
|
|
610
|
+
|
|
611
|
+
postToHost({
|
|
612
|
+
jsonrpc: '2.0',
|
|
613
|
+
id: initCallId,
|
|
614
|
+
method: 'ui/initialize',
|
|
615
|
+
params: {
|
|
616
|
+
appInfo: { name: ctx.photon || 'photon-app', version: '1.0.0' },
|
|
617
|
+
appCapabilities: {},
|
|
618
|
+
protocolVersion: '2026-01-26'
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
})();
|
|
623
|
+
</script>`;
|
|
624
|
+
}
|
|
625
|
+
// ════════════════════════════════════════════════════════════════════════════════
|
|
626
|
+
// HOST-SIDE HELPERS
|
|
627
|
+
// ════════════════════════════════════════════════════════════════════════════════
|
|
628
|
+
//# sourceMappingURL=platform-compat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-compat.js","sourceRoot":"","sources":["../../src/auto-ui/platform-compat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,cAAc,EAAkB,MAAM,2BAA2B,CAAC;AAG3E,0DAA0D;AAC1D,OAAO,EAQL,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AA0C7B,mFAAmF;AACnF,mCAAmC;AACnC,mFAAmF;AAEnF;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAAC,OAAwB;IACnE,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACpD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAE5C,OAAO;;;;;;;;;cASK,WAAW;sBACH,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAwkB3B,CAAC;AACX,CAAC;AAED,mFAAmF;AACnF,oBAAoB;AACpB,mFAAmF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playground HTML Template
|
|
3
|
+
*
|
|
4
|
+
* Generates the interactive playground UI for testing MCP tools.
|
|
5
|
+
* This is used by PhotonServer when serving the playground at /playground.
|
|
6
|
+
*/
|
|
7
|
+
export interface PlaygroundOptions {
|
|
8
|
+
name: string;
|
|
9
|
+
port: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Generate playground HTML for interactive testing
|
|
13
|
+
*/
|
|
14
|
+
export declare function generatePlaygroundHTML(options: PlaygroundOptions): string;
|
|
15
|
+
//# sourceMappingURL=playground-html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playground-html.d.ts","sourceRoot":"","sources":["../../src/auto-ui/playground-html.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CA8kCzE"}
|