@portel/photon 1.20.1 → 1.22.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 (148) hide show
  1. package/README.md +5 -5
  2. package/dist/ag-ui/adapter.d.ts +4 -1
  3. package/dist/ag-ui/adapter.d.ts.map +1 -1
  4. package/dist/ag-ui/adapter.js +58 -3
  5. package/dist/ag-ui/adapter.js.map +1 -1
  6. package/dist/ag-ui/types.d.ts +12 -0
  7. package/dist/ag-ui/types.d.ts.map +1 -1
  8. package/dist/auto-ui/beam/routes/api-browse.d.ts.map +1 -1
  9. package/dist/auto-ui/beam/routes/api-browse.js +8 -49
  10. package/dist/auto-ui/beam/routes/api-browse.js.map +1 -1
  11. package/dist/auto-ui/beam/routes/api-config.d.ts +1 -1
  12. package/dist/auto-ui/beam/routes/api-config.d.ts.map +1 -1
  13. package/dist/auto-ui/beam/routes/api-config.js +79 -1
  14. package/dist/auto-ui/beam/routes/api-config.js.map +1 -1
  15. package/dist/auto-ui/beam.d.ts.map +1 -1
  16. package/dist/auto-ui/beam.js +23 -31
  17. package/dist/auto-ui/beam.js.map +1 -1
  18. package/dist/auto-ui/bridge/index.d.ts.map +1 -1
  19. package/dist/auto-ui/bridge/index.js +107 -11
  20. package/dist/auto-ui/bridge/index.js.map +1 -1
  21. package/dist/auto-ui/bridge/renderers.d.ts +14 -0
  22. package/dist/auto-ui/bridge/renderers.d.ts.map +1 -1
  23. package/dist/auto-ui/bridge/renderers.js +680 -57
  24. package/dist/auto-ui/bridge/renderers.js.map +1 -1
  25. package/dist/auto-ui/frontend/index.html +3 -3
  26. package/dist/auto-ui/frontend/pure-view.html +19 -19
  27. package/dist/auto-ui/streamable-http-transport.d.ts.map +1 -1
  28. package/dist/auto-ui/streamable-http-transport.js +53 -2
  29. package/dist/auto-ui/streamable-http-transport.js.map +1 -1
  30. package/dist/auto-ui/ui-resolver.d.ts +25 -0
  31. package/dist/auto-ui/ui-resolver.d.ts.map +1 -0
  32. package/dist/auto-ui/ui-resolver.js +95 -0
  33. package/dist/auto-ui/ui-resolver.js.map +1 -0
  34. package/dist/beam-form.bundle.js +7 -7
  35. package/dist/beam-form.bundle.js.map +1 -1
  36. package/dist/beam.bundle.js +905 -185
  37. package/dist/beam.bundle.js.map +4 -4
  38. package/dist/cli/commands/build.d.ts.map +1 -1
  39. package/dist/cli/commands/build.js +9 -5
  40. package/dist/cli/commands/build.js.map +1 -1
  41. package/dist/cli/commands/init.d.ts.map +1 -1
  42. package/dist/cli/commands/init.js +93 -53
  43. package/dist/cli/commands/init.js.map +1 -1
  44. package/dist/cli/commands/publish.d.ts +14 -0
  45. package/dist/cli/commands/publish.d.ts.map +1 -0
  46. package/dist/cli/commands/publish.js +126 -0
  47. package/dist/cli/commands/publish.js.map +1 -0
  48. package/dist/cli/commands/run.d.ts.map +1 -1
  49. package/dist/cli/commands/run.js +2 -0
  50. package/dist/cli/commands/run.js.map +1 -1
  51. package/dist/cli/index.d.ts.map +1 -1
  52. package/dist/cli/index.js +3 -0
  53. package/dist/cli/index.js.map +1 -1
  54. package/dist/cli.d.ts +4 -0
  55. package/dist/cli.d.ts.map +1 -1
  56. package/dist/cli.js +11 -1
  57. package/dist/cli.js.map +1 -1
  58. package/dist/context.d.ts +6 -0
  59. package/dist/context.d.ts.map +1 -1
  60. package/dist/context.js +17 -5
  61. package/dist/context.js.map +1 -1
  62. package/dist/daemon/client.d.ts +9 -1
  63. package/dist/daemon/client.d.ts.map +1 -1
  64. package/dist/daemon/client.js +54 -1
  65. package/dist/daemon/client.js.map +1 -1
  66. package/dist/daemon/manager.d.ts +3 -0
  67. package/dist/daemon/manager.d.ts.map +1 -1
  68. package/dist/daemon/manager.js +88 -38
  69. package/dist/daemon/manager.js.map +1 -1
  70. package/dist/daemon/ownership.d.ts +12 -0
  71. package/dist/daemon/ownership.d.ts.map +1 -0
  72. package/dist/daemon/ownership.js +55 -0
  73. package/dist/daemon/ownership.js.map +1 -0
  74. package/dist/daemon/protocol.d.ts +4 -2
  75. package/dist/daemon/protocol.d.ts.map +1 -1
  76. package/dist/daemon/protocol.js +15 -2
  77. package/dist/daemon/protocol.js.map +1 -1
  78. package/dist/daemon/server.js +557 -83
  79. package/dist/daemon/server.js.map +1 -1
  80. package/dist/daemon/session-manager.d.ts +9 -1
  81. package/dist/daemon/session-manager.d.ts.map +1 -1
  82. package/dist/daemon/session-manager.js +54 -1
  83. package/dist/daemon/session-manager.js.map +1 -1
  84. package/dist/daemon/worker-manager.d.ts +12 -0
  85. package/dist/daemon/worker-manager.d.ts.map +1 -1
  86. package/dist/daemon/worker-manager.js +89 -6
  87. package/dist/daemon/worker-manager.js.map +1 -1
  88. package/dist/loader.d.ts +17 -9
  89. package/dist/loader.d.ts.map +1 -1
  90. package/dist/loader.js +415 -141
  91. package/dist/loader.js.map +1 -1
  92. package/dist/photon-cli-runner.d.ts.map +1 -1
  93. package/dist/photon-cli-runner.js +26 -2
  94. package/dist/photon-cli-runner.js.map +1 -1
  95. package/dist/photons/canvas/ui/canvas.photon.html +1493 -0
  96. package/dist/photons/canvas.photon.d.ts +400 -0
  97. package/dist/photons/canvas.photon.d.ts.map +1 -0
  98. package/dist/photons/canvas.photon.js +662 -0
  99. package/dist/photons/canvas.photon.js.map +1 -0
  100. package/dist/photons/canvas.photon.ts +814 -0
  101. package/dist/photons/publish.photon.d.ts +97 -0
  102. package/dist/photons/publish.photon.d.ts.map +1 -0
  103. package/dist/photons/publish.photon.js +569 -0
  104. package/dist/photons/publish.photon.js.map +1 -0
  105. package/dist/photons/publish.photon.ts +683 -0
  106. package/dist/photons/ui/canvas.photon.html +624 -0
  107. package/dist/resource-server.d.ts.map +1 -1
  108. package/dist/resource-server.js +7 -1
  109. package/dist/resource-server.js.map +1 -1
  110. package/dist/server.d.ts +7 -0
  111. package/dist/server.d.ts.map +1 -1
  112. package/dist/server.js +67 -37
  113. package/dist/server.js.map +1 -1
  114. package/dist/shared/error-handler.d.ts +1 -0
  115. package/dist/shared/error-handler.d.ts.map +1 -1
  116. package/dist/shared/error-handler.js +68 -10
  117. package/dist/shared/error-handler.js.map +1 -1
  118. package/dist/shared/logger.d.ts.map +1 -1
  119. package/dist/shared/logger.js +34 -0
  120. package/dist/shared/logger.js.map +1 -1
  121. package/dist/shared-utils.d.ts.map +1 -1
  122. package/dist/shared-utils.js +2 -2
  123. package/dist/shared-utils.js.map +1 -1
  124. package/dist/telemetry/context.d.ts +24 -0
  125. package/dist/telemetry/context.d.ts.map +1 -0
  126. package/dist/telemetry/context.js +17 -0
  127. package/dist/telemetry/context.js.map +1 -0
  128. package/dist/telemetry/logs.d.ts +38 -0
  129. package/dist/telemetry/logs.d.ts.map +1 -0
  130. package/dist/telemetry/logs.js +108 -0
  131. package/dist/telemetry/logs.js.map +1 -0
  132. package/dist/telemetry/metrics.d.ts +71 -0
  133. package/dist/telemetry/metrics.d.ts.map +1 -0
  134. package/dist/telemetry/metrics.js +184 -0
  135. package/dist/telemetry/metrics.js.map +1 -0
  136. package/dist/telemetry/otel.d.ts +20 -1
  137. package/dist/telemetry/otel.d.ts.map +1 -1
  138. package/dist/telemetry/otel.js +79 -2
  139. package/dist/telemetry/otel.js.map +1 -1
  140. package/dist/telemetry/sdk.d.ts +49 -0
  141. package/dist/telemetry/sdk.d.ts.map +1 -0
  142. package/dist/telemetry/sdk.js +110 -0
  143. package/dist/telemetry/sdk.js.map +1 -0
  144. package/dist/tsx-compiler.d.ts +23 -0
  145. package/dist/tsx-compiler.d.ts.map +1 -0
  146. package/dist/tsx-compiler.js +221 -0
  147. package/dist/tsx-compiler.js.map +1 -0
  148. package/package.json +7 -7
