@byok-sdk/client 0.2.0 → 0.4.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 (46) hide show
  1. package/README.md +58 -5
  2. package/dist/adapters/claude/claude-adapter.d.ts +6 -19
  3. package/dist/adapters/claude/events.d.ts +3 -0
  4. package/dist/adapters/claude/process-client.d.ts +9 -1
  5. package/dist/adapters/codex/codex-adapter.d.ts +4 -15
  6. package/dist/adapters/codex/process-runner.d.ts +4 -1
  7. package/dist/adapters/index.d.ts +4 -2
  8. package/dist/adapters/index.js +1081 -258
  9. package/dist/adapters/index.js.map +1 -1
  10. package/dist/adapters/pi/pi-adapter.d.ts +24 -15
  11. package/dist/adapters/pi/rpc-client.d.ts +9 -1
  12. package/dist/adapters/process-tree.d.ts +19 -0
  13. package/dist/adapters/provider-credential-environment.d.ts +18 -0
  14. package/dist/bin/audit-log.d.ts +12 -0
  15. package/dist/bin/byok-agent.js +2686 -912
  16. package/dist/bin/byok-agent.js.map +1 -1
  17. package/dist/bin/byok-approval-mcp.js +2 -2
  18. package/dist/bin/byok-approval-mcp.js.map +1 -1
  19. package/dist/bin/commands/workspaces.d.ts +11 -0
  20. package/dist/bin/format.d.ts +13 -0
  21. package/dist/bin/runtime-probe.d.ts +1 -1
  22. package/dist/bin/tasks-view.d.ts +13 -0
  23. package/dist/daemon/approvals.d.ts +2 -2
  24. package/dist/daemon/assertion-client.d.ts +68 -0
  25. package/dist/daemon/capabilities-client.d.ts +48 -0
  26. package/dist/daemon/connection-manager.d.ts +4 -2
  27. package/dist/daemon/control-protocol.d.ts +81 -4
  28. package/dist/daemon/control-server.d.ts +18 -1
  29. package/dist/daemon/create-daemon.d.ts +171 -3
  30. package/dist/daemon/daemon-owner.d.ts +37 -0
  31. package/dist/daemon/device-assertion-signer.d.ts +41 -0
  32. package/dist/daemon/device-keys.d.ts +15 -13
  33. package/dist/daemon/environment.d.ts +9 -9
  34. package/dist/daemon/git-workspace.d.ts +21 -0
  35. package/dist/daemon/observer.d.ts +81 -3
  36. package/dist/daemon/presence-publisher.d.ts +98 -0
  37. package/dist/daemon/runtime-capabilities.d.ts +1 -1
  38. package/dist/daemon/skill-pack-installer.d.ts +116 -0
  39. package/dist/daemon/task-runner.d.ts +156 -37
  40. package/dist/daemon/ws-transport.d.ts +3 -1
  41. package/dist/index.d.ts +25 -4
  42. package/dist/index.js +2972 -597
  43. package/dist/index.js.map +1 -1
  44. package/dist/runtime-failure.d.ts +64 -0
  45. package/dist/types.d.ts +114 -58
  46. package/package.json +4 -4
package/README.md CHANGED
@@ -5,16 +5,69 @@ WebSocket or long poll, dispatches to local Claude Code, Codex, or pi adapters,
5
5
  and exposes authenticated local diagnostics/control commands.
6
6
 
7
7
  The package installs `byok-agent` and `byok-approval-mcp` binaries. Provider
8
- credentials are not read by the dispatch plane; `@byok-sdk/keys` is separate.
8
+ credentials are not read by the dispatch plane; `@byok-sdk/keys` is a separate
9
+ install and keeps a zero dependency edge to this package.
9
10
 
10
- Pi is a required exact npm dependency and runs as an external Node subprocess;
11
- authenticate it with your own provider credentials. Claude Code and Codex
12
- remain user-installed runtimes. The SDK never reads or packages provider
13
- credentials. Hosts that only need runtime detection/composition can import the
11
+ Pi is a required exact npm dependency and runs as an external Node subprocess.
12
+ For an authoritative BYOK `dispatchSelection`, configure `piByokLauncher` with
13
+ the separately installed `byok-pi-provider-launcher`, the local non-secret
14
+ profile database path, and a stable Pi session directory. The client passes
15
+ only those paths plus provider/model ids; the launcher alone reads the OS
16
+ credential when required and spawns Pi. Both custody paths must be absolute;
17
+ missing launcher configuration fails closed.
18
+
19
+ Claude Code and Codex remain user-installed runtimes and use their own login
20
+ state. Hosts that only need runtime detection/composition can import the
14
21
  transport-free adapter surface:
