mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-23 11:46:28 +00:00
Align Assistant prompt history recall
This commit is contained in:
@@ -123,8 +123,14 @@ runtime cost control, and shared AI transport surfaces.
|
||||
may persist a bounded local history of submitted prompt text and structured
|
||||
mentions for ArrowUp/ArrowDown recall, but that history must not persist or
|
||||
replay one-shot finding handoff, approval, autonomous-mode, or other scoped
|
||||
send options. Scoped context replay remains owned by explicit session
|
||||
handoff metadata or queued follow-up edit state.
|
||||
send options. The referenced OpenCode source at fetched `origin/dev` commit
|
||||
`ba57718b0516c7a8670d1e820b1a24146a8b8262` binds prompt history navigation
|
||||
in `packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx` to the
|
||||
input cursor boundary: previous history is available at the start of the
|
||||
current draft, and next history restores the saved draft at the end. Pulse's
|
||||
Assistant drawer follows that draft-safe recall model rather than limiting
|
||||
history recall to an empty composer. Scoped context replay remains owned by
|
||||
explicit session handoff metadata or queued follow-up edit state.
|
||||
Failed-turn retry is part of that same local chat-runtime boundary: a
|
||||
retryable in-memory assistant error may replay the original user turn's
|
||||
structured mentions, finding id, approval override, handoff resources,
|
||||
|
||||
@@ -1332,7 +1332,7 @@ describe('AIChat', () => {
|
||||
await waitFor(() => expect(textarea.value).toBe(''));
|
||||
});
|
||||
|
||||
it('does not replace a non-empty composer draft with prompt history', () => {
|
||||
it('recalls prompt history from the start of a draft and restores the draft', async () => {
|
||||
localStorage.setItem(
|
||||
'pulse:ai_chat_prompt_history',
|
||||
JSON.stringify([{ prompt: 'previous prompt', mentions: [] }]),
|
||||
@@ -1344,9 +1344,14 @@ describe('AIChat', () => {
|
||||
) as HTMLTextAreaElement;
|
||||
|
||||
fireEvent.input(textarea, { target: { value: 'draft prompt' } });
|
||||
textarea.setSelectionRange(0, 0);
|
||||
fireEvent.keyDown(textarea, { key: 'ArrowUp' });
|
||||
|
||||
expect(textarea.value).toBe('draft prompt');
|
||||
await waitFor(() => expect(textarea.value).toBe('previous prompt'));
|
||||
|
||||
fireEvent.keyDown(textarea, { key: 'ArrowDown' });
|
||||
|
||||
await waitFor(() => expect(textarea.value).toBe('draft prompt'));
|
||||
});
|
||||
|
||||
it('loads persisted prompt history for recall', async () => {
|
||||
|
||||
@@ -592,7 +592,7 @@ export const AIChat: Component<AIChatProps> = (props) => {
|
||||
const cursor = textareaRef.selectionStart ?? text.length;
|
||||
const inHistory = promptHistoryIndex() >= 0;
|
||||
if (inHistory) return cursor === 0 || cursor === text.length;
|
||||
if (direction === 'up') return cursor === 0 && text.length === 0;
|
||||
if (direction === 'up') return cursor === 0;
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user