@positronic/cli 0.0.45 → 0.0.47

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.
@@ -6,6 +6,9 @@ function _array_like_to_array(arr, len) {
6
6
  function _array_with_holes(arr) {
7
7
  if (Array.isArray(arr)) return arr;
8
8
  }
9
+ function _array_without_holes(arr) {
10
+ if (Array.isArray(arr)) return _array_like_to_array(arr);
11
+ }
9
12
  function _define_property(obj, key, value) {
10
13
  if (key in obj) {
11
14
  Object.defineProperty(obj, key, {
@@ -19,6 +22,9 @@ function _define_property(obj, key, value) {
19
22
  }
20
23
  return obj;
21
24
  }
25
+ function _iterable_to_array(iter) {
26
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
27
+ }
22
28
  function _iterable_to_array_limit(arr, i) {
23
29
  var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
24
30
  if (_i == null) return;
@@ -46,6 +52,9 @@ function _iterable_to_array_limit(arr, i) {
46
52
  function _non_iterable_rest() {
47
53
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
48
54
  }
55
+ function _non_iterable_spread() {
56
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
57
+ }
49
58
  function _object_spread(target) {
50
59
  for(var i = 1; i < arguments.length; i++){
51
60
  var source = arguments[i] != null ? arguments[i] : {};
@@ -88,6 +97,9 @@ function _object_spread_props(target, source) {
88
97
  function _sliced_to_array(arr, i) {
89
98
  return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
90
99
  }
100
+ function _to_consumable_array(arr) {
101
+ return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
102
+ }
91
103
  function _unsupported_iterable_to_array(o, minLen) {
92
104
  if (!o) return;
93
105
  if (typeof o === "string") return _array_like_to_array(o, minLen);
@@ -99,8 +111,7 @@ function _unsupported_iterable_to_array(o, minLen) {
99
111
  import React, { useState, useEffect, useRef } from 'react';
100
112
  import { Text, Box, useStdout } from 'ink';
101
113
  import { EventSource } from 'eventsource';
102
- import { BRAIN_EVENTS } from '@positronic/core';
103
- import { STATUS } from '@positronic/core';
114
+ import { BRAIN_EVENTS, STATUS, createBrainExecutionMachine, sendEvent } from '@positronic/core';
104
115
  import { getApiBaseUrl, isApiLocalDevMode } from '../commands/helpers.js';
105
116
  import { ErrorComponent } from './error.js';
106
117
  // Get the index of the currently running step (or last completed if none running)
@@ -191,16 +202,16 @@ var StepWindow = function(param) {
191
202
  }, getStatusChar(nextStep.status), " ", nextStep.title)));
192
203
  };
193
204
  var BrainSection = function(param) {
194
- var brain = param.brain, _param_isInner = param.isInner, isInner = _param_isInner === void 0 ? false : _param_isInner, brains = param.brains;
205
+ var brain = param.brain, _param_isInner = param.isInner, isInner = _param_isInner === void 0 ? false : _param_isInner, brainStack = param.brainStack;
195
206
  var indent = isInner ? 2 : 0;
196
207
  var completed = getCompletedCount(brain.steps);
197
208
  var total = brain.steps.length;
198
209
  // Find the currently running step to check for inner brain
199
210
  var currentIndex = getCurrentStepIndex(brain.steps);
200
211
  var currentStep = brain.steps[currentIndex];
201
- // Find any inner brain associated with the current step
202
- var innerBrain = currentStep ? Array.from(brains.values()).find(function(b) {
203
- return b.parentStepId === currentStep.id && !b.isComplete;
212
+ // Find any inner brain associated with the current step (active inner brains are on the stack)
213
+ var innerBrain = currentStep ? brainStack.find(function(b) {
214
+ return b.parentStepId === currentStep.id;
204
215
  }) : null;
205
216
  return /*#__PURE__*/ React.createElement(Box, {
206
217
  flexDirection: "column",
@@ -226,22 +237,20 @@ var BrainSection = function(param) {
226
237
  }, /*#__PURE__*/ React.createElement(BrainSection, {
227
238
  brain: innerBrain,
228
239
  isInner: true,
229
- brains: brains
240
+ brainStack: brainStack
230
241
  })));
231
242
  };
232
243
  export var Watch = function(param) {
233
244
  var runId = param.runId;
234
245
  var write = useStdout().write;
235
- // Track all brains (parent and inner) by their brainRunId
236
- var _useState = _sliced_to_array(useState(new Map()), 2), brains = _useState[0], setBrains = _useState[1];
246
+ // Use state machine to track brain execution state
247
+ var machineRef = useRef(createBrainExecutionMachine());
248
+ // Store brain stack in state to trigger re-renders when it changes
249
+ var _useState = _sliced_to_array(useState([]), 2), brainStack = _useState[0], setBrainStack = _useState[1];
237
250
  var _useState1 = _sliced_to_array(useState(undefined), 2), brainError = _useState1[0], setBrainError = _useState1[1];
238
251
  var _useState2 = _sliced_to_array(useState(null), 2), error = _useState2[0], setError = _useState2[1];
239
252
  var _useState3 = _sliced_to_array(useState(false), 2), isConnected = _useState3[0], setIsConnected = _useState3[1];
240
253
  var _useState4 = _sliced_to_array(useState(false), 2), isCompleted = _useState4[0], setIsCompleted = _useState4[1];
241
- // Track the main brain's brainRunId to distinguish from inner brain events
242
- var mainBrainRunIdRef = useRef(null);
243
- // Track the currently running step ID to associate inner brains with their parent step
244
- var runningStepIdRef = useRef(null);
245
254
  // Enter alternate screen buffer on mount, exit on unmount
246
255
  // Skip in test environment to avoid interfering with test output capture
247
256
  useEffect(function() {
@@ -261,11 +270,13 @@ export var Watch = function(param) {
261
270
  var baseUrl = getApiBaseUrl();
262
271
  var url = "".concat(baseUrl, "/brains/runs/").concat(runId, "/watch");
263
272
  var es = new EventSource(url);
273
+ // Reset state machine for new connection
274
+ machineRef.current = createBrainExecutionMachine();
264
275
  setIsConnected(false);
265
276
  setError(null);
266
- setBrains(new Map());
267
- mainBrainRunIdRef.current = null;
268
- runningStepIdRef.current = null;
277
+ setBrainStack([]);
278
+ setBrainError(undefined);
279
+ setIsCompleted(false);
269
280
  es.onopen = function() {
270
281
  setIsConnected(true);
271
282
  setError(null);
@@ -273,68 +284,29 @@ export var Watch = function(param) {
273
284
  es.onmessage = function(event) {
274
285
  try {
275
286
  var eventData = JSON.parse(event.data);
276
- // Handle brain start - register new brain (parent or inner)
277
- if (eventData.type === BRAIN_EVENTS.START || eventData.type === BRAIN_EVENTS.RESTART) {
278
- var startEvent = eventData;
279
- var isMainBrain = mainBrainRunIdRef.current === null;
280
- if (isMainBrain) {
281
- mainBrainRunIdRef.current = startEvent.brainRunId;
282
- }
283
- setBrains(function(prev) {
284
- var next = new Map(prev);
285
- next.set(startEvent.brainRunId, {
286
- brainRunId: startEvent.brainRunId,
287
- brainTitle: startEvent.brainTitle,
288
- steps: [],
289
- parentStepId: isMainBrain ? null : runningStepIdRef.current,
290
- isComplete: false
287
+ var machine = machineRef.current;
288
+ // Feed event to state machine - it handles all the state tracking
289
+ sendEvent(machine, eventData);
290
+ // Update React state from machine context to trigger re-render
291
+ // Deep copy brainStack to ensure React detects the change
292
+ // Note: Only update if brainStack has entries - preserve last known state for completed brains
293
+ var currentStack = machine.context.brainStack;
294
+ if (currentStack.length > 0) {
295
+ setBrainStack(currentStack.map(function(entry) {
296
+ return _object_spread_props(_object_spread({}, entry), {
297
+ steps: _to_consumable_array(entry.steps)
291
298
  });
292
- return next;
293
- });
294
- setIsCompleted(false);
295
- }
296
- // Handle step status - update steps for the specific brain only
297
- if (eventData.type === BRAIN_EVENTS.STEP_STATUS) {
298
- var statusEvent = eventData;
299
- setBrains(function(prev) {
300
- var next = new Map(prev);
301
- var brain = next.get(statusEvent.brainRunId);
302
- if (brain) {
303
- next.set(statusEvent.brainRunId, _object_spread_props(_object_spread({}, brain), {
304
- steps: statusEvent.steps
305
- }));
306
- }
307
- return next;
308
- });
299
+ }));
309
300
  }
310
- // Handle step start - track the running step for inner brain association
311
- if (eventData.type === BRAIN_EVENTS.STEP_START) {
312
- var stepEvent = eventData;
313
- runningStepIdRef.current = stepEvent.stepId;
314
- }
315
- // Mark brain as complete when it completes
316
- if (eventData.type === BRAIN_EVENTS.COMPLETE || eventData.type === BRAIN_EVENTS.ERROR) {
317
- var completeEvent = eventData;
318
- // Mark this brain as complete
319
- setBrains(function(prev) {
320
- var next = new Map(prev);
321
- var brain = next.get(completeEvent.brainRunId);
322
- if (brain) {
323
- next.set(completeEvent.brainRunId, _object_spread_props(_object_spread({}, brain), {
324
- isComplete: true
325
- }));
326
- }
327
- return next;
328
- });
329
- // Only mark overall as complete when the main brain completes
330
- if (completeEvent.brainRunId === mainBrainRunIdRef.current) {
331
- setIsCompleted(true);
332
- }
301
+ // Check for completion (outer brain)
302
+ if (machine.context.isComplete) {
303
+ setIsCompleted(true);
333
304
  }
305
+ // Check for error (capture the error event for display)
334
306
  if (eventData.type === BRAIN_EVENTS.ERROR) {
335
307
  var errorEvent = eventData;
336
- // Only show error for the main brain
337
- if (errorEvent.brainRunId === mainBrainRunIdRef.current) {
308
+ // Only show error for the main brain (isTopLevel check)
309
+ if (machine.context.brainRunId === errorEvent.brainRunId) {
338
310
  setBrainError(errorEvent);
339
311
  }
340
312
  }
@@ -354,12 +326,13 @@ export var Watch = function(param) {
354
326
  }, [
355
327
  runId
356
328
  ]);
357
- var mainBrain = mainBrainRunIdRef.current ? brains.get(mainBrainRunIdRef.current) : null;
329
+ // Main brain is the first entry in the stack (outer brain)
330
+ var mainBrain = brainStack.length > 0 ? brainStack[0] : null;
358
331
  return /*#__PURE__*/ React.createElement(Box, {
359
332
  flexDirection: "column"
360
- }, !isConnected && brains.size === 0 ? /*#__PURE__*/ React.createElement(Text, null, "Connecting to watch service...") : !mainBrain ? /*#__PURE__*/ React.createElement(Text, null, "Waiting for brain to start...") : /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(BrainSection, {
333
+ }, !isConnected && brainStack.length === 0 ? /*#__PURE__*/ React.createElement(Text, null, "Connecting to watch service...") : !mainBrain ? /*#__PURE__*/ React.createElement(Text, null, "Waiting for brain to start...") : /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(BrainSection, {
361
334
  brain: mainBrain,
362
- brains: brains
335
+ brainStack: brainStack
363
336
  }), isCompleted && !error && !brainError && /*#__PURE__*/ React.createElement(Box, {
364
337
  marginTop: 1,
365
338
  borderStyle: "round",
@@ -1 +1 @@
1
- {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../../src/components/watch.tsx"],"names":[],"mappings":"AA8LA,UAAU,UAAU;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,KAAK,GAAI,WAAW,UAAU,4CAsL1C,CAAC"}
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../../src/components/watch.tsx"],"names":[],"mappings":"AAuLA,UAAU,UAAU;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,KAAK,GAAI,WAAW,UAAU,4CAyI1C,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@positronic/cli",
3
- "version": "0.0.45",
3
+ "version": "0.0.47",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -23,9 +23,9 @@
23
23
  "clean": "rm -rf tsconfig.tsbuildinfo dist node_modules"
24
24
  },
25
25
  "dependencies": {
26
- "@positronic/core": "^0.0.45",
27
- "@positronic/spec": "^0.0.45",
28
- "@positronic/template-new-project": "^0.0.45",
26
+ "@positronic/core": "^0.0.47",
27
+ "@positronic/spec": "^0.0.47",
28
+ "@positronic/template-new-project": "^0.0.47",
29
29
  "caz": "^2.0.0",
30
30
  "chokidar": "^3.6.0",
31
31
  "dotenv": "^16.4.7",