@nimbus-sh/worker 0.4.0 → 0.6.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 (95) hide show
  1. package/README.md +46 -43
  2. package/dist/_shared/preview-host.d.ts +33 -2
  3. package/dist/_shared/preview-host.d.ts.map +1 -1
  4. package/dist/_shared/preview-host.js +73 -8
  5. package/dist/_shared/session-router.d.ts +43 -0
  6. package/dist/_shared/session-router.d.ts.map +1 -1
  7. package/dist/_shared/session-router.js +59 -12
  8. package/dist/facets/durable-images.d.ts +59 -0
  9. package/dist/facets/durable-images.d.ts.map +1 -0
  10. package/dist/facets/durable-images.js +94 -0
  11. package/dist/facets/durable-slots.d.ts +45 -0
  12. package/dist/facets/durable-slots.d.ts.map +1 -0
  13. package/dist/facets/durable-slots.js +95 -0
  14. package/dist/facets/esbuild-transform.d.ts +10 -0
  15. package/dist/facets/esbuild-transform.d.ts.map +1 -0
  16. package/dist/facets/esbuild-transform.js +36 -0
  17. package/dist/facets/manager.d.ts +244 -6
  18. package/dist/facets/manager.d.ts.map +1 -1
  19. package/dist/facets/manager.js +901 -117
  20. package/dist/facets/resident-identity.d.ts +23 -0
  21. package/dist/facets/resident-identity.d.ts.map +1 -0
  22. package/dist/facets/resident-identity.js +31 -0
  23. package/dist/git/commands.d.ts +22 -1
  24. package/dist/git/commands.d.ts.map +1 -1
  25. package/dist/git/commands.js +429 -425
  26. package/dist/git-bundle.generated.d.ts +2 -2
  27. package/dist/git-bundle.generated.d.ts.map +1 -1
  28. package/dist/git-bundle.generated.js +3 -3
  29. package/dist/index.d.ts +2 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +2 -1
  32. package/dist/node-shims-artifact.generated.js +3 -3
  33. package/dist/router/index.d.ts.map +1 -1
  34. package/dist/router/index.js +97 -3
  35. package/dist/router/public-directory-do.d.ts +17 -0
  36. package/dist/router/public-directory-do.d.ts.map +1 -0
  37. package/dist/router/public-directory-do.js +16 -0
  38. package/dist/router/public-directory.d.ts +79 -0
  39. package/dist/router/public-directory.d.ts.map +1 -0
  40. package/dist/router/public-directory.js +122 -0
  41. package/dist/router/remote-api.d.ts +27 -1
  42. package/dist/router/remote-api.d.ts.map +1 -1
  43. package/dist/router/remote-api.js +48 -2
  44. package/dist/runtime/cpython-resident.d.ts.map +1 -1
  45. package/dist/runtime/cpython-resident.js +3 -1
  46. package/dist/runtime/node-shims.d.ts +4 -1
  47. package/dist/runtime/node-shims.d.ts.map +1 -1
  48. package/dist/runtime/node-shims.js +324 -6
  49. package/dist/runtime/package-manager.d.ts +44 -1
  50. package/dist/runtime/package-manager.d.ts.map +1 -1
  51. package/dist/runtime/package-manager.js +168 -3
  52. package/dist/runtime/ruby-resident.d.ts.map +1 -1
  53. package/dist/runtime/ruby-resident.js +2 -0
  54. package/dist/session/agent.d.ts +11 -0
  55. package/dist/session/agent.d.ts.map +1 -1
  56. package/dist/session/agent.js +28 -1
  57. package/dist/session/helpers.js +1 -1
  58. package/dist/session/init-phases.d.ts +17 -23
  59. package/dist/session/init-phases.d.ts.map +1 -1
  60. package/dist/session/init-phases.js +17 -41
  61. package/dist/session/init.d.ts.map +1 -1
  62. package/dist/session/init.js +28 -15
  63. package/dist/session/keys.d.ts +12 -0
  64. package/dist/session/keys.d.ts.map +1 -1
  65. package/dist/session/keys.js +12 -0
  66. package/dist/session/nimbus-session.d.ts +63 -5
  67. package/dist/session/nimbus-session.d.ts.map +1 -1
  68. package/dist/session/nimbus-session.js +131 -17
  69. package/dist/session/port-capability.d.ts +141 -8
  70. package/dist/session/port-capability.d.ts.map +1 -1
  71. package/dist/session/port-capability.js +265 -8
  72. package/dist/session/programmatic.d.ts +145 -3
  73. package/dist/session/programmatic.d.ts.map +1 -1
  74. package/dist/session/programmatic.js +434 -12
  75. package/dist/session/routes.d.ts +26 -0
  76. package/dist/session/routes.d.ts.map +1 -1
  77. package/dist/session/routes.js +117 -25
  78. package/dist/session/rpc.d.ts +24 -1
  79. package/dist/session/rpc.d.ts.map +1 -1
  80. package/dist/session/rpc.js +65 -98
  81. package/dist/session/shell-socket.d.ts +76 -0
  82. package/dist/session/shell-socket.d.ts.map +1 -0
  83. package/dist/session/shell-socket.js +172 -0
  84. package/dist/session/start-real-vite.js +1 -1
  85. package/dist/session/supervisor-op.d.ts +42 -0
  86. package/dist/session/supervisor-op.d.ts.map +1 -0
  87. package/dist/session/supervisor-op.js +96 -0
  88. package/dist/session/supervisor-rpc.d.ts +6 -10
  89. package/dist/session/supervisor-rpc.d.ts.map +1 -1
  90. package/dist/session/supervisor-rpc.js +91 -71
  91. package/dist/session/ws.d.ts.map +1 -1
  92. package/dist/session/ws.js +19 -4
  93. package/package.json +4 -4
  94. package/public/_assets/runtime/{node-shims-fea906843f6d594e.js → node-shims-9e1380d9ee430fcc.js} +320 -5
  95. package/public/s/index.html +101 -5
