clarity-ai 6.3.1 → 6.3.2

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": "clarity-ai",
3
- "version": "6.3.1",
3
+ "version": "6.3.2",
4
4
  "description": "Premium terminal AI agent — fixed-height viewport, box-drawing UI, TrueColor theme, streaming with abort",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,8 +1,9 @@
1
- import React, { useState, useCallback, useRef, useEffect } from 'react';
1
+ import React, { useState, useCallback, useRef } from 'react';
2
2
  import { Box } from 'ink';
3
3
  import { createChatState, handleSend, handleCommand } from '../chat.js';
4
4
  import { hex } from '../config/theme.js';
5
5
  import { Layout } from './Layout.js';
6
+ const { createElement: h } = React;
6
7
 
7
8
  let abortController = null;
8
9
 
@@ -73,8 +74,8 @@ export function App({ config }) {
73
74
  }));
74
75
  }
75
76
 
76
- return Box({ flexDirection: 'column', backgroundColor: hex.bg },
77
- Layout({
77
+ return h(Box, { flexDirection: 'column', backgroundColor: hex.bg },
78
+ h(Layout, {
78
79
  state,
79
80
  streamContent,
80
81
  model,
@@ -1,7 +1,8 @@
1
- import React, { useState, useCallback, useRef } from 'react';
1
+ import React, { useState, useRef } from 'react';
2
2
  import { Box, Text, useInput } from 'ink';
3
3
  import { hex, usym, u } from '../config/theme.js';
4
4
  import { getLayout } from '../config/layout.js';
5
+ const { createElement: h } = React;
5
6
 
6
7
  const MAX_VISIBLE_ROWS = 3;
7
8
 
@@ -57,19 +58,18 @@ export function Composer({ provider, model, agentMode, thinking, onSlash, onSubm
57
58
 
58
59
  const rows = [];
59
60
  rows.push(
60
- Box({ key: 'dock_header', height: 1, backgroundColor: hex.surfaceAlt },
61
- Text({ color: hex.textMuted, backgroundColor: hex.surfaceAlt }, ' ' + u.h.repeat(Math.max(0, cols - 2)))
61
+ h(Box, { key: 'dock_header', height: 1, backgroundColor: hex.surfaceAlt },
62
+ h(Text, { color: hex.textMuted, backgroundColor: hex.surfaceAlt }, ' ' + u.h.repeat(Math.max(0, cols - 2)))
62
63
  )
63
64
  );
64
65
 
65
- const inputRows = [];
66
- for (let i = 0; i < visibleLines; i++) {
66
+ for (let i = 0; i < MAX_VISIBLE_ROWS; i++) {
67
67
  const start = i * w;
68
68
  const end = start + w;
69
69
  const seg = displayText.slice(start, end);
70
- inputRows.push(
71
- Box({ key: 'in' + i, height: 1, backgroundColor: hex.bg },
72
- Text({
70
+ rows.push(
71
+ h(Box, { key: 'in' + i, height: 1, backgroundColor: hex.bg },
72
+ h(Text, {
73
73
  color: isPlaceholder ? hex.textMuted : hex.text,
74
74
  backgroundColor: hex.bg,
75
75
  wrap: 'truncate-end',
@@ -78,27 +78,15 @@ export function Composer({ provider, model, agentMode, thinking, onSlash, onSubm
78
78
  );
79
79
  }
80
80
 
81
- for (let i = visibleLines; i < MAX_VISIBLE_ROWS + 1; i++) {
82
- if (i === MAX_VISIBLE_ROWS + 0) break;
83
- inputRows.push(
84
- Box({ key: 'in_fill' + i, height: 1, backgroundColor: hex.bg },
85
- Text({ color: hex.textMuted, backgroundColor: hex.bg }, ' ' + usym.lightV)
81
+ rows.push(
82
+ h(Box, { key: 'dock_status', height: 1, backgroundColor: hex.surfaceAlt },
83
+ h(Text, { color: hex.textMuted, backgroundColor: hex.surfaceAlt },
84
+ ' ' + provider + ' ' + usym.midDot + ' ' + modelShort +
85
+ (agentMode ? ' ' + usym.midDot + ' Agent' : '') +
86
+ ' ' + usym.midDot + ' Ctrl+P commands'
86
87
  )
87
- );
88
- }
89
-
90
- const statusLine = Box({ key: 'dock_status', height: 1, backgroundColor: hex.surfaceAlt },
91
- Text({ color: hex.textMuted, backgroundColor: hex.surfaceAlt },
92
- ' ' + provider + ' ' + usym.midDot + ' ' + modelShort +
93
- (agentMode ? ' ' + usym.midDot + ' Agent' : '') +
94
- ' ' + usym.midDot + ' Ctrl+P commands'
95
88
  )
96
89
  );
97
90
 
98
- rows.push(...inputRows);
99
- rows.push(statusLine);
100
-
101
- return Box({ flexDirection: 'column', backgroundColor: hex.surfaceAlt },
102
- ...rows
103
- );
91
+ return h(Box, { flexDirection: 'column', backgroundColor: hex.surfaceAlt }, ...rows);
104
92
  }
@@ -1,69 +1,70 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import { Box, Text } from 'ink';
3
3
  import { hex, usym, u } from '../config/theme.js';
4
- import { getLayout, wrapText, sliceToViewport, buildLineArray } from '../config/layout.js';
4
+ import { getLayout, sliceToViewport, buildLineArray } from '../config/layout.js';
5
+ const { createElement: h } = React;
5
6
 
6
7
  function LineRenderer({ type, text, data }) {
7
8
  const { cols } = getLayout();
8
9
  switch (type) {
9
10
  case 'user_head':
10
- return Box({ height: 1, backgroundColor: hex.userBg },
11
- Text({ color: hex.accent, bold: true, backgroundColor: hex.userBg }, ' ' + usym.circle + ' YOU'),
12
- Text({ color: hex.textMuted, backgroundColor: hex.userBg }, ' ' + u.h.repeat(Math.max(0, cols - 10)))
11
+ return h(Box, { height: 1, backgroundColor: hex.userBg },
12
+ h(Text, { color: hex.accent, bold: true, backgroundColor: hex.userBg }, ' ' + usym.circle + ' YOU'),
13
+ h(Text, { color: hex.textMuted, backgroundColor: hex.userBg }, ' ' + u.h.repeat(Math.max(0, cols - 10)))
13
14
  );
14
15
  case 'user_line':
15
- return Box({ height: 1, backgroundColor: hex.userBg },
16
- Text({ color: hex.text, backgroundColor: hex.userBg, wrap: 'wrap' }, ' ' + (text || ' '))
16
+ return h(Box, { height: 1, backgroundColor: hex.userBg },
17
+ h(Text, { color: hex.text, backgroundColor: hex.userBg, wrap: 'wrap' }, ' ' + (text || ' '))
17
18
  );
18
19
  case 'asst_head':
19
- return Box({ height: 1, backgroundColor: hex.surface },
20
- Text({ color: hex.purple, bold: true, backgroundColor: hex.surface }, ' ' + usym.circle + ' CLARITY'),
21
- Text({ color: hex.textMuted, backgroundColor: hex.surface }, ' ' + u.h.repeat(Math.max(0, cols - 14)))
20
+ return h(Box, { height: 1, backgroundColor: hex.surface },
21
+ h(Text, { color: hex.purple, bold: true, backgroundColor: hex.surface }, ' ' + usym.circle + ' CLARITY'),
22
+ h(Text, { color: hex.textMuted, backgroundColor: hex.surface }, ' ' + u.h.repeat(Math.max(0, cols - 14)))
22
23
  );
23
24
  case 'asst_bar':
24
- return Box({ height: 1, backgroundColor: hex.surface },
25
- Text({ color: hex.textMuted, backgroundColor: hex.surface }, ' ' + usym.lightV)
25
+ return h(Box, { height: 1, backgroundColor: hex.surface },
26
+ h(Text, { color: hex.textMuted, backgroundColor: hex.surface }, ' ' + usym.lightV)
26
27
  );
27
28
  case 'asst_line':
28
- return Box({ height: 1, backgroundColor: hex.surface },
29
- Text({ color: hex.text, backgroundColor: hex.surface, wrap: 'wrap' }, ' ' + (text || ' '))
29
+ return h(Box, { height: 1, backgroundColor: hex.surface },
30
+ h(Text, { color: hex.text, backgroundColor: hex.surface, wrap: 'wrap' }, ' ' + (text || ' '))
30
31
  );
31
32
  case 'asst_foot':
32
- return Box({ height: 1, backgroundColor: hex.surface },
33
- Text({ color: hex.textDim, backgroundColor: hex.surface }, ' ' + usym.triR2 + ' ' + (parseInt(text) < 1000 ? text + 'ms' : (parseInt(text) / 1000).toFixed(1) + 's'))
33
+ return h(Box, { height: 1, backgroundColor: hex.surface },
34
+ h(Text, { color: hex.textDim, backgroundColor: hex.surface }, ' ' + usym.triR2 + ' ' + (parseInt(text) < 1000 ? text + 'ms' : (parseInt(text) / 1000).toFixed(1) + 's'))
34
35
  );
35
36
  case 'tool_head':
36
- return Box({ height: 1, backgroundColor: hex.surfaceAlt },
37
- Text({ color: hex.purple, backgroundColor: hex.surfaceAlt }, ' ' + usym.circle + ' ' + text)
37
+ return h(Box, { height: 1, backgroundColor: hex.surfaceAlt },
38
+ h(Text, { color: hex.purple, backgroundColor: hex.surfaceAlt }, ' ' + usym.circle + ' ' + text)
38
39
  );
39
40
  case 'tool_line':
40
- return Box({ height: 1, backgroundColor: hex.surfaceAlt },
41
- Text({ color: hex.textDim, backgroundColor: hex.surfaceAlt }, ' ' + (text || ' '))
41
+ return h(Box, { height: 1, backgroundColor: hex.surfaceAlt },
42
+ h(Text, { color: hex.textDim, backgroundColor: hex.surfaceAlt }, ' ' + (text || ' '))
42
43
  );
43
44
  case 'sys_line':
44
- return Box({ height: 1, backgroundColor: hex.surfaceAlt },
45
- Text({ color: hex.green, backgroundColor: hex.surfaceAlt }, ' ' + usym.circle + ' ' + (text || ''))
45
+ return h(Box, { height: 1, backgroundColor: hex.surfaceAlt },
46
+ h(Text, { color: hex.green, backgroundColor: hex.surfaceAlt }, ' ' + usym.circle + ' ' + (text || ''))
46
47
  );
47
48
  case 'err_line':
48
- return Box({ height: 1, backgroundColor: hex.surfaceAlt },
49
- Text({ color: hex.red, backgroundColor: hex.surfaceAlt }, ' ' + usym.cross + ' ' + (text || ''))
49
+ return h(Box, { height: 1, backgroundColor: hex.surfaceAlt },
50
+ h(Text, { color: hex.red, backgroundColor: hex.surfaceAlt }, ' ' + usym.cross + ' ' + (text || ''))
50
51
  );
51
52
  case 'stream_head':
52
- return Box({ height: 1, backgroundColor: hex.surface },
53
- Text({ color: hex.purple, bold: true, backgroundColor: hex.surface }, ' ' + usym.circle + ' CLARITY'),
54
- Text({ color: hex.textMuted, backgroundColor: hex.surface }, ' ' + u.h.repeat(Math.max(0, cols - 14)))
53
+ return h(Box, { height: 1, backgroundColor: hex.surface },
54
+ h(Text, { color: hex.purple, bold: true, backgroundColor: hex.surface }, ' ' + usym.circle + ' CLARITY'),
55
+ h(Text, { color: hex.textMuted, backgroundColor: hex.surface }, ' ' + u.h.repeat(Math.max(0, cols - 14)))
55
56
  );
56
57
  case 'stream_bar':
57
- return Box({ height: 1, backgroundColor: hex.surface },
58
- Text({ color: hex.textMuted, backgroundColor: hex.surface }, ' ' + usym.lightV)
58
+ return h(Box, { height: 1, backgroundColor: hex.surface },
59
+ h(Text, { color: hex.textMuted, backgroundColor: hex.surface }, ' ' + usym.lightV)
59
60
  );
60
61
  case 'stream_status':
61
- return Box({ height: 1, backgroundColor: hex.surface },
62
- Text({ color: hex.blue, backgroundColor: hex.surface }, ' ' + usym.dot + ' ' + (text || ''))
62
+ return h(Box, { height: 1, backgroundColor: hex.surface },
63
+ h(Text, { color: hex.blue, backgroundColor: hex.surface }, ' ' + usym.dot + ' ' + (text || ''))
63
64
  );
64
65
  case 'stream_line':
65
- return Box({ height: 1, backgroundColor: hex.surface },
66
- Text({ color: hex.text, backgroundColor: hex.surface, wrap: 'wrap' }, ' ' + (text || ' '))
66
+ return h(Box, { height: 1, backgroundColor: hex.surface },
67
+ h(Text, { color: hex.text, backgroundColor: hex.surface, wrap: 'wrap' }, ' ' + (text || ' '))
67
68
  );
68
69
  default:
69
70
  return null;
@@ -110,13 +111,13 @@ export function MessageList({ messages, thinking, streamContent, agentStatus, to
110
111
  const paddedLines = lines;
111
112
  for (let i = 0; i < padCount; i++) paddedLines.unshift({ type: 'empty' });
112
113
 
113
- return Box({ height: viewport, flexDirection: 'column', overflow: 'hidden' },
114
+ return h(Box, { height: viewport, flexDirection: 'column', overflow: 'hidden' },
114
115
  paddedLines.map((ln, i) =>
115
116
  ln.type === 'empty'
116
- ? Box({ key: 'e' + i, height: 1, backgroundColor: hex.bg },
117
- Text({ color: hex.textMuted, backgroundColor: hex.bg }, ' '))
118
- : Box({ key: (ln.data?.id || 'l') + '-' + i, height: 1 },
119
- LineRenderer({ type: ln.type, text: ln.text, data: ln.data })
117
+ ? h(Box, { key: 'e' + i, height: 1, backgroundColor: hex.bg },
118
+ h(Text, { color: hex.textMuted, backgroundColor: hex.bg }, ' '))
119
+ : h(Box, { key: (ln.data?.id || 'l') + '-' + i, height: 1 },
120
+ h(LineRenderer, { type: ln.type, text: ln.text, data: ln.data })
120
121
  )
121
122
  )
122
123
  );
@@ -2,15 +2,16 @@ import React from 'react';
2
2
  import { Box, Text } from 'ink';
3
3
  import { getLayout } from '../config/layout.js';
4
4
  import { hex, usym } from '../config/theme.js';
5
+ const { createElement: h } = React;
5
6
 
6
7
  export function StatusBar({ model, provider, agentMode, thinking }) {
7
- const { cols, contentWidth } = getLayout();
8
+ const { cols } = getLayout();
8
9
  const modelShort = model.replace(/^[^/]+\//, '').slice(0, 20);
9
10
  const left = '\u25C9 CLARITY ' + usym.midDot + ' ' + modelShort + ' ' + usym.midDot + ' ' + provider;
10
11
  const right = (agentMode ? 'Agent:ON' : 'Agent:OFF') + (thinking ? ' \u25CF' : '');
11
12
  const gap = Math.max(1, cols - left.length - right.length - 2);
12
13
  const line = left + ' '.repeat(gap) + right;
13
- return Box({ height: 1, backgroundColor: hex.surfaceAlt },
14
- Text({ color: hex.textDim, bold: false, backgroundColor: hex.surfaceAlt }, ' ' + line)
14
+ return h(Box, { height: 1, backgroundColor: hex.surfaceAlt },
15
+ h(Text, { color: hex.textDim, backgroundColor: hex.surfaceAlt }, ' ' + line)
15
16
  );
16
17
  }
@@ -2,6 +2,7 @@ import React, { useState } from 'react';
2
2
  import { Box, Text } from 'ink';
3
3
  import { hex, usym, u } from '../config/theme.js';
4
4
  import { getLayout } from '../config/layout.js';
5
+ const { createElement: h } = React;
5
6
 
6
7
  export function ThinkingBlock({ toolResults, duration }) {
7
8
  const [collapsed, setCollapsed] = useState(true);
@@ -16,13 +17,13 @@ export function ThinkingBlock({ toolResults, duration }) {
16
17
  const rows = 1;
17
18
  const totalRows = collapsed ? 1 : 1 + items.length;
18
19
 
19
- return Box({ flexDirection: 'column', backgroundColor: hex.surfaceAlt },
20
- Box({ height: 1 },
21
- Text({ color: hex.purple, backgroundColor: hex.surfaceAlt }, ' ' + headerText)
20
+ return h(Box, { flexDirection: 'column', backgroundColor: hex.surfaceAlt },
21
+ h(Box, { height: 1 },
22
+ h(Text, { color: hex.purple, backgroundColor: hex.surfaceAlt }, ' ' + headerText)
22
23
  ),
23
24
  collapsed
24
25
  ? null
25
- : Box({ flexDirection: 'column', backgroundColor: hex.surfaceAlt },
26
+ : h(Box, { flexDirection: 'column', backgroundColor: hex.surfaceAlt },
26
27
  items.map((tr, i) => {
27
28
  const isLast = i === items.length - 1;
28
29
  const prefix = isLast ? usym.treeTip + u.h : usym.treeFork + u.h;
@@ -34,13 +35,13 @@ export function ThinkingBlock({ toolResults, duration }) {
34
35
  const contentLine = tr.content && tr.content.length < 200
35
36
  ? ' ' + conn + ' ' + String(tr.content).slice(0, cols - 10)
36
37
  : null;
37
- return Box({ key: tr.execId || i, flexDirection: 'column' },
38
- Box({ height: 1 },
39
- Text({ color: hex.textMuted, backgroundColor: hex.surfaceAlt }, line)
38
+ return h(Box, { key: tr.execId || i, flexDirection: 'column' },
39
+ h(Box, { height: 1 },
40
+ h(Text, { color: hex.textMuted, backgroundColor: hex.surfaceAlt }, line)
40
41
  ),
41
42
  contentLine
42
- ? Box({ height: 1 },
43
- Text({ color: hex.textDim, backgroundColor: hex.surfaceAlt }, contentLine)
43
+ ? h(Box, { height: 1 },
44
+ h(Text, { color: hex.textDim, backgroundColor: hex.surfaceAlt }, contentLine)
44
45
  )
45
46
  : null
46
47
  );
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
2
  import { Box, Text } from 'ink';
3
3
  import { hex, usym } from '../config/theme.js';
4
- import { getLayout, wrapText } from '../config/layout.js';
4
+ import { getLayout } from '../config/layout.js';
5
+ const { createElement: h } = React;
5
6
 
6
7
  export function ToolCard({ exec, isActive }) {
7
8
  const { cols } = getLayout();
@@ -19,8 +20,8 @@ export function ToolCard({ exec, isActive }) {
19
20
  const col = status === 'failed' ? hex.red : hex.green;
20
21
  const icon = status === 'failed' ? usym.cross : usym.circle;
21
22
  const label = icon + ' Tool: ' + name + ' ' + (status === 'failed' ? 'Failed' : 'Successful') + (duration ? ' (' + duration + ')' : '');
22
- return Box({ height: minRender },
23
- Text({ color: col, backgroundColor: hex.surfaceAlt }, ' ' + label)
23
+ return h(Box, { height: minRender },
24
+ h(Text, { color: col, backgroundColor: hex.surfaceAlt }, ' ' + label)
24
25
  );
25
26
  }
26
27
 
@@ -37,10 +38,10 @@ export function ToolCard({ exec, isActive }) {
37
38
  if (status === 'running') lines.push(' running...');
38
39
 
39
40
  const totalLines = Math.min(lines.length, 4);
40
- return Box({ height: totalLines, flexDirection: 'column', backgroundColor: hex.surfaceAlt },
41
+ return h(Box, { height: totalLines, flexDirection: 'column', backgroundColor: hex.surfaceAlt },
41
42
  lines.slice(0, 4).map((line, i) =>
42
- Box({ key: i, height: 1 },
43
- Text({ color: i === 0 ? hex.purple : hex.textDim, backgroundColor: hex.surfaceAlt }, ' ' + line)
43
+ h(Box, { key: i, height: 1 },
44
+ h(Text, { color: i === 0 ? hex.purple : hex.textDim, backgroundColor: hex.surfaceAlt }, ' ' + line)
44
45
  )
45
46
  )
46
47
  );