@astrale-os/sdk 0.1.0 → 0.1.2

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 (193) hide show
  1. package/dist/auth/authenticate.d.ts +24 -0
  2. package/dist/auth/authenticate.d.ts.map +1 -0
  3. package/dist/auth/authenticate.js +29 -0
  4. package/dist/auth/authenticate.js.map +1 -0
  5. package/dist/auth/check.d.ts +39 -0
  6. package/dist/auth/check.d.ts.map +1 -0
  7. package/dist/auth/check.js +54 -0
  8. package/dist/auth/check.js.map +1 -0
  9. package/dist/auth/compose.d.ts +22 -0
  10. package/dist/auth/compose.d.ts.map +1 -0
  11. package/dist/auth/compose.js +23 -0
  12. package/dist/auth/compose.js.map +1 -0
  13. package/dist/auth/errors.d.ts +16 -0
  14. package/dist/auth/errors.d.ts.map +1 -0
  15. package/dist/auth/errors.js +26 -0
  16. package/dist/auth/errors.js.map +1 -0
  17. package/dist/auth/identity.d.ts +16 -0
  18. package/dist/auth/identity.d.ts.map +1 -0
  19. package/dist/auth/identity.js +2 -0
  20. package/dist/auth/identity.js.map +1 -0
  21. package/dist/auth/index.d.ts +12 -0
  22. package/dist/auth/index.d.ts.map +1 -0
  23. package/dist/auth/index.js +9 -0
  24. package/dist/auth/index.js.map +1 -0
  25. package/dist/auth/kernel-client.d.ts +28 -0
  26. package/dist/auth/kernel-client.d.ts.map +1 -0
  27. package/dist/auth/kernel-client.js +84 -0
  28. package/dist/auth/kernel-client.js.map +1 -0
  29. package/dist/auth/resolve.d.ts +19 -0
  30. package/dist/auth/resolve.d.ts.map +1 -0
  31. package/dist/auth/resolve.js +43 -0
  32. package/dist/auth/resolve.js.map +1 -0
  33. package/dist/auth/sign.d.ts +15 -0
  34. package/dist/auth/sign.d.ts.map +1 -0
  35. package/dist/auth/sign.js +24 -0
  36. package/dist/auth/sign.js.map +1 -0
  37. package/dist/auth/verify.d.ts +26 -0
  38. package/dist/auth/verify.d.ts.map +1 -0
  39. package/dist/auth/verify.js +96 -0
  40. package/dist/auth/verify.js.map +1 -0
  41. package/dist/define/index.d.ts +5 -0
  42. package/dist/define/index.d.ts.map +1 -0
  43. package/dist/define/index.js +3 -0
  44. package/dist/define/index.js.map +1 -0
  45. package/dist/define/remote-function.d.ts +86 -0
  46. package/dist/define/remote-function.d.ts.map +1 -0
  47. package/dist/define/remote-function.js +25 -0
  48. package/dist/define/remote-function.js.map +1 -0
  49. package/dist/define/view.d.ts +86 -0
  50. package/dist/define/view.d.ts.map +1 -0
  51. package/dist/define/view.js +28 -0
  52. package/dist/define/view.js.map +1 -0
  53. package/dist/deploy/check.d.ts +30 -0
  54. package/dist/deploy/check.d.ts.map +1 -0
  55. package/dist/deploy/check.js +82 -0
  56. package/dist/deploy/check.js.map +1 -0
  57. package/dist/deploy/hash-spec.d.ts +9 -0
  58. package/dist/deploy/hash-spec.d.ts.map +1 -0
  59. package/dist/deploy/hash-spec.js +29 -0
  60. package/dist/deploy/hash-spec.js.map +1 -0
  61. package/dist/deploy/index.d.ts +4 -0
  62. package/dist/deploy/index.d.ts.map +1 -0
  63. package/dist/deploy/index.js +4 -0
  64. package/dist/deploy/index.js.map +1 -0
  65. package/dist/deploy/meta.d.ts +18 -0
  66. package/dist/deploy/meta.d.ts.map +1 -0
  67. package/dist/deploy/meta.js +22 -0
  68. package/dist/deploy/meta.js.map +1 -0
  69. package/dist/dispatch/authorize.d.ts +14 -0
  70. package/dist/dispatch/authorize.d.ts.map +1 -0
  71. package/dist/dispatch/authorize.js +24 -0
  72. package/dist/dispatch/authorize.js.map +1 -0
  73. package/dist/dispatch/call-remote.d.ts +35 -0
  74. package/dist/dispatch/call-remote.d.ts.map +1 -0
  75. package/dist/dispatch/call-remote.js +37 -0
  76. package/dist/dispatch/call-remote.js.map +1 -0
  77. package/dist/dispatch/dispatcher.d.ts +60 -0
  78. package/dist/dispatch/dispatcher.d.ts.map +1 -0
  79. package/dist/dispatch/dispatcher.js +177 -0
  80. package/dist/dispatch/dispatcher.js.map +1 -0
  81. package/dist/dispatch/errors.d.ts +47 -0
  82. package/dist/dispatch/errors.d.ts.map +1 -0
  83. package/dist/dispatch/errors.js +76 -0
  84. package/dist/dispatch/errors.js.map +1 -0
  85. package/dist/dispatch/execute.d.ts +33 -0
  86. package/dist/dispatch/execute.d.ts.map +1 -0
  87. package/dist/dispatch/execute.js +24 -0
  88. package/dist/dispatch/execute.js.map +1 -0
  89. package/dist/dispatch/identity.d.ts +73 -0
  90. package/dist/dispatch/identity.d.ts.map +1 -0
  91. package/dist/dispatch/identity.js +106 -0
  92. package/dist/dispatch/identity.js.map +1 -0
  93. package/dist/dispatch/index.d.ts +8 -0
  94. package/dist/dispatch/index.d.ts.map +1 -0
  95. package/dist/dispatch/index.js +8 -0
  96. package/dist/dispatch/index.js.map +1 -0
  97. package/dist/dispatch/resolve.d.ts +27 -0
  98. package/dist/dispatch/resolve.d.ts.map +1 -0
  99. package/dist/dispatch/resolve.js +65 -0
  100. package/dist/dispatch/resolve.js.map +1 -0
  101. package/dist/dispatch/self.d.ts +27 -0
  102. package/dist/dispatch/self.d.ts.map +1 -0
  103. package/dist/dispatch/self.js +25 -0
  104. package/dist/dispatch/self.js.map +1 -0
  105. package/dist/dispatch/validate.d.ts +35 -0
  106. package/dist/dispatch/validate.d.ts.map +1 -0
  107. package/dist/dispatch/validate.js +27 -0
  108. package/dist/dispatch/validate.js.map +1 -0
  109. package/dist/domain/build-spec.d.ts +37 -0
  110. package/dist/domain/build-spec.d.ts.map +1 -0
  111. package/dist/domain/build-spec.js +95 -0
  112. package/dist/domain/build-spec.js.map +1 -0
  113. package/dist/domain/contract.d.ts +17 -0
  114. package/dist/domain/contract.d.ts.map +1 -0
  115. package/dist/domain/contract.js +26 -0
  116. package/dist/domain/contract.js.map +1 -0
  117. package/dist/domain/define.d.ts +82 -0
  118. package/dist/domain/define.d.ts.map +1 -0
  119. package/dist/domain/define.js +99 -0
  120. package/dist/domain/define.js.map +1 -0
  121. package/dist/domain/extend-core.d.ts +49 -0
  122. package/dist/domain/extend-core.d.ts.map +1 -0
  123. package/dist/domain/extend-core.js +182 -0
  124. package/dist/domain/extend-core.js.map +1 -0
  125. package/dist/domain/index.d.ts +5 -0
  126. package/dist/domain/index.d.ts.map +1 -0
  127. package/dist/domain/index.js +4 -0
  128. package/dist/domain/index.js.map +1 -0
  129. package/dist/index.d.ts +19 -0
  130. package/dist/index.d.ts.map +1 -0
  131. package/dist/index.js +32 -0
  132. package/dist/index.js.map +1 -0
  133. package/dist/method/class.d.ts +70 -0
  134. package/dist/method/class.d.ts.map +1 -0
  135. package/dist/method/class.js +26 -0
  136. package/dist/method/class.js.map +1 -0
  137. package/dist/method/context.d.ts +43 -0
  138. package/dist/method/context.d.ts.map +1 -0
  139. package/dist/method/context.js +10 -0
  140. package/dist/method/context.js.map +1 -0
  141. package/dist/method/index.d.ts +6 -0
  142. package/dist/method/index.d.ts.map +1 -0
  143. package/dist/method/index.js +3 -0
  144. package/dist/method/index.js.map +1 -0
  145. package/dist/method/single.d.ts +88 -0
  146. package/dist/method/single.d.ts.map +1 -0
  147. package/dist/method/single.js +18 -0
  148. package/dist/method/single.js.map +1 -0
  149. package/dist/server/auxiliary-routes.d.ts +44 -0
  150. package/dist/server/auxiliary-routes.d.ts.map +1 -0
  151. package/dist/server/auxiliary-routes.js +237 -0
  152. package/dist/server/auxiliary-routes.js.map +1 -0
  153. package/dist/server/config.d.ts +83 -0
  154. package/dist/server/config.d.ts.map +1 -0
  155. package/dist/server/config.js +8 -0
  156. package/dist/server/config.js.map +1 -0
  157. package/dist/server/create.d.ts +21 -0
  158. package/dist/server/create.d.ts.map +1 -0
  159. package/dist/server/create.js +210 -0
  160. package/dist/server/create.js.map +1 -0
  161. package/dist/server/handle.d.ts +35 -0
  162. package/dist/server/handle.d.ts.map +1 -0
  163. package/dist/server/handle.js +9 -0
  164. package/dist/server/handle.js.map +1 -0
  165. package/dist/server/index.d.ts +11 -0
  166. package/dist/server/index.d.ts.map +1 -0
  167. package/dist/server/index.js +8 -0
  168. package/dist/server/index.js.map +1 -0
  169. package/dist/server/jwks.d.ts +11 -0
  170. package/dist/server/jwks.d.ts.map +1 -0
  171. package/dist/server/jwks.js +15 -0
  172. package/dist/server/jwks.js.map +1 -0
  173. package/dist/server/require-env.d.ts +15 -0
  174. package/dist/server/require-env.d.ts.map +1 -0
  175. package/dist/server/require-env.js +21 -0
  176. package/dist/server/require-env.js.map +1 -0
  177. package/dist/server/serving-url.d.ts +14 -0
  178. package/dist/server/serving-url.d.ts.map +1 -0
  179. package/dist/server/serving-url.js +28 -0
  180. package/dist/server/serving-url.js.map +1 -0
  181. package/dist/server/start.d.ts +11 -0
  182. package/dist/server/start.d.ts.map +1 -0
  183. package/dist/server/start.js +30 -0
  184. package/dist/server/start.js.map +1 -0
  185. package/dist/server/worker-entry.d.ts +60 -0
  186. package/dist/server/worker-entry.d.ts.map +1 -0
  187. package/dist/server/worker-entry.js +79 -0
  188. package/dist/server/worker-entry.js.map +1 -0
  189. package/dist/server/worker-meta.d.ts +6 -0
  190. package/dist/server/worker-meta.d.ts.map +1 -0
  191. package/dist/server/worker-meta.js +10 -0
  192. package/dist/server/worker-meta.js.map +1 -0
  193. package/package.json +2 -2
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Inbound credential verification.
3
+ *
4
+ * Uses kernel-core's credential verification infrastructure
5
+ * (CredentialMethodResolver, MethodRegistry) instead of manual JWT handling.
6
+ * Not tied to JWT — supports any credential method kernel-core provides.
7
+ */
8
+ import { CredentialMethodResolver, MethodRegistry, verifyAudience, verifyCredential, } from '@astrale-os/kernel-core';
9
+ import { createLocalJWKSet, createRemoteJWKSet } from 'jose';
10
+ import { derivePublicJwk } from '../server/jwks';
11
+ import { canonicalizeServingUrl } from '../server/serving-url';
12
+ const methodResolver = new CredentialMethodResolver(new MethodRegistry());
13
+ /**
14
+ * Build the key resolver for one verifying server. Captures `config` so it can
15
+ * short-circuit the server's OWN issuer (`config.issuer`): a self-issued
16
+ * credential is verified against the in-memory public key, never fetched — a
17
+ * Worker can't fetch its own hostname, and it already holds the key. Every other
18
+ * issuer is resolved live via JWKS (`createRemoteJWKSet`).
19
+ */
20
+ function makeResolveKeys(config) {
21
+ // The worker's own canonical iss. STRICT: `config.issuer` is the serving URL
22
+ // by contract (both producers — buildIdentityMap / buildAuxIdentityMap — feed
23
+ // it `canonicalizeServingUrl(config.url)`), so a value that doesn't parse is
24
+ // a construction-time config error. Swallowing it would silently disable
25
+ // self-verification and route self-issued credentials to a JWKS fetch on the
26
+ // worker's own hostname — which Cloudflare forbids — turning a config bug
27
+ // into an opaque per-call failure.
28
+ const selfIssuer = canonicalizeServingUrl(config.issuer);
29
+ // TODO(cache): Re-add JWKS caching with a short TTL or kid-miss retry.
30
+ // A prior implementation cached `createRemoteJWKSet` per issuer URL
31
+ // indefinitely. jose's internal cache (30s cooldown, 10min max-age) caused
32
+ // stale keys when the issuer restarted — the resolver served old keys and
33
+ // jose refused to refetch within the cooldown window. On CF Workers the
34
+ // module-level Map persisted across requests, making it worse. For now we
35
+ // create a fresh resolver per call (jose deduplicates concurrent fetches).
36
+ return async (issuer, _method, _kid) => {
37
+ const url = issuer;
38
+ // Self-issued credential (iss == this worker's own serving URL): resolve
39
+ // from the in-memory public key. Never fetch self — Cloudflare forbids a
40
+ // Worker fetching its own hostname, and the published JWKS is this key.
41
+ if (selfIssuer !== undefined) {
42
+ let canonical;
43
+ try {
44
+ canonical = canonicalizeServingUrl(url);
45
+ }
46
+ catch {
47
+ canonical = undefined;
48
+ }
49
+ if (canonical === selfIssuer) {
50
+ return createLocalJWKSet({ keys: [derivePublicJwk(config.privateKey)] });
51
+ }
52
+ }
53
+ // M-28 fix: a bare-slug iss (`mails.localhost`) makes
54
+ // `new URL('mails.localhost/.well-known/jwks.json')` throw "Invalid
55
+ // URL string". The dispatcher's identity map normalizes the iss it
56
+ // signs with, but inbound creds from older clients may still carry
57
+ // the slug form. Coerce to a URL with a default `https://` scheme
58
+ // (matches kernel.astrale.ai canonical form). If the actual receiver
59
+ // is on http://localhost the receiver-side resolver still works
60
+ // because both endpoints are on localhost — but for prod targets
61
+ // requiring TLS this is the right default.
62
+ const normalized = /^https?:\/\//.test(url) ? url : `https://${url}`;
63
+ return createRemoteJWKSet(new URL(`${normalized}/.well-known/jwks.json`));
64
+ };
65
+ }
66
+ /**
67
+ * Verify an inbound delegation credential using kernel-core's verification.
68
+ *
69
+ * @throws AuthenticationError subclasses from kernel-core on verification failure
70
+ */
71
+ export async function verifyInboundCredential(credential, config) {
72
+ // Verify using kernel-core's credential verification pipeline
73
+ const verified = await verifyCredential({
74
+ methodResolver,
75
+ resolveKeys: makeResolveKeys(config),
76
+ }, credential);
77
+ // Validate audience matches this function's issuer (its serving URL).
78
+ // kernel-core's verifyAudience compares canonically.
79
+ verifyAudience(verified, config.issuer);
80
+ // Extract attestation and delegation from claims
81
+ const attestation = verified.claims.attestation;
82
+ if (!attestation?.expr) {
83
+ throw new Error('Credential missing attestation');
84
+ }
85
+ const delegation = verified.claims.delegation;
86
+ if (!delegation?.credential) {
87
+ throw new Error('Credential missing delegation');
88
+ }
89
+ return {
90
+ verified,
91
+ issuer: verified.iss,
92
+ attestation,
93
+ delegation,
94
+ };
95
+ }
96
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/auth/verify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { defineView } from './view';
2
+ export type { ViewDef, ViewRenderContext } from './view';
3
+ export { defineRemoteFunction } from './remote-function';
4
+ export type { AnyRemoteFunctionDef, RemoteFunctionContext, RemoteFunctionDef, } from './remote-function';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/define/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACnC,YAAY,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAA;AAExD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,YAAY,EACV,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,mBAAmB,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { defineView } from './view';
2
+ export { defineRemoteFunction } from './remote-function';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/define/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AAGnC,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Authoring a standalone remote function — a callable not bound to a class.
3
+ * (The verb keeps the `defineRemoteFunction` name; the node it materializes is
4
+ * the canonical kernel `Function` class, the former distribution `RemoteFunction`.)
5
+ *
6
+ * Each entry in `defineRemoteDomain({ remoteFunctions: { ... } })` becomes:
7
+ * - a graph node at `/${origin}/core/<functionsFolder>/<slug>`, materialized
8
+ * as the kernel `Function` class by `buildCorePath` so kernel discovery /
9
+ * `View.resolve` can list it. The `core/` anchor appears in the GRAPH path only.
10
+ * - a Hono route on the worker at the path implied by `binding`
11
+ * (`/<functionsFolder>/<slug>` POST by default — no `core/` in the URL).
12
+ *
13
+ * The slug = the map key (single source of truth, no duplication).
14
+ *
15
+ * `ref` is auto-derived as `function.<slug>` if omitted — used as
16
+ * `Function.ref` on the graph node and as the dispatch key.
17
+ */
18
+ import type { AuthPolicy, FunctionBinding } from '@astrale-os/kernel-api/routed';
19
+ import type { FnMap } from '@astrale-os/kernel-client';
20
+ import type { BoundClientSessionView } from '@astrale-os/kernel-client/session';
21
+ import type { AuthContext } from '@astrale-os/kernel-core';
22
+ import type { Context } from 'hono';
23
+ import type { z } from 'zod';
24
+ import type { CallRemoteFn } from '../dispatch/call-remote';
25
+ export type RemoteFunctionContext<TParams, TDeps = unknown> = {
26
+ /** Validated params (Zod-checked against `inputSchema`). */
27
+ params: TParams;
28
+ /** Hono request context — escape hatch for headers, raw body, etc. */
29
+ c: Context;
30
+ /** Resolved auth context. `null` when `auth: 'public'` or absent. */
31
+ auth: AuthContext | null;
32
+ /** Typed dependency container injected at server startup. */
33
+ deps: TDeps;
34
+ /**
35
+ * `BoundClientSessionView` to the parent kernel, bound to the composed
36
+ * credential `union(delegation, self)` — same shape as `RemoteContext.kernel`
37
+ * for `remoteMethod`. `null` when `auth: 'public'`, or `auth: 'optional'`
38
+ * with no inbound credential.
39
+ */
40
+ kernel: BoundClientSessionView<FnMap> | null;
41
+ /**
42
+ * Call another worker's remote method, re-minting the credential for the
43
+ * target's audience. Same contract as {@link RemoteContext.callRemote}: throws
44
+ * on a public/unauthenticated request; needs `USE` on
45
+ * `Identity.mintDelegationCredential` + the target method's grants.
46
+ */
47
+ callRemote: CallRemoteFn;
48
+ };
49
+ export type RemoteFunctionDef<TParams = unknown, TResult = unknown, TDeps = unknown> = {
50
+ /**
51
+ * Canonical callable identity. Auto-derived as `function.<slug>` (where
52
+ * `<slug>` is the map key) when omitted. Stored as `Function.ref` on the
53
+ * graph node and used by the kernel dispatcher to route the call.
54
+ */
55
+ ref?: string;
56
+ /** Zod schema for the call's parameters. */
57
+ inputSchema: z.ZodType<TParams>;
58
+ /** Zod schema for the call's result. */
59
+ outputSchema: z.ZodType<TResult>;
60
+ /**
61
+ * Override the binding (URL + route shape). When absent, SDK defaults to
62
+ * `{ remoteUrl: ${url}/<functionsFolder>/<slug> }`. The HTTP verb (POST
63
+ * for functions) is applied by the worker route mounter at mount time — it is
64
+ * NOT stored on the binding, so the materialized `Function.binding` carries
65
+ * `remoteUrl` only.
66
+ *
67
+ * Use this to bind to a custom host or REST-style path. Host + path
68
+ * placeholders both supported.
69
+ */
70
+ binding?: FunctionBinding;
71
+ /** Authentication policy. Defaults to `'required'`. */
72
+ auth?: AuthPolicy;
73
+ /** Optional pre-execute authorization. Throw to deny. */
74
+ authorize?: (ctx: RemoteFunctionContext<TParams, TDeps>) => void | Promise<void>;
75
+ /** The function body. May be async. */
76
+ execute: (ctx: RemoteFunctionContext<TParams, TDeps>) => TResult | Promise<TResult>;
77
+ /** Optional human-readable description. */
78
+ description?: string;
79
+ };
80
+ export type AnyRemoteFunctionDef = RemoteFunctionDef<any, any, any>;
81
+ /**
82
+ * Identity helper for authoring a RemoteFunction. Returns its argument
83
+ * unchanged — `defineRemoteDomain` consumes the typed shape.
84
+ */
85
+ export declare function defineRemoteFunction<TParams, TResult, TDeps = unknown>(def: RemoteFunctionDef<TParams, TResult, TDeps>): RemoteFunctionDef<TParams, TResult, TDeps>;
86
+ //# sourceMappingURL=remote-function.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-function.d.ts","sourceRoot":"","sources":["../../src/define/remote-function.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAChF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAA;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAA;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAE5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAE3D,MAAM,MAAM,qBAAqB,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,IAAI;IAC5D,4DAA4D;IAC5D,MAAM,EAAE,OAAO,CAAA;IACf,sEAAsE;IACtE,CAAC,EAAE,OAAO,CAAA;IACV,qEAAqE;IACrE,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;IACxB,6DAA6D;IAC7D,IAAI,EAAE,KAAK,CAAA;IACX;;;;;OAKG;IACH,MAAM,EAAE,sBAAsB,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;IAC5C;;;;;OAKG;IACH,UAAU,EAAE,YAAY,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,iBAAiB,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,KAAK,GAAG,OAAO,IAAI;IACrF;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,4CAA4C;IAC5C,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/B,wCAAwC;IACxC,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAChC;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB,uDAAuD;IACvD,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,yDAAyD;IACzD,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAChF,uCAAuC;IACvC,OAAO,EAAE,CAAC,GAAG,EAAE,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACnF,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAGD,MAAM,MAAM,oBAAoB,GAAG,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAEnE;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,GAAG,OAAO,EACpE,GAAG,EAAE,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,GAC9C,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAE5C"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Authoring a standalone remote function — a callable not bound to a class.
3
+ * (The verb keeps the `defineRemoteFunction` name; the node it materializes is
4
+ * the canonical kernel `Function` class, the former distribution `RemoteFunction`.)
5
+ *
6
+ * Each entry in `defineRemoteDomain({ remoteFunctions: { ... } })` becomes:
7
+ * - a graph node at `/${origin}/core/<functionsFolder>/<slug>`, materialized
8
+ * as the kernel `Function` class by `buildCorePath` so kernel discovery /
9
+ * `View.resolve` can list it. The `core/` anchor appears in the GRAPH path only.
10
+ * - a Hono route on the worker at the path implied by `binding`
11
+ * (`/<functionsFolder>/<slug>` POST by default — no `core/` in the URL).
12
+ *
13
+ * The slug = the map key (single source of truth, no duplication).
14
+ *
15
+ * `ref` is auto-derived as `function.<slug>` if omitted — used as
16
+ * `Function.ref` on the graph node and as the dispatch key.
17
+ */
18
+ /**
19
+ * Identity helper for authoring a RemoteFunction. Returns its argument
20
+ * unchanged — `defineRemoteDomain` consumes the typed shape.
21
+ */
22
+ export function defineRemoteFunction(def) {
23
+ return def;
24
+ }
25
+ //# sourceMappingURL=remote-function.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-function.js","sourceRoot":"","sources":["../../src/define/remote-function.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAuEH;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,GAA+C;IAE/C,OAAO,GAAG,CAAA;AACZ,CAAC"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Authoring a `View` — iframe-mountable callable served by the domain worker.
3
+ *
4
+ * Each entry in `defineRemoteDomain({ views: { ... } })` becomes both:
5
+ * - a graph node at `/${origin}/core/<viewsFolder>/<slug>` (auto-materialized
6
+ * by the SDK; the `core/` segment is the universal anchor injected by
7
+ * `buildCorePath`. `<slug>` is the map key, so it lives in exactly one place)
8
+ * - a Hono route on the worker at the path implied by `binding`
9
+ * (`/<viewsFolder>/<slug>` by default — note: no `core/` in the URL).
10
+ *
11
+ * The `core/` segment appears in the GRAPH path only; the URL path that
12
+ * lands in `Function.binding.remoteUrl` is `${url}/<viewsFolder>/<slug>`.
13
+ *
14
+ * The author can override the URL via `binding` — host and/or path
15
+ * placeholders are supported (the kernel's `route` mechanism does the
16
+ * substitution + Hono matching, same as for methods). When `render` is
17
+ * omitted, no worker route is mounted — useful for Views whose iframe
18
+ * lives at an external host.
19
+ */
20
+ import type { AuthPolicy, FunctionBinding } from '@astrale-os/kernel-api/routed';
21
+ import type { AuthContext } from '@astrale-os/kernel-core';
22
+ import type { EdgeEndpoint } from '@astrale-os/kernel-dsl';
23
+ import type { Context } from 'hono';
24
+ export type ViewRenderContext<TDeps = unknown> = {
25
+ /** Hono request context — read params, headers, query, etc. */
26
+ c: Context;
27
+ /**
28
+ * Placeholders extracted from the request URL (host + path placeholders
29
+ * declared in `binding.remoteUrl` / `binding.route.path`). Empty when
30
+ * the binding has no placeholders.
31
+ */
32
+ params: Record<string, string>;
33
+ /** Resolved auth context. `null` when `auth: 'public'` or absent. */
34
+ auth: AuthContext | null;
35
+ /** Typed dependency container injected at server startup. */
36
+ deps: TDeps;
37
+ };
38
+ export type ViewDef<TDeps = unknown> = {
39
+ /**
40
+ * Override the binding (URL + route shape). When absent, SDK defaults to
41
+ * `{ remoteUrl: ${url}/<viewsFolder>/<slug> }`. The HTTP verb (GET for
42
+ * views) is applied by the worker route mounter at mount time — it is NOT
43
+ * stored on the binding.
44
+ *
45
+ * Use this to bind to a custom host (e.g. `https://{tenant}.example.com`)
46
+ * or REST-style path. Host + path placeholders both supported.
47
+ */
48
+ binding?: FunctionBinding;
49
+ /**
50
+ * Worker-relative path the View's iframe is served from (e.g. `'/ui/note'`),
51
+ * for Views backed by the client SPA instead of a `render`. The spec producer
52
+ * resolves it against the serving url (`binding.remoteUrl = ${url}${mount}`)
53
+ * at materialize time — so the dev never hardcodes a URL. Mutually exclusive
54
+ * with `render`; takes precedence over `binding`.
55
+ */
56
+ mount?: string;
57
+ /** Authentication policy. Defaults to `'required'`. */
58
+ auth?: AuthPolicy;
59
+ /**
60
+ * Optional pre-render authorization. Runs after auth resolution; throw to
61
+ * deny. SDK wraps as 403.
62
+ */
63
+ authorize?: (ctx: ViewRenderContext<TDeps>) => void | Promise<void>;
64
+ /**
65
+ * Render the iframe response. May return a redirect, a proxy, or inline
66
+ * HTML. When omitted, no worker route is mounted — the binding URL
67
+ * points elsewhere (CDN, external service).
68
+ */
69
+ render?: (ctx: ViewRenderContext<TDeps>) => Response | Promise<Response>;
70
+ /**
71
+ * Optional target(s) the View attaches to via `view_for` edge(s). Typically
72
+ * `selfOf(SomeClass)` to bind to a class meta-node, or a `CorePath`
73
+ * pointing at a specific instance. Pass an array to attach the same View
74
+ * to multiple targets (one `view_for` edge is materialized per entry).
75
+ */
76
+ viewFor?: EdgeEndpoint | EdgeEndpoint[];
77
+ /** Optional human-readable description. */
78
+ description?: string;
79
+ };
80
+ /**
81
+ * Identity helper for authoring a View. Returns its argument unchanged —
82
+ * `defineRemoteDomain` consumes the typed shape and the author retains
83
+ * full type inference on `render` / `authorize`.
84
+ */
85
+ export declare function defineView<TDeps = unknown>(def: ViewDef<TDeps>): ViewDef<TDeps>;
86
+ //# sourceMappingURL=view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/define/view.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAChF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAEnC,MAAM,MAAM,iBAAiB,CAAC,KAAK,GAAG,OAAO,IAAI;IAC/C,+DAA+D;IAC/D,CAAC,EAAE,OAAO,CAAA;IACV;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,qEAAqE;IACrE,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;IACxB,6DAA6D;IAC7D,IAAI,EAAE,KAAK,CAAA;CACZ,CAAA;AAED,MAAM,MAAM,OAAO,CAAC,KAAK,GAAG,OAAO,IAAI;IACrC;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uDAAuD;IACvD,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,CAAC,KAAK,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACnE;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,CAAC,KAAK,CAAC,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IACxE;;;;;OAKG;IACH,OAAO,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAA;IACvC,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,GAAG,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAE/E"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Authoring a `View` — iframe-mountable callable served by the domain worker.
3
+ *
4
+ * Each entry in `defineRemoteDomain({ views: { ... } })` becomes both:
5
+ * - a graph node at `/${origin}/core/<viewsFolder>/<slug>` (auto-materialized
6
+ * by the SDK; the `core/` segment is the universal anchor injected by
7
+ * `buildCorePath`. `<slug>` is the map key, so it lives in exactly one place)
8
+ * - a Hono route on the worker at the path implied by `binding`
9
+ * (`/<viewsFolder>/<slug>` by default — note: no `core/` in the URL).
10
+ *
11
+ * The `core/` segment appears in the GRAPH path only; the URL path that
12
+ * lands in `Function.binding.remoteUrl` is `${url}/<viewsFolder>/<slug>`.
13
+ *
14
+ * The author can override the URL via `binding` — host and/or path
15
+ * placeholders are supported (the kernel's `route` mechanism does the
16
+ * substitution + Hono matching, same as for methods). When `render` is
17
+ * omitted, no worker route is mounted — useful for Views whose iframe
18
+ * lives at an external host.
19
+ */
20
+ /**
21
+ * Identity helper for authoring a View. Returns its argument unchanged —
22
+ * `defineRemoteDomain` consumes the typed shape and the author retains
23
+ * full type inference on `render` / `authorize`.
24
+ */
25
+ export function defineView(def) {
26
+ return def;
27
+ }
28
+ //# sourceMappingURL=view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view.js","sourceRoot":"","sources":["../../src/define/view.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAiEH;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAkB,GAAmB;IAC7D,OAAO,GAAG,CAAA;AACZ,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { Meta } from './meta';
2
+ export type DeployCheckOptions = {
3
+ /** Deployed worker URL (e.g. `https://dist.astrale.ai`). */
4
+ url: string;
5
+ /**
6
+ * Expected `meta.schemaHash` — the hash of the locally-built `spec.json`
7
+ * (via `hashSpecFile`). REQUIRED to verify schema drift: when the worker
8
+ * advertises a `schemaHash` but this is absent, the check fails loudly rather
9
+ * than silently "passing" an unverified deploy. Per-domain deploy scripts
10
+ * compute it (`hashSpecFile('./spec.json')`) and pass it.
11
+ */
12
+ expectedSchemaHash?: string;
13
+ /**
14
+ * Path to the SDK repo used to read `sdkCommit`. If omitted and
15
+ * `workspaceRoot` is provided, defaults to `<workspaceRoot>/sdk`.
16
+ */
17
+ sdkRepoPath?: string;
18
+ /** Astrale workspace root — enables auto-resolution of `sdkRepoPath` (`<root>/sdk`). */
19
+ workspaceRoot?: string;
20
+ /** Sink for progress output. Defaults to `console.log`. */
21
+ log?: (line: string) => void;
22
+ };
23
+ /**
24
+ * Validate a deployed worker against local state by fetching `/meta` and
25
+ * verifying sdkCommit / schemaHash / JWKS reachability.
26
+ *
27
+ * Throws on any mismatch. Returns `Meta` on success.
28
+ */
29
+ export declare function deployCheck(opts: DeployCheckOptions): Promise<Meta>;
30
+ //# sourceMappingURL=check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/deploy/check.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAIlC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAA;IACX;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,wFAAwF;IACxF,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,2DAA2D;IAC3D,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC7B,CAAA;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBzE"}
@@ -0,0 +1,82 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { join } from 'node:path';
3
+ import { MetaSchema } from './meta';
4
+ /**
5
+ * Validate a deployed worker against local state by fetching `/meta` and
6
+ * verifying sdkCommit / schemaHash / JWKS reachability.
7
+ *
8
+ * Throws on any mismatch. Returns `Meta` on success.
9
+ */
10
+ export async function deployCheck(opts) {
11
+ // oxlint-disable-next-line no-console
12
+ const log = opts.log ?? ((line) => console.log(line));
13
+ const base = opts.url.replace(/\/+$/, '');
14
+ log(`# deploy:check ${base}`);
15
+ const meta = await fetchMeta(base);
16
+ log(` meta: ${JSON.stringify(meta)}`);
17
+ // `meta.iss` is required + non-empty by `MetaSchema`, enforced in `fetchMeta`.
18
+ await Promise.all([
19
+ checkSdkCommit(meta, opts, log),
20
+ checkSchemaHash(meta, opts, log),
21
+ checkJwks(meta.iss, log),
22
+ ]);
23
+ return meta;
24
+ }
25
+ async function fetchMeta(base) {
26
+ const res = await fetch(`${base}/meta`);
27
+ if (!res.ok)
28
+ throw new Error(`GET ${base}/meta → ${res.status}`);
29
+ return MetaSchema.parse(await res.json());
30
+ }
31
+ async function checkSdkCommit(meta, opts, log) {
32
+ if (!meta.sdkCommit) {
33
+ log(' ! meta.sdkCommit absent — skipping sdkCommit check');
34
+ return;
35
+ }
36
+ const sdkRepo = opts.sdkRepoPath ?? (opts.workspaceRoot ? join(opts.workspaceRoot, 'sdk') : undefined);
37
+ if (!sdkRepo) {
38
+ log(` ! no sdkRepoPath / workspaceRoot — skipping sdkCommit check`);
39
+ return;
40
+ }
41
+ const localSha = gitHead(sdkRepo);
42
+ if (!localSha) {
43
+ log(` ! could not read git HEAD from ${sdkRepo} — skipping sdkCommit check`);
44
+ return;
45
+ }
46
+ if (!localSha.startsWith(meta.sdkCommit) && !meta.sdkCommit.startsWith(localSha)) {
47
+ throw new Error(`sdkCommit mismatch: deployed=${meta.sdkCommit} local=${localSha} (${sdkRepo})`);
48
+ }
49
+ log(` ✓ sdkCommit ${meta.sdkCommit} matches local HEAD`);
50
+ }
51
+ async function checkSchemaHash(meta, opts, log) {
52
+ if (!meta.schemaHash)
53
+ return;
54
+ // Fail loud: the worker advertises a schemaHash, so a missing expected value
55
+ // means we CANNOT verify drift — never silently "pass" an unverified deploy.
56
+ if (!opts.expectedSchemaHash) {
57
+ throw new Error(`worker advertises schemaHash=${meta.schemaHash} but no expectedSchemaHash was provided — ` +
58
+ `cannot verify schema drift (pass expectedSchemaHash, e.g. hashSpecFile('./spec.json'))`);
59
+ }
60
+ if (meta.schemaHash !== opts.expectedSchemaHash) {
61
+ throw new Error(`schemaHash mismatch: deployed=${meta.schemaHash} local=${opts.expectedSchemaHash}`);
62
+ }
63
+ log(` ✓ schemaHash ${meta.schemaHash} matches local`);
64
+ }
65
+ async function checkJwks(iss, log) {
66
+ const jwksUrl = `${iss.replace(/\/+$/, '')}/.well-known/jwks.json`;
67
+ const res = await fetch(jwksUrl);
68
+ if (!res.ok)
69
+ throw new Error(`GET ${jwksUrl} → ${res.status}`);
70
+ const body = (await res.json());
71
+ const keys = body.keys ?? [];
72
+ if (keys.length === 0)
73
+ throw new Error(`${jwksUrl} returned no keys`);
74
+ log(` ✓ JWKS resolves (${keys.length} key${keys.length === 1 ? '' : 's'})`);
75
+ }
76
+ function gitHead(repoPath) {
77
+ const r = spawnSync('git', ['-C', repoPath, 'rev-parse', 'HEAD'], { encoding: 'utf-8' });
78
+ if (r.status !== 0)
79
+ return null;
80
+ return r.stdout.trim();
81
+ }
82
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/deploy/check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Hash a `spec.json` file deterministically. Only the schema payload
3
+ * (`nodes` + `edges`) is hashed — the `meta` block carries `builtAt`
4
+ * timestamps that would poison drift detection.
5
+ *
6
+ * Returns `sha256:<hex>`.
7
+ */
8
+ export declare function hashSpecFile(path: string): string;
9
+ //# sourceMappingURL=hash-spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash-spec.d.ts","sourceRoot":"","sources":["../../src/deploy/hash-spec.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD"}
@@ -0,0 +1,29 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { readFileSync } from 'node:fs';
3
+ const HASH_ALGORITHM = 'sha256';
4
+ /**
5
+ * Hash a `spec.json` file deterministically. Only the schema payload
6
+ * (`nodes` + `edges`) is hashed — the `meta` block carries `builtAt`
7
+ * timestamps that would poison drift detection.
8
+ *
9
+ * Returns `sha256:<hex>`.
10
+ */
11
+ export function hashSpecFile(path) {
12
+ const raw = readFileSync(path, 'utf-8');
13
+ const parsed = JSON.parse(raw);
14
+ const canonical = canonicalJson({ nodes: parsed.nodes ?? [], edges: parsed.edges ?? [] });
15
+ return `${HASH_ALGORITHM}:${createHash(HASH_ALGORITHM).update(canonical).digest('hex')}`;
16
+ }
17
+ function canonicalJson(value) {
18
+ if (value === null || typeof value !== 'object')
19
+ return JSON.stringify(value);
20
+ if (Array.isArray(value))
21
+ return '[' + value.map(canonicalJson).join(',') + ']';
22
+ const keys = Object.keys(value).sort();
23
+ return ('{' +
24
+ keys
25
+ .map((k) => JSON.stringify(k) + ':' + canonicalJson(value[k]))
26
+ .join(',') +
27
+ '}');
28
+ }
29
+ //# sourceMappingURL=hash-spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash-spec.js","sourceRoot":"","sources":["../../src/deploy/hash-spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAEtC,MAAM,cAAc,GAAG,QAAQ,CAAA;AAE/B;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACvC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAyC,CAAA;IACtE,MAAM,SAAS,GAAG,aAAa,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC,CAAA;IACzF,OAAO,GAAG,cAAc,IAAI,UAAU,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;AAC1F,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC7E,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAA;IAC/E,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAgC,CAAC,CAAC,IAAI,EAAE,CAAA;IACjE,OAAO,CACL,GAAG;QACH,IAAI;aACD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,aAAa,CAAE,KAAiC,CAAC,CAAC,CAAC,CAAC,CAAC;aAC1F,IAAI,CAAC,GAAG,CAAC;QACZ,GAAG,CACJ,CAAA;AACH,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { MetaSchema, type Meta } from './meta';
2
+ export { hashSpecFile } from './hash-spec';
3
+ export { deployCheck, type DeployCheckOptions } from './check';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/deploy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,SAAS,CAAA"}
@@ -0,0 +1,4 @@
1
+ export { MetaSchema } from './meta';
2
+ export { hashSpecFile } from './hash-spec';
3
+ export { deployCheck } from './check';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/deploy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,QAAQ,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,WAAW,EAA2B,MAAM,SAAS,CAAA"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `/meta` payload — the contract between `createRemoteServer` (producer)
3
+ * and `deployCheck` (verifier). Both sides parse through `MetaSchema`, so
4
+ * a new field added here flows to both paths and drift is caught at the
5
+ * boundary rather than silently skipped.
6
+ *
7
+ * Scope: **domain workers only**. Kernels rely on OIDC discovery
8
+ * (`/.well-known/openid-configuration`) + JWKS — they have no `/meta`.
9
+ */
10
+ import { z } from 'zod';
11
+ export declare const MetaSchema: z.ZodObject<{
12
+ iss: z.ZodString;
13
+ sdkCommit: z.ZodOptional<z.ZodString>;
14
+ schemaHash: z.ZodOptional<z.ZodString>;
15
+ domainName: z.ZodOptional<z.ZodString>;
16
+ }, z.core.$strip>;
17
+ export type Meta = z.infer<typeof MetaSchema>;
18
+ //# sourceMappingURL=meta.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/deploy/meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,UAAU;;;;;iBAUrB,CAAA;AAEF,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `/meta` payload — the contract between `createRemoteServer` (producer)
3
+ * and `deployCheck` (verifier). Both sides parse through `MetaSchema`, so
4
+ * a new field added here flows to both paths and drift is caught at the
5
+ * boundary rather than silently skipped.
6
+ *
7
+ * Scope: **domain workers only**. Kernels rely on OIDC discovery
8
+ * (`/.well-known/openid-configuration`) + JWKS — they have no `/meta`.
9
+ */
10
+ import { z } from 'zod';
11
+ export const MetaSchema = z.object({
12
+ /** Base URL where JWKS is published. Always stamped by `createRemoteServer`
13
+ * and required by `deployCheck` to verify JWKS reachability. */
14
+ iss: z.string().min(1),
15
+ /** Short git SHA of the SDK used to build the worker. */
16
+ sdkCommit: z.string().optional(),
17
+ /** Deterministic hash of the compiled spec (`sha256:<hex>`). */
18
+ schemaHash: z.string().optional(),
19
+ /** Local directory name under `kernel/domains/<...>/` — used to auto-resolve the local spec. */
20
+ domainName: z.string().optional(),
21
+ });
22
+ //# sourceMappingURL=meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta.js","sourceRoot":"","sources":["../../src/deploy/meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC;qEACiE;IACjE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACtB,yDAAyD;IACzD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,gEAAgE;IAChE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,gGAAgG;IAChG,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAClC,CAAC,CAAA"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Shared `authorize`-hook runner.
3
+ *
4
+ * Both the method dispatcher (`dispatcher.ts`) and the worker-side aux routes
5
+ * (`server/auxiliary-routes.ts`) let an author deny a call by throwing from an
6
+ * `authorize` hook. They MUST agree on the wire semantics: an already-typed
7
+ * `AuthorizationDeniedError` passes through unchanged (so callers can attach
8
+ * hints), and any other thrown error is wrapped into `AuthorizationDeniedError`
9
+ * (→ `PERMISSION_DENIED` / HTTP 403). Centralised here so the two call sites
10
+ * cannot drift — previously the aux routes awaited `authorize` directly, so a
11
+ * plain `Error` thrown to deny leaked out as a 500 instead of a 403.
12
+ */
13
+ export declare function runAuthorize<C>(hook: (ctx: C) => void | Promise<void>, ctx: C): Promise<void>;
14
+ //# sourceMappingURL=authorize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../src/dispatch/authorize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,wBAAsB,YAAY,CAAC,CAAC,EAClC,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EACtC,GAAG,EAAE,CAAC,GACL,OAAO,CAAC,IAAI,CAAC,CAUf"}