@jini-ai/core 0.1.2 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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, isReadOnlyTool, 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,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACxF,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, isReadOnlyTool, 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,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACxF,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":"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"}
@@ -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;
@@ -47,7 +54,80 @@ export interface ToolDescriptor {
47
54
  readonly timeoutMs?: number;
48
55
  /** Byte/character ceiling `ToolExecutor` truncates string output to. Omit for no truncation. */
49
56
  readonly maxOutputBytes?: number;
57
+ /**
58
+ * True when running this tool changes nothing a later read could observe — no durable write, no
59
+ * token minted, no external side effect. Consumed by {@link isReadOnlyTool}, which is the one
60
+ * place the question is ever answered.
61
+ *
62
+ * The kernel does not derive it: a tool's risk must not be self-declared by the layer that also
63
+ * decides to run it, so the value is set by whatever wiring layer independently classifies what a
64
+ * handler calls (`@jini-ai/cms`'s `buildDomainRegistrations` maps its domains' `sideEffects`
65
+ * vocabulary onto it, after `assertToolIsWirable` has already refused any tool whose declaration
66
+ * disagrees with the derived classification).
67
+ *
68
+ * Optional and additive, so no existing registration changes shape — and deliberately NOT
69
+ * defaulted to `true`: an omitted flag means "nobody has classified this", which
70
+ * {@link isReadOnlyTool} treats as not-read-only. A read-only gate that read silence as safety
71
+ * would admit every unclassified write, which is the exact failure the flag exists to prevent.
72
+ */
73
+ readonly readOnly?: boolean;
50
74
  }
75
+ /**
76
+ * The single read-only determination: may this tool run through a surface that has promised its
77
+ * caller it only reads?
78
+ *
79
+ * Every read-only gate in the system asks this one function rather than testing the field itself,
80
+ * so the rule lives in exactly one place — a change to what counts as read-only is a change to this
81
+ * body, not a sweep across transports.
82
+ *
83
+ * @param descriptor - The registered descriptor, or `undefined` for an id that resolved to nothing.
84
+ * @returns `true` only for a descriptor that explicitly declares `readOnly: true`.
85
+ * @complexity O(1).
86
+ */
87
+ export declare function isReadOnlyTool(descriptor: ToolDescriptor | undefined): boolean;
88
+ /**
89
+ * One human-facing message a handler pushes out mid-call.
90
+ *
91
+ * `channel` becomes the run event payload's `type`, and `payload` is merged in beside it. It is
92
+ * deliberately NOT a union of the known channels: `@jini-ai/protocol` sits below every package in
93
+ * the graph and already types each channel's own body as `unknown` for exactly this reason —
94
+ * structural validation belongs where the concrete type is known (`@jini-ai/ui`'s `parseUIResource`
95
+ * for mcp-ui, `@jini-ai/agentic/a2ui`'s `parseAgentToRendererMessage` for a2ui). Naming the channel
96
+ * as a string is what lets a handler drive `mcp-ui`, `a2ui`, or `surface_request` — or a channel
97
+ * that does not exist yet — through one seam.
98
+ *
99
+ * @example mcp-ui — a sandboxed HTML surface; the transport supplies `toolUseId`
100
+ * `{ channel: 'mcp-ui', payload: { resource } }`
101
+ * @example a2ui — a component tree that can be updated repeatedly on one held-open call
102
+ * `{ channel: 'a2ui', payload: { message: createSurface(exchangeId, ...) } }`
103
+ * @example the protocol-neutral human-in-the-loop pair
104
+ * `{ channel: 'surface_request', payload: { surfaceId, surfaceKind: 'form', payload: {...} } }`
105
+ */
106
+ export interface SurfaceEmission {
107
+ /** The run event payload `type` this belongs on. */
108
+ readonly channel: string;
109
+ /** The channel's own fields, merged into the emitted event beside `type`. */
110
+ readonly payload: Readonly<Record<string, unknown>>;
111
+ }
112
+ /**
113
+ * Pushes a human-facing message into the run's event stream *while the call is still in flight*.
114
+ *
115
+ * A handler's return value is the only other way to reach a human, and that route is useless to a
116
+ * handler that must WAIT for one: the daemon reads surfaces out of the completed result, so a
117
+ * handler that parks first never emits the thing being answered, and the park can never resolve.
118
+ * That is a deadlock by construction, not a race. This is the seam that breaks it — emit, then await.
119
+ *
120
+ * Callable any number of times before the call settles, which is what makes a multi-turn exchange
121
+ * (A2UI's `createSurface` → action → `updateComponents` → action) expressible on a single tool call
122
+ * rather than only a one-shot ask.
123
+ *
124
+ * Human-only in both directions: emitting never puts anything into model context.
125
+ *
126
+ * Optional because it is transport-supplied. A caller with no run event stream to emit into (a
127
+ * headless or synthetic execution) omits it, and a handler that finds it absent must fall back to
128
+ * returning its surface rather than parking — see the `@jini-ai/daemon` bridge for the supplying end.
129
+ */
130
+ export type SurfaceEmitter = (emission: SurfaceEmission) => Promise<void>;
51
131
  /** What a `ToolHandler` receives — everything it needs and nothing it could use to bypass the gate (no registry access, no other tools' state). */
