@portel/photon 1.32.6 → 1.33.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 (71) hide show
  1. package/README.md +5 -1
  2. package/dist/auth/mcp-jwt.d.ts +59 -0
  3. package/dist/auth/mcp-jwt.d.ts.map +1 -0
  4. package/dist/auth/mcp-jwt.js +177 -0
  5. package/dist/auth/mcp-jwt.js.map +1 -0
  6. package/dist/auto-ui/beam/types.d.ts +1 -0
  7. package/dist/auto-ui/beam/types.d.ts.map +1 -1
  8. package/dist/auto-ui/beam.d.ts +1 -0
  9. package/dist/auto-ui/beam.d.ts.map +1 -1
  10. package/dist/auto-ui/beam.js +92 -9
  11. package/dist/auto-ui/beam.js.map +1 -1
  12. package/dist/auto-ui/playground-html.d.ts.map +1 -1
  13. package/dist/auto-ui/playground-html.js +28 -38
  14. package/dist/auto-ui/playground-html.js.map +1 -1
  15. package/dist/auto-ui/streamable-http-transport.d.ts +1 -0
  16. package/dist/auto-ui/streamable-http-transport.d.ts.map +1 -1
  17. package/dist/auto-ui/streamable-http-transport.js +9 -1
  18. package/dist/auto-ui/streamable-http-transport.js.map +1 -1
  19. package/dist/auto-ui/ui-resolver.d.ts +12 -1
  20. package/dist/auto-ui/ui-resolver.d.ts.map +1 -1
  21. package/dist/auto-ui/ui-resolver.js +19 -3
  22. package/dist/auto-ui/ui-resolver.js.map +1 -1
  23. package/dist/beam.bundle.js +6 -0
  24. package/dist/beam.bundle.js.map +2 -2
  25. package/dist/cli/commands/auth.d.ts +15 -0
  26. package/dist/cli/commands/auth.d.ts.map +1 -0
  27. package/dist/cli/commands/auth.js +105 -0
  28. package/dist/cli/commands/auth.js.map +1 -0
  29. package/dist/cli/commands/build.d.ts.map +1 -1
  30. package/dist/cli/commands/build.js +13 -5
  31. package/dist/cli/commands/build.js.map +1 -1
  32. package/dist/cli/commands/host.d.ts.map +1 -1
  33. package/dist/cli/commands/host.js +9 -0
  34. package/dist/cli/commands/host.js.map +1 -1
  35. package/dist/cli/commands/run.d.ts.map +1 -1
  36. package/dist/cli/commands/run.js +3 -0
  37. package/dist/cli/commands/run.js.map +1 -1
  38. package/dist/cli/index.d.ts.map +1 -1
  39. package/dist/cli/index.js +6 -0
  40. package/dist/cli/index.js.map +1 -1
  41. package/dist/daemon/manager.d.ts +8 -0
  42. package/dist/daemon/manager.d.ts.map +1 -1
  43. package/dist/daemon/manager.js +46 -9
  44. package/dist/daemon/manager.js.map +1 -1
  45. package/dist/deploy/cloudflare.d.ts +2 -0
  46. package/dist/deploy/cloudflare.d.ts.map +1 -1
  47. package/dist/deploy/cloudflare.js +171 -16
  48. package/dist/deploy/cloudflare.js.map +1 -1
  49. package/dist/editor-support/docblock-tag-catalog.d.ts.map +1 -1
  50. package/dist/editor-support/docblock-tag-catalog.js +6 -0
  51. package/dist/editor-support/docblock-tag-catalog.js.map +1 -1
  52. package/dist/loader.d.ts +3 -0
  53. package/dist/loader.d.ts.map +1 -1
  54. package/dist/loader.js +49 -0
  55. package/dist/loader.js.map +1 -1
  56. package/dist/photon-doc-extractor.d.ts +1 -0
  57. package/dist/photon-doc-extractor.d.ts.map +1 -1
  58. package/dist/photon-doc-extractor.js +13 -0
  59. package/dist/photon-doc-extractor.js.map +1 -1
  60. package/dist/resource-server.d.ts.map +1 -1
  61. package/dist/resource-server.js +5 -2
  62. package/dist/resource-server.js.map +1 -1
  63. package/dist/server.d.ts.map +1 -1
  64. package/dist/server.js +231 -185
  65. package/dist/server.js.map +1 -1
  66. package/dist/tsx-compiler.d.ts +65 -5
  67. package/dist/tsx-compiler.d.ts.map +1 -1
  68. package/dist/tsx-compiler.js +531 -52
  69. package/dist/tsx-compiler.js.map +1 -1
  70. package/package.json +1 -1
  71. package/templates/cloudflare/worker.ts.template +374 -47
