@portel/photon 1.4.0 → 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 +81 -0
  148. package/dist/daemon/client.d.ts.map +1 -1
  149. package/dist/daemon/client.js +583 -13
  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 +74 -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 +778 -117
  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 +172 -15
  175. package/dist/loader.d.ts.map +1 -1
  176. package/dist/loader.js +1132 -267
  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 +216 -73
  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 +177 -88
  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
@@ -6,15 +6,35 @@
6
6
  */
7
7
  import * as path from 'path';
8
8
  import * as fs from 'fs/promises';
9
- import { SchemaExtractor } from '@portel/photon-core';
9
+ import { SchemaExtractor, setPromptHandler, setElicitHandler, elicitReadline, } from '@portel/photon-core';
10
+ import * as readline from 'readline';
10
11
  import chalk from 'chalk';
11
12
  import { highlight } from 'cli-highlight';
12
13
  import { resolvePhotonPath } from './path-resolver.js';
13
14
  import { PhotonLoader } from './loader.js';
15
+ import { fileURLToPath } from 'url';
16
+ import { getBundledPhotonPath } from './shared-utils.js';
17
+ const __filename = fileURLToPath(import.meta.url);
18
+ const __dirname = path.dirname(__filename);
19
+ // getBundledPhotonPath is imported from shared-utils.js
20
+ /**
21
+ * Resolve photon path - checks bundled first, then user directory
22
+ */
23
+ async function resolvePhotonPathWithBundled(name) {
24
+ // Check bundled photons first
25
+ const bundledPath = getBundledPhotonPath(name, __dirname);
26
+ if (bundledPath) {
27
+ return bundledPath;
28
+ }
29
+ // Fall back to user photons
30
+ return resolvePhotonPath(name);
31
+ }
14
32
  import { PhotonDocExtractor } from './photon-doc-extractor.js';
15
33
  import { isDaemonRunning, startDaemon } from './daemon/manager.js';
16
34
  import { sendCommand, pingDaemon } from './daemon/client.js';
17
35
  import { formatOutput as baseFormatOutput, renderNone, formatKey, } from './cli-formatter.js';
36
+ import { getErrorMessage } from './shared/error-handler.js';
37
+ import { logger } from './shared/logger.js';
18
38
  /**
19
39
  * Extract all public async methods from a photon file
20
40
  */
