@maiaos/sdk 0.1.0-canary.2

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 (198) hide show
  1. package/README.md +177 -0
  2. package/dist/agent-permission/agent-permission.d.ts +9 -0
  3. package/dist/agent-permission/agent-permission.js +5 -0
  4. package/dist/agent-permission/effect.d.ts +4 -0
  5. package/dist/agent-permission/effect.js +34 -0
  6. package/dist/agent-permission/index.d.ts +2 -0
  7. package/dist/agent-permission/index.js +2 -0
  8. package/dist/approval/approval.d.ts +10 -0
  9. package/dist/approval/approval.js +5 -0
  10. package/dist/approval/effect.d.ts +5 -0
  11. package/dist/approval/effect.js +43 -0
  12. package/dist/approval/index.d.ts +2 -0
  13. package/dist/approval/index.js +2 -0
  14. package/dist/call/call.d.ts +26 -0
  15. package/dist/call/call.js +6 -0
  16. package/dist/call/effect.d.ts +5 -0
  17. package/dist/call/effect.js +46 -0
  18. package/dist/call/index.d.ts +2 -0
  19. package/dist/call/index.js +2 -0
  20. package/dist/client/effect.d.ts +8 -0
  21. package/dist/client/effect.js +283 -0
  22. package/dist/client/index.d.ts +2 -0
  23. package/dist/client/index.js +2 -0
  24. package/dist/client/local-node-client.d.ts +100 -0
  25. package/dist/client/local-node-client.js +4 -0
  26. package/dist/connection/connection.d.ts +19 -0
  27. package/dist/connection/connection.js +5 -0
  28. package/dist/connection/effect.d.ts +5 -0
  29. package/dist/connection/effect.js +119 -0
  30. package/dist/connection/index.d.ts +2 -0
  31. package/dist/connection/index.js +2 -0
  32. package/dist/container/container.d.ts +14 -0
  33. package/dist/container/container.js +5 -0
  34. package/dist/container/effect.d.ts +4 -0
  35. package/dist/container/effect.js +90 -0
  36. package/dist/container/index.d.ts +2 -0
  37. package/dist/container/index.js +2 -0
  38. package/dist/discovery/discovery.d.ts +11 -0
  39. package/dist/discovery/discovery.js +5 -0
  40. package/dist/discovery/effect.d.ts +5 -0
  41. package/dist/discovery/effect.js +44 -0
  42. package/dist/discovery/index.d.ts +2 -0
  43. package/dist/discovery/index.js +2 -0
  44. package/dist/execution/effect.d.ts +4 -0
  45. package/dist/execution/effect.js +8 -0
  46. package/dist/execution/index.d.ts +2 -0
  47. package/dist/execution/index.js +2 -0
  48. package/dist/execution/relocation.d.ts +10 -0
  49. package/dist/execution/relocation.js +4 -0
  50. package/dist/feature-bindings/feature-bindings.d.ts +10 -0
  51. package/dist/feature-bindings/feature-bindings.js +2 -0
  52. package/dist/feature-bindings/index.d.ts +2 -0
  53. package/dist/feature-bindings/index.js +2 -0
  54. package/dist/hold/effect.d.ts +5 -0
  55. package/dist/hold/effect.js +61 -0
  56. package/dist/hold/hold.d.ts +12 -0
  57. package/dist/hold/hold.js +5 -0
  58. package/dist/hold/index.d.ts +2 -0
  59. package/dist/hold/index.js +2 -0
  60. package/dist/index.d.ts +26 -0
  61. package/dist/index.js +21 -0
  62. package/dist/interaction/effect.d.ts +5 -0
  63. package/dist/interaction/effect.js +79 -0
  64. package/dist/interaction/index.d.ts +2 -0
  65. package/dist/interaction/index.js +2 -0
  66. package/dist/interaction/interaction.d.ts +12 -0
  67. package/dist/interaction/interaction.js +5 -0
  68. package/dist/node/attach.d.ts +11 -0
  69. package/dist/node/attach.js +33 -0
  70. package/dist/node/bridge-frame.d.ts +18 -0
  71. package/dist/node/bridge-frame.js +67 -0
  72. package/dist/node/bridge.d.ts +31 -0
  73. package/dist/node/bridge.js +148 -0
  74. package/dist/node/discovery.d.ts +187 -0
  75. package/dist/node/discovery.js +408 -0
  76. package/dist/node/effect.d.ts +9 -0
  77. package/dist/node/effect.js +9 -0
  78. package/dist/node/fetch.d.ts +2 -0
  79. package/dist/node/fetch.js +2 -0
  80. package/dist/node/http.d.ts +27 -0
  81. package/dist/node/http.js +258 -0
  82. package/dist/node/index.d.ts +3 -0
  83. package/dist/node/index.js +3 -0
  84. package/dist/node/local-node.d.ts +26 -0
  85. package/dist/node/local-node.js +67 -0
  86. package/dist/node/session.d.ts +15 -0
  87. package/dist/node/session.js +27 -0
  88. package/dist/node/ssh.d.ts +16 -0
  89. package/dist/node/ssh.js +74 -0
  90. package/dist/node/transport.d.ts +52 -0
  91. package/dist/node/transport.js +211 -0
  92. package/dist/node-changes/effect.d.ts +11 -0
  93. package/dist/node-changes/effect.js +61 -0
  94. package/dist/node-changes/index.d.ts +2 -0
  95. package/dist/node-changes/index.js +2 -0
  96. package/dist/node-changes/node-changes.d.ts +21 -0
  97. package/dist/node-changes/node-changes.js +23 -0
  98. package/dist/port-lease/effect.d.ts +5 -0
  99. package/dist/port-lease/effect.js +53 -0
  100. package/dist/port-lease/index.d.ts +2 -0
  101. package/dist/port-lease/index.js +2 -0
  102. package/dist/port-lease/port-lease.d.ts +11 -0
  103. package/dist/port-lease/port-lease.js +5 -0
  104. package/dist/presentation/client.d.ts +10 -0
  105. package/dist/presentation/client.js +4 -0
  106. package/dist/presentation/effect.d.ts +5 -0
  107. package/dist/presentation/effect.js +30 -0
  108. package/dist/presentation/index.d.ts +5 -0
  109. package/dist/presentation/index.js +3 -0
  110. package/dist/presentation/project-list.d.ts +7 -0
  111. package/dist/presentation/project-list.js +24 -0
  112. package/dist/presentation/session-list.d.ts +7 -0
  113. package/dist/presentation/session-list.js +32 -0
  114. package/dist/project-guard/effect.d.ts +5 -0
  115. package/dist/project-guard/effect.js +39 -0
  116. package/dist/project-guard/index.d.ts +2 -0
  117. package/dist/project-guard/index.js +2 -0
  118. package/dist/project-guard/project-guard.d.ts +10 -0
  119. package/dist/project-guard/project-guard.js +5 -0
  120. package/dist/project-workspace/effect.d.ts +5 -0
  121. package/dist/project-workspace/effect.js +124 -0
  122. package/dist/project-workspace/index.d.ts +2 -0
  123. package/dist/project-workspace/index.js +2 -0
  124. package/dist/project-workspace/project-workspace.d.ts +23 -0
  125. package/dist/project-workspace/project-workspace.js +4 -0
  126. package/dist/provider-pool/effect.d.ts +4 -0
  127. package/dist/provider-pool/effect.js +5 -0
  128. package/dist/provider-pool/index.d.ts +2 -0
  129. package/dist/provider-pool/index.js +2 -0
  130. package/dist/provider-pool/provider-pool.d.ts +7 -0
  131. package/dist/provider-pool/provider-pool.js +4 -0
  132. package/dist/remote-node/effect.d.ts +4 -0
  133. package/dist/remote-node/effect.js +57 -0
  134. package/dist/remote-node/index.d.ts +2 -0
  135. package/dist/remote-node/index.js +2 -0
  136. package/dist/remote-node/remote-node.d.ts +12 -0
  137. package/dist/remote-node/remote-node.js +5 -0
  138. package/dist/request/classify.d.ts +15 -0
  139. package/dist/request/classify.js +96 -0
  140. package/dist/request/client-error.d.ts +10 -0
  141. package/dist/request/client-error.js +11 -0
  142. package/dist/request/effect.d.ts +22 -0
  143. package/dist/request/effect.js +104 -0
  144. package/dist/request/envelope-schema.d.ts +2 -0
  145. package/dist/request/envelope-schema.js +2 -0
  146. package/dist/request/index.d.ts +5 -0
  147. package/dist/request/index.js +4 -0
  148. package/dist/request/maia-client.d.ts +21 -0
  149. package/dist/request/maia-client.js +9 -0
  150. package/dist/request/options.d.ts +9 -0
  151. package/dist/request/options.js +2 -0
  152. package/dist/run-ledger/effect.d.ts +5 -0
  153. package/dist/run-ledger/effect.js +72 -0
  154. package/dist/run-ledger/index.d.ts +2 -0
  155. package/dist/run-ledger/index.js +2 -0
  156. package/dist/run-ledger/run-ledger.d.ts +12 -0
  157. package/dist/run-ledger/run-ledger.js +2 -0
  158. package/dist/session/effect.d.ts +4 -0
  159. package/dist/session/effect.js +7 -0
  160. package/dist/session/index.d.ts +2 -0
  161. package/dist/session/index.js +2 -0
  162. package/dist/session/mailbox.d.ts +9 -0
  163. package/dist/session/mailbox.js +4 -0
  164. package/dist/session-creation/effect.d.ts +25 -0
  165. package/dist/session-creation/effect.js +269 -0
  166. package/dist/session-creation/index.d.ts +3 -0
  167. package/dist/session-creation/index.js +3 -0
  168. package/dist/session-creation/session-creation.d.ts +18 -0
  169. package/dist/session-creation/session-creation.js +24 -0
  170. package/dist/session-creation/tasks.d.ts +69 -0
  171. package/dist/session-creation/tasks.js +37 -0
  172. package/dist/session-view/index.d.ts +2 -0
  173. package/dist/session-view/index.js +2 -0
  174. package/dist/session-view/view.d.ts +42 -0
  175. package/dist/session-view/view.js +137 -0
  176. package/dist/stream/effect.d.ts +29 -0
  177. package/dist/stream/effect.js +77 -0
  178. package/dist/stream/index.d.ts +2 -0
  179. package/dist/stream/index.js +2 -0
  180. package/dist/stream/stream.d.ts +9 -0
  181. package/dist/stream/stream.js +2 -0
  182. package/dist/voice/effect.d.ts +7 -0
  183. package/dist/voice/effect.js +71 -0
  184. package/dist/voice/index.d.ts +4 -0
  185. package/dist/voice/index.js +3 -0
  186. package/dist/voice/managed-turn.d.ts +9 -0
  187. package/dist/voice/managed-turn.js +4 -0
  188. package/dist/voice/orchestrator-contract.d.ts +5 -0
  189. package/dist/voice/orchestrator-contract.js +4 -0
  190. package/dist/voice/orchestrator.d.ts +25 -0
  191. package/dist/voice/orchestrator.js +169 -0
  192. package/dist/voice/pi-relay-contract.d.ts +4 -0
  193. package/dist/voice/pi-relay-contract.js +2 -0
  194. package/dist/voice/pi-relay.d.ts +12 -0
  195. package/dist/voice/pi-relay.js +9 -0
  196. package/dist/voice/wire-schema.d.ts +215 -0
  197. package/dist/voice/wire-schema.js +16 -0
  198. package/package.json +84 -0
