@rayrun/sdk 0.5.0 → 0.6.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 (4) hide show
  1. package/README.md +155 -14
  2. package/index.d.ts +368 -11
  3. package/index.js +70 -7
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -15,8 +15,8 @@ const { items: matchingTools } = await rayrun.tools.list({ query: 'create issue'
15
15
  Create keys in **Dashboard → Settings → API keys**. The plaintext is shown once.
16
16
 
17
17
  The client covers catalog search, connection and credential setup, OAuth links, indexing, tool and
18
- client policies, reusable access profiles, activity, review queues, and webhooks. Safe reads retry
19
- rate limits, server errors, and transient network failures; writes do not retry automatically.
18
+ client policies, access profiles, Workspace Skills, Activity, review queues, and webhooks. Safe
19
+ reads retry transient failures; writes do not retry automatically.
20
20
 
21
21
  Inspect the effective policy applied to one connected client without reproducing policy logic in
22
22
  your application:
@@ -38,17 +38,66 @@ const { profile } = await rayrun.accessProfiles.create({
38
38
  description: 'Read by default; sensitive tools stay blocked.',
39
39
  });
40
40
 
41
- await rayrun.accessProfiles.setPolicy(profile.uid, 'read-only', profile.toolPolicyVersion);
42
- await rayrun.accessProfiles.update(profile.uid, {
43
- description: 'Read by default; sensitive tools stay blocked.',
44
- expectedVersion: profile.toolPolicyVersion + 1,
41
+ const policy = await rayrun.accessProfiles.setPolicy(
42
+ profile.uid,
43
+ 'read-only',
44
+ profile.toolPolicyVersion,
45
+ );
46
+ const details = await rayrun.accessProfiles.update(profile.uid, {
47
+ description: 'Read-only support access; sensitive tools stay blocked.',
48
+ expectedVersion: policy.toolPolicyVersion,
45
49
  name: 'Support agents',
46
50
  });
47
51
  await rayrun.clients.setAccessProfile(clientUid, profile.uid, clientToolPolicyVersion);
52
+
53
+ const profileHistory = await rayrun.accessProfiles.listConfigurationVersions(profile.uid);
54
+ const original = await rayrun.accessProfiles.getConfigurationVersion(
55
+ profile.uid,
56
+ profileHistory.items.at(-1).uid,
57
+ );
58
+ await rayrun.accessProfiles.restoreConfigurationVersion(profile.uid, original.version.uid, {
59
+ expectedVersion: details.toolPolicyVersion,
60
+ reason: 'Restore the reviewed access ceiling',
61
+ riskConfirmed: true,
62
+ });
48
63
  ```
49
64
 
50
65
  The effective policy is always the intersection of the workspace, profile, and client rules. A
51
- profile can narrow access but cannot grant something blocked by the workspace or client.
66
+ profile can narrow access but cannot grant something blocked by the workspace or client. History
67
+ versions profile details and rules together; assignments and archival stay outside the snapshot.
68
+ Restore refuses missing tools and requires `riskConfirmed` when it would allow a Destructive or
69
+ Unknown tool. Profile history is limited to 64 MiB per workspace.
70
+
71
+ ## Manage connection configuration history
72
+
73
+ Connection names, slugs, descriptions, timeouts, enablement, and payload-capture preferences are
74
+ saved as one immutable configuration snapshot. Credentials, headers, OAuth state, identity and tool
75
+ policy, health, and index state are deliberately excluded.
76
+
77
+ ```js
78
+ const { items: connections } = await rayrun.connections.list();
79
+ const connection = connections[0];
80
+
81
+ const updated = await rayrun.connections.setEnabled(connection.uid, {
82
+ enabled: false,
83
+ expectedVersion: connection.configurationVersion,
84
+ });
85
+
86
+ const history = await rayrun.connections.listConfigurationVersions(connection.uid, { limit: 25 });
87
+ const selected = await rayrun.connections.getConfigurationVersion(
88
+ connection.uid,
89
+ history.items.at(-1).uid,
90
+ );
91
+
92
+ await rayrun.connections.restoreConfigurationVersion(connection.uid, selected.version.uid, {
93
+ expectedVersion: updated.connection.configurationVersion,
94
+ reason: 'Restore the reviewed service configuration',
95
+ });
96
+ ```
97
+
98
+ Every material update records the user or API key, channel, time, and optional reason. Identical
99
+ saves are no-ops. Restore creates a new attributed version and fails with `version_conflict` if the
100
+ connection changed after it was read.
52
101
 
53
102
  ## Manage hosted tool hooks
54
103
 
@@ -69,14 +118,22 @@ const saved = await rayrun.hooks.saveDraft(connectionUid, toolUid, {
69
118
  source: hook.draftSource,
70
119
  config: hook.draftConfig,
71
120
  expectedVersion: hook.version,
121
+ reason: 'Normalize upstream release results',
72
122
  });
73
123
 
74
- await rayrun.hooks.deploy(connectionUid, toolUid, {
124
+ const deployed = await rayrun.hooks.deploy(connectionUid, toolUid, {
75
125
  expectedVersion: saved.hook.version,
76
126
  mode: 'shadow',
77
127
  });
78
128
 
79
129
  const runs = await rayrun.hooks.listRuns(connectionUid, toolUid, { limit: 25 });
130
+
131
+ const history = await rayrun.hooks.listDraftVersions(connectionUid, toolUid, { limit: 25 });
132
+ const prior = await rayrun.hooks.getDraftVersion(connectionUid, toolUid, history.items.at(-1).uid);
133
+ await rayrun.hooks.restoreDraft(connectionUid, toolUid, prior.version.uid, {
134
+ expectedVersion: deployed.hook.version,
135
+ reason: 'Restore the previous argument mapping',
136
+ });
80
137
  ```
81
138
 
82
139
  `setDeployment` moves an active or shadow pointer to an existing compatible revision, or deactivates
@@ -86,6 +143,56 @@ inspect source, generated declarations, revision history, and deployed-run metad
86
143
  and errors require `hooks:write`. `RayrunApiError.diagnostics` carries compiler line and column
87
144
  details for editor and CI output.
88
145
 
146
+ Draft history is immutable and separate from deployment revisions: every material save records the
147
+ API key or user, optional change note, source, and non-secret config. Re-saving identical content is
148
+ a no-op. Restore always creates a new attributed draft head; it never rewrites the selected version.
149
+ Source plus config history is limited to 64 MiB per workspace. Export required versions, then call
150
+ `hooks.reset` with the current hook UID and version to permanently remove that hook's draft history
151
+ and deployment revisions. Rayrun blocks connection deletion while hook history remains.
152
+
153
+ ## Publish Workspace Skills
154
+
155
+ Encode each file as a package-relative path and base64 content. Validate before creating when CI
156
+ needs the parsed name, frontmatter, digests, and warnings before it mutates workspace state.
157
+
158
+ ```js
159
+ const files = [
160
+ {
161
+ path: 'SKILL.md',
162
+ contentBase64: Buffer.from(
163
+ `---
164
+ name: incident-response
165
+ description: Investigate and communicate production incidents.
166
+ ---
167
+
168
+ # Incident response
169
+ `,
170
+ ).toString('base64'),
171
+ },
172
+ ];
173
+
174
+ const validation = await rayrun.skills.validate(files);
175
+ const created = await rayrun.skills.create({ files, source: 'api' });
176
+
177
+ await rayrun.skills.publish(created.skillUid, {
178
+ deliveryMode: 'both',
179
+ expectedVersion: created.configurationVersion,
180
+ profileUids: [],
181
+ riskConfirmed: validation.riskFlags.length > 0,
182
+ });
183
+ ```
184
+
185
+ `saveDraft` creates an immutable revision without changing the published pointer. `updateAudience`
186
+ changes Code/Direct delivery and access-profile targeting without republishing. `setEnabled`,
187
+ `archive`, `export`, `exportVersion`, and `restoreVersion` cover the reversible lifecycle;
188
+ `delete` permanently removes retained revisions and delivery summaries after name and version
189
+ confirmation. The name remains reserved.
190
+
191
+ Use `skills:read` for inspection and export and add `skills:write` deliberately for publication
192
+ automation. The ordinary workspace-management key preset excludes `skills:write`. Rayrun stores
193
+ Skill bytes encrypted under the workspace key and serves them only after reauthorizing the MCP
194
+ client on each read. `allowed-tools` is guidance, not access policy.
195
+
89
196
  ## Stream code run-ahead
90
197
 
91
198
  A model harness that receives `execute_code` arguments incrementally can let Rayrun start eligible
@@ -119,13 +226,47 @@ try {
119
226
  `open()` returns `null` when this optional optimization is rate-limited or temporarily unavailable.
120
227
  `feedArguments()` coalesces snapshots while one request is in flight; call `flush()` once before the
121
228
  final MCP request. It throws synchronously when a snapshot is not a string, so TypeScript users get
122
- the mistake at the call site. If an active session becomes unavailable, `meta` becomes an empty object. In
123
- either case, send the final MCP call normally. Rayrun only runs ahead tools that are explicitly
124
- allowed, approved as Read by a workspace owner, and advertised by their server as read-only and
125
- idempotent. The final MCP call rechecks the token, complete program, policy, definition, arguments,
126
- and upstream identity before it can use an early result.
229
+ the mistake at the call site. If a session becomes unavailable, send the final MCP call normally.
230
+ Rayrun runs ahead only allowed tools approved as Read and advertised as read-only and idempotent.
231
+ The final call rechecks identity, policy, definition, arguments, and program before using an early
232
+ result.
233
+
234
+ ## Manage webhook configuration history
235
+
236
+ Webhook destination, description, event selection, delivery mode, batch size, enablement, and
237
+ payload forwarding are saved together as immutable configuration versions. Signing secrets,
238
+ delivery attempts, retry state, and health stay outside the snapshot.
239
+
240
+ ```js
241
+ const { items: webhooks } = await rayrun.webhooks.list();
242
+ const webhook = webhooks[0];
243
+
244
+ const updated = await rayrun.webhooks.update(webhook.uid, {
245
+ enabled: false,
246
+ expectedVersion: webhook.configurationVersion,
247
+ reason: 'Pause deliveries during maintenance',
248
+ });
249
+
250
+ const history = await rayrun.webhooks.listConfigurationVersions(webhook.uid, { limit: 25 });
251
+ const selected = await rayrun.webhooks.getConfigurationVersion(
252
+ webhook.uid,
253
+ history.items.at(-1).uid,
254
+ );
255
+
256
+ await rayrun.webhooks.restoreConfigurationVersion(webhook.uid, selected.version.uid, {
257
+ expectedVersion: updated.configurationVersion,
258
+ reason: 'Restore the reviewed destination',
259
+ });
260
+ ```
261
+
262
+ Every material update records the user or API key, channel, time, and optional reason. Restore
263
+ creates a new version, revalidates the historical destination URL, and preserves the endpoint’s
264
+ current signing secret and delivery state. Identical saves are no-ops, stale expected versions fail,
265
+ and immutable webhook configuration history is limited to 64 MiB per workspace. Destination paths
266
+ and query strings can contain provider tokens, so read-only keys receive `null` URLs; keys with
267
+ `webhooks:write` receive the full current and historical destination.
127
268
 
128
- ## Verify webhooks
269
+ ## Verify webhook signatures
129
270
 
130
271
  Pass the exact request body and the `Rayrun-Signature` header before parsing the event. Verification
131
272
  also rejects timestamps outside a five-minute replay window by default.
package/index.d.ts CHANGED
@@ -12,10 +12,38 @@ export type ToolDecision = 'allow' | 'ask' | 'block';
12
12
  export type ToolAccessMode = 'read-only' | 'ask-before-changes' | 'allow-all' | 'custom';
13
13
  export type AccessProfileMode = 'read-only' | 'ask-before-changes' | 'allow-all' | 'block-all';
14
14
  export type Risk = 'read' | 'change' | 'destructive' | 'unknown';
15
+ export type ConfigurationVersionSummary = {
16
+ actor: { name: string; type: 'api-key' | 'system' | 'user'; uid: string };
17
+ changeReason: string | null;
18
+ changeType: 'restore' | 'save';
19
+ channel: 'api' | 'browser' | 'legacy';
20
+ createdAt: string;
21
+ isCurrent: boolean;
22
+ restoredFromVersionUid: string | null;
23
+ revisionNumber: number;
24
+ uid: string;
25
+ };
26
+ export type ConnectionConfiguration = {
27
+ captureToolPayloads: boolean;
28
+ description: string | null;
29
+ displayName: string;
30
+ enabled: boolean;
31
+ requestTimeoutMs: number;
32
+ slug: string;
33
+ };
34
+ export type ConnectionConfigurationVersion = ConfigurationVersionSummary & {
35
+ previous: {
36
+ revisionNumber: number;
37
+ snapshot: ConnectionConfiguration;
38
+ uid: string;
39
+ } | null;
40
+ snapshot: ConnectionConfiguration;
41
+ };
15
42
  export type Connection = {
16
43
  authorizedAt: string | null;
17
44
  authType: 'api-key' | 'basic' | 'none' | 'oauth2';
18
45
  createdAt: string;
46
+ configurationVersion: number;
19
47
  uid: string;
20
48
  displayName: string;
21
49
  enabled: boolean;
@@ -69,6 +97,7 @@ export type ToolHookRevision = {
69
97
  export type ToolHook = {
70
98
  activeRevisionStale: boolean;
71
99
  activeRevisionUid: string | null;
100
+ currentDraftRevisionNumber: number;
72
101
  draftConfig: Record<string, JsonValue>;
73
102
  draftSource: string;
74
103
  hookUid: string | null;
@@ -76,6 +105,7 @@ export type ToolHook = {
76
105
  shadowRevisionStale: boolean;
77
106
  shadowRevisionUid: string | null;
78
107
  target: {
108
+ available: boolean;
79
109
  definitionHash: string | null;
80
110
  inputSchema: Record<string, unknown>;
81
111
  name: string;
@@ -85,6 +115,31 @@ export type ToolHook = {
85
115
  types: string;
86
116
  version: number;
87
117
  };
118
+ export type ToolHookDraftVersionSummary = {
119
+ actor: {
120
+ name: string;
121
+ type: 'api-key' | 'user';
122
+ uid: string;
123
+ };
124
+ changeReason: string | null;
125
+ changeType: 'restore' | 'save';
126
+ channel: 'api' | 'browser' | 'legacy';
127
+ createdAt: string;
128
+ isCurrent: boolean;
129
+ restoredFromVersionUid: string | null;
130
+ revisionNumber: number;
131
+ uid: string;
132
+ };
133
+ export type ToolHookDraftVersion = ToolHookDraftVersionSummary & {
134
+ config: Record<string, JsonValue>;
135
+ previous: {
136
+ config: Record<string, JsonValue>;
137
+ revisionNumber: number;
138
+ source: string;
139
+ uid: string;
140
+ } | null;
141
+ source: string;
142
+ };
88
143
  export type ToolHookLogEntry = {
89
144
  data?: JsonValue;
90
145
  level: 'debug' | 'error' | 'info' | 'warn';
@@ -169,6 +224,7 @@ export type ClientTool = {
169
224
  };
170
225
  export type AccessProfile = {
171
226
  assignedClientCount: number;
227
+ assignedSkillCount: number;
172
228
  description: string;
173
229
  name: string;
174
230
  toolAccessMode: AccessProfileMode;
@@ -183,6 +239,24 @@ export type AccessProfileTool = {
183
239
  serviceName: string;
184
240
  uid: string;
185
241
  };
242
+ export type AccessProfileConfiguration = {
243
+ description: string;
244
+ name: string;
245
+ toolAccessMode: AccessProfileMode;
246
+ toolRules: Array<{
247
+ connectionUid: string;
248
+ decision: ToolDecision;
249
+ toolUid: string;
250
+ }>;
251
+ };
252
+ export type AccessProfileConfigurationVersion = ConfigurationVersionSummary & {
253
+ previous: {
254
+ revisionNumber: number;
255
+ snapshot: AccessProfileConfiguration;
256
+ uid: string;
257
+ } | null;
258
+ snapshot: AccessProfileConfiguration;
259
+ };
186
260
  export type Activity = {
187
261
  calledAt: string;
188
262
  clientName: string | null;
@@ -203,15 +277,109 @@ export type Review = {
203
277
  toolName: string;
204
278
  uid: string;
205
279
  };
206
- export type Webhook = {
280
+ export type SkillFileInput = { contentBase64: string; path: string };
281
+ export type SkillRiskFlag = 'binary-files' | 'possible-secrets' | 'scripts';
282
+ export type SkillDeliveryMode = 'both' | 'code' | 'direct';
283
+ export type Skill = {
284
+ archivedAt: string | null;
285
+ byteCount: number;
286
+ configurationVersion: number;
287
+ createdAt: string;
288
+ currentDraftRevisionNumber: number;
289
+ currentDraftVersionUid: string;
290
+ deliveryMode: SkillDeliveryMode;
291
+ description: string;
292
+ enabled: boolean;
293
+ fetchCount: number;
294
+ fileCount: number;
295
+ frontmatter: Record<string, JsonValue>;
296
+ lastFetchedAt: string | null;
297
+ name: string;
298
+ profiles: Array<{ name: string; uid: string }>;
299
+ publishedRevisionNumber: number | null;
300
+ publishedVersionUid: string | null;
301
+ riskFlags: SkillRiskFlag[];
302
+ state: 'archived' | 'disabled' | 'draft' | 'published';
303
+ uid: string;
304
+ updatedAt: string;
305
+ uri: string;
306
+ };
307
+ export type SkillVersion = {
308
+ actorName: string;
309
+ actorType: 'api-key' | 'user';
310
+ actorUid: string;
311
+ byteCount: number;
312
+ changeReason: string | null;
207
313
  createdAt: string;
314
+ fileCount: number;
315
+ isCurrentDraft: boolean;
316
+ isPublished: boolean;
317
+ restoredFromVersionUid: string | null;
318
+ revisionNumber: number;
319
+ riskFlags: SkillRiskFlag[];
320
+ source: 'api' | 'cli' | 'dashboard-folder' | 'dashboard-zip' | 'restore';
321
+ uid: string;
322
+ };
323
+ export type SkillDetail = {
324
+ deliveries: Array<{
325
+ clientName: string;
326
+ fetchCount: number;
327
+ firstFetchedAt: string;
328
+ lastFetchedAt: string;
329
+ method: 'resources/directory/read' | 'resources/read' | 'skills/get';
330
+ resourceUri: string;
331
+ userName: string | null;
332
+ versionUid: string;
333
+ }>;
334
+ files: Array<{ digest: string; mimeType: string; path: string; size: number; uri: string }>;
335
+ skill: Skill;
336
+ versions: SkillVersion[];
337
+ };
338
+ export type SkillMutationResult = {
339
+ configurationVersion: number;
340
+ skillUid: string;
341
+ unchanged: boolean;
342
+ versionUid: string | null;
343
+ };
344
+ export type SkillValidationResult = {
345
+ byteCount: number;
346
+ fileCount: number;
347
+ frontmatter: Record<string, JsonValue>;
348
+ manifestDigest: string;
349
+ name: string;
350
+ riskFlags: SkillRiskFlag[];
351
+ };
352
+ export type WebhookConfiguration = {
353
+ batchMaxEvents: number;
354
+ deliveryMode: 'batch' | 'single';
208
355
  description: string | null;
209
356
  enabled: boolean;
210
357
  eventTypes: WebhookEvent[];
211
358
  forwardToolPayloads: boolean;
212
- uid: string;
213
359
  url: string;
214
360
  };
361
+ export type WebhookConfigurationVersion = ConfigurationVersionSummary & {
362
+ previous: {
363
+ revisionNumber: number;
364
+ snapshot: WebhookConfigurationHistorySnapshot;
365
+ uid: string;
366
+ } | null;
367
+ snapshot: WebhookConfigurationHistorySnapshot;
368
+ };
369
+ export type WebhookConfigurationHistorySnapshot = Omit<WebhookConfiguration, 'url'> & {
370
+ url: string | null;
371
+ };
372
+ export type Webhook = Omit<WebhookConfiguration, 'url'> & {
373
+ configurationVersion: number;
374
+ createdAt: string;
375
+ health: 'delayed' | 'failing' | 'healthy' | 'idle' | 'pending';
376
+ lastDeliveredAt: string | null;
377
+ lastFailedAt: string | null;
378
+ oldestPendingAt: string | null;
379
+ pendingDeliveryCount: number;
380
+ uid: string;
381
+ url: string | null;
382
+ };
215
383
  export type Credential =
216
384
  | {
217
385
  authType: 'api-key';
@@ -233,6 +401,7 @@ export type WebhookEvent =
233
401
  | 'connection.changed'
234
402
  | 'connection.indexed'
235
403
  | 'review.changed'
404
+ | 'skill.changed'
236
405
  | 'tool.definition-changed'
237
406
  | 'tool.policy-changed';
238
407
  export type WebhookDeliveryEvent = Exclude<WebhookEvent, '*'> | 'webhook.test';
@@ -305,6 +474,28 @@ export type WebhookPayload =
305
474
  toolUid: string;
306
475
  }
307
476
  >
477
+ | WebhookEnvelope<
478
+ 'skill.changed',
479
+ {
480
+ deliveryMode?: SkillDeliveryMode;
481
+ eventType:
482
+ | 'skill-archived'
483
+ | 'skill-audience-changed'
484
+ | 'skill-deleted'
485
+ | 'skill-disabled'
486
+ | 'skill-draft-created'
487
+ | 'skill-enabled'
488
+ | 'skill-published'
489
+ | 'skill-restored';
490
+ eventUid: string;
491
+ name?: string;
492
+ profileUids?: string[];
493
+ restoredFromVersionUid?: string;
494
+ revisionNumber?: number;
495
+ skillUid: string;
496
+ versionUid?: string;
497
+ }
498
+ >
308
499
  | WebhookEnvelope<
309
500
  'tool.definition-changed',
310
501
  { approved: boolean; connectionUid: string; kind: 'added' | 'changed'; toolUid: string }
@@ -357,14 +548,39 @@ export class Rayrun {
357
548
  | { kind: 'openapi'; specificationUrl: string; baseUrl?: string; name?: string },
358
549
  ): Promise<{ connection: { uid: string } }>;
359
550
  createOAuthLink(uid: string): Promise<{ authorizationUrl: string }>;
360
- delete(uid: string, expectedVersion: number): Promise<void>;
551
+ delete(uid: string): Promise<void>;
361
552
  index(uid: string): Promise<{ enqueued: boolean }>;
362
553
  list(query?: PageQuery): Promise<CursorPage<Connection>>;
554
+ getConfigurationVersion(
555
+ uid: string,
556
+ versionUid: string,
557
+ ): Promise<{ version: ConnectionConfigurationVersion }>;
558
+ listConfigurationVersions(
559
+ uid: string,
560
+ query?: PageQuery,
561
+ ): Promise<CursorPage<ConfigurationVersionSummary>>;
562
+ restoreConfigurationVersion(
563
+ uid: string,
564
+ versionUid: string,
565
+ body: { expectedVersion: number; reason?: string },
566
+ ): Promise<{
567
+ configuration: ConnectionConfiguration;
568
+ configurationVersion: number;
569
+ versionUid: string;
570
+ }>;
363
571
  setCredential(uid: string, body: Credential): Promise<{ enqueued: boolean }>;
364
572
  setEnabled(
365
573
  uid: string,
366
574
  enabled: boolean,
367
- ): Promise<{ connection: Pick<Connection, 'displayName' | 'enabled' | 'uid'> }>;
575
+ ): Promise<{
576
+ connection: Pick<Connection, 'configurationVersion' | 'displayName' | 'enabled' | 'uid'>;
577
+ }>;
578
+ setEnabled(
579
+ uid: string,
580
+ body: { enabled: boolean; expectedVersion?: number },
581
+ ): Promise<{
582
+ connection: Pick<Connection, 'configurationVersion' | 'displayName' | 'enabled' | 'uid'>;
583
+ }>;
368
584
  setPolicy(uid: string, mode: ToolAccessMode): Promise<void>;
369
585
  };
370
586
  tools: {
@@ -382,20 +598,49 @@ export class Rayrun {
382
598
  body: { expectedVersion: number; mode: 'active' | 'shadow' },
383
599
  ): Promise<{ hook: ToolHook }>;
384
600
  get(connectionUid: string, toolUid: string): Promise<{ hook: ToolHook }>;
601
+ getDraftVersion(
602
+ connectionUid: string,
603
+ toolUid: string,
604
+ versionUid: string,
605
+ ): Promise<{ version: ToolHookDraftVersion }>;
606
+ listDraftVersions(
607
+ connectionUid: string,
608
+ toolUid: string,
609
+ query?: PageQuery,
610
+ ): Promise<CursorPage<ToolHookDraftVersionSummary>>;
385
611
  listRuns(
386
612
  connectionUid: string,
387
613
  toolUid: string,
388
614
  query?: PageQuery,
389
615
  ): Promise<CursorPage<ToolHookRun>>;
616
+ reset(
617
+ connectionUid: string,
618
+ toolUid: string,
619
+ body: { confirmationHookUid: string; expectedVersion: number; reason: string },
620
+ ): Promise<void>;
390
621
  saveDraft(
391
622
  connectionUid: string,
392
623
  toolUid: string,
393
624
  body: {
394
625
  config?: Record<string, JsonValue>;
395
626
  expectedVersion: number;
627
+ reason?: string;
396
628
  source: string;
397
629
  },
398
- ): Promise<{ hook: ToolHook }>;
630
+ ): Promise<{
631
+ draftVersion: { revisionNumber: number; uid: string; unchanged: boolean };
632
+ hook: ToolHook;
633
+ }>;
634
+ restoreDraft(
635
+ connectionUid: string,
636
+ toolUid: string,
637
+ versionUid: string,
638
+ body: { expectedVersion: number; reason?: string },
639
+ ): Promise<{
640
+ draftVersion: { revisionNumber: number; uid: string };
641
+ hook: ToolHook;
642
+ restoredVersionUid: string;
643
+ }>;
399
644
  setDeployment(
400
645
  connectionUid: string,
401
646
  toolUid: string,
@@ -438,37 +683,149 @@ export class Rayrun {
438
683
  };
439
684
  accessProfiles: {
440
685
  archive(uid: string, expectedVersion: number): Promise<void>;
441
- create(body: { description: string; name: string }): Promise<{ profile: AccessProfile }>;
686
+ create(body: {
687
+ description: string;
688
+ name: string;
689
+ reason?: string;
690
+ }): Promise<{ profile: AccessProfile }>;
442
691
  /** @deprecated Use archive. */
443
692
  delete(uid: string, expectedVersion: number): Promise<void>;
693
+ getConfigurationVersion(
694
+ uid: string,
695
+ versionUid: string,
696
+ ): Promise<{ version: AccessProfileConfigurationVersion }>;
444
697
  list(query?: PageQuery): Promise<CursorPage<AccessProfile>>;
698
+ listConfigurationVersions(
699
+ uid: string,
700
+ query?: PageQuery,
701
+ ): Promise<CursorPage<ConfigurationVersionSummary>>;
445
702
  listTools(uid: string, query?: PageQuery): Promise<CursorPage<AccessProfileTool>>;
446
- setPolicy(uid: string, mode: AccessProfileMode, expectedVersion: number): Promise<void>;
703
+ restoreConfigurationVersion(
704
+ uid: string,
705
+ versionUid: string,
706
+ body: { expectedVersion: number; reason?: string; riskConfirmed?: boolean },
707
+ ): Promise<{
708
+ configuration: AccessProfileConfiguration;
709
+ toolPolicyVersion: number;
710
+ versionUid: string;
711
+ }>;
712
+ setPolicy(
713
+ uid: string,
714
+ mode: AccessProfileMode,
715
+ expectedVersion: number,
716
+ reason?: string,
717
+ ): Promise<{ toolPolicyVersion: number; unchanged: boolean }>;
447
718
  setToolPolicy(
448
719
  uid: string,
449
720
  toolUid: string,
450
721
  body: {
451
722
  decision: ToolDecision | null;
452
723
  expectedVersion: number;
724
+ reason?: string;
453
725
  riskConfirmed?: boolean;
454
726
  },
455
- ): Promise<void>;
727
+ ): Promise<{ toolPolicyVersion: number; unchanged: boolean }>;
456
728
  update(
457
729
  uid: string,
458
- body: { description: string; expectedVersion: number; name: string },
459
- ): Promise<void>;
730
+ body: { description: string; expectedVersion: number; name: string; reason?: string },
731
+ ): Promise<{ toolPolicyVersion: number; unchanged: boolean }>;
460
732
  };
461
733
  activity: { list(query?: PageQuery): Promise<CursorPage<Activity>> };
462
734
  reviews: { list(query?: PageQuery): Promise<CursorPage<Review>> };
735
+ skills: {
736
+ archive(uid: string, expectedVersion: number): Promise<SkillMutationResult>;
737
+ create(body: {
738
+ changeReason?: string;
739
+ files: SkillFileInput[];
740
+ source?: 'api' | 'cli';
741
+ }): Promise<SkillMutationResult>;
742
+ delete(
743
+ uid: string,
744
+ body: { confirmationName: string; expectedVersion: number },
745
+ ): Promise<SkillMutationResult>;
746
+ export(uid: string): Promise<{ files: SkillFileInput[]; name: string }>;
747
+ exportVersion(uid: string, versionUid: string): Promise<{ files: SkillFileInput[] }>;
748
+ get(uid: string): Promise<SkillDetail>;
749
+ list(): Promise<{
750
+ items: Skill[];
751
+ usage: { archivedSkillCount: number; liveSkillCount: number; storedByteCount: number };
752
+ }>;
753
+ publish(
754
+ uid: string,
755
+ body: {
756
+ changeReason?: string;
757
+ deliveryMode: SkillDeliveryMode;
758
+ expectedVersion: number;
759
+ profileUids: string[];
760
+ riskConfirmed?: boolean;
761
+ },
762
+ ): Promise<SkillMutationResult>;
763
+ restoreVersion(
764
+ uid: string,
765
+ versionUid: string,
766
+ body: { changeReason?: string; expectedVersion: number },
767
+ ): Promise<SkillMutationResult>;
768
+ saveDraft(
769
+ uid: string,
770
+ body: {
771
+ changeReason?: string;
772
+ expectedVersion: number;
773
+ files: SkillFileInput[];
774
+ source?: 'api' | 'cli';
775
+ },
776
+ ): Promise<SkillMutationResult>;
777
+ setEnabled(
778
+ uid: string,
779
+ enabled: boolean,
780
+ expectedVersion: number,
781
+ ): Promise<SkillMutationResult>;
782
+ updateAudience(
783
+ uid: string,
784
+ body: {
785
+ deliveryMode: SkillDeliveryMode;
786
+ expectedVersion: number;
787
+ profileUids: string[];
788
+ },
789
+ ): Promise<SkillMutationResult>;
790
+ validate(files: SkillFileInput[]): Promise<SkillValidationResult>;
791
+ };
463
792
  webhooks: {
464
793
  create(body: {
465
- url: string;
794
+ batchMaxEvents?: number;
795
+ deliveryMode?: 'batch' | 'single';
466
796
  description?: string | null;
467
797
  eventTypes: WebhookEvent[];
468
798
  forwardToolPayloads?: boolean;
799
+ url: string;
469
800
  }): Promise<{ uid: string; secret: string }>;
470
801
  delete(uid: string): Promise<void>;
802
+ getConfigurationVersion(
803
+ uid: string,
804
+ versionUid: string,
805
+ ): Promise<{ version: WebhookConfigurationVersion }>;
471
806
  list(): Promise<{ items: Webhook[] }>;
807
+ listConfigurationVersions(
808
+ uid: string,
809
+ query?: PageQuery,
810
+ ): Promise<CursorPage<ConfigurationVersionSummary>>;
811
+ restoreConfigurationVersion(
812
+ uid: string,
813
+ versionUid: string,
814
+ body: { expectedVersion: number; reason?: string },
815
+ ): Promise<{
816
+ configuration: WebhookConfiguration;
817
+ configurationVersion: number;
818
+ versionUid: string;
819
+ }>;
820
+ update(
821
+ uid: string,
822
+ body: Partial<WebhookConfiguration> & { expectedVersion: number; reason?: string },
823
+ ): Promise<{
824
+ configuration: WebhookConfiguration;
825
+ configurationVersion: number;
826
+ unchanged: boolean;
827
+ versionUid: string;
828
+ }>;
472
829
  verify: typeof verifyWebhookSignature;
473
830
  };
474
831
  request(
package/index.js CHANGED
@@ -100,11 +100,19 @@ export class Rayrun {
100
100
  create: (body) => this.request('POST', '/connections', { body }),
101
101
  createOAuthLink: (uid) => this.request('POST', `/connections/${uid}/oauth-link`),
102
102
  delete: (uid) => this.request('DELETE', `/connections/${uid}`),
103
+ getConfigurationVersion: (uid, versionUid) =>
104
+ this.request('GET', `/connections/${uid}/history/${versionUid}`),
103
105
  index: (uid) => this.request('POST', `/connections/${uid}/index`),
104
106
  list: (query) => this.request('GET', '/connections', { query }),
107
+ listConfigurationVersions: (uid, query) =>
108
+ this.request('GET', `/connections/${uid}/history`, { query }),
109
+ restoreConfigurationVersion: (uid, versionUid, body) =>
110
+ this.request('POST', `/connections/${uid}/history/${versionUid}/restore`, { body }),
105
111
  setCredential: (uid, body) => this.request('PUT', `/connections/${uid}/credential`, { body }),
106
- setEnabled: (uid, enabled) =>
107
- this.request('PATCH', `/connections/${uid}`, { body: { enabled } }),
112
+ setEnabled: (uid, input) =>
113
+ this.request('PATCH', `/connections/${uid}`, {
114
+ body: typeof input === 'boolean' ? { enabled: input } : input,
115
+ }),
108
116
  setPolicy: (uid, mode) =>
109
117
  this.request('PATCH', `/connections/${uid}/policy`, { body: { mode } }),
110
118
  };
@@ -119,8 +127,20 @@ export class Rayrun {
119
127
  deploy: (connectionUid, toolUid, body) =>
120
128
  this.request('POST', `${toolHookPath(connectionUid, toolUid)}/deploy`, { body }),
121
129
  get: (connectionUid, toolUid) => this.request('GET', toolHookPath(connectionUid, toolUid)),
130
+ getDraftVersion: (connectionUid, toolUid, versionUid) =>
131
+ this.request('GET', `${toolHookPath(connectionUid, toolUid)}/history/${versionUid}`),
132
+ listDraftVersions: (connectionUid, toolUid, query) =>
133
+ this.request('GET', `${toolHookPath(connectionUid, toolUid)}/history`, { query }),
122
134
  listRuns: (connectionUid, toolUid, query) =>
123
135
  this.request('GET', `${toolHookPath(connectionUid, toolUid)}/runs`, { query }),
136
+ reset: (connectionUid, toolUid, body) =>
137
+ this.request('DELETE', toolHookPath(connectionUid, toolUid), { body }),
138
+ restoreDraft: (connectionUid, toolUid, versionUid, body) =>
139
+ this.request(
140
+ 'POST',
141
+ `${toolHookPath(connectionUid, toolUid)}/history/${versionUid}/restore`,
142
+ { body },
143
+ ),
124
144
  saveDraft: (connectionUid, toolUid, body) =>
125
145
  this.request('PUT', toolHookPath(connectionUid, toolUid), { body }),
126
146
  setDeployment: (connectionUid, toolUid, body) =>
@@ -145,27 +165,69 @@ export class Rayrun {
145
165
  archive: archiveAccessProfile,
146
166
  create: (body) => this.request('POST', '/access-profiles', { body }),
147
167
  delete: archiveAccessProfile,
168
+ getConfigurationVersion: (uid, versionUid) =>
169
+ this.request('GET', `/access-profiles/${uid}/history/${versionUid}`),
148
170
  list: (query) => this.request('GET', '/access-profiles', { query }),
171
+ listConfigurationVersions: (uid, query) =>
172
+ this.request('GET', `/access-profiles/${uid}/history`, { query }),
149
173
  listTools: (uid, query) => this.request('GET', `/access-profiles/${uid}/tools`, { query }),
150
- setPolicy: (uid, mode, expectedVersion) =>
174
+ restoreConfigurationVersion: (uid, versionUid, body) =>
175
+ this.request('POST', `/access-profiles/${uid}/history/${versionUid}/restore`, { body }),
176
+ setPolicy: (uid, mode, expectedVersion, reason) =>
151
177
  this.request('PATCH', `/access-profiles/${uid}/policy`, {
152
- body: { expectedVersion, mode },
178
+ body: withoutUndefined({ expectedVersion, mode, reason }),
179
+ headers: { prefer: 'return=representation' },
153
180
  }),
154
181
  setToolPolicy: (uid, toolUid, body) =>
155
- this.request('PATCH', `/access-profiles/${uid}/tools/${toolUid}/policy`, { body }),
156
- update: (uid, body) => this.request('PATCH', `/access-profiles/${uid}`, { body }),
182
+ this.request('PATCH', `/access-profiles/${uid}/tools/${toolUid}/policy`, {
183
+ body,
184
+ headers: { prefer: 'return=representation' },
185
+ }),
186
+ update: (uid, body) =>
187
+ this.request('PATCH', `/access-profiles/${uid}`, {
188
+ body,
189
+ headers: { prefer: 'return=representation' },
190
+ }),
157
191
  };
158
192
  this.activity = { list: (query) => this.request('GET', '/activity', { query }) };
159
193
  this.reviews = { list: (query) => this.request('GET', '/reviews', { query }) };
194
+ this.skills = {
195
+ archive: (uid, expectedVersion) =>
196
+ this.request('POST', `/skills/${uid}/archive`, { body: { expectedVersion } }),
197
+ create: (body) => this.request('POST', '/skills', { body }),
198
+ delete: (uid, body) => this.request('DELETE', `/skills/${uid}`, { body }),
199
+ export: (uid) => this.request('GET', `/skills/${uid}/export`),
200
+ exportVersion: (uid, versionUid) =>
201
+ this.request('GET', `/skills/${uid}/versions/${versionUid}/export`),
202
+ get: (uid) => this.request('GET', `/skills/${uid}`),
203
+ list: () => this.request('GET', '/skills'),
204
+ publish: (uid, body) => this.request('POST', `/skills/${uid}/publish`, { body }),
205
+ restoreVersion: (uid, versionUid, body) =>
206
+ this.request('POST', `/skills/${uid}/versions/${versionUid}/restore`, { body }),
207
+ saveDraft: (uid, body) => this.request('PUT', `/skills/${uid}/draft`, { body }),
208
+ setEnabled: (uid, enabled, expectedVersion) =>
209
+ this.request('PATCH', `/skills/${uid}/enabled`, {
210
+ body: { enabled, expectedVersion },
211
+ }),
212
+ updateAudience: (uid, body) => this.request('PATCH', `/skills/${uid}/audience`, { body }),
213
+ validate: (files) => this.request('POST', '/skills/validate', { body: { files } }),
214
+ };
160
215
  this.webhooks = {
161
216
  create: (body) => this.request('POST', '/webhooks', { body }),
162
217
  delete: (uid) => this.request('DELETE', `/webhooks/${uid}`),
218
+ getConfigurationVersion: (uid, versionUid) =>
219
+ this.request('GET', `/webhooks/${uid}/history/${versionUid}`),
163
220
  list: () => this.request('GET', '/webhooks'),
221
+ listConfigurationVersions: (uid, query) =>
222
+ this.request('GET', `/webhooks/${uid}/history`, { query }),
223
+ restoreConfigurationVersion: (uid, versionUid, body) =>
224
+ this.request('POST', `/webhooks/${uid}/history/${versionUid}/restore`, { body }),
225
+ update: (uid, body) => this.request('PATCH', `/webhooks/${uid}`, { body }),
164
226
  verify: verifyWebhookSignature,
165
227
  };
166
228
  }
167
229
 
168
- async request(method, path, { body, query, signal } = {}) {
230
+ async request(method, path, { body, headers, query, signal } = {}) {
169
231
  const url = new URL(`${this.baseUrl}/v1${path}`);
170
232
  for (const [name, value] of Object.entries(withoutUndefined(query ?? {}))) {
171
233
  url.searchParams.set(name, String(value));
@@ -179,6 +241,7 @@ export class Rayrun {
179
241
  response = await this.fetch(url, {
180
242
  body: body === undefined ? undefined : JSON.stringify(body),
181
243
  headers: withoutUndefined({
244
+ ...headers,
182
245
  authorization: `Bearer ${this.#apiKey}`,
183
246
  'content-type': body === undefined ? undefined : 'application/json',
184
247
  'user-agent': '@rayrun/sdk',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rayrun/sdk",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Type-safe client for the Rayrun public API",
5
5
  "license": "MIT",
6
6
  "repository": {