@positronic/cli 0.0.55 → 0.0.57

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.
Files changed (94) hide show
  1. package/dist/src/cli.js +142 -2
  2. package/dist/src/commands/auth.js +98 -0
  3. package/dist/src/commands/brain.js +3 -2
  4. package/dist/src/commands/helpers.js +48 -10
  5. package/dist/src/commands/project-config-manager.js +119 -0
  6. package/dist/src/commands/users.js +91 -0
  7. package/dist/src/components/agent-chat-view.js +125 -0
  8. package/dist/src/components/auth-list.js +56 -0
  9. package/dist/src/components/auth-login.js +209 -0
  10. package/dist/src/components/auth-logout.js +75 -0
  11. package/dist/src/components/auth-status.js +88 -0
  12. package/dist/src/components/brain-run.js +287 -254
  13. package/dist/src/components/brain-top-table.js +4 -0
  14. package/dist/src/components/event-detail.js +364 -0
  15. package/dist/src/components/events-view.js +379 -0
  16. package/dist/src/components/state-view.js +52 -0
  17. package/dist/src/components/top-navigator.js +80 -6
  18. package/dist/src/components/types.js +1 -0
  19. package/dist/src/components/users-create.js +293 -0
  20. package/dist/src/components/users-delete.js +294 -0
  21. package/dist/src/components/users-keys-add.js +156 -0
  22. package/dist/src/components/users-keys-list.js +119 -0
  23. package/dist/src/components/users-keys-remove.js +299 -0
  24. package/dist/src/components/users-list.js +109 -0
  25. package/dist/src/components/watch-keyboard.js +136 -0
  26. package/dist/src/components/watch-machine.js +573 -0
  27. package/dist/src/components/watch-resolver.js +3 -2
  28. package/dist/src/components/watch.js +390 -36
  29. package/dist/src/hooks/useApi.js +80 -42
  30. package/dist/src/lib/request-signer.js +208 -0
  31. package/dist/src/lib/ssh-key-utils.js +212 -0
  32. package/dist/src/utils/agent-utils.js +107 -0
  33. package/dist/types/cli.d.ts.map +1 -1
  34. package/dist/types/commands/auth.d.ts +36 -0
  35. package/dist/types/commands/auth.d.ts.map +1 -0
  36. package/dist/types/commands/brain.d.ts +2 -1
  37. package/dist/types/commands/brain.d.ts.map +1 -1
  38. package/dist/types/commands/helpers.d.ts.map +1 -1
  39. package/dist/types/commands/project-config-manager.d.ts +43 -0
  40. package/dist/types/commands/project-config-manager.d.ts.map +1 -1
  41. package/dist/types/commands/users.d.ts +33 -0
  42. package/dist/types/commands/users.d.ts.map +1 -0
  43. package/dist/types/components/agent-chat-view.d.ts +12 -0
  44. package/dist/types/components/agent-chat-view.d.ts.map +1 -0
  45. package/dist/types/components/auth-list.d.ts +7 -0
  46. package/dist/types/components/auth-list.d.ts.map +1 -0
  47. package/dist/types/components/auth-login.d.ts +9 -0
  48. package/dist/types/components/auth-login.d.ts.map +1 -0
  49. package/dist/types/components/auth-logout.d.ts +8 -0
  50. package/dist/types/components/auth-logout.d.ts.map +1 -0
  51. package/dist/types/components/auth-status.d.ts +7 -0
  52. package/dist/types/components/auth-status.d.ts.map +1 -0
  53. package/dist/types/components/brain-run.d.ts +11 -1
  54. package/dist/types/components/brain-run.d.ts.map +1 -1
  55. package/dist/types/components/brain-top-table.d.ts.map +1 -1
  56. package/dist/types/components/event-detail.d.ts +10 -0
  57. package/dist/types/components/event-detail.d.ts.map +1 -0
  58. package/dist/types/components/events-view.d.ts +13 -0
  59. package/dist/types/components/events-view.d.ts.map +1 -0
  60. package/dist/types/components/state-view.d.ts +13 -0
  61. package/dist/types/components/state-view.d.ts.map +1 -0
  62. package/dist/types/components/top-navigator.d.ts.map +1 -1
  63. package/dist/types/components/types.d.ts +11 -0
  64. package/dist/types/components/types.d.ts.map +1 -0
  65. package/dist/types/components/users-create.d.ts +6 -0
  66. package/dist/types/components/users-create.d.ts.map +1 -0
  67. package/dist/types/components/users-delete.d.ts +7 -0
  68. package/dist/types/components/users-delete.d.ts.map +1 -0
  69. package/dist/types/components/users-keys-add.d.ts +8 -0
  70. package/dist/types/components/users-keys-add.d.ts.map +1 -0
  71. package/dist/types/components/users-keys-list.d.ts +6 -0
  72. package/dist/types/components/users-keys-list.d.ts.map +1 -0
  73. package/dist/types/components/users-keys-remove.d.ts +8 -0
  74. package/dist/types/components/users-keys-remove.d.ts.map +1 -0
  75. package/dist/types/components/users-list.d.ts +2 -0
  76. package/dist/types/components/users-list.d.ts.map +1 -0
  77. package/dist/types/components/watch-keyboard.d.ts +56 -0
  78. package/dist/types/components/watch-keyboard.d.ts.map +1 -0
  79. package/dist/types/components/watch-machine.d.ts +171 -0
  80. package/dist/types/components/watch-machine.d.ts.map +1 -0
  81. package/dist/types/components/watch-resolver.d.ts +2 -1
  82. package/dist/types/components/watch-resolver.d.ts.map +1 -1
  83. package/dist/types/components/watch.d.ts +2 -1
  84. package/dist/types/components/watch.d.ts.map +1 -1
  85. package/dist/types/hooks/useApi.d.ts.map +1 -1
  86. package/dist/types/hooks/useBrainMachine.d.ts +9 -3
  87. package/dist/types/hooks/useBrainMachine.d.ts.map +1 -1
  88. package/dist/types/lib/request-signer.d.ts +51 -0
  89. package/dist/types/lib/request-signer.d.ts.map +1 -0
  90. package/dist/types/lib/ssh-key-utils.d.ts +45 -0
  91. package/dist/types/lib/ssh-key-utils.d.ts.map +1 -0
  92. package/dist/types/utils/agent-utils.d.ts +20 -0
  93. package/dist/types/utils/agent-utils.d.ts.map +1 -0
  94. package/package.json +7 -4