package/README.md ADDED
@@ -0,0 +1,177 @@
1
+ # `@maiaos/sdk`
2
+
3
+ [![npm canary](https://img.shields.io/npm/v/@maiaos/sdk/canary?label=npm%20canary)](https://www.npmjs.com/package/@maiaos/sdk)
4
+
5
+ The TypeScript SDK for Maia Node: typed, validated calls to create and start
6
+ AI coding agent Sessions (Claude Code, Codex), send turns, wait for results,
7
+ read receipts and observe events, from any Node.js tool or Maia client.
8
+
9
+ `@maiaos/sdk` is the only supported request boundary between product clients
10
+ and Maia Node. The `maia` CLI, the `maia mcp` MCP server and the Desktop and
11
+ Expo clients all use it. Use it when you build your own tool or orchestrator on
12
+ top of a local Node; it transports typed operations but never owns business
13
+ authority.
14
+
15
+ ## Install
16
+
17
+ ```sh
18
+ pnpm add @maiaos/sdk@canary
19
+ ```
20
+
21
+ Only `canary` builds are published. They are not release-qualified and can lag
22
+ the source in this repository; npm's automatic `latest` tag also points at a
23
+ canary build. A Node must be running locally (see the
24
+ [quick start](../../README.md#quick-start)).
25
+
26
+ ## Example
27
+
28
+ ```ts
29
+ import { connectNodeApi } from "@maiaos/sdk/node";
30
+
31
+ const { client, status } = await connectNodeApi({ profile: "default" });
32
+ console.log(status.lifecycle); // "ready"
33
+
34
+ const projects = await client.listProjects(
35
+ { afterCursor: "0", limit: 20 },
36
+ { messageId: "request_projects_1" },
37
+ );
38
+ for (const project of projects.items) console.log(project.id, project.name);
39
+ ```
40
+
41
+ `connectNodeApi` finds the profile's private connection descriptor, reads its
42
+ credential and proves the Node's identity with an authenticated `node.status`
43
+ before it returns the client.
44
+
45
+ ## Key concepts
46
+
47
+ - **One typed client.** `LocalNodeClient` has one method per operation, for
48
+ example `createSession`, `startSession`, `sendTurn`, `waitTurns`,
49
+ `observeSessions`, `stopSession`, `resumeSession`, `diffSession`,
50
+ `archiveSession`, `getReceipt`,
51
+ `listConnections` and `showConnectionUsage`. Parameters and results are the
52
+ `@maiaos/protocol` types, validated on both sides. Human-only methods such as
53
+ `previewHoldPlace`, `confirmHoldPlace`, `previewHoldRelease`,
54
+ `confirmHoldRelease` and `listHolds` check that the Node echoes the exact
55
+ binding they sent.
56
+ - **Typed call.** `call(method, parameters, options)` serves every operation
57
+ whose feature descriptor binds `sdk.operation: "call"` (today
58
+ `reference.resolve` and `session.rename`; `LOCAL_NODE_CALL_METHODS` lists
59
+ them from a static table the type checker holds to the descriptors, so a
60
+ client does not bundle the feature registry): parameters and results are
61
+ typed from the protocol unions, the payload is validated before sending,
62
+ and the answer must name the method and, for a command, carry a receipt
63
+ with the command ID sent. An unconfirmed command fails `outcome_unknown`.
64
+ Such an operation has no method of its own.
65
+ - **Request options.** Every call takes `{ messageId, signal? }`. The
66
+ `AbortSignal` cancels the request; a mutation cancelled after dispatch
67
+ reports `outcome_unknown` instead of guessing.
68
+ - **Errors.** Failures are `MaiaClientError` values with a stable code
69
+ (`transport_failure`, `cancelled`, `outcome_unknown`, `remote_error`, ...)
70
+ and, for Node rejections, the protocol error. Reconcile an unknown outcome
71
+ with `getReceipt` and the same command ID; never retry with a new one.
72
+ - **Errors as one value.** `classifyClientError` turns any failure into a
73
+ `MaiaError` (`_tag: "MaiaError"`); `mutation: true` marks a request that may
74
+ have changed Node state. Its `kind` is `cancelled`, `conflict`, `declined` (a person declined the
75
+ native confirmation; nothing was sent), `denied`, `invalid`, `not_found`,
76
+ `offline`, `outcome_unknown` (a mutation's answer never arrived), `refused`
77
+ or `unavailable`, plus the Node's `code` and `retryable`. The CLI and
78
+ clients act on `kind`, never on a code string.
79
+ - **Session tasks.** `planSessionCreation` splits text into tasks (one per
80
+ line, or the whole text; at most 32 of at most 16 KiB each), picks the
81
+ Workspace (a Project's ready Workspaces, its main checkout first, through
82
+ `orderExecutionWorkspaces`; a choice for the caller, which the Node still
83
+ validates) and mints every command ID once. `createSessions` runs each
84
+ item, four at a time: `session.create`, `session.start`,
85
+ `awaitSessionRunning`, then the task as the first `turn.send`. Each item
86
+ ends `sent` (or `started` without a task), `refused` with its `MaiaError`,
87
+ or `unknown`. Each outcome has a required `receipts` field with the Node's
88
+ receipt of every step that committed (`create`, `start`, `send`; `{}`
89
+ before any). When `session.create`, `session.start` or `turn.send` fails,
90
+ refused or unknown, the error carries that step's `commandId`; only an
91
+ `unknown` one needs reconciling with `receipt.get`. A `session.show`
92
+ failure has none. A caller passing hand-built `previous` outcomes adds
93
+ `receipts: {}`. Called again with `previous` outcomes, it replays only the
94
+ unsettled items with the same command IDs and request bodies, so the Node
95
+ answers with the original Sessions and turns and no turn is sent twice.
96
+ The SDK composes existing operations here and owns no authority.
97
+ `@maiaos/sdk/node/effect` has the same as `planSessionCreationEffect`,
98
+ `createSessionsEffect` and `awaitSessionRunningEffect`.
99
+ - **Node changes.** `watchNodeChanges(relay, { instanceId, newId })` builds
100
+ each `observe.events` subscribe message, checks every frame's size, schema
101
+ and correlation, and yields `records` and `resync` changes; when the
102
+ platform `StreamRelay` closes it resubscribes from the last cursor, and a
103
+ gap or reset yields a `resync`. `reduceNodeChanges` is the pure frame
104
+ step.
105
+ - **Session attach (S12b).** `attachSession` (`@maiaos/sdk/node`) yields one
106
+ Session's `session.attach` frames; `attachSessionEffect`
107
+ (`@maiaos/sdk/node/effect`) discovers the Node first. The pure
108
+ `reduceSessionAttach` reducer in the root entry folds frames into the view
109
+ every client renders, with `sessionAttachCursor` for a reattach.
110
+ - **Transport limits.** The Node.js adapter accepts only the exact
111
+ `127.0.0.1` origin, bounds bodies to 1 MiB, admits eight concurrent
112
+ requests per transport and applies a five-second deadline.
113
+
114
+ | Entry point | Contents |
115
+ | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
116
+ | `@maiaos/sdk` | Platform-neutral `LocalNodeClient`, request options, errors, attach reducer |
117
+ | `@maiaos/sdk/node` | `connectNodeApi`, `createNodeApiClient` and WebSocket observations (Node.js) |
118
+ | `@maiaos/sdk/node/effect` | The same discovery and client as Effect values, for Effect programs (Node.js); `connectSessionNodeApiEffect` connects as one executor Session from its launch environment; `openNodeBridge` speaks the SSH stdio bridge over a process the caller spawned, with `sshCommandArguments` and `bridgeScript` to build it |
119
+ | `@maiaos/sdk/voice-orchestrator` | Voice orchestrator prompt and tool schemas for Realtime clients |
120
+ | `@maiaos/sdk/voice-pi-relay` | Voice-to-Pi relay contracts |
121
+
122
+ Browser and mobile bundles import only the root entry, so they never receive
123
+ Node.js filesystem modules or the profile credential.
124
+
125
+ ## Status
126
+
127
+ Source-implemented candidate. Methods mirror the registered operations; many
128
+ are release-disabled at the Node. The SDK never starts or stops a Node, reads
129
+ Node storage or supervises processes.
130
+
131
+ ### Target observation client
132
+
133
+ Planned, not exported: one aggregate, transport-neutral observation client
134
+ generated from the protocol.
135
+
136
+ ```ts
137
+ client.observations.snapshot(query, options);
138
+ client.observations.subscribe(query, { after, signal });
139
+ client.observations.session({ agentSessionId, includeContent }, options);
140
+ client.observations.pipeline({ processorId, partitionId }, options);
141
+ ```
142
+
143
+ `subscribe` opens one authorized feed for any number of Projects and Sessions
144
+ with a signed, resumable cursor; slow consumers get typed gap and reset
145
+ results rather than backpressuring workers. A generated, reflective operation
146
+ catalog (`client.operations.list`, `show`, `invoke`) is also planned.
147
+
148
+ ## How it fits in Maia
149
+
150
+ ```text
151
+ product client ──► @maiaos/sdk ── authenticated loopback HTTP ──► Maia Node
152
+ │
153
+ └── types and schemas from @maiaos/protocol
154
+ ```
155
+
156
+ See [`ARCHITECTURE.md`](../../ARCHITECTURE.md) and the
157
+ [Node README](../../services/node/README.md).
158
+
159
+ ## Development
160
+
161
+ ```sh
162
+ pnpm --filter @maiaos/sdk build
163
+ pnpm --filter @maiaos/sdk lint
164
+ pnpm --filter @maiaos/sdk typecheck
165
+ pnpm --filter @maiaos/sdk test
166
+ ```
167
+
168
+ ## Documentation
169
+
170
+ - [Normative contracts](../../docs/reference/contracts.md)
171
+ - [CLI reference](../../docs/reference/cli.md) for the JSON projections of the
172
+ same operations
173
+ - [`@maiaos/protocol`](../protocol/README.md)
174
+
175
+ ## License
176
+
177
+ No license has been published yet. All rights reserved.
@@ -0,0 +1,9 @@
1
+ import type { AgentPermissionConfirmParameters, AgentPermissionConfirmResult, AgentPermissionPreviewParameters, AgentPermissionPreviewResult } from "@maiaos/protocol";
2
+ import type { LocalNodeRequester, LocalNodeRequestOptions } from "../request/index.js";
3
+ export declare const makeAgentPermissionClient: (request: LocalNodeRequester) => AgentPermissionClient;
4
+ export type AgentPermissionClient = {
5
+ readonly confirmAgentPermission: (parameters: AgentPermissionConfirmParameters, options: LocalNodeRequestOptions) => Promise<AgentPermissionConfirmResult>;
6
+ readonly previewAgentPermission: (parameters: AgentPermissionPreviewParameters, options: LocalNodeRequestOptions) => Promise<AgentPermissionPreviewResult>;
7
+ };
8
+ export { type AgentPermissionConfirmParameters, agentPermissionConfirmParametersSchema, type AgentPermissionConfirmResult, type AgentPermissionPreviewParameters, agentPermissionPreviewParametersSchema, type AgentPermissionPreviewResult, } from "@maiaos/protocol";
9
+ //# sourceMappingURL=agent-permission.d.ts.map
@@ -0,0 +1,5 @@
1
+ import { fromPromiseRequester, toPromiseClient } from "../request/effect.js";
2
+ import { makeAgentPermissionOperations } from "./effect.js";
3
+ export const makeAgentPermissionClient = (request) => toPromiseClient(makeAgentPermissionOperations(fromPromiseRequester(request)));
4
+ export { agentPermissionConfirmParametersSchema, agentPermissionPreviewParametersSchema, } from "@maiaos/protocol";
5
+ //# sourceMappingURL=agent-permission.js.map
@@ -0,0 +1,4 @@
1
+ import type { EffectClient, LocalNodeEffectRequester } from "../request/effect.js";
2
+ import type { AgentPermissionClient } from "./agent-permission.js";
3
+ export declare const makeAgentPermissionOperations: <TError>(request: LocalNodeEffectRequester<TError>) => EffectClient<AgentPermissionClient, TError>;
4
+ //# sourceMappingURL=effect.d.ts.map
@@ -0,0 +1,34 @@
1
+ import { agentPermissionConfirmResultSchema, agentPermissionPreviewResultSchema, } from "@maiaos/protocol";
2
+ import { MaiaClientError } from "../request/index.js";
3
+ const requireBinding = (result, parameters) => {
4
+ const operations = [...new Set(parameters.operationIds)].sort();
5
+ if (result.commandId !== parameters.commandId ||
6
+ result.sessionId !== parameters.sessionId ||
7
+ result.workspaceId !== parameters.workspaceId ||
8
+ result.expectedSessionRevision !== parameters.expectedSessionRevision ||
9
+ result.expectedWorkspaceRevision !== parameters.expectedWorkspaceRevision ||
10
+ result.definitionRef.key !== parameters.definitionRef.key ||
11
+ result.definitionRef.version !== parameters.definitionRef.version ||
12
+ result.definitionRef.contentDigest !==
13
+ parameters.definitionRef.contentDigest ||
14
+ result.operationIds.length !== operations.length ||
15
+ result.operationIds.some((id, index) => id !== operations[index]))
16
+ throw new MaiaClientError("invalid_response", "The Agent permission response did not match the request.");
17
+ return result;
18
+ };
19
+ const parseConfirmation = (value, parameters) => {
20
+ const result = agentPermissionConfirmResultSchema.parse(value);
21
+ requireBinding(result.grant, parameters);
22
+ if (result.grant.inputDigest !== parameters.inputDigest)
23
+ throw new MaiaClientError("invalid_response", "The Agent permission digest did not match the request.");
24
+ return result;
25
+ };
26
+ export const makeAgentPermissionOperations = (request) => ({
27
+ confirmAgentPermission: (parameters, options) => request({ method: "session.agent-permission.confirm", parameters }, {
28
+ parse: (value) => parseConfirmation(value, parameters),
29
+ }, options),
30
+ previewAgentPermission: (parameters, options) => request({ method: "session.agent-permission.preview", parameters }, {
31
+ parse: (value) => requireBinding(agentPermissionPreviewResultSchema.parse(value), parameters),
32
+ }, options),
33
+ });
34
+ //# sourceMappingURL=effect.js.map
@@ -0,0 +1,2 @@
1
+ export { type AgentPermissionClient, type AgentPermissionConfirmParameters, agentPermissionConfirmParametersSchema, type AgentPermissionConfirmResult, type AgentPermissionPreviewParameters, agentPermissionPreviewParametersSchema, type AgentPermissionPreviewResult, makeAgentPermissionClient, } from "./agent-permission.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export { agentPermissionConfirmParametersSchema, agentPermissionPreviewParametersSchema, makeAgentPermissionClient, } from "./agent-permission.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,10 @@
1
+ import type { ApprovalListParameters, ApprovalListResult, ApprovalRespondParameters, ApprovalRespondResult, ApprovalShowParameters, ApprovalShowResult } from "@maiaos/protocol";
2
+ import type { LocalNodeRequester, LocalNodeRequestOptions } from "../request/index.js";
3
+ export type ApprovalClient = {
4
+ readonly listApprovals: (parameters: ApprovalListParameters, options: LocalNodeRequestOptions) => Promise<ApprovalListResult>;
5
+ readonly respondToApproval: (parameters: ApprovalRespondParameters, options: LocalNodeRequestOptions) => Promise<ApprovalRespondResult>;
6
+ readonly showApproval: (parameters: ApprovalShowParameters, options: LocalNodeRequestOptions) => Promise<ApprovalShowResult>;
7
+ };
8
+ export declare const makeApprovalClient: (request: LocalNodeRequester) => ApprovalClient;
9
+ export { type Approval, APPROVAL_ERROR_CODES, APPROVAL_SCHEMA_VERSION, APPROVAL_TTL_MILLISECONDS, type ApprovalErrorCode, type ApprovalListParameters, approvalListParametersSchema, type ApprovalListResult, approvalListResultSchema, type ApprovalRespondParameters, approvalRespondParametersSchema, type ApprovalRespondResult, approvalRespondResultSchema, approvalSchema, type ApprovalShowParameters, approvalShowParametersSchema, type ApprovalShowResult, approvalShowResultSchema, MAX_APPROVAL_PAGE_SIZE, } from "@maiaos/protocol";
10
+ //# sourceMappingURL=approval.d.ts.map
@@ -0,0 +1,5 @@
1
+ import { fromPromiseRequester, toPromiseClient } from "../request/effect.js";
2
+ import { makeApprovalOperations } from "./effect.js";
3
+ export const makeApprovalClient = (request) => toPromiseClient(makeApprovalOperations(fromPromiseRequester(request)));
4
+ export { APPROVAL_ERROR_CODES, APPROVAL_SCHEMA_VERSION, APPROVAL_TTL_MILLISECONDS, approvalListParametersSchema, approvalListResultSchema, approvalRespondParametersSchema, approvalRespondResultSchema, approvalSchema, approvalShowParametersSchema, approvalShowResultSchema, MAX_APPROVAL_PAGE_SIZE, } from "@maiaos/protocol";
5
+ //# sourceMappingURL=approval.js.map
@@ -0,0 +1,5 @@
1
+ import { type EffectClient, type LocalNodeEffectRequester } from "../request/effect.js";
2
+ import { MaiaClientError } from "../request/index.js";
3
+ import type { ApprovalClient } from "./approval.js";
4
+ export declare const makeApprovalOperations: <TError>(request: LocalNodeEffectRequester<TError>) => EffectClient<ApprovalClient, MaiaClientError | TError>;
5
+ //# sourceMappingURL=effect.d.ts.map
@@ -0,0 +1,43 @@
1
+ import { approvalListResultSchema, approvalRespondResultSchema, approvalShowResultSchema, } from "@maiaos/protocol";
2
+ import { verifiedMutation, } from "../request/effect.js";
3
+ import { MaiaClientError } from "../request/index.js";
4
+ const requireMatch = (matches) => {
5
+ if (!matches)
6
+ throw new MaiaClientError("invalid_response", "The approval response did not match the request.");
7
+ };
8
+ const parseList = (value, input) => {
9
+ const result = approvalListResultSchema.parse(value);
10
+ requireMatch(result.items.length <= input.limit &&
11
+ result.items.every((item) => (input.sessionId === undefined ||
12
+ item.sessionId === input.sessionId) &&
13
+ (input.pendingOnly === false || item.status === "pending")));
14
+ return result;
15
+ };
16
+ const parseShow = (value, input) => {
17
+ const result = approvalShowResultSchema.parse(value);
18
+ requireMatch(result.approval.approvalId === input.approvalId);
19
+ return result;
20
+ };
21
+ const decided = (status, input, forSession) => {
22
+ if (input.decision === "answer")
23
+ return status === "answered";
24
+ if (input.decision === "deny")
25
+ return status === "denied";
26
+ return (status === "approved" &&
27
+ forSession === (input.decision === "approve_for_session"));
28
+ };
29
+ const parseRespond = (value, input) => {
30
+ const result = approvalRespondResultSchema.parse(value);
31
+ const { approval, commandId } = result;
32
+ requireMatch(commandId === input.commandId &&
33
+ approval.approvalId === input.approvalId &&
34
+ approval.requestDigest === input.requestDigest &&
35
+ decided(approval.status, input, approval.resolution?.forSession === true));
36
+ return result;
37
+ };
38
+ export const makeApprovalOperations = (request) => ({
39
+ listApprovals: (parameters, options) => request({ method: "approval.list", parameters }, { parse: (value) => parseList(value, parameters) }, options),
40
+ respondToApproval: (parameters, options) => verifiedMutation(request({ method: "approval.respond", parameters }, { parse: (value) => parseRespond(value, parameters) }, options), options),
41
+ showApproval: (parameters, options) => request({ method: "approval.show", parameters }, { parse: (value) => parseShow(value, parameters) }, options),
42
+ });
43
+ //# sourceMappingURL=effect.js.map
@@ -0,0 +1,2 @@
1
+ export { type Approval, APPROVAL_ERROR_CODES, APPROVAL_SCHEMA_VERSION, APPROVAL_TTL_MILLISECONDS, type ApprovalClient, type ApprovalErrorCode, type ApprovalListParameters, approvalListParametersSchema, type ApprovalListResult, approvalListResultSchema, type ApprovalRespondParameters, approvalRespondParametersSchema, type ApprovalRespondResult, approvalRespondResultSchema, approvalSchema, type ApprovalShowParameters, approvalShowParametersSchema, type ApprovalShowResult, approvalShowResultSchema, makeApprovalClient, MAX_APPROVAL_PAGE_SIZE, } from "./approval.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export { APPROVAL_ERROR_CODES, APPROVAL_SCHEMA_VERSION, APPROVAL_TTL_MILLISECONDS, approvalListParametersSchema, approvalListResultSchema, approvalRespondParametersSchema, approvalRespondResultSchema, approvalSchema, approvalShowParametersSchema, approvalShowResultSchema, makeApprovalClient, MAX_APPROVAL_PAGE_SIZE, } from "./approval.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,26 @@
1
+ import type { LocalNodeRequestPayload, LocalNodeSuccessResult } from "@maiaos/protocol";
2
+ import type { MaiaRegisteredFeatureOperation } from "@maiaos/protocol/feature-registry";
3
+ import type * as Effect from "effect/Effect";
4
+ import type { LocalNodeRequestOptions } from "../request/index.js";
5
+ type CallBoundOperation = Extract<MaiaRegisteredFeatureOperation, {
6
+ readonly sdk: {
7
+ readonly operation: "call";
8
+ };
9
+ }>;
10
+ export type LocalNodeCallMethod = CallBoundOperation["method"];
11
+ export declare const LOCAL_NODE_CALL_ENTRIES: readonly [readonly ["session.rename", "command-id"], readonly ["reference.resolve", "none"]];
12
+ export declare const LOCAL_NODE_CALL_METHODS: readonly LocalNodeCallMethod[];
13
+ export type LocalNodeCallParameters<TMethod extends LocalNodeCallMethod> = Extract<LocalNodeRequestPayload, {
14
+ readonly method: TMethod;
15
+ }>["parameters"];
16
+ export type LocalNodeCallResult<TMethod extends LocalNodeCallMethod> = Extract<LocalNodeSuccessResult, {
17
+ readonly method: TMethod;
18
+ }>;
19
+ export type LocalNodeCallClient = {
20
+ readonly call: <TMethod extends LocalNodeCallMethod>(method: TMethod, parameters: LocalNodeCallParameters<TMethod>, options: LocalNodeRequestOptions) => Promise<LocalNodeCallResult<TMethod>>;
21
+ };
22
+ export type LocalNodeEffectCallClient<TError> = {
23
+ readonly call: <TMethod extends LocalNodeCallMethod>(method: TMethod, parameters: LocalNodeCallParameters<TMethod>, options: LocalNodeRequestOptions) => Effect.Effect<LocalNodeCallResult<TMethod>, TError>;
24
+ };
25
+ export {};
26
+ //# sourceMappingURL=call.d.ts.map
@@ -0,0 +1,6 @@
1
+ export const LOCAL_NODE_CALL_ENTRIES = [
2
+ ["session.rename", "command-id"],
3
+ ["reference.resolve", "none"],
4
+ ];
5
+ export const LOCAL_NODE_CALL_METHODS = LOCAL_NODE_CALL_ENTRIES.map(([method]) => method);
6
+ //# sourceMappingURL=call.js.map
@@ -0,0 +1,5 @@
1
+ import { type LocalNodeEffectRequester } from "../request/effect.js";
2
+ import { MaiaClientError } from "../request/index.js";
3
+ import { type LocalNodeEffectCallClient } from "./call.js";
4
+ export declare const makeCallOperation: <TError>(request: LocalNodeEffectRequester<TError>) => LocalNodeEffectCallClient<MaiaClientError | TError>;
5
+ //# sourceMappingURL=effect.d.ts.map
@@ -0,0 +1,46 @@
1
+ import { localNodeRequestPayloadSchema, localNodeSuccessResultSchema, } from "@maiaos/protocol";
2
+ import * as Effect from "effect/Effect";
3
+ import { verifiedMutation, } from "../request/effect.js";
4
+ import { MaiaClientError } from "../request/index.js";
5
+ import { LOCAL_NODE_CALL_ENTRIES, } from "./call.js";
6
+ const isCallResult = (result, method) => result.method === method;
7
+ const field = (value, name) => typeof value === "object" && value !== null
8
+ ? Reflect.get(value, name)
9
+ : undefined;
10
+ const receiptMatches = (parameters, receipt) => {
11
+ const commandId = field(parameters, "commandId");
12
+ if (commandId === undefined)
13
+ return true;
14
+ const target = field(receipt, "target");
15
+ const type = field(target, "type");
16
+ const named = typeof type === "string" ? field(parameters, `${type}Id`) : undefined;
17
+ return (field(receipt, "commandId") === commandId &&
18
+ typeof named === "string" &&
19
+ field(target, "id") === named);
20
+ };
21
+ const parseCallResult = (method, parameters, value) => {
22
+ const result = localNodeSuccessResultSchema.parse(value);
23
+ if (isCallResult(result, method) &&
24
+ receiptMatches(parameters, field(result, "receipt")))
25
+ return result;
26
+ throw new MaiaClientError("invalid_response", `The ${method} response did not match the request.`);
27
+ };
28
+ const invalidCall = (method, cause) => new MaiaClientError("invalid_request", `The Maia request for ${method} failed runtime validation.`, { cause });
29
+ export const makeCallOperation = (request) => ({
30
+ call: (method, parameters, options) => {
31
+ const idempotency = LOCAL_NODE_CALL_ENTRIES.find(([bound]) => bound === method)?.[1];
32
+ const payload = localNodeRequestPayloadSchema.safeParse({
33
+ method,
34
+ parameters,
35
+ });
36
+ if (!payload.success)
37
+ return Effect.fail(invalidCall(method, payload.error));
38
+ if (idempotency === undefined)
39
+ return Effect.fail(invalidCall(method));
40
+ const effect = request(payload.data, { parse: (value) => parseCallResult(method, parameters, value) }, options);
41
+ return idempotency === "command-id"
42
+ ? verifiedMutation(effect, options)
43
+ : effect;
44
+ },
45
+ });
46
+ //# sourceMappingURL=effect.js.map
@@ -0,0 +1,2 @@
1
+ export { LOCAL_NODE_CALL_METHODS, type LocalNodeCallClient, type LocalNodeCallMethod, type LocalNodeCallParameters, type LocalNodeCallResult, type LocalNodeEffectCallClient, } from "./call.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export { LOCAL_NODE_CALL_METHODS, } from "./call.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,8 @@
1
+ import type { LocalNodeEffectCallClient } from "../call/index.js";
2
+ import { type EffectClient, type LocalNodeEffectRequester } from "../request/effect.js";
3
+ import { MaiaClientError, type MaiaTransport } from "../request/index.js";
4
+ import type { LocalNodeClient } from "./local-node-client.js";
5
+ export type LocalNodeEffectClient = EffectClient<Omit<LocalNodeClient, "call">> & LocalNodeEffectCallClient<MaiaClientError>;
6
+ export declare const makeLocalNodeEffectClient: (request: LocalNodeEffectRequester) => LocalNodeEffectClient;
7
+ export declare const createLocalNodeEffectClient: (transport: MaiaTransport) => LocalNodeEffectClient;
8
+ //# sourceMappingURL=effect.d.ts.map