@@ -9,6 +9,7 @@ const noopSpan = {
9
9
  setAttribute() { },
10
10
  addEvent() { },
11
11
  setStatus() { },
12
+ recordException() { },
12
13
  end() { },
13
14
  };
14
15
  // Cached reference to the OTel API (undefined = not yet checked, null = not available)
@@ -53,23 +54,99 @@ function wrapOtelSpan(otelSpan, otelApi) {
53
54
  setStatus(code, message) {
54
55
  const statusCode = code === 'OK' ? otelApi.SpanStatusCode.OK : otelApi.SpanStatusCode.ERROR;
55
56
  otelSpan.setStatus({ code: statusCode, message });
57
+ // Force-sample failed spans even under head-based sampling
58
+ if (code === 'ERROR') {
59
+ try {
60
+ otelSpan.setAttribute('sampling.priority', 1);
61
+ }
62
+ catch {
63
+ /* best-effort */
64
+ }
65
+ }
66
+ },
67
+ recordException(error) {
68
+ try {
69
+ if (error instanceof Error) {
70
+ otelSpan.recordException(error);
71
+ }
72
+ else {
73
+ otelSpan.recordException(new Error(String(error)));
74
+ }
75
+ }
76
+ catch {
77
+ /* best-effort */
78
+ }
56
79
  },
57
80
  end() {
58
81
  otelSpan.end();
59
82
  },
60
83
  };
