@tangle-network/hub-sdk 0.2.2 → 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.
package/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # @tangle-network/hub-sdk
2
2
 
3
3
  Typed SDK for the Tangle Hub `/v1/hub/*` surface. Status, connections, tools
4
- discovery and invocation, capability tokens, policies, approvals, audit.
4
+ discovery and invocation, capability tokens, policies, approvals, audit,
5
+ inbound channels, and product event subscriptions.
5
6
 
6
7
  ## Install
7
8
 
@@ -125,11 +126,106 @@ const hub = HubClient.fromEnv({
125
126
  });
126
127
  ```
127
128
 
129
+ ## Workflows
130
+
131
+ `hub.workflows` covers the `/v1/workflows` surface — the same resource the
132
+ platform web UI and the `tangle workflows` CLI drive. It authenticates with the
133
+ `sk-tan-*` API key (or a session), **not** a hub capability token. Alongside
134
+ CRUD (`list`/`get`/`create`/`update`/`delete`), `setEnabled`, `validate`, and
135
+ `schema`, it can trigger and observe runs:
136
+
137
+ ```ts
138
+ const hub = HubClient.fromEnv();
139
+
140
+ // Trigger a run with the trigger fields the workflow reads, then wait for it.
141
+ const { runId } = await hub.workflows.run("wf_123", {
142
+ "pull_request.number": "123",
143
+ });
144
+ const run = await hub.workflows.waitForRun("wf_123", runId, {
145
+ timeoutMs: 300_000,
146
+ });
147
+ console.log(run.status, run.actionResults);
148
+
149
+ // Or tail live progress as it executes.
150
+ for await (const event of hub.workflows.watchRun("wf_123", runId)) {
151
+ if (event.type === "token") process.stdout.write(event.delta);
152
+ if (event.type === "run.done") console.log("\n", event.status);
153
+ }
154
+
155
+ // One page of run history + a single run's full detail.
156
+ const { runs, nextCursor } = await hub.workflows.listRuns("wf_123");
157
+ const detail = await hub.workflows.getRun("wf_123", runs[0].id);
158
+ ```
159
+
160
+ `run` throws `HubSdkError` with `MISSING_RUN_INPUTS` (the workflow reads trigger
161
+ fields none were supplied for — `details.missing` names them) or
162
+ `WORKFLOW_DISABLED` (enable it first). `waitForRun` throws
163
+ `WORKFLOW_RUN_TIMEOUT` if the run has not finished within `timeoutMs`. Live
164
+ `watchRun` ticks require the worker executing the run to share the API process;
165
+ across instances only `snapshot` + `run.done` arrive, and the persisted record
166
+ read via `getRun` stays the source of truth.
167
+
168
+ ## Product event subscriptions
169
+
170
+ Products can bind a managed channel or a hosted provider connection to a signed
171
+ server callback without authoring workflow YAML:
172
+
173
+ OAuth readiness and inbound-event readiness are separate.
174
+ Check `provider.eventIngressConfigured === true` before presenting an inbound
175
+ channel as available.
176
+ An absent value means the server predates readiness discovery and should be
177
+ treated as unavailable.
178
+
179
+ ```ts
180
+ const callbackSecret = await deriveHubEventCallbackSecret({
181
+ rootSecret: env.HUB_EVENT_CALLBACK_ROOT_SECRET,
182
+ productId: "relationships",
183
+ ownerId: tangleUserId,
184
+ bindingId: channel.id,
185
+ });
186
+
187
+ const { subscription } = await hub.eventSubscriptions.create({
188
+ clientReference: `relationships:${channel.id}`,
189
+ label: "Relationship workspace inbound",
190
+ source: { type: "channel", channelId: channel.id },
191
+ event: "email.received",
192
+ callback: {
193
+ url: "https://relationships.example/api/events",
194
+ secret: callbackSecret,
195
+ },
196
+ });
197
+ ```
198
+
199
+ `clientReference` is the product-owned idempotency key.
200
+ The callback URL and secret are encrypted by the platform and never returned.
201
+ The derivation scopes one callback secret to one product, owner, and binding, so
202
+ the product stores only those existing ids.
203
+ On receipt, authenticate and parse the exact raw request in one call:
204
+
205
+ ```ts
206
+ const authenticated = await authenticateHubEventRequest({
207
+ request,
208
+ secret: callbackSecret,
209
+ });
210
+ if (!authenticated.ok) return authenticated.response;
211
+
212
+ const { delivery } = authenticated;
213
+ const email = delivery.providerEvent.payload;
214
+ ```
215
+
216
+ The signed delivery includes the verified provider event directly, so the
217
+ product does not need a second workflow-run request.
218
+ Callbacks may be retried; use `delivery.runId` as the durable idempotency key
219
+ before starting product work.
220
+
128
221
  ## Exports
129
222
 
130
223
  - `HubClient`, `HubClient.fromEnv(options?)`
131
224
  - `HubConnectionsClient`, `HubPermissionsClient`, `HubTokensClient`,
132
- `HubToolsClient`, `HubApprovalsClient`, `HubAuditClient`
225
+ `HubChannelsClient`, `HubEventSubscriptionsClient`, `HubToolsClient`,
226
+ `HubApprovalsClient`, `HubAuditClient`, `HubWorkflowsClient`
227
+ - `deriveHubEventCallbackSecret`, `authenticateHubEventRequest`,
228
+ `verifyHubEventSignature`, `parseHubEventDelivery`, `HubEventDeliveryError`
133
229
  - `HubSdkError` — typed `code: HubErrorCode`, redacted `details`, optional
134
230
  HTTP `status`
135
231
  - `HUB_URL_ENV_VAR`, `HUB_API_KEY_ENV_VAR`, `HUB_CAPABILITY_TOKEN_ENV_VAR` —