52
132
  export interface ToolExecutionContext {
53
133
  /** 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 +136,27 @@ export interface ToolExecutionContext {
56
136
  readonly run: RunRef;
57
137
  readonly input: unknown;
58
138
  readonly signal: AbortSignal;
139
+ /** Present only when the invoking transport owns a run event stream — see {@link SurfaceEmitter}. */
140
+ readonly emitSurface?: SurfaceEmitter;
59
141
  }
60
142
  /** Runs the tool's actual side effect. Only ever invoked by `ToolExecutor`, never called directly by a route/agent holding the registry. */
61
143
  export type ToolHandler = (ctx: ToolExecutionContext) => Promise<unknown>;
144
+ /**
145
+ * Thrown by a `ToolHandler` (or a validator it calls, e.g. `@jini-ai/cms`'s `registration-kit.ts`
146
+ * `requireString`/`requireInputRecord`/etc.) to mean "the caller's input was malformed or missing a
147
+ * required field" — a fact about the CALL, not the server. `@jini-ai/daemon`'s `ToolExecutor.execute`
148
+ * tags a handler rejection's `ToolExecutionResult.errorKind` as `'validation'` when the thrown error
149
+ * is `instanceof ToolInputError`, and every HTTP-facing mapping of a `'failed'` execution (today:
150
+ * `@jini-ai/http-kit`'s `delegated-tools.ts`) uses that tag to answer with a 4xx instead of folding
151
+ * it into the same redacted 500 an actual internal/infrastructure failure gets.
152
+ *
153
+ * Deliberately a plain marker with no extra fields: the message itself is already caller-actionable
154
+ * (`withSchemaOnRejection` appends the tool's own input schema to it), so nothing beyond "this IS one
155
+ * of these" needs to survive the `instanceof` check.
156
+ */
157
+ export declare class ToolInputError extends Error {
158
+ constructor(message: string);
159
+ }
62
160
  export type AuthorizationDecision = 'allow' | 'deny';
