statelyai 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -3
- package/dist/bin.mjs +1 -1
- package/dist/{cli-1Nrsh5Xl.mjs → cli-DB0A-O4Y.mjs} +179 -104
- package/dist/index.d.mts +27 -2
- package/dist/index.mjs +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -26,6 +26,8 @@ statelyai init
|
|
|
26
26
|
statelyai init --scan
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
If you have an older `statelyai.json` that still uses the legacy `sources` shape, the CLI will rewrite simple single-source configs automatically when it reads them.
|
|
30
|
+
|
|
29
31
|
That writes a `statelyai.json` like:
|
|
30
32
|
|
|
31
33
|
```json
|
|
@@ -37,7 +39,7 @@ That writes a `statelyai.json` like:
|
|
|
37
39
|
"defaultXStateVersion": 5,
|
|
38
40
|
"include": ["src/**/*.ts"],
|
|
39
41
|
"exclude": ["**/*.test.*", "**/*.spec.*"],
|
|
40
|
-
"
|
|
42
|
+
"newMachinesDir": "src"
|
|
41
43
|
}
|
|
42
44
|
```
|
|
43
45
|
|
|
@@ -55,13 +57,13 @@ statelyai push --dry-run
|
|
|
55
57
|
|
|
56
58
|
If a saved `// @statelyai id=...` points to a deleted or inaccessible remote machine, `push` will prompt to relink the file as a new remote machine and replace the local id.
|
|
57
59
|
|
|
58
|
-
6. Pull remote changes back into linked local files and create new local files for remote-only project machines when `
|
|
60
|
+
6. Pull remote changes back into linked local files and create new local files for remote-only project machines when `newMachinesDir` is configured:
|
|
59
61
|
|
|
60
62
|
```bash
|
|
61
63
|
statelyai pull
|
|
62
64
|
```
|
|
63
65
|
|
|
64
|
-
`pull` skips locally modified linked files unless you pass `--force`. New remote-only machines are written as `<machine-name>.machine.ts` inside `
|
|
66
|
+
`pull` skips locally modified linked files unless you pass `--force`. New remote-only machines are written as `<machine-name>.machine.ts` inside `newMachinesDir`.
|
|
65
67
|
|
|
66
68
|
Run it without installing it globally:
|
|
67
69
|
|
package/dist/bin.mjs
CHANGED
|
@@ -10,7 +10,6 @@ import { promisify } from "node:util";
|
|
|
10
10
|
import { Args, Command, Flags, flush, handle, run } from "@oclif/core";
|
|
11
11
|
import * as crypto from "node:crypto";
|
|
12
12
|
import * as http from "node:http";
|
|
13
|
-
import * as https from "node:https";
|
|
14
13
|
import os from "node:os";
|
|
15
14
|
import { StudioApiError, createStatelyClient, getStatelyPragma } from "@statelyai/sdk";
|
|
16
15
|
import { planSync, pullSync, pushLocalMachineLinks } from "@statelyai/sdk/sync";
|
|
@@ -594,33 +593,7 @@ function listen(server, port, host) {
|
|
|
594
593
|
}
|
|
595
594
|
async function fetchEditorHost(input, init) {
|
|
596
595
|
const url = typeof input === "string" ? new URL(input) : input;
|
|
597
|
-
|
|
598
|
-
const body = typeof init?.body === "string" ? init.body : init?.body instanceof URLSearchParams ? init.body.toString() : void 0;
|
|
599
|
-
return new Promise((resolve, reject) => {
|
|
600
|
-
const request = https.request(url, {
|
|
601
|
-
method: init?.method ?? "GET",
|
|
602
|
-
headers: init?.headers,
|
|
603
|
-
rejectUnauthorized: false
|
|
604
|
-
}, (response) => {
|
|
605
|
-
const chunks = [];
|
|
606
|
-
response.on("data", (chunk) => {
|
|
607
|
-
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
608
|
-
});
|
|
609
|
-
response.on("end", () => {
|
|
610
|
-
const text = Buffer.concat(chunks).toString("utf8");
|
|
611
|
-
resolve({
|
|
612
|
-
ok: typeof response.statusCode === "number" && response.statusCode >= 200 && response.statusCode < 300,
|
|
613
|
-
status: response.statusCode ?? 0,
|
|
614
|
-
async json() {
|
|
615
|
-
return JSON.parse(text);
|
|
616
|
-
}
|
|
617
|
-
});
|
|
618
|
-
});
|
|
619
|
-
});
|
|
620
|
-
request.on("error", reject);
|
|
621
|
-
if (body !== void 0) request.write(body);
|
|
622
|
-
request.end();
|
|
623
|
-
});
|
|
596
|
+
return fetch(url, init);
|
|
624
597
|
}
|
|
625
598
|
async function assertEditorHostAvailable(editorUrl) {
|
|
626
599
|
const baseUrl = normalizedBaseUrl(editorUrl);
|
|
@@ -634,16 +607,7 @@ async function assertEditorHostAvailable(editorUrl) {
|
|
|
634
607
|
if (response.status === 404) throw new Error(formatEditorHostError(baseUrl, response.status));
|
|
635
608
|
}
|
|
636
609
|
function formatEditorHostError(baseUrl, status, cause) {
|
|
637
|
-
|
|
638
|
-
return `Cannot reach a usable editor host at ${baseUrl}.${status ? ` HTTP ${status} from /embed.` : ""}${cause instanceof Error && cause.message ? ` ${cause.message}` : ""} The CLI loads editor URL defaults from your environment, including \`.env.local\`.${hint}`;
|
|
639
|
-
}
|
|
640
|
-
function isLocalVizHost(value) {
|
|
641
|
-
try {
|
|
642
|
-
const url = new URL(value);
|
|
643
|
-
return url.protocol === "https:" && url.hostname === "viz.localhost";
|
|
644
|
-
} catch {
|
|
645
|
-
return false;
|
|
646
|
-
}
|
|
610
|
+
return `Cannot reach a usable editor host at ${baseUrl}.${status ? ` HTTP ${status} from /embed.` : ""}${cause instanceof Error && cause.message ? ` ${cause.message}` : ""} The CLI loads editor URL defaults from your environment, including \`.env.local\`. Start the editor host, set \`STATELY_EDITOR_URL\`, or pass \`--editor-url <url>\`.`;
|
|
647
611
|
}
|
|
648
612
|
function openBrowser(url) {
|
|
649
613
|
spawn(process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open", process.platform === "win32" ? [
|
|
@@ -976,17 +940,44 @@ function normalizeProjectConfig(config) {
|
|
|
976
940
|
defaultXStateVersion: Math.max(5, config.defaultXStateVersion ?? 5),
|
|
977
941
|
include: [...config.include ?? firstSource?.include ?? []],
|
|
978
942
|
exclude: config.exclude == null ? [...firstSource?.exclude ?? DEFAULT_SOURCE_EXCLUDES] : [...config.exclude],
|
|
979
|
-
...config.
|
|
943
|
+
...config.newMachinesDir ? { newMachinesDir: config.newMachinesDir } : {}
|
|
944
|
+
};
|
|
945
|
+
}
|
|
946
|
+
function getConfigRewriteStatus(config) {
|
|
947
|
+
if (!config.sources) return { needsRewrite: false };
|
|
948
|
+
if (config.sources.length > 1) return {
|
|
949
|
+
needsRewrite: true,
|
|
950
|
+
reason: "multiple-legacy-sources"
|
|
951
|
+
};
|
|
952
|
+
return {
|
|
953
|
+
needsRewrite: true,
|
|
954
|
+
reason: "legacy-sources"
|
|
980
955
|
};
|
|
981
956
|
}
|
|
982
957
|
async function readStatelyProjectConfig(options = {}) {
|
|
983
958
|
const rootDir = path.resolve(options.cwd ?? process.cwd());
|
|
984
959
|
const configPath = path.resolve(rootDir, options.configPath ?? STATELY_CONFIG_FILE);
|
|
985
960
|
const raw = await fsPromises.readFile(configPath, "utf8");
|
|
961
|
+
const parsed = JSON.parse(raw);
|
|
962
|
+
const config = normalizeProjectConfig(parsed);
|
|
963
|
+
const rewriteStatus = getConfigRewriteStatus(parsed);
|
|
964
|
+
if (options.rewriteIfNeeded && rewriteStatus.reason === "legacy-sources") {
|
|
965
|
+
await fsPromises.writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`, "utf8");
|
|
966
|
+
return {
|
|
967
|
+
config,
|
|
968
|
+
configPath,
|
|
969
|
+
rootDir,
|
|
970
|
+
rewriteStatus: {
|
|
971
|
+
needsRewrite: false,
|
|
972
|
+
rewritten: true
|
|
973
|
+
}
|
|
974
|
+
};
|
|
975
|
+
}
|
|
986
976
|
return {
|
|
987
|
-
config
|
|
977
|
+
config,
|
|
988
978
|
configPath,
|
|
989
|
-
rootDir
|
|
979
|
+
rootDir,
|
|
980
|
+
rewriteStatus
|
|
990
981
|
};
|
|
991
982
|
}
|
|
992
983
|
async function walkFiles(rootDir, currentDir = rootDir) {
|
|
@@ -1162,6 +1153,12 @@ async function discoverStatelySourceFiles(options = {}) {
|
|
|
1162
1153
|
const execFileAsync = promisify(execFile);
|
|
1163
1154
|
const STATELY_API_KEY_SETTINGS_URL = "https://stately.ai/registry/user/my-settings?tab=API+Key";
|
|
1164
1155
|
const DEFAULT_NEW_MACHINE_FILE_SUFFIX = ".machine.ts";
|
|
1156
|
+
const ANSI_RESET = "\x1B[0m";
|
|
1157
|
+
const ANSI_BOLD = "\x1B[1m";
|
|
1158
|
+
const ANSI_DIM = "\x1B[2m";
|
|
1159
|
+
const ANSI_CYAN = "\x1B[36m";
|
|
1160
|
+
const ANSI_GREEN = "\x1B[32m";
|
|
1161
|
+
const ANSI_YELLOW = "\x1B[33m";
|
|
1165
1162
|
function loadLocalEnv() {
|
|
1166
1163
|
if (typeof process.loadEnvFile !== "function") return;
|
|
1167
1164
|
const cwdEnvPath = path.join(process.cwd(), ".env.local");
|
|
@@ -1206,7 +1203,7 @@ function getDefaultBaseUrl() {
|
|
|
1206
1203
|
return process.env.STATELY_API_URL ?? process.env.NEXT_PUBLIC_BASE_URL ?? process.env.NEXT_PUBLIC_STATELY_API_URL;
|
|
1207
1204
|
}
|
|
1208
1205
|
function getDefaultEditorUrl() {
|
|
1209
|
-
return process.env.STATELY_EDITOR_URL ?? process.env.NEXT_PUBLIC_BETA_EDITOR_URL ?? process.env.NEXT_PUBLIC_BASE_URL ?? "https://
|
|
1206
|
+
return process.env.STATELY_EDITOR_URL ?? process.env.NEXT_PUBLIC_BETA_EDITOR_URL ?? process.env.NEXT_PUBLIC_BASE_URL ?? "https://editor.stately.ai";
|
|
1210
1207
|
}
|
|
1211
1208
|
function getResolvedStudioUrl(baseUrl) {
|
|
1212
1209
|
return baseUrl ?? getDefaultBaseUrl() ?? "https://stately.ai";
|
|
@@ -1315,8 +1312,42 @@ function normalizeApiKey(value) {
|
|
|
1315
1312
|
function pluralize(count, singular, plural = `${singular}s`) {
|
|
1316
1313
|
return count === 1 ? singular : plural;
|
|
1317
1314
|
}
|
|
1315
|
+
function supportsColor() {
|
|
1316
|
+
return Boolean(process.stdout.isTTY) && process.env.NO_COLOR == null && process.env.CI !== "true";
|
|
1317
|
+
}
|
|
1318
|
+
function colorize(text, ...codes) {
|
|
1319
|
+
if (!supportsColor()) return text;
|
|
1320
|
+
return `${codes.join("")}${text}${ANSI_RESET}`;
|
|
1321
|
+
}
|
|
1322
|
+
function formatSectionLabel(label, tone = "info") {
|
|
1323
|
+
return colorize(label, ANSI_BOLD, tone === "success" ? ANSI_GREEN : tone === "warning" ? ANSI_YELLOW : ANSI_CYAN);
|
|
1324
|
+
}
|
|
1325
|
+
function formatSecondaryText(text) {
|
|
1326
|
+
return colorize(text, ANSI_DIM);
|
|
1327
|
+
}
|
|
1328
|
+
function inferSuggestedNewMachineDir(config) {
|
|
1329
|
+
const include = config.include[0];
|
|
1330
|
+
if (!include) return "src";
|
|
1331
|
+
const groupedRootMatch = include.match(/^(src|packages\/[^/]+\/src|apps\/[^/]+\/src)(?:\/|$)/);
|
|
1332
|
+
if (groupedRootMatch?.[1]) return groupedRootMatch[1];
|
|
1333
|
+
const globIndex = include.indexOf("**/");
|
|
1334
|
+
if (globIndex > 0) return include.slice(0, globIndex).replace(/\/$/, "") || "src";
|
|
1335
|
+
const wildcardIndex = include.indexOf("*");
|
|
1336
|
+
if (wildcardIndex > 0) return path.posix.dirname(include.slice(0, wildcardIndex)) || "src";
|
|
1337
|
+
return path.posix.dirname(include) === "." ? "src" : path.posix.dirname(include);
|
|
1338
|
+
}
|
|
1339
|
+
function formatMissingNewMachineDirMessage(options) {
|
|
1340
|
+
const suggestedDir = inferSuggestedNewMachineDir(options.config);
|
|
1341
|
+
const countLabel = pluralize(options.remoteMachineCount, "remote-only project machine");
|
|
1342
|
+
return [
|
|
1343
|
+
`Found ${options.remoteMachineCount} ${countLabel}, but statelyai.json does not set newMachinesDir, so they will be skipped.`,
|
|
1344
|
+
"To import new machines created in Studio, add this to statelyai.json:",
|
|
1345
|
+
` "newMachinesDir": "${suggestedDir}"`,
|
|
1346
|
+
"Then run `statelyai pull` again."
|
|
1347
|
+
].join("\n");
|
|
1348
|
+
}
|
|
1318
1349
|
function toMachineFileStem(machineName) {
|
|
1319
|
-
return machineName.trim().replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[^A-Za-z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase() || "machine";
|
|
1350
|
+
return (typeof machineName === "string" ? machineName : "").trim().replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[^A-Za-z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase() || "machine";
|
|
1320
1351
|
}
|
|
1321
1352
|
function getMissingApiKeyMessage() {
|
|
1322
1353
|
return `No API key configured. Use \`statelyai login\`, set \`STATELY_API_KEY\`, or pass \`--api-key\`.\nGet or create an API key at ${STATELY_API_KEY_SETTINGS_URL}`;
|
|
@@ -1418,23 +1449,34 @@ async function discoverLinkedPullTargets(files) {
|
|
|
1418
1449
|
return linkedTargets;
|
|
1419
1450
|
}
|
|
1420
1451
|
async function discoverRemoteProjectMachineTargets(options) {
|
|
1421
|
-
const newMachineDir = options.config.
|
|
1452
|
+
const newMachineDir = options.config.newMachinesDir?.trim();
|
|
1422
1453
|
if (!newMachineDir) return [];
|
|
1423
1454
|
const targets = [];
|
|
1455
|
+
const reservedRelativePaths = /* @__PURE__ */ new Set();
|
|
1424
1456
|
for (const machine of options.project.machines) {
|
|
1425
|
-
|
|
1457
|
+
const candidate = machine;
|
|
1458
|
+
const machineId = typeof candidate.machineId === "string" ? candidate.machineId : typeof candidate.id === "string" ? candidate.id : void 0;
|
|
1459
|
+
if (!machineId || options.linkedMachineIds.has(machineId)) continue;
|
|
1426
1460
|
const baseDirectory = path.join(options.rootDir, newMachineDir);
|
|
1427
|
-
|
|
1461
|
+
let machineName = typeof candidate.name === "string" && candidate.name.trim().length > 0 ? candidate.name : typeof candidate.key === "string" && candidate.key.trim().length > 0 ? candidate.key : void 0;
|
|
1462
|
+
if ((!machineName || machineName === machineId) && options.client?.machines?.get) try {
|
|
1463
|
+
const remoteMachine = await options.client.machines.get(machineId);
|
|
1464
|
+
const fetchedName = typeof remoteMachine?.name === "string" && remoteMachine.name.trim().length > 0 ? remoteMachine.name : void 0;
|
|
1465
|
+
if (fetchedName) machineName = fetchedName;
|
|
1466
|
+
} catch {}
|
|
1467
|
+
machineName ??= machineId;
|
|
1468
|
+
const stem = toMachineFileStem(machineName);
|
|
1428
1469
|
let candidateFileName = `${stem}${DEFAULT_NEW_MACHINE_FILE_SUFFIX}`;
|
|
1429
1470
|
let attempt = 2;
|
|
1430
1471
|
for (;;) {
|
|
1431
1472
|
const filePath = path.join(baseDirectory, candidateFileName);
|
|
1432
1473
|
const relativePath = path.relative(options.rootDir, filePath).replace(/\\/g, "/");
|
|
1433
|
-
if (!isTrackedByStatelyProjectConfig(options.config, relativePath)) throw new Error(`Generated path ${relativePath} for remote machine ${
|
|
1434
|
-
if (!await fileExists(filePath)) {
|
|
1474
|
+
if (!isTrackedByStatelyProjectConfig(options.config, relativePath)) throw new Error(`Generated path ${relativePath} for remote machine ${machineName} is not covered by include/exclude globs.`);
|
|
1475
|
+
if (!reservedRelativePaths.has(relativePath) && !await fileExists(filePath)) {
|
|
1476
|
+
reservedRelativePaths.add(relativePath);
|
|
1435
1477
|
targets.push({
|
|
1436
|
-
machineId
|
|
1437
|
-
machineName
|
|
1478
|
+
machineId,
|
|
1479
|
+
machineName,
|
|
1438
1480
|
filePath,
|
|
1439
1481
|
relativePath
|
|
1440
1482
|
});
|
|
@@ -1453,7 +1495,8 @@ async function initProject(options) {
|
|
|
1453
1495
|
const defaultXStateVersion = Math.max(5, options.defaultXStateVersion ?? 5);
|
|
1454
1496
|
const existingConfig = !options.force ? await readStatelyProjectConfig({
|
|
1455
1497
|
cwd,
|
|
1456
|
-
configPath: options.configPath
|
|
1498
|
+
configPath: options.configPath,
|
|
1499
|
+
rewriteIfNeeded: true
|
|
1457
1500
|
}).catch(() => void 0) : void 0;
|
|
1458
1501
|
const client = options.client ?? createStatelyClient({
|
|
1459
1502
|
apiKey: options.apiKey,
|
|
@@ -1521,9 +1564,10 @@ function supportsMachineDiscovery(file) {
|
|
|
1521
1564
|
return file.source.format === "xstate" || file.source.format === "auto";
|
|
1522
1565
|
}
|
|
1523
1566
|
async function resolveConfiguredProject(options) {
|
|
1524
|
-
const { config, configPath, rootDir } = await readStatelyProjectConfig({
|
|
1567
|
+
const { config, configPath, rootDir, rewriteStatus } = await readStatelyProjectConfig({
|
|
1525
1568
|
cwd: options.cwd,
|
|
1526
|
-
configPath: options.configPath
|
|
1569
|
+
configPath: options.configPath,
|
|
1570
|
+
rewriteIfNeeded: true
|
|
1527
1571
|
});
|
|
1528
1572
|
const studioUrl = options.baseUrl ?? config.studioUrl;
|
|
1529
1573
|
return {
|
|
@@ -1536,7 +1580,37 @@ async function resolveConfiguredProject(options) {
|
|
|
1536
1580
|
files: await discoverStatelySourceFiles({
|
|
1537
1581
|
cwd: rootDir,
|
|
1538
1582
|
config
|
|
1539
|
-
})
|
|
1583
|
+
}),
|
|
1584
|
+
rewriteStatus
|
|
1585
|
+
};
|
|
1586
|
+
}
|
|
1587
|
+
async function resolveConfiguredPullTargets(options) {
|
|
1588
|
+
const { client, files, config, configPath, rewriteStatus } = await resolveConfiguredProject(options);
|
|
1589
|
+
const linkedTargets = await discoverLinkedPullTargets(files);
|
|
1590
|
+
const linkedMachineIds = new Set(linkedTargets.map((linkedTarget) => linkedTarget.machineId));
|
|
1591
|
+
const project = await client.projects.get(config.projectId);
|
|
1592
|
+
const skipped = [];
|
|
1593
|
+
let remoteOnlyTargets = [];
|
|
1594
|
+
try {
|
|
1595
|
+
remoteOnlyTargets = await discoverRemoteProjectMachineTargets({
|
|
1596
|
+
rootDir: path.dirname(configPath),
|
|
1597
|
+
config,
|
|
1598
|
+
project,
|
|
1599
|
+
linkedMachineIds,
|
|
1600
|
+
client
|
|
1601
|
+
});
|
|
1602
|
+
} catch (error) {
|
|
1603
|
+
skipped.push(error instanceof Error ? error.message : String(error));
|
|
1604
|
+
}
|
|
1605
|
+
return {
|
|
1606
|
+
client,
|
|
1607
|
+
config,
|
|
1608
|
+
configPath,
|
|
1609
|
+
linkedTargets,
|
|
1610
|
+
project,
|
|
1611
|
+
remoteOnlyTargets,
|
|
1612
|
+
skipped,
|
|
1613
|
+
rewriteStatus
|
|
1540
1614
|
};
|
|
1541
1615
|
}
|
|
1542
1616
|
const sharedFlags = {
|
|
@@ -1654,37 +1728,33 @@ var PullCommand = class PullCommand extends ParsedSyncCommand {
|
|
|
1654
1728
|
const apiKey = (await resolveApiKey(flags["api-key"])).apiKey;
|
|
1655
1729
|
if (!args.source) {
|
|
1656
1730
|
if (!apiKey) this.error(getMissingApiKeyMessage());
|
|
1657
|
-
this.log("Resolving configured project and linked source files...");
|
|
1658
|
-
const {
|
|
1731
|
+
this.log(colorize("Resolving configured project and linked source files...", ANSI_CYAN));
|
|
1732
|
+
const { config, linkedTargets, project, remoteOnlyTargets, skipped, rewriteStatus } = await resolveConfiguredPullTargets({
|
|
1659
1733
|
apiKey,
|
|
1660
1734
|
baseUrl: flags["base-url"],
|
|
1661
1735
|
configPath: flags.config
|
|
1662
1736
|
});
|
|
1663
|
-
|
|
1664
|
-
const linkedMachineIds = new Set(linkedTargets.map((linkedTarget) => linkedTarget.machineId));
|
|
1665
|
-
const project = await client.projects.get(config.projectId);
|
|
1666
|
-
const skipped = [];
|
|
1667
|
-
let remoteOnlyTargets = [];
|
|
1668
|
-
try {
|
|
1669
|
-
remoteOnlyTargets = await discoverRemoteProjectMachineTargets({
|
|
1670
|
-
rootDir: path.dirname(configPath),
|
|
1671
|
-
config,
|
|
1672
|
-
project,
|
|
1673
|
-
linkedMachineIds
|
|
1674
|
-
});
|
|
1675
|
-
} catch (error) {
|
|
1676
|
-
skipped.push(error instanceof Error ? error.message : String(error));
|
|
1677
|
-
}
|
|
1737
|
+
if (rewriteStatus.reason === "multiple-legacy-sources") this.log("Legacy statelyai.json detected with multiple sources entries. It cannot be rewritten automatically without losing information, so please update it manually.");
|
|
1678
1738
|
if (linkedTargets.length === 0 && remoteOnlyTargets.length === 0) {
|
|
1679
|
-
if (project.machines.length > 0 && !config.
|
|
1680
|
-
this.log("
|
|
1739
|
+
if (project.machines.length > 0 && !config.newMachinesDir) {
|
|
1740
|
+
this.log(formatSectionLabel("Skipped:", "warning"));
|
|
1741
|
+
this.log(formatMissingNewMachineDirMessage({
|
|
1742
|
+
config,
|
|
1743
|
+
remoteMachineCount: project.machines.length
|
|
1744
|
+
}));
|
|
1681
1745
|
return;
|
|
1682
1746
|
}
|
|
1683
1747
|
this.log("No linked local machine files or remote-only project machines were discovered.");
|
|
1684
1748
|
return;
|
|
1685
1749
|
}
|
|
1686
|
-
if (project.machines.length > linkedTargets.length && !config.
|
|
1687
|
-
|
|
1750
|
+
if (project.machines.length > linkedTargets.length && !config.newMachinesDir) {
|
|
1751
|
+
this.log(formatSectionLabel("Skipped:", "warning"));
|
|
1752
|
+
this.log(formatMissingNewMachineDirMessage({
|
|
1753
|
+
config,
|
|
1754
|
+
remoteMachineCount: project.machines.length - linkedTargets.length
|
|
1755
|
+
}));
|
|
1756
|
+
}
|
|
1757
|
+
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));
|
|
1688
1758
|
const pulled = [];
|
|
1689
1759
|
const created = [];
|
|
1690
1760
|
for (const linkedTarget of linkedTargets) {
|
|
@@ -1693,7 +1763,7 @@ var PullCommand = class PullCommand extends ParsedSyncCommand {
|
|
|
1693
1763
|
skipped.push(`${linkedTarget.file.relativePath}: local git changes detected (pass --force to overwrite)`);
|
|
1694
1764
|
continue;
|
|
1695
1765
|
}
|
|
1696
|
-
this.log(`Pulling ${linkedTarget.file.relativePath}
|
|
1766
|
+
this.log(colorize(`Pulling ${linkedTarget.file.relativePath}...`, ANSI_CYAN));
|
|
1697
1767
|
try {
|
|
1698
1768
|
const result = await pullSync({
|
|
1699
1769
|
source: linkedTarget.machineId,
|
|
@@ -1701,13 +1771,13 @@ var PullCommand = class PullCommand extends ParsedSyncCommand {
|
|
|
1701
1771
|
apiKey,
|
|
1702
1772
|
baseUrl: flags["base-url"] ?? config.studioUrl
|
|
1703
1773
|
});
|
|
1704
|
-
pulled.push(`${linkedTarget.file.relativePath}: ${result.source.locator}`);
|
|
1774
|
+
pulled.push(`${linkedTarget.file.relativePath}: ${formatSecondaryText(result.source.locator)}`);
|
|
1705
1775
|
} catch (error) {
|
|
1706
1776
|
skipped.push(`${linkedTarget.file.relativePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1707
1777
|
}
|
|
1708
1778
|
}
|
|
1709
1779
|
for (const remoteTarget of remoteOnlyTargets) {
|
|
1710
|
-
this.log(`Pulling new remote machine ${remoteTarget.machineName} into ${remoteTarget.relativePath}
|
|
1780
|
+
this.log(colorize(`Pulling new remote machine ${remoteTarget.machineName} into ${remoteTarget.relativePath}...`, ANSI_CYAN));
|
|
1711
1781
|
try {
|
|
1712
1782
|
await fsPromises.mkdir(path.dirname(remoteTarget.filePath), { recursive: true });
|
|
1713
1783
|
const result = await pullSync({
|
|
@@ -1716,14 +1786,14 @@ var PullCommand = class PullCommand extends ParsedSyncCommand {
|
|
|
1716
1786
|
apiKey,
|
|
1717
1787
|
baseUrl: flags["base-url"] ?? config.studioUrl
|
|
1718
1788
|
});
|
|
1719
|
-
created.push(`${remoteTarget.relativePath}: ${result.source.locator}`);
|
|
1789
|
+
created.push(`${remoteTarget.relativePath}: ${formatSecondaryText(result.source.locator)}`);
|
|
1720
1790
|
} catch (error) {
|
|
1721
1791
|
skipped.push(`${remoteTarget.relativePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1722
1792
|
}
|
|
1723
1793
|
}
|
|
1724
|
-
if (pulled.length > 0) this.log(
|
|
1725
|
-
if (created.length > 0) this.log(
|
|
1726
|
-
if (skipped.length > 0) this.log(
|
|
1794
|
+
if (pulled.length > 0) this.log(`${formatSectionLabel("Pulled:", "success")}\n${pulled.join("\n")}`);
|
|
1795
|
+
if (created.length > 0) this.log(`${formatSectionLabel("Created:", "success")}\n${created.join("\n")}`);
|
|
1796
|
+
if (skipped.length > 0) this.log(`${formatSectionLabel("Skipped:", "warning")}\n${skipped.join("\n")}`);
|
|
1727
1797
|
return;
|
|
1728
1798
|
}
|
|
1729
1799
|
const localCandidate = path.resolve(process.cwd(), args.source);
|
|
@@ -1738,14 +1808,14 @@ var PullCommand = class PullCommand extends ParsedSyncCommand {
|
|
|
1738
1808
|
if (!target) this.error("Missing target path. Pass `statelyai pull <machine-id|url> <file>` or `statelyai pull <linked-file>`.");
|
|
1739
1809
|
if (!apiKey) this.error(getMissingApiKeyMessage());
|
|
1740
1810
|
if (!flags.force && await fileExists(target) && await isFileGitDirty(target)) this.error(`Refusing to overwrite locally modified file ${target}. Pass --force to overwrite it.`);
|
|
1741
|
-
this.log(`Pulling ${source} into ${target}
|
|
1811
|
+
this.log(colorize(`Pulling ${source} into ${target}...`, ANSI_CYAN));
|
|
1742
1812
|
const result = await pullSync({
|
|
1743
1813
|
source,
|
|
1744
1814
|
target,
|
|
1745
1815
|
apiKey,
|
|
1746
1816
|
baseUrl: flags["base-url"] ?? getDefaultBaseUrl()
|
|
1747
1817
|
});
|
|
1748
|
-
this.log(
|
|
1818
|
+
this.log(`${formatSectionLabel("Pulled:", "success")} ${formatSecondaryText(result.source.locator)} -> ${result.outputPath}\nTarget: ${result.target.kind} (${result.target.format})`);
|
|
1749
1819
|
}
|
|
1750
1820
|
};
|
|
1751
1821
|
var PushCommand = class PushCommand extends Command {
|
|
@@ -1770,22 +1840,27 @@ var PushCommand = class PushCommand extends Command {
|
|
|
1770
1840
|
const { args, flags } = await this.parse(PushCommand);
|
|
1771
1841
|
const resolvedApiKey = flags["dry-run"] ? { source: "missing" } : await resolveApiKey(flags["api-key"]);
|
|
1772
1842
|
if (!flags["dry-run"] && !resolvedApiKey.apiKey) this.error(getMissingApiKeyMessage());
|
|
1773
|
-
this.log("Resolving configured project and source files...");
|
|
1774
|
-
const { client, config, files } = flags["dry-run"] ? await (async () => {
|
|
1775
|
-
const { config, rootDir } = await readStatelyProjectConfig({
|
|
1843
|
+
this.log(colorize("Resolving configured project and source files...", ANSI_CYAN));
|
|
1844
|
+
const { client, config, files, rewriteStatus } = flags["dry-run"] ? await (async () => {
|
|
1845
|
+
const { config, rootDir, rewriteStatus } = await readStatelyProjectConfig({
|
|
1846
|
+
configPath: flags.config,
|
|
1847
|
+
rewriteIfNeeded: true
|
|
1848
|
+
});
|
|
1776
1849
|
return {
|
|
1777
1850
|
client: void 0,
|
|
1778
1851
|
config,
|
|
1779
1852
|
files: await discoverStatelySourceFiles({
|
|
1780
1853
|
cwd: rootDir,
|
|
1781
1854
|
config
|
|
1782
|
-
})
|
|
1855
|
+
}),
|
|
1856
|
+
rewriteStatus
|
|
1783
1857
|
};
|
|
1784
1858
|
})() : await resolveConfiguredProject({
|
|
1785
1859
|
apiKey: resolvedApiKey.apiKey,
|
|
1786
1860
|
baseUrl: flags["base-url"],
|
|
1787
1861
|
configPath: flags.config
|
|
1788
1862
|
});
|
|
1863
|
+
if (rewriteStatus.reason === "multiple-legacy-sources") this.log("Legacy statelyai.json detected with multiple sources entries. It cannot be rewritten automatically without losing information, so please update it manually.");
|
|
1789
1864
|
const candidateFiles = args.file ? [{
|
|
1790
1865
|
filePath: path.resolve(args.file),
|
|
1791
1866
|
relativePath: path.relative(process.cwd(), path.resolve(args.file)),
|
|
@@ -1797,33 +1872,33 @@ var PushCommand = class PushCommand extends Command {
|
|
|
1797
1872
|
}
|
|
1798
1873
|
}] : files.filter(supportsMachineDiscovery);
|
|
1799
1874
|
if (candidateFiles.length === 0) {
|
|
1800
|
-
this.log("No matching local machine source files were discovered.");
|
|
1875
|
+
this.log(colorize("No matching local machine source files were discovered.", ANSI_YELLOW));
|
|
1801
1876
|
return;
|
|
1802
1877
|
}
|
|
1803
1878
|
const { machineFiles } = await classifyPushCandidates(candidateFiles);
|
|
1804
1879
|
if (machineFiles.length === 0) {
|
|
1805
|
-
this.log(`Matched ${candidateFiles.length} ${pluralize(candidateFiles.length, "file")}, but no local machine sources were discovered
|
|
1880
|
+
this.log(colorize(`Matched ${candidateFiles.length} ${pluralize(candidateFiles.length, "file")}, but no local machine sources were discovered.`, ANSI_YELLOW));
|
|
1806
1881
|
return;
|
|
1807
1882
|
}
|
|
1808
|
-
this.log(`Discovered ${machineFiles.length} ${pluralize(machineFiles.length, "file with a machine")} from ${candidateFiles.length} matched ${pluralize(candidateFiles.length, "file")}
|
|
1883
|
+
this.log(colorize(`Discovered ${machineFiles.length} ${pluralize(machineFiles.length, "file with a machine")} from ${candidateFiles.length} matched ${pluralize(candidateFiles.length, "file")}.`, ANSI_CYAN));
|
|
1809
1884
|
if (flags["dry-run"]) {
|
|
1810
1885
|
const wouldLink = [];
|
|
1811
1886
|
const wouldUpdate = [];
|
|
1812
1887
|
for (const file of machineFiles) {
|
|
1813
1888
|
const pragma = getStatelyPragma(await fsPromises.readFile(file.filePath, "utf8"), file.filePath);
|
|
1814
|
-
if (pragma?.id) wouldUpdate.push(`${file.relativePath}: ${pragma.id}`);
|
|
1889
|
+
if (pragma?.id) wouldUpdate.push(`${file.relativePath}: ${formatSecondaryText(pragma.id)}`);
|
|
1815
1890
|
else wouldLink.push(file.relativePath);
|
|
1816
1891
|
}
|
|
1817
|
-
if (wouldLink.length > 0) this.log(
|
|
1818
|
-
if (wouldUpdate.length > 0) this.log(
|
|
1892
|
+
if (wouldLink.length > 0) this.log(`${formatSectionLabel("Would link:")}\n${wouldLink.join("\n")}`);
|
|
1893
|
+
if (wouldUpdate.length > 0) this.log(`${formatSectionLabel("Would update:")}\n${wouldUpdate.join("\n")}`);
|
|
1819
1894
|
return;
|
|
1820
1895
|
}
|
|
1821
|
-
this.log(`Processing ${machineFiles.length} ${pluralize(machineFiles.length, "source file")}
|
|
1896
|
+
this.log(colorize(`Processing ${machineFiles.length} ${pluralize(machineFiles.length, "source file")}...`, ANSI_CYAN));
|
|
1822
1897
|
const linked = [];
|
|
1823
1898
|
const refreshed = [];
|
|
1824
1899
|
const skipped = [];
|
|
1825
1900
|
for (const file of machineFiles) {
|
|
1826
|
-
this.log(`Pushing ${file.relativePath}
|
|
1901
|
+
this.log(colorize(`Pushing ${file.relativePath}...`, ANSI_CYAN));
|
|
1827
1902
|
if (!supportsMachineDiscovery(file)) {
|
|
1828
1903
|
skipped.push(`${file.relativePath}: unsupported format ${file.source.format}`);
|
|
1829
1904
|
continue;
|
|
@@ -1848,7 +1923,7 @@ var PushCommand = class PushCommand extends Command {
|
|
|
1848
1923
|
skipped.push(`${file.relativePath}: linked remote machine is missing or inaccessible.`);
|
|
1849
1924
|
continue;
|
|
1850
1925
|
}
|
|
1851
|
-
this.log(`Relinking ${file.relativePath} as a new remote machine
|
|
1926
|
+
this.log(colorize(`Relinking ${file.relativePath} as a new remote machine...`, ANSI_YELLOW));
|
|
1852
1927
|
result = await pushLocalMachineLinks({
|
|
1853
1928
|
source: file.filePath,
|
|
1854
1929
|
apiKey: resolvedApiKey.apiKey,
|
|
@@ -1860,13 +1935,13 @@ var PushCommand = class PushCommand extends Command {
|
|
|
1860
1935
|
});
|
|
1861
1936
|
} else throw error;
|
|
1862
1937
|
}
|
|
1863
|
-
if (result.created.length > 0) linked.push(`${file.relativePath}: ${result.created.map(({ machineIndex, machine }) => `${machine.id} [${machineIndex}] ${buildMachineEditorUrl(config.studioUrl, config.projectId, machine.id)}`).join(", ")}`);
|
|
1864
|
-
if (result.updated.length > 0) refreshed.push(`${file.relativePath}: ${result.updated.map(({ machineIndex, machine }) => `${machine.id} [${machineIndex}] ${buildMachineEditorUrl(config.studioUrl, config.projectId, machine.id)}`).join(", ")}`);
|
|
1938
|
+
if (result.created.length > 0) linked.push(`${file.relativePath}: ${result.created.map(({ machineIndex, machine }) => `${formatSecondaryText(`${machine.id} [${machineIndex}]`)} ${formatSecondaryText(buildMachineEditorUrl(config.studioUrl, config.projectId, machine.id))}`).join(", ")}`);
|
|
1939
|
+
if (result.updated.length > 0) refreshed.push(`${file.relativePath}: ${result.updated.map(({ machineIndex, machine }) => `${formatSecondaryText(`${machine.id} [${machineIndex}]`)} ${formatSecondaryText(buildMachineEditorUrl(config.studioUrl, config.projectId, machine.id))}`).join(", ")}`);
|
|
1865
1940
|
for (const entry of result.skipped) skipped.push(`${file.relativePath} [${entry.machineIndex}]: ${entry.reason}`);
|
|
1866
1941
|
}
|
|
1867
|
-
if (linked.length > 0) this.log(
|
|
1868
|
-
if (refreshed.length > 0) this.log(
|
|
1869
|
-
if (skipped.length > 0) this.log(
|
|
1942
|
+
if (linked.length > 0) this.log(`${formatSectionLabel("Linked:", "success")}\n${linked.join("\n")}`);
|
|
1943
|
+
if (refreshed.length > 0) this.log(`${formatSectionLabel("Updated:", "success")}\n${refreshed.join("\n")}`);
|
|
1944
|
+
if (skipped.length > 0) this.log(`${formatSectionLabel("Skipped:", "warning")}\n${skipped.join("\n")}`);
|
|
1870
1945
|
}
|
|
1871
1946
|
};
|
|
1872
1947
|
var OpenCommand = class OpenCommand extends Command {
|
|
@@ -1975,7 +2050,7 @@ var InitCommand = class InitCommand extends Command {
|
|
|
1975
2050
|
...result.config,
|
|
1976
2051
|
include: suggestions.flatMap((suggestion) => suggestion.include),
|
|
1977
2052
|
exclude: [...new Set(suggestions.flatMap((suggestion) => suggestion.exclude ?? []))],
|
|
1978
|
-
...inferredNewMachineDir ? {
|
|
2053
|
+
...inferredNewMachineDir ? { newMachinesDir: inferredNewMachineDir } : {}
|
|
1979
2054
|
};
|
|
1980
2055
|
await fsPromises.writeFile(result.configPath, `${JSON.stringify(nextConfig, null, 2)}\n`, "utf8");
|
|
1981
2056
|
this.log(inferredNewMachineDir ? `Saved scanned source globs to statelyai.json.\nNew remote machines will be created under ${inferredNewMachineDir}/ by default.` : "Saved scanned source globs to statelyai.json.");
|
|
@@ -2074,4 +2149,4 @@ function isDirectExecution() {
|
|
|
2074
2149
|
if (isDirectExecution()) run$1();
|
|
2075
2150
|
|
|
2076
2151
|
//#endregion
|
|
2077
|
-
export {
|
|
2152
|
+
export { formatMissingNewMachineDirMessage as a, inferInitProjectName as c, resolveApiKey as d, resolveConfiguredPullTargets as f, createStatelyProjectConfig as h, discoverRemoteProjectMachineTargets as i, initProject as l, scanProjectSources as m, classifyPushCandidates as n, formatPlanSummary as o, run$1 as p, discoverLinkedPullTargets as r, getEnvApiKey as s, COMMANDS as t, isFileGitDirty as u };
|
package/dist/index.d.mts
CHANGED
|
@@ -18,7 +18,7 @@ interface StatelyProjectConfig {
|
|
|
18
18
|
defaultXStateVersion: number;
|
|
19
19
|
include: string[];
|
|
20
20
|
exclude?: string[];
|
|
21
|
-
|
|
21
|
+
newMachinesDir?: string;
|
|
22
22
|
}
|
|
23
23
|
interface DiscoveredSourceFile {
|
|
24
24
|
filePath: string;
|
|
@@ -66,6 +66,19 @@ interface PushCandidateClassification {
|
|
|
66
66
|
machineFiles: DiscoveredSourceFile[];
|
|
67
67
|
nonMachineFiles: DiscoveredSourceFile[];
|
|
68
68
|
}
|
|
69
|
+
interface ResolvedConfiguredPullTargets {
|
|
70
|
+
client: StudioClient;
|
|
71
|
+
config: StatelyProjectConfig;
|
|
72
|
+
configPath: string;
|
|
73
|
+
linkedTargets: LinkedPullTarget[];
|
|
74
|
+
project: ProjectData;
|
|
75
|
+
remoteOnlyTargets: RemoteProjectMachineTarget[];
|
|
76
|
+
skipped: string[];
|
|
77
|
+
rewriteStatus: {
|
|
78
|
+
needsRewrite: boolean;
|
|
79
|
+
reason?: string;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
69
82
|
type ApiKeyResolution = {
|
|
70
83
|
apiKey: string;
|
|
71
84
|
detail: string;
|
|
@@ -81,6 +94,10 @@ declare function getEnvApiKey(): {
|
|
|
81
94
|
} | undefined;
|
|
82
95
|
declare function resolveApiKey(explicitApiKey?: string): Promise<ApiKeyResolution>;
|
|
83
96
|
declare function inferInitProjectName(cwd: string, repo?: ConnectedRepo): string;
|
|
97
|
+
declare function formatMissingNewMachineDirMessage(options: {
|
|
98
|
+
config: Pick<StatelyProjectConfig, 'include' | 'newMachinesDir'>;
|
|
99
|
+
remoteMachineCount: number;
|
|
100
|
+
}): string;
|
|
84
101
|
declare function isFileGitDirty(filePath: string): Promise<boolean>;
|
|
85
102
|
declare function discoverLinkedPullTargets(files: DiscoveredSourceFile[]): Promise<LinkedPullTarget[]>;
|
|
86
103
|
declare function discoverRemoteProjectMachineTargets(options: {
|
|
@@ -88,10 +105,18 @@ declare function discoverRemoteProjectMachineTargets(options: {
|
|
|
88
105
|
config: StatelyProjectConfig;
|
|
89
106
|
project: ProjectData;
|
|
90
107
|
linkedMachineIds: Set<string>;
|
|
108
|
+
client?: Pick<StudioClient, 'machines'>;
|
|
91
109
|
}): Promise<RemoteProjectMachineTarget[]>;
|
|
92
110
|
declare function initProject(options: InitProjectOptions): Promise<InitProjectResult>;
|
|
93
111
|
declare function scanProjectSources(options: ScanProjectSourcesOptions): Promise<Array<Pick<StatelyProjectConfig, 'include' | 'exclude'>>>;
|
|
94
112
|
declare function classifyPushCandidates(files: DiscoveredSourceFile[]): Promise<PushCandidateClassification>;
|
|
113
|
+
declare function resolveConfiguredPullTargets(options: {
|
|
114
|
+
cwd?: string;
|
|
115
|
+
configPath?: string;
|
|
116
|
+
apiKey: string;
|
|
117
|
+
baseUrl?: string;
|
|
118
|
+
client?: StudioClient;
|
|
119
|
+
}): Promise<ResolvedConfiguredPullTargets>;
|
|
95
120
|
declare function formatPlanSummary(plan: SyncPlan): string;
|
|
96
121
|
declare abstract class BaseSyncCommand extends Command {
|
|
97
122
|
static enableJsonFlag: boolean;
|
|
@@ -240,4 +265,4 @@ declare const COMMANDS: {
|
|
|
240
265
|
};
|
|
241
266
|
declare function run(argv?: any, entryUrl?: string): Promise<void>;
|
|
242
267
|
//#endregion
|
|
243
|
-
export { ApiKeyResolution, COMMANDS, InitProjectOptions, InitProjectResult, LinkedPullTarget, PushCandidateClassification, RemoteProjectMachineTarget, ScanProjectSourcesOptions, classifyPushCandidates, createStatelyProjectConfig, discoverLinkedPullTargets, discoverRemoteProjectMachineTargets, formatPlanSummary, getEnvApiKey, inferInitProjectName, initProject, isFileGitDirty, resolveApiKey, run, scanProjectSources };
|
|
268
|
+
export { ApiKeyResolution, COMMANDS, InitProjectOptions, InitProjectResult, LinkedPullTarget, PushCandidateClassification, RemoteProjectMachineTarget, ResolvedConfiguredPullTargets, ScanProjectSourcesOptions, classifyPushCandidates, createStatelyProjectConfig, discoverLinkedPullTargets, discoverRemoteProjectMachineTargets, formatMissingNewMachineDirMessage, formatPlanSummary, getEnvApiKey, inferInitProjectName, initProject, isFileGitDirty, resolveApiKey, resolveConfiguredPullTargets, run, scanProjectSources };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as formatMissingNewMachineDirMessage, c as inferInitProjectName, d as resolveApiKey, f as resolveConfiguredPullTargets, h as createStatelyProjectConfig, i as discoverRemoteProjectMachineTargets, l as initProject, m as scanProjectSources, n as classifyPushCandidates, o as formatPlanSummary, p as run, r as discoverLinkedPullTargets, s as getEnvApiKey, t as COMMANDS, u as isFileGitDirty } from "./cli-DB0A-O4Y.mjs";
|
|
2
2
|
|
|
3
|
-
export { COMMANDS, classifyPushCandidates, createStatelyProjectConfig, discoverLinkedPullTargets, discoverRemoteProjectMachineTargets, formatPlanSummary, getEnvApiKey, inferInitProjectName, initProject, isFileGitDirty, resolveApiKey, run, scanProjectSources };
|
|
3
|
+
export { COMMANDS, classifyPushCandidates, createStatelyProjectConfig, discoverLinkedPullTargets, discoverRemoteProjectMachineTargets, formatMissingNewMachineDirMessage, formatPlanSummary, getEnvApiKey, inferInitProjectName, initProject, isFileGitDirty, resolveApiKey, resolveConfiguredPullTargets, run, scanProjectSources };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "statelyai",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "Command-line tools for Stately",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@oclif/core": "^4.10.3",
|
|
24
|
-
"@statelyai/sdk": "0.10.
|
|
24
|
+
"@statelyai/sdk": "0.10.1"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"tsdown": "0.21.0-beta.2",
|