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.
- package/dist/ui/v3/commands/commandEngine.d.ts +3 -1
- package/dist/ui/v3/commands/commandEngine.d.ts.map +1 -1
- package/dist/ui/v3/commands/commandEngine.js +702 -15
- package/dist/ui/v3/commands/commandEngine.js.map +1 -1
- package/dist/ui/v3/core/eventBus.d.ts +1 -1
- package/dist/ui/v3/core/eventBus.d.ts.map +1 -1
- package/dist/ui/v3/core/eventBus.js +5 -2
- package/dist/ui/v3/core/eventBus.js.map +1 -1
- package/dist/ui/v3/core/logger.js +4 -4
- package/dist/ui/v3/core/logger.js.map +1 -1
- package/dist/ui/v3/core/opEvent.d.ts +2 -0
- package/dist/ui/v3/core/opEvent.d.ts.map +1 -1
- package/dist/ui/v3/state/uiStateTypes.d.ts +2 -2
- package/dist/ui/v3/state/uiStateTypes.d.ts.map +1 -1
- package/dist/ui/v3/state/value.js +1 -1
- package/dist/ui/v3/state/value.js.map +1 -1
- package/dist/ui/v3/ui/phase1Runtime.d.ts.map +1 -1
- package/dist/ui/v3/ui/phase1Runtime.js +20 -10
- package/dist/ui/v3/ui/phase1Runtime.js.map +1 -1
- package/dist/ui/v3/v1Adapters/agents.d.ts +25 -5
- package/dist/ui/v3/v1Adapters/agents.d.ts.map +1 -1
- package/dist/ui/v3/v1Adapters/agents.js +57 -9
- package/dist/ui/v3/v1Adapters/agents.js.map +1 -1
- package/dist/ui/v3/v1Adapters/config.d.ts +8 -3
- package/dist/ui/v3/v1Adapters/config.d.ts.map +1 -1
- package/dist/ui/v3/v1Adapters/config.js +8 -9
- package/dist/ui/v3/v1Adapters/config.js.map +1 -1
- package/dist/ui/v3/v1Adapters/connect.d.ts +3 -0
- package/dist/ui/v3/v1Adapters/connect.d.ts.map +1 -1
- package/dist/ui/v3/v1Adapters/connect.js +27 -1
- package/dist/ui/v3/v1Adapters/connect.js.map +1 -1
- package/dist/ui/v3/v1Adapters/runs.d.ts +17 -0
- package/dist/ui/v3/v1Adapters/runs.d.ts.map +1 -1
- package/dist/ui/v3/v1Adapters/runs.js +30 -0
- package/dist/ui/v3/v1Adapters/runs.js.map +1 -1
- 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 -
|
|
94
|
-
if (current
|
|
95
|
-
tokens.push(current
|
|
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
|
|
106
|
-
tokens.push(current
|
|
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
|
-
|
|
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
|