63
161
  export interface ToolAuthorizationContext {
64
162
  readonly principal: Principal;
@@ -95,20 +193,53 @@ export interface ToolRegistry {
95
193
  *
96
194
  * @returns A `ToolRegistry` whose backing `{descriptor, handler, policy}`
97
195
  * map is held in a module-private `WeakMap` keyed by the returned instance
98
- * — reachable only via {@link getToolRegistration}, not through any method
196
+ * — reachable only via {@link authorizeToolInvocation}, not through any method
99
197
  * on the returned object itself.
100
198
  * @complexity `register`/`has` O(1); `list` O(n) in registered tool count.
101
199
  * @overallScore 100/100
102
200
  */
103
201
  export declare function createToolRegistry(): ToolRegistry;
202
+ /** Transport-level authorization veto, structurally matching `@jini-ai/daemon`'s `ExecutionDelegate.onAuthorize` without either package importing the other's type. */
203
+ export interface ToolAuthorizationDelegate {
204
+ onAuthorize?(ctx: ToolAuthorizationContext): AuthorizationDecision | Promise<AuthorizationDecision>;
205
+ }
104
206
  /**
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
207
+ * Outcome of {@link authorizeToolInvocation} — a union discriminated on
208
+ * `decision`, deliberately rather than one shape with an optional `handler`.
209
+ * "A handler exists if and only if the call was allowed" is the whole point
210
+ * of this function, so it is expressed as something the compiler enforces:
211
+ * the `'deny'` arm has no `handler` property to read at all, and the
212
+ * `'allow'` arm's is non-optional, so the caller needs no non-null assertion
213
+ * to use it after checking the decision.
214
+ */
215
+ export type ToolInvocationAuthorization = {
216
+ readonly descriptor: ToolDescriptor;
217
+ readonly decision: 'allow';
218
+ readonly handler: ToolHandler;
219
+ } | {
220
+ readonly descriptor: ToolDescriptor;
221
+ readonly decision: 'deny';
222
+ };
223
+ /**
224
+ * Package-internal escape hatch: resolves `toolId` in `registry` and runs
225
+ * its authorization gate — the tool's own {@link ToolPolicy}, then an
226
+ * optional transport-level `delegate.onAuthorize` veto — before ever
227
+ * exposing the handler. Exported only from `./internal.js` (see this
228
+ * package's `package.json` `exports` map) — `@jini-ai/daemon`'s
108
229
  * `ToolExecutor` is the one and only intended caller. Not re-exported from
109
230
  * `index.ts`, so it never reaches `@jini-ai/core`'s public consumers.
110
231
  *
232
+ * Replaces an earlier `getToolRegistration` that returned the full
233
+ * `{descriptor, handler, policy}` triple unconditionally — since a
234
+ * package.json `exports` subpath is not an access modifier (see this
235
+ * package's `source-map.md`), that let any consumer able to `import` this
236
+ * package-internal entry point retrieve a live handler closure without
237
+ * ever calling a policy. Bundling resolution with authorization here means
238
+ * the handler itself is now unobtainable without already having passed the
239
+ * gate — the leak closes structurally rather than by convention.
240
+ *
241
+ * @returns `undefined` if `toolId` isn't registered on `registry`.
111
242
  * @internal
112
243
  */
113
- export declare function getToolRegistration(registry: ToolRegistry, toolId: string): ToolRegistration | undefined;
244
+ export declare function authorizeToolInvocation(registry: ToolRegistry, toolId: string, principal: Principal, run: RunRef, input: unknown, delegate?: ToolAuthorizationDelegate): Promise<ToolInvocationAuthorization | undefined>;
114
245
  //# 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,44 @@
1
+ /**
2
+ * The single read-only determination: may this tool run through a surface that has promised its
3
+ * caller it only reads?
4
+ *
5
+ * Every read-only gate in the system asks this one function rather than testing the field itself,
6
+ * so the rule lives in exactly one place — a change to what counts as read-only is a change to this
7
+ * body, not a sweep across transports.
8
+ *
9
+ * @param descriptor - The registered descriptor, or `undefined` for an id that resolved to nothing.
10
+ * @returns `true` only for a descriptor that explicitly declares `readOnly: true`.
11
+ * @complexity O(1).
12
+ */
13
+ export function isReadOnlyTool(descriptor) {
14
+ return descriptor?.readOnly === true;
15
+ }
16
+ /**
17
+ * Thrown by a `ToolHandler` (or a validator it calls, e.g. `@jini-ai/cms`'s `registration-kit.ts`
18
+ * `requireString`/`requireInputRecord`/etc.) to mean "the caller's input was malformed or missing a
19
+ * required field" — a fact about the CALL, not the server. `@jini-ai/daemon`'s `ToolExecutor.execute`
20
+ * tags a handler rejection's `ToolExecutionResult.errorKind` as `'validation'` when the thrown error
21
+ * is `instanceof ToolInputError`, and every HTTP-facing mapping of a `'failed'` execution (today:
22
+ * `@jini-ai/http-kit`'s `delegated-tools.ts`) uses that tag to answer with a 4xx instead of folding
23
+ * it into the same redacted 500 an actual internal/infrastructure failure gets.
24
+ *
25
+ * Deliberately a plain marker with no extra fields: the message itself is already caller-actionable
26
+ * (`withSchemaOnRejection` appends the tool's own input schema to it), so nothing beyond "this IS one
27
+ * of these" needs to survive the `instanceof` check.
28
+ */
29
+ export class ToolInputError extends Error {
30
+ constructor(message) {
31
+ super(message);
32
+ this.name = 'ToolInputError';
33
+ }
34
+ }
1
35
  const registrationsByRegistry = new WeakMap();
2
36
  /**
3
37
  * Creates an empty, append-only `ToolRegistry`.
4
38
  *
5
39
  * @returns A `ToolRegistry` whose backing `{descriptor, handler, policy}`
6
40
  * map is held in a module-private `WeakMap` keyed by the returned instance
7
- * — reachable only via {@link getToolRegistration}, not through any method
41
+ * — reachable only via {@link authorizeToolInvocation}, not through any method
8
42
  * on the returned object itself.
9
43
  * @complexity `register`/`has` O(1); `list` O(n) in registered tool count.
10
44
  * @overallScore 100/100
@@ -29,15 +63,36 @@ export function createToolRegistry() {
29
63
  return registry;
30
64
  }
31
65
  /**
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
66
+ * Package-internal escape hatch: resolves `toolId` in `registry` and runs
67
+ * its authorization gate — the tool's own {@link ToolPolicy}, then an
68
+ * optional transport-level `delegate.onAuthorize` veto — before ever
69
+ * exposing the handler. Exported only from `./internal.js` (see this
70
+ * package's `package.json` `exports` map) — `@jini-ai/daemon`'s
35
71
  * `ToolExecutor` is the one and only intended caller. Not re-exported from
36
72
  * `index.ts`, so it never reaches `@jini-ai/core`'s public consumers.
37
73
  *
74
+ * Replaces an earlier `getToolRegistration` that returned the full
75
+ * `{descriptor, handler, policy}` triple unconditionally — since a
76
+ * package.json `exports` subpath is not an access modifier (see this
77
+ * package's `source-map.md`), that let any consumer able to `import` this
78
+ * package-internal entry point retrieve a live handler closure without
79
+ * ever calling a policy. Bundling resolution with authorization here means
80
+ * the handler itself is now unobtainable without already having passed the
81
+ * gate — the leak closes structurally rather than by convention.
82
+ *
83
+ * @returns `undefined` if `toolId` isn't registered on `registry`.
38
84
  * @internal
39
85
  */
40
- export function getToolRegistration(registry, toolId) {
41
- return registrationsByRegistry.get(registry)?.get(toolId);
86
+ export async function authorizeToolInvocation(registry, toolId, principal, run, input, delegate) {
87
+ const registration = registrationsByRegistry.get(registry)?.get(toolId);
88
+ if (!registration) {
89
+ return undefined;
90
+ }
91
+ const { descriptor, handler, policy } = registration;
92
+ let decision = await policy.authorize({ principal, run, tool: descriptor, input });
93
+ if (decision === 'allow' && delegate?.onAuthorize) {
94
+ decision = await delegate.onAuthorize({ principal, run, tool: descriptor, input });
95
+ }
96
+ return decision === 'allow' ? { descriptor, decision, handler } : { descriptor, decision: 'deny' };
42
97
  }
43
98
  //# 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":"AA6EA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAAC,UAAsC;IACnE,OAAO,UAAU,EAAE,QAAQ,KAAK,IAAI,CAAC;AACvC,CAAC;AA8DD;;;;;;;;;;;;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.2",
3
+ "version": "0.3.1",
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,10 @@
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,
17
18
  "main": "./dist/index.js",
18
19
  "types": "./dist/index.d.ts",
19
20
  "exports": {
@@ -40,13 +41,13 @@
40
41
  "access": "public",
41
42
  "registry": "https://registry.npmjs.org"
42
43
  },
43
- "devDependencies": {
44
- "@vitest/coverage-v8": "^2.1.9"
45
- },
46
44
  "scripts": {
47
45
  "build": "tsc -p tsconfig.json",
48
46
  "typecheck": "tsc -p tsconfig.json --noEmit",
49
47
  "test": "vitest run",
50
48
  "test:coverage": "vitest run --coverage"
49
+ },
50
+ "devDependencies": {
51
+ "@vitest/coverage-v8": "^2.1.9"
51
52
  }
52
- }
53
+ }
package/LICENSE DELETED
@@ -1,201 +0,0 @@
1
- Apache License
2
- Version 2.0, January 2004
3
- http://www.apache.org/licenses/
4
-
5
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
-
7
- 1. Definitions.
8
-
9
- "License" shall mean the terms and conditions for use, reproduction,
10
- and distribution as defined by Sections 1 through 9 of this document.
11
-
12
- "Licensor" shall mean the copyright owner or entity authorized by
13
- the copyright owner that is granting the License.
14
-
15
- "Legal Entity" shall mean the union of the acting entity and all
16
- other entities that control, are controlled by, or are under common
17
- control with that entity. For the purposes of this definition,
18
- "control" means (i) the power, direct or indirect, to cause the
19
- direction or management of such entity, whether by contract or
20
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
- outstanding shares, or (iii) beneficial ownership of such entity.
22
-
23
- "You" (or "Your") shall mean an individual or Legal Entity
24
- exercising permissions granted by this License.
25
-
26
- "Source" form shall mean the preferred form for making modifications,
27
- including but not limited to software source code, documentation
28
- source, and configuration files.
29
-
30
- "Object" form shall mean any form resulting from mechanical
31
- transformation or translation of a Source form, including but
32
- not limited to compiled object code, generated documentation,
33
- and conversions to other media types.
34
-
35
- "Work" shall mean the work of authorship, whether in Source or
36
- Object form, made available under the License, as indicated by a
37
- copyright notice that is included in or attached to the work
38
- (an example is provided in the Appendix below).
39
-
40
- "Derivative Works" shall mean any work, whether in Source or Object
41
- form, that is based on (or derived from) the Work and for which the
42
- editorial revisions, annotations, elaborations, or other modifications
43
- represent, as a whole, an original work of authorship. For the purposes
44
- of this License, Derivative Works shall not include works that remain
45
- separable from, or merely link (or bind by name) to the interfaces of,
46
- the Work and Derivative Works thereof.
47
-
48
- "Contribution" shall mean any work of authorship, including
49
- the original version of the Work and any modifications or additions
50
- to that Work or Derivative Works thereof, that is intentionally
51
- submitted to Licensor for inclusion in the Work by the copyright owner
52
- or by an individual or Legal Entity authorized to submit on behalf of
53
- the copyright owner. For the purposes of this definition, "submitted"
54
- means any form of electronic, verbal, or written communication sent
55
- to the Licensor or its representatives, including but not limited to
56
- communication on electronic mailing lists, source code control systems,
57
- and issue tracking systems that are managed by, or on behalf of, the
58
- Licensor for the purpose of discussing and improving the Work, but
59
- excluding communication that is conspicuously marked or otherwise
60
- designated in writing by the copyright owner as "Not a Contribution."
61
-
62
- "Contributor" shall mean Licensor and any individual or Legal Entity
63
- on behalf of whom a Contribution has been received by Licensor and
64
- subsequently incorporated within the Work.
65
-
66
- 2. Grant of Copyright License. Subject to the terms and conditions of
67
- this License, each Contributor hereby grants to You a perpetual,
68
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
- copyright license to reproduce, prepare Derivative Works of,
70
- publicly display, publicly perform, sublicense, and distribute the
71
- Work and such Derivative Works in Source or Object form.
72
-
73
- 3. Grant of Patent License. Subject to the terms and conditions of
74
- this License, each Contributor hereby grants to You a perpetual,
75
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
- (except as stated in this section) patent license to make, have made,
77
- use, offer to sell, sell, import, and otherwise transfer the Work,
78
- where such license applies only to those patent claims licensable
79
- by such Contributor that are necessarily infringed by their
80
- Contribution(s) alone or by combination of their Contribution(s)
81
- with the Work to which such Contribution(s) was submitted. If You
82
- institute patent litigation against any entity (including a
83
- cross-claim or counterclaim in a lawsuit) alleging that the Work
84
- or a Contribution incorporated within the Work constitutes direct
85
- or contributory patent infringement, then any patent licenses
86
- granted to You under this License for that Work shall terminate
87
- as of the date such litigation is filed.
88
-
89
- 4. Redistribution. You may reproduce and distribute copies of the
90
- Work or Derivative Works thereof in any medium, with or without
91
- modifications, and in Source or Object form, provided that You
92
- meet the following conditions:
93
-
94
- (a) You must give any other recipients of the Work or
95
- Derivative Works a copy of this License; and
96
-
97
- (b) You must cause any modified files to carry prominent notices
98
- stating that You changed the files; and
99
-
100
- (c) You must retain, in the Source form of any Derivative Works
101
- that You distribute, all copyright, patent, trademark, and
102
- attribution notices from the Source form of the Work,
103
- excluding those notices that do not pertain to any part of
104
- the Derivative Works; and
105
-
106
- (d) If the Work includes a "NOTICE" text file as part of its
107
- distribution, then any Derivative Works that You distribute must
108
- include a readable copy of the attribution notices contained
109
- within such NOTICE file, excluding those notices that do not
110
- pertain to any part of the Derivative Works, in at least one
111
- of the following places: within a NOTICE text file distributed
112
- as part of the Derivative Works; within the Source form or
113
- documentation, if provided along with the Derivative Works; or,
114
- within a display generated by the Derivative Works, if and
115
- wherever such third-party notices normally appear. The contents
116
- of the NOTICE file are for informational purposes only and
117
- do not modify the License. You may add Your own attribution
118
- notices within Derivative Works that You distribute, alongside
119
- or as an addendum to the NOTICE text from the Work, provided
120
- that such additional attribution notices cannot be construed
121
- as modifying the License.
122
-
123
- You may add Your own copyright statement to Your modifications and
124
- may provide additional or different license terms and conditions
125
- for use, reproduction, or distribution of Your modifications, or
126
- for any such Derivative Works as a whole, provided Your use,
127
- reproduction, and distribution of the Work otherwise complies with
128
- the conditions stated in this License.
129
-
130
- 5. Submission of Contributions. Unless You explicitly state otherwise,
131
- any Contribution intentionally submitted for inclusion in the Work
132
- by You to the Licensor shall be under the terms and conditions of
133
- this License, without any additional terms or conditions.
134
- Notwithstanding the above, nothing herein shall supersede or modify
135
- the terms of any separate license agreement you may have executed
136
- with Licensor regarding such Contributions.
137
-
138
- 6. Trademarks. This License does not grant permission to use the trade
139
- names, trademarks, service marks, or product names of the Licensor,
140
- except as required for describing the origin of the Work and
141
- reproducing the content of the NOTICE file.
142
-
143
- 7. Disclaimer of Warranty. Unless required by applicable law or
144
- agreed to in writing, Licensor provides the Work (and each
145
- Contributor provides its Contributions) on an "AS IS" BASIS,
146
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
- implied, including, without limitation, any warranties or conditions
148
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
- PARTICULAR PURPOSE. You are solely responsible for determining the
150
- appropriateness of using or redistributing the Work and assume any
151
- risks associated with Your exercise of permissions under this License.
152
-
153
- 8. Limitation of Liability. In no event and under no legal theory,
154
- whether in tort (including negligence), contract, or otherwise,
155
- unless required by applicable law (such as deliberate and grossly
156
- negligent acts) or agreed to in writing, shall any Contributor be
157
- liable to You for damages, including any direct, indirect, special,
158
- incidental, or consequential damages of any character arising as a
159
- result of this License or out of the use or inability to use the
160
- Work (including but not limited to damages for loss of goodwill,
161
- work stoppage, computer failure or malfunction, or any and all
162
- other commercial damages or losses), even if such Contributor
163
- has been advised of the possibility of such damages.
164
-
165
- 9. Accepting Warranty or Support. While redistributing the Work or
166
- Derivative Works thereof, You may choose to offer, and charge a
167
- fee for, acceptance of support, warranty, indemnity, or other
168
- liability obligations and/or rights consistent with this License.
169
- However, in accepting such obligations, You may act only on Your
170
- own behalf and on Your sole responsibility, not on behalf of any
171
- other Contributor, and only if You agree to indemnify, defend,
172
- and hold each Contributor harmless for any liability incurred by,
173
- or claims asserted against, such Contributor by reason of your
174
- accepting any such warranty or support.
175
-
176
- END OF TERMS AND CONDITIONS
177
-
178
- APPENDIX: How to apply the Apache License to your work.
179
-
180
- To apply the Apache License to your work, attach the following
181
- boilerplate notice, with the fields enclosed by brackets "[]"
182
- replaced with your own identifying information. (Don't include
183
- the brackets!) The text should be enclosed in the appropriate
184
- comment syntax for the file format. We also recommend that a
185
- file or class name and description of purpose be included on the
186
- same "printed page" as the copyright notice for easier
187
- identification within third-party archives.
188
-
189
- Copyright 2026 Open Design contributors
190
-
191
- Licensed under the Apache License, Version 2.0 (the "License");
192
- you may not use this file except in compliance with the License.
193
- You may obtain a copy of the License at
194
-
195
- http://www.apache.org/licenses/LICENSE-2.0
196
-
197
- Unless required by applicable law or agreed to in writing, software
198
- distributed under the License is distributed on an "AS IS" BASIS,
199
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
- See the License for the specific language governing permissions and
201
- limitations under the License.