@@ -48,6 +48,13 @@ function _define_property(obj, key, value) {
48
48
  }
49
49
  return obj;
50
50
  }
51
+ function _instanceof(left, right) {
52
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
53
+ return !!right[Symbol.hasInstance](left);
54
+ } else {
55
+ return left instanceof right;
56
+ }
57
+ }
51
58
  function _iterable_to_array_limit(arr, i) {
52
59
  var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
53
60
  if (_i == null) return;
@@ -117,6 +124,10 @@ function _object_spread_props(target, source) {
117
124
  function _sliced_to_array(arr, i) {
118
125
  return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
119
126
  }
127
+ function _type_of(obj) {
128
+ "@swc/helpers - typeof";
129
+ return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
130
+ }
120
131
  function _unsupported_iterable_to_array(o, minLen) {
121
132
  if (!o) return;
122
133
  if (typeof o === "string") return _array_like_to_array(o, minLen);
@@ -216,280 +227,302 @@ function _ts_generator(thisArg, body) {
216
227
  };
217
228
  }
218
229
  }
219
- import React, { useState, useEffect, useCallback } from 'react';
230
+ import React, { useMemo, useEffect } from 'react';
220
231
  import { Box, Text, useApp } from 'ink';
232
+ import { createMachine, state, transition, reduce, invoke, immediate, guard } from 'robot3';
233
+ import { useMachine } from 'react-robot';
221
234
  import { ErrorComponent } from './error.js';
222
235
  import { SelectList } from './select-list.js';
223
236
  import { Watch } from './watch.js';
224
237
  import { apiClient, isApiLocalDevMode } from '../commands/helpers.js';
225
- export var BrainRun = function(param) {
226
- var identifier = param.identifier, watch = param.watch, options = param.options;
227
- var _useState = _sliced_to_array(useState('searching'), 2), phase = _useState[0], setPhase = _useState[1];
228
- var _useState1 = _sliced_to_array(useState([]), 2), brains = _useState1[0], setBrains = _useState1[1];
229
- var _useState2 = _sliced_to_array(useState(null), 2), runId = _useState2[0], setRunId = _useState2[1];
230
- var _useState3 = _sliced_to_array(useState(null), 2), error = _useState3[0], setError = _useState3[1];
231
- var exit = useApp().exit;
232
- var getConnectionError = useCallback(function() {
233
- if (isApiLocalDevMode()) {
234
- return {
235
- title: 'Connection Error',
236
- message: 'Error connecting to the local development server.',
237
- details: "Please ensure the server is running ('positronic server' or 'px s')."
238
- };
239
- } else {
240
- return {
241
- title: 'Connection Error',
242
- message: 'Error connecting to the remote project server.',
243
- details: 'Please check your network connection and verify the project URL is correct.'
244
- };
245
- }
246
- }, []);
247
- var runBrain = useCallback(function(brainTitle) {
248
- return _async_to_generator(function() {
249
- var response, result, errorText, err, baseError;
250
- return _ts_generator(this, function(_state) {
251
- switch(_state.label){
252
- case 0:
253
- setPhase('running');
254
- _state.label = 1;
255
- case 1:
256
- _state.trys.push([
257
- 1,
258
- 8,
259
- ,
260
- 9
261
- ]);
262
- return [
263
- 4,
264
- apiClient.fetch('/brains/runs', {
265
- method: 'POST',
266
- headers: {
267
- 'Content-Type': 'application/json'
268
- },
269
- body: JSON.stringify({
270
- identifier: brainTitle,
271
- options: options
272
- })
238
+ // Helper to get connection error message
239
+ var getConnectionError = function() {
240
+ if (isApiLocalDevMode()) {
241
+ return {
242
+ title: 'Connection Error',
243
+ message: 'Error connecting to the local development server.',
244
+ details: "Please ensure the server is running ('positronic server' or 'px s')."
245
+ };
246
+ }
247
+ return {
248
+ title: 'Connection Error',
249
+ message: 'Error connecting to the remote project server.',
250
+ details: 'Please check your network connection and verify the project URL is correct.'
251
+ };
252
+ };
253
+ // Error handler for network errors
254
+ var handleNetworkError = function(err) {
255
+ // If it's already an ErrorInfo object (thrown from our async functions)
256
+ if (err && (typeof err === "undefined" ? "undefined" : _type_of(err)) === 'object' && 'title' in err && 'message' in err) {
257
+ return err;
258
+ }
259
+ // Network/connection error
260
+ var baseError = getConnectionError();
261
+ var message = _instanceof(err, Error) ? err.message : String(err);
262
+ return _object_spread_props(_object_spread({}, baseError), {
263
+ details: "".concat(baseError.details, " ").concat(message)
264
+ });
265
+ };
266
+ // Async functions for invoke states
267
+ var searchBrains = function(ctx) {
268
+ return _async_to_generator(function() {
269
+ var url, response, errorText;
270
+ return _ts_generator(this, function(_state) {
271
+ switch(_state.label){
272
+ case 0:
273
+ url = "/brains?q=".concat(encodeURIComponent(ctx.identifier));
274
+ return [
275
+ 4,
276
+ apiClient.fetch(url, {
277
+ method: 'GET'
278
+ })
279
+ ];
280
+ case 1:
281
+ response = _state.sent();
282
+ if (!!response.ok) return [
283
+ 3,
284
+ 3
285
+ ];
286
+ return [
287
+ 4,
288
+ response.text()
289
+ ];
290
+ case 2:
291
+ errorText = _state.sent();
292
+ throw {
293
+ title: 'Server Error',
294
+ message: "Error searching for brains: ".concat(response.status, " ").concat(response.statusText),
295
+ details: errorText
296
+ };
297
+ case 3:
298
+ return [
299
+ 4,
300
+ response.json()
301
+ ];
302
+ case 4:
303
+ return [
304
+ 2,
305
+ _state.sent()
306
+ ];
307
+ }
308
+ });
309
+ })();
310
+ };
311
+ var startRun = function(ctx) {
312
+ return _async_to_generator(function() {
313
+ var response, errorText;
314
+ return _ts_generator(this, function(_state) {
315
+ switch(_state.label){
316
+ case 0:
317
+ return [
318
+ 4,
319
+ apiClient.fetch('/brains/runs', {
320
+ method: 'POST',
321
+ headers: {
322
+ 'Content-Type': 'application/json'
323
+ },
324
+ body: JSON.stringify({
325
+ identifier: ctx.selectedBrainTitle,
326
+ options: ctx.options
273
327
  })
274
- ];
275
- case 2:
276
- response = _state.sent();
277
- if (!(response.status === 201)) return [
278
- 3,
279
- 4
280
- ];
281
- return [
282
- 4,
283
- response.json()
284
- ];
285
- case 3:
286
- result = _state.sent();
287
- setRunId(result.brainRunId);
288
- setPhase('complete');
289
- return [
290
- 3,
291
- 7
292
- ];
293
- case 4:
294
- if (!(response.status === 404)) return [
295
- 3,
296
- 5
297
- ];
298
- setError({
328
+ })
329
+ ];
330
+ case 1:
331
+ response = _state.sent();
332
+ if (!(response.status === 201)) return [
333
+ 3,
334
+ 3
335
+ ];
336
+ return [
337
+ 4,
338
+ response.json()
339
+ ];
340
+ case 2:
341
+ return [
342
+ 2,
343
+ _state.sent()
344
+ ];
345
+ case 3:
346
+ if (response.status === 404) {
347
+ throw {
299
348
  title: 'Brain Not Found',
300
- message: "Brain '".concat(brainTitle, "' not found."),
349
+ message: "Brain '".concat(ctx.selectedBrainTitle, "' not found."),
301
350
  details: 'The brain may have been removed or renamed since the search.'
302
- });
303
- setPhase('error');
304
- return [
305
- 3,
306
- 7
307
- ];
308
- case 5:
309
- return [
310
- 4,
311
- response.text()
312
- ];
313
- case 6:
314
- errorText = _state.sent();
315
- setError({
316
- title: 'Server Error',
317
- message: "Error starting brain run: ".concat(response.status, " ").concat(response.statusText),
318
- details: errorText
319
- });
320
- setPhase('error');
321
- _state.label = 7;
322
- case 7:
323
- return [
324
- 3,
325
- 9
326
- ];
327
- case 8:
328
- err = _state.sent();
329
- baseError = getConnectionError();
330
- setError(_object_spread_props(_object_spread({}, baseError), {
331
- details: "".concat(baseError.details, " ").concat(err.message)
332
- }));
333
- setPhase('error');
334
- return [
335
- 3,
336
- 9
337
- ];
338
- case 9:
339
- return [
340
- 2
341
- ];
342
- }
343
- });
344
- })();
345
- }, [
346
- options,
347
- getConnectionError
348
- ]);
349
- // Initial search
350
- useEffect(function() {
351
- var searchBrains = function() {
352
- return _async_to_generator(function() {
353
- var url, response, errorText, data, err, baseError;
354
- return _ts_generator(this, function(_state) {
355
- switch(_state.label){
356
- case 0:
357
- _state.trys.push([
358
- 0,
359
- 9,
360
- ,
361
- 10
362
- ]);
363
- url = "/brains?q=".concat(encodeURIComponent(identifier));
364
- return [
365
- 4,
366
- apiClient.fetch(url, {
367
- method: 'GET'
368
- })
369
- ];
370
- case 1:
371
- response = _state.sent();
372
- if (!!response.ok) return [
373
- 3,
374
- 3
375
- ];
376
- return [
377
- 4,
378
- response.text()
379
- ];
380
- case 2:
381
- errorText = _state.sent();
382
- setError({
383
- title: 'Server Error',
384
- message: "Error searching for brains: ".concat(response.status, " ").concat(response.statusText),
385
- details: errorText
386
- });
387
- setPhase('error');
388
- return [
389
- 2
390
- ];
391
- case 3:
392
- return [
393
- 4,
394
- response.json()
395
- ];
396
- case 4:
397
- data = _state.sent();
398
- if (!(data.count === 0)) return [
399
- 3,
400
- 5
401
- ];
402
- setError({
403
- title: 'Brain Not Found',
404
- message: "No brains found matching '".concat(identifier, "'."),
405
- details: 'Please check that:\n 1. The brain name is spelled correctly\n 2. The brain exists in your project\n 3. The brain has been properly defined and exported\n\nYou can list available brains with: positronic list'
406
- });
407
- setPhase('error');
408
- return [
409
- 3,
410
- 8
411
- ];
412
- case 5:
413
- if (!(data.count === 1)) return [
414
- 3,
415
- 7
416
- ];
417
- // Exactly one match - run it directly
418
- return [
419
- 4,
420
- runBrain(data.brains[0].title)
421
- ];
422
- case 6:
423
- _state.sent();
424
- return [
425
- 3,
426
- 8
427
- ];
428
- case 7:
429
- // Multiple matches - show disambiguation UI
430
- setBrains(data.brains);
431
- setPhase('disambiguating');
432
- _state.label = 8;
433
- case 8:
434
- return [
435
- 3,
436
- 10
437
- ];
438
- case 9:
439
- err = _state.sent();
440
- baseError = getConnectionError();
441
- setError(_object_spread_props(_object_spread({}, baseError), {
442
- details: "".concat(baseError.details, " ").concat(err.message)
443
- }));
444
- setPhase('error');
445
- return [
446
- 3,
447
- 10
448
- ];
449
- case 10:
450
- return [
451
- 2
452
- ];
351
+ };
453
352
  }
454
- });
455
- })();
353
+ return [
354
+ 4,
355
+ response.text()
356
+ ];
357
+ case 4:
358
+ errorText = _state.sent();
359
+ throw {
360
+ title: 'Server Error',
361
+ message: "Error starting brain run: ".concat(response.status, " ").concat(response.statusText),
362
+ details: errorText
363
+ };
364
+ }
365
+ });
366
+ })();
367
+ };
368
+ // Reducers
369
+ var storeBrainSearchResult = reduce(function(ctx, ev) {
370
+ return _object_spread_props(_object_spread({}, ctx), {
371
+ brainSearchResult: ev.data
372
+ });
373
+ });
374
+ var applySingleBrainFound = reduce(function(ctx) {
375
+ return _object_spread_props(_object_spread({}, ctx), {
376
+ selectedBrainTitle: ctx.brainSearchResult.brains[0].title
377
+ });
378
+ });
379
+ var applyBrainsMultiple = reduce(function(ctx) {
380
+ return _object_spread_props(_object_spread({}, ctx), {
381
+ brains: ctx.brainSearchResult.brains
382
+ });
383
+ });
384
+ var applyBrainNotFoundError = reduce(function(ctx) {
385
+ return _object_spread_props(_object_spread({}, ctx), {
386
+ error: {
387
+ title: 'Brain Not Found',
388
+ message: "No brains found matching '".concat(ctx.identifier, "'."),
389
+ details: 'Please check that:\n 1. The brain name is spelled correctly\n 2. The brain exists in your project\n 3. The brain has been properly defined and exported\n\nYou can list available brains with: positronic list'
390
+ }
391
+ });
392
+ });
393
+ var setBrainTitleFromSelection = reduce(function(ctx, ev) {
394
+ return _object_spread_props(_object_spread({}, ctx), {
395
+ selectedBrainTitle: ev.brainTitle
396
+ });
397
+ });
398
+ var storeRunResult = reduce(function(ctx, ev) {
399
+ return _object_spread_props(_object_spread({}, ctx), {
400
+ runId: ev.data.brainRunId
401
+ });
402
+ });
403
+ var setErrorFromEvent = reduce(function(ctx, ev) {
404
+ return _object_spread_props(_object_spread({}, ctx), {
405
+ error: handleNetworkError(ev.error)
406
+ });
407
+ });
408
+ // Guards for routing
409
+ var brainFoundGuard = guard(function(ctx) {
410
+ var _ctx_brainSearchResult;
411
+ return ((_ctx_brainSearchResult = ctx.brainSearchResult) === null || _ctx_brainSearchResult === void 0 ? void 0 : _ctx_brainSearchResult.count) === 1;
412
+ });
413
+ var brainNotFoundGuard = guard(function(ctx) {
414
+ var _ctx_brainSearchResult;
415
+ return ((_ctx_brainSearchResult = ctx.brainSearchResult) === null || _ctx_brainSearchResult === void 0 ? void 0 : _ctx_brainSearchResult.count) === 0;
416
+ });
417
+ var brainsMultipleGuard = guard(function(ctx) {
418
+ var _ctx_brainSearchResult;
419
+ var _ctx_brainSearchResult_count;
420
+ return ((_ctx_brainSearchResult_count = (_ctx_brainSearchResult = ctx.brainSearchResult) === null || _ctx_brainSearchResult === void 0 ? void 0 : _ctx_brainSearchResult.count) !== null && _ctx_brainSearchResult_count !== void 0 ? _ctx_brainSearchResult_count : 0) > 1;
421
+ });
422
+ // State machine definition
423
+ var createBrainRunMachine = function(identifier, watch, options) {
424
+ return createMachine('searching', {
425
+ // Invoke state: search for brain by name
426
+ searching: invoke(searchBrains, transition('done', 'routeSearch', storeBrainSearchResult), transition('error', 'error', setErrorFromEvent)),
427
+ // Route based on brain search result
428
+ routeSearch: state(immediate('running', brainFoundGuard, applySingleBrainFound), immediate('error', brainNotFoundGuard, applyBrainNotFoundError), immediate('disambiguating', brainsMultipleGuard, applyBrainsMultiple)),
429
+ // User selects from multiple matching brains
430
+ disambiguating: state(transition('BRAIN_SELECTED', 'running', setBrainTitleFromSelection)),
431
+ // Invoke state: start the brain run
432
+ running: invoke(startRun, transition('done', 'complete', storeRunResult), transition('error', 'error', setErrorFromEvent)),
433
+ // Terminal states
434
+ complete: state(),
435
+ error: state()
436
+ }, function() {
437
+ return {
438
+ identifier: identifier,
439
+ watch: watch,
440
+ options: options,
441
+ brainSearchResult: null,
442
+ brains: [],
443
+ selectedBrainTitle: null,
444
+ runId: null,
445
+ error: null
456
446
  };
457
- searchBrains();
447
+ });
448
+ };
449
+ /**
450
+ * BrainRun - Searches for a brain by identifier and runs it.
451
+ *
452
+ * State machine handles all async operations via invoke.
453
+ * Flow:
454
+ * 1. Search for brain by name (fuzzy search)
455
+ * 2. If single match, run it; if multiple, show disambiguation UI; if none, show error
456
+ * 3. Start the brain run
457
+ * 4. Show run ID or Watch component based on watch flag
458
+ */ export var BrainRun = function(param) {
459
+ var identifier = param.identifier, _param_watch = param.watch, watch = _param_watch === void 0 ? false : _param_watch, options = param.options;
460
+ var machine = useMemo(function() {
461
+ return createBrainRunMachine(identifier, watch, options);
458
462
  }, [
459
463
  identifier,
460
- runBrain,
461
- getConnectionError
464
+ watch,
465
+ options
462
466
  ]);
467
+ var _useMachine = _sliced_to_array(useMachine(machine), 2), current = _useMachine[0], send = _useMachine[1];
468
+ var exit = useApp().exit;
469
+ var currentState = current.name;
470
+ var _current_context = current.context, brains = _current_context.brains, runId = _current_context.runId, error = _current_context.error;
463
471
  // Exit the app when run completes without watch mode
464
472
  useEffect(function() {
465
- if (phase === 'complete' && runId && !watch) {
473
+ if (currentState === 'complete' && runId && !watch) {
466
474
  exit();
467
475
  }
468
476
  }, [
469
- phase,
477
+ currentState,
470
478
  runId,
471
479
  watch,
472
480
  exit
473
481
  ]);
474
- // Maintain consistent Box wrapper to help Ink properly calculate
475
- // terminal clearing between renders (prevents appending instead of overwriting)
476
- return /*#__PURE__*/ React.createElement(Box, {
477
- flexDirection: "column"
478
- }, phase === 'searching' ? /*#__PURE__*/ React.createElement(Text, null, "Searching for brain '", identifier, "'...") : phase === 'error' && error ? /*#__PURE__*/ React.createElement(ErrorComponent, {
479
- error: error
480
- }) : phase === 'disambiguating' ? /*#__PURE__*/ React.createElement(SelectList, {
481
- items: brains.map(function(b) {
482
- return {
483
- id: b.title,
484
- label: b.title,
485
- description: b.description
486
- };
487
- }),
488
- header: "Multiple brains match '".concat(identifier, "':"),
489
- onSelect: function(item) {
490
- runBrain(item.label);
491
- }
492
- }) : phase === 'running' ? /*#__PURE__*/ React.createElement(Text, null, "Starting brain run...") : phase === 'complete' && runId ? watch ? /*#__PURE__*/ React.createElement(Watch, {
493
- runId: runId
494
- }) : /*#__PURE__*/ React.createElement(Text, null, "Run ID: ", runId) : null);
482
+ // Render based on state
483
+ switch(currentState){
484
+ case 'searching':
485
+ case 'routeSearch':
486
+ return /*#__PURE__*/ React.createElement(Box, {
487
+ flexDirection: "column"
488
+ }, /*#__PURE__*/ React.createElement(Text, null, "Searching for brain '", identifier, "'..."));
489
+ case 'disambiguating':
490
+ return /*#__PURE__*/ React.createElement(Box, {
491
+ flexDirection: "column"
492
+ }, /*#__PURE__*/ React.createElement(SelectList, {
493
+ items: brains.map(function(b) {
494
+ return {
495
+ id: b.title,
496
+ label: b.title,
497
+ description: b.description
498
+ };
499
+ }),
500
+ header: "Multiple brains match '".concat(identifier, "':"),
501
+ onSelect: function(item) {
502
+ send({
503
+ type: 'BRAIN_SELECTED',
504
+ brainTitle: item.label
505
+ });
506
+ }
507
+ }));
508
+ case 'running':
509
+ return /*#__PURE__*/ React.createElement(Box, {
510
+ flexDirection: "column"
511
+ }, /*#__PURE__*/ React.createElement(Text, null, "Starting brain run..."));
512
+ case 'complete':
513
+ if (!runId) return null;
514
+ return /*#__PURE__*/ React.createElement(Box, {
515
+ flexDirection: "column"
516
+ }, watch ? /*#__PURE__*/ React.createElement(Watch, {
517
+ runId: runId
518
+ }) : /*#__PURE__*/ React.createElement(Text, null, "Run ID: ", runId));
519
+ case 'error':
520
+ return /*#__PURE__*/ React.createElement(Box, {
521
+ flexDirection: "column"
522
+ }, error ? /*#__PURE__*/ React.createElement(ErrorComponent, {
523
+ error: error
524
+ }) : null);
525
+ default:
526
+ return null;
527
+ }
495
528
  };
@@ -45,6 +45,10 @@ var getStatusColor = function(status) {
45
45
  return 'yellow';
46
46
  case STATUS.CANCELLED:
47
47
  return 'gray';
48
+ case STATUS.PAUSED:
49
+ return 'cyan';
50
+ case STATUS.WAITING:
51
+ return 'magenta';
48
52
  default:
49
53
  return 'white';
50
54
  }