statelyai 0.13.0 → 0.14.1
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 +83 -5
- package/dist/bin.mjs +1 -1
- package/dist/{cli-b1m4txJ7.mjs → cli-a0Z1igmj.mjs} +413 -139
- package/dist/index.d.mts +59 -2
- package/dist/index.mjs +2 -2
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -32,6 +32,8 @@ npm install --global statelyai
|
|
|
32
32
|
| Set up local discovery | `statelyai init --local --scan` | Local `statelyai.json` |
|
|
33
33
|
| Set up project sync | `statelyai init --scan` | Remote project and local `statelyai.json` |
|
|
34
34
|
| Inspect project machines | `statelyai status` | Nothing |
|
|
35
|
+
| Connect to a Studio project | `statelyai link --project <id>` | Project association in `statelyai.json` |
|
|
36
|
+
| Associate an existing machine | `statelyai link <file> --machine <id>` | Selected source machine ID comment |
|
|
35
37
|
| Preview project uploads | `statelyai push --dry-run` | Nothing |
|
|
36
38
|
| Upload local machines | `statelyai push [file]` | Remote machines and local `@statelyai` IDs |
|
|
37
39
|
| Download project machines | `statelyai pull` | Linked local files and new files under `newMachinesDir` |
|
|
@@ -40,7 +42,7 @@ npm install --global statelyai
|
|
|
40
42
|
|
|
41
43
|
## Quick start
|
|
42
44
|
|
|
43
|
-
<!-- project initialization and sync flow from InitCommand, PushCommand, PullCommand, and projectConfig.ts -->
|
|
45
|
+
<!-- project initialization and sync flow from InitCommand, LinkCommand, PushCommand, PullCommand, and projectConfig.ts -->
|
|
44
46
|
|
|
45
47
|
For hosted Stately, authenticate once:
|
|
46
48
|
|
|
@@ -48,10 +50,11 @@ For hosted Stately, authenticate once:
|
|
|
48
50
|
statelyai login
|
|
49
51
|
```
|
|
50
52
|
|
|
51
|
-
Initialize
|
|
53
|
+
Initialize local discovery, then choose the Studio project:
|
|
52
54
|
|
|
53
55
|
```bash
|
|
54
|
-
statelyai init --scan
|
|
56
|
+
statelyai init --local --scan
|
|
57
|
+
statelyai link --project <project-id-or-url>
|
|
55
58
|
```
|
|
56
59
|
|
|
57
60
|
`--scan` suggests `include` globs and asks before saving them. Without
|
|
@@ -66,8 +69,8 @@ statelyai init --local --scan
|
|
|
66
69
|
statelyai status
|
|
67
70
|
```
|
|
68
71
|
|
|
69
|
-
Run `statelyai
|
|
70
|
-
|
|
72
|
+
Run `statelyai link` later to choose a Studio project without losing discovery
|
|
73
|
+
globs. Plain `init` still supports the existing connected setup for compatibility.
|
|
71
74
|
|
|
72
75
|
To list machines without creating any config:
|
|
73
76
|
|
|
@@ -114,6 +117,67 @@ migrated to the shared machine key on the next save.
|
|
|
114
117
|
New states keep their generated coordinates when clear, or move beside
|
|
115
118
|
existing states when they would overlap restored layout.
|
|
116
119
|
|
|
120
|
+
## Local setup and Studio linking
|
|
121
|
+
|
|
122
|
+
<!-- association workflow from src/link.ts and LinkCommand in src/cli.ts -->
|
|
123
|
+
|
|
124
|
+
Local configuration, Studio association, and data sync are separate steps:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
statelyai init --local --scan
|
|
128
|
+
statelyai login
|
|
129
|
+
statelyai link --project <project-id-or-url>
|
|
130
|
+
statelyai push --dry-run
|
|
131
|
+
statelyai push
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`link` without flags offers a project picker in an interactive terminal. In
|
|
135
|
+
scripts, pass `--project` or explicitly create a project:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
statelyai link --create --name "Checkout" --visibility Private
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Link an existing remote machine to local source without uploading or downloading
|
|
142
|
+
its definition:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
statelyai link ./test.ts --machine <machine-id-or-url>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The remote machine must belong to the connected project. For a file containing
|
|
149
|
+
multiple machines, select one with `--machine-index 0` (zero-based). This changes
|
|
150
|
+
only the selected machine's `@statelyai id` comment. It does not compare or
|
|
151
|
+
reconcile the two definitions. Review `push --dry-run` and choose `push` or `pull`
|
|
152
|
+
when ready to sync; `linked` describes association, not equality.
|
|
153
|
+
|
|
154
|
+
Use `--force` to replace an existing project or machine association. Changing the
|
|
155
|
+
project retains existing source machine IDs. `link` preserves discovery globs and
|
|
156
|
+
local writeback settings; it does not scan or include new files automatically.
|
|
157
|
+
Plain `init` retains its existing Studio-connected behavior for compatibility.
|
|
158
|
+
The executable remains `statelyai`.
|
|
159
|
+
|
|
160
|
+
```mermaid
|
|
161
|
+
stateDiagram-v2
|
|
162
|
+
[*] --> Unconfigured
|
|
163
|
+
Unconfigured --> Local: init --local
|
|
164
|
+
Unconfigured --> Connected: init (compatibility)
|
|
165
|
+
Unconfigured --> Connected: link
|
|
166
|
+
Local --> Connected: link
|
|
167
|
+
state Connected {
|
|
168
|
+
[*] --> LocalOnly
|
|
169
|
+
LocalOnly --> Linked: link file --machine (association only)
|
|
170
|
+
LocalOnly --> Linked: push (create remote + upload + ID)
|
|
171
|
+
Linked --> Linked: push (upload)
|
|
172
|
+
Linked --> Linked: pull (download)
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Authentication is independent of this state machine. `open`, `scan`, and
|
|
177
|
+
`push --dry-run` do not establish machine links. `--scan` proposes source globs;
|
|
178
|
+
a new config without it has an empty `include` list. Project-wide `pull` creates
|
|
179
|
+
remote-only files only when `newMachinesDir` is configured.
|
|
180
|
+
|
|
117
181
|
## Authentication
|
|
118
182
|
|
|
119
183
|
<!-- authentication flags, environment resolution, and credential storage from src/cli.ts and src/credentials.ts -->
|
|
@@ -252,6 +316,20 @@ Use `--json` for automation or `--auth` to show only credential resolution.
|
|
|
252
316
|
|
|
253
317
|
Flags: `--config <path>`, `--base-url <url>`, `--json`, `--auth`.
|
|
254
318
|
|
|
319
|
+
### `link`
|
|
320
|
+
|
|
321
|
+
Connect to Studio without moving machine definitions:
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
statelyai link --project <project-id-or-url>
|
|
325
|
+
statelyai link --create --name "Checkout"
|
|
326
|
+
statelyai link ./test.ts --machine <machine-id-or-url>
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Flags: `--project <id|url>` or `--create`, `--name`, `--visibility`,
|
|
330
|
+
`--machine <id|url>`, `--machine-index <zero-based-index>`, `--config`,
|
|
331
|
+
`--base-url`, `--force`. See [Local setup and Studio linking](#local-setup-and-studio-linking).
|
|
332
|
+
|
|
255
333
|
### `init`
|
|
256
334
|
|
|
257
335
|
Create a local config or reuse a Studio project and write `statelyai.json`.
|
package/dist/bin.mjs
CHANGED
|
@@ -7,22 +7,23 @@ import { z, z as z$1 } from "zod";
|
|
|
7
7
|
import { execFile, execFileSync, spawn } from "node:child_process";
|
|
8
8
|
import { promisify } from "node:util";
|
|
9
9
|
import * as crypto from "node:crypto";
|
|
10
|
+
import { randomUUID } from "node:crypto";
|
|
11
|
+
import { StudioApiError, buildAuthorizeUrl, createPkcePair, createStatelyClient, discoverAuthorizationServer, discoverProtectedResource, exchangeCodeForToken, refreshToken, registerOAuthClient } from "@statelyai/sdk";
|
|
12
|
+
import * as ts$1 from "typescript";
|
|
13
|
+
import ts from "typescript";
|
|
10
14
|
import fs, { promises, statSync, watch } from "node:fs";
|
|
11
15
|
import { createInterface } from "node:readline/promises";
|
|
12
16
|
import { Writable } from "node:stream";
|
|
13
17
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
14
18
|
import * as http from "node:http";
|
|
15
|
-
import * as ts$1 from "typescript";
|
|
16
|
-
import ts from "typescript";
|
|
17
19
|
import * as fs$1 from "fs";
|
|
18
20
|
import * as path$2 from "path";
|
|
19
21
|
import { fileURLToPath as fileURLToPath$1, pathToFileURL as pathToFileURL$1 } from "url";
|
|
20
22
|
import { fromStudioMachine, toStudioMachine } from "@statelyai/sdk/graph";
|
|
21
23
|
import { EDITOR_PROTOCOL_VERSION } from "@statelyai/sdk/editor-host-protocol";
|
|
22
|
-
import { createStatelyClient, createStatelyClient as createStatelyClient$1$1 } from "@statelyai/sdk/studio";
|
|
24
|
+
import { createStatelyClient as createStatelyClient$1, createStatelyClient as createStatelyClient$1$1 } from "@statelyai/sdk/studio";
|
|
23
25
|
import { WebSocket, WebSocketServer } from "ws";
|
|
24
26
|
import os from "node:os";
|
|
25
|
-
import { StudioApiError, buildAuthorizeUrl, createPkcePair, createStatelyClient as createStatelyClient$1, discoverAuthorizationServer, discoverProtectedResource, exchangeCodeForToken, refreshToken, registerOAuthClient } from "@statelyai/sdk";
|
|
26
27
|
|
|
27
28
|
//#region \0rolldown/runtime.js
|
|
28
29
|
var __commonJSMin$1 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
@@ -897,6 +898,236 @@ var VerifyCommand = class VerifyCommand extends Command {
|
|
|
897
898
|
}
|
|
898
899
|
};
|
|
899
900
|
|
|
901
|
+
//#endregion
|
|
902
|
+
//#region ../editor-sync/dist/statelyPragma-D46lczJR.mjs
|
|
903
|
+
function findStatelyPragmaAttachments(sourceText, fileName = "machine.ts") {
|
|
904
|
+
const sourceFile = ts.createSourceFile(fileName, sourceText, ts.ScriptTarget.Latest, true, getScriptKind$4(fileName));
|
|
905
|
+
const attachments = [];
|
|
906
|
+
const visit = (node) => {
|
|
907
|
+
if (ts.isCallExpression(node) && isCreateMachineExpression$3(node.expression)) {
|
|
908
|
+
const attachNode = findAttachNode(node);
|
|
909
|
+
if (attachNode) attachments.push({
|
|
910
|
+
machineStart: getMachineExpressionStart(node.expression, sourceFile),
|
|
911
|
+
attachStart: attachNode.getStart(sourceFile),
|
|
912
|
+
pragma: findAttachedStatelyPragma(sourceText, attachNode)
|
|
913
|
+
});
|
|
914
|
+
}
|
|
915
|
+
ts.forEachChild(node, visit);
|
|
916
|
+
};
|
|
917
|
+
visit(sourceFile);
|
|
918
|
+
return attachments;
|
|
919
|
+
}
|
|
920
|
+
function getStatelyPragma(sourceText, fileName = "machine.ts", machineIndex = 0) {
|
|
921
|
+
return findStatelyPragmaAttachments(sourceText, fileName)[machineIndex]?.pragma;
|
|
922
|
+
}
|
|
923
|
+
function upsertStatelyPragma(sourceText, id, options = {}) {
|
|
924
|
+
const attachment = findStatelyPragmaAttachments(sourceText, options.fileName ?? "machine.ts")[options.machineIndex ?? 0];
|
|
925
|
+
if (!attachment) return sourceText;
|
|
926
|
+
const lineEnding = options.lineEnding ?? detectLineEnding(sourceText);
|
|
927
|
+
const canonicalComment = `// @statelyai id=${id}`;
|
|
928
|
+
if (attachment.pragma) return sourceText.slice(0, attachment.pragma.start) + canonicalComment + sourceText.slice(attachment.pragma.end);
|
|
929
|
+
const insertText = `${getIndentationAtOffset(sourceText, attachment.attachStart)}${canonicalComment}${lineEnding}`;
|
|
930
|
+
return sourceText.slice(0, attachment.attachStart) + insertText + sourceText.slice(attachment.attachStart);
|
|
931
|
+
}
|
|
932
|
+
function findAttachedStatelyPragma(sourceText, node) {
|
|
933
|
+
const comments = ts.getLeadingCommentRanges(sourceText, node.getFullStart()) ?? [];
|
|
934
|
+
for (let index = comments.length - 1; index >= 0; index -= 1) {
|
|
935
|
+
const comment = comments[index];
|
|
936
|
+
const parsed = parseStatelyPragma(sourceText, comment.pos, comment.end);
|
|
937
|
+
if (parsed) return parsed;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
function parseStatelyPragma(sourceText, start, end) {
|
|
941
|
+
const match = normalizeCommentContent(sourceText.slice(start, end)).match(/^@statelyai(?:\s+(.*))?$/s);
|
|
942
|
+
if (!match) return;
|
|
943
|
+
const fields = parseFields(match[1] ?? "");
|
|
944
|
+
return {
|
|
945
|
+
tag: "@statelyai",
|
|
946
|
+
id: fields.id,
|
|
947
|
+
fields,
|
|
948
|
+
start,
|
|
949
|
+
end
|
|
950
|
+
};
|
|
951
|
+
}
|
|
952
|
+
function normalizeCommentContent(rawComment) {
|
|
953
|
+
if (rawComment.startsWith("//")) return rawComment.slice(2).trim();
|
|
954
|
+
if (rawComment.startsWith("/*")) return rawComment.slice(2, rawComment.endsWith("*/") ? -2 : void 0).split(/\r?\n/).map((line) => line.replace(/^\s*\*\s?/, "")).join(" ").trim();
|
|
955
|
+
return rawComment.trim();
|
|
956
|
+
}
|
|
957
|
+
function parseFields(input) {
|
|
958
|
+
const fields = {};
|
|
959
|
+
for (const token of input.split(/\s+/)) {
|
|
960
|
+
if (!token) continue;
|
|
961
|
+
const equalsIndex = token.indexOf("=");
|
|
962
|
+
if (equalsIndex <= 0) continue;
|
|
963
|
+
const key = token.slice(0, equalsIndex);
|
|
964
|
+
const value = token.slice(equalsIndex + 1);
|
|
965
|
+
if (!key || !value) continue;
|
|
966
|
+
fields[key] = value;
|
|
967
|
+
}
|
|
968
|
+
return fields;
|
|
969
|
+
}
|
|
970
|
+
function findAttachNode(node) {
|
|
971
|
+
let current = node;
|
|
972
|
+
while (current?.parent) {
|
|
973
|
+
if (ts.isVariableStatement(current.parent) || ts.isExpressionStatement(current.parent) || ts.isExportAssignment(current.parent)) return current.parent;
|
|
974
|
+
current = current.parent;
|
|
975
|
+
}
|
|
976
|
+
return current;
|
|
977
|
+
}
|
|
978
|
+
function isCreateMachineExpression$3(expression) {
|
|
979
|
+
const isMachineFactoryName = (name) => name === "createMachine" || name === "createMachineFromConfig";
|
|
980
|
+
return ts.isIdentifier(expression) && isMachineFactoryName(expression.text) || ts.isPropertyAccessExpression(expression) && isMachineFactoryName(expression.name.text);
|
|
981
|
+
}
|
|
982
|
+
function getMachineExpressionStart(expression, sourceFile) {
|
|
983
|
+
if (ts.isPropertyAccessExpression(expression)) return expression.name.getStart(sourceFile);
|
|
984
|
+
return expression.getStart(sourceFile);
|
|
985
|
+
}
|
|
986
|
+
function getIndentationAtOffset(sourceText, offset) {
|
|
987
|
+
const lineStart = sourceText.lastIndexOf("\n", Math.max(0, offset - 1)) + 1;
|
|
988
|
+
return sourceText.slice(lineStart, offset).match(/^[ \t]*/)?.[0] ?? "";
|
|
989
|
+
}
|
|
990
|
+
function detectLineEnding(sourceText) {
|
|
991
|
+
return sourceText.includes("\r\n") ? "\r\n" : "\n";
|
|
992
|
+
}
|
|
993
|
+
function getScriptKind$4(fileName) {
|
|
994
|
+
if (fileName.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
995
|
+
if (fileName.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
996
|
+
if (fileName.endsWith(".js")) return ts.ScriptKind.JS;
|
|
997
|
+
return ts.ScriptKind.TS;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
//#endregion
|
|
1001
|
+
//#region src/link.ts
|
|
1002
|
+
function resourceId(locator, kind) {
|
|
1003
|
+
let id = locator.trim();
|
|
1004
|
+
if (/^https?:\/\//.test(id)) {
|
|
1005
|
+
const url = new URL(id);
|
|
1006
|
+
id = kind === "machine" ? url.searchParams.get("machineId") ?? url.pathname.match(/\/machines?\/([^/]+)/)?.[1] ?? "" : url.pathname.match(/\/(?:projects?|editor)\/([^/]+)/)?.[1] ?? "";
|
|
1007
|
+
id = decodeURIComponent(id);
|
|
1008
|
+
}
|
|
1009
|
+
if (!/^[\w-]+$/.test(id)) throw new Error(`Pass a ${kind} ID or a URL containing a ${kind} ID.`);
|
|
1010
|
+
return id;
|
|
1011
|
+
}
|
|
1012
|
+
/** Association only: no definitions are uploaded, downloaded, or executed. */
|
|
1013
|
+
async function linkProject(options) {
|
|
1014
|
+
if (options.projectId && options.create) throw new Error("Choose --project or --create, not both.");
|
|
1015
|
+
if (Boolean(options.file) !== Boolean(options.machineId)) throw new Error("Machine association requires a file and --machine <id|url>.");
|
|
1016
|
+
if (options.create && options.machineId) throw new Error("Link an existing machine to its existing project with --project; --create creates an empty project.");
|
|
1017
|
+
if (options.visibility && !options.create) throw new Error("--visibility requires --create.");
|
|
1018
|
+
if (options.name && !options.create) throw new Error("--name requires --create.");
|
|
1019
|
+
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
1020
|
+
const configPath = path.resolve(cwd, options.configPath ?? STATELY_CONFIG_FILE);
|
|
1021
|
+
const existing = await readStatelyProjectConfig({
|
|
1022
|
+
cwd,
|
|
1023
|
+
configPath,
|
|
1024
|
+
rewriteIfNeeded: false
|
|
1025
|
+
}).catch((error) => {
|
|
1026
|
+
if (error.code === "ENOENT") return void 0;
|
|
1027
|
+
throw error;
|
|
1028
|
+
});
|
|
1029
|
+
if (existing?.rewriteStatus.reason === "multiple-legacy-sources") throw new Error("Update the legacy sources configuration manually before linking; no files were changed.");
|
|
1030
|
+
const studioUrl = options.baseUrl ?? existing?.config.studioUrl ?? "https://stately.ai";
|
|
1031
|
+
const requestedId = options.projectId ? resourceId(options.projectId, "project") : void 0;
|
|
1032
|
+
const sameDeployment = !existing?.config.studioUrl || resolveApiBaseUrl(studioUrl) === resolveApiBaseUrl(existing.config.studioUrl);
|
|
1033
|
+
if (existing?.config.projectId && (!sameDeployment || options.create || requestedId && requestedId !== existing.config.projectId) && !options.force) throw new Error(`Already linked to project ${existing.config.projectId}. Use --force to change the project association; existing machine IDs are retained.`);
|
|
1034
|
+
const machineId = options.machineId ? resourceId(options.machineId, "machine") : void 0;
|
|
1035
|
+
const filePath = options.file ? path.resolve(cwd, options.file) : void 0;
|
|
1036
|
+
const source = filePath ? await fsPromises.readFile(filePath, "utf8") : void 0;
|
|
1037
|
+
const machineIndex = options.machineIndex ?? 0;
|
|
1038
|
+
if (filePath && source !== void 0) {
|
|
1039
|
+
if (!/\.[cm]?[jt]sx?$/.test(filePath)) throw new Error("Machine association supports JavaScript and TypeScript source files.");
|
|
1040
|
+
const attachments = findStatelyPragmaAttachments(source, filePath);
|
|
1041
|
+
if (attachments.length > 1 && options.machineIndex === void 0) throw new Error("This file contains multiple machines. Select one with --machine-index (zero-based).");
|
|
1042
|
+
const attachment = attachments[machineIndex];
|
|
1043
|
+
if (!attachment || !Number.isInteger(machineIndex) || machineIndex < 0) throw new Error("No machine at the selected index.");
|
|
1044
|
+
if (attachment.pragma?.id && attachment.pragma.id !== machineId && !options.force) throw new Error(`Machine already linked to ${attachment.pragma.id}. Use --force to replace its association.`);
|
|
1045
|
+
} else if (options.machineIndex !== void 0) throw new Error("--machine-index requires a file and --machine.");
|
|
1046
|
+
const client = options.client ?? createStatelyClient({
|
|
1047
|
+
apiKey: options.apiKey,
|
|
1048
|
+
baseUrl: resolveApiBaseUrl(studioUrl)
|
|
1049
|
+
});
|
|
1050
|
+
let project;
|
|
1051
|
+
if (options.create) project = await client.projects.create({
|
|
1052
|
+
name: options.name ?? path.basename(cwd),
|
|
1053
|
+
visibility: options.visibility ?? "Private"
|
|
1054
|
+
});
|
|
1055
|
+
else {
|
|
1056
|
+
const projectId = requestedId ?? existing?.config.projectId;
|
|
1057
|
+
if (!projectId) throw new Error("Choose --project <id|url> or --create to connect this workspace.");
|
|
1058
|
+
project = await client.projects.get(projectId);
|
|
1059
|
+
}
|
|
1060
|
+
if (machineId) {
|
|
1061
|
+
if (!project.machines.some((machine) => machine.machineId === machineId)) throw new Error(`Machine ${machineId} is not in project ${project.projectId}. No files were changed.`);
|
|
1062
|
+
await client.machines.get(machineId);
|
|
1063
|
+
}
|
|
1064
|
+
if (filePath && await fsPromises.readFile(filePath, "utf8") !== source) throw new Error("Source changed while linking. Retry; no files were changed.");
|
|
1065
|
+
const config = {
|
|
1066
|
+
...existing?.config ?? createStatelyProjectConfig({}),
|
|
1067
|
+
projectId: project.projectId,
|
|
1068
|
+
studioUrl
|
|
1069
|
+
};
|
|
1070
|
+
const writes = [];
|
|
1071
|
+
const stage = async (destination, write) => {
|
|
1072
|
+
const suffix = randomUUID();
|
|
1073
|
+
const entry = {
|
|
1074
|
+
path: destination,
|
|
1075
|
+
staged: `${destination}.${suffix}.tmp`,
|
|
1076
|
+
backup: `${destination}.${suffix}.bak`,
|
|
1077
|
+
existed: false,
|
|
1078
|
+
committed: false
|
|
1079
|
+
};
|
|
1080
|
+
writes.push(entry);
|
|
1081
|
+
try {
|
|
1082
|
+
await fsPromises.copyFile(destination, entry.backup);
|
|
1083
|
+
entry.existed = true;
|
|
1084
|
+
} catch (error) {
|
|
1085
|
+
if (error.code !== "ENOENT") throw error;
|
|
1086
|
+
}
|
|
1087
|
+
await write(entry.staged);
|
|
1088
|
+
if (entry.existed) await fsPromises.chmod(entry.staged, (await fsPromises.stat(destination)).mode);
|
|
1089
|
+
};
|
|
1090
|
+
let rollbackFailed = false;
|
|
1091
|
+
try {
|
|
1092
|
+
await stage(configPath, (temporary) => writeStatelyProjectConfig(temporary, config));
|
|
1093
|
+
if (filePath && source !== void 0 && machineId) {
|
|
1094
|
+
const updated = upsertStatelyPragma(source, machineId, {
|
|
1095
|
+
fileName: filePath,
|
|
1096
|
+
machineIndex
|
|
1097
|
+
});
|
|
1098
|
+
if (updated !== source) await stage(filePath, (temporary) => fsPromises.writeFile(temporary, updated, "utf8"));
|
|
1099
|
+
}
|
|
1100
|
+
if (filePath && await fsPromises.readFile(filePath, "utf8") !== source) throw new Error("Source changed while linking. Retry; no files were changed.");
|
|
1101
|
+
for (const entry of writes) {
|
|
1102
|
+
await fsPromises.rename(entry.staged, entry.path);
|
|
1103
|
+
entry.committed = true;
|
|
1104
|
+
}
|
|
1105
|
+
} catch (error) {
|
|
1106
|
+
const rollbackErrors = [];
|
|
1107
|
+
for (const entry of [...writes].reverse()) {
|
|
1108
|
+
if (!entry.committed) continue;
|
|
1109
|
+
try {
|
|
1110
|
+
if (entry.existed) await fsPromises.rename(entry.backup, entry.path);
|
|
1111
|
+
else await fsPromises.unlink(entry.path);
|
|
1112
|
+
} catch (rollbackError) {
|
|
1113
|
+
rollbackFailed = true;
|
|
1114
|
+
rollbackErrors.push(rollbackError);
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
if (rollbackFailed) throw new AggregateError([error, ...rollbackErrors], "Link failed and could not restore every file. Original files are retained in .bak files beside their destinations.");
|
|
1118
|
+
throw error;
|
|
1119
|
+
} finally {
|
|
1120
|
+
await Promise.all(writes.flatMap((entry) => rollbackFailed ? [entry.staged] : [entry.staged, entry.backup]).map((temporary) => fsPromises.rm(temporary, { force: true })));
|
|
1121
|
+
}
|
|
1122
|
+
return {
|
|
1123
|
+
project,
|
|
1124
|
+
config,
|
|
1125
|
+
configPath,
|
|
1126
|
+
machineId,
|
|
1127
|
+
filePath
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1130
|
+
|
|
900
1131
|
//#endregion
|
|
901
1132
|
//#region ../editor-sync/dist/fs-Dw5c-Wnp.mjs
|
|
902
1133
|
function comparePosition(left, right) {
|
|
@@ -7418,7 +7649,7 @@ function buildMeta(meta, color, showStatelyMeta = true) {
|
|
|
7418
7649
|
if (meta) {
|
|
7419
7650
|
for (const [k, v] of Object.entries(meta)) if (v !== void 0 && v !== null && (showStatelyMeta || k === FN_PROJECTION_META || !k.startsWith("@statelyai"))) result[k] = v;
|
|
7420
7651
|
}
|
|
7421
|
-
if (color && showStatelyMeta) result["@statelyai.color"] = color;
|
|
7652
|
+
if (color !== void 0 && showStatelyMeta) result["@statelyai.color"] = color;
|
|
7422
7653
|
return Object.keys(result).length > 0 ? result : void 0;
|
|
7423
7654
|
}
|
|
7424
7655
|
/** Format event param — supports { type: string } (new) and plain string (legacy) */
|
|
@@ -10355,7 +10586,7 @@ function graphToXStateTSResult(inputGraph, options = {}) {
|
|
|
10355
10586
|
if (xstateVersion === 6) stripStateSchemas(machineConfig);
|
|
10356
10587
|
let machineExpr;
|
|
10357
10588
|
if (hasSetup) {
|
|
10358
|
-
const setupObj = buildSetupObject(schemas, impls, {
|
|
10589
|
+
const setupObj = buildSetupObject(graph, schemas, impls, {
|
|
10359
10590
|
includeTypeSyntax: supportsTypeSyntax,
|
|
10360
10591
|
xstateVersion,
|
|
10361
10592
|
xstateV6SchemaFormat
|
|
@@ -11155,7 +11386,7 @@ function getActorSourceImports(graph) {
|
|
|
11155
11386
|
}
|
|
11156
11387
|
return imports;
|
|
11157
11388
|
}
|
|
11158
|
-
function buildSetupObject(schemas, impls, options) {
|
|
11389
|
+
function buildSetupObject(graph, schemas, impls, options) {
|
|
11159
11390
|
const setup = {};
|
|
11160
11391
|
if (options.xstateVersion === 6) {
|
|
11161
11392
|
const schemasBlock = buildV6SchemasBlock(schemas, options);
|
|
@@ -11165,7 +11396,10 @@ function buildSetupObject(schemas, impls, options) {
|
|
|
11165
11396
|
if (types) setup.types = types;
|
|
11166
11397
|
}
|
|
11167
11398
|
if (impls?.actions.length) setup.actions = buildActionsBlock(impls.actions, options);
|
|
11168
|
-
if (impls?.guards.length) setup.guards = buildGuardsBlock(impls.guards,
|
|
11399
|
+
if (impls?.guards.length) setup.guards = buildGuardsBlock(impls.guards, {
|
|
11400
|
+
...options,
|
|
11401
|
+
argsTypes: options.xstateVersion === 6 && options.includeTypeSyntax ? new Map(impls.guards.map((guard) => [guard.name, getV6GuardArgsType(graph, guard.name)])) : void 0
|
|
11402
|
+
});
|
|
11169
11403
|
if (impls?.actors.length) setup.actors = buildActorsBlock(impls.actors, {
|
|
11170
11404
|
...options,
|
|
11171
11405
|
xstateVersion: options.xstateVersion
|
|
@@ -11266,18 +11500,68 @@ function buildActionsBlock(actions, options) {
|
|
|
11266
11500
|
} else block[implementation.name] = raw(options.xstateVersion === 6 ? `function () {\n // TODO: implement ${implementation.name}\n}` : `function ({ context, event }) {\n // TODO: implement ${implementation.name}\n}`);
|
|
11267
11501
|
return block;
|
|
11268
11502
|
}
|
|
11503
|
+
/**
|
|
11504
|
+
* XState v6 types `setup({ guards })` entries as `(...params: any[]) => boolean`
|
|
11505
|
+
* and injects nothing: a named guard receives exactly what its caller passes.
|
|
11506
|
+
* Generated transition functions call `guards[name]({ context, event }, params)`
|
|
11507
|
+
* (as does `createMachineFromConfig`), so that is the argument type to declare.
|
|
11508
|
+
*/
|
|
11509
|
+
function getV6GuardArgsType(graph, guardName) {
|
|
11510
|
+
const schemas = graph.data.schemas;
|
|
11511
|
+
const rootContextType = contextSchemaToTSType(schemas?.context);
|
|
11512
|
+
const contexts = graph.edges.filter((edge) => !edge.data.temp && edge.data.guard?.type === guardName).map((edge) => {
|
|
11513
|
+
const types = [];
|
|
11514
|
+
let node = graph.nodes.find((candidate) => candidate.id === edge.sourceId);
|
|
11515
|
+
while (node) {
|
|
11516
|
+
const type = contextSchemaToTSType(node.data.schemas?.context);
|
|
11517
|
+
if (type) types.unshift(type);
|
|
11518
|
+
node = graph.nodes.find((candidate) => candidate.id === node?.parentId);
|
|
11519
|
+
}
|
|
11520
|
+
if (rootContextType) types.unshift(rootContextType);
|
|
11521
|
+
return types.length ? types.join(" & ") : void 0;
|
|
11522
|
+
});
|
|
11523
|
+
const contextType = contexts.some(Boolean) ? [...new Set(contexts.map((type) => type ?? "any"))].join(" | ") : rootContextType;
|
|
11524
|
+
const eventSchemas = {
|
|
11525
|
+
...schemas?.events,
|
|
11526
|
+
...schemas?.internalEvents
|
|
11527
|
+
};
|
|
11528
|
+
const declaredEventType = eventsSchemaToTSType(eventSchemas);
|
|
11529
|
+
if (!contextType && !declaredEventType) return void 0;
|
|
11530
|
+
const eventType = declaredEventType ? `${declaredEventType} | Exclude<import('xstate').ReservedMachineEvent, { type: ${Object.keys(eventSchemas).map((type) => serializeJS(type)).join(" | ")} }>` : "any";
|
|
11531
|
+
return `{ context: ${contextType ?? "any"}; event: ${eventType} }`;
|
|
11532
|
+
}
|
|
11533
|
+
/**
|
|
11534
|
+
* True when an authored guard expression destructures the generated
|
|
11535
|
+
* `{ context, event }` argument without annotating it, so contextual typing
|
|
11536
|
+
* can supply the types without contradicting an authored signature.
|
|
11537
|
+
*/
|
|
11538
|
+
function usesGeneratedGuardArgs(code) {
|
|
11539
|
+
const expression = parseSingleExpression(code)?.expression;
|
|
11540
|
+
if (!expression || !ts.isArrowFunction(expression) && !ts.isFunctionExpression(expression)) return false;
|
|
11541
|
+
const [first] = expression.parameters;
|
|
11542
|
+
if (!first || first.type || !ts.isObjectBindingPattern(first.name)) return false;
|
|
11543
|
+
return first.name.elements.every((element) => {
|
|
11544
|
+
const property = element.propertyName ?? element.name;
|
|
11545
|
+
return !element.dotDotDotToken && ts.isIdentifier(property) && (property.text === "context" || property.text === "event");
|
|
11546
|
+
});
|
|
11547
|
+
}
|
|
11269
11548
|
function buildGuardsBlock(guards, options) {
|
|
11270
11549
|
const block = {};
|
|
11271
|
-
for (const guard of guards)
|
|
11272
|
-
const
|
|
11273
|
-
|
|
11274
|
-
|
|
11275
|
-
|
|
11276
|
-
|
|
11277
|
-
|
|
11278
|
-
|
|
11279
|
-
|
|
11280
|
-
|
|
11550
|
+
for (const guard of guards) {
|
|
11551
|
+
const argsType = options.argsTypes?.get(guard.name);
|
|
11552
|
+
const argsAnnotation = argsType ? `: ${argsType}` : "";
|
|
11553
|
+
const paramsType = hasSchemaProperties(guard.paramsSchema) ? jsonSchemaToTSType(guard.paramsSchema) : void 0;
|
|
11554
|
+
if (guard.code?.body) {
|
|
11555
|
+
const inlineExpression = getInlineExpression$1(guard.code.body);
|
|
11556
|
+
if (inlineExpression) {
|
|
11557
|
+
block[guard.name] = argsType && usesGeneratedGuardArgs(inlineExpression) ? rawWithSourceSlice("(", inlineExpression, `) satisfies (args: ${argsType}, params: ${paramsType ?? "any"}) => boolean`, guard.code) : raw(inlineExpression, guard.code);
|
|
11558
|
+
continue;
|
|
11559
|
+
}
|
|
11560
|
+
const params = paramsType ? options.includeTypeSyntax ? `, params: ${paramsType}` : ", params" : "";
|
|
11561
|
+
const body = dedent(guard.code.body);
|
|
11562
|
+
block[guard.name] = rawWithSourceSlice(`function ({ context, event }${argsAnnotation}${params}) {\n `, body, "\n}", guard.code);
|
|
11563
|
+
} else block[guard.name] = raw(`function ({ context, event }${argsAnnotation}) {\n // TODO: implement ${guard.name}\n return false;\n}`);
|
|
11564
|
+
}
|
|
11281
11565
|
return block;
|
|
11282
11566
|
}
|
|
11283
11567
|
function buildActorsBlock(actors, options) {
|
|
@@ -13528,7 +13812,7 @@ function modify(text, path, value, options) {
|
|
|
13528
13812
|
//#region ../editor-sync/dist/adapters-9XXzVfbF.mjs
|
|
13529
13813
|
const sourceFileUris = /* @__PURE__ */ new WeakMap();
|
|
13530
13814
|
function collectXStateSourceLocations(sourceText, document, options = {}) {
|
|
13531
|
-
const sourceFile = ts$1.createSourceFile(document.fileName, sourceText, ts$1.ScriptTarget.Latest, true, getScriptKind$2
|
|
13815
|
+
const sourceFile = ts$1.createSourceFile(document.fileName, sourceText, ts$1.ScriptTarget.Latest, true, getScriptKind$2(document.fileName));
|
|
13532
13816
|
const uri = document.uri?.toString() ?? document.fileName;
|
|
13533
13817
|
sourceFileUris.set(sourceFile, uri);
|
|
13534
13818
|
const bindings = collectBindings(sourceFile, uri, document.fileName, options);
|
|
@@ -13590,7 +13874,7 @@ function machineFactoryPackage(sourceFile, document, machineIndex = 0, resolver)
|
|
|
13590
13874
|
let target = modules.get(snapshot.uri);
|
|
13591
13875
|
if (!target) {
|
|
13592
13876
|
target = {
|
|
13593
|
-
file: ts$1.createSourceFile(snapshot.fileName, snapshot.text, ts$1.ScriptTarget.Latest, true, getScriptKind$2
|
|
13877
|
+
file: ts$1.createSourceFile(snapshot.fileName, snapshot.text, ts$1.ScriptTarget.Latest, true, getScriptKind$2(snapshot.fileName)),
|
|
13594
13878
|
document: snapshot
|
|
13595
13879
|
};
|
|
13596
13880
|
modules.set(snapshot.uri, target);
|
|
@@ -13663,7 +13947,7 @@ function machineFactoryPackage(sourceFile, document, machineIndex = 0, resolver)
|
|
|
13663
13947
|
let index = 0;
|
|
13664
13948
|
const visit = (node) => {
|
|
13665
13949
|
if (factory) return;
|
|
13666
|
-
if (ts$1.isCallExpression(node) && isCreateMachineExpression$1
|
|
13950
|
+
if (ts$1.isCallExpression(node) && isCreateMachineExpression$1(node.expression)) {
|
|
13667
13951
|
if (index++ === machineIndex) factory = node;
|
|
13668
13952
|
return;
|
|
13669
13953
|
}
|
|
@@ -13744,7 +14028,7 @@ function parseRangePart(value) {
|
|
|
13744
14028
|
}
|
|
13745
14029
|
function collectImportedXStateTransitionSources(sourceText, document, options = {}) {
|
|
13746
14030
|
if (!options.resolver) return [];
|
|
13747
|
-
const sourceFile = ts$1.createSourceFile(document.fileName, sourceText, ts$1.ScriptTarget.Latest, true, getScriptKind$2
|
|
14031
|
+
const sourceFile = ts$1.createSourceFile(document.fileName, sourceText, ts$1.ScriptTarget.Latest, true, getScriptKind$2(document.fileName));
|
|
13748
14032
|
const uri = document.uri?.toString() ?? document.fileName;
|
|
13749
14033
|
sourceFileUris.set(sourceFile, uri);
|
|
13750
14034
|
const bindings = collectBindings(sourceFile, uri, document.fileName, options);
|
|
@@ -13835,7 +14119,7 @@ function resolveExportedStaticValue(document, exportName, resolver, visited) {
|
|
|
13835
14119
|
if (visited.has(visitKey)) return null;
|
|
13836
14120
|
visited.add(visitKey);
|
|
13837
14121
|
try {
|
|
13838
|
-
const sourceFile = ts$1.createSourceFile(document.fileName, document.text, ts$1.ScriptTarget.Latest, true, getScriptKind$2
|
|
14122
|
+
const sourceFile = ts$1.createSourceFile(document.fileName, document.text, ts$1.ScriptTarget.Latest, true, getScriptKind$2(document.fileName));
|
|
13839
14123
|
sourceFileUris.set(sourceFile, document.uri);
|
|
13840
14124
|
const localBindings = collectStaticValueBindings(sourceFile);
|
|
13841
14125
|
const localBinding = localBindings.get(exportName);
|
|
@@ -13973,7 +14257,7 @@ function addImportedBindings(bindings, sourceFile, uri, fileName, options, cache
|
|
|
13973
14257
|
uri
|
|
13974
14258
|
}, statement.moduleSpecifier.text);
|
|
13975
14259
|
if (!importedDocument) continue;
|
|
13976
|
-
const importedSourceFile = ts$1.createSourceFile(importedDocument.fileName, importedDocument.text, ts$1.ScriptTarget.Latest, true, getScriptKind$2
|
|
14260
|
+
const importedSourceFile = ts$1.createSourceFile(importedDocument.fileName, importedDocument.text, ts$1.ScriptTarget.Latest, true, getScriptKind$2(importedDocument.fileName));
|
|
13977
14261
|
sourceFileUris.set(importedSourceFile, importedDocument.uri);
|
|
13978
14262
|
const importedBindings = collectBindings(importedSourceFile, importedDocument.uri, importedDocument.fileName, options, cache);
|
|
13979
14263
|
for (const element of namedBindings.elements) {
|
|
@@ -14044,7 +14328,7 @@ function findMachineConfigObjectLiteral$1(sourceFile, bindings, machineIndex = 0
|
|
|
14044
14328
|
let currentMachineIndex = 0;
|
|
14045
14329
|
const visit = (node) => {
|
|
14046
14330
|
if (found) return;
|
|
14047
|
-
if (ts$1.isCallExpression(node) && isCreateMachineExpression$1
|
|
14331
|
+
if (ts$1.isCallExpression(node) && isCreateMachineExpression$1(node.expression)) {
|
|
14048
14332
|
const isSelectedMachine = currentMachineIndex === machineIndex;
|
|
14049
14333
|
currentMachineIndex += 1;
|
|
14050
14334
|
if (!isSelectedMachine) return;
|
|
@@ -14312,7 +14596,7 @@ function getEnumMemberName(name) {
|
|
|
14312
14596
|
if (ts$1.isIdentifier(name) || ts$1.isStringLiteral(name) || ts$1.isNumericLiteral(name)) return name.text;
|
|
14313
14597
|
return null;
|
|
14314
14598
|
}
|
|
14315
|
-
function isCreateMachineExpression$1
|
|
14599
|
+
function isCreateMachineExpression$1(expression) {
|
|
14316
14600
|
const isMachineFactoryName = (name) => name === "createMachine" || name === "createMachineFromConfig";
|
|
14317
14601
|
return ts$1.isIdentifier(expression) && isMachineFactoryName(expression.text) || ts$1.isPropertyAccessExpression(expression) && isMachineFactoryName(expression.name.text);
|
|
14318
14602
|
}
|
|
@@ -14348,7 +14632,7 @@ function toSourceRange$1(sourceFile, node) {
|
|
|
14348
14632
|
endChar: end.character
|
|
14349
14633
|
};
|
|
14350
14634
|
}
|
|
14351
|
-
function getScriptKind$2
|
|
14635
|
+
function getScriptKind$2(fileName) {
|
|
14352
14636
|
if (fileName.endsWith(".tsx")) return ts$1.ScriptKind.TSX;
|
|
14353
14637
|
if (fileName.endsWith(".jsx")) return ts$1.ScriptKind.JSX;
|
|
14354
14638
|
if (fileName.endsWith(".js")) return ts$1.ScriptKind.JS;
|
|
@@ -14440,7 +14724,7 @@ function selectMachineInModule(source, machineIndex, factory, expression) {
|
|
|
14440
14724
|
let factoryAlias = "__stately_sync_factory";
|
|
14441
14725
|
while (source.includes(factoryAlias)) factoryAlias += "_";
|
|
14442
14726
|
const visit = (node) => {
|
|
14443
|
-
if (ts$1.isCallExpression(node) && isCreateMachineExpression$1
|
|
14727
|
+
if (ts$1.isCallExpression(node) && isCreateMachineExpression$1(node.expression)) {
|
|
14444
14728
|
if (index++ === machineIndex) replacements.push({
|
|
14445
14729
|
start: node.getStart(file),
|
|
14446
14730
|
end: node.getEnd(),
|
|
@@ -21030,7 +21314,7 @@ function sourceLocationUris(sourceLocations) {
|
|
|
21030
21314
|
|
|
21031
21315
|
//#endregion
|
|
21032
21316
|
//#region src/version.ts
|
|
21033
|
-
const CLI_VERSION = "0.
|
|
21317
|
+
const CLI_VERSION = "0.14.1";
|
|
21034
21318
|
|
|
21035
21319
|
//#endregion
|
|
21036
21320
|
//#region src/cliHost.ts
|
|
@@ -21482,7 +21766,7 @@ async function openSourceDocument(fileName) {
|
|
|
21482
21766
|
};
|
|
21483
21767
|
}
|
|
21484
21768
|
function collectRelativeImportSpecifiers(text, fileName) {
|
|
21485
|
-
const sourceFile = ts$1.createSourceFile(fileName, text, ts$1.ScriptTarget.Latest, true, getScriptKind$
|
|
21769
|
+
const sourceFile = ts$1.createSourceFile(fileName, text, ts$1.ScriptTarget.Latest, true, getScriptKind$1(fileName));
|
|
21486
21770
|
const specifiers = [];
|
|
21487
21771
|
for (const statement of sourceFile.statements) {
|
|
21488
21772
|
const moduleSpecifier = ts$1.isImportDeclaration(statement) || ts$1.isExportDeclaration(statement) ? statement.moduleSpecifier : void 0;
|
|
@@ -21509,7 +21793,7 @@ function resolveRelativeImportCandidates(fromFileName, specifier) {
|
|
|
21509
21793
|
...importExtensions.map((extension) => path$1.join(basePath, `index${extension}`))
|
|
21510
21794
|
];
|
|
21511
21795
|
}
|
|
21512
|
-
function getScriptKind$
|
|
21796
|
+
function getScriptKind$1(fileName) {
|
|
21513
21797
|
if (fileName.endsWith(".tsx")) return ts$1.ScriptKind.TSX;
|
|
21514
21798
|
if (fileName.endsWith(".jsx")) return ts$1.ScriptKind.JSX;
|
|
21515
21799
|
if (/\.(?:c|m)?js$/.test(fileName)) return ts$1.ScriptKind.JS;
|
|
@@ -22031,105 +22315,6 @@ function describeCredentialBackend(backend, location) {
|
|
|
22031
22315
|
}
|
|
22032
22316
|
}
|
|
22033
22317
|
|
|
22034
|
-
//#endregion
|
|
22035
|
-
//#region ../editor-sync/dist/statelyPragma-D46lczJR.mjs
|
|
22036
|
-
function findStatelyPragmaAttachments(sourceText, fileName = "machine.ts") {
|
|
22037
|
-
const sourceFile = ts.createSourceFile(fileName, sourceText, ts.ScriptTarget.Latest, true, getScriptKind$1(fileName));
|
|
22038
|
-
const attachments = [];
|
|
22039
|
-
const visit = (node) => {
|
|
22040
|
-
if (ts.isCallExpression(node) && isCreateMachineExpression$1(node.expression)) {
|
|
22041
|
-
const attachNode = findAttachNode(node);
|
|
22042
|
-
if (attachNode) attachments.push({
|
|
22043
|
-
machineStart: getMachineExpressionStart(node.expression, sourceFile),
|
|
22044
|
-
attachStart: attachNode.getStart(sourceFile),
|
|
22045
|
-
pragma: findAttachedStatelyPragma(sourceText, attachNode)
|
|
22046
|
-
});
|
|
22047
|
-
}
|
|
22048
|
-
ts.forEachChild(node, visit);
|
|
22049
|
-
};
|
|
22050
|
-
visit(sourceFile);
|
|
22051
|
-
return attachments;
|
|
22052
|
-
}
|
|
22053
|
-
function getStatelyPragma(sourceText, fileName = "machine.ts", machineIndex = 0) {
|
|
22054
|
-
return findStatelyPragmaAttachments(sourceText, fileName)[machineIndex]?.pragma;
|
|
22055
|
-
}
|
|
22056
|
-
function upsertStatelyPragma(sourceText, id, options = {}) {
|
|
22057
|
-
const attachment = findStatelyPragmaAttachments(sourceText, options.fileName ?? "machine.ts")[options.machineIndex ?? 0];
|
|
22058
|
-
if (!attachment) return sourceText;
|
|
22059
|
-
const lineEnding = options.lineEnding ?? detectLineEnding(sourceText);
|
|
22060
|
-
const canonicalComment = `// @statelyai id=${id}`;
|
|
22061
|
-
if (attachment.pragma) return sourceText.slice(0, attachment.pragma.start) + canonicalComment + sourceText.slice(attachment.pragma.end);
|
|
22062
|
-
const insertText = `${getIndentationAtOffset(sourceText, attachment.attachStart)}${canonicalComment}${lineEnding}`;
|
|
22063
|
-
return sourceText.slice(0, attachment.attachStart) + insertText + sourceText.slice(attachment.attachStart);
|
|
22064
|
-
}
|
|
22065
|
-
function findAttachedStatelyPragma(sourceText, node) {
|
|
22066
|
-
const comments = ts.getLeadingCommentRanges(sourceText, node.getFullStart()) ?? [];
|
|
22067
|
-
for (let index = comments.length - 1; index >= 0; index -= 1) {
|
|
22068
|
-
const comment = comments[index];
|
|
22069
|
-
const parsed = parseStatelyPragma(sourceText, comment.pos, comment.end);
|
|
22070
|
-
if (parsed) return parsed;
|
|
22071
|
-
}
|
|
22072
|
-
}
|
|
22073
|
-
function parseStatelyPragma(sourceText, start, end) {
|
|
22074
|
-
const match = normalizeCommentContent(sourceText.slice(start, end)).match(/^@statelyai(?:\s+(.*))?$/s);
|
|
22075
|
-
if (!match) return;
|
|
22076
|
-
const fields = parseFields(match[1] ?? "");
|
|
22077
|
-
return {
|
|
22078
|
-
tag: "@statelyai",
|
|
22079
|
-
id: fields.id,
|
|
22080
|
-
fields,
|
|
22081
|
-
start,
|
|
22082
|
-
end
|
|
22083
|
-
};
|
|
22084
|
-
}
|
|
22085
|
-
function normalizeCommentContent(rawComment) {
|
|
22086
|
-
if (rawComment.startsWith("//")) return rawComment.slice(2).trim();
|
|
22087
|
-
if (rawComment.startsWith("/*")) return rawComment.slice(2, rawComment.endsWith("*/") ? -2 : void 0).split(/\r?\n/).map((line) => line.replace(/^\s*\*\s?/, "")).join(" ").trim();
|
|
22088
|
-
return rawComment.trim();
|
|
22089
|
-
}
|
|
22090
|
-
function parseFields(input) {
|
|
22091
|
-
const fields = {};
|
|
22092
|
-
for (const token of input.split(/\s+/)) {
|
|
22093
|
-
if (!token) continue;
|
|
22094
|
-
const equalsIndex = token.indexOf("=");
|
|
22095
|
-
if (equalsIndex <= 0) continue;
|
|
22096
|
-
const key = token.slice(0, equalsIndex);
|
|
22097
|
-
const value = token.slice(equalsIndex + 1);
|
|
22098
|
-
if (!key || !value) continue;
|
|
22099
|
-
fields[key] = value;
|
|
22100
|
-
}
|
|
22101
|
-
return fields;
|
|
22102
|
-
}
|
|
22103
|
-
function findAttachNode(node) {
|
|
22104
|
-
let current = node;
|
|
22105
|
-
while (current?.parent) {
|
|
22106
|
-
if (ts.isVariableStatement(current.parent) || ts.isExpressionStatement(current.parent) || ts.isExportAssignment(current.parent)) return current.parent;
|
|
22107
|
-
current = current.parent;
|
|
22108
|
-
}
|
|
22109
|
-
return current;
|
|
22110
|
-
}
|
|
22111
|
-
function isCreateMachineExpression$1(expression) {
|
|
22112
|
-
const isMachineFactoryName = (name) => name === "createMachine" || name === "createMachineFromConfig";
|
|
22113
|
-
return ts.isIdentifier(expression) && isMachineFactoryName(expression.text) || ts.isPropertyAccessExpression(expression) && isMachineFactoryName(expression.name.text);
|
|
22114
|
-
}
|
|
22115
|
-
function getMachineExpressionStart(expression, sourceFile) {
|
|
22116
|
-
if (ts.isPropertyAccessExpression(expression)) return expression.name.getStart(sourceFile);
|
|
22117
|
-
return expression.getStart(sourceFile);
|
|
22118
|
-
}
|
|
22119
|
-
function getIndentationAtOffset(sourceText, offset) {
|
|
22120
|
-
const lineStart = sourceText.lastIndexOf("\n", Math.max(0, offset - 1)) + 1;
|
|
22121
|
-
return sourceText.slice(lineStart, offset).match(/^[ \t]*/)?.[0] ?? "";
|
|
22122
|
-
}
|
|
22123
|
-
function detectLineEnding(sourceText) {
|
|
22124
|
-
return sourceText.includes("\r\n") ? "\r\n" : "\n";
|
|
22125
|
-
}
|
|
22126
|
-
function getScriptKind$1(fileName) {
|
|
22127
|
-
if (fileName.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
22128
|
-
if (fileName.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
22129
|
-
if (fileName.endsWith(".js")) return ts.ScriptKind.JS;
|
|
22130
|
-
return ts.ScriptKind.TS;
|
|
22131
|
-
}
|
|
22132
|
-
|
|
22133
22318
|
//#endregion
|
|
22134
22319
|
//#region ../../node_modules/.pnpm/@statelyai+graph@2.1.0_@statelyai+layout@0.4.3_cytoscape@3.34.0_d3-force@3.0.0_d3-hiera_2afdfa88fae2fa10712f99651d0f58d6/node_modules/@statelyai/graph/dist/index.mjs
|
|
22135
22320
|
const LAYOUT_KEYS = {
|
|
@@ -22582,7 +22767,7 @@ function fromXStateConfig(config) {
|
|
|
22582
22767
|
};
|
|
22583
22768
|
}
|
|
22584
22769
|
async function pushLocalMachineLinks(options) {
|
|
22585
|
-
const client = options.client ?? createStatelyClient({
|
|
22770
|
+
const client = options.client ?? createStatelyClient$1({
|
|
22586
22771
|
apiKey: options.apiKey,
|
|
22587
22772
|
baseUrl: options.baseUrl,
|
|
22588
22773
|
fetch: options.fetch
|
|
@@ -22679,7 +22864,7 @@ async function resolveLocalFile(locator, options, machineIndex = 0) {
|
|
|
22679
22864
|
let config = localExtraction.machines[0]?.config;
|
|
22680
22865
|
const extractionIssue = localExtraction.error;
|
|
22681
22866
|
if (!config) {
|
|
22682
|
-
const extracted = await (options.client ?? createStatelyClient({
|
|
22867
|
+
const extracted = await (options.client ?? createStatelyClient$1({
|
|
22683
22868
|
apiKey: options.apiKey,
|
|
22684
22869
|
baseUrl: options.baseUrl,
|
|
22685
22870
|
fetch: options.fetch
|
|
@@ -22751,7 +22936,7 @@ function inferXStateTargetLanguage(targetPath) {
|
|
|
22751
22936
|
return /\.(?:c|m)?jsx?$/i.test(targetPath) ? "javascript" : "typescript";
|
|
22752
22937
|
}
|
|
22753
22938
|
async function resolveRemoteMachine(machineId, baseUrl, kind, locator, options) {
|
|
22754
|
-
const digraph = (await (options.client ?? createStatelyClient({
|
|
22939
|
+
const digraph = (await (options.client ?? createStatelyClient$1({
|
|
22755
22940
|
apiKey: options.apiKey,
|
|
22756
22941
|
baseUrl,
|
|
22757
22942
|
fetch: options.fetch
|
|
@@ -23523,7 +23708,7 @@ async function initProject(options) {
|
|
|
23523
23708
|
reusedExistingConfig: true
|
|
23524
23709
|
};
|
|
23525
23710
|
if (existingConfig.config.projectId) {
|
|
23526
|
-
const client = options.client ?? createStatelyClient
|
|
23711
|
+
const client = options.client ?? createStatelyClient({
|
|
23527
23712
|
apiKey: options.apiKey,
|
|
23528
23713
|
baseUrl: apiBaseUrl
|
|
23529
23714
|
});
|
|
@@ -23544,7 +23729,7 @@ async function initProject(options) {
|
|
|
23544
23729
|
reusedExistingConfig: false
|
|
23545
23730
|
};
|
|
23546
23731
|
}
|
|
23547
|
-
const client = options.client ?? createStatelyClient
|
|
23732
|
+
const client = options.client ?? createStatelyClient({
|
|
23548
23733
|
apiKey: options.apiKey,
|
|
23549
23734
|
baseUrl: apiBaseUrl
|
|
23550
23735
|
});
|
|
@@ -23670,9 +23855,9 @@ async function resolveConfiguredProject(options) {
|
|
|
23670
23855
|
configPath: options.configPath,
|
|
23671
23856
|
rewriteIfNeeded: options.rewriteIfNeeded ?? true
|
|
23672
23857
|
});
|
|
23673
|
-
if (!config.projectId) throw new Error("This is a local-only project. Run `statelyai
|
|
23858
|
+
if (!config.projectId) throw new Error("This is a local-only project. Run `statelyai link` to connect it to Stately Studio.");
|
|
23674
23859
|
return {
|
|
23675
|
-
client: options.client ?? createStatelyClient
|
|
23860
|
+
client: options.client ?? createStatelyClient({
|
|
23676
23861
|
apiKey: options.apiKey,
|
|
23677
23862
|
baseUrl: resolveApiBaseUrl(options.baseUrl ?? config.studioUrl)
|
|
23678
23863
|
}),
|
|
@@ -23779,7 +23964,7 @@ async function resolveProjectStatus(options = {}) {
|
|
|
23779
23964
|
};
|
|
23780
23965
|
}
|
|
23781
23966
|
const apiKey = options.apiKey ?? (options.client ? void 0 : (await resolveApiKey()).apiKey);
|
|
23782
|
-
const client = options.client ?? createStatelyClient
|
|
23967
|
+
const client = options.client ?? createStatelyClient({
|
|
23783
23968
|
apiKey,
|
|
23784
23969
|
baseUrl: resolveApiBaseUrl(studioUrl)
|
|
23785
23970
|
});
|
|
@@ -24293,6 +24478,93 @@ async function discoverMachinesInFile(filePath) {
|
|
|
24293
24478
|
relativePath: path.basename(filePath)
|
|
24294
24479
|
}];
|
|
24295
24480
|
}
|
|
24481
|
+
var LinkCommand = class LinkCommand extends Command {
|
|
24482
|
+
static summary = "Connect a workspace or source machine to Stately Studio without syncing definitions.";
|
|
24483
|
+
static args = { file: Args.string({ description: "Source file to associate with --machine" }) };
|
|
24484
|
+
static flags = {
|
|
24485
|
+
help: Flags.help({ char: "h" }),
|
|
24486
|
+
project: Flags.string({
|
|
24487
|
+
description: "Existing Studio project ID or URL",
|
|
24488
|
+
exclusive: ["create"]
|
|
24489
|
+
}),
|
|
24490
|
+
create: Flags.boolean({
|
|
24491
|
+
description: "Create a new Studio project",
|
|
24492
|
+
default: false
|
|
24493
|
+
}),
|
|
24494
|
+
name: Flags.string({
|
|
24495
|
+
description: "Name for --create",
|
|
24496
|
+
dependsOn: ["create"]
|
|
24497
|
+
}),
|
|
24498
|
+
visibility: Flags.string({
|
|
24499
|
+
description: "Visibility for --create",
|
|
24500
|
+
options: [
|
|
24501
|
+
"Private",
|
|
24502
|
+
"Public",
|
|
24503
|
+
"Unlisted"
|
|
24504
|
+
]
|
|
24505
|
+
}),
|
|
24506
|
+
machine: Flags.string({ description: "Existing remote machine ID or URL; requires a source file" }),
|
|
24507
|
+
"machine-index": Flags.integer({
|
|
24508
|
+
description: "Zero-based machine index in a multi-machine source file",
|
|
24509
|
+
min: 0
|
|
24510
|
+
}),
|
|
24511
|
+
"base-url": Flags.string({ description: "Studio deployment origin" }),
|
|
24512
|
+
config: Flags.string({ description: "Path to statelyai.json" }),
|
|
24513
|
+
force: Flags.boolean({
|
|
24514
|
+
description: "Replace an existing project or machine association",
|
|
24515
|
+
default: false
|
|
24516
|
+
})
|
|
24517
|
+
};
|
|
24518
|
+
async run() {
|
|
24519
|
+
const { args, flags } = await this.parse(LinkCommand);
|
|
24520
|
+
let projectId = flags.project;
|
|
24521
|
+
let create = flags.create;
|
|
24522
|
+
const credential = await resolveApiKey();
|
|
24523
|
+
const config = await readStatelyProjectConfig({ configPath: flags.config }).catch((error) => {
|
|
24524
|
+
if (error.code === "ENOENT") return void 0;
|
|
24525
|
+
throw error;
|
|
24526
|
+
});
|
|
24527
|
+
const baseUrl = flags["base-url"] ?? config?.config.studioUrl ?? getResolvedStudioUrl();
|
|
24528
|
+
if (!projectId && !create && !config?.config.projectId && process.stdin.isTTY && process.stdout.isTTY) {
|
|
24529
|
+
const projects = await createStatelyClient({
|
|
24530
|
+
apiKey: credential.apiKey,
|
|
24531
|
+
baseUrl: resolveApiBaseUrl(baseUrl)
|
|
24532
|
+
}).projects.list();
|
|
24533
|
+
projects.forEach((project, index) => this.log(`${index + 1}. ${project.name} (${project.projectId})`));
|
|
24534
|
+
this.log("0. Create a new Studio project");
|
|
24535
|
+
const rl = createInterface({
|
|
24536
|
+
input: process.stdin,
|
|
24537
|
+
output: process.stdout
|
|
24538
|
+
});
|
|
24539
|
+
try {
|
|
24540
|
+
const answer = (await rl.question("Choose a project number: ")).trim();
|
|
24541
|
+
if (!/^\d+$/.test(answer)) this.error("Choose a project number, or pass --project <id> or --create.");
|
|
24542
|
+
const choice = Number(answer);
|
|
24543
|
+
if (choice === 0) create = true;
|
|
24544
|
+
else if (projects[choice - 1]) projectId = projects[choice - 1].projectId;
|
|
24545
|
+
else this.error("No project at that number.");
|
|
24546
|
+
} finally {
|
|
24547
|
+
rl.close();
|
|
24548
|
+
}
|
|
24549
|
+
}
|
|
24550
|
+
const result = await linkProject({
|
|
24551
|
+
projectId,
|
|
24552
|
+
create,
|
|
24553
|
+
apiKey: credential.apiKey,
|
|
24554
|
+
baseUrl,
|
|
24555
|
+
configPath: flags.config,
|
|
24556
|
+
name: flags.name,
|
|
24557
|
+
visibility: flags.visibility,
|
|
24558
|
+
force: flags.force,
|
|
24559
|
+
file: args.file,
|
|
24560
|
+
machineId: flags.machine,
|
|
24561
|
+
machineIndex: flags["machine-index"]
|
|
24562
|
+
});
|
|
24563
|
+
this.log(`Connected to Studio project ${result.project.name} (${result.project.projectId}).`);
|
|
24564
|
+
if (result.machineId) this.log(`Associated ${args.file} with machine ${result.machineId}.`);
|
|
24565
|
+
this.log("No machine definitions uploaded or downloaded. Use push or pull to sync.");
|
|
24566
|
+
}
|
|
24567
|
+
};
|
|
24296
24568
|
var InitCommand = class InitCommand extends Command {
|
|
24297
24569
|
static enableJsonFlag = false;
|
|
24298
24570
|
static summary = "Create a local or Studio-connected statelyai.json.";
|
|
@@ -24343,6 +24615,7 @@ var InitCommand = class InitCommand extends Command {
|
|
|
24343
24615
|
if (resolvedApiKey.source === "missing" && error instanceof StudioApiError && (error.status === 401 || error.status === 403)) this.error("Not logged in. Run `npx statelyai login` and retry. To initialize without an account, run `npx statelyai init --local` (add `--force` to replace an existing config).");
|
|
24344
24616
|
throw error;
|
|
24345
24617
|
}
|
|
24618
|
+
this.log("For separate local setup and Studio linking, use `statelyai init --local --scan`, then `statelyai link`.");
|
|
24346
24619
|
const initMessage = result.project ? (() => {
|
|
24347
24620
|
const projectEditorUrl = buildProjectEditorUrl(result.config.studioUrl, result.project.projectId);
|
|
24348
24621
|
return result.reusedExistingConfig ? `Using existing statelyai.json at ${result.configPath} for project ${result.project.projectId}.\nEditor: ${projectEditorUrl}` : `Initialized project ${result.project.projectId} and wrote ${result.configPath}.\nEditor: ${projectEditorUrl}`;
|
|
@@ -24510,6 +24783,7 @@ const COMMANDS = {
|
|
|
24510
24783
|
scan: ScanCommand,
|
|
24511
24784
|
status: StatusCommand,
|
|
24512
24785
|
init: InitCommand,
|
|
24786
|
+
link: LinkCommand,
|
|
24513
24787
|
login: LoginCommand,
|
|
24514
24788
|
logout: LogoutCommand,
|
|
24515
24789
|
whoami: WhoamiCommand,
|
|
@@ -24539,4 +24813,4 @@ function isDirectExecution() {
|
|
|
24539
24813
|
if (isDirectExecution()) run$1();
|
|
24540
24814
|
|
|
24541
24815
|
//#endregion
|
|
24542
|
-
export {
|
|
24816
|
+
export { formatVerificationJUnit as A, run$1 as C, resourceId as D, linkProject as E, readGraphFile as F, verifyReport as I, briefReport as M, changesReport as N, resolveVerificationRequest as O, pendingReport as P, resolveProjectStatus as S, scanProjectSources as T, isFileGitDirty as _, discoverMachinesInSource as a, resolveCredentialStatus as b, formatDiscoveredMachines as c, formatProjectStatus as d, formatStoredCredentialSource as f, initProject as g, inferInitProjectName as h, discoverLinkedPullTargets as i, createStatelyProjectConfig as j, verifyProject as k, formatMissingNewMachineDirMessage as l, getEnvCredential as m, buildOAuthLoginStart as n, discoverOAuthLogin as o, getEnvApiKey as p, classifyPushCandidates as r, discoverRemoteProjectMachineTargets as s, COMMANDS as t, formatPlanSummary as u, resolveApiKey as v, scanProjectMachines as w, resolveOpenRootDir as x, resolveConfiguredPullTargets as y };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Command } from "@oclif/core";
|
|
2
2
|
import { XGraph } from "@statelyai/mcp/loop";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
+
import { ConnectedRepo, CreateProjectInput, LegacyProjectVisibility, OAuthAuthorizationServerMetadata, OAuthProtectedResourceMetadata, ProjectData, ProjectMachineSummary, ProjectVisibility, StudioClient } from "@statelyai/sdk";
|
|
4
5
|
import { StatelyGraph } from "@statelyai/sdk/graph";
|
|
5
|
-
import { ConnectedRepo, CreateProjectInput, OAuthAuthorizationServerMetadata, OAuthProtectedResourceMetadata, ProjectData, ProjectMachineSummary, StudioClient } from "@statelyai/sdk";
|
|
6
6
|
import * as _oclif_core_interfaces0 from "@oclif/core/interfaces";
|
|
7
7
|
|
|
8
8
|
//#region src/verifyCommand.d.ts
|
|
@@ -27,6 +27,43 @@ declare class VerifyCommand extends Command {
|
|
|
27
27
|
run(): Promise<void>;
|
|
28
28
|
}
|
|
29
29
|
//#endregion
|
|
30
|
+
//#region src/link.d.ts
|
|
31
|
+
interface LinkProjectOptions {
|
|
32
|
+
cwd?: string;
|
|
33
|
+
configPath?: string;
|
|
34
|
+
apiKey?: string;
|
|
35
|
+
baseUrl?: string;
|
|
36
|
+
client?: StudioClient;
|
|
37
|
+
projectId?: string;
|
|
38
|
+
create?: boolean;
|
|
39
|
+
name?: string;
|
|
40
|
+
visibility?: ProjectVisibility | LegacyProjectVisibility;
|
|
41
|
+
force?: boolean;
|
|
42
|
+
file?: string;
|
|
43
|
+
machineId?: string;
|
|
44
|
+
machineIndex?: number;
|
|
45
|
+
}
|
|
46
|
+
declare function resourceId(locator: string, kind: 'project' | 'machine'): string;
|
|
47
|
+
/** Association only: no definitions are uploaded, downloaded, or executed. */
|
|
48
|
+
declare function linkProject(options: LinkProjectOptions): Promise<{
|
|
49
|
+
project: ProjectData;
|
|
50
|
+
config: {
|
|
51
|
+
projectId: string;
|
|
52
|
+
studioUrl: string;
|
|
53
|
+
$schema: string;
|
|
54
|
+
version: string;
|
|
55
|
+
defaultXStateVersion: number;
|
|
56
|
+
sourceUpdateStrategy?: "preserve" | "rewrite";
|
|
57
|
+
include: string[];
|
|
58
|
+
exclude?: string[];
|
|
59
|
+
newMachinesDir?: string;
|
|
60
|
+
storage?: "local" | "hosted";
|
|
61
|
+
};
|
|
62
|
+
configPath: string;
|
|
63
|
+
machineId: string | undefined;
|
|
64
|
+
filePath: string | undefined;
|
|
65
|
+
}>;
|
|
66
|
+
//#endregion
|
|
30
67
|
//#region src/loopCommands.d.ts
|
|
31
68
|
/**
|
|
32
69
|
* Offline loop commands over XGraph JSON files and the repository's
|
|
@@ -609,6 +646,25 @@ declare class OpenCommand extends Command {
|
|
|
609
646
|
run(): Promise<void>;
|
|
610
647
|
}
|
|
611
648
|
declare function resolveOpenRootDir(cwd: string, fileArg?: string): string;
|
|
649
|
+
declare class LinkCommand extends Command {
|
|
650
|
+
static summary: string;
|
|
651
|
+
static args: {
|
|
652
|
+
file: _oclif_core_interfaces0.Arg<string | undefined, Record<string, unknown>>;
|
|
653
|
+
};
|
|
654
|
+
static flags: {
|
|
655
|
+
help: _oclif_core_interfaces0.BooleanFlag<void>;
|
|
656
|
+
project: _oclif_core_interfaces0.OptionFlag<string | undefined, _oclif_core_interfaces0.CustomOptions>;
|
|
657
|
+
create: _oclif_core_interfaces0.BooleanFlag<boolean>;
|
|
658
|
+
name: _oclif_core_interfaces0.OptionFlag<string | undefined, _oclif_core_interfaces0.CustomOptions>;
|
|
659
|
+
visibility: _oclif_core_interfaces0.OptionFlag<string | undefined, _oclif_core_interfaces0.CustomOptions>;
|
|
660
|
+
machine: _oclif_core_interfaces0.OptionFlag<string | undefined, _oclif_core_interfaces0.CustomOptions>;
|
|
661
|
+
'machine-index': _oclif_core_interfaces0.OptionFlag<number | undefined, _oclif_core_interfaces0.CustomOptions>;
|
|
662
|
+
'base-url': _oclif_core_interfaces0.OptionFlag<string | undefined, _oclif_core_interfaces0.CustomOptions>;
|
|
663
|
+
config: _oclif_core_interfaces0.OptionFlag<string | undefined, _oclif_core_interfaces0.CustomOptions>;
|
|
664
|
+
force: _oclif_core_interfaces0.BooleanFlag<boolean>;
|
|
665
|
+
};
|
|
666
|
+
run(): Promise<void>;
|
|
667
|
+
}
|
|
612
668
|
declare class InitCommand extends Command {
|
|
613
669
|
static enableJsonFlag: boolean;
|
|
614
670
|
static summary: string;
|
|
@@ -689,6 +745,7 @@ declare const COMMANDS: {
|
|
|
689
745
|
scan: typeof ScanCommand;
|
|
690
746
|
status: typeof StatusCommand;
|
|
691
747
|
init: typeof InitCommand;
|
|
748
|
+
link: typeof LinkCommand;
|
|
692
749
|
login: typeof LoginCommand;
|
|
693
750
|
logout: typeof LogoutCommand;
|
|
694
751
|
whoami: typeof WhoamiCommand;
|
|
@@ -1616,4 +1673,4 @@ declare function verifyProject(options?: VerifyProjectOptions): Promise<{
|
|
|
1616
1673
|
/** One case per recorded path/probe. Unattributed divergences remain separate cases. */
|
|
1617
1674
|
declare function formatVerificationJUnit(report: VerificationRunReport): string;
|
|
1618
1675
|
//#endregion
|
|
1619
|
-
export { ApiKeyResolution, COMMANDS, CredentialStatus, DiscoveredMachine, InitProjectOptions, InitProjectResult, LinkedPullTarget, OAuthLoginDiscovery, ProjectMachineStatus, ProjectStatusMachine, ProjectStatusResult, PushCandidateClassification, RemoteProjectMachineTarget, ResolveApiKeyOptions, ResolvedConfiguredPullTargets, ScanProjectSourcesOptions, type VerificationExecutor, type VerificationRequest, type VerificationRunReport, type VerifyProjectOptions, briefReport, buildOAuthLoginStart, changesReport, classifyPushCandidates, createStatelyProjectConfig, discoverLinkedPullTargets, discoverMachinesInSource, discoverOAuthLogin, discoverRemoteProjectMachineTargets, formatDiscoveredMachines, formatMissingNewMachineDirMessage, formatPlanSummary, formatProjectStatus, formatStoredCredentialSource, formatVerificationJUnit, getEnvApiKey, getEnvCredential, inferInitProjectName, initProject, isFileGitDirty, pendingReport, readGraphFile, resolveApiKey, resolveConfiguredPullTargets, resolveCredentialStatus, resolveOpenRootDir, resolveProjectStatus, resolveVerificationRequest, run, scanProjectMachines, scanProjectSources, verifyProject, verifyReport };
|
|
1676
|
+
export { ApiKeyResolution, COMMANDS, CredentialStatus, DiscoveredMachine, InitProjectOptions, InitProjectResult, type LinkProjectOptions, LinkedPullTarget, OAuthLoginDiscovery, ProjectMachineStatus, ProjectStatusMachine, ProjectStatusResult, PushCandidateClassification, RemoteProjectMachineTarget, ResolveApiKeyOptions, ResolvedConfiguredPullTargets, ScanProjectSourcesOptions, type VerificationExecutor, type VerificationRequest, type VerificationRunReport, type VerifyProjectOptions, briefReport, buildOAuthLoginStart, changesReport, classifyPushCandidates, createStatelyProjectConfig, discoverLinkedPullTargets, discoverMachinesInSource, discoverOAuthLogin, discoverRemoteProjectMachineTargets, formatDiscoveredMachines, formatMissingNewMachineDirMessage, formatPlanSummary, formatProjectStatus, formatStoredCredentialSource, formatVerificationJUnit, getEnvApiKey, getEnvCredential, inferInitProjectName, initProject, isFileGitDirty, linkProject, pendingReport, readGraphFile, resolveApiKey, resolveConfiguredPullTargets, resolveCredentialStatus, resolveOpenRootDir, resolveProjectStatus, resolveVerificationRequest, resourceId, run, scanProjectMachines, scanProjectSources, verifyProject, verifyReport };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as formatVerificationJUnit, C as run, D as resourceId, E as linkProject, F as readGraphFile, I as verifyReport, M as briefReport, N as changesReport, O as resolveVerificationRequest, P as pendingReport, S as resolveProjectStatus, T as scanProjectSources, _ 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, j as createStatelyProjectConfig, k as verifyProject, 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 scanProjectMachines, x as resolveOpenRootDir, y as resolveConfiguredPullTargets } from "./cli-a0Z1igmj.mjs";
|
|
2
2
|
|
|
3
|
-
export { COMMANDS, briefReport, buildOAuthLoginStart, changesReport, classifyPushCandidates, createStatelyProjectConfig, discoverLinkedPullTargets, discoverMachinesInSource, discoverOAuthLogin, discoverRemoteProjectMachineTargets, formatDiscoveredMachines, formatMissingNewMachineDirMessage, formatPlanSummary, formatProjectStatus, formatStoredCredentialSource, formatVerificationJUnit, getEnvApiKey, getEnvCredential, inferInitProjectName, initProject, isFileGitDirty, pendingReport, readGraphFile, resolveApiKey, resolveConfiguredPullTargets, resolveCredentialStatus, resolveOpenRootDir, resolveProjectStatus, resolveVerificationRequest, run, scanProjectMachines, scanProjectSources, verifyProject, verifyReport };
|
|
3
|
+
export { COMMANDS, briefReport, buildOAuthLoginStart, changesReport, classifyPushCandidates, createStatelyProjectConfig, discoverLinkedPullTargets, discoverMachinesInSource, discoverOAuthLogin, discoverRemoteProjectMachineTargets, formatDiscoveredMachines, formatMissingNewMachineDirMessage, formatPlanSummary, formatProjectStatus, formatStoredCredentialSource, formatVerificationJUnit, getEnvApiKey, getEnvCredential, inferInitProjectName, initProject, isFileGitDirty, linkProject, pendingReport, readGraphFile, resolveApiKey, resolveConfiguredPullTargets, resolveCredentialStatus, resolveOpenRootDir, resolveProjectStatus, resolveVerificationRequest, resourceId, run, scanProjectMachines, scanProjectSources, verifyProject, verifyReport };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "statelyai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.1",
|
|
4
4
|
"description": "Command-line tools for Stately",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -24,15 +24,15 @@
|
|
|
24
24
|
"typescript": "^5.9.3",
|
|
25
25
|
"ws": "^8.21.0",
|
|
26
26
|
"zod": "^4.4.1",
|
|
27
|
-
"@statelyai/mcp": "0.
|
|
28
|
-
"@statelyai/sdk": "0.39.
|
|
27
|
+
"@statelyai/mcp": "0.18.0",
|
|
28
|
+
"@statelyai/sdk": "0.39.1"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/ws": "^8.18.1",
|
|
32
32
|
"tsdown": "0.21.0-beta.2",
|
|
33
33
|
"vitest": "^3.2.4",
|
|
34
|
-
"@statelyai/api-contract": "0.
|
|
35
|
-
"@statelyai/editor-sync": "0.2.
|
|
34
|
+
"@statelyai/api-contract": "0.7.1",
|
|
35
|
+
"@statelyai/editor-sync": "0.2.2"
|
|
36
36
|
},
|
|
37
37
|
"oclif": {
|
|
38
38
|
"bin": "statelyai",
|