@usestatemachines/sdk 0.7.0 → 0.8.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 +86 -33
- package/agents/SKILL.md +71 -48
- package/agents/index.d.ts +2 -0
- package/agents/index.js +9 -7
- package/agents/llms.txt +23 -15
- package/agents/prompt.md +5 -25
- package/esm/extensions/client.d.ts +11 -7
- package/esm/extensions/client.js +32 -49
- package/esm/extensions/credentials.d.ts +25 -8
- package/esm/extensions/credentials.js +75 -40
- package/esm/extensions/environment.d.ts +1 -1
- package/esm/extensions/errors.js +1 -1
- package/esm/extensions/index.d.ts +2 -2
- package/esm/extensions/yaml.js +14 -12
- package/esm/funcs/environments-creators.d.ts +11 -0
- package/esm/funcs/environments-creators.js +90 -0
- package/esm/funcs/environments-list.js +2 -0
- package/esm/funcs/requests-list.js +5 -1
- package/esm/funcs/requests-stats.js +5 -1
- package/esm/lib/config.d.ts +2 -2
- package/esm/lib/config.js +2 -2
- package/esm/models/app-entry.d.ts +8 -0
- package/esm/models/app-entry.js +11 -0
- package/esm/models/create-environment-app.d.ts +25 -0
- package/esm/models/create-environment-app.js +14 -0
- package/esm/models/create-environment.d.ts +3 -26
- package/esm/models/create-environment.js +2 -19
- package/esm/models/credential.d.ts +50 -0
- package/esm/models/credential.js +60 -0
- package/esm/models/credentials.d.ts +26 -5
- package/esm/models/credentials.js +20 -3
- package/esm/models/environment-failure.d.ts +3 -2
- package/esm/models/environment-failure.js +3 -2
- package/esm/models/environment.d.ts +4 -1
- package/esm/models/environment.js +2 -1
- package/esm/models/error.d.ts +1 -0
- package/esm/models/error.js +1 -0
- package/esm/models/index.d.ts +6 -1
- package/esm/models/index.js +6 -1
- package/esm/models/mcp-server.d.ts +11 -0
- package/esm/models/mcp-server.js +16 -0
- package/esm/models/mcp-tool.d.ts +12 -0
- package/esm/models/mcp-tool.js +16 -0
- package/esm/models/me.d.ts +2 -0
- package/esm/models/me.js +2 -0
- package/esm/models/operations/create-credentials.d.ts +2 -0
- package/esm/models/operations/create-credentials.js +1 -0
- package/esm/models/operations/get-request-stats.d.ts +10 -2
- package/esm/models/operations/get-request-stats.js +5 -1
- package/esm/models/operations/index.d.ts +1 -0
- package/esm/models/operations/index.js +1 -0
- package/esm/models/operations/list-environment-creators.d.ts +23 -0
- package/esm/models/operations/list-environment-creators.js +20 -0
- package/esm/models/operations/list-environments.d.ts +5 -1
- package/esm/models/operations/list-environments.js +2 -0
- package/esm/models/operations/list-requests.d.ts +10 -2
- package/esm/models/operations/list-requests.js +5 -1
- package/esm/models/request-detail.d.ts +8 -1
- package/esm/models/request-detail.js +5 -1
- package/esm/models/request-stats.d.ts +8 -0
- package/esm/models/request-stats.js +9 -0
- package/esm/models/request.d.ts +8 -1
- package/esm/models/request.js +5 -1
- package/esm/models/service.d.ts +25 -0
- package/esm/models/service.js +28 -0
- package/esm/models/snapshot.d.ts +7 -0
- package/esm/models/snapshot.js +3 -0
- package/esm/models/version.d.ts +2 -2
- package/esm/models/version.js +2 -2
- package/esm/sdk/environments.d.ts +1 -0
- package/esm/sdk/environments.js +4 -0
- package/esm/types/discriminated-union.d.ts +24 -0
- package/esm/types/discriminated-union.js +60 -0
- package/esm/types/smart-union.js +2 -1
- package/openapi.json +596 -116
- package/package.json +6 -1
- package/esm/models/api.d.ts +0 -17
- package/esm/models/api.js +0 -21
package/README.md
CHANGED
|
@@ -14,13 +14,18 @@ npm install @usestatemachines/sdk
|
|
|
14
14
|
|
|
15
15
|
## Quickstart
|
|
16
16
|
|
|
17
|
+
<!-- quickstart:start -->
|
|
17
18
|
```ts
|
|
18
19
|
import { StateMachines } from '@usestatemachines/sdk';
|
|
19
20
|
|
|
20
21
|
const sm = new StateMachines(); // reads STATEMACHINES_API_KEY
|
|
21
|
-
const env = await sm.environments.create(
|
|
22
|
+
const env = await sm.environments.create(
|
|
23
|
+
{ apps: ['salesforce'] },
|
|
24
|
+
{ wait: false },
|
|
25
|
+
);
|
|
22
26
|
|
|
23
27
|
try {
|
|
28
|
+
await sm.environments.wait(env.id, { status: 'running' });
|
|
24
29
|
const salesforce = await env.connect('salesforce');
|
|
25
30
|
const res = await salesforce.fetch('/services/data/v67.0/limits');
|
|
26
31
|
console.log(res.status, await res.json());
|
|
@@ -28,39 +33,53 @@ try {
|
|
|
28
33
|
await env.delete();
|
|
29
34
|
}
|
|
30
35
|
```
|
|
36
|
+
<!-- quickstart:end -->
|
|
31
37
|
|
|
32
|
-
`create` waits until the environment is `running
|
|
33
|
-
the environment
|
|
38
|
+
`create` waits until the environment is `running` by default. This example uses `wait: false`
|
|
39
|
+
to retain the environment ID before waiting, so cleanup also covers startup failures. It rejects
|
|
40
|
+
unsuccessful app responses and preserves both verification and cleanup errors.
|
|
41
|
+
[Waiting](#waiting) lists what each method throws.
|
|
34
42
|
|
|
35
43
|
## The client
|
|
36
44
|
|
|
37
45
|
```ts
|
|
38
46
|
const sm = new StateMachines({
|
|
39
47
|
apiKey: process.env.STATEMACHINES_API_KEY, // the default where `process` exists
|
|
40
|
-
baseUrl: 'https://api.usestatemachines.com', // the default
|
|
41
48
|
workspaceId: 'ws_...', // for member tokens; an API key has its own workspace
|
|
42
49
|
fetch, // defaults to the global fetch
|
|
43
50
|
attemptTimeoutMs: 60_000, // per HTTP attempt; a retry gets a fresh one
|
|
44
51
|
});
|
|
45
52
|
```
|
|
46
53
|
|
|
54
|
+
`baseUrl` takes precedence over `STATEMACHINES_BASE_URL`. The SDK reads the environment
|
|
55
|
+
variable where `process` exists. If neither is set, it uses `https://api.usestatemachines.com`.
|
|
56
|
+
|
|
57
|
+
The selected URL must be an HTTPS origin. HTTP is allowed only for `localhost` or `127.0.0.1`,
|
|
58
|
+
with an optional port. A single trailing slash is allowed. Credentials, paths, queries,
|
|
59
|
+
fragments, URL templates, and URL spellings that require normalization are rejected.
|
|
60
|
+
An empty or invalid selected value throws `TypeError` before any request.
|
|
61
|
+
|
|
62
|
+
`sm.me()` returns the caller's `credential` metadata, including its kind, ID, name, expiry
|
|
63
|
+
dates, and API key kind. Expiry dates are `Date` objects when present, or `null`.
|
|
64
|
+
|
|
47
65
|
| Namespace | Methods |
|
|
48
66
|
| --- | --- |
|
|
49
67
|
| `sm` | `me()` |
|
|
50
68
|
| `sm.apps` | `list(query?)`, `versions(appId, query?)` |
|
|
51
69
|
| `sm.workspaces` | `list(query?)`, `get(id)` |
|
|
52
|
-
| `sm.environments` | `create(input, options?)`, `list(query?)`, `get(id)`, `update(id, { name?, labels? })`, `delete(id)`, `wait(id, { status })`, `connect(id,
|
|
70
|
+
| `sm.environments` | `create(input, options?)`, `list(query?)`, `get(id)`, `update(id, { name?, labels? })`, `delete(id)`, `wait(id, { status })`, `connect(id, appName, { actorId?, services? }?)` |
|
|
53
71
|
| `sm.snapshots` | `create({ environmentId, name? }, options?)`, `list(query?)`, `get(id)`, `update(id, { name })`, `delete(id)`, `wait(id, { status })` |
|
|
54
72
|
| `sm.requests` | `list(query)`, `get(id)`, `stats(query)`, `body(id, 'request' \| 'response')` |
|
|
55
73
|
| `sm.auditEvents` | `list(query?)` |
|
|
56
74
|
|
|
57
|
-
Every environment the SDK returns carries bound helpers: `env.connect(
|
|
75
|
+
Every environment the SDK returns carries bound helpers: `env.connect(appName)`, `env.delete()`, `env.refresh()` and `env.snapshots.create({ name? })`. They are
|
|
58
76
|
not enumerable, so `JSON.stringify(env)` holds only the API's fields.
|
|
59
77
|
|
|
60
78
|
## Apps
|
|
61
79
|
|
|
62
|
-
A string names the app, and its name in the environment is the same string. Use the
|
|
63
|
-
for your own name, for two copies of one app, or for
|
|
80
|
+
A string names the app by its ID, and its name in the environment is the same string. Use the
|
|
81
|
+
object form, with the ID in `appId`, for your own name, for two copies of one app, or for the
|
|
82
|
+
app's setup:
|
|
64
83
|
|
|
65
84
|
```ts
|
|
66
85
|
await sm.environments.create({
|
|
@@ -70,44 +89,62 @@ await sm.environments.create({
|
|
|
70
89
|
apps: [
|
|
71
90
|
'salesforce',
|
|
72
91
|
{
|
|
73
|
-
|
|
92
|
+
appId: 'salesforce',
|
|
74
93
|
name: 'partner-org',
|
|
75
|
-
|
|
94
|
+
setup: { settings: { soapApiLoginEnabled: false } },
|
|
76
95
|
},
|
|
77
96
|
],
|
|
78
97
|
});
|
|
79
98
|
```
|
|
80
99
|
|
|
81
|
-
`
|
|
82
|
-
|
|
83
|
-
`
|
|
84
|
-
|
|
85
|
-
|
|
100
|
+
`setup` is passed to the app unchanged, and the app applies it when the environment first starts.
|
|
101
|
+
Salesforce takes
|
|
102
|
+
`{ preset?: 'development', configure?, settings?: { soapApiLoginEnabled?: boolean }, automation? }`,
|
|
103
|
+
where `configure` can set the organization's `Name` and the administrator's `Username`, and
|
|
104
|
+
`automation` holds the rules and flows that the app runs. A refused value fails the start with
|
|
105
|
+
`failure.code: 'invalid_setup'`, and its `failure.message` starts with the path of the value, such
|
|
106
|
+
as `setup.preset`.
|
|
86
107
|
|
|
87
|
-
`
|
|
88
|
-
|
|
108
|
+
`services` holds the configuration of each service that takes one, by service ID. Salesforce's
|
|
109
|
+
`api` service takes none. The API refuses a wrong value at create with `invalid_request`. The app
|
|
110
|
+
checks `services` again when the environment starts, and a value that it refuses fails the start
|
|
111
|
+
with `failure.code: 'invalid_services'`.
|
|
89
112
|
|
|
90
|
-
|
|
113
|
+
`sm.apps.list()` lists the apps. `sm.apps.versions(appId)` lists each version's services and
|
|
114
|
+
actors. A new environment runs each app's default version.
|
|
91
115
|
|
|
92
|
-
|
|
93
|
-
`expiresAt` and `login`, plus `fetch(path, init?)`.
|
|
116
|
+
## Credentials
|
|
94
117
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
-
|
|
118
|
+
`env.connect(appName, { actorId?, services? })` returns the API's `Credentials`: `token`,
|
|
119
|
+
`services`, `expiresAt` and `login`, plus `fetch(path, init?)` and `service(id)`.
|
|
120
|
+
|
|
121
|
+
- Each entry of `services` has an `id`, a `url` and the `headers` that every request to that URL
|
|
122
|
+
needs. A service's `url` is the app URL followed by the service's `path`. The `api` service is
|
|
123
|
+
at `/`, so its `url` is the app URL. Its `headers` hold `Authorization: Bearer` with `token`
|
|
124
|
+
and, unless the environment has `tokenInUrl: true`, `StateMachines-Environment-Token`.
|
|
125
|
+
- The credentials always list each `public` service of the app's version. The `services` option
|
|
126
|
+
names more services to list, by ID, and a `preview` service is listed only when it is named.
|
|
127
|
+
`sm.apps.versions(appId)` gives the `path` and `visibility` of each service that you can name.
|
|
128
|
+
An unknown ID, or an ID named twice, fails with `invalid_request`.
|
|
129
|
+
- `service(id)` returns the entry with that ID. It throws a `TypeError` that names the listed
|
|
130
|
+
services when there is none.
|
|
131
|
+
- `fetch` joins `path` to the `url` of the `api` service and sends its `headers` as defaults. A
|
|
132
|
+
header that you set in `init.headers` is sent in place of the service's header of the same
|
|
133
|
+
name, whatever its case. The exception is the service's `StateMachines-Environment-Token`,
|
|
134
|
+
which `fetch` always sends when the service has one. A leading `/` means the root of the app.
|
|
135
|
+
- Salesforce SOAP also takes the token in the envelope: put `credentials.token` in
|
|
99
136
|
`SessionHeader/sessionId` yourself.
|
|
100
137
|
- `fetch` never sends your API key, never follows redirects, never retries and only reaches paths
|
|
101
|
-
under `
|
|
138
|
+
under the `api` service URL.
|
|
102
139
|
- `actorId` defaults to the app's default actor (for Salesforce, the administrator). Pick another
|
|
103
140
|
from the version's `actors` to act with that user's permissions.
|
|
104
141
|
- `login` holds what the vendor's own login call needs, when the version declares one for the
|
|
105
142
|
actor.
|
|
106
|
-
- `token` and `headers` are secrets. To use another client, such as jsforce, send
|
|
107
|
-
the
|
|
143
|
+
- `token` and each service's `headers` are secrets. To use another client, such as jsforce, send
|
|
144
|
+
the service's `headers` only to its `url`, with redirects off.
|
|
108
145
|
|
|
109
|
-
Environments created with `tokenInUrl: true` carry the environment token in `url`
|
|
110
|
-
`headers
|
|
146
|
+
Environments created with `tokenInUrl: true` carry the environment token in each service's `url`
|
|
147
|
+
instead of in its `headers`.
|
|
111
148
|
|
|
112
149
|
## Snapshots
|
|
113
150
|
|
|
@@ -173,7 +210,7 @@ response body.
|
|
|
173
210
|
| `body_too_large` | 413 | The request body is over the API's size limit, which the message names. |
|
|
174
211
|
| `version_unavailable` | 422 | The app has no default version. |
|
|
175
212
|
| `environment_limit_reached` | 429 | Too many environments `starting` or `running`. |
|
|
176
|
-
| `internal_error` | 500 | An error
|
|
213
|
+
| `internal_error` | 500 | An error in State Machines. |
|
|
177
214
|
| `unavailable` | 503 | Retried automatically. |
|
|
178
215
|
|
|
179
216
|
### Errors from the app URL
|
|
@@ -187,7 +224,9 @@ error envelope, and never retries them. These codes come from State Machines, in
|
|
|
187
224
|
| `environment_starting` | 503 | The environment is still `starting`. The response carries `Retry-After`. |
|
|
188
225
|
| `environment_unavailable` | 503 | The app is restarting or did not answer. The response carries `Retry-After`. |
|
|
189
226
|
| `response_too_large` | 502 | The app's response is over the size limit of State Machines. |
|
|
190
|
-
| `
|
|
227
|
+
| `invalid_setup` | 503 | The app refused its `setup` after the environment started, such as in a newer version. The message starts with the path of the value. |
|
|
228
|
+
| `invalid_services` | 503 | The app refused a value in `services` after the environment started. The message starts with the path of the value. |
|
|
229
|
+
| `unsupported_protocol` | 501 | The app does not serve this path, method or content type, or the request body is compressed. |
|
|
191
230
|
|
|
192
231
|
## Retries and timeouts
|
|
193
232
|
|
|
@@ -220,8 +259,9 @@ are open: handle values you don't recognise.
|
|
|
220
259
|
|
|
221
260
|
## Upgrade from 0.5
|
|
222
261
|
|
|
223
|
-
0.
|
|
224
|
-
against it.
|
|
262
|
+
0.8 follows the current API. 0.5 and older call routes that the API no longer serves, so they fail
|
|
263
|
+
against it. 0.7 removed `pause()` and `resume()`, because the API no longer serves them. Create a
|
|
264
|
+
snapshot of the data to reuse, then create a new environment from it.
|
|
225
265
|
|
|
226
266
|
| 0.5 | 0.6 |
|
|
227
267
|
| --- | --- |
|
|
@@ -243,6 +283,19 @@ against it.
|
|
|
243
283
|
| `error.retryAfter` | `error.retryAfterMs` |
|
|
244
284
|
| Error codes such as `environment-limit` and `capture-in-progress` | Codes such as `environment_limit_reached` and `snapshot_in_progress`. See [Errors](#errors) |
|
|
245
285
|
|
|
286
|
+
## Upgrade from 0.7
|
|
287
|
+
|
|
288
|
+
| 0.7 | 0.8 |
|
|
289
|
+
| --- | --- |
|
|
290
|
+
| `{ app, settings }` | `{ appId, setup }` |
|
|
291
|
+
| `credentials.app`, a request's `app`, `failure.app` | `credentials.appName`, a request's `appName`, `failure.appName` |
|
|
292
|
+
| `sm.requests.list({ app })`, `sm.requests.stats({ app })` | `sm.requests.list({ appName })`, `sm.requests.stats({ appName })` |
|
|
293
|
+
| `app` in the `data` of an audit event, such as `credentials.created` | `appName` |
|
|
294
|
+
| `credentials.url`, `credentials.headers` | `credentials.service('api').url`, `credentials.service('api').headers` |
|
|
295
|
+
| `fetch` puts `token` in the header of the API whose path matches | `fetch` sends the headers of the `api` service on every path |
|
|
296
|
+
| A version's `apis` | A version's `services` |
|
|
297
|
+
| The failure code of a refused `settings` value | `invalid_setup` for a refused `setup`, and `invalid_services` for a refused `services` value |
|
|
298
|
+
|
|
246
299
|
## License
|
|
247
300
|
|
|
248
301
|
MIT
|
package/agents/SKILL.md
CHANGED
|
@@ -1,27 +1,56 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: state-machines
|
|
3
|
-
description: Use when
|
|
3
|
+
description: Use when setting up State Machines or running code, integration tests, or API experiments against disposable SaaS replicas such as Salesforce. Applies to @usestatemachines/sdk and STATEMACHINES_API_KEY, including environment creation, actors, snapshots, cleanup and recovery.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
## Start with the user's task
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
During skill installation, read the repository instructions and preserve its existing structure. Do not create a new project, install dependencies, write examples or create remote resources. Report the installed skill location and any reload requirement, then ask "What would you like to run or test?" and wait. Skill installation does not verify a connection.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
2. Create the environment with only the apps the task needs: `const env = await sm.environments.create({ apps: ['salesforce'] })`. Log `await sm.apps.list()` for each app's ID. Don't guess IDs. `create` waits until the environment is `running`. If the start fails, the server deletes the environment and `create` throws `EnvironmentFailedError` with `err.environment.failure`.
|
|
12
|
-
3. Open a `try` right after `create` returns, and call `await env.delete()` in its `finally`. It deletes the environment and its data.
|
|
13
|
-
4. Get credentials for one app: `const crm = await env.connect('salesforce')`. This acts as the app's default actor, the Salesforce administrator. To act with another user's permissions, pass an `actorId` from the `actors` of the environment's version: the entry of `(await sm.apps.versions('salesforce')).data` whose `id` is `env.apps[0].versionId`. Salesforce actor IDs are its user IDs, such as `005…`, never a role name.
|
|
14
|
-
5. Call the app with `crm.fetch(path)`. A leading `/` means the root of the app's `url`.
|
|
10
|
+
Once the user chooses a task, inspect the project's package manager, runtime, runner and secret loader. Install or reuse a compatible `@usestatemachines/sdk` only when the task needs it. Read the installed README for API signatures and `package.json` for runtime requirements. The SDK is ESM and runs on Node.js and Cloudflare Workers, not in a browser. Follow the user's task and existing project conventions without requiring a separate onboarding example.
|
|
15
11
|
|
|
16
|
-
|
|
12
|
+
## Check access in the right process
|
|
13
|
+
|
|
14
|
+
The SDK reads `STATEMACHINES_API_KEY` from the process environment. It does not load `.env` files. Use the project's existing test command or secret loader. An empty variable in your current shell does not prove that the test process lacks it. Verify presence without displaying the value. In Workers, pass the binding explicitly with `new StateMachines({ apiKey: env.STATEMACHINES_API_KEY })`.
|
|
15
|
+
|
|
16
|
+
Call `sm.me()` to verify access and workspace scope before creating resources. `me.limits` can be null. If the key is missing, prepare the local test or example and tell the user the exact local file, binding, or launch command to configure and rerun, without asking for the key in chat. Do not call the API until access is available. If access is denied or the workspace differs from the task, report the blocker. Do not invite or remove members, or change permissions.
|
|
17
|
+
|
|
18
|
+
Never print, log or commit API keys, `credentials.token`, the `headers` of `credentials.services`, environment dumps, or secret-file contents. Use synthetic test data.
|
|
19
|
+
|
|
20
|
+
## Run the user’s chosen task
|
|
21
|
+
|
|
22
|
+
Apply this section after setup, once the user has chosen a task.
|
|
23
|
+
|
|
24
|
+
- `sm.apps.list()` returns app IDs. Every list returns `{ data, nextCursor }`. Follow cursors until the required entry is found or `nextCursor` is null.
|
|
25
|
+
- Create only the apps the task needs. A string such as `'salesforce'` is both its app ID and its name in the environment. For named apps, later `connect()` calls use the name.
|
|
26
|
+
- `connect(appName)` uses the app's default actor, the Salesforce administrator. For another actor, find the matching app by name in `environment.apps`, read its `versionId`, then find that exact version through `sm.apps.versions(appId)`. Use an actor ID from its `actors`, never a role label, workspace member ID, or the first version in a list.
|
|
27
|
+
- Check the app's services and [known differences](https://docs.usestatemachines.com/apps/known-differences.md) for the behavior under test. A replica does not import a customer's org or run arbitrary customer automation.
|
|
28
|
+
- Configure the existing integration's test transport with the returned app URL and credentials. Verify its requests reach that URL. A successful standalone SDK request does not prove the integration uses the replica. If transport configuration needs a broader change, explain it before expanding the task.
|
|
29
|
+
- Check the expected HTTP status and assert the result. For writes, read the stored data back and assert the relevant fields. For negative tests, assert the expected error. Do not weaken an assertion to make unsupported behavior pass.
|
|
30
|
+
|
|
31
|
+
## Own the full lifecycle
|
|
32
|
+
|
|
33
|
+
Create with `{ wait: false }` to retain the accepted environment ID before waiting. Enter `try` immediately, then wait for `running`, connect and run the check inside it. Delete in `finally`, including after a startup failure, timeout or failed assertion. An aborted wait does not cancel the work that the API accepted. Cleanup must use a fresh, un-aborted signal. Preserve both verification and cleanup errors, and report the environment ID if deletion fails.
|
|
34
|
+
|
|
35
|
+
Delete only environments created for this task. If the organization is at its limit, clean up a known leftover from this task or ask the user to free capacity. Do not delete unrelated environments or a user-supplied reusable snapshot.
|
|
36
|
+
|
|
37
|
+
The SDK retries management connection errors and `502`, `503`, `504` with one idempotency key per create call. To recover across separate attempts or a restart, retain the input and an explicit `idempotencyKey` before creation. Replay using the same input, key, workspace and caller. Do not create a replacement with a new key while the first outcome is unknown. See [operation recovery](https://docs.usestatemachines.com/sdk-api/recovery.md).
|
|
38
|
+
|
|
39
|
+
## Optional connection check
|
|
40
|
+
|
|
41
|
+
Run this only when the user asks to verify the connection. It proves the connection and cleanup, not an existing integration's behavior. Save it in the project's examples or test location and run it with the existing TypeScript runner and secret loader. In a new Node.js project, `state-quickstart.mts` and `npx tsx state-quickstart.mts` are a fallback. Load the key into that process first.
|
|
17
42
|
|
|
18
43
|
```ts
|
|
19
44
|
import { StateMachines } from '@usestatemachines/sdk';
|
|
20
45
|
|
|
21
46
|
const sm = new StateMachines(); // reads STATEMACHINES_API_KEY
|
|
22
|
-
const env = await sm.environments.create(
|
|
47
|
+
const env = await sm.environments.create(
|
|
48
|
+
{ apps: ['salesforce'] },
|
|
49
|
+
{ wait: false },
|
|
50
|
+
);
|
|
23
51
|
|
|
24
52
|
try {
|
|
53
|
+
await sm.environments.wait(env.id, { status: 'running' });
|
|
25
54
|
const salesforce = await env.connect('salesforce');
|
|
26
55
|
const res = await salesforce.fetch('/services/data/v67.0/limits');
|
|
27
56
|
console.log(res.status, await res.json());
|
|
@@ -30,41 +59,35 @@ try {
|
|
|
30
59
|
}
|
|
31
60
|
```
|
|
32
61
|
|
|
33
|
-
##
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
|
55
|
-
|
|
|
56
|
-
| `
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
| `environment_not_running`, 409, from `crm.fetch` | The environment is failed or deleted. `crm.fetch` returns it as a response and never retries. | Read `(await res.json()).error.status`. Create a new environment if you need another run. |
|
|
66
|
-
| `environment_starting` or `environment_unavailable`, 503, from `crm.fetch` | The app is starting or restarting. | Wait the `Retry-After` seconds and call again. |
|
|
67
|
-
| A vendor client such as jsforce is refused by the gateway | The gateway needs `StateMachines-Environment-Token` on every request. | Prefer `crm.fetch`. If you pass `crm.headers` to another client, send them only to `crm.url` and disable redirects. |
|
|
68
|
-
| `TypeError: Pass apiKey or set STATEMACHINES_API_KEY.` | No key in the environment. | Ask the user to set `STATEMACHINES_API_KEY`. In Workers, pass `apiKey`. |
|
|
69
|
-
|
|
70
|
-
More: https://docs.usestatemachines.com, https://app.usestatemachines.com/llms.txt and https://www.npmjs.com/package/@usestatemachines/sdk
|
|
62
|
+
## Load details when needed
|
|
63
|
+
|
|
64
|
+
- **Repeated fixtures or parallel tests:** Read [isolated tests](https://docs.usestatemachines.com/sdk-api/testing.md). Save seeded data with `env.snapshots.create({ name })`, then create each test's environment with `{ snapshotId }`. A snapshot in `saving` cannot be deleted yet. Retain its ID and wait for `ready` or `failed` before cleanup. Delete a reusable snapshot only when the task calls for it.
|
|
65
|
+
- **Another actor, vendor client or SOAP:** Read [credentials](https://docs.usestatemachines.com/environments/credentials.md). `credentials.fetch()` confines requests to the app URL, adds its authentication headers, and never follows redirects. External clients must send a service's `headers` only to its `url` and disable redirects. For Salesforce SOAP, put the actor token in `SessionHeader/sessionId` in the envelope.
|
|
66
|
+
- **Cloudflare Workers:** Pass the key explicitly. Use `{ wait: false }` and keep the environment ID across requests or in the job's state. A request ending does not cancel startup. Follow the worker's background-job lifecycle for polling and cleanup.
|
|
67
|
+
- **Long runs:** Read `sm.me().limits` when non-null. The environment time limit covers starting and running. Use a supported `timeLimitMinutes` when the task needs it.
|
|
68
|
+
|
|
69
|
+
## Recover without changing the test's meaning
|
|
70
|
+
|
|
71
|
+
Management failures throw SDK errors. App HTTP failures are returned as `Response` objects. Use `instanceof` with the SDK error classes. Native `credentials.fetch()` never retries. Read the State Machines error code in `error.code` and distinguish it from an app's own error.
|
|
72
|
+
|
|
73
|
+
| Failure | Next action |
|
|
74
|
+
| --- | --- |
|
|
75
|
+
| `invalid_request` | Read `err.fields` and the installed method signature. |
|
|
76
|
+
| `version_unavailable` | Discover the app ID and available versions. Stop if the required version is unavailable. |
|
|
77
|
+
| `environment_limit_reached` | Clean up only this task's known leftovers, or report the capacity blocker. |
|
|
78
|
+
| `EnvironmentFailedError` | Read `err.environment.failure` and clean up the owned environment. |
|
|
79
|
+
| `WaitTimeoutError` or abort | Use the retained environment ID. If older code waited inside `create`, a non-null `WaitTimeoutError.resource` carries its ID. If neither an ID nor a replay key is recoverable, report unresolved cleanup. Do not guess from a list. Wait again only if the task should continue. Otherwise delete the owned environment. |
|
|
80
|
+
| Unknown create outcome | Replay the retained input and idempotency key. Do not start another operation with a new key. |
|
|
81
|
+
| `invalid_status` | Read the current resource status before choosing the next call. |
|
|
82
|
+
| `snapshot_in_progress` | Find the saving snapshot for this environment and wait for it before creating another. |
|
|
83
|
+
| `SnapshotFailedError` | Report the failure. Retry only if the task still needs a snapshot and the source environment is running. |
|
|
84
|
+
| App `environment_not_running` | Inspect the environment. Do not silently switch the integration to another target. |
|
|
85
|
+
| App `invalid_setup` or `invalid_services` | The app refused a value of `setup` or `services` after the start. `error.message` starts with its path. Create another environment with a value that the app accepts, and delete the owned one. |
|
|
86
|
+
| App or gateway `503` | For a retryable read, honor `Retry-After`. For a write with an uncertain outcome, inspect stored state or report uncertainty before retrying. |
|
|
87
|
+
| Cleanup failure | Preserve the task result, report the owned resource ID and retry deletion with valid access and a fresh signal. Do not report cleanup as successful. |
|
|
88
|
+
|
|
89
|
+
## Finish with evidence
|
|
90
|
+
|
|
91
|
+
Leave the smallest rerunnable test or example. Report the behavior checked, command, assertion result, SDK and app versions, selected actor, resource IDs without secrets, and cleanup outcome. Say when execution was blocked or only typechecking ran. A passing replica check establishes the asserted behavior for that version and actor, not full production compatibility.
|
|
92
|
+
|
|
93
|
+
Find other guides through https://docs.usestatemachines.com/llms.txt. Read focused pages before the full documentation bundle. This dashboard also serves an agent index at https://app.usestatemachines.com/llms.txt.
|
package/agents/index.d.ts
CHANGED