dexto 1.5.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/cli/commands/interactive-commands/command-parser.d.ts +1 -1
  2. package/dist/cli/commands/interactive-commands/command-parser.d.ts.map +1 -1
  3. package/dist/cli/commands/interactive-commands/command-parser.js +11 -1
  4. package/dist/cli/commands/interactive-commands/general-commands.d.ts.map +1 -1
  5. package/dist/cli/commands/interactive-commands/general-commands.js +63 -0
  6. package/dist/cli/commands/interactive-commands/system/system-commands.d.ts.map +1 -1
  7. package/dist/cli/commands/interactive-commands/system/system-commands.js +3 -2
  8. package/dist/cli/commands/setup.d.ts.map +1 -1
  9. package/dist/cli/commands/setup.js +163 -28
  10. package/dist/cli/ink-cli/components/TextBufferInput.d.ts.map +1 -1
  11. package/dist/cli/ink-cli/components/TextBufferInput.js +7 -3
  12. package/dist/cli/ink-cli/components/chat/Header.js +1 -1
  13. package/dist/cli/ink-cli/components/chat/MessageItem.d.ts.map +1 -1
  14. package/dist/cli/ink-cli/components/chat/MessageItem.js +4 -1
  15. package/dist/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.d.ts.map +1 -1
  16. package/dist/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.js +1 -1
  17. package/dist/cli/ink-cli/components/overlays/CustomModelWizard.d.ts.map +1 -1
  18. package/dist/cli/ink-cli/components/overlays/CustomModelWizard.js +19 -8
  19. package/dist/cli/ink-cli/components/overlays/LogLevelSelector.js +1 -1
  20. package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.d.ts +2 -1
  21. package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.d.ts.map +1 -1
  22. package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.js +64 -2
  23. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.d.ts.map +1 -1
  24. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.js +44 -1
  25. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/types.d.ts +6 -0
  26. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/types.d.ts.map +1 -1
  27. package/dist/cli/ink-cli/containers/OverlayContainer.d.ts.map +1 -1
  28. package/dist/cli/ink-cli/containers/OverlayContainer.js +2 -2
  29. package/dist/cli/ink-cli/hooks/useAgentEvents.d.ts +8 -1
  30. package/dist/cli/ink-cli/hooks/useAgentEvents.d.ts.map +1 -1
  31. package/dist/cli/ink-cli/hooks/useAgentEvents.js +144 -6
  32. package/dist/cli/ink-cli/hooks/useCLIState.d.ts.map +1 -1
  33. package/dist/cli/ink-cli/hooks/useCLIState.js +3 -0
  34. package/dist/cli/ink-cli/hooks/useTokenCounter.d.ts +11 -7
  35. package/dist/cli/ink-cli/hooks/useTokenCounter.d.ts.map +1 -1
  36. package/dist/cli/ink-cli/hooks/useTokenCounter.js +41 -18
  37. package/dist/cli/ink-cli/services/processStream.d.ts.map +1 -1
  38. package/dist/cli/ink-cli/services/processStream.js +20 -8
  39. package/dist/cli/ink-cli/state/types.d.ts +2 -2
  40. package/dist/cli/ink-cli/state/types.d.ts.map +1 -1
  41. package/dist/index.js +24 -3
  42. package/package.json +7 -7
@@ -31,7 +31,7 @@ export interface CommandDefinition {
31
31
  handler: (args: string[], agent: DextoAgent, ctx: CommandContext) => Promise<CommandHandlerResult>;
32
32
  }
33
33
  /**
34
- * Parses user input to determine if it's a slash command or a regular prompt
34
+ * Parses user input to determine if it's a slash command, shell command, or regular prompt
35
35
  */
36
36
  export declare function parseInput(input: string): CommandResult;
37
37
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"command-parser.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/interactive-commands/command-parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAEhG,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,MAAM,GAAG,YAAY,GAAG,iBAAiB,CAAC;AAEvF;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,uDAAuD;IACvD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAClC,OAAO,EAAE,CACL,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,cAAc,KAClB,OAAO,CAAC,oBAAoB,CAAC,CAAC;CACtC;AA4CD;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAsBvD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,EAAE,GAAG,MAAM,EAAE,CAoB9F;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,iBAAiB,EAAE,QAAQ,GAAE,OAAe,GAAG,MAAM,CAmB3F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAuDtE"}
1
+ {"version":3,"file":"command-parser.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/interactive-commands/command-parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAEhG,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,MAAM,GAAG,YAAY,GAAG,iBAAiB,CAAC;AAEvF;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,uDAAuD;IACvD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAClC,OAAO,EAAE,CACL,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,cAAc,KAClB,OAAO,CAAC,oBAAoB,CAAC,CAAC;CACtC;AA4CD;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAiCvD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,EAAE,GAAG,MAAM,EAAE,CAoB9F;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,iBAAiB,EAAE,QAAQ,GAAE,OAAe,GAAG,MAAM,CAmB3F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAuDtE"}
@@ -41,10 +41,20 @@ function parseQuotedArguments(input) {
41
41
  return args.filter((arg) => arg.length > 0);
42
42
  }
