4runr-os 1.0.100 → 1.0.102

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 (36) hide show
  1. package/dist/ui/v3/commands/commandEngine.d.ts +3 -1
  2. package/dist/ui/v3/commands/commandEngine.d.ts.map +1 -1
  3. package/dist/ui/v3/commands/commandEngine.js +702 -15
  4. package/dist/ui/v3/commands/commandEngine.js.map +1 -1
  5. package/dist/ui/v3/core/eventBus.d.ts +1 -1
  6. package/dist/ui/v3/core/eventBus.d.ts.map +1 -1
  7. package/dist/ui/v3/core/eventBus.js +5 -2
  8. package/dist/ui/v3/core/eventBus.js.map +1 -1
  9. package/dist/ui/v3/core/logger.js +4 -4
  10. package/dist/ui/v3/core/logger.js.map +1 -1
  11. package/dist/ui/v3/core/opEvent.d.ts +2 -0
  12. package/dist/ui/v3/core/opEvent.d.ts.map +1 -1
  13. package/dist/ui/v3/state/uiStateTypes.d.ts +2 -2
  14. package/dist/ui/v3/state/uiStateTypes.d.ts.map +1 -1
  15. package/dist/ui/v3/state/value.js +1 -1
  16. package/dist/ui/v3/state/value.js.map +1 -1
  17. package/dist/ui/v3/ui/phase1Runtime.d.ts.map +1 -1
  18. package/dist/ui/v3/ui/phase1Runtime.js +20 -10
  19. package/dist/ui/v3/ui/phase1Runtime.js.map +1 -1
  20. package/dist/ui/v3/v1Adapters/agents.d.ts +25 -5
  21. package/dist/ui/v3/v1Adapters/agents.d.ts.map +1 -1
  22. package/dist/ui/v3/v1Adapters/agents.js +57 -9
  23. package/dist/ui/v3/v1Adapters/agents.js.map +1 -1
  24. package/dist/ui/v3/v1Adapters/config.d.ts +8 -3
  25. package/dist/ui/v3/v1Adapters/config.d.ts.map +1 -1
  26. package/dist/ui/v3/v1Adapters/config.js +8 -9
  27. package/dist/ui/v3/v1Adapters/config.js.map +1 -1
  28. package/dist/ui/v3/v1Adapters/connect.d.ts +3 -0
  29. package/dist/ui/v3/v1Adapters/connect.d.ts.map +1 -1
  30. package/dist/ui/v3/v1Adapters/connect.js +27 -1
  31. package/dist/ui/v3/v1Adapters/connect.js.map +1 -1
  32. package/dist/ui/v3/v1Adapters/runs.d.ts +17 -0
  33. package/dist/ui/v3/v1Adapters/runs.d.ts.map +1 -1
  34. package/dist/ui/v3/v1Adapters/runs.js +30 -0
  35. package/dist/ui/v3/v1Adapters/runs.js.map +1 -1
  36. package/package.json +1 -1
@@ -15,6 +15,11 @@
15
15
  * - Side-effect free
16
16
  * - Deterministic
17
17
  */
18
+ import { available, unavailable } from '../state/value.js';
19
+ import { listAgents, getAgent, createAgent as v1CreateAgent } from '../v1Adapters/agents.js';
20
+ import { connect as v1Connect, getConnectionState } from '../v1Adapters/connect.js';
21
+ import { startRun, listRuns } from '../v1Adapters/runs.js';
22
+ import { loadConfig } from '../v1Adapters/config.js';
18
23
  /**
19
24
  * UI actions that the UI layer interprets
20
25
  */
@@ -66,10 +71,6 @@ export function parse(line) {
66
71
  }
67
72
  else {
68
73
  // Start of double-quoted string
69
- if (current.trim()) {
70
- tokens.push(current.trim());
71
- current = '';
72
- }
73
74
  inDoubleQuote = true;
74
75
  }
75
76
  }
@@ -82,17 +83,13 @@ export function parse(line) {
82
83
  }
