statelyai 0.8.22 → 0.9.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 +28 -7
- package/dist/bin.mjs +1 -1
- package/dist/{cli-Dlvr6Nde.mjs → cli-uNjqtpTz.mjs} +24 -11
- package/dist/index.d.mts +1 -0
- package/dist/index.mjs +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -88,9 +88,14 @@ statelyai pull
|
|
|
88
88
|
```
|
|
89
89
|
|
|
90
90
|
`push` creates remote machines for unlinked source machines, updates already
|
|
91
|
-
linked machines, and writes returned IDs into source comments.
|
|
92
|
-
linked
|
|
93
|
-
|
|
91
|
+
linked machines, and writes returned IDs into source comments. Updating a
|
|
92
|
+
linked machine preserves Studio layout, colors, and annotations for unchanged
|
|
93
|
+
states while applying local structural changes. New states use default layout.
|
|
94
|
+
`pull` updates linked files. If `newMachinesDir` is configured, it also creates
|
|
95
|
+
local files for machines that exist only in the Studio project.
|
|
96
|
+
Push re-reads and retries when it observes a concurrent Studio edit. Registry
|
|
97
|
+
updates do not yet expose an atomic revision precondition, so avoid editing the
|
|
98
|
+
same machine in Studio during a push.
|
|
94
99
|
|
|
95
100
|
## Authentication
|
|
96
101
|
|
|
@@ -296,9 +301,10 @@ Locators may be:
|
|
|
296
301
|
- a Studio machine ID
|
|
297
302
|
- a Studio machine URL
|
|
298
303
|
|
|
299
|
-
`--fail-on-changes` exits with status `1` when
|
|
300
|
-
|
|
301
|
-
|
|
304
|
+
`--fail-on-changes` exits with status `1` when machine semantics differ.
|
|
305
|
+
Entity IDs and presentation-only layout or color fields do not count as
|
|
306
|
+
changes. Use `--base-url` for remote IDs at another Studio origin. `plan`
|
|
307
|
+
remains a hidden compatibility alias for `diff`.
|
|
302
308
|
|
|
303
309
|
### `push`
|
|
304
310
|
|
|
@@ -323,6 +329,13 @@ statelyai push --dry-run
|
|
|
323
329
|
`--dry-run` does not create or update machines, write `@statelyai` IDs, or
|
|
324
330
|
migrate legacy configuration.
|
|
325
331
|
|
|
332
|
+
For linked machines, `push` reads the current remote definition before updating
|
|
333
|
+
it. Local source remains authoritative for structure; Studio presentation for
|
|
334
|
+
unchanged states and transitions is preserved.
|
|
335
|
+
Push re-reads before writing and retries if it observes a remote change.
|
|
336
|
+
Registry updates do not yet expose an atomic revision precondition, so avoid
|
|
337
|
+
editing the same machine in Studio during a push.
|
|
338
|
+
|
|
326
339
|
Flags: `--config <path>`, `--base-url <url>`, `--dry-run`.
|
|
327
340
|
|
|
328
341
|
### `pull`
|
|
@@ -347,9 +360,17 @@ statelyai pull machine_123 src/checkout.machine.ts
|
|
|
347
360
|
|
|
348
361
|
New targets support JavaScript/TypeScript, `.digraph.json`, and `.graph.json`.
|
|
349
362
|
For existing JSON targets, the current file shape determines the output format.
|
|
363
|
+
Existing JavaScript and TypeScript targets are updated through surgical graph
|
|
364
|
+
patches so surrounding comments, imports, helpers, and implementation bodies
|
|
365
|
+
survive. New source files and JSON targets are generated as complete files.
|
|
350
366
|
|
|
351
367
|
Project-wide pull skips linked files with uncommitted Git changes. Pass
|
|
352
|
-
`--force` to overwrite them.
|
|
368
|
+
`--force` to overwrite them. If an existing source file cannot be updated
|
|
369
|
+
safely, pull leaves it unchanged and exits nonzero; `--force` explicitly allows
|
|
370
|
+
complete regeneration, which discards comments, imports, and helper code around
|
|
371
|
+
the machine. `--force` enables both behaviors together, so use it only when full
|
|
372
|
+
regeneration is acceptable. Every linked machine in a multi-machine source file
|
|
373
|
+
is pulled independently. Remote-only machines are skipped until
|
|
353
374
|
`newMachinesDir` is set.
|
|
354
375
|
|
|
355
376
|
Flags: `--config <path>`, `--base-url <url>`, `--force`.
|
package/dist/bin.mjs
CHANGED
|
@@ -14,10 +14,10 @@ import * as ts from "typescript";
|
|
|
14
14
|
import { EditorHostSession, StudioApiError, buildAuthorizeUrl, createPkcePair, createRemoteEditorSyncBackend, createStatelyClient, discoverAuthorizationServer, discoverProtectedResource, exchangeCodeForToken, findStatelyPragmaAttachments, getStatelyPragma, refreshToken, registerOAuthClient } from "@statelyai/sdk";
|
|
15
15
|
import { WebSocket, WebSocketServer } from "ws";
|
|
16
16
|
import os from "node:os";
|
|
17
|
-
import { planSync, pullSync, pushLocalMachineLinks } from "@statelyai/sdk/sync";
|
|
17
|
+
import { PullSourceReconciliationError, planSync, pullSync, pushLocalMachineLinks } from "@statelyai/sdk/sync";
|
|
18
18
|
|
|
19
19
|
//#region src/version.ts
|
|
20
|
-
const CLI_VERSION = "0.
|
|
20
|
+
const CLI_VERSION = "0.9.0";
|
|
21
21
|
|
|
22
22
|
//#endregion
|
|
23
23
|
//#region src/cliHost.ts
|
|
@@ -1601,11 +1601,12 @@ async function discoverLinkedPullTargets(files) {
|
|
|
1601
1601
|
const linkedTargets = [];
|
|
1602
1602
|
for (const file of files) {
|
|
1603
1603
|
if (!supportsMachineDiscovery(file)) continue;
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1604
|
+
findStatelyPragmaAttachments(await fsPromises.readFile(file.filePath, "utf8"), file.filePath).forEach((attachment, machineIndex) => {
|
|
1605
|
+
if (attachment.pragma?.id) linkedTargets.push({
|
|
1606
|
+
file,
|
|
1607
|
+
machineId: attachment.pragma.id,
|
|
1608
|
+
machineIndex
|
|
1609
|
+
});
|
|
1609
1610
|
});
|
|
1610
1611
|
}
|
|
1611
1612
|
return linkedTargets;
|
|
@@ -2125,9 +2126,14 @@ var PullCommand = class PullCommand extends ParsedSyncCommand {
|
|
|
2125
2126
|
this.log(colorize(`Processing ${linkedTargets.length} ${pluralize(linkedTargets.length, "linked file")}${remoteOnlyTargets.length > 0 ? ` and ${remoteOnlyTargets.length} ${pluralize(remoteOnlyTargets.length, "new remote machine")}` : ""}...`, ANSI_CYAN));
|
|
2126
2127
|
const pulled = [];
|
|
2127
2128
|
const created = [];
|
|
2129
|
+
let hadSourceReconciliationFailure = false;
|
|
2130
|
+
const dirtyLinkedFiles = /* @__PURE__ */ new Map();
|
|
2131
|
+
if (!flags.force) await Promise.all([...new Set(linkedTargets.map((target) => target.file.filePath))].map(async (filePath) => {
|
|
2132
|
+
dirtyLinkedFiles.set(filePath, await isFileGitDirty(filePath));
|
|
2133
|
+
}));
|
|
2128
2134
|
for (const linkedTarget of linkedTargets) {
|
|
2129
2135
|
const targetPath = linkedTarget.file.filePath;
|
|
2130
|
-
if (!flags.force &&
|
|
2136
|
+
if (!flags.force && dirtyLinkedFiles.get(targetPath)) {
|
|
2131
2137
|
skipped.push(`${linkedTarget.file.relativePath}: local git changes detected (pass --force to overwrite)`);
|
|
2132
2138
|
continue;
|
|
2133
2139
|
}
|
|
@@ -2137,10 +2143,13 @@ var PullCommand = class PullCommand extends ParsedSyncCommand {
|
|
|
2137
2143
|
source: linkedTarget.machineId,
|
|
2138
2144
|
target: targetPath,
|
|
2139
2145
|
apiKey,
|
|
2140
|
-
baseUrl: resolveApiBaseUrl(flags["base-url"] ?? config.studioUrl)
|
|
2146
|
+
baseUrl: resolveApiBaseUrl(flags["base-url"] ?? config.studioUrl),
|
|
2147
|
+
force: flags.force,
|
|
2148
|
+
machineIndex: linkedTarget.machineIndex
|
|
2141
2149
|
});
|
|
2142
2150
|
pulled.push(`${linkedTarget.file.relativePath}: ${formatSecondaryText(result.source.locator)}`);
|
|
2143
2151
|
} catch (error) {
|
|
2152
|
+
if (error instanceof PullSourceReconciliationError) hadSourceReconciliationFailure = true;
|
|
2144
2153
|
skipped.push(`${linkedTarget.file.relativePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
2145
2154
|
}
|
|
2146
2155
|
}
|
|
@@ -2152,16 +2161,19 @@ var PullCommand = class PullCommand extends ParsedSyncCommand {
|
|
|
2152
2161
|
source: remoteTarget.machineId,
|
|
2153
2162
|
target: remoteTarget.filePath,
|
|
2154
2163
|
apiKey,
|
|
2155
|
-
baseUrl: resolveApiBaseUrl(flags["base-url"] ?? config.studioUrl)
|
|
2164
|
+
baseUrl: resolveApiBaseUrl(flags["base-url"] ?? config.studioUrl),
|
|
2165
|
+
force: flags.force
|
|
2156
2166
|
});
|
|
2157
2167
|
created.push(`${remoteTarget.relativePath}: ${formatSecondaryText(result.source.locator)}`);
|
|
2158
2168
|
} catch (error) {
|
|
2169
|
+
if (error instanceof PullSourceReconciliationError) hadSourceReconciliationFailure = true;
|
|
2159
2170
|
skipped.push(`${remoteTarget.relativePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
2160
2171
|
}
|
|
2161
2172
|
}
|
|
2162
2173
|
if (pulled.length > 0) this.log(`${formatSectionLabel("Pulled:", "success")}\n${pulled.join("\n")}`);
|
|
2163
2174
|
if (created.length > 0) this.log(`${formatSectionLabel("Created:", "success")}\n${created.join("\n")}`);
|
|
2164
2175
|
if (skipped.length > 0) this.log(`${formatSectionLabel("Skipped:", "warning")}\n${skipped.join("\n")}`);
|
|
2176
|
+
if (hadSourceReconciliationFailure) this.exit(1);
|
|
2165
2177
|
return;
|
|
2166
2178
|
}
|
|
2167
2179
|
const localCandidate = path.resolve(process.cwd(), args.source);
|
|
@@ -2180,7 +2192,8 @@ var PullCommand = class PullCommand extends ParsedSyncCommand {
|
|
|
2180
2192
|
source,
|
|
2181
2193
|
target,
|
|
2182
2194
|
apiKey,
|
|
2183
|
-
baseUrl: resolveApiBaseUrl(flags["base-url"] ?? getDefaultBaseUrl())
|
|
2195
|
+
baseUrl: resolveApiBaseUrl(flags["base-url"] ?? getDefaultBaseUrl()),
|
|
2196
|
+
force: flags.force
|
|
2184
2197
|
});
|
|
2185
2198
|
this.log(`${formatSectionLabel("Pulled:", "success")} ${formatSecondaryText(result.source.locator)} -> ${result.outputPath}\nTarget: ${result.target.kind} (${result.target.format})`);
|
|
2186
2199
|
}
|
package/dist/index.d.mts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as scanProjectMachines, S as run, T as createStatelyProjectConfig, _ as isFileGitDirty, a as discoverMachinesInSource, b as resolveCredentialStatus, c as formatDiscoveredMachines, d as formatProjectStatus, f as formatStoredCredentialSource, g as initProject, h as inferInitProjectName, i as discoverLinkedPullTargets, l as formatMissingNewMachineDirMessage, m as getEnvCredential, n as buildOAuthLoginStart, o as discoverOAuthLogin, p as getEnvApiKey, r as classifyPushCandidates, s as discoverRemoteProjectMachineTargets, t as COMMANDS, u as formatPlanSummary, v as resolveApiKey, w as scanProjectSources, x as resolveProjectStatus, y as resolveConfiguredPullTargets } from "./cli-
|
|
1
|
+
import { C as scanProjectMachines, S as run, T as createStatelyProjectConfig, _ as isFileGitDirty, a as discoverMachinesInSource, b as resolveCredentialStatus, c as formatDiscoveredMachines, d as formatProjectStatus, f as formatStoredCredentialSource, g as initProject, h as inferInitProjectName, i as discoverLinkedPullTargets, l as formatMissingNewMachineDirMessage, m as getEnvCredential, n as buildOAuthLoginStart, o as discoverOAuthLogin, p as getEnvApiKey, r as classifyPushCandidates, s as discoverRemoteProjectMachineTargets, t as COMMANDS, u as formatPlanSummary, v as resolveApiKey, w as scanProjectSources, x as resolveProjectStatus, y as resolveConfiguredPullTargets } from "./cli-uNjqtpTz.mjs";
|
|
2
2
|
|
|
3
3
|
export { COMMANDS, buildOAuthLoginStart, classifyPushCandidates, createStatelyProjectConfig, discoverLinkedPullTargets, discoverMachinesInSource, discoverOAuthLogin, discoverRemoteProjectMachineTargets, formatDiscoveredMachines, formatMissingNewMachineDirMessage, formatPlanSummary, formatProjectStatus, formatStoredCredentialSource, getEnvApiKey, getEnvCredential, inferInitProjectName, initProject, isFileGitDirty, resolveApiKey, resolveConfiguredPullTargets, resolveCredentialStatus, resolveProjectStatus, run, scanProjectMachines, scanProjectSources };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "statelyai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Command-line tools for Stately",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"@oclif/core": "^4.10.3",
|
|
24
24
|
"typescript": "^5.9.3",
|
|
25
25
|
"ws": "^8.21.0",
|
|
26
|
-
"@statelyai/sdk": "0.
|
|
26
|
+
"@statelyai/sdk": "0.27.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/ws": "^8.18.1",
|