@portel/photon 1.4.1 → 1.5.1

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 (379) hide show
  1. package/README.md +287 -1160
  2. package/dist/auto-ui/beam.d.ts +9 -0
  3. package/dist/auto-ui/beam.d.ts.map +1 -0
  4. package/dist/auto-ui/beam.js +2381 -0
  5. package/dist/auto-ui/beam.js.map +1 -0
  6. package/dist/auto-ui/components/card.d.ts +13 -0
  7. package/dist/auto-ui/components/card.d.ts.map +1 -0
  8. package/dist/auto-ui/components/card.js +64 -0
  9. package/dist/auto-ui/components/card.js.map +1 -0
  10. package/dist/auto-ui/components/form.d.ts +15 -0
  11. package/dist/auto-ui/components/form.d.ts.map +1 -0
  12. package/dist/auto-ui/components/form.js +72 -0
  13. package/dist/auto-ui/components/form.js.map +1 -0
  14. package/dist/auto-ui/components/list.d.ts +13 -0
  15. package/dist/auto-ui/components/list.d.ts.map +1 -0
  16. package/dist/auto-ui/components/list.js +58 -0
  17. package/dist/auto-ui/components/list.js.map +1 -0
  18. package/dist/auto-ui/components/progress.d.ts +18 -0
  19. package/dist/auto-ui/components/progress.d.ts.map +1 -0
  20. package/dist/auto-ui/components/progress.js +125 -0
  21. package/dist/auto-ui/components/progress.js.map +1 -0
  22. package/dist/auto-ui/components/table.d.ts +13 -0
  23. package/dist/auto-ui/components/table.d.ts.map +1 -0
  24. package/dist/auto-ui/components/table.js +82 -0
  25. package/dist/auto-ui/components/table.js.map +1 -0
  26. package/dist/auto-ui/components/tree.d.ts +13 -0
  27. package/dist/auto-ui/components/tree.d.ts.map +1 -0
  28. package/dist/auto-ui/components/tree.js +61 -0
  29. package/dist/auto-ui/components/tree.js.map +1 -0
  30. package/dist/auto-ui/daemon-tools.d.ts +45 -0
  31. package/dist/auto-ui/daemon-tools.d.ts.map +1 -0
  32. package/dist/auto-ui/daemon-tools.js +580 -0
  33. package/dist/auto-ui/daemon-tools.js.map +1 -0
  34. package/dist/auto-ui/design-system/index.d.ts +21 -0
  35. package/dist/auto-ui/design-system/index.d.ts.map +1 -0
  36. package/dist/auto-ui/design-system/index.js +27 -0
  37. package/dist/auto-ui/design-system/index.js.map +1 -0
  38. package/dist/auto-ui/design-system/tokens.d.ts +9 -0
  39. package/dist/auto-ui/design-system/tokens.d.ts.map +1 -0
  40. package/dist/auto-ui/design-system/tokens.js +27 -0
  41. package/dist/auto-ui/design-system/tokens.js.map +1 -0
  42. package/dist/auto-ui/design-system/transaction-ui.d.ts +70 -0
  43. package/dist/auto-ui/design-system/transaction-ui.d.ts.map +1 -0
  44. package/dist/auto-ui/design-system/transaction-ui.js +982 -0
  45. package/dist/auto-ui/design-system/transaction-ui.js.map +1 -0
  46. package/dist/auto-ui/frontend/index.html +84 -0
  47. package/dist/auto-ui/index.d.ts +21 -0
  48. package/dist/auto-ui/index.d.ts.map +1 -0
  49. package/dist/auto-ui/index.js +25 -0
  50. package/dist/auto-ui/index.js.map +1 -0
  51. package/dist/auto-ui/openapi-generator.d.ts +71 -0
  52. package/dist/auto-ui/openapi-generator.d.ts.map +1 -0
  53. package/dist/auto-ui/openapi-generator.js +223 -0
  54. package/dist/auto-ui/openapi-generator.js.map +1 -0
  55. package/dist/auto-ui/photon-bridge.d.ts +159 -0
  56. package/dist/auto-ui/photon-bridge.d.ts.map +1 -0
  57. package/dist/auto-ui/photon-bridge.js +262 -0
  58. package/dist/auto-ui/photon-bridge.js.map +1 -0
  59. package/dist/auto-ui/photon-host.d.ts +113 -0
  60. package/dist/auto-ui/photon-host.d.ts.map +1 -0
  61. package/dist/auto-ui/photon-host.js +284 -0
  62. package/dist/auto-ui/photon-host.js.map +1 -0
  63. package/dist/auto-ui/platform-compat.d.ts +71 -0
  64. package/dist/auto-ui/platform-compat.d.ts.map +1 -0
  65. package/dist/auto-ui/platform-compat.js +574 -0
  66. package/dist/auto-ui/platform-compat.js.map +1 -0
  67. package/dist/auto-ui/playground-html.d.ts +15 -0
  68. package/dist/auto-ui/playground-html.d.ts.map +1 -0
  69. package/dist/auto-ui/playground-html.js +1113 -0
  70. package/dist/auto-ui/playground-html.js.map +1 -0
  71. package/dist/auto-ui/playground-server.d.ts +7 -0
  72. package/dist/auto-ui/playground-server.d.ts.map +1 -0
  73. package/dist/auto-ui/playground-server.js +840 -0
  74. package/dist/auto-ui/playground-server.js.map +1 -0
  75. package/dist/auto-ui/registry.d.ts +13 -0
  76. package/dist/auto-ui/registry.d.ts.map +1 -0
  77. package/dist/auto-ui/registry.js +62 -0
  78. package/dist/auto-ui/registry.js.map +1 -0
  79. package/dist/auto-ui/renderer.d.ts +14 -0
  80. package/dist/auto-ui/renderer.d.ts.map +1 -0
  81. package/dist/auto-ui/renderer.js +88 -0
  82. package/dist/auto-ui/renderer.js.map +1 -0
  83. package/dist/auto-ui/rendering/components.d.ts +29 -0
  84. package/dist/auto-ui/rendering/components.d.ts.map +1 -0
  85. package/dist/auto-ui/rendering/components.js +773 -0
  86. package/dist/auto-ui/rendering/components.js.map +1 -0
  87. package/dist/auto-ui/rendering/field-analyzer.d.ts +48 -0
  88. package/dist/auto-ui/rendering/field-analyzer.d.ts.map +1 -0
  89. package/dist/auto-ui/rendering/field-analyzer.js +270 -0
  90. package/dist/auto-ui/rendering/field-analyzer.js.map +1 -0
  91. package/dist/auto-ui/rendering/field-renderers.d.ts +64 -0
  92. package/dist/auto-ui/rendering/field-renderers.d.ts.map +1 -0
  93. package/dist/auto-ui/rendering/field-renderers.js +317 -0
  94. package/dist/auto-ui/rendering/field-renderers.js.map +1 -0
  95. package/dist/auto-ui/rendering/index.d.ts +28 -0
  96. package/dist/auto-ui/rendering/index.d.ts.map +1 -0
  97. package/dist/auto-ui/rendering/index.js +60 -0
  98. package/dist/auto-ui/rendering/index.js.map +1 -0
  99. package/dist/auto-ui/rendering/layout-selector.d.ts +48 -0
  100. package/dist/auto-ui/rendering/layout-selector.d.ts.map +1 -0
  101. package/dist/auto-ui/rendering/layout-selector.js +352 -0
  102. package/dist/auto-ui/rendering/layout-selector.js.map +1 -0
  103. package/dist/auto-ui/rendering/template-engine.d.ts +41 -0
  104. package/dist/auto-ui/rendering/template-engine.d.ts.map +1 -0
  105. package/dist/auto-ui/rendering/template-engine.js +238 -0
  106. package/dist/auto-ui/rendering/template-engine.js.map +1 -0
  107. package/dist/auto-ui/streamable-http-transport.d.ts +79 -0
  108. package/dist/auto-ui/streamable-http-transport.d.ts.map +1 -0
  109. package/dist/auto-ui/streamable-http-transport.js +1314 -0
  110. package/dist/auto-ui/streamable-http-transport.js.map +1 -0
  111. package/dist/auto-ui/types.d.ts +310 -0
  112. package/dist/auto-ui/types.d.ts.map +1 -0
  113. package/dist/auto-ui/types.js +71 -0
  114. package/dist/auto-ui/types.js.map +1 -0
  115. package/dist/beam.bundle.js +13506 -0
  116. package/dist/beam.bundle.js.map +7 -0
  117. package/dist/claude-code-plugin.d.ts.map +1 -1
  118. package/dist/claude-code-plugin.js +30 -30
  119. package/dist/claude-code-plugin.js.map +1 -1
  120. package/dist/cli/commands/info.d.ts +11 -0
  121. package/dist/cli/commands/info.d.ts.map +1 -0
  122. package/dist/cli/commands/info.js +313 -0
  123. package/dist/cli/commands/info.js.map +1 -0
  124. package/dist/cli/commands/marketplace.d.ts +11 -0
  125. package/dist/cli/commands/marketplace.d.ts.map +1 -0
  126. package/dist/cli/commands/marketplace.js +198 -0
  127. package/dist/cli/commands/marketplace.js.map +1 -0
  128. package/dist/cli/commands/package-app.d.ts +9 -0
  129. package/dist/cli/commands/package-app.d.ts.map +1 -0
  130. package/dist/cli/commands/package-app.js +191 -0
  131. package/dist/cli/commands/package-app.js.map +1 -0
  132. package/dist/cli/commands/package.d.ts +11 -0
  133. package/dist/cli/commands/package.d.ts.map +1 -0
  134. package/dist/cli/commands/package.js +573 -0
  135. package/dist/cli/commands/package.js.map +1 -0
  136. package/dist/cli-alias.d.ts.map +1 -1
  137. package/dist/cli-alias.js +30 -28
  138. package/dist/cli-alias.js.map +1 -1
  139. package/dist/cli-formatter.d.ts +8 -24
  140. package/dist/cli-formatter.d.ts.map +1 -1
  141. package/dist/cli-formatter.js +8 -325
  142. package/dist/cli-formatter.js.map +1 -1
  143. package/dist/cli.d.ts +15 -1
  144. package/dist/cli.d.ts.map +1 -1
  145. package/dist/cli.js +1157 -1132
  146. package/dist/cli.js.map +1 -1
  147. package/dist/daemon/client.d.ts +79 -0
  148. package/dist/daemon/client.d.ts.map +1 -1
  149. package/dist/daemon/client.js +532 -8
  150. package/dist/daemon/client.js.map +1 -1
  151. package/dist/daemon/manager.d.ts +46 -12
  152. package/dist/daemon/manager.d.ts.map +1 -1
  153. package/dist/daemon/manager.js +102 -61
  154. package/dist/daemon/manager.js.map +1 -1
  155. package/dist/daemon/protocol.d.ts +62 -6
  156. package/dist/daemon/protocol.d.ts.map +1 -1
  157. package/dist/daemon/protocol.js +76 -1
  158. package/dist/daemon/protocol.js.map +1 -1
  159. package/dist/daemon/server.d.ts +6 -6
  160. package/dist/daemon/server.js +743 -133
  161. package/dist/daemon/server.js.map +1 -1
  162. package/dist/daemon/session-manager.d.ts +8 -1
  163. package/dist/daemon/session-manager.d.ts.map +1 -1
  164. package/dist/daemon/session-manager.js +32 -9
  165. package/dist/daemon/session-manager.js.map +1 -1
  166. package/dist/deploy/cloudflare.d.ts +12 -0
  167. package/dist/deploy/cloudflare.d.ts.map +1 -0
  168. package/dist/deploy/cloudflare.js +216 -0
  169. package/dist/deploy/cloudflare.js.map +1 -0
  170. package/dist/index.d.ts +1 -0
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js +3 -0
  173. package/dist/index.js.map +1 -1
  174. package/dist/loader.d.ts +168 -21
  175. package/dist/loader.d.ts.map +1 -1
  176. package/dist/loader.js +1120 -318
  177. package/dist/loader.js.map +1 -1
  178. package/dist/markdown-utils.d.ts +8 -0
  179. package/dist/markdown-utils.d.ts.map +1 -0
  180. package/dist/markdown-utils.js +63 -0
  181. package/dist/markdown-utils.js.map +1 -0
  182. package/dist/marketplace-manager.d.ts +10 -0
  183. package/dist/marketplace-manager.d.ts.map +1 -1
  184. package/dist/marketplace-manager.js +112 -28
  185. package/dist/marketplace-manager.js.map +1 -1
  186. package/dist/mcp-client.d.ts +9 -0
  187. package/dist/mcp-client.d.ts.map +1 -0
  188. package/dist/mcp-client.js +11 -0
  189. package/dist/mcp-client.js.map +1 -0
  190. package/dist/mcp-elicitation.d.ts +32 -0
  191. package/dist/mcp-elicitation.d.ts.map +1 -0
  192. package/dist/mcp-elicitation.js +26 -0
  193. package/dist/mcp-elicitation.js.map +1 -0
  194. package/dist/path-resolver.d.ts +9 -12
  195. package/dist/path-resolver.d.ts.map +1 -1
  196. package/dist/path-resolver.js +13 -43
  197. package/dist/path-resolver.js.map +1 -1
  198. package/dist/photon-cli-runner.d.ts.map +1 -1
  199. package/dist/photon-cli-runner.js +202 -77
  200. package/dist/photon-cli-runner.js.map +1 -1
  201. package/dist/photon-doc-extractor.d.ts +88 -0
  202. package/dist/photon-doc-extractor.d.ts.map +1 -1
  203. package/dist/photon-doc-extractor.js +536 -27
  204. package/dist/photon-doc-extractor.js.map +1 -1
  205. package/dist/photons/maker.photon.d.ts +182 -0
  206. package/dist/photons/maker.photon.d.ts.map +1 -0
  207. package/dist/photons/maker.photon.js +504 -0
  208. package/dist/photons/maker.photon.js.map +1 -0
  209. package/dist/photons/maker.photon.ts +626 -0
  210. package/dist/photons/marketplace.photon.d.ts +110 -0
  211. package/dist/photons/marketplace.photon.d.ts.map +1 -0
  212. package/dist/photons/marketplace.photon.js +260 -0
  213. package/dist/photons/marketplace.photon.js.map +1 -0
  214. package/dist/photons/marketplace.photon.ts +378 -0
  215. package/dist/photons/tunnel.photon.d.ts +80 -0
  216. package/dist/photons/tunnel.photon.d.ts.map +1 -0
  217. package/dist/photons/tunnel.photon.js +269 -0
  218. package/dist/photons/tunnel.photon.js.map +1 -0
  219. package/dist/photons/tunnel.photon.ts +345 -0
  220. package/dist/security-scanner.d.ts.map +1 -1
  221. package/dist/security-scanner.js +18 -15
  222. package/dist/security-scanner.js.map +1 -1
  223. package/dist/serv/auth/jwt.d.ts +89 -0
  224. package/dist/serv/auth/jwt.d.ts.map +1 -0
  225. package/dist/serv/auth/jwt.js +239 -0
  226. package/dist/serv/auth/jwt.js.map +1 -0
  227. package/dist/serv/auth/oauth.d.ts +117 -0
  228. package/dist/serv/auth/oauth.d.ts.map +1 -0
  229. package/dist/serv/auth/oauth.js +395 -0
  230. package/dist/serv/auth/oauth.js.map +1 -0
  231. package/dist/serv/auth/well-known.d.ts +60 -0
  232. package/dist/serv/auth/well-known.d.ts.map +1 -0
  233. package/dist/serv/auth/well-known.js +154 -0
  234. package/dist/serv/auth/well-known.js.map +1 -0
  235. package/dist/serv/db/d1-client.d.ts +65 -0
  236. package/dist/serv/db/d1-client.d.ts.map +1 -0
  237. package/dist/serv/db/d1-client.js +137 -0
  238. package/dist/serv/db/d1-client.js.map +1 -0
  239. package/dist/serv/db/d1-stores.d.ts +62 -0
  240. package/dist/serv/db/d1-stores.d.ts.map +1 -0
  241. package/dist/serv/db/d1-stores.js +307 -0
  242. package/dist/serv/db/d1-stores.js.map +1 -0
  243. package/dist/serv/index.d.ts +114 -0
  244. package/dist/serv/index.d.ts.map +1 -0
  245. package/dist/serv/index.js +172 -0
  246. package/dist/serv/index.js.map +1 -0
  247. package/dist/serv/local.d.ts +118 -0
  248. package/dist/serv/local.d.ts.map +1 -0
  249. package/dist/serv/local.js +392 -0
  250. package/dist/serv/local.js.map +1 -0
  251. package/dist/serv/middleware/auth.d.ts +66 -0
  252. package/dist/serv/middleware/auth.d.ts.map +1 -0
  253. package/dist/serv/middleware/auth.js +178 -0
  254. package/dist/serv/middleware/auth.js.map +1 -0
  255. package/dist/serv/middleware/tenant.d.ts +94 -0
  256. package/dist/serv/middleware/tenant.d.ts.map +1 -0
  257. package/dist/serv/middleware/tenant.js +152 -0
  258. package/dist/serv/middleware/tenant.js.map +1 -0
  259. package/dist/serv/runtime/executor.d.ts +76 -0
  260. package/dist/serv/runtime/executor.d.ts.map +1 -0
  261. package/dist/serv/runtime/executor.js +105 -0
  262. package/dist/serv/runtime/executor.js.map +1 -0
  263. package/dist/serv/runtime/index.d.ts +8 -0
  264. package/dist/serv/runtime/index.d.ts.map +1 -0
  265. package/dist/serv/runtime/index.js +10 -0
  266. package/dist/serv/runtime/index.js.map +1 -0
  267. package/dist/serv/runtime/oauth-context.d.ts +121 -0
  268. package/dist/serv/runtime/oauth-context.d.ts.map +1 -0
  269. package/dist/serv/runtime/oauth-context.js +153 -0
  270. package/dist/serv/runtime/oauth-context.js.map +1 -0
  271. package/dist/serv/session/kv-store.d.ts +54 -0
  272. package/dist/serv/session/kv-store.d.ts.map +1 -0
  273. package/dist/serv/session/kv-store.js +149 -0
  274. package/dist/serv/session/kv-store.js.map +1 -0
  275. package/dist/serv/session/store.d.ts +113 -0
  276. package/dist/serv/session/store.d.ts.map +1 -0
  277. package/dist/serv/session/store.js +284 -0
  278. package/dist/serv/session/store.js.map +1 -0
  279. package/dist/serv/types/index.d.ts +147 -0
  280. package/dist/serv/types/index.d.ts.map +1 -0
  281. package/dist/serv/types/index.js +8 -0
  282. package/dist/serv/types/index.js.map +1 -0
  283. package/dist/serv/vault/token-vault.d.ts +102 -0
  284. package/dist/serv/vault/token-vault.d.ts.map +1 -0
  285. package/dist/serv/vault/token-vault.js +177 -0
  286. package/dist/serv/vault/token-vault.js.map +1 -0
  287. package/dist/server.d.ts +173 -0
  288. package/dist/server.d.ts.map +1 -1
  289. package/dist/server.js +1622 -86
  290. package/dist/server.js.map +1 -1
  291. package/dist/shared/cli-sections.d.ts +6 -0
  292. package/dist/shared/cli-sections.d.ts.map +1 -0
  293. package/dist/shared/cli-sections.js +16 -0
  294. package/dist/shared/cli-sections.js.map +1 -0
  295. package/dist/shared/cli-utils.d.ts +81 -0
  296. package/dist/shared/cli-utils.d.ts.map +1 -0
  297. package/dist/shared/cli-utils.js +174 -0
  298. package/dist/shared/cli-utils.js.map +1 -0
  299. package/dist/shared/config-docs.d.ts +6 -0
  300. package/dist/shared/config-docs.d.ts.map +1 -0
  301. package/dist/shared/config-docs.js +6 -0
  302. package/dist/shared/config-docs.js.map +1 -0
  303. package/dist/shared/error-handler.d.ts +128 -0
  304. package/dist/shared/error-handler.d.ts.map +1 -0
  305. package/dist/shared/error-handler.js +342 -0
  306. package/dist/shared/error-handler.js.map +1 -0
  307. package/dist/shared/logger.d.ts +42 -0
  308. package/dist/shared/logger.d.ts.map +1 -0
  309. package/dist/shared/logger.js +123 -0
  310. package/dist/shared/logger.js.map +1 -0
  311. package/dist/shared/performance.d.ts +65 -0
  312. package/dist/shared/performance.d.ts.map +1 -0
  313. package/dist/shared/performance.js +136 -0
  314. package/dist/shared/performance.js.map +1 -0
  315. package/dist/shared/task-runner.d.ts +2 -0
  316. package/dist/shared/task-runner.d.ts.map +1 -0
  317. package/dist/shared/task-runner.js +16 -0
  318. package/dist/shared/task-runner.js.map +1 -0
  319. package/dist/shared/validation.d.ts +6 -0
  320. package/dist/shared/validation.d.ts.map +1 -0
  321. package/dist/shared/validation.js +6 -0
  322. package/dist/shared/validation.js.map +1 -0
  323. package/dist/shared-utils.d.ts +63 -0
  324. package/dist/shared-utils.d.ts.map +1 -0
  325. package/dist/shared-utils.js +123 -0
  326. package/dist/shared-utils.js.map +1 -0
  327. package/dist/template-manager.d.ts +23 -2
  328. package/dist/template-manager.d.ts.map +1 -1
  329. package/dist/template-manager.js +175 -86
  330. package/dist/template-manager.js.map +1 -1
  331. package/dist/test-client.d.ts.map +1 -1
  332. package/dist/test-client.js +10 -8
  333. package/dist/test-client.js.map +1 -1
  334. package/dist/test-runner.d.ts +52 -0
  335. package/dist/test-runner.d.ts.map +1 -0
  336. package/dist/test-runner.js +785 -0
  337. package/dist/test-runner.js.map +1 -0
  338. package/dist/testing.d.ts +103 -0
  339. package/dist/testing.d.ts.map +1 -0
  340. package/dist/testing.js +163 -0
  341. package/dist/testing.js.map +1 -0
  342. package/dist/version-checker.d.ts.map +1 -1
  343. package/dist/version-checker.js +2 -2
  344. package/dist/version-checker.js.map +1 -1
  345. package/dist/version.d.ts +2 -0
  346. package/dist/version.d.ts.map +1 -0
  347. package/dist/version.js +5 -0
  348. package/dist/version.js.map +1 -0
  349. package/dist/watcher.d.ts +6 -3
  350. package/dist/watcher.d.ts.map +1 -1
  351. package/dist/watcher.js +49 -10
  352. package/dist/watcher.js.map +1 -1
  353. package/package.json +47 -7
  354. package/templates/cloudflare/worker.ts.template +381 -0
  355. package/templates/cloudflare/wrangler.toml.template +9 -0
  356. package/dist/base.d.ts +0 -58
  357. package/dist/base.d.ts.map +0 -1
  358. package/dist/base.js +0 -92
  359. package/dist/base.js.map +0 -1
  360. package/dist/dependency-manager.d.ts +0 -49
  361. package/dist/dependency-manager.d.ts.map +0 -1
  362. package/dist/dependency-manager.js +0 -165
  363. package/dist/dependency-manager.js.map +0 -1
  364. package/dist/registry-manager.d.ts +0 -76
  365. package/dist/registry-manager.d.ts.map +0 -1
  366. package/dist/registry-manager.js +0 -220
  367. package/dist/registry-manager.js.map +0 -1
  368. package/dist/schema-extractor.d.ts +0 -110
  369. package/dist/schema-extractor.d.ts.map +0 -1
  370. package/dist/schema-extractor.js +0 -727
  371. package/dist/schema-extractor.js.map +0 -1
  372. package/dist/test-marketplace-sources.d.ts +0 -5
  373. package/dist/test-marketplace-sources.d.ts.map +0 -1
  374. package/dist/test-marketplace-sources.js +0 -53
  375. package/dist/test-marketplace-sources.js.map +0 -1
  376. package/dist/types.d.ts +0 -109
  377. package/dist/types.d.ts.map +0 -1
  378. package/dist/types.js +0 -12
  379. package/dist/types.js.map +0 -1