package/README.md CHANGED
@@ -550,6 +550,8 @@ Uses Bun's compiler under the hood. The binary bundles the photon, its `@depende
550
550
  | `@param ... {@format email}` | Param | Input validation and field type |
551
551
  | `@param ... {@min N} {@max N}` | Param | Numeric range constraints |
552
552
  | `@ui` | Class/Method | Link a custom HTML template |
553
+ | `@auth` | Class | Require or describe MCP authentication and populate `this.caller` |
554
+ | `@scope` | Method | Override the inferred OAuth scope for a protected MCP tool call |
553
555
  | `@expose` | Method | Auto-bind to `POST /api/<kebab>` for SPA fetch (`public` skips the SameSite gate) |
554
556
  | `@get /path` | Method | HTTP-only GET route; shown as a web app in Beam, not an MCP tool. Supports `:param` segments |
555
557
  | `@post /path` | Method | HTTP-only POST route; shown as a web app in Beam, not an MCP tool. Supports `:param` segments |
@@ -574,6 +576,7 @@ Uses Bun's compiler under the hood. The binary bundles the photon, its `@depende
574
576
  |---|---|
575
577
  | [Getting Started](./docs/getting-started.md) | Install, build, and run your first photon in 5 minutes |
576
578
  | [Core Concepts](./docs/concepts.md) | The 6 ideas behind Photon |
579
+ | [Tag Reference](./docs/reference/DOCBLOCK-TAGS.md) | Public reference for every docblock tag Photon understands |
577
580
  | [Output Formats](./docs/formats.md) | Visual gallery of every `@format` type |
578
581
  | [Intent Metadata](./docs/reference/INTENT-METADATA.md) | How comments, schemas, annotations, and formats map to native surfaces |