61
84
  }
85
+ /**
86
+ * Parse a W3C traceparent header into its components.
87
+ * Format: `{version}-{traceId}-{parentSpanId}-{flags}` (e.g. `00-abc...-def...-01`).
88
+ * Returns null if the header is malformed.
89
+ */
90
+ export function parseTraceparent(traceparent) {
91
+ if (!traceparent || typeof traceparent !== 'string')
92
+ return null;
93
+ const parts = traceparent.trim().split('-');
94
+ if (parts.length !== 4)
95
+ return null;
96
+ const [version, traceId, spanId, flags] = parts;
97
+ if (version.length !== 2 || traceId.length !== 32 || spanId.length !== 16 || flags.length !== 2) {
98
+ return null;
99
+ }
100
+ if (!/^[0-9a-f]+$/i.test(traceId) || !/^[0-9a-f]+$/i.test(spanId))
101
+ return null;
102
+ // All-zero trace/span IDs are invalid per the spec.
103
+ if (/^0+$/.test(traceId) || /^0+$/.test(spanId))
104
+ return null;
105
+ return { version, traceId, spanId, flags };
106
+ }
62
107
  /**
63
108
  * Start a span for tool execution following GenAI semantic conventions.
109
+ * @param traceId - Optional W3C-compatible trace ID (32 hex chars) for async executions.
110
+ * When provided, set as `photon.trace_id` on the span so async executions are
111
+ * correlated with the execution ID returned to the caller.
112
+ * @param stateful - When true, sets `photon.stateful=true` on the span.
113
+ * @param parentTraceparent - Optional W3C traceparent header. When provided, the new
114
+ * span is created as a child of that remote span context so distributed traces
115
+ * chain across client → photon → downstream calls.
64
116
  */