@@ -0,0 +1,626 @@
1
+ /**
2
+ * Photon Maker - Create and manage photons
3
+ * @description System photon for scaffolding and managing photons
4
+ * @internal
5
+ *
6
+ * ## Method Types
7
+ *
8
+ * This photon demonstrates two patterns for organizing methods:
9
+ *
10
+ * ### Static Methods (Global Actions)
11
+ * - Called on the class itself, no instance needed
12
+ * - In Beam UI: Appear in the Marketplace dropdown menu
13
+ * - In CLI: `photon cli maker <method>`
14
+ * - In MCP: Available as tools without instance context
15
+ * - Use for: Creating new photons, syncing marketplace, validating
16
+ *
17
+ * ### Instance Methods (Contextual Actions)
18
+ * - Called on a specific photon instance
19
+ * - In Beam UI: Appear in the per-photon gear menu
20
+ * - In CLI: Require photon context (future: `photon cli maker rename --photon serum`)
21
+ * - Use for: Renaming, describing, adding methods to a specific photon
22
+ *
23
+ * ### Generator Functions (Progress Streaming)
24
+ * - Use `async *method()` syntax for step-by-step progress
25
+ * - Yield `{ step, message }` objects for UI updates
26
+ * - Final yield should include `{ step: 'done', result }` or `{ type: 'done', result }`
27
+ *
28
+ * ### Wizard Pattern (Multi-Step UI)
29
+ * - Mark with `@wizard` JSDoc tag
30
+ * - Yield step definitions, receive user input via `yield`
31
+ * - Steps: input, select, multi-input, progress, done
32
+ *
33
+ * ## Decorators
34
+ *
35
+ * - `@internal` - Bundled with runtime, special UI treatment
36
+ * - `@wizard` - Renders as multi-step wizard instead of form
37
+ * - `@template` - Returns a prompt string (for MCP prompts)
38
+ * - `@resource` - Exposes as MCP resource with URI
39
+ */
40
+
41
+ import * as fs from 'fs/promises';
42
+ import * as path from 'path';
43
+ import * as os from 'os';
44
+ import { exec } from 'child_process';
45
+ import { promisify } from 'util';
46
+
47
+ const execAsync = promisify(exec);
48
+
49
+ /** Wizard step types using standard ask/emit protocol */
50
+ type WizardStep =
51
+ | { ask: 'text'; id: string; message: string; label?: string; placeholder?: string; hint?: string; required?: boolean }
52
+ | { ask: 'select'; id: string; message: string; options: Array<{ value: string; label: string }>; multi?: boolean }
53
+ | { emit: 'status'; message: string }
54
+ | { emit: 'result'; data: any };
55
+
56
+ export default class Maker {
57
+ private photonPath: string;
58
+ private photonName: string;
59
+
60
+ /**
61
+ * Instance is created with target photon context for per-photon operations
62
+ */
63
+ constructor(photonPath?: string) {
64
+ this.photonPath = photonPath || '';
65
+ this.photonName = photonPath ? path.basename(photonPath, '.photon.ts') : '';
66
+ }
67
+
68
+ // ============================================
69
+ // Static Methods → Marketplace Menu
70
+ // ============================================
71
+
72
+ /**
73
+ * Create a new photon
74
+ * @param name Name for the new photon (kebab-case recommended)
75
+ * @param methods Tool method names to scaffold (optional)
76
+ * @param prompts Prompt template names to scaffold (optional)
77
+ * @param resources Resource method names to scaffold (optional)
78
+ */
79
+ static async *new({
80
+ name,
81
+ methods = [],
82
+ prompts = [],
83
+ resources = [],
84
+ }: {
85
+ /** Name for the new photon */
86
+ name: string;
87
+ /** Tool method names (optional) */
88
+ methods?: string[];
89
+ /** Prompt template names (optional) */
90
+ prompts?: string[];
91
+ /** Resource method names (optional) */
92
+ resources?: string[];
93
+ }): AsyncGenerator<{ step: string; message?: string; path?: string; code?: string }> {
94
+ const workingDir = process.env.PHOTON_DIR || path.join(os.homedir(), '.photon');
95
+ const fileName = `${name}.photon.ts`;
96
+ const filePath = path.join(workingDir, fileName);
97
+
98
+ yield { step: 'checking', message: `Checking if ${fileName} exists...` };
99
+
100
+ // Check if exists
101
+ try {
102
+ await fs.access(filePath);
103
+ throw new Error(`Photon already exists: ${filePath}`);
104
+ } catch (e: any) {
105
+ if (e.code !== 'ENOENT') throw e;
106
+ }
107
+
108
+ yield { step: 'generating', message: 'Generating scaffold...' };
109
+
110
+ // Generate class name from kebab-case
111
+ const className = name
112
+ .split(/[-_]/)
113
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
114
+ .join('');
115
+
116
+ // Helper to normalize input (handles string or array)
117
+ const toArray = (input: string | string[] | undefined): string[] => {
118
+ if (!input) return [];
119
+ if (Array.isArray(input)) return input.filter(Boolean);
120
+ return input
121
+ .split(',')
122
+ .map((s) => s.trim())
123
+ .filter(Boolean);
124
+ };
125
+
126
+ // Generate all stubs
127
+ const allStubs: string[] = [];
128
+ const methodList = toArray(methods);
129
+ const promptList = toArray(prompts);
130
+ const resourceList = toArray(resources);
131
+
132
+ // Tools
133
+ if (methodList.length > 0) {
134
+ allStubs.push(...methodList.map((m) => Maker.generateMethodStub(m, 'tool')));
135
+ }
136
+
137
+ // Prompts (templates)
138
+ if (promptList.length > 0) {
139
+ allStubs.push(...promptList.map((p) => Maker.generateMethodStub(p, 'prompt')));
140
+ }
141
+
142
+ // Resources
143
+ if (resourceList.length > 0) {
144
+ allStubs.push(...resourceList.map((r) => Maker.generateMethodStub(r, 'resource')));
145
+ }
146
+
147
+ // Default if nothing specified
148
+ if (allStubs.length === 0) {
149
+ allStubs.push(Maker.generateMethodStub('example', 'tool'));
150
+ }
151
+
152
+ const code = `/**
153
+ * ${className}
154
+ * @description [Add description]
155
+ */
156
+ export default class ${className} {
157
+ ${allStubs.join('\n\n')}
158
+ }
159
+ `;
160
+
161
+ yield { step: 'writing', message: `Writing ${fileName}...` };
162
+
163
+ await fs.writeFile(filePath, code, 'utf-8');
164
+
165
+ yield { step: 'done', message: `Created ${fileName}`, path: filePath, code };
166
+ }
167
+
168
+ /**
169
+ * Validate all photons in the current directory
170
+ */
171
+ static async *validate(): AsyncGenerator<{
172
+ step: string;
173
+ photon?: string;
174
+ status?: 'valid' | 'error';
175
+ error?: string;
176
+ summary?: { valid: number; errors: number };
177
+ }> {
178
+ const workingDir = process.env.PHOTON_DIR || process.cwd();
179
+
180
+ yield { step: 'scanning', photon: undefined };
181
+
182
+ const files = await fs.readdir(workingDir);
183
+ const photonFiles = files.filter((f) => f.endsWith('.photon.ts'));
184
+
185
+ let validCount = 0;
186
+ let errorCount = 0;
187
+
188
+ for (const file of photonFiles) {
189
+ try {
190
+ const content = await fs.readFile(path.join(workingDir, file), 'utf-8');
191
+ if (content.includes('export default class')) {
192
+ validCount++;
193
+ yield { step: 'validating', photon: file, status: 'valid' };
194
+ } else {
195
+ errorCount++;
196
+ yield {
197
+ step: 'validating',
198
+ photon: file,
199
+ status: 'error',
200
+ error: 'Missing default class export',
201
+ };
202
+ }
203
+ } catch (e: any) {
204
+ errorCount++;
205
+ yield { step: 'validating', photon: file, status: 'error', error: e.message };
206
+ }
207
+ }
208
+
209
+ yield { step: 'done', summary: { valid: validCount, errors: errorCount } };
210
+ }
211
+
212
+ /**
213
+ * Guided wizard to create a new photon
214
+ * @wizard
215
+ * @param name Photon name in kebab-case (e.g., my-tools, api-wrapper)
216
+ * @returns {@label Create}
217
+ */
218
+ static async *wizard({ name }: { name: string }): AsyncGenerator<WizardStep, void, any> {
219
+ if (!name) return;
220
+
221
+ // Step 1: Description
222
+ const descriptionRaw = yield {
223
+ ask: 'text' as const,
224
+ id: 'description',
225
+ message: 'What does this photon do?',
226
+ label: 'Description',
227
+ placeholder: 'e.g. Fetches and parses web pages',
228
+ hint: 'A short description of what this photon does',
229
+ required: true,
230
+ };
231
+
232
+ // Step 2: Icon
233
+ const iconRaw = yield {
234
+ ask: 'text' as const,
235
+ id: 'icon',
236
+ message: 'Pick an emoji icon',
237
+ label: 'Icon',
238
+ placeholder: '⚡',
239
+ hint: 'An emoji icon for your photon (default: ⚡)',
240
+ required: false,
241
+ };
242
+
243
+ // Step 3: Methods
244
+ const methodsRaw = yield {
245
+ ask: 'text' as const,
246
+ id: 'methods',
247
+ message: 'Name your tool methods',
248
+ label: 'Methods',
249
+ placeholder: 'e.g. search, fetch, analyze',
250
+ hint: 'Comma-separated method names (default: example)',
251
+ required: false,
252
+ };
253
+
254
+ // Step 4: Dependencies
255
+ const depsRaw = yield {
256
+ ask: 'text' as const,
257
+ id: 'dependencies',
258
+ message: 'npm packages to use',
259
+ label: 'Dependencies',
260
+ placeholder: 'e.g. axios, cheerio',
261
+ hint: 'Comma-separated npm package names (optional)',
262
+ required: false,
263
+ };
264
+
265
+ // Progress
266
+ yield { emit: 'status' as const, message: 'Creating photon...' };
267
+
268
+ const nameStr = String(name);
269
+ const description = typeof descriptionRaw === 'string' && descriptionRaw.trim()
270
+ ? descriptionRaw.trim()
271
+ : '[Add description]';
272
+ const icon = typeof iconRaw === 'string' && iconRaw.trim() ? iconRaw.trim() : '⚡';
273
+ const workingDir = process.env.PHOTON_DIR || path.join(os.homedir(), '.photon');
274
+ const fileName = `${nameStr}.photon.ts`;
275
+ const filePath = path.join(workingDir, fileName);
276
+
277
+ // Generate class name
278
+ const className = nameStr
279
+ .split(/[-_]/)
280
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
281
+ .join('');
282
+
283
+ // Parse comma-separated lists
284
+ const parseCsv = (val: any): string[] =>
285
+ typeof val === 'string' && val.trim()
286
+ ? val.split(',').map((s) => s.trim()).filter(Boolean)
287
+ : Array.isArray(val) ? val : [];
288
+
289
+ const methodList = parseCsv(methodsRaw);
290
+ if (methodList.length === 0) methodList.push('example');
291
+
292
+ // Validate npm dependencies
293
+ const depsList = parseCsv(depsRaw);
294
+ const validDeps: Array<{ name: string; version: string }> = [];
295
+
296
+ for (const pkg of depsList) {
297
+ yield { emit: 'status' as const, message: `Checking ${pkg}...` };
298
+ const result = await Maker.validateNpmPackage(pkg);
299
+ if (result.valid && result.version) {
300
+ validDeps.push({ name: pkg, version: result.version });
301
+ yield { emit: 'status' as const, message: `✓ ${pkg}@${result.version}` };
302
+ } else {
303
+ yield { emit: 'status' as const, message: `✗ ${pkg} — not found, skipped` };
304
+ }
305
+ }
306
+
307
+ yield { emit: 'status' as const, message: 'Generating scaffold...' };
308
+
309
+ // Build imports from valid deps
310
+ const importLines = validDeps.map((d) => Maker.importForPackage(d.name));
311
+
312
+ // Build @dependencies tag value
313
+ const depsTag = validDeps.map((d) => `${d.name}@^${d.version}`).join(', ');
314
+
315
+ // Generate method stubs
316
+ const allStubs = methodList.map((m) => Maker.generateMethodStub(m, 'tool'));
317
+
318
+ // Assemble JSDoc
319
+ const jsdocLines = [
320
+ '/**',
321
+ ` * ${className} - ${description}`,
322
+ ` * @description ${description}`,
323
+ ` * @icon ${icon}`,
324
+ ];
325
+ if (depsTag) {
326
+ jsdocLines.push(` * @dependencies ${depsTag}`);
327
+ }
328
+ jsdocLines.push(' */');
329
+
330
+ // Final code assembly: imports first, then JSDoc + class
331
+ const codeParts: string[] = [];
332
+ if (importLines.length > 0) {
333
+ codeParts.push(importLines.join('\n'));
334
+ codeParts.push('');
335
+ }
336
+ codeParts.push(jsdocLines.join('\n'));
337
+ codeParts.push(`export default class ${className} {`);
338
+ codeParts.push(allStubs.join('\n\n'));
339
+ codeParts.push('}');
340
+ codeParts.push('');
341
+
342
+ const code = codeParts.join('\n');
343
+
344
+ await fs.writeFile(filePath, code, 'utf-8');
345
+
346
+ // Done
347
+ yield {
348
+ emit: 'result' as const,
349
+ data: { message: `Created ${fileName}`, path: filePath, code },
350
+ };
351
+ }
352
+
353
+ // ============================================
354
+ // Instance Methods → Per-Photon Gear Menu
355
+ // ============================================
356
+
357
+ /**
358
+ * Rename this photon
359
+ * @param name New name for the photon
360
+ * @param photonPath Path to the photon file (optional, uses instance context if not provided)
361
+ */
362
+ async rename({
363
+ name,
364
+ photonPath,
365
+ }: {
366
+ name: string;
367
+ photonPath?: string;
368
+ }): Promise<{ oldPath: string; newPath: string }> {
369
+ const targetPath = photonPath || this.photonPath;
370
+ if (!targetPath) throw new Error('No photon context - provide photonPath parameter');
371
+
372
+ const dir = path.dirname(targetPath);
373
+ const newPath = path.join(dir, `${name}.photon.ts`);
374
+
375
+ // Read content and update class name
376
+ let content = await fs.readFile(targetPath, 'utf-8');
377
+
378
+ const newClassName = name
379
+ .split(/[-_]/)
380
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
381
+ .join('');
382
+
383
+ const oldPhotonName = path.basename(targetPath, '.photon.ts');
384
+ const oldClassName = oldPhotonName
385
+ .split(/[-_]/)
386
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
387
+ .join('');
388
+
389
+ content = content.replace(new RegExp(`class ${oldClassName}`, 'g'), `class ${newClassName}`);
390
+
391
+ // Write to new path
392
+ await fs.writeFile(newPath, content, 'utf-8');
393
+
394
+ // Remove old file
395
+ await fs.unlink(targetPath);
396
+
397
+ return { oldPath: targetPath, newPath };
398
+ }
399
+
400
+ /**
401
+ * Update photon description
402
+ * @param description New description
403
+ * @param photonPath Path to the photon file (optional, uses instance context if not provided)
404
+ */
405
+ async describe({
406
+ description,
407
+ photonPath,
408
+ }: {
409
+ description: string;
410
+ photonPath?: string;
411
+ }): Promise<{ updated: boolean }> {
412
+ const targetPath = photonPath || this.photonPath;
413
+ if (!targetPath) throw new Error('No photon context - provide photonPath parameter');
414
+
415
+ let content = await fs.readFile(targetPath, 'utf-8');
416
+
417
+ // Update @description in JSDoc
418
+ if (content.includes('@description')) {
419
+ content = content.replace(/@description\s+.*/, `@description ${description}`);
420
+ } else {
421
+ // Add description to class JSDoc
422
+ content = content.replace(
423
+ /(\/\*\*[\s\S]*?)(\s*\*\/\s*export default class)/,
424
+ `$1\n * @description ${description}$2`
425
+ );
426
+ }
427
+
428
+ await fs.writeFile(targetPath, content, 'utf-8');
429
+
430
+ return { updated: true };
431
+ }
432
+
433
+ /**
434
+ * Add a new method to this photon
435
+ * @param name Method name
436
+ * @param type Method type
437
+ * @param photonPath Path to the photon file (optional, uses instance context if not provided)
438
+ */
439
+ async addmethod({
440
+ name,
441
+ type = 'tool',
442
+ photonPath,
443
+ }: {
444
+ /** Method name */
445
+ name: string;
446
+ /** Method type */
447
+ type?: 'tool' | 'prompt' | 'resource';
448
+ /** Path to the photon file */
449
+ photonPath?: string;
450
+ }): Promise<{ added: string; type: string }> {
451
+ const targetPath = photonPath || this.photonPath;
452
+ if (!targetPath) throw new Error('No photon context - provide photonPath parameter');
453
+
454
+ let content = await fs.readFile(targetPath, 'utf-8');
455
+
456
+ const methodCode = Maker.generateMethodStub(name, type);
457
+
458
+ // Insert before the closing brace of the class
459
+ const lastBraceIndex = content.lastIndexOf('}');
460
+ content =
461
+ content.slice(0, lastBraceIndex) + '\n' + methodCode + '\n' + content.slice(lastBraceIndex);
462
+
463
+ await fs.writeFile(targetPath, content, 'utf-8');
464
+
465
+ return { added: name, type };
466
+ }
467
+
468
+ /**
469
+ * Delete this photon
470
+ * @param photonPath Path to the photon file (optional, uses instance context if not provided)
471
+ */
472
+ async delete({ photonPath }: { photonPath?: string } = {}): Promise<{ deleted: string }> {
473
+ const targetPath = photonPath || this.photonPath;
474
+ if (!targetPath) throw new Error('No photon context - provide photonPath parameter');
475
+
476
+ await fs.unlink(targetPath);
477
+
478
+ return { deleted: targetPath };
479
+ }
480
+
481
+ /**
482
+ * View source code of this photon
483
+ * @param photonPath Path to the photon file (optional, uses instance context if not provided)
484
+ */
485
+ async source({ photonPath }: { photonPath?: string } = {}): Promise<{
486
+ path: string;
487
+ code: string;
488
+ }> {
489
+ const targetPath = photonPath || this.photonPath;
490
+ if (!targetPath) throw new Error('No photon context - provide photonPath parameter');
491
+
492
+ const code = await fs.readFile(targetPath, 'utf-8');
493
+
494
+ return { path: targetPath, code };
495
+ }
496
+
497
+ // ============================================
498
+ // Helper Methods
499
+ // ============================================
500
+
501
+ private static async validateNpmPackage(name: string): Promise<{ valid: boolean; version?: string }> {
502
+ try {
503
+ const { stdout } = await execAsync(`npm view ${name} version --json`, { timeout: 10000 });
504
+ const version = JSON.parse(stdout.trim());
505
+ if (typeof version === 'string') return { valid: true, version };
506
+ return { valid: false };
507
+ } catch {
508
+ return { valid: false };
509
+ }
510
+ }
511
+
512
+ private static importForPackage(pkg: string): string {
513
+ const knownImports: Record<string, string> = {
514
+ axios: `import axios from 'axios';`,
515
+ cheerio: `import * as cheerio from 'cheerio';`,
516
+ lodash: `import _ from 'lodash';`,
517
+ 'node-fetch': `import fetch from 'node-fetch';`,
518
+ chalk: `import chalk from 'chalk';`,
519
+ dayjs: `import dayjs from 'dayjs';`,
520
+ zod: `import { z } from 'zod';`,
521
+ uuid: `import { v4 as uuid } from 'uuid';`,
522
+ };
523
+ if (knownImports[pkg]) return knownImports[pkg];
524
+ // Sanitize package name to valid JS identifier
525
+ const alias = pkg.replace(/^@/, '').replace(/[^a-zA-Z0-9]/g, '_');
526
+ return `import * as ${alias} from '${pkg}';`;
527
+ }
528
+
529
+ private static paramNameForMethod(method: string): string {
530
+ const map: Record<string, string> = {
531
+ search: 'query',
532
+ fetch: 'url',
533
+ analyze: 'content',
534
+ parse: 'content',
535
+ get: 'url',
536
+ post: 'url',
537
+ create: 'name',
538
+ delete: 'id',
539
+ update: 'id',
540
+ send: 'message',
541
+ read: 'path',
542
+ write: 'path',
543
+ download: 'url',
544
+ upload: 'file',
545
+ translate: 'text',
546
+ summarize: 'text',
547
+ convert: 'input',
548
+ validate: 'input',
549
+ format: 'input',
550
+ };
551
+ return map[method] || 'input';
552
+ }
553
+
554
+ private static paramDescForMethod(method: string): string {
555
+ const map: Record<string, string> = {
556
+ search: 'Search query',
557
+ fetch: 'URL to fetch',
558
+ analyze: 'Content to analyze',
559
+ parse: 'Content to parse',
560
+ get: 'URL to request',
561
+ post: 'URL to post to',
562
+ create: 'Name to create',
563
+ delete: 'ID to delete',
564
+ update: 'ID to update',
565
+ send: 'Message to send',
566
+ read: 'File path to read',
567
+ write: 'File path to write',
568
+ download: 'URL to download',
569
+ upload: 'File to upload',
570
+ translate: 'Text to translate',
571
+ summarize: 'Text to summarize',
572
+ convert: 'Input to convert',
573
+ validate: 'Input to validate',
574
+ format: 'Input to format',
575
+ };
576
+ return map[method] || 'Input value';
577
+ }
578
+
579
+ private static generateMethodStub(name: string, type: string): string {
580
+ const indent = ' ';
581
+
582
+ if (type === 'prompt' || type === 'prompts') {
583
+ return `${indent}/**
584
+ ${indent} * ${name}
585
+ ${indent} * @template
586
+ ${indent} */
587
+ ${indent}async ${name}({
588
+ ${indent} topic
589
+ ${indent}}: {
590
+ ${indent} /** Topic or subject */
591
+ ${indent} topic: string;
592
+ ${indent}}): Promise<string> {
593
+ ${indent} return \`Prompt about: \${topic}\`;
594
+ ${indent}}`;
595
+ }
596
+
597
+ if (type === 'resource') {
598
+ return `${indent}/**
599
+ ${indent} * ${name}
600
+ ${indent} * @resource
601
+ ${indent} * @uri ${name}://default
602
+ ${indent} * @mimetype text/plain
603
+ ${indent} */
604
+ ${indent}async ${name}(): Promise<string> {
605
+ ${indent} // Replace with your resource content
606
+ ${indent} return 'Resource content here';
607
+ ${indent}}`;
608
+ }
609
+
610
+ // Default: tool
611
+ const paramName = Maker.paramNameForMethod(name);
612
+ const paramDesc = Maker.paramDescForMethod(name);
613
+
614
+ return `${indent}/**
615
+ ${indent} * ${name}
616
+ ${indent} * @param ${paramName} ${paramDesc}
617
+ ${indent} */
618
+ ${indent}async ${name}({ ${paramName} }: {
619
+ ${indent} /** ${paramDesc} */
620
+ ${indent} ${paramName}: string;
621
+ ${indent}}): Promise<{ result: string }> {
622
+ ${indent} // Replace with your logic
623
+ ${indent} return { result: ${paramName} };
624
+ ${indent}}`;
625
+ }
626
+ }