@robota-sdk/agent-cli 3.0.0-beta.52 → 3.0.0-beta.54
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/node/bin.js +1 -1
- package/dist/node/{chunk-QZUCO4ZK.js → chunk-ASBCJDLC.js} +452 -360
- package/dist/node/index.cjs +615 -522
- package/dist/node/index.js +1 -1
- package/package.json +8 -6
package/dist/node/index.cjs
CHANGED
|
@@ -38,7 +38,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
38
38
|
var import_node_fs3 = require("fs");
|
|
39
39
|
var import_node_path5 = require("path");
|
|
40
40
|
var import_node_url = require("url");
|
|
41
|
-
var
|
|
41
|
+
var import_agent_sdk4 = require("@robota-sdk/agent-sdk");
|
|
42
42
|
var import_agent_sessions = require("@robota-sdk/agent-sessions");
|
|
43
43
|
|
|
44
44
|
// src/utils/cli-args.ts
|
|
@@ -111,7 +111,14 @@ function getUserSettingsPath() {
|
|
|
111
111
|
}
|
|
112
112
|
function readSettings(path) {
|
|
113
113
|
if (!(0, import_node_fs.existsSync)(path)) return {};
|
|
114
|
-
|
|
114
|
+
const raw = (0, import_node_fs.readFileSync)(path, "utf8");
|
|
115
|
+
try {
|
|
116
|
+
return JSON.parse(raw);
|
|
117
|
+
} catch {
|
|
118
|
+
process.stderr.write(`Warning: corrupt settings file at ${path}, resetting to defaults
|
|
119
|
+
`);
|
|
120
|
+
return {};
|
|
121
|
+
}
|
|
115
122
|
}
|
|
116
123
|
function writeSettings(path, settings) {
|
|
117
124
|
(0, import_node_fs.mkdirSync)((0, import_node_path.dirname)(path), { recursive: true });
|
|
@@ -180,20 +187,18 @@ function createProviderFromSettings(cwd, modelOverride) {
|
|
|
180
187
|
var import_agent_transport_headless = require("@robota-sdk/agent-transport-headless");
|
|
181
188
|
|
|
182
189
|
// src/ui/render.tsx
|
|
183
|
-
var
|
|
190
|
+
var import_ink17 = require("ink");
|
|
184
191
|
|
|
185
192
|
// src/ui/App.tsx
|
|
186
|
-
var
|
|
187
|
-
var
|
|
188
|
-
var
|
|
193
|
+
var import_react17 = require("react");
|
|
194
|
+
var import_ink16 = require("ink");
|
|
195
|
+
var import_agent_core5 = require("@robota-sdk/agent-core");
|
|
189
196
|
|
|
190
197
|
// src/ui/hooks/useInteractiveSession.ts
|
|
191
|
-
var
|
|
198
|
+
var import_react2 = require("react");
|
|
192
199
|
var import_node_os2 = require("os");
|
|
193
200
|
var import_node_path3 = require("path");
|
|
194
|
-
var
|
|
195
|
-
var import_agent_core = require("@robota-sdk/agent-core");
|
|
196
|
-
var import_node_crypto = require("crypto");
|
|
201
|
+
var import_agent_sdk2 = require("@robota-sdk/agent-sdk");
|
|
197
202
|
|
|
198
203
|
// src/ui/tui-state-manager.ts
|
|
199
204
|
var MAX_RENDERED_MESSAGES = 100;
|
|
@@ -321,9 +326,97 @@ var TuiStateManager = class {
|
|
|
321
326
|
}
|
|
322
327
|
};
|
|
323
328
|
|
|
329
|
+
// src/ui/hooks/useSlashRouting.ts
|
|
330
|
+
var import_react = require("react");
|
|
331
|
+
var import_node_crypto = require("crypto");
|
|
332
|
+
var import_agent_sdk = require("@robota-sdk/agent-sdk");
|
|
333
|
+
var import_agent_core = require("@robota-sdk/agent-core");
|
|
334
|
+
function useSlashRouting(interactiveSession, registry, manager) {
|
|
335
|
+
return (0, import_react.useCallback)(
|
|
336
|
+
async (input) => {
|
|
337
|
+
if (!input.startsWith("/")) {
|
|
338
|
+
await interactiveSession.submit(input);
|
|
339
|
+
manager.setPendingPrompt(interactiveSession.getPendingPrompt());
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
const parts = input.slice(1).split(/\s+/);
|
|
343
|
+
const cmd = parts[0]?.toLowerCase() ?? "";
|
|
344
|
+
const args = parts.slice(1).join(" ");
|
|
345
|
+
const result = await interactiveSession.executeCommand(cmd, args);
|
|
346
|
+
if (result) {
|
|
347
|
+
manager.addEntry((0, import_agent_core.messageToHistoryEntry)((0, import_agent_core.createSystemMessage)(result.message)));
|
|
348
|
+
const effects = interactiveSession;
|
|
349
|
+
if (result.data?.modelId) {
|
|
350
|
+
effects._pendingModelId = result.data.modelId;
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
if (result.data?.language) {
|
|
354
|
+
effects._pendingLanguage = result.data.language;
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
if (result.data?.resetRequested) {
|
|
358
|
+
effects._resetRequested = true;
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
if (result.data?.triggerResumePicker) {
|
|
362
|
+
effects._triggerResumePicker = true;
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
if (result.data?.name) {
|
|
366
|
+
effects._sessionName = result.data.name;
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
const ctx = interactiveSession.getContextState();
|
|
370
|
+
manager.setContextState({
|
|
371
|
+
percentage: ctx.usedPercentage,
|
|
372
|
+
usedTokens: ctx.usedTokens,
|
|
373
|
+
maxTokens: ctx.maxTokens
|
|
374
|
+
});
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
const skillCmd = registry.getCommands().find((c) => c.name === cmd && (c.source === "skill" || c.source === "plugin"));
|
|
378
|
+
if (skillCmd) {
|
|
379
|
+
manager.addEntry({
|
|
380
|
+
id: (0, import_node_crypto.randomUUID)(),
|
|
381
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
382
|
+
category: "event",
|
|
383
|
+
type: "skill-invocation",
|
|
384
|
+
data: {
|
|
385
|
+
skillName: cmd,
|
|
386
|
+
source: skillCmd.source,
|
|
387
|
+
message: `Invoking ${skillCmd.source}: ${cmd}`
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
const prompt = await (0, import_agent_sdk.buildSkillPrompt)(input, registry);
|
|
391
|
+
if (prompt) {
|
|
392
|
+
const qualifiedName = registry.resolveQualifiedName(cmd);
|
|
393
|
+
const hookInput = qualifiedName ? `/${qualifiedName}${input.slice(1 + cmd.length)}` : input;
|
|
394
|
+
await interactiveSession.submit(prompt, input, hookInput);
|
|
395
|
+
manager.setPendingPrompt(interactiveSession.getPendingPrompt());
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
if (cmd === "exit") {
|
|
400
|
+
interactiveSession._exitRequested = true;
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
if (cmd === "plugin") {
|
|
404
|
+
interactiveSession._triggerPluginTUI = true;
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
manager.addEntry(
|
|
408
|
+
(0, import_agent_core.messageToHistoryEntry)(
|
|
409
|
+
(0, import_agent_core.createSystemMessage)(`Unknown command "/${cmd}". Type /help for help.`)
|
|
410
|
+
)
|
|
411
|
+
);
|
|
412
|
+
},
|
|
413
|
+
[interactiveSession, registry, manager]
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
|
|
324
417
|
// src/ui/hooks/useInteractiveSession.ts
|
|
325
418
|
function initializeSession(props, permissionHandler) {
|
|
326
|
-
const interactiveSession = new
|
|
419
|
+
const interactiveSession = new import_agent_sdk2.InteractiveSession({
|
|
327
420
|
cwd: props.cwd,
|
|
328
421
|
provider: props.provider,
|
|
329
422
|
permissionMode: props.permissionMode,
|
|
@@ -334,15 +427,15 @@ function initializeSession(props, permissionHandler) {
|
|
|
334
427
|
forkSession: props.forkSession,
|
|
335
428
|
sessionName: props.sessionName
|
|
336
429
|
});
|
|
337
|
-
const registry = new
|
|
338
|
-
registry.addSource(new
|
|
339
|
-
registry.addSource(new
|
|
430
|
+
const registry = new import_agent_sdk2.CommandRegistry();
|
|
431
|
+
registry.addSource(new import_agent_sdk2.BuiltinCommandSource());
|
|
432
|
+
registry.addSource(new import_agent_sdk2.SkillCommandSource(props.cwd));
|
|
340
433
|
const pluginsDir = (0, import_node_path3.join)((0, import_node_os2.homedir)(), ".robota", "plugins");
|
|
341
|
-
const loader = new
|
|
434
|
+
const loader = new import_agent_sdk2.BundlePluginLoader(pluginsDir);
|
|
342
435
|
try {
|
|
343
436
|
const plugins = loader.loadPluginsSync();
|
|
344
437
|
if (plugins.length > 0) {
|
|
345
|
-
registry.addSource(new
|
|
438
|
+
registry.addSource(new import_agent_sdk2.PluginCommandSource(plugins));
|
|
346
439
|
}
|
|
347
440
|
} catch {
|
|
348
441
|
}
|
|
@@ -350,11 +443,11 @@ function initializeSession(props, permissionHandler) {
|
|
|
350
443
|
return { interactiveSession, registry, manager };
|
|
351
444
|
}
|
|
352
445
|
function useInteractiveSession(props) {
|
|
353
|
-
const [, forceRender] = (0,
|
|
354
|
-
const [permissionRequest, setPermissionRequest] = (0,
|
|
355
|
-
const permissionQueueRef = (0,
|
|
356
|
-
const processingRef = (0,
|
|
357
|
-
const processNextPermission = (0,
|
|
446
|
+
const [, forceRender] = (0, import_react2.useState)(0);
|
|
447
|
+
const [permissionRequest, setPermissionRequest] = (0, import_react2.useState)(null);
|
|
448
|
+
const permissionQueueRef = (0, import_react2.useRef)([]);
|
|
449
|
+
const processingRef = (0, import_react2.useRef)(false);
|
|
450
|
+
const processNextPermission = (0, import_react2.useCallback)(() => {
|
|
358
451
|
if (processingRef.current) return;
|
|
359
452
|
const next = permissionQueueRef.current[0];
|
|
360
453
|
if (!next) {
|
|
@@ -374,14 +467,14 @@ function useInteractiveSession(props) {
|
|
|
374
467
|
}
|
|
375
468
|
});
|
|
376
469
|
}, []);
|
|
377
|
-
const permissionHandler = (0,
|
|
470
|
+
const permissionHandler = (0, import_react2.useCallback)(
|
|
378
471
|
(toolName, toolArgs) => new Promise((resolve) => {
|
|
379
472
|
permissionQueueRef.current.push({ toolName, toolArgs, resolve });
|
|
380
473
|
processNextPermission();
|
|
381
474
|
}),
|
|
382
475
|
[processNextPermission]
|
|
383
476
|
);
|
|
384
|
-
const stateRef = (0,
|
|
477
|
+
const stateRef = (0, import_react2.useRef)(null);
|
|
385
478
|
if (stateRef.current === null) {
|
|
386
479
|
stateRef.current = initializeSession(props, permissionHandler);
|
|
387
480
|
}
|
|
@@ -393,7 +486,7 @@ function useInteractiveSession(props) {
|
|
|
393
486
|
manager.syncHistory(restored);
|
|
394
487
|
}
|
|
395
488
|
}
|
|
396
|
-
(0,
|
|
489
|
+
(0, import_react2.useEffect)(() => {
|
|
397
490
|
interactiveSession.on("text_delta", manager.onTextDelta);
|
|
398
491
|
interactiveSession.on("tool_start", manager.onToolStart);
|
|
399
492
|
interactiveSession.on("tool_end", manager.onToolEnd);
|
|
@@ -428,97 +521,18 @@ function useInteractiveSession(props) {
|
|
|
428
521
|
interactiveSession.off("error", manager.onError);
|
|
429
522
|
};
|
|
430
523
|
}, [interactiveSession, manager]);
|
|
431
|
-
(0,
|
|
524
|
+
(0, import_react2.useEffect)(() => {
|
|
432
525
|
manager.syncHistory(interactiveSession.getFullHistory());
|
|
433
526
|
if (!manager.isThinking) {
|
|
434
527
|
manager.setPendingPrompt(interactiveSession.getPendingPrompt());
|
|
435
528
|
}
|
|
436
529
|
}, [manager.isThinking, interactiveSession, manager]);
|
|
437
|
-
const handleSubmit = (
|
|
438
|
-
|
|
439
|
-
if (input.startsWith("/")) {
|
|
440
|
-
const parts = input.slice(1).split(/\s+/);
|
|
441
|
-
const cmd = parts[0]?.toLowerCase() ?? "";
|
|
442
|
-
const args = parts.slice(1).join(" ");
|
|
443
|
-
const result = await interactiveSession.executeCommand(cmd, args);
|
|
444
|
-
if (result) {
|
|
445
|
-
manager.addEntry((0, import_agent_core.messageToHistoryEntry)((0, import_agent_core.createSystemMessage)(result.message)));
|
|
446
|
-
const effects = interactiveSession;
|
|
447
|
-
if (result.data?.modelId) {
|
|
448
|
-
effects._pendingModelId = result.data.modelId;
|
|
449
|
-
return;
|
|
450
|
-
}
|
|
451
|
-
if (result.data?.language) {
|
|
452
|
-
effects._pendingLanguage = result.data.language;
|
|
453
|
-
return;
|
|
454
|
-
}
|
|
455
|
-
if (result.data?.resetRequested) {
|
|
456
|
-
effects._resetRequested = true;
|
|
457
|
-
return;
|
|
458
|
-
}
|
|
459
|
-
if (result.data?.triggerResumePicker) {
|
|
460
|
-
effects._triggerResumePicker = true;
|
|
461
|
-
return;
|
|
462
|
-
}
|
|
463
|
-
if (result.data?.name) {
|
|
464
|
-
effects._sessionName = result.data.name;
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
const ctx = interactiveSession.getContextState();
|
|
468
|
-
manager.setContextState({
|
|
469
|
-
percentage: ctx.usedPercentage,
|
|
470
|
-
usedTokens: ctx.usedTokens,
|
|
471
|
-
maxTokens: ctx.maxTokens
|
|
472
|
-
});
|
|
473
|
-
return;
|
|
474
|
-
}
|
|
475
|
-
const skillCmd = registry.getCommands().find((c) => c.name === cmd && (c.source === "skill" || c.source === "plugin"));
|
|
476
|
-
if (skillCmd) {
|
|
477
|
-
manager.addEntry({
|
|
478
|
-
id: (0, import_node_crypto.randomUUID)(),
|
|
479
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
480
|
-
category: "event",
|
|
481
|
-
type: "skill-invocation",
|
|
482
|
-
data: {
|
|
483
|
-
skillName: cmd,
|
|
484
|
-
source: skillCmd.source,
|
|
485
|
-
message: `Invoking ${skillCmd.source}: ${cmd}`
|
|
486
|
-
}
|
|
487
|
-
});
|
|
488
|
-
const prompt = await (0, import_agent_sdk.buildSkillPrompt)(input, registry);
|
|
489
|
-
if (prompt) {
|
|
490
|
-
const qualifiedName = registry.resolveQualifiedName(cmd);
|
|
491
|
-
const hookInput = qualifiedName ? `/${qualifiedName}${input.slice(1 + cmd.length)}` : input;
|
|
492
|
-
await interactiveSession.submit(prompt, input, hookInput);
|
|
493
|
-
manager.setPendingPrompt(interactiveSession.getPendingPrompt());
|
|
494
|
-
return;
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
if (cmd === "exit") {
|
|
498
|
-
interactiveSession._exitRequested = true;
|
|
499
|
-
return;
|
|
500
|
-
}
|
|
501
|
-
if (cmd === "plugin") {
|
|
502
|
-
interactiveSession._triggerPluginTUI = true;
|
|
503
|
-
return;
|
|
504
|
-
}
|
|
505
|
-
manager.addEntry(
|
|
506
|
-
(0, import_agent_core.messageToHistoryEntry)(
|
|
507
|
-
(0, import_agent_core.createSystemMessage)(`Unknown command "/${cmd}". Type /help for help.`)
|
|
508
|
-
)
|
|
509
|
-
);
|
|
510
|
-
return;
|
|
511
|
-
}
|
|
512
|
-
await interactiveSession.submit(input);
|
|
513
|
-
manager.setPendingPrompt(interactiveSession.getPendingPrompt());
|
|
514
|
-
},
|
|
515
|
-
[interactiveSession, registry, manager]
|
|
516
|
-
);
|
|
517
|
-
const handleAbort = (0, import_react.useCallback)(() => {
|
|
530
|
+
const handleSubmit = useSlashRouting(interactiveSession, registry, manager);
|
|
531
|
+
const handleAbort = (0, import_react2.useCallback)(() => {
|
|
518
532
|
manager.setAborting(true);
|
|
519
533
|
interactiveSession.abort();
|
|
520
534
|
}, [interactiveSession, manager]);
|
|
521
|
-
const handleCancelQueue = (0,
|
|
535
|
+
const handleCancelQueue = (0, import_react2.useCallback)(() => {
|
|
522
536
|
interactiveSession.cancelQueue();
|
|
523
537
|
manager.setPendingPrompt(null);
|
|
524
538
|
}, [interactiveSession, manager]);
|
|
@@ -541,23 +555,23 @@ function useInteractiveSession(props) {
|
|
|
541
555
|
}
|
|
542
556
|
|
|
543
557
|
// src/ui/hooks/usePluginCallbacks.ts
|
|
544
|
-
var
|
|
558
|
+
var import_react3 = require("react");
|
|
545
559
|
var import_node_os3 = require("os");
|
|
546
560
|
var import_node_path4 = require("path");
|
|
547
|
-
var
|
|
561
|
+
var import_agent_sdk3 = require("@robota-sdk/agent-sdk");
|
|
548
562
|
function usePluginCallbacks(cwd) {
|
|
549
|
-
return (0,
|
|
563
|
+
return (0, import_react3.useMemo)(() => {
|
|
550
564
|
const home = (0, import_node_os3.homedir)();
|
|
551
565
|
const pluginsDir = (0, import_node_path4.join)(home, ".robota", "plugins");
|
|
552
566
|
const userSettingsPath = (0, import_node_path4.join)(home, ".robota", "settings.json");
|
|
553
|
-
const settingsStore = new
|
|
554
|
-
const marketplace = new
|
|
555
|
-
const installer = new
|
|
567
|
+
const settingsStore = new import_agent_sdk3.PluginSettingsStore(userSettingsPath);
|
|
568
|
+
const marketplace = new import_agent_sdk3.MarketplaceClient({ pluginsDir });
|
|
569
|
+
const installer = new import_agent_sdk3.BundlePluginInstaller({
|
|
556
570
|
pluginsDir,
|
|
557
571
|
settingsStore,
|
|
558
572
|
marketplaceClient: marketplace
|
|
559
573
|
});
|
|
560
|
-
const loader = new
|
|
574
|
+
const loader = new import_agent_sdk3.BundlePluginLoader(pluginsDir);
|
|
561
575
|
return {
|
|
562
576
|
listInstalled: async () => {
|
|
563
577
|
const plugins = await loader.loadAll();
|
|
@@ -596,7 +610,7 @@ function usePluginCallbacks(cwd) {
|
|
|
596
610
|
}
|
|
597
611
|
if (scope === "project") {
|
|
598
612
|
const projectPluginsDir = (0, import_node_path4.join)(cwd, ".robota", "plugins");
|
|
599
|
-
const projectInstaller = new
|
|
613
|
+
const projectInstaller = new import_agent_sdk3.BundlePluginInstaller({
|
|
600
614
|
pluginsDir: projectPluginsDir,
|
|
601
615
|
settingsStore,
|
|
602
616
|
marketplaceClient: marketplace
|
|
@@ -644,10 +658,128 @@ function usePluginCallbacks(cwd) {
|
|
|
644
658
|
}, [cwd]);
|
|
645
659
|
}
|
|
646
660
|
|
|
647
|
-
// src/ui/
|
|
648
|
-
var
|
|
649
|
-
var
|
|
661
|
+
// src/ui/hooks/useSideEffects.ts
|
|
662
|
+
var import_react4 = require("react");
|
|
663
|
+
var import_ink = require("ink");
|
|
650
664
|
var import_agent_core2 = require("@robota-sdk/agent-core");
|
|
665
|
+
var EXIT_DELAY_MS = 500;
|
|
666
|
+
function useSideEffects({
|
|
667
|
+
interactiveSession,
|
|
668
|
+
addEntry,
|
|
669
|
+
baseHandleSubmit,
|
|
670
|
+
setSessionName
|
|
671
|
+
}) {
|
|
672
|
+
const { exit } = (0, import_ink.useApp)();
|
|
673
|
+
const [pendingModelId, setPendingModelId] = (0, import_react4.useState)(null);
|
|
674
|
+
const pendingModelChangeRef = (0, import_react4.useRef)(null);
|
|
675
|
+
const [showPluginTUI, setShowPluginTUI] = (0, import_react4.useState)(false);
|
|
676
|
+
const [showSessionPicker, setShowSessionPicker] = (0, import_react4.useState)(false);
|
|
677
|
+
const handleSubmit = (0, import_react4.useCallback)(
|
|
678
|
+
async (input) => {
|
|
679
|
+
await baseHandleSubmit(input);
|
|
680
|
+
const sideEffects = interactiveSession;
|
|
681
|
+
if (sideEffects._pendingModelId) {
|
|
682
|
+
const modelId = sideEffects._pendingModelId;
|
|
683
|
+
delete sideEffects._pendingModelId;
|
|
684
|
+
pendingModelChangeRef.current = modelId;
|
|
685
|
+
setPendingModelId(modelId);
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
688
|
+
if (sideEffects._pendingLanguage) {
|
|
689
|
+
const lang = sideEffects._pendingLanguage;
|
|
690
|
+
delete sideEffects._pendingLanguage;
|
|
691
|
+
const settingsPath = getUserSettingsPath();
|
|
692
|
+
const settings = readSettings(settingsPath);
|
|
693
|
+
settings.language = lang;
|
|
694
|
+
writeSettings(settingsPath, settings);
|
|
695
|
+
addEntry(
|
|
696
|
+
(0, import_agent_core2.messageToHistoryEntry)((0, import_agent_core2.createSystemMessage)(`Language set to "${lang}". Restarting...`))
|
|
697
|
+
);
|
|
698
|
+
setTimeout(() => exit(), EXIT_DELAY_MS);
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
if (sideEffects._resetRequested) {
|
|
702
|
+
delete sideEffects._resetRequested;
|
|
703
|
+
const settingsPath = getUserSettingsPath();
|
|
704
|
+
if (deleteSettings(settingsPath)) {
|
|
705
|
+
addEntry(
|
|
706
|
+
(0, import_agent_core2.messageToHistoryEntry)((0, import_agent_core2.createSystemMessage)(`Deleted ${settingsPath}. Exiting...`))
|
|
707
|
+
);
|
|
708
|
+
} else {
|
|
709
|
+
addEntry((0, import_agent_core2.messageToHistoryEntry)((0, import_agent_core2.createSystemMessage)("No user settings found.")));
|
|
710
|
+
}
|
|
711
|
+
setTimeout(() => exit(), EXIT_DELAY_MS);
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
if (sideEffects._exitRequested) {
|
|
715
|
+
delete sideEffects._exitRequested;
|
|
716
|
+
setTimeout(() => exit(), EXIT_DELAY_MS);
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
if (sideEffects._triggerPluginTUI) {
|
|
720
|
+
delete sideEffects._triggerPluginTUI;
|
|
721
|
+
setShowPluginTUI(true);
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
if (sideEffects._triggerResumePicker) {
|
|
725
|
+
delete sideEffects._triggerResumePicker;
|
|
726
|
+
setShowSessionPicker(true);
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
if (sideEffects._sessionName) {
|
|
730
|
+
const name = sideEffects._sessionName;
|
|
731
|
+
delete sideEffects._sessionName;
|
|
732
|
+
interactiveSession.setName(name);
|
|
733
|
+
setSessionName(name);
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
},
|
|
737
|
+
[interactiveSession, baseHandleSubmit, addEntry, exit, setSessionName]
|
|
738
|
+
);
|
|
739
|
+
const handleModelConfirm = (0, import_react4.useCallback)(
|
|
740
|
+
(index) => {
|
|
741
|
+
const modelId = pendingModelChangeRef.current;
|
|
742
|
+
setPendingModelId(null);
|
|
743
|
+
pendingModelChangeRef.current = null;
|
|
744
|
+
if (index === 0 && modelId) {
|
|
745
|
+
try {
|
|
746
|
+
const settingsPath = getUserSettingsPath();
|
|
747
|
+
updateModelInSettings(settingsPath, modelId);
|
|
748
|
+
addEntry(
|
|
749
|
+
(0, import_agent_core2.messageToHistoryEntry)(
|
|
750
|
+
(0, import_agent_core2.createSystemMessage)(`Model changed to ${(0, import_agent_core2.getModelName)(modelId)}. Restarting...`)
|
|
751
|
+
)
|
|
752
|
+
);
|
|
753
|
+
setTimeout(() => exit(), EXIT_DELAY_MS);
|
|
754
|
+
} catch (err) {
|
|
755
|
+
addEntry(
|
|
756
|
+
(0, import_agent_core2.messageToHistoryEntry)(
|
|
757
|
+
(0, import_agent_core2.createSystemMessage)(`Failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
758
|
+
)
|
|
759
|
+
);
|
|
760
|
+
}
|
|
761
|
+
} else {
|
|
762
|
+
addEntry((0, import_agent_core2.messageToHistoryEntry)((0, import_agent_core2.createSystemMessage)("Model change cancelled.")));
|
|
763
|
+
}
|
|
764
|
+
},
|
|
765
|
+
[addEntry, exit]
|
|
766
|
+
);
|
|
767
|
+
return {
|
|
768
|
+
handleSubmit,
|
|
769
|
+
pendingModelId,
|
|
770
|
+
showPluginTUI,
|
|
771
|
+
showSessionPicker,
|
|
772
|
+
setPendingModelId,
|
|
773
|
+
setShowPluginTUI,
|
|
774
|
+
setShowSessionPicker,
|
|
775
|
+
handleModelConfirm
|
|
776
|
+
};
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
// src/ui/MessageList.tsx
|
|
780
|
+
var import_react5 = __toESM(require("react"), 1);
|
|
781
|
+
var import_ink3 = require("ink");
|
|
782
|
+
var import_agent_core3 = require("@robota-sdk/agent-core");
|
|
651
783
|
|
|
652
784
|
// src/ui/render-markdown.ts
|
|
653
785
|
var import_marked = require("marked");
|
|
@@ -661,7 +793,7 @@ function renderMarkdown(md) {
|
|
|
661
793
|
}
|
|
662
794
|
|
|
663
795
|
// src/ui/DiffBlock.tsx
|
|
664
|
-
var
|
|
796
|
+
var import_ink2 = require("ink");
|
|
665
797
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
666
798
|
var MAX_DIFF_LINES = 12;
|
|
667
799
|
var TRUNCATED_SHOW = 10;
|
|
@@ -671,15 +803,15 @@ function DiffBlock({ file, lines }) {
|
|
|
671
803
|
const remaining = lines.length - TRUNCATED_SHOW;
|
|
672
804
|
const maxLineNum = Math.max(...visible.map((l) => l.lineNumber), 0);
|
|
673
805
|
const numWidth = String(maxLineNum).length;
|
|
674
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
675
|
-
file && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
806
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink2.Box, { flexDirection: "column", marginLeft: 4, children: [
|
|
807
|
+
file && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink2.Text, { color: "white", dimColor: true, children: [
|
|
676
808
|
"\u2502 ",
|
|
677
809
|
file
|
|
678
810
|
] }),
|
|
679
811
|
visible.map((line, i) => {
|
|
680
812
|
const lineNum = String(line.lineNumber).padStart(numWidth, " ");
|
|
681
813
|
if (line.type === "context") {
|
|
682
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
814
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink2.Text, { color: "white", dimColor: true, children: [
|
|
683
815
|
"\u2502 ",
|
|
684
816
|
lineNum,
|
|
685
817
|
" ",
|
|
@@ -689,7 +821,7 @@ function DiffBlock({ file, lines }) {
|
|
|
689
821
|
const prefix = line.type === "remove" ? "-" : "+";
|
|
690
822
|
const bgColor = line.type === "remove" ? "#5c1a1a" : "#1a3d1a";
|
|
691
823
|
const fgColor = line.type === "remove" ? "#ff9999" : "#99ff99";
|
|
692
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
824
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink2.Text, { color: fgColor, backgroundColor: bgColor, children: [
|
|
693
825
|
"\u2502 ",
|
|
694
826
|
lineNum,
|
|
695
827
|
" ",
|
|
@@ -698,7 +830,7 @@ function DiffBlock({ file, lines }) {
|
|
|
698
830
|
line.text
|
|
699
831
|
] }, i);
|
|
700
832
|
}),
|
|
701
|
-
truncated && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
833
|
+
truncated && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink2.Text, { color: "white", dimColor: true, children: [
|
|
702
834
|
"\u2502 ... and ",
|
|
703
835
|
remaining,
|
|
704
836
|
" more lines"
|
|
@@ -711,29 +843,29 @@ var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
|
711
843
|
function RoleLabel({ role }) {
|
|
712
844
|
switch (role) {
|
|
713
845
|
case "user":
|
|
714
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
846
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Text, { color: "green", bold: true, children: [
|
|
715
847
|
"You:",
|
|
716
848
|
" "
|
|
717
849
|
] });
|
|
718
850
|
case "assistant":
|
|
719
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
851
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Text, { color: "cyan", bold: true, children: [
|
|
720
852
|
"Robota:",
|
|
721
853
|
" "
|
|
722
854
|
] });
|
|
723
855
|
case "system":
|
|
724
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
856
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Text, { color: "yellow", bold: true, children: [
|
|
725
857
|
"System:",
|
|
726
858
|
" "
|
|
727
859
|
] });
|
|
728
860
|
case "tool":
|
|
729
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
861
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Text, { color: "white", bold: true, children: [
|
|
730
862
|
"Tool:",
|
|
731
863
|
" "
|
|
732
864
|
] });
|
|
733
865
|
}
|
|
734
866
|
}
|
|
735
867
|
function ToolMessage({ message }) {
|
|
736
|
-
if (!(0,
|
|
868
|
+
if (!(0, import_agent_core3.isToolMessage)(message)) {
|
|
737
869
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, {});
|
|
738
870
|
}
|
|
739
871
|
const toolName = message.name;
|
|
@@ -747,21 +879,21 @@ function ToolMessage({ message }) {
|
|
|
747
879
|
} catch {
|
|
748
880
|
}
|
|
749
881
|
if (summaries) {
|
|
750
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
751
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
752
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
882
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
883
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Box, { children: [
|
|
884
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Text, { color: "white", bold: true, children: [
|
|
753
885
|
"Tool:",
|
|
754
886
|
" "
|
|
755
887
|
] }),
|
|
756
|
-
toolName && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
888
|
+
toolName && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Text, { color: "white", dimColor: true, children: [
|
|
757
889
|
"[",
|
|
758
890
|
toolName,
|
|
759
891
|
"]"
|
|
760
892
|
] })
|
|
761
893
|
] }),
|
|
762
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
763
|
-
summaries.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
764
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
894
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink3.Text, { children: " " }),
|
|
895
|
+
summaries.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Box, { flexDirection: "column", children: [
|
|
896
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Text, { color: "green", children: [
|
|
765
897
|
" ",
|
|
766
898
|
"\u2713",
|
|
767
899
|
" ",
|
|
@@ -772,20 +904,20 @@ function ToolMessage({ message }) {
|
|
|
772
904
|
] });
|
|
773
905
|
}
|
|
774
906
|
const lines = content.split("\n").filter((l) => l.trim());
|
|
775
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
776
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
777
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
907
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
908
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Box, { children: [
|
|
909
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Text, { color: "white", bold: true, children: [
|
|
778
910
|
"Tool:",
|
|
779
911
|
" "
|
|
780
912
|
] }),
|
|
781
|
-
toolName && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
913
|
+
toolName && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Text, { color: "white", dimColor: true, children: [
|
|
782
914
|
"[",
|
|
783
915
|
toolName,
|
|
784
916
|
"]"
|
|
785
917
|
] })
|
|
786
918
|
] }),
|
|
787
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
788
|
-
lines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
919
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink3.Text, { children: " " }),
|
|
920
|
+
lines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Text, { color: "green", children: [
|
|
789
921
|
" ",
|
|
790
922
|
"\u2713",
|
|
791
923
|
" ",
|
|
@@ -793,30 +925,30 @@ function ToolMessage({ message }) {
|
|
|
793
925
|
] }, i))
|
|
794
926
|
] });
|
|
795
927
|
}
|
|
796
|
-
var MessageItem =
|
|
928
|
+
var MessageItem = import_react5.default.memo(function MessageItem2({
|
|
797
929
|
message
|
|
798
930
|
}) {
|
|
799
|
-
if ((0,
|
|
931
|
+
if ((0, import_agent_core3.isToolMessage)(message)) {
|
|
800
932
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ToolMessage, { message });
|
|
801
933
|
}
|
|
802
934
|
const content = message.content ?? "";
|
|
803
935
|
const isInterrupted = message.state === "interrupted";
|
|
804
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
805
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
806
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
807
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
936
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
937
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink3.Box, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RoleLabel, { role: message.role }) }),
|
|
938
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink3.Text, { children: " " }),
|
|
939
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink3.Box, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink3.Text, { wrap: "wrap", children: (0, import_agent_core3.isAssistantMessage)(message) ? renderMarkdown(content + (isInterrupted ? "\n\n_(interrupted)_" : "")) : content }) })
|
|
808
940
|
] });
|
|
809
941
|
});
|
|
810
942
|
function ToolSummaryEntry({ entry }) {
|
|
811
943
|
const data = entry.data;
|
|
812
944
|
const lines = data?.summary?.split("\n") ?? [];
|
|
813
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
814
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
945
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
946
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink3.Box, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Text, { color: "white", bold: true, children: [
|
|
815
947
|
"Tool:",
|
|
816
948
|
" "
|
|
817
949
|
] }) }),
|
|
818
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
819
|
-
lines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
950
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink3.Text, { children: " " }),
|
|
951
|
+
lines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Text, { color: "green", children: [
|
|
820
952
|
" ",
|
|
821
953
|
line
|
|
822
954
|
] }, i))
|
|
@@ -825,13 +957,13 @@ function ToolSummaryEntry({ entry }) {
|
|
|
825
957
|
function EventEntry({ entry }) {
|
|
826
958
|
const eventData = entry.data;
|
|
827
959
|
const eventMessage = typeof eventData?.message === "string" ? eventData.message : typeof eventData?.content === "string" ? eventData.content : entry.type;
|
|
828
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
829
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
960
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
961
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink3.Box, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink3.Text, { color: "yellow", bold: true, children: [
|
|
830
962
|
"System:",
|
|
831
963
|
" "
|
|
832
964
|
] }) }),
|
|
833
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
834
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
965
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink3.Text, { children: " " }),
|
|
966
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink3.Box, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink3.Text, { wrap: "wrap", children: eventMessage }) })
|
|
835
967
|
] });
|
|
836
968
|
}
|
|
837
969
|
function EntryItem({ entry }) {
|
|
@@ -848,12 +980,12 @@ function EntryItem({ entry }) {
|
|
|
848
980
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EventEntry, { entry });
|
|
849
981
|
}
|
|
850
982
|
function MessageList({ history }) {
|
|
851
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
983
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink3.Box, { flexDirection: "column", children: history.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EntryItem, { entry }, entry.id)) });
|
|
852
984
|
}
|
|
853
985
|
|
|
854
986
|
// src/ui/StatusBar.tsx
|
|
855
|
-
var
|
|
856
|
-
var
|
|
987
|
+
var import_ink4 = require("ink");
|
|
988
|
+
var import_agent_core4 = require("@robota-sdk/agent-core");
|
|
857
989
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
858
990
|
var CONTEXT_YELLOW_THRESHOLD = 70;
|
|
859
991
|
var CONTEXT_RED_THRESHOLD = 90;
|
|
@@ -875,7 +1007,7 @@ function StatusBar({
|
|
|
875
1007
|
}) {
|
|
876
1008
|
const contextColor = getContextColor(contextPercentage);
|
|
877
1009
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
878
|
-
|
|
1010
|
+
import_ink4.Box,
|
|
879
1011
|
{
|
|
880
1012
|
borderStyle: "single",
|
|
881
1013
|
borderColor: "gray",
|
|
@@ -883,30 +1015,30 @@ function StatusBar({
|
|
|
883
1015
|
paddingRight: 1,
|
|
884
1016
|
justifyContent: "space-between",
|
|
885
1017
|
children: [
|
|
886
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
887
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1018
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_ink4.Text, { children: [
|
|
1019
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ink4.Text, { color: "cyan", bold: true, children: "Mode:" }),
|
|
888
1020
|
" ",
|
|
889
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1021
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ink4.Text, { children: permissionMode }),
|
|
890
1022
|
sessionName && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
891
1023
|
" | ",
|
|
892
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1024
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ink4.Text, { color: "magenta", children: sessionName })
|
|
893
1025
|
] }),
|
|
894
1026
|
" | ",
|
|
895
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1027
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ink4.Text, { dimColor: true, children: modelName }),
|
|
896
1028
|
" | ",
|
|
897
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1029
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_ink4.Text, { color: contextColor, children: [
|
|
898
1030
|
"Context: ",
|
|
899
1031
|
Math.round(contextPercentage),
|
|
900
1032
|
"% (",
|
|
901
|
-
(0,
|
|
1033
|
+
(0, import_agent_core4.formatTokenCount)(contextUsedTokens),
|
|
902
1034
|
"/",
|
|
903
|
-
(0,
|
|
1035
|
+
(0, import_agent_core4.formatTokenCount)(contextMaxTokens),
|
|
904
1036
|
")"
|
|
905
1037
|
] })
|
|
906
1038
|
] }),
|
|
907
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
908
|
-
isThinking && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
909
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1039
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_ink4.Text, { children: [
|
|
1040
|
+
isThinking && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ink4.Text, { color: "yellow", children: "Thinking... " }),
|
|
1041
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_ink4.Text, { dimColor: true, children: [
|
|
910
1042
|
"msgs: ",
|
|
911
1043
|
messageCount
|
|
912
1044
|
] })
|
|
@@ -917,12 +1049,12 @@ function StatusBar({
|
|
|
917
1049
|
}
|
|
918
1050
|
|
|
919
1051
|
// src/ui/InputArea.tsx
|
|
920
|
-
var
|
|
921
|
-
var
|
|
1052
|
+
var import_react9 = require("react");
|
|
1053
|
+
var import_ink8 = require("ink");
|
|
922
1054
|
|
|
923
1055
|
// src/ui/CjkTextInput.tsx
|
|
924
|
-
var
|
|
925
|
-
var
|
|
1056
|
+
var import_react6 = require("react");
|
|
1057
|
+
var import_ink5 = require("ink");
|
|
926
1058
|
var import_chalk = __toESM(require("chalk"), 1);
|
|
927
1059
|
var import_string_width = __toESM(require("string-width"), 1);
|
|
928
1060
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
@@ -968,16 +1100,16 @@ function CjkTextInput({
|
|
|
968
1100
|
availableWidth,
|
|
969
1101
|
cursorHint = null
|
|
970
1102
|
}) {
|
|
971
|
-
const valueRef = (0,
|
|
972
|
-
const cursorRef = (0,
|
|
973
|
-
const [, forceRender] = (0,
|
|
974
|
-
const isPastingRef = (0,
|
|
975
|
-
const pasteBufferRef = (0,
|
|
1103
|
+
const valueRef = (0, import_react6.useRef)(value);
|
|
1104
|
+
const cursorRef = (0, import_react6.useRef)(value.length);
|
|
1105
|
+
const [, forceRender] = (0, import_react6.useState)(0);
|
|
1106
|
+
const isPastingRef = (0, import_react6.useRef)(false);
|
|
1107
|
+
const pasteBufferRef = (0, import_react6.useRef)("");
|
|
976
1108
|
if (value !== valueRef.current) {
|
|
977
1109
|
valueRef.current = value;
|
|
978
1110
|
cursorRef.current = cursorHint != null ? Math.min(cursorHint, value.length) : value.length;
|
|
979
1111
|
}
|
|
980
|
-
(0,
|
|
1112
|
+
(0, import_ink5.useInput)(
|
|
981
1113
|
(input, key) => {
|
|
982
1114
|
try {
|
|
983
1115
|
if (input === PASTE_START || input.startsWith(PASTE_START)) {
|
|
@@ -1074,7 +1206,7 @@ function CjkTextInput({
|
|
|
1074
1206
|
},
|
|
1075
1207
|
{ isActive: focus }
|
|
1076
1208
|
);
|
|
1077
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1209
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ink5.Text, { children: renderWithCursor(valueRef.current, cursorRef.current, placeholder, showCursor && focus) });
|
|
1078
1210
|
}
|
|
1079
1211
|
function renderWithCursor(value, cursorOffset, placeholder, showCursor) {
|
|
1080
1212
|
if (!showCursor) {
|
|
@@ -1099,30 +1231,30 @@ function renderWithCursor(value, cursorOffset, placeholder, showCursor) {
|
|
|
1099
1231
|
}
|
|
1100
1232
|
|
|
1101
1233
|
// src/ui/WaveText.tsx
|
|
1102
|
-
var
|
|
1103
|
-
var
|
|
1234
|
+
var import_react7 = require("react");
|
|
1235
|
+
var import_ink6 = require("ink");
|
|
1104
1236
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1105
1237
|
var WAVE_COLORS = ["#666666", "#888888", "#aaaaaa", "#888888"];
|
|
1106
1238
|
var INTERVAL_MS = 400;
|
|
1107
1239
|
var CHARS_PER_GROUP = 4;
|
|
1108
1240
|
function WaveText({ text }) {
|
|
1109
|
-
const [tick, setTick] = (0,
|
|
1110
|
-
(0,
|
|
1241
|
+
const [tick, setTick] = (0, import_react7.useState)(0);
|
|
1242
|
+
(0, import_react7.useEffect)(() => {
|
|
1111
1243
|
const timer = setInterval(() => {
|
|
1112
1244
|
setTick((prev) => prev + 1);
|
|
1113
1245
|
}, INTERVAL_MS);
|
|
1114
1246
|
return () => clearInterval(timer);
|
|
1115
1247
|
}, []);
|
|
1116
1248
|
const chars = [...text];
|
|
1117
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1249
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_ink6.Text, { children: chars.map((char, i) => {
|
|
1118
1250
|
const group = Math.floor(i / CHARS_PER_GROUP);
|
|
1119
1251
|
const colorIndex = (tick + group) % WAVE_COLORS.length;
|
|
1120
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1252
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_ink6.Text, { color: WAVE_COLORS[colorIndex], children: char }, i);
|
|
1121
1253
|
}) });
|
|
1122
1254
|
}
|
|
1123
1255
|
|
|
1124
1256
|
// src/ui/SlashAutocomplete.tsx
|
|
1125
|
-
var
|
|
1257
|
+
var import_ink7 = require("ink");
|
|
1126
1258
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1127
1259
|
var MAX_VISIBLE = 8;
|
|
1128
1260
|
function CommandRow(props) {
|
|
@@ -1130,7 +1262,7 @@ function CommandRow(props) {
|
|
|
1130
1262
|
const indicator = isSelected ? "\u25B8 " : " ";
|
|
1131
1263
|
const nameColor = isSelected ? "cyan" : void 0;
|
|
1132
1264
|
const dimmed = !isSelected;
|
|
1133
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1265
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_ink7.Box, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_ink7.Text, { color: nameColor, dimColor: dimmed, children: [
|
|
1134
1266
|
indicator,
|
|
1135
1267
|
showSlash ? `/${cmd.name} ${cmd.description}` : cmd.description
|
|
1136
1268
|
] }) });
|
|
@@ -1144,7 +1276,7 @@ function SlashAutocomplete({
|
|
|
1144
1276
|
if (!visible || commands.length === 0) return null;
|
|
1145
1277
|
const scrollOffset = computeScrollOffset(selectedIndex, commands.length);
|
|
1146
1278
|
const visibleCommands = commands.slice(scrollOffset, scrollOffset + MAX_VISIBLE);
|
|
1147
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1279
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_ink7.Box, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1, children: visibleCommands.map((cmd, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1148
1280
|
CommandRow,
|
|
1149
1281
|
{
|
|
1150
1282
|
cmd,
|
|
@@ -1167,8 +1299,8 @@ function expandPasteLabels(text, store) {
|
|
|
1167
1299
|
return text.replace(PASTE_LABEL_RE, (_, id) => store.get(Number(id)) ?? "");
|
|
1168
1300
|
}
|
|
1169
1301
|
|
|
1170
|
-
// src/ui/
|
|
1171
|
-
var
|
|
1302
|
+
// src/ui/hooks/useAutocomplete.ts
|
|
1303
|
+
var import_react8 = __toESM(require("react"), 1);
|
|
1172
1304
|
function parseSlashInput(value) {
|
|
1173
1305
|
if (!value.startsWith("/")) return { isSlash: false, parentCommand: "", filter: "" };
|
|
1174
1306
|
const afterSlash = value.slice(1);
|
|
@@ -1179,16 +1311,16 @@ function parseSlashInput(value) {
|
|
|
1179
1311
|
return { isSlash: true, parentCommand: parent, filter: rest };
|
|
1180
1312
|
}
|
|
1181
1313
|
function useAutocomplete(value, registry) {
|
|
1182
|
-
const [selectedIndex, setSelectedIndex] = (0,
|
|
1183
|
-
const [dismissed, setDismissed] = (0,
|
|
1184
|
-
const prevValueRef =
|
|
1314
|
+
const [selectedIndex, setSelectedIndex] = (0, import_react8.useState)(0);
|
|
1315
|
+
const [dismissed, setDismissed] = (0, import_react8.useState)(false);
|
|
1316
|
+
const prevValueRef = import_react8.default.useRef(value);
|
|
1185
1317
|
if (prevValueRef.current !== value) {
|
|
1186
1318
|
prevValueRef.current = value;
|
|
1187
1319
|
if (dismissed) setDismissed(false);
|
|
1188
1320
|
}
|
|
1189
1321
|
const parsed = parseSlashInput(value);
|
|
1190
1322
|
const isSubcommandMode = parsed.isSlash && parsed.parentCommand.length > 0;
|
|
1191
|
-
const filteredCommands = (0,
|
|
1323
|
+
const filteredCommands = (0, import_react8.useMemo)(() => {
|
|
1192
1324
|
if (!registry || !parsed.isSlash || dismissed) return [];
|
|
1193
1325
|
if (isSubcommandMode) {
|
|
1194
1326
|
const subs = registry.getSubcommands(parsed.parentCommand);
|
|
@@ -1221,6 +1353,9 @@ function useAutocomplete(value, registry) {
|
|
|
1221
1353
|
}
|
|
1222
1354
|
};
|
|
1223
1355
|
}
|
|
1356
|
+
|
|
1357
|
+
// src/ui/InputArea.tsx
|
|
1358
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1224
1359
|
var BORDER_HORIZONTAL = 2;
|
|
1225
1360
|
var PADDING_LEFT = 1;
|
|
1226
1361
|
var PROMPT_WIDTH = 2;
|
|
@@ -1234,13 +1369,13 @@ function InputArea({
|
|
|
1234
1369
|
registry,
|
|
1235
1370
|
sessionName
|
|
1236
1371
|
}) {
|
|
1237
|
-
const [value, setValue] = (0,
|
|
1238
|
-
const [cursorHint, setCursorHint] = (0,
|
|
1239
|
-
const pasteStore = (0,
|
|
1240
|
-
const { stdout } = (0,
|
|
1372
|
+
const [value, setValue] = (0, import_react9.useState)("");
|
|
1373
|
+
const [cursorHint, setCursorHint] = (0, import_react9.useState)(null);
|
|
1374
|
+
const pasteStore = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
|
|
1375
|
+
const { stdout } = (0, import_ink8.useStdout)();
|
|
1241
1376
|
const terminalColumns = stdout?.columns ?? 80;
|
|
1242
1377
|
const availableWidth = Math.max(1, terminalColumns - INPUT_AREA_OVERHEAD);
|
|
1243
|
-
const pasteIdRef = (0,
|
|
1378
|
+
const pasteIdRef = (0, import_react9.useRef)(0);
|
|
1244
1379
|
const {
|
|
1245
1380
|
showPopup,
|
|
1246
1381
|
filteredCommands,
|
|
@@ -1249,7 +1384,7 @@ function InputArea({
|
|
|
1249
1384
|
isSubcommandMode,
|
|
1250
1385
|
setShowPopup
|
|
1251
1386
|
} = useAutocomplete(value, registry);
|
|
1252
|
-
const handlePaste = (0,
|
|
1387
|
+
const handlePaste = (0, import_react9.useCallback)((text, cursorPosition) => {
|
|
1253
1388
|
pasteIdRef.current += 1;
|
|
1254
1389
|
const id = pasteIdRef.current;
|
|
1255
1390
|
pasteStore.current.set(id, text);
|
|
@@ -1259,7 +1394,7 @@ function InputArea({
|
|
|
1259
1394
|
setCursorHint(newCursorPos);
|
|
1260
1395
|
setValue((prev) => prev.slice(0, cursorPosition) + label + prev.slice(cursorPosition));
|
|
1261
1396
|
}, []);
|
|
1262
|
-
const tabCompleteCommand = (0,
|
|
1397
|
+
const tabCompleteCommand = (0, import_react9.useCallback)(
|
|
1263
1398
|
(cmd) => {
|
|
1264
1399
|
const parsed = parseSlashInput(value);
|
|
1265
1400
|
if (parsed.parentCommand) {
|
|
@@ -1275,7 +1410,7 @@ function InputArea({
|
|
|
1275
1410
|
},
|
|
1276
1411
|
[value, setSelectedIndex]
|
|
1277
1412
|
);
|
|
1278
|
-
const enterSelectCommand = (0,
|
|
1413
|
+
const enterSelectCommand = (0, import_react9.useCallback)(
|
|
1279
1414
|
(cmd) => {
|
|
1280
1415
|
const parsed = parseSlashInput(value);
|
|
1281
1416
|
if (parsed.parentCommand) {
|
|
@@ -1294,7 +1429,7 @@ function InputArea({
|
|
|
1294
1429
|
},
|
|
1295
1430
|
[value, onSubmit, setSelectedIndex]
|
|
1296
1431
|
);
|
|
1297
|
-
const handleSubmit = (0,
|
|
1432
|
+
const handleSubmit = (0, import_react9.useCallback)(
|
|
1298
1433
|
(text) => {
|
|
1299
1434
|
const trimmed = text.trim();
|
|
1300
1435
|
if (trimmed.length === 0) return;
|
|
@@ -1310,7 +1445,7 @@ function InputArea({
|
|
|
1310
1445
|
},
|
|
1311
1446
|
[showPopup, filteredCommands, selectedIndex, onSubmit, enterSelectCommand]
|
|
1312
1447
|
);
|
|
1313
|
-
(0,
|
|
1448
|
+
(0, import_ink8.useInput)(
|
|
1314
1449
|
(_input, key) => {
|
|
1315
1450
|
if (!showPopup) return;
|
|
1316
1451
|
if (key.upArrow) {
|
|
@@ -1326,7 +1461,7 @@ function InputArea({
|
|
|
1326
1461
|
},
|
|
1327
1462
|
{ isActive: showPopup && !isDisabled }
|
|
1328
1463
|
);
|
|
1329
|
-
(0,
|
|
1464
|
+
(0, import_ink8.useInput)(
|
|
1330
1465
|
(_input, key) => {
|
|
1331
1466
|
if ((key.backspace || key.delete) && pendingPrompt) {
|
|
1332
1467
|
onCancelQueue?.();
|
|
@@ -1345,7 +1480,7 @@ function InputArea({
|
|
|
1345
1480
|
}
|
|
1346
1481
|
return { left: "\u250C" + "\u2500".repeat(innerWidth), label: "", right: "\u2510" };
|
|
1347
1482
|
})();
|
|
1348
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1483
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_ink8.Box, { flexDirection: "column", children: [
|
|
1349
1484
|
showPopup && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1350
1485
|
SlashAutocomplete,
|
|
1351
1486
|
{
|
|
@@ -1355,19 +1490,19 @@ function InputArea({
|
|
|
1355
1490
|
isSubcommandMode
|
|
1356
1491
|
}
|
|
1357
1492
|
),
|
|
1358
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1493
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_ink8.Text, { color: borderColor, children: [
|
|
1359
1494
|
topBorder.left,
|
|
1360
|
-
topBorder.label ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1495
|
+
topBorder.label ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_ink8.Text, { backgroundColor: borderColor, color: "black", bold: true, children: topBorder.label }) : null,
|
|
1361
1496
|
topBorder.right
|
|
1362
1497
|
] }),
|
|
1363
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1498
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_ink8.Box, { borderStyle: "single", borderTop: false, borderColor, paddingLeft: 1, children: isAborting ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_ink8.Text, { color: "yellow", children: " Interrupting..." }) : pendingPrompt ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_ink8.Text, { color: "cyan", children: [
|
|
1364
1499
|
" ",
|
|
1365
1500
|
"Queued: ",
|
|
1366
1501
|
pendingPrompt.length > 50 ? pendingPrompt.slice(0, 47) + "..." : pendingPrompt,
|
|
1367
1502
|
" ",
|
|
1368
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1369
|
-
] }) : isDisabled ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(WaveText, { text: " Waiting for response... (ESC to interrupt)" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1370
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1503
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_ink8.Text, { dimColor: true, children: "(Backspace to cancel)" })
|
|
1504
|
+
] }) : isDisabled ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(WaveText, { text: " Waiting for response... (ESC to interrupt)" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_ink8.Box, { children: [
|
|
1505
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_ink8.Text, { color: "green", bold: true, children: "> " }),
|
|
1371
1506
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1372
1507
|
CjkTextInput,
|
|
1373
1508
|
{
|
|
@@ -1388,17 +1523,17 @@ function InputArea({
|
|
|
1388
1523
|
}
|
|
1389
1524
|
|
|
1390
1525
|
// src/ui/ConfirmPrompt.tsx
|
|
1391
|
-
var
|
|
1392
|
-
var
|
|
1526
|
+
var import_react10 = require("react");
|
|
1527
|
+
var import_ink9 = require("ink");
|
|
1393
1528
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1394
1529
|
function ConfirmPrompt({
|
|
1395
1530
|
message,
|
|
1396
1531
|
options = ["Yes", "No"],
|
|
1397
1532
|
onSelect
|
|
1398
1533
|
}) {
|
|
1399
|
-
const [selected, setSelected] = (0,
|
|
1400
|
-
const resolvedRef = (0,
|
|
1401
|
-
const doSelect = (0,
|
|
1534
|
+
const [selected, setSelected] = (0, import_react10.useState)(0);
|
|
1535
|
+
const resolvedRef = (0, import_react10.useRef)(false);
|
|
1536
|
+
const doSelect = (0, import_react10.useCallback)(
|
|
1402
1537
|
(index) => {
|
|
1403
1538
|
if (resolvedRef.current) return;
|
|
1404
1539
|
resolvedRef.current = true;
|
|
@@ -1406,7 +1541,7 @@ function ConfirmPrompt({
|
|
|
1406
1541
|
},
|
|
1407
1542
|
[onSelect]
|
|
1408
1543
|
);
|
|
1409
|
-
(0,
|
|
1544
|
+
(0, import_ink9.useInput)((input, key) => {
|
|
1410
1545
|
if (resolvedRef.current) return;
|
|
1411
1546
|
if (key.leftArrow || key.upArrow) {
|
|
1412
1547
|
setSelected((prev) => prev > 0 ? prev - 1 : prev);
|
|
@@ -1420,19 +1555,19 @@ function ConfirmPrompt({
|
|
|
1420
1555
|
doSelect(1);
|
|
1421
1556
|
}
|
|
1422
1557
|
});
|
|
1423
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1424
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1425
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1558
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_ink9.Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
1559
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_ink9.Text, { color: "yellow", children: message }),
|
|
1560
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_ink9.Box, { marginTop: 1, children: options.map((opt, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_ink9.Box, { marginRight: 2, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_ink9.Text, { color: i === selected ? "cyan" : void 0, bold: i === selected, children: [
|
|
1426
1561
|
i === selected ? "> " : " ",
|
|
1427
1562
|
opt
|
|
1428
1563
|
] }) }, opt)) }),
|
|
1429
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1564
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_ink9.Text, { dimColor: true, children: " arrow keys to select, Enter to confirm" })
|
|
1430
1565
|
] });
|
|
1431
1566
|
}
|
|
1432
1567
|
|
|
1433
1568
|
// src/ui/PermissionPrompt.tsx
|
|
1434
|
-
var
|
|
1435
|
-
var
|
|
1569
|
+
var import_react11 = __toESM(require("react"), 1);
|
|
1570
|
+
var import_ink10 = require("ink");
|
|
1436
1571
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1437
1572
|
var OPTIONS = ["Allow", "Allow always (this session)", "Deny"];
|
|
1438
1573
|
function formatArgs(args) {
|
|
@@ -1441,15 +1576,15 @@ function formatArgs(args) {
|
|
|
1441
1576
|
return entries.map(([k, v]) => `${k}: ${typeof v === "string" ? v : JSON.stringify(v)}`).join(", ");
|
|
1442
1577
|
}
|
|
1443
1578
|
function PermissionPrompt({ request }) {
|
|
1444
|
-
const [selected, setSelected] =
|
|
1445
|
-
const resolvedRef =
|
|
1446
|
-
const prevRequestRef =
|
|
1579
|
+
const [selected, setSelected] = import_react11.default.useState(0);
|
|
1580
|
+
const resolvedRef = import_react11.default.useRef(false);
|
|
1581
|
+
const prevRequestRef = import_react11.default.useRef(request);
|
|
1447
1582
|
if (prevRequestRef.current !== request) {
|
|
1448
1583
|
prevRequestRef.current = request;
|
|
1449
1584
|
resolvedRef.current = false;
|
|
1450
1585
|
setSelected(0);
|
|
1451
1586
|
}
|
|
1452
|
-
const doResolve =
|
|
1587
|
+
const doResolve = import_react11.default.useCallback(
|
|
1453
1588
|
(index) => {
|
|
1454
1589
|
if (resolvedRef.current) return;
|
|
1455
1590
|
resolvedRef.current = true;
|
|
@@ -1459,7 +1594,7 @@ function PermissionPrompt({ request }) {
|
|
|
1459
1594
|
},
|
|
1460
1595
|
[request]
|
|
1461
1596
|
);
|
|
1462
|
-
(0,
|
|
1597
|
+
(0, import_ink10.useInput)((input, key) => {
|
|
1463
1598
|
if (resolvedRef.current) return;
|
|
1464
1599
|
if (key.upArrow || key.leftArrow) {
|
|
1465
1600
|
setSelected((prev) => prev > 0 ? prev - 1 : prev);
|
|
@@ -1475,27 +1610,27 @@ function PermissionPrompt({ request }) {
|
|
|
1475
1610
|
doResolve(2);
|
|
1476
1611
|
}
|
|
1477
1612
|
});
|
|
1478
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1479
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1480
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1613
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink10.Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
1614
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink10.Text, { color: "yellow", bold: true, children: "[Permission Required]" }),
|
|
1615
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink10.Text, { children: [
|
|
1481
1616
|
"Tool:",
|
|
1482
1617
|
" ",
|
|
1483
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1618
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink10.Text, { color: "cyan", bold: true, children: request.toolName })
|
|
1484
1619
|
] }),
|
|
1485
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1620
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink10.Text, { dimColor: true, children: [
|
|
1486
1621
|
" ",
|
|
1487
1622
|
formatArgs(request.toolArgs)
|
|
1488
1623
|
] }),
|
|
1489
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1624
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink10.Box, { marginTop: 1, children: OPTIONS.map((opt, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink10.Box, { marginRight: 2, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink10.Text, { color: i === selected ? "cyan" : void 0, bold: i === selected, children: [
|
|
1490
1625
|
i === selected ? "> " : " ",
|
|
1491
1626
|
opt
|
|
1492
1627
|
] }) }, opt)) }),
|
|
1493
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1628
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink10.Text, { dimColor: true, children: " left/right to select, Enter to confirm" })
|
|
1494
1629
|
] });
|
|
1495
1630
|
}
|
|
1496
1631
|
|
|
1497
1632
|
// src/ui/StreamingIndicator.tsx
|
|
1498
|
-
var
|
|
1633
|
+
var import_ink11 = require("ink");
|
|
1499
1634
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1500
1635
|
function getToolStyle(t) {
|
|
1501
1636
|
if (t.isRunning) return { color: "yellow", icon: "\u27F3", strikethrough: false };
|
|
@@ -1509,14 +1644,14 @@ function StreamingIndicator({ text, activeTools }) {
|
|
|
1509
1644
|
if (!hasTools && !hasText) {
|
|
1510
1645
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, {});
|
|
1511
1646
|
}
|
|
1512
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1513
|
-
hasTools && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1514
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1515
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1647
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_ink11.Box, { flexDirection: "column", children: [
|
|
1648
|
+
hasTools && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_ink11.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
1649
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ink11.Text, { color: "white", bold: true, children: "Tools:" }),
|
|
1650
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ink11.Text, { children: " " }),
|
|
1516
1651
|
activeTools.map((t, i) => {
|
|
1517
1652
|
const { color, icon, strikethrough } = getToolStyle(t);
|
|
1518
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1519
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1653
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_ink11.Box, { flexDirection: "column", children: [
|
|
1654
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_ink11.Text, { color, strikethrough, children: [
|
|
1520
1655
|
" ",
|
|
1521
1656
|
icon,
|
|
1522
1657
|
" ",
|
|
@@ -1529,20 +1664,20 @@ function StreamingIndicator({ text, activeTools }) {
|
|
|
1529
1664
|
] }, `${t.toolName}-${i}`);
|
|
1530
1665
|
})
|
|
1531
1666
|
] }),
|
|
1532
|
-
hasText && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1533
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1534
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1535
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1667
|
+
hasText && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_ink11.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
1668
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ink11.Text, { color: "cyan", bold: true, children: "Robota:" }),
|
|
1669
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ink11.Text, { children: " " }),
|
|
1670
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ink11.Box, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ink11.Text, { wrap: "wrap", children: renderMarkdown(text) }) })
|
|
1536
1671
|
] })
|
|
1537
1672
|
] });
|
|
1538
1673
|
}
|
|
1539
1674
|
|
|
1540
1675
|
// src/ui/PluginTUI.tsx
|
|
1541
|
-
var
|
|
1676
|
+
var import_react15 = require("react");
|
|
1542
1677
|
|
|
1543
1678
|
// src/ui/MenuSelect.tsx
|
|
1544
|
-
var
|
|
1545
|
-
var
|
|
1679
|
+
var import_react12 = require("react");
|
|
1680
|
+
var import_ink12 = require("ink");
|
|
1546
1681
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1547
1682
|
function MenuSelect({
|
|
1548
1683
|
title,
|
|
@@ -1552,10 +1687,10 @@ function MenuSelect({
|
|
|
1552
1687
|
loading,
|
|
1553
1688
|
error
|
|
1554
1689
|
}) {
|
|
1555
|
-
const [selected, setSelected] = (0,
|
|
1556
|
-
const selectedRef = (0,
|
|
1557
|
-
const resolvedRef = (0,
|
|
1558
|
-
const doSelect = (0,
|
|
1690
|
+
const [selected, setSelected] = (0, import_react12.useState)(0);
|
|
1691
|
+
const selectedRef = (0, import_react12.useRef)(0);
|
|
1692
|
+
const resolvedRef = (0, import_react12.useRef)(false);
|
|
1693
|
+
const doSelect = (0, import_react12.useCallback)(
|
|
1559
1694
|
(index) => {
|
|
1560
1695
|
if (resolvedRef.current || items.length === 0) return;
|
|
1561
1696
|
resolvedRef.current = true;
|
|
@@ -1563,7 +1698,7 @@ function MenuSelect({
|
|
|
1563
1698
|
},
|
|
1564
1699
|
[items, onSelect]
|
|
1565
1700
|
);
|
|
1566
|
-
(0,
|
|
1701
|
+
(0, import_ink12.useInput)((input, key) => {
|
|
1567
1702
|
if (resolvedRef.current) return;
|
|
1568
1703
|
if (key.escape) {
|
|
1569
1704
|
resolvedRef.current = true;
|
|
@@ -1583,30 +1718,30 @@ function MenuSelect({
|
|
|
1583
1718
|
doSelect(selectedRef.current);
|
|
1584
1719
|
}
|
|
1585
1720
|
});
|
|
1586
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1587
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1588
|
-
loading && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1589
|
-
error && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1590
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1591
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1721
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_ink12.Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
1722
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_ink12.Text, { color: "yellow", bold: true, children: title }),
|
|
1723
|
+
loading && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_ink12.Box, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_ink12.Text, { dimColor: true, children: "Loading..." }) }),
|
|
1724
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_ink12.Box, { marginTop: 1, flexDirection: "column", children: [
|
|
1725
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_ink12.Text, { color: "red", children: error }),
|
|
1726
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_ink12.Text, { dimColor: true, children: "Press Esc to go back" })
|
|
1592
1727
|
] }),
|
|
1593
|
-
!loading && !error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1594
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1728
|
+
!loading && !error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_ink12.Box, { flexDirection: "column", marginTop: 1, children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_ink12.Box, { children: [
|
|
1729
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_ink12.Text, { color: i === selected ? "cyan" : void 0, bold: i === selected, children: [
|
|
1595
1730
|
i === selected ? "> " : " ",
|
|
1596
1731
|
item.label
|
|
1597
1732
|
] }),
|
|
1598
|
-
item.hint && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1733
|
+
item.hint && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_ink12.Text, { dimColor: true, children: [
|
|
1599
1734
|
" ",
|
|
1600
1735
|
item.hint
|
|
1601
1736
|
] })
|
|
1602
1737
|
] }, item.value)) }),
|
|
1603
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1738
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_ink12.Text, { dimColor: true, children: loading || error ? "" : " \u2191\u2193 Navigate Enter Select Esc Back" })
|
|
1604
1739
|
] });
|
|
1605
1740
|
}
|
|
1606
1741
|
|
|
1607
1742
|
// src/ui/TextPrompt.tsx
|
|
1608
|
-
var
|
|
1609
|
-
var
|
|
1743
|
+
var import_react13 = require("react");
|
|
1744
|
+
var import_ink13 = require("ink");
|
|
1610
1745
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1611
1746
|
function TextPrompt({
|
|
1612
1747
|
title,
|
|
@@ -1615,11 +1750,11 @@ function TextPrompt({
|
|
|
1615
1750
|
onCancel,
|
|
1616
1751
|
validate
|
|
1617
1752
|
}) {
|
|
1618
|
-
const [value, setValue] = (0,
|
|
1619
|
-
const [error, setError] = (0,
|
|
1620
|
-
const resolvedRef = (0,
|
|
1621
|
-
const valueRef = (0,
|
|
1622
|
-
const handleSubmit = (0,
|
|
1753
|
+
const [value, setValue] = (0, import_react13.useState)("");
|
|
1754
|
+
const [error, setError] = (0, import_react13.useState)();
|
|
1755
|
+
const resolvedRef = (0, import_react13.useRef)(false);
|
|
1756
|
+
const valueRef = (0, import_react13.useRef)("");
|
|
1757
|
+
const handleSubmit = (0, import_react13.useCallback)(() => {
|
|
1623
1758
|
if (resolvedRef.current) return;
|
|
1624
1759
|
const trimmed = valueRef.current.trim();
|
|
1625
1760
|
if (!trimmed) return;
|
|
@@ -1633,7 +1768,7 @@ function TextPrompt({
|
|
|
1633
1768
|
resolvedRef.current = true;
|
|
1634
1769
|
onSubmit(trimmed);
|
|
1635
1770
|
}, [validate, onSubmit]);
|
|
1636
|
-
(0,
|
|
1771
|
+
(0, import_ink13.useInput)((input, key) => {
|
|
1637
1772
|
if (resolvedRef.current) return;
|
|
1638
1773
|
if (key.escape) {
|
|
1639
1774
|
resolvedRef.current = true;
|
|
@@ -1656,15 +1791,15 @@ function TextPrompt({
|
|
|
1656
1791
|
setError(void 0);
|
|
1657
1792
|
}
|
|
1658
1793
|
});
|
|
1659
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
1660
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1661
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
1662
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1663
|
-
value ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1664
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1794
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_ink13.Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
1795
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink13.Text, { color: "yellow", bold: true, children: title }),
|
|
1796
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_ink13.Box, { marginTop: 1, children: [
|
|
1797
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink13.Text, { color: "cyan", children: "> " }),
|
|
1798
|
+
value ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink13.Text, { children: value }) : placeholder ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink13.Text, { dimColor: true, children: placeholder }) : null,
|
|
1799
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink13.Text, { color: "cyan", children: "\u2588" })
|
|
1665
1800
|
] }),
|
|
1666
|
-
error && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1667
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1801
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink13.Text, { color: "red", children: error }),
|
|
1802
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink13.Text, { dimColor: true, children: " Enter Submit Esc Cancel" })
|
|
1668
1803
|
] });
|
|
1669
1804
|
}
|
|
1670
1805
|
|
|
@@ -1760,61 +1895,16 @@ function handleInstalledActionSelect(value, pluginId, callbacks, nav) {
|
|
|
1760
1895
|
}
|
|
1761
1896
|
}
|
|
1762
1897
|
|
|
1763
|
-
// src/ui/
|
|
1764
|
-
var
|
|
1765
|
-
function
|
|
1766
|
-
const [
|
|
1767
|
-
const [
|
|
1768
|
-
const [
|
|
1769
|
-
|
|
1770
|
-
const [confirm, setConfirm] = (0, import_react11.useState)();
|
|
1771
|
-
const [refreshCounter, setRefreshCounter] = (0, import_react11.useState)(0);
|
|
1772
|
-
const current = stack[stack.length - 1] ?? { screen: "main" };
|
|
1773
|
-
const push = (0, import_react11.useCallback)((state) => {
|
|
1774
|
-
setStack((prev) => [...prev, state]);
|
|
1898
|
+
// src/ui/hooks/usePluginScreenData.ts
|
|
1899
|
+
var import_react14 = require("react");
|
|
1900
|
+
function usePluginScreenData(screen, marketplace, callbacks, refreshCounter, stackLength) {
|
|
1901
|
+
const [items, setItems] = (0, import_react14.useState)([]);
|
|
1902
|
+
const [loading, setLoading] = (0, import_react14.useState)(false);
|
|
1903
|
+
const [error, setError] = (0, import_react14.useState)();
|
|
1904
|
+
(0, import_react14.useEffect)(() => {
|
|
1775
1905
|
setItems([]);
|
|
1776
1906
|
setError(void 0);
|
|
1777
|
-
|
|
1778
|
-
const pop = (0, import_react11.useCallback)(() => {
|
|
1779
|
-
setStack((prev) => {
|
|
1780
|
-
if (prev.length <= 1) {
|
|
1781
|
-
onClose();
|
|
1782
|
-
return prev;
|
|
1783
|
-
}
|
|
1784
|
-
return prev.slice(0, -1);
|
|
1785
|
-
});
|
|
1786
|
-
setItems([]);
|
|
1787
|
-
setError(void 0);
|
|
1788
|
-
}, [onClose]);
|
|
1789
|
-
const popN = (0, import_react11.useCallback)(
|
|
1790
|
-
(n) => {
|
|
1791
|
-
setStack((prev) => {
|
|
1792
|
-
const next = prev.slice(0, Math.max(1, prev.length - n));
|
|
1793
|
-
if (next.length === 0) {
|
|
1794
|
-
onClose();
|
|
1795
|
-
return prev;
|
|
1796
|
-
}
|
|
1797
|
-
return next;
|
|
1798
|
-
});
|
|
1799
|
-
setItems([]);
|
|
1800
|
-
setError(void 0);
|
|
1801
|
-
},
|
|
1802
|
-
[onClose]
|
|
1803
|
-
);
|
|
1804
|
-
const notify = (0, import_react11.useCallback)(
|
|
1805
|
-
(content) => {
|
|
1806
|
-
addMessage?.({ role: "system", content });
|
|
1807
|
-
},
|
|
1808
|
-
[addMessage]
|
|
1809
|
-
);
|
|
1810
|
-
const refresh = (0, import_react11.useCallback)(() => {
|
|
1811
|
-
setItems([]);
|
|
1812
|
-
setRefreshCounter((c) => c + 1);
|
|
1813
|
-
}, []);
|
|
1814
|
-
const nav = { push, pop, popN, notify, setConfirm, refresh };
|
|
1815
|
-
(0, import_react11.useEffect)(() => {
|
|
1816
|
-
const screen2 = current.screen;
|
|
1817
|
-
if (screen2 === "marketplace-list") {
|
|
1907
|
+
if (screen === "marketplace-list") {
|
|
1818
1908
|
setLoading(true);
|
|
1819
1909
|
callbacks.marketplaceList().then((sources) => {
|
|
1820
1910
|
const baseItems = [{ label: "Add Marketplace", value: "__add__" }];
|
|
@@ -1829,10 +1919,10 @@ function PluginTUI({ callbacks, onClose, addMessage }) {
|
|
|
1829
1919
|
setError(err instanceof Error ? err.message : String(err));
|
|
1830
1920
|
setLoading(false);
|
|
1831
1921
|
});
|
|
1832
|
-
} else if (
|
|
1833
|
-
const
|
|
1922
|
+
} else if (screen === "marketplace-browse") {
|
|
1923
|
+
const mp = marketplace ?? "";
|
|
1834
1924
|
setLoading(true);
|
|
1835
|
-
callbacks.listAvailablePlugins(
|
|
1925
|
+
callbacks.listAvailablePlugins(mp).then((plugins) => {
|
|
1836
1926
|
setItems(
|
|
1837
1927
|
plugins.map((p) => ({
|
|
1838
1928
|
label: p.name,
|
|
@@ -1845,7 +1935,7 @@ function PluginTUI({ callbacks, onClose, addMessage }) {
|
|
|
1845
1935
|
setError(err instanceof Error ? err.message : String(err));
|
|
1846
1936
|
setLoading(false);
|
|
1847
1937
|
});
|
|
1848
|
-
} else if (
|
|
1938
|
+
} else if (screen === "installed-list") {
|
|
1849
1939
|
setLoading(true);
|
|
1850
1940
|
callbacks.listInstalled().then((plugins) => {
|
|
1851
1941
|
setItems(
|
|
@@ -1861,8 +1951,68 @@ function PluginTUI({ callbacks, onClose, addMessage }) {
|
|
|
1861
1951
|
setLoading(false);
|
|
1862
1952
|
});
|
|
1863
1953
|
}
|
|
1864
|
-
}, [
|
|
1865
|
-
|
|
1954
|
+
}, [stackLength, screen, marketplace, callbacks, refreshCounter]);
|
|
1955
|
+
return { items, loading, error };
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1958
|
+
// src/ui/PluginTUI.tsx
|
|
1959
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1960
|
+
function PluginTUI({ callbacks, onClose, addMessage }) {
|
|
1961
|
+
const [stack, setStack] = (0, import_react15.useState)([{ screen: "main" }]);
|
|
1962
|
+
const [confirm, setConfirm] = (0, import_react15.useState)();
|
|
1963
|
+
const [refreshCounter, setRefreshCounter] = (0, import_react15.useState)(0);
|
|
1964
|
+
const current = stack[stack.length - 1] ?? { screen: "main" };
|
|
1965
|
+
const push = (0, import_react15.useCallback)((state) => {
|
|
1966
|
+
setStack((prev) => [...prev, state]);
|
|
1967
|
+
}, []);
|
|
1968
|
+
const pop = (0, import_react15.useCallback)(() => {
|
|
1969
|
+
setStack((prev) => {
|
|
1970
|
+
if (prev.length <= 1) {
|
|
1971
|
+
onClose();
|
|
1972
|
+
return prev;
|
|
1973
|
+
}
|
|
1974
|
+
return prev.slice(0, -1);
|
|
1975
|
+
});
|
|
1976
|
+
}, [onClose]);
|
|
1977
|
+
const popN = (0, import_react15.useCallback)(
|
|
1978
|
+
(n) => {
|
|
1979
|
+
setStack((prev) => {
|
|
1980
|
+
const next = prev.slice(0, Math.max(1, prev.length - n));
|
|
1981
|
+
if (next.length === 0) {
|
|
1982
|
+
onClose();
|
|
1983
|
+
return prev;
|
|
1984
|
+
}
|
|
1985
|
+
return next;
|
|
1986
|
+
});
|
|
1987
|
+
},
|
|
1988
|
+
[onClose]
|
|
1989
|
+
);
|
|
1990
|
+
const notify = (0, import_react15.useCallback)(
|
|
1991
|
+
(content) => {
|
|
1992
|
+
addMessage?.({ role: "system", content });
|
|
1993
|
+
},
|
|
1994
|
+
[addMessage]
|
|
1995
|
+
);
|
|
1996
|
+
const refresh = (0, import_react15.useCallback)(() => {
|
|
1997
|
+
setRefreshCounter((c) => c + 1);
|
|
1998
|
+
}, []);
|
|
1999
|
+
const setConfirmNav = (0, import_react15.useCallback)(
|
|
2000
|
+
(state) => setConfirm(state),
|
|
2001
|
+
[setConfirm]
|
|
2002
|
+
);
|
|
2003
|
+
const pushNav = (0, import_react15.useCallback)(
|
|
2004
|
+
(state) => push({ screen: state.screen, context: state.context }),
|
|
2005
|
+
[push]
|
|
2006
|
+
);
|
|
2007
|
+
const nav = { push: pushNav, pop, popN, notify, setConfirm: setConfirmNav, refresh };
|
|
2008
|
+
const { items, loading, error } = usePluginScreenData(
|
|
2009
|
+
current.screen,
|
|
2010
|
+
current.context?.marketplace,
|
|
2011
|
+
callbacks,
|
|
2012
|
+
refreshCounter,
|
|
2013
|
+
stack.length
|
|
2014
|
+
);
|
|
2015
|
+
const handleSelect = (0, import_react15.useCallback)(
|
|
1866
2016
|
(value) => {
|
|
1867
2017
|
const screen2 = current.screen;
|
|
1868
2018
|
const ctx = current.context;
|
|
@@ -1880,7 +2030,7 @@ function PluginTUI({ callbacks, onClose, addMessage }) {
|
|
|
1880
2030
|
},
|
|
1881
2031
|
[current, items, callbacks, push, pop, popN, notify, setConfirm, refresh]
|
|
1882
2032
|
);
|
|
1883
|
-
const handleTextSubmit = (0,
|
|
2033
|
+
const handleTextSubmit = (0, import_react15.useCallback)(
|
|
1884
2034
|
(value) => {
|
|
1885
2035
|
if (current.screen === "marketplace-add") {
|
|
1886
2036
|
callbacks.marketplaceAdd(value).then((name) => {
|
|
@@ -1988,9 +2138,12 @@ function PluginTUI({ callbacks, onClose, addMessage }) {
|
|
|
1988
2138
|
);
|
|
1989
2139
|
}
|
|
1990
2140
|
|
|
2141
|
+
// src/ui/SessionPicker.tsx
|
|
2142
|
+
var import_ink15 = require("ink");
|
|
2143
|
+
|
|
1991
2144
|
// src/ui/ListPicker.tsx
|
|
1992
|
-
var
|
|
1993
|
-
var
|
|
2145
|
+
var import_react16 = require("react");
|
|
2146
|
+
var import_ink14 = require("ink");
|
|
1994
2147
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1995
2148
|
var DEFAULT_MAX_VISIBLE = 3;
|
|
1996
2149
|
function ListPicker({
|
|
@@ -2000,11 +2153,11 @@ function ListPicker({
|
|
|
2000
2153
|
onCancel,
|
|
2001
2154
|
maxVisible = DEFAULT_MAX_VISIBLE
|
|
2002
2155
|
}) {
|
|
2003
|
-
const [selectedIndex, setSelectedIndex] = (0,
|
|
2004
|
-
const [scrollOffset, setScrollOffset] = (0,
|
|
2005
|
-
const selectedRef = (0,
|
|
2006
|
-
const resolvedRef = (0,
|
|
2007
|
-
(0,
|
|
2156
|
+
const [selectedIndex, setSelectedIndex] = (0, import_react16.useState)(0);
|
|
2157
|
+
const [scrollOffset, setScrollOffset] = (0, import_react16.useState)(0);
|
|
2158
|
+
const selectedRef = (0, import_react16.useRef)(0);
|
|
2159
|
+
const resolvedRef = (0, import_react16.useRef)(false);
|
|
2160
|
+
(0, import_ink14.useInput)((_input, key) => {
|
|
2008
2161
|
if (resolvedRef.current) return;
|
|
2009
2162
|
if (key.escape) {
|
|
2010
2163
|
resolvedRef.current = true;
|
|
@@ -2035,19 +2188,19 @@ function ListPicker({
|
|
|
2035
2188
|
}
|
|
2036
2189
|
});
|
|
2037
2190
|
if (items.length === 0) {
|
|
2038
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2191
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink14.Box, {});
|
|
2039
2192
|
}
|
|
2040
2193
|
const visibleItems = items.slice(scrollOffset, scrollOffset + maxVisible);
|
|
2041
2194
|
const hasMore = scrollOffset + maxVisible < items.length;
|
|
2042
2195
|
const hasLess = scrollOffset > 0;
|
|
2043
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
2044
|
-
hasLess && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
2196
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_ink14.Box, { flexDirection: "column", children: [
|
|
2197
|
+
hasLess && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_ink14.Text, { dimColor: true, children: [
|
|
2045
2198
|
" \u2191 ",
|
|
2046
2199
|
scrollOffset,
|
|
2047
2200
|
" more above"
|
|
2048
2201
|
] }),
|
|
2049
|
-
visibleItems.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2050
|
-
hasMore && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
2202
|
+
visibleItems.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink14.Box, { marginBottom: 1, children: renderItem(item, scrollOffset + index === selectedIndex) }, scrollOffset + index)),
|
|
2203
|
+
hasMore && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_ink14.Text, { dimColor: true, children: [
|
|
2051
2204
|
" \u2193 ",
|
|
2052
2205
|
items.length - scrollOffset - maxVisible,
|
|
2053
2206
|
" more below"
|
|
@@ -2055,13 +2208,62 @@ function ListPicker({
|
|
|
2055
2208
|
] });
|
|
2056
2209
|
}
|
|
2057
2210
|
|
|
2058
|
-
// src/ui/
|
|
2211
|
+
// src/ui/SessionPicker.tsx
|
|
2059
2212
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2060
|
-
var EXIT_DELAY_MS = 500;
|
|
2061
2213
|
var SESSION_ID_DISPLAY_LENGTH = 8;
|
|
2214
|
+
function SessionPicker({
|
|
2215
|
+
sessionStore,
|
|
2216
|
+
cwd,
|
|
2217
|
+
onSelect,
|
|
2218
|
+
onCancel
|
|
2219
|
+
}) {
|
|
2220
|
+
const sessions = (sessionStore?.list() ?? []).filter((s) => s.cwd === cwd);
|
|
2221
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink15.Box, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [
|
|
2222
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink15.Text, { bold: true, color: "cyan", children: "Select a session to resume (ESC to cancel):" }),
|
|
2223
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2224
|
+
ListPicker,
|
|
2225
|
+
{
|
|
2226
|
+
items: sessions,
|
|
2227
|
+
renderItem: (session, isSelected) => {
|
|
2228
|
+
const lastMsg = session.messages.slice().reverse().find((m) => {
|
|
2229
|
+
const msg = m;
|
|
2230
|
+
return msg.role === "assistant" && msg.content;
|
|
2231
|
+
});
|
|
2232
|
+
const rawPreview = lastMsg?.content?.replace(/[\n\r]+/g, " ").trim() ?? "";
|
|
2233
|
+
const preview = rawPreview ? rawPreview.slice(0, 60) + (rawPreview.length > 60 ? "..." : "") : "";
|
|
2234
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink15.Text, { children: [
|
|
2235
|
+
isSelected ? "> " : " ",
|
|
2236
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink15.Text, { bold: true, children: session.name ?? session.id.slice(0, SESSION_ID_DISPLAY_LENGTH) }),
|
|
2237
|
+
" ",
|
|
2238
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink15.Text, { dimColor: true, children: new Date(session.updatedAt).toLocaleString(void 0, {
|
|
2239
|
+
month: "short",
|
|
2240
|
+
day: "numeric",
|
|
2241
|
+
hour: "2-digit",
|
|
2242
|
+
minute: "2-digit"
|
|
2243
|
+
}) }),
|
|
2244
|
+
" ",
|
|
2245
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink15.Text, { dimColor: true, children: [
|
|
2246
|
+
"msgs: ",
|
|
2247
|
+
session.messages.length
|
|
2248
|
+
] }),
|
|
2249
|
+
preview ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
2250
|
+
"\n ",
|
|
2251
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink15.Text, { color: "gray", children: preview })
|
|
2252
|
+
] }) : null
|
|
2253
|
+
] });
|
|
2254
|
+
},
|
|
2255
|
+
onSelect: (session) => onSelect(session.id),
|
|
2256
|
+
onCancel
|
|
2257
|
+
}
|
|
2258
|
+
)
|
|
2259
|
+
] });
|
|
2260
|
+
}
|
|
2261
|
+
|
|
2262
|
+
// src/ui/App.tsx
|
|
2263
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2062
2264
|
function App(props) {
|
|
2063
|
-
const [activeSessionId, setActiveSessionId] = (0,
|
|
2064
|
-
return /* @__PURE__ */ (0,
|
|
2265
|
+
const [activeSessionId, setActiveSessionId] = (0, import_react17.useState)(props.resumeSessionId);
|
|
2266
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2065
2267
|
AppInner,
|
|
2066
2268
|
{
|
|
2067
2269
|
...props,
|
|
@@ -2072,7 +2274,6 @@ function App(props) {
|
|
|
2072
2274
|
);
|
|
2073
2275
|
}
|
|
2074
2276
|
function AppInner(props) {
|
|
2075
|
-
const { exit } = (0, import_ink14.useApp)();
|
|
2076
2277
|
const cwd = props.cwd;
|
|
2077
2278
|
const {
|
|
2078
2279
|
interactiveSession,
|
|
@@ -2100,83 +2301,32 @@ function AppInner(props) {
|
|
|
2100
2301
|
sessionName: props.sessionName
|
|
2101
2302
|
});
|
|
2102
2303
|
const pluginCallbacks = usePluginCallbacks(cwd);
|
|
2103
|
-
const [
|
|
2104
|
-
const
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2304
|
+
const [sessionName, setSessionName] = (0, import_react17.useState)(props.sessionName);
|
|
2305
|
+
const {
|
|
2306
|
+
handleSubmit,
|
|
2307
|
+
pendingModelId,
|
|
2308
|
+
showPluginTUI,
|
|
2309
|
+
showSessionPicker,
|
|
2310
|
+
setShowPluginTUI,
|
|
2311
|
+
setShowSessionPicker,
|
|
2312
|
+
handleModelConfirm
|
|
2313
|
+
} = useSideEffects({
|
|
2314
|
+
interactiveSession,
|
|
2315
|
+
addEntry,
|
|
2316
|
+
baseHandleSubmit,
|
|
2317
|
+
setSessionName
|
|
2318
|
+
});
|
|
2319
|
+
(0, import_react17.useEffect)(() => {
|
|
2111
2320
|
const name = interactiveSession?.getName?.();
|
|
2112
2321
|
if (name && !sessionName) setSessionName(name);
|
|
2113
2322
|
}, [interactiveSession, sessionName]);
|
|
2114
|
-
(0,
|
|
2323
|
+
(0, import_react17.useEffect)(() => {
|
|
2115
2324
|
const title = sessionName ? `Robota \u2014 ${sessionName}` : "Robota";
|
|
2116
2325
|
process.stdout.write(`\x1B]0;${title}\x07`);
|
|
2117
2326
|
}, [sessionName]);
|
|
2118
|
-
|
|
2119
|
-
await baseHandleSubmit(input);
|
|
2120
|
-
const sideEffects = interactiveSession;
|
|
2121
|
-
if (sideEffects._pendingModelId) {
|
|
2122
|
-
const modelId = sideEffects._pendingModelId;
|
|
2123
|
-
delete sideEffects._pendingModelId;
|
|
2124
|
-
pendingModelChangeRef.current = modelId;
|
|
2125
|
-
setPendingModelId(modelId);
|
|
2126
|
-
return;
|
|
2127
|
-
}
|
|
2128
|
-
if (sideEffects._pendingLanguage) {
|
|
2129
|
-
const lang = sideEffects._pendingLanguage;
|
|
2130
|
-
delete sideEffects._pendingLanguage;
|
|
2131
|
-
const settingsPath = getUserSettingsPath();
|
|
2132
|
-
const settings = readSettings(settingsPath);
|
|
2133
|
-
settings.language = lang;
|
|
2134
|
-
writeSettings(settingsPath, settings);
|
|
2135
|
-
addEntry(
|
|
2136
|
-
(0, import_agent_core4.messageToHistoryEntry)((0, import_agent_core4.createSystemMessage)(`Language set to "${lang}". Restarting...`))
|
|
2137
|
-
);
|
|
2138
|
-
setTimeout(() => exit(), EXIT_DELAY_MS);
|
|
2139
|
-
return;
|
|
2140
|
-
}
|
|
2141
|
-
if (sideEffects._resetRequested) {
|
|
2142
|
-
delete sideEffects._resetRequested;
|
|
2143
|
-
const settingsPath = getUserSettingsPath();
|
|
2144
|
-
if (deleteSettings(settingsPath)) {
|
|
2145
|
-
addEntry((0, import_agent_core4.messageToHistoryEntry)((0, import_agent_core4.createSystemMessage)(`Deleted ${settingsPath}. Exiting...`)));
|
|
2146
|
-
} else {
|
|
2147
|
-
addEntry((0, import_agent_core4.messageToHistoryEntry)((0, import_agent_core4.createSystemMessage)("No user settings found.")));
|
|
2148
|
-
}
|
|
2149
|
-
setTimeout(() => exit(), EXIT_DELAY_MS);
|
|
2150
|
-
return;
|
|
2151
|
-
}
|
|
2152
|
-
if (sideEffects._exitRequested) {
|
|
2153
|
-
delete sideEffects._exitRequested;
|
|
2154
|
-
setTimeout(() => exit(), EXIT_DELAY_MS);
|
|
2155
|
-
return;
|
|
2156
|
-
}
|
|
2157
|
-
if (sideEffects._triggerPluginTUI) {
|
|
2158
|
-
delete sideEffects._triggerPluginTUI;
|
|
2159
|
-
setShowPluginTUI(true);
|
|
2160
|
-
return;
|
|
2161
|
-
}
|
|
2162
|
-
if (sideEffects._triggerResumePicker) {
|
|
2163
|
-
delete sideEffects._triggerResumePicker;
|
|
2164
|
-
setShowSessionPicker(true);
|
|
2165
|
-
return;
|
|
2166
|
-
}
|
|
2167
|
-
if (sideEffects._sessionName) {
|
|
2168
|
-
const name = sideEffects._sessionName;
|
|
2169
|
-
delete sideEffects._sessionName;
|
|
2170
|
-
interactiveSession.setName(name);
|
|
2171
|
-
setSessionName(name);
|
|
2172
|
-
return;
|
|
2173
|
-
}
|
|
2174
|
-
};
|
|
2175
|
-
(0, import_ink14.useInput)(
|
|
2327
|
+
(0, import_ink16.useInput)(
|
|
2176
2328
|
(_input, key) => {
|
|
2177
|
-
if (key.escape && isThinking)
|
|
2178
|
-
handleAbort();
|
|
2179
|
-
}
|
|
2329
|
+
if (key.escape && isThinking) handleAbort();
|
|
2180
2330
|
},
|
|
2181
2331
|
{ isActive: !permissionRequest && !showPluginTUI && !showSessionPicker }
|
|
2182
2332
|
);
|
|
@@ -2188,117 +2338,60 @@ function AppInner(props) {
|
|
|
2188
2338
|
sessionId = session.getSessionId();
|
|
2189
2339
|
} catch {
|
|
2190
2340
|
}
|
|
2191
|
-
return /* @__PURE__ */ (0,
|
|
2192
|
-
/* @__PURE__ */ (0,
|
|
2193
|
-
/* @__PURE__ */ (0,
|
|
2341
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_ink16.Box, { flexDirection: "column", children: [
|
|
2342
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_ink16.Box, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [
|
|
2343
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_ink16.Text, { color: "cyan", bold: true, children: `
|
|
2194
2344
|
____ ___ ____ ___ _____ _
|
|
2195
2345
|
| _ \\ / _ \\| __ ) / _ \\_ _|/ \\
|
|
2196
2346
|
| |_) | | | | _ \\| | | || | / _ \\
|
|
2197
2347
|
| _ <| |_| | |_) | |_| || |/ ___ \\
|
|
2198
2348
|
|_| \\_\\\\___/|____/ \\___/ |_/_/ \\_\\
|
|
2199
2349
|
` }),
|
|
2200
|
-
/* @__PURE__ */ (0,
|
|
2350
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_ink16.Text, { dimColor: true, children: [
|
|
2201
2351
|
" v",
|
|
2202
2352
|
props.version ?? "0.0.0"
|
|
2203
2353
|
] })
|
|
2204
2354
|
] }),
|
|
2205
|
-
/* @__PURE__ */ (0,
|
|
2206
|
-
/* @__PURE__ */ (0,
|
|
2207
|
-
(isThinking || activeTools.length > 0) && /* @__PURE__ */ (0,
|
|
2355
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_ink16.Box, { flexDirection: "column", paddingX: 1, flexGrow: 1, children: [
|
|
2356
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MessageList, { history }),
|
|
2357
|
+
(isThinking || activeTools.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_ink16.Box, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(StreamingIndicator, { text: streamingText, activeTools }) })
|
|
2208
2358
|
] }),
|
|
2209
|
-
permissionRequest && /* @__PURE__ */ (0,
|
|
2210
|
-
pendingModelId && /* @__PURE__ */ (0,
|
|
2359
|
+
permissionRequest && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PermissionPrompt, { request: permissionRequest }),
|
|
2360
|
+
pendingModelId && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2211
2361
|
ConfirmPrompt,
|
|
2212
2362
|
{
|
|
2213
|
-
message: `Change model to ${(0,
|
|
2214
|
-
onSelect:
|
|
2215
|
-
setPendingModelId(null);
|
|
2216
|
-
pendingModelChangeRef.current = null;
|
|
2217
|
-
if (index === 0) {
|
|
2218
|
-
try {
|
|
2219
|
-
const settingsPath = getUserSettingsPath();
|
|
2220
|
-
updateModelInSettings(settingsPath, pendingModelId);
|
|
2221
|
-
addEntry(
|
|
2222
|
-
(0, import_agent_core4.messageToHistoryEntry)(
|
|
2223
|
-
(0, import_agent_core4.createSystemMessage)(
|
|
2224
|
-
`Model changed to ${(0, import_agent_core4.getModelName)(pendingModelId)}. Restarting...`
|
|
2225
|
-
)
|
|
2226
|
-
)
|
|
2227
|
-
);
|
|
2228
|
-
setTimeout(() => exit(), EXIT_DELAY_MS);
|
|
2229
|
-
} catch (err) {
|
|
2230
|
-
addEntry(
|
|
2231
|
-
(0, import_agent_core4.messageToHistoryEntry)(
|
|
2232
|
-
(0, import_agent_core4.createSystemMessage)(
|
|
2233
|
-
`Failed: ${err instanceof Error ? err.message : String(err)}`
|
|
2234
|
-
)
|
|
2235
|
-
)
|
|
2236
|
-
);
|
|
2237
|
-
}
|
|
2238
|
-
} else {
|
|
2239
|
-
addEntry((0, import_agent_core4.messageToHistoryEntry)((0, import_agent_core4.createSystemMessage)("Model change cancelled.")));
|
|
2240
|
-
}
|
|
2241
|
-
}
|
|
2363
|
+
message: `Change model to ${(0, import_agent_core5.getModelName)(pendingModelId)}? This will restart the session.`,
|
|
2364
|
+
onSelect: handleModelConfirm
|
|
2242
2365
|
}
|
|
2243
2366
|
),
|
|
2244
|
-
showPluginTUI && /* @__PURE__ */ (0,
|
|
2367
|
+
showPluginTUI && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2245
2368
|
PluginTUI,
|
|
2246
2369
|
{
|
|
2247
2370
|
callbacks: pluginCallbacks,
|
|
2248
2371
|
onClose: () => setShowPluginTUI(false),
|
|
2249
|
-
addMessage: (msg) => addEntry((0,
|
|
2372
|
+
addMessage: (msg) => addEntry((0, import_agent_core5.messageToHistoryEntry)((0, import_agent_core5.createSystemMessage)(msg.content)))
|
|
2250
2373
|
}
|
|
2251
2374
|
),
|
|
2252
|
-
showSessionPicker && /* @__PURE__ */ (0,
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
const preview = rawPreview ? rawPreview.slice(0, 60) + (rawPreview.length > 60 ? "..." : "") : "";
|
|
2265
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink14.Text, { children: [
|
|
2266
|
-
isSelected ? "> " : " ",
|
|
2267
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink14.Text, { bold: true, children: session.name ?? session.id.slice(0, SESSION_ID_DISPLAY_LENGTH) }),
|
|
2268
|
-
" ",
|
|
2269
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink14.Text, { dimColor: true, children: new Date(session.updatedAt).toLocaleString(void 0, {
|
|
2270
|
-
month: "short",
|
|
2271
|
-
day: "numeric",
|
|
2272
|
-
hour: "2-digit",
|
|
2273
|
-
minute: "2-digit"
|
|
2274
|
-
}) }),
|
|
2275
|
-
" ",
|
|
2276
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink14.Text, { dimColor: true, children: [
|
|
2277
|
-
"msgs: ",
|
|
2278
|
-
session.messages.length
|
|
2279
|
-
] }),
|
|
2280
|
-
preview ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
2281
|
-
"\n ",
|
|
2282
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink14.Text, { color: "gray", children: preview })
|
|
2283
|
-
] }) : null
|
|
2284
|
-
] });
|
|
2285
|
-
},
|
|
2286
|
-
onSelect: (session) => {
|
|
2287
|
-
setShowSessionPicker(false);
|
|
2288
|
-
props.onSessionSwitch(session.id);
|
|
2289
|
-
},
|
|
2290
|
-
onCancel: () => {
|
|
2291
|
-
setShowSessionPicker(false);
|
|
2292
|
-
addEntry((0, import_agent_core4.messageToHistoryEntry)((0, import_agent_core4.createSystemMessage)("Session resume cancelled.")));
|
|
2293
|
-
}
|
|
2375
|
+
showSessionPicker && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2376
|
+
SessionPicker,
|
|
2377
|
+
{
|
|
2378
|
+
sessionStore: props.sessionStore,
|
|
2379
|
+
cwd: props.cwd,
|
|
2380
|
+
onSelect: (id) => {
|
|
2381
|
+
setShowSessionPicker(false);
|
|
2382
|
+
props.onSessionSwitch(id);
|
|
2383
|
+
},
|
|
2384
|
+
onCancel: () => {
|
|
2385
|
+
setShowSessionPicker(false);
|
|
2386
|
+
addEntry((0, import_agent_core5.messageToHistoryEntry)((0, import_agent_core5.createSystemMessage)("Session resume cancelled.")));
|
|
2294
2387
|
}
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
/* @__PURE__ */ (0,
|
|
2388
|
+
}
|
|
2389
|
+
),
|
|
2390
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2298
2391
|
StatusBar,
|
|
2299
2392
|
{
|
|
2300
2393
|
permissionMode,
|
|
2301
|
-
modelName: props.modelId ? (0,
|
|
2394
|
+
modelName: props.modelId ? (0, import_agent_core5.getModelName)(props.modelId) : "",
|
|
2302
2395
|
sessionId,
|
|
2303
2396
|
messageCount: history.length,
|
|
2304
2397
|
isThinking,
|
|
@@ -2308,7 +2401,7 @@ function AppInner(props) {
|
|
|
2308
2401
|
sessionName
|
|
2309
2402
|
}
|
|
2310
2403
|
),
|
|
2311
|
-
/* @__PURE__ */ (0,
|
|
2404
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2312
2405
|
InputArea,
|
|
2313
2406
|
{
|
|
2314
2407
|
onSubmit: handleSubmit,
|
|
@@ -2320,12 +2413,12 @@ function AppInner(props) {
|
|
|
2320
2413
|
sessionName
|
|
2321
2414
|
}
|
|
2322
2415
|
),
|
|
2323
|
-
/* @__PURE__ */ (0,
|
|
2416
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_ink16.Text, { children: " " })
|
|
2324
2417
|
] });
|
|
2325
2418
|
}
|
|
2326
2419
|
|
|
2327
2420
|
// src/ui/render.tsx
|
|
2328
|
-
var
|
|
2421
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2329
2422
|
function renderApp(options) {
|
|
2330
2423
|
process.on("unhandledRejection", (reason) => {
|
|
2331
2424
|
process.stderr.write(`
|
|
@@ -2339,7 +2432,7 @@ function renderApp(options) {
|
|
|
2339
2432
|
if (process.stdin.isTTY && process.stdout.isTTY) {
|
|
2340
2433
|
process.stdout.write("\x1B[?2004h");
|
|
2341
2434
|
}
|
|
2342
|
-
const instance = (0,
|
|
2435
|
+
const instance = (0, import_ink17.render)(/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(App, { ...options }), {
|
|
2343
2436
|
exitOnCtrlC: true
|
|
2344
2437
|
});
|
|
2345
2438
|
instance.waitUntilExit().then(() => {
|
|
@@ -2544,7 +2637,7 @@ async function startCli() {
|
|
|
2544
2637
|
process.stderr.write("Print mode (-p) requires a prompt argument.\n");
|
|
2545
2638
|
process.exit(1);
|
|
2546
2639
|
}
|
|
2547
|
-
const session = new
|
|
2640
|
+
const session = new import_agent_sdk4.InteractiveSession({
|
|
2548
2641
|
cwd,
|
|
2549
2642
|
provider,
|
|
2550
2643
|
permissionMode: args.permissionMode ?? "bypassPermissions",
|