@byok-sdk/client 0.10.2 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -6
- package/dist/adapters/claude/claude-adapter.d.ts +3 -2
- package/dist/adapters/claude/permission-mapping.d.ts +48 -1
- package/dist/adapters/claude/resolve-approval-mcp-bin.d.ts +3 -2
- package/dist/adapters/codex/permission-mapping.d.ts +16 -0
- package/dist/adapters/index.js +292 -23
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/mcp-tool-grants.d.ts +36 -0
- package/dist/adapters/pi/resolve-extensions.d.ts +4 -1
- package/dist/adapters/pi/subagents-policy-config.d.ts +7 -0
- package/dist/adapters/pi/subagents-policy-extension.js +137 -0
- package/dist/adapters/pi/subagents-policy-extension.js.map +1 -0
- package/dist/agent-home.d.ts +33 -0
- package/dist/agent-memory/index.d.ts +1 -1
- package/dist/agent-memory/index.js +12 -9
- package/dist/agent-memory/index.js.map +1 -1
- package/dist/bin/agent-memory-mcp-server.d.ts +2 -2
- package/dist/bin/agent-message-mcp-server.d.ts +0 -1
- package/dist/bin/byok-agent-memory-mcp.js +340 -7
- package/dist/bin/byok-agent-memory-mcp.js.map +1 -1
- package/dist/bin/byok-agent-message-mcp.js +331 -7
- package/dist/bin/byok-agent-message-mcp.js.map +1 -1
- package/dist/bin/byok-agent-team-mcp.d.ts +2 -0
- package/dist/bin/byok-agent-team-mcp.js +765 -0
- package/dist/bin/byok-agent-team-mcp.js.map +1 -0
- package/dist/bin/byok-agent.js +16413 -14479
- package/dist/bin/byok-agent.js.map +1 -1
- package/dist/bin/byok-approval-mcp.js +312 -45
- package/dist/bin/byok-approval-mcp.js.map +1 -1
- package/dist/bin/commands/team.d.ts +15 -0
- package/dist/bin/sdk-reserved-helper-runners.d.ts +2 -0
- package/dist/bin/team-mcp-server.d.ts +27 -0
- package/dist/bin/team-tmux-view.d.ts +19 -0
- package/dist/daemon/agent-egress-controller.d.ts +4 -0
- package/dist/daemon/agent-message-mcp-preflight.d.ts +17 -0
- package/dist/daemon/auth-manager.d.ts +20 -0
- package/dist/daemon/blob-client.d.ts +24 -6
- package/dist/daemon/connection-manager.d.ts +7 -0
- package/dist/daemon/control-protocol.d.ts +38 -0
- package/dist/daemon/create-daemon.d.ts +9 -0
- package/dist/daemon/device-credential-store.d.ts +16 -0
- package/dist/daemon/long-poll-transport.d.ts +3 -0
- package/dist/daemon/mcp-tools-probe.d.ts +105 -0
- package/dist/daemon/replay-cursor.d.ts +9 -0
- package/dist/daemon/resolve-agent-memory-mcp-bin.d.ts +2 -1
- package/dist/daemon/resolve-agent-message-mcp-bin.d.ts +2 -1
- package/dist/daemon/task-runner.d.ts +22 -1
- package/dist/daemon/team-workspace.d.ts +202 -0
- package/dist/daemon/toolset-registry.d.ts +0 -2
- package/dist/daemon/url.d.ts +7 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.js +3611 -1364
- package/dist/index.js.map +1 -1
- package/dist/sdk-reserved-helper-host.d.ts +25 -0
- package/dist/sdk-reserved-mcp.d.ts +23 -0
- package/dist/types.d.ts +36 -0
- package/package.json +10 -5
package/README.md
CHANGED
|
@@ -14,6 +14,31 @@ Provider
|
|
|
14
14
|
credentials are not read by the dispatch plane; `@byok-sdk/keys` is a separate
|
|
15
15
|
install and keeps a zero dependency edge to this package.
|
|
16
16
|
|
|
17
|
+
Single-file Bun/SEA products must explicitly re-enter SDK-reserved helpers
|
|
18
|
+
before their own CLI parser. The SDK owns the reserved subcommand and helper
|
|
19
|
+
implementation; the product does not resolve `dist/bin` paths:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { createDaemon, runSdkReservedHelperCommand } from '@byok-sdk/client';
|
|
23
|
+
|
|
24
|
+
if (await runSdkReservedHelperCommand()) process.exit(0);
|
|
25
|
+
|
|
26
|
+
const daemon = createDaemon({
|
|
27
|
+
// ...normal device, Agent-home, and egress configuration
|
|
28
|
+
sdkHelperHost: { mode: 'self-executable' },
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Normal Node/Bun source hosts omit `sdkHelperHost` and continue to use the
|
|
33
|
+
package's installed helper scripts. A required-message offer performs an exact
|
|
34
|
+
stdio MCP initialize/tools-list handshake before adapter preparation; an
|
|
35
|
+
unwired or unstartable single-file helper is declined before runtime execution.
|
|
36
|
+
For Codex 0.149+, the adapter additionally proves the native per-MCP-tool
|
|
37
|
+
approval contract before claim, then approves only the SDK-reserved
|
|
38
|
+
`byokagentmessage/send_agent_message` tool. The global Codex
|
|
39
|
+
`approval_policy=never` remains pinned and every other MCP/tool retains the
|
|
40
|
+
normal non-interactive fail-closed posture.
|
|
41
|
+
|
|
17
42
|
Pi is a required exact npm dependency and runs as an external Node subprocess.
|
|
18
43
|
For an authoritative BYOK `dispatchSelection`, configure `piByokLauncher` with
|
|
19
44
|
the separately installed `byok-pi-provider-launcher`, the local non-secret
|
|
@@ -64,9 +89,31 @@ createDaemon({
|
|
|
64
89
|
```
|
|
65
90
|
|
|
66
91
|
The map accepts only `command` and `args`; put OAuth tokens, cookies, and other
|
|
67
|
-
secrets behind the local MCP process's own credential broker.
|
|
68
|
-
|
|
69
|
-
|
|
92
|
+
secrets behind the local MCP process's own credential broker.
|
|
93
|
+
|
|
94
|
+
A projected toolset must also be *callable*, and neither runtime grants an MCP
|
|
95
|
+
tool implicitly: Claude auto-denies an ungranted `mcp__<server>__<tool>` call
|
|
96
|
+
under `--permission-mode default` and under `acceptEdits`, and Codex refuses
|
|
97
|
+
every MCP tool call under its pinned `approval_policy=never`. So before an
|
|
98
|
+
adapter is asked to admit a toolset offer, the daemon starts each projected
|
|
99
|
+
server and reads that server's own `tools/list` answer. Those observed names —
|
|
100
|
+
never a configured value, never a wildcard — are what each adapter grants:
|
|
101
|
+
|
|
102
|
+
- Claude: `--allowedTools mcp__<server>__<tool>,…` under `readonly` and
|
|
103
|
+
`auto`, alongside the unchanged `--tools` (so `readonly` with
|
|
104
|
+
`allowTools: []` still runs with every built-in disabled). `confirm` and
|
|
105
|
+
`plan` never pre-grant: `confirm`'s approval channel must see each call, and
|
|
106
|
+
`plan` promises not to execute one.
|
|
107
|
+
- Codex: `mcp_servers.<server>.enabled_tools` plus
|
|
108
|
+
`mcp_servers.<server>.tools.<tool>.approval_mode="approve"` for exactly
|
|
109
|
+
those tools. Global `approval_policy=never` and the mode's `sandbox_mode`
|
|
110
|
+
stay untouched, and Codex older than 0.149 is rejected before spawn.
|
|
111
|
+
|
|
112
|
+
A projected server that cannot start, or that lists no tools, is declined
|
|
113
|
+
pre-claim and retryably, rather than claimed and handed a toolset the model can
|
|
114
|
+
list but never call. A server that answers with a tool name that cannot be
|
|
115
|
+
expressed as a runtime grant is declined permanently (`retryable: false`), with
|
|
116
|
+
the server and the offending tool named in the decline.
|
|
70
117
|
|
|
71
118
|
The daemon derives one sorted `configuredToolsets` snapshot from this
|
|
72
119
|
validated registry. Only those logical IDs are advertised in `conn.hello`
|
|
@@ -128,9 +175,21 @@ strict Agent execution has one workspace authority and never falls back to a
|
|
|
128
175
|
task-scoped Git workspace.
|
|
129
176
|
|
|
130
177
|
Successful startup with this configuration advertises `agent-home-contract`. Agent offers are distinct
|
|
131
|
-
from legacy task offers and fail closed when identity, profile revision,
|
|
132
|
-
session/runtime/cwd evidence
|
|
133
|
-
|
|
178
|
+
from legacy task offers and fail closed when identity, profile revision, or
|
|
179
|
+
session/runtime/cwd evidence does not match. Within one daemon process,
|
|
180
|
+
execution leases are scoped to `(agentId, sessionRef)`: different sessions of
|
|
181
|
+
one Agent may run concurrently in the same canonical home, while the same
|
|
182
|
+
session remains serialized. Fresh
|
|
183
|
+
tasks bind their task-scoped admission lease to the runtime-created session
|
|
184
|
+
before the SDK exposes that session. Shared `.byok` metadata mutations use a
|
|
185
|
+
short per-home gate. Agent-memory hosted projection serializes the complete
|
|
186
|
+
close-time outbox transaction per home because its durable outbox is one CAS
|
|
187
|
+
authority; the publish wait remains timeout-bounded and does not serialize the
|
|
188
|
+
sessions' runtime execution. The process-owned home activity marker remains
|
|
189
|
+
held until the final active session exits so relocation stays fail-closed. A
|
|
190
|
+
second daemon process remains excluded by that marker; cross-process session
|
|
191
|
+
multiplexing is not provided. Agent files
|
|
192
|
+
other than the SDK-reserved `.byok` namespace are opaque; there is no
|
|
134
193
|
required `artifacts/` directory and the client does not parse or index their
|
|
135
194
|
contents.
|
|
136
195
|
|
|
@@ -261,4 +320,25 @@ OS-backed refresh-token custody, a PKCE desktop Google OAuth flow, exact domain
|
|
|
261
320
|
policy, a real read-only Gmail metadata adapter, and a closed metadata-only MCP
|
|
262
321
|
result.
|
|
263
322
|
|
|
323
|
+
## Local TeamWorkspace and tmux communication pane
|
|
324
|
+
|
|
325
|
+
`byok-agent team` provides one local-only broadcast channel for Pi, Claude,
|
|
326
|
+
and Codex harnesses. The daemon owns durable ordered messages, member receipts,
|
|
327
|
+
quotas, and short-lived member leases under `<storeDir>/team-workspaces/v1`.
|
|
328
|
+
`team join` prints the exact `byokagentteam` stdio MCP configuration for a
|
|
329
|
+
member; model tool inputs never contain workspace or sender identity.
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
byok-agent team create dev --members pi,claude,codex --config /absolute/agent.json
|
|
333
|
+
byok-agent team join dev --member pi --config /absolute/agent.json
|
|
334
|
+
byok-agent team open dev --tmux-bin /opt/homebrew/bin/tmux --config /absolute/agent.json
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
The tmux view has one explicit native dependency: tmux must be installed and
|
|
338
|
+
its absolute executable path supplied with `--tmux-bin`. It is intentionally
|
|
339
|
+
not an npm dependency and is not required to run the daemon, MCP channel, or
|
|
340
|
+
plain watcher. Native Windows returns `unsupported_platform` for the tmux view.
|
|
341
|
+
The launcher never uses `send-keys` or `capture-pane`; tmux displays the
|
|
342
|
+
daemon-owned stream but is never message transport or protocol authority.
|
|
343
|
+
|
|
264
344
|
MIT licensed. Node.js 22.22.0 or newer.
|
|
@@ -2,8 +2,9 @@ import { type RuntimeAdapter, type RuntimeDetectResult, type RuntimeAdapterPrepa
|
|
|
2
2
|
import { type ResolvedBin } from './resolve-bin';
|
|
3
3
|
import { type ResolvedApprovalMcpBin } from './resolve-approval-mcp-bin';
|
|
4
4
|
import { type SpawnFn } from './process-client';
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
import { APPROVAL_MCP_SERVER_NAME } from '../../sdk-reserved-mcp';
|
|
6
|
+
/** The MCP server NAME this adapter registers `byok-approval-mcp` under in the generated `--mcp-config` — combined with {@link APPROVAL_TOOL_NAME} (single-sourced from `bin/approval-mcp-server.ts` so the two can never independently drift) to form the `mcp__<server>__<tool>` identifier `--permission-prompt-tool` expects. Defined in `sdk-reserved-mcp.ts` beside the other SDK-owned server names, and re-exported from here, its original home, so the host-config rejection and the toolset-grant rule read one list. */
|
|
7
|
+
export { APPROVAL_MCP_SERVER_NAME };
|
|
7
8
|
export interface ClaudeAdapterOptions {
|
|
8
9
|
/** Override bin resolution — tests substitute the fake-claude fixture script. */
|
|
9
10
|
resolveBin?: () => ResolvedBin;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PermissionPolicy } from '@byok-sdk/protocol';
|
|
2
|
+
import type { McpToolsetGrant } from '../mcp-tool-grants';
|
|
2
3
|
export interface ClaudePermissionMapping {
|
|
3
4
|
ok: boolean;
|
|
4
5
|
/** CLI args to append to `claude -p ...`. Only meaningful when `ok` is true. */
|
|
@@ -131,6 +132,52 @@ export interface ClaudePermissionMapping {
|
|
|
131
132
|
* "default set minus these" this mapper can construct. Refusing is the
|
|
132
133
|
* fail-closed choice over guessing a set that might not match reality.
|
|
133
134
|
*
|
|
135
|
+
* ## Projected MCP toolset tools: `--allowedTools`, and ONLY for them
|
|
136
|
+
*
|
|
137
|
+
* The two flags above govern claude's BUILT-IN tools. A projected host
|
|
138
|
+
* toolset arrives by a third path entirely — `--mcp-config` (see
|
|
139
|
+
* `claude-adapter.ts`) — and empirically it is granted by neither: on the
|
|
140
|
+
* installed 2.1.251 binary, a `mcp__<server>__<tool>` call is auto-denied
|
|
141
|
+
* (`system:permission_denied`, `permission_denials` populated) under
|
|
142
|
+
* `--permission-mode default` AND under `--permission-mode acceptEdits`,
|
|
143
|
+
* whether or not `--tools` is present. `acceptEdits`' documented breadth
|
|
144
|
+
* (which really does cover Write and Bash — see `auto` above) stops at
|
|
145
|
+
* claude's own built-ins; MCP tools are never implicitly permitted.
|
|
146
|
+
*
|
|
147
|
+
* So a projected toolset is only actually callable if its tools appear in
|
|
148
|
+
* `--allowedTools`. Live-verified against 2.1.251 against a one-tool stdio
|
|
149
|
+
* echo server: with `--permission-mode default --tools "" --mcp-config …
|
|
150
|
+
* --strict-mcp-config`, `tools/list` reached the server and `tools/call`
|
|
151
|
+
* never did; appending `--allowedTools mcp__saleskoprobe__echo` (nothing
|
|
152
|
+
* else changed) produced `permission_denials: []`, a real `tools/call` on
|
|
153
|
+
* the server, and the tool's own result — while `system/init` still
|
|
154
|
+
* reported `tools: ["mcp__saleskoprobe__echo"]`, i.e. `--tools ""` kept
|
|
155
|
+
* every built-in disabled. This is the one use of `--allowedTools` this
|
|
156
|
+
* mapper makes, and it is a PERMISSION pre-grant (what the flag genuinely
|
|
157
|
+
* is), never a capability restriction (what the findings above prove it is
|
|
158
|
+
* not): the capability surface is still fixed by `--tools` alone.
|
|
159
|
+
*
|
|
160
|
+
* Which modes receive the grant, and why the others deliberately do not:
|
|
161
|
+
*
|
|
162
|
+
* - `readonly` and `auto`: granted. Both auto-deny MCP calls without it
|
|
163
|
+
* (live-confirmed above for each), so withholding it would offer a task
|
|
164
|
+
* a toolset it can list and never call. Nothing is widened: the granted
|
|
165
|
+
* identifiers are exactly the tools the daemon OBSERVED on exactly the
|
|
166
|
+
* servers this task projected (`daemon/mcp-tools-probe.ts`), an unobserved
|
|
167
|
+
* name is never granted, and no server-scoped `mcp__<server>` wildcard is
|
|
168
|
+
* ever emitted (that form was never verified, and it would silently grant
|
|
169
|
+
* tools a server adds later).
|
|
170
|
+
* - `confirm`: NOT granted, deliberately. Confirm's whole point is that a
|
|
171
|
+
* human answers each call through `--permission-prompt-tool`; a pre-grant
|
|
172
|
+
* would resolve those calls before the channel ever sees them, silently
|
|
173
|
+
* removing the decision the caller asked for.
|
|
174
|
+
* - `plan`: NOT granted, deliberately. Plan mode's contract is that the
|
|
175
|
+
* mutating call never actually runs. This SDK cannot know whether an
|
|
176
|
+
* opaque host toolset tool mutates anything, so pre-granting one would
|
|
177
|
+
* turn plan into an executing mode for exactly the tools it knows least
|
|
178
|
+
* about. A plan-mode task that needs its toolset callable belongs in
|
|
179
|
+
* `readonly`.
|
|
180
|
+
*
|
|
134
181
|
* `network: false` fails closed for the same reason as pi: no verified
|
|
135
182
|
* network sandbox exists for claude's Bash tool either (`claude --help`
|
|
136
183
|
* exposes no network/sandbox flag at all) — this was not independently
|
|
@@ -139,4 +186,4 @@ export interface ClaudePermissionMapping {
|
|
|
139
186
|
* task didn't run), but is the same conservative, precedent-consistent
|
|
140
187
|
* default pi already applies for an unverifiable constraint.
|
|
141
188
|
*/
|
|
142
|
-
export declare function mapPermissionPolicyToClaudeArgs(policy: PermissionPolicy): ClaudePermissionMapping;
|
|
189
|
+
export declare function mapPermissionPolicyToClaudeArgs(policy: PermissionPolicy, toolsetGrants?: readonly McpToolsetGrant[]): ClaudePermissionMapping;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { type SdkHelperHostConfig } from '../../sdk-reserved-helper-host';
|
|
1
2
|
export interface ResolvedApprovalMcpBin {
|
|
2
3
|
command: string;
|
|
3
4
|
args: string[];
|
|
4
|
-
source: 'env' | 'dist';
|
|
5
|
+
source: 'env' | 'dist' | 'host';
|
|
5
6
|
}
|
|
6
7
|
/**
|
|
7
8
|
* Resolve `byok-approval-mcp` — the small stdio MCP server
|
|
@@ -42,4 +43,4 @@ export interface ResolvedApprovalMcpBin {
|
|
|
42
43
|
* (see `claude-adapter.test.ts`), exactly like `BYOK_CLAUDE_BIN` already
|
|
43
44
|
* does for the real `claude` binary.
|
|
44
45
|
*/
|
|
45
|
-
export declare function resolveApprovalMcpBin(): ResolvedApprovalMcpBin;
|
|
46
|
+
export declare function resolveApprovalMcpBin(host?: SdkHelperHostConfig): ResolvedApprovalMcpBin;
|
|
@@ -103,5 +103,21 @@ export interface CodexPermissionMapping {
|
|
|
103
103
|
* `~/.codex/config.toml` default is more permissive than anything this
|
|
104
104
|
* adapter should ever grant implicitly. Every invocation pins both keys
|
|
105
105
|
* explicitly so behavior never depends on the end user's own codex config.
|
|
106
|
+
* Codex 0.149's per-MCP-tool approval setting is a separate, narrower
|
|
107
|
+
* control: `codex-adapter.ts` uses it for the SDK-reserved
|
|
108
|
+
* `byokagentmessage/send_agent_message` terminal protocol tool, and for the
|
|
109
|
+
* tools of the MCP servers a task's own `requiredToolsets` projected — each
|
|
110
|
+
* with an exact `enabled_tools` allowlist naming those tools and nothing
|
|
111
|
+
* else. Global approval stays `never` and `sandbox_mode` is untouched, so
|
|
112
|
+
* shell/file authority remains exactly what the mode above selected.
|
|
113
|
+
* Without that grant a projected toolset is dead weight: `approval_policy=
|
|
114
|
+
* never` refuses every MCP tool call outright ("MCP tool call requires
|
|
115
|
+
* approval, but approval policy is never"), under `workspace-write` and
|
|
116
|
+
* `read-only` alike, so the model can list a toolset's tools and never call
|
|
117
|
+
* one. The granted names are only ever the ones the daemon OBSERVED via
|
|
118
|
+
* `tools/list` on that exact server (`daemon/mcp-tools-probe.ts`) — never a
|
|
119
|
+
* configured value, never a wildcard, and never
|
|
120
|
+
* `default_tools_approval_mode`, which codex reads back happily but which
|
|
121
|
+
* was empirically ineffective under `approval_policy=never` on 0.149.0.
|
|
106
122
|
*/
|
|
107
123
|
export declare function mapPermissionPolicyToCodexArgs(policy: PermissionPolicy): CodexPermissionMapping;
|