statelyai 0.8.5 → 0.8.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -263,7 +263,10 @@ statelyai open src/checkout.machine.ts
263
263
  ```
264
264
 
265
265
  Saved file changes refresh the editor. Saving visual edits writes them back to
266
- the source file.
266
+ the source file. Editor sync sends the opened file, its reachable relative
267
+ imports, and ancestor package manifests; unrelated sibling files are excluded.
268
+ The CLI verifies the visual editor protocol before sending source data and
269
+ versions remote Editor Sync requests automatically.
267
270
 
268
271
  Flags:
269
272
 
@@ -272,7 +275,7 @@ Flags:
272
275
  - `--host <host>` sets the local bridge host. Default: `127.0.0.1`.
273
276
  - `--port <port>` selects a port. Default: a random available port.
274
277
  - `--no-open` starts the bridge without launching a browser.
275
- - `--debug` logs editor protocol messages.
278
+ - `--debug` logs editor protocol messages with credentials redacted.
276
279
 
277
280
  ### `diff`
278
281
 
package/dist/bin.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { S as run } from "./cli-Dx1dw7Cy.mjs";
2
+ import { S as run } from "./cli-CTUGfkL5.mjs";
3
3
 
4
4
  //#region src/bin.ts
5
5
  run();
@@ -10,11 +10,16 @@ import { fileURLToPath, pathToFileURL } from "node:url";
10
10
  import { promisify } from "node:util";
11
11
  import { Args, Command, Flags, flush, handle, run } from "@oclif/core";
12
12
  import * as http from "node:http";
13
+ import * as ts from "typescript";
14
+ import { EditorHostSession, StudioApiError, buildAuthorizeUrl, createPkcePair, createRemoteEditorSyncBackend, createStatelyClient, discoverAuthorizationServer, discoverProtectedResource, exchangeCodeForToken, findStatelyPragmaAttachments, getStatelyPragma, refreshToken, registerOAuthClient } from "@statelyai/sdk";
13
15
  import { WebSocket, WebSocketServer } from "ws";
14
16
  import os from "node:os";
15
- import { StudioApiError, buildAuthorizeUrl, createPkcePair, createStatelyClient, discoverAuthorizationServer, discoverProtectedResource, exchangeCodeForToken, findStatelyPragmaAttachments, getStatelyPragma, refreshToken, registerOAuthClient } from "@statelyai/sdk";
16
17
  import { planSync, pullSync, pushLocalMachineLinks } from "@statelyai/sdk/sync";
17
18
 
19
+ //#region src/version.ts
20
+ const CLI_VERSION = "0.8.8";
21
+
22
+ //#endregion
18
23
  //#region src/cliHost.ts
19
24
  const DEFAULT_SYNC_MAX_FILES = 150;
20
25
  const DEFAULT_SYNC_MAX_BYTES = 2e6;
@@ -51,289 +56,58 @@ function rawDataToBuffer(data) {
51
56
  return Buffer.from(data);
52
57
  }
53
58
  var RemoteEditorSession = class {
54
- currentGraph;
55
- lastPersistedGraph;
56
- currentSourceLocations;
57
- currentFormat;
58
- editorSyncAccess;
59
- ready = false;
60
- pendingMessages = [];
61
- pendingRetrievals = /* @__PURE__ */ new Map();
62
- retrieveRequestCount = 0;
63
- watchedSourceUris = /* @__PURE__ */ new Set();
64
- selfEditCount = 0;
65
- watcher;
59
+ session;
66
60
  constructor(options, sendMessage) {
67
61
  this.options = options;
68
- this.sendMessage = sendMessage;
69
- this.watcher = watchWorkspace(this.options.rootDir, (uri) => {
70
- this.handleSavedDocument(uri);
71
- });
72
- }
73
- dispose() {
74
- for (const pending of this.pendingRetrievals.values()) pending.reject(/* @__PURE__ */ new Error("Editor session disposed before export completed."));
75
- this.pendingRetrievals.clear();
76
- this.watcher?.dispose();
77
- }
78
- async receiveMessage(msg) {
79
- this.log("recv", msg.type, msg);
80
- switch (msg.type) {
81
- case "@statelyai.ready":
82
- await this.initializeEditor();
83
- break;
84
- case "@statelyai.loaded":
85
- this.currentGraph = msg.graph;
86
- this.lastPersistedGraph = msg.graph;
87
- this.currentSourceLocations = msg.sourceLocations ?? this.currentSourceLocations;
88
- this.updateSourceLocations(this.currentSourceLocations);
89
- break;
90
- case "@statelyai.change":
91
- this.currentGraph = msg.graph;
92
- this.currentSourceLocations = msg.sourceLocations ?? this.currentSourceLocations;
93
- this.updateSourceLocations(this.currentSourceLocations);
94
- break;
95
- case "@statelyai.save":
96
- await this.saveFromEditor(msg);
97
- break;
98
- case "@statelyai.retrieved":
99
- this.resolveRetrievedSource(msg);
100
- break;
101
- case "@statelyai.clipboardRead":
102
- this.postMessage({
103
- type: "@statelyai.clipboardReadResponse",
104
- requestId: msg.requestId,
105
- text: ""
106
- });
107
- break;
108
- case "@statelyai.error":
109
- this.handleErrorMessage(msg);
110
- break;
111
- }
112
- }
113
- async initializeEditor() {
114
- this.ready = true;
115
- try {
116
- const update = await this.parseRootDocument();
117
- this.currentFormat = update.format;
118
- this.currentSourceLocations = update.sourceLocations;
119
- this.editorSyncAccess = update.access;
120
- this.updateSourceLocations(update.sourceLocations);
121
- if (this.options.apiKey) this.sendMessage({
122
- type: "@statelyai.setApiKey",
123
- apiKey: this.options.apiKey
124
- });
125
- this.postMessage({
126
- type: "@statelyai.init",
127
- machine: update.machine,
128
- format: update.format,
129
- sourceLocations: update.sourceLocations,
130
- mode: update.access?.readOnly ? "viewing" : "editing",
131
- readOnly: update.access?.readOnly,
132
- capabilities: update.access?.capabilities,
133
- theme: "light",
134
- unsavedIndicator: { enabled: true },
135
- leftPanels: [],
136
- rightPanels: [],
137
- activePanels: []
138
- });
139
- } catch (error) {
140
- const message = formatError(error, "Failed to initialize the visual editor.");
141
- this.postMessage({
142
- type: "@statelyai.error",
143
- code: "initialization_failed",
144
- message
145
- });
146
- this.showError(message);
147
- return;
148
- }
149
- for (const pending of this.pendingMessages) this.sendMessage(pending);
150
- this.pendingMessages = [];
151
- }
152
- async handleSavedDocument(uri) {
153
- if (uri !== this.options.rootUri && !this.watchedSourceUris.has(uri)) return;
154
- if (this.selfEditCount > 0) return;
155
- try {
156
- const update = await this.parseRootDocument();
157
- this.currentFormat = update.format;
158
- this.currentSourceLocations = update.sourceLocations;
159
- this.editorSyncAccess = update.access ?? this.editorSyncAccess;
160
- this.updateSourceLocations(update.sourceLocations);
161
- this.postMessage({
162
- type: "@statelyai.update",
163
- machine: update.machine,
164
- format: update.format,
165
- sourceLocations: update.sourceLocations
166
- });
167
- } catch (error) {
168
- this.showError(formatError(error, "Failed to read the saved document."));
169
- }
170
- }
171
- async saveFromEditor(msg) {
172
- if (this.editorSyncAccess?.readOnly) {
173
- const message = "Your Stately plan allows read-only editor sync.";
174
- this.postMessage({
175
- type: "@statelyai.toast",
176
- message,
177
- toastType: "error"
178
- });
179
- this.showError(message);
180
- return;
181
- }
182
- const validationErrors = getValidationErrors(msg.validations);
183
- if (validationErrors.length > 0) {
184
- const message = formatValidationErrorMessage(validationErrors);
185
- this.postMessage({
186
- type: "@statelyai.toast",
187
- message,
188
- toastType: "error"
189
- });
190
- this.showError(message);
191
- return;
192
- }
193
- this.currentSourceLocations = msg.sourceLocations ?? this.currentSourceLocations;
194
- this.updateSourceLocations(this.currentSourceLocations);
195
- try {
196
- const serialized = await this.getSerializedPayloadForCurrentFormat();
197
- const documents = await collectSourceDocuments({
198
- rootFileName: this.options.fileName,
199
- rootDir: this.options.rootDir,
200
- extraUris: sourceLocationUris(this.currentSourceLocations)
201
- });
202
- const response = await this.postSync("/api/editor-sync/apply", {
203
- rootUri: this.options.rootUri,
204
- rootFileName: this.options.fileName,
205
- rootDir: this.options.rootDir,
206
- documents,
207
- machineConfig: msg.machineConfig,
208
- patches: msg.patches,
209
- prevGraph: this.lastPersistedGraph ?? this.currentGraph,
210
- nextGraph: msg.graph,
211
- sourceLocations: this.currentSourceLocations,
212
- serialized
213
- });
214
- if (response.replacements.length === 0) {
215
- const message = "Unable to apply Viz changes to the source file automatically.";
216
- this.postMessage({
217
- type: "@statelyai.toast",
218
- message,
219
- toastType: "error"
220
- });
221
- this.showError(message);
222
- return;
223
- }
224
- await this.runWithSelfEdit(async () => {
225
- await applyFileReplacements(response.replacements, this.options.rootUri);
226
- });
227
- this.currentGraph = msg.graph;
228
- this.lastPersistedGraph = msg.graph;
229
- } catch (error) {
230
- const message = formatError(error, "Failed to apply Viz changes.");
231
- this.postMessage({
232
- type: "@statelyai.toast",
233
- message,
234
- toastType: "error"
235
- });
236
- this.showError(message);
237
- }
238
- }
239
- async parseRootDocument() {
240
- const documents = await collectSourceDocuments({
241
- rootFileName: this.options.fileName,
242
- rootDir: this.options.rootDir,
243
- extraUris: sourceLocationUris(this.currentSourceLocations)
244
- });
245
- return this.postSync("/api/editor-sync/parse", {
246
- rootUri: this.options.rootUri,
247
- rootFileName: this.options.fileName,
248
- rootDir: this.options.rootDir,
249
- documents
250
- });
251
- }
252
- async postSync(pathname, body) {
253
- const url = new URL(pathname, normalizedBaseUrl(this.options.editorUrl));
254
- const headers = { "Content-Type": "application/json" };
255
- if (this.options.apiKey) headers.Authorization = `Bearer ${this.options.apiKey}`;
256
- const response = await fetchEditorHost(url, {
257
- method: "POST",
258
- headers,
259
- body: JSON.stringify(body)
260
- });
261
- const data = await response.json().catch(() => null);
262
- if (!response.ok) {
263
- const message = data && typeof data === "object" && "error" in data && typeof data.error === "string" ? data.error : `HTTP ${response.status}`;
264
- throw new Error(message);
265
- }
266
- return data;
267
- }
268
- async getSerializedPayloadForCurrentFormat() {
269
- const format = this.currentFormat;
270
- if (!format || format === "xstate") return;
271
- try {
272
- const serialized = await this.requestSerialized(format);
273
- return { [format]: serialized };
274
- } catch {
275
- return;
276
- }
277
- }
278
- requestSerialized(format) {
279
- const requestId = `retrieve-${++this.retrieveRequestCount}`;
280
- return new Promise((resolve, reject) => {
281
- this.pendingRetrievals.set(requestId, {
282
- resolve,
283
- reject
284
- });
285
- this.postMessage({
286
- type: "@statelyai.retrieve",
287
- requestId,
288
- format
289
- });
62
+ const send = (message) => {
63
+ this.log("send", message.type, message);
64
+ sendMessage(message);
65
+ };
66
+ this.session = new EditorHostSession({
67
+ source: {
68
+ rootUri: options.rootUri,
69
+ rootFileName: options.fileName,
70
+ rootDir: options.rootDir,
71
+ collectDocuments: (extraUris) => collectSourceDocuments({
72
+ rootFileName: options.fileName,
73
+ extraUris: [...extraUris ?? []]
74
+ }),
75
+ applyReplacements: async (replacements, rootUri) => {
76
+ await applyFileReplacements(replacements, rootUri);
77
+ return [...new Set(replacements.map((replacement) => replacement.uri ?? rootUri))];
78
+ },
79
+ watchSavedDocuments: (listener) => watchWorkspace(options.rootDir, listener)
80
+ },
81
+ sync: createRemoteEditorSyncBackend({
82
+ editorUrl: options.editorUrl,
83
+ apiKey: options.apiKey,
84
+ fetch: (input, init) => fetchEditorHost(input instanceof URL ? input : new URL(String(input)), init)
85
+ }),
86
+ send,
87
+ apiKey: options.apiKey,
88
+ client: {
89
+ name: "statelyai",
90
+ version: CLI_VERSION
91
+ },
92
+ showError: (message) => console.error(`Stately Editor: ${message}`)
290
93
  });
291
94
  }
292
- resolveRetrievedSource(msg) {
293
- const pending = this.pendingRetrievals.get(msg.requestId);
294
- if (!pending) return;
295
- this.pendingRetrievals.delete(msg.requestId);
296
- const serialized = typeof msg.data === "string" ? msg.data : JSON.stringify(msg.data, null, 2);
297
- pending.resolve(serialized);
298
- }
299
- handleErrorMessage(msg) {
300
- if (msg.requestId) {
301
- const pending = this.pendingRetrievals.get(msg.requestId);
302
- if (pending) {
303
- this.pendingRetrievals.delete(msg.requestId);
304
- pending.reject(new Error(msg.message));
305
- return;
306
- }
307
- }
308
- this.showError(msg.message);
309
- }
310
- updateSourceLocations(sourceLocations) {
311
- this.watchedSourceUris.clear();
312
- for (const location of sourceLocations?.states ?? []) if (location.uri !== this.options.rootUri) this.watchedSourceUris.add(location.uri);
313
- }
314
- async runWithSelfEdit(operation) {
315
- this.selfEditCount++;
316
- try {
317
- return await operation();
318
- } finally {
319
- this.selfEditCount--;
320
- }
321
- }
322
- postMessage(msg) {
323
- this.log("send", msg.type, msg);
324
- if (!this.ready) {
325
- this.pendingMessages.push(msg);
326
- return;
327
- }
328
- this.sendMessage(msg);
95
+ receiveMessage(message) {
96
+ this.log("recv", message.type, message);
97
+ return this.session.receive(message);
329
98
  }
330
- showError(message) {
331
- console.error(`Stately Editor: ${message}`);
99
+ dispose() {
100
+ this.session.dispose();
332
101
  }
333
102
  log(direction, type, payload) {
334
- if (this.options.debug) console.error(`[${direction}] ${type}`, payload ?? "");
103
+ if (this.options.debug) console.error(`[${direction}] ${type}`, redactDebugPayload(payload) ?? "");
335
104
  }
336
105
  };
106
+ function redactDebugPayload(payload) {
107
+ if (Array.isArray(payload)) return payload.map(redactDebugPayload);
108
+ if (!payload || typeof payload !== "object") return payload;
109
+ return Object.fromEntries(Object.entries(payload).map(([key, value]) => [key, /^(?:apiKey|accessToken|refreshToken|token|authorization)$/i.test(key) ? "[REDACTED]" : redactDebugPayload(value)]));
110
+ }
337
111
  async function openEditor(options) {
338
112
  const fileName = path$1.resolve(options.fileName);
339
113
  await fsPromises.access(fileName);
@@ -395,50 +169,88 @@ async function openEditor(options) {
395
169
  });
396
170
  }
397
171
  async function collectSourceDocuments(options) {
398
- const files = new Set([options.rootFileName]);
399
172
  const maxFiles = Number.parseInt(process.env.STATELY_SYNC_MAX_FILES ?? "", 10) || DEFAULT_SYNC_MAX_FILES;
400
173
  const maxBytes = Number.parseInt(process.env.STATELY_SYNC_MAX_BYTES ?? "", 10) || DEFAULT_SYNC_MAX_BYTES;
401
- for (const uri of options.extraUris ?? []) files.add(sourceUriToFileName(uri));
402
- await collectDirectoryFiles(options.rootDir, files, maxFiles);
403
- const documents = [];
174
+ const documents = /* @__PURE__ */ new Map();
175
+ const queue = [];
404
176
  let totalBytes = 0;
405
- for (const fileName of files) {
406
- if (!isSupportedDocument(fileName)) continue;
407
- const text = await fsPromises.readFile(fileName, "utf8").catch(() => null);
408
- if (text === null) continue;
409
- totalBytes += Buffer.byteLength(text);
410
- if (totalBytes > maxBytes) throw new Error(`Source payload exceeds ${maxBytes} bytes.`);
411
- documents.push({
412
- uri: fileNameToUri(fileName),
413
- fileName,
414
- text
415
- });
416
- }
417
- return documents;
418
- }
419
- async function collectDirectoryFiles(rootDir, files, maxFiles) {
420
- const queue = [rootDir];
421
- while (queue.length > 0 && files.size < maxFiles) {
422
- const dir = queue.shift();
423
- const entries = await fsPromises.readdir(dir, { withFileTypes: true }).catch(() => []);
424
- for (const entry of entries) {
425
- if (files.size >= maxFiles) break;
426
- if (entry.name.startsWith(".") || shouldSkipDirectory(entry.name)) continue;
427
- const fileName = path$1.join(dir, entry.name);
428
- if (entry.isDirectory()) queue.push(fileName);
429
- else if (entry.isFile() && isSupportedDocument(fileName)) files.add(fileName);
177
+ for (const fileName of [options.rootFileName, ...(options.extraUris ?? []).map(sourceUriToFileName)]) {
178
+ const document = await openSourceDocument(fileName);
179
+ if (document) addDocument(document);
180
+ }
181
+ let packageDirectory = path$1.dirname(path$1.resolve(options.rootFileName));
182
+ while (true) {
183
+ const packageDocument = await openSourceDocument(path$1.join(packageDirectory, "package.json"));
184
+ if (packageDocument) addDocument(packageDocument);
185
+ const parent = path$1.dirname(packageDirectory);
186
+ if (parent === packageDirectory) break;
187
+ packageDirectory = parent;
188
+ }
189
+ for (let index = 0; index < queue.length; index++) {
190
+ const document = queue[index];
191
+ if (path$1.basename(document.fileName) === "package.json") continue;
192
+ for (const specifier of collectRelativeImportSpecifiers(document.text, document.fileName)) for (const candidate of resolveRelativeImportCandidates(document.fileName, specifier)) {
193
+ if (documents.has(path$1.resolve(candidate))) break;
194
+ const importedDocument = await openSourceDocument(candidate);
195
+ if (!importedDocument) continue;
196
+ addDocument(importedDocument);
197
+ break;
430
198
  }
431
199
  }
200
+ return [...documents.values()];
201
+ function addDocument(document) {
202
+ const normalizedFileName = path$1.resolve(document.fileName);
203
+ if (documents.has(normalizedFileName)) return;
204
+ if (documents.size >= maxFiles) throw new Error(`Source payload exceeds ${maxFiles} reachable files.`);
205
+ const byteLength = Buffer.byteLength(document.text);
206
+ if (totalBytes + byteLength > maxBytes) throw new Error(`Source payload exceeds ${maxBytes} bytes.`);
207
+ documents.set(normalizedFileName, document);
208
+ queue.push(document);
209
+ totalBytes += byteLength;
210
+ }
211
+ }
212
+ async function openSourceDocument(fileName) {
213
+ if (!isSupportedDocument(fileName)) return null;
214
+ const text = await fsPromises.readFile(fileName, "utf8").catch(() => null);
215
+ return text === null ? null : {
216
+ uri: fileNameToUri(fileName),
217
+ fileName,
218
+ text
219
+ };
220
+ }
221
+ function collectRelativeImportSpecifiers(text, fileName) {
222
+ const sourceFile = ts.createSourceFile(fileName, text, ts.ScriptTarget.Latest, true, getScriptKind(fileName));
223
+ const specifiers = [];
224
+ for (const statement of sourceFile.statements) {
225
+ const moduleSpecifier = ts.isImportDeclaration(statement) || ts.isExportDeclaration(statement) ? statement.moduleSpecifier : void 0;
226
+ if (moduleSpecifier && ts.isStringLiteral(moduleSpecifier) && moduleSpecifier.text.startsWith(".")) specifiers.push(moduleSpecifier.text);
227
+ }
228
+ return specifiers;
432
229
  }
433
- function shouldSkipDirectory(name) {
230
+ const importExtensions = [
231
+ ".ts",
232
+ ".tsx",
233
+ ".js",
234
+ ".jsx",
235
+ ".mjs",
236
+ ".cjs",
237
+ ".mts",
238
+ ".cts"
239
+ ];
240
+ function resolveRelativeImportCandidates(fromFileName, specifier) {
241
+ const basePath = path$1.resolve(path$1.dirname(fromFileName), specifier);
242
+ if (path$1.extname(basePath)) return [basePath];
434
243
  return [
435
- "node_modules",
436
- "dist",
437
- "out",
438
- "build",
439
- "coverage",
440
- ".git"
441
- ].includes(name);
244
+ basePath,
245
+ ...importExtensions.map((extension) => `${basePath}${extension}`),
246
+ ...importExtensions.map((extension) => path$1.join(basePath, `index${extension}`))
247
+ ];
248
+ }
249
+ function getScriptKind(fileName) {
250
+ if (fileName.endsWith(".tsx")) return ts.ScriptKind.TSX;
251
+ if (fileName.endsWith(".jsx")) return ts.ScriptKind.JSX;
252
+ if (/\.(?:c|m)?js$/.test(fileName)) return ts.ScriptKind.JS;
253
+ return ts.ScriptKind.TS;
442
254
  }
443
255
  function isSupportedDocument(fileName) {
444
256
  return supportedDocumentPattern.test(fileName);
@@ -583,22 +395,6 @@ function openBrowser(url) {
583
395
  stdio: "ignore"
584
396
  }).unref();
585
397
  }
586
- function getValidationErrors(validations) {
587
- return (validations ?? []).filter((validation) => validation.level === "error");
588
- }
589
- function formatValidationErrorMessage(errors) {
590
- const [firstError] = errors;
591
- if (!firstError) return "Cannot save Viz changes because the graph has validation errors.";
592
- if (errors.length === 1) return `Cannot save Viz changes: ${firstError.message}`;
593
- return `Cannot save Viz changes: ${errors.length} validation errors. First: ${firstError.message}`;
594
- }
595
- function sourceLocationUris(sourceLocations) {
596
- return [
597
- ...sourceLocations?.root ? [sourceLocations.root.uri] : [],
598
- ...(sourceLocations?.states ?? []).map((state) => state.uri),
599
- ...(sourceLocations?.staticValues ?? []).map((value) => value.uri)
600
- ];
601
- }
602
398
  function fileNameToUri(fileName) {
603
399
  return pathToFileURL(path$1.resolve(fileName)).toString();
604
400
  }
@@ -624,25 +420,6 @@ function compareReplacementRangesDescending(left, right) {
624
420
  function normalizedBaseUrl(value) {
625
421
  return value.replace(/\/+$/, "");
626
422
  }
627
- function formatError(error, fallback) {
628
- if (!(error instanceof Error)) return fallback;
629
- const details = collectErrorDetails(error);
630
- return details.length > 0 ? `${error.message} (${details.join(" | ")})` : error.message;
631
- }
632
- function collectErrorDetails(error) {
633
- const details = [];
634
- const seen = /* @__PURE__ */ new Set();
635
- let current = error;
636
- while (current && typeof current === "object" && !seen.has(current)) {
637
- seen.add(current);
638
- const code = "code" in current && typeof current.code === "string" ? current.code : void 0;
639
- const message = "message" in current && typeof current.message === "string" ? current.message : void 0;
640
- if (code && message) details.push(`${code}: ${message}`);
641
- else if (code) details.push(code);
642
- current = "cause" in current ? current.cause : void 0;
643
- }
644
- return details;
645
- }
646
423
  function escapeAttribute(value) {
647
424
  return value.replaceAll("&", "&amp;").replaceAll("\"", "&quot;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
648
425
  }
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { C as scanProjectMachines, S as run, T as createStatelyProjectConfig, _ as isFileGitDirty, a as discoverMachinesInSource, b as resolveCredentialStatus, c as formatDiscoveredMachines, d as formatProjectStatus, f as formatStoredCredentialSource, g as initProject, h as inferInitProjectName, i as discoverLinkedPullTargets, l as formatMissingNewMachineDirMessage, m as getEnvCredential, n as buildOAuthLoginStart, o as discoverOAuthLogin, p as getEnvApiKey, r as classifyPushCandidates, s as discoverRemoteProjectMachineTargets, t as COMMANDS, u as formatPlanSummary, v as resolveApiKey, w as scanProjectSources, x as resolveProjectStatus, y as resolveConfiguredPullTargets } from "./cli-Dx1dw7Cy.mjs";
1
+ import { C as scanProjectMachines, S as run, T as createStatelyProjectConfig, _ as isFileGitDirty, a as discoverMachinesInSource, b as resolveCredentialStatus, c as formatDiscoveredMachines, d as formatProjectStatus, f as formatStoredCredentialSource, g as initProject, h as inferInitProjectName, i as discoverLinkedPullTargets, l as formatMissingNewMachineDirMessage, m as getEnvCredential, n as buildOAuthLoginStart, o as discoverOAuthLogin, p as getEnvApiKey, r as classifyPushCandidates, s as discoverRemoteProjectMachineTargets, t as COMMANDS, u as formatPlanSummary, v as resolveApiKey, w as scanProjectSources, x as resolveProjectStatus, y as resolveConfiguredPullTargets } from "./cli-CTUGfkL5.mjs";
2
2
 
3
3
  export { COMMANDS, buildOAuthLoginStart, classifyPushCandidates, createStatelyProjectConfig, discoverLinkedPullTargets, discoverMachinesInSource, discoverOAuthLogin, discoverRemoteProjectMachineTargets, formatDiscoveredMachines, formatMissingNewMachineDirMessage, formatPlanSummary, formatProjectStatus, formatStoredCredentialSource, getEnvApiKey, getEnvCredential, inferInitProjectName, initProject, isFileGitDirty, resolveApiKey, resolveConfiguredPullTargets, resolveCredentialStatus, resolveProjectStatus, run, scanProjectMachines, scanProjectSources };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "statelyai",
3
- "version": "0.8.5",
3
+ "version": "0.8.8",
4
4
  "description": "Command-line tools for Stately",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -21,8 +21,9 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "@oclif/core": "^4.10.3",
24
+ "typescript": "^5.9.3",
24
25
  "ws": "^8.21.0",
25
- "@statelyai/sdk": "0.17.0"
26
+ "@statelyai/sdk": "0.20.0"
26
27
  },
27
28
  "devDependencies": {
28
29
  "@types/ws": "^8.18.1",