@zackbart/connecta 0.9.1 → 0.10.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/CHANGELOG.md +128 -0
- package/README.md +49 -92
- package/dist/access-tokens.d.ts +32 -0
- package/dist/access-tokens.d.ts.map +1 -0
- package/dist/access-tokens.js +225 -0
- package/dist/access-tokens.js.map +1 -0
- package/dist/catalog-service.d.ts.map +1 -1
- package/dist/catalog-service.js +1 -4
- package/dist/catalog-service.js.map +1 -1
- package/dist/errors.d.ts +5 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +26 -0
- package/dist/errors.js.map +1 -1
- package/dist/execute.d.ts +3 -1
- package/dist/execute.d.ts.map +1 -1
- package/dist/execute.js +79 -18
- package/dist/execute.js.map +1 -1
- package/dist/executor-result.d.ts.map +1 -1
- package/dist/executor-result.js +37 -6
- package/dist/executor-result.js.map +1 -1
- package/dist/executors/quickjs-protocol.d.ts +12 -0
- package/dist/executors/quickjs-protocol.d.ts.map +1 -1
- package/dist/executors/quickjs-protocol.js +14 -0
- package/dist/executors/quickjs-protocol.js.map +1 -1
- package/dist/executors/quickjs-runtime.d.ts.map +1 -1
- package/dist/executors/quickjs-runtime.js +6 -3
- package/dist/executors/quickjs-runtime.js.map +1 -1
- package/dist/executors/quickjs.d.ts.map +1 -1
- package/dist/executors/quickjs.js +10 -4
- package/dist/executors/quickjs.js.map +1 -1
- package/dist/index.d.ts +27 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +43 -1
- package/dist/index.js.map +1 -1
- package/dist/invocation.d.ts.map +1 -1
- package/dist/invocation.js +1 -4
- package/dist/invocation.js.map +1 -1
- package/dist/meta-tools.d.ts +26 -5
- package/dist/meta-tools.d.ts.map +1 -1
- package/dist/meta-tools.js +84 -40
- package/dist/meta-tools.js.map +1 -1
- package/dist/operator-ui/generated.d.ts +2 -2
- package/dist/operator-ui/generated.d.ts.map +1 -1
- package/dist/operator-ui/generated.js +2 -2
- package/dist/operator-ui/generated.js.map +1 -1
- package/dist/operator-ui/model.d.ts +2 -0
- package/dist/operator-ui/model.d.ts.map +1 -1
- package/dist/operator-ui/model.js.map +1 -1
- package/dist/routes/access-tokens.d.ts +7 -0
- package/dist/routes/access-tokens.d.ts.map +1 -0
- package/dist/routes/access-tokens.js +84 -0
- package/dist/routes/access-tokens.js.map +1 -0
- package/dist/routes/mcp.d.ts.map +1 -1
- package/dist/routes/mcp.js +8 -2
- package/dist/routes/mcp.js.map +1 -1
- package/dist/routes/shared.d.ts +11 -2
- package/dist/routes/shared.d.ts.map +1 -1
- package/dist/routes/shared.js.map +1 -1
- package/dist/routes/ui.d.ts.map +1 -1
- package/dist/routes/ui.js +9 -1
- package/dist/routes/ui.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +5 -0
- package/dist/server.js.map +1 -1
- package/dist/skills.d.ts +15 -3
- package/dist/skills.d.ts.map +1 -1
- package/dist/skills.js +63 -10
- package/dist/skills.js.map +1 -1
- package/dist/storage/file.d.ts.map +1 -1
- package/dist/storage/file.js +5 -0
- package/dist/storage/file.js.map +1 -1
- package/dist/storage/memory.d.ts.map +1 -1
- package/dist/storage/memory.js +8 -0
- package/dist/storage/memory.js.map +1 -1
- package/dist/types.d.ts +19 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui.d.ts +4 -4
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +44 -1
- package/dist/ui.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +2 -2
- package/src/access-tokens.ts +289 -0
- package/src/catalog-service.ts +1 -5
- package/src/errors.ts +28 -0
- package/src/execute.ts +123 -48
- package/src/executor-result.ts +50 -6
- package/src/executors/quickjs-protocol.ts +19 -0
- package/src/executors/quickjs-runtime.ts +6 -2
- package/src/executors/quickjs.ts +10 -3
- package/src/index.ts +85 -5
- package/src/invocation.ts +1 -5
- package/src/meta-tools.ts +116 -53
- package/src/operator-ui/browser.css +63 -0
- package/src/operator-ui/browser.ts +288 -2
- package/src/operator-ui/generated.ts +2 -2
- package/src/operator-ui/model.ts +6 -0
- package/src/routes/access-tokens.ts +115 -0
- package/src/routes/mcp.ts +8 -2
- package/src/routes/shared.ts +11 -1
- package/src/routes/ui.ts +9 -0
- package/src/server.ts +5 -0
- package/src/skills.ts +79 -9
- package/src/storage/file.ts +5 -0
- package/src/storage/memory.ts +8 -0
- package/src/types.ts +20 -0
- package/src/ui.ts +50 -1
- package/src/version.ts +1 -1
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.10.1 — 2026-07-30
|
|
6
|
+
|
|
7
|
+
An inbound-auth escape hatch for MCP clients whose OAuth implementations do not
|
|
8
|
+
interoperate cleanly with a Connecta deployment. Eligible Clerk operators can
|
|
9
|
+
now issue named, revocable Bearer tokens from `/tokens`; each call is attributed
|
|
10
|
+
to the token's immutable identity while activity history resolves the current
|
|
11
|
+
friendly name. The secret is shown once, only a SHA-256 digest is stored, and a
|
|
12
|
+
token can authenticate MCP without gaining operator privileges. **Deployments
|
|
13
|
+
that do not set `accessTokens: {}` are unchanged.** Enabling it requires a
|
|
14
|
+
storage adapter with `list(prefix)` and a Clerk auth provider so token lifecycle
|
|
15
|
+
operations remain behind the human operator boundary.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- **Managed MCP access tokens.** `accessTokens: {}` adds a Clerk-only operator
|
|
20
|
+
ledger for creating, naming, renaming, and revoking `cta_…` Bearer tokens.
|
|
21
|
+
`maxActive` defaults to 100 and can be configured from 1 through 1,000.
|
|
22
|
+
- **Token-attributed activity.** Calls authenticated by a managed token record
|
|
23
|
+
its immutable token ID and resolve the current friendly name when an eligible
|
|
24
|
+
operator reads activity. Revoked metadata remains as a tombstone so historical
|
|
25
|
+
attribution survives rotation.
|
|
26
|
+
- **Enumerable storage.** `KVStorage.list(prefix)` is available for durable
|
|
27
|
+
metadata ledgers, with implementations in the built-in memory and file
|
|
28
|
+
adapters and the Cloudflare Workers KV example.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- **One-time secrets leave no reusable operator-UI state.** The plaintext token
|
|
33
|
+
disappears when it is dismissed, when the operator navigates away or signs
|
|
34
|
+
out, and before the document enters the browser back-forward cache. The create
|
|
35
|
+
form stays unavailable while a newly issued secret is waiting to be stored.
|
|
36
|
+
|
|
37
|
+
## 0.10.0 — 2026-07-30
|
|
38
|
+
|
|
39
|
+
**Code-first is what a model sees.** A deployment with an executor now serves
|
|
40
|
+
seven meta-tools instead of ten: `list_connectors`, `describe_tools`, and
|
|
41
|
+
`batch_call` are no longer top-level tools, and their behavior lives in
|
|
42
|
+
`connecta.search`, `connecta.describe`, and `connecta.batch` inside a program.
|
|
43
|
+
Nothing became unreachable and no policy machinery changed — writes still cross
|
|
44
|
+
`call_destructive_tool`, and `call_tool` deliberately stays, because a single cold
|
|
45
|
+
call is measurably cheaper direct than through a program. What breaks is a client
|
|
46
|
+
that calls one of the three folded names against an executor-backed deployment:
|
|
47
|
+
it gets an unknown-tool error. The always-loaded instructions, the `skills`
|
|
48
|
+
guidance, and the routing sentences in `call_tool`, `search_tools`, `get_result`,
|
|
49
|
+
and `execute_code` are rewritten for that surface, which measures 19.6% smaller
|
|
50
|
+
serialized tool definitions (10,675B → 8,587B), correcting the exploration's ~32%
|
|
51
|
+
estimate. **An executor-free deployment can ignore all of it**: it serves the same
|
|
52
|
+
nine tools with the same descriptions and the same instructions as before, byte
|
|
53
|
+
for byte. `surface: "classic"` alongside an executor restores the ten-tool shape.
|
|
54
|
+
|
|
55
|
+
The default was flipped by owner decision for a single-operator deployment rather
|
|
56
|
+
than by the repeated per-model eval that [`ethos.md`](./ethos.md) had gated it on;
|
|
57
|
+
that row now records the decision and its reasoning, and
|
|
58
|
+
[`eval/code-first-gate`](./eval/code-first-gate/README.md) remains as measurement
|
|
59
|
+
with all three of its arms now real deployment shapes rather than harness
|
|
60
|
+
simulations.
|
|
61
|
+
|
|
62
|
+
The code-mode guest API is now specified rather than merely described:
|
|
63
|
+
[`documentation/code-mode.md`](./documentation/code-mode.md) states what a
|
|
64
|
+
program is promised — surface, addressing, error shapes, projection, retry,
|
|
65
|
+
cancellation, limits, activity — with clause identifiers the tests cite, and
|
|
66
|
+
names the QuickJS/Dynamic Worker divergences as documented exceptions instead of
|
|
67
|
+
leaving them to be discovered. Both executors now run the same contract case
|
|
68
|
+
table, the Workers arm against a real Dynamic Worker in workerd. Writing the
|
|
69
|
+
clauses down turned up four places where the code did not quite match the
|
|
70
|
+
behavior worth having; those are the changes below, all additive or corrective,
|
|
71
|
+
and one of them (retryable policy refusals) reaches `call_tool` and `batch_call`
|
|
72
|
+
as well as programs.
|
|
73
|
+
|
|
74
|
+
### Changed
|
|
75
|
+
|
|
76
|
+
- **The code-first surface is the default wherever an executor is configured.**
|
|
77
|
+
Seven tools: `execute_code`, `search_tools`, `call_tool`,
|
|
78
|
+
`call_destructive_tool`, `authorize_connector`, `get_result`, `skills`. Four
|
|
79
|
+
overlapping ways to reach one connector became two — `search_tools` then
|
|
80
|
+
`call_tool` for a single cold read, one `execute_code` run for everything wider.
|
|
81
|
+
An executor-free deployment is unchanged.
|
|
82
|
+
- **`ConnectaConfig.surface`** overrides what the executor implies. The reason to
|
|
83
|
+
set it is `"classic"` beside an executor, which is the ten-tool shape the eval
|
|
84
|
+
gate's incremental arm measures. `"code-first"` without an executor throws at
|
|
85
|
+
construction rather than advertise a program surface that does not exist, as
|
|
86
|
+
does any other value.
|
|
87
|
+
- **The eval gate configures its arms instead of faking one.** `gate-server.ts`
|
|
88
|
+
no longer filters `tools/list` or rewrites connecta's descriptions: all three
|
|
89
|
+
arms are ordinary deployments, so the harness measures the product and the arms
|
|
90
|
+
are byte-for-byte identical in the transport layer.
|
|
91
|
+
|
|
92
|
+
### Added
|
|
93
|
+
|
|
94
|
+
- **Typed failures inside `connecta.batch`.** A failed call now reports
|
|
95
|
+
`{ address, ok: false, error, errorDetails }`, where `errorDetails` is the
|
|
96
|
+
same typed object `batch_call` returns (`code`, `retryable`, `retryAfterMs`,
|
|
97
|
+
and the `auth_required` recovery envelope). A thrown host error crosses the
|
|
98
|
+
sandbox bridge as a bare message in every executor, so this is the one channel
|
|
99
|
+
through which a program can tell a policy refusal from a transient failure
|
|
100
|
+
instead of cheerfully retrying the refusal. Programs reading `error` are
|
|
101
|
+
unaffected. An entry connecta could not even attempt — a malformed call object
|
|
102
|
+
— reports `batch_call_failed`, the code `batch_call` already uses for the same
|
|
103
|
+
situation.
|
|
104
|
+
|
|
105
|
+
### Fixed
|
|
106
|
+
|
|
107
|
+
- **A policy refusal can no longer look retryable.** `unknown_address`,
|
|
108
|
+
`unknown_tool`, `ambiguous_tool_alias`, and
|
|
109
|
+
`destructive_tool_requires_approval` now pin `retryable: false` instead of
|
|
110
|
+
deriving it from their own message text. Those messages embed the address the
|
|
111
|
+
caller asked for, and the heuristic that classifies connector errors matches
|
|
112
|
+
`503`, `429`, and `temporar`, so a connector named `svc-503` or
|
|
113
|
+
`temporary-export` turned a refusal that will never succeed into one an agent
|
|
114
|
+
was told to retry. This affects `call_tool` and `batch_call` too, not only
|
|
115
|
+
programs.
|
|
116
|
+
- **An uncaught discovery-bound failure inside a program is typed.** A bad
|
|
117
|
+
`limit`, an oversized `addresses` list, or a discovery page over the
|
|
118
|
+
256,000-byte ceiling now reaches the model as `invalid_args` or
|
|
119
|
+
`result_too_large` with `retryable: false`, the same envelope a failed tool
|
|
120
|
+
call gets, instead of as untyped error prose.
|
|
121
|
+
- **Bridge-limit errors name the address, not the plumbing.** A host call over
|
|
122
|
+
the QuickJS 256 KiB bound reported `connecta.__callNamespace` — the internal
|
|
123
|
+
dispatcher every shortcut namespace shares — where it now reports the
|
|
124
|
+
`connector.tool` address the program called.
|
|
125
|
+
- **An oversized program result is truncated once.** The over-cap notice is now
|
|
126
|
+
sized so its *serialized* form fits the 24,000-character result cap.
|
|
127
|
+
Previously the QuickJS path truncated in the child and again in the parent, so
|
|
128
|
+
a very large result came back as a truncation envelope wrapped in a truncation
|
|
129
|
+
envelope whose `totalChars` reported the inner envelope's length rather than
|
|
130
|
+
the real size. Previews are somewhat shorter; `totalChars` is now the true
|
|
131
|
+
serialized size of what the program returned.
|
|
132
|
+
|
|
5
133
|
## 0.9.1 — 2026-07-29
|
|
6
134
|
|
|
7
135
|
A code-mode routing release. Agents that needed an unknown address *and* a
|
package/README.md
CHANGED
|
@@ -2,104 +2,61 @@
|
|
|
2
2
|
|
|
3
3
|

