agentk8 2.3.3 → 2.3.4

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,8 +27,10 @@ const cli = meow(`
27
27
  /exit Exit AGENT-K
28
28
 
29
29
  Keyboard
30
- Esc Esc Exit (double-press)
30
+ Esc Cancel current operation (when processing)
31
+ Esc Esc Exit (double-press when idle)
31
32
  Ctrl+U Clear input line
33
+ Shift+Tab Toggle auto-edit mode
32
34
  `, {
33
35
  importMeta: import.meta,
34
36
  flags: {
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useEffect } from 'react';
2
+ import { useState, useEffect, useRef } from 'react';
3
3
  import { Box, Text, useApp, useInput, Static } from 'ink';
4
4
  import { WelcomeBox } from './WelcomeBox.js';
5
5
  import { ChatMessage } from './ChatMessage.js';
@@ -37,6 +37,9 @@ export const App = ({ mode, version }) => {
37
37
  const [lastEscapeTime, setLastEscapeTime] = useState(0);
38
38
  const [showExitHint, setShowExitHint] = useState(false);
39
39
  const [questionWizardState, setQuestionWizardState] = useState(null);
40
+ const [showCancelHint, setShowCancelHint] = useState(false);
41
+ // Ref to track cancellation (can be checked inside async operations)
42
+ const cancelledRef = useRef(false);
40
43
  // Clean orchestrator internal tags from response
41
44
  const cleanOrchestratorTags = (response) => {
42
45
  let cleaned = response;
@@ -138,6 +141,7 @@ export const App = ({ mode, version }) => {
138
141
  };
139
142
  // Execute via Council
140
143
  const executeCouncil = async (input) => {
144
+ cancelledRef.current = false;
141
145
  setIsProcessing(true);
142
146
  setProcessingStartTime(new Date());
143
147
  setActiveAgent('Orchestrator');
@@ -185,6 +189,7 @@ export const App = ({ mode, version }) => {
185
189
  };
186
190
  // Generate a plan for approval
187
191
  const generatePlan = async (input) => {
192
+ cancelledRef.current = false;
188
193
  setIsProcessing(true);
189
194
  setProcessingStartTime(new Date());
190
195
  setActiveAgent('Orchestrator');
@@ -278,6 +283,7 @@ Format your response clearly with headers.`;
278
283
  };
279
284
  // Execute task directly
280
285
  const executeTask = async (input) => {
286
+ cancelledRef.current = false;
281
287
  setIsProcessing(true);
282
288
  setProcessingStartTime(new Date());
283
289
  setActiveAgent('Orchestrator');
@@ -463,8 +469,9 @@ Format your response clearly with headers.`;
463
469
  Keyboard shortcuts:
464
470
  ↑/↓ - Browse command history
465
471
  Tab - Autocomplete commands
466
- Shift+Tab - Toggle auto-accept edits
467
- Esc Esc - Exit
472
+ Shift+Tab - Toggle auto-edit mode
473
+ Esc - Cancel operation (when processing)
474
+ Esc Esc - Exit (when idle)
468
475
  Ctrl+U - Clear input line`,
469
476
  timestamp: new Date(),
470
477
  };
@@ -494,9 +501,29 @@ Ctrl+U - Clear input line`,
494
501
  };
495
502
  // Handle keyboard shortcuts
496
503
  useInput((input, key) => {
497
- // Double-escape to exit (like Claude Code)
504
+ // Escape key handling
498
505
  if (key.escape) {
499
506
  const now = Date.now();
507
+ // If processing, single Esc cancels the operation
508
+ if (isProcessing) {
509
+ cancelledRef.current = true;
510
+ setIsProcessing(false);
511
+ setProcessingStartTime(null);
512
+ setActiveAgent(undefined);
513
+ setCouncilStage(null);
514
+ setShowCancelHint(true);
515
+ setTimeout(() => setShowCancelHint(false), 2000);
516
+ // Add cancellation message
517
+ const cancelMessage = {
518
+ id: Date.now().toString(),
519
+ role: 'system',
520
+ content: '⚠ Operation cancelled',
521
+ timestamp: new Date(),
522
+ };
523
+ setMessages(prev => [...prev, cancelMessage]);
524
+ return;
525
+ }
526
+ // Double-escape to exit (like Claude Code)
500
527
  if (now - lastEscapeTime < 500) {
501
528
  // Double escape - exit
502
529
  exit();
@@ -95,7 +95,7 @@ export const StatusBar = ({ mode, executionMode, tokens, startTime, isProcessing
95
95
  };
96
96
  return stages[councilStage] || councilStage;
97
97
  };
98
- return (_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", width: "100%", children: [_jsxs(Box, { children: [_jsx(Text, { color: theme.dim, children: " " }), _jsx(Text, { color: theme.accent, children: modeLabel }), _jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: executionMode === 'auto' ? theme.active : theme.accent, children: executionMode.toUpperCase() }), _jsx(Text, { color: theme.border, children: " \u2502 " }), councilMode !== 'off' ? (_jsxs(_Fragment, { children: [Object.entries(modelIcons).map(([model, icon], i) => {
98
+ return (_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", width: "100%", children: [_jsxs(Box, { children: [_jsx(Text, { color: theme.dim, children: " " }), _jsx(Text, { color: theme.accent, children: modeLabel }), _jsx(Text, { color: theme.border, children: " \u2502 " }), councilMode !== 'off' ? (_jsxs(_Fragment, { children: [Object.entries(modelIcons).map(([model, icon], i) => {
99
99
  const isAvailable = availableModels[model];
100
100
  const color = isAvailable ? theme.done : theme.dim;
101
101
  return (_jsxs(React.Fragment, { children: [_jsx(Text, { color: color, children: "[" }), _jsx(Text, { color: color, children: icon }), _jsx(Text, { color: color, children: "]" }), i < Object.keys(modelIcons).length - 1 && _jsx(Text, { color: theme.dim, children: " " })] }, model));
@@ -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' })] })), autoAccept && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.active, children: "FAST" })] })), 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 " })] })] }));
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 === 'auto' && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.active, children: "AUTO-EXEC" })] })), autoAccept && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.active, children: "AUTO-EDIT" })] })), 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;
@@ -54,6 +54,6 @@ export const ThinkingIndicator = ({ startTime, tokens = 0, }) => {
54
54
  return `${(t / 1000).toFixed(1)}k`;
55
55
  return t.toString();
56
56
  };