15
22
 
16
23
  ```ts
17
24
  import { PiAdapter, ClaudeAdapter, CodexAdapter } from '@byok-sdk/client/adapters';
18
25
  ```
19
26
 
27
+ Version 0.4.0 intentionally breaks custom adapters: they expose a frozen
28
+ descriptor and side-effect-free `prepare()` that returns one prepared
29
+ operation; the old direct `start()` surface is removed. A published
30
+ `Session.close()` is a bounded quiescent-disposal receipt. It resolves only
31
+ after the adapter-owned process tree and task resources are gone, or rejects
32
+ with `RuntimeDisposalFailure`. The daemon keeps active/Git ownership after a
33
+ rejection and never rewrites the task's already-established terminal result.
34
+
35
+ Claude tasks can select operator-owned local stdio MCP servers by logical id.
36
+ The toolset selector carries no MCP command or connector credential:
37
+
38
+ ```ts
39
+ import { createDaemon } from '@byok-sdk/client';
40
+
41
+ createDaemon({
42
+ // ...normal device and transport configuration
43
+ mcpToolsets: {
44
+ 'salesko.prospecting': {
45
+ mcpServers: {
46
+ 'salesko-connectors': {
47
+ command: '/opt/salesko/bin/connector-mcp',
48
+ args: ['--profile', 'default'],
49
+ },
50
+ },
51
+ },
52
+ },
53
+ });
54
+ ```
55
+
56
+ The map accepts only `command` and `args`; put OAuth tokens, cookies, and other
57
+ secrets behind the local MCP process's own credential broker. Toolset offers
58
+ for Pi or Codex are declined because those adapters do not yet expose a strict
59
+ task-scoped MCP configuration boundary.
60
+
61
+ The daemon derives one sorted `configuredToolsets` snapshot from this
62
+ validated registry. Only those logical IDs are advertised in `conn.hello`
63
+ and hosted presence; command, args, environment, headers, and credentials
64
+ remain local.
65
+
66
+ For a concrete private host composition, see the
67
+ [`examples/salesko-connector-broker`](../../examples/salesko-connector-broker)
68
+ reference. It keeps `@byok-sdk/client` credential-blind while combining
69
+ OS-backed refresh-token custody, a PKCE desktop Google OAuth flow, exact domain
70
+ policy, a real read-only Gmail metadata adapter, and a closed metadata-only MCP
71
+ result.
72
+
20
73
  MIT licensed. Node.js 22.19.0 or newer.
@@ -1,8 +1,9 @@
1
- import type { TaskOfferPayload } from '@byok-sdk/protocol';
2
- import { type RuntimeAdapter, type RuntimeCapabilities, type RuntimeDetectResult, type RuntimeEnvironmentRequirements, type Session, type TaskContext } from '../../types';
1
+ import { type RuntimeAdapter, type RuntimeDetectResult, type RuntimeAdapterPrepareInput, type RuntimeAdapterPrepareResult } from '../../types';
3
2
  import { type ResolvedBin } from './resolve-bin';
4
3
  import { type ResolvedApprovalMcpBin } from './resolve-approval-mcp-bin';
5
4
  import { type SpawnFn } from './process-client';
