agentk8 2.3.4 → 2.3.6
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/cli.js
CHANGED
|
@@ -27,10 +27,14 @@ const cli = meow(`
|
|
|
27
27
|
/exit Exit AGENT-K
|
|
28
28
|
|
|
29
29
|
Keyboard
|
|
30
|
-
Esc Cancel
|
|
30
|
+
Esc Cancel operation (when processing)
|
|
31
31
|
Esc Esc Exit (double-press when idle)
|
|
32
32
|
Ctrl+U Clear input line
|
|
33
|
-
|
|
33
|
+
|
|
34
|
+
Modes (/normal, /plan, /auto)
|
|
35
|
+
normal Execute, confirm edits (default)
|
|
36
|
+
plan Plan first, then execute
|
|
37
|
+
auto No confirmations
|
|
34
38
|
`, {
|
|
35
39
|
importMeta: import.meta,
|
|
36
40
|
flags: {
|
package/dist/components/App.js
CHANGED
|
@@ -25,7 +25,7 @@ export const App = ({ mode, version }) => {
|
|
|
25
25
|
const [totalTokens, setTotalTokens] = useState(0);
|
|
26
26
|
const [startTime] = useState(new Date());
|
|
27
27
|
const [error, setError] = useState(null);
|
|
28
|
-
const [executionMode, setExecutionMode] = useState('
|
|
28
|
+
const [executionMode, setExecutionMode] = useState('normal');
|
|
29
29
|
const [activeAgent, setActiveAgent] = useState(undefined);
|
|
30
30
|
const [completedAgents, setCompletedAgents] = useState([]);
|
|
31
31
|
const [confirmationState, setConfirmationState] = useState(null);
|
|
@@ -136,6 +136,7 @@ export const App = ({ mode, version }) => {
|
|
|
136
136
|
await generatePlan(input);
|
|
137
137
|
}
|
|
138
138
|
else {
|
|
139
|
+
// normal or auto mode - executeTask handles autoAccept
|
|
139
140
|
await executeTask(input);
|
|
140
141
|
}
|
|
141
142
|
};
|
|
@@ -372,35 +373,36 @@ Format your response clearly with headers.`;
|
|
|
372
373
|
setActiveAgent(undefined);
|
|
373
374
|
setCompletedAgents([]);
|
|
374
375
|
break;
|
|
376
|
+
case 'normal':
|
|
377
|
+
setExecutionMode('normal');
|
|
378
|
+
setAutoAccept(false);
|
|
379
|
+
// Status bar shows the mode change
|
|
380
|
+
break;
|
|
375
381
|
case 'plan':
|
|
376
382
|
setExecutionMode('plan');
|
|
377
|
-
|
|
383
|
+
setAutoAccept(false);
|
|
384
|
+
// Status bar shows the mode change
|
|
378
385
|
break;
|
|
379
386
|
case 'auto':
|
|
387
|
+
// Only auto mode shows a warning confirmation
|
|
380
388
|
setConfirmationState({
|
|
381
|
-
message: '⚠️
|
|
389
|
+
message: '⚠️ Enable Auto Mode? This executes everything without confirmations.',
|
|
382
390
|
options: [
|
|
383
|
-
{ label: 'Yes, enable auto
|
|
384
|
-
{ label: 'No, stay
|
|
391
|
+
{ label: 'Yes, enable auto', value: 'yes' },
|
|
392
|
+
{ label: 'No, stay normal', value: 'no' },
|
|
385
393
|
],
|
|
386
394
|
onSelect: (value) => {
|
|
387
395
|
setConfirmationState(null);
|
|
388
396
|
if (value === 'yes') {
|
|
389
397
|
setExecutionMode('auto');
|
|
390
|
-
|
|
391
|
-
}
|
|
392
|
-
else {
|
|
393
|
-
addSystemMessage('Kept in plan mode.');
|
|
398
|
+
setAutoAccept(true);
|
|
394
399
|
}
|
|
395
400
|
},
|
|
396
|
-
onCancel: () =>
|
|
397
|
-
setConfirmationState(null);
|
|
398
|
-
addSystemMessage('Kept in plan mode.');
|
|
399
|
-
},
|
|
401
|
+
onCancel: () => setConfirmationState(null),
|
|
400
402
|
});
|
|
401
403
|
break;
|
|
402
404
|
case 'mode':
|
|
403
|
-
addSystemMessage(`Current
|
|
405
|
+
addSystemMessage(`Current mode: ${executionMode}\nUse /normal, /plan, or /auto to switch.`);
|
|
404
406
|
break;
|
|
405
407
|
case 'agents':
|
|
406
408
|
if (!activeAgent && completedAgents.length === 0) {
|
|
@@ -457,9 +459,10 @@ Format your response clearly with headers.`;
|
|
|
457
459
|
/help - Show this help
|
|
458
460
|
/clear - Clear chat history
|
|
459
461
|
/status - Show session status
|
|
460
|
-
/
|
|
461
|
-
/
|
|
462
|
-
/
|
|
462
|
+
/normal - Normal mode (execute, confirm edits)
|
|
463
|
+
/plan - Plan mode (plan first, then execute)
|
|
464
|
+
/auto - Auto mode (no confirmations)
|
|
465
|
+
/mode - Show current mode
|
|
463
466
|
/agents - Show active agents
|
|
464
467
|
/council - Toggle council mode (multi-LLM consensus)
|
|
465
468
|
/solo - Enable solo council (multi-Claude personas)
|
|
@@ -467,9 +470,9 @@ Format your response clearly with headers.`;
|
|
|
467
470
|
/exit - Exit AGENT-K
|
|
468
471
|
|
|
469
472
|
Keyboard shortcuts:
|
|
473
|
+
Shift+Tab - Cycle mode (normal/plan/auto)
|
|
470
474
|
↑/↓ - Browse command history
|
|
471
475
|
Tab - Autocomplete commands
|
|
472
|
-
Shift+Tab - Toggle auto-edit mode
|
|
473
476
|
Esc - Cancel operation (when processing)
|
|
474
477
|
Esc Esc - Exit (when idle)
|
|
475
478
|
Ctrl+U - Clear input line`,
|
|
@@ -499,8 +502,52 @@ Ctrl+U - Clear input line`,
|
|
|
499
502
|
setError(`Unknown command: /${command}`);
|
|
500
503
|
}
|
|
501
504
|
};
|
|
505
|
+
// Cycle execution mode (normal -> plan -> auto)
|
|
506
|
+
// Only shows warning for auto mode, otherwise just updates status bar silently
|
|
507
|
+
const cycleExecutionMode = () => {
|
|
508
|
+
const modes = ['normal', 'plan', 'auto'];
|
|
509
|
+
const currentIndex = modes.indexOf(executionMode);
|
|
510
|
+
const nextMode = modes[(currentIndex + 1) % modes.length];
|
|
511
|
+
if (nextMode === 'auto') {
|
|
512
|
+
// Show warning confirmation only for auto mode
|
|
513
|
+
setConfirmationState({
|
|
514
|
+
message: '⚠️ Enable Auto Mode? This executes everything without confirmations.',
|
|
515
|
+
options: [
|
|
516
|
+
{ label: 'Yes, enable auto', value: 'yes' },
|
|
517
|
+
{ label: 'No, stay normal', value: 'no' },
|
|
518
|
+
],
|
|
519
|
+
onSelect: (value) => {
|
|
520
|
+
setConfirmationState(null);
|
|
521
|
+
if (value === 'yes') {
|
|
522
|
+
setExecutionMode('auto');
|
|
523
|
+
setAutoAccept(true);
|
|
524
|
+
}
|
|
525
|
+
else {
|
|
526
|
+
// Rejected - go back to normal
|
|
527
|
+
setExecutionMode('normal');
|
|
528
|
+
setAutoAccept(false);
|
|
529
|
+
}
|
|
530
|
+
},
|
|
531
|
+
onCancel: () => {
|
|
532
|
+
setConfirmationState(null);
|
|
533
|
+
setExecutionMode('normal');
|
|
534
|
+
setAutoAccept(false);
|
|
535
|
+
},
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
else {
|
|
539
|
+
// normal and plan modes switch silently - status bar shows the change
|
|
540
|
+
setExecutionMode(nextMode);
|
|
541
|
+
setAutoAccept(false);
|
|
542
|
+
}
|
|
543
|
+
};
|
|
502
544
|
// Handle keyboard shortcuts
|
|
503
|
-
useInput((
|
|
545
|
+
useInput((_input, key) => {
|
|
546
|
+
// Shift+Tab to cycle execution mode
|
|
547
|
+
if (key.tab && key.shift && !isProcessing && !confirmationState && !questionWizardState) {
|
|
548
|
+
cycleExecutionMode();
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
504
551
|
// Escape key handling
|
|
505
552
|
if (key.escape) {
|
|
506
553
|
const now = Date.now();
|
|
@@ -537,30 +584,6 @@ Ctrl+U - Clear input line`,
|
|
|
537
584
|
}
|
|
538
585
|
}
|
|
539
586
|
}
|
|
540
|
-
// Shift+Tab to toggle auto-accept
|
|
541
|
-
if (key.shift && key.tab) {
|
|
542
|
-
if (autoAccept) {
|
|
543
|
-
// Disable silently
|
|
544
|
-
setAutoAccept(false);
|
|
545
|
-
}
|
|
546
|
-
else {
|
|
547
|
-
// Show confirmation prompt
|
|
548
|
-
setConfirmationState({
|
|
549
|
-
message: 'Enable auto-accept for code edits?',
|
|
550
|
-
options: [
|
|
551
|
-
{ label: 'Yes, enable auto-accept', value: 'yes' },
|
|
552
|
-
{ label: 'No, keep asking', value: 'no' },
|
|
553
|
-
],
|
|
554
|
-
onSelect: (value) => {
|
|
555
|
-
setConfirmationState(null);
|
|
556
|
-
if (value === 'yes') {
|
|
557
|
-
setAutoAccept(true);
|
|
558
|
-
}
|
|
559
|
-
},
|
|
560
|
-
onCancel: () => setConfirmationState(null),
|
|
561
|
-
});
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
587
|
});
|
|
565
588
|
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Static, { items: messages, children: (item) => {
|
|
566
589
|
if ('isWelcome' in item && item.isWelcome) {
|
|
@@ -13,10 +13,28 @@ const theme = {
|
|
|
13
13
|
code: '#f6ad55', // Orange for inline code
|
|
14
14
|
header: '#63b3ed', // Blue for headers
|
|
15
15
|
};
|
|
16
|
+
// Pre-process text to remove orphaned markdown markers
|
|
17
|
+
function cleanOrphanedMarkers(text) {
|
|
18
|
+
let result = text;
|
|
19
|
+
// Remove orphaned ** (bold markers without pairs)
|
|
20
|
+
// Count ** occurrences - if odd, the last one is orphaned
|
|
21
|
+
const boldMatches = result.match(/\*\*/g);
|
|
22
|
+
if (boldMatches && boldMatches.length % 2 !== 0) {
|
|
23
|
+
// Find and remove the last unmatched **
|
|
24
|
+
const lastIndex = result.lastIndexOf('**');
|
|
25
|
+
result = result.slice(0, lastIndex) + result.slice(lastIndex + 2);
|
|
26
|
+
}
|
|
27
|
+
// Also handle case where ** appears at start or end without content
|
|
28
|
+
result = result.replace(/^\*\*\s*$/, '');
|
|
29
|
+
result = result.replace(/^\*\*(?!\S)/, '');
|
|
30
|
+
result = result.replace(/(?<!\S)\*\*$/, '');
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
16
33
|
// Parse inline markdown and return React elements
|
|
17
34
|
function parseInlineMarkdown(text, defaultColor) {
|
|
18
35
|
const elements = [];
|
|
19
|
-
|
|
36
|
+
// Clean orphaned markers first
|
|
37
|
+
let remaining = cleanOrphanedMarkers(text);
|
|
20
38
|
let key = 0;
|
|
21
39
|
while (remaining.length > 0) {
|
|
22
40
|
// Check for bold **text**
|
|
@@ -48,9 +66,14 @@ function parseInlineMarkdown(text, defaultColor) {
|
|
|
48
66
|
break;
|
|
49
67
|
}
|
|
50
68
|
else if (nextSpecial === 0) {
|
|
51
|
-
// Special char at start but didn't match pattern -
|
|
52
|
-
|
|
53
|
-
|
|
69
|
+
// Special char at start but didn't match pattern - skip marker silently
|
|
70
|
+
// Check if it's a double asterisk that didn't match
|
|
71
|
+
if (remaining.startsWith('**')) {
|
|
72
|
+
remaining = remaining.slice(2);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
remaining = remaining.slice(1);
|
|
76
|
+
}
|
|
54
77
|
}
|
|
55
78
|
else {
|
|
56
79
|
// Add text before special char
|
package/dist/components/Input.js
CHANGED
|
@@ -31,9 +31,46 @@ export const Input = ({ onSubmit, placeholder = 'Type a message...', prefix = '
|
|
|
31
31
|
return matches[0].slice(value.length);
|
|
32
32
|
};
|
|
33
33
|
const suggestion = getSuggestion();
|
|
34
|
+
// Navigate history up
|
|
35
|
+
const navigateHistoryUp = () => {
|
|
36
|
+
if (commandHistory.length > 0) {
|
|
37
|
+
if (historyIndex === -1) {
|
|
38
|
+
setTempValue(value);
|
|
39
|
+
const newIndex = commandHistory.length - 1;
|
|
40
|
+
setHistoryIndex(newIndex);
|
|
41
|
+
setValue(commandHistory[newIndex]);
|
|
42
|
+
setCursorPosition(commandHistory[newIndex].length);
|
|
43
|
+
}
|
|
44
|
+
else if (historyIndex > 0) {
|
|
45
|
+
const newIndex = historyIndex - 1;
|
|
46
|
+
setHistoryIndex(newIndex);
|
|
47
|
+
setValue(commandHistory[newIndex]);
|
|
48
|
+
setCursorPosition(commandHistory[newIndex].length);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
// Navigate history down
|
|
53
|
+
const navigateHistoryDown = () => {
|
|
54
|
+
if (historyIndex !== -1) {
|
|
55
|
+
if (historyIndex < commandHistory.length - 1) {
|
|
56
|
+
const newIndex = historyIndex + 1;
|
|
57
|
+
setHistoryIndex(newIndex);
|
|
58
|
+
setValue(commandHistory[newIndex]);
|
|
59
|
+
setCursorPosition(commandHistory[newIndex].length);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
setHistoryIndex(-1);
|
|
63
|
+
setValue(tempValue);
|
|
64
|
+
setCursorPosition(tempValue.length);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
34
68
|
useInput((input, key) => {
|
|
35
69
|
if (disabled)
|
|
36
70
|
return;
|
|
71
|
+
// Handle arrow keys first (including escape sequence fallback)
|
|
72
|
+
const isUpArrow = key.upArrow || input === '\x1b[A' || input === '\x1bOA';
|
|
73
|
+
const isDownArrow = key.downArrow || input === '\x1b[B' || input === '\x1bOB';
|
|
37
74
|
if (key.return) {
|
|
38
75
|
if (value.trim()) {
|
|
39
76
|
if (commandHistory.length === 0 || commandHistory[commandHistory.length - 1] !== value) {
|
|
@@ -49,37 +86,11 @@ export const Input = ({ onSubmit, placeholder = 'Type a message...', prefix = '
|
|
|
49
86
|
setTempValue('');
|
|
50
87
|
}
|
|
51
88
|
}
|
|
52
|
-
else if (
|
|
53
|
-
|
|
54
|
-
if (historyIndex === -1) {
|
|
55
|
-
setTempValue(value);
|
|
56
|
-
const newIndex = commandHistory.length - 1;
|
|
57
|
-
setHistoryIndex(newIndex);
|
|
58
|
-
setValue(commandHistory[newIndex]);
|
|
59
|
-
setCursorPosition(commandHistory[newIndex].length);
|
|
60
|
-
}
|
|
61
|
-
else if (historyIndex > 0) {
|
|
62
|
-
const newIndex = historyIndex - 1;
|
|
63
|
-
setHistoryIndex(newIndex);
|
|
64
|
-
setValue(commandHistory[newIndex]);
|
|
65
|
-
setCursorPosition(commandHistory[newIndex].length);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
89
|
+
else if (isUpArrow) {
|
|
90
|
+
navigateHistoryUp();
|
|
68
91
|
}
|
|
69
|
-
else if (
|
|
70
|
-
|
|
71
|
-
if (historyIndex < commandHistory.length - 1) {
|
|
72
|
-
const newIndex = historyIndex + 1;
|
|
73
|
-
setHistoryIndex(newIndex);
|
|
74
|
-
setValue(commandHistory[newIndex]);
|
|
75
|
-
setCursorPosition(commandHistory[newIndex].length);
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
setHistoryIndex(-1);
|
|
79
|
-
setValue(tempValue);
|
|
80
|
-
setCursorPosition(tempValue.length);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
92
|
+
else if (isDownArrow) {
|
|
93
|
+
navigateHistoryDown();
|
|
83
94
|
}
|
|
84
95
|
else if (key.backspace || key.delete) {
|
|
85
96
|
if (cursorPosition > 0) {
|
|
@@ -108,7 +119,8 @@ export const Input = ({ onSubmit, placeholder = 'Type a message...', prefix = '
|
|
|
108
119
|
else if (key.ctrl && input === 'e') {
|
|
109
120
|
setCursorPosition(value.length);
|
|
110
121
|
}
|
|
111
|
-
else if (key.tab) {
|
|
122
|
+
else if (key.tab && !key.shift) {
|
|
123
|
+
// Plain Tab for autocomplete (Shift+Tab handled by App for mode cycling)
|
|
112
124
|
if (suggestion) {
|
|
113
125
|
const completed = value + suggestion;
|
|
114
126
|
setValue(completed);
|
|
@@ -3,7 +3,7 @@ import { AgentName } from './AgentPanel.js';
|
|
|
3
3
|
type CouncilMode = 'solo' | 'council' | 'off';
|
|
4
4
|
interface StatusBarProps {
|
|
5
5
|
mode: 'dev' | 'ml';
|
|
6
|
-
executionMode: 'plan' | 'auto';
|
|
6
|
+
executionMode: 'normal' | 'plan' | 'auto';
|
|
7
7
|
tokens: number;
|
|
8
8
|
startTime: Date;
|
|
9
9
|
isProcessing?: boolean;
|
|
@@ -106,6 +106,6 @@ export const StatusBar = ({ mode, executionMode, tokens, startTime, isProcessing
|
|
|
106
106
|
const leftBracket = isActive ? pulseBrackets[pulseFrame] : '[';
|
|
107
107
|
const rightBracket = isActive ? pulseBrackets[(pulseFrame + 3) % pulseBrackets.length] === '<' ? '>' : pulseBrackets[(pulseFrame + 3) % pulseBrackets.length] === '{' ? '}' : pulseBrackets[(pulseFrame + 3) % pulseBrackets.length] === '(' ? ')' : ']' : ']';
|
|
108
108
|
return (_jsxs(React.Fragment, { children: [_jsx(Text, { color: getAgentColor(agent), children: leftBracket }), _jsx(Text, { color: getAgentColor(agent), children: agentIcons[agent] }), _jsx(Text, { color: getAgentColor(agent), children: rightBracket }), i < modeAgents.length - 1 && _jsx(Text, { color: theme.dim, children: " " })] }, agent));
|
|
109
|
-
})), _jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.dim, children: "? help" }), councilMode !== 'off' && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.highlight, children: councilMode === 'council' ? 'COUNCIL' : 'SOLO' })] })), executionMode
|
|
109
|
+
})), _jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.dim, children: "? help" }), councilMode !== 'off' && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.highlight, children: councilMode === 'council' ? 'COUNCIL' : 'SOLO' })] })), executionMode !== 'normal' && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: executionMode === 'auto' ? theme.active : theme.accent, children: executionMode.toUpperCase() })] })), isProcessing && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.highlight, children: icons.spinner[spinnerFrame] })] })), elapsed && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.dim, children: elapsed })] }))] }), _jsxs(Box, { children: [showExitHint && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.dim, children: "Press Esc again to exit" }), _jsx(Text, { color: theme.border, children: " \u2502 " })] })), _jsxs(Text, { color: theme.accent, children: ["\u2191 ", formatTokens(tokens)] }), _jsx(Text, { color: theme.dim, children: " tokens " })] })] }));
|
|
110
110
|
};
|
|
111
111
|
export default StatusBar;
|