@zackbart/connecta 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/README.md +31 -55
  3. package/SECURITY.md +5 -11
  4. package/dist/activity.d.ts +0 -8
  5. package/dist/activity.d.ts.map +1 -1
  6. package/dist/activity.js +0 -1
  7. package/dist/activity.js.map +1 -1
  8. package/dist/auth/bearer.d.ts +1 -7
  9. package/dist/auth/bearer.d.ts.map +1 -1
  10. package/dist/auth/bearer.js +2 -23
  11. package/dist/auth/bearer.js.map +1 -1
  12. package/dist/auth/clerk.d.ts +2 -11
  13. package/dist/auth/clerk.d.ts.map +1 -1
  14. package/dist/auth/clerk.js +31 -46
  15. package/dist/auth/clerk.js.map +1 -1
  16. package/dist/auth/downstream-oauth.d.ts +15 -6
  17. package/dist/auth/downstream-oauth.d.ts.map +1 -1
  18. package/dist/auth/downstream-oauth.js +60 -11
  19. package/dist/auth/downstream-oauth.js.map +1 -1
  20. package/dist/call-admission.d.ts.map +1 -1
  21. package/dist/call-admission.js +0 -1
  22. package/dist/call-admission.js.map +1 -1
  23. package/dist/catalog-service.d.ts +1 -2
  24. package/dist/catalog-service.d.ts.map +1 -1
  25. package/dist/catalog-service.js +12 -18
  26. package/dist/catalog-service.js.map +1 -1
  27. package/dist/catalog.d.ts +6 -0
  28. package/dist/catalog.d.ts.map +1 -1
  29. package/dist/catalog.js +51 -0
  30. package/dist/catalog.js.map +1 -1
  31. package/dist/connectors/remote-mcp.d.ts +1 -1
  32. package/dist/connectors/remote-mcp.d.ts.map +1 -1
  33. package/dist/connectors/remote-mcp.js +73 -71
  34. package/dist/connectors/remote-mcp.js.map +1 -1
  35. package/dist/errors.d.ts +19 -1
  36. package/dist/errors.d.ts.map +1 -1
  37. package/dist/errors.js +1 -0
  38. package/dist/errors.js.map +1 -1
  39. package/dist/execute.d.ts +4 -9
  40. package/dist/execute.d.ts.map +1 -1
  41. package/dist/execute.js +41 -20
  42. package/dist/execute.js.map +1 -1
  43. package/dist/executor-result.js +1 -1
  44. package/dist/executor-result.js.map +1 -1
  45. package/dist/index.d.ts +3 -82
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +17 -90
  48. package/dist/index.js.map +1 -1
  49. package/dist/invocation.d.ts +5 -0
  50. package/dist/invocation.d.ts.map +1 -1
  51. package/dist/invocation.js +46 -10
  52. package/dist/invocation.js.map +1 -1
  53. package/dist/meta-tools.d.ts +4 -12
  54. package/dist/meta-tools.d.ts.map +1 -1
  55. package/dist/meta-tools.js +119 -169
  56. package/dist/meta-tools.js.map +1 -1
  57. package/dist/operator-ui/generated.d.ts +2 -2
  58. package/dist/operator-ui/generated.d.ts.map +1 -1
  59. package/dist/operator-ui/generated.js +2 -2
  60. package/dist/operator-ui/generated.js.map +1 -1
  61. package/dist/operator-ui/model.d.ts +1 -22
  62. package/dist/operator-ui/model.d.ts.map +1 -1
  63. package/dist/operator-ui/model.js.map +1 -1
  64. package/dist/registry.d.ts +11 -178
  65. package/dist/registry.d.ts.map +1 -1
  66. package/dist/registry.js +52 -330
  67. package/dist/registry.js.map +1 -1
  68. package/dist/retired-toolkits.d.ts +3 -0
  69. package/dist/retired-toolkits.d.ts.map +1 -0
  70. package/dist/retired-toolkits.js +9 -0
  71. package/dist/retired-toolkits.js.map +1 -0
  72. package/dist/routes/activity.d.ts.map +1 -1
  73. package/dist/routes/activity.js +2 -5
  74. package/dist/routes/activity.js.map +1 -1
  75. package/dist/routes/credentials.d.ts.map +1 -1
  76. package/dist/routes/credentials.js +1 -12
  77. package/dist/routes/credentials.js.map +1 -1
  78. package/dist/routes/mcp.d.ts.map +1 -1
  79. package/dist/routes/mcp.js +94 -188
  80. package/dist/routes/mcp.js.map +1 -1
  81. package/dist/routes/oauth.d.ts.map +1 -1
  82. package/dist/routes/oauth.js +3 -8
  83. package/dist/routes/oauth.js.map +1 -1
  84. package/dist/routes/shared.d.ts +9 -30
  85. package/dist/routes/shared.d.ts.map +1 -1
  86. package/dist/routes/shared.js +10 -69
  87. package/dist/routes/shared.js.map +1 -1
  88. package/dist/routes/ui.d.ts.map +1 -1
  89. package/dist/routes/ui.js +4 -10
  90. package/dist/routes/ui.js.map +1 -1
  91. package/dist/server.d.ts.map +1 -1
  92. package/dist/server.js +1 -31
  93. package/dist/server.js.map +1 -1
  94. package/dist/skills.d.ts +3 -6
  95. package/dist/skills.d.ts.map +1 -1
  96. package/dist/skills.js +9 -38
  97. package/dist/skills.js.map +1 -1
  98. package/dist/timeout.d.ts.map +1 -1
  99. package/dist/timeout.js +2 -4
  100. package/dist/timeout.js.map +1 -1
  101. package/dist/types.d.ts +8 -61
  102. package/dist/types.d.ts.map +1 -1
  103. package/dist/ui.d.ts +1 -2
  104. package/dist/ui.d.ts.map +1 -1
  105. package/dist/ui.js +5 -35
  106. package/dist/ui.js.map +1 -1
  107. package/dist/version.d.ts +1 -1
  108. package/dist/version.js +1 -1
  109. package/package.json +3 -2
  110. package/src/activity.ts +0 -9
  111. package/src/auth/bearer.ts +3 -32
  112. package/src/auth/clerk.ts +35 -48
  113. package/src/auth/downstream-oauth.ts +106 -24
  114. package/src/call-admission.ts +0 -1
  115. package/src/catalog-service.ts +23 -23
  116. package/src/catalog.ts +55 -0
  117. package/src/connectors/remote-mcp.ts +106 -86
  118. package/src/errors.ts +22 -0
  119. package/src/execute.ts +43 -24
  120. package/src/executor-result.ts +1 -1
  121. package/src/index.ts +24 -208
  122. package/src/invocation.ts +63 -10
  123. package/src/meta-tools.ts +139 -187
  124. package/src/operator-ui/browser.css +1 -54
  125. package/src/operator-ui/browser.ts +16 -150
  126. package/src/operator-ui/generated.ts +2 -2
  127. package/src/operator-ui/model.ts +1 -23
  128. package/src/registry.ts +59 -429
  129. package/src/retired-toolkits.ts +14 -0
  130. package/src/routes/activity.ts +1 -6
  131. package/src/routes/credentials.ts +0 -12
  132. package/src/routes/mcp.ts +110 -230
  133. package/src/routes/oauth.ts +2 -8
  134. package/src/routes/shared.ts +10 -100
  135. package/src/routes/ui.ts +2 -12
  136. package/src/server.ts +1 -31
  137. package/src/skills.ts +9 -38
  138. package/src/timeout.ts +2 -4
  139. package/src/types.ts +11 -62
  140. package/src/ui.ts +9 -46
  141. package/src/version.ts +1 -1
  142. package/dist/credential-health.d.ts +0 -205
  143. package/dist/credential-health.d.ts.map +0 -1
  144. package/dist/credential-health.js +0 -610
  145. package/dist/credential-health.js.map +0 -1
  146. package/dist/toolkits.d.ts +0 -124
  147. package/dist/toolkits.d.ts.map +0 -1
  148. package/dist/toolkits.js +0 -322
  149. package/dist/toolkits.js.map +0 -1
  150. package/src/credential-health.ts +0 -835
  151. package/src/toolkits.ts +0 -461