@@ -23,7 +43,8 @@ async function extractMethods(filePath) {
23
43
  const extractor = new SchemaExtractor();
24
44
  const methods = [];
25
45
  // Extract methods using the schema extractor
26
- const methodMatches = source.matchAll(/async\s+(\w+)\s*\(([^)]*)\)/g);
46
+ // Also match async generator methods (async *methodName) and static methods
47
+ const methodMatches = source.matchAll(/(?:static\s+)?async\s+\*?\s*(\w+)\s*\(([^)]*)\)/g);
27
48
  for (const match of methodMatches) {
28
49
  const methodName = match[1];
29
50
  const methodParams = match[2];
@@ -50,7 +71,7 @@ async function extractMethods(filePath) {
50
71
  const description = descMatch
51
72
  ? descMatch[1]
52
73
  .split('\n')
53
- .map(line => line.replace(/^\s*\*\s?/, '').trim())
74
+ .map((line) => line.replace(/^\s*\*\s?/, '').trim())
54
75
  .join(' ')
55
76
  .trim()
56
77
  : undefined;
@@ -80,8 +101,8 @@ async function extractMethods(filePath) {
80
101
  }
81
102
  // Extract format hint from @format tag (structural and content formats)
82
103
  let format;
83
- // Match structural formats
84
- const structuralMatch = jsdoc.match(/@format\s+(primitive|table|tree|list|none)/i);
104
+ // Match structural formats (including card, tabs, accordion)
105
+ const structuralMatch = jsdoc.match(/@format\s+(primitive|table|tree|list|card|tabs|accordion|none)/i);
85
106
  if (structuralMatch) {
86
107
  format = structuralMatch[1].toLowerCase();
87
108
  }
@@ -106,8 +127,51 @@ async function extractMethods(filePath) {
106
127
  while ((paramMatch = paramRegex.exec(jsdoc)) !== null) {
107
128
  const paramName = paramMatch[1];
108
129
  const paramDesc = paramMatch[2].trim();
109
- // Remove JSDoc constraint tags for display
110
- const cleanDesc = paramDesc
130
+ // Extract custom label from {@label displayName} tag
131
+ const labelMatch = paramDesc.match(/\{@label\s+([^}]+)\}/);
132
+ const customLabel = labelMatch ? labelMatch[1].trim() : undefined;
133
+ // Extract {@example ...} - handle nested braces/brackets for JSON
134
+ let example;
135
+ const exampleStart = paramDesc.indexOf('{@example ');
136
+ if (exampleStart !== -1) {
137
+ const contentStart = exampleStart + '{@example '.length;
138
+ let braceDepth = 0;
139
+ let bracketDepth = 0;
140
+ let i = contentStart;
141
+ let inString = false;
142
+ while (i < paramDesc.length) {
143
+ const ch = paramDesc[i];
144
+ const prevCh = i > 0 ? paramDesc[i - 1] : '';
145
+ if (ch === '"' && prevCh !== '\\') {
146
+ inString = !inString;
147
+ }
148
+ else if (!inString) {
149
+ if (ch === '{')
150
+ braceDepth++;
151
+ else if (ch === '[')
152
+ bracketDepth++;
153
+ else if (ch === ']')
154
+ bracketDepth--;
155
+ else if (ch === '}') {
156
+ if (braceDepth === 0 && bracketDepth === 0) {
157
+ example = paramDesc.substring(contentStart, i).trim();
158
+ break;
159
+ }
160
+ braceDepth--;
161
+ }
162
+ }
163
+ i++;
164
+ }
165
+ }
166
+ // Remove {@example ...} tag (handles nested braces/brackets)
167
+ let cleanedParamDesc = paramDesc;
168
+ if (exampleStart !== -1 && example) {
169
+ // Remove the full {@example ...} tag we extracted
170
+ const tagEnd = exampleStart + '{@example '.length + example.length + 1; // +1 for closing }
171
+ cleanedParamDesc = paramDesc.substring(0, exampleStart) + paramDesc.substring(tagEnd);
172
+ }
173
+ // Remove remaining JSDoc constraint tags for display
174
+ const cleanDesc = cleanedParamDesc
111
175
  .replace(/\{@\w+[^}]*\}/g, '')
112
176
  .replace(/\(optional\)/gi, '')
113
177
  .replace(/\(default:.*?\)/gi, '')
@@ -121,13 +185,19 @@ async function extractMethods(filePath) {
121
185
  type: tsParamTypes.get(paramName) || 'any',
122
186
  optional,
123
187
  description: cleanDesc,
188
+ ...(customLabel ? { label: customLabel } : {}),
189
+ ...(example ? { example } : {}),
124
190
  });
125
191
  }
192
+ // Extract button label from @returns {@label ...} tag
193
+ const returnsMatch = jsdoc.match(/@returns?\s+.*?\{@label\s+([^}]+)\}/i);
194
+ const buttonLabel = returnsMatch ? returnsMatch[1].trim() : undefined;
126
195
  methods.push({
127
196
  name: methodName,
128
197
  params,
129
198
  description,
130
199
  ...(format ? { format } : {}),
200
+ ...(buttonLabel ? { buttonLabel } : {}),
131
201
  });
132
202
  }
133
203
  return methods;
@@ -146,7 +216,7 @@ function extractBaseType(typeStr) {
146
216
  return objectMatch[1];
147
217
  }
148
218
  // Handle unions: boolean | number -> take first primitive type
