osai-agent 4.2.41 → 4.2.42

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "osai-agent",
3
- "version": "4.2.41",
3
+ "version": "4.2.42",
4
4
  "type": "module",
5
5
  "description": "OS AI Agent - YOUR AI AGENT",
6
6
  "main": "src/index.js",
@@ -1,7 +1,7 @@
1
1
  import Conf from 'conf';
2
2
  import chalk from 'chalk';
3
3
  import boxen from 'boxen';
4
- import { DOT, EMPTY } from '../utils/unicode.js';
4
+ import { DOT, EMPTY, WARN } from '../utils/unicode.js';
5
5
  import ora from 'ora';
6
6
  import { createInterface } from 'node:readline';
7
7
  import { rmSync, existsSync } from 'node:fs';
@@ -39,7 +39,7 @@ export const deleteAccount = async ({ server: serverArg }) => {
39
39
  }
40
40
 
41
41
  console.log(boxen(
42
- chalk.hex('#f7768e').bold('⚠ WARNING') +
42
+ chalk.hex('#f7768e').bold(`${WARN} WARNING`) +
43
43
  chalk.hex('#c0caf5')('\n\nThis will permanently delete your account and all associated data.') +
44
44
  chalk.hex('#c0caf5')('\nThis includes: devices, logs, sessions, provider settings, pro key, and more.') +
45
45
  chalk.hex('#ff9e64')('\n\nThis action CANNOT be undone.') +
@@ -3,7 +3,7 @@ import Conf from 'conf';
3
3
  import inquirer from 'inquirer';
4
4
  import ora from 'ora';
5
5
  import { printError, printSuccess, printInfo, printNotLoggedIn } from '../ui/terminal.js';
6
- import { isUnicode, DASH } from '../utils/unicode.js';
6
+ import { isUnicode, DASH, WARN } from '../utils/unicode.js';
7
7
  import { toHttpUrl } from '../services/server-url.js';
8
8
  import { encrypt, decrypt, deriveKey } from '../services/crypto.js';
9
9
  import pkg from 'node-machine-id';
@@ -340,7 +340,7 @@ export const showProviderModels = async (provider) => {
340
340
  console.log(chalk.hex('#7aa2f7').bold(` ${data.provider} — Available Models`));
341
341
  console.log(chalk.hex('#565f89')(` Source: ${sourceLabel}`));
342
342
  if (data.warning) {
343
- console.log(chalk.hex('#ff9e64')(` ${data.warning}`));
343
+ console.log(chalk.hex('#ff9e64')(` ${WARN} ${data.warning}`));
344
344
  }
345
345
 
346
346
  if (provider === 'ollama') {
package/src/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ process.title = 'osai-agent';
2
3
 
3
4
  import { run } from './commands/run.js';
4
5
  import { login } from './commands/login.js';
@@ -8,6 +8,7 @@ import os from 'os';
8
8
  import { DEFAULTS, TOOLS } from '../utils/constants.js';
9
9
  import { logger } from '../utils/logger.js';
10
10
  import { searchDDG, searchSerpAPI, searchTavily, searchDDGHttp, formatSearchOutput } from './search-providers.js';
11
+ import { TREE_BRANCH, TREE_LAST, TREE_VLINE, TREE_SPACE } from '../utils/unicode.js';
11
12
  import { extractExports, extractLocalImports } from '../parser/dependencies.js';
12
13
 
13
14
  const execAsync = promisify(exec);
@@ -627,8 +628,8 @@ export const treeView = async (dirPath, maxDepth = 3, includeHidden = false) =>
627
628
  if (lines.length >= MAX_TOTAL_LINES) return;
628
629
  const entry = shown[i];
629
630
  const isLast = i === shown.length - 1;
630
- const connector = isLast ? '└── ' : '├── ';
631
- const childPrefix = isLast ? ' ' : '│ ';
631
+ const connector = isLast ? TREE_LAST : TREE_BRANCH;
632
+ const childPrefix = isLast ? TREE_SPACE : TREE_VLINE;
632
633
 
633
634
  if (entry.isDirectory()) {
634
635
  lines.push(`${prefix}${connector}${entry.name}/`);
@@ -639,7 +640,7 @@ export const treeView = async (dirPath, maxDepth = 3, includeHidden = false) =>
639
640
  }
640
641
 
641
642
  if (!showAll) {
642
- lines.push(`${prefix}└── ... (${filtered.length - MAX_FILES_PER_DIR} more entries)`);
643
+ lines.push(`${prefix}${TREE_LAST}... (${filtered.length - MAX_FILES_PER_DIR} more entries)`);
643
644
  }
644
645
  }
645
646
 
package/src/ui/App.js CHANGED
@@ -31,10 +31,11 @@ import Conf from 'conf';
31
31
  import chalk from 'chalk';
32
32
  import boxen from 'boxen';
33
33
  import { ENABLE_UI_ANIMATIONS, useAnimationFrame } from './animation.js';
34
+ import { DASH, TRIANGLE, HEADER_LOGO_L, HEADER_LOGO_M, HEADER_LOGO_R, SPINNER_BRAILLE, LOADING_DOTS } from '../utils/unicode.js';
34
35
 
35
36
  function TaskSeparator({ label, columns }) {
36
37
  const width = Math.max(16, (columns || 80) - 1);
37
- const line = '─'.repeat(width);
38
+ const line = DASH.repeat(width);
38
39
 
39
40
  return h(Box, { flexDirection: 'column', width: '100%' },
40
41
  h(Text, { color: '#2a2e3f' }, line),
@@ -43,12 +44,11 @@ function TaskSeparator({ label, columns }) {
43
44
  }
44
45
 
45
46
  let InputFrameLine = ({ columns }) => {
46
- const line = '─'.repeat(columns || 80);
47
+ const line = DASH.repeat(columns || 80);
47
48
  return h(Text, { color: '#c0caf5' }, line);
48
49
  };
49
50
 
50
- const LOADING_SPINNER = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
51
- const LOADING_DOTS = ['', '∘', '∘∘', '∘∘∘'];
51
+ const LOADING_SPINNER = SPINNER_BRAILLE;
52
52
 
53
53
  function LoadingDots({ text }) {
54
54
  const frame = useAnimationFrame();
@@ -1871,7 +1871,7 @@ Tip: Press Tab to toggle between PLAN and EXEC mode_
1871
1871
  h(Text, { color: 'white' }, '\u250C\u2500\u2500\u2500\u2510'),
1872
1872
  h(Box, { flexDirection: 'row' },
1873
1873
  h(Text, { color: 'white' }, '\u2502 '),
1874
- h(Text, { color: '#4a9eff' }, '\u25B2'),
1874
+ h(Text, { color: '#4a9eff' }, TRIANGLE),
1875
1875
  h(Text, { color: 'white' }, ' \u2502'),
1876
1876
  ),
1877
1877
  h(Text, { color: 'white' }, '\u2514\u2500\u2500\u2500\u2518'),
@@ -1907,9 +1907,9 @@ Tip: Press Tab to toggle between PLAN and EXEC mode_
1907
1907
  h(Box, { paddingLeft: 2, paddingTop: 1 },
1908
1908
  h(Text, { color: '#e0af68', bold: true }, `[${agentConfig.mode}/${executionMode}]`),
1909
1909
  h(Text, { color: '#565f89', dimColor: true }, ' '),
1910
- h(Text, { color: 'white' }, '\u2590'),
1911
- h(Text, { color: '#4a9eff' }, '\u25B3'),
1912
- h(Text, { color: 'white' }, '\u258C'),
1910
+ h(Text, { color: 'white' }, HEADER_LOGO_L),
1911
+ h(Text, { color: '#4a9eff' }, HEADER_LOGO_M),
1912
+ h(Text, { color: 'white' }, HEADER_LOGO_R),
1913
1913
  isLocal
1914
1914
  ? (currentProvider && currentProvider.type
1915
1915
  ? h(Text, { color: '#9ece6a' }, ` ${currentProvider.type}${currentProvider.model ? '/' + currentProvider.model : ''} - `)
@@ -2039,9 +2039,9 @@ Tip: Press Tab to toggle between PLAN and EXEC mode_
2039
2039
  state === 'thinking' ? h(Text, { color: '#565f89', dimColor: true }, ' to toggle thinking') : null,
2040
2040
  ),
2041
2041
  h(Box, { flexDirection: 'row', flexWrap: 'wrap' },
2042
- h(Text, { color: 'white' }, '\u2590'),
2043
- h(Text, { color: '#4a9eff' }, '\u25B3'),
2044
- h(Text, { color: 'white' }, '\u258C'),
2042
+ h(Text, { color: 'white' }, HEADER_LOGO_L),
2043
+ h(Text, { color: '#4a9eff' }, HEADER_LOGO_M),
2044
+ h(Text, { color: 'white' }, HEADER_LOGO_R),
2045
2045
  isLocal
2046
2046
  ? (currentProvider && currentProvider.type
2047
2047
  ? h(Text, { color: '#9ece6a' }, ` ${currentProvider.type}${currentProvider.model ? '/' + currentProvider.model : ''} - `)
@@ -3,6 +3,7 @@ import { Box, Text, useInput, useWindowSize } from 'ink';
3
3
  import { h } from '../h.js';
4
4
  import { InputShell } from './InputShell.js';
5
5
  import { isOnlySgrMouseInput } from '../mouse-scroll.js';
6
+ import { ARROW, CLOUD } from '../../utils/unicode.js';
6
7
 
7
8
  export function HistoryPicker({ sessions, visible, onSelect, onCancel }) {
8
9
  const [cursor, setCursor] = useState(0);
@@ -101,8 +102,8 @@ export function HistoryPicker({ sessions, visible, onSelect, onCancel }) {
101
102
  ...visibleItems.map((s, i) => {
102
103
  const realIdx = startIdx + i;
103
104
  const isHL = realIdx === cursor;
104
- const prefix = isHL ? h(Text, { color: '#9ece6a' }, ' ') : h(Text, { color: '#3b3f52' }, ' ');
105
- const storageIcon = s.storage === 'cloud' ? '☁ ' : ' ';
105
+ const prefix = isHL ? h(Text, { color: '#9ece6a' }, ` ${ARROW} `) : h(Text, { color: '#3b3f52' }, ' ');
106
+ const storageIcon = s.storage === 'cloud' ? `${CLOUD} ` : ' ';
106
107
 
107
108
  return h(Box, { key: realIdx },
108
109
  prefix,
@@ -3,6 +3,7 @@ import { Box, Text, useInput, useWindowSize } from 'ink';
3
3
  import { h } from '../h.js';
4
4
  import { InputShell } from './InputShell.js';
5
5
  import { isOnlySgrMouseInput } from '../mouse-scroll.js';
6
+ import { ARROW } from '../../utils/unicode.js';
6
7
 
7
8
  /**
8
9
  * Reusable interactive menu with:
@@ -143,7 +144,7 @@ export function SelectMenu({
143
144
  ...visibleItems.map((item, i) => {
144
145
  const realIdx = startIdx + i;
145
146
  const isHighlighted = realIdx === cursor;
146
- const icon = isHighlighted ? h(Text, { color: '#9ece6a' }, ' ') : h(Text, { color: '#3b3f52' }, ' ');
147
+ const icon = isHighlighted ? h(Text, { color: '#9ece6a' }, ` ${ARROW} `) : h(Text, { color: '#3b3f52' }, ' ');
147
148
  const label = item.label || item.cmd || item.name || '';
148
149
  const desc = item.desc ? ` ${item.desc}` : '';
149
150
  const mark = item.active ? ' ◀' : '';
@@ -3,6 +3,7 @@ import { Box, Text, useInput, useWindowSize } from 'ink';
3
3
  import { h } from '../h.js';
4
4
  import { InputShell } from './InputShell.js';
5
5
  import { isOnlySgrMouseInput } from '../mouse-scroll.js';
6
+ import { ARROW } from '../../utils/unicode.js';
6
7
 
7
8
  const COMMANDS = [
8
9
  { cmd: '/clear', desc: 'Clear displayed history', action: 'clear' },
@@ -123,7 +124,7 @@ export function SlashMenu({ visible, onSelect, onCancel }) {
123
124
  ...visibleItems.map((cmd, i) => {
124
125
  const realIdx = startIdx + i;
125
126
  const isHighlighted = realIdx === cursor;
126
- const prefix = isHighlighted ? h(Text, { color: '#9ece6a' }, ' ') : h(Text, { color: '#3b3f52' }, ' ');
127
+ const prefix = isHighlighted ? h(Text, { color: '#9ece6a' }, ` ${ARROW} `) : h(Text, { color: '#3b3f52' }, ' ');
127
128
 
128
129
  return h(
129
130
  Box,
@@ -187,7 +187,7 @@ export function ToolResult({ result }) {
187
187
  if (!result) return null;
188
188
 
189
189
  const color = getToolColor(result.name);
190
- const label = result.success ? '✓' : '✗';
190
+ const label = result.success ? TICK : CROSS;
191
191
  const labelColor = result.success ? '#9ece6a' : '#f7768e';
192
192
  const out = String(result.output || '');
193
193
  const target = formatTarget(result.toolCall);
@@ -40,3 +40,13 @@ export const MODE_ICONS = isUnicode
40
40
  export const HEADER_LOGO_L = isUnicode ? '▐' : '[';
41
41
  export const HEADER_LOGO_M = isUnicode ? '△' : '^';
42
42
  export const HEADER_LOGO_R = isUnicode ? '▌' : ']';
43
+ export const WARN = isUnicode ? '⚠' : '!';
44
+ export const CLOUD = isUnicode ? '☁' : '~';
45
+ export const TRIANGLE = isUnicode ? '▲' : '^';
46
+ export const TREE_BRANCH = isUnicode ? '├── ' : '|-- ';
47
+ export const TREE_LAST = isUnicode ? '└── ' : '`-- ';
48
+ export const TREE_VLINE = isUnicode ? '│ ' : '| ';
49
+ export const TREE_SPACE = ' ';
50
+ export const LOADING_DOTS = isUnicode
51
+ ? ['', '∘', '∘∘', '∘∘∘']
52
+ : ['', '.', '..', '...'];