83
84
  else {
84
85
  // Start of single-quoted string
85
- if (current.trim()) {
86
- tokens.push(current.trim());
87
- current = '';
88
- }
89
86
  inSingleQuote = true;
90
87
  }
91
88
  }
92
89
  else if ((char === ' ' || char === '\t') && !inDoubleQuote && !inSingleQuote) {
93
- // Whitespace outside quotes - split token
94
- if (current.trim()) {
95
- tokens.push(current.trim());
90
+ // Whitespace outside quotes - end current token
91
+ if (current) {
92
+ tokens.push(current);
96
93
  current = '';
97
94
  }
98
95
  }
@@ -102,8 +99,8 @@ export function parse(line) {
102
99
  }
103
100
  }
104
101
  // Add final token if any
105
- if (current.trim() || inDoubleQuote || inSingleQuote) {
106
- tokens.push(current.trim());
102
+ if (current || inDoubleQuote || inSingleQuote) {
103
+ tokens.push(current);
107
104
  }
108
105
  if (tokens.length === 0) {
109
106
  return { name: '', args: [], raw };
@@ -124,7 +121,7 @@ export function parse(line) {
124
121
  * - Never emits UI output directly
125
122
  * - Only side effects via returned data
126
123
  */
127
- export function execute(parsed, ctx) {
124
+ export async function execute(parsed, ctx) {
128
125
  // Empty command
129
126
  if (!parsed.name) {
130
127
  return { events: [] };
@@ -136,7 +133,9 @@ export function execute(parsed, ctx) {
136
133
  return handleUnknown(parsed.name);
137
134
  }
138
135
  try {
139
- return handler(ctx, parsed.args);
136
+ const result = handler(ctx, parsed.args);
137
+ // Handle both sync and async handlers
138
+ return await Promise.resolve(result);
140
139
  }
141
140
  catch (error) {
142
141
  // Handler error - emit error event
@@ -146,6 +145,7 @@ export function execute(parsed, ctx) {
146
145
  id: `err-${Date.now()}`,
147
146
  ts: Date.now(),
148
147
  tag: 'ERR',
148
+ level: 'ERROR',
149
149
  msg: `Command error: ${errorMsg.substring(0, 50)}`,
150
150
  }],
151
151
  };
@@ -180,6 +180,7 @@ function handleUnknown(cmd) {
180
180
  id: `err-${Date.now()}`,
181
181
  ts: Date.now(),
182
182
  tag: 'ERR',
183
+ level: 'ERROR',
183
184
  msg: `UNKNOWN COMMAND: ${sanitizedCmd} (try: help)`,
184
185
  }],
185
186
  };
@@ -194,6 +195,12 @@ const commands = {
194
195
  clear: handleClear,
195
196
  home: handleHome,
196
197
  exit: handleExit,
198
+ // Section 6: Real commands (V1-backed)
199
+ 'agents': handleAgents,
200
+ 'connect': handleConnect,
201
+ 'start': handleStart,
202
+ 'runs': handleRuns,
203
+ 'system': handleSystem,
197
204
  };
198
205
  /**
199
206
  * Handle help command
@@ -208,32 +215,86 @@ function handleHelp(ctx, args) {
208
215
  id: `help-1-${Date.now()}`,
209
216
  ts: Date.now(),
210
217
  tag: 'SYS',
218
+ level: 'INFO',
211
219
  msg: 'AVAILABLE COMMANDS:',
212
220
  },
213
221
  {
214
222
  id: `help-2-${Date.now()}`,
215
223
  ts: Date.now(),
216
224
  tag: 'SYS',
225
+ level: 'INFO',
217
226
  msg: ' help',
218
227
  },
219
228
  {
220
229
  id: `help-3-${Date.now()}`,
221
230
  ts: Date.now(),
222
231
  tag: 'SYS',
232
+ level: 'INFO',
223
233
  msg: ' clear',
224
234
  },
225
235
  {
226
236
  id: `help-4-${Date.now()}`,
227
237
  ts: Date.now(),
228
238
  tag: 'SYS',
239
+ level: 'INFO',
229
240
  msg: ' home',
230
241
  },
231
242
  {
232
243
  id: `help-5-${Date.now()}`,
233
244
  ts: Date.now(),
234
245
  tag: 'SYS',
246
+ level: 'INFO',
235
247
  msg: ' exit',
236
248
  },
249
+ {
250
+ id: `help-6-${Date.now()}`,
251
+ ts: Date.now(),
252
+ tag: 'SYS',
253
+ level: 'INFO',
254
+ msg: ' agents list',
255
+ },
256
+ {
257
+ id: `help-7-${Date.now()}`,
258
+ ts: Date.now(),
259
+ tag: 'SYS',
260
+ level: 'INFO',
261
+ msg: ' agents create',
262
+ },
263
+ {
264
+ id: `help-8-${Date.now()}`,
265
+ ts: Date.now(),
266
+ tag: 'SYS',
267
+ level: 'INFO',
268
+ msg: ' agents inspect <id>',
269
+ },
270
+ {
271
+ id: `help-9-${Date.now()}`,
272
+ ts: Date.now(),
273
+ tag: 'SYS',
274
+ level: 'INFO',
275
+ msg: ' connect <target>',
276
+ },
277
+ {
278
+ id: `help-10-${Date.now()}`,
279
+ ts: Date.now(),
280
+ tag: 'SYS',
281
+ level: 'INFO',
282
+ msg: ' start <agentId>',
283
+ },
284
+ {
285
+ id: `help-11-${Date.now()}`,
286
+ ts: Date.now(),
287
+ tag: 'SYS',
288
+ level: 'INFO',
289
+ msg: ' runs list',
290
+ },
291
+ {
292
+ id: `help-12-${Date.now()}`,
293
+ ts: Date.now(),
294
+ tag: 'SYS',
295
+ level: 'INFO',
296
+ msg: ' system',
297
+ },
237
298
  ],
238
299
  };
239
300
  }
@@ -264,6 +325,7 @@ function handleHome(ctx, args) {
264
325
  id: `home-${Date.now()}`,
265
326
  ts: Date.now(),
266
327
  tag: 'SYS',
328
+ level: 'INFO',
267
329
  msg: 'HOME VIEW',
268
330
  },
269
331
  ],
@@ -283,10 +345,635 @@ function handleExit(ctx, args) {
283
345
  id: `exit-${Date.now()}`,
284
346
  ts: Date.now(),
285
347
  tag: 'SYS',
348
+ level: 'INFO',
286
349
  msg: 'Exiting...',
287
350
  },
288
351
  ],
289
352
  action: UiAction.EXIT,
290
353
  };
291
354
  }
355
+ // ============================================================================
356
+ // Section 6: Real Commands (V1-Backed)
357
+ // ============================================================================
358
+ /**
359
+ * Handle agents command (list, create, inspect)
360
+ */
361
+ async function handleAgents(ctx, args) {
362
+ const subcommand = args[0]?.toLowerCase() || 'list';
363
+ if (subcommand === 'list') {
364
+ return handleAgentsList(ctx, args.slice(1));
365
+ }
366
+ else if (subcommand === 'create') {
367
+ return handleAgentsCreate(ctx, args.slice(1));
368
+ }
369
+ else if (subcommand === 'inspect') {
370
+ return handleAgentsInspect(ctx, args.slice(1));
371
+ }
372
+ else {
373
+ return {
374
+ events: [{
375
+ id: `err-${Date.now()}`,
376
+ ts: Date.now(),
377
+ tag: 'ERR',
378
+ level: 'ERROR',
379
+ msg: `Unknown agents subcommand: ${subcommand} (try: list, create, inspect)`,
380
+ }],
381
+ };
382
+ }
383
+ }
384
+ /**
385
+ * 1️⃣ agents list
386
+ *
387
+ * Calls v1Adapters/agents.listAgents()
388
+ * Updates assets → AVAILABLE with real counts
389
+ */
390
+ async function handleAgentsList(ctx, args) {
391
+ const cmdEvent = {
392
+ id: `cmd-${Date.now()}`,
393
+ ts: Date.now(),
394
+ tag: 'CMD',
395
+ level: 'INFO',
396
+ msg: 'agents list',
397
+ };
398
+ try {
399
+ const result = listAgents();
400
+ if (!result.ok) {
401
+ // Failure: assets → UNAVAILABLE
402
+ return {
403
+ events: [
404
+ cmdEvent,
405
+ {
406
+ id: `err-${Date.now()}`,
407
+ ts: Date.now(),
408
+ tag: 'ERR',
409
+ level: 'ERROR',
410
+ msg: `Failed to list agents: ${result.error.message}`,
411
+ },
412
+ ],
413
+ uiStateUpdate: (prev) => ({
414
+ ...prev,
415
+ assets: unavailable(result.error.message || 'Agent registry unavailable', result.error.nextAction || 'Run "agents create"'),
416
+ }),
417
+ };
418
+ }
419
+ const agents = result.data;
420
+ const count = agents.length;
421
+ // Success: assets → AVAILABLE
422
+ const assetsState = {
423
+ total: count,
424
+ active: 0, // TODO: track active agents
425
+ idle: count,
426
+ error: 0,
427
+ };
428
+ return {
429
+ events: [
430
+ cmdEvent,
431
+ {
432
+ id: `ok-${Date.now()}`,
433
+ ts: Date.now(),
434
+ tag: count === 0 ? 'SYS' : 'CMD',
435
+ level: count === 0 ? 'WARN' : 'INFO',
436
+ msg: count === 0 ? 'No agents found' : `${count} agent${count === 1 ? '' : 's'} found`,
437
+ },
438
+ ],
439
+ uiStateUpdate: (prev) => ({
440
+ ...prev,
441
+ assets: available(assetsState),
442
+ }),
443
+ };
444
+ }
445
+ catch (error) {
446
+ return {
447
+ events: [
448
+ cmdEvent,
449
+ {
450
+ id: `err-${Date.now()}`,
451
+ ts: Date.now(),
452
+ tag: 'ERR',
453
+ level: 'ERROR',
454
+ msg: `Failed to list agents: ${error.message || 'Unknown error'}`,
455
+ },
456
+ ],
457
+ uiStateUpdate: (prev) => ({
458
+ ...prev,
459
+ assets: unavailable('Agent registry unavailable', 'Run "agents create"'),
460
+ }),
461
+ };
462
+ }
463
+ }
464
+ /**
465
+ * 2️⃣ agents create
466
+ *
467
+ * Accepts arguments or minimal defaults
468
+ * Calls v1Adapters/agents.createAgent()
469
+ */
470
+ async function handleAgentsCreate(ctx, args) {
471
+ const cmdEvent = {
472
+ id: `cmd-${Date.now()}`,
473
+ ts: Date.now(),
474
+ tag: 'CMD',
475
+ level: 'INFO',
476
+ msg: 'agents create',
477
+ };
478
+ try {
479
+ // Parse agent name from args (first arg)
480
+ const name = args[0]?.trim();
481
+ if (!name) {
482
+ return {
483
+ events: [
484
+ cmdEvent,
485
+ {
486
+ id: `err-${Date.now()}`,
487
+ ts: Date.now(),
488
+ tag: 'ERR',
489
+ level: 'ERROR',
490
+ msg: 'Agent name required (usage: agents create <name>)',
491
+ },
492
+ ],
493
+ };
494
+ }
495
+ // Create minimal agent (can be extended later)
496
+ const agent = {
497
+ name,
498
+ description: args[1] || undefined,
499
+ provider: {
500
+ type: 'openai',
501
+ model: 'gpt-3.5-turbo',
502
+ },
503
+ };
504
+ const result = v1CreateAgent(agent);
505
+ if (!result.ok) {
506
+ return {
507
+ events: [
508
+ cmdEvent,
509
+ {
510
+ id: `err-${Date.now()}`,
511
+ ts: Date.now(),
512
+ tag: 'ERR',
513
+ level: 'ERROR',
514
+ msg: `Failed to create agent: ${result.error.message}`,
515
+ },
516
+ ],
517
+ uiStateUpdate: (prev) => ({
518
+ ...prev,
519
+ assets: unavailable(result.error.message || 'Failed to create agent', result.error.nextAction || 'Check config and retry'),
520
+ }),
521
+ };
522
+ }
523
+ // Success: refresh assets list
524
+ const listResult = listAgents();
525
+ const assetsState = listResult.ok ? {
526
+ total: listResult.data.length,
527
+ active: 0,
528
+ idle: listResult.data.length,
529
+ error: 0,
530
+ } : {
531
+ total: 0,
532
+ active: 0,
533
+ idle: 0,
534
+ error: 0,
535
+ };
536
+ return {
537
+ events: [
538
+ cmdEvent,
539
+ {
540
+ id: `ok-${Date.now()}`,
541
+ ts: Date.now(),
542
+ tag: 'CMD',
543
+ level: 'INFO',
544
+ msg: `Agent "${name}" created`,
545
+ },
546
+ ],
547
+ uiStateUpdate: (prev) => ({
548
+ ...prev,
549
+ assets: available(assetsState),
550
+ }),
551
+ };
552
+ }
553
+ catch (error) {
554
+ return {
555
+ events: [
556
+ cmdEvent,
557
+ {
558
+ id: `err-${Date.now()}`,
559
+ ts: Date.now(),
560
+ tag: 'ERR',
561
+ level: 'ERROR',
562
+ msg: `Failed to create agent: ${error.message || 'Unknown error'}`,
563
+ },
564
+ ],
565
+ uiStateUpdate: (prev) => ({
566
+ ...prev,
567
+ assets: unavailable('Failed to create agent', 'Check config and retry'),
568
+ }),
569
+ };
570
+ }
571
+ }
572
+ /**
573
+ * 3️⃣ agents inspect <id>
574
+ *
575
+ * Calls v1Adapters/agents.getAgent(id)
576
+ * Updates posture → AVAILABLE
577
+ */
578
+ async function handleAgentsInspect(ctx, args) {
579
+ const agentId = args[0]?.trim();
580
+ const cmdEvent = {
581
+ id: `cmd-${Date.now()}`,
582
+ ts: Date.now(),
583
+ tag: 'CMD',
584
+ level: 'INFO',
585
+ msg: `agents inspect ${agentId || ''}`,
586
+ };
587
+ if (!agentId) {
588
+ return {
589
+ events: [
590
+ cmdEvent,
591
+ {
592
+ id: `err-${Date.now()}`,
593
+ ts: Date.now(),
594
+ tag: 'ERR',
595
+ level: 'ERROR',
596
+ msg: 'Agent ID required (usage: agents inspect <id>)',
597
+ },
598
+ ],
599
+ };
600
+ }
601
+ try {
602
+ const result = getAgent(agentId);
603
+ if (!result.ok) {
604
+ return {
605
+ events: [
606
+ cmdEvent,
607
+ {
608
+ id: `err-${Date.now()}`,
609
+ ts: Date.now(),
610
+ tag: 'ERR',
611
+ level: 'ERROR',
612
+ msg: `Agent not found: ${agentId}`,
613
+ },
614
+ ],
615
+ uiStateUpdate: (prev) => ({
616
+ ...prev,
617
+ posture: unavailable(result.error.message || 'Agent not found', result.error.nextAction || 'Run "agents list"'),
618
+ }),
619
+ };
620
+ }
621
+ // Success: posture → AVAILABLE
622
+ return {
623
+ events: [
624
+ cmdEvent,
625
+ {
626
+ id: `ok-${Date.now()}`,
627
+ ts: Date.now(),
628
+ tag: 'CMD',
629
+ level: 'INFO',
630
+ msg: `Agent loaded: ${result.data.name}`,
631
+ },
632
+ ],
633
+ uiStateUpdate: (prev) => ({
634
+ ...prev,
635
+ posture: available({
636
+ mode: 'HUB',
637
+ }),
638
+ }),
639
+ };
640
+ }
641
+ catch (error) {
642
+ return {
643
+ events: [
644
+ cmdEvent,
645
+ {
646
+ id: `err-${Date.now()}`,
647
+ ts: Date.now(),
648
+ tag: 'ERR',
649
+ level: 'ERROR',
650
+ msg: `Failed to inspect agent: ${error.message || 'Unknown error'}`,
651
+ },
652
+ ],
653
+ uiStateUpdate: (prev) => ({
654
+ ...prev,
655
+ posture: unavailable('Agent not found', 'Run "agents list"'),
656
+ }),
657
+ };
658
+ }
659
+ }
660
+ /**
661
+ * 4️⃣ connect <target>
662
+ *
663
+ * Calls v1Adapters/connect.connect(target)
664
+ * Updates network → AVAILABLE, capabilities → AVAILABLE, statusStrip → AVAILABLE
665
+ */
666
+ async function handleConnect(ctx, args) {
667
+ const target = args[0]?.trim();
668
+ const cmdEvent = {
669
+ id: `cmd-${Date.now()}`,
670
+ ts: Date.now(),
671
+ tag: 'CMD',
672
+ level: 'INFO',
673
+ msg: `connect ${target || ''}`,
674
+ };
675
+ try {
676
+ const result = await v1Connect(target);
677
+ if (!result.ok) {
678
+ return {
679
+ events: [
680
+ cmdEvent,
681
+ {
682
+ id: `err-${Date.now()}`,
683
+ ts: Date.now(),
684
+ tag: 'ERR',
685
+ level: 'ERROR',
686
+ msg: `Failed to connect: ${result.error.message}`,
687
+ },
688
+ ],
689
+ uiStateUpdate: (prev) => ({
690
+ ...prev,
691
+ network: unavailable(result.error.message || 'Gateway unreachable', result.error.nextAction || 'Verify URL or run "system"'),
692
+ }),
693
+ };
694
+ }
695
+ // Success: network, capabilities, statusStrip → AVAILABLE
696
+ return {
697
+ events: [
698
+ cmdEvent,
699
+ {
700
+ id: `ok-${Date.now()}`,
701
+ ts: Date.now(),
702
+ tag: 'NET',
703
+ level: 'INFO',
704
+ msg: `Connected to Gateway${target ? ` at ${target}` : ''}`,
705
+ },
706
+ ],
707
+ uiStateUpdate: (prev) => ({
708
+ ...prev,
709
+ network: available({
710
+ gateway: 'CONNECTED',
711
+ }),
712
+ capabilities: available({
713
+ items: [], // TODO: load capabilities from gateway
714
+ }),
715
+ statusStrip: available({
716
+ left: 'CONNECTED',
717
+ right: target || result.data.gatewayUrl || 'Gateway',
718
+ }),
719
+ }),
720
+ };
721
+ }
722
+ catch (error) {
723
+ return {
724
+ events: [
725
+ cmdEvent,
726
+ {
727
+ id: `err-${Date.now()}`,
728
+ ts: Date.now(),
729
+ tag: 'ERR',
730
+ level: 'ERROR',
731
+ msg: `Failed to connect: ${error.message || 'Unknown error'}`,
732
+ },
733
+ ],
734
+ uiStateUpdate: (prev) => ({
735
+ ...prev,
736
+ network: unavailable('Gateway unreachable', 'Verify URL or run "system"'),
737
+ }),
738
+ };
739
+ }
740
+ }
741
+ /**
742
+ * 5️⃣ start <agentId>
743
+ *
744
+ * Calls v1Adapters/runs.startRun(agentId)
745
+ * Updates posture → AVAILABLE (mode: RUNNING)
746
+ */
747
+ async function handleStart(ctx, args) {
748
+ const agentId = args[0]?.trim();
749
+ const cmdEvent = {
750
+ id: `cmd-${Date.now()}`,
751
+ ts: Date.now(),
752
+ tag: 'CMD',
753
+ level: 'INFO',
754
+ msg: `start ${agentId || ''}`,
755
+ };
756
+ if (!agentId) {
757
+ return {
758
+ events: [
759
+ cmdEvent,
760
+ {
761
+ id: `err-${Date.now()}`,
762
+ ts: Date.now(),
763
+ tag: 'ERR',
764
+ level: 'ERROR',
765
+ msg: 'Agent ID required (usage: start <agentId>)',
766
+ },
767
+ ],
768
+ };
769
+ }
770
+ try {
771
+ const result = await startRun(agentId);
772
+ if (!result.ok) {
773
+ return {
774
+ events: [
775
+ cmdEvent,
776
+ {
777
+ id: `err-${Date.now()}`,
778
+ ts: Date.now(),
779
+ tag: 'ERR',
780
+ level: 'ERROR',
781
+ msg: `Failed to start run: ${result.error.message}`,
782
+ },
783
+ ],
784
+ uiStateUpdate: (prev) => ({
785
+ ...prev,
786
+ posture: unavailable(result.error.message || 'Run failed to start', result.error.nextAction || 'Run "runs list"'),
787
+ }),
788
+ };
789
+ }
790
+ // Success: posture → AVAILABLE (mode: RUNNING)
791
+ return {
792
+ events: [
793
+ cmdEvent,
794
+ {
795
+ id: `ok-${Date.now()}`,
796
+ ts: Date.now(),
797
+ tag: 'RUN',
798
+ level: 'INFO',
799
+ msg: `Run started (id: ${result.data.id})`,
800
+ },
801
+ ],
802
+ uiStateUpdate: (prev) => ({
803
+ ...prev,
804
+ posture: available({
805
+ mode: 'RUNNING',
806
+ }),
807
+ }),
808
+ };
809
+ }
810
+ catch (error) {
811
+ return {
812
+ events: [
813
+ cmdEvent,
814
+ {
815
+ id: `err-${Date.now()}`,
816
+ ts: Date.now(),
817
+ tag: 'ERR',
818
+ level: 'ERROR',
819
+ msg: `Failed to start run: ${error.message || 'Unknown error'}`,
820
+ },
821
+ ],
822
+ uiStateUpdate: (prev) => ({
823
+ ...prev,
824
+ posture: unavailable('Run failed to start', 'Run "runs list"'),
825
+ }),
826
+ };
827
+ }
828
+ }
829
+ /**
830
+ * 6️⃣ runs list
831
+ *
832
+ * Calls v1Adapters/runs (needs listRuns function - TODO)
833
+ * Updates posture → AVAILABLE
834
+ */
835
+ async function handleRuns(ctx, args) {
836
+ const subcommand = args[0]?.toLowerCase() || 'list';
837
+ if (subcommand === 'list') {
838
+ return handleRunsList(ctx, args.slice(1));
839
+ }
840
+ else {
841
+ return {
842
+ events: [{
843
+ id: `err-${Date.now()}`,
844
+ ts: Date.now(),
845
+ tag: 'ERR',
846
+ level: 'ERROR',
847
+ msg: `Unknown runs subcommand: ${subcommand} (try: list)`,
848
+ }],
849
+ };
850
+ }
851
+ }
852
+ async function handleRunsList(ctx, args) {
853
+ const cmdEvent = {
854
+ id: `cmd-${Date.now()}`,
855
+ ts: Date.now(),
856
+ tag: 'CMD',
857
+ level: 'INFO',
858
+ msg: 'runs list',
859
+ };
860
+ try {
861
+ const result = await listRuns();
862
+ if (!result.ok) {
863
+ return {
864
+ events: [
865
+ cmdEvent,
866
+ {
867
+ id: `err-${Date.now()}`,
868
+ ts: Date.now(),
869
+ tag: 'ERR',
870
+ level: 'ERROR',
871
+ msg: `Failed to list runs: ${result.error.message}`,
872
+ },
873
+ ],
874
+ uiStateUpdate: (prev) => ({
875
+ ...prev,
876
+ posture: unavailable(result.error.message || 'Cannot fetch runs', result.error.nextAction || 'Run "connect" first'),
877
+ }),
878
+ };
879
+ }
880
+ const runs = result.data;
881
+ const count = runs.length;
882
+ // Success: posture → AVAILABLE
883
+ return {
884
+ events: [
885
+ cmdEvent,
886
+ {
887
+ id: `ok-${Date.now()}`,
888
+ ts: Date.now(),
889
+ tag: 'RUN',
890
+ level: 'INFO',
891
+ msg: `${count} run${count === 1 ? '' : 's'} found`,
892
+ },
893
+ ],
894
+ uiStateUpdate: (prev) => ({
895
+ ...prev,
896
+ posture: available({
897
+ mode: 'HUB',
898
+ }),
899
+ }),
900
+ };
901
+ }
902
+ catch (error) {
903
+ return {
904
+ events: [
905
+ cmdEvent,
906
+ {
907
+ id: `err-${Date.now()}`,
908
+ ts: Date.now(),
909
+ tag: 'ERR',
910
+ level: 'ERROR',
911
+ msg: `Failed to list runs: ${error.message || 'Unknown error'}`,
912
+ },
913
+ ],
914
+ uiStateUpdate: (prev) => ({
915
+ ...prev,
916
+ posture: unavailable('Cannot fetch runs', 'Run "connect" first'),
917
+ }),
918
+ };
919
+ }
920
+ }
921
+ /**
922
+ * 7️⃣ system
923
+ *
924
+ * Aggregates network state, config, agent count, run count
925
+ * Updates statusStrip → AVAILABLE
926
+ */
927
+ async function handleSystem(ctx, args) {
928
+ const cmdEvent = {
929
+ id: `cmd-${Date.now()}`,
930
+ ts: Date.now(),
931
+ tag: 'CMD',
932
+ level: 'INFO',
933
+ msg: 'system',
934
+ };
935
+ try {
936
+ // Aggregate system state
937
+ const agentsResult = listAgents();
938
+ const configResult = loadConfig();
939
+ const connectionResult = await getConnectionState();
940
+ const agentCount = agentsResult.ok ? agentsResult.data.length : 0;
941
+ const connected = connectionResult.ok && connectionResult.data.connected;
942
+ const statusLeft = connected ? 'CONNECTED' : 'OFFLINE';
943
+ const statusRight = `Agents: ${agentCount}`;
944
+ return {
945
+ events: [
946
+ cmdEvent,
947
+ {
948
+ id: `ok-${Date.now()}`,
949
+ ts: Date.now(),
950
+ tag: 'SYS',
951
+ level: connected ? 'INFO' : 'WARN',
952
+ msg: connected ? 'System healthy' : 'Partial connectivity',
953
+ },
954
+ ],
955
+ uiStateUpdate: (prev) => ({
956
+ ...prev,
957
+ statusStrip: available({
958
+ left: statusLeft,
959
+ right: statusRight,
960
+ }),
961
+ }),
962
+ };
963
+ }
964
+ catch (error) {
965
+ return {
966
+ events: [
967
+ cmdEvent,
968
+ {
969
+ id: `err-${Date.now()}`,
970
+ ts: Date.now(),
971
+ tag: 'ERR',
972
+ level: 'ERROR',
973
+ msg: `System check failed: ${error.message || 'Unknown error'}`,
974
+ },
975
+ ],
976
+ };
977
+ }
978
+ }
292
979
  //# sourceMappingURL=commandEngine.js.map