@portel/photon 1.22.0 → 1.23.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 (211) hide show
  1. package/README.md +19 -8
  2. package/dist/a2ui/mapper.d.ts +40 -0
  3. package/dist/a2ui/mapper.d.ts.map +1 -0
  4. package/dist/a2ui/mapper.js +286 -0
  5. package/dist/a2ui/mapper.js.map +1 -0
  6. package/dist/a2ui/types.d.ts +129 -0
  7. package/dist/a2ui/types.d.ts.map +1 -0
  8. package/dist/a2ui/types.js +20 -0
  9. package/dist/a2ui/types.js.map +1 -0
  10. package/dist/ag-ui/adapter.d.ts +9 -1
  11. package/dist/ag-ui/adapter.d.ts.map +1 -1
  12. package/dist/ag-ui/adapter.js +33 -16
  13. package/dist/ag-ui/adapter.js.map +1 -1
  14. package/dist/auto-ui/beam/routes/api-daemon.d.ts +18 -0
  15. package/dist/auto-ui/beam/routes/api-daemon.d.ts.map +1 -0
  16. package/dist/auto-ui/beam/routes/api-daemon.js +118 -0
  17. package/dist/auto-ui/beam/routes/api-daemon.js.map +1 -0
  18. package/dist/auto-ui/beam.d.ts.map +1 -1
  19. package/dist/auto-ui/beam.js +34 -34
  20. package/dist/auto-ui/beam.js.map +1 -1
  21. package/dist/auto-ui/bridge/renderers.d.ts.map +1 -1
  22. package/dist/auto-ui/bridge/renderers.js +371 -0
  23. package/dist/auto-ui/bridge/renderers.js.map +1 -1
  24. package/dist/auto-ui/streamable-http-transport.d.ts.map +1 -1
  25. package/dist/auto-ui/streamable-http-transport.js +38 -1
  26. package/dist/auto-ui/streamable-http-transport.js.map +1 -1
  27. package/dist/auto-ui/types.d.ts +19 -0
  28. package/dist/auto-ui/types.d.ts.map +1 -1
  29. package/dist/auto-ui/types.js.map +1 -1
  30. package/dist/beam.bundle.js +757 -107
  31. package/dist/beam.bundle.js.map +4 -4
  32. package/dist/cli/commands/beam.d.ts.map +1 -1
  33. package/dist/cli/commands/beam.js +2 -0
  34. package/dist/cli/commands/beam.js.map +1 -1
  35. package/dist/cli/commands/build.d.ts.map +1 -1
  36. package/dist/cli/commands/build.js +2 -0
  37. package/dist/cli/commands/build.js.map +1 -1
  38. package/dist/cli/commands/doctor.d.ts.map +1 -1
  39. package/dist/cli/commands/doctor.js +92 -3
  40. package/dist/cli/commands/doctor.js.map +1 -1
  41. package/dist/cli/commands/host.d.ts.map +1 -1
  42. package/dist/cli/commands/host.js +9 -1
  43. package/dist/cli/commands/host.js.map +1 -1
  44. package/dist/cli/commands/info.d.ts.map +1 -1
  45. package/dist/cli/commands/info.js +7 -3
  46. package/dist/cli/commands/info.js.map +1 -1
  47. package/dist/cli/commands/init.d.ts.map +1 -1
  48. package/dist/cli/commands/init.js +4 -0
  49. package/dist/cli/commands/init.js.map +1 -1
  50. package/dist/cli/commands/maker.d.ts +8 -0
  51. package/dist/cli/commands/maker.d.ts.map +1 -1
  52. package/dist/cli/commands/maker.js +113 -46
  53. package/dist/cli/commands/maker.js.map +1 -1
  54. package/dist/cli/commands/marketplace.d.ts.map +1 -1
  55. package/dist/cli/commands/marketplace.js +7 -1
  56. package/dist/cli/commands/marketplace.js.map +1 -1
  57. package/dist/cli/commands/mcp.d.ts +10 -0
  58. package/dist/cli/commands/mcp.d.ts.map +1 -1
  59. package/dist/cli/commands/mcp.js +215 -4
  60. package/dist/cli/commands/mcp.js.map +1 -1
  61. package/dist/cli/commands/package.d.ts.map +1 -1
  62. package/dist/cli/commands/package.js +33 -15
  63. package/dist/cli/commands/package.js.map +1 -1
  64. package/dist/cli/commands/ps.d.ts +16 -0
  65. package/dist/cli/commands/ps.d.ts.map +1 -0
  66. package/dist/cli/commands/ps.js +267 -0
  67. package/dist/cli/commands/ps.js.map +1 -0
  68. package/dist/cli/commands/run.d.ts.map +1 -1
  69. package/dist/cli/commands/run.js +7 -0
  70. package/dist/cli/commands/run.js.map +1 -1
  71. package/dist/cli/commands/update.d.ts.map +1 -1
  72. package/dist/cli/commands/update.js +14 -4
  73. package/dist/cli/commands/update.js.map +1 -1
  74. package/dist/cli/index.d.ts.map +1 -1
  75. package/dist/cli/index.js +9 -4
  76. package/dist/cli/index.js.map +1 -1
  77. package/dist/context-store.d.ts +4 -4
  78. package/dist/context-store.d.ts.map +1 -1
  79. package/dist/context-store.js +20 -17
  80. package/dist/context-store.js.map +1 -1
  81. package/dist/context.d.ts +5 -4
  82. package/dist/context.d.ts.map +1 -1
  83. package/dist/context.js +68 -14
  84. package/dist/context.js.map +1 -1
  85. package/dist/daemon/client.d.ts +60 -0
  86. package/dist/daemon/client.d.ts.map +1 -1
  87. package/dist/daemon/client.js +76 -0
  88. package/dist/daemon/client.js.map +1 -1
  89. package/dist/daemon/execution-history-sqlite.d.ts +50 -0
  90. package/dist/daemon/execution-history-sqlite.d.ts.map +1 -0
  91. package/dist/daemon/execution-history-sqlite.js +165 -0
  92. package/dist/daemon/execution-history-sqlite.js.map +1 -0
  93. package/dist/daemon/execution-history.d.ts +78 -0
  94. package/dist/daemon/execution-history.d.ts.map +1 -0
  95. package/dist/daemon/execution-history.js +246 -0
  96. package/dist/daemon/execution-history.js.map +1 -0
  97. package/dist/daemon/hot-reload-state.d.ts +27 -0
  98. package/dist/daemon/hot-reload-state.d.ts.map +1 -0
  99. package/dist/daemon/hot-reload-state.js +48 -0
  100. package/dist/daemon/hot-reload-state.js.map +1 -0
  101. package/dist/daemon/protocol.d.ts +5 -1
  102. package/dist/daemon/protocol.d.ts.map +1 -1
  103. package/dist/daemon/protocol.js +13 -0
  104. package/dist/daemon/protocol.js.map +1 -1
  105. package/dist/daemon/registry-keys.d.ts +88 -0
  106. package/dist/daemon/registry-keys.d.ts.map +1 -0
  107. package/dist/daemon/registry-keys.js +91 -0
  108. package/dist/daemon/registry-keys.js.map +1 -0
  109. package/dist/daemon/server.js +1521 -186
  110. package/dist/daemon/server.js.map +1 -1
  111. package/dist/daemon/session-resolver.d.ts +28 -0
  112. package/dist/daemon/session-resolver.d.ts.map +1 -0
  113. package/dist/daemon/session-resolver.js +41 -0
  114. package/dist/daemon/session-resolver.js.map +1 -0
  115. package/dist/data-migration.js +20 -9
  116. package/dist/data-migration.js.map +1 -1
  117. package/dist/loader.d.ts +22 -8
  118. package/dist/loader.d.ts.map +1 -1
  119. package/dist/loader.js +214 -94
  120. package/dist/loader.js.map +1 -1
  121. package/dist/marketplace-manager.d.ts.map +1 -1
  122. package/dist/marketplace-manager.js +9 -5
  123. package/dist/marketplace-manager.js.map +1 -1
  124. package/dist/namespace-migration.d.ts.map +1 -1
  125. package/dist/namespace-migration.js +28 -23
  126. package/dist/namespace-migration.js.map +1 -1
  127. package/dist/photon-cli-runner.d.ts.map +1 -1
  128. package/dist/photon-cli-runner.js +57 -8
  129. package/dist/photon-cli-runner.js.map +1 -1
  130. package/dist/serv/auth/auth-store.d.ts +155 -0
  131. package/dist/serv/auth/auth-store.d.ts.map +1 -0
  132. package/dist/serv/auth/auth-store.js +240 -0
  133. package/dist/serv/auth/auth-store.js.map +1 -0
  134. package/dist/serv/auth/endpoints.d.ts +113 -0
  135. package/dist/serv/auth/endpoints.d.ts.map +1 -0
  136. package/dist/serv/auth/endpoints.js +1005 -0
  137. package/dist/serv/auth/endpoints.js.map +1 -0
  138. package/dist/serv/auth/http-adapter.d.ts +60 -0
  139. package/dist/serv/auth/http-adapter.d.ts.map +1 -0
  140. package/dist/serv/auth/http-adapter.js +235 -0
  141. package/dist/serv/auth/http-adapter.js.map +1 -0
  142. package/dist/serv/auth/jwt.d.ts +92 -6
  143. package/dist/serv/auth/jwt.d.ts.map +1 -1
  144. package/dist/serv/auth/jwt.js +226 -24
  145. package/dist/serv/auth/jwt.js.map +1 -1
  146. package/dist/serv/auth/oauth-sqlite-stores.d.ts +48 -0
  147. package/dist/serv/auth/oauth-sqlite-stores.d.ts.map +1 -0
  148. package/dist/serv/auth/oauth-sqlite-stores.js +212 -0
  149. package/dist/serv/auth/oauth-sqlite-stores.js.map +1 -0
  150. package/dist/serv/auth/sqlite-stores.d.ts +85 -0
  151. package/dist/serv/auth/sqlite-stores.d.ts.map +1 -0
  152. package/dist/serv/auth/sqlite-stores.js +446 -0
  153. package/dist/serv/auth/sqlite-stores.js.map +1 -0
  154. package/dist/serv/auth/well-known.d.ts +54 -1
  155. package/dist/serv/auth/well-known.d.ts.map +1 -1
  156. package/dist/serv/auth/well-known.js +166 -17
  157. package/dist/serv/auth/well-known.js.map +1 -1
  158. package/dist/serv/index.d.ts +45 -2
  159. package/dist/serv/index.d.ts.map +1 -1
  160. package/dist/serv/index.js +65 -1
  161. package/dist/serv/index.js.map +1 -1
  162. package/dist/serv/types/index.d.ts +80 -0
  163. package/dist/serv/types/index.d.ts.map +1 -1
  164. package/dist/serv/types/index.js.map +1 -1
  165. package/dist/server.d.ts.map +1 -1
  166. package/dist/server.js +61 -6
  167. package/dist/server.js.map +1 -1
  168. package/dist/shared/announce-context.d.ts +51 -0
  169. package/dist/shared/announce-context.d.ts.map +1 -0
  170. package/dist/shared/announce-context.js +73 -0
  171. package/dist/shared/announce-context.js.map +1 -0
  172. package/dist/shared/audit-sqlite.d.ts +63 -0
  173. package/dist/shared/audit-sqlite.d.ts.map +1 -0
  174. package/dist/shared/audit-sqlite.js +187 -0
  175. package/dist/shared/audit-sqlite.js.map +1 -0
  176. package/dist/shared/audit.d.ts +25 -3
  177. package/dist/shared/audit.d.ts.map +1 -1
  178. package/dist/shared/audit.js +97 -3
  179. package/dist/shared/audit.js.map +1 -1
  180. package/dist/shared/error-handler.d.ts +10 -1
  181. package/dist/shared/error-handler.d.ts.map +1 -1
  182. package/dist/shared/error-handler.js +17 -2
  183. package/dist/shared/error-handler.js.map +1 -1
  184. package/dist/shared/security.d.ts +12 -0
  185. package/dist/shared/security.d.ts.map +1 -1
  186. package/dist/shared/security.js +80 -0
  187. package/dist/shared/security.js.map +1 -1
  188. package/dist/shared/sqlite-runtime.d.ts +46 -0
  189. package/dist/shared/sqlite-runtime.d.ts.map +1 -0
  190. package/dist/shared/sqlite-runtime.js +110 -0
  191. package/dist/shared/sqlite-runtime.js.map +1 -0
  192. package/dist/tasks/store.d.ts +1 -1
  193. package/dist/tasks/store.d.ts.map +1 -1
  194. package/dist/tasks/store.js +29 -15
  195. package/dist/tasks/store.js.map +1 -1
  196. package/dist/telemetry/metrics.d.ts +26 -0
  197. package/dist/telemetry/metrics.d.ts.map +1 -1
  198. package/dist/telemetry/metrics.js +31 -0
  199. package/dist/telemetry/metrics.js.map +1 -1
  200. package/dist/test-runner.d.ts.map +1 -1
  201. package/dist/test-runner.js +3 -3
  202. package/dist/test-runner.js.map +1 -1
  203. package/dist/version-checker.d.ts.map +1 -1
  204. package/dist/version-checker.js +7 -14
  205. package/dist/version-checker.js.map +1 -1
  206. package/dist/version.d.ts +12 -0
  207. package/dist/version.d.ts.map +1 -1
  208. package/dist/version.js +103 -1
  209. package/dist/version.js.map +1 -1
  210. package/package.json +6 -2
  211. package/templates/photon.template.ts +7 -13
