@jini-ai/core 0.1.1 → 0.3.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.
package/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # `@jini-ai/core`
2
+
3
+ The Jini kernel: typed DI tokens, pack composition and lifecycle, the tool registry, redaction,
4
+ and origin/API-token auth primitives. It has zero runtime dependencies and is not lifted from
5
+ Open Design — it's a from-scratch implementation of the typed composition contract described in
6
+ the extraction plan (a deliberate rejection of the "structural dependency bag" pattern, e.g. OD's
7
+ `ServerContext`, that decays into dozens of `any` fields). A `Pack` is the one composition unit:
8
+ a named bundle of `services`, plus the optional `tools`/`http`/`cli` transports and `dispose`
9
+ teardown that belong to those services. `createDaemon` composes a set of packs against a bound
10
+ set of tokens, and fails to typecheck if any pack's declared dependency is left unbound.
11
+
12
+ ## Install
13
+
14
+ ```sh
15
+ npm install @jini-ai/core
16
+ ```
17
+
18
+ No peer dependencies — this package is pure TypeScript with no runtime dependencies at all.
19
+
20
+ ## What you get
21
+
22
+ - **DI tokens** — `token<T>(id)` / `manyToken<T>(id)`, nominal and versioned, plus `bindings()`
23
+ building a typed `Bindings<BoundIds>` set (`.bind`, `.bindMany`) that tracks which ids are bound
24
+ in its own type parameter.
25
+ - **Pack composition** — `definePack({ name, deps, services, tools?, http?, cli?, dispose? })`,
26
+ the `Pack`/`PackContainer` types, and `createDaemon({ packs, bindings, transports? })`, which
27
+ composes packs against bound tokens and resolves each pack's `services` against a container
28
+ scoped to only that pack's declared `deps`.
29
+ - **Pack lifecycle helpers** — `registerPackTools` (walks composed packs' `tools()` into a shared
30
+ `ToolRegistry`) and `disposePacks` (best-effort reverse-order teardown; one pack's `dispose`
31
+ failure never blocks another's, recorded as `PackDisposalFailure`).
32
+ - **Tool registry** — `createToolRegistry()` and the `ToolRegistry`/`ToolDescriptor`/`ToolPolicy`/
33
+ `ToolHandler`/`ToolRegistration`/`ToolAuthorizationContext`/`AuthorizationDecision` types. The
34
+ registry's public surface (`register`/`has`/`list`) exposes descriptors only — handlers and
35
+ policies are never publicly retrievable, so holding a `ToolRegistry` reference lets you enumerate
36
+ what's available but never run a tool yourself; only `@jini-ai/daemon`'s `ToolExecutor` can.
37
+ - **Principal** — the minimal `Principal` interface (`id` + optional `roles`) a tool call or run is
38
+ performed on behalf of.
39
+ - **Security/auth primitives** — `redact` (PII/secret redaction, including Luhn-checked card
40
+ numbers), `api-token-auth`, and `origin-validation` (same-origin decision tree, private-IP/
41
+ loopback classification), each genericized to take env-var names as config rather than hardcoded
42
+ product constants.
43
+
44
+ ## Usage
45
+
46
+ ```ts
47
+ import { bindings, definePack, createDaemon, token, createToolRegistry, registerPackTools } from '@jini-ai/core';
48
+
49
+ interface Logger {
50
+ log(msg: string): void;
51
+ }
52
+
53
+ const LoggerToken = token<Logger>('app.logger');
54
+
55
+ const loggerPack = definePack({
56
+ name: 'logger',
57
+ deps: [],
58
+ services: () => ({ logger: { log: (m: string) => console.log(m) } }),
59
+ });
60
+
61
+ const consumerPack = definePack({
62
+ name: 'consumer',
63
+ deps: [LoggerToken],
64
+ services: (c) => ({ logger: c.get(LoggerToken) }),
65
+ });
66
+
67
+ const bound = bindings().bind(LoggerToken, { log: (m: string) => console.log(m) });
68
+
69
+ const daemon = createDaemon({
70
+ packs: [loggerPack, consumerPack] as const,
71
+ bindings: bound,
72
+ });
73
+
74
+ const registry = createToolRegistry();
75
+ registerPackTools([loggerPack, consumerPack], daemon.services, registry);
76
+ ```
77
+
78
+ ## Entry points
79
+
80
+ | subpath | what's behind it |
81
+ |---|---|
82
+ | `.` | The public surface above: tokens, packs, daemon composition, tool registry (descriptors only), principal, redact, auth primitives. |
83
+ | `./internal` | **Not part of the public contract.** Exposes `authorizeToolInvocation` (resolves a registry's tool and runs its authorization gate — a security-sensitive value export, but one that only ever hands back a handler alongside an `'allow'` decision) plus type-only `AnyPack`/`RequiredTokenIds`/`MissingTokenIds` re-derivation helpers. Its sole intended consumers are `@jini-ai/daemon`'s `ToolExecutor` and `@jini-ai/server`'s `createLocalNodeDaemon`. Node's resolver will happily let any consumer import it — the boundary is enforced by `scripts/check-engine-boundaries.ts`, not by the exports map — so external adopters should treat it as off-limits regardless. |
84
+
85
+ ## What's swappable
86
+
87
+ Everything a pack declares as a `deps` token is a swap point by construction: bind any
88
+ implementation that satisfies the token's type via `bindings().bind(...)`, and `createDaemon`
89
+ resolves it into that pack's `PackContainer` with no other change. `ToolPolicy.authorize` is
90
+ likewise a seam you supply per tool registration. The kernel logic itself (composition ordering,
91
+ the missing-binding compile-time gate, the tool registry's append-only enforcement) is fixed and
92
+ not meant to be replaced.
93
+
94
+ ## Runtime
95
+
96
+ Universal — no Node/browser-specific APIs.
97
+ ESM only — ships `"type": "module"` with no CommonJS `require` build.
98
+
99
+ ## Provenance
100
+
101
+ See [source-map.md](./source-map.md) for per-file provenance and scope decisions. Apache-2.0.
package/dist/daemon.d.ts CHANGED
@@ -3,9 +3,9 @@ import type { Pack } from './pack.js';
3
3
  /**
4
4
  * Exported (not just used locally) so `./internal.js` can re-derive `createDaemon`'s exact
5
5
  * compile-time "missing binding" gate for a wrapper composition function (today:
6
- * `@jini-ai/node-host`'s `createLocalNodeDaemon`) without duplicating the type-level logic. Not
6
+ * `@jini-ai/server`'s `createLocalNodeDaemon`) without duplicating the type-level logic. Not
7
7
  * re-exported from `index.ts` — see `./internal.ts`'s module doc for why this stays off the
8
- * public surface (same boundary pattern as `tool-registry.ts`'s `getToolRegistration`).
8
+ * public surface (same boundary pattern as `tool-registry.ts`'s `authorizeToolInvocation`).
9
9
  */
10
10
  export type AnyPack = Pack<any, any, string>;
11
11
  export type RequiredTokenIds<Packs extends readonly AnyPack[]> = Packs[number]['deps'][number]['id'];
package/dist/index.d.ts CHANGED
@@ -3,11 +3,13 @@ export * from './pack.js';
3
3
  export * from './bindings.js';
4
4
  export type { Daemon, DaemonConfig } from './daemon.js';
5
5
  export { createDaemon } from './daemon.js';
6
+ export type { PackDisposalFailure } from './pack-lifecycle.js';
7
+ export { disposePacks, registerPackTools } from './pack-lifecycle.js';
6
8
  export * from './redact.js';
7
9
  export * from './api-token-auth.js';
8
10
  export * from './origin-validation.js';
9
11
  export * from './principal.js';
10
- export type { AuthorizationDecision, RunRef, ToolAuthorizationContext, ToolDescriptor, ToolExecutionContext, ToolHandler, ToolPolicy, ToolRegistration, ToolRegistry, } from './tool-registry.js';
11
- export { createToolRegistry } from './tool-registry.js';
12
+ export type { AuthorizationDecision, RunRef, SurfaceEmission, SurfaceEmitter, ToolAuthorizationContext, ToolDescriptor, ToolExecutionContext, ToolHandler, ToolPolicy, ToolRegistration, ToolRegistry, } from './tool-registry.js';
13
+ export { createToolRegistry, ToolInputError } from './tool-registry.js';
12
14
  export * from './tool-tokens.js';
13
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAI9B,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,YAAY,EACV,qBAAqB,EACrB,MAAM,EACN,wBAAwB,EACxB,cAAc,EACd,oBAAoB,EACpB,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,YAAY,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAI9B,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACtE,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,YAAY,EACV,qBAAqB,EACrB,MAAM,EACN,eAAe,EACf,cAAc,EACd,wBAAwB,EACxB,cAAc,EACd,oBAAoB,EACpB,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,YAAY,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACxE,cAAc,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -2,10 +2,11 @@ export * from './token.js';
2
2
  export * from './pack.js';
3
3
  export * from './bindings.js';
4
4
  export { createDaemon } from './daemon.js';
5
+ export { disposePacks, registerPackTools } from './pack-lifecycle.js';
5
6
  export * from './redact.js';
6
7
  export * from './api-token-auth.js';
7
8
  export * from './origin-validation.js';
8
9
  export * from './principal.js';
9
- export { createToolRegistry } from './tool-registry.js';
10
+ export { createToolRegistry, ToolInputError } from './tool-registry.js';
10
11
  export * from './tool-tokens.js';
11
12
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAK9B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAY/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAK9B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACtE,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAc/B,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACxE,cAAc,kBAAkB,CAAC"}
@@ -5,18 +5,22 @@
5
5
  * contract. Two unrelated escape hatches live here, each for its own
6
6
  * single intended consumer:
7
7
  *
8
- * - {@link getToolRegistration} so `@jini-ai/daemon`'s `ToolExecutor` can
9
- * resolve a registered tool's full `{descriptor, handler, policy}`
10
- * triple. This is the security-sensitive one: it is a runtime *value*
11
- * export that returns live handler closures, and it is what the
12
- * `ToolExecutor` authorization gate exists to guard.
13
- * - `AnyPack`/`RequiredTokenIds`/`MissingTokenIds` so `@jini-ai/node-host`'s
8
+ * - {@link authorizeToolInvocation} so `@jini-ai/daemon`'s `ToolExecutor` can
9
+ * resolve a registered tool and run its authorization gate — the tool's
10
+ * own `ToolPolicy`, then an optional transport-level veto — before ever
11
+ * receiving the handler. This is the security-sensitive one: it is a
12
+ * runtime *value* export, but unlike the `getToolRegistration` it
13
+ * replaced (2026-07-29 hardening pass), it only ever returns a handler
14
+ * closure alongside a `decision: 'allow'` — a denied or unauthorized call
15
+ * gets no handler at all, so the authorization gate cannot be bypassed by
16
+ * calling this export directly instead of going through `ToolExecutor`.
17
+ * - `AnyPack`/`RequiredTokenIds`/`MissingTokenIds` so `@jini-ai/server`'s
14
18
  * `createLocalNodeDaemon` can re-derive `createDaemon`'s exact
15
19
  * compile-time "missing binding" gate on its own wrapper config type,
16
20
  * instead of either duplicating the type-level logic or losing the
17
21
  * compile-time check through the wrapper. These are `import type`-only —
18
22
  * erased at build time, carry no runtime capability, and are not a
19
- * security boundary the way {@link getToolRegistration} is.
23
+ * security boundary the way {@link authorizeToolInvocation} is.
20
24
  *
21
25
  * **Correction (2026-07-19 hardening pass):** a package.json `exports` map
22
26
  * subpath is NOT a language-level or per-consumer access modifier — Node's
@@ -25,12 +29,13 @@
25
29
  * Earlier revisions of this doc comment claimed this boundary was
26
30
  * "enforced" by the exports map; that was inaccurate and left the leak
27
31
  * undetected. The actual enforcement is `scripts/check-engine-boundaries.ts`'s
28
- * rule forbidding any *value* import of `getToolRegistration` from
29
- * `@jini-ai/core/internal` outside `packages/daemon/**` (type-only imports of
30
- * the DI-token-derivation types remain unrestricted, since they carry no
31
- * runtime capability). Until that guard is finished and wired into CI, this
32
- * boundary is documentation-only — treat it as such.
32
+ * rule forbidding any *value* import from `@jini-ai/core/internal` outside
33
+ * `packages/daemon/**` (type-only imports of the DI-token-derivation types
34
+ * remain unrestricted, since they carry no runtime capability) — that guard
35
+ * is wired in, but is a second, independent layer on top of the 2026-07-29
36
+ * structural fix above, not a substitute for it.
33
37
  */
34
- export { getToolRegistration } from './tool-registry.js';
38
+ export { authorizeToolInvocation } from './tool-registry.js';
39
+ export type { ToolAuthorizationDelegate, ToolInvocationAuthorization } from './tool-registry.js';
35
40
  export type { AnyPack, MissingTokenIds, RequiredTokenIds } from './daemon.js';
36
41
  //# sourceMappingURL=internal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,YAAY,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AACjG,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
package/dist/internal.js CHANGED
@@ -5,18 +5,22 @@
5
5
  * contract. Two unrelated escape hatches live here, each for its own
6
6
  * single intended consumer:
7
7
  *
8
- * - {@link getToolRegistration} so `@jini-ai/daemon`'s `ToolExecutor` can
9
- * resolve a registered tool's full `{descriptor, handler, policy}`
10
- * triple. This is the security-sensitive one: it is a runtime *value*
11
- * export that returns live handler closures, and it is what the
12
- * `ToolExecutor` authorization gate exists to guard.
13
- * - `AnyPack`/`RequiredTokenIds`/`MissingTokenIds` so `@jini-ai/node-host`'s
8
+ * - {@link authorizeToolInvocation} so `@jini-ai/daemon`'s `ToolExecutor` can
9
+ * resolve a registered tool and run its authorization gate — the tool's
10
+ * own `ToolPolicy`, then an optional transport-level veto — before ever
11
+ * receiving the handler. This is the security-sensitive one: it is a
12
+ * runtime *value* export, but unlike the `getToolRegistration` it
13
+ * replaced (2026-07-29 hardening pass), it only ever returns a handler
14
+ * closure alongside a `decision: 'allow'` — a denied or unauthorized call
15
+ * gets no handler at all, so the authorization gate cannot be bypassed by
16
+ * calling this export directly instead of going through `ToolExecutor`.
17
+ * - `AnyPack`/`RequiredTokenIds`/`MissingTokenIds` so `@jini-ai/server`'s
14
18
  * `createLocalNodeDaemon` can re-derive `createDaemon`'s exact
15
19
  * compile-time "missing binding" gate on its own wrapper config type,
16
20
  * instead of either duplicating the type-level logic or losing the
17
21
  * compile-time check through the wrapper. These are `import type`-only —
18
22
  * erased at build time, carry no runtime capability, and are not a
19
- * security boundary the way {@link getToolRegistration} is.
23
+ * security boundary the way {@link authorizeToolInvocation} is.
20
24
  *
21
25
  * **Correction (2026-07-19 hardening pass):** a package.json `exports` map
22
26
  * subpath is NOT a language-level or per-consumer access modifier — Node's
@@ -25,11 +29,11 @@
25
29
  * Earlier revisions of this doc comment claimed this boundary was
26
30
  * "enforced" by the exports map; that was inaccurate and left the leak
27
31
  * undetected. The actual enforcement is `scripts/check-engine-boundaries.ts`'s
28
- * rule forbidding any *value* import of `getToolRegistration` from
29
- * `@jini-ai/core/internal` outside `packages/daemon/**` (type-only imports of
30
- * the DI-token-derivation types remain unrestricted, since they carry no
31
- * runtime capability). Until that guard is finished and wired into CI, this
32
- * boundary is documentation-only — treat it as such.
32
+ * rule forbidding any *value* import from `@jini-ai/core/internal` outside
33
+ * `packages/daemon/**` (type-only imports of the DI-token-derivation types
34
+ * remain unrestricted, since they carry no runtime capability) — that guard
35
+ * is wired in, but is a second, independent layer on top of the 2026-07-29
36
+ * structural fix above, not a substitute for it.
33
37
  */
34
- export { getToolRegistration } from './tool-registry.js';
38
+ export { authorizeToolInvocation } from './tool-registry.js';
35
39
  //# sourceMappingURL=internal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -36,8 +36,24 @@ export interface OriginValidationEnvConfig {
36
36
  /** Env var carrying the host the daemon itself is bound to (default `'127.0.0.1'`). */
37
37
  bindHostEnvVar: string;
38
38
  }
39
- /** Parses and validates {@link OriginValidationEnvConfig.allowedOriginsEnvVar} into normalized origins. */
39
+ /**
40
+ * Parses {@link OriginValidationEnvConfig.allowedOriginsEnvVar} into normalized origins.
41
+ *
42
+ * Deliberately never throws — this is on the hot path of {@link isLocalSameOrigin}, called fresh
43
+ * on every same-origin decision a host makes. A malformed entry is dropped and logged instead of
44
+ * aborting the whole parse (see the twin `@jini-ai/http-kit` copy of this module for the fuller
45
+ * incident history this mirrors: a request-time throw here used to turn one config typo into
46
+ * either a 500 on every request, or — on a route with no enclosing catch — an unhandled
47
+ * rejection). Call {@link assertValidAllowedOrigins} once at host startup instead, to fail loudly
48
+ * before any request-serving traffic exists.
49
+ */
40
50
  export declare function configuredAllowedOrigins(config: OriginValidationEnvConfig, env?: NodeJS.ProcessEnv): string[];
51
+ /**
52
+ * Boot-time companion to {@link configuredAllowedOrigins}: throws, naming every malformed entry,
53
+ * instead of silently dropping them. Call once, early in host startup, before the HTTP server
54
+ * accepts connections.
55
+ */
56
+ export declare function assertValidAllowedOrigins(config: OriginValidationEnvConfig, env?: NodeJS.ProcessEnv): void;
41
57
  /** The `host` (hostname:port) component of each configured allowed origin. */
42
58
  export declare function configuredAllowedHosts(origins: string[]): string[];
43
59
  /** The set of browser-facing ports considered "local": the daemon's own port plus an optional configured web port. */
@@ -1 +1 @@
1
- {"version":3,"file":"origin-validation.d.ts","sourceRoot":"","sources":["../src/origin-validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC5B,CAAC;CACH;AAED,0CAA0C;AAC1C,MAAM,WAAW,yBAAyB;IACxC,6EAA6E;IAC7E,oBAAoB,EAAE,MAAM,CAAC;IAC7B,6GAA6G;IAC7G,aAAa,EAAE,MAAM,CAAC;IACtB,uFAAuF;IACvF,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,2GAA2G;AAC3G,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,yBAAyB,EACjC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,EAAE,CAcV;AAED,8EAA8E;AAC9E,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAElE;AAED,sHAAsH;AACtH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,yBAAyB,EACjC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACxC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,EAAE,CAOV;AAUD,4FAA4F;AAC5F,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,CASvE;AAED,uHAAuH;AACvH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAQxD;AAED,yGAAyG;AACzG,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAQ9D;AAED,6EAA6E;AAC7E,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAWrE;AAED,gGAAgG;AAChG,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,yBAAyB,EACjC,UAAU,EAAE,OAAO,EACnB,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,EAAE,MAAM,EAChB,mBAAmB,EAAE,MAAM,EAAE,GAC5B,OAAO,CAaT;AAED,iGAAiG;AACjG,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,yBAAyB,EACjC,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,OAAO,EACnB,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,EAAE,MAAM,EAChB,mBAAmB,EAAE,MAAM,EAAE,GAC5B,OAAO,CA4BT;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,yBAAyB,EACjC,GAAG,EAAE,wBAAwB,EAC7B,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACxC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAmCT"}
1
+ {"version":3,"file":"origin-validation.d.ts","sourceRoot":"","sources":["../src/origin-validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC5B,CAAC;CACH;AAED,0CAA0C;AAC1C,MAAM,WAAW,yBAAyB;IACxC,6EAA6E;IAC7E,oBAAoB,EAAE,MAAM,CAAC;IAC7B,6GAA6G;IAC7G,aAAa,EAAE,MAAM,CAAC;IACtB,uFAAuF;IACvF,cAAc,EAAE,MAAM,CAAC;CACxB;AAsBD;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,yBAAyB,EACjC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,EAAE,CAaV;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,yBAAyB,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,IAAI,CAOvH;AAED,8EAA8E;AAC9E,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAElE;AAED,sHAAsH;AACtH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,yBAAyB,EACjC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACxC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,EAAE,CAOV;AAUD,4FAA4F;AAC5F,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,CASvE;AAED,uHAAuH;AACvH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAQxD;AAED,yGAAyG;AACzG,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAQ9D;AAED,6EAA6E;AAC7E,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAWrE;AAED,gGAAgG;AAChG,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,yBAAyB,EACjC,UAAU,EAAE,OAAO,EACnB,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,EAAE,MAAM,EAChB,mBAAmB,EAAE,MAAM,EAAE,GAC5B,OAAO,CAaT;AAED,iGAAiG;AACjG,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,yBAAyB,EACjC,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,OAAO,EACnB,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,EAAE,MAAM,EAChB,mBAAmB,EAAE,MAAM,EAAE,GAC5B,OAAO,CA4BT;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,yBAAyB,EACjC,GAAG,EAAE,wBAAwB,EAC7B,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACxC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAmCT"}
@@ -15,22 +15,61 @@
15
15
  * it names a specific product route and product feature with no generic
16
16
  * equivalent; see `source-map.md`.
17
17
  */
18
- /** Parses and validates {@link OriginValidationEnvConfig.allowedOriginsEnvVar} into normalized origins. */
19
- export function configuredAllowedOrigins(config, env = process.env) {
18
+ function splitAllowedOriginsEnv(config, env) {
20
19
  const raw = env[config.allowedOriginsEnvVar] || '';
21
20
  if (!raw.trim())
22
21
  return [];
23
22
  return raw
24
23
  .split(',')
25
24
  .map((origin) => origin.trim())
26
- .filter(Boolean)
27
- .map((origin) => {
28
- const parsed = new URL(origin);
29
- if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
30
- throw new Error(`${config.allowedOriginsEnvVar} only supports http:// and https:// origins`);
25
+ .filter(Boolean);
26
+ }
27
+ function parseAllowedOrigin(entry) {
28
+ let parsed;
29
+ try {
30
+ parsed = new URL(entry);
31
+ }
32
+ catch {
33
+ return undefined;
34
+ }
35
+ if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:')
36
+ return undefined;
37
+ return parsed.origin;
38
+ }
39
+ /**
40
+ * Parses {@link OriginValidationEnvConfig.allowedOriginsEnvVar} into normalized origins.
41
+ *
42
+ * Deliberately never throws — this is on the hot path of {@link isLocalSameOrigin}, called fresh
43
+ * on every same-origin decision a host makes. A malformed entry is dropped and logged instead of
44
+ * aborting the whole parse (see the twin `@jini-ai/http-kit` copy of this module for the fuller
45
+ * incident history this mirrors: a request-time throw here used to turn one config typo into
46
+ * either a 500 on every request, or — on a route with no enclosing catch — an unhandled
47
+ * rejection). Call {@link assertValidAllowedOrigins} once at host startup instead, to fail loudly
48
+ * before any request-serving traffic exists.
49
+ */
50
+ export function configuredAllowedOrigins(config, env = process.env) {
51
+ const origins = [];
52
+ for (const entry of splitAllowedOriginsEnv(config, env)) {
53
+ const origin = parseAllowedOrigin(entry);
54
+ if (origin === undefined) {
55
+ console.warn(`[@jini-ai/core] ignoring malformed ${config.allowedOriginsEnvVar} entry (must be an http:// or https:// origin): ${entry}`);
56
+ continue;
31
57
  }
32
- return parsed.origin;
33
- });
58
+ origins.push(origin);
59
+ }
60
+ return origins;
61
+ }
62
+ /**
63
+ * Boot-time companion to {@link configuredAllowedOrigins}: throws, naming every malformed entry,
64
+ * instead of silently dropping them. Call once, early in host startup, before the HTTP server
65
+ * accepts connections.
66
+ */
67
+ export function assertValidAllowedOrigins(config, env = process.env) {
68
+ const invalid = splitAllowedOriginsEnv(config, env).filter((entry) => parseAllowedOrigin(entry) === undefined);
69
+ if (invalid.length === 0)
70
+ return;
71
+ throw new Error(`${config.allowedOriginsEnvVar} has ${invalid.length} invalid entr${invalid.length === 1 ? 'y' : 'ies'} ` +
72
+ `(must be http:// or https:// origins): ${invalid.join(', ')}`);
34
73
  }
35
74
  /** The `host` (hostname:port) component of each configured allowed origin. */
36
75
  export function configuredAllowedHosts(origins) {
@@ -1 +1 @@
1
- {"version":3,"file":"origin-validation.js","sourceRoot":"","sources":["../src/origin-validation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"origin-validation.js","sourceRoot":"","sources":["../src/origin-validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AA0BH,SAAS,sBAAsB,CAAC,MAAiC,EAAE,GAAsB;IACvF,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC;IACnD,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,CAAC;IAC3B,OAAO,GAAG;SACP,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;SAC9B,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa;IACvC,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAClF,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,wBAAwB,CACtC,MAAiC,EACjC,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,KAAK,IAAI,sBAAsB,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;QACxD,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CACV,sCAAsC,MAAM,CAAC,oBAAoB,mDAAmD,KAAK,EAAE,CAC5H,CAAC;YACF,SAAS;QACX,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAiC,EAAE,MAAyB,OAAO,CAAC,GAAG;IAC/G,MAAM,OAAO,GAAG,sBAAsB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,kBAAkB,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC;IAC/G,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACjC,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,CAAC,oBAAoB,QAAQ,OAAO,CAAC,MAAM,gBAAgB,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG;QACvG,0CAA0C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACjE,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,sBAAsB,CAAC,OAAiB;IACtD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;AACvD,CAAC;AAED,sHAAsH;AACtH,MAAM,UAAU,mBAAmB,CACjC,MAAiC,EACjC,IAAwC,EACxC,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;IAClD,IAAI,OAAO,IAAI,OAAO,KAAK,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACnD,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACpD,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;QACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;IACrF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,uHAAuH;AACvH,MAAM,UAAU,aAAa,CAAC,QAAiB;IAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7D,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACjD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAClF,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAA0C,CAAC;IAC1D,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;AAC/G,CAAC;AAED,yGAAyG;AACzG,MAAM,UAAU,mBAAmB,CAAC,QAAiB;IACnD,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7D,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;AACnF,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,0BAA0B,CAAC,QAAiB;IAC1D,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAClD,OAAO,CACL,IAAI,KAAK,WAAW;QACpB,IAAI,KAAK,WAAW;QACpB,IAAI,KAAK,KAAK;QACd,IAAI,KAAK,OAAO;QAChB,IAAI,KAAK,SAAS;QAClB,IAAI,KAAK,IAAI;QACb,aAAa,CAAC,IAAI,CAAC,CACpB,CAAC;AACJ,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,oBAAoB,CAClC,MAAiC,EACjC,UAAmB,EACnB,KAAe,EACf,QAAgB,EAChB,mBAA6B;IAE7B,MAAM,WAAW,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC;IAE/B,MAAM,aAAa,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAC1D,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;QAC5B,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,GAAG,QAAQ,IAAI,CAAC,EAAE,CAAC,CAAC;QACvF,GAAG,sBAAsB,CAAC,mBAAmB,CAAC;KAC/C,CAAC,CAAC;IACH,IAAI,aAAa,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAErD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAChE,OAAO,0BAA0B,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;AAC1D,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,sBAAsB,CACpC,MAAiC,EACjC,MAAe,EACf,UAAmB,EACnB,KAAe,EACf,QAAgB,EAChB,mBAA6B;IAE7B,IAAI,mBAAmB,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAE9D,IAAI,YAAY,CAAC;IACjB,IAAI,CAAC;QACH,YAAY,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,YAAY,CAAC,QAAQ,KAAK,OAAO,IAAI,YAAY,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAE1F,MAAM,WAAW,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC;IAE/B,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,MAAM,aAAa,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAC1D,MAAM,eAAe,GAAG,IAAI,GAAG,CAC7B,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACnB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,QAAQ,IAAI,CAAC,EAAE,CAAC;KACjD,CAAC,CACH,CAAC;IACF,IAAI,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAErD,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC5F,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1D,IAAI,YAAY,CAAC,QAAQ,KAAK,WAAW,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IACjE,OAAO,0BAA0B,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;AAC3D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAiC,EACjC,GAA6B,EAC7B,IAAwC,EACxC,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,mBAAmB,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,WAAW,CAAC;IAC3D,MAAM,mBAAmB,GAAG,wBAAwB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAClE,MAAM,kBAAkB,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEvG,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CAAC;IACjG,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QACpC,IAAI,gBAAgB;YAAE,OAAO,IAAI,CAAC;QAClC,wEAAwE;QACxE,mEAAmE;QACnE,mEAAmE;QACnE,uEAAuE;QACvE,uEAAuE;QACvE,uEAAuE;QACvE,oEAAoE;QACpE,8DAA8D;QAC9D,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAC/D,IAAI,SAAS,KAAK,aAAa,EAAE,CAAC;YAChC,OAAO,oBAAoB,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAC;QAClF,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,0EAA0E;IAC1E,0EAA0E;IAC1E,uEAAuE;IACvE,sEAAsE;IACtE,0EAA0E;IAC1E,yEAAyE;IACzE,2EAA2E;IAC3E,IAAI,mBAAmB,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IACtD,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,mBAAmB,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5F,OAAO,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAC;AAC5F,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @module pack-lifecycle
3
+ *
4
+ * The non-HTTP half of pack mounting: `registerPackTools` drains every composed pack's `tools`
5
+ * contribution into one shared `ToolRegistry`, and `disposePacks` runs every composed pack's
6
+ * `dispose` in reverse composition order.
7
+ *
8
+ * These live in `@jini-ai/core` rather than beside `@jini-ai/http-kit`'s `mountPackHttp` because
9
+ * neither has anything to do with a transport — a CLI-only or headless composition needs the tool
10
+ * registry and the teardown just as much as an HTTP one does. `mountPackHttp` stays where it is for
11
+ * the same reason in reverse: it is the only one of the three that touches an `app`.
12
+ */
13
+ import type { Daemon } from './daemon.js';
14
+ import type { Pack } from './pack.js';
15
+ import type { ToolRegistration, ToolRegistry } from './tool-registry.js';
16
+ type AnyPack = Pack<any, any, string>;
17
+ /**
18
+ * Registers `pack.tools(services)` for every pack in `packs` that declares one, in pack order,
19
+ * into the single shared `registry`.
20
+ *
21
+ * Order matters and is deliberately the caller's to choose: `ToolRegistry.register` throws on a
22
+ * duplicate descriptor id, so whichever pack registers second is the one named in the error. A
23
+ * composition root that wants a host's own tools to win that message registers the host's packs
24
+ * last.
25
+ *
26
+ * @param registry - The shared registry every composed pack contributes into.
27
+ * @param packs - The composed packs, in composition order.
28
+ * @param daemon - The `createDaemon` result holding each pack's already-built services.
29
+ * @returns Every registration that was added, in the order it was added — so a caller can seed a
30
+ * catalog, log an inventory, or assert on the composition without re-deriving it.
31
+ * @throws Whatever `ToolRegistry.register` throws (notably a duplicate descriptor id), at the
32
+ * moment of the offending registration. Composition roots should treat this as fatal: a partially
33
+ * registered tool set is not a state anything downstream can reason about.
34
+ * @complexity O(t) in total contributed tools.
35
+ */
36
+ export declare function registerPackTools<const Packs extends readonly AnyPack[]>(registry: ToolRegistry, packs: Packs, daemon: Daemon<Packs>): readonly ToolRegistration[];
37
+ /** One pack's teardown failure, kept with the pack's name so a caller can report which one failed. */
38
+ export interface PackDisposalFailure {
39
+ readonly pack: string;
40
+ readonly error: unknown;
41
+ }
42
+ /**
43
+ * Runs `pack.dispose(services)` for every pack that declares one, in **reverse** composition order
44
+ * (a pack composed later may depend on an earlier pack's resources, so it must release first).
45
+ *
46
+ * Best-effort by design: one pack throwing must never prevent the rest from disposing, or a single
47
+ * misbehaving pack would leak every other pack's file handles and listeners. Failures are collected
48
+ * and returned rather than thrown, leaving the composition root free to decide whether a teardown
49
+ * failure is worth surfacing to its own caller.
50
+ *
51
+ * @param packs - The composed packs, in composition order (this function reverses them itself).
52
+ * @param daemon - The `createDaemon` result holding each pack's already-built services.
53
+ * @returns The failures, in the order they occurred. Empty when every pack disposed cleanly.
54
+ * @complexity O(p) in pack count, plus each pack's own teardown cost.
55
+ */
56
+ export declare function disposePacks<const Packs extends readonly AnyPack[]>(packs: Packs, daemon: Daemon<Packs>): Promise<readonly PackDisposalFailure[]>;
57
+ export {};
58
+ //# sourceMappingURL=pack-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-lifecycle.d.ts","sourceRoot":"","sources":["../src/pack-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEzE,KAAK,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;AAEtC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,CAAC,KAAK,SAAS,SAAS,OAAO,EAAE,EACtE,QAAQ,EAAE,YAAY,EACtB,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,GACpB,SAAS,gBAAgB,EAAE,CAU7B;AAED,sGAAsG;AACtG,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,YAAY,CAAC,KAAK,CAAC,KAAK,SAAS,SAAS,OAAO,EAAE,EACvE,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,GACpB,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC,CAazC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Registers `pack.tools(services)` for every pack in `packs` that declares one, in pack order,
3
+ * into the single shared `registry`.
4
+ *
5
+ * Order matters and is deliberately the caller's to choose: `ToolRegistry.register` throws on a
6
+ * duplicate descriptor id, so whichever pack registers second is the one named in the error. A
7
+ * composition root that wants a host's own tools to win that message registers the host's packs
8
+ * last.
9
+ *
10
+ * @param registry - The shared registry every composed pack contributes into.
11
+ * @param packs - The composed packs, in composition order.
12
+ * @param daemon - The `createDaemon` result holding each pack's already-built services.
13
+ * @returns Every registration that was added, in the order it was added — so a caller can seed a
14
+ * catalog, log an inventory, or assert on the composition without re-deriving it.
15
+ * @throws Whatever `ToolRegistry.register` throws (notably a duplicate descriptor id), at the
16
+ * moment of the offending registration. Composition roots should treat this as fatal: a partially
17
+ * registered tool set is not a state anything downstream can reason about.
18
+ * @complexity O(t) in total contributed tools.
19
+ */
20
+ export function registerPackTools(registry, packs, daemon) {
21
+ const services = daemon.services;
22
+ const registered = [];
23
+ for (const pack of packs) {
24
+ for (const registration of pack.tools?.(services[pack.name]) ?? []) {
25
+ registry.register(registration);
26
+ registered.push(registration);
27
+ }
28
+ }
29
+ return registered;
30
+ }
31
+ /**
32
+ * Runs `pack.dispose(services)` for every pack that declares one, in **reverse** composition order
33
+ * (a pack composed later may depend on an earlier pack's resources, so it must release first).
34
+ *
35
+ * Best-effort by design: one pack throwing must never prevent the rest from disposing, or a single
36
+ * misbehaving pack would leak every other pack's file handles and listeners. Failures are collected
37
+ * and returned rather than thrown, leaving the composition root free to decide whether a teardown
38
+ * failure is worth surfacing to its own caller.
39
+ *
40
+ * @param packs - The composed packs, in composition order (this function reverses them itself).
41
+ * @param daemon - The `createDaemon` result holding each pack's already-built services.
42
+ * @returns The failures, in the order they occurred. Empty when every pack disposed cleanly.
43
+ * @complexity O(p) in pack count, plus each pack's own teardown cost.
44
+ */
45
+ export async function disposePacks(packs, daemon) {
46
+ const services = daemon.services;
47
+ const failures = [];
48
+ for (let index = packs.length - 1; index >= 0; index -= 1) {
49
+ const pack = packs[index];
50
+ if (!pack.dispose)
51
+ continue;
52
+ try {
53
+ await pack.dispose(services[pack.name]);
54
+ }
55
+ catch (error) {
56
+ failures.push({ pack: pack.name, error });
57
+ }
58
+ }
59
+ return failures;
60
+ }
61
+ //# sourceMappingURL=pack-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-lifecycle.js","sourceRoot":"","sources":["../src/pack-lifecycle.ts"],"names":[],"mappings":"AAkBA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAsB,EACtB,KAAY,EACZ,MAAqB;IAErB,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAmC,CAAC;IAC5D,MAAM,UAAU,GAAuB,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,YAAY,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACnE,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YAChC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAQD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAY,EACZ,MAAqB;IAErB,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAmC,CAAC;IAC5D,MAAM,QAAQ,GAA0B,EAAE,CAAC;IAC3C,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAE,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,SAAS;QAC5B,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
package/dist/pack.d.ts CHANGED
@@ -1,3 +1,23 @@
1
+ /**
2
+ * @module pack
3
+ *
4
+ * A `Pack` is this kernel's one composition unit: a named bundle of services, plus the optional
5
+ * transports (`http`/`cli`), **tool registrations** (`tools`), and teardown (`dispose`) that belong
6
+ * to those services.
7
+ *
8
+ * `tools` and `dispose` were added 2026-07-29 to close the **Route-vs-Tool Gap**. Before them a
9
+ * pack could contribute an HTTP surface but had no way to contribute a `ToolRegistration`, so every
10
+ * real composition (notably `@jini-ai/server`'s `createLocalNodeDaemon`) registered a feature's
11
+ * tools in one place and mounted that feature's routes in another. Those two steps could then be
12
+ * gated independently — turning a route family "off" while leaving its tool registered and
13
+ * reachable through the always-mounted delegated-tool-call route. Putting both contributions on one
14
+ * object makes that failure unrepresentable: a pack that is not composed contributes neither, and
15
+ * there is no separate mounting step for a caller to forget.
16
+ *
17
+ * The rule for pack authors is therefore: **a capability's tools and its routes belong to the same
18
+ * pack.** Splitting them across two packs re-opens the gap by hand.
19
+ */
20
+ import type { ToolRegistration } from './tool-registry.js';
1
21
  import type { AnyToken, ManyToken, Token } from './token.js';
2
22
  /**
3
23
  * The only resolver a pack's `services` factory ever sees. Scoped to that
@@ -13,14 +33,32 @@ export interface Pack<Deps extends readonly AnyToken<unknown, string>[] = readon
13
33
  readonly name: Name;
14
34
  readonly deps: Deps;
15
35
  readonly services: (c: PackContainer) => Services;
36
+ /**
37
+ * `{descriptor, handler, policy}` triples this pack contributes to the composition's shared
38
+ * `ToolRegistry`. Called exactly once per composed pack, before any transport is mounted, so a
39
+ * pack's routes can assume its own tools are already registered.
40
+ *
41
+ * Atomic with `http`/`cli` by construction: a pack that is not composed contributes neither its
42
+ * tools nor its routes. See this module's own doc for the failure mode that makes this
43
+ * load-bearing rather than a convenience.
44
+ */
45
+ readonly tools?: (services: Services) => readonly ToolRegistration[];
16
46
  readonly http?: (app: unknown, services: Services) => void;
17
47
  readonly cli?: (reg: unknown, services: Services) => void;
48
+ /**
49
+ * Releases whatever this pack's `services` acquired (a pty manager, a database handle, an OAuth
50
+ * callback listener). Composition roots call these in reverse composition order, best-effort:
51
+ * one pack's failure to dispose must never prevent another's from running.
52
+ */
53
+ readonly dispose?: (services: Services) => Promise<void> | void;
18
54
  }
19
55
  export declare function definePack<const Name extends string, const Deps extends readonly AnyToken<unknown, string>[], Services>(def: {
20
56
  name: Name;
21
57
  deps: Deps;
22
58
  services: (c: PackContainer) => Services;
59
+ tools?: (services: Services) => readonly ToolRegistration[];
23
60
  http?: (app: unknown, services: Services) => void;
24
61
  cli?: (reg: unknown, services: Services) => void;
62
+ dispose?: (services: Services) => Promise<void> | void;
25
63
  }): Pack<Deps, Services, Name>;
26
64
  //# sourceMappingURL=pack.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../src/pack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;CAC1C;AAED,MAAM,WAAW,IAAI,CACnB,IAAI,SAAS,SAAS,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,GAAG,SAAS,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EACxF,QAAQ,GAAG,OAAO,EAClB,IAAI,SAAS,MAAM,GAAG,MAAM;IAE5B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,QAAQ,CAAC;IAClD,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC3D,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;CAC3D;AAED,wBAAgB,UAAU,CACxB,KAAK,CAAC,IAAI,SAAS,MAAM,EACzB,KAAK,CAAC,IAAI,SAAS,SAAS,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EACvD,QAAQ,EACR,GAAG,EAAE;IACL,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,QAAQ,CAAC;IACzC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAClD,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;CAClD,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAE7B"}
1
+ {"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../src/pack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;CAC1C;AAED,MAAM,WAAW,IAAI,CACnB,IAAI,SAAS,SAAS,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,GAAG,SAAS,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EACxF,QAAQ,GAAG,OAAO,EAClB,IAAI,SAAS,MAAM,GAAG,MAAM;IAE5B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,QAAQ,CAAC;IAClD;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,SAAS,gBAAgB,EAAE,CAAC;IACrE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC3D,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC1D;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACjE;AAED,wBAAgB,UAAU,CACxB,KAAK,CAAC,IAAI,SAAS,MAAM,EACzB,KAAK,CAAC,IAAI,SAAS,SAAS,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EACvD,QAAQ,EACR,GAAG,EAAE;IACL,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,CAAC,CAAC,EAAE,aAAa,KAAK,QAAQ,CAAC;IACzC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,SAAS,gBAAgB,EAAE,CAAC;IAC5D,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAClD,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IACjD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACxD,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAE7B"}
package/dist/pack.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"pack.js","sourceRoot":"","sources":["../src/pack.ts"],"names":[],"mappings":"AAyBA,MAAM,UAAU,UAAU,CAIxB,GAMD;IACC,OAAO,GAA4C,CAAC;AACtD,CAAC"}
1
+ {"version":3,"file":"pack.js","sourceRoot":"","sources":["../src/pack.ts"],"names":[],"mappings":"AA6DA,MAAM,UAAU,UAAU,CAIxB,GAQD;IACC,OAAO,GAA4C,CAAC;AACtD,CAAC"}
@@ -12,11 +12,18 @@
12
12
  * or an agent holding a `ToolRegistry` reference can enumerate what's
13
13
  * available and check membership, but the only way to actually *run* a
14
14
  * tool is through `@jini-ai/daemon`'s `ToolExecutor`, which is the sole
15
- * consumer of {@link getToolRegistration} — a function deliberately
15
+ * consumer of {@link authorizeToolInvocation} — a function deliberately
16
16
  * exported from `./internal.js` (a package-internal entry point, see this
17
17
  * package's `package.json` `exports` map and `source-map.md`) rather than
18
18
  * from the public `index.ts` barrel. Every other caller of
19
19
  * `@jini-ai/core`'s default entry point gets descriptors only.
20
+ * `authorizeToolInvocation` itself runs the tool's `ToolPolicy` (and an
21
+ * optional transport veto) before ever handing back a handler, so a
22
+ * runtime handler closure is unobtainable without already having passed
23
+ * authorization — the earlier design (a separate `getToolRegistration`
24
+ * that returned the handler unconditionally) let any caller of this
25
+ * package-internal entry point skip the gate entirely; see this package's
26
+ * `source-map.md` for the 2026-07-29 hardening note.
20
27
  */
21
28
  import type { Principal } from './principal.js';
22
29
  /** A structural run reference — anything with a stable `id` satisfies this (e.g. `@jini-ai/protocol`'s `RunStatus`). No import needed to satisfy it; see the module doc. */
@@ -25,7 +32,7 @@ export interface RunRef {
25
32
  }
26
33
  /**
27
34
  * The public, non-secret shape of a registered tool. Never carries the
28
- * handler or policy — those are only reachable via {@link getToolRegistration}.
35
+ * handler or policy — those are only reachable via {@link authorizeToolInvocation}.
29
36
  */
30
37
  export interface ToolDescriptor {
31
38
  readonly id: string;
@@ -48,6 +55,49 @@ export interface ToolDescriptor {
48
55
  /** Byte/character ceiling `ToolExecutor` truncates string output to. Omit for no truncation. */
49
56
  readonly maxOutputBytes?: number;
50
57
  }
58
+ /**
59
+ * One human-facing message a handler pushes out mid-call.
60
+ *
61
+ * `channel` becomes the run event payload's `type`, and `payload` is merged in beside it. It is
62
+ * deliberately NOT a union of the known channels: `@jini-ai/protocol` sits below every package in
63
+ * the graph and already types each channel's own body as `unknown` for exactly this reason —
64
+ * structural validation belongs where the concrete type is known (`@jini-ai/ui`'s `parseUIResource`
65
+ * for mcp-ui, `@jini-ai/agentic/a2ui`'s `parseAgentToRendererMessage` for a2ui). Naming the channel
66
+ * as a string is what lets a handler drive `mcp-ui`, `a2ui`, or `surface_request` — or a channel
67
+ * that does not exist yet — through one seam.
68
+ *
69
+ * @example mcp-ui — a sandboxed HTML surface; the transport supplies `toolUseId`
70
+ * `{ channel: 'mcp-ui', payload: { resource } }`
71
+ * @example a2ui — a component tree that can be updated repeatedly on one held-open call
72
+ * `{ channel: 'a2ui', payload: { message: createSurface(exchangeId, ...) } }`
73
+ * @example the protocol-neutral human-in-the-loop pair
74
+ * `{ channel: 'surface_request', payload: { surfaceId, surfaceKind: 'form', payload: {...} } }`
75
+ */
76
+ export interface SurfaceEmission {
77
+ /** The run event payload `type` this belongs on. */
78
+ readonly channel: string;
79
+ /** The channel's own fields, merged into the emitted event beside `type`. */
80
+ readonly payload: Readonly<Record<string, unknown>>;
81
+ }
82
+ /**
83
+ * Pushes a human-facing message into the run's event stream *while the call is still in flight*.
84
+ *
85
+ * A handler's return value is the only other way to reach a human, and that route is useless to a
86
+ * handler that must WAIT for one: the daemon reads surfaces out of the completed result, so a
87
+ * handler that parks first never emits the thing being answered, and the park can never resolve.
88
+ * That is a deadlock by construction, not a race. This is the seam that breaks it — emit, then await.
89
+ *
90
+ * Callable any number of times before the call settles, which is what makes a multi-turn exchange
91
+ * (A2UI's `createSurface` → action → `updateComponents` → action) expressible on a single tool call
92
+ * rather than only a one-shot ask.
93
+ *
94
+ * Human-only in both directions: emitting never puts anything into model context.
95
+ *
96
+ * Optional because it is transport-supplied. A caller with no run event stream to emit into (a
97
+ * headless or synthetic execution) omits it, and a handler that finds it absent must fall back to
98
+ * returning its surface rather than parking — see the `@jini-ai/daemon` bridge for the supplying end.
99
+ */
100
+ export type SurfaceEmitter = (emission: SurfaceEmission) => Promise<void>;
51
101
  /** What a `ToolHandler` receives — everything it needs and nothing it could use to bypass the gate (no registry access, no other tools' state). */
52
102
  export interface ToolExecutionContext {
53
103
  /** The id `ToolExecutor` assigned this call — for the handler's own logging/correlation; carries no authority (the gate already ran before the handler is invoked). */
@@ -56,9 +106,27 @@ export interface ToolExecutionContext {
56
106
  readonly run: RunRef;
57
107
  readonly input: unknown;
58
108
  readonly signal: AbortSignal;
109
+ /** Present only when the invoking transport owns a run event stream — see {@link SurfaceEmitter}. */
110
+ readonly emitSurface?: SurfaceEmitter;
59
111
  }
60
112
  /** Runs the tool's actual side effect. Only ever invoked by `ToolExecutor`, never called directly by a route/agent holding the registry. */
61
113
  export type ToolHandler = (ctx: ToolExecutionContext) => Promise<unknown>;
114
+ /**
115
+ * Thrown by a `ToolHandler` (or a validator it calls, e.g. `@jini-ai/cms`'s `registration-kit.ts`
116
+ * `requireString`/`requireInputRecord`/etc.) to mean "the caller's input was malformed or missing a
117
+ * required field" — a fact about the CALL, not the server. `@jini-ai/daemon`'s `ToolExecutor.execute`
118
+ * tags a handler rejection's `ToolExecutionResult.errorKind` as `'validation'` when the thrown error
119
+ * is `instanceof ToolInputError`, and every HTTP-facing mapping of a `'failed'` execution (today:
120
+ * `@jini-ai/http-kit`'s `delegated-tools.ts`) uses that tag to answer with a 4xx instead of folding
121
+ * it into the same redacted 500 an actual internal/infrastructure failure gets.
122
+ *
123
+ * Deliberately a plain marker with no extra fields: the message itself is already caller-actionable
124
+ * (`withSchemaOnRejection` appends the tool's own input schema to it), so nothing beyond "this IS one
125
+ * of these" needs to survive the `instanceof` check.
126
+ */
127
+ export declare class ToolInputError extends Error {
128
+ constructor(message: string);
129
+ }
62
130
  export type AuthorizationDecision = 'allow' | 'deny';
63
131
  export interface ToolAuthorizationContext {
64
132
  readonly principal: Principal;
@@ -95,20 +163,53 @@ export interface ToolRegistry {
95
163
  *
96
164
  * @returns A `ToolRegistry` whose backing `{descriptor, handler, policy}`
97
165
  * map is held in a module-private `WeakMap` keyed by the returned instance
98
- * — reachable only via {@link getToolRegistration}, not through any method
166
+ * — reachable only via {@link authorizeToolInvocation}, not through any method
99
167
  * on the returned object itself.
100
168
  * @complexity `register`/`has` O(1); `list` O(n) in registered tool count.
101
169
  * @overallScore 100/100
102
170
  */
103
171
  export declare function createToolRegistry(): ToolRegistry;
172
+ /** Transport-level authorization veto, structurally matching `@jini-ai/daemon`'s `ExecutionDelegate.onAuthorize` without either package importing the other's type. */
173
+ export interface ToolAuthorizationDelegate {
174
+ onAuthorize?(ctx: ToolAuthorizationContext): AuthorizationDecision | Promise<AuthorizationDecision>;
175
+ }
104
176
  /**
105
- * Package-internal escape hatch: resolves a tool's full `{descriptor,
106
- * handler, policy}` registration. Exported only from `./internal.js` (see
107
- * this package's `package.json` `exports` map) — `@jini-ai/daemon`'s
177
+ * Outcome of {@link authorizeToolInvocation} — a union discriminated on
178
+ * `decision`, deliberately rather than one shape with an optional `handler`.
179
+ * "A handler exists if and only if the call was allowed" is the whole point
180
+ * of this function, so it is expressed as something the compiler enforces:
181
+ * the `'deny'` arm has no `handler` property to read at all, and the
182
+ * `'allow'` arm's is non-optional, so the caller needs no non-null assertion
183
+ * to use it after checking the decision.
184
+ */
185
+ export type ToolInvocationAuthorization = {
186
+ readonly descriptor: ToolDescriptor;
187
+ readonly decision: 'allow';
188
+ readonly handler: ToolHandler;
189
+ } | {
190
+ readonly descriptor: ToolDescriptor;
191
+ readonly decision: 'deny';
192
+ };
193
+ /**
194
+ * Package-internal escape hatch: resolves `toolId` in `registry` and runs
195
+ * its authorization gate — the tool's own {@link ToolPolicy}, then an
196
+ * optional transport-level `delegate.onAuthorize` veto — before ever
197
+ * exposing the handler. Exported only from `./internal.js` (see this
198
+ * package's `package.json` `exports` map) — `@jini-ai/daemon`'s
108
199
  * `ToolExecutor` is the one and only intended caller. Not re-exported from
109
200
  * `index.ts`, so it never reaches `@jini-ai/core`'s public consumers.
110
201
  *
202
+ * Replaces an earlier `getToolRegistration` that returned the full
203
+ * `{descriptor, handler, policy}` triple unconditionally — since a
204
+ * package.json `exports` subpath is not an access modifier (see this
205
+ * package's `source-map.md`), that let any consumer able to `import` this
206
+ * package-internal entry point retrieve a live handler closure without
207
+ * ever calling a policy. Bundling resolution with authorization here means
208
+ * the handler itself is now unobtainable without already having passed the
209
+ * gate — the leak closes structurally rather than by convention.
210
+ *
211
+ * @returns `undefined` if `toolId` isn't registered on `registry`.
111
212
  * @internal
112
213
  */
113
- export declare function getToolRegistration(registry: ToolRegistry, toolId: string): ToolRegistration | undefined;
214
+ export declare function authorizeToolInvocation(registry: ToolRegistry, toolId: string, principal: Principal, run: RunRef, input: unknown, delegate?: ToolAuthorizationDelegate): Promise<ToolInvocationAuthorization | undefined>;
114
215
  //# sourceMappingURL=tool-registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../src/tool-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,4KAA4K;AAC5K,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;OASG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,iIAAiI;IACjI,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC,kHAAkH;IAClH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,gGAAgG;IAChG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,mJAAmJ;AACnJ,MAAM,WAAW,oBAAoB;IACnC,uKAAuK;IACvK,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED,4IAA4I;AAC5I,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,oBAAoB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE1E,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,CAAC,GAAG,EAAE,wBAAwB,GAAG,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAClG;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;CAC7B;AAED,oHAAoH;AACpH,MAAM,WAAW,YAAY;IAC3B,yPAAyP;IACzP,QAAQ,CAAC,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC/C,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7B,uFAAuF;IACvF,IAAI,IAAI,SAAS,cAAc,EAAE,CAAC;CACnC;AAID;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CAoBjD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAExG"}
1
+ {"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../src/tool-registry.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,29 @@
1
+ /**
2
+ * Thrown by a `ToolHandler` (or a validator it calls, e.g. `@jini-ai/cms`'s `registration-kit.ts`
3
+ * `requireString`/`requireInputRecord`/etc.) to mean "the caller's input was malformed or missing a
4
+ * required field" — a fact about the CALL, not the server. `@jini-ai/daemon`'s `ToolExecutor.execute`
5
+ * tags a handler rejection's `ToolExecutionResult.errorKind` as `'validation'` when the thrown error
6
+ * is `instanceof ToolInputError`, and every HTTP-facing mapping of a `'failed'` execution (today:
7
+ * `@jini-ai/http-kit`'s `delegated-tools.ts`) uses that tag to answer with a 4xx instead of folding
8
+ * it into the same redacted 500 an actual internal/infrastructure failure gets.
9
+ *
10
+ * Deliberately a plain marker with no extra fields: the message itself is already caller-actionable
11
+ * (`withSchemaOnRejection` appends the tool's own input schema to it), so nothing beyond "this IS one
12
+ * of these" needs to survive the `instanceof` check.
13
+ */
14
+ export class ToolInputError extends Error {
15
+ constructor(message) {
16
+ super(message);
17
+ this.name = 'ToolInputError';
18
+ }
19
+ }
1
20
  const registrationsByRegistry = new WeakMap();
2
21
  /**
3
22
  * Creates an empty, append-only `ToolRegistry`.
4
23
  *
5
24
  * @returns A `ToolRegistry` whose backing `{descriptor, handler, policy}`
6
25
  * map is held in a module-private `WeakMap` keyed by the returned instance
7
- * — reachable only via {@link getToolRegistration}, not through any method
26
+ * — reachable only via {@link authorizeToolInvocation}, not through any method
8
27
  * on the returned object itself.
9
28
  * @complexity `register`/`has` O(1); `list` O(n) in registered tool count.
10
29
  * @overallScore 100/100
@@ -29,15 +48,36 @@ export function createToolRegistry() {
29
48
  return registry;
30
49
  }
31
50
  /**
32
- * Package-internal escape hatch: resolves a tool's full `{descriptor,
33
- * handler, policy}` registration. Exported only from `./internal.js` (see
34
- * this package's `package.json` `exports` map) — `@jini-ai/daemon`'s
51
+ * Package-internal escape hatch: resolves `toolId` in `registry` and runs
52
+ * its authorization gate — the tool's own {@link ToolPolicy}, then an
53
+ * optional transport-level `delegate.onAuthorize` veto — before ever
54
+ * exposing the handler. Exported only from `./internal.js` (see this
55
+ * package's `package.json` `exports` map) — `@jini-ai/daemon`'s
35
56
  * `ToolExecutor` is the one and only intended caller. Not re-exported from
36
57
  * `index.ts`, so it never reaches `@jini-ai/core`'s public consumers.
37
58
  *
59
+ * Replaces an earlier `getToolRegistration` that returned the full
60
+ * `{descriptor, handler, policy}` triple unconditionally — since a
61
+ * package.json `exports` subpath is not an access modifier (see this
62
+ * package's `source-map.md`), that let any consumer able to `import` this
63
+ * package-internal entry point retrieve a live handler closure without
64
+ * ever calling a policy. Bundling resolution with authorization here means
65
+ * the handler itself is now unobtainable without already having passed the
66
+ * gate — the leak closes structurally rather than by convention.
67
+ *
68
+ * @returns `undefined` if `toolId` isn't registered on `registry`.
38
69
  * @internal
39
70
  */
40
- export function getToolRegistration(registry, toolId) {
41
- return registrationsByRegistry.get(registry)?.get(toolId);
71
+ export async function authorizeToolInvocation(registry, toolId, principal, run, input, delegate) {
72
+ const registration = registrationsByRegistry.get(registry)?.get(toolId);
73
+ if (!registration) {
74
+ return undefined;
75
+ }
76
+ const { descriptor, handler, policy } = registration;
77
+ let decision = await policy.authorize({ principal, run, tool: descriptor, input });
78
+ if (decision === 'allow' && delegate?.onAuthorize) {
79
+ decision = await delegate.onAuthorize({ principal, run, tool: descriptor, input });
80
+ }
81
+ return decision === 'allow' ? { descriptor, decision, handler } : { descriptor, decision: 'deny' };
42
82
  }
43
83
  //# sourceMappingURL=tool-registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool-registry.js","sourceRoot":"","sources":["../src/tool-registry.ts"],"names":[],"mappings":"AAsGA,MAAM,uBAAuB,GAAG,IAAI,OAAO,EAA+C,CAAC;AAE3F;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,aAAa,GAAG,IAAI,GAAG,EAA4B,CAAC;IAE1D,MAAM,QAAQ,GAAiB;QAC7B,QAAQ,CAAC,YAA8B;YACrC,IAAI,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;gBAClD,MAAM,IAAI,KAAK,CAAC,uBAAuB,YAAY,CAAC,UAAU,CAAC,EAAE,yBAAyB,CAAC,CAAC;YAC9F,CAAC;YACD,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;QAC9D,CAAC;QACD,GAAG,CAAC,MAAc;YAChB,OAAO,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;QACD,IAAI;YACF,OAAO,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACjE,CAAC;KACF,CAAC;IAEF,uBAAuB,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACrD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAsB,EAAE,MAAc;IACxE,OAAO,uBAAuB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;AAC5D,CAAC"}
1
+ {"version":3,"file":"tool-registry.js","sourceRoot":"","sources":["../src/tool-registry.ts"],"names":[],"mappings":"AAwHA;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAsCD,MAAM,uBAAuB,GAAG,IAAI,OAAO,EAA+C,CAAC;AAE3F;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,aAAa,GAAG,IAAI,GAAG,EAA4B,CAAC;IAE1D,MAAM,QAAQ,GAAiB;QAC7B,QAAQ,CAAC,YAA8B;YACrC,IAAI,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;gBAClD,MAAM,IAAI,KAAK,CAAC,uBAAuB,YAAY,CAAC,UAAU,CAAC,EAAE,yBAAyB,CAAC,CAAC;YAC9F,CAAC;YACD,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;QAC9D,CAAC;QACD,GAAG,CAAC,MAAc;YAChB,OAAO,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;QACD,IAAI;YACF,OAAO,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACjE,CAAC;KACF,CAAC;IAEF,uBAAuB,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACrD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAoBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,QAAsB,EACtB,MAAc,EACd,SAAoB,EACpB,GAAW,EACX,KAAc,EACd,QAAoC;IAEpC,MAAM,YAAY,GAAG,uBAAuB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACxE,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC;IACrD,IAAI,QAAQ,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;IACnF,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,EAAE,WAAW,EAAE,CAAC;QAClD,QAAQ,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;IACrF,CAAC;IACD,OAAO,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AACrG,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@jini-ai/core",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
+ "description": "The Jini kernel: typed DI tokens, pack composition and lifecycle, the tool registry, redaction, and origin/API-token auth primitives. Zero dependencies.",
4
5
  "license": "Apache-2.0",
5
6
  "repository": {
6
7
  "type": "git",
@@ -10,10 +11,12 @@
10
11
  "jini": {
11
12
  "domain": "engine",
12
13
  "kind": "kernel",
13
- "runtime": "universal",
14
- "admission": "locked"
14
+ "runtime": "universal"
15
15
  },
16
16
  "type": "module",
17
+ "sideEffects": false,
18
+ "main": "./dist/index.js",
19
+ "types": "./dist/index.d.ts",
17
20
  "exports": {
18
21
  ".": {
19
22
  "types": "./dist/index.d.ts",