wiggum-cli 0.10.3 → 0.10.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/tui/components/ChatInput.d.ts +13 -10
- package/dist/tui/components/ChatInput.d.ts.map +1 -1
- package/dist/tui/components/ChatInput.js +61 -22
- package/dist/tui/components/ChatInput.js.map +1 -1
- package/dist/tui/components/CommandDropdown.d.ts +53 -0
- package/dist/tui/components/CommandDropdown.d.ts.map +1 -0
- package/dist/tui/components/CommandDropdown.js +75 -0
- package/dist/tui/components/CommandDropdown.js.map +1 -0
- package/dist/tui/components/MessageList.d.ts +14 -21
- package/dist/tui/components/MessageList.d.ts.map +1 -1
- package/dist/tui/components/MessageList.js +15 -26
- package/dist/tui/components/MessageList.js.map +1 -1
- package/dist/tui/components/index.d.ts +2 -0
- package/dist/tui/components/index.d.ts.map +1 -1
- package/dist/tui/components/index.js +1 -0
- package/dist/tui/components/index.js.map +1 -1
- package/dist/tui/screens/MainShell.js +1 -1
- package/dist/tui/screens/MainShell.js.map +1 -1
- package/package.json +1 -1
- package/src/tui/components/ChatInput.tsx +106 -39
- package/src/tui/components/CommandDropdown.tsx +132 -0
- package/src/tui/components/MessageList.tsx +42 -52
- package/src/tui/components/index.ts +3 -0
- package/src/tui/screens/MainShell.tsx +1 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ChatInput - Multi-line input with
|
|
2
|
+
* ChatInput - Multi-line input with slash command support
|
|
3
3
|
*
|
|
4
|
-
* Displays a prompt character followed by a text input.
|
|
5
|
-
*
|
|
4
|
+
* Displays a `›` prompt character followed by a text input.
|
|
5
|
+
* Shows command dropdown when typing `/`.
|
|
6
6
|
*/
|
|
7
7
|
import React from 'react';
|
|
8
|
+
import { type Command } from './CommandDropdown.js';
|
|
8
9
|
/**
|
|
9
10
|
* Props for the ChatInput component
|
|
10
11
|
*/
|
|
@@ -15,26 +16,28 @@ export interface ChatInputProps {
|
|
|
15
16
|
placeholder?: string;
|
|
16
17
|
/** Whether input is disabled (e.g., during AI processing) */
|
|
17
18
|
disabled?: boolean;
|
|
18
|
-
/** Prompt character/text shown before input (default "> ") */
|
|
19
|
-
prompt?: string;
|
|
20
19
|
/** Allow empty submissions (e.g., to continue/skip phases) */
|
|
21
20
|
allowEmpty?: boolean;
|
|
21
|
+
/** Available slash commands (uses defaults if not provided) */
|
|
22
|
+
commands?: Command[];
|
|
23
|
+
/** Called when a slash command is selected */
|
|
24
|
+
onCommand?: (command: string) => void;
|
|
22
25
|
}
|
|
23
26
|
/**
|
|
24
27
|
* ChatInput component
|
|
25
28
|
*
|
|
26
|
-
* Provides a text input with
|
|
27
|
-
*
|
|
29
|
+
* Provides a text input with `›` prompt for chat-style interactions.
|
|
30
|
+
* Shows command dropdown when input starts with `/`.
|
|
28
31
|
*
|
|
29
32
|
* @example
|
|
30
33
|
* ```tsx
|
|
31
34
|
* <ChatInput
|
|
32
35
|
* onSubmit={(value) => console.log('User said:', value)}
|
|
33
|
-
* placeholder="Type your
|
|
36
|
+
* placeholder="Type your message..."
|
|
34
37
|
* disabled={isProcessing}
|
|
35
38
|
* />
|
|
36
|
-
* // Renders:
|
|
39
|
+
* // Renders: › Type your message...
|
|
37
40
|
* ```
|
|
38
41
|
*/
|
|
39
|
-
export declare function ChatInput({ onSubmit, placeholder, disabled,
|
|
42
|
+
export declare function ChatInput({ onSubmit, placeholder, disabled, allowEmpty, commands, onCommand, }: ChatInputProps): React.ReactElement;
|
|
40
43
|
//# sourceMappingURL=ChatInput.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatInput.d.ts","sourceRoot":"","sources":["../../../src/tui/components/ChatInput.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"ChatInput.d.ts","sourceRoot":"","sources":["../../../src/tui/components/ChatInput.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAgC,MAAM,OAAO,CAAC;AAIrD,OAAO,EAAqC,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEvF;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,WAAoC,EACpC,QAAgB,EAChB,UAAkB,EAClB,QAA2B,EAC3B,SAAS,GACV,EAAE,cAAc,GAAG,KAAK,CAAC,YAAY,CAqHrC"}
|
|
@@ -1,40 +1,52 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
|
-
* ChatInput - Multi-line input with
|
|
3
|
+
* ChatInput - Multi-line input with slash command support
|
|
4
4
|
*
|
|
5
|
-
* Displays a prompt character followed by a text input.
|
|
6
|
-
*
|
|
5
|
+
* Displays a `›` prompt character followed by a text input.
|
|
6
|
+
* Shows command dropdown when typing `/`.
|
|
7
7
|
*/
|
|
8
|
-
import { useState } from 'react';
|
|
8
|
+
import { useState, useCallback } from 'react';
|
|
9
9
|
import { Box, Text } from 'ink';
|
|
10
10
|
import TextInput from 'ink-text-input';
|
|
11
11
|
import { colors } from '../theme.js';
|
|
12
|
+
import { CommandDropdown, DEFAULT_COMMANDS } from './CommandDropdown.js';
|
|
12
13
|
/**
|
|
13
14
|
* ChatInput component
|
|
14
15
|
*
|
|
15
|
-
* Provides a text input with
|
|
16
|
-
*
|
|
16
|
+
* Provides a text input with `›` prompt for chat-style interactions.
|
|
17
|
+
* Shows command dropdown when input starts with `/`.
|
|
17
18
|
*
|
|
18
19
|
* @example
|
|
19
20
|
* ```tsx
|
|
20
21
|
* <ChatInput
|
|
21
22
|
* onSubmit={(value) => console.log('User said:', value)}
|
|
22
|
-
* placeholder="Type your
|
|
23
|
+
* placeholder="Type your message..."
|
|
23
24
|
* disabled={isProcessing}
|
|
24
25
|
* />
|
|
25
|
-
* // Renders:
|
|
26
|
+
* // Renders: › Type your message...
|
|
26
27
|
* ```
|
|
27
28
|
*/
|
|
28
|
-
export function ChatInput({ onSubmit, placeholder = 'Type your message...', disabled = false,
|
|
29
|
+
export function ChatInput({ onSubmit, placeholder = 'Type your message...', disabled = false, allowEmpty = false, commands = DEFAULT_COMMANDS, onCommand, }) {
|
|
29
30
|
const [value, setValue] = useState('');
|
|
31
|
+
const [showDropdown, setShowDropdown] = useState(false);
|
|
32
|
+
// Check if input is a slash command
|
|
33
|
+
const isSlashCommand = value.startsWith('/');
|
|
34
|
+
const commandFilter = isSlashCommand ? value.slice(1) : '';
|
|
30
35
|
/**
|
|
31
36
|
* Handle input submission
|
|
32
|
-
* Calls onSubmit with current value and clears the input
|
|
33
37
|
*/
|
|
34
|
-
const handleSubmit = (submittedValue) => {
|
|
35
|
-
|
|
36
|
-
if (disabled) {
|
|
38
|
+
const handleSubmit = useCallback((submittedValue) => {
|
|
39
|
+
if (disabled)
|
|
37
40
|
return;
|
|
41
|
+
// Handle slash commands
|
|
42
|
+
if (submittedValue.startsWith('/') && onCommand) {
|
|
43
|
+
const cmdName = submittedValue.slice(1).trim().split(' ')[0];
|
|
44
|
+
if (cmdName) {
|
|
45
|
+
onCommand(cmdName);
|
|
46
|
+
setValue('');
|
|
47
|
+
setShowDropdown(false);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
38
50
|
}
|
|
39
51
|
// Don't submit empty values unless allowEmpty is true
|
|
40
52
|
if (!submittedValue.trim() && !allowEmpty) {
|
|
@@ -42,20 +54,47 @@ export function ChatInput({ onSubmit, placeholder = 'Type your message...', disa
|
|
|
42
54
|
}
|
|
43
55
|
onSubmit(submittedValue);
|
|
44
56
|
setValue('');
|
|
45
|
-
|
|
57
|
+
setShowDropdown(false);
|
|
58
|
+
}, [disabled, allowEmpty, onSubmit, onCommand]);
|
|
46
59
|
/**
|
|
47
60
|
* Handle value changes
|
|
48
|
-
* Only update if not disabled
|
|
49
61
|
*/
|
|
50
|
-
const handleChange = (newValue) => {
|
|
51
|
-
if (
|
|
52
|
-
|
|
62
|
+
const handleChange = useCallback((newValue) => {
|
|
63
|
+
if (disabled)
|
|
64
|
+
return;
|
|
65
|
+
setValue(newValue);
|
|
66
|
+
// Show dropdown when typing /
|
|
67
|
+
if (newValue.startsWith('/')) {
|
|
68
|
+
setShowDropdown(true);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
setShowDropdown(false);
|
|
72
|
+
}
|
|
73
|
+
}, [disabled]);
|
|
74
|
+
/**
|
|
75
|
+
* Handle command selection from dropdown
|
|
76
|
+
*/
|
|
77
|
+
const handleCommandSelect = useCallback((cmdName) => {
|
|
78
|
+
if (onCommand) {
|
|
79
|
+
onCommand(cmdName);
|
|
53
80
|
}
|
|
54
|
-
|
|
81
|
+
else {
|
|
82
|
+
// If no onCommand handler, just submit the command
|
|
83
|
+
onSubmit(`/${cmdName}`);
|
|
84
|
+
}
|
|
85
|
+
setValue('');
|
|
86
|
+
setShowDropdown(false);
|
|
87
|
+
}, [onCommand, onSubmit]);
|
|
88
|
+
/**
|
|
89
|
+
* Handle dropdown cancel
|
|
90
|
+
*/
|
|
91
|
+
const handleDropdownCancel = useCallback(() => {
|
|
92
|
+
setShowDropdown(false);
|
|
93
|
+
}, []);
|
|
55
94
|
// When disabled, show a waiting message
|
|
56
95
|
if (disabled) {
|
|
57
|
-
return (_jsx(Box, { flexDirection: "row", children:
|
|
96
|
+
return (_jsx(Box, { flexDirection: "row", children: _jsx(Text, { dimColor: true, color: colors.brown, children: "\u203A [waiting for AI...]" }) }));
|
|
58
97
|
}
|
|
59
|
-
return (_jsxs(Box, { flexDirection: "
|
|
98
|
+
return (_jsxs(Box, { flexDirection: "column", children: [showDropdown && isSlashCommand && (_jsx(CommandDropdown, { commands: commands, filter: commandFilter, onSelect: handleCommandSelect, onCancel: handleDropdownCancel })), _jsxs(Box, { flexDirection: "row", children: [_jsxs(Text, { color: colors.blue, bold: true, children: ["\u203A", ' '] }), _jsx(TextInput, { value: value, onChange: handleChange, onSubmit: handleSubmit, placeholder: placeholder })] })] }));
|
|
60
99
|
}
|
|
61
100
|
//# sourceMappingURL=ChatInput.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatInput.js","sourceRoot":"","sources":["../../../src/tui/components/ChatInput.tsx"],"names":[],"mappings":";AAAA;;;;;GAKG;AAEH,OAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ChatInput.js","sourceRoot":"","sources":["../../../src/tui/components/ChatInput.tsx"],"names":[],"mappings":";AAAA;;;;;GAKG;AAEH,OAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAY,MAAM,KAAK,CAAC;AAC1C,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAgB,MAAM,sBAAsB,CAAC;AAoBvF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,SAAS,CAAC,EACxB,QAAQ,EACR,WAAW,GAAG,sBAAsB,EACpC,QAAQ,GAAG,KAAK,EAChB,UAAU,GAAG,KAAK,EAClB,QAAQ,GAAG,gBAAgB,EAC3B,SAAS,GACM;IACf,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACvC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExD,oCAAoC;IACpC,MAAM,cAAc,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,aAAa,GAAG,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE3D;;OAEG;IACH,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,cAAsB,EAAQ,EAAE;QAC/B,IAAI,QAAQ;YAAE,OAAO;QAErB,wBAAwB;QACxB,IAAI,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,SAAS,EAAE,CAAC;YAChD,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7D,IAAI,OAAO,EAAE,CAAC;gBACZ,SAAS,CAAC,OAAO,CAAC,CAAC;gBACnB,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACb,eAAe,CAAC,KAAK,CAAC,CAAC;gBACvB,OAAO;YACT,CAAC;QACH,CAAC;QAED,sDAAsD;QACtD,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;YAC1C,OAAO;QACT,CAAC;QAED,QAAQ,CAAC,cAAc,CAAC,CAAC;QACzB,QAAQ,CAAC,EAAE,CAAC,CAAC;QACb,eAAe,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC,EACD,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAC5C,CAAC;IAEF;;OAEG;IACH,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,QAAgB,EAAQ,EAAE;QACzB,IAAI,QAAQ;YAAE,OAAO;QACrB,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAEnB,8BAA8B;QAC9B,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,eAAe,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,eAAe,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;IACH,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAC;IAEF;;OAEG;IACH,MAAM,mBAAmB,GAAG,WAAW,CACrC,CAAC,OAAe,EAAE,EAAE;QAClB,IAAI,SAAS,EAAE,CAAC;YACd,SAAS,CAAC,OAAO,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,mDAAmD;YACnD,QAAQ,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC;QAC1B,CAAC;QACD,QAAQ,CAAC,EAAE,CAAC,CAAC;QACb,eAAe,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC,EACD,CAAC,SAAS,EAAE,QAAQ,CAAC,CACtB,CAAC;IAEF;;OAEG;IACH,MAAM,oBAAoB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC5C,eAAe,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,wCAAwC;IACxC,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CACL,KAAC,GAAG,IAAC,aAAa,EAAC,KAAK,YACtB,KAAC,IAAI,IAAC,QAAQ,QAAC,KAAK,EAAE,MAAM,CAAC,KAAK,2CAE3B,GACH,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aAExB,YAAY,IAAI,cAAc,IAAI,CACjC,KAAC,eAAe,IACd,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,mBAAmB,EAC7B,QAAQ,EAAE,oBAAoB,GAC9B,CACH,EAGD,MAAC,GAAG,IAAC,aAAa,EAAC,KAAK,aACtB,MAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,6BAC1B,GAAG,IACA,EACP,KAAC,SAAS,IACR,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,YAAY,EACtB,WAAW,EAAE,WAAW,GACxB,IACE,IACF,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CommandDropdown - Slash command autocomplete dropdown
|
|
3
|
+
*
|
|
4
|
+
* Shows available commands when user types "/" in the input.
|
|
5
|
+
* Supports arrow key navigation and Enter to select.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
/**
|
|
9
|
+
* Command definition
|
|
10
|
+
*/
|
|
11
|
+
export interface Command {
|
|
12
|
+
/** Command name (without /) */
|
|
13
|
+
name: string;
|
|
14
|
+
/** Description shown next to command */
|
|
15
|
+
description: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Props for the CommandDropdown component
|
|
19
|
+
*/
|
|
20
|
+
export interface CommandDropdownProps {
|
|
21
|
+
/** Available commands */
|
|
22
|
+
commands: Command[];
|
|
23
|
+
/** Filter string (what user typed after /) */
|
|
24
|
+
filter: string;
|
|
25
|
+
/** Called when a command is selected */
|
|
26
|
+
onSelect: (command: string) => void;
|
|
27
|
+
/** Called when dropdown is dismissed (Escape) */
|
|
28
|
+
onCancel: () => void;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* CommandDropdown component
|
|
32
|
+
*
|
|
33
|
+
* Displays a filtered list of available slash commands.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```tsx
|
|
37
|
+
* <CommandDropdown
|
|
38
|
+
* commands={[
|
|
39
|
+
* { name: 'init', description: 'Initialize a new CLAUDE.md file' },
|
|
40
|
+
* { name: 'new', description: 'Create a new feature spec' },
|
|
41
|
+
* ]}
|
|
42
|
+
* filter="in"
|
|
43
|
+
* onSelect={(cmd) => console.log('Selected:', cmd)}
|
|
44
|
+
* onCancel={() => setShowDropdown(false)}
|
|
45
|
+
* />
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare function CommandDropdown({ commands, filter, onSelect, onCancel, }: CommandDropdownProps): React.ReactElement;
|
|
49
|
+
/**
|
|
50
|
+
* Default commands available in wiggum
|
|
51
|
+
*/
|
|
52
|
+
export declare const DEFAULT_COMMANDS: Command[];
|
|
53
|
+
//# sourceMappingURL=CommandDropdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandDropdown.d.ts","sourceRoot":"","sources":["../../../src/tui/components/CommandDropdown.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,yBAAyB;IACzB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,iDAAiD;IACjD,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,QAAQ,GACT,EAAE,oBAAoB,GAAG,KAAK,CAAC,YAAY,CA6D3C;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,OAAO,EAOrC,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* CommandDropdown - Slash command autocomplete dropdown
|
|
4
|
+
*
|
|
5
|
+
* Shows available commands when user types "/" in the input.
|
|
6
|
+
* Supports arrow key navigation and Enter to select.
|
|
7
|
+
*/
|
|
8
|
+
import React, { useState } from 'react';
|
|
9
|
+
import { Box, Text, useInput } from 'ink';
|
|
10
|
+
import { colors } from '../theme.js';
|
|
11
|
+
/**
|
|
12
|
+
* CommandDropdown component
|
|
13
|
+
*
|
|
14
|
+
* Displays a filtered list of available slash commands.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* <CommandDropdown
|
|
19
|
+
* commands={[
|
|
20
|
+
* { name: 'init', description: 'Initialize a new CLAUDE.md file' },
|
|
21
|
+
* { name: 'new', description: 'Create a new feature spec' },
|
|
22
|
+
* ]}
|
|
23
|
+
* filter="in"
|
|
24
|
+
* onSelect={(cmd) => console.log('Selected:', cmd)}
|
|
25
|
+
* onCancel={() => setShowDropdown(false)}
|
|
26
|
+
* />
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export function CommandDropdown({ commands, filter, onSelect, onCancel, }) {
|
|
30
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
31
|
+
// Filter commands based on input
|
|
32
|
+
const filteredCommands = commands.filter((cmd) => cmd.name.toLowerCase().includes(filter.toLowerCase()));
|
|
33
|
+
// Handle keyboard input
|
|
34
|
+
useInput((input, key) => {
|
|
35
|
+
if (key.escape) {
|
|
36
|
+
onCancel();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (key.return && filteredCommands.length > 0) {
|
|
40
|
+
onSelect(filteredCommands[selectedIndex].name);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (key.upArrow) {
|
|
44
|
+
setSelectedIndex((prev) => Math.max(0, prev - 1));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (key.downArrow) {
|
|
48
|
+
setSelectedIndex((prev) => Math.min(filteredCommands.length - 1, prev + 1));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
// Reset selection when filter changes
|
|
53
|
+
React.useEffect(() => {
|
|
54
|
+
setSelectedIndex(0);
|
|
55
|
+
}, [filter]);
|
|
56
|
+
if (filteredCommands.length === 0) {
|
|
57
|
+
return (_jsx(Box, { paddingLeft: 2, children: _jsx(Text, { dimColor: true, children: "No matching commands" }) }));
|
|
58
|
+
}
|
|
59
|
+
return (_jsx(Box, { flexDirection: "column", paddingLeft: 2, children: filteredCommands.map((cmd, index) => {
|
|
60
|
+
const isSelected = index === selectedIndex;
|
|
61
|
+
return (_jsxs(Box, { flexDirection: "row", gap: 2, children: [_jsxs(Text, { color: isSelected ? colors.blue : colors.yellow, children: ["/", cmd.name] }), _jsx(Text, { color: isSelected ? colors.white : undefined, dimColor: !isSelected, children: cmd.description })] }, cmd.name));
|
|
62
|
+
}) }));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Default commands available in wiggum
|
|
66
|
+
*/
|
|
67
|
+
export const DEFAULT_COMMANDS = [
|
|
68
|
+
{ name: 'init', description: 'Initialize project with CLAUDE.md' },
|
|
69
|
+
{ name: 'new', description: 'Create a new feature specification' },
|
|
70
|
+
{ name: 'run', description: 'Run a spec file with AI' },
|
|
71
|
+
{ name: 'help', description: 'Show available commands' },
|
|
72
|
+
{ name: 'clear', description: 'Clear conversation history' },
|
|
73
|
+
{ name: 'exit', description: 'Exit wiggum' },
|
|
74
|
+
];
|
|
75
|
+
//# sourceMappingURL=CommandDropdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandDropdown.js","sourceRoot":"","sources":["../../../src/tui/components/CommandDropdown.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MessageList -
|
|
2
|
+
* MessageList - Conversation history display
|
|
3
3
|
*
|
|
4
|
-
* Displays the full conversation history
|
|
5
|
-
* - User messages
|
|
6
|
-
* - Assistant messages
|
|
7
|
-
* -
|
|
8
|
-
* - Tool call cards inline with assistant messages
|
|
4
|
+
* Displays the full conversation history with clean formatting:
|
|
5
|
+
* - User messages: › prefix
|
|
6
|
+
* - Assistant messages: ● bullet with clean markdown-like styling
|
|
7
|
+
* - Tool calls: Inline action indicators
|
|
9
8
|
*/
|
|
10
9
|
import React from 'react';
|
|
11
10
|
import { type ToolCallStatus } from './ToolCallCard.js';
|
|
@@ -51,28 +50,22 @@ export interface MessageListProps {
|
|
|
51
50
|
/**
|
|
52
51
|
* MessageList component
|
|
53
52
|
*
|
|
54
|
-
* Displays the full conversation history
|
|
55
|
-
*
|
|
56
|
-
* -
|
|
57
|
-
* -
|
|
58
|
-
* - System messages: dimmed brown text
|
|
59
|
-
*
|
|
60
|
-
* For streaming messages, uses the StreamingText component to show
|
|
61
|
-
* the cursor indicator.
|
|
53
|
+
* Displays the full conversation history with clean styling:
|
|
54
|
+
* - User messages: `› ` prefix in blue
|
|
55
|
+
* - Assistant messages: `● ` prefix in yellow, with inline tool cards
|
|
56
|
+
* - System messages: dimmed text
|
|
62
57
|
*
|
|
63
58
|
* @example
|
|
64
59
|
* ```tsx
|
|
65
60
|
* <MessageList
|
|
66
61
|
* messages={[
|
|
67
|
-
* { id: '1', role: '
|
|
68
|
-
* { id: '2', role: 'assistant', content: '
|
|
69
|
-
* { id: '3', role: 'user', content: 'A todo app' },
|
|
70
|
-
* { id: '4', role: 'assistant', content: 'Let me check...',
|
|
71
|
-
* toolCalls: [{ toolName: 'Read File', status: 'running', input: 'package.json' }],
|
|
72
|
-
* isStreaming: true
|
|
73
|
-
* },
|
|
62
|
+
* { id: '1', role: 'user', content: 'Hello' },
|
|
63
|
+
* { id: '2', role: 'assistant', content: 'Hi! How can I help?' },
|
|
74
64
|
* ]}
|
|
75
65
|
* />
|
|
66
|
+
* // Renders:
|
|
67
|
+
* // › Hello
|
|
68
|
+
* // ● Hi! How can I help?
|
|
76
69
|
* ```
|
|
77
70
|
*/
|
|
78
71
|
export declare function MessageList({ messages, maxHeight }: MessageListProps): React.ReactElement;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/tui/components/MessageList.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/tui/components/MessageList.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,2BAA2B;IAC3B,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtC,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,kDAAkD;IAClD,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mCAAmC;IACnC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA0ED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,gBAAgB,GAAG,KAAK,CAAC,YAAY,CAyBzF"}
|
|
@@ -4,56 +4,45 @@ import { colors } from '../theme.js';
|
|
|
4
4
|
import { StreamingText } from './StreamingText.js';
|
|
5
5
|
import { ToolCallCard } from './ToolCallCard.js';
|
|
6
6
|
/**
|
|
7
|
-
* Renders a single user message
|
|
7
|
+
* Renders a single user message with › prefix
|
|
8
8
|
*/
|
|
9
9
|
function UserMessage({ content }) {
|
|
10
|
-
return (_jsxs(Box, { flexDirection: "row", marginY: 1, children: [_jsxs(Text, { color: colors.
|
|
10
|
+
return (_jsxs(Box, { flexDirection: "row", marginY: 1, children: [_jsxs(Text, { color: colors.blue, bold: true, children: ["\u203A", ' '] }), _jsx(Text, { color: colors.white, children: content })] }));
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
* Renders a single assistant message with
|
|
13
|
+
* Renders a single assistant message with ● prefix and tool calls
|
|
14
14
|
*/
|
|
15
15
|
function AssistantMessage({ content, toolCalls, isStreaming, }) {
|
|
16
|
-
return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [toolCalls &&
|
|
17
|
-
toolCalls.length > 0 &&
|
|
18
|
-
toolCalls.map((toolCall, index) => (_jsx(Box, { marginBottom: 1, children: _jsx(ToolCallCard, { toolName: toolCall.toolName, status: toolCall.status, input: toolCall.input, output: toolCall.output, error: toolCall.error }) }, `tool-${index}`))), _jsxs(Box, { flexDirection: "row", children: [_jsxs(Text, { color: colors.yellow, bold: true, children: ["AI:", ' '] }), isStreaming ? (_jsx(StreamingText, { text: content, isStreaming: true, color: colors.yellow })) : (_jsx(Text, { color: colors.yellow, children: content }))] })] }));
|
|
16
|
+
return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [toolCalls && toolCalls.length > 0 && (_jsx(Box, { flexDirection: "column", marginBottom: 1, children: toolCalls.map((toolCall, index) => (_jsx(ToolCallCard, { toolName: toolCall.toolName, status: toolCall.status, input: toolCall.input, output: toolCall.output, error: toolCall.error }, `tool-${index}`))) })), content && (_jsxs(Box, { flexDirection: "row", children: [_jsxs(Text, { color: colors.yellow, children: ["\u25CF", ' '] }), _jsx(Box, { flexDirection: "column", flexGrow: 1, children: isStreaming ? (_jsx(StreamingText, { text: content, isStreaming: true, color: colors.yellow })) : (_jsx(Text, { color: colors.yellow, children: content })) })] }))] }));
|
|
19
17
|
}
|
|
20
18
|
/**
|
|
21
|
-
* Renders a system message (dimmed
|
|
19
|
+
* Renders a system message (dimmed, no prefix)
|
|
22
20
|
*/
|
|
23
21
|
function SystemMessage({ content }) {
|
|
24
|
-
return (_jsx(Box, {
|
|
22
|
+
return (_jsx(Box, { marginY: 1, children: _jsx(Text, { dimColor: true, children: content }) }));
|
|
25
23
|
}
|
|
26
24
|
/**
|
|
27
25
|
* MessageList component
|
|
28
26
|
*
|
|
29
|
-
* Displays the full conversation history
|
|
30
|
-
*
|
|
31
|
-
* -
|
|
32
|
-
* -
|
|
33
|
-
* - System messages: dimmed brown text
|
|
34
|
-
*
|
|
35
|
-
* For streaming messages, uses the StreamingText component to show
|
|
36
|
-
* the cursor indicator.
|
|
27
|
+
* Displays the full conversation history with clean styling:
|
|
28
|
+
* - User messages: `› ` prefix in blue
|
|
29
|
+
* - Assistant messages: `● ` prefix in yellow, with inline tool cards
|
|
30
|
+
* - System messages: dimmed text
|
|
37
31
|
*
|
|
38
32
|
* @example
|
|
39
33
|
* ```tsx
|
|
40
34
|
* <MessageList
|
|
41
35
|
* messages={[
|
|
42
|
-
* { id: '1', role: '
|
|
43
|
-
* { id: '2', role: 'assistant', content: '
|
|
44
|
-
* { id: '3', role: 'user', content: 'A todo app' },
|
|
45
|
-
* { id: '4', role: 'assistant', content: 'Let me check...',
|
|
46
|
-
* toolCalls: [{ toolName: 'Read File', status: 'running', input: 'package.json' }],
|
|
47
|
-
* isStreaming: true
|
|
48
|
-
* },
|
|
36
|
+
* { id: '1', role: 'user', content: 'Hello' },
|
|
37
|
+
* { id: '2', role: 'assistant', content: 'Hi! How can I help?' },
|
|
49
38
|
* ]}
|
|
50
39
|
* />
|
|
40
|
+
* // Renders:
|
|
41
|
+
* // › Hello
|
|
42
|
+
* // ● Hi! How can I help?
|
|
51
43
|
* ```
|
|
52
44
|
*/
|
|
53
45
|
export function MessageList({ messages, maxHeight }) {
|
|
54
|
-
// Note: maxHeight is accepted for future scrolling support
|
|
55
|
-
// Currently renders all messages - parent handles any scroll-like behavior
|
|
56
|
-
// by controlling which messages are passed in
|
|
57
46
|
return (_jsx(Box, { flexDirection: "column", ...(maxHeight ? { height: maxHeight } : {}), children: messages.map((message) => {
|
|
58
47
|
switch (message.role) {
|
|
59
48
|
case 'user':
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageList.js","sourceRoot":"","sources":["../../../src/tui/components/MessageList.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"MessageList.js","sourceRoot":"","sources":["../../../src/tui/components/MessageList.tsx"],"names":[],"mappings":"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"}
|
|
@@ -13,6 +13,8 @@ export { MessageList } from './MessageList.js';
|
|
|
13
13
|
export type { MessageListProps, Message, ToolCall } from './MessageList.js';
|
|
14
14
|
export { ChatInput } from './ChatInput.js';
|
|
15
15
|
export type { ChatInputProps } from './ChatInput.js';
|
|
16
|
+
export { CommandDropdown, DEFAULT_COMMANDS } from './CommandDropdown.js';
|
|
17
|
+
export type { CommandDropdownProps, Command } from './CommandDropdown.js';
|
|
16
18
|
export { Select } from './Select.js';
|
|
17
19
|
export type { SelectProps, SelectOption } from './Select.js';
|
|
18
20
|
export { PasswordInput } from './PasswordInput.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tui/components/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,YAAY,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAEjF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAE3E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5E,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC7D,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tui/components/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,YAAY,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAEjF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAE3E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5E,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACzE,YAAY,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE1E,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC7D,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -7,6 +7,7 @@ export { StreamingText } from './StreamingText.js';
|
|
|
7
7
|
export { ToolCallCard } from './ToolCallCard.js';
|
|
8
8
|
export { MessageList } from './MessageList.js';
|
|
9
9
|
export { ChatInput } from './ChatInput.js';
|
|
10
|
+
export { CommandDropdown, DEFAULT_COMMANDS } from './CommandDropdown.js';
|
|
10
11
|
export { Select } from './Select.js';
|
|
11
12
|
export { PasswordInput } from './PasswordInput.js';
|
|
12
13
|
export { Confirm } from './Confirm.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tui/components/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tui/components/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGzE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -191,6 +191,6 @@ export function MainShell({ sessionState, onNavigate, }) {
|
|
|
191
191
|
addSystemMessage('Use /exit to quit');
|
|
192
192
|
}
|
|
193
193
|
});
|
|
194
|
-
return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: colors.yellow, bold: true, children: "Wiggum Interactive Mode" }), _jsx(Text, { dimColor: true, children: " \u2502 " }), sessionState.initialized ? (_jsx(Text, { color: colors.green, children: "Ready" })) : (_jsx(Text, { color: colors.orange, children: "Not initialized - run /init" }))] }), _jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { dimColor: true, children: sessionState.provider ? `${sessionState.provider}/${sessionState.model}` : 'No provider configured' }), _jsx(Text, { dimColor: true, children: " \u2502 Type /help for commands" })] }), messages.length > 0 && (_jsx(Box, { marginY: 1, flexDirection: "column", children: _jsx(MessageList, { messages: messages }) })), _jsx(Box, { marginTop: 1, children: _jsx(ChatInput, { onSubmit: handleSubmit, disabled: false, placeholder: "Enter command or type /help...",
|
|
194
|
+
return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: colors.yellow, bold: true, children: "Wiggum Interactive Mode" }), _jsx(Text, { dimColor: true, children: " \u2502 " }), sessionState.initialized ? (_jsx(Text, { color: colors.green, children: "Ready" })) : (_jsx(Text, { color: colors.orange, children: "Not initialized - run /init" }))] }), _jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { dimColor: true, children: sessionState.provider ? `${sessionState.provider}/${sessionState.model}` : 'No provider configured' }), _jsx(Text, { dimColor: true, children: " \u2502 Type /help for commands" })] }), messages.length > 0 && (_jsx(Box, { marginY: 1, flexDirection: "column", children: _jsx(MessageList, { messages: messages }) })), _jsx(Box, { marginTop: 1, children: _jsx(ChatInput, { onSubmit: handleSubmit, disabled: false, placeholder: "Enter command or type /help...", onCommand: (cmd) => handleSubmit(`/${cmd}`) }) })] }));
|
|
195
195
|
}
|
|
196
196
|
//# sourceMappingURL=MainShell.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MainShell.js","sourceRoot":"","sources":["../../../src/tui/screens/MainShell.tsx"],"names":[],"mappings":";AAAA;;;;;GAKG;AAEH,OAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAClD,OAAO,EAAE,WAAW,EAAgB,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EACL,UAAU,EACV,mBAAmB,EACnB,cAAc,GAEf,MAAM,8BAA8B,CAAC;AA4BtC;;GAEG;AACH,SAAS,UAAU;IACjB,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACvE,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,SAAS,CAAC,EACxB,YAAY,EACZ,UAAU,GACK;IACf,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;IAC1B,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAY,EAAE,CAAC,CAAC;IAExD;;OAEG;IACH,MAAM,gBAAgB,GAAG,WAAW,CAAC,CAAC,OAAe,EAAE,EAAE;QACvD,MAAM,OAAO,GAAY;YACvB,EAAE,EAAE,UAAU,EAAE;YAChB,IAAI,EAAE,QAAQ;YACd,OAAO;SACR,CAAC;QACF,WAAW,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5C,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP;;OAEG;IACH,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;QAClC,gBAAgB,CAAC,cAAc,EAAE,CAAC,CAAC;IACrC,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEvB;;OAEG;IACH,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;QAClC,0BAA0B;QAC1B,UAAU,CAAC,MAAM,CAAC,CAAC;IACrB,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB;;OAEG;IACH,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,IAAc,EAAE,EAAE;QAC/C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,gBAAgB,CAAC,mDAAmD,CAAC,CAAC;YACtE,OAAO;QACT,CAAC;QAED,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;YAC9B,gBAAgB,CAAC,2CAA2C,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B,UAAU,CAAC,WAAW,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;IAC3C,CAAC,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAE7D;;OAEG;IACH,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,IAAc,EAAE,EAAE;QAC/C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,gBAAgB,CAAC,mDAAmD,CAAC,CAAC;YACtE,OAAO;QACT,CAAC;QAED,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;YAC9B,gBAAgB,CAAC,2CAA2C,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;QAED,wCAAwC;QACxC,gBAAgB,CAAC,oBAAoB,IAAI,CAAC,CAAC,CAAC,sCAAsC,CAAC,CAAC;IACtF,CAAC,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAEjD;;OAEG;IACH,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,IAAc,EAAE,EAAE;QACnD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,gBAAgB,CAAC,uDAAuD,CAAC,CAAC;YAC1E,OAAO;QACT,CAAC;QAED,4CAA4C;QAC5C,gBAAgB,CAAC,wBAAwB,IAAI,CAAC,CAAC,CAAC,sCAAsC,CAAC,CAAC;IAC1F,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEvB;;OAEG;IACH,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,IAAc,EAAE,EAAE;QAClD,iDAAiD;QACjD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,gBAAgB,CAAC,6EAA6E,CAAC,CAAC;QAClG,CAAC;aAAM,CAAC;YACN,gBAAgB,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;QACnF,CAAC;IACH,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEvB;;OAEG;IACH,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;QAClC,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAC7B,0CAA0C;QAC1C,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,EAAE,CAAC;QACT,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC,EAAE,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC;IAE7B;;OAEG;IACH,MAAM,cAAc,GAAG,WAAW,CAAC,CAAC,WAA4B,EAAE,IAAc,EAAE,EAAE;QAClF,QAAQ,WAAW,EAAE,CAAC;YACpB,KAAK,MAAM;gBACT,UAAU,EAAE,CAAC;gBACb,MAAM;YACR,KAAK,MAAM;gBACT,UAAU,EAAE,CAAC;gBACb,MAAM;YACR,KAAK,KAAK;gBACR,SAAS,CAAC,IAAI,CAAC,CAAC;gBAChB,MAAM;YACR,KAAK,KAAK;gBACR,SAAS,CAAC,IAAI,CAAC,CAAC;gBAChB,MAAM;YACR,KAAK,SAAS;gBACZ,aAAa,CAAC,IAAI,CAAC,CAAC;gBACpB,MAAM;YACR,KAAK,QAAQ;gBACX,YAAY,CAAC,IAAI,CAAC,CAAC;gBACnB,MAAM;YACR,KAAK,MAAM;gBACT,UAAU,EAAE,CAAC;gBACb,MAAM;YACR;gBACE,gBAAgB,CAAC,oBAAoB,WAAW,EAAE,CAAC,CAAC;QACxD,CAAC;IACH,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAE9G;;OAEG;IACH,MAAM,qBAAqB,GAAG,WAAW,CAAC,CAAC,KAAa,EAAE,EAAE;QAC1D,wEAAwE;QACxE,gBAAgB,CAAC,+EAA+E,CAAC,CAAC;IACpG,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEvB;;OAEG;IACH,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,KAAa,EAAE,EAAE;QACjD,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QAEjC,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;YACpB,KAAK,OAAO;gBACV,qBAAqB;gBACrB,MAAM;YAER,KAAK,eAAe,CAAC,CAAC,CAAC;gBACrB,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;gBAC3B,IAAI,CAAC,OAAO;oBAAE,MAAM;gBAEpB,MAAM,YAAY,GAAG,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACvD,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,gBAAgB,CAAC,qBAAqB,OAAO,CAAC,IAAI,sCAAsC,CAAC,CAAC;oBAC1F,MAAM;gBACR,CAAC;gBAED,cAAc,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;gBAC3C,MAAM;YACR,CAAC;YAED,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBACxB,qBAAqB,CAAC,MAAM,CAAC,IAAK,CAAC,CAAC;gBACpC,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC,EAAE,CAAC,cAAc,EAAE,qBAAqB,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAE9D,gBAAgB;IAChB,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,IAAI,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YAC9B,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;QACxC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC,aAEpC,MAAC,GAAG,IAAC,YAAY,EAAE,CAAC,aAClB,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,8CAA+B,EAC/D,KAAC,IAAI,IAAC,QAAQ,+BAAW,EACxB,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,CAC1B,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,KAAK,sBAAc,CACxC,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,4CAAoC,CAC/D,IACG,EAGN,MAAC,GAAG,IAAC,YAAY,EAAE,CAAC,aAClB,KAAC,IAAI,IAAC,QAAQ,kBACX,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,QAAQ,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,wBAAwB,GAC/F,EACP,KAAC,IAAI,IAAC,QAAQ,sDAAkC,IAC5C,EAGL,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,CACtB,KAAC,GAAG,IAAC,OAAO,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ,YACrC,KAAC,WAAW,IAAC,QAAQ,EAAE,QAAQ,GAAI,GAC/B,CACP,EAGD,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,SAAS,IACR,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,KAAK,EACf,WAAW,EAAC,gCAAgC,EAC5C,
|
|
1
|
+
{"version":3,"file":"MainShell.js","sourceRoot":"","sources":["../../../src/tui/screens/MainShell.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ChatInput - Multi-line input with
|
|
2
|
+
* ChatInput - Multi-line input with slash command support
|
|
3
3
|
*
|
|
4
|
-
* Displays a prompt character followed by a text input.
|
|
5
|
-
*
|
|
4
|
+
* Displays a `›` prompt character followed by a text input.
|
|
5
|
+
* Shows command dropdown when typing `/`.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import React, { useState } from 'react';
|
|
9
|
-
import { Box, Text } from 'ink';
|
|
8
|
+
import React, { useState, useCallback } from 'react';
|
|
9
|
+
import { Box, Text, useInput } from 'ink';
|
|
10
10
|
import TextInput from 'ink-text-input';
|
|
11
11
|
import { colors } from '../theme.js';
|
|
12
|
+
import { CommandDropdown, DEFAULT_COMMANDS, type Command } from './CommandDropdown.js';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Props for the ChatInput component
|
|
@@ -20,86 +21,152 @@ export interface ChatInputProps {
|
|
|
20
21
|
placeholder?: string;
|
|
21
22
|
/** Whether input is disabled (e.g., during AI processing) */
|
|
22
23
|
disabled?: boolean;
|
|
23
|
-
/** Prompt character/text shown before input (default "> ") */
|
|
24
|
-
prompt?: string;
|
|
25
24
|
/** Allow empty submissions (e.g., to continue/skip phases) */
|
|
26
25
|
allowEmpty?: boolean;
|
|
26
|
+
/** Available slash commands (uses defaults if not provided) */
|
|
27
|
+
commands?: Command[];
|
|
28
|
+
/** Called when a slash command is selected */
|
|
29
|
+
onCommand?: (command: string) => void;
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
/**
|
|
30
33
|
* ChatInput component
|
|
31
34
|
*
|
|
32
|
-
* Provides a text input with
|
|
33
|
-
*
|
|
35
|
+
* Provides a text input with `›` prompt for chat-style interactions.
|
|
36
|
+
* Shows command dropdown when input starts with `/`.
|
|
34
37
|
*
|
|
35
38
|
* @example
|
|
36
39
|
* ```tsx
|
|
37
40
|
* <ChatInput
|
|
38
41
|
* onSubmit={(value) => console.log('User said:', value)}
|
|
39
|
-
* placeholder="Type your
|
|
42
|
+
* placeholder="Type your message..."
|
|
40
43
|
* disabled={isProcessing}
|
|
41
44
|
* />
|
|
42
|
-
* // Renders:
|
|
45
|
+
* // Renders: › Type your message...
|
|
43
46
|
* ```
|
|
44
47
|
*/
|
|
45
48
|
export function ChatInput({
|
|
46
49
|
onSubmit,
|
|
47
50
|
placeholder = 'Type your message...',
|
|
48
51
|
disabled = false,
|
|
49
|
-
prompt = '> ',
|
|
50
52
|
allowEmpty = false,
|
|
53
|
+
commands = DEFAULT_COMMANDS,
|
|
54
|
+
onCommand,
|
|
51
55
|
}: ChatInputProps): React.ReactElement {
|
|
52
56
|
const [value, setValue] = useState('');
|
|
57
|
+
const [showDropdown, setShowDropdown] = useState(false);
|
|
58
|
+
|
|
59
|
+
// Check if input is a slash command
|
|
60
|
+
const isSlashCommand = value.startsWith('/');
|
|
61
|
+
const commandFilter = isSlashCommand ? value.slice(1) : '';
|
|
53
62
|
|
|
54
63
|
/**
|
|
55
64
|
* Handle input submission
|
|
56
|
-
* Calls onSubmit with current value and clears the input
|
|
57
65
|
*/
|
|
58
|
-
const handleSubmit = (
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
const handleSubmit = useCallback(
|
|
67
|
+
(submittedValue: string): void => {
|
|
68
|
+
if (disabled) return;
|
|
69
|
+
|
|
70
|
+
// Handle slash commands
|
|
71
|
+
if (submittedValue.startsWith('/') && onCommand) {
|
|
72
|
+
const cmdName = submittedValue.slice(1).trim().split(' ')[0];
|
|
73
|
+
if (cmdName) {
|
|
74
|
+
onCommand(cmdName);
|
|
75
|
+
setValue('');
|
|
76
|
+
setShowDropdown(false);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
63
80
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
81
|
+
// Don't submit empty values unless allowEmpty is true
|
|
82
|
+
if (!submittedValue.trim() && !allowEmpty) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
68
85
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
86
|
+
onSubmit(submittedValue);
|
|
87
|
+
setValue('');
|
|
88
|
+
setShowDropdown(false);
|
|
89
|
+
},
|
|
90
|
+
[disabled, allowEmpty, onSubmit, onCommand]
|
|
91
|
+
);
|
|
72
92
|
|
|
73
93
|
/**
|
|
74
94
|
* Handle value changes
|
|
75
|
-
* Only update if not disabled
|
|
76
95
|
*/
|
|
77
|
-
const handleChange = (
|
|
78
|
-
|
|
96
|
+
const handleChange = useCallback(
|
|
97
|
+
(newValue: string): void => {
|
|
98
|
+
if (disabled) return;
|
|
79
99
|
setValue(newValue);
|
|
80
|
-
|
|
81
|
-
|
|
100
|
+
|
|
101
|
+
// Show dropdown when typing /
|
|
102
|
+
if (newValue.startsWith('/')) {
|
|
103
|
+
setShowDropdown(true);
|
|
104
|
+
} else {
|
|
105
|
+
setShowDropdown(false);
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
[disabled]
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Handle command selection from dropdown
|
|
113
|
+
*/
|
|
114
|
+
const handleCommandSelect = useCallback(
|
|
115
|
+
(cmdName: string) => {
|
|
116
|
+
if (onCommand) {
|
|
117
|
+
onCommand(cmdName);
|
|
118
|
+
} else {
|
|
119
|
+
// If no onCommand handler, just submit the command
|
|
120
|
+
onSubmit(`/${cmdName}`);
|
|
121
|
+
}
|
|
122
|
+
setValue('');
|
|
123
|
+
setShowDropdown(false);
|
|
124
|
+
},
|
|
125
|
+
[onCommand, onSubmit]
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Handle dropdown cancel
|
|
130
|
+
*/
|
|
131
|
+
const handleDropdownCancel = useCallback(() => {
|
|
132
|
+
setShowDropdown(false);
|
|
133
|
+
}, []);
|
|
82
134
|
|
|
83
135
|
// When disabled, show a waiting message
|
|
84
136
|
if (disabled) {
|
|
85
137
|
return (
|
|
86
138
|
<Box flexDirection="row">
|
|
87
139
|
<Text dimColor color={colors.brown}>
|
|
88
|
-
|
|
140
|
+
› [waiting for AI...]
|
|
89
141
|
</Text>
|
|
90
142
|
</Box>
|
|
91
143
|
);
|
|
92
144
|
}
|
|
93
145
|
|
|
94
146
|
return (
|
|
95
|
-
<Box flexDirection="
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
147
|
+
<Box flexDirection="column">
|
|
148
|
+
{/* Command dropdown */}
|
|
149
|
+
{showDropdown && isSlashCommand && (
|
|
150
|
+
<CommandDropdown
|
|
151
|
+
commands={commands}
|
|
152
|
+
filter={commandFilter}
|
|
153
|
+
onSelect={handleCommandSelect}
|
|
154
|
+
onCancel={handleDropdownCancel}
|
|
155
|
+
/>
|
|
156
|
+
)}
|
|
157
|
+
|
|
158
|
+
{/* Input line */}
|
|
159
|
+
<Box flexDirection="row">
|
|
160
|
+
<Text color={colors.blue} bold>
|
|
161
|
+
›{' '}
|
|
162
|
+
</Text>
|
|
163
|
+
<TextInput
|
|
164
|
+
value={value}
|
|
165
|
+
onChange={handleChange}
|
|
166
|
+
onSubmit={handleSubmit}
|
|
167
|
+
placeholder={placeholder}
|
|
168
|
+
/>
|
|
169
|
+
</Box>
|
|
103
170
|
</Box>
|
|
104
171
|
);
|
|
105
172
|
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CommandDropdown - Slash command autocomplete dropdown
|
|
3
|
+
*
|
|
4
|
+
* Shows available commands when user types "/" in the input.
|
|
5
|
+
* Supports arrow key navigation and Enter to select.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React, { useState } from 'react';
|
|
9
|
+
import { Box, Text, useInput } from 'ink';
|
|
10
|
+
import { colors } from '../theme.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Command definition
|
|
14
|
+
*/
|
|
15
|
+
export interface Command {
|
|
16
|
+
/** Command name (without /) */
|
|
17
|
+
name: string;
|
|
18
|
+
/** Description shown next to command */
|
|
19
|
+
description: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Props for the CommandDropdown component
|
|
24
|
+
*/
|
|
25
|
+
export interface CommandDropdownProps {
|
|
26
|
+
/** Available commands */
|
|
27
|
+
commands: Command[];
|
|
28
|
+
/** Filter string (what user typed after /) */
|
|
29
|
+
filter: string;
|
|
30
|
+
/** Called when a command is selected */
|
|
31
|
+
onSelect: (command: string) => void;
|
|
32
|
+
/** Called when dropdown is dismissed (Escape) */
|
|
33
|
+
onCancel: () => void;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* CommandDropdown component
|
|
38
|
+
*
|
|
39
|
+
* Displays a filtered list of available slash commands.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```tsx
|
|
43
|
+
* <CommandDropdown
|
|
44
|
+
* commands={[
|
|
45
|
+
* { name: 'init', description: 'Initialize a new CLAUDE.md file' },
|
|
46
|
+
* { name: 'new', description: 'Create a new feature spec' },
|
|
47
|
+
* ]}
|
|
48
|
+
* filter="in"
|
|
49
|
+
* onSelect={(cmd) => console.log('Selected:', cmd)}
|
|
50
|
+
* onCancel={() => setShowDropdown(false)}
|
|
51
|
+
* />
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export function CommandDropdown({
|
|
55
|
+
commands,
|
|
56
|
+
filter,
|
|
57
|
+
onSelect,
|
|
58
|
+
onCancel,
|
|
59
|
+
}: CommandDropdownProps): React.ReactElement {
|
|
60
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
61
|
+
|
|
62
|
+
// Filter commands based on input
|
|
63
|
+
const filteredCommands = commands.filter((cmd) =>
|
|
64
|
+
cmd.name.toLowerCase().includes(filter.toLowerCase())
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
// Handle keyboard input
|
|
68
|
+
useInput((input, key) => {
|
|
69
|
+
if (key.escape) {
|
|
70
|
+
onCancel();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (key.return && filteredCommands.length > 0) {
|
|
75
|
+
onSelect(filteredCommands[selectedIndex].name);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (key.upArrow) {
|
|
80
|
+
setSelectedIndex((prev) => Math.max(0, prev - 1));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (key.downArrow) {
|
|
85
|
+
setSelectedIndex((prev) => Math.min(filteredCommands.length - 1, prev + 1));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Reset selection when filter changes
|
|
91
|
+
React.useEffect(() => {
|
|
92
|
+
setSelectedIndex(0);
|
|
93
|
+
}, [filter]);
|
|
94
|
+
|
|
95
|
+
if (filteredCommands.length === 0) {
|
|
96
|
+
return (
|
|
97
|
+
<Box paddingLeft={2}>
|
|
98
|
+
<Text dimColor>No matching commands</Text>
|
|
99
|
+
</Box>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<Box flexDirection="column" paddingLeft={2}>
|
|
105
|
+
{filteredCommands.map((cmd, index) => {
|
|
106
|
+
const isSelected = index === selectedIndex;
|
|
107
|
+
return (
|
|
108
|
+
<Box key={cmd.name} flexDirection="row" gap={2}>
|
|
109
|
+
<Text color={isSelected ? colors.blue : colors.yellow}>
|
|
110
|
+
/{cmd.name}
|
|
111
|
+
</Text>
|
|
112
|
+
<Text color={isSelected ? colors.white : undefined} dimColor={!isSelected}>
|
|
113
|
+
{cmd.description}
|
|
114
|
+
</Text>
|
|
115
|
+
</Box>
|
|
116
|
+
);
|
|
117
|
+
})}
|
|
118
|
+
</Box>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Default commands available in wiggum
|
|
124
|
+
*/
|
|
125
|
+
export const DEFAULT_COMMANDS: Command[] = [
|
|
126
|
+
{ name: 'init', description: 'Initialize project with CLAUDE.md' },
|
|
127
|
+
{ name: 'new', description: 'Create a new feature specification' },
|
|
128
|
+
{ name: 'run', description: 'Run a spec file with AI' },
|
|
129
|
+
{ name: 'help', description: 'Show available commands' },
|
|
130
|
+
{ name: 'clear', description: 'Clear conversation history' },
|
|
131
|
+
{ name: 'exit', description: 'Exit wiggum' },
|
|
132
|
+
];
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MessageList -
|
|
2
|
+
* MessageList - Conversation history display
|
|
3
3
|
*
|
|
4
|
-
* Displays the full conversation history
|
|
5
|
-
* - User messages
|
|
6
|
-
* - Assistant messages
|
|
7
|
-
* -
|
|
8
|
-
* - Tool call cards inline with assistant messages
|
|
4
|
+
* Displays the full conversation history with clean formatting:
|
|
5
|
+
* - User messages: › prefix
|
|
6
|
+
* - Assistant messages: ● bullet with clean markdown-like styling
|
|
7
|
+
* - Tool calls: Inline action indicators
|
|
9
8
|
*/
|
|
10
9
|
|
|
11
10
|
import React from 'react';
|
|
@@ -57,13 +56,13 @@ export interface MessageListProps {
|
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
/**
|
|
60
|
-
* Renders a single user message
|
|
59
|
+
* Renders a single user message with › prefix
|
|
61
60
|
*/
|
|
62
61
|
function UserMessage({ content }: { content: string }): React.ReactElement {
|
|
63
62
|
return (
|
|
64
63
|
<Box flexDirection="row" marginY={1}>
|
|
65
|
-
<Text color={colors.
|
|
66
|
-
|
|
64
|
+
<Text color={colors.blue} bold>
|
|
65
|
+
›{' '}
|
|
67
66
|
</Text>
|
|
68
67
|
<Text color={colors.white}>{content}</Text>
|
|
69
68
|
</Box>
|
|
@@ -71,7 +70,7 @@ function UserMessage({ content }: { content: string }): React.ReactElement {
|
|
|
71
70
|
}
|
|
72
71
|
|
|
73
72
|
/**
|
|
74
|
-
* Renders a single assistant message with
|
|
73
|
+
* Renders a single assistant message with ● prefix and tool calls
|
|
75
74
|
*/
|
|
76
75
|
function AssistantMessage({
|
|
77
76
|
content,
|
|
@@ -84,45 +83,46 @@ function AssistantMessage({
|
|
|
84
83
|
}): React.ReactElement {
|
|
85
84
|
return (
|
|
86
85
|
<Box flexDirection="column" marginY={1}>
|
|
87
|
-
{/* Tool calls appear
|
|
88
|
-
{toolCalls &&
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
<Box key={`tool-${index}`} marginBottom={1}>
|
|
86
|
+
{/* Tool calls appear first */}
|
|
87
|
+
{toolCalls && toolCalls.length > 0 && (
|
|
88
|
+
<Box flexDirection="column" marginBottom={1}>
|
|
89
|
+
{toolCalls.map((toolCall, index) => (
|
|
92
90
|
<ToolCallCard
|
|
91
|
+
key={`tool-${index}`}
|
|
93
92
|
toolName={toolCall.toolName}
|
|
94
93
|
status={toolCall.status}
|
|
95
94
|
input={toolCall.input}
|
|
96
95
|
output={toolCall.output}
|
|
97
96
|
error={toolCall.error}
|
|
98
97
|
/>
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
))}
|
|
99
|
+
</Box>
|
|
100
|
+
)}
|
|
101
101
|
|
|
102
|
-
{/* Message content with prefix */}
|
|
103
|
-
|
|
104
|
-
<
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
102
|
+
{/* Message content with bullet prefix */}
|
|
103
|
+
{content && (
|
|
104
|
+
<Box flexDirection="row">
|
|
105
|
+
<Text color={colors.yellow}>●{' '}</Text>
|
|
106
|
+
<Box flexDirection="column" flexGrow={1}>
|
|
107
|
+
{isStreaming ? (
|
|
108
|
+
<StreamingText text={content} isStreaming={true} color={colors.yellow} />
|
|
109
|
+
) : (
|
|
110
|
+
<Text color={colors.yellow}>{content}</Text>
|
|
111
|
+
)}
|
|
112
|
+
</Box>
|
|
113
|
+
</Box>
|
|
114
|
+
)}
|
|
113
115
|
</Box>
|
|
114
116
|
);
|
|
115
117
|
}
|
|
116
118
|
|
|
117
119
|
/**
|
|
118
|
-
* Renders a system message (dimmed
|
|
120
|
+
* Renders a system message (dimmed, no prefix)
|
|
119
121
|
*/
|
|
120
122
|
function SystemMessage({ content }: { content: string }): React.ReactElement {
|
|
121
123
|
return (
|
|
122
|
-
<Box
|
|
123
|
-
<Text
|
|
124
|
-
{content}
|
|
125
|
-
</Text>
|
|
124
|
+
<Box marginY={1}>
|
|
125
|
+
<Text dimColor>{content}</Text>
|
|
126
126
|
</Box>
|
|
127
127
|
);
|
|
128
128
|
}
|
|
@@ -130,35 +130,25 @@ function SystemMessage({ content }: { content: string }): React.ReactElement {
|
|
|
130
130
|
/**
|
|
131
131
|
* MessageList component
|
|
132
132
|
*
|
|
133
|
-
* Displays the full conversation history
|
|
134
|
-
*
|
|
135
|
-
* -
|
|
136
|
-
* -
|
|
137
|
-
* - System messages: dimmed brown text
|
|
138
|
-
*
|
|
139
|
-
* For streaming messages, uses the StreamingText component to show
|
|
140
|
-
* the cursor indicator.
|
|
133
|
+
* Displays the full conversation history with clean styling:
|
|
134
|
+
* - User messages: `› ` prefix in blue
|
|
135
|
+
* - Assistant messages: `● ` prefix in yellow, with inline tool cards
|
|
136
|
+
* - System messages: dimmed text
|
|
141
137
|
*
|
|
142
138
|
* @example
|
|
143
139
|
* ```tsx
|
|
144
140
|
* <MessageList
|
|
145
141
|
* messages={[
|
|
146
|
-
* { id: '1', role: '
|
|
147
|
-
* { id: '2', role: 'assistant', content: '
|
|
148
|
-
* { id: '3', role: 'user', content: 'A todo app' },
|
|
149
|
-
* { id: '4', role: 'assistant', content: 'Let me check...',
|
|
150
|
-
* toolCalls: [{ toolName: 'Read File', status: 'running', input: 'package.json' }],
|
|
151
|
-
* isStreaming: true
|
|
152
|
-
* },
|
|
142
|
+
* { id: '1', role: 'user', content: 'Hello' },
|
|
143
|
+
* { id: '2', role: 'assistant', content: 'Hi! How can I help?' },
|
|
153
144
|
* ]}
|
|
154
145
|
* />
|
|
146
|
+
* // Renders:
|
|
147
|
+
* // › Hello
|
|
148
|
+
* // ● Hi! How can I help?
|
|
155
149
|
* ```
|
|
156
150
|
*/
|
|
157
151
|
export function MessageList({ messages, maxHeight }: MessageListProps): React.ReactElement {
|
|
158
|
-
// Note: maxHeight is accepted for future scrolling support
|
|
159
|
-
// Currently renders all messages - parent handles any scroll-like behavior
|
|
160
|
-
// by controlling which messages are passed in
|
|
161
|
-
|
|
162
152
|
return (
|
|
163
153
|
<Box
|
|
164
154
|
flexDirection="column"
|
|
@@ -20,6 +20,9 @@ export type { MessageListProps, Message, ToolCall } from './MessageList.js';
|
|
|
20
20
|
export { ChatInput } from './ChatInput.js';
|
|
21
21
|
export type { ChatInputProps } from './ChatInput.js';
|
|
22
22
|
|
|
23
|
+
export { CommandDropdown, DEFAULT_COMMANDS } from './CommandDropdown.js';
|
|
24
|
+
export type { CommandDropdownProps, Command } from './CommandDropdown.js';
|
|
25
|
+
|
|
23
26
|
export { Select } from './Select.js';
|
|
24
27
|
export type { SelectProps, SelectOption } from './Select.js';
|
|
25
28
|
|