@@ -21876,6 +21876,7 @@ var MCPClientService = class {
21876
21876
  internal: tool["x-photon-internal"],
21877
21877
  stateful: tool["x-photon-stateful"] || false,
21878
21878
  hasSettings: tool["x-photon-has-settings"] || false,
21879
+ requiredParams: tool["x-photon-required-params"] || [],
21879
21880
  installSource: tool["x-photon-install-source"],
21880
21881
  promptCount: tool["x-photon-prompt-count"] || 0,
21881
21882
  resourceCount: tool["x-photon-resource-count"] || 0,
@@ -22655,6 +22656,7 @@ var BeamApp = class extends i4 {
22655
22656
  this._view = "list";
22656
22657
  this._welcomePhase = "welcome";
22657
22658
  this._configMode = "initial";
22659
+ this._settingsTab = "configuration";
22658
22660
  this._pendingStudioOpen = false;
22659
22661
  this._diagnosticsData = null;
22660
22662
  this._testResults = [];
@@ -22787,6 +22789,13 @@ var BeamApp = class extends i4 {
22787
22789
  this._view = "marketplace";
22788
22790
  return;
22789
22791
  }
22792
+ if (photonName === "daemon") {
22793
+ this._selectedPhoton = null;
22794
+ this._selectedMethod = null;
22795
+ this._lastResult = null;
22796
+ this._view = "daemon";
22797
+ return;
22798
+ }
22790
22799
  if (!photonName || photonName === "home") {
22791
22800
  this._selectedPhoton = null;
22792
22801
  this._selectedMethod = null;
@@ -24946,6 +24955,8 @@ var BeamApp = class extends i4 {
24946
24955
  let path;
24947
24956
  if (this._view === "marketplace") {
24948
24957
  path = "/marketplace";
24958
+ } else if (this._view === "daemon") {
24959
+ path = "/daemon";
24949
24960
  } else if (!this._selectedPhoton) {
24950
24961
  path = "/";
24951
24962
  } else {
@@ -25360,6 +25371,7 @@ var BeamApp = class extends i4 {
25360
25371
  .mainTab=${this._mainTab}
25361
25372
  .isApp=${!!(this._selectedPhoton?.isApp || this._selectedPhoton?.isExternalMCP && this._selectedPhoton?.hasMcpApp)}
25362
25373
  .hasSettings=${!!(this._selectedPhoton?.hasSettings && !this._selectedPhoton?.isExternalMCP)}
25374
+ .hasSetup=${!!(this._selectedPhoton?.requiredParams?.length && !this._selectedPhoton?.isExternalMCP)}
25363
25375
  .isExternalMCP=${!!this._selectedPhoton?.isExternalMCP}
25364
25376
  .hasPath=${!!this._selectedPhoton?.path}
25365
25377
  @tab-change=${(e8) => {
@@ -25394,7 +25406,19 @@ var BeamApp = class extends i4 {
25394
25406
  if (settingsMethod) {
25395
25407
  this._selectedMethod = settingsMethod;
25396
25408
  this._view = "form";
25397
- this._maybeAutoInvoke(settingsMethod);
25409
+ } else {
25410
+ this._selectedMethod = null;
25411
+ this._lastResult = null;
25412
+ }
25413
+ const hasSetup = Array.isArray(this._selectedPhoton?.requiredParams) && this._selectedPhoton.requiredParams.length > 0;
25414
+ const hasConfig = !!settingsMethod;
25415
+ const configured = this._selectedPhoton?.configured !== false;
25416
+ if (hasSetup && hasConfig) {
25417
+ this._settingsTab = configured ? "configuration" : "setup";
25418
+ } else if (hasSetup) {
25419
+ this._settingsTab = "setup";
25420
+ } else {
25421
+ this._settingsTab = "configuration";
25398
25422
  }
25399
25423
  return;
25400
25424
  }
@@ -25411,6 +25435,13 @@ var BeamApp = class extends i4 {
25411
25435
  @home=${this._goHome}
25412
25436
  @select=${(e8) => this._handlePhotonSelectMobile(e8)}
25413
25437
  @marketplace=${() => this._handleMarketplaceMobile()}
25438
+ @daemon=${() => {
25439
+ this._selectedPhoton = null;
25440
+ this._selectedMethod = null;
25441
+ this._lastResult = null;
25442
+ this._view = "daemon";
25443
+ this._updateRoute();
25444
+ }}
25414
25445
  @theme-change=${this._handleThemeChange}
25415
25446
  @open-theme-settings=${() => this._showThemeSettings = true}
25416
25447
  @show-shortcuts=${this._showHelpModal}
@@ -25636,6 +25667,22 @@ var BeamApp = class extends i4 {
25636
25667
  ${this._renderDiagnostics()}
25637
25668
  `;
25638
25669
  }
25670
+ if (this._view === "daemon") {
25671
+ return b2`
25672
+ <div style="margin-bottom: var(--space-md);">
25673
+ <button
25674
+ style="background:none; border:none; color:var(--accent-secondary); cursor:pointer;"
25675
+ @click=${() => {
25676
+ this._view = "list";
25677
+ this._updateRoute();
25678
+ }}
25679
+ >
25680
+ ← Back to Dashboard
25681
+ </button>
25682
+ </div>
25683
+ <daemon-panel></daemon-panel>
25684
+ `;
25685
+ }
25639
25686
  if (this._view === "marketplace") {
25640
25687
  const globalMethods = this._globalStaticMethods;
25641
25688
  return b2`
@@ -28898,120 +28945,159 @@ ${photon.errorMessage || "Unknown error"}</pre
28898
28945
  const photon = this._selectedPhoton;
28899
28946
  if (!photon) return "";
28900
28947
  const settingsMethod = photon.methods?.find((m3) => m3.name === "settings");
28901
- if (!settingsMethod)
28948
+ const hasSetup = Array.isArray(photon.requiredParams) && photon.requiredParams.length > 0;
28949
+ const hasConfiguration = !!settingsMethod;
28950
+ if (!hasSetup && !hasConfiguration) {
28902
28951
  return b2`<div style="padding: var(--space-xl); color: var(--t-muted); text-align: center;">
28903
28952
  No settings available for this photon.
28904
28953
  </div>`;
28905
- const params = settingsMethod.params;
28906
- const properties = params?.properties || {};
28907
- const propEntries = Object.entries(properties);
28908
- const hasResult = this._lastResult !== null;
28909
- let statusEntries = [];
28910
- if (hasResult) {
28911
- try {
28912
- const resultData = typeof this._lastResult === "string" ? JSON.parse(this._lastResult) : Array.isArray(this._lastResult) ? this._lastResult.find((c5) => c5.type === "text")?.text ? JSON.parse(this._lastResult.find((c5) => c5.type === "text").text) : this._lastResult : this._lastResult;
28913
- if (resultData && typeof resultData === "object" && !Array.isArray(resultData)) {
28914
- statusEntries = Object.entries(resultData).filter(([, v2]) => v2 !== null && v2 !== void 0).map(([k3, v2]) => [k3, String(v2)]);
28915
- }
28916
- } catch {
28917
- }
28918
28954
  }
28955
+ const showTabs = hasSetup && hasConfiguration;
28956
+ const activeTab = hasConfiguration && this._settingsTab === "configuration" ? "configuration" : hasSetup && this._settingsTab === "setup" ? "setup" : hasConfiguration ? "configuration" : "setup";
28919
28957
  return b2`
28920
28958
  <div style="padding: var(--space-lg); max-width: 900px; margin: 0 auto; width: 100%;">
28921
- <!-- Settings Header -->
28922
- <div style="margin-bottom: var(--space-xl);">
28959
+ <div style="margin-bottom: var(--space-lg);">
28923
28960
  <h2
28924
28961
  style="font-family: var(--font-display); font-size: var(--text-xl); font-weight: 700; color: var(--t-primary); margin: 0 0 4px 0;"
28925
28962
  >
28926
28963
  ${photon.name} Settings
28927
28964
  </h2>
28928
- ${settingsMethod.description ? b2`<p
28929
- style="color: var(--t-muted); font-size: var(--text-sm); margin: 0; line-height: 1.5;"
28930
- >
28931
- View or update photon configuration. Changes are applied immediately.
28932
- </p>` : ""}
28965
+ <p style="color: var(--t-muted); font-size: var(--text-sm); margin: 0; line-height: 1.5;">
28966
+ ${activeTab === "setup" ? "What this photon needs to run. Applies to every instance; changes take effect on next load." : "How this photon behaves. Applies to the current instance only; changes are saved immediately."}
28967
+ </p>
28933
28968
  </div>
28934
28969
 
28935
- <!-- Configuration Section -->
28936
- ${propEntries.length > 0 ? b2`
28937
- <div class="glass-panel" style="margin-bottom: var(--space-lg); overflow: hidden;">
28938
- <div
28939
- style="padding: var(--space-sm) var(--space-md); border-bottom: 1px solid var(--border-glass); background: var(--bg-glass);"
28970
+ ${showTabs ? this._renderSettingsTabStrip(activeTab) : ""}
28971
+ ${activeTab === "setup" ? this._renderSettingsSetup(photon) : this._renderSettingsConfiguration(photon, settingsMethod)}
28972
+ </div>
28973
+ `;
28974
+ }
28975
+ _renderSettingsTabStrip(active) {
28976
+ const tab = (id2, label) => b2`
28977
+ <button
28978
+ type="button"
28979
+ @click=${() => {
28980
+ this._settingsTab = id2;
28981
+ }}
28982
+ style="
28983
+ padding: 8px 16px;
28984
+ background: ${active === id2 ? "var(--bg-glass-strong)" : "transparent"};
28985
+ color: ${active === id2 ? "var(--t-primary)" : "var(--t-muted)"};
28986
+ border: none;
28987
+ border-bottom: 2px solid ${active === id2 ? "var(--accent-primary)" : "transparent"};
28988
+ cursor: pointer;
28989
+ font-size: var(--text-sm);
28990
+ font-weight: ${active === id2 ? "600" : "500"};
28991
+ transition: all 0.15s;
28992
+ "
28993
+ >
28994
+ ${label}
28995
+ </button>
28996
+ `;
28997
+ return b2`
28998
+ <div
28999
+ role="tablist"
29000
+ style="display: flex; gap: 4px; border-bottom: 1px solid var(--border-glass); margin-bottom: var(--space-lg);"
29001
+ >
29002
+ ${tab("setup", "Setup")} ${tab("configuration", "Configuration")}
29003
+ </div>
29004
+ `;
29005
+ }
29006
+ _renderSettingsSetup(photon) {
29007
+ const isInitial = photon.configured === false;
29008
+ return b2`
29009
+ <div class="glass-panel" style="overflow: hidden;">
29010
+ <div
29011
+ style="padding: var(--space-sm) var(--space-md); border-bottom: 1px solid var(--border-glass); background: var(--bg-glass);"
29012
+ >
29013
+ <span
29014
+ style="font-family: var(--font-display); font-size: var(--text-sm); font-weight: 600; color: var(--t-primary); text-transform: uppercase; letter-spacing: 0.05em;"
29015
+ >Setup</span
29016
+ >
29017
+ </div>
29018
+ <div style="padding: var(--space-lg);">
29019
+ <photon-config
29020
+ embedded
29021
+ .photon=${{
29022
+ ...photon,
29023
+ // photon-config expects an UnconfiguredPhoton-shape with a
29024
+ // requiredParams field. Pass the existing data through.
29025
+ requiredParams: photon.requiredParams || []
29026
+ }}
29027
+ .mode=${isInitial ? "initial" : "edit"}
29028
+ @configure=${(e8) => {
29029
+ void this._handleConfigure(e8);
29030
+ }}
29031
+ ></photon-config>
29032
+ </div>
29033
+ </div>
29034
+ `;
29035
+ }
29036
+ _renderSettingsConfiguration(photon, settingsMethod) {
29037
+ const params = settingsMethod.params;
29038
+ const properties = params?.properties || {};
29039
+ const propEntries = Object.entries(properties);
29040
+ const showInstanceLabel = !!photon?.stateful || Array.isArray(this._instances) && this._instances.length > 1;
29041
+ const instanceName = this._currentInstance || "default";
29042
+ return b2`
29043
+ ${showInstanceLabel ? b2`
29044
+ <div
29045
+ style="display: flex; align-items: center; gap: var(--space-xs); margin-bottom: var(--space-sm); font-size: var(--text-sm); color: var(--t-muted);"
29046
+ >
29047
+ <span>Instance:</span>
29048
+ <span
29049
+ style="font-family: var(--font-mono); color: var(--t-primary); background: var(--bg-glass); padding: 2px 8px; border-radius: var(--radius-xs);"
29050
+ >${instanceName}</span
29051
+ >
29052
+ <span style="font-size: var(--text-xs);">
29053
+ — switch via the picker in the header above
29054
+ </span>
29055
+ </div>
29056
+ ` : ""}
29057
+ ${propEntries.length > 0 ? b2`
29058
+ <div class="glass-panel" style="margin-bottom: var(--space-lg); overflow: hidden;">
29059
+ <div
29060
+ style="padding: var(--space-sm) var(--space-md); border-bottom: 1px solid var(--border-glass); background: var(--bg-glass);"
29061
+ >
29062
+ <span
29063
+ style="font-family: var(--font-display); font-size: var(--text-sm); font-weight: 600; color: var(--t-primary); text-transform: uppercase; letter-spacing: 0.05em;"
29064
+ >Configuration</span
28940
29065
  >
28941
- <span
28942
- style="font-family: var(--font-display); font-size: var(--text-sm); font-weight: 600; color: var(--t-primary); text-transform: uppercase; letter-spacing: 0.05em;"
28943
- >Configuration</span
28944
- >
28945
- </div>
28946
- <div class="method-detail" style="padding: 0;">
28947
- <invoke-form
28948
- .params=${params}
28949
- .loading=${this._isExecuting}
28950
- .photonName=${photon.name}
28951
- .methodName=${"settings"}
28952
- .rememberValues=${this._rememberFormValues}
28953
- .sharedValues=${this._sharedFormParams ?? this._lastFormParams}
28954
- .settingsLayout=${true}
28955
- @submit=${(e8) => void this._handleExecute(e8)}
28956
- @cancel=${() => {
29066
+ </div>
29067
+ <div class="method-detail" style="padding: 0;">
29068
+ <invoke-form
29069
+ .params=${params}
29070
+ .loading=${this._isExecuting}
29071
+ .photonName=${photon.name}
29072
+ .methodName=${"settings"}
29073
+ .rememberValues=${this._rememberFormValues}
29074
+ .sharedValues=${this._sharedFormParams ?? this._lastFormParams}
29075
+ .settingsLayout=${true}
29076
+ @submit=${(e8) => void this._handleExecute(e8)}
29077
+ @cancel=${() => {
28957
29078
  }}
28958
- ></invoke-form>
28959
- <div
28960
- style="display: flex; justify-content: flex-end; padding: var(--space-sm) var(--space-md); border-top: 1px solid var(--border-glass);"
28961
- >
28962
- <button
28963
- class="btn-primary"
28964
- style="font-size: var(--text-sm); padding: 6px 20px;"
28965
- @click=${(e8) => {
29079
+ ></invoke-form>
29080
+ <div
29081
+ style="display: flex; justify-content: flex-end; padding: var(--space-sm) var(--space-md); border-top: 1px solid var(--border-glass);"
29082
+ >
29083
+ <button
29084
+ class="btn-primary"
29085
+ style="font-size: var(--text-sm); padding: 6px 20px;"
29086
+ @click=${(e8) => {
28966
29087
  const panel = e8.target.closest(".glass-panel");
28967
29088
  const form = panel?.querySelector("invoke-form");
28968
29089
  form?.handleSubmit();
28969
29090
  }}
28970
- ?disabled=${this._isExecuting}
28971
- >
28972
- ${this._isExecuting ? b2`<span class="btn-loading"
28973
- ><span class="spinner"></span>Saving...</span
28974
- >` : "Save Settings"}
28975
- </button>
28976
- </div>
28977
- </div>
28978
- </div>
28979
- ` : ""}
28980
-
28981
- <!-- Status Section (from last result) -->
28982
- ${statusEntries.length > 0 ? b2`
28983
- <div class="glass-panel" style="overflow: hidden;">
28984
- <div
28985
- style="padding: var(--space-sm) var(--space-md); border-bottom: 1px solid var(--border-glass); background: var(--bg-glass);"
28986
- >
28987
- <span
28988
- style="font-family: var(--font-display); font-size: var(--text-sm); font-weight: 600; color: var(--t-primary); text-transform: uppercase; letter-spacing: 0.05em;"
28989
- >Status</span
29091
+ ?disabled=${this._isExecuting}
28990
29092
  >
28991
- </div>
28992
- <div style="padding: 0;">
28993
- ${statusEntries.map(
28994
- ([key, value], i7) => b2`
28995
- <div
28996
- style="display: grid; grid-template-columns: 200px 1fr; border-bottom: ${i7 < statusEntries.length - 1 ? "1px solid var(--border-glass)" : "none"};"
28997
- >
28998
- <div
28999
- style="padding: 10px var(--space-md); font-size: var(--text-xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--t-muted); background: var(--bg-glass);"
29000
- >
29001
- ${key.replace(/([A-Z])/g, " $1").replace(/_/g, " ").trim()}
29002
- </div>
29003
- <div
29004
- style="padding: 10px var(--space-md); font-size: var(--text-sm); color: var(--t-primary); word-break: break-word;"
29005
- >
29006
- ${value}
29007
- </div>
29008
- </div>
29009
- `
29010
- )}
29093
+ ${this._isExecuting ? b2`<span class="btn-loading"
29094
+ ><span class="spinner"></span>Saving...</span
29095
+ >` : "Save Settings"}
29096
+ </button>
29011
29097
  </div>
29012
29098
  </div>
29013
- ` : ""}
29014
- </div>
29099
+ </div>
29100
+ ` : ""}
29015
29101
  `;
29016
29102
  }
29017
29103
  /** Render source code as an inline view (not a modal) — Phase 2 */
@@ -31259,6 +31345,9 @@ __decorateClass([
31259
31345
  __decorateClass([
31260
31346
  r5()
31261
31347
  ], BeamApp.prototype, "_configMode", 2);
31348
+ __decorateClass([
31349
+ r5()
31350
+ ], BeamApp.prototype, "_settingsTab", 2);
31262
31351
  __decorateClass([
31263
31352
  r5()
31264
31353
  ], BeamApp.prototype, "_diagnosticsData", 2);
@@ -31452,6 +31541,7 @@ var BeamSidebar = class extends i4 {
31452
31541
  this.mainTab = "methods";
31453
31542
  this.isApp = false;
31454
31543
  this.hasSettings = false;
31544
+ this.hasSetup = false;
31455
31545
  this.isExternalMCP = false;
31456
31546
  this.hasPath = false;
31457
31547
  this._searchQuery = "";
@@ -31691,6 +31781,14 @@ var BeamSidebar = class extends i4 {
31691
31781
  ${marketplace} Marketplace
31692
31782
  ${this.updatesAvailable > 0 ? b2`<span class="update-badge">${this.updatesAvailable}</span>` : ""}
31693
31783
  </button>
31784
+ <button
31785
+ class="filter-btn"
31786
+ @click=${() => this.dispatchEvent(new CustomEvent("daemon"))}
31787
+ aria-label="Open daemon panel"
31788
+ title="View scheduled jobs, webhooks, and sessions"
31789
+ >
31790
+ ${activity} Daemon
31791
+ </button>
31694
31792
  </div>
31695
31793
  </div>
31696
31794
 
@@ -32043,7 +32141,7 @@ ${photon.path}` : ""}"
32043
32141
  ...this.isApp ? [{ id: "app", label: "App", icon: appTabIcon }] : [],
32044
32142
  { id: "methods", label: "Methods", icon: methodsTabIcon },
32045
32143
  { id: "log", label: "Activity", icon: activity },
32046
- ...this.hasSettings ? [{ id: "settings", label: "Settings", icon: settings }] : [],
32144
+ ...this.hasSettings || this.hasSetup ? [{ id: "settings", label: "Settings", icon: settings }] : [],
32047
32145
  ...this.hasPath && !this.isExternalMCP ? [{ id: "source", label: "Source", icon: source }] : [],
32048
32146
  { id: "help", label: "Help", icon: docs }
32049
32147
  ];
@@ -33116,6 +33214,9 @@ __decorateClass([
33116
33214
  __decorateClass([
33117
33215
  n4({ type: Boolean })
33118
33216
  ], BeamSidebar.prototype, "hasSettings", 2);
33217
+ __decorateClass([
33218
+ n4({ type: Boolean })
33219
+ ], BeamSidebar.prototype, "hasSetup", 2);
33119
33220
  __decorateClass([
33120
33221
  n4({ type: Boolean })
33121
33222
  ], BeamSidebar.prototype, "isExternalMCP", 2);
@@ -36701,6 +36802,11 @@ var ResultViewer = class extends i4 {
36701
36802
  this._handlePanEnd = () => {
36702
36803
  this._isPanning = false;
36703
36804
  };
36805
+ this._handleA2UIAction = (ev2) => {
36806
+ ev2.preventDefault();
36807
+ const detail = ev2.detail;
36808
+ void this._invokeA2UIAction(detail.name, detail.context ?? {});
36809
+ };
36704
36810
  // Non-reactive property to avoid infinite update loops
36705
36811
  this._pendingMermaidBlocks = [];
36706
36812
  // Store code blocks for Prism highlighting after DOM update
@@ -37543,7 +37649,8 @@ var ResultViewer = class extends i4 {
37543
37649
  "slides",
37544
37650
  "checklist",
37545
37651
  "article",
37546
- "magazine"
37652
+ "magazine",
37653
+ "a2ui"
37547
37654
  ].includes(format)) {
37548
37655
  return format;
37549
37656
  }
@@ -37782,11 +37889,51 @@ var ResultViewer = class extends i4 {
37782
37889
  case "magazine":
37783
37890
  case "article":
37784
37891
  return this._renderMagazine(filteredData);
37892
+ case "a2ui":
37893
+ return this._renderA2UI(filteredData);
37785
37894
  case "json":
37786
37895
  default:
37787
37896
  return this._renderJson(filteredData);
37788
37897
  }
37789
37898
  }
37899
+ /**
37900
+ * Render an A2UI v0.9 surface by handing the result off to the shared
37901
+ * photon-renderers.js runtime. The renderer walks the component tree
37902
+ * (auto-mapped from the raw result) and produces the final DOM, then
37903
+ * dispatches `a2ui:action` events when buttons fire — we route those to
37904
+ * `<photonName>/<actionName>` per the convention documented in
37905
+ * docs/formats.md (button name == method name on the same photon).
37906
+ */
37907
+ _renderA2UI(filteredData) {
37908
+ const data = filteredData;
37909
+ const slotId = `a2ui-${Math.random().toString(36).slice(2)}`;
37910
+ queueMicrotask(() => {
37911
+ const target2 = this.shadowRoot?.getElementById(slotId);
37912
+ if (target2) this._renderSlideFormat(target2, data, "a2ui");
37913
+ });
37914
+ return b2`<div
37915
+ id=${slotId}
37916
+ class="a2ui-host"
37917
+ style="padding: 4px"
37918
+ @a2ui:action=${this._handleA2UIAction}
37919
+ ></div>`;
37920
+ }
37921
+ /**
37922
+ * Invoke a photon method that an A2UI button asked for and re-render the
37923
+ * surface with the new result. Action name comes from the button's
37924
+ * `event.name`; context is the local data-model snapshot (TextField edits
37925
+ * captured by the renderer).
37926
+ */
37927
+ async _invokeA2UIAction(actionName, context) {
37928
+ if (!this.photonName || !actionName) return;
37929
+ try {
37930
+ const result = await mcpClient.callTool(`${this.photonName}/${actionName}`, context);
37931
+ const next = mcpClient.parseToolResult(result);
37932
+ this.result = next;
37933
+ } catch (err) {
37934
+ console.error("[a2ui] action failed:", actionName, err);
37935
+ }
37936
+ }
37790
37937
  _renderTable(data) {
37791
37938
  if (!Array.isArray(data) && data && typeof data === "object") {
37792
37939
  const arrayEntries = Object.entries(data).filter(([, v2]) => Array.isArray(v2) && v2.length > 0);
@@ -48404,6 +48551,494 @@ MarketplaceView = __decorateClass([
48404
48551
  t4("marketplace-view")
48405
48552
  ], MarketplaceView);
48406
48553
 
48554
+ // src/auto-ui/frontend/components/daemon-panel.ts
48555
+ var POLL_INTERVAL_MS = 3e3;
48556
+ function formatWhen(ts) {
48557
+ if (!ts) return "-";
48558
+ const delta = ts - Date.now();
48559
+ const abs = Math.abs(delta);
48560
+ const mins = Math.round(abs / 6e4);
48561
+ const hrs = Math.round(mins / 60);
48562
+ if (abs < 6e4) return delta < 0 ? "just now" : "in <1m";
48563
+ if (mins < 90) return delta < 0 ? `${mins}m ago` : `in ${mins}m`;
48564
+ if (hrs < 48) return delta < 0 ? `${hrs}h ago` : `in ${hrs}h`;
48565
+ return new Date(ts).toISOString().replace("T", " ").slice(0, 16);
48566
+ }
48567
+ function tilde(p5) {
48568
+ if (!p5) return "-";
48569
+ const parts = p5.split("/").filter(Boolean);
48570
+ if (parts.length <= 2) return p5;
48571
+ return "\u2026/" + parts.slice(-2).join("/");
48572
+ }
48573
+ var DaemonPanel = class extends i4 {
48574
+ constructor() {
48575
+ super(...arguments);
48576
+ this._snap = null;
48577
+ this._error = null;
48578
+ this._loading = false;
48579
+ this._history = null;
48580
+ this._historyLoading = false;
48581
+ this._pollTimer = null;
48582
+ }
48583
+ connectedCallback() {
48584
+ super.connectedCallback();
48585
+ void this._refresh();
48586
+ this._pollTimer = setInterval(() => void this._refresh(true), POLL_INTERVAL_MS);
48587
+ }
48588
+ disconnectedCallback() {
48589
+ super.disconnectedCallback();
48590
+ if (this._pollTimer) {
48591
+ clearInterval(this._pollTimer);
48592
+ this._pollTimer = null;
48593
+ }
48594
+ }
48595
+ async _refresh(silent = false) {
48596
+ if (!silent) this._loading = true;
48597
+ try {
48598
+ const res = await fetch("/api/daemon/ps", {
48599
+ signal: AbortSignal.timeout(1e4)
48600
+ });
48601
+ if (!res.ok) {
48602
+ const err = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
48603
+ this._error = err.error || `HTTP ${res.status}`;
48604
+ return;
48605
+ }
48606
+ this._snap = await res.json();
48607
+ this._error = null;
48608
+ } catch (err) {
48609
+ this._error = err instanceof Error ? err.message : String(err);
48610
+ } finally {
48611
+ this._loading = false;
48612
+ }
48613
+ }
48614
+ async _scheduleAction(action, photon, method) {
48615
+ try {
48616
+ const res = await fetch(`/api/daemon/schedules/${action}`, {
48617
+ method: "POST",
48618
+ headers: {
48619
+ "Content-Type": "application/json",
48620
+ "X-Photon-Request": "1"
48621
+ },
48622
+ body: JSON.stringify({ photon, method }),
48623
+ signal: AbortSignal.timeout(1e4)
48624
+ });
48625
+ const body = await res.json().catch(() => ({}));
48626
+ if (!res.ok) {
48627
+ showToast(body.error || `Action "${action}" failed`, "error");
48628
+ return;
48629
+ }
48630
+ showToast(`${action}d ${photon}:${method}`, "success");
48631
+ await this._refresh(true);
48632
+ } catch (err) {
48633
+ showToast(err instanceof Error ? err.message : String(err), "error");
48634
+ }
48635
+ }
48636
+ async _openHistory(photon, method) {
48637
+ this._history = { photon, method, entries: [] };
48638
+ this._historyLoading = true;
48639
+ try {
48640
+ const res = await fetch(
48641
+ `/api/daemon/history?photon=${encodeURIComponent(photon)}&method=${encodeURIComponent(
48642
+ method
48643
+ )}&limit=50`,
48644
+ { signal: AbortSignal.timeout(1e4) }
48645
+ );
48646
+ if (!res.ok) {
48647
+ const err = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
48648
+ showToast(err.error || `History load failed`, "error");
48649
+ this._history = null;
48650
+ return;
48651
+ }
48652
+ this._history = await res.json();
48653
+ } catch (err) {
48654
+ showToast(err instanceof Error ? err.message : String(err), "error");
48655
+ this._history = null;
48656
+ } finally {
48657
+ this._historyLoading = false;
48658
+ }
48659
+ }
48660
+ _closeHistory() {
48661
+ this._history = null;
48662
+ }
48663
+ _renderActive() {
48664
+ const rows = this._snap?.active ?? [];
48665
+ return b2`
48666
+ <h2>Active schedules (${rows.length})</h2>
48667
+ <div class="table-wrap">
48668
+ <table>
48669
+ <thead>
48670
+ <tr>
48671
+ <th>PHOTON_DIR</th>
48672
+ <th>Photon</th>
48673
+ <th>Method</th>
48674
+ <th>Cron</th>
48675
+ <th>Next run</th>
48676
+ <th>Last run</th>
48677
+ <th>Runs</th>
48678
+ <th></th>
48679
+ </tr>
48680
+ </thead>
48681
+ <tbody>
48682
+ ${rows.length === 0 ? b2`<tr class="empty">
48683
+ <td colspan="8">no active schedules</td>
48684
+ </tr>` : rows.map(
48685
+ (r7) => b2`
48686
+ <tr>
48687
+ <td>${tilde(r7.workingDir)}</td>
48688
+ <td>${r7.photon}</td>
48689
+ <td>${r7.method}</td>
48690
+ <td><code>${r7.cron}</code></td>
48691
+ <td>${formatWhen(r7.nextRun)}</td>
48692
+ <td>${formatWhen(r7.lastRun)}</td>
48693
+ <td>${r7.runCount}</td>
48694
+ <td class="actions">
48695
+ <button @click=${() => this._openHistory(r7.photon, r7.method)}>
48696
+ History
48697
+ </button>
48698
+ <button @click=${() => this._scheduleAction("pause", r7.photon, r7.method)}>
48699
+ Pause
48700
+ </button>
48701
+ <button @click=${() => this._scheduleAction("disable", r7.photon, r7.method)}>
48702
+ Disable
48703
+ </button>
48704
+ </td>
48705
+ </tr>
48706
+ `
48707
+ )}
48708
+ </tbody>
48709
+ </table>
48710
+ </div>
48711
+ `;
48712
+ }
48713
+ _renderDeclared() {
48714
+ const rows = (this._snap?.declared ?? []).filter((d5) => !d5.active);
48715
+ return b2`
48716
+ <h2>Declared but not enrolled (${rows.length})</h2>
48717
+ <p class="hint">
48718
+ These photons declare <code>@scheduled</code> methods that haven't been enrolled yet.
48719
+ </p>
48720
+ <div class="table-wrap">
48721
+ <table>
48722
+ <thead>
48723
+ <tr>
48724
+ <th>PHOTON_DIR</th>
48725
+ <th>Photon</th>
48726
+ <th>Method</th>
48727
+ <th>Cron</th>
48728
+ <th></th>
48729
+ </tr>
48730
+ </thead>
48731
+ <tbody>
48732
+ ${rows.length === 0 ? b2`<tr class="empty">
48733
+ <td colspan="5">no dormant declarations</td>
48734
+ </tr>` : rows.map(
48735
+ (r7) => b2`
48736
+ <tr>
48737
+ <td>${tilde(r7.workingDir)}</td>
48738
+ <td>${r7.photon}</td>
48739
+ <td>${r7.method}</td>
48740
+ <td><code>${r7.cron}</code></td>
48741
+ <td class="actions">
48742
+ <button @click=${() => this._scheduleAction("enable", r7.photon, r7.method)}>
48743
+ Enable
48744
+ </button>
48745
+ </td>
48746
+ </tr>
48747
+ `
48748
+ )}
48749
+ </tbody>
48750
+ </table>
48751
+ </div>
48752
+ `;
48753
+ }
48754
+ _renderWebhooks() {
48755
+ const rows = this._snap?.webhooks ?? [];
48756
+ return b2`
48757
+ <h2>Webhooks (${rows.length})</h2>
48758
+ <div class="table-wrap">
48759
+ <table>
48760
+ <thead>
48761
+ <tr>
48762
+ <th>PHOTON_DIR</th>
48763
+ <th>Photon</th>
48764
+ <th>Route</th>
48765
+ <th>Method</th>
48766
+ </tr>
48767
+ </thead>
48768
+ <tbody>
48769
+ ${rows.length === 0 ? b2`<tr class="empty">
48770
+ <td colspan="4">no webhook routes</td>
48771
+ </tr>` : rows.map(
48772
+ (r7) => b2`
48773
+ <tr>
48774
+ <td>${tilde(r7.workingDir)}</td>
48775
+ <td>${r7.photon}</td>
48776
+ <td><code>${r7.route}</code></td>
48777
+ <td>${r7.method}</td>
48778
+ </tr>
48779
+ `
48780
+ )}
48781
+ </tbody>
48782
+ </table>
48783
+ </div>
48784
+ `;
48785
+ }
48786
+ _renderSessions() {
48787
+ const rows = this._snap?.sessions ?? [];
48788
+ return b2`
48789
+ <h2>Active sessions (${rows.length})</h2>
48790
+ <div class="table-wrap">
48791
+ <table>
48792
+ <thead>
48793
+ <tr>
48794
+ <th>PHOTON_DIR</th>
48795
+ <th>Photon</th>
48796
+ <th>Instances</th>
48797
+ </tr>
48798
+ </thead>
48799
+ <tbody>
48800
+ ${rows.length === 0 ? b2`<tr class="empty">
48801
+ <td colspan="3">no loaded sessions</td>
48802
+ </tr>` : rows.map(
48803
+ (r7) => b2`
48804
+ <tr>
48805
+ <td>${tilde(r7.workingDir)}</td>
48806
+ <td>${r7.photon}</td>
48807
+ <td>${r7.instanceCount}</td>
48808
+ </tr>
48809
+ `
48810
+ )}
48811
+ </tbody>
48812
+ </table>
48813
+ </div>
48814
+ `;
48815
+ }
48816
+ _renderHistoryDrawer() {
48817
+ if (!this._history) return "";
48818
+ const { photon, method, entries } = this._history;
48819
+ return b2`
48820
+ <div class="drawer">
48821
+ <div class="drawer-header">
48822
+ <h2>History for ${photon}:${method}</h2>
48823
+ <button @click=${() => this._closeHistory()}>Close</button>
48824
+ </div>
48825
+ ${this._historyLoading ? b2`<p class="hint">Loading…</p>` : entries.length === 0 ? b2`<p class="hint">No firings recorded.</p>` : b2`
48826
+ <div class="table-wrap">
48827
+ <table>
48828
+ <thead>
48829
+ <tr>
48830
+ <th>When</th>
48831
+ <th>Status</th>
48832
+ <th>Duration</th>
48833
+ <th>Detail</th>
48834
+ </tr>
48835
+ </thead>
48836
+ <tbody>
48837
+ ${entries.map(
48838
+ (e8) => b2`
48839
+ <tr>
48840
+ <td>${formatWhen(e8.ts)}</td>
48841
+ <td class="status-${e8.status}">${e8.status.toUpperCase()}</td>
48842
+ <td>${e8.durationMs}ms</td>
48843
+ <td>
48844
+ ${e8.status === "success" ? (e8.outputPreview ?? "").slice(0, 120) : (e8.errorMessage ?? "").slice(0, 120)}
48845
+ </td>
48846
+ </tr>
48847
+ `
48848
+ )}
48849
+ </tbody>
48850
+ </table>
48851
+ </div>
48852
+ `}
48853
+ </div>
48854
+ `;
48855
+ }
48856
+ render() {
48857
+ return b2`
48858
+ <h1>Daemon</h1>
48859
+ <p class="hint">
48860
+ Observability for scheduled work, webhook routes, and loaded sessions. Mirrors
48861
+ <code>photon ps</code>.
48862
+ </p>
48863
+
48864
+ <div class="refresh-bar">
48865
+ <button class="refresh" @click=${() => this._refresh()} ?disabled=${this._loading}>
48866
+ ${this._loading ? "Refreshing\u2026" : "Refresh"}
48867
+ </button>
48868
+ <span class="hint">auto-refresh every ${POLL_INTERVAL_MS / 1e3}s</span>
48869
+ </div>
48870
+
48871
+ ${this._error ? b2`<div class="error">${this._error}</div>` : ""} ${this._renderActive()}
48872
+ ${this._renderDeclared()} ${this._renderWebhooks()} ${this._renderSessions()}
48873
+ ${this._renderHistoryDrawer()}
48874
+ `;
48875
+ }
48876
+ };
48877
+ DaemonPanel.styles = [
48878
+ theme,
48879
+ forms,
48880
+ i`
48881
+ :host {
48882
+ display: block;
48883
+ height: 100%;
48884
+ overflow-y: auto;
48885
+ }
48886
+
48887
+ h1 {
48888
+ font-size: 1.5rem;
48889
+ margin: 0 0 var(--space-sm) 0;
48890
+ }
48891
+
48892
+ h2 {
48893
+ font-size: 1rem;
48894
+ margin: var(--space-lg) 0 var(--space-xs) 0;
48895
+ color: var(--t-primary);
48896
+ }
48897
+
48898
+ p.hint {
48899
+ color: var(--t-muted);
48900
+ font-size: 0.85rem;
48901
+ margin: 0 0 var(--space-md) 0;
48902
+ }
48903
+
48904
+ .refresh-bar {
48905
+ display: flex;
48906
+ align-items: center;
48907
+ gap: var(--space-sm);
48908
+ margin-bottom: var(--space-md);
48909
+ }
48910
+
48911
+ button.refresh {
48912
+ background: var(--surface-secondary, #222);
48913
+ color: var(--t-primary);
48914
+ border: 1px solid var(--border, #333);
48915
+ padding: 4px 12px;
48916
+ border-radius: 4px;
48917
+ cursor: pointer;
48918
+ }
48919
+ button.refresh:hover {
48920
+ background: var(--surface-hover, #2a2a2a);
48921
+ }
48922
+
48923
+ .table-wrap {
48924
+ overflow-x: auto;
48925
+ border: 1px solid var(--border, #333);
48926
+ border-radius: 4px;
48927
+ }
48928
+
48929
+ table {
48930
+ width: 100%;
48931
+ border-collapse: collapse;
48932
+ font-size: 0.85rem;
48933
+ }
48934
+
48935
+ th,
48936
+ td {
48937
+ padding: 6px 10px;
48938
+ text-align: left;
48939
+ border-bottom: 1px solid var(--border, #2a2a2a);
48940
+ }
48941
+
48942
+ th {
48943
+ background: var(--surface-secondary, #1a1a1a);
48944
+ font-weight: 600;
48945
+ color: var(--t-muted);
48946
+ }
48947
+
48948
+ tr.empty td {
48949
+ text-align: center;
48950
+ color: var(--t-muted);
48951
+ padding: var(--space-md);
48952
+ }
48953
+
48954
+ .actions {
48955
+ display: flex;
48956
+ gap: 4px;
48957
+ }
48958
+
48959
+ .actions button {
48960
+ font-size: 0.75rem;
48961
+ padding: 2px 8px;
48962
+ border: 1px solid var(--border, #333);
48963
+ background: transparent;
48964
+ color: var(--t-primary);
48965
+ cursor: pointer;
48966
+ border-radius: 3px;
48967
+ }
48968
+
48969
+ .actions button:hover {
48970
+ background: var(--surface-hover, #2a2a2a);
48971
+ }
48972
+
48973
+ .status-success {
48974
+ color: var(--success, #4ade80);
48975
+ }
48976
+ .status-error {
48977
+ color: var(--danger, #f87171);
48978
+ }
48979
+ .status-timeout {
48980
+ color: var(--warning, #fbbf24);
48981
+ }
48982
+
48983
+ .error {
48984
+ background: var(--danger-bg, #3a1b1b);
48985
+ color: var(--danger, #f87171);
48986
+ padding: var(--space-sm);
48987
+ border-radius: 4px;
48988
+ font-size: 0.85rem;
48989
+ margin-bottom: var(--space-md);
48990
+ }
48991
+
48992
+ .drawer {
48993
+ position: fixed;
48994
+ top: 0;
48995
+ right: 0;
48996
+ bottom: 0;
48997
+ width: min(520px, 100vw);
48998
+ background: var(--surface-primary, #111);
48999
+ border-left: 1px solid var(--border, #333);
49000
+ padding: var(--space-md);
49001
+ overflow-y: auto;
49002
+ z-index: 9999;
49003
+ box-shadow: -4px 0 12px rgba(0, 0, 0, 0.4);
49004
+ }
49005
+
49006
+ .drawer-header {
49007
+ display: flex;
49008
+ justify-content: space-between;
49009
+ align-items: center;
49010
+ margin-bottom: var(--space-md);
49011
+ }
49012
+
49013
+ .drawer-header button {
49014
+ background: transparent;
49015
+ border: 1px solid var(--border, #333);
49016
+ color: var(--t-primary);
49017
+ padding: 4px 10px;
49018
+ cursor: pointer;
49019
+ border-radius: 3px;
49020
+ }
49021
+ `
49022
+ ];
49023
+ __decorateClass([
49024
+ r5()
49025
+ ], DaemonPanel.prototype, "_snap", 2);
49026
+ __decorateClass([
49027
+ r5()
49028
+ ], DaemonPanel.prototype, "_error", 2);
49029
+ __decorateClass([
49030
+ r5()
49031
+ ], DaemonPanel.prototype, "_loading", 2);
49032
+ __decorateClass([
49033
+ r5()
49034
+ ], DaemonPanel.prototype, "_history", 2);
49035
+ __decorateClass([
49036
+ r5()
49037
+ ], DaemonPanel.prototype, "_historyLoading", 2);
49038
+ DaemonPanel = __decorateClass([
49039
+ t4("daemon-panel")
49040
+ ], DaemonPanel);
49041
+
48407
49042
  // src/auto-ui/frontend/styles/beam-tokens.ts
48408
49043
  var beamTypographyTokens = {
48409
49044
  "--font-display": "'Sora', 'Space Grotesk', -apple-system, BlinkMacSystemFont, sans-serif",
@@ -98447,18 +99082,20 @@ var PhotonConfig = class extends i4 {
98447
99082
  this.mode = "initial";
98448
99083
  this._loading = false;
98449
99084
  this._formData = {};
99085
+ this.embedded = false;
98450
99086
  }
98451
99087
  render() {
98452
99088
  if (!this.photon) return b2``;
98453
99089
  const params = this.photon.requiredParams || [];
98454
99090
  return b2`
98455
- <div class="config-header">
98456
- <h2 class="config-title text-gradient">${this.photon.name}</h2>
98457
- <p class="config-description">
98458
- ${this.mode === "edit" ? "Edit configuration values. Only changed fields will be updated." : this.photon.errorMessage || "Configure this photon to enable its features"}
98459
- </p>
98460
- </div>
98461
-
99091
+ ${!this.embedded ? b2`
99092
+ <div class="config-header">
99093
+ <h2 class="config-title text-gradient">${this.photon.name}</h2>
99094
+ <p class="config-description">
99095
+ ${this.mode === "edit" ? "Edit configuration values. Only changed fields will be updated." : this.photon.errorMessage || "Configure this photon to enable its features"}
99096
+ </p>
99097
+ </div>
99098
+ ` : ""}
98462
99099
  ${this.mode === "initial" && this.photon.errorMessage ? b2` <div class="error-banner">${this.photon.errorMessage}</div> ` : ""}
98463
99100
 
98464
99101
  <div class="config-form" role="presentation">
@@ -98482,18 +99119,25 @@ var PhotonConfig = class extends i4 {
98482
99119
  }
98483
99120
  _renderField(param) {
98484
99121
  const isRequired = !param.isOptional && !param.hasDefault;
98485
- const isSecret = this._isSecretField(param.name);
99122
+ const isSecret = param.isSecret ?? this._isSecretField(param.name);
98486
99123
  const isBoolean = param.type === "boolean";
98487
99124
  const isNumber2 = param.type === "number";
98488
99125
  const defaultValue = param.hasDefault ? String(param.defaultValue ?? "") : "";
99126
+ const seedValue = param.currentValue ?? defaultValue;
98489
99127
  return b2`
98490
99128
  <div class="form-group">
98491
99129
  <label>
98492
99130
  ${formatLabel(param.name)}${isRequired ? b2`<span class="required">*</span>` : ""}
98493
99131
  <span class="hint">${param.envVar}</span>
99132
+ ${isSecret ? b2`<span class="hint" style="color: var(--accent-secondary);">secret</span>` : ""}
98494
99133
  </label>
98495
99134
 
98496
- ${isBoolean ? this._renderToggle(param, defaultValue) : isNumber2 ? this._renderNumberInput(param, defaultValue, isRequired) : this._renderTextInput(param, defaultValue, isRequired, isSecret)}
99135
+ ${param.description ? b2`<p
99136
+ style="margin: 0; color: var(--t-muted); font-size: var(--text-xs); line-height: 1.4;"
99137
+ >
99138
+ ${param.description}
99139
+ </p>` : ""}
99140
+ ${isBoolean ? this._renderToggle(param, seedValue) : isNumber2 ? this._renderNumberInput(param, seedValue, isRequired) : this._renderTextInput(param, seedValue, isRequired, isSecret, !!param.currentValue)}
98497
99141
  </div>
98498
99142
  `;
98499
99143
  }
@@ -98530,15 +99174,18 @@ var PhotonConfig = class extends i4 {
98530
99174
  />
98531
99175
  `;
98532
99176
  }
98533
- _renderTextInput(param, defaultValue, isRequired, isSecret) {
99177
+ _renderTextInput(param, seedValue, isRequired, isSecret, hasCurrentValue) {
99178
+ const masked = isSecret && hasCurrentValue;
99179
+ const placeholder = masked ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022 (configured \u2014 type to replace)" : `Enter ${param.name}...`;
99180
+ const value = masked ? this._formData[param.envVar] ?? "" : this._formData[param.envVar] ?? seedValue;
98534
99181
  return b2`
98535
99182
  <input
98536
99183
  type="text"
98537
99184
  id="photon-${param.envVar}"
98538
99185
  name="${param.envVar}"
98539
99186
  class="${isSecret ? "secret-field" : ""}"
98540
- .value=${this._formData[param.envVar] ?? defaultValue}
98541
- placeholder="Enter ${param.name}..."
99187
+ .value=${value}
99188
+ placeholder="${placeholder}"
98542
99189
  @input=${(e8) => this._updateField(param.envVar, e8.target.value)}
98543
99190
  />
98544
99191
  `;
@@ -98775,6 +99422,9 @@ __decorateClass([
98775
99422
  __decorateClass([
98776
99423
  r5()
98777
99424
  ], PhotonConfig.prototype, "_formData", 2);
99425
+ __decorateClass([
99426
+ n4({ type: Boolean, attribute: "embedded" })
99427
+ ], PhotonConfig.prototype, "embedded", 2);
98778
99428
  PhotonConfig = __decorateClass([
98779
99429
  t4("photon-config")
98780
99430
  ], PhotonConfig);