65
- export function startToolSpan(photon, tool, params) {
117
+ export function startToolSpan(photon, tool, params, traceId, stateful, parentTraceparent) {
66
118
  const tracer = getTracerSync();
67
119
  if (!tracer)
68
120
  return noopSpan;
69
- const span = tracer.startSpan(`gen_ai.tool.call ${photon}.${tool}`);
121
+ const parent = parseTraceparent(parentTraceparent);
122
+ let span;
123
+ if (parent && otelApi?.trace && otelApi?.context) {
124
+ try {
125
+ const spanContext = {
126
+ traceId: parent.traceId,
127
+ spanId: parent.spanId,
128
+ traceFlags: parseInt(parent.flags, 16) || 0,
129
+ isRemote: true,
130
+ };
131
+ const ctx = otelApi.trace.setSpanContext(otelApi.context.active(), spanContext);
132
+ span = tracer.startSpan(`gen_ai.tool.call ${photon}.${tool}`, undefined, ctx);
133
+ }
134
+ catch {
135
+ span = tracer.startSpan(`gen_ai.tool.call ${photon}.${tool}`);
136
+ }
137
+ }
138
+ else {
139
+ span = tracer.startSpan(`gen_ai.tool.call ${photon}.${tool}`);
140
+ }
70
141
  span.setAttribute('gen_ai.tool.name', tool);
71
142
  span.setAttribute('gen_ai.agent.name', photon);
72
143
  span.setAttribute('gen_ai.operation.name', 'execute_tool');
144
+ if (traceId) {
145
+ span.setAttribute('photon.trace_id', traceId);
146
+ }
147
+ if (typeof stateful === 'boolean') {
148
+ span.setAttribute('photon.stateful', stateful);
149
+ }
73
150
  if (params) {
74
151
  const paramKeys = Object.keys(params);
75
152
  if (paramKeys.length > 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"otel.js","sourceRoot":"","sources":["../../src/telemetry/otel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"otel.js","sourceRoot":"","sources":["../../src/telemetry/otel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * OpenTelemetry NodeSDK bootstrap for Photon.
3
+ *
4
+ * Zero required dependencies. When `OTEL_EXPORTER_OTLP_ENDPOINT` is set in
5
+ * the environment AND `@opentelemetry/sdk-node` is installed, the runtime
6
+ * wires up OTLP exporters for traces, metrics, and logs so every span,
7
+ * counter, histogram, and log record emitted elsewhere in the codebase
8
+ * lands in an OTLP-compatible backend (Jaeger, Grafana Tempo, SigNoz,
9
+ * Honeycomb, DataDog, etc.) without further configuration.
10
+ *
11
+ * This is the final piece that makes the instrumentation shipped in
12
+ * otel.ts / metrics.ts / logs.ts observable in practice.
13
+ */
14
+ import type { PhotonSpan } from './otel.js';
15
+ /**
16
+ * Returns true if the caller has opted into OTel export via the standard
17
+ * environment variable. The OTel spec treats `OTEL_EXPORTER_OTLP_ENDPOINT`
18
+ * as the universal switch.
19
+ */
20
+ export declare function isOtelRequested(): boolean;
21
+ export interface OtelSdkOptions {
22
+ /** Service name attached to every exported record. Defaults to `photon`. */
23
+ serviceName?: string;
24
+ /** Service version. Defaults to PHOTON_VERSION if available. */
25
+ serviceVersion?: string;
26
+ /** Deployment environment (e.g. "prod", "staging"). */
27
+ deploymentEnvironment?: string;
28
+ }
29
+ /**
30
+ * Start the OTel NodeSDK if the env + dependencies are present.
31
+ *
32
+ * Idempotent — safe to call multiple times. Returns true if the SDK was
33
+ * actually started, false if the bootstrap was skipped (env missing, SDK
34
+ * not installed, or already running).
35
+ *
36
+ * Call this as early as possible in process startup, before any photon
37
+ * code runs, so spans from the very first tool call are captured.
38
+ */
39
+ export declare function initOtelSdk(options?: OtelSdkOptions): Promise<boolean>;
40
+ /**
41
+ * Shut down the SDK and flush exporters. For tests.
42
+ */
43
+ export declare function shutdownOtelSdk(): Promise<void>;
44
+ /**
45
+ * Returns true if the SDK has been started in this process.
46
+ */
47
+ export declare function isOtelSdkStarted(): boolean;
48
+ export type { PhotonSpan };
49
+ //# sourceMappingURL=sdk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/telemetry/sdk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAK5C;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,MAAM,WAAW,cAAc;IAC7B,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CAyDhF;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAWrD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAID,YAAY,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * OpenTelemetry NodeSDK bootstrap for Photon.
3
+ *
4
+ * Zero required dependencies. When `OTEL_EXPORTER_OTLP_ENDPOINT` is set in
5
+ * the environment AND `@opentelemetry/sdk-node` is installed, the runtime
6
+ * wires up OTLP exporters for traces, metrics, and logs so every span,
7
+ * counter, histogram, and log record emitted elsewhere in the codebase
8
+ * lands in an OTLP-compatible backend (Jaeger, Grafana Tempo, SigNoz,
9
+ * Honeycomb, DataDog, etc.) without further configuration.
10
+ *
11
+ * This is the final piece that makes the instrumentation shipped in
12
+ * otel.ts / metrics.ts / logs.ts observable in practice.
13
+ */
14
+ let started = false;
15
+ let sdkInstance;
16
+ /**
17
+ * Returns true if the caller has opted into OTel export via the standard
18
+ * environment variable. The OTel spec treats `OTEL_EXPORTER_OTLP_ENDPOINT`
19
+ * as the universal switch.
20
+ */
21
+ export function isOtelRequested() {
22
+ return Boolean(process.env.OTEL_EXPORTER_OTLP_ENDPOINT || process.env.OTEL_SDK_DISABLED === '0');
23
+ }
24
+ /**
25
+ * Start the OTel NodeSDK if the env + dependencies are present.
26
+ *
27
+ * Idempotent — safe to call multiple times. Returns true if the SDK was
28
+ * actually started, false if the bootstrap was skipped (env missing, SDK
29
+ * not installed, or already running).
30
+ *
31
+ * Call this as early as possible in process startup, before any photon
32
+ * code runs, so spans from the very first tool call are captured.
33
+ */
34
+ export async function initOtelSdk(options = {}) {
35
+ if (started)
36
+ return false;
37
+ if (!isOtelRequested())
38
+ return false;
39
+ try {
40
+ const sdkNodeModule = '@opentelemetry/sdk-node';
41
+ const resourcesModule = '@opentelemetry/resources';
42
+ const semconvModule = '@opentelemetry/semantic-conventions';
43
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
44
+ const sdkNode = await import(/* webpackIgnore: true */ sdkNodeModule);
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
+ const resources = await import(/* webpackIgnore: true */ resourcesModule);
47
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
+ const semconv = await import(/* webpackIgnore: true */ semconvModule);
49
+ const attrs = {
50
+ [semconv.SemanticResourceAttributes?.SERVICE_NAME ?? 'service.name']: options.serviceName || process.env.OTEL_SERVICE_NAME || 'photon',
51
+ };
52
+ if (options.serviceVersion) {
53
+ attrs[semconv.SemanticResourceAttributes?.SERVICE_VERSION ?? 'service.version'] =
54
+ options.serviceVersion;
55
+ }
56
+ if (options.deploymentEnvironment) {
57
+ attrs['deployment.environment'] = options.deploymentEnvironment;
58
+ }
59
+ const resource = resources.Resource?.default
60
+ ? resources.Resource.default().merge(new resources.Resource(attrs))
61
+ : new resources.Resource(attrs);
62
+ const sdk = new sdkNode.NodeSDK({
63
+ resource,
64
+ // The SDK auto-detects OTLP exporters from OTEL_EXPORTER_OTLP_ENDPOINT
65
+ // and OTEL_EXPORTER_OTLP_PROTOCOL (grpc, http/protobuf, http/json).
66
+ });
67
+ sdk.start();
68
+ sdkInstance = sdk;
69
+ started = true;
70
+ // Graceful shutdown on process exit — flush pending spans/metrics/logs.
71
+ const shutdown = () => {
72
+ void sdk.shutdown?.().catch(() => {
73
+ /* best-effort */
74
+ });
75
+ };
76
+ process.once('SIGTERM', shutdown);
77
+ process.once('SIGINT', shutdown);
78
+ process.once('beforeExit', shutdown);
79
+ return true;
80
+ }
81
+ catch {
82
+ // SDK not installed or bootstrap failed — stay silent. The runtime's
83
+ // no-op wrappers in otel.ts/metrics.ts/logs.ts continue to work.
84
+ return false;
85
+ }
86
+ }
87
+ /**
88
+ * Shut down the SDK and flush exporters. For tests.
89
+ */
90
+ export async function shutdownOtelSdk() {
91
+ if (!started)
92
+ return;
93
+ started = false;
94
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
95
+ const sdk = sdkInstance;
96
+ try {
97
+ await sdk?.shutdown?.();
98
+ }
99
+ catch {
100
+ /* best-effort */
101
+ }
102
+ sdkInstance = undefined;
103
+ }
104
+ /**
105
+ * Returns true if the SDK has been started in this process.
106
+ */
107
+ export function isOtelSdkStarted() {
108
+ return started;
109
+ }
110
+ //# sourceMappingURL=sdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/telemetry/sdk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * TSX View Compiler
3
+ *
4
+ * Transpiles and bundles .tsx view files into self-contained HTML documents
5
+ * using esbuild. Ships a tiny built-in JSX runtime (~1KB) that maps directly
6
+ * to DOM calls — no React, no Preact, no virtual DOM.
7
+ *
8
+ * Users can override with `@jsxImportSource` pragma or tsconfig.json in the
9
+ * ui/ folder to use React/Preact/Solid if they prefer.
10
+ */
11
+ /**
12
+ * Compile a TSX file into a self-contained HTML document.
13
+ */
14
+ export declare function compileTsx(filePath: string): Promise<string>;
15
+ /**
16
+ * Compile with mtime-based caching. Re-transpiles only when the file changes.
17
+ */
18
+ export declare function compileTsxCached(filePath: string): Promise<string>;
19
+ /**
20
+ * Synchronous variant for the build command (uses esbuild.buildSync).
21
+ */
22
+ export declare function compileTsxSync(filePath: string): string;
23
+ //# sourceMappingURL=tsx-compiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsx-compiler.d.ts","sourceRoot":"","sources":["../src/tsx-compiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAoLH;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUlE;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CASxE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAUvD"}
@@ -0,0 +1,221 @@
1
+ /**
2
+ * TSX View Compiler
3
+ *
4
+ * Transpiles and bundles .tsx view files into self-contained HTML documents
5
+ * using esbuild. Ships a tiny built-in JSX runtime (~1KB) that maps directly
6
+ * to DOM calls — no React, no Preact, no virtual DOM.
7
+ *
8
+ * Users can override with `@jsxImportSource` pragma or tsconfig.json in the
9
+ * ui/ folder to use React/Preact/Solid if they prefer.
10
+ */
11
+ import * as esbuild from 'esbuild';
12
+ import * as fs from 'fs';
13
+ import * as fsAsync from 'fs/promises';
14
+ import * as os from 'os';
15
+ import * as path from 'path';
16
+ // ─── Built-in JSX Runtime ──────────────────────────────────────────────────
17
+ // Tiny DOM-based JSX factory. `h()` returns real DOM nodes, not virtual nodes.
18
+ // Injected into every TSX build unless the user overrides via tsconfig.
19
+ const JSX_RUNTIME = `
20
+ export function h(type, props, ...children) {
21
+ if (type === Fragment) {
22
+ const frag = document.createDocumentFragment();
23
+ _append(frag, children);
24
+ return frag;
25
+ }
26
+ if (typeof type === 'function') {
27
+ return type(Object.assign({}, props, { children: children.length <= 1 ? children[0] : children }));
28
+ }
29
+ const el = document.createElement(type);
30
+ if (props) {
31
+ for (const [k, v] of Object.entries(props)) {
32
+ if (k === 'children' || v == null || v === false) continue;
33
+ if (k.startsWith('on') && typeof v === 'function') {
34
+ el.addEventListener(k[2].toLowerCase() + k.slice(3), v);
35
+ } else if (k === 'style' && typeof v === 'object') {
36
+ Object.assign(el.style, v);
37
+ } else if (k === 'className') {
38
+ el.setAttribute('class', v);
39
+ } else if (k === 'htmlFor') {
40
+ el.setAttribute('for', v);
41
+ } else if (k === 'dangerouslySetInnerHTML') {
42
+ el.innerHTML = v.__html;
43
+ } else if (v === true) {
44
+ el.setAttribute(k, '');
45
+ } else {
46
+ el.setAttribute(k, String(v));
47
+ }
48
+ }
49
+ }
50
+ _append(el, children);
51
+ return el;
52
+ }
53
+
54
+ export function Fragment() {}
55
+
56
+ export function _append(parent, children) {
57
+ for (const child of children) {
58
+ if (child == null || child === false || child === true) continue;
59
+ if (Array.isArray(child)) { _append(parent, child); continue; }
60
+ parent.append(typeof child === 'object' ? child : String(child));
61
+ }
62
+ }
63
+
64
+ export function render(element, container) {
65
+ if (typeof container === 'string') container = document.querySelector(container);
66
+ container.replaceChildren(element);
67
+ return element;
68
+ }
69
+ `.trim();
70
+ // Write runtime to a temp file once per process for esbuild inject
71
+ let _runtimePath = null;
72
+ function getRuntimePath() {
73
+ if (!_runtimePath) {
74
+ _runtimePath = path.join(os.tmpdir(), `photon-jsx-runtime-${process.pid}.js`);
75
+ fs.writeFileSync(_runtimePath, JSX_RUNTIME);
76
+ }
77
+ return _runtimePath;
78
+ }
79
+ // In-memory cache: filePath → { mtimeMs, html }
80
+ const cache = new Map();
81
+ /**
82
+ * Find the nearest tsconfig.json walking up from startDir.
83
+ * Stops at the photon asset folder root (parent of ui/).
84
+ */
85
+ function findTsconfig(startDir) {
86
+ let dir = startDir;
87
+ const root = path.dirname(dir); // stop at parent of ui/
88
+ while (true) {
89
+ const candidate = path.join(dir, 'tsconfig.json');
90
+ if (fs.existsSync(candidate))
91
+ return candidate;
92
+ if (dir === root || dir === path.dirname(dir))
93
+ break;
94
+ dir = path.dirname(dir);
95
+ }
96
+ return undefined;
97
+ }
98
+ /**
99
+ * Build esbuild options for a TSX file.
100
+ * Uses built-in DOM-based JSX runtime by default.
101
+ * Users can override via tsconfig.json (jsx/jsxImportSource settings).
102
+ */
103
+ function buildOptions(filePath, tsconfigPath) {
104
+ const uiDir = path.dirname(filePath);
105
+ // If user has a tsconfig, let it control JSX settings
106
+ // Otherwise use our built-in runtime via inject
107
+ const hasUserTsconfig = !!tsconfigPath;
108
+ return {
109
+ entryPoints: [filePath],
110
+ bundle: true,
111
+ write: false,
112
+ format: 'esm',
113
+ platform: 'browser',
114
+ target: 'es2020',
115
+ // Built-in runtime: classic transform with injected h/Fragment
116
+ ...(!hasUserTsconfig
117
+ ? {
118
+ jsx: 'transform',
119
+ jsxFactory: 'h',
120
+ jsxFragment: 'Fragment',
121
+ inject: [getRuntimePath()],
122
+ }
123
+ : {
124
+ // Let tsconfig control jsx mode and import source
125
+ tsconfig: tsconfigPath,
126
+ }),
127
+ nodePaths: [
128
+ path.join(uiDir, 'node_modules'),
129
+ path.join(uiDir, '..', 'node_modules'),
130
+ path.join(uiDir, '..', '..', 'node_modules'),
131
+ path.join(uiDir, '..', '..', '..', 'node_modules'),
132
+ ],
133
+ logLevel: 'silent',
134
+ };
135
+ }
136
+ /**
137
+ * Wrap bundled JS in a self-contained HTML document.
138
+ */
139
+ function wrapInHtml(js) {
140
+ return `<!doctype html>
141
+ <html lang="en">
142
+ <head>
143
+ <meta charset="UTF-8">
144
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
145
+ <style>*, *::before, *::after { box-sizing: border-box; } body { margin: 0; font-family: system-ui, -apple-system, sans-serif; }</style>
146
+ </head>
147
+ <body>
148
+ <div id="root"></div>
149
+ <script type="module">
150
+ ${js}
151
+ </script>
152
+ </body>
153
+ </html>`;
154
+ }
155
+ /**
156
+ * Wrap an esbuild error in a developer-friendly HTML error page.
157
+ */
158
+ function wrapError(filePath, error) {
159
+ const message = error instanceof Error ? error.message : String(error);
160
+ const escaped = message.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
161
+ return `<!doctype html>
162
+ <html lang="en">
163
+ <head>
164
+ <meta charset="UTF-8">
165
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
166
+ <style>
167
+ body { margin: 0; padding: 24px; font-family: ui-monospace, monospace; background: #1a0000; color: #ff6b6b; }
168
+ h2 { margin: 0 0 16px; font-size: 14px; color: #ff4444; }
169
+ pre { white-space: pre-wrap; word-break: break-word; font-size: 13px; line-height: 1.5; }
170
+ .file { color: #888; font-size: 12px; margin-bottom: 8px; }
171
+ </style>
172
+ </head>
173
+ <body>
174
+ <h2>TSX Build Error</h2>
175
+ <div class="file">${path.basename(filePath)}</div>
176
+ <pre>${escaped}</pre>
177
+ </body>
178
+ </html>`;
179
+ }
180
+ /**
181
+ * Compile a TSX file into a self-contained HTML document.
182
+ */
183
+ export async function compileTsx(filePath) {
184
+ const tsconfigPath = findTsconfig(path.dirname(filePath));
185
+ try {
186
+ const result = await esbuild.build(buildOptions(filePath, tsconfigPath));
187
+ const js = result.outputFiles?.[0]?.text ?? '';
188
+ return wrapInHtml(js);
189
+ }
190
+ catch (err) {
191
+ return wrapError(filePath, err);
192
+ }
193
+ }
194
+ /**
195
+ * Compile with mtime-based caching. Re-transpiles only when the file changes.
196
+ */
197
+ export async function compileTsxCached(filePath) {
198
+ const stat = await fsAsync.stat(filePath);
199
+ const cached = cache.get(filePath);
200
+ if (cached && cached.mtimeMs === stat.mtimeMs) {
201
+ return cached.html;
202
+ }
203
+ const html = await compileTsx(filePath);
204
+ cache.set(filePath, { mtimeMs: stat.mtimeMs, html });
205
+ return html;
206
+ }
207
+ /**
208
+ * Synchronous variant for the build command (uses esbuild.buildSync).
209
+ */
210
+ export function compileTsxSync(filePath) {
211
+ const tsconfigPath = findTsconfig(path.dirname(filePath));
212
+ try {
213
+ const result = esbuild.buildSync(buildOptions(filePath, tsconfigPath));
214
+ const js = result.outputFiles?.[0]?.text ?? '';
215
+ return wrapInHtml(js);
216
+ }
217
+ catch (err) {
218
+ return wrapError(filePath, err);
219
+ }
220
+ }
221
+ //# sourceMappingURL=tsx-compiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsx-compiler.js","sourceRoot":"","sources":["../src/tsx-compiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,OAAO,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,8EAA8E;AAC9E,+EAA+E;AAC/E,wEAAwE;AAExE,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkDnB,CAAC,IAAI,EAAE,CAAC;AAET,mEAAmE;AACnE,IAAI,YAAY,GAAkB,IAAI,CAAC;AACvC,SAAS,cAAc;IACrB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,sBAAsB,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;QAC9E,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,gDAAgD;AAChD,MAAM,KAAK,GAAG,IAAI,GAAG,EAA6C,CAAC;AAEnE;;;GAGG;AACH,SAAS,YAAY,CAAC,QAAgB;IACpC,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,wBAAwB;IACxD,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAClD,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;QAC/C,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;YAAE,MAAM;QACrD,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,QAAgB,EAAE,YAAqB;IAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAErC,sDAAsD;IACtD,gDAAgD;IAChD,MAAM,eAAe,GAAG,CAAC,CAAC,YAAY,CAAC;IAEvC,OAAO;QACL,WAAW,EAAE,CAAC,QAAQ,CAAC;QACvB,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,SAAS;QACnB,MAAM,EAAE,QAAQ;QAChB,+DAA+D;QAC/D,GAAG,CAAC,CAAC,eAAe;YAClB,CAAC,CAAC;gBACE,GAAG,EAAE,WAAW;gBAChB,UAAU,EAAE,GAAG;gBACf,WAAW,EAAE,UAAU;gBACvB,MAAM,EAAE,CAAC,cAAc,EAAE,CAAC;aAC3B;YACH,CAAC,CAAC;gBACE,kDAAkD;gBAClD,QAAQ,EAAE,YAAY;aACvB,CAAC;QACN,SAAS,EAAE;YACT,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,cAAc,CAAC;YAChC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,cAAc,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC;YAC5C,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC;SACnD;QACD,QAAQ,EAAE,QAAQ;KACnB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,EAAU;IAC5B,OAAO;;;;;;;;;;EAUP,EAAE;;;QAGI,CAAC;AACT,CAAC;AAED;;GAEG;AACH,SAAS,SAAS,CAAC,QAAgB,EAAE,KAAc;IACjD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC3F,OAAO;;;;;;;;;;;;;;oBAcW,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;OACpC,OAAO;;QAEN,CAAC;AACT,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE1D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC;QACzE,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;QAC/C,OAAO,UAAU,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,QAAgB;IACrD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,MAAM,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;QAC9C,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;IACxC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE1D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC;QACvE,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;QAC/C,OAAO,UAAU,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAClC,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portel/photon",
3
- "version": "1.20.1",
3
+ "version": "1.22.0",
4
4
  "description": "You focus on the business logic. We'll enable the rest. Build MCP servers and CLI tools in a single TypeScript file.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -14,7 +14,7 @@
14
14
  ],
15
15
  "scripts": {
16
16
  "prepare": "git config core.hooksPath .githooks || true",
17
- "build": "eslint src/ --quiet && tsc && cp -r src/photons dist/ && chmod +x dist/cli.js && tsx scripts/build-beam.ts",
17
+ "build": "eslint src/ --quiet && tsc && cp -r src/photons dist/ && chmod +x dist/cli.js && node scripts/build-beam.mjs",
18
18
  "dev": "tsc --watch",
19
19
  "lint": "eslint src/",
20
20
  "lint:fix": "eslint src/ --fix",
@@ -22,9 +22,9 @@
22
22
  "format": "prettier --write \"src/**/*.ts\"",
23
23
  "format:check": "prettier --check \"src/**/*.ts\"",
24
24
  "typecheck": "tsc --noEmit",
25
- "build:beam": "tsx scripts/build-beam.ts",
26
- "watch:beam": "tsx scripts/build-beam.ts --watch",
27
- "dev:beam": "npm run build && npm run build:beam && (trap 'kill 0' EXIT; tsc --watch --preserveWatchOutput & tsx scripts/build-beam.ts --watch & sleep 1 && tsx watch src/cli.ts beam)",
25
+ "build:beam": "node scripts/build-beam.mjs",
26
+ "watch:beam": "node scripts/build-beam.mjs --watch",
27
+ "dev:beam": "npm run build && npm run build:beam && (trap 'kill 0' EXIT; tsc --watch --preserveWatchOutput & node scripts/build-beam.mjs --watch & sleep 1 && tsx watch src/cli.ts beam)",
28
28
  "prepublishOnly": "node -e \"const p=require('./package.json'); if(JSON.stringify(p.dependencies).includes('file:')) { console.error('ERROR: file: dependency found.'); process.exit(1); }\" && node -e \"const fs=require('fs'),path=require('path'); const p=require('./package.json'); for(const d of Object.keys(p.dependencies||{})){const t=path.join('node_modules',d); if(fs.lstatSync(t).isSymbolicLink()){console.error('ERROR: '+d+' is npm-linked. Run: npm unlink '+d+' && npm install '+d); process.exit(1);}}\" && npm run build && npm run build:beam",
29
29
  "test": "bash scripts/run-tests.sh",
30
30
  "test:chain": "npm run test:all",
@@ -112,7 +112,7 @@
112
112
  "@modelcontextprotocol/ext-apps": "^1.0.1",
113
113
  "@modelcontextprotocol/sdk": "^1.25.2",
114
114
  "@portel/cli": "^1.1.0",
115
- "@portel/photon-core": "^2.18.1",
115
+ "@portel/photon-core": "^2.22.0",
116
116
  "boxen": "^8.0.1",
117
117
  "chalk": "^5.4.1",
118
118
  "chart.js": "^4.5.1",
@@ -120,7 +120,7 @@
120
120
  "cli-highlight": "^2.1.11",
121
121
  "cli-table3": "^0.6.5",
122
122
  "commander": "^12.1.0",
123
- "esbuild": "^0.27.0",
123
+ "esbuild": "^0.28.0",
124
124
  "fast-json-patch": "^3.1.1",
125
125
  "ora": "^9.3.0",
126
126
  "qrcode": "^1.5.4"