@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.
- package/dist/src/cli.js +142 -2
- package/dist/src/commands/auth.js +98 -0
- package/dist/src/commands/brain.js +3 -2
- package/dist/src/commands/helpers.js +48 -10
- package/dist/src/commands/project-config-manager.js +119 -0
- package/dist/src/commands/users.js +91 -0
- package/dist/src/components/agent-chat-view.js +125 -0
- package/dist/src/components/auth-list.js +56 -0
- package/dist/src/components/auth-login.js +209 -0
- package/dist/src/components/auth-logout.js +75 -0
- package/dist/src/components/auth-status.js +88 -0
- package/dist/src/components/brain-run.js +287 -254
- package/dist/src/components/brain-top-table.js +4 -0
- package/dist/src/components/event-detail.js +364 -0
- package/dist/src/components/events-view.js +379 -0
- package/dist/src/components/state-view.js +52 -0
- package/dist/src/components/top-navigator.js +80 -6
- package/dist/src/components/types.js +1 -0
- package/dist/src/components/users-create.js +293 -0
- package/dist/src/components/users-delete.js +294 -0
- package/dist/src/components/users-keys-add.js +156 -0
- package/dist/src/components/users-keys-list.js +119 -0
- package/dist/src/components/users-keys-remove.js +299 -0
- package/dist/src/components/users-list.js +109 -0
- package/dist/src/components/watch-keyboard.js +136 -0
- package/dist/src/components/watch-machine.js +573 -0
- package/dist/src/components/watch-resolver.js +3 -2
- package/dist/src/components/watch.js +390 -36
- package/dist/src/hooks/useApi.js +80 -42
- package/dist/src/lib/request-signer.js +208 -0
- package/dist/src/lib/ssh-key-utils.js +212 -0
- package/dist/src/utils/agent-utils.js +107 -0
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/commands/auth.d.ts +36 -0
- package/dist/types/commands/auth.d.ts.map +1 -0
- package/dist/types/commands/brain.d.ts +2 -1
- package/dist/types/commands/brain.d.ts.map +1 -1
- package/dist/types/commands/helpers.d.ts.map +1 -1
- package/dist/types/commands/project-config-manager.d.ts +43 -0
- package/dist/types/commands/project-config-manager.d.ts.map +1 -1
- package/dist/types/commands/users.d.ts +33 -0
- package/dist/types/commands/users.d.ts.map +1 -0
- package/dist/types/components/agent-chat-view.d.ts +12 -0
- package/dist/types/components/agent-chat-view.d.ts.map +1 -0
- package/dist/types/components/auth-list.d.ts +7 -0
- package/dist/types/components/auth-list.d.ts.map +1 -0
- package/dist/types/components/auth-login.d.ts +9 -0
- package/dist/types/components/auth-login.d.ts.map +1 -0
- package/dist/types/components/auth-logout.d.ts +8 -0
- package/dist/types/components/auth-logout.d.ts.map +1 -0
- package/dist/types/components/auth-status.d.ts +7 -0
- package/dist/types/components/auth-status.d.ts.map +1 -0
- package/dist/types/components/brain-run.d.ts +11 -1
- package/dist/types/components/brain-run.d.ts.map +1 -1
- package/dist/types/components/brain-top-table.d.ts.map +1 -1
- package/dist/types/components/event-detail.d.ts +10 -0
- package/dist/types/components/event-detail.d.ts.map +1 -0
- package/dist/types/components/events-view.d.ts +13 -0
- package/dist/types/components/events-view.d.ts.map +1 -0
- package/dist/types/components/state-view.d.ts +13 -0
- package/dist/types/components/state-view.d.ts.map +1 -0
- package/dist/types/components/top-navigator.d.ts.map +1 -1
- package/dist/types/components/types.d.ts +11 -0
- package/dist/types/components/types.d.ts.map +1 -0
- package/dist/types/components/users-create.d.ts +6 -0
- package/dist/types/components/users-create.d.ts.map +1 -0
- package/dist/types/components/users-delete.d.ts +7 -0
- package/dist/types/components/users-delete.d.ts.map +1 -0
- package/dist/types/components/users-keys-add.d.ts +8 -0
- package/dist/types/components/users-keys-add.d.ts.map +1 -0
- package/dist/types/components/users-keys-list.d.ts +6 -0
- package/dist/types/components/users-keys-list.d.ts.map +1 -0
- package/dist/types/components/users-keys-remove.d.ts +8 -0
- package/dist/types/components/users-keys-remove.d.ts.map +1 -0
- package/dist/types/components/users-list.d.ts +2 -0
- package/dist/types/components/users-list.d.ts.map +1 -0
- package/dist/types/components/watch-keyboard.d.ts +56 -0
- package/dist/types/components/watch-keyboard.d.ts.map +1 -0
- package/dist/types/components/watch-machine.d.ts +171 -0
- package/dist/types/components/watch-machine.d.ts.map +1 -0
- package/dist/types/components/watch-resolver.d.ts +2 -1
- package/dist/types/components/watch-resolver.d.ts.map +1 -1
- package/dist/types/components/watch.d.ts +2 -1
- package/dist/types/components/watch.d.ts.map +1 -1
- package/dist/types/hooks/useApi.d.ts.map +1 -1
- package/dist/types/hooks/useBrainMachine.d.ts +9 -3
- package/dist/types/hooks/useBrainMachine.d.ts.map +1 -1
- package/dist/types/lib/request-signer.d.ts +51 -0
- package/dist/types/lib/request-signer.d.ts.map +1 -0
- package/dist/types/lib/ssh-key-utils.d.ts +45 -0
- package/dist/types/lib/ssh-key-utils.d.ts.map +1 -0
- package/dist/types/utils/agent-utils.d.ts +20 -0
- package/dist/types/utils/agent-utils.d.ts.map +1 -0
- 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, {
|
|
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
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
var
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
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
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
461
|
-
|
|
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 (
|
|
473
|
+
if (currentState === 'complete' && runId && !watch) {
|
|
466
474
|
exit();
|
|
467
475
|
}
|
|
468
476
|
}, [
|
|
469
|
-
|
|
477
|
+
currentState,
|
|
470
478
|
runId,
|
|
471
479
|
watch,
|
|
472
480
|
exit
|
|
473
481
|
]);
|
|
474
|
-
//
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
return {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
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
|
};
|