package/dist/index.d.ts CHANGED
@@ -22,6 +22,7 @@
22
22
  * runtime and generated assets in one place.
23
23
  */
24
24
  import { NimbusSession, NimbusAssetsRPC, NimbusLoaderRPC, NimbusLoadedWorker, NimbusLoadedEntrypoint, NimbusDurableObjectNamespace, NimbusDOStub } from './session/nimbus-session.js';
25
+ import { NimbusPublicDirectory } from './router/public-directory-do.js';
25
26
  import { SupervisorRPC } from './session/supervisor-rpc.js';
26
27
  import { CirrusHmrRPC } from './facets/real-vite-hmr.js';
27
28
  export { createNimbusHandler } from './router/index.js';
@@ -36,7 +37,7 @@ export { base64Utf8, base64Url, base64UrlDecode, decodeJsonBase64Url, encodeJson
36
37
  export { clearNimbusAgentOAuthCookie, createNimbusAgentOAuthCookie, fetchNimbusCloudflareAccounts, fetchNimbusCloudflareUserInfo, isNimbusCloudflareAccountId, isNimbusTenantSegment, loadNimbusAgentOAuthFromRequest, nimbusAgentAuthCookiePath, nimbusAgentRouteContext, NIMBUS_AGENT_AUTH_COOKIE, NIMBUS_AGENT_AUTH_COOKIE_PURPOSE, NIMBUS_AGENT_AUTH_COOKIE_TTL_SECONDS, NIMBUS_CF_OAUTH_AUTH_URL, NIMBUS_CF_OAUTH_TOKEN_URL, NIMBUS_CF_OAUTH_USERINFO_URL, NIMBUS_CLOUDFLARE_API, readNimbusAgentCookieSecret, readNimbusCookie, requestNimbusCloudflareOAuthToken, serializeNimbusCookie, } from './session/agent-oauth.js';
37
38
  export type { NimbusAgentOAuthCookie, NimbusCloudflareAccount, } from './session/agent-oauth.js';
38
39
  export type { NimbusAuthEnv, NimbusTokenClaims, VerifiedNimbusToken, } from './auth/index.js';
39
- export { NimbusSession, SupervisorRPC, NimbusAssetsRPC, NimbusLoaderRPC, NimbusLoadedWorker, NimbusLoadedEntrypoint, NimbusDurableObjectNamespace, NimbusDOStub, CirrusHmrRPC, };
40
+ export { NimbusSession, NimbusPublicDirectory, SupervisorRPC, NimbusAssetsRPC, NimbusLoaderRPC, NimbusLoadedWorker, NimbusLoadedEntrypoint, NimbusDurableObjectNamespace, NimbusDOStub, CirrusHmrRPC, };
40
41
  /**
41
42
  * Module-level reference to ctx.exports from the fetch handler.
42
43
  * Used by NimbusSession to create loopback bindings for facets.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EACL,aAAa,EACb,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,4BAA4B,EAC5B,YAAY,EACb,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAWzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EACV,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,0BAA0B,EAC1B,QAAQ,EACR,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,GAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAIjE,OAAO,EAAE,eAAe,EAAE,MAAM,+CAA+C,CAAC;AAChF,YAAY,EAAE,sBAAsB,EAAE,MAAM,+CAA+C,CAAC;AAC5F,YAAY,EACV,WAAW,EACX,eAAe,EACf,MAAM,EACN,QAAQ,EACR,eAAe,GAChB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EACL,UAAU,EACV,SAAS,EACT,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,QAAQ,EACR,eAAe,EACf,UAAU,GACX,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,2BAA2B,EAC3B,4BAA4B,EAC5B,6BAA6B,EAC7B,6BAA6B,EAC7B,2BAA2B,EAC3B,qBAAqB,EACrB,+BAA+B,EAC/B,yBAAyB,EACzB,uBAAuB,EACvB,wBAAwB,EACxB,gCAAgC,EAChC,oCAAoC,EACpC,wBAAwB,EACxB,yBAAyB,EACzB,4BAA4B,EAC5B,qBAAqB,EACrB,2BAA2B,EAC3B,gBAAgB,EAChB,iCAAiC,EACjC,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AA4BzB,OAAO,EACL,aAAa,EACb,aAAa,EACb,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,4BAA4B,EAC5B,YAAY,EACZ,YAAY,GACb,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAEnC;;AAOD,wBAAqC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EACL,aAAa,EACb,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,4BAA4B,EAC5B,YAAY,EACb,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAWzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EACV,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,0BAA0B,EAC1B,QAAQ,EACR,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,GAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAIjE,OAAO,EAAE,eAAe,EAAE,MAAM,+CAA+C,CAAC;AAChF,YAAY,EAAE,sBAAsB,EAAE,MAAM,+CAA+C,CAAC;AAC5F,YAAY,EACV,WAAW,EACX,eAAe,EACf,MAAM,EACN,QAAQ,EACR,eAAe,GAChB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EACL,UAAU,EACV,SAAS,EACT,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,QAAQ,EACR,eAAe,EACf,UAAU,GACX,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,2BAA2B,EAC3B,4BAA4B,EAC5B,6BAA6B,EAC7B,6BAA6B,EAC7B,2BAA2B,EAC3B,qBAAqB,EACrB,+BAA+B,EAC/B,yBAAyB,EACzB,uBAAuB,EACvB,wBAAwB,EACxB,gCAAgC,EAChC,oCAAoC,EACpC,wBAAwB,EACxB,yBAAyB,EACzB,4BAA4B,EAC5B,qBAAqB,EACrB,2BAA2B,EAC3B,gBAAgB,EAChB,iCAAiC,EACjC,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AA4BzB,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,aAAa,EACb,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,4BAA4B,EAC5B,YAAY,EACZ,YAAY,GACb,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAEnC;;AAOD,wBAAqC"}
package/dist/index.js CHANGED
@@ -22,6 +22,7 @@
22
22
  * runtime and generated assets in one place.
23
23
  */
24
24
  import { NimbusSession, NimbusAssetsRPC, NimbusLoaderRPC, NimbusLoadedWorker, NimbusLoadedEntrypoint, NimbusDurableObjectNamespace, NimbusDOStub, } from './session/nimbus-session.js';
25
+ import { NimbusPublicDirectory } from './router/public-directory-do.js';
25
26
  import { SupervisorRPC } from './session/supervisor-rpc.js';
26
27
  import { CirrusHmrRPC } from './facets/real-vite-hmr.js';
27
28
  import { createNimbusHandler } from './router/index.js';
@@ -71,7 +72,7 @@ setRegistryEventSink((e) => {
71
72
  // Re-export inner-Worker binding shims so wrangler bundles them AND
72
73
  // ctx.exports auto-populates Service Bindings for them (via
73
74
  // enable_ctx_exports; default at compat date 2026-04-01+).
74
- export { NimbusSession, SupervisorRPC, NimbusAssetsRPC, NimbusLoaderRPC, NimbusLoadedWorker, NimbusLoadedEntrypoint, NimbusDurableObjectNamespace, NimbusDOStub, CirrusHmrRPC, };
75
+ export { NimbusSession, NimbusPublicDirectory, SupervisorRPC, NimbusAssetsRPC, NimbusLoaderRPC, NimbusLoadedWorker, NimbusLoadedEntrypoint, NimbusDurableObjectNamespace, NimbusDOStub, CirrusHmrRPC, };
75
76
  /**
76
77
  * Module-level reference to ctx.exports from the fetch handler.
77
78
  * Used by NimbusSession to create loopback bindings for facets.
@@ -7,6 +7,6 @@
7
7
  * prefix so cache layers never serve stale bytes after a rebuild;
8
8
  * NODE_SHIMS_SHA256 is the full digest verified at fetch time.
9
9
  */
10
- export const NODE_SHIMS_ENTRY = "/_assets/runtime/node-shims-fea906843f6d594e.js";
11
- export const NODE_SHIMS_BUILD_ID = "fea906843f6d594e";
12
- export const NODE_SHIMS_SHA256 = "fea906843f6d594ee6ba6e9fe286ecc8a803e600c4b340c9343dd6844eaac9a2";
10
+ export const NODE_SHIMS_ENTRY = "/_assets/runtime/node-shims-9e1380d9ee430fcc.js";
11
+ export const NODE_SHIMS_BUILD_ID = "9e1380d9ee430fcc";
12
+ export const NODE_SHIMS_SHA256 = "9e1380d9ee430fcca4e8700a97da811eee0fe7e9cab4c6357e94c3fc21efa2d9";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/router/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAqCH,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,iBAAiB,CAAC;AAGzB,YAAY,EACV,YAAY,IAAI,eAAe,EAC/B,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAEzB;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAC;IACtB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,OAAO,EAAE,OAAO,CAAC;IACjB,oBAAoB;IACpB,GAAG,EAAE,GAAG,CAAC;CACV;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;;OAMG;IACH,cAAc,CAAC,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9D;;;OAGG;IACH,YAAY,CAAC,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAErD,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,gBAAgB,KAClB,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;AAEhD,+CAA+C;AAC/C,MAAM,WAAW,0BAA0B;IACzC,oCAAoC;IACpC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,qDAAqD;IACrD,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,yEAAyE;IACzE,GAAG,CAAC,EAAE,qBAAqB,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC7E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,0BAA+B,GACvC,aAAa,CAoSf"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/router/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAuCH,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,iBAAiB,CAAC;AA+CzB,YAAY,EACV,YAAY,IAAI,eAAe,EAC/B,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAEzB;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAC;IACtB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,OAAO,EAAE,OAAO,CAAC;IACjB,oBAAoB;IACpB,GAAG,EAAE,GAAG,CAAC;CACV;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;;OAMG;IACH,cAAc,CAAC,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9D;;;OAGG;IACH,YAAY,CAAC,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAErD,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,gBAAgB,KAClB,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;AAEhD,+CAA+C;AAC/C,MAAM,WAAW,0BAA0B;IACzC,oCAAoC;IACpC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,qDAAqD;IACrD,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,yEAAyE;IACzE,GAAG,CAAC,EAAE,qBAAqB,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC7E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,0BAA+B,GACvC,aAAa,CAoWf"}
@@ -33,11 +33,48 @@
33
33
  */
34
34
  import { generateSessionId, isValidSessionId, } from '../_shared/session-id.js';
35
35
  import { buildPreviewHost, isPreviewHostSafeSid, parsePreviewHost, readPreviewHostSuffix, } from '../_shared/preview-host.js';
36
- import { parseSessionRoute, forwardToSession, renderInvalidSessionHtml, SESSION_ROUTE_PREFIX, LEGACY_PUBLIC_DO_SEGMENT, } from '../_shared/session-router.js';
36
+ import { parseSessionRoute, forwardToSession, renderInvalidSessionHtml, SESSION_ROUTE_PREFIX, LEGACY_PUBLIC_DO_SEGMENT, PREVIEW_CAPABILITY_HEADER, PUBLIC_BEARER_HEADER, } from '../_shared/session-router.js';
37
37
  import { issueNimbusToken, verifyNimbusToken, verifyRequestToken, requireScopes, requireSessionPin, authErrorResponse, setNimbusTokenCookie, NIMBUS_TOKEN_QUERY, NimbusAuthError, NimbusBootstrapConsumedError, NimbusTokenClaimsError, DEFAULT_TOKEN_TTL_MS, ATTACH_BOOTSTRAP_TTL_MS, } from '../auth/index.js';
38
38
  import { adoptCtxExports } from '@nimbus-sh/fabric/composition.js';
39
39
  import { handleNimbusRemoteApi, } from './remote-api.js';
40
40
  import { parseAgentOAuthStateParam } from '../session/agent.js';
41
+ import { publicDirectoryStub } from './public-directory.js';
42
+ /**
43
+ * Positive directory resolutions, per isolate. A capability that resolved
44
+ * once keeps resolving — the row is deleted only when the port goes
45
+ * private, and a stale cache entry 404s honestly at the session's own
46
+ * visibility check anyway. Misses are never cached.
47
+ */
48
+ const publicTenantCache = new Map();
49
+ /**
50
+ * The tenant segment a public capability URL forwards under. The directory
51
+ * is consulted first; a deployment without the binding falls back to the
52
+ * legacy-public DO name, which is where legacy-mode sessions already live.
53
+ * The directory row also carries the port and name the capability was
54
+ * bound with, which is what the `<cap>--<name>--<sid>` form resolves and
55
+ * verifies against.
56
+ */
57
+ async function resolvePublicCapability(capability, env, uncached = false) {
58
+ const cached = publicTenantCache.get(capability);
59
+ if (!uncached && cached !== undefined)
60
+ return cached;
61
+ const stub = publicDirectoryStub(env);
62
+ if (stub === null)
63
+ return { tenantSegment: LEGACY_PUBLIC_DO_SEGMENT, port: null, name: null };
64
+ const entry = await stub.resolve(capability).catch(() => null);
65
+ if (entry === null) {
66
+ // An unresolvable capability 404s: no session DO is named for it.
67
+ publicTenantCache.delete(capability);
68
+ return null;
69
+ }
70
+ const resolved = {
71
+ tenantSegment: entry.tenantSegment,
72
+ port: entry.port,
73
+ name: entry.name ?? null,
74
+ };
75
+ publicTenantCache.set(capability, resolved);
76
+ return resolved;
77
+ }
41
78
  /**
42
79
  * Build a Nimbus default-export handler. The returned object is exactly
43
80
  * what `export default` expects in a Workers entry module.
@@ -102,6 +139,52 @@ export function createNimbusHandler(options = {}) {
102
139
  },
103
140
  });
104
141
  }
142
+ if (preview.capability !== undefined) {
143
+ // The public capability form carries no attach token and never
144
+ // asks for one: the capability IS the bearer, so there is no
145
+ // session:attach exchange and no embedder credential to verify.
146
+ // The capability names the owning session through the public
147
+ // directory — a positive hit is cached for the life of this
148
+ // isolate, a miss 404s, and a deployment without the binding
149
+ // falls back to the legacy-public DO name.
150
+ let resolved = await resolvePublicCapability(preview.capability, env);
151
+ const matchesHost = (entry) => entry !== null && (preview.name !== undefined
152
+ ? entry.name === preview.name && entry.port !== null
153
+ : entry.port === null || entry.port === preview.port);
154
+ // Rename/rebinding can leave a positive isolate cache entry behind.
155
+ // Verify BOTH host forms, and read through once before refusing.
156
+ if (resolved !== null && !matchesHost(resolved)) {
157
+ resolved = await resolvePublicCapability(preview.capability, env, true);
158
+ }
159
+ if (resolved === null || !matchesHost(resolved)) {
160
+ return new Response('Not found', { status: 404 });
161
+ }
162
+ // The name form is resolved by capability like the port form, then
163
+ // the name is verified against the directory row: a capability
164
+ // presented under a name it was not bound with is a 404, never a
165
+ // guess at some other application.
166
+ let port;
167
+ if (preview.name !== undefined) {
168
+ if (resolved.name !== preview.name || resolved.port === null) {
169
+ return new Response('Not found', { status: 404 });
170
+ }
171
+ port = resolved.port;
172
+ }
173
+ else {
174
+ port = preview.port;
175
+ }
176
+ return forwardToSession(request, {
177
+ sessionId: preview.sid,
178
+ innerPath: `/port/${port}${url.pathname === '/' ? '/' : url.pathname}`,
179
+ basePath: '',
180
+ }, env, {
181
+ tenantSegment: resolved.tenantSegment,
182
+ extraHeaders: {
183
+ [PREVIEW_CAPABILITY_HEADER]: preview.capability,
184
+ [PUBLIC_BEARER_HEADER]: '1',
185
+ },
186
+ });
187
+ }
105
188
  if (request.method === 'GET'
106
189
  && request.headers.get('Upgrade') !== 'websocket'
107
190
  && url.searchParams.get(NIMBUS_TOKEN_QUERY)
@@ -120,9 +203,15 @@ export function createNimbusHandler(options = {}) {
120
203
  });
121
204
  if (auth instanceof Response)
122
205
  return auth;
206
+ // The scoped name form is resolved INSIDE the session — the name is
207
+ // a reservation alias only that session's records know — so it is
208
+ // forwarded as `/app/<name>/`, the session's own name-addressed door.
209
+ const scopedInner = preview.name !== undefined
210
+ ? `/app/${preview.name}`
211
+ : `/port/${preview.port}`;
123
212
  return forwardToSession(request, {
124
213
  sessionId: preview.sid,
125
- innerPath: `/port/${preview.port}${url.pathname === '/' ? '/' : url.pathname}`,
214
+ innerPath: `${scopedInner}${url.pathname === '/' ? '/' : url.pathname}`,
126
215
  basePath: '',
127
216
  }, env, { tenantSegment: auth.tenantSegment });
128
217
  }
@@ -281,7 +370,12 @@ export function createNimbusHandler(options = {}) {
281
370
  console.warn('[nimbus] onSessionStart hook threw synchronously:', e);
282
371
  }
283
372
  }
284
- return forwardToSession(request, route, env, { tenantSegment });
373
+ return forwardToSession(request, route, env, {
374
+ tenantSegment,
375
+ ...(auth.verified?.claims.scopes !== undefined
376
+ ? { callerScopes: auth.verified.claims.scopes }
377
+ : {}),
378
+ });
285
379
  }
286
380
  // ── Back-compat legacy root paths → landing page ────────────────
287
381
  if (isLegacyRootPath(url.pathname)) {
@@ -0,0 +1,17 @@
1
+ /**
2
+ * public-directory-do.ts — the NimbusPublicDirectory Durable Object class.
3
+ *
4
+ * Lives apart from `public-directory.ts` so the session-side helpers and
5
+ * the router-side stub stay importable outside workerd — this file alone
6
+ * needs `cloudflare:workers` for `DurableObject`. The wrangler binding
7
+ * name and migration entry are `NimbusPublicDirectory`.
8
+ */
9
+ import { DurableObject } from 'cloudflare:workers';
10
+ import { type PublicDirectoryEntry } from './public-directory.js';
11
+ export declare class NimbusPublicDirectory extends DurableObject {
12
+ private store;
13
+ bind(capability: string, entry: PublicDirectoryEntry): Promise<void>;
14
+ unbind(capability: string): Promise<void>;
15
+ resolve(capability: string): Promise<PublicDirectoryEntry | null>;
16
+ }
17
+ //# sourceMappingURL=public-directory-do.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-directory-do.d.ts","sourceRoot":"","sources":["../../src/router/public-directory-do.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,uBAAuB,CAAC;AAE/B,qBAAa,qBAAsB,SAAQ,aAAa;IACtD,OAAO,CAAC,KAAK,CAAsC;IAEnD,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB;IACpD,MAAM,CAAC,UAAU,EAAE,MAAM;IACzB,OAAO,CAAC,UAAU,EAAE,MAAM;CAC3B"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * public-directory-do.ts — the NimbusPublicDirectory Durable Object class.
3
+ *
4
+ * Lives apart from `public-directory.ts` so the session-side helpers and
5
+ * the router-side stub stay importable outside workerd — this file alone
6
+ * needs `cloudflare:workers` for `DurableObject`. The wrangler binding
7
+ * name and migration entry are `NimbusPublicDirectory`.
8
+ */
9
+ import { DurableObject } from 'cloudflare:workers';
10
+ import { PublicDirectoryStore, } from './public-directory.js';
11
+ export class NimbusPublicDirectory extends DurableObject {
12
+ store = new PublicDirectoryStore(this.ctx);
13
+ bind(capability, entry) { return this.store.bind(capability, entry); }
14
+ unbind(capability) { return this.store.unbind(capability); }
15
+ resolve(capability) { return this.store.resolve(capability); }
16
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * public-directory.ts — capability → session routing for public preview hosts.
3
+ *
4
+ * The public capability host form `<cap>--<port>--<sid>.<suffix>` carries
5
+ * no session:attach credential, so the router has no verified tenant to
6
+ * name the session DO with. This singleton Durable Object is the one
7
+ * lookup that answers it: keyed by the unguessable 24-hex capability,
8
+ * it says which tenant segment + sid + port the capability belongs to.
9
+ * Rows are written by the session the moment a port goes public and are
10
+ * deleted on unexpose/clear/remove — there is no listing API, so the
11
+ * directory is never an enumeration surface.
12
+ */
13
+ export interface PublicDirectoryEntry {
14
+ readonly tenantSegment: string;
15
+ readonly sid: string;
16
+ readonly port: number;
17
+ /** The reservation's name alias, when the capability was bound with one —
18
+ * what the `<cap>--<name>--<sid>` host form is verified against. */
19
+ readonly name?: string;
20
+ }
21
+ /** The DO body, usable with any `{ storage }` the tests hand it. */
22
+ export declare class PublicDirectoryStore {
23
+ private ctx;
24
+ constructor(ctx: {
25
+ storage: {
26
+ get<T = unknown>(key: string): Promise<T | undefined>;
27
+ put(key: string, value: unknown): Promise<void>;
28
+ delete(key: string): Promise<unknown>;
29
+ };
30
+ });
31
+ bind(capability: string, entry: {
32
+ tenantSegment: string;
33
+ sid: string;
34
+ port: number;
35
+ name?: string;
36
+ }): Promise<void>;
37
+ unbind(capability: string): Promise<void>;
38
+ resolve(capability: string): Promise<PublicDirectoryEntry | null>;
39
+ }
40
+ /**
41
+ * The stub the router and the session share: one name, one binding, one
42
+ * instance. A missing binding on an enforce-mode deployment is loud at the
43
+ * caller — this helper returns null and the caller decides.
44
+ */
45
+ export declare function publicDirectoryStub(env: unknown): {
46
+ bind(capability: string, entry: PublicDirectoryEntry): Promise<void>;
47
+ unbind(capability: string): Promise<void>;
48
+ resolve(capability: string): Promise<PublicDirectoryEntry | null>;
49
+ } | null;
50
+ /**
51
+ * Publish a public port's capability to the routing directory. A legacy-
52
+ * public deployment needs no directory — its DO name is already the one
53
+ * the public form resolves to — and is allowed to run without the binding.
54
+ * Anything else MUST bind, and a missing `NIMBUS_PUBLIC_DIRECTORY` binding
55
+ * on a non-legacy deployment is a loud error: the exposure would be half-
56
+ * public — stored as public, unroutable in practice.
57
+ */
58
+ export declare function bindPublicPortCapability(host: {
59
+ env?: unknown;
60
+ ctx?: {
61
+ id?: {
62
+ name?: unknown;
63
+ };
64
+ };
65
+ tenantSegment?: string;
66
+ sessionId?: string;
67
+ }, capability: string, port: number, name?: string): Promise<void>;
68
+ /** Retire a public port's capability from the routing directory. */
69
+ export declare function unbindPublicPortCapability(host: {
70
+ env?: unknown;
71
+ ctx?: {
72
+ id?: {
73
+ name?: unknown;
74
+ };
75
+ };
76
+ tenantSegment?: string;
77
+ sessionId?: string;
78
+ }, capability: string): Promise<void>;
79
+ //# sourceMappingURL=public-directory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-directory.d.ts","sourceRoot":"","sources":["../../src/router/public-directory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;yEACqE;IACrE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD,oEAAoE;AACpE,qBAAa,oBAAoB;IACnB,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE;QAAE,OAAO,EAAE;YAClC,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;YACtD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YAChD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;SACvC,CAAA;KAAE;IAEG,IAAI,CACR,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GACzE,OAAO,CAAC,IAAI,CAAC;IAoBV,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;CAKxE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG;IACjD,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;CACnE,GAAG,IAAI,CAUP;AA6BD;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,OAAO,CAAA;SAAE,CAAA;KAAE,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,EACtG,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,oEAAoE;AACpE,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,OAAO,CAAA;SAAE,CAAA;KAAE,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,EACtG,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAOf"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * public-directory.ts — capability → session routing for public preview hosts.
3
+ *
4
+ * The public capability host form `<cap>--<port>--<sid>.<suffix>` carries
5
+ * no session:attach credential, so the router has no verified tenant to
6
+ * name the session DO with. This singleton Durable Object is the one
7
+ * lookup that answers it: keyed by the unguessable 24-hex capability,
8
+ * it says which tenant segment + sid + port the capability belongs to.
9
+ * Rows are written by the session the moment a port goes public and are
10
+ * deleted on unexpose/clear/remove — there is no listing API, so the
11
+ * directory is never an enumeration surface.
12
+ */
13
+ const BINDING_NAME = 'NIMBUS_PUBLIC_DIRECTORY';
14
+ const DIRECTORY_NAME = 'public-directory';
15
+ const ROW_PREFIX = 'public-capability:';
16
+ function rowKey(capability) {
17
+ return `${ROW_PREFIX}${capability}`;
18
+ }
19
+ /** The DO body, usable with any `{ storage }` the tests hand it. */
20
+ export class PublicDirectoryStore {
21
+ ctx;
22
+ constructor(ctx) {
23
+ this.ctx = ctx;
24
+ }
25
+ async bind(capability, entry) {
26
+ if (!/^[a-f0-9]{24}$/.test(capability)) {
27
+ throw new Error('NimbusPublicDirectory.bind: capability must be 24 lowercase hex');
28
+ }
29
+ if (typeof entry.tenantSegment !== 'string' || entry.tenantSegment.length === 0
30
+ || typeof entry.sid !== 'string' || entry.sid.length === 0
31
+ || !Number.isInteger(entry.port) || entry.port < 1 || entry.port > 65535) {
32
+ throw new Error('NimbusPublicDirectory.bind: entry needs tenantSegment, sid, and a real port');
33
+ }
34
+ if (entry.name !== undefined && !/^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/.test(entry.name)) {
35
+ throw new Error('NimbusPublicDirectory.bind: name must be one DNS label');
36
+ }
37
+ await this.ctx.storage.put(rowKey(capability), {
38
+ tenantSegment: entry.tenantSegment,
39
+ sid: entry.sid,
40
+ port: entry.port,
41
+ ...(entry.name !== undefined ? { name: entry.name } : {}),
42
+ });
43
+ }
44
+ async unbind(capability) {
45
+ await this.ctx.storage.delete(rowKey(capability));
46
+ }
47
+ async resolve(capability) {
48
+ const stored = await this.ctx.storage.get(rowKey(capability));
49
+ if (!stored)
50
+ return null;
51
+ return stored;
52
+ }
53
+ }
54
+ /**
55
+ * The stub the router and the session share: one name, one binding, one
56
+ * instance. A missing binding on an enforce-mode deployment is loud at the
57
+ * caller — this helper returns null and the caller decides.
58
+ */
59
+ export function publicDirectoryStub(env) {
60
+ const namespace = env?.[BINDING_NAME];
61
+ if (!namespace || typeof namespace.idFromName !== 'function')
62
+ return null;
63
+ return namespace.get(namespace.idFromName(DIRECTORY_NAME));
64
+ }
65
+ // ── Session side ─────────────────────────────────────────────────────────────
66
+ import { LEGACY_PUBLIC_DO_SEGMENT } from '../_shared/session-router.js';
67
+ /**
68
+ * `{ tenantSegment, sid }` for the session DO this host is, read off its own
69
+ * DO name — `tn:sub:sid` (or `legacy:public:_:sid`), no request header
70
+ * needed. A host without a DO id (a unit-test stub) may carry the fields on
71
+ * itself.
72
+ */
73
+ function sessionIdentity(host) {
74
+ const name = host.ctx?.id?.name;
75
+ if (typeof name === 'string' && name.length > 0) {
76
+ const cut = name.lastIndexOf(':');
77
+ if (cut > 0)
78
+ return { tenantSegment: name.slice(0, cut), sid: name.slice(cut + 1) };
79
+ }
80
+ if (typeof host.tenantSegment === 'string' && typeof host.sessionId === 'string'
81
+ && host.tenantSegment.length > 0 && host.sessionId.length > 0) {
82
+ return { tenantSegment: host.tenantSegment, sid: host.sessionId };
83
+ }
84
+ return null;
85
+ }
86
+ /**
87
+ * Publish a public port's capability to the routing directory. A legacy-
88
+ * public deployment needs no directory — its DO name is already the one
89
+ * the public form resolves to — and is allowed to run without the binding.
90
+ * Anything else MUST bind, and a missing `NIMBUS_PUBLIC_DIRECTORY` binding
91
+ * on a non-legacy deployment is a loud error: the exposure would be half-
92
+ * public — stored as public, unroutable in practice.
93
+ */
94
+ export async function bindPublicPortCapability(host, capability, port, name) {
95
+ const identity = sessionIdentity(host);
96
+ if (identity === null)
97
+ return;
98
+ if (identity.tenantSegment === LEGACY_PUBLIC_DO_SEGMENT)
99
+ return;
100
+ const stub = publicDirectoryStub(host.env);
101
+ if (stub === null) {
102
+ throw new Error('Nimbus: a public port exposure needs the NIMBUS_PUBLIC_DIRECTORY binding '
103
+ + '— without it the capability URL cannot resolve to this session. '
104
+ + 'Add the binding and the NimbusPublicDirectory migration to wrangler.jsonc.');
105
+ }
106
+ await stub.bind(capability, {
107
+ tenantSegment: identity.tenantSegment, sid: identity.sid, port,
108
+ ...(name !== undefined ? { name } : {}),
109
+ });
110
+ }
111
+ /** Retire a public port's capability from the routing directory. */
112
+ export async function unbindPublicPortCapability(host, capability) {
113
+ const identity = sessionIdentity(host);
114
+ if (identity === null)
115
+ return;
116
+ if (identity.tenantSegment === LEGACY_PUBLIC_DO_SEGMENT)
117
+ return;
118
+ const stub = publicDirectoryStub(host.env);
119
+ if (stub === null)
120
+ return; // unbind of a bind that never happened is not an error
121
+ await stub.unbind(capability);
122
+ }
@@ -81,10 +81,36 @@ interface NimbusSessionRpcStub {
81
81
  bytes?: number;
82
82
  }): Promise<unknown>;
83
83
  _rpcListPorts(): Promise<unknown>;
84
- _rpcExposePort(port: number): Promise<unknown>;
84
+ _rpcExposePort(port: number, options?: {
85
+ visibility?: 'scoped' | 'public';
86
+ name?: string;
87
+ }): Promise<unknown>;
88
+ _rpcEnsureDurableApp(input: {
89
+ owner?: string;
90
+ preferredPort?: number;
91
+ visibility?: 'scoped' | 'public';
92
+ }): Promise<unknown>;
93
+ _rpcRemoveDurableApp(owner: string): Promise<unknown>;
94
+ _rpcExposeApp(target: RemoteAppTarget, options?: {
95
+ visibility?: 'scoped' | 'public';
96
+ name?: string;
97
+ }): Promise<unknown>;
98
+ _rpcListApps(): Promise<unknown>;
99
+ _rpcRotateLink(target: RemoteAppTarget): Promise<unknown>;
100
+ _rpcRemoveApp(target: RemoteAppTarget): Promise<unknown>;
85
101
  _rpcUnexposePort(port: number): Promise<unknown>;
86
102
  _rpcDestroy(options?: Record<string, unknown>): Promise<unknown>;
87
103
  }
104
+ /** An app target on the wire: a port, a pid, a name/owner, or the explicit object forms. */
105
+ type RemoteAppTarget = number | string | {
106
+ port: number;
107
+ } | {
108
+ pid: number;
109
+ } | {
110
+ name: string;
111
+ } | {
112
+ owner: string;
113
+ };
88
114
  interface NimbusSessionNamespace {
89
115
  idFromName(name: string): DurableObjectId;
90
116
  get(id: DurableObjectId): NimbusSessionRpcStub;
@@ -1 +1 @@
1
- {"version":3,"file":"remote-api.d.ts","sourceRoot":"","sources":["../../src/router/remote-api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"remote-api.d.ts","sourceRoot":"","sources":["../../src/router/remote-api.ts"],"names":[],"mappings":"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"}
@@ -221,8 +221,32 @@ async function dispatchRemoteRpc(ctx) {
221
221
  return ctx.stub._rpcProcessLogs(numberArg(args[0], 'pid'), processLogOptions(args[1]));
222
222
  case 'listPorts':
223
223
  return ctx.stub._rpcListPorts();
224
- case 'exposePort':
225
- return ctx.stub._rpcExposePort(numberArg(args[0], 'port'));
224
+ case 'exposePort': {
225
+ const options = args[1] === undefined ? undefined : objectArg(args[1]);
226
+ return ctx.stub._rpcExposePort(numberArg(args[0], 'port'), options === undefined ? undefined : exposeOptions(options));
227
+ }
228
+ case 'exposeApp': {
229
+ const options = args[1] === undefined ? undefined : objectArg(args[1]);
230
+ return ctx.stub._rpcExposeApp(appTargetArg(args[0]), options === undefined ? undefined : exposeOptions(options));
231
+ }
232
+ case 'listApps':
233
+ return ctx.stub._rpcListApps();
234
+ case 'rotateLink':
235
+ return ctx.stub._rpcRotateLink(appTargetArg(args[0]));
236
+ case 'removeApp':
237
+ return ctx.stub._rpcRemoveApp(appTargetArg(args[0]));
238
+ case 'ensureDurableApp': {
239
+ const input = objectArg(args[0]);
240
+ return ctx.stub._rpcEnsureDurableApp({
241
+ owner: stringArg(input.owner, 'owner'),
242
+ ...(input.preferredPort === undefined ? {} : { preferredPort: numberArg(input.preferredPort, 'preferredPort') }),
243
+ ...(input.visibility === undefined ? {} : { visibility: input.visibility === 'public' ? 'public' : 'scoped' }),
244
+ });
245
+ }
246
+ case 'removeDurableApp': {
247
+ const input = objectArg(args[0]);
248
+ return ctx.stub._rpcRemoveDurableApp(stringArg(input.owner, 'owner'));
249
+ }
226
250
  case 'unexposePort':
227
251
  return ctx.stub._rpcUnexposePort(numberArg(args[0], 'port'));
228
252
  case 'destroy':
@@ -232,6 +256,28 @@ async function dispatchRemoteRpc(ctx) {
232
256
  throw apiError(`Unknown Nimbus sandbox operation: ${String(op)}`, 'E_REMOTE_OP', 400);
233
257
  }
234
258
  }
259
+ function exposeOptions(options) {
260
+ return {
261
+ ...(options.visibility === undefined ? {} : { visibility: options.visibility === 'public' ? 'public' : 'scoped' }),
262
+ ...(options.name === undefined ? {} : { name: stringArg(options.name, 'name') }),
263
+ };
264
+ }
265
+ function appTargetArg(value) {
266
+ if (typeof value === 'number')
267
+ return numberArg(value, 'target');
268
+ if (typeof value === 'string')
269
+ return stringArg(value, 'target');
270
+ const target = objectArg(value);
271
+ if (target.port !== undefined)
272
+ return { port: numberArg(target.port, 'port') };
273
+ if (target.pid !== undefined)
274
+ return { pid: numberArg(target.pid, 'pid') };
275
+ if (target.name !== undefined)
276
+ return { name: stringArg(target.name, 'name') };
277
+ if (target.owner !== undefined)
278
+ return { owner: stringArg(target.owner, 'owner') };
279
+ throw apiError('Nimbus app target must be a port, a pid, a name, or { port | pid | name | owner }', 'E_ARG_SHAPE', 400);
280
+ }
235
281
  function requireAnyScope(ctx, scopes) {
236
282
  const explicit = ctx.verified?.claims.scopes;
237
283
  if (explicit === undefined)
@@ -1 +1 @@
1
- {"version":3,"file":"cpython-resident.d.ts","sourceRoot":"","sources":["../../src/runtime/cpython-resident.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAwDxE;AAeD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,YAAY,GAAG,oBAAoB,CA8CjF"}
1
+ {"version":3,"file":"cpython-resident.d.ts","sourceRoot":"","sources":["../../src/runtime/cpython-resident.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAwDxE;AAeD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,YAAY,GAAG,oBAAoB,CAgDjF"}
@@ -91,6 +91,8 @@ export function cpythonResidentStart(facetMgr) {
91
91
  const command = args.command;
92
92
  const workerCode = buildCPythonSocketProcessWorker(buildCPythonPreamble());
93
93
  const spawned = await facetMgr.spawnWorker(workerCode, command, args.cwd, {
94
+ resident: { argv: args.argv, runtime: 'python' },
95
+ restart: z.object({ NIMBUS_RESTART: z.literal('on-failure') }).safeParse(args.startArgs.userEnv).success ? 'on-failure' : 'never',
94
96
  compatibilityFlags: ['nodejs_compat'],
95
97
  // By path, not by value: the interpreter is 10.6 MiB, more than a single
96
98
  // RPC value may carry, so whichever host runs this process reads it itself.
@@ -106,7 +108,7 @@ export function cpythonResidentStart(facetMgr) {
106
108
  }
107
109
  const data = boot.data;
108
110
  if (data.state === 'listening' && typeof data.port === 'number' && data.port > 0) {
109
- facetMgr.registerPort(spawned.pid, data.port);
111
+ await facetMgr.registerPort(spawned.pid, data.port);
110
112
  const routeable = await facetMgr.waitForRouteablePorts(spawned.pid);
111
113
  const port = routeable.includes(data.port) ? data.port : routeable[0];
112
114
  if (!port) {
@@ -9,7 +9,10 @@
9
9
  * - events: full EventEmitter
10
10
  * - stream: real Readable/Writable/Transform/Duplex with backpressure
11
11
  * - crypto: createHash (FNV-1a sync, SubtleCrypto async), randomBytes/UUID
12
- * - zlib: real gzip/gunzip/deflate via CompressionStream/DecompressionStream
12
+ * - zlib: forward to workerd's native node:zlib when the facet real-import
13
+ * block materialised (full sync/brotli/stream surface; results are the
14
+ * host realm's own Buffers, recognized by the widened isBuffer);
15
+ * CompressionStream fallback with honest sync refusal
13
16
  * - dns: real DNS resolution via Cloudflare DNS-over-HTTPS
14
17
  * - http: virtual server with port registry for supervisor routing
15
18
  * - https: fetch()-backed request/get
@@ -1 +1 @@
1
- {"version":3,"file":"node-shims.d.ts","sourceRoot":"","sources":["../../src/runtime/node-shims.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAgDH,wBAAgB,iBAAiB,IAAI,MAAM,CAo8N1C"}
1
+ {"version":3,"file":"node-shims.d.ts","sourceRoot":"","sources":["../../src/runtime/node-shims.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAgDH,wBAAgB,iBAAiB,IAAI,MAAM,CA+vO1C"}