579
582
  | [Settings](./docs/GUIDE.md#settings-user-configurable-knobs) | Declare runtime knobs with `protected settings` (the canonical config pattern) |
@@ -585,6 +588,7 @@ Uses Bun's compiler under the hood. The binary bundles the photon, its `@depende
585
588
  |---|---|
586
589
  | [Custom UI](./docs/guides/CUSTOM-UI.md) | Build rich interactive interfaces with the photon bridge API |
587
590
  | [OAuth](./docs/guides/AUTH.md) | Built-in OAuth 2.0 with Google, GitHub, Microsoft |
591
+ | [MCP JWT Auth](./docs/guides/MCP-JWT-AUTH.md) | Secure deployed MCP tool calls with short-lived scoped JWTs |
588
592
  | [MCP Client Registration](./docs/guides/mcp-client-registration.md) | Register MCP clients with Photon's AS via CIMD or DCR |
589
593
  | [Observability](./docs/guides/observability.md) | OpenTelemetry traces, metrics, logs, and structured errors |
590
594
  | [Protocol Features](./docs/guides/PROTOCOL-FEATURES.md) | Capability handshake, structured errors, trace correlation |
@@ -603,7 +607,7 @@ Uses Bun's compiler under the hood. The binary bundles the photon, its `@depende
603
607
  | [Marketplace Publishing](./docs/guides/MARKETPLACE-PUBLISHING.md) | Create and share team marketplaces |
604
608
  | [Best Practices](./docs/guides/BEST-PRACTICES.md) | Patterns for production photons |
605
609
 
606
- **Reference:** [Complete Developer Guide](./docs/GUIDE.md) · [Tag Reference](./docs/reference/DOCBLOCK-TAGS.md) · [Naming Conventions](./docs/guides/NAMING-CONVENTIONS.md) · [Architecture](./docs/internals/ARCHITECTURE.md) · [OAuth Authorization Server](./docs/internals/OAUTH-AUTHORIZATION-SERVER.md) · [Lifecycle & Ingress](./docs/internals/LIFECYCLE-AND-INGRESS.md) · [PHOTON_DIR & Namespace](./docs/internals/PHOTON-DIR-AND-NAMESPACE.md) · [Changelog](./CHANGELOG.md) · [Contributing](./CONTRIBUTING.md)
610
+ **Reference:** [Complete Developer Guide](./docs/GUIDE.md) · [Tag Reference](./docs/reference/DOCBLOCK-TAGS.md) · [Naming Conventions](./docs/guides/NAMING-CONVENTIONS.md) · [Architecture](./docs/internals/ARCHITECTURE.md) · [Lifecycle & Ingress](./docs/internals/LIFECYCLE-AND-INGRESS.md) · [PHOTON_DIR & Namespace](./docs/internals/PHOTON-DIR-AND-NAMESPACE.md) · [Changelog](./CHANGELOG.md) · [Contributing](./CONTRIBUTING.md)
607
611
 
608
612
  ---
609
613
 
@@ -0,0 +1,59 @@
1
+ import { type JsonWebKey } from 'node:crypto';
2
+ export interface PhotonAuthIssuer {
3
+ issuer: string;
4
+ algorithm: 'ES256';
5
+ kid: string;
6
+ defaultTtlSeconds: number;
7
+ }
8
+ export interface PhotonAuthTokenOptions {
9
+ agent: string;
10
+ audience: string;
11
+ tenant?: string;
12
+ scopes?: string[];
13
+ ttlSeconds?: number;
14
+ now?: Date;
15
+ jti?: string;
16
+ }
17
+ export interface PhotonAuthVerifyOptions {
18
+ issuer: string;
19
+ audience: string;
20
+ jwks: {
21
+ keys: JsonWebKey[];
22
+ };
23
+ now?: Date;
24
+ clockSkewSeconds?: number;
25
+ requiredScopes?: string[];
26
+ }
27
+ export type PhotonJwtVerifyReason = 'missing_token' | 'malformed_token' | 'unsupported_alg' | 'unknown_kid' | 'bad_signature' | 'expired_token' | 'token_not_yet_valid' | 'wrong_issuer' | 'wrong_audience' | 'insufficient_scope' | 'tenant_mismatch';
28
+ export interface PhotonJwtClaims {
29
+ iss: string;
30
+ sub: string;
31
+ aud: string | string[];
32
+ tenant_id: string;
33
+ client_id: string;
34
+ scope?: string;
35
+ iat: number;
36
+ nbf: number;
37
+ exp: number;
38
+ jti: string;
39
+ [key: string]: unknown;
40
+ }
41
+ export type PhotonJwtVerifyResult = {
42
+ ok: true;
43
+ claims: PhotonJwtClaims;
44
+ } | {
45
+ ok: false;
46
+ reason: PhotonJwtVerifyReason;
47
+ };
48
+ export declare function createPhotonAuthKeypair(name: string, now?: Date): {
49
+ issuer: PhotonAuthIssuer;
50
+ privateJwk: JsonWebKey;
51
+ publicJwk: JsonWebKey;
52
+ jwks: {
53
+ keys: JsonWebKey[];
54
+ };
55
+ };
56
+ export declare function signPhotonAuthToken(issuer: PhotonAuthIssuer, privateJwk: JsonWebKey, options: PhotonAuthTokenOptions): string;
57
+ export declare function verifyPhotonAuthToken(token: string | null | undefined, options: PhotonAuthVerifyOptions): PhotonJwtVerifyResult;
58
+ export declare function normalizeScopes(scopes: string[]): string[];
59
+ //# sourceMappingURL=mcp-jwt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-jwt.d.ts","sourceRoot":"","sources":["../../src/auth/mcp-jwt.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE;QAAE,IAAI,EAAE,UAAU,EAAE,CAAA;KAAE,CAAC;IAC7B,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,MAAM,qBAAqB,GAC7B,eAAe,GACf,iBAAiB,GACjB,iBAAiB,GACjB,aAAa,GACb,eAAe,GACf,eAAe,GACf,qBAAqB,GACrB,cAAc,GACd,gBAAgB,GAChB,oBAAoB,GACpB,iBAAiB,CAAC;AAEtB,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,qBAAqB,GAC7B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GACrC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,qBAAqB,CAAA;CAAE,CAAC;AAEjD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,GAAG,OAAa,GACf;IACD,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,UAAU,CAAC;IACtB,IAAI,EAAE;QAAE,IAAI,EAAE,UAAU,EAAE,CAAA;KAAE,CAAC;CAC9B,CAsBA;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,gBAAgB,EACxB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,sBAAsB,GAC9B,MAAM,CAiBR;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,OAAO,EAAE,uBAAuB,GAC/B,qBAAqB,CA4CvB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAY1D"}
@@ -0,0 +1,177 @@
1
+ import { createPrivateKey, createPublicKey, createSign, createVerify, generateKeyPairSync, randomBytes, } from 'node:crypto';
2
+ export function createPhotonAuthKeypair(name, now = new Date()) {
3
+ const date = now.toISOString().slice(0, 10);
4
+ const kid = `${name}-${date}`;
5
+ const { privateKey, publicKey } = generateKeyPairSync('ec', { namedCurve: 'P-256' });
6
+ const privateJwk = privateKey.export({ format: 'jwk' });
7
+ const publicJwk = publicKey.export({ format: 'jwk' });
8
+ for (const jwk of [privateJwk, publicJwk]) {
9
+ jwk.alg = 'ES256';
10
+ jwk.kid = kid;
11
+ jwk.use = 'sig';
12
+ }
13
+ return {
14
+ issuer: {
15
+ issuer: `photon-local:${name}`,
16
+ algorithm: 'ES256',
17
+ kid,
18
+ defaultTtlSeconds: 15 * 60,
19
+ },
20
+ privateJwk,
21
+ publicJwk,
22
+ jwks: { keys: [publicJwk] },
23
+ };
24
+ }
25
+ export function signPhotonAuthToken(issuer, privateJwk, options) {
26
+ const nowSec = Math.floor((options.now?.getTime() ?? Date.now()) / 1000);
27
+ const ttl = options.ttlSeconds ?? issuer.defaultTtlSeconds;
28
+ const scopes = normalizeScopes(options.scopes ?? []);
29
+ const payload = {
30
+ iss: issuer.issuer,
31
+ sub: `agent:${options.agent}`,
32
+ aud: options.audience,
33
+ tenant_id: options.tenant ?? 'default',
34
+ client_id: options.agent,
35
+ ...(scopes.length > 0 ? { scope: scopes.join(' ') } : {}),
36
+ iat: nowSec,
37
+ nbf: nowSec,
38
+ exp: nowSec + ttl,
39
+ jti: options.jti ?? `tok_${randomBytes(16).toString('base64url')}`,
40
+ };
41
+ return signJwt(payload, privateJwk, issuer.kid);
42
+ }
43
+ export function verifyPhotonAuthToken(token, options) {
44
+ if (!token)
45
+ return { ok: false, reason: 'missing_token' };
46
+ const parts = token.split('.');
47
+ if (parts.length !== 3)
48
+ return { ok: false, reason: 'malformed_token' };
49
+ let header;
50
+ let claims;
51
+ try {
52
+ header = JSON.parse(base64UrlDecode(parts[0]));
53
+ claims = JSON.parse(base64UrlDecode(parts[1]));
54
+ }
55
+ catch {
56
+ return { ok: false, reason: 'malformed_token' };
57
+ }
58
+ if (header.alg !== 'ES256')
59
+ return { ok: false, reason: 'unsupported_alg' };
60
+ const kid = typeof header.kid === 'string' ? header.kid : '';
61
+ const jwk = options.jwks.keys.find((key) => key.kid === kid);
62
+ if (!kid || !jwk)
63
+ return { ok: false, reason: 'unknown_kid' };
64
+ if (!verifyJwtSignature(parts, jwk))
65
+ return { ok: false, reason: 'bad_signature' };
66
+ if (claims.iss !== options.issuer)
67
+ return { ok: false, reason: 'wrong_issuer' };
68
+ const audMatches = Array.isArray(claims.aud)
69
+ ? claims.aud.includes(options.audience)
70
+ : claims.aud === options.audience;
71
+ if (!audMatches)
72
+ return { ok: false, reason: 'wrong_audience' };
73
+ const now = Math.floor((options.now?.getTime() ?? Date.now()) / 1000);
74
+ const skew = options.clockSkewSeconds ?? 60;
75
+ if (typeof claims.exp !== 'number' || claims.exp < now - skew) {
76
+ return { ok: false, reason: 'expired_token' };
77
+ }
78
+ if (typeof claims.nbf === 'number' && claims.nbf > now + skew) {
79
+ return { ok: false, reason: 'token_not_yet_valid' };
80
+ }
81
+ if (typeof claims.iat === 'number' && claims.iat > now + skew) {
82
+ return { ok: false, reason: 'token_not_yet_valid' };
83
+ }
84
+ const required = normalizeScopes(options.requiredScopes ?? []);
85
+ if (required.length > 0) {
86
+ const granted = new Set(normalizeScopes((claims.scope ?? '').split(/\s+/)));
87
+ for (const scope of required) {
88
+ if (!granted.has(scope))
89
+ return { ok: false, reason: 'insufficient_scope' };
90
+ }
91
+ }
92
+ return { ok: true, claims };
93
+ }
94
+ export function normalizeScopes(scopes) {
95
+ const out = [];
96
+ const seen = new Set();
97
+ for (const raw of scopes) {
98
+ for (const scope of raw.split(/\s+/)) {
99
+ const trimmed = scope.trim();
100
+ if (!trimmed || seen.has(trimmed))
101
+ continue;
102
+ seen.add(trimmed);
103
+ out.push(trimmed);
104
+ }
105
+ }
106
+ return out;
107
+ }
108
+ function signJwt(payload, privateJwk, kid) {
109
+ const header = { alg: 'ES256', typ: 'JWT', kid };
110
+ const input = `${base64UrlEncode(JSON.stringify(header))}.${base64UrlEncode(JSON.stringify(payload))}`;
111
+ const key = createPrivateKey({ key: privateJwk, format: 'jwk' });
112
+ const signer = createSign('sha256');
113
+ signer.update(input);
114
+ signer.end();
115
+ const der = signer.sign(key);
116
+ return `${input}.${derToP1363(der, 32).toString('base64url')}`;
117
+ }
118
+ function verifyJwtSignature(parts, publicJwk) {
119
+ try {
120
+ const key = createPublicKey({ key: publicJwk, format: 'jwk' });
121
+ const verifier = createVerify('sha256');
122
+ verifier.update(`${parts[0]}.${parts[1]}`);
123
+ verifier.end();
124
+ return verifier.verify(key, p1363ToDer(Buffer.from(parts[2], 'base64url')));
125
+ }
126
+ catch {
127
+ return false;
128
+ }
129
+ }
130
+ function base64UrlEncode(str) {
131
+ return Buffer.from(str, 'utf-8').toString('base64url');
132
+ }
133
+ function base64UrlDecode(str) {
134
+ return Buffer.from(str, 'base64url').toString('utf-8');
135
+ }
136
+ function derToP1363(der, componentLen) {
137
+ if (der[0] !== 0x30)
138
+ throw new Error('invalid DER signature');
139
+ let offset = 2;
140
+ if ((der[1] & 0x80) !== 0)
141
+ offset += der[1] & 0x7f;
142
+ const readInt = () => {
143
+ if (der[offset] !== 0x02)
144
+ throw new Error('invalid DER signature');
145
+ const len = der[offset + 1];
146
+ const start = offset + 2;
147
+ let value = der.subarray(start, start + len);
148
+ offset = start + len;
149
+ while (value.length > 1 && value[0] === 0x00)
150
+ value = value.subarray(1);
151
+ if (value.length > componentLen)
152
+ throw new Error('ECDSA component overflow');
153
+ return value;
154
+ };
155
+ const r = readInt();
156
+ const s = readInt();
157
+ const out = Buffer.alloc(componentLen * 2);
158
+ r.copy(out, componentLen - r.length);
159
+ s.copy(out, componentLen * 2 - s.length);
160
+ return out;
161
+ }
162
+ function p1363ToDer(p1363) {
163
+ if (p1363.length % 2 !== 0)
164
+ throw new Error('invalid P1363 signature');
165
+ const half = p1363.length / 2;
166
+ const encodeInt = (value) => {
167
+ let v = value;
168
+ while (v.length > 1 && v[0] === 0x00)
169
+ v = v.subarray(1);
170
+ if ((v[0] & 0x80) !== 0)
171
+ v = Buffer.concat([Buffer.from([0x00]), v]);
172
+ return Buffer.concat([Buffer.from([0x02, v.length]), v]);
173
+ };
174
+ const body = Buffer.concat([encodeInt(p1363.subarray(0, half)), encodeInt(p1363.subarray(half))]);
175
+ return Buffer.concat([Buffer.from([0x30, body.length]), body]);
176
+ }
177
+ //# sourceMappingURL=mcp-jwt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-jwt.js","sourceRoot":"","sources":["../../src/auth/mcp-jwt.ts"],"names":[],"mappings":"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"}
@@ -42,6 +42,7 @@ export interface BeamActions {
42
42
  loadUIAsset: (photonName: string, uiId: string) => Promise<{
43
43
  content: string;
44
44
  isPhotonTemplate: boolean;
45
+ compiled?: import('../../tsx-compiler.js').CompiledTsx;
45
46
  } | null>;
46
47
  subscribeToChannel: (channel: string) => Promise<void>;
47
48
  unsubscribeFromChannel: (channel: string) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/auto-ui/beam/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/auto-ui/beam/types.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,7 @@ export declare function shouldServeLinkedAppForWebPath(pathname: string, searchP
16
16
  export declare function selectClientAppUi(photonInfo: PhotonInfo | undefined): string | undefined;
17
17
  export declare function shouldFallbackToClientAppForWebPath(pathname: string, searchParams: URLSearchParams, route: BeamWebRouteDef | undefined): boolean;
18
18
  export declare function findBeamWebRoute(routes: BeamWebRouteDef[] | undefined, method: string, requestPath: string): BeamWebRouteDef | undefined;
19
+ export declare function rewriteBeamWebRedirectLocation(location: string | null, prefix: string, requestOrigin: string): string | null;
19
20
  import type { PhotonInfo } from './types.js';
20
21
  export type { PhotonConfig } from './beam/types.js';
21
22
  export type { BeamState } from './beam/types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"beam.d.ts","sourceRoot":"","sources":["../../src/auto-ui/beam.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAQD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAenF;AAYD,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,eAAe,GAC5B,OAAO,CAIT;AAUD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAmBxF;AAED,wBAAgB,mCAAmC,CACjD,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,eAAe,EAC7B,KAAK,EAAE,eAAe,GAAG,SAAS,GACjC,OAAO,CAIT;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,eAAe,EAAE,GAAG,SAAS,EACrC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,eAAe,GAAG,SAAS,CAO7B;AA2GD,OAAO,KAAK,EACV,UAAU,EAKX,MAAM,YAAY,CAAC;AAsCpB,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAqYjD,wBAAsB,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAy2FlF;AAED;;;GAGG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAM9C"}
1
+ {"version":3,"file":"beam.d.ts","sourceRoot":"","sources":["../../src/auto-ui/beam.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAQD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAenF;AAYD,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,eAAe,GAC5B,OAAO,CAIT;AAUD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAmBxF;AAED,wBAAgB,mCAAmC,CACjD,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,eAAe,EAC7B,KAAK,EAAE,eAAe,GAAG,SAAS,GACjC,OAAO,CAIT;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,eAAe,EAAE,GAAG,SAAS,EACrC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,eAAe,GAAG,SAAS,CAO7B;AAwCD,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,GACpB,MAAM,GAAG,IAAI,CAaf;AAsED,OAAO,KAAK,EACV,UAAU,EAKX,MAAM,YAAY,CAAC;AAsCpB,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAqYjD,wBAAsB,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAi7FlF;AAED;;;GAGG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAM9C"}
@@ -165,6 +165,22 @@ async function writeFetchResponseToNode(response, res) {
165
165
  res.off('close', cancelReader);
166
166
  }
167
167
  }
168
+ export function rewriteBeamWebRedirectLocation(location, prefix, requestOrigin) {
169
+ if (!location)
170
+ return null;
171
+ try {
172
+ const target = new URL(location, requestOrigin);
173
+ if (target.origin !== requestOrigin)
174
+ return location;
175
+ if (target.pathname === prefix || target.pathname.startsWith(`${prefix}/`)) {
176
+ return target.pathname + target.search + target.hash;
177
+ }
178
+ return `${prefix}${target.pathname}${target.search}${target.hash}`;
179
+ }
180
+ catch {
181
+ return location;
182
+ }
183
+ }
168
184
  /**
169
185
  * Resolve raw icon image paths to MCP Icon[] format (data URIs)
170
186
  */
@@ -215,7 +231,7 @@ import { ensurePhotonEditorDeclaration, writePhotonEditorDeclaration, } from '..
215
231
  import { ensureDaemon } from '../daemon/manager.js';
216
232
  import { SchemaExtractor } from '@portel/photon-core';
217
233
  import { generateServerCard } from '../server-card.js';
218
- import { resolveUIAssetPath, readUIContent } from './ui-resolver.js';
234
+ import { resolveUIAssetPath, readUIContent, readUICompiled } from './ui-resolver.js';
219
235
  import { handleStreamableHTTP, broadcastNotification, broadcastToBeam, stopSessionCleanup, attachLoaderForResourceUpdates, } from './streamable-http-transport.js';
220
236
  import { getBundledPhotonPath, BEAM_BUNDLED_PHOTONS } from '../shared-utils.js';
221
237
  // BUNDLED_PHOTONS and getBundledPhotonPath are imported from shared-utils.js
@@ -1080,8 +1096,8 @@ export async function startBeam(rawWorkingDir, port) {
1080
1096
  }
1081
1097
  const isPhotonTemplate = resolved.isPhotonTemplate || resolved.isPhotonMarkdown;
1082
1098
  try {
1083
- const content = await readUIContent(resolved.path);
1084
- return { content, isPhotonTemplate };
1099
+ const { content, compiled } = await readUICompiled(resolved.path);
1100
+ return { content, isPhotonTemplate, compiled };
1085
1101
  }
1086
1102
  catch {
1087
1103
  // Fall through to check custom format renderers
@@ -2026,6 +2042,28 @@ export async function startBeam(rawWorkingDir, port) {
2026
2042
  const httpRoutes = photonClass?._httpRoutes;
2027
2043
  const route = findBeamWebRoute(httpRoutes, req.method || 'GET', photonPath);
2028
2044
  const linkedAppUi = photonInfo?.configured ? selectClientAppUi(photonInfo) : undefined;
2045
+ // Compiled .tsx bundle for the linked app UI. The shell references
2046
+ // `./<base>.<hash>.js`, which arrives here as a /web sub-path. Serve
2047
+ // it from the compile cache with an immutable policy — the hash in
2048
+ // the filename is the cache key, so a source change yields a new URL
2049
+ // and the browser never runs a stale bundle.
2050
+ if (req.method === 'GET' && photonName && photonInfo?.configured && linkedAppUi) {
2051
+ const lastSeg = decodeURIComponent(pathParts[pathParts.length - 1] ?? '');
2052
+ if (/^[\w-]+\.[0-9a-f]{12}\.js$/.test(lastSeg)) {
2053
+ const appAsset = await loadUIAsset(photonName, linkedAppUi);
2054
+ if (appAsset?.compiled && lastSeg === appAsset.compiled.jsFileName) {
2055
+ const js = appAsset.compiled.js;
2056
+ res.writeHead(200, {
2057
+ 'Content-Type': 'text/javascript; charset=utf-8',
2058
+ 'Cache-Control': 'public, max-age=31536000, immutable',
2059
+ 'Cross-Origin-Resource-Policy': 'same-origin',
2060
+ 'Content-Length': Buffer.byteLength(js).toString(),
2061
+ });
2062
+ res.end(js);
2063
+ return;
2064
+ }
2065
+ }
2066
+ }
2029
2067
  if (req.method === 'GET' &&
2030
2068
  photonName &&
2031
2069
  photonInfo?.configured &&
@@ -2034,6 +2072,13 @@ export async function startBeam(rawWorkingDir, port) {
2034
2072
  const appAsset = await loadUIAsset(photonName, linkedAppUi);
2035
2073
  if (appAsset) {
2036
2074
  let body = appAsset.content;
2075
+ const shellEtag = appAsset.compiled?.hash ? `"${appAsset.compiled.hash}"` : undefined;
2076
+ const inm = req.headers['if-none-match'];
2077
+ if (shellEtag && inm && inm === shellEtag) {
2078
+ res.writeHead(304, { ETag: shellEtag });
2079
+ res.end();
2080
+ return;
2081
+ }
2037
2082
  const prefix = `/web/${photonName}`;
2038
2083
  const interceptor = `<script>
2039
2084
  (function(){
@@ -2054,11 +2099,25 @@ export async function startBeam(rawWorkingDir, port) {
2054
2099
  body = body.includes('<head>')
2055
2100
  ? body.replace('<head>', '<head>' + interceptor)
2056
2101
  : interceptor + body;
2057
- res.writeHead(200, {
2102
+ // The compiled shell references the bundle relatively
2103
+ // (`./<base>.<hash>.js`). Under the /web/<photon> mount the
2104
+ // document URL has no trailing slash, so a relative resolve
2105
+ // would miss; pin it to the absolute prefixed path that the
2106
+ // hashed-JS handler above serves.
2107
+ if (appAsset.compiled?.jsFileName) {
2108
+ const jf = appAsset.compiled.jsFileName;
2109
+ body = body.replace(`src="./${jf}"`, `src="${prefix}/${jf}"`);
2110
+ }
2111
+ const shellHeaders = {
2058
2112
  'Content-Type': 'text/html; charset=utf-8',
2059
- 'Cache-Control': 'no-cache, no-store, must-revalidate',
2113
+ // Revalidate every load; ETag makes that a cheap 304 when the
2114
+ // compiled bundle (and thus the referenced hash) is unchanged.
2115
+ 'Cache-Control': 'no-cache',
2060
2116
  'Content-Length': Buffer.byteLength(body).toString(),
2061
- });
2117
+ };
2118
+ if (shellEtag)
2119
+ shellHeaders['ETag'] = shellEtag;
2120
+ res.writeHead(200, shellHeaders);
2062
2121
  res.end(body);
2063
2122
  return;
2064
2123
  }
@@ -2082,6 +2141,25 @@ export async function startBeam(rawWorkingDir, port) {
2082
2141
  });
2083
2142
  const result = await fn.call(photonClass.instance, webReq);
2084
2143
  if (result instanceof Response) {
2144
+ const prefix = `/web/${photonName}`;
2145
+ if (result.status >= 300 && result.status < 400) {
2146
+ const responseHeaders = {};
2147
+ result.headers.forEach((value, key) => {
2148
+ if (key.toLowerCase() !== 'location')
2149
+ responseHeaders[key] = value;
2150
+ });
2151
+ const location = rewriteBeamWebRedirectLocation(result.headers.get('location'), prefix, internalUrl.origin);
2152
+ if (location) {
2153
+ responseHeaders.location = location;
2154
+ }
2155
+ const body = Buffer.from(await result.arrayBuffer());
2156
+ if (body.length > 0) {
2157
+ responseHeaders['content-length'] = String(body.length);
2158
+ }
2159
+ res.writeHead(result.status, responseHeaders);
2160
+ res.end(body.length > 0 ? body : undefined);
2161
+ return;
2162
+ }
2085
2163
  const contentType = result.headers.get('content-type') || '';
2086
2164
  if (!contentType.includes('text/html')) {
2087
2165
  await writeFetchResponseToNode(result, res);
@@ -2094,7 +2172,6 @@ export async function startBeam(rawWorkingDir, port) {
2094
2172
  responseHeaders[key] = value;
2095
2173
  });
2096
2174
  let body = Buffer.from(await result.arrayBuffer());
2097
- const prefix = `/web/${photonName}`;
2098
2175
  const interceptor = `<script>
2099
2176
  (function(){
2100
2177
  const _prefix="${prefix}";
@@ -2734,11 +2811,17 @@ export async function startBeam(rawWorkingDir, port) {
2734
2811
  };
2735
2812
  // Watch working directory recursively
2736
2813
  try {
2814
+ // Directories that never hold photon source but generate huge event
2815
+ // volume (dependency installs, git ops, build output). The recursive
2816
+ // watch still descends them, but short-circuiting here stops every
2817
+ // write from fanning out into getPhotonForPath/handleFileChange — the
2818
+ // amplification that turns several Beam instances into FD/CPU pressure.
2819
+ const IGNORED_TOP_DIRS = new Set(['.data', 'node_modules', '.git', 'dist', '.photon-ui']);
2737
2820
  const watcher = watch(workingDir, { recursive: true }, (eventType, filename) => {
2738
2821
  if (!filename)
2739
2822
  return;
2740
- // Skip all runtime data — .data/ contains all photon data, never source code
2741
- if (filename.startsWith('.data' + path.sep) || filename === '.data')
2823
+ const firstSeg = filename.split(path.sep)[0];
2824
+ if (IGNORED_TOP_DIRS.has(firstSeg))
2742
2825
  return;
2743
2826
  const fullPath = path.join(workingDir, filename);
2744
2827
  logger.debug(`📂 File event: ${eventType} ${filename}`);