@@ -51,6 +51,7 @@ import {
5151 getEffectiveSystemPrompt ,
5252 getAgentConfig ,
5353} from '@/lib/agent-session'
54+ import { addChatHistory , HistoryNavigator } from '@/lib/chat-history'
5455import {
5556 SKILL_FIRST_OVERRIDE_TOKEN ,
5657 buildSkillFirstBlockMessage ,
@@ -396,6 +397,7 @@ export function AgentPanel() {
396397 } | null > ( null )
397398
398399 const inputRef = useRef < HTMLTextAreaElement > ( null )
400+ const historyNav = useRef ( new HistoryNavigator ( ) )
399401 const sessionInitRef = useRef ( false )
400402 const sentKeysRef = useRef ( new Set < string > ( ) )
401403 const handledKeysRef = useRef ( new Set < string > ( ) )
@@ -554,6 +556,9 @@ export function AgentPanel() {
554556 }
555557 } , [ isStreaming , sending , turnStartTime ] )
556558
559+ // ─── Load chat input history ─────────────────────────────────
560+ useEffect ( ( ) => { historyNav . current . load ( ) } , [ ] )
561+
557562 // ─── Listen for chat events (streaming replies) ───────────────
558563 useEffect ( ( ) => {
559564 const callbacks = {
@@ -1213,6 +1218,21 @@ export function AgentPanel() {
12131218 const text = ( overrideText ?? input ) . trim ( )
12141219 if ( ! text || sending ) return
12151220
1221+ // Handle slash commands locally
1222+ if ( text === '/ask' ) { setAgentMode ( 'ask' ) ; setInput ( '' ) ; return }
1223+ if ( text === '/agent' ) { setAgentMode ( 'agent' ) ; setInput ( '' ) ; return }
1224+ if ( text === '/plan' ) { setAgentMode ( 'plan' ) ; setInput ( '' ) ; return }
1225+ if ( text === '/clear' ) {
1226+ setMessages ( [ ] )
1227+ setAgentActivities ( [ ] )
1228+ setInput ( '' )
1229+ return
1230+ }
1231+
1232+ // Save to cross-session history
1233+ addChatHistory ( text )
1234+ historyNav . current . reset ( )
1235+
12161236 logChatDebug ( 'send attempt' , {
12171237 textLength : text . length ,
12181238 mode : agentMode ,
@@ -1881,33 +1901,39 @@ export function AgentPanel() {
18811901 const suggestions = useMemo ( ( ) => {
18821902 if ( ! input . startsWith ( '/' ) ) return [ ]
18831903 const cmds = [
1904+ // Coding
18841905 { cmd : '/edit' , desc : 'Edit current file' , icon : 'lucide:pencil' } ,
18851906 { cmd : '/explain' , desc : 'Explain code' , icon : 'lucide:book-open' } ,
18861907 { cmd : '/refactor' , desc : 'Refactor code' , icon : 'lucide:refresh-cw' } ,
18871908 { cmd : '/generate' , desc : 'Generate new code' , icon : 'lucide:plus' } ,
18881909 { cmd : '/search' , desc : 'Search across repo' , icon : 'lucide:search' } ,
1889- {
1890- cmd : '/commit' ,
1891- desc : 'Commit changes (AI if empty)' ,
1892- icon : 'lucide:git-commit-horizontal' ,
1893- } ,
1910+ { cmd : '/fix' , desc : 'Fix errors in code' , icon : 'lucide:wrench' } ,
1911+ { cmd : '/test' , desc : 'Write tests for code' , icon : 'lucide:flask-conical' } ,
1912+ { cmd : '/review' , desc : 'Code review current changes' , icon : 'lucide:scan-eye' } ,
1913+ // Git
1914+ { cmd : '/commit' , desc : 'Commit changes (AI message)' , icon : 'lucide:git-commit-horizontal' } ,
18941915 { cmd : '/diff' , desc : 'Show changes' , icon : 'lucide:git-compare' } ,
1895- { cmd : '/skill' , desc : 'Open skill commands' , icon : 'lucide:sparkles' } ,
1896- { cmd : '/skill find' , desc : 'Search for more skills' , icon : 'lucide:search' } ,
1897- { cmd : '/skill use' , desc : 'Apply a bundled skill' , icon : 'lucide:play' } ,
18981916 { cmd : '/changes' , desc : 'Pre-commit review' , icon : 'lucide:eye' } ,
18991917 { cmd : '/unstage' , desc : 'Unstage all staged files' , icon : 'lucide:minus-circle' } ,
19001918 { cmd : '/undo' , desc : 'Undo last commit' , icon : 'lucide:undo-2' } ,
19011919 { cmd : '/pull' , desc : 'Pull latest changes' , icon : 'lucide:arrow-down-circle' } ,
19021920 { cmd : '/push' , desc : 'Push to origin' , icon : 'lucide:arrow-up-circle' } ,
19031921 { cmd : '/sync' , desc : 'Pull and push current branch' , icon : 'lucide:refresh-cw' } ,
19041922 { cmd : '/pr' , desc : 'View pull requests' , icon : 'lucide:git-pull-request' } ,
1905- {
1906- cmd : '/pr create' ,
1907- desc : 'Create pull request' ,
1908- icon : 'lucide:git-pull-request-create-arrow' ,
1909- } ,
1923+ { cmd : '/pr create' , desc : 'Create pull request' , icon : 'lucide:git-pull-request-create-arrow' } ,
19101924 { cmd : '/merge' , desc : 'Merge pull request' , icon : 'lucide:git-merge' } ,
1925+ // Modes
1926+ { cmd : '/ask' , desc : 'Switch to Ask mode' , icon : 'lucide:message-circle' } ,
1927+ { cmd : '/agent' , desc : 'Switch to Agent mode' , icon : 'lucide:bot' } ,
1928+ { cmd : '/plan' , desc : 'Switch to Plan mode' , icon : 'lucide:list-checks' } ,
1929+ // Session
1930+ { cmd : '/clear' , desc : 'Clear chat history' , icon : 'lucide:trash-2' } ,
1931+ { cmd : '/compact' , desc : 'Compact session context' , icon : 'lucide:minimize-2' } ,
1932+ { cmd : '/model' , desc : 'Show or set model' , icon : 'lucide:cpu' } ,
1933+ // Skills
1934+ { cmd : '/skill' , desc : 'Open skill commands' , icon : 'lucide:sparkles' } ,
1935+ { cmd : '/skill find' , desc : 'Search for more skills' , icon : 'lucide:search' } ,
1936+ { cmd : '/skill use' , desc : 'Apply a bundled skill' , icon : 'lucide:play' } ,
19111937 ]
19121938 const term = input . toLowerCase ( )
19131939 return cmds . filter ( ( c ) => c . cmd . startsWith ( term ) )
@@ -1941,6 +1967,30 @@ export function AgentPanel() {
19411967 return
19421968 }
19431969 }
1970+ // ↑/↓: navigate input history (only when input is empty or at history position)
1971+ if ( e . key === 'ArrowUp' && ! e . shiftKey ) {
1972+ const textarea = inputRef . current
1973+ if ( textarea && textarea . selectionStart === 0 && textarea . selectionEnd === 0 ) {
1974+ historyNav . current . setDraft ( input )
1975+ const prev = historyNav . current . up ( )
1976+ if ( prev !== null ) {
1977+ e . preventDefault ( )
1978+ setInput ( prev )
1979+ return
1980+ }
1981+ }
1982+ }
1983+ if ( e . key === 'ArrowDown' && ! e . shiftKey ) {
1984+ const textarea = inputRef . current
1985+ if ( textarea && textarea . selectionStart === textarea . value . length ) {
1986+ const next = historyNav . current . down ( )
1987+ if ( next !== null ) {
1988+ e . preventDefault ( )
1989+ setInput ( next )
1990+ return
1991+ }
1992+ }
1993+ }
19441994 // Shift+Tab: cycle agent mode (Ask → Agent → Plan → Ask)
19451995 if ( e . key === 'Tab' && e . shiftKey ) {
19461996 e . preventDefault ( )
0 commit comments