@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.
Files changed (395) hide show
  1. package/README.md +326 -1177
  2. package/dist/auto-ui/beam.d.ts +14 -0
  3. package/dist/auto-ui/beam.d.ts.map +1 -0
  4. package/dist/auto-ui/beam.js +3057 -0
  5. package/dist/auto-ui/beam.js.map +1 -0
  6. package/dist/auto-ui/bridge/index.d.ts +37 -0
  7. package/dist/auto-ui/bridge/index.d.ts.map +1 -0
  8. package/dist/auto-ui/bridge/index.js +555 -0
  9. package/dist/auto-ui/bridge/index.js.map +1 -0
  10. package/dist/auto-ui/bridge/openai-shim.d.ts +20 -0
  11. package/dist/auto-ui/bridge/openai-shim.d.ts.map +1 -0
  12. package/dist/auto-ui/bridge/openai-shim.js +231 -0
  13. package/dist/auto-ui/bridge/openai-shim.js.map +1 -0
  14. package/dist/auto-ui/bridge/photon-app.d.ts +162 -0
  15. package/dist/auto-ui/bridge/photon-app.d.ts.map +1 -0
  16. package/dist/auto-ui/bridge/photon-app.js +460 -0
  17. package/dist/auto-ui/bridge/photon-app.js.map +1 -0
  18. package/dist/auto-ui/bridge/types.d.ts +128 -0
  19. package/dist/auto-ui/bridge/types.d.ts.map +1 -0
  20. package/dist/auto-ui/bridge/types.js +7 -0
  21. package/dist/auto-ui/bridge/types.js.map +1 -0
  22. package/dist/auto-ui/components/card.d.ts +13 -0
  23. package/dist/auto-ui/components/card.d.ts.map +1 -0
  24. package/dist/auto-ui/components/card.js +64 -0
  25. package/dist/auto-ui/components/card.js.map +1 -0
  26. package/dist/auto-ui/components/form.d.ts +15 -0
  27. package/dist/auto-ui/components/form.d.ts.map +1 -0
  28. package/dist/auto-ui/components/form.js +72 -0
  29. package/dist/auto-ui/components/form.js.map +1 -0
  30. package/dist/auto-ui/components/list.d.ts +13 -0
  31. package/dist/auto-ui/components/list.d.ts.map +1 -0
  32. package/dist/auto-ui/components/list.js +58 -0
  33. package/dist/auto-ui/components/list.js.map +1 -0
  34. package/dist/auto-ui/components/progress.d.ts +18 -0
  35. package/dist/auto-ui/components/progress.d.ts.map +1 -0
  36. package/dist/auto-ui/components/progress.js +125 -0
  37. package/dist/auto-ui/components/progress.js.map +1 -0
  38. package/dist/auto-ui/components/table.d.ts +13 -0
  39. package/dist/auto-ui/components/table.d.ts.map +1 -0
  40. package/dist/auto-ui/components/table.js +82 -0
  41. package/dist/auto-ui/components/table.js.map +1 -0
  42. package/dist/auto-ui/components/tree.d.ts +13 -0
  43. package/dist/auto-ui/components/tree.d.ts.map +1 -0
  44. package/dist/auto-ui/components/tree.js +61 -0
  45. package/dist/auto-ui/components/tree.js.map +1 -0
  46. package/dist/auto-ui/daemon-tools.d.ts +45 -0
  47. package/dist/auto-ui/daemon-tools.d.ts.map +1 -0
  48. package/dist/auto-ui/daemon-tools.js +580 -0
  49. package/dist/auto-ui/daemon-tools.js.map +1 -0
  50. package/dist/auto-ui/design-system/index.d.ts +21 -0
  51. package/dist/auto-ui/design-system/index.d.ts.map +1 -0
  52. package/dist/auto-ui/design-system/index.js +27 -0
  53. package/dist/auto-ui/design-system/index.js.map +1 -0
  54. package/dist/auto-ui/design-system/tokens.d.ts +9 -0
  55. package/dist/auto-ui/design-system/tokens.d.ts.map +1 -0
  56. package/dist/auto-ui/design-system/tokens.js +27 -0
  57. package/dist/auto-ui/design-system/tokens.js.map +1 -0
  58. package/dist/auto-ui/design-system/transaction-ui.d.ts +70 -0
  59. package/dist/auto-ui/design-system/transaction-ui.d.ts.map +1 -0
  60. package/dist/auto-ui/design-system/transaction-ui.js +982 -0
  61. package/dist/auto-ui/design-system/transaction-ui.js.map +1 -0
  62. package/dist/auto-ui/frontend/index.html +84 -0
  63. package/dist/auto-ui/index.d.ts +23 -0
  64. package/dist/auto-ui/index.d.ts.map +1 -0
  65. package/dist/auto-ui/index.js +28 -0
  66. package/dist/auto-ui/index.js.map +1 -0
  67. package/dist/auto-ui/openapi-generator.d.ts +71 -0
  68. package/dist/auto-ui/openapi-generator.d.ts.map +1 -0
  69. package/dist/auto-ui/openapi-generator.js +223 -0
  70. package/dist/auto-ui/openapi-generator.js.map +1 -0
  71. package/dist/auto-ui/photon-bridge.d.ts +159 -0
  72. package/dist/auto-ui/photon-bridge.d.ts.map +1 -0
  73. package/dist/auto-ui/photon-bridge.js +262 -0
  74. package/dist/auto-ui/photon-bridge.js.map +1 -0
  75. package/dist/auto-ui/photon-host.d.ts +113 -0
  76. package/dist/auto-ui/photon-host.d.ts.map +1 -0
  77. package/dist/auto-ui/photon-host.js +284 -0
  78. package/dist/auto-ui/photon-host.js.map +1 -0
  79. package/dist/auto-ui/platform-compat.d.ts +71 -0
  80. package/dist/auto-ui/platform-compat.d.ts.map +1 -0
  81. package/dist/auto-ui/platform-compat.js +628 -0
  82. package/dist/auto-ui/platform-compat.js.map +1 -0
  83. package/dist/auto-ui/playground-html.d.ts +15 -0
  84. package/dist/auto-ui/playground-html.d.ts.map +1 -0
  85. package/dist/auto-ui/playground-html.js +1113 -0
  86. package/dist/auto-ui/playground-html.js.map +1 -0
  87. package/dist/auto-ui/playground-server.d.ts +7 -0
  88. package/dist/auto-ui/playground-server.d.ts.map +1 -0
  89. package/dist/auto-ui/playground-server.js +840 -0
  90. package/dist/auto-ui/playground-server.js.map +1 -0
  91. package/dist/auto-ui/registry.d.ts +13 -0
  92. package/dist/auto-ui/registry.d.ts.map +1 -0
  93. package/dist/auto-ui/registry.js +62 -0
  94. package/dist/auto-ui/registry.js.map +1 -0
  95. package/dist/auto-ui/renderer.d.ts +14 -0
  96. package/dist/auto-ui/renderer.d.ts.map +1 -0
  97. package/dist/auto-ui/renderer.js +88 -0
  98. package/dist/auto-ui/renderer.js.map +1 -0
  99. package/dist/auto-ui/rendering/components.d.ts +29 -0
  100. package/dist/auto-ui/rendering/components.d.ts.map +1 -0
  101. package/dist/auto-ui/rendering/components.js +773 -0
  102. package/dist/auto-ui/rendering/components.js.map +1 -0
  103. package/dist/auto-ui/rendering/field-analyzer.d.ts +48 -0
  104. package/dist/auto-ui/rendering/field-analyzer.d.ts.map +1 -0
  105. package/dist/auto-ui/rendering/field-analyzer.js +270 -0
  106. package/dist/auto-ui/rendering/field-analyzer.js.map +1 -0
  107. package/dist/auto-ui/rendering/field-renderers.d.ts +64 -0
  108. package/dist/auto-ui/rendering/field-renderers.d.ts.map +1 -0
  109. package/dist/auto-ui/rendering/field-renderers.js +317 -0
  110. package/dist/auto-ui/rendering/field-renderers.js.map +1 -0
  111. package/dist/auto-ui/rendering/index.d.ts +28 -0
  112. package/dist/auto-ui/rendering/index.d.ts.map +1 -0
  113. package/dist/auto-ui/rendering/index.js +60 -0
  114. package/dist/auto-ui/rendering/index.js.map +1 -0
  115. package/dist/auto-ui/rendering/layout-selector.d.ts +48 -0
  116. package/dist/auto-ui/rendering/layout-selector.d.ts.map +1 -0
  117. package/dist/auto-ui/rendering/layout-selector.js +352 -0
  118. package/dist/auto-ui/rendering/layout-selector.js.map +1 -0
  119. package/dist/auto-ui/rendering/template-engine.d.ts +41 -0
  120. package/dist/auto-ui/rendering/template-engine.d.ts.map +1 -0
  121. package/dist/auto-ui/rendering/template-engine.js +238 -0
  122. package/dist/auto-ui/rendering/template-engine.js.map +1 -0
  123. package/dist/auto-ui/streamable-http-transport.d.ts +103 -0
  124. package/dist/auto-ui/streamable-http-transport.d.ts.map +1 -0
  125. package/dist/auto-ui/streamable-http-transport.js +1875 -0
  126. package/dist/auto-ui/streamable-http-transport.js.map +1 -0
  127. package/dist/auto-ui/types.d.ts +384 -0
  128. package/dist/auto-ui/types.d.ts.map +1 -0
  129. package/dist/auto-ui/types.js +92 -0
  130. package/dist/auto-ui/types.js.map +1 -0
  131. package/dist/beam.bundle.js +63137 -0
  132. package/dist/beam.bundle.js.map +7 -0
  133. package/dist/claude-code-plugin.d.ts.map +1 -1
  134. package/dist/claude-code-plugin.js +30 -30
  135. package/dist/claude-code-plugin.js.map +1 -1
  136. package/dist/cli/commands/info.d.ts +11 -0
  137. package/dist/cli/commands/info.d.ts.map +1 -0
  138. package/dist/cli/commands/info.js +313 -0
  139. package/dist/cli/commands/info.js.map +1 -0
  140. package/dist/cli/commands/marketplace.d.ts +11 -0
  141. package/dist/cli/commands/marketplace.d.ts.map +1 -0
  142. package/dist/cli/commands/marketplace.js +198 -0
  143. package/dist/cli/commands/marketplace.js.map +1 -0
  144. package/dist/cli/commands/package-app.d.ts +9 -0
  145. package/dist/cli/commands/package-app.d.ts.map +1 -0
  146. package/dist/cli/commands/package-app.js +191 -0
  147. package/dist/cli/commands/package-app.js.map +1 -0
  148. package/dist/cli/commands/package.d.ts +11 -0
  149. package/dist/cli/commands/package.d.ts.map +1 -0
  150. package/dist/cli/commands/package.js +573 -0
  151. package/dist/cli/commands/package.js.map +1 -0
  152. package/dist/cli-alias.d.ts.map +1 -1
  153. package/dist/cli-alias.js +30 -28
  154. package/dist/cli-alias.js.map +1 -1
  155. package/dist/cli-formatter.d.ts +8 -24
  156. package/dist/cli-formatter.d.ts.map +1 -1
  157. package/dist/cli-formatter.js +8 -325
  158. package/dist/cli-formatter.js.map +1 -1
  159. package/dist/cli.d.ts +15 -1
  160. package/dist/cli.d.ts.map +1 -1
  161. package/dist/cli.js +1166 -1131
  162. package/dist/cli.js.map +1 -1
  163. package/dist/daemon/client.d.ts +84 -3
  164. package/dist/daemon/client.d.ts.map +1 -1
  165. package/dist/daemon/client.js +561 -11
  166. package/dist/daemon/client.js.map +1 -1
  167. package/dist/daemon/manager.d.ts +51 -12
  168. package/dist/daemon/manager.d.ts.map +1 -1
  169. package/dist/daemon/manager.js +122 -61
  170. package/dist/daemon/manager.js.map +1 -1
  171. package/dist/daemon/protocol.d.ts +62 -6
  172. package/dist/daemon/protocol.d.ts.map +1 -1
  173. package/dist/daemon/protocol.js +76 -1
  174. package/dist/daemon/protocol.js.map +1 -1
  175. package/dist/daemon/server.d.ts +6 -6
  176. package/dist/daemon/server.js +743 -133
  177. package/dist/daemon/server.js.map +1 -1
  178. package/dist/daemon/session-manager.d.ts +8 -1
  179. package/dist/daemon/session-manager.d.ts.map +1 -1
  180. package/dist/daemon/session-manager.js +32 -9
  181. package/dist/daemon/session-manager.js.map +1 -1
  182. package/dist/deploy/cloudflare.d.ts +12 -0
  183. package/dist/deploy/cloudflare.d.ts.map +1 -0
  184. package/dist/deploy/cloudflare.js +216 -0
  185. package/dist/deploy/cloudflare.js.map +1 -0
  186. package/dist/index.d.ts +1 -0
  187. package/dist/index.d.ts.map +1 -1
  188. package/dist/index.js +3 -0
  189. package/dist/index.js.map +1 -1
  190. package/dist/loader.d.ts +191 -21
  191. package/dist/loader.d.ts.map +1 -1
  192. package/dist/loader.js +1186 -319
  193. package/dist/loader.js.map +1 -1
  194. package/dist/markdown-utils.d.ts +8 -0
  195. package/dist/markdown-utils.d.ts.map +1 -0
  196. package/dist/markdown-utils.js +63 -0
  197. package/dist/markdown-utils.js.map +1 -0
  198. package/dist/marketplace-manager.d.ts +10 -0
  199. package/dist/marketplace-manager.d.ts.map +1 -1
  200. package/dist/marketplace-manager.js +112 -28
  201. package/dist/marketplace-manager.js.map +1 -1
  202. package/dist/mcp-client.d.ts +9 -0
  203. package/dist/mcp-client.d.ts.map +1 -0
  204. package/dist/mcp-client.js +11 -0
  205. package/dist/mcp-client.js.map +1 -0
  206. package/dist/mcp-elicitation.d.ts +32 -0
  207. package/dist/mcp-elicitation.d.ts.map +1 -0
  208. package/dist/mcp-elicitation.js +26 -0
  209. package/dist/mcp-elicitation.js.map +1 -0
  210. package/dist/path-resolver.d.ts +9 -12
  211. package/dist/path-resolver.d.ts.map +1 -1
  212. package/dist/path-resolver.js +13 -43
  213. package/dist/path-resolver.js.map +1 -1
  214. package/dist/photon-cli-runner.d.ts.map +1 -1
  215. package/dist/photon-cli-runner.js +204 -77
  216. package/dist/photon-cli-runner.js.map +1 -1
  217. package/dist/photon-doc-extractor.d.ts +89 -0
  218. package/dist/photon-doc-extractor.d.ts.map +1 -1
  219. package/dist/photon-doc-extractor.js +560 -32
  220. package/dist/photon-doc-extractor.js.map +1 -1
  221. package/dist/photons/maker.photon.d.ts +182 -0
  222. package/dist/photons/maker.photon.d.ts.map +1 -0
  223. package/dist/photons/maker.photon.js +504 -0
  224. package/dist/photons/maker.photon.js.map +1 -0
  225. package/dist/photons/maker.photon.ts +626 -0
  226. package/dist/photons/marketplace.photon.d.ts +110 -0
  227. package/dist/photons/marketplace.photon.d.ts.map +1 -0
  228. package/dist/photons/marketplace.photon.js +260 -0
  229. package/dist/photons/marketplace.photon.js.map +1 -0
  230. package/dist/photons/marketplace.photon.ts +378 -0
  231. package/dist/photons/tunnel.photon.d.ts +80 -0
  232. package/dist/photons/tunnel.photon.d.ts.map +1 -0
  233. package/dist/photons/tunnel.photon.js +269 -0
  234. package/dist/photons/tunnel.photon.js.map +1 -0
  235. package/dist/photons/tunnel.photon.ts +345 -0
  236. package/dist/security-scanner.d.ts.map +1 -1
  237. package/dist/security-scanner.js +18 -15
  238. package/dist/security-scanner.js.map +1 -1
  239. package/dist/serv/auth/jwt.d.ts +89 -0
  240. package/dist/serv/auth/jwt.d.ts.map +1 -0
  241. package/dist/serv/auth/jwt.js +239 -0
  242. package/dist/serv/auth/jwt.js.map +1 -0
  243. package/dist/serv/auth/oauth.d.ts +117 -0
  244. package/dist/serv/auth/oauth.d.ts.map +1 -0
  245. package/dist/serv/auth/oauth.js +395 -0
  246. package/dist/serv/auth/oauth.js.map +1 -0
  247. package/dist/serv/auth/well-known.d.ts +60 -0
  248. package/dist/serv/auth/well-known.d.ts.map +1 -0
  249. package/dist/serv/auth/well-known.js +154 -0
  250. package/dist/serv/auth/well-known.js.map +1 -0
  251. package/dist/serv/db/d1-client.d.ts +65 -0
  252. package/dist/serv/db/d1-client.d.ts.map +1 -0
  253. package/dist/serv/db/d1-client.js +137 -0
  254. package/dist/serv/db/d1-client.js.map +1 -0
  255. package/dist/serv/db/d1-stores.d.ts +62 -0
  256. package/dist/serv/db/d1-stores.d.ts.map +1 -0
  257. package/dist/serv/db/d1-stores.js +307 -0
  258. package/dist/serv/db/d1-stores.js.map +1 -0
  259. package/dist/serv/index.d.ts +114 -0
  260. package/dist/serv/index.d.ts.map +1 -0
  261. package/dist/serv/index.js +172 -0
  262. package/dist/serv/index.js.map +1 -0
  263. package/dist/serv/local.d.ts +118 -0
  264. package/dist/serv/local.d.ts.map +1 -0
  265. package/dist/serv/local.js +392 -0
  266. package/dist/serv/local.js.map +1 -0
  267. package/dist/serv/middleware/auth.d.ts +66 -0
  268. package/dist/serv/middleware/auth.d.ts.map +1 -0
  269. package/dist/serv/middleware/auth.js +178 -0
  270. package/dist/serv/middleware/auth.js.map +1 -0
  271. package/dist/serv/middleware/tenant.d.ts +94 -0
  272. package/dist/serv/middleware/tenant.d.ts.map +1 -0
  273. package/dist/serv/middleware/tenant.js +152 -0
  274. package/dist/serv/middleware/tenant.js.map +1 -0
  275. package/dist/serv/runtime/executor.d.ts +76 -0
  276. package/dist/serv/runtime/executor.d.ts.map +1 -0
  277. package/dist/serv/runtime/executor.js +105 -0
  278. package/dist/serv/runtime/executor.js.map +1 -0
  279. package/dist/serv/runtime/index.d.ts +8 -0
  280. package/dist/serv/runtime/index.d.ts.map +1 -0
  281. package/dist/serv/runtime/index.js +10 -0
  282. package/dist/serv/runtime/index.js.map +1 -0
  283. package/dist/serv/runtime/oauth-context.d.ts +121 -0
  284. package/dist/serv/runtime/oauth-context.d.ts.map +1 -0
  285. package/dist/serv/runtime/oauth-context.js +153 -0
  286. package/dist/serv/runtime/oauth-context.js.map +1 -0
  287. package/dist/serv/session/kv-store.d.ts +54 -0
  288. package/dist/serv/session/kv-store.d.ts.map +1 -0
  289. package/dist/serv/session/kv-store.js +149 -0
  290. package/dist/serv/session/kv-store.js.map +1 -0
  291. package/dist/serv/session/store.d.ts +113 -0
  292. package/dist/serv/session/store.d.ts.map +1 -0
  293. package/dist/serv/session/store.js +284 -0
  294. package/dist/serv/session/store.js.map +1 -0
  295. package/dist/serv/types/index.d.ts +147 -0
  296. package/dist/serv/types/index.d.ts.map +1 -0
  297. package/dist/serv/types/index.js +8 -0
  298. package/dist/serv/types/index.js.map +1 -0
  299. package/dist/serv/vault/token-vault.d.ts +102 -0
  300. package/dist/serv/vault/token-vault.d.ts.map +1 -0
  301. package/dist/serv/vault/token-vault.js +177 -0
  302. package/dist/serv/vault/token-vault.js.map +1 -0
  303. package/dist/server.d.ts +184 -0
  304. package/dist/server.d.ts.map +1 -1
  305. package/dist/server.js +1995 -86
  306. package/dist/server.js.map +1 -1
  307. package/dist/shared/cli-sections.d.ts +6 -0
  308. package/dist/shared/cli-sections.d.ts.map +1 -0
  309. package/dist/shared/cli-sections.js +16 -0
  310. package/dist/shared/cli-sections.js.map +1 -0
  311. package/dist/shared/cli-utils.d.ts +81 -0
  312. package/dist/shared/cli-utils.d.ts.map +1 -0
  313. package/dist/shared/cli-utils.js +174 -0
  314. package/dist/shared/cli-utils.js.map +1 -0
  315. package/dist/shared/config-docs.d.ts +6 -0
  316. package/dist/shared/config-docs.d.ts.map +1 -0
  317. package/dist/shared/config-docs.js +6 -0
  318. package/dist/shared/config-docs.js.map +1 -0
  319. package/dist/shared/error-handler.d.ts +128 -0
  320. package/dist/shared/error-handler.d.ts.map +1 -0
  321. package/dist/shared/error-handler.js +342 -0
  322. package/dist/shared/error-handler.js.map +1 -0
  323. package/dist/shared/logger.d.ts +42 -0
  324. package/dist/shared/logger.d.ts.map +1 -0
  325. package/dist/shared/logger.js +123 -0
  326. package/dist/shared/logger.js.map +1 -0
  327. package/dist/shared/performance.d.ts +65 -0
  328. package/dist/shared/performance.d.ts.map +1 -0
  329. package/dist/shared/performance.js +136 -0
  330. package/dist/shared/performance.js.map +1 -0
  331. package/dist/shared/task-runner.d.ts +2 -0
  332. package/dist/shared/task-runner.d.ts.map +1 -0
  333. package/dist/shared/task-runner.js +16 -0
  334. package/dist/shared/task-runner.js.map +1 -0
  335. package/dist/shared/validation.d.ts +6 -0
  336. package/dist/shared/validation.d.ts.map +1 -0
  337. package/dist/shared/validation.js +6 -0
  338. package/dist/shared/validation.js.map +1 -0
  339. package/dist/shared-utils.d.ts +63 -0
  340. package/dist/shared-utils.d.ts.map +1 -0
  341. package/dist/shared-utils.js +123 -0
  342. package/dist/shared-utils.js.map +1 -0
  343. package/dist/template-manager.d.ts +23 -2
  344. package/dist/template-manager.d.ts.map +1 -1
  345. package/dist/template-manager.js +176 -87
  346. package/dist/template-manager.js.map +1 -1
  347. package/dist/test-client.d.ts.map +1 -1
  348. package/dist/test-client.js +10 -8
  349. package/dist/test-client.js.map +1 -1
  350. package/dist/test-runner.d.ts +52 -0
  351. package/dist/test-runner.d.ts.map +1 -0
  352. package/dist/test-runner.js +785 -0
  353. package/dist/test-runner.js.map +1 -0
  354. package/dist/testing.d.ts +103 -0
  355. package/dist/testing.d.ts.map +1 -0
  356. package/dist/testing.js +163 -0
  357. package/dist/testing.js.map +1 -0
  358. package/dist/version-checker.d.ts.map +1 -1
  359. package/dist/version-checker.js +2 -2
  360. package/dist/version-checker.js.map +1 -1
  361. package/dist/version.d.ts +10 -0
  362. package/dist/version.d.ts.map +1 -0
  363. package/dist/version.js +21 -0
  364. package/dist/version.js.map +1 -0
  365. package/dist/watcher.d.ts +6 -3
  366. package/dist/watcher.d.ts.map +1 -1
  367. package/dist/watcher.js +49 -10
  368. package/dist/watcher.js.map +1 -1
  369. package/package.json +57 -7
  370. package/templates/cloudflare/worker.ts.template +381 -0
  371. package/templates/cloudflare/wrangler.toml.template +9 -0
  372. package/dist/base.d.ts +0 -58
  373. package/dist/base.d.ts.map +0 -1
  374. package/dist/base.js +0 -92
  375. package/dist/base.js.map +0 -1
  376. package/dist/dependency-manager.d.ts +0 -49
  377. package/dist/dependency-manager.d.ts.map +0 -1
  378. package/dist/dependency-manager.js +0 -165
  379. package/dist/dependency-manager.js.map +0 -1
  380. package/dist/registry-manager.d.ts +0 -76
  381. package/dist/registry-manager.d.ts.map +0 -1
  382. package/dist/registry-manager.js +0 -220
  383. package/dist/registry-manager.js.map +0 -1
  384. package/dist/schema-extractor.d.ts +0 -110
  385. package/dist/schema-extractor.d.ts.map +0 -1
  386. package/dist/schema-extractor.js +0 -727
  387. package/dist/schema-extractor.js.map +0 -1
  388. package/dist/test-marketplace-sources.d.ts +0 -5
  389. package/dist/test-marketplace-sources.d.ts.map +0 -1
  390. package/dist/test-marketplace-sources.js +0 -53
  391. package/dist/test-marketplace-sources.js.map +0 -1
  392. package/dist/types.d.ts +0 -109
  393. package/dist/types.d.ts.map +0 -1
  394. package/dist/types.js +0 -12
  395. package/dist/types.js.map +0 -1