57
- return (_jsxs(Box, { marginY: 1, marginLeft: 1, children: [_jsxs(Text, { color: theme.purple, bold: true, children: [symbols[frame], " "] }), _jsxs(Text, { color: theme.highlight, italic: true, children: [verb, "\u2026"] }), _jsx(Text, { color: theme.dim, children: " (" }), _jsx(Text, { color: theme.dim, children: "esc esc to exit" }), _jsx(Text, { color: theme.dim, children: " \u00B7 " }), _jsx(Text, { color: theme.accent, children: elapsed }), tokens > 0 && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.dim, children: " \u00B7 " }), _jsxs(Text, { color: theme.accent, children: ["\u2193 ", formatTokens(tokens)] }), _jsx(Text, { color: theme.dim, children: " tokens" })] })), _jsx(Text, { color: theme.dim, children: " \u00B7 " }), _jsx(Text, { color: theme.purple, children: "thinking" }), _jsx(Text, { color: theme.dim, children: ")" })] }));
57
+ return (_jsxs(Box, { marginY: 1, marginLeft: 1, children: [_jsxs(Text, { color: theme.purple, bold: true, children: [symbols[frame], " "] }), _jsxs(Text, { color: theme.highlight, italic: true, children: [verb, "\u2026"] }), _jsx(Text, { color: theme.dim, children: " (" }), _jsx(Text, { color: theme.dim, children: "Esc to cancel" }), _jsx(Text, { color: theme.dim, children: " \u00B7 " }), _jsx(Text, { color: theme.accent, children: elapsed }), tokens > 0 && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.dim, children: " \u00B7 " }), _jsxs(Text, { color: theme.accent, children: ["\u2193 ", formatTokens(tokens)] }), _jsx(Text, { color: theme.dim, children: " tokens" })] })), _jsx(Text, { color: theme.dim, children: " \u00B7 " }), _jsx(Text, { color: theme.purple, children: "thinking" }), _jsx(Text, { color: theme.dim, children: ")" })] }));
58
58
  };
59
59
  export default ThinkingIndicator;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentk8",
3
- "version": "2.3.3",
3
+ "version": "2.3.4",
4
4
  "description": "Multi-LLM Council Terminal Suite - Three-stage consensus with GPT, Gemini, and Claude",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",