5
+ /** The MCP server NAME this adapter registers `byok-approval-mcp` under in the generated `--mcp-config` (arbitrary, local to this file) — combined with {@link APPROVAL_TOOL_NAME} (imported, 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. */
6
+ export declare const APPROVAL_MCP_SERVER_NAME = "byokapproval";
6
7
  export interface ClaudeAdapterOptions {
7
8
  /** Override bin resolution — tests substitute the fake-claude fixture script. */
8
9
  resolveBin?: () => ResolvedBin;
@@ -112,25 +113,11 @@ export interface ClaudeAdapterOptions {
112
113
  */
113
114
  export declare class ClaudeAdapter implements RuntimeAdapter {
114
115
  private readonly options;
115
- readonly id = "claude";
116
+ readonly descriptor: import("..").RuntimeAdapterDescriptor;
116
117
  constructor(options?: ClaudeAdapterOptions);
117
118
  detect(): Promise<RuntimeDetectResult>;
118
- capabilities(): RuntimeCapabilities;
119
- /**
120
- * M5: deliberate product-boundary decision, not an oversight — byok's
121
- * current ToS posture for claude is login-state-only (`claude auth
122
- * login`'s own OAuth session — see `probeAuthPresent` below), so this
123
- * adapter declares NO credential env vars at all; env-based API-key
124
- * passthrough for claude is a separate, still-pending product decision.
125
- * A product that genuinely needs it can opt in locally per-device via
126
- * `DaemonConfig.runtimeEnvironment.claude.allow` (`create-daemon.ts`).
127
- * `baseNames` is empty too: nothing in this adapter reads a
128
- * claude-specific config-discovery variable (e.g. `CLAUDE_CONFIG_DIR`)
129
- * today — if a future version of this adapter starts reading one, it
130
- * belongs here, not left to rely on the platform baseline alone.
131
- */
132
- environmentRequirements(): RuntimeEnvironmentRequirements;
133
- start(task: TaskOfferPayload, ctx: TaskContext): Promise<Session>;
119
+ prepare(input: RuntimeAdapterPrepareInput): Promise<RuntimeAdapterPrepareResult>;
120
+ private startPrepared;
134
121
  /**
135
122
  * `claude auth status --json` is claude's OWN non-secret login-state
136
123
  * signal (see the credential-isolation rule on `RuntimeAdapter` in
@@ -1,4 +1,5 @@
1
1
  import type { AgentEvent } from '@byok-sdk/protocol';
2
+ import { RuntimeExecutionFailure } from '../../runtime-failure';
2
3
  /**
3
4
  * A raw parsed line from `claude --output-format stream-json`. Shapes vary
4
5
  * a lot by `type` (and, for `system`, by `subtype`) — see the doc comments
@@ -38,6 +39,8 @@ export interface MapClaudeMessageOptions {
38
39
  }
39
40
  export interface MapClaudeMessageResult {
40
41
  events: AgentEvent[];
42
+ /** Present only when this frame is authoritative terminal failure evidence. */
43
+ terminalFailure?: RuntimeExecutionFailure;
41
44
  /**
42
45
  * Set when this exact frame (or, for `assistant`/`user` frames, one
43
46
  * content block inside it) was genuinely unrecognized — a frame/subtype/
@@ -52,6 +52,9 @@ export declare class ClaudeProcessClient {
52
52
  private readonly eventQueue;
53
53
  private closed;
54
54
  private exitError;
55
+ private readonly closedPromise;
56
+ private resolveClosed;
57
+ private disposalAttempt;
55
58
  private readonly stderrRing;
56
59
  private readonly unmappedFrameCounts;
57
60
  private sessionId;
@@ -81,6 +84,8 @@ export declare class ClaudeProcessClient {
81
84
  waitForInit(): Promise<string>;
82
85
  /** Every parsed stream-json line — `system/init` is consumed internally (see `waitForInit`) but is also forwarded here like any other frame, so routine-frame accounting in `ClaudeSession`'s mapper stays uniform. */
83
86
  get events(): AsyncIterable<ClaudeStreamMessage>;
87
+ /** Local transport diagnostic retained when the process closes; consumers classify it at the session boundary. */
88
+ get terminalError(): Error | undefined;
84
89
  /**
85
90
  * Record a claude stream-json frame/subtype/content-block label that
86
91
  * `ClaudeSession`'s event iterator (`../claude-adapter.ts`) decided has
@@ -92,8 +97,11 @@ export declare class ClaudeProcessClient {
92
97
  * post-mortem without separate log scraping.
93
98
  */
94
99
  recordUnmappedFrame(label: string): void;
95
- /** Best-effort teardown. SIGTERM on POSIX; `taskkill /T /F` on Windows to also reap child processes claude itself spawned (e.g. Bash) — mirrors pi's cross-platform `kill()` exactly. Empirically confirmed on this (POSIX) machine: a running claude process exits cleanly within ~1s of SIGTERM (observed exit code 143 = 128+SIGTERM, i.e. claude catches and handles the signal itself rather than needing a harder kill). */
100
+ /** Immediate process-tree termination request. `dispose()` is the settlement receipt. */
96
101
  kill(): void;
102
+ waitClosed(): Promise<void>;
103
+ dispose(): Promise<void>;
104
+ private processTreeOptions;
97
105
  private onData;
98
106
  private onLine;
99
107
  private onStderr;
@@ -1,5 +1,4 @@
1
- import type { TaskOfferPayload } from '@byok-sdk/protocol';
2
- import { type RuntimeAdapter, type RuntimeCapabilities, type RuntimeDetectResult, type RuntimeEnvironmentRequirements, type Session, type TaskContext } from '../../types';
1
+ import { type RuntimeAdapter, type RuntimeDetectResult, type RuntimeAdapterPrepareInput, type RuntimeAdapterPrepareResult } from '../../types';
3
2
  import { type ResolvedBin } from './resolve-bin';
4
3
  import { type SpawnFn } from './process-runner';
5
4
  export interface CodexAdapterOptions {
@@ -52,7 +51,7 @@ export interface CodexAdapterOptions {
52
51
  */
53
52
  export declare class CodexAdapter implements RuntimeAdapter {
54
53
  private readonly options;
55
- readonly id = "codex";
54
+ readonly descriptor: import("..").RuntimeAdapterDescriptor;
56
55
  constructor(options?: CodexAdapterOptions);
57
56
  detect(): Promise<RuntimeDetectResult>;
58
57
  /**
@@ -82,17 +81,7 @@ export declare class CodexAdapter implements RuntimeAdapter {
82
81
  * empirical pass on a logged-out machine, not asserted as verified.
83
82
  */
84
83
  private probeAuthPresent;
85
- capabilities(): RuntimeCapabilities;
86
- /**
87
- * M5: same deliberate posture as the claude adapter (see its own doc
88
- * comment) — codex authenticates via its own `codex login`-managed
89
- * ChatGPT OAuth session (`probeAuthPresent` above), not an env var, so
90
- * there is no credential env var this adapter needs forwarded; env-based
91
- * API-key passthrough remains a separate, pending product decision. No
92
- * `baseNames` either: nothing in this adapter reads a codex-specific
93
- * config-discovery variable (e.g. `CODEX_HOME`) today.
94
- */
95
- environmentRequirements(): RuntimeEnvironmentRequirements;
96
- start(task: TaskOfferPayload, ctx: TaskContext): Promise<Session>;
84
+ prepare(input: RuntimeAdapterPrepareInput): Promise<RuntimeAdapterPrepareResult>;
85
+ private startPrepared;
97
86
  private resolveBin;
98
87
  }
@@ -59,13 +59,14 @@ export declare class CodexProcessRunner {
59
59
  private exitSignal;
60
60
  private readonly closedPromise;
61
61
  private resolveClosed;
62
+ private disposalAttempt;
62
63
  constructor(options: CodexProcessOptions);
63
64
  private finishClosing;
64
65
  /** Resolves once the child process has fully exited (both exit and stdio-flush guaranteed — see the `close` listener above). Never rejects. */
65
66
  waitClosed(): Promise<void>;
66
67
  get isClosed(): boolean;
67
68
  /**
68
- * Best-effort teardown. SIGTERM on POSIX: SIGINT was empirically confirmed
69
+ * Immediate tree termination request. SIGTERM on POSIX: SIGINT was empirically confirmed
69
70
  * to be silently ignored by `codex exec` (a real, direct test — a 60s
70
71
  * shell `sleep` ran to full, unaffected completion despite SIGINT sent at
71
72
  * t=4s) — a genuine, evidence-based correction to this task's own initial
@@ -78,6 +79,8 @@ export declare class CodexProcessRunner {
78
79
  * `../pi/rpc-client.ts`'s own cross-platform convention.
79
80
  */
80
81
  kill(): void;
82
+ dispose(): Promise<void>;
83
+ private processTreeOptions;
81
84
  /** Builds a descriptive error folding in the exit code/signal and the stderr tail — mirrors `PiRpcClient.buildExitError`'s reasoning: a post-mortem on a failed start/resume should never need separately re-running codex by hand with a raw JSONL logger to learn why. */
82
85
  buildExitError(context: string): Error;
83
86
  private onData;
@@ -1,7 +1,9 @@
1
- export type { RuntimeAdapter, RuntimeCapabilities, RuntimeDetectResult, } from '../types';
1
+ export type { RuntimeAdapter, RuntimeAdapterDescriptor, RuntimeAdapterPrepareInput, RuntimeAdapterPrepareResult, RuntimeAdapterRejectedOperation, RuntimeAdapterPreparedOperation, PreparedRuntimeOperation, RuntimeOperationManifest, RuntimeOperationStartInput, RuntimeCapabilities, RuntimeDetectResult, } from '../types';
2
2
  export type { RuntimeEnvironmentRequirements } from '../daemon/environment';
3
+ export { RuntimeDisposalFailure, RuntimeExecutionFailure } from '../runtime-failure';
4
+ export type { RuntimeDisposalFailureInput, RuntimeDisposalStage, RuntimeExecutionFailureInput, RuntimeFailureCategory, RuntimeFailurePhase, RuntimeRetryDisposition, } from '../runtime-failure';
3
5
  export { PiAdapter } from './pi/pi-adapter';
4
- export type { PiAdapterOptions } from './pi/pi-adapter';
6
+ export type { PiAdapterOptions, PiByokLauncherConfig } from './pi/pi-adapter';
5
7
  export { PI_PACKAGE_NAME } from './pi/resolve-bin';
6
8
  export { ClaudeAdapter } from './claude/claude-adapter';
7
9
  export type { ClaudeAdapterOptions } from './claude/claude-adapter';