149
- const unionTypes = typeStr.split('|').map(t => t.trim());
219
+ const unionTypes = typeStr.split('|').map((t) => t.trim());
150
220
  for (const type of unionTypes) {
151
221
  if (/^(boolean|number|string)/.test(type)) {
152
222
  return type;
@@ -204,7 +274,10 @@ function formatOutput(result, formatHint) {
204
274
  hint = inlineMarkdownFormat;
205
275
  }
206
276
  if (markdownText) {
207
- const primaryBlock = buildMarkdownBlockFromPrepared(markdownText, { hint, inlineFormat: inlineMarkdownFormat });
277
+ const primaryBlock = buildMarkdownBlockFromPrepared(markdownText, {
278
+ hint,
279
+ inlineFormat: inlineMarkdownFormat,
280
+ });
208
281
  if (primaryBlock) {
209
282
  const metadata = extractMetadataFields(result);
210
283
  renderMarkdownBlocks([primaryBlock], { additionalMetadata: metadata });
@@ -216,10 +289,10 @@ function formatOutput(result, formatHint) {
216
289
  dataToFormat = result.data;
217
290
  }
218
291
  else {
219
- const otherFields = Object.keys(result).filter(k => k !== 'success' && k !== 'message' && k !== 'error');
292
+ const otherFields = Object.keys(result).filter((k) => k !== 'success' && k !== 'message' && k !== 'error');
220
293
  if (otherFields.length > 0) {
221
294
  dataToFormat = {};
222
- otherFields.forEach(k => dataToFormat[k] = result[k]);
295
+ otherFields.forEach((k) => (dataToFormat[k] = result[k]));
223
296
  }
224
297
  else {
225
298
  if (!result.message) {
@@ -236,7 +309,10 @@ function formatOutput(result, formatHint) {
236
309
  }
237
310
  dataToFormat = inline.text;
238
311
  }
239
- const markdownBlock = buildMarkdownBlockFromPrepared(dataToFormat, { hint, inlineFormat: inline?.format });
312
+ const markdownBlock = buildMarkdownBlockFromPrepared(dataToFormat, {
313
+ hint,
314
+ inlineFormat: inline?.format,
315
+ });
240
316
  if (markdownBlock) {
241
317
  renderMarkdownBlocks([markdownBlock]);
242
318
  return true;
@@ -262,7 +338,10 @@ function formatOutput(result, formatHint) {
262
338
  }
263
339
  payload = inline.text;
264
340
  }
265
- const standaloneBlock = buildMarkdownBlockFromPrepared(payload, { hint, inlineFormat: inline?.format });
341
+ const standaloneBlock = buildMarkdownBlockFromPrepared(payload, {
342
+ hint,
343
+ inlineFormat: inline?.format,
344
+ });
266
345
  if (standaloneBlock) {
267
346
  renderMarkdownBlocks([standaloneBlock]);
268
347
  return true;
@@ -287,7 +366,7 @@ function formatOutput(result, formatHint) {
287
366
  function parseCliArgs(args, params) {
288
367
  const result = {};
289
368
  // Create a map of param names to types for quick lookup
290
- const paramTypes = new Map(params.map(p => [p.name, p.type]));
369
+ const paramTypes = new Map(params.map((p) => [p.name, p.type]));
291
370
  // Handle both positional and --flag style arguments
292
371
  let positionalIndex = 0;
293
372
  for (let i = 0; i < args.length; i++) {
@@ -398,7 +477,7 @@ function looksLikeMarkdown(value) {
398
477
  /^```/m,
399
478
  /(?:^|\n)(?:-{3,}|_{3,}|\*{3,})(?:\n|$)/m,
400
479
  ];
401
- if (blockPatterns.some(pattern => pattern.test(trimmed))) {
480
+ if (blockPatterns.some((pattern) => pattern.test(trimmed))) {
402
481
  return true;
403
482
  }
404
483
  if (/\[.+?\]\(.+?\)/.test(trimmed)) {
@@ -435,7 +514,9 @@ function renderMarkdownNicely(content) {
435
514
  return `\u0000CODE${codeBlocks.length - 1}\u0000`;
436
515
  });
437
516
  // Wrap text paragraphs
438
- rendered = rendered.split('\n').map(line => {
517
+ rendered = rendered
518
+ .split('\n')
519
+ .map((line) => {
439
520
  // Skip headers, placeholders, empty lines, lists, quotes
440
521
  if (line.startsWith('#') ||
441
522
  line.includes('\u0000CODE') ||
@@ -445,7 +526,8 @@ function renderMarkdownNicely(content) {
445
526
  }
446
527
  // Wrap plain text line
447
528
  return wrapToWidth(line, termWidth).join('\n');
448
- }).join('\n');
529
+ })
530
+ .join('\n');
449
531
  // Restore code blocks and highlight
450
532
  rendered = rendered.replace(/\u0000CODE(\d+)\u0000/g, (_m, index) => {
451
533
  const block = codeBlocks[parseInt(index)];
@@ -476,7 +558,10 @@ function renderMarkdownNicely(content) {
476
558
  rendered = rendered.replace(/\*(.+?)\*/g, (_m, text) => chalk.italic(text));
477
559
  rendered = rendered.replace(/_(.+?)_/g, (_m, text) => chalk.italic(text));
478
560
  rendered = rendered.replace(/`([^`]+)`/g, (_m, code) => chalk.cyan(code));
479
- rendered = rendered.split('\n').map(line => line.trimEnd()).join('\n');
561
+ rendered = rendered
562
+ .split('\n')
563
+ .map((line) => line.trimEnd())
564
+ .join('\n');
480
565
  rendered = rendered.replace(/\n{3,}/g, '\n\n');
481
566
  console.log(rendered.trim());
482
567
  }
@@ -504,12 +589,10 @@ function convertFrontMatterToMarkdown(markdown) {
504
589
  return { markdown: prefix + text, metadata, hadFrontMatter };
505
590
  }
506
591
  function frontMatterToTable(parsed) {
507
- const rows = Object.entries(parsed).map(([key, value]) => `| ${escapePipes(key)} | ${escapePipes(value)} |`).join('\n');
508
- return [
509
- '| Field | Value |',
510
- '| --- | --- |',
511
- rows,
512
- ].join('\n');
592
+ const rows = Object.entries(parsed)
593
+ .map(([key, value]) => `| ${escapePipes(key)} | ${escapePipes(value)} |`)
594
+ .join('\n');
595
+ return ['| Field | Value |', '| --- | --- |', rows].join('\n');
513
596
  }
514
597
  function escapePipes(text) {
515
598
  return text.replace(/\|/g, '\\|');
@@ -820,7 +903,7 @@ function renderMarkdownTableBlock(block) {
820
903
  const rows = lines
821
904
  .slice(2)
822
905
  .map(parseMarkdownTableRow)
823
- .filter(row => row.length === header.length);
906
+ .filter((row) => row.length === header.length);
824
907
  if (!rows.length) {
825
908
  return block;
826
909
  }
@@ -832,18 +915,18 @@ function parseMarkdownTableRow(line) {
832
915
  .replace(/^\|/, '')
833
916
  .replace(/\|$/, '')
834
917
  .split('|')
835
- .map(cell => cell.trim());
918
+ .map((cell) => cell.trim());
836
919
  }
837
920
  function renderGenericTable(headers, rows) {
838
921
  if (!headers.length) {
839
- return rows.map(row => row.join(' | ')).join('\n');
922
+ return rows.map((row) => row.join(' | ')).join('\n');
840
923
  }
841
924
  const termWidth = process.stdout.columns || 80;
842
925
  const columns = headers.length;
843
926
  const baseOverhead = 2 * columns + (columns - 1) + 2; // padding + connectors + borders
844
927
  const maxAvailable = Math.max(columns, termWidth - baseOverhead);
845
- const colWidths = headers.map(header => Math.max(visibleLength(header), 3));
846
- rows.forEach(row => {
928
+ const colWidths = headers.map((header) => Math.max(visibleLength(header), 3));
929
+ rows.forEach((row) => {
847
930
  row.forEach((cell, idx) => {
848
931
  const width = visibleLength(cell ?? '');
849
932
  if (width > (colWidths[idx] || 0)) {
@@ -863,13 +946,13 @@ function renderGenericTable(headers, rows) {
863
946
  }
864
947
  colWidths[maxIdx]--;
865
948
  }
866
- const wrappedRows = [headers, ...rows].map(row => row.map((cell, idx) => wrapToWidth(cell ?? '', colWidths[idx] || 1)));
867
- const horizontal = colWidths.map(width => '─'.repeat(width + 2));
949
+ const wrappedRows = [headers, ...rows].map((row) => row.map((cell, idx) => wrapToWidth(cell ?? '', colWidths[idx] || 1)));
950
+ const horizontal = colWidths.map((width) => '─'.repeat(width + 2));
868
951
  const top = `┌${horizontal.join('┬')}┐`;
869
952
  const mid = `├${horizontal.join('┼')}┤`;
870
953
  const bottom = `└${horizontal.join('┴')}┘`;
871
954
  const formatWrappedRow = (wrappedCells) => {
872
- const maxLines = Math.max(...wrappedCells.map(cell => cell.length));
955
+ const maxLines = Math.max(...wrappedCells.map((cell) => cell.length));
873
956
  const lines = [];
874
957
  for (let lineIdx = 0; lineIdx < maxLines; lineIdx++) {
875
958
  const parts = wrappedCells.map((cellLines, idx) => {
@@ -891,6 +974,16 @@ function renderGenericTable(headers, rows) {
891
974
  });
892
975
  return output.join('\n');
893
976
  }
977
+ /**
978
+ * Format camelCase/PascalCase to "Title Case With Spaces"
979
+ */
980
+ function formatLabel(name) {
981
+ return name
982
+ .replace(/([A-Z])/g, ' $1') // Add space before capitals
983
+ .replace(/([a-zA-Z])(\d)/g, '$1 $2') // Add space before numbers
984
+ .replace(/^./, (str) => str.toUpperCase()) // Capitalize first letter
985
+ .trim();
986
+ }
894
987
  /**
895
988
  * Print help for a specific method
896
989
  */
@@ -898,11 +991,11 @@ function printMethodHelp(photonName, method) {
898
991
  console.log(`\nNAME:`);
899
992
  console.log(` ${method.name} - ${method.description || 'No description'}\n`);
900
993
  console.log(`USAGE:`);
901
- const requiredParams = method.params.filter(p => !p.optional);
902
- const optionalParams = method.params.filter(p => p.optional);
994
+ const requiredParams = method.params.filter((p) => !p.optional);
995
+ const optionalParams = method.params.filter((p) => p.optional);
903
996
  let usage = ` photon cli ${photonName} ${method.name}`;
904
997
  if (requiredParams.length > 0) {
905
- usage += ' ' + requiredParams.map(p => `--${p.name} <value>`).join(' ');
998
+ usage += ' ' + requiredParams.map((p) => `--${p.name} <value>`).join(' ');
906
999
  }
907
1000
  if (optionalParams.length > 0) {
908
1001
  usage += ' [options]';
@@ -912,20 +1005,32 @@ function printMethodHelp(photonName, method) {
912
1005
  if (requiredParams.length > 0) {
913
1006
  console.log(`REQUIRED:`);
914
1007
  for (const param of requiredParams) {
915
- console.log(` --${param.name}`);
1008
+ // Show custom label or formatted name
1009
+ const displayLabel = param.label || formatLabel(param.name);
1010
+ console.log(` --${param.name} (${displayLabel})`);
916
1011
  if (param.description) {
917
1012
  console.log(` ${param.description}`);
918
1013
  }
1014
+ // Show example for complex types (JSON)
1015
+ if (param.example) {
1016
+ console.log(` Example: ${param.example}`);
1017
+ }
919
1018
  }
920
1019
  console.log('');
921
1020
  }
922
1021
  if (optionalParams.length > 0) {
923
1022
  console.log(`OPTIONS:`);
924
1023
  for (const param of optionalParams) {
925
- console.log(` --${param.name}`);
1024
+ // Show custom label or formatted name
1025
+ const displayLabel = param.label || formatLabel(param.name);
1026
+ console.log(` --${param.name} (${displayLabel})`);
926
1027
  if (param.description) {
927
1028
  console.log(` ${param.description}`);
928
1029
  }
1030
+ // Show example for complex types (JSON)
1031
+ if (param.example) {
1032
+ console.log(` Example: ${param.example}`);
1033
+ }
929
1034
  }
930
1035
  console.log('');
931
1036
  }
@@ -935,7 +1040,7 @@ function printMethodHelp(photonName, method) {
935
1040
  }
936
1041
  console.log(`EXAMPLE:`);
937
1042
  if (requiredParams.length > 0) {
938
- const exampleParams = requiredParams.map(p => `--${p.name} <value>`).join(' ');
1043
+ const exampleParams = requiredParams.map((p) => `--${p.name} <value>`).join(' ');
939
1044
  console.log(` photon cli ${photonName} ${method.name} ${exampleParams}\n`);
940
1045
  }
941
1046
  else {
@@ -947,9 +1052,9 @@ function printMethodHelp(photonName, method) {
947
1052
  */
948
1053
  export async function listMethods(photonName) {
949
1054
  try {
950
- const resolvedPath = await resolvePhotonPath(photonName);
1055
+ const resolvedPath = await resolvePhotonPathWithBundled(photonName);
951
1056
  if (!resolvedPath) {
952
- console.error(`❌ Photon '${photonName}' not found`);
1057
+ logger.error(`Photon '${photonName}' not found`);
953
1058
  console.error(`\nMake sure the photon is installed in ~/.photon/`);
954
1059
  process.exit(1);
955
1060
  }
@@ -960,7 +1065,7 @@ export async function listMethods(photonName) {
960
1065
  // Print commands
961
1066
  console.log(`COMMANDS:`);
962
1067
  // Find longest method name for alignment
963
- const maxLength = Math.max(...methods.map(m => m.name.length));
1068
+ const maxLength = Math.max(...methods.map((m) => m.name.length));
964
1069
  for (const method of methods) {
965
1070
  const padding = ' '.repeat(maxLength - method.name.length + 4);
966
1071
  const description = method.description || 'No description';
@@ -975,9 +1080,9 @@ export async function listMethods(photonName) {
975
1080
  // Show first 3 methods as examples
976
1081
  const exampleMethods = methods.slice(0, 3);
977
1082
  for (const method of exampleMethods) {
978
- const requiredParams = method.params.filter(p => !p.optional);
1083
+ const requiredParams = method.params.filter((p) => !p.optional);
979
1084
  if (requiredParams.length > 0) {
980
- const paramStr = requiredParams.map(p => `--${p.name} <value>`).join(' ');
1085
+ const paramStr = requiredParams.map((p) => `--${p.name} <value>`).join(' ');
981
1086
  console.log(` photon cli ${photonName} ${method.name} ${paramStr}`);
982
1087
  }
983
1088
  else {
@@ -988,7 +1093,7 @@ export async function listMethods(photonName) {
988
1093
  }
989
1094
  }
990
1095
  catch (error) {
991
- console.error(`❌ Error: ${error.message}`);
1096
+ logger.error(`Error: ${getErrorMessage(error)}`);
992
1097
  process.exit(1);
993
1098
  }
994
1099
  }
@@ -996,11 +1101,27 @@ export async function listMethods(photonName) {
996
1101
  * Run a photon method from CLI
997
1102
  */
998
1103
  export async function runMethod(photonName, methodName, args) {
1104
+ // Set up readline prompt handler for CLI
1105
+ setPromptHandler(async (message, defaultValue) => {
1106
+ return new Promise((resolve) => {
1107
+ const rl = readline.createInterface({
1108
+ input: process.stdin,
1109
+ output: process.stdout,
1110
+ });
1111
+ const prompt = defaultValue ? `${message} [${defaultValue}]: ` : `${message}: `;
1112
+ rl.question(prompt, (answer) => {
1113
+ rl.close();
1114
+ resolve(answer || defaultValue || null);
1115
+ });
1116
+ });
1117
+ });
1118
+ // Set up readline elicit handler for CLI (confirm, select, etc.)
1119
+ setElicitHandler(elicitReadline);
999
1120
  try {
1000
1121
  // Resolve photon path
1001
- const resolvedPath = await resolvePhotonPath(photonName);
1122
+ const resolvedPath = await resolvePhotonPathWithBundled(photonName);
1002
1123
  if (!resolvedPath) {
1003
- console.error(`❌ Photon '${photonName}' not found`);
1124
+ logger.error(`Photon '${photonName}' not found`);
1004
1125
  console.error(`\nMake sure the photon is installed in ~/.photon/`);
1005
1126
  process.exit(1);
1006
1127
  }
@@ -1013,10 +1134,10 @@ export async function runMethod(photonName, methodName, args) {
1013
1134
  await listMethods(photonName);
1014
1135
  return;
1015
1136
  }
1016
- const method = methods.find(m => m.name === methodName);
1137
+ const method = methods.find((m) => m.name === methodName);
1017
1138
  if (!method) {
1018
- console.error(`❌ Method '${methodName}' not found in ${photonName}`);
1019
- console.error(`\nAvailable methods: ${methods.map(m => m.name).join(', ')}`);
1139
+ logger.error(`Method '${methodName}' not found in ${photonName}`);
1140
+ console.error(`\nAvailable methods: ${methods.map((m) => m.name).join(', ')}`);
1020
1141
  console.error(`\nRun 'photon cli ${photonName}' to see all methods`);
1021
1142
  process.exit(1);
1022
1143
  }
@@ -1027,7 +1148,14 @@ export async function runMethod(photonName, methodName, args) {
1027
1148
  }
1028
1149
  // Check for --json flag
1029
1150
  const jsonOutput = args.includes('--json');
1030
- const filteredArgs = args.filter(arg => arg !== '--json');
1151
+ // Check for --resume <runId> flag
1152
+ let resumeRunId;
1153
+ const resumeIndex = args.indexOf('--resume');
1154
+ if (resumeIndex !== -1 && args[resumeIndex + 1]) {
1155
+ resumeRunId = args[resumeIndex + 1];
1156
+ }
1157
+ // Filter out special flags before parsing method args
1158
+ const filteredArgs = args.filter((arg, i) => arg !== '--json' && arg !== '--resume' && (resumeIndex === -1 || i !== resumeIndex + 1));
1031
1159
  // Parse arguments
1032
1160
  const parsedArgs = parseCliArgs(filteredArgs, method.params);
1033
1161
  // Validate required parameters
@@ -1038,8 +1166,10 @@ export async function runMethod(photonName, methodName, args) {
1038
1166
  }
1039
1167
  }
1040
1168
  if (missing.length > 0) {
1041
- console.error(`❌ Missing required parameters: ${missing.join(', ')}`);
1042
- console.error(`\nUsage: photon cli ${photonName} ${methodName} ${method.params.map(p => p.optional ? `[--${p.name}]` : `--${p.name} <value>`).join(' ')}`);
1169
+ logger.error(`Missing required parameters: ${missing.join(', ')}`);
1170
+ console.error(`\nUsage: photon cli ${photonName} ${methodName} ${method.params
1171
+ .map((p) => (p.optional ? `[--${p.name}]` : `--${p.name} <value>`))
1172
+ .join(' ')}`);
1043
1173
  process.exit(1);
1044
1174
  }
1045
1175
  // Check if photon is stateful
@@ -1054,14 +1184,14 @@ export async function runMethod(photonName, methodName, args) {
1054
1184
  // Wait for daemon to be ready
1055
1185
  let ready = false;
1056
1186
  for (let i = 0; i < 10; i++) {
1057
- await new Promise(resolve => setTimeout(resolve, 500));
1187
+ await new Promise((resolve) => setTimeout(resolve, 500));
1058
1188
  if (await pingDaemon(photonName)) {
1059
1189
  ready = true;
1060
1190
  break;
1061
1191
  }
1062
1192
  }
1063
1193
  if (!ready) {
1064
- console.error(`❌ Failed to start daemon for ${photonName}`);
1194
+ logger.error(`Failed to start daemon for ${photonName}`);
1065
1195
  process.exit(1);
1066
1196
  }
1067
1197
  }
@@ -1072,40 +1202,53 @@ export async function runMethod(photonName, methodName, args) {
1072
1202
  // STATELESS PATH: Direct execution
1073
1203
  const loader = new PhotonLoader(false); // verbose=false for CLI mode
1074
1204
  const photonInstance = await loader.loadFile(resolvedPath);
1075
- // Call the method
1076
- result = await loader.executeTool(photonInstance, methodName, parsedArgs);
1205
+ // Print resume message before execution
1206
+ if (resumeRunId) {
1207
+ console.log(`Resuming workflow ${resumeRunId}...`);
1208
+ }
1209
+ // Call the method (with optional resume)
1210
+ result = await loader.executeTool(photonInstance, methodName, parsedArgs, { resumeRunId });
1077
1211
  }
1212
+ // Check if this was a stateful workflow execution
1213
+ const isStateful = result && typeof result === 'object' && result._stateful === true;
1214
+ const actualResult = isStateful ? result.result : result;
1078
1215
  // Display result
1079
1216
  if (jsonOutput) {
1080
- const jsonStr = JSON.stringify(result, null, 2);
1217
+ // For JSON output, include workflow metadata if stateful
1218
+ const outputData = isStateful ? { ...result, result: actualResult } : actualResult;
1219
+ const jsonStr = JSON.stringify(outputData, null, 2);
1081
1220
  baseFormatOutput(jsonStr, 'json');
1082
1221
  // Check for errors in JSON output too
1083
- if (result && typeof result === 'object' && result.success === false) {
1222
+ if (actualResult && typeof actualResult === 'object' && actualResult.success === false) {
1084
1223
  process.exit(1);
1085
1224
  }
1086
1225
  }
1087
1226
  else {
1088
- const formatHint = method.format || (looksLikeMarkdown(result) ? 'markdown' : undefined);
1089
- const success = formatOutput(result, formatHint);
1227
+ const formatHint = method.format || (looksLikeMarkdown(actualResult) ? 'markdown' : undefined);
1228
+ const success = formatOutput(actualResult, formatHint);
1090
1229
  if (!success) {
1091
1230
  process.exit(1);
1092
1231
  }
1232
+ // Show run ID for stateful workflows
1233
+ if (isStateful && result.runId) {
1234
+ console.log('');
1235
+ if (result.resumed && result.resumedFromStep !== undefined) {
1236
+ console.log(`Resumed from step ${result.resumedFromStep}, completed ${result.checkpointsCompleted} checkpoints`);
1237
+ }
1238
+ console.log(`Run ID: ${result.runId}`);
1239
+ }
1093
1240
  }
1094
1241
  }
1095
1242
  catch (error) {
1096
- // User-friendly error messages without stack traces
1097
- const errorMsg = error.message || 'Unknown error occurred';
1098
- // Provide helpful context based on error type
1099
- if (errorMsg.includes('timeout')) {
1100
- console.log(' Request timed out. The TV may be unreachable or the operation took too long.');
1101
- console.log('💡 Check that your TV is on and connected to the network.');
1102
- }
1103
- else if (errorMsg.includes('Connection error') || errorMsg.includes('Connection closed')) {
1104
- console.log('❌ Failed to communicate with the TV.');
1105
- console.log('💡 Try reconnecting with: photon cli lg-remote connect --ip <tv-ip>');
1106
- }
1107
- else {
1108
- console.log(`❌ ${errorMsg}`);
1243
+ // Check for custom user-facing message from photon
1244
+ // Photons can throw: throw Object.assign(new Error('internal'), { userMessage: 'friendly msg', hint: 'try this' })
1245
+ const userMessage = (error && typeof error === 'object' && 'userMessage' in error && error.userMessage) ||
1246
+ getErrorMessage(error) ||
1247
+ 'Unknown error occurred';
1248
+ const hint = error && typeof error === 'object' && 'hint' in error ? error.hint : undefined;
1249
+ logger.error(`${userMessage}`);
1250
+ if (hint) {
1251
+ console.error(`💡 ${hint}`);
1109
1252
  }
1110
1253
  process.exit(1);
1111
1254
  }