43
43
  /**
44
- * Parses user input to determine if it's a slash command or a regular prompt
44
+ * Parses user input to determine if it's a slash command, shell command, or regular prompt
45
45
  */
46
46
  export function parseInput(input) {
47
47
  const trimmed = input.trim();
48
+ // Check if it's a shell command (! prefix)
49
+ if (trimmed.startsWith('!')) {
50
+ const shellCommand = trimmed.slice(1).trim();
51
+ return {
52
+ type: 'command',
53
+ command: 'shell',
54
+ args: [shellCommand],
55
+ rawInput: trimmed,
56
+ };
57
+ }
48
58
  // Check if it's a slash command
49
59
  if (trimmed.startsWith('/')) {
50
60
  const args = parseQuotedArguments(trimmed.slice(1));
@@ -1 +1 @@
1
- {"version":3,"file":"general-commands.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/interactive-commands/general-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAwC,MAAM,qBAAqB,CAAC;AAMnG;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,cAAc,EAAE,MAAM,iBAAiB,EAAE,GAAG,iBAAiB,CAgC9F;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,iBAAiB,EAiM9C,CAAC"}
1
+ {"version":3,"file":"general-commands.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/interactive-commands/general-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,iBAAiB,EAAwC,MAAM,qBAAqB,CAAC;AAiDnG;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,cAAc,EAAE,MAAM,iBAAiB,EAAE,GAAG,iBAAiB,CAgC9F;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,iBAAiB,EAyO9C,CAAC"}
@@ -10,9 +10,42 @@
10
10
  * - /clear, /reset - Clear conversation history
11
11
  */
12
12
  import chalk from 'chalk';
13
+ import { spawn } from 'child_process';
13
14
  import { formatForInkCli } from './utils/format-output.js';
14
15
  import { CommandOutputHelper } from './utils/command-output.js';
15
16
  import { writeToClipboard } from '../../ink-cli/utils/clipboardUtils.js';
17
+ /**
18
+ * Execute a shell command and return the output
19
+ */
20
+ async function executeShellCommand(command, cwd, timeoutMs = 30000) {
21
+ return new Promise((resolve) => {
22
+ const child = spawn(command, [], {
23
+ cwd,
24
+ shell: true,
25
+ stdio: ['ignore', 'pipe', 'pipe'],
26
+ });
27
+ let stdout = '';
28
+ let stderr = '';
29
+ const timer = setTimeout(() => {
30
+ child.kill();
31
+ resolve({ stdout, stderr: `Command timed out after ${timeoutMs}ms`, exitCode: -1 });
32
+ }, timeoutMs);
33
+ child.stdout.on('data', (data) => {
34
+ stdout += data.toString();
35
+ });
36
+ child.stderr.on('data', (data) => {
37
+ stderr += data.toString();
38
+ });
39
+ child.on('error', (error) => {
40
+ clearTimeout(timer);
41
+ resolve({ stdout, stderr: error.message, exitCode: -1 });
42
+ });
43
+ child.on('close', (code) => {
44
+ clearTimeout(timer);
45
+ resolve({ stdout, stderr, exitCode: code ?? -1 });
46
+ });
47
+ });
48
+ }
16
49
  /**
17
50
  * Creates the help command with access to all commands for display
18
51
  */
@@ -47,6 +80,36 @@ export function createHelpCommand(getAllCommands) {
47
80
  * Note: The help command is created separately to avoid circular dependencies
48
81
  */
49
82
  export const generalCommands = [
83
+ {
84
+ name: 'shell',
85
+ description: 'Execute shell command directly (use !command as shortcut)',
86
+ usage: '!<command> or /shell <command>',
87
+ category: 'General',
88
+ handler: async (args, agent, _ctx) => {
89
+ const command = args.join(' ').trim();
90
+ if (!command) {
91
+ return formatForInkCli('❌ No command provided. Usage: !<command>');
92
+ }
93
+ const cwd = process.cwd();
94
+ agent.logger.debug(`Executing shell command: ${command}`);
95
+ const { stdout, stderr, exitCode } = await executeShellCommand(command, cwd);
96
+ // Build output
97
+ const lines = [];
98
+ if (stdout.trim()) {
99
+ lines.push(stdout.trim());
100
+ }
101
+ if (stderr.trim()) {
102
+ lines.push(chalk.yellow(stderr.trim()));
103
+ }
104
+ if (exitCode !== 0) {
105
+ lines.push(chalk.red(`Exit code: ${exitCode}`));
106
+ }
107
+ if (lines.length === 0) {
108
+ return formatForInkCli(chalk.gray('(no output)'));
109
+ }
110
+ return formatForInkCli(lines.join('\n'));
111
+ },
112
+ },
50
113
  {
51
114
  name: 'exit',
52
115
  description: 'Exit the CLI',
@@ -1 +1 @@
1
- {"version":3,"file":"system-commands.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/interactive-commands/system/system-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAwC,MAAM,sBAAsB,CAAC;AAKpG;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,iBAAiB,EAwO7C,CAAC"}
1
+ {"version":3,"file":"system-commands.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/interactive-commands/system/system-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAwC,MAAM,sBAAsB,CAAC;AAKpG;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,iBAAiB,EAyO7C,CAAC"}
@@ -33,7 +33,7 @@ export const systemCommands = [
33
33
  const logFilePath = logger.getLogFilePath();
34
34
  console.log(chalk.bold.blue('\n📊 Logging Configuration:\n'));
35
35
  console.log(` Current level: ${chalk.green.bold(currentLevel)}`);
36
- if (logFilePath) {
36
+ if (logFilePath && process.env.DEXTO_PRIVACY_MODE !== 'true') {
37
37
  console.log(` Log file: ${chalk.cyan(logFilePath)}`);
38
38
  }
39
39
  console.log(chalk.gray('\n Available levels (from least to most verbose):'));
@@ -44,10 +44,11 @@ export const systemCommands = [
44
44
  console.log(` ${marker} ${levelText}`);
45
45
  });
46
46
  console.log(chalk.gray('\n 💡 Use /log <level> to change level (e.g., /log debug)\n'));
47
+ const isPrivacyMode = process.env.DEXTO_PRIVACY_MODE === 'true';
47
48
  const output = [
48
49
  '\n📊 Logging Configuration:',
49
50
  `Current level: ${currentLevel}`,
50
- logFilePath ? `Log file: ${logFilePath}` : '',
51
+ logFilePath && !isPrivacyMode ? `Log file: ${logFilePath}` : '',
51
52
  '\nAvailable levels: error, warn, info, http, verbose, debug, silly',
52
53
  '💡 Use /log <level> to change level',
53
54
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/setup.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA0CxB,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0ClB,CAAC;AAEP,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAClE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAiGtE;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAmC9F"}
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/setup.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA2CxB,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0ClB,CAAC;AAEP,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAClE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAsHtE;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAmC9F"}
@@ -1,7 +1,7 @@
1
1
  // packages/cli/src/cli/commands/setup.ts
2
2
  import chalk from 'chalk';
3
3
  import { z } from 'zod';
4
- import { getDefaultModelForProvider, LLM_PROVIDERS, LLM_REGISTRY, isValidProviderModel, getSupportedModels, acceptsAnyModel, supportsCustomModels, requiresApiKey, } from '@dexto/core';
4
+ import { getDefaultModelForProvider, LLM_PROVIDERS, LLM_REGISTRY, isValidProviderModel, getSupportedModels, acceptsAnyModel, supportsCustomModels, requiresApiKey, isReasoningCapableModel, } from '@dexto/core';
5
5
  import { resolveApiKeyForProvider } from '@dexto/core';
6
6
  import { createInitialPreferences, saveGlobalPreferences, loadGlobalPreferences, getGlobalPreferencesPath, updateGlobalPreferences, setActiveModel, } from '@dexto/agent-management';
7
7
  import { interactiveApiKeySetup, hasApiKeyConfigured } from '../utils/api-key-setup.js';
@@ -56,34 +56,44 @@ const SetupCommandSchema = z
56
56
  }
57
57
  });
58
58
  /**
59
- * Get the steps to display for the current provider.
60
- * Local/Ollama providers skip the API Key step.
59
+ * Get the steps to display for the current provider and model.
60
+ * - Local/Ollama providers skip the API Key step.
61
+ * - Reasoning-capable models (o1, o3, codex, gpt-5.x) show the Reasoning step.
61
62
  */
62
- function getWizardSteps(provider) {
63
+ function getWizardSteps(provider, model) {
63
64
  const isLocalProvider = provider === 'local' || provider === 'ollama';
65
+ const showReasoningStep = model && isReasoningCapableModel(model);
64
66
  if (isLocalProvider) {
65
- return [
67
+ const steps = [
66
68
  { key: 'provider', label: 'Provider' },
67
69
  { key: 'model', label: 'Model' },
68
- { key: 'mode', label: 'Mode' },
69
70
  ];
71
+ if (showReasoningStep) {
72
+ steps.push({ key: 'reasoningEffort', label: 'Reasoning' });
73
+ }
74
+ steps.push({ key: 'mode', label: 'Mode' });
75
+ return steps;
70
76
  }
71
- return [
77
+ const steps = [
72
78
  { key: 'provider', label: 'Provider' },
73
79
  { key: 'model', label: 'Model' },
74
- { key: 'apiKey', label: 'API Key' },
75
- { key: 'mode', label: 'Mode' },
76
80
  ];
81
+ if (showReasoningStep) {
82
+ steps.push({ key: 'reasoningEffort', label: 'Reasoning' });
83
+ }
84
+ steps.push({ key: 'apiKey', label: 'API Key' });
85
+ steps.push({ key: 'mode', label: 'Mode' });
86
+ return steps;
77
87
  }
78
88
  /**
79
89
  * Display step progress indicator for the setup wizard
80
90
  */
81
- function showStepProgress(currentStep, provider) {
91
+ function showStepProgress(currentStep, provider, model) {
82
92
  // Don't show progress for setupType (it's the entry point)
83
93
  if (currentStep === 'setupType' || currentStep === 'complete') {
84
94
  return;
85
95
  }
86
- const steps = getWizardSteps(provider);
96
+ const steps = getWizardSteps(provider, model);
87
97
  const currentIndex = steps.findIndex((s) => s.key === currentStep);
88
98
  if (currentIndex === -1) {
89
99
  return;
@@ -226,6 +236,9 @@ async function handleInteractiveSetup(_options) {
226
236
  case 'model':
227
237
  state = await wizardStepModel(state);
228
238
  break;
239
+ case 'reasoningEffort':
240
+ state = await wizardStepReasoningEffort(state);
241
+ break;
229
242
  case 'apiKey':
230
243
  state = await wizardStepApiKey(state);
231
244
  break;
@@ -299,8 +312,10 @@ async function wizardStepModel(state) {
299
312
  if (!hasSelectedModel(localResult)) {
300
313
  return { ...state, step: 'provider', model: undefined };
301
314
  }
302
- // Local providers skip apiKey step
303
- return { ...state, step: 'mode', model: getModelFromResult(localResult) };
315
+ const model = getModelFromResult(localResult);
316
+ // Check if model supports reasoning effort
317
+ const nextStep = isReasoningCapableModel(model) ? 'reasoningEffort' : 'mode';
318
+ return { ...state, step: nextStep, model };
304
319
  }
305
320
  if (provider === 'ollama') {
306
321
  const ollamaResult = await setupOllamaModels();
@@ -308,8 +323,10 @@ async function wizardStepModel(state) {
308
323
  if (!hasSelectedModel(ollamaResult)) {
309
324
  return { ...state, step: 'provider', model: undefined };
310
325
  }
311
- // Ollama skips apiKey step
312
- return { ...state, step: 'mode', model: getModelFromResult(ollamaResult) };
326
+ const model = getModelFromResult(ollamaResult);
327
+ // Check if model supports reasoning effort
328
+ const nextStep = isReasoningCapableModel(model) ? 'reasoningEffort' : 'mode';
329
+ return { ...state, step: nextStep, model };
313
330
  }
314
331
  // Handle baseURL for providers that need it
315
332
  let baseURL;
@@ -326,7 +343,52 @@ async function wizardStepModel(state) {
326
343
  if (model === '_back') {
327
344
  return { ...state, step: 'provider', model: undefined, baseURL: undefined };
328
345
  }
329
- return { ...state, step: 'apiKey', model, baseURL };
346
+ // Check if model supports reasoning effort
347
+ const nextStep = isReasoningCapableModel(model) ? 'reasoningEffort' : 'apiKey';
348
+ return { ...state, step: nextStep, model, baseURL };
349
+ }
350
+ /**
351
+ * Wizard Step: Reasoning Effort Selection (for OpenAI reasoning models)
352
+ */
353
+ async function wizardStepReasoningEffort(state) {
354
+ const provider = state.provider;
355
+ const model = state.model;
356
+ const isLocalProvider = provider === 'local' || provider === 'ollama';
357
+ showStepProgress('reasoningEffort', provider, model);
358
+ const result = await p.select({
359
+ message: 'Select reasoning effort level',
360
+ options: [
361
+ {
362
+ value: 'medium',
363
+ label: 'Medium (Recommended)',
364
+ hint: 'Balanced reasoning for most tasks',
365
+ },
366
+ { value: 'low', label: 'Low', hint: 'Light reasoning, fast responses' },
367
+ {
368
+ value: 'minimal',
369
+ label: 'Minimal',
370
+ hint: 'Barely any reasoning, very fast',
371
+ },
372
+ { value: 'high', label: 'High', hint: 'More thorough reasoning' },
373
+ {
374
+ value: 'xhigh',
375
+ label: 'Extra High',
376
+ hint: 'Maximum reasoning, slower responses',
377
+ },
378
+ { value: 'none', label: 'None', hint: 'Disable reasoning' },
379
+ { value: '_back', label: chalk.gray('← Back'), hint: 'Change model' },
380
+ ],
381
+ });
382
+ if (p.isCancel(result)) {
383
+ p.cancel('Setup cancelled');
384
+ process.exit(0);
385
+ }
386
+ if (result === '_back') {
387
+ return { ...state, step: 'model', reasoningEffort: undefined };
388
+ }
389
+ // Determine next step based on provider type
390
+ const nextStep = isLocalProvider ? 'mode' : 'apiKey';
391
+ return { ...state, step: nextStep, reasoningEffort: result };
330
392
  }
331
393
  /**
332
394
  * Wizard Step: API Key Configuration
@@ -334,7 +396,7 @@ async function wizardStepModel(state) {
334
396
  async function wizardStepApiKey(state) {
335
397
  const provider = state.provider;
336
398
  const model = state.model;
337
- showStepProgress('apiKey', provider);
399
+ showStepProgress('apiKey', provider, model);
338
400
  const hasKey = hasApiKeyConfigured(provider);
339
401
  const needsApiKey = requiresApiKey(provider);
340
402
  if (needsApiKey && !hasKey) {
@@ -343,8 +405,9 @@ async function wizardStepApiKey(state) {
343
405
  model,
344
406
  });
345
407
  if (result.cancelled) {
346
- // Go back to model selection
347
- return { ...state, step: 'model', apiKeySkipped: undefined };
408
+ // Go back to reasoning effort if model supports it, otherwise model selection
409
+ const prevStep = isReasoningCapableModel(model) ? 'reasoningEffort' : 'model';
410
+ return { ...state, step: prevStep, apiKeySkipped: undefined };
348
411
  }
349
412
  const apiKeySkipped = result.skipped || !result.success;
350
413
  return { ...state, step: 'mode', apiKeySkipped };
@@ -362,14 +425,22 @@ async function wizardStepApiKey(state) {
362
425
  */
363
426
  async function wizardStepMode(state) {
364
427
  const provider = state.provider;
428
+ const model = state.model;
365
429
  const isLocalProvider = provider === 'local' || provider === 'ollama';
366
- showStepProgress('mode', provider);
430
+ const hasReasoningStep = isReasoningCapableModel(model);
431
+ showStepProgress('mode', provider, model);
367
432
  const mode = await selectDefaultModeWithBack();
368
433
  if (mode === '_back') {
369
- // Go back to previous step (apiKey for cloud, model for local)
434
+ // Go back to previous step based on provider type and model capabilities
370
435
  if (isLocalProvider) {
371
- return { ...state, step: 'model', defaultMode: undefined };
436
+ // Local: reasoning effort -> model
437
+ return {
438
+ ...state,
439
+ step: hasReasoningStep ? 'reasoningEffort' : 'model',
440
+ defaultMode: undefined,
441
+ };
372
442
  }
443
+ // Cloud: always go back to apiKey (reasoning effort comes before apiKey)
373
444
  return { ...state, step: 'apiKey', defaultMode: undefined };
374
445
  }
375
446
  return { ...state, step: 'complete', defaultMode: mode };
@@ -472,6 +543,9 @@ async function saveWizardPreferences(state) {
472
543
  if (state.baseURL) {
473
544
  preferencesOptions.baseURL = state.baseURL;
474
545
  }
546
+ if (state.reasoningEffort) {
547
+ preferencesOptions.reasoningEffort = state.reasoningEffort;
548
+ }
475
549
  const preferences = createInitialPreferences(preferencesOptions);
476
550
  await saveGlobalPreferences(preferences);
477
551
  // Analytics
@@ -544,6 +618,9 @@ async function showSettingsMenu() {
544
618
  ...(currentPrefs.llm.baseURL
545
619
  ? [`Base URL: ${chalk.cyan(currentPrefs.llm.baseURL)}`]
546
620
  : []),
621
+ ...(currentPrefs.llm.reasoningEffort
622
+ ? [`Reasoning Effort: ${chalk.cyan(currentPrefs.llm.reasoningEffort)}`]
623
+ : []),
547
624
  ].join('\n');
548
625
  p.note(currentConfig, 'Current Configuration');
549
626
  }
@@ -634,9 +711,18 @@ async function changeModel(currentProvider) {
634
711
  return;
635
712
  }
636
713
  const model = getModelFromResult(localResult);
637
- await updateGlobalPreferences({
638
- llm: { provider, model },
639
- });
714
+ const llmUpdate = {
715
+ provider,
716
+ model,
717
+ };
718
+ // Ask for reasoning effort if applicable
719
+ if (isReasoningCapableModel(model)) {
720
+ const reasoningEffort = await selectReasoningEffort();
721
+ if (reasoningEffort !== null) {
722
+ llmUpdate.reasoningEffort = reasoningEffort;
723
+ }
724
+ }
725
+ await updateGlobalPreferences({ llm: llmUpdate });
640
726
  p.log.success(`Model changed to ${model}`);
641
727
  return;
642
728
  }
@@ -648,9 +734,18 @@ async function changeModel(currentProvider) {
648
734
  return;
649
735
  }
650
736
  const model = getModelFromResult(ollamaResult);
651
- await updateGlobalPreferences({
652
- llm: { provider, model },
653
- });
737
+ const llmUpdate = {
738
+ provider,
739
+ model,
740
+ };
741
+ // Ask for reasoning effort if applicable
742
+ if (isReasoningCapableModel(model)) {
743
+ const reasoningEffort = await selectReasoningEffort();
744
+ if (reasoningEffort !== null) {
745
+ llmUpdate.reasoningEffort = reasoningEffort;
746
+ }
747
+ }
748
+ await updateGlobalPreferences({ llm: llmUpdate });
654
749
  p.log.success(`Model changed to ${model}`);
655
750
  return;
656
751
  }
@@ -671,6 +766,13 @@ async function changeModel(currentProvider) {
671
766
  if (needsApiKey) {
672
767
  llmUpdate.apiKey = `$${apiKeyVar}`;
673
768
  }
769
+ // Ask for reasoning effort if applicable
770
+ if (isReasoningCapableModel(model)) {
771
+ const reasoningEffort = await selectReasoningEffort();
772
+ if (reasoningEffort !== null) {
773
+ llmUpdate.reasoningEffort = reasoningEffort;
774
+ }
775
+ }
674
776
  await updateGlobalPreferences({ llm: llmUpdate });
675
777
  p.log.success(`Model changed to ${model}`);
676
778
  }
@@ -810,6 +912,39 @@ async function selectDefaultMode() {
810
912
  }
811
913
  return mode;
812
914
  }
915
+ /**
916
+ * Select reasoning effort level for reasoning-capable models
917
+ * Used in settings menu when changing to a reasoning-capable model
918
+ */
919
+ async function selectReasoningEffort() {
920
+ const effort = await p.select({
921
+ message: 'Select reasoning effort level',
922
+ options: [
923
+ {
924
+ value: 'medium',
925
+ label: 'Medium (Recommended)',
926
+ hint: 'Balanced reasoning for most tasks',
927
+ },
928
+ { value: 'low', label: 'Low', hint: 'Light reasoning, fast responses' },
929
+ {
930
+ value: 'minimal',
931
+ label: 'Minimal',
932
+ hint: 'Barely any reasoning, very fast',
933
+ },
934
+ { value: 'high', label: 'High', hint: 'More thorough reasoning' },
935
+ {
936
+ value: 'xhigh',
937
+ label: 'Extra High',
938
+ hint: 'Maximum reasoning, slower responses',
939
+ },
940
+ { value: 'none', label: 'None', hint: 'Disable reasoning' },
941
+ ],
942
+ });
943
+ if (p.isCancel(effort)) {
944
+ return null;
945
+ }
946
+ return effort;
947
+ }
813
948
  /**
814
949
  * Select model interactively
815
950
  * Returns null if user cancels
@@ -1 +1 @@
1
- {"version":3,"file":"TextBufferInput.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/components/TextBufferInput.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGnE,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG,oBAAoB,GAAG,uBAAuB,GAAG,OAAO,CAAC;AActF,UAAU,oBAAoB;IAC1B,oCAAoC;IACpC,MAAM,EAAE,UAAU,CAAC;IACnB,+CAA+C;IAC/C,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,mEAAmE;IACnE,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACrE,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACnE,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,kDAAkD;IAClD,QAAQ,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACpE,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,iDAAiD;IACjD,YAAY,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC3D,iEAAiE;IACjE,MAAM,CAAC,EAAE,YAAY,EAAE,GAAG,SAAS,CAAC;IACpC,4DAA4D;IAC5D,aAAa,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACxD,wDAAwD;IACxD,YAAY,CAAC,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;IACzC,oEAAoE;IACpE,YAAY,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC1D,8DAA8D;IAC9D,kBAAkB,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC5F,iEAAiE;IACjE,kBAAkB,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC7D,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAuCD,wBAAgB,eAAe,CAAC,EAC5B,MAAM,EACN,QAAQ,EACR,WAAW,EACX,UAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAqB,EACrB,QAAQ,EACR,gBAAgB,EAChB,UAAc,EACd,YAAY,EACZ,MAAW,EACX,aAAa,EACb,YAAiB,EACjB,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,GACjB,EAAE,oBAAoB,2CAsgBtB"}
1
+ {"version":3,"file":"TextBufferInput.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/components/TextBufferInput.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGnE,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG,oBAAoB,GAAG,uBAAuB,GAAG,OAAO,CAAC;AActF,UAAU,oBAAoB;IAC1B,oCAAoC;IACpC,MAAM,EAAE,UAAU,CAAC;IACnB,+CAA+C;IAC/C,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,mEAAmE;IACnE,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACrE,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACnE,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,kDAAkD;IAClD,QAAQ,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACpE,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,iDAAiD;IACjD,YAAY,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC3D,iEAAiE;IACjE,MAAM,CAAC,EAAE,YAAY,EAAE,GAAG,SAAS,CAAC;IACpC,4DAA4D;IAC5D,aAAa,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACxD,wDAAwD;IACxD,YAAY,CAAC,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;IACzC,oEAAoE;IACpE,YAAY,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC1D,8DAA8D;IAC9D,kBAAkB,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC5F,iEAAiE;IACjE,kBAAkB,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC7D,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAuCD,wBAAgB,eAAe,CAAC,EAC5B,MAAM,EACN,QAAQ,EACR,WAAW,EACX,UAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAqB,EACrB,QAAQ,EACR,gBAAgB,EAChB,UAAc,EACd,YAAY,EACZ,MAAW,EACX,aAAa,EACb,YAAiB,EACjB,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,GACjB,EAAE,oBAAoB,2CA2gBtB"}
@@ -415,6 +415,10 @@ export function TextBufferInput({ buffer, onSubmit, placeholder, isDisabled = fa
415
415
  const cursorVisualCol = visualCursor[1];
416
416
  const separator = '─'.repeat(terminalWidth);
417
417
  const totalLines = visualLines.length;
418
+ // Detect shell command mode (input starts with "!")
419
+ const isShellMode = bufferText.startsWith('!');
420
+ const promptPrefix = isShellMode ? '$ ' : '> ';
421
+ const promptColor = isShellMode ? 'yellow' : 'green';
418
422
  // Calculate visible window
419
423
  let startLine = 0;
420
424
  let endLine = totalLines;
@@ -434,15 +438,15 @@ export function TextBufferInput({ buffer, onSubmit, placeholder, isDisabled = fa
434
438
  return (_jsxs(Box, { flexDirection: "column", width: terminalWidth, children: [_jsx(Text, { color: "gray", children: separator }), startLine > 0 && (_jsxs(Text, { color: "gray", children: [' ', "\u2191 ", startLine, " more line", startLine > 1 ? 's' : '', " above (", KEY_LABELS.altUp, " to jump)"] })), visibleLines.map((line, idx) => {
435
439
  const absoluteRow = startLine + idx;
436
440
  const isFirst = absoluteRow === 0;
437
- const prefix = isFirst ? '> ' : ' ';
441
+ const prefix = isFirst ? promptPrefix : ' ';
438
442
  const isCursorLine = absoluteRow === cursorVisualRow;
439
443
  if (!isCursorLine) {
440
- return (_jsxs(Box, { width: terminalWidth, children: [_jsx(Text, { color: "green", bold: isFirst, children: prefix }), _jsx(HighlightedText, { text: line, query: highlightQuery }), _jsx(Text, { children: ' '.repeat(Math.max(0, terminalWidth - prefix.length - line.length)) })] }, absoluteRow));
444
+ return (_jsxs(Box, { width: terminalWidth, children: [_jsx(Text, { color: promptColor, bold: isFirst, children: prefix }), _jsx(HighlightedText, { text: line, query: highlightQuery }), _jsx(Text, { children: ' '.repeat(Math.max(0, terminalWidth - prefix.length - line.length)) })] }, absoluteRow));
441
445
  }
442
446
  const before = line.slice(0, cursorVisualCol);
443
447
  const atCursor = line.charAt(cursorVisualCol) || ' ';
444
448
  const after = line.slice(cursorVisualCol + 1);
445
- return (_jsxs(Box, { width: terminalWidth, children: [_jsx(Text, { color: "green", bold: isFirst, children: prefix }), _jsx(HighlightedText, { text: before, query: highlightQuery }), _jsx(Text, { inverse: true, children: atCursor }), _jsx(HighlightedText, { text: after, query: highlightQuery }), _jsx(Text, { children: ' '.repeat(Math.max(0, terminalWidth - prefix.length - before.length - 1 - after.length)) })] }, absoluteRow));
449
+ return (_jsxs(Box, { width: terminalWidth, children: [_jsx(Text, { color: promptColor, bold: isFirst, children: prefix }), _jsx(HighlightedText, { text: before, query: highlightQuery }), _jsx(Text, { inverse: true, children: atCursor }), _jsx(HighlightedText, { text: after, query: highlightQuery }), _jsx(Text, { children: ' '.repeat(Math.max(0, terminalWidth - prefix.length - before.length - 1 - after.length)) })] }, absoluteRow));
446
450
  }), endLine < totalLines && (_jsxs(Text, { color: "gray", children: [' ', "\u2193 ", totalLines - endLine, " more line", totalLines - endLine > 1 ? 's' : '', ' ', "below (", KEY_LABELS.altDown, " to jump)"] })), pastedBlocks.length > 0 && (_jsx(PasteBlockHint, { pastedBlocks: pastedBlocks, expandedBlock: findExpandedBlock(), cursorOnCollapsed: findCollapsedBlockAtCursor() })), _jsx(Text, { color: "gray", children: separator })] }));
447
451
  }
448
452
  /** Hint component for paste blocks */
@@ -12,5 +12,5 @@ export function Header({ modelName, sessionId, hasActiveSession, startupInfo })
12
12
  ██║ ██║█████╗ ╚███╔╝ ██║ ██║ ██║
13
13
  ██║ ██║██╔══╝ ██╔██╗ ██║ ██║ ██║
14
14
  ██████╔╝███████╗██╔╝ ██╗ ██║ ╚██████╔╝
15
- ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝` }) }), _jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsx(Text, { color: "gray", children: "Model: " }), _jsx(Text, { color: "white", children: modelName }), hasActiveSession && sessionId && (_jsxs(_Fragment, { children: [_jsx(Text, { color: "gray", children: " \u2022 Session: " }), _jsx(Text, { color: "white", children: sessionId.slice(0, 8) })] }))] }), _jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "gray", children: "Servers: " }), _jsx(Text, { color: "white", children: startupInfo.connectedServers.count }), _jsx(Text, { color: "gray", children: " \u2022 Tools: " }), _jsx(Text, { color: "white", children: startupInfo.toolCount })] }), startupInfo.failedConnections.length > 0 && (_jsx(Box, { flexDirection: "row", children: _jsxs(Text, { color: "yellowBright", children: ["\u26A0\uFE0F Failed: ", startupInfo.failedConnections.join(', ')] }) })), startupInfo.logFile && (_jsx(Box, { flexDirection: "row", children: _jsxs(Text, { color: "gray", children: ["Logs: ", startupInfo.logFile] }) })), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: " " }) })] }));
15
+ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝` }) }), _jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsx(Text, { color: "gray", children: "Model: " }), _jsx(Text, { color: "white", children: modelName }), hasActiveSession && sessionId && (_jsxs(_Fragment, { children: [_jsx(Text, { color: "gray", children: " \u2022 Session: " }), _jsx(Text, { color: "white", children: sessionId.slice(0, 8) })] }))] }), _jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "gray", children: "Servers: " }), _jsx(Text, { color: "white", children: startupInfo.connectedServers.count }), _jsx(Text, { color: "gray", children: " \u2022 Tools: " }), _jsx(Text, { color: "white", children: startupInfo.toolCount })] }), startupInfo.failedConnections.length > 0 && (_jsx(Box, { flexDirection: "row", children: _jsxs(Text, { color: "yellowBright", children: ["\u26A0\uFE0F Failed: ", startupInfo.failedConnections.join(', ')] }) })), startupInfo.logFile && process.env.DEXTO_PRIVACY_MODE !== 'true' && (_jsx(Box, { flexDirection: "row", children: _jsxs(Text, { color: "gray", children: ["Logs: ", startupInfo.logFile] }) })), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: " " }) })] }));
16
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MessageItem.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/chat/MessageItem.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EACR,OAAO,EAUV,MAAM,sBAAsB,CAAC;AAuC9B,UAAU,gBAAgB;IACtB,OAAO,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,oDACN,gBAAgB,6CAwJjC,CAAC"}
1
+ {"version":3,"file":"MessageItem.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/chat/MessageItem.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EACR,OAAO,EAUV,MAAM,sBAAsB,CAAC;AAuC9B,UAAU,gBAAgB;IACtB,OAAO,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,oDACN,gBAAgB,6CA2JjC,CAAC"}
@@ -55,7 +55,10 @@ export const MessageItem = memo(({ message }) => {
55
55
  case 'run-summary': {
56
56
  const data = message.styledData;
57
57
  const durationStr = formatDuration(data.durationMs);
58
- const tokensStr = data.outputTokens > 0 ? `, Used ${data.outputTokens} tokens` : '';
58
+ // Only show tokens when >= 1000, using K notation
59
+ const tokensStr = data.totalTokens >= 1000
60
+ ? `, Used ${(data.totalTokens / 1000).toFixed(1)}K tokens`
61
+ : '';
59
62
  return (_jsx(Box, { marginTop: 1, marginBottom: 1, width: "100%", children: _jsxs(Text, { color: "gray", children: ["\u2500 Worked for ", durationStr, tokensStr, " \u2500"] }) }));
60
63
  }
61
64
  case 'shortcuts':
@@ -1 +1 @@
1
- {"version":3,"file":"LogConfigBox.d.ts","sourceRoot":"","sources":["../../../../../../src/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGnE,UAAU,iBAAiB;IACvB,IAAI,EAAE,mBAAmB,CAAC;CAC7B;AAED,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,iBAAiB,2CA4BvD"}
1
+ {"version":3,"file":"LogConfigBox.d.ts","sourceRoot":"","sources":["../../../../../../src/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGnE,UAAU,iBAAiB;IACvB,IAAI,EAAE,mBAAmB,CAAC;CAC7B;AAED,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,iBAAiB,2CA8BvD"}
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Text } from 'ink';
3
3
  import { StyledBox, StyledRow, StyledListItem } from './StyledBox.js';
4
4
  export function LogConfigBox({ data }) {
5
- return (_jsxs(StyledBox, { title: "Logging Configuration", children: [_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(StyledRow, { label: "Current level", value: data.currentLevel, valueColor: "green" }), data.logFile && _jsx(StyledRow, { label: "Log file", value: data.logFile })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "Available levels (least to most verbose):" }), data.availableLevels.map((level) => {
5
+ return (_jsxs(StyledBox, { title: "Logging Configuration", children: [_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(StyledRow, { label: "Current level", value: data.currentLevel, valueColor: "green" }), data.logFile && process.env.DEXTO_PRIVACY_MODE !== 'true' && (_jsx(StyledRow, { label: "Log file", value: data.logFile }))] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "Available levels (least to most verbose):" }), data.availableLevels.map((level) => {
6
6
  const isCurrent = level === data.currentLevel;
7
7
  return (_jsx(StyledListItem, { icon: isCurrent ? '>' : ' ', text: level, isActive: isCurrent }, level));
8
8
  })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: "Use /log <level> to change level" }) })] }));
@@ -1 +1 @@
1
- {"version":3,"file":"CustomModelWizard.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/CustomModelWizard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,EAIH,KAAK,WAAW,EAMnB,MAAM,yBAAyB,CAAC;AAmBjC,UAAU,sBAAsB;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACzC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,uEAAuE;IACvE,YAAY,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,uBAAuB;IACpC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAED;;;GAGG;AACH,QAAA,MAAM,iBAAiB,wGAqXtB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"CustomModelWizard.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/CustomModelWizard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,EAIH,KAAK,WAAW,EAMnB,MAAM,yBAAyB,CAAC;AAmBjC,UAAU,sBAAsB;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACzC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,uEAAuE;IACvE,YAAY,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,uBAAuB;IACpC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAED;;;GAGG;AACH,QAAA,MAAM,iBAAiB,wGAwYtB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}