@statelyai/sdk 0.13.0 → 0.13.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.
package/README.md CHANGED
@@ -1,20 +1,32 @@
1
1
  # @statelyai/sdk
2
2
 
3
- > **Preview** -- this SDK is not yet publicly available. Reach out to [team@stately.ai](mailto:team@stately.ai) for early access.
3
+ The public alpha SDK for embedding the Stately visual editor, inspecting live
4
+ actor systems, and using the Stately Studio API.
4
5
 
5
- The Stately SDK lets you embed the [Stately visual editor](https://stately.ai) directly into your own application, inspect live actor systems, and programmatically manage Stately Studio projects and machines.
6
+ APIs may change between minor releases. Review generated source changes before
7
+ committing them.
6
8
 
7
- ## What's coming
9
+ ## Install
10
+
11
+ <!-- install command derived from package.json#name -->
12
+
13
+ ```bash
14
+ npm install @statelyai/sdk
15
+ ```
16
+
17
+ ## Capabilities
8
18
 
9
19
  ### Embeddable editor
10
20
 
21
+ <!-- createStatelyEmbed usage from src/embed.ts and the hosted editor URL -->
22
+
11
23
  Drop a fully interactive state machine editor into any web app. The embed communicates over `postMessage` and gives you full control over theme, layout, panels, read-only mode, and more.
12
24
 
13
25
  ```ts
14
26
  import { createStatelyEmbed } from '@statelyai/sdk';
15
27
 
16
28
  const embed = createStatelyEmbed({
17
- baseUrl: 'https://stately.ai',
29
+ baseUrl: 'https://editor.stately.ai',
18
30
  apiKey: 'your-api-key',
19
31
  });
20
32
 
@@ -68,30 +80,6 @@ Key capabilities:
68
80
  - **Asset uploads** with built-in S3 and Supabase adapters, or bring your own upload handler
69
81
  - **Runtime settings** - toggle color mode, grid, snap lines, autolayout, and view mode on the fly
70
82
 
71
- ### Self-hosting
72
-
73
- The SDK is designed to work with both hosted Stately (`stately.ai`) and self-hosted deployments of the editor.
74
-
75
- When self-hosting, authentication is handled by your editor server, not by this npm package. The editor host supports configurable auth strategies, and you can disable API-key checks for editor-sync endpoints when running behind your own auth layer.
76
-
77
- A fully self-contained deployment with no external auth looks like:
78
-
79
- ```ts
80
- const embed = createStatelyEmbed({
81
- baseUrl: 'https://your-editor.example.com',
82
- });
83
- ```
84
-
85
- Key environment variables for self-hosted deployments:
86
-
87
- | Variable | Purpose |
88
- | --------------------------- | -------------------------------------------- |
89
- | `AUTH_PROVIDER` | Auth strategy used by the editor host |
90
- | `EDITOR_SYNC_AUTH_REQUIRED` | Set to `false` to skip editor-sync API-key checks |
91
- | `STATELY_API_KEY` | Server-side API key for Stately data fetching |
92
- | `STATELY_API_URL` | Stately API base URL override |
93
- | `NEXT_PUBLIC_BASE_URL` | Public-facing editor URL |
94
-
95
83
  ### Studio API client
96
84
 
97
85
  Programmatic access to Stately Studio for managing projects and machines, extracting machine configs from source code, and verifying API keys.
@@ -112,8 +100,10 @@ const extracted = await studio.code.extractMachines(sourceCode);
112
100
  ```
113
101
 
114
102
  Legacy `apiKey` is still accepted as an alias for
115
- `credential: { type: 'api_key', token }`. Use `authMode: 'none'` only for
116
- self-hosted deployments that intentionally accept unauthenticated calls.
103
+ `credential: { type: 'api_key', token }`. The default `authMode: 'auto'` sends
104
+ a credential when present and otherwise lets the server accept or reject an
105
+ unauthenticated request. Use `authMode: 'bearer'` to require a credential before
106
+ making requests, or `authMode: 'none'` to ignore a configured credential.
117
107
 
118
108
  ### Inspector
119
109
 
@@ -127,7 +117,7 @@ import { createInspector } from '@statelyai/sdk';
127
117
 
128
118
  const actor = createActor(machine);
129
119
  const inspector = createInspector({
130
- url: 'ws://localhost:1999/inspect/local',
120
+ url: 'ws://localhost:4242',
131
121
  });
132
122
 
133
123
  inspector.inspect(actor);
@@ -136,15 +126,25 @@ actor.start();
136
126
 
137
127
  XState v5 and v6 inspection events normalize to actor, transition, and stop
138
128
  events before crossing the WebSocket protocol.
139
- In Node, the inspector opens in the default browser automatically.
129
+ In Node, the inspector opens in the default browser automatically. The SDK
130
+ generates a cryptographically random session capability; hosted inspectors send
131
+ signed-out users through OAuth and return them to that same live session. The
132
+ Node process does not need a Stately API key.
140
133
 
141
134
  ### CLI and sync
142
135
 
143
- A `statelyai` CLI for syncing local XState source files with Stately Studio projects: push local machines to the cloud, pull remote changes back into source, and open a local file in a browser-backed visual editor session.
136
+ <!-- CLI package identity and commands from ../cli/package.json and ../cli/src/cli.ts#COMMANDS -->
137
+
138
+ The separate [`statelyai`](https://www.npmjs.com/package/statelyai) CLI syncs
139
+ local XState source files with Stately Studio projects: push local machines,
140
+ pull remote changes, inspect project inventory, compare machines, and open a
141
+ local file in a browser-backed visual editor session.
144
142
 
145
143
  ```bash
144
+ npx statelyai status
146
145
  npx statelyai push
147
146
  npx statelyai pull
147
+ npx statelyai diff ./checkout.machine.ts machine-id
148
148
  npx statelyai open ./checkout.machine.ts
149
149
  ```
150
150
 
@@ -152,6 +152,38 @@ npx statelyai open ./checkout.machine.ts
152
152
 
153
153
  Convert between Studio graph data, XState machine configs, and TypeScript source. Generate types from JSON Schema.
154
154
 
155
- ## Get notified
155
+ ## Support
156
+
157
+ For pricing and support, contact
158
+ [team@stately.ai](mailto:team@stately.ai).
159
+
160
+ ## Self-hosting
161
+
162
+ <!-- self-host configuration from the editor app auth and editor-sync routes -->
163
+
164
+ The SDK works with both the hosted Stately editor (`editor.stately.ai`) and
165
+ self-hosted deployments.
166
+
167
+ When self-hosting, authentication is handled by your editor server, not by this
168
+ npm package. The editor host supports configurable auth strategies, and you can
169
+ disable API-key checks for editor-sync endpoints when running behind your own
170
+ auth layer.
171
+
172
+ A fully self-contained deployment with no external auth looks like:
173
+
174
+ ```ts
175
+ const embed = createStatelyEmbed({
176
+ baseUrl: 'https://your-editor.example.com',
177
+ });
178
+ ```
179
+
180
+ Key environment variables for self-hosted deployments:
181
+
182
+ | Variable | Purpose |
183
+ | --------------------------- | ------------------------------------------------- |
184
+ | `AUTH_PROVIDER` | Auth strategy used by the editor host |
185
+ | `EDITOR_SYNC_AUTH_REQUIRED` | Set to `false` to skip editor-sync API-key checks |
186
+ | `NEXT_PUBLIC_BASE_URL` | Public-facing editor URL |
156
187
 
157
- This SDK and the embeddable editor are in active development. For early access, pricing, and self-hosting details, contact [team@stately.ai](mailto:team@stately.ai).
188
+ For self-hosting details, contact
189
+ [team@stately.ai](mailto:team@stately.ai).
package/dist/index.d.mts CHANGED
@@ -5,7 +5,7 @@ import { i as getCredentialToken, n as StatelyCredential, r as createAuthorizati
5
5
  import { AssetConfig, StatelyEmbed, StatelyEmbedOptions, createStatelyEmbed } from "./embed.mjs";
6
6
  import { _ as serializeJS, c as MachineConfigOptions, d as contextSchemaToTSType, f as eventsSchemaToTSType, g as raw, h as jsonSchemaToTSType, i as CodeGenGraph, l as RawCode, m as graphToXStateTS, o as GraphPatch, p as graphToMachineConfig, t as ActionLocation, u as XStateTSOptions } from "./index-DVjNSTuQ.mjs";
7
7
  import { C as EventTypeData, S as DigraphNodeConfig, _ as studioMachineConverter, a as StatelyGraphData, b as DigraphConfig, c as StatelyInvoke, d as StudioAction, f as StudioEdge, g as fromStudioMachine, h as StudioNode, i as StatelyGraph, l as StatelyNodeData, m as StudioMachine, o as StatelyGuard, r as StatelyEdgeData, t as StatelyAction, v as toStudioMachine, w as StateNodeJSONData, x as DigraphEdgeConfig, y as DigraphAction } from "./graph-R0sbxnZ7.mjs";
8
- import { a as InspectorEvents, c as createStatelyInspector, d as MultiplexedWebSocketConnectionOptions, f as Transport, h as createWebSocketTransport, i as Inspector, l as MultiplexedChannelOptions, m as createPostMessageTransport, n as CreateInspectorOptions, o as ManualActorOptions, p as createMultiplexedWebSocketConnection, r as InspectedTransition, s as createInspector, t as AdoptedActor, u as MultiplexedWebSocketConnection } from "./inspect-BMHheAvx.mjs";
8
+ import { a as InspectorEvents, c as createStatelyInspector, d as MultiplexedWebSocketConnectionOptions, f as Transport, h as createWebSocketTransport, i as Inspector, l as MultiplexedChannelOptions, m as createPostMessageTransport, n as CreateInspectorOptions, o as ManualActorOptions, p as createMultiplexedWebSocketConnection, r as InspectedTransition, s as createInspector, t as AdoptedActor, u as MultiplexedWebSocketConnection } from "./inspect-COqtklcn.mjs";
9
9
  import { ConnectedRepo, CreateMachineFromDefinitionInput, CreateMachineFromTemplateInput, CreateMachineInput, CreateMachineTemplate, CreateProjectInput, EnsureProjectInput, ExtractMachinesResponse, ExtractedMachine, GetMachineOptions, ProjectData, ProjectMachine, ProjectVisibility, RepoType, StudioApiError, StudioClient, StudioClientOptions, StudioMachineRecord, UpdateMachineInput, VerifyApiKeyResponse, XStateVersion, createStatelyClient } from "./studio.mjs";
10
10
  import { OAuthAuthorizationServerMetadata, OAuthClientRegistrationResponse, OAuthProtectedResourceMetadata, OAuthTokenResponse, PkcePair, buildAuthorizeUrl, createPkcePair, discoverAuthorizationServer, discoverProtectedResource, exchangeCodeForToken, refreshToken, registerOAuthClient } from "./oauth.mjs";
11
11
  import { PlanSyncOptions, PullSyncResult, PushLocalMachineLinksResult, PushSyncOptions, PushSyncProjectOptions, PushSyncResult, ResolvedSyncInput, SyncInputFormat, SyncPlan, SyncPlanSummary } from "./sync.mjs";
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@ import { n as createPostMessageTransport, r as createWebSocketTransport, t as cr
2
2
  import { INSPECTION_PROTOCOL_VERSION } from "./protocol.mjs";
3
3
  import { createStatelyEmbed } from "./embed.mjs";
4
4
  import { createS3AssetUploadAdapter, createSupabaseAssetUploadAdapter } from "./assetStorage.mjs";
5
- import { n as createStatelyInspector, t as createInspector } from "./inspect-D9GyHTTW.mjs";
5
+ import { n as createStatelyInspector, t as createInspector } from "./inspect-pcNCbL7j.mjs";
6
6
  import { createAuthorizationHeader, getCredentialToken } from "./auth.mjs";
7
7
  import { StudioApiError, createStatelyClient } from "./studio.mjs";
8
8
  import { buildAuthorizeUrl, createPkcePair, discoverAuthorizationServer, discoverProtectedResource, exchangeCodeForToken, refreshToken, registerOAuthClient } from "./oauth.mjs";
@@ -204,8 +204,9 @@ interface CreateInspectorOptions {
204
204
  /** Auto-open browser to visualizer. Default: `true`. */
205
205
  autoOpen?: boolean;
206
206
  /**
207
- * Relay session id. Defaults to a random id. This is the `?session=<id>`
208
- * value the viz iframe connects with.
207
+ * Relay session capability. Defaults to a cryptographically random UUID.
208
+ * This is the `?session=<id>` value the visualizer connects with. Custom
209
+ * values used with a hosted relay must be unguessable.
209
210
  */
210
211
  sessionId?: string;
211
212
  /** Display name for this system in the visualizer. */
@@ -33,9 +33,9 @@ const defaultSerializeSnapshot = (snapshot) => ({
33
33
  status: snapshot?.status
34
34
  });
35
35
  const defaultExtractMachineConfig = (actor, source) => actor?.logic?.config ?? source?.config ?? null;
36
- let nextManualId = 0;
37
36
  function generateSessionId() {
38
- return `manual-${Date.now()}-${nextManualId++}`;
37
+ if (!globalThis.crypto?.randomUUID) throw new Error("createInspector() requires crypto.randomUUID() to generate a secure session capability. Pass sessionId explicitly in older runtimes.");
38
+ return globalThis.crypto.randomUUID();
39
39
  }
40
40
  function createInspectorLaunchUrl(websocketUrl, sessionId) {
41
41
  try {
@@ -1,3 +1,3 @@
1
1
  import { EditorCapabilities, EmbedEventHandler, EmbedEventMap, EmbedEventName, EmbedMode, ExportCallOptions, ExportFormat, ExportFormatMap, InspectionAction, InspectionSentEvent, InspectionTakenTransition } from "./protocol.mjs";
2
- import { a as InspectorEvents, c as createStatelyInspector, f as Transport, i as Inspector, n as CreateInspectorOptions, o as ManualActorOptions, r as InspectedTransition, s as createInspector, t as AdoptedActor } from "./inspect-BMHheAvx.mjs";
2
+ import { a as InspectorEvents, c as createStatelyInspector, f as Transport, i as Inspector, n as CreateInspectorOptions, o as ManualActorOptions, r as InspectedTransition, s as createInspector, t as AdoptedActor } from "./inspect-COqtklcn.mjs";
3
3
  export { AdoptedActor, CreateInspectorOptions, EditorCapabilities, EmbedEventHandler, EmbedEventMap, EmbedEventName, EmbedMode, ExportCallOptions, ExportFormat, ExportFormatMap, InspectedTransition, InspectionAction, InspectionSentEvent, InspectionTakenTransition, Inspector, InspectorEvents, ManualActorOptions, Transport, createInspector, createStatelyInspector };
package/dist/inspect.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { n as createStatelyInspector, t as createInspector } from "./inspect-D9GyHTTW.mjs";
1
+ import { n as createStatelyInspector, t as createInspector } from "./inspect-pcNCbL7j.mjs";
2
2
 
3
3
  export { createInspector, createStatelyInspector };
package/dist/studio.mjs CHANGED
@@ -91,8 +91,9 @@ function createStatelyClient(options = {}) {
91
91
  const authMode = authModeOverride ?? defaultAuthMode;
92
92
  const credential = credentialOverride ?? defaultCredential;
93
93
  if (authMode !== "none") {
94
- if (!getCredentialToken(credential) || !credential) throw new StudioApiError("No Stately credential configured. Pass createStatelyClient({ credential }) or set authMode: \"none\" for no-auth self-hosted deployments.", 401);
95
- headers.set("Authorization", createAuthorizationHeader(credential));
94
+ const token = getCredentialToken(credential);
95
+ if (authMode === "bearer" && (!token || !credential)) throw new StudioApiError("No Stately credential configured. Pass createStatelyClient({ credential }) or use authMode: \"auto\" to let the server decide whether authentication is required.", 401);
96
+ if (token && credential) headers.set("Authorization", createAuthorizationHeader(credential));
96
97
  }
97
98
  const response = await fetchImpl(joinApiUrl(baseUrl, path), {
98
99
  ...init,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statelyai/sdk",
3
- "version": "0.13.0",
3
+ "version": "0.13.2",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "dist",