agent-state-machine 1.4.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,7 +45,7 @@ Requirements: Node.js >= 16.
45
45
  state-machine --setup <workflow-name>
46
46
  state-machine run <workflow-name>
47
47
 
48
- state-machine follow <workflow-name> (view prompt trace history in browser with live updates)
48
+
49
49
  state-machine history <workflow-name> [limit]
50
50
  state-machine reset <workflow-name> (clears memory/state)
51
51
  state-machine reset-hard <workflow-name> (clears everything: history/interactions/memory)
@@ -298,11 +298,7 @@ export const config = {
298
298
  };
299
299
  ```
300
300
 
301
- The runtime captures the fully-built prompt in `state/history.jsonl`, viewable in the browser with live updates via:
302
-
303
- ```bash
304
- state-machine follow <workflow-name>
305
- ```
301
+ The runtime captures the fully-built prompt in `state/history.jsonl`, viewable in the browser with live updates when running with the `--local` flag or via the remote URL.
306
302
 
307
303
  ---
308
304
 
package/bin/cli.js CHANGED
@@ -5,7 +5,8 @@ import fs from 'fs';
5
5
  import { pathToFileURL, fileURLToPath } from 'url';
6
6
  import { WorkflowRuntime } from '../lib/index.js';
7
7
  import { setup } from '../lib/setup.js';
8
- import { startServer } from '../lib/ui/server.js';
8
+
9
+ import { startLocalServer } from '../vercel-server/local-server.js';
9
10
 
10
11
  const __filename = fileURLToPath(import.meta.url);
11
12
  const __dirname = path.dirname(__filename);
@@ -32,8 +33,9 @@ Agent State Machine CLI (Native JS Workflows Only) v${getVersion()}
32
33
 
33
34
  Usage:
34
35
  state-machine --setup <workflow-name> Create a new workflow project
35
- state-machine run <workflow-name> [--remote] Run a workflow (--remote enables remote follow)
36
- state-machine follow <workflow-name> View prompt trace history in browser with live updates
36
+ state-machine run <workflow-name> Run a workflow (remote follow enabled by default)
37
+ state-machine run <workflow-name> -l Run with local server (localhost:3000)
38
+
37
39
  state-machine status [workflow-name] Show current state (or list all)
38
40
  state-machine history <workflow-name> [limit] Show execution history logs
39
41
  state-machine reset <workflow-name> Reset workflow state (clears memory/state)
@@ -43,12 +45,12 @@ Usage:
43
45
 
44
46
  Options:
45
47
  --setup, -s Initialize a new workflow with directory structure
46
- --remote, -r Enable remote follow (generates shareable URL for browser access)
48
+ --local, -l Use local server instead of remote (starts on localhost:3000)
47
49
  --help, -h Show help
48
50
  --version, -v Show version
49
51
 
50
52
  Environment Variables:
51
- STATE_MACHINE_REMOTE_URL Override the default remote server URL
53
+ STATE_MACHINE_REMOTE_URL Override the default remote server URL (for local dev testing)
52
54
 
53
55
  Workflow Structure:
54
56
  workflows/<name>/
@@ -143,7 +145,7 @@ function listWorkflows() {
143
145
  console.log('');
144
146
  }
145
147
 
146
- async function runOrResume(workflowName, { remoteEnabled = false } = {}) {
148
+ async function runOrResume(workflowName, { remoteEnabled = false, useLocalServer = false } = {}) {
147
149
  const workflowDir = resolveWorkflowDir(workflowName);
148
150
 
149
151
  if (!fs.existsSync(workflowDir)) {
@@ -161,19 +163,39 @@ async function runOrResume(workflowName, { remoteEnabled = false } = {}) {
161
163
  const runtime = new WorkflowRuntime(workflowDir);
162
164
  const workflowUrl = pathToFileURL(entry).href;
163
165
 
164
- // Enable remote follow mode if requested
165
- if (remoteEnabled) {
166
- const remoteUrl = process.env.STATE_MACHINE_REMOTE_URL || DEFAULT_REMOTE_URL;
166
+ let localServer = null;
167
+ let remoteUrl = null;
168
+
169
+ // Start local server if --local flag is used
170
+ if (useLocalServer) {
171
+ try {
172
+ const result = await startLocalServer(3000, true);
173
+ localServer = result.server;
174
+ remoteUrl = result.url;
175
+ console.log(`Local server started at ${remoteUrl}`);
176
+ } catch (err) {
177
+ console.error(`Failed to start local server: ${err.message}`);
178
+ process.exit(1);
179
+ }
180
+ } else if (remoteEnabled) {
181
+ remoteUrl = process.env.STATE_MACHINE_REMOTE_URL || DEFAULT_REMOTE_URL;
182
+ }
183
+
184
+ // Enable remote follow mode if we have a URL
185
+ if (remoteUrl) {
167
186
  await runtime.enableRemote(remoteUrl);
168
187
  }
169
188
 
170
189
  try {
171
190
  await runtime.runWorkflow(workflowUrl);
172
191
  } finally {
173
- // Always disable remote on completion
174
- if (remoteEnabled) {
192
+ // Cleanup
193
+ if (remoteUrl) {
175
194
  await runtime.disableRemote();
176
195
  }
196
+ if (localServer) {
197
+ localServer.close();
198
+ }
177
199
  }
178
200
  }
179
201
 
@@ -205,13 +227,15 @@ async function main() {
205
227
  case 'run':
206
228
  if (!workflowName) {
207
229
  console.error('Error: Workflow name required');
208
- console.error(`Usage: state-machine ${command} <workflow-name> [--remote]`);
230
+ console.error(`Usage: state-machine ${command} <workflow-name> [--local]`);
209
231
  process.exit(1);
210
232
  }
211
233
  {
212
- const remoteEnabled = args.includes('--remote') || args.includes('-r');
234
+ // Remote is enabled by default, --local uses local server instead
235
+ const useLocalServer = args.includes('--local') || args.includes('-l');
236
+ const remoteEnabled = !useLocalServer; // Use Vercel if not local
213
237
  try {
214
- await runOrResume(workflowName, { remoteEnabled });
238
+ await runOrResume(workflowName, { remoteEnabled, useLocalServer });
215
239
  } catch (err) {
216
240
  console.error('Error:', err.message || String(err));
217
241
  process.exit(1);
@@ -245,22 +269,7 @@ async function main() {
245
269
  }
246
270
  break;
247
271
 
248
- case 'follow':
249
- if (!workflowName) {
250
- console.error('Error: Workflow name required');
251
- console.error('Usage: state-machine follow <workflow-name>');
252
- process.exit(1);
253
- }
254
- {
255
- const workflowDir = resolveWorkflowDir(workflowName);
256
- if (!fs.existsSync(workflowDir)) {
257
- console.error(`Error: Workflow '${workflowName}' not found`);
258
- process.exit(1);
259
- }
260
- startServer(workflowDir);
261
- // Do not exit, server needs to stay alive
262
- }
263
- break;
272
+
264
273
 
265
274
  case 'reset':
266
275
  if (!workflowName) {
@@ -39,6 +39,7 @@ export async function initialPrompt(question, options = {}) {
39
39
  runtime.prependHistory({
40
40
  event: 'PROMPT_REQUESTED',
41
41
  slug,
42
+ targetKey: memoryKey,
42
43
  question
43
44
  });
44
45