package/CHANGELOG.md CHANGED
@@ -2,6 +2,134 @@
2
2
 
3
3
  All notable changes to this package are documented here.
4
4
 
5
+ ## 0.9.0 — 2026-07-29
6
+
7
+ Connecta now speaks the 2026-07-28 MCP revision on both sides while retaining
8
+ its legacy compatibility floor (#176). Nothing breaks for deployments:
9
+ Connecta's exports, configuration, connector definitions, meta-tool surface,
10
+ and its own stateless `/mcp` behavior are unchanged. Deployments can ignore the
11
+ wire revision entirely unless they imported or pinned transitive MCP SDK
12
+ internals; those internals moved from the v1 monolith to the exact-pinned v2
13
+ client and server packages.
14
+
15
+ This is alignment and compatibility work, not a state-management rewrite. The
16
+ new spec arrived at Connecta's existing stateless server design. Modern clients
17
+ now negotiate without `initialize`, while legacy clients remain served.
18
+ Stateful legacy *downstreams* still require Connecta's explicit session DELETE:
19
+ tests confirm SDK v2 client close does not make it redundant.
20
+
21
+ ### Added
22
+
23
+ - **Modern/legacy version negotiation and cache metadata.** Modern
24
+ `tools/list` results declare a one-hour private cache lifetime; the legacy
25
+ initialize path and session headers remain supported.
26
+ - **Issuer-bound downstream OAuth storage.** Registrations and tokens are
27
+ stored with the validated authorization-server issuer. A changed issuer
28
+ advances the existing generation fence before the SDK starts a fresh grant;
29
+ pre-upgrade credentials bind in place on their first validated read.
30
+ - **A complete in-repo disposition of the revision** in
31
+ [`documentation/mcp-2026-07-28.md`](./documentation/mcp-2026-07-28.md),
32
+ including the declined and gated surfaces.
33
+
34
+ ### Changed
35
+
36
+ - **Downstream multi-round-trip results fail loudly instead of being
37
+ misread as complete.** `call_tool`, `batch_call`, and the `execute_code` host
38
+ boundary preserve the non-retryable `input_required_unsupported` code.
39
+ Passthrough remains gated until a real host and downstream establish the
40
+ resumed-call contract.
41
+ - **Browser CORS allows the modern `Mcp-Method` and `Mcp-Name` request
42
+ headers.**
43
+ - **JSON Schema 2020-12 compatibility is pinned by exotic-keyword discovery
44
+ and validation coverage.**
45
+
46
+ ## 0.8.1 — 2026-07-29
47
+
48
+ 0.8.1 hardens agent routing, response efficiency, and credential recovery while
49
+ making deployment boundaries the audience-scoping model. It removes toolkits
50
+ and proactive credential liveness probing: deployments still using either
51
+ retired configuration must migrate, and stale configuration fails at startup
52
+ instead of silently widening access. Deployments that use neither retired
53
+ feature need no configuration or storage migration; orphaned credential-health
54
+ records and old toolkit columns can remain unused.
55
+
56
+ Against the pre-0.8.1 release-audit baseline, all 21 task scenarios still pass,
57
+ discovery remains at 89.7% top-1 accuracy and 100% positive/default-page recall,
58
+ and discovery mean precision improves from 46.4% to 73.5%. The same 55 round
59
+ trips take 225.6 ms versus 228.4 ms of summed local-call latency (effectively
60
+ flat). Definition tokens move from 2,164 to 2,174 and request tokens from 1,144
61
+ to 1,145, while response tokens fall from 68,765 to 16,343 (-76.2%) and the
62
+ complete measured surface falls from 72,073 to 19,662 tokens (-72.7%).
63
+
64
+ ### Added
65
+
66
+ - **A current-version release audit and independently authored discovery
67
+ holdout** (#189). It exercises every meta-tool, destructive routing, OAuth
68
+ and static-credential recovery, result paging, client compatibility, and the
69
+ payload-free activity invariant on Node 20 and 22. Its evidence stays under
70
+ `eval/` and is excluded from the published package.
71
+
72
+ ### Changed
73
+
74
+ - **Lexical discovery ignores conservative conversational framing and defaults
75
+ to eight results instead of 25** (#190). Action terms such as `get`, `list`,
76
+ `search`, `find`, and `create` remain significant; cleanup that removes every
77
+ term falls back to the original query. Explicit `limit` still supports up to
78
+ 100 results, and `total`, `hasMore`, and `nextOffset` preserve complete
79
+ pagination. On the holdout, mean results fall from 14.0 to 2.853 and negative
80
+ false positives from 80% to 20%, without losing positive or default-page
81
+ recall.
82
+ - **`execute_code` is advertised only with a configured live executor** (#193).
83
+ The existing capability boundary is now explicit in instructions,
84
+ documentation, and regression coverage: deployments without code mode expose
85
+ the nine base meta-tools; deployments with it expose ten.
86
+ - **The `usage` guide is slimmer and fetched on demand** (#194). The
87
+ `skills` meta-tool and per-connector guide delivery remain unchanged, while
88
+ the generic guide drops redundant examples and keeps only routing, probe,
89
+ recovery, and code-mode rules. Server instructions now recommend fetching it
90
+ when the routing workflow is unfamiliar instead of once per task.
91
+ - **Structured results now serialize compactly in text compatibility content**
92
+ (#191). `structuredContent` remains the canonical full-fidelity object and
93
+ `content` remains complete JSON for text-only clients, but indentation no
94
+ longer inflates discovery, call, paging, batch, authorization, or code-mode
95
+ responses. Replacing the compatibility copy with a summary remains deferred
96
+ until host-forwarding measurements justify departing from MCP's compatibility
97
+ guidance.
98
+ - **Credential recovery has one agent-facing route** (#192).
99
+ `auth_required` errors now name the connector, failed operation, recovery
100
+ class, `authorize_connector` call, operator handoff, and retry. Calling
101
+ `authorize_connector` returns `recovery: "oauth"`, `"operator_config"`, or
102
+ `"unavailable"`; static handoffs expose only declared field names and
103
+ guidance plus the Clerk-protected `/credentials` URL, never credential
104
+ values. A missing `credentials.encryptionKey` now boots with an explicit
105
+ unavailable recovery state instead of preventing the deployment from
106
+ explaining the problem.
107
+ - **Toolkits are removed** (#178). `ConnectaConfig.toolkits`, toolkit bindings
108
+ on `bearerToken` and `clerkAuth`, `?toolkit=` routing, scoped registries, and
109
+ the operator UI's toolkit projection no longer exist. Passing `toolkits` or
110
+ `unscoped` to any of those construction surfaces throws instead of silently
111
+ widening access, and an `/mcp` request still carrying `?toolkit=` — a URL
112
+ minted before the retirement — gets an explicit 404 naming #178, never a
113
+ silent widening to the full registry.
114
+ - **Activity events no longer carry `toolkitId`.** The Worker D1 example drops
115
+ its `toolkit_id` column; existing columns may be left in place unused.
116
+ - **Proactive credential liveness is removed** (#179), reverting the feature
117
+ introduced in #24. `credentials.health`, legacy `credentialHealth`,
118
+ `Connecta.checkCredentials`, scheduled sweep wiring, persisted verdict reads
119
+ and writes, and `credentialCheck` response/UI fields no longer exist.
120
+ Operator-triggered credential tests and local stored-shape drift detection
121
+ remain. A drifted connector now reports `auth_required` directly from the
122
+ drift check — `list_connectors` with `probe: true` and `/ui/data` no longer
123
+ live-probe a connector whose stored credential cannot be consumed anyway.
124
+ Existing `credhealth:*` KV records are harmless orphaned data: they are
125
+ never read or rewritten, and no cleanup migration runs.
126
+
127
+ ### Fixed
128
+
129
+ - **Missing credential-vault configuration now fails at use with a typed,
130
+ actionable recovery envelope** (#192) instead of preventing the deployment
131
+ from starting before an agent or operator can diagnose it.
132
+
5
133
  ## 0.8.0 — 2026-07-28
6
134
 
7
135
  0.8.0 is consolidation before capability growth (#157): the semantics that were
package/README.md CHANGED
@@ -6,23 +6,16 @@ One MCP endpoint in front of every integration you've deliberately chosen.
6
6
  Agents see a handful of meta-tools instead of hundreds of definitions, and each
7
7
  client is configured once instead of once per integration.
8
8
 
9
- ## The problem
10
-
11
- An agent connected to N MCP servers pays for all N before it does anything:
12
- every server's full tool list lands in the context window at connect time,
13
- nearly all of it irrelevant to the task at hand. The second cost is
14
- configuration — every client has to be pointed at every server separately,
15
- each with its own auth, and rotating one token means finding every place it
16
- was pasted.
17
-
18
9
  ## What connecta is
19
10
 
20
- One MCP endpoint you deploy a Cloudflare Worker or a Node process in a
21
- Docker stack, same code either way aggregating your downstream connectors
22
- behind a small, fixed set of meta-tools. A connector is either a remote MCP
23
- server that connecta proxies, or a plain HTTP API with hand-written tool
24
- definitions and a fetch handler. Both come out identical: same two-segment
25
- addresses (`<connectorId>.<toolName>`), same catalog, same safety rules.
11
+ An agent connected to N MCP servers pays for all N before it does anything:
12
+ every server's full tool list lands in the context window at connect time, and
13
+ every client is pointed at every server separately, each with its own auth.
14
+ Connecta is one endpoint you deploy instead — a Cloudflare Worker or a Node
15
+ process, same code either way aggregating your connectors behind nine
16
+ meta-tools. A connector is a remote MCP server connecta proxies or a plain
17
+ HTTP API with hand-written tool definitions; both come out identical,
18
+ addressed as `<connectorId>.<toolName>`.
26
19
 
27
20
  ```
28
21
  ┌── remoteMcp("notion") → mcp.notion.com
@@ -31,30 +24,22 @@ Claude / Cursor ── MCP ──▶ connecta ───┼── remoteMcp("lin
31
24
  └── api("internal") → fetch(...)
32
25
  ```
33
26
 
34
- Rather than receiving every tool up front, the agent discovers what it needs:
35
- `search_tools` ranks matches, `describe_tools` returns schemas for only the
36
- addresses about to be called, and `call_tool` / `batch_call` /
37
- `call_destructive_tool` invoke them by address. `list_connectors` reports what
38
- exists, `authorize_connector` starts a downstream OAuth flow, `get_result`
39
- pages through oversized results, and `skills` hands the model a short guide to
40
- the rest. The agent's context holds nine tool definitions whether ten tools
41
- sit behind them or a thousand.
42
-
43
- An optional tenth, `execute_code`, runs model-written JavaScript in a sandbox
44
- with no network, filesystem, or environment access — only the explicitly
45
- read-only tools as callable globals — turning a loop or a cross-connector join
46
- into one round trip. Configure no executor and connecta is exactly the
47
- nine-tool server.
27
+ The agent discovers instead of preloading: `search_tools` ranks matches,
28
+ `describe_tools` returns schemas for only the addresses about to be called,
29
+ `call_tool` / `batch_call` / `call_destructive_tool` invoke them, and
30
+ `list_connectors`, `authorize_connector`, `get_result`, and `skills` round out
31
+ the nine. An optional tenth, `execute_code`, runs model-written JavaScript in
32
+ a sandbox with no network, filesystem, or environment access only the
33
+ read-only tools in scope. Context holds nine definitions whether ten tools sit
34
+ behind them or a thousand.
48
35
 
49
36
  Three properties are load-bearing enough to name here; the rest live in the
50
- [ethos](./ethos.md). **Read-only is fail-closed**: only tools explicitly
51
- annotated read-only are reachable through `call_tool`, `batch_call`, and the
52
- sandbox everything else crosses `call_destructive_tool`, which is annotated
53
- so the MCP host can ask a human. **Credentials stay server-side**: downstream
54
- tokens live in an encrypted vault, rotated from an operator page rather than a
55
- redeploy, and no surface ever returns a secret. **Config is code**: adding a
56
- connector is an edit and a deploy — no registration API, no admin UI, one
57
- small file you can review in a pull request.
37
+ [ethos](./ethos.md). **Read-only is fail-closed**: anything not explicitly
38
+ annotated read-only crosses `call_destructive_tool`, which is annotated so the
39
+ MCP host can ask a human. **Credentials stay server-side**: an encrypted
40
+ vault, rotated from an operator page, and no surface ever returns a secret.
41
+ **Config is code**: adding a connector is an edit and a deploy you can review
42
+ in a pull request.
58
43
 
59
44
  ## Getting started
60
45
 
@@ -97,18 +82,12 @@ Point an MCP client at `http://localhost:8787/mcp` with an
97
82
  `search_tools`.
98
83
 
99
84
  Runnable deployments live in
100
- [`examples/`](https://github.com/zackbart/connecta/tree/main/examples):
101
- [`worker/`](https://github.com/zackbart/connecta/tree/main/examples/worker) is
102
- a free-tier-compatible Cloudflare Worker with KV and D1 adapters and the
103
- template to copy for a real deployment;
104
- [`node/`](https://github.com/zackbart/connecta/tree/main/examples/node) extends
105
- the server above;
106
- [`docker/`](https://github.com/zackbart/connecta/tree/main/examples/docker) is
107
- a single-service compose stack. Anything beyond the core is installed only by
108
- the deployments that use it — `@clerk/backend` and `quickjs-emscripten` are
109
- optional peers behind the `/auth/clerk` and `/quickjs` subpaths — and connecta
110
- ships no service-specific connectors: endpoint, credential, and tool choices
111
- stay in your project, declared with `remoteMcp()` and `api()`.
85
+ [`examples/`](https://github.com/zackbart/connecta/tree/main/examples): a
86
+ free-tier-compatible Cloudflare Worker with KV and D1 adapters, a Node server
87
+ extending the one above, and a single-service Docker compose stack.
88
+ Heavyweight extras are optional peers behind subpaths (`/auth/clerk`,
89
+ `/quickjs`), and connecta ships no service-specific connectors — endpoint,
90
+ credential, and tool choices stay in your project.
112
91
 
113
92
  A candid note on maturity: connecta is built for its author's deployments
114
93
  first and published openly. Breaking changes are cheap and the version number
@@ -117,12 +96,9 @@ signals change, not stability — the [ethos](./ethos.md) says so on purpose.
117
96
  ## Learn more
118
97
 
119
98
  - **[ethos.md](./ethos.md)** — what this is, what it refuses to be, the
120
- decisions table, and the invariants every change must preserve. Read this
121
- before proposing anything.
122
- - **[documentation/](./documentation/)** per-subsystem guides. Currently
123
- stubs: the old manual was retired during the phase-1 docs restructure and
124
- each guide is being rewritten as the ideas settle; prior text lives in git
125
- history.
99
+ decisions table, and the invariants. Read it before proposing anything.
100
+ - **[documentation/](./documentation/)** — per-subsystem guides (currently
101
+ stubs; the prior manual lives in git history).
126
102
  - **[CHANGELOG](./CHANGELOG.md)** — what changed in each release.
127
103
  - **[SECURITY](./SECURITY.md)** — supported versions and how to report a
128
104
  vulnerability.
package/SECURITY.md CHANGED
@@ -16,14 +16,8 @@ CI blocks moderate, high, and critical production dependency advisories. Lower
16
16
  findings are reviewed for reachability and recorded when an upstream package has
17
17
  not yet released a compatible fix.
18
18
 
19
- `@modelcontextprotocol/sdk@1.29.0` declares `@hono/node-server` 1.x, which is
20
- covered by `GHSA-frvp-7c67-39w9`. The advisory affects Hono's Windows
21
- `serve-static` implementation. Connecta does not import that adapter or serve
22
- static files through Hono. npm's suggested fix downgrades the MCP SDK below
23
- security behavior Connecta relies on, so the package instead pins
24
- `@hono/node-server` to 2.x through an `overrides` entry and keeps SDK 1.29.0.
25
-
26
- Because npm only applies `overrides` to the root project, that pin governs this
27
- repository's own installs rather than trees built by consumers of the published
28
- package. The override is removed once the SDK declares `@hono/node-server` ^2
29
- upstream.
19
+ The MCP TypeScript SDK 2.x packages are exact-pinned. The split client and
20
+ server packages no longer install Hono or `@hono/node-server`, so the temporary
21
+ root-project override used with SDK 1.x is gone. A dependency bump must pass
22
+ both `npm run release:check` and the Node/Workers runtime suites before the pin
23
+ moves.
@@ -40,12 +40,6 @@ export interface ToolCallActivityEvent {
40
40
  serverName: string;
41
41
  serverVersion: string;
42
42
  deploymentId?: string;
43
- /**
44
- * Name of the toolkit this connection selected with `?toolkit=`, when it
45
- * selected one. Calls are recorded the same way with or without it; this only
46
- * says which scoped view the call came through.
47
- */
48
- toolkitId?: string;
49
43
  }
50
44
  export interface ActivityPage {
51
45
  events: ToolCallActivityEvent[];
@@ -92,8 +86,6 @@ export interface ActivityRequestContext {
92
86
  version: string;
93
87
  };
94
88
  deploymentId?: string;
95
- /** Toolkit this connection is scoped to, when `?toolkit=` selected one. */
96
- toolkitId?: string;
97
89
  defer?: (promise: Promise<unknown>) => void;
98
90
  logger: Logger;
99
91
  }
@@ -1 +1 @@
1
- {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"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"}
package/dist/activity.js CHANGED
@@ -32,7 +32,6 @@ export function recordToolActivity(context, input) {
32
32
  ...(context.deploymentId
33
33
  ? { deploymentId: context.deploymentId }
34
34
  : {}),
35
- ...(context.toolkitId ? { toolkitId: context.toolkitId } : {}),
36
35
  };
37
36
  try {
38
37
  const result = context.sink.record(event);
@@ -1 +1 @@
1
- {"version":3,"file":"activity.js","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"AA+FA,iFAAiF;AACjF,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAC1C,IAAI,GAAG,4BAA4B,CAAC;IAE7C;QACE,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACnC,CAAC;CACF;AA+BD;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAA2C,EAC3C,KAAyB;IAEzB,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,MAAM,KAAK,GAA0B;QACnC,aAAa,EAAE,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACrD,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACjD,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI;QACnC,aAAa,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO;QACzC,GAAG,CAAC,OAAO,CAAC,YAAY;YACtB,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE;YACxC,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/D,CAAC;IACF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,IAAI,OAAQ,MAA2B,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACvE,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACtD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,KAAK;YAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;IAClE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"activity.js","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"AAyFA,iFAAiF;AACjF,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAC1C,IAAI,GAAG,4BAA4B,CAAC;IAE7C;QACE,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACnC,CAAC;CACF;AA6BD;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAA2C,EAC3C,KAAyB;IAEzB,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,MAAM,KAAK,GAA0B;QACnC,aAAa,EAAE,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACrD,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACjD,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI;QACnC,aAAa,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO;QACzC,GAAG,CAAC,OAAO,CAAC,YAAY;YACtB,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE;YACxC,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;IACF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,IAAI,OAAQ,MAA2B,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACvE,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACtD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,KAAK;YAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;IAClE,CAAC;AACH,CAAC"}
@@ -1,6 +1,5 @@
1
- import { type ToolkitBindingOptions } from "../toolkits.js";
2
1
  import type { InboundAuth } from "../types.js";
3
- export interface BearerTokenOptions extends ToolkitBindingOptions {
2
+ export interface BearerTokenOptions {
4
3
  /** Stable identity for this credential, used on activity events. */
5
4
  subjectId?: string;
6
5
  }
@@ -8,11 +7,6 @@ export interface BearerTokenOptions extends ToolkitBindingOptions {
8
7
  * Static bearer-token inbound auth. Constant-time compares the Bearer token
9
8
  * against `secret`. Checked BEFORE the Clerk gate in the server; a mismatch
10
9
  * falls through so a co-configured Clerk provider can still admit the request.
11
- *
12
- * `toolkits` binds the token to named toolkits (documentation/toolkits.md): one
13
- * `bearerToken(...)` per team credential, each naming the view that team may
14
- * open. Omit it and the token stays unbound — every declared toolkit plus the
15
- * full registry.
16
10
  */
17
11
  export declare function bearerToken(secret: string, options?: BearerTokenOptions): InboundAuth;
18
12
  //# sourceMappingURL=bearer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bearer.d.ts","sourceRoot":"","sources":["../../src/auth/bearer.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,aAAa,CAAC;AAiB3D,MAAM,WAAW,kBAAmB,SAAQ,qBAAqB;IAC/D,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,kBAAuB,GAC/B,WAAW,CAkDb"}
1
+ {"version":3,"file":"bearer.d.ts","sourceRoot":"","sources":["../../src/auth/bearer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,aAAa,CAAC;AAiB3D,MAAM,WAAW,kBAAkB;IACjC,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,kBAAuB,GAC/B,WAAW,CA6Bb"}
@@ -1,4 +1,4 @@
1
- import { resolveToolkitBinding, } from "../toolkits.js";
1
+ import { assertNoRetiredToolkitOptions } from "../retired-toolkits.js";
2
2
  const encoder = new TextEncoder();
3
3
  /** Constant-time byte comparison. Differing lengths still iterate to reduce leak. */
4
4
  function timingSafeEqual(a, b) {
@@ -18,33 +18,12 @@ function timingSafeEqual(a, b) {
18
18
  * Static bearer-token inbound auth. Constant-time compares the Bearer token
19
19
  * against `secret`. Checked BEFORE the Clerk gate in the server; a mismatch
20
20
  * falls through so a co-configured Clerk provider can still admit the request.
21
- *
22
- * `toolkits` binds the token to named toolkits (documentation/toolkits.md): one
23
- * `bearerToken(...)` per team credential, each naming the view that team may
24
- * open. Omit it and the token stays unbound — every declared toolkit plus the
25
- * full registry.
26
21
  */
27
22
  export function bearerToken(secret, options = {}) {
23
+ assertNoRetiredToolkitOptions("bearerToken", options);
28
24
  const secretBytes = encoder.encode(secret);
29
- const toolkitBinding = resolveToolkitBinding(options.subjectId
30
- ? `bearerToken (subjectId "${options.subjectId}")`
31
- : "bearerToken", options);
32
- if (toolkitBinding && !options.subjectId) {
33
- // A bound token stands for one team, and both surfaces that report on it —
34
- // the 403 refusal log (documentation/toolkits.md) and activity events
35
- // (documentation/operator-ui.md) — can only say "bearer" without a subjectId. With
36
- // several bound tokens that makes an operator unable to tell which
37
- // credential was refused, or whose call succeeded. console.warn (as the
38
- // Clerk adapter does) because an adapter is constructed before
39
- // `createConnecta` has a logger to hand it.
40
- console.warn("[connecta] bearerToken is bound to toolkits " +
41
- `(${toolkitBinding.toolkits.join(", ") || "unscoped only"}) but has no ` +
42
- "subjectId: refusal logs and activity events cannot say which " +
43
- "credential they came from. Pass { subjectId: \"<team>\" }.");
44
- }
45
25
  return {
46
26
  kind: "bearer",
47
- ...(toolkitBinding ? { toolkitBinding } : {}),
48
27
  authorize(request) {
49
28
  const header = request.headers.get("authorization") ?? "";
50
29
  const match = /^Bearer\s+(.+)$/i.exec(header);
@@ -1 +1 @@
1
- {"version":3,"file":"bearer.js","sourceRoot":"","sources":["../../src/auth/bearer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bearer.js","sourceRoot":"","sources":["../../src/auth/bearer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,wBAAwB,CAAC;AAGvE,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAElC,qFAAqF;AACrF,SAAS,eAAe,CAAC,CAAa,EAAE,CAAa;IACnD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3D,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC;AAOD;;;;GAIG;AACH,MAAM,UAAU,WAAW,CACzB,MAAc,EACd,UAA8B,EAAE;IAEhC,6BAA6B,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACtD,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3C,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,SAAS,CAAC,OAAO;YACf,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;YAC1D,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC9C,IAAI,KAAK,IAAI,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC;gBACpE,OAAO;oBACL,EAAE,EAAE,IAAI;oBACR,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC/D,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,QAAQ,EAAE,IAAI,QAAQ,CACpB,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,EACzC;oBACE,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE;wBACP,cAAc,EAAE,kBAAkB;wBAClC,kBAAkB,EAAE,QAAQ;qBAC7B;iBACF,CACF;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,8 +1,7 @@
1
1
  import { createClerkClient } from "@clerk/backend";
2
- import { type ToolkitBindingOptions } from "../toolkits.js";
3
2
  import type { InboundAuth } from "../types.js";
4
3
  type ClerkClient = ReturnType<typeof createClerkClient>;
5
- export interface ClerkAuthOptions extends ToolkitBindingOptions {
4
+ export interface ClerkAuthOptions {
6
5
  publishableKey: string;
7
6
  secretKey: string;
8
7
  /** Public base URL of this deployment. Defaults to the request origin. */
@@ -31,15 +30,7 @@ export interface ClerkAuthOptions extends ToolkitBindingOptions {
31
30
  /**
32
31
  * Clerk inbound auth.
33
32
  *
34
- * `allowedDomains` and `gate` decide WHO is admitted (both must pass);
35
- * `toolkits` decides WHICH view the admitted user gets.
36
- *
37
- * `toolkits` binds every user this provider admits to those toolkits
38
- * (documentation/toolkits.md). For a per-team split, configure one `clerkAuth(...)` per
39
- * team — the same keys, a `gate` naming that team's users, and that team's
40
- * `toolkits`. The server tries providers in order and the first that admits the
41
- * user supplies the binding, so a user one gate rejects falls through to the
42
- * next.
33
+ * `allowedDomains` and `gate` decide who is admitted; both must pass.
43
34
  */
44
35
  export declare function clerkAuth(opts: ClerkAuthOptions): InboundAuth;
45
36
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"clerk.d.ts","sourceRoot":"","sources":["../../src/auth/clerk.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,aAAa,CAAC;AAE3D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAGxD,MAAM,WAAW,gBAAiB,SAAQ,qBAAqB;IAC7D,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,8EAA8E;IAC9E,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1E,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,0FAA0F;IAC1F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0FAA0F;IAC1F,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8KD;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,WAAW,CAmV7D"}
1
+ {"version":3,"file":"clerk.d.ts","sourceRoot":"","sources":["../../src/auth/clerk.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,aAAa,CAAC;AAE3D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAGxD,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,8EAA8E;IAC9E,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1E,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,0FAA0F;IAC1F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0FAA0F;IAC1F,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsMD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,WAAW,CAyT7D"}
@@ -2,7 +2,7 @@
2
2
  // Single tenant, no tenant-tag requirement, optional allowedDomains/gate() with
3
3
  // ~60s identity caching.
4
4
  import { createClerkClient } from "@clerk/backend";
5
- import { resolveToolkitBinding, } from "../toolkits.js";
5
+ import { assertNoRetiredToolkitOptions } from "../retired-toolkits.js";
6
6
  const CORS_HEADERS = {
7
7
  "Access-Control-Allow-Origin": "*",
8
8
  "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
@@ -38,6 +38,25 @@ const ACTIVITY_LABEL_MAX_IN_FLIGHT = 8;
38
38
  // identities define the isolate's lifetime memory footprint.
39
39
  const GATE_CACHE_MAX_IDENTITIES = 1_024;
40
40
  const ACTIVITY_LABEL_MAX_LENGTH = 160;
41
+ function readIdentityCache(cache, key) {
42
+ const hit = cache.get(key);
43
+ if (!hit)
44
+ return undefined;
45
+ cache.delete(key);
46
+ if (Date.now() >= hit.exp)
47
+ return undefined;
48
+ cache.set(key, hit);
49
+ return hit;
50
+ }
51
+ function writeIdentityCache(cache, key, value) {
52
+ cache.delete(key);
53
+ cache.set(key, value);
54
+ if (cache.size <= GATE_CACHE_MAX_IDENTITIES)
55
+ return;
56
+ const oldest = cache.keys().next();
57
+ if (!oldest.done)
58
+ cache.delete(oldest.value);
59
+ }
41
60
  function cleanActivityLabel(value) {
42
61
  if (!value)
43
62
  return undefined;
@@ -119,7 +138,7 @@ function normalizeAllowedDomains(value) {
119
138
  }
120
139
  /**
121
140
  * Bounded, escaped form of the denied domain for the operator log — the same
122
- * treatment `src/server.ts` gives a rejected toolkit name. An email domain is
141
+ * treatment server logs give other caller-controlled values. An email domain is
123
142
  * caller-influenced (anyone who controls a mailbox controls its domain): the
124
143
  * bound is what a 253-byte domain needs, and the escaping — JSON.stringify plus
125
144
  * the hand-rolled U+2028/U+2029 pass it leaves raw — is defense in depth behind
@@ -152,22 +171,14 @@ function emailDomain(email) {
152
171
  /**
153
172
  * Clerk inbound auth.
154
173
  *
155
- * `allowedDomains` and `gate` decide WHO is admitted (both must pass);
156
- * `toolkits` decides WHICH view the admitted user gets.
157
- *
158
- * `toolkits` binds every user this provider admits to those toolkits
159
- * (documentation/toolkits.md). For a per-team split, configure one `clerkAuth(...)` per
160
- * team — the same keys, a `gate` naming that team's users, and that team's
161
- * `toolkits`. The server tries providers in order and the first that admits the
162
- * user supplies the binding, so a user one gate rejects falls through to the
163
- * next.
174
+ * `allowedDomains` and `gate` decide who is admitted; both must pass.
164
175
  */
165
176
  export function clerkAuth(opts) {
177
+ assertNoRetiredToolkitOptions("clerkAuth", opts);
166
178
  const clerk = createClerkClient({
167
179
  secretKey: opts.secretKey,
168
180
  publishableKey: opts.publishableKey,
169
181
  });
170
- const toolkitBinding = resolveToolkitBinding("clerkAuth", opts);
171
182
  const allowedDomains = normalizeAllowedDomains(opts.allowedDomains);
172
183
  const scopes = opts.scopes ?? ["openid", "profile", "email"];
173
184
  const gateCache = new Map();
@@ -177,28 +188,16 @@ export function clerkAuth(opts) {
177
188
  let activeActivityLabelLookups = 0;
178
189
  const resolveBase = (baseUrl) => opts.publicUrl ?? baseUrl;
179
190
  const cacheActivityLabel = (userId, label) => {
180
- activityLabelCache.delete(userId);
181
- activityLabelCache.set(userId, {
191
+ writeIdentityCache(activityLabelCache, userId, {
182
192
  ...(label ? { label } : {}),
183
193
  exp: Date.now() +
184
194
  (label ? ACTIVITY_LABEL_TTL_MS : ACTIVITY_LABEL_MISS_TTL_MS),
185
195
  });
186
- if (activityLabelCache.size > GATE_CACHE_MAX_IDENTITIES) {
187
- const oldest = activityLabelCache.keys().next();
188
- if (!oldest.done)
189
- activityLabelCache.delete(oldest.value);
190
- }
191
196
  };
192
197
  const resolveActivityLabel = async (userId) => {
193
- const cached = activityLabelCache.get(userId);
194
- if (cached) {
195
- if (Date.now() < cached.exp) {
196
- activityLabelCache.delete(userId);
197
- activityLabelCache.set(userId, cached);
198
- return cached.label;
199
- }
200
- activityLabelCache.delete(userId);
201
- }
198
+ const cached = readIdentityCache(activityLabelCache, userId);
199
+ if (cached)
200
+ return cached.label;
202
201
  const existing = pendingActivityLabels.get(userId);
203
202
  if (existing)
204
203
  return existing;
@@ -309,17 +308,9 @@ export function clerkAuth(opts) {
309
308
  const checkGate = async (userId) => {
310
309
  if (!opts.gate && !allowedDomains)
311
310
  return true;
312
- const hit = gateCache.get(userId);
313
- if (hit) {
314
- if (Date.now() < hit.exp) {
315
- // Map iteration order is the LRU order. Refreshing a valid hit keeps a
316
- // small active identity set resident when one-off identities churn.
317
- gateCache.delete(userId);
318
- gateCache.set(userId, hit);
319
- return hit.allowed;
320
- }
321
- gateCache.delete(userId);
322
- }
311
+ const hit = readIdentityCache(gateCache, userId);
312
+ if (hit)
313
+ return hit.allowed;
323
314
  let allowed = false;
324
315
  try {
325
316
  allowed =
@@ -329,22 +320,16 @@ export function clerkAuth(opts) {
329
320
  catch {
330
321
  allowed = false;
331
322
  }
332
- gateCache.set(userId, {
323
+ writeIdentityCache(gateCache, userId, {
333
324
  allowed,
334
325
  exp: Date.now() +
335
326
  (allowed ? GATE_ALLOWED_TTL_MS : GATE_FORBIDDEN_TTL_MS),
336
327
  });
337
- if (gateCache.size > GATE_CACHE_MAX_IDENTITIES) {
338
- const oldest = gateCache.keys().next();
339
- if (!oldest.done)
340
- gateCache.delete(oldest.value);
341
- }
342
328
  return allowed;
343
329
  };
344
330
  return {
345
331
  kind: "clerk",
346
332
  activityActorNamespace: fapiUrl(opts.publishableKey),
347
- ...(toolkitBinding ? { toolkitBinding } : {}),
348
333
  activityActorLabel: resolveActivityLabel,
349
334
  uiAuth: {
350
335
  kind: "clerk",