|
|
4
4
|
|
|
5
|
-
One
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return their compact schemas in the same response, while `describe_tools`
|
|
29
|
-
expands only schemas that remain unclear. `call_tool` / `batch_call` /
|
|
30
|
-
`call_destructive_tool` invoke them, and `list_connectors`,
|
|
31
|
-
`authorize_connector`, `get_result`, and `skills` round out the nine. An
|
|
32
|
-
optional tenth, `execute_code`, runs model-written JavaScript in a sandbox with
|
|
33
|
-
no network, filesystem, or environment access — only the read-only tools in
|
|
34
|
-
scope. Context holds nine definitions whether ten tools sit behind them or a
|
|
35
|
-
thousand.
|
|
36
|
-
|
|
37
|
-
Three properties are load-bearing enough to name here; the rest live in the
|
|
38
|
-
[ethos](./ethos.md). **Read-only is fail-closed**: anything not explicitly
|
|
39
|
-
annotated read-only crosses `call_destructive_tool`, which is annotated so the
|
|
40
|
-
MCP host can ask a human. **Credentials stay server-side**: an encrypted
|
|
41
|
-
vault, rotated from an operator page, and no surface ever returns a secret.
|
|
42
|
-
**Config is code**: adding a connector is an edit and a deploy you can review
|
|
43
|
-
in a pull request.
|
|
44
|
-
|
|
45
|
-
## Getting started
|
|
46
|
-
|
|
47
|
-
Node deployments require Node.js 20.9 or newer.
|
|
48
|
-
|
|
49
|
-
```sh
|
|
50
|
-
npm install @zackbart/connecta
|
|
5
|
+
One place for AI agents to connect to the tools you choose.
|
|
6
|
+
|
|
7
|
+
Connecta gives an agent a single MCP endpoint instead of making it connect to
|
|
8
|
+
every service separately. You decide which integrations are available and
|
|
9
|
+
Connecta holds their credentials, and the agent mostly works by writing
|
|
10
|
+
ordinary JavaScript that Connecta runs in a sandbox next to them — with a few
|
|
11
|
+
explicit tools for the jobs a program is the wrong shape for, destructive calls
|
|
12
|
+
among them.
|
|
13
|
+
|
|
14
|
+
```mermaid
|
|
15
|
+
flowchart LR
|
|
16
|
+
Agent["AI agent"]
|
|
17
|
+
Integrations["The integrations you chose"]
|
|
18
|
+
|
|
19
|
+
subgraph Connecta["Connecta: one MCP endpoint; credentials stay here"]
|
|
20
|
+
Sandbox["execute_code<br/>server-side sandbox"]
|
|
21
|
+
Explicit["Explicit tools<br/>destructive calls, search, auth"]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
Agent -->|"writes a program"| Sandbox
|
|
25
|
+
Agent -->|"one deliberate call"| Explicit
|
|
26
|
+
Sandbox --> Integrations
|
|
27
|
+
Explicit --> Integrations
|
|
51
28
|
```
|
|
52
29
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
```ts
|
|
56
|
-
import { api, bearerToken, createConnecta } from "@zackbart/connecta";
|
|
57
|
-
import { fileStorage, listen } from "@zackbart/connecta/node";
|
|
30
|
+
## Why Connecta
|
|
58
31
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
inputSchema: { type: "object", properties: {} },
|
|
70
|
-
annotations: { readOnlyHint: true },
|
|
71
|
-
handler: async () => ({ now: new Date().toISOString() }),
|
|
72
|
-
},
|
|
73
|
-
],
|
|
74
|
-
}),
|
|
75
|
-
],
|
|
76
|
-
});
|
|
32
|
+
- **One connection.** Configure clients once, even as integrations change.
|
|
33
|
+
- **Seven tools, not seven hundred.** A program can search the catalog, chain
|
|
34
|
+
calls, and trim the results before the agent ever sees them — so nothing has
|
|
35
|
+
to be loaded up front.
|
|
36
|
+
- **Safer access.** Credentials stay server-side — the program never sees them
|
|
37
|
+
— and consequential actions remain explicit and individual.
|
|
38
|
+
- **Named client access.** A Clerk operator can issue and revoke one-time,
|
|
39
|
+
hashed Bearer tokens for MCP clients that support header authentication.
|
|
40
|
+
- **Your deployment.** Connecta runs on Node, Docker, or Cloudflare Workers,
|
|
41
|
+
with configuration you can review and version.
|
|
77
42
|
|
|
78
|
-
|
|
79
|
-
```
|
|
43
|
+
## Start here
|
|
80
44
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
45
|
+
- [Node example](./examples/node/)
|
|
46
|
+
- [Docker example](./examples/docker/)
|
|
47
|
+
- [Cloudflare Worker example](./examples/worker/)
|
|
48
|
+
- [Documentation](./documentation/)
|
|
84
49
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
Heavyweight extras are optional peers behind subpaths (`/auth/clerk`,
|
|
90
|
-
`/quickjs`), and connecta ships no service-specific connectors — endpoint,
|
|
91
|
-
credential, and tool choices stay in your project.
|
|
50
|
+
Configuring a sandbox — a Dynamic Worker on Cloudflare, QuickJS on Node — is
|
|
51
|
+
what selects the code-first surface, and it is the assumed posture. A
|
|
52
|
+
deployment without one keeps the earlier nine-tool, call-by-call interface,
|
|
53
|
+
which stays supported.
|
|
92
54
|
|
|
93
|
-
|
|
94
|
-
first and published openly. Breaking changes are cheap and the version number
|
|
95
|
-
signals change, not stability — the [ethos](./ethos.md) says so on purpose.
|
|
55
|
+
## Project status
|
|
96
56
|
|
|
97
|
-
|
|
57
|
+
Connecta is built for its author's deployments first and is still evolving.
|
|
58
|
+
Breaking changes are expected before 1.0.
|
|
98
59
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
stubs; the prior manual lives in git history).
|
|
103
|
-
- **[CHANGELOG](./CHANGELOG.md)** — what changed in each release.
|
|
104
|
-
- **[SECURITY](./SECURITY.md)** — supported versions and how to report a
|
|
105
|
-
vulnerability.
|
|
60
|
+
Read the [ethos](./ethos.md) for the product's principles, the
|
|
61
|
+
[changelog](./CHANGELOG.md) for releases, and [security policy](./SECURITY.md)
|
|
62
|
+
for vulnerability reporting.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { InboundAuth, KVStorage } from "./types.js";
|
|
2
|
+
export interface AccessTokenMetadata {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
tokenPrefix: string;
|
|
6
|
+
createdAt: string;
|
|
7
|
+
revokedAt?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface CreatedAccessToken {
|
|
10
|
+
token: string;
|
|
11
|
+
accessToken: AccessTokenMetadata;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Deployment-scoped personal access tokens. Secret material is never
|
|
15
|
+
* recoverable: authentication indexes a SHA-256 digest of a random 256-bit
|
|
16
|
+
* token, while separately enumerable metadata powers operator management.
|
|
17
|
+
*/
|
|
18
|
+
export declare class AccessTokenManager {
|
|
19
|
+
private readonly storage;
|
|
20
|
+
readonly auth: InboundAuth;
|
|
21
|
+
private readonly maxActive;
|
|
22
|
+
constructor(storage: KVStorage, options?: {
|
|
23
|
+
maxActive?: number;
|
|
24
|
+
});
|
|
25
|
+
private read;
|
|
26
|
+
list(): Promise<AccessTokenMetadata[]>;
|
|
27
|
+
create(name: unknown, createdBy: string): Promise<CreatedAccessToken>;
|
|
28
|
+
rename(id: string, name: unknown): Promise<AccessTokenMetadata | null>;
|
|
29
|
+
revoke(id: string, revokedBy: string): Promise<AccessTokenMetadata | null>;
|
|
30
|
+
private authorize;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=access-tokens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access-tokens.d.ts","sourceRoot":"","sources":["../src/access-tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA6BrE,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,mBAAmB,CAAC;CAClC;AAyGD;;;;GAIG;AACH,qBAAa,kBAAkB;IAK3B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAGhB,OAAO,EAAE,SAAS,EACnC,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO;YAgCxB,IAAI;IAKZ,IAAI,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;IActC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAoCrE,MAAM,CACV,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAQhC,MAAM,CACV,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;YAexB,SAAS;CAgBxB"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
const TOKEN_PREFIX = "cta_";
|
|
2
|
+
const TOKEN_BYTES = 32;
|
|
3
|
+
const TOKEN_VALUE_RE = /^cta_[A-Za-z0-9_-]{43}$/;
|
|
4
|
+
const RECORD_PREFIX = "access-token:v1:record:";
|
|
5
|
+
const LOOKUP_PREFIX = "access-token:v1:lookup:";
|
|
6
|
+
const MAX_NAME_CHARACTERS = 80;
|
|
7
|
+
const DEFAULT_MAX_ACTIVE = 100;
|
|
8
|
+
const MAX_CONFIGURED_ACTIVE = 1_000;
|
|
9
|
+
const encoder = new TextEncoder();
|
|
10
|
+
function recordKey(id) {
|
|
11
|
+
return `${RECORD_PREFIX}${id}`;
|
|
12
|
+
}
|
|
13
|
+
function lookupKey(hash) {
|
|
14
|
+
return `${LOOKUP_PREFIX}${hash}`;
|
|
15
|
+
}
|
|
16
|
+
function bytesToBase64Url(bytes) {
|
|
17
|
+
let binary = "";
|
|
18
|
+
for (const byte of bytes)
|
|
19
|
+
binary += String.fromCharCode(byte);
|
|
20
|
+
return btoa(binary)
|
|
21
|
+
.replaceAll("+", "-")
|
|
22
|
+
.replaceAll("/", "_")
|
|
23
|
+
.replace(/=+$/u, "");
|
|
24
|
+
}
|
|
25
|
+
function bytesToHex(bytes) {
|
|
26
|
+
return [...bytes]
|
|
27
|
+
.map((byte) => byte.toString(16).padStart(2, "0"))
|
|
28
|
+
.join("");
|
|
29
|
+
}
|
|
30
|
+
async function hashToken(token) {
|
|
31
|
+
return bytesToHex(new Uint8Array(await crypto.subtle.digest("SHA-256", encoder.encode(token))));
|
|
32
|
+
}
|
|
33
|
+
function normalizeName(value) {
|
|
34
|
+
if (typeof value !== "string") {
|
|
35
|
+
throw new Error("Token name must be a string");
|
|
36
|
+
}
|
|
37
|
+
const compact = value.replace(/\s+/gu, " ").trim();
|
|
38
|
+
if (!compact)
|
|
39
|
+
throw new Error("Token name cannot be empty");
|
|
40
|
+
if (Array.from(compact).length > MAX_NAME_CHARACTERS) {
|
|
41
|
+
throw new Error(`Token name cannot exceed ${MAX_NAME_CHARACTERS} characters`);
|
|
42
|
+
}
|
|
43
|
+
return compact;
|
|
44
|
+
}
|
|
45
|
+
function parseRecord(raw) {
|
|
46
|
+
try {
|
|
47
|
+
const value = JSON.parse(raw);
|
|
48
|
+
if (value.version !== 1 ||
|
|
49
|
+
typeof value.id !== "string" ||
|
|
50
|
+
!/^[0-9a-f-]{36}$/u.test(value.id) ||
|
|
51
|
+
typeof value.name !== "string" ||
|
|
52
|
+
typeof value.tokenHash !== "string" ||
|
|
53
|
+
!/^[0-9a-f]{64}$/u.test(value.tokenHash) ||
|
|
54
|
+
typeof value.tokenPrefix !== "string" ||
|
|
55
|
+
typeof value.createdAt !== "string" ||
|
|
56
|
+
typeof value.createdBy !== "string" ||
|
|
57
|
+
(value.revokedAt !== undefined &&
|
|
58
|
+
typeof value.revokedAt !== "string") ||
|
|
59
|
+
(value.revokedBy !== undefined &&
|
|
60
|
+
typeof value.revokedBy !== "string")) {
|
|
61
|
+
throw new Error("invalid token record");
|
|
62
|
+
}
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
throw new Error("Stored access token metadata is invalid or corrupted");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function parseLookup(raw) {
|
|
70
|
+
try {
|
|
71
|
+
const value = JSON.parse(raw);
|
|
72
|
+
return value.version === 1 && typeof value.id === "string"
|
|
73
|
+
? { version: 1, id: value.id }
|
|
74
|
+
: null;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function metadata(record) {
|
|
81
|
+
return {
|
|
82
|
+
id: record.id,
|
|
83
|
+
name: record.name,
|
|
84
|
+
tokenPrefix: record.tokenPrefix,
|
|
85
|
+
createdAt: record.createdAt,
|
|
86
|
+
...(record.revokedAt ? { revokedAt: record.revokedAt } : {}),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function unauthorized() {
|
|
90
|
+
return {
|
|
91
|
+
ok: false,
|
|
92
|
+
response: new Response(JSON.stringify({ error: "unauthorized" }), {
|
|
93
|
+
status: 401,
|
|
94
|
+
headers: {
|
|
95
|
+
"Content-Type": "application/json",
|
|
96
|
+
"WWW-Authenticate": "Bearer",
|
|
97
|
+
},
|
|
98
|
+
}),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Deployment-scoped personal access tokens. Secret material is never
|
|
103
|
+
* recoverable: authentication indexes a SHA-256 digest of a random 256-bit
|
|
104
|
+
* token, while separately enumerable metadata powers operator management.
|
|
105
|
+
*/
|
|
106
|
+
export class AccessTokenManager {
|
|
107
|
+
storage;
|
|
108
|
+
auth;
|
|
109
|
+
maxActive;
|
|
110
|
+
constructor(storage, options = {}) {
|
|
111
|
+
this.storage = storage;
|
|
112
|
+
if (!storage.list) {
|
|
113
|
+
throw new Error("accessTokens requires a storage adapter that implements list(prefix)");
|
|
114
|
+
}
|
|
115
|
+
const maxActive = options.maxActive ?? DEFAULT_MAX_ACTIVE;
|
|
116
|
+
if (!Number.isInteger(maxActive) ||
|
|
117
|
+
maxActive < 1 ||
|
|
118
|
+
maxActive > MAX_CONFIGURED_ACTIVE) {
|
|
119
|
+
throw new Error(`accessTokens.maxActive must be a whole number from 1 to ${MAX_CONFIGURED_ACTIVE}`);
|
|
120
|
+
}
|
|
121
|
+
this.maxActive = maxActive;
|
|
122
|
+
this.auth = {
|
|
123
|
+
kind: "access_token",
|
|
124
|
+
activityActorNamespace: "connecta:access-tokens:v1",
|
|
125
|
+
activityActorLabel: async (id) => {
|
|
126
|
+
try {
|
|
127
|
+
return (await this.read(id))?.name;
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
authorize: (request) => this.authorize(request),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
async read(id) {
|
|
137
|
+
const raw = await this.storage.get(recordKey(id));
|
|
138
|
+
return raw ? parseRecord(raw) : null;
|
|
139
|
+
}
|
|
140
|
+
async list() {
|
|
141
|
+
const keys = await this.storage.list(RECORD_PREFIX);
|
|
142
|
+
const records = await Promise.all(keys.map(async (key) => {
|
|
143
|
+
const raw = await this.storage.get(key);
|
|
144
|
+
return raw ? parseRecord(raw) : null;
|
|
145
|
+
}));
|
|
146
|
+
return records
|
|
147
|
+
.filter((record) => Boolean(record))
|
|
148
|
+
.sort((a, b) => b.createdAt.localeCompare(a.createdAt))
|
|
149
|
+
.map(metadata);
|
|
150
|
+
}
|
|
151
|
+
async create(name, createdBy) {
|
|
152
|
+
const normalizedName = normalizeName(name);
|
|
153
|
+
const active = (await this.list()).filter((token) => !token.revokedAt);
|
|
154
|
+
if (active.length >= this.maxActive) {
|
|
155
|
+
throw new Error(`This deployment already has the maximum of ${this.maxActive} active access tokens`);
|
|
156
|
+
}
|
|
157
|
+
const secretBytes = crypto.getRandomValues(new Uint8Array(TOKEN_BYTES));
|
|
158
|
+
const token = TOKEN_PREFIX + bytesToBase64Url(secretBytes);
|
|
159
|
+
const hash = await hashToken(token);
|
|
160
|
+
if (await this.storage.get(lookupKey(hash))) {
|
|
161
|
+
throw new Error("Access token collision; create another token");
|
|
162
|
+
}
|
|
163
|
+
const record = {
|
|
164
|
+
version: 1,
|
|
165
|
+
id: crypto.randomUUID(),
|
|
166
|
+
name: normalizedName,
|
|
167
|
+
tokenHash: hash,
|
|
168
|
+
tokenPrefix: token.slice(0, 12),
|
|
169
|
+
createdAt: new Date().toISOString(),
|
|
170
|
+
createdBy,
|
|
171
|
+
};
|
|
172
|
+
await this.storage.set(recordKey(record.id), JSON.stringify(record));
|
|
173
|
+
try {
|
|
174
|
+
await this.storage.set(lookupKey(hash), JSON.stringify({ version: 1, id: record.id }));
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
await this.storage.delete(recordKey(record.id)).catch(() => { });
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
return { token, accessToken: metadata(record) };
|
|
181
|
+
}
|
|
182
|
+
async rename(id, name) {
|
|
183
|
+
const record = await this.read(id);
|
|
184
|
+
if (!record)
|
|
185
|
+
return null;
|
|
186
|
+
record.name = normalizeName(name);
|
|
187
|
+
await this.storage.set(recordKey(id), JSON.stringify(record));
|
|
188
|
+
return metadata(record);
|
|
189
|
+
}
|
|
190
|
+
async revoke(id, revokedBy) {
|
|
191
|
+
const record = await this.read(id);
|
|
192
|
+
if (!record)
|
|
193
|
+
return null;
|
|
194
|
+
if (!record.revokedAt) {
|
|
195
|
+
// Admission disappears first. A metadata-write failure may leave the UI
|
|
196
|
+
// calling the record active, but can never leave a token labelled
|
|
197
|
+
// revoked while its lookup still admits requests.
|
|
198
|
+
await this.storage.delete(lookupKey(record.tokenHash));
|
|
199
|
+
record.revokedAt = new Date().toISOString();
|
|
200
|
+
record.revokedBy = revokedBy;
|
|
201
|
+
await this.storage.set(recordKey(id), JSON.stringify(record));
|
|
202
|
+
}
|
|
203
|
+
return metadata(record);
|
|
204
|
+
}
|
|
205
|
+
async authorize(request) {
|
|
206
|
+
const header = request.headers.get("authorization") ?? "";
|
|
207
|
+
const match = /^Bearer\s+(.+)$/iu.exec(header);
|
|
208
|
+
const token = match?.[1];
|
|
209
|
+
if (!token || !TOKEN_VALUE_RE.test(token))
|
|
210
|
+
return unauthorized();
|
|
211
|
+
const hash = await hashToken(token);
|
|
212
|
+
const lookupRaw = await this.storage.get(lookupKey(hash));
|
|
213
|
+
if (!lookupRaw)
|
|
214
|
+
return unauthorized();
|
|
215
|
+
const lookup = parseLookup(lookupRaw);
|
|
216
|
+
if (!lookup)
|
|
217
|
+
return unauthorized();
|
|
218
|
+
const record = await this.read(lookup.id);
|
|
219
|
+
if (!record || record.revokedAt || record.tokenHash !== hash) {
|
|
220
|
+
return unauthorized();
|
|
221
|
+
}
|
|
222
|
+
return { ok: true, subjectId: record.id };
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=access-tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access-tokens.js","sourceRoot":"","sources":["../src/access-tokens.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog-service.d.ts","sourceRoot":"","sources":["../src/catalog-service.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EACV,yBAAyB,EACzB,YAAY,EACb,MAAM,eAAe,CAAC;AAUvB,OAAO,KAAK,EACV,SAAS,EAET,OAAO,EACR,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,eAAO,MAAM,gBAAgB,MAAM,CAAC;AACpC,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAC1C,eAAO,MAAM,0BAA0B,SAAU,CAAC;AAIlD,qBAAa,oBAAqB,SAAQ,KAAK;IAE3C,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,kBAAkB;gBAAzC,IAAI,EAAE,cAAc,GAAG,kBAAkB,EAClD,OAAO,EAAE,MAAM;CAKlB;AAoCD,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAazE;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACpC,kFAAkF;IAClF,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,UAAU,kBAAkB;IAC1B,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC7B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB,WAAW,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;KACtC,CAAC;CACH;AA4BD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,iBAAiB,GACzB;IACE,EAAE,EAAE,IAAI,CAAC;IACT,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,gBAAgB,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;
|
|
1
|
+
{"version":3,"file":"catalog-service.d.ts","sourceRoot":"","sources":["../src/catalog-service.ts"],"names":[],"mappings":"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"}
|
package/dist/catalog-service.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { compactSchema, lexicalCorpusStatistics, lexicalSearchQuery, rankTools, schemaObjectKeys, summarizeDescription, } from "./catalog.js";
|
|
2
2
|
import { mapSettledWithConcurrency, resolveDiscoveryConcurrency, } from "./concurrency.js";
|
|
3
|
-
import { classifyCallError,
|
|
3
|
+
import { classifyCallError, framingError } from "./errors.js";
|
|
4
4
|
import { connectorGuide, connectorSkillName, } from "./skills.js";
|
|
5
5
|
import { DEFAULT_PROBE_TIMEOUT_MS, normalizeTimeoutMs, withAbortableTimeout, } from "./timeout.js";
|
|
6
6
|
export const DEFAULT_SEARCH_LIMIT = 8;
|
|
@@ -68,9 +68,6 @@ function schemaKeyMetadata(input, output) {
|
|
|
68
68
|
...(outputKeys ? { outputKeys: outputKeys.properties } : {}),
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
|
-
function framingError(code, message) {
|
|
72
|
-
return { code, message, retryable: messageLooksRetryable(message) };
|
|
73
|
-
}
|
|
74
71
|
function renderSchema(schema, format) {
|
|
75
72
|
return format === "json" ? schema : compactSchema(schema);
|
|
76
73
|
}
|