@@ -0,0 +1,1113 @@
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
+ /**
8
+ * Generate playground HTML for interactive testing
9
+ */
10
+ export function generatePlaygroundHTML(options) {
11
+ const { name, port } = options;
12
+ return `<!DOCTYPE html>
13
+ <html lang="en">
14
+ <head>
15
+ <meta charset="UTF-8">
16
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
17
+ <title>${name} - Playground</title>
18
+ <style>
19
+ * { margin: 0; padding: 0; box-sizing: border-box; }
20
+ :root {
21
+ --bg: #0a0a0f;
22
+ --card: #12121a;
23
+ --border: #1e1e2e;
24
+ --text: #e4e4e7;
25
+ --muted: #71717a;
26
+ --accent: #6366f1;
27
+ --green: #22c55e;
28
+ --orange: #f97316;
29
+ --blue: #3b82f6;
30
+ --purple: #a855f7;
31
+ --cyan: #06b6d4;
32
+ }
33
+ body {
34
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
35
+ background: var(--bg);
36
+ color: var(--text);
37
+ min-height: 100vh;
38
+ }
39
+ .header {
40
+ background: var(--card);
41
+ border-bottom: 1px solid var(--border);
42
+ padding: 16px 24px;
43
+ display: flex;
44
+ align-items: center;
45
+ justify-content: space-between;
46
+ }
47
+ .header h1 {
48
+ font-size: 18px;
49
+ font-weight: 600;
50
+ display: flex;
51
+ align-items: center;
52
+ gap: 8px;
53
+ }
54
+ .header h1::before {
55
+ content: '';
56
+ width: 8px;
57
+ height: 8px;
58
+ background: var(--green);
59
+ border-radius: 50%;
60
+ box-shadow: 0 0 8px var(--green);
61
+ }
62
+ .badge {
63
+ background: var(--accent);
64
+ color: white;
65
+ padding: 4px 8px;
66
+ border-radius: 4px;
67
+ font-size: 12px;
68
+ }
69
+ .container {
70
+ display: grid;
71
+ grid-template-columns: 320px 1fr;
72
+ height: calc(100vh - 57px);
73
+ }
74
+ .status-panel {
75
+ background: white;
76
+ border: 1px solid var(--border);
77
+ border-radius: 20px;
78
+ padding: 20px;
79
+ margin-bottom: 20px;
80
+ box-shadow: 0 15px 30px rgba(15, 23, 42, 0.08);
81
+ }
82
+ .status-pill {
83
+ display: inline-flex;
84
+ align-items: center;
85
+ gap: 8px;
86
+ padding: 6px 14px;
87
+ border-radius: 999px;
88
+ font-weight: 600;
89
+ background: #eef2ff;
90
+ color: var(--accent);
91
+ }
92
+ .status-pill.success {
93
+ background: #dcfce7;
94
+ color: #16a34a;
95
+ }
96
+ .status-pill.error {
97
+ background: #fee2e2;
98
+ color: #ef4444;
99
+ }
100
+ .status-pill.warn {
101
+ background: #fef3c7;
102
+ color: #d97706;
103
+ }
104
+ .status-detail {
105
+ margin-top: 12px;
106
+ color: var(--muted);
107
+ font-size: 14px;
108
+ }
109
+ .status-warnings {
110
+ margin-top: 12px;
111
+ padding: 12px;
112
+ border-radius: 12px;
113
+ background: #fff7ed;
114
+ color: #b45309;
115
+ font-size: 13px;
116
+ display: none;
117
+ }
118
+ .status-grid {
119
+ margin-top: 16px;
120
+ display: grid;
121
+ grid-template-columns: repeat(4, minmax(80px, 1fr));
122
+ gap: 12px;
123
+ }
124
+ .status-card {
125
+ padding: 14px;
126
+ border: 1px solid var(--border);
127
+ border-radius: 16px;
128
+ background: #f8fafc;
129
+ }
130
+ .status-card-label {
131
+ font-size: 12px;
132
+ text-transform: uppercase;
133
+ letter-spacing: 0.08em;
134
+ color: var(--muted);
135
+ margin-bottom: 6px;
136
+ }
137
+ .status-card-value {
138
+ font-size: 20px;
139
+ font-weight: 600;
140
+ color: var(--text);
141
+ }
142
+ .sidebar {
143
+ background: var(--card);
144
+ border-right: 1px solid var(--border);
145
+ overflow-y: auto;
146
+ padding: 16px;
147
+ }
148
+ .sidebar h2 {
149
+ font-size: 12px;
150
+ text-transform: uppercase;
151
+ color: var(--muted);
152
+ margin-bottom: 12px;
153
+ letter-spacing: 0.5px;
154
+ }
155
+ .tool-item {
156
+ padding: 12px;
157
+ border: 1px solid var(--border);
158
+ border-radius: 8px;
159
+ margin-bottom: 8px;
160
+ cursor: pointer;
161
+ transition: all 0.2s;
162
+ }
163
+ .tool-item:hover, .tool-item.active {
164
+ border-color: var(--accent);
165
+ background: rgba(99, 102, 241, 0.1);
166
+ }
167
+ .tool-name {
168
+ font-weight: 500;
169
+ font-size: 14px;
170
+ margin-bottom: 4px;
171
+ display: flex;
172
+ align-items: center;
173
+ gap: 8px;
174
+ }
175
+ .tool-name .ui-badge {
176
+ background: rgba(34, 197, 94, 0.2);
177
+ color: var(--green);
178
+ padding: 2px 6px;
179
+ border-radius: 4px;
180
+ font-size: 10px;
181
+ font-weight: 600;
182
+ }
183
+ .tool-desc {
184
+ font-size: 12px;
185
+ color: var(--muted);
186
+ }
187
+ .main {
188
+ display: flex;
189
+ flex-direction: column;
190
+ overflow: hidden;
191
+ position: relative;
192
+ }
193
+ .toolbar {
194
+ padding: 16px 24px;
195
+ border-bottom: 1px solid var(--border);
196
+ display: flex;
197
+ align-items: center;
198
+ gap: 12px;
199
+ }
200
+ .toolbar h3 {
201
+ font-size: 16px;
202
+ flex: 1;
203
+ }
204
+ .btn {
205
+ padding: 8px 16px;
206
+ border-radius: 6px;
207
+ border: none;
208
+ font-size: 13px;
209
+ cursor: pointer;
210
+ transition: all 0.2s;
211
+ }
212
+ .btn-primary {
213
+ background: var(--accent);
214
+ color: white;
215
+ }
216
+ .btn-primary:hover:not(:disabled) {
217
+ background: #5558e3;
218
+ }
219
+ .btn-primary:disabled {
220
+ opacity: 0.5;
221
+ cursor: not-allowed;
222
+ }
223
+ .tabs {
224
+ display: flex;
225
+ border-bottom: 1px solid var(--border);
226
+ background: var(--card);
227
+ }
228
+ .tab {
229
+ padding: 12px 24px;
230
+ font-size: 14px;
231
+ cursor: pointer;
232
+ border-bottom: 2px solid transparent;
233
+ color: var(--muted);
234
+ transition: all 0.2s;
235
+ }
236
+ .tab:hover {
237
+ color: var(--text);
238
+ }
239
+ .tab.active {
240
+ color: var(--accent);
241
+ border-bottom-color: var(--accent);
242
+ }
243
+ .tab-content {
244
+ flex: 1;
245
+ overflow: hidden;
246
+ display: none;
247
+ }
248
+ .tab-content.active {
249
+ display: flex;
250
+ flex-direction: column;
251
+ }
252
+ .panel {
253
+ flex: 1;
254
+ padding: 20px;
255
+ overflow-y: auto;
256
+ }
257
+ .panel-header {
258
+ font-size: 12px;
259
+ text-transform: uppercase;
260
+ color: var(--muted);
261
+ margin-bottom: 12px;
262
+ letter-spacing: 0.5px;
263
+ }
264
+ .form-group {
265
+ margin-bottom: 16px;
266
+ }
267
+ .form-group label {
268
+ display: block;
269
+ font-size: 13px;
270
+ margin-bottom: 6px;
271
+ color: var(--muted);
272
+ }
273
+ .form-group input, .form-group select, .form-group textarea {
274
+ width: 100%;
275
+ padding: 10px 12px;
276
+ background: var(--card);
277
+ border: 1px solid var(--border);
278
+ border-radius: 6px;
279
+ color: var(--text);
280
+ font-size: 14px;
281
+ font-family: inherit;
282
+ }
283
+ .form-group textarea {
284
+ min-height: 80px;
285
+ resize: vertical;
286
+ }
287
+ .form-group input:focus, .form-group select:focus, .form-group textarea:focus {
288
+ outline: none;
289
+ border-color: var(--accent);
290
+ }
291
+ .form-note {
292
+ background: rgba(99, 102, 241, 0.1);
293
+ border: 1px solid rgba(99, 102, 241, 0.3);
294
+ border-radius: 8px;
295
+ padding: 12px 16px;
296
+ margin-bottom: 20px;
297
+ font-size: 12px;
298
+ color: var(--muted);
299
+ }
300
+ .form-note strong {
301
+ color: var(--accent);
302
+ }
303
+ #data-form-container {
304
+ margin-bottom: 16px;
305
+ }
306
+ .json-output {
307
+ background: var(--card);
308
+ border: 1px solid var(--border);
309
+ border-radius: 8px;
310
+ padding: 16px;
311
+ font-family: 'SF Mono', Monaco, 'Fira Code', monospace;
312
+ font-size: 13px;
313
+ white-space: pre-wrap;
314
+ overflow-x: auto;
315
+ line-height: 1.5;
316
+ }
317
+ .json-key { color: var(--cyan); }
318
+ .json-string { color: var(--green); }
319
+ .json-number { color: var(--orange); }
320
+ .json-boolean { color: var(--purple); }
321
+ .json-null { color: var(--muted); }
322
+ .json-bracket { color: var(--text); }
323
+ #ui-preview {
324
+ min-height: 200px;
325
+ }
326
+ #ui-preview iframe {
327
+ width: 100%;
328
+ border: none;
329
+ }
330
+ .empty-state {
331
+ display: flex;
332
+ flex-direction: column;
333
+ align-items: center;
334
+ justify-content: center;
335
+ height: 100%;
336
+ color: var(--muted);
337
+ text-align: center;
338
+ padding: 40px;
339
+ }
340
+ .empty-state svg {
341
+ width: 48px;
342
+ height: 48px;
343
+ margin-bottom: 16px;
344
+ opacity: 0.5;
345
+ }
346
+ .loading-overlay {
347
+ position: absolute;
348
+ inset: 0;
349
+ background: rgba(10, 10, 15, 0.8);
350
+ display: flex;
351
+ align-items: center;
352
+ justify-content: center;
353
+ z-index: 10;
354
+ }
355
+ .loading {
356
+ display: inline-block;
357
+ width: 24px;
358
+ height: 24px;
359
+ border: 3px solid var(--border);
360
+ border-top-color: var(--accent);
361
+ border-radius: 50%;
362
+ animation: spin 0.8s linear infinite;
363
+ }
364
+ .status-bar {
365
+ padding: 8px 16px;
366
+ background: var(--card);
367
+ border-top: 1px solid var(--border);
368
+ font-size: 12px;
369
+ color: var(--muted);
370
+ display: flex;
371
+ align-items: center;
372
+ gap: 8px;
373
+ }
374
+ .dot {
375
+ width: 8px;
376
+ height: 8px;
377
+ border-radius: 50%;
378
+ background: var(--muted);
379
+ display: inline-block;
380
+ }
381
+ .dot.success { background: var(--green); }
382
+ .dot.error { background: #ef4444; }
383
+ .dot.loading { background: var(--orange); animation: pulse 1s infinite; }
384
+ .dot.warn { background: #d97706; animation: pulse 1s infinite; }
385
+ .ui-overlay {
386
+ position: absolute;
387
+ inset: 0;
388
+ background: rgba(8, 9, 15, 0.65);
389
+ display: none;
390
+ align-items: center;
391
+ justify-content: center;
392
+ z-index: 30;
393
+ }
394
+ .ui-overlay.active {
395
+ display: flex;
396
+ }
397
+ .overlay-card {
398
+ background: rgba(18, 20, 30, 0.9);
399
+ border: 1px solid rgba(99, 102, 241, 0.4);
400
+ border-radius: 12px;
401
+ padding: 24px 32px;
402
+ text-align: center;
403
+ box-shadow: 0 20px 60px rgba(10, 10, 15, 0.5);
404
+ max-width: 360px;
405
+ width: 100%;
406
+ }
407
+ .overlay-spinner {
408
+ width: 36px;
409
+ height: 36px;
410
+ border: 4px solid rgba(255, 255, 255, 0.2);
411
+ border-top-color: var(--accent);
412
+ border-radius: 50%;
413
+ margin: 0 auto 16px;
414
+ animation: spin 0.8s linear infinite;
415
+ }
416
+ .overlay-progress {
417
+ display: none;
418
+ gap: 10px;
419
+ align-items: center;
420
+ margin-bottom: 12px;
421
+ }
422
+ .overlay-progress-bar {
423
+ flex: 1;
424
+ height: 8px;
425
+ background: rgba(255, 255, 255, 0.12);
426
+ border-radius: 999px;
427
+ overflow: hidden;
428
+ }
429
+ .overlay-progress-fill {
430
+ height: 100%;
431
+ width: 0;
432
+ background: var(--accent);
433
+ border-radius: inherit;
434
+ transition: width 0.2s ease;
435
+ }
436
+ .overlay-progress-percent {
437
+ font-size: 12px;
438
+ color: rgba(255, 255, 255, 0.8);
439
+ min-width: 36px;
440
+ text-align: right;
441
+ }
442
+ .overlay-title {
443
+ font-size: 16px;
444
+ font-weight: 600;
445
+ color: white;
446
+ margin-bottom: 6px;
447
+ }
448
+ .overlay-text {
449
+ font-size: 13px;
450
+ color: rgba(255, 255, 255, 0.75);
451
+ }
452
+ @keyframes spin {
453
+ to { transform: rotate(360deg); }
454
+ }
455
+ @keyframes pulse {
456
+ 0%, 100% { opacity: 1; }
457
+ 50% { opacity: 0.5; }
458
+ }
459
+ </style>
460
+ </head>
461
+ <body>
462
+ <div class="header">
463
+ <h1>${name}</h1>
464
+ <span class="badge">Playground</span>
465
+ </div>
466
+ <div class="container">
467
+ <div class="sidebar">
468
+ <h2>Tools</h2>
469
+ <div id="tools-list">Loading...</div>
470
+ </div>
471
+ <div class="main">
472
+ <div class="status-panel">
473
+ <div class="status-pill" id="status-pill">
474
+ <span class="dot loading" id="status-pill-dot"></span>
475
+ <span id="status-pill-text">Checking status…</span>
476
+ </div>
477
+ <div class="status-detail" id="status-detail">Initializing runtime…</div>
478
+ <div class="status-warnings" id="status-warning"></div>
479
+ <div class="status-grid">
480
+ <div class="status-card">
481
+ <div class="status-card-label">Methods</div>
482
+ <div class="status-card-value" id="summary-tools">0</div>
483
+ </div>
484
+ <div class="status-card">
485
+ <div class="status-card-label">Linked UI</div>
486
+ <div class="status-card-value" id="summary-ui">0</div>
487
+ </div>
488
+ <div class="status-card">
489
+ <div class="status-card-label">Prompts</div>
490
+ <div class="status-card-value" id="summary-prompts">0</div>
491
+ </div>
492
+ <div class="status-card">
493
+ <div class="status-card-label">Resources</div>
494
+ <div class="status-card-value" id="summary-resources">0</div>
495
+ </div>
496
+ </div>
497
+ </div>
498
+ <div class="toolbar">
499
+ <h3 id="selected-tool">Select a tool</h3>
500
+ <button class="btn btn-primary" id="run-btn" disabled style="display: none;">Run</button>
501
+ </div>
502
+ <div class="tabs" id="tabs" style="display: none;">
503
+ <div class="tab active" data-tab="ui">UI</div>
504
+ <div class="tab" data-tab="data">Data</div>
505
+ </div>
506
+ <div class="tab-content active" id="tab-ui">
507
+ <div class="panel">
508
+ <div id="ui-form-container"></div>
509
+ <div class="panel-header" id="ui-results-header" style="display: none;">Results</div>
510
+ <div id="ui-preview">
511
+ <div class="empty-state">
512
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
513
+ <rect x="3" y="3" width="18" height="18" rx="2" />
514
+ <path d="M3 9h18M9 21V9" />
515
+ </svg>
516
+ <p>Select a tool and fill the form to see results</p>
517
+ </div>
518
+ </div>
519
+ </div>
520
+ </div>
521
+ <div class="tab-content" id="tab-data">
522
+ <div class="panel">
523
+ <div class="panel-header">Raw JSON Data</div>
524
+ <div class="json-output" id="output">// Run a tool to see raw JSON data</div>
525
+ </div>
526
+ </div>
527
+ <div class="status-bar">
528
+ <span class="dot" id="status-dot"></span>
529
+ <span id="status-text">Ready</span>
530
+ </div>
531
+ <div class="ui-overlay" id="execution-overlay">
532
+ <div class="overlay-card">
533
+ <div class="overlay-spinner" id="overlay-spinner"></div>
534
+ <div class="overlay-progress" id="overlay-progress">
535
+ <div class="overlay-progress-bar">
536
+ <div class="overlay-progress-fill" id="overlay-progress-fill"></div>
537
+ </div>
538
+ <div class="overlay-progress-percent" id="overlay-progress-percent">0%</div>
539
+ </div>
540
+ <div class="overlay-title" id="overlay-title">Preparing tool...</div>
541
+ <div class="overlay-text" id="overlay-text">Please wait while the tool runs.</div>
542
+ </div>
543
+ </div>
544
+ </div>
545
+ </div>
546
+
547
+ <script>
548
+ let photons = [];
549
+ let tools = [];
550
+ let selectedTool = null;
551
+ let selectedPhoton = null;
552
+ let lastResult = null;
553
+ let currentProgressToken = null;
554
+ let currentRequestId = null;
555
+
556
+ const overlayElement = document.getElementById('execution-overlay');
557
+ const overlayTitle = document.getElementById('overlay-title');
558
+ const overlayText = document.getElementById('overlay-text');
559
+ const overlaySpinner = document.getElementById('overlay-spinner');
560
+ const overlayProgress = document.getElementById('overlay-progress');
561
+ const overlayProgressFill = document.getElementById('overlay-progress-fill');
562
+ const overlayProgressPercent = document.getElementById('overlay-progress-percent');
563
+ const statusElements = {
564
+ pill: document.getElementById('status-pill'),
565
+ pillDot: document.getElementById('status-pill-dot'),
566
+ pillText: document.getElementById('status-pill-text'),
567
+ detail: document.getElementById('status-detail'),
568
+ warning: document.getElementById('status-warning'),
569
+ summaryTools: document.getElementById('summary-tools'),
570
+ summaryUI: document.getElementById('summary-ui'),
571
+ summaryPrompts: document.getElementById('summary-prompts'),
572
+ summaryResources: document.getElementById('summary-resources'),
573
+ };
574
+ let statusSource = null;
575
+
576
+ function showOverlay(title, text, progress = null) {
577
+ overlayElement.classList.add('active');
578
+ overlayTitle.textContent = title || 'Working...';
579
+ overlayText.textContent = text || '';
580
+ updateOverlayProgress(progress);
581
+ }
582
+
583
+ function hideOverlay() {
584
+ overlayElement.classList.remove('active');
585
+ updateOverlayProgress(null);
586
+ }
587
+
588
+ function updateOverlayProgress(progress) {
589
+ if (typeof progress === 'number' && !Number.isNaN(progress)) {
590
+ const percent = Math.max(0, Math.min(100, Math.round(progress * 100)));
591
+ overlaySpinner.style.display = 'none';
592
+ overlayProgress.style.display = 'flex';
593
+ overlayProgressFill.style.width = percent + '%';
594
+ overlayProgressPercent.textContent = percent + '%';
595
+ } else {
596
+ overlaySpinner.style.display = 'block';
597
+ overlayProgress.style.display = 'none';
598
+ overlayProgressFill.style.width = '0%';
599
+ overlayProgressPercent.textContent = '';
600
+ }
601
+ }
602
+
603
+ async function loadTools() {
604
+ const res = await fetch('/api/photons', { signal: AbortSignal.timeout(10000) });
605
+ const data = await res.json();
606
+ photons = data.photons;
607
+ // Flatten all tools from all photons
608
+ tools = photons.flatMap(p => p.tools.map(t => ({
609
+ ...t,
610
+ photon: p.name,
611
+ photonFile: p.file
612
+ })));
613
+ renderToolsList();
614
+ }
615
+
616
+ async function loadStatus() {
617
+ try {
618
+ const res = await fetch('/api/status', { signal: AbortSignal.timeout(5000) });
619
+ const data = await res.json();
620
+ renderStatus(data);
621
+ } catch (error) {
622
+ if (statusElements.pill) {
623
+ statusElements.pill.className = 'status-pill warn';
624
+ statusElements.pillDot.className = 'dot warn';
625
+ statusElements.pillText.textContent = 'Status unavailable';
626
+ statusElements.detail.textContent = 'Unable to connect to Photon runtime.';
627
+ }
628
+ }
629
+ }
630
+
631
+ function subscribeStatus() {
632
+ if (statusSource) {
633
+ statusSource.close();
634
+ }
635
+ const source = new EventSource('/api/status-stream');
636
+ statusSource = source;
637
+ source.onmessage = (event) => {
638
+ try {
639
+ const payload = JSON.parse(event.data);
640
+ renderStatus(payload);
641
+ } catch (error) {
642
+ // ignore malformed payloads
643
+ }
644
+ };
645
+ source.onerror = () => {
646
+ source.close();
647
+ setTimeout(subscribeStatus, 3000);
648
+ };
649
+ }
650
+
651
+ function renderStatus(data) {
652
+ if (!data || !statusElements.pill) return;
653
+ const state = data.status || {};
654
+ const type = state.type || 'info';
655
+ statusElements.pill.className = 'status-pill ' + type;
656
+ const dotClass = type === 'success' ? 'dot success' : type === 'error' ? 'dot error' : type === 'warn' ? 'dot warn' : 'dot loading';
657
+ statusElements.pillDot.className = dotClass;
658
+ statusElements.pillText.textContent = state.message || 'Ready';
659
+
660
+ if (data.hotReloadDisabled) {
661
+ statusElements.detail.textContent = 'Hot reload paused after repeated errors. Restart dev server after fixing issues.';
662
+ } else if (data.devMode) {
663
+ statusElements.detail.textContent = 'Dev mode with hot reload and live playground.';
664
+ } else {
665
+ statusElements.detail.textContent = 'Standard runtime mode.';
666
+ }
667
+
668
+ const warnings = data.warnings || [];
669
+ if (warnings.length > 0) {
670
+ statusElements.warning.style.display = 'block';
671
+ statusElements.warning.innerHTML = warnings.map(w => '⚠️ ' + w).join('<br>');
672
+ } else {
673
+ statusElements.warning.style.display = 'none';
674
+ statusElements.warning.innerHTML = '';
675
+ }
676
+
677
+ const summary = data.summary || {};
678
+ statusElements.summaryTools.textContent = summary.toolCount ?? tools.length;
679
+ statusElements.summaryUI.textContent = summary.uiAssets?.length ?? 0;
680
+ statusElements.summaryPrompts.textContent = summary.promptCount ?? 0;
681
+ statusElements.summaryResources.textContent = summary.resourceCount ?? 0;
682
+ }
683
+
684
+ function renderToolsList() {
685
+ const container = document.getElementById('tools-list');
686
+ if (photons.length === 0) {
687
+ container.innerHTML = '<div style="color: var(--muted); padding: 12px; text-align: center;">No photons found</div>';
688
+ return;
689
+ }
690
+
691
+ container.innerHTML = photons.map(photon => {
692
+ const toolsHtml = photon.tools.map(t => \`
693
+ <div class="tool-item" data-tool="\${t.name}" data-photon="\${photon.name}">
694
+ <div class="tool-name">
695
+ \${t.name}
696
+ \${t.ui ? '<span class="ui-badge">UI</span>' : ''}
697
+ </div>
698
+ <div class="tool-desc">\${t.description || 'No description'}</div>
699
+ </div>
700
+ \`).join('');
701
+
702
+ return \`
703
+ <div class="photon-group">
704
+ <div class="photon-header" data-photon="\${photon.name}">
705
+ <span class="photon-toggle">▶</span>
706
+ <span class="photon-name">\${photon.name}</span>
707
+ <span class="photon-count">\${photon.tools.length}</span>
708
+ </div>
709
+ <div class="photon-tools collapsed">
710
+ \${toolsHtml}
711
+ </div>
712
+ </div>
713
+ \`;
714
+ }).join('');
715
+
716
+ // Add click handlers for photon headers
717
+ container.querySelectorAll('.photon-header').forEach(el => {
718
+ el.addEventListener('click', () => {
719
+ const toolsDiv = el.nextElementSibling;
720
+ const toggle = el.querySelector('.photon-toggle');
721
+ toolsDiv.classList.toggle('collapsed');
722
+ toggle.textContent = toolsDiv.classList.contains('collapsed') ? '▶' : '▼';
723
+ });
724
+ });
725
+
726
+ // Add click handlers for tools
727
+ container.querySelectorAll('.tool-item').forEach(el => {
728
+ el.addEventListener('click', () => {
729
+ selectedPhoton = el.dataset.photon;
730
+ selectTool(el.dataset.tool);
731
+ });
732
+ });
733
+
734
+ // Auto-expand first photon
735
+ const firstToggle = container.querySelector('.photon-toggle');
736
+ const firstTools = container.querySelector('.photon-tools');
737
+ if (firstToggle && firstTools) {
738
+ firstTools.classList.remove('collapsed');
739
+ firstToggle.textContent = '▼';
740
+ }
741
+ }
742
+
743
+ function setUIPreviewMessage(title, description) {
744
+ document.getElementById('ui-preview').innerHTML = \`
745
+ <div class="empty-state">
746
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
747
+ <rect x="3" y="3" width="18" height="18" rx="2" />
748
+ <path d="M3 9h18M9 21V9" />
749
+ </svg>
750
+ <p style="font-weight: 600; color: var(--text);">\${title}</p>
751
+ \${description ? '<p style="margin-top: 6px; color: var(--muted); font-size: 13px;">' + description + '</p>' : ''}
752
+ </div>
753
+ \`;
754
+ }
755
+
756
+ function selectTool(name) {
757
+ selectedTool = tools.find(t => t.name === name);
758
+ document.querySelectorAll('.tool-item').forEach(el => {
759
+ el.classList.toggle('active', el.dataset.tool === name);
760
+ });
761
+ document.getElementById('selected-tool').textContent = name;
762
+
763
+ // Show tabs
764
+ document.getElementById('tabs').style.display = 'flex';
765
+
766
+ // Clear previous forms/placeholders
767
+ setUIPreviewMessage('Fill the form to see results', 'Enter parameters below and run the tool.');
768
+ document.getElementById('ui-form-container').innerHTML = '';
769
+
770
+ const hasUI = Boolean(selectedTool.ui);
771
+
772
+ // Check if tool has required parameters
773
+ const props = selectedTool.inputSchema?.properties || {};
774
+ const required = selectedTool.inputSchema?.required || [];
775
+ const hasRequiredParams = required.length > 0;
776
+
777
+ // Always switch to UI tab and show form
778
+ switchTab('ui');
779
+
780
+ if (hasRequiredParams) {
781
+ showParamsForm();
782
+ } else {
783
+ // Auto-run for tools with no params
784
+ setUIPreviewMessage('Running tool...', 'Loading results...');
785
+ runTool();
786
+ }
787
+ }
788
+
789
+ function showParamsForm() {
790
+ const props = selectedTool.inputSchema?.properties || {};
791
+ const required = selectedTool.inputSchema?.required || [];
792
+
793
+ const formHtml = \`
794
+ <div class="form-note">
795
+ <strong>Input Parameters</strong><br>
796
+ Fill in the parameters below and click Run to execute the tool.
797
+ </div>
798
+ <div id="params-form">
799
+ \${Object.entries(props).map(([name, schema]) => {
800
+ const isRequired = required.includes(name);
801
+ const desc = schema.description || '';
802
+ if (schema.enum) {
803
+ return \`
804
+ <div class="form-group">
805
+ <label>\${name}\${isRequired ? ' *' : ''}</label>
806
+ <select name="\${name}">
807
+ <option value="">Select...</option>
808
+ \${schema.enum.map(v => \`<option value="\${v}">\${v}</option>\`).join('')}
809
+ </select>
810
+ \${desc ? \`<div style="font-size: 11px; color: var(--muted); margin-top: 4px;">\${desc}</div>\` : ''}
811
+ </div>
812
+ \`;
813
+ }
814
+ const inputType = schema.type === 'number' ? 'number' : 'text';
815
+ const isLongText = desc.length > 50 || name.toLowerCase().includes('content') || name.toLowerCase().includes('body');
816
+ if (isLongText && schema.type === 'string') {
817
+ return \`
818
+ <div class="form-group">
819
+ <label>\${name}\${isRequired ? ' *' : ''}</label>
820
+ <textarea name="\${name}" placeholder="\${desc}"></textarea>
821
+ </div>
822
+ \`;
823
+ }
824
+ return \`
825
+ <div class="form-group">
826
+ <label>\${name}\${isRequired ? ' *' : ''}</label>
827
+ <input type="\${inputType}" name="\${name}" placeholder="\${desc}" />
828
+ </div>
829
+ \`;
830
+ }).join('')}
831
+ </div>
832
+ <button class="btn btn-primary" onclick="runTool()" style="margin-top: 16px;">Run Tool</button>
833
+ \`;
834
+
835
+ // Always render form in UI tab
836
+ document.getElementById('ui-form-container').innerHTML = formHtml;
837
+ }
838
+
839
+ function switchTab(tabName) {
840
+ document.querySelectorAll('.tab').forEach(t => t.classList.toggle('active', t.dataset.tab === tabName));
841
+ document.querySelectorAll('.tab-content').forEach(c => c.classList.toggle('active', c.id === 'tab-' + tabName));
842
+ }
843
+
844
+ function syntaxHighlight(json) {
845
+ if (typeof json !== 'string') {
846
+ json = JSON.stringify(json, null, 2);
847
+ }
848
+ return json.replace(/("(\\\\u[a-zA-Z0-9]{4}|\\\\[^u]|[^\\\\"])*"(\\s*:)?|\\b(true|false|null)\\b|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)/g, function (match) {
849
+ let cls = 'json-number';
850
+ if (/^"/.test(match)) {
851
+ if (/:$/.test(match)) {
852
+ cls = 'json-key';
853
+ match = match.slice(0, -1) + '</span><span class="json-bracket">:</span>';
854
+ return '<span class="' + cls + '">' + match;
855
+ } else {
856
+ cls = 'json-string';
857
+ }
858
+ } else if (/true|false/.test(match)) {
859
+ cls = 'json-boolean';
860
+ } else if (/null/.test(match)) {
861
+ cls = 'json-null';
862
+ }
863
+ return '<span class="' + cls + '">' + match + '</span>';
864
+ });
865
+ }
866
+
867
+ function setStatus(status, text, progress = null) {
868
+ const dot = document.getElementById('status-dot');
869
+ const statusText = document.getElementById('status-text');
870
+ const dotState = status === 'success' ? 'success' : status === 'error' ? 'error' : status === 'warn' ? 'warn' : 'loading';
871
+ dot.className = 'dot ' + dotState;
872
+ statusText.textContent = text;
873
+
874
+ // Remove existing progress bar if any
875
+ const existingBar = document.getElementById('status-progress');
876
+ if (existingBar) existingBar.remove();
877
+
878
+ if (progress !== null) {
879
+ const bar = document.createElement('div');
880
+ bar.id = 'status-progress';
881
+ bar.style.width = '100px';
882
+ bar.style.height = '4px';
883
+ bar.style.background = 'var(--border)';
884
+ bar.style.borderRadius = '2px';
885
+ bar.style.marginLeft = '12px';
886
+ bar.style.overflow = 'hidden';
887
+
888
+ const fill = document.createElement('div');
889
+ fill.style.width = (progress * 100) + '%';
890
+ fill.style.height = '100%';
891
+ fill.style.background = 'var(--accent)';
892
+ fill.style.transition = 'width 0.2s';
893
+
894
+ bar.appendChild(fill);
895
+ statusText.parentElement.appendChild(bar);
896
+ }
897
+ }
898
+
899
+ async function runTool() {
900
+ if (!selectedTool) return;
901
+
902
+ const progressToken = 'progress_' + Date.now();
903
+ const requestId = 'req_' + Date.now();
904
+ currentProgressToken = progressToken;
905
+ currentRequestId = requestId;
906
+
907
+ setStatus('loading', 'Executing ' + selectedTool.name + '...');
908
+ showOverlay('Executing ' + selectedTool.name, 'Starting tool...');
909
+
910
+ const args = {};
911
+ document.querySelectorAll('#params-form input, #params-form select, #params-form textarea').forEach(el => {
912
+ if (el.value) {
913
+ const schema = selectedTool.inputSchema?.properties?.[el.name];
914
+ args[el.name] = schema?.type === 'number' ? Number(el.value) : el.value;
915
+ }
916
+ });
917
+
918
+ // Clear output
919
+ document.getElementById('output').textContent = '// Waiting for response...';
920
+
921
+ try {
922
+ const response = await fetch('/api/call-stream', {
923
+ method: 'POST',
924
+ body: JSON.stringify({ tool: selectedTool.name, args, progressToken, requestId }),
925
+ signal: AbortSignal.timeout(120000), // 2min for tool calls
926
+ });
927
+
928
+ if (!response.ok || !response.body) {
929
+ throw new Error('Unable to start tool execution');
930
+ }
931
+
932
+ const reader = response.body.getReader();
933
+ const decoder = new TextDecoder();
934
+ let buffer = '';
935
+ let finished = false;
936
+
937
+ while (!finished) {
938
+ const { done, value } = await reader.read();
939
+ if (done) break;
940
+
941
+ buffer += decoder.decode(value, { stream: true });
942
+ const segments = buffer.split('\\n\\n');
943
+ buffer = segments.pop() || '';
944
+
945
+ for (const segment of segments) {
946
+ const dataLine = segment.split('\\n').find(line => line.startsWith('data: '));
947
+ if (!dataLine) continue;
948
+ let payload;
949
+ try {
950
+ payload = JSON.parse(dataLine.slice(6));
951
+ } catch (e) {
952
+ console.error('Invalid payload from server', e);
953
+ continue;
954
+ }
955
+ if (handleServerMessage(payload)) {
956
+ finished = true;
957
+ break;
958
+ }
959
+ }
960
+ }
961
+ } catch (err) {
962
+ document.getElementById('output').innerHTML = '<span style="color: #ef4444;">Error: ' + err.message + '</span>';
963
+ switchTab('data');
964
+ setStatus('error', 'Error: ' + err.message);
965
+ }
966
+ }
967
+
968
+ function handleServerMessage(payload) {
969
+ if (!payload) {
970
+ return false;
971
+ }
972
+
973
+ if (payload.method === 'notifications/progress') {
974
+ const params = payload.params || {};
975
+ const total = typeof params.total === 'number' ? params.total : 100;
976
+ const rawProgress = typeof params.progress === 'number' ? params.progress : 0;
977
+ const ratio = total ? rawProgress / total : rawProgress;
978
+ const normalized = Math.max(0, Math.min(ratio <= 1 ? ratio : ratio / 100, 1));
979
+ const message = params.message || 'Processing...';
980
+ setStatus('loading', message, normalized);
981
+ showOverlay('Processing', message, normalized);
982
+ return false;
983
+ }
984
+
985
+ if (payload.method === 'notifications/status') {
986
+ const params = payload.params || {};
987
+ const statusType = params.type || 'info';
988
+ const message = params.message || 'Working...';
989
+ const target = statusType === 'success' ? 'success' : statusType === 'error' ? 'error' : 'loading';
990
+ setStatus(target, message);
991
+ if (statusType === 'error') {
992
+ showOverlay('Action needed', message);
993
+ }
994
+ return false;
995
+ }
996
+
997
+ if (payload.method === 'notifications/emit') {
998
+ const event = payload.params?.event;
999
+ if (event?.emit === 'status') {
1000
+ setStatus('loading', event.message || 'Working...');
1001
+ }
1002
+ return false;
1003
+ }
1004
+
1005
+ if (Object.prototype.hasOwnProperty.call(payload, 'id')) {
1006
+ hideOverlay();
1007
+ if (payload.error) {
1008
+ document.getElementById('output').innerHTML = '<span style="color: #ef4444;">Error: ' + (payload.error.message || JSON.stringify(payload.error)) + '</span>';
1009
+ switchTab('data');
1010
+ setStatus('error', 'Error: ' + (payload.error.message || 'Unknown error'));
1011
+ } else if (payload.result) {
1012
+ handleResult(payload.result);
1013
+ }
1014
+ return true;
1015
+ }
1016
+
1017
+ return false;
1018
+ }
1019
+
1020
+ async function handleResult(result) {
1021
+ lastResult = result.data;
1022
+
1023
+ // Update data tab with syntax highlighting
1024
+ document.getElementById('output').innerHTML = syntaxHighlight(JSON.stringify(result.data, null, 2));
1025
+
1026
+ // Clear form from UI tab
1027
+ document.getElementById('ui-form-container').innerHTML = '';
1028
+ document.getElementById('ui-results-header').style.display = 'block';
1029
+
1030
+ // If tool has linked UI, render it in iframe with bridge script
1031
+ if (selectedTool.ui) {
1032
+ const [uiRes, bridgeRes] = await Promise.all([
1033
+ fetch('/api/ui/' + selectedTool.ui.id, {
1034
+ signal: AbortSignal.timeout(10000),
1035
+ }),
1036
+ fetch('/api/platform-bridge?photon=' + encodeURIComponent(selectedTool.photon || '') + '&method=' + encodeURIComponent(selectedTool.name || ''), {
1037
+ signal: AbortSignal.timeout(10000),
1038
+ }),
1039
+ ]);
1040
+ let html = await uiRes.text();
1041
+ const bridgeScript = await bridgeRes.text();
1042
+ // Inject bridge script so iframe can use window.photon.callTool()
1043
+ if (html.includes('</head>')) {
1044
+ html = html.replace('</head>', bridgeScript + '</head>');
1045
+ } else {
1046
+ html = '<html><head>' + bridgeScript + '</head><body>' + html + '</body></html>';
1047
+ }
1048
+ const blob = new Blob([html], { type: 'text/html' });
1049
+ document.getElementById('ui-preview').innerHTML = \`<iframe src="\${URL.createObjectURL(blob)}" style="width: 100%; height: 600px; border: 1px solid var(--border); border-radius: 8px;"></iframe>\`;
1050
+ } else {
1051
+ // Auto-render data using Auto-UI components
1052
+ document.getElementById('ui-preview').innerHTML = renderAutoUI(result.data);
1053
+ }
1054
+
1055
+ setStatus('success', 'Completed successfully');
1056
+ }
1057
+
1058
+ function renderAutoUI(data) {
1059
+ // Auto-detect data structure and render appropriately
1060
+ if (Array.isArray(data)) {
1061
+ if (data.length === 0) {
1062
+ return '<div class="empty-state"><p>No results found</p></div>';
1063
+ }
1064
+ // Render as list of cards
1065
+ return \`<div style="display: flex; flex-direction: column; gap: 12px; padding: 16px;">\${data.map(item => renderCard(item)).join('')}</div>\`;
1066
+ } else if (typeof data === 'object' && data !== null) {
1067
+ // Single object - render as card
1068
+ return \`<div style="padding: 16px;">\${renderCard(data)}</div>\`;
1069
+ } else {
1070
+ // Primitive value
1071
+ return \`<div style="padding: 16px; color: var(--text);">\${String(data)}</div>\`;
1072
+ }
1073
+ }
1074
+
1075
+ function renderCard(item) {
1076
+ if (typeof item !== 'object' || item === null) {
1077
+ return \`<div style="padding: 12px; background: var(--card); border: 1px solid var(--border); border-radius: 8px;">\${String(item)}</div>\`;
1078
+ }
1079
+
1080
+ const entries = Object.entries(item);
1081
+ const title = item.title || item.name || item.id || entries[0]?.[1] || 'Item';
1082
+ const description = item.description || item.snippet || item.summary || '';
1083
+ const url = item.url || item.link || item.href || '';
1084
+
1085
+ return \`
1086
+ <div style="padding: 16px; background: var(--card); border: 1px solid var(--border); border-radius: 8px;">
1087
+ <div style="font-weight: 600; font-size: 15px; color: var(--text); margin-bottom: 6px;">\${escapeHtml(String(title))}</div>
1088
+ \${description ? \`<div style="color: var(--muted); font-size: 13px; margin-bottom: 8px;">\${escapeHtml(String(description))}</div>\` : ''}
1089
+ \${url ? \`<a href="\${escapeHtml(url)}" target="_blank" style="color: var(--accent); font-size: 12px; text-decoration: none;">View →</a>\` : ''}
1090
+ \${!description && !url ? \`<div style="color: var(--muted); font-size: 12px; margin-top: 6px;">\${entries.slice(1).map(([k, v]) => \`<div><strong>\${k}:</strong> \${String(v)}</div>\`).join('')}</div>\` : ''}
1091
+ </div>
1092
+ \`;
1093
+ }
1094
+
1095
+ function escapeHtml(text) {
1096
+ const div = document.createElement('div');
1097
+ div.textContent = text;
1098
+ return div.innerHTML;
1099
+ }
1100
+
1101
+ // Tab switching
1102
+ document.querySelectorAll('.tab').forEach(tab => {
1103
+ tab.addEventListener('click', () => switchTab(tab.dataset.tab));
1104
+ });
1105
+
1106
+ loadTools();
1107
+ loadStatus();
1108
+ subscribeStatus();
1109
+ </script>
1110
+ </body>
1111
+ </html>`;
1112
+ }
1113
+ //# sourceMappingURL=playground-html.js.map