refactor(shared): organize native chat ask input owners (#34251)

* refactor(shared): group native chat ask input owners

* refactor(shared): keep split ask type imports erased
This commit is contained in:
Neil
2026-10-26 22:18:52 -07:00
committed by GitHub
parent 619ee954c9
commit bff2843fca
66 changed files with 89 additions and 122 deletions
+2 -2
View File
@@ -12662,8 +12662,8 @@
"src/shared/native-chat-agent-support.test.ts": 38,
"src/shared/native-chat-appearance-settings.test.ts": 34,
"src/shared/native-chat-approval-envelope.test.ts": 49,
"src/shared/native-chat-ask-fifo.test.ts": 30,
"src/shared/native-chat-ask.test.ts": 95,
"src/shared/native-chat/input/native-chat-ask-fifo.test.ts": 30,
"src/shared/native-chat/input/native-chat-ask.test.ts": 95,
"src/shared/native-chat/input/native-chat-background-task-row.test.ts": 67,
"src/shared/native-chat-context-usage.test.ts": 28,
"src/shared/native-chat-cut-turn-notice.test.ts": 217,
@@ -3,7 +3,7 @@ import { MessageSquareMore } from 'lucide-react-native'
import {
NATIVE_CHAT_ASK_ROW_COPY,
type NativeChatAskRowSubject
} from '../../../src/shared/native-chat-ask-row'
} from '../../../src/shared/native-chat/input/native-chat-ask-row'
import { INLINE_TEXT_SELECTION } from '../components/inline-text-selection'
import { colors, spacing, typography } from '../theme/mobile-theme'
import { scaledType } from './mobile-native-chat-message-styles'
@@ -38,7 +38,7 @@ import { MobileNativeChatResolutionReceipt } from './MobileNativeChatResolutionR
import {
nativeChatAskRunBlocks,
nativeChatAskRunSubject
} from '../../../src/shared/native-chat-ask-row'
} from '../../../src/shared/native-chat/input/native-chat-ask-row'
import type { NativeChatResolvedPrompt } from '../../../src/shared/native-chat-resolution-receipt'
import { MobileNativeChatSubagentGroup } from './MobileNativeChatSubagentGroup'
import { ToolRun } from './MobileNativeChatToolRun'
+1 -1
View File
@@ -14,7 +14,7 @@ import {
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { GestureDetector, GestureHandlerRootView } from 'react-native-gesture-handler'
import type { AskAnswerSelection } from '../../../src/shared/native-chat-ask-answer'
import type { AskPrompt } from '../../../src/shared/native-chat-ask-types'
import type { AskPrompt } from '../../../src/shared/native-chat/input/native-chat-ask-types'
import type { NativeChatMessage } from '../../../src/shared/native-chat-types'
import type {
NativeChatLiveTurnIndicator,
@@ -1,7 +1,8 @@
import type { StructuredMobileSendAttachment } from './use-mobile-structured-send-with-outcome'
import type { MobileSessionView } from '../storage/session-view-preferences'
import type { Dispatch, MutableRefObject, SetStateAction } from 'react'
import type { AskAnswerSelection, AskPrompt } from '../../../src/shared/native-chat-ask'
import type { AskAnswerSelection } from '../../../src/shared/native-chat-ask-answer'
import type { AskPrompt } from '../../../src/shared/native-chat/input/native-chat-ask-types'
import type { MobileChatPermission } from './native-chat/input/mobile-native-chat-permission'
import type { MobileChatQuestion } from './native-chat/input/mobile-native-chat-question'
import type {
@@ -2,7 +2,7 @@ import type { NativeChatMessage } from '../../../src/shared/native-chat-types'
import type { NativeChatResolvedPrompt } from '../../../src/shared/native-chat-resolution-receipt'
import { splitNativeChatBlocks } from '../../../src/shared/native-chat/tools/native-chat-tool-fold'
import { nativeChatWorkRunEntries } from '../../../src/shared/native-chat-work-run'
import { nativeChatAskRunBlocks } from '../../../src/shared/native-chat-ask-row'
import { nativeChatAskRunBlocks } from '../../../src/shared/native-chat/input/native-chat-ask-row'
import type { MobileNativeChatWorkRuns } from './use-mobile-native-chat-transcript-rows'
import type { MobileNativeChatRowSources } from './mobile-native-chat-row-keys'
@@ -2,7 +2,7 @@ import { act } from 'react-test-renderer'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import type { RpcResponse } from '../transport/types'
import type { RpcClient } from '../transport/rpc-client'
import type { AskPrompt } from '../../../src/shared/native-chat-ask'
import type { AskPrompt } from '../../../src/shared/native-chat/input/native-chat-ask-types'
import {
visible,
handleRef,
@@ -1,8 +1,8 @@
import { createElement } from 'react'
import { act, create, type ReactTestRenderer } from 'react-test-renderer'
import { afterEach, describe, expect, it, vi } from 'vitest'
import type { AskPrompt } from '../../../../../src/shared/native-chat-ask'
import { NATIVE_CHAT_QUESTION_AUTO_ADVANCE_MS } from '../../../../../src/shared/native-chat-question-auto-advance'
import type { AskPrompt } from '../../../../../src/shared/native-chat/input/native-chat-ask-types'
import { NATIVE_CHAT_QUESTION_AUTO_ADVANCE_MS } from '../../../../../src/shared/native-chat/input/native-chat-question-auto-advance'
import { encodeAgentSessionQuestionAnswers } from '../../../../../src/shared/agent-session-question-answer'
import { MobileNativeChatAsk } from './MobileNativeChatAsk'
import { MobileNativeChatStructuredAsk } from './MobileNativeChatStructuredAsk'
@@ -1,7 +1,8 @@
import { useRef, useState } from 'react'
import { Pressable, ScrollView, StyleSheet, Text, TextInput, View } from 'react-native'
import { Check } from 'lucide-react-native'
import type { AskAnswerSelection, AskPrompt } from '../../../../../src/shared/native-chat-ask'
import type { AskAnswerSelection } from '../../../../../src/shared/native-chat-ask-answer'
import type { AskPrompt } from '../../../../../src/shared/native-chat/input/native-chat-ask-types'
import type { AgentJournalFreeTextInput } from '../../../../../src/shared/agent-session-journal-types'
import {
askAcceptsEmptyAnswer,
@@ -1,7 +1,7 @@
import { Pressable, StyleSheet, Text, View } from 'react-native'
import { colors, radii, spacing, typography } from '../../../theme/mobile-theme'
import type { AskAnswerSelection } from '../../../../../src/shared/native-chat-ask-answer'
import type { AskPrompt } from '../../../../../src/shared/native-chat-ask-types'
import type { AskPrompt } from '../../../../../src/shared/native-chat/input/native-chat-ask-types'
import { MobileNativeChatAsk } from './MobileNativeChatAsk'
import { MobileNativeChatPermission } from './MobileNativeChatPermission'
import type { MobileChatPermission } from './mobile-native-chat-permission'
@@ -4,7 +4,7 @@ import {
NATIVE_CHAT_ADVANCE_BUFFER_MS,
NATIVE_CHAT_QUESTION_STEP_MS,
NATIVE_CHAT_SUBMIT_DELAY_MS
} from '../../../../../src/shared/native-chat-answer-stepping'
} from '../../../../../src/shared/native-chat/input/native-chat-answer-stepping'
export const MOBILE_NATIVE_CHAT_ADVANCE_BUFFER_MS = NATIVE_CHAT_ADVANCE_BUFFER_MS
export const MOBILE_NATIVE_CHAT_QUESTION_STEP_MS = NATIVE_CHAT_QUESTION_STEP_MS
@@ -1,7 +1,7 @@
import { createElement } from 'react'
import { act, create, type ReactTestRenderer } from 'react-test-renderer'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import type { AskPrompt } from '../../../../../src/shared/native-chat-ask-types'
import type { AskPrompt } from '../../../../../src/shared/native-chat/input/native-chat-ask-types'
import type { RpcClient } from '../../../transport/rpc-client'
import { useMobileNativeChatAnswerSend } from './use-mobile-native-chat-answer-send'
import { useNativeChatAcceptedAction } from '../../use-native-chat-action-outcomes'
@@ -5,7 +5,7 @@ vi.mock('../../../terminal/worker-terminal-takeover-report', () => ({
import { createElement } from 'react'
import { act, create, type ReactTestRenderer } from 'react-test-renderer'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import type { AskPrompt } from '../../../../../src/shared/native-chat-ask'
import type { AskPrompt } from '../../../../../src/shared/native-chat/input/native-chat-ask-types'
import type { AgentType } from '../../../../../src/shared/native-chat-types'
import { buildNativeChatPasteBytes } from '../../../../../src/shared/native-chat-paste-bytes'
import type { RpcClient } from '../../../transport/rpc-client'
@@ -6,7 +6,7 @@ import {
hasAskAnswer
} from '../../../../../src/shared/native-chat-ask-answer'
import type { AskAnswerSelection } from '../../../../../src/shared/native-chat-ask-answer'
import type { AskPrompt } from '../../../../../src/shared/native-chat-ask-types'
import type { AskPrompt } from '../../../../../src/shared/native-chat/input/native-chat-ask-types'
import type { RpcClient } from '../../../transport/rpc-client'
import { MOBILE_NATIVE_CHAT_QUESTION_STEP_MS } from './mobile-native-chat-answer-stepping'
import {
@@ -1,5 +1,5 @@
import { useEffect, useRef } from 'react'
import { NATIVE_CHAT_QUESTION_AUTO_ADVANCE_MS } from '../../../../../src/shared/native-chat-question-auto-advance'
import { NATIVE_CHAT_QUESTION_AUTO_ADVANCE_MS } from '../../../../../src/shared/native-chat/input/native-chat-question-auto-advance'
/** Mirrors desktop's useNativeChatQuestionAutoAdvance; shared code cannot import this app's React. */
export function useMobileNativeChatAskAutoAdvance(): {
@@ -1,7 +1,7 @@
import { createElement } from 'react'
import { act, create, type ReactTestRenderer } from 'react-test-renderer'
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
import type { AskPrompt } from '../../../../../src/shared/native-chat-ask-types'
import type { AskPrompt } from '../../../../../src/shared/native-chat/input/native-chat-ask-types'
import { useMobileNativeChatAskDismiss } from './use-mobile-native-chat-ask-dismiss'
import { mobileNativeChatPromptDismissals } from './mobile-native-chat-prompt-dismissals'
@@ -1,5 +1,5 @@
import { useMemo } from 'react'
import type { AskPrompt } from '../../../../../src/shared/native-chat-ask'
import type { AskPrompt } from '../../../../../src/shared/native-chat/input/native-chat-ask-types'
import { useMobileNativeChatPromptDismiss } from './use-mobile-native-chat-prompt-dismiss'
// Keep answered/collapsed asks across view toggles and remounts until an observed prompt supersedes them.
@@ -1,6 +1,6 @@
import { useMemo } from 'react'
import type { AgentStatusEntry } from '../../../../../src/shared/agent-status-types'
import type { AskPrompt } from '../../../../../src/shared/native-chat-ask'
import type { AskPrompt } from '../../../../../src/shared/native-chat/input/native-chat-ask-types'
import {
resolveNativeChatInteractivePromptCard,
type ChatApproval
@@ -1,10 +1,10 @@
import { useCallback, useMemo } from 'react'
import { extractPendingMessageReplyAsk } from '../../../src/shared/native-chat/input/native-chat-ask'
import {
extractPendingMessageReplyAsk,
formatAskAnswer,
type AskAnswerSelection,
type AskPrompt
} from '../../../src/shared/native-chat-ask'
type AskAnswerSelection
} from '../../../src/shared/native-chat-ask-answer'
import type { AskPrompt } from '../../../src/shared/native-chat/input/native-chat-ask-types'
import type { NativeChatMessage } from '../../../src/shared/native-chat-types'
import type { useMobileStructuredAgentSession } from './use-mobile-structured-agent-session'
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest'
import { extractPendingAsk } from '../../shared/native-chat-ask'
import { extractPendingAsk } from '../../shared/native-chat/input/native-chat-ask'
import { codexItemBody } from './codex-structured-item-translation'
describe('Codex async question items', () => {
@@ -2,7 +2,7 @@ import { mkdtemp, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import { extractPendingAsk } from '../../shared/native-chat-ask'
import { extractPendingAsk } from '../../shared/native-chat/input/native-chat-ask'
import { decodeCodexTranscriptLine } from './transcript-line-decoders-codex'
import { readNativeChatTranscript } from './transcript-reader'
import { readNativeChatTranscriptTail } from './transcript-tail-reader'
@@ -3,11 +3,11 @@ import {
AGENT_STATUS_INTERACTIVE_PROMPT_MAX_LENGTH,
parseAgentStatusPayload
} from '../../../../shared/agent-status-types'
import { nativeChatAskDismissKey } from '../../../../shared/native-chat-ask-dismiss-key'
import {
nativeChatAskDismissKey,
parseAskFromStatus,
parseAskFromToolInput
} from '../../../../shared/native-chat-ask'
} from '../../../../shared/native-chat/input/native-chat-ask'
import type { NativeChatBlock } from '../../../../shared/native-chat-types'
import { sanitizeNativeChatRpcBlock } from './native-chat-rpc-block-sanitize'
@@ -3,7 +3,7 @@ import {
normalizeSubagentState
} from '../../../../shared/native-chat-subagent-summary'
import { fitInteractivePrompt } from '../../../../shared/agent-status-field-normalization'
import { parseAskFromToolInput } from '../../../../shared/native-chat-ask'
import { parseAskFromToolInput } from '../../../../shared/native-chat/input/native-chat-ask'
import type { NativeChatBlock, NativeChatSubagentState } from '../../../../shared/native-chat-types'
import { boundSubagentEntryId } from '../../../native-chat/subagent-entry-id-bounds'
import type { RpcContext } from '../core'
@@ -11,7 +11,7 @@ import {
isPlanApprovalSubject
} from '../../../../shared/agent-session-approval-subject'
import { NativeChatCodeBlock } from './NativeChatCodeBlock'
import type { ChatApproval } from './native-chat-interactive-prompt'
import type { ChatApproval } from '../../../../shared/native-chat-interactive-prompt'
import { NativeChatPromptCollapseToggle } from './NativeChatPromptCollapse'
import { useNativeChatPromptCardFocus } from './use-native-chat-prompt-card-focus'
@@ -4,7 +4,7 @@ import { translate } from '@/i18n/i18n'
import {
NATIVE_CHAT_ASK_ROW_COPY,
type NativeChatAskRowSubject
} from '../../../../shared/native-chat-ask-row'
} from '../../../../shared/native-chat/input/native-chat-ask-row'
import { useNativeChatDisclosure } from './native-chat-disclosure-store'
import { NativeChatToolRunIcon } from './NativeChatToolIcon'
import { useNativeChatClippedLine } from './use-native-chat-clipped-line'
@@ -1,5 +1,5 @@
import { useCallback, useLayoutEffect, useRef, useState } from 'react'
import type { InteractivePromptCard } from './native-chat-interactive-prompt'
import type { InteractivePromptCard } from '../../../../shared/native-chat-interactive-prompt'
import { NativeChatQuestionCard } from './NativeChatQuestionCard'
import { NativeChatApprovalCard } from './NativeChatApprovalCard'
import type { NativeChatInteractiveSend } from './use-native-chat-interactive-send'
@@ -3,7 +3,7 @@ import { Button } from '@/components/ui/button'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import { ShortcutKeyCombo } from '@/components/ShortcutKeyCombo'
import { translate } from '@/i18n/i18n'
import type { InteractivePromptCard } from './native-chat-interactive-prompt'
import type { InteractivePromptCard } from '../../../../shared/native-chat-interactive-prompt'
/** A prompt card's one collapse affordance; folding or unfolding writes nothing to the agent. */
export function NativeChatPromptCollapseToggle({
@@ -4,8 +4,9 @@ import { act } from 'react'
import { createRoot } from 'react-dom/client'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { NativeChatQuestionCard } from './NativeChatQuestionCard'
import type { AskAnswerSelection, AskPrompt } from './native-chat-interactive-prompt'
import { NATIVE_CHAT_QUESTION_AUTO_ADVANCE_MS } from '../../../../shared/native-chat-question-auto-advance'
import type { AskAnswerSelection } from '../../../../shared/native-chat-ask-answer'
import type { AskPrompt } from '../../../../shared/native-chat/input/native-chat-ask-types'
import { NATIVE_CHAT_QUESTION_AUTO_ADVANCE_MS } from '../../../../shared/native-chat/input/native-chat-question-auto-advance'
// Answers must use option indices; labels can be duplicated and a non-first choice must retain its position.
@@ -4,7 +4,8 @@ import { useRef, useState, type RefObject } from 'react'
import { Check, Pencil, X } from 'lucide-react'
import { cn } from '@/lib/utils'
import { translate } from '@/i18n/i18n'
import type { AskAnswerSelection, AskPrompt } from './native-chat-interactive-prompt'
import type { AskAnswerSelection } from '../../../../shared/native-chat-ask-answer'
import type { AskPrompt } from '../../../../shared/native-chat/input/native-chat-ask-types'
import { NativeChatPromptCollapseToggle } from './NativeChatPromptCollapse'
import { useNativeChatPromptCardFocus } from './use-native-chat-prompt-card-focus'
import { useNativeChatQuestionAutoAdvance } from './use-native-chat-question-auto-advance'
@@ -4,7 +4,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest'
import { cleanup, fireEvent, render, screen } from '@testing-library/react'
import { useImperativeHandle } from 'react'
import type { NativeChatLiveSession } from './use-native-chat-live-session'
import type { AskPrompt } from './native-chat-interactive-prompt'
import type { AskPrompt } from '../../../../shared/native-chat/input/native-chat-ask-types'
import type { NativeChatInteractiveSend } from './use-native-chat-interactive-send'
import type { NativeChatMessageListHandle } from './use-native-chat-reveal-latest'
import type * as InteractiveCardModule from './NativeChatInteractiveCard'
@@ -1,5 +1,6 @@
import { useMemo } from 'react'
import { extractPendingMessageReplyAsk, formatAskAnswer } from '../../../../shared/native-chat-ask'
import { extractPendingMessageReplyAsk } from '../../../../shared/native-chat/input/native-chat-ask'
import { formatAskAnswer } from '../../../../shared/native-chat-ask-answer'
import type { NativeChatStructuredComposerTransport } from './native-chat-composer-types'
import { NativeChatQuestionCard } from './NativeChatQuestionCard'
import type { NativeChatLiveSession } from './use-native-chat-live-session'
@@ -46,7 +46,7 @@ import { useNativeChatRewindHost } from './use-native-chat-rewind-host'
import { NativeChatRewindContext } from './native-chat-rewind-context'
import { NativeChatQueuedMessageList } from './NativeChatQueuedMessageList'
import { nativeChatStructuredStopControls } from './native-chat-structured-stop-controls'
import { chatApprovalFromJournal } from './native-chat-interactive-prompt'
import { chatApprovalFromJournal } from '../../../../shared/native-chat-interactive-prompt'
import { useAppStore } from '../../store'
import { structuredAgentLabel } from '@/lib/structured-agent-session-launch-label'
import { useNativeChatStructuredComposerTransport } from './use-native-chat-structured-composer-transport'
@@ -27,7 +27,7 @@ import { nativeChatToolRunOutcome } from '../../../../shared/native-chat/tools/n
import {
nativeChatAskRunBlocks,
nativeChatAskRunSubject
} from '../../../../shared/native-chat-ask-row'
} from '../../../../shared/native-chat/input/native-chat-ask-row'
import { NativeChatAwaitingInputRow } from './NativeChatAwaitingInputRow'
import { NativeChatBackgroundTaskRun } from './NativeChatBackgroundTaskRun'
import { NativeChatSubagentRun } from './NativeChatSubagentRun'
@@ -4,11 +4,11 @@ import {
buildAskAnswerKeys,
buildCodexAskAnswerKeys,
formatAskAnswer,
hasAskAnswer,
parseAskFromStatus,
sayNativeChatApprovalTranslated,
type AskPrompt
} from './native-chat-interactive-prompt'
hasAskAnswer
} from '../../../../shared/native-chat-ask-answer'
import { parseAskFromStatus } from '../../../../shared/native-chat/input/native-chat-ask'
import { sayNativeChatApprovalTranslated } from './native-chat-interactive-prompt'
import type { AskPrompt } from '../../../../shared/native-chat/input/native-chat-ask-types'
import { parseApprovalFromStatus } from '../../../../shared/native-chat-interactive-prompt'
const ESC = String.fromCharCode(27)
@@ -4,26 +4,6 @@ import {
type NativeChatApprovalSay
} from '../../../../shared/native-chat-interactive-prompt'
export {
buildAskAnswerKeys,
buildCodexAskAnswerKeys,
formatAskAnswer,
hasAskAnswer,
parseAskFromStatus,
registerQuestionTool,
type AskAnswerKeyGroup,
type AskAnswerSelection,
type AskOption,
type AskPrompt,
type AskQuestion,
type InteractiveQuestionParser
} from '../../../../shared/native-chat-ask'
export {
chatApprovalFromJournal,
type ChatApproval,
type InteractivePromptCard
} from '../../../../shared/native-chat-interactive-prompt'
const PIECES: Record<keyof typeof COPY, (values?: { value0: string }) => string> = {
title: (values) => translate('components.native-chat.approval.title', COPY.title, values),
allow: () => translate('components.native-chat.approval.allow', COPY.allow),
@@ -2,7 +2,7 @@ import { sendNativeChatObservedWrites } from './native-chat-observed-send'
import { agentImagePasteWrites, formatAgentImagePath } from '../../../../shared/agent-image-paste'
import type { AgentType } from '../../../../shared/agent-status-types'
import { sendRuntimePtyInput } from '@/runtime/runtime-terminal-inspection'
import { NATIVE_CHAT_SUBMIT_DELAY_MS } from '../../../../shared/native-chat-answer-stepping'
import { NATIVE_CHAT_SUBMIT_DELAY_MS } from '../../../../shared/native-chat/input/native-chat-answer-stepping'
import {
buildNativeChatImagePasteBytes,
buildNativeChatPasteBytes,
@@ -1,7 +1,7 @@
import { sendNativeChatObservedWrites } from './native-chat-observed-send'
import { sendRuntimePtyInput } from '@/runtime/runtime-terminal-inspection'
import { sendRuntimePtyInputVerified } from '@/runtime/runtime-terminal-verified-input'
import type { AskAnswerKeyGroup } from './native-chat-interactive-prompt'
import type { AskAnswerKeyGroup } from '../../../../shared/native-chat-ask-answer'
import {
clearConfirmDurationMs,
clearThenWrite,
@@ -12,7 +12,7 @@ import {
NATIVE_CHAT_ADVANCE_BUFFER_MS,
NATIVE_CHAT_QUESTION_STEP_MS,
NATIVE_CHAT_SUBMIT_DELAY_MS
} from '../../../../shared/native-chat-answer-stepping'
} from '../../../../shared/native-chat/input/native-chat-answer-stepping'
import {
buildNativeChatPasteBytes,
NATIVE_CHAT_SUBMIT
@@ -2,10 +2,8 @@ import { useMemo } from 'react'
import { useAppStore } from '../../store'
import type { NativeChatMessage } from '../../../../shared/native-chat-types'
import { resolveNativeChatInteractivePromptCard } from '../../../../shared/native-chat-interactive-prompt'
import {
sayNativeChatApprovalTranslated,
type InteractivePromptCard
} from './native-chat-interactive-prompt'
import { sayNativeChatApprovalTranslated } from './native-chat-interactive-prompt'
import type { InteractivePromptCard } from '../../../../shared/native-chat-interactive-prompt'
export function useNativeChatInteractivePromptCard({
paneKey,
@@ -44,7 +44,7 @@ vi.mock('./native-chat-runtime-send', () => ({
}))
import { useNativeChatInteractiveSend } from './use-native-chat-interactive-send'
import type { AskPrompt } from './native-chat-interactive-prompt'
import type { AskPrompt } from '../../../../shared/native-chat/input/native-chat-ask-types'
const PROMPT: AskPrompt = {
questions: [{ question: 'q', multiSelect: false, options: [{ label: 'A' }, { label: 'B' }] }]
@@ -13,9 +13,9 @@ import {
buildCodexAskAnswerKeys,
formatAskAnswer,
hasAskAnswer,
type AskAnswerSelection,
type AskPrompt
} from './native-chat-interactive-prompt'
type AskAnswerSelection
} from '../../../../shared/native-chat-ask-answer'
import type { AskPrompt } from '../../../../shared/native-chat/input/native-chat-ask-types'
import {
sendNativeChatAskAnswer,
sendNativeChatMessage,
@@ -8,7 +8,7 @@ import {
nativeChatPromptDismissals,
forgetNativeChatPromptDismissalsForTab
} from './native-chat-prompt-dismissals'
import type { InteractivePromptCard } from './native-chat-interactive-prompt'
import type { InteractivePromptCard } from '../../../../shared/native-chat-interactive-prompt'
const PANE = 'tab-1:leaf-1'
const question: InteractivePromptCard = {
@@ -10,7 +10,7 @@ import {
nativeChatPromptDismissals as dismissals,
type NativeChatPromptDismissal
} from './native-chat-prompt-dismissals'
import type { InteractivePromptCard } from './native-chat-interactive-prompt'
import type { InteractivePromptCard } from '../../../../shared/native-chat-interactive-prompt'
export type NativeChatPromptCardPresentation = {
/** The card that owns the input region now; null leaves it to the composer. */
@@ -1,5 +1,5 @@
import { useEffect, useRef } from 'react'
import { NATIVE_CHAT_QUESTION_AUTO_ADVANCE_MS } from '../../../../shared/native-chat-question-auto-advance'
import { NATIVE_CHAT_QUESTION_AUTO_ADVANCE_MS } from '../../../../shared/native-chat/input/native-chat-question-auto-advance'
/** One cancellable delayed step: a single-select pick shows as chosen before the card moves on. */
export function useNativeChatQuestionAutoAdvance(): {
@@ -1,5 +1,5 @@
import { useCallback, useImperativeHandle, useMemo, useRef } from 'react'
import { hasAskAnswer } from './native-chat-interactive-prompt'
import { hasAskAnswer } from '../../../../shared/native-chat-ask-answer'
import { nativeChatSlotCopyText } from './native-chat-message-copy-text'
import type { NativeChatTranscriptSlot } from './native-chat-transcript-slots'
import type { NativeChatInteractiveSend } from './use-native-chat-interactive-send'
+1 -1
View File
@@ -1,6 +1,6 @@
import type { AgentStatusIpcPayload } from './agent-status-ipc-payload'
import { hookRowAgentPhase } from './agent-transitions'
import { parseAskFromStatus } from './native-chat-ask'
import { parseAskFromStatus } from './native-chat/input/native-chat-ask'
import { buildAskAnswerKeys, buildCodexAskAnswerKeys } from './native-chat-ask-answer'
import { parseNativeChatApprovalEnvelope } from './native-chat-approval-envelope'
import {
+1 -1
View File
@@ -1,5 +1,5 @@
import type { AgentType } from './agent-status-types'
import { askOptionsHavePreview } from './native-chat-ask'
import { askOptionsHavePreview } from './native-chat/input/native-chat-ask'
/** Main revalidates the renderer's submit snapshot against cached status so racing real hooks outrank inference. */
export type AgentQuestionAnsweredInferenceRequest = {
+1 -1
View File
@@ -20,7 +20,7 @@ import {
ORCA_DISPATCH_PROMPT_LEAD_LINE,
ORCA_DISPATCH_STATUS_PREAMBLE_PREFIX
} from './orca-dispatch-status-prompt'
import { parseAskFromStatus } from './native-chat-ask'
import { parseAskFromStatus } from './native-chat/input/native-chat-ask'
afterEach(() => {
vi.restoreAllMocks()
+1 -1
View File
@@ -1,4 +1,4 @@
import type { AskPrompt, AskQuestion } from './native-chat-ask-types'
import type { AskPrompt, AskQuestion } from './native-chat/input/native-chat-ask-types'
/** Return accepted immediately; nonblocking questions receive answers in later user messages ({questions:[{title, options?: string[]}]}). */
export const CODEX_ASYNC_QUESTION_TOOL = 'request_user_input_async'
+1 -1
View File
@@ -1,6 +1,6 @@
// Deliver answers as pasted messages or Claude/Codex selector keystrokes.
import type { AskPrompt, AskQuestion } from './native-chat-ask-types'
import type { AskPrompt, AskQuestion } from './native-chat/input/native-chat-ask-types'
/** Option indices in display order plus free text; selectors address stable numbers rather than labels. */
export type AskAnswerSelection = { indices: number[]; other?: string }
+1 -1
View File
@@ -1,5 +1,5 @@
import type { AgentJournalFreeTextInput } from './agent-session-journal-types'
import type { AskQuestion } from './native-chat-ask-types'
import type { AskQuestion } from './native-chat/input/native-chat-ask-types'
// How a stepped question card picks, labels and confirms; desktop and mobile draw it differently.
+1 -1
View File
@@ -1,4 +1,4 @@
import type { AskPrompt } from './native-chat-ask-types'
import type { AskPrompt } from './native-chat/input/native-chat-ask-types'
// Live/status transcripts shorten question text differently; identity uses a prefix both retain.
const ASK_DISMISS_KEY_TEXT_PREFIX = 200
+2 -1
View File
@@ -3,7 +3,8 @@ import type {
AgentJournalApprovalItem,
AgentJournalApprovalSubject
} from './agent-session-journal-types'
import { parseAskFromStatus, resolveNativeChatAsk, type AskPrompt } from './native-chat-ask'
import { parseAskFromStatus, resolveNativeChatAsk } from './native-chat/input/native-chat-ask'
import type { AskPrompt } from './native-chat/input/native-chat-ask-types'
import type { NativeChatMessage } from './native-chat-types'
import { parseOmpPlanReviewPrompt } from './omp-plan-review-prompt'
+1 -1
View File
@@ -6,7 +6,7 @@ import {
agentSessionPromptQuestions,
legacyAgentSessionQuestionAnswers
} from './agent-session-question-answer'
import type { NativeChatAskRowSubject } from './native-chat-ask-row'
import type { NativeChatAskRowSubject } from './native-chat/input/native-chat-ask-row'
/** Desktop's fallbacks for its translations; the phone's words. */
export const NATIVE_CHAT_RECEIPT_COPY = {
@@ -4,7 +4,7 @@ import './native-chat/tools/native-chat-tool-activity.spec'
import './native-chat/tools/native-chat-tool-pair-limit.spec'
import './native-chat/tools/native-chat-tool-fold-attribution.spec'
import './native-chat-turn-grouping.spec'
import './native-chat-ask-row.spec'
import './native-chat/input/native-chat-ask-row.spec'
import './native-chat/tools/native-chat-tool-pairing.spec'
import './native-chat-live-line.spec'
import './native-chat-merge-pairs.spec'
+1 -1
View File
@@ -1,6 +1,6 @@
// Group tool calls and finished thoughts into one collapsible run between prose rows; thinking before each call must not double the visible rows.
import { isNativeChatAskCall } from './native-chat-ask-row'
import { isNativeChatAskCall } from './native-chat/input/native-chat-ask-row'
import { deriveNativeChatRowContent } from './native-chat-row-content'
import { isStoppedBeforeStartBlock } from './native-chat-stopped-before-start'
import { pairToolBlocks } from './native-chat/tools/native-chat-tool-pairs'
@@ -1,6 +1,6 @@
import { expect, it } from 'vitest'
import { extractPendingAsk } from './native-chat-ask'
import type { NativeChatMessage } from './native-chat-types'
import type { NativeChatMessage } from '../../native-chat-types'
type Block = NativeChatMessage['blocks'][number]
@@ -4,7 +4,7 @@ import {
nativeChatAskRunSubject,
nativeChatAskRunBlocks
} from './native-chat-ask-row'
import type { NativeChatBlock } from './native-chat-types'
import type { NativeChatBlock } from '../../native-chat-types'
function askCall(input: unknown, name = 'AskUserQuestion'): NativeChatBlock {
return { type: 'tool-call', name, input }
@@ -1,10 +1,10 @@
// Shared desktop i18n fallbacks and direct mobile copy keep pending-question rows consistent.
import { isAskUserQuestionTool } from './agent-question-answered-intent'
import { CODEX_ASYNC_QUESTION_TOOL } from './codex-async-question-input'
import { isAskUserQuestionTool } from '../../agent-question-answered-intent'
import { CODEX_ASYNC_QUESTION_TOOL } from '../../codex-async-question-input'
import { parseAskFromToolInput } from './native-chat-ask'
import { isToolCallBlock, type NativeChatBlock } from './native-chat-types'
import { pairToolBlocks } from './native-chat/tools/native-chat-tool-pairs'
import { isToolCallBlock, type NativeChatBlock } from '../../native-chat-types'
import { pairToolBlocks } from '../tools/native-chat-tool-pairs'
export const NATIVE_CHAT_ASK_ROW_COPY = {
awaiting: 'Awaiting user input:',
@@ -3,13 +3,9 @@ import {
NATIVE_CHAT_INTERRUPTED_STATUS_TEXT,
type NativeChatBlock,
type NativeChatMessage
} from './native-chat-types'
import {
extractPendingAsk,
nativeChatAskDismissKey,
parseAskFromStatus,
resolveNativeChatAsk
} from './native-chat-ask'
} from '../../native-chat-types'
import { extractPendingAsk, parseAskFromStatus, resolveNativeChatAsk } from './native-chat-ask'
import { nativeChatAskDismissKey } from '../../native-chat-ask-dismiss-key'
function message(id: string, blocks: NativeChatBlock[]): NativeChatMessage {
return { id, role: 'assistant', blocks, timestamp: 1, source: 'transcript' }
@@ -4,18 +4,14 @@ import type {
AskQuestion,
InteractiveQuestionParser
} from './native-chat-ask-types'
import { isInterruptedStatusMessage, type NativeChatMessage } from './native-chat-types'
import { isInterruptedStatusMessage, type NativeChatMessage } from '../../native-chat-types'
import {
CODEX_ASYNC_QUESTION_TOOL,
parseCodexAsyncQuestionsInput
} from './codex-async-question-input'
export type { AskOption, AskPrompt, AskQuestion, InteractiveQuestionParser }
} from '../../codex-async-question-input'
const QUESTION_TOOL_PARSERS = new Map<string, InteractiveQuestionParser>()
export { nativeChatAskDismissKey } from './native-chat-ask-dismiss-key'
export function registerQuestionTool(toolName: string, parser: InteractiveQuestionParser): void {
QUESTION_TOOL_PARSERS.set(toolName, parser)
}
@@ -223,12 +219,3 @@ export function resolveNativeChatAsk(args: {
}): AskPrompt | null {
return args.liveAsk ?? (args.transcriptSettled ? extractPendingAsk(args.messages) : null)
}
export {
buildAskAnswerKeys,
buildCodexAskAnswerKeys,
formatAskAnswer,
hasAskAnswer,
type AskAnswerKeyGroup,
type AskAnswerSelection
} from './native-chat-ask-answer'
+1 -1
View File
@@ -1,7 +1,7 @@
import type { AgentJournalFreeTextInput, AgentJournalQuestion } from './agent-session-journal-types'
import type { AgentSessionQuestionAnswer } from './agent-session-question-answer'
import type { AskAnswerSelection } from './native-chat-ask-answer'
import type { AskPrompt } from './native-chat-ask-types'
import type { AskPrompt } from './native-chat/input/native-chat-ask-types'
import { askTypedText } from './native-chat-ask-card-rules'
/** A structured prompt drawn with the same stepped card as a terminal ask. */
@@ -3,7 +3,7 @@ import type {
AgentJournalQuestionItem
} from './agent-session-journal-types'
import { isAskUserQuestionTool } from './agent-question-answered-intent'
import { parseAskFromToolInput } from './native-chat-ask'
import { parseAskFromToolInput } from './native-chat/input/native-chat-ask'
import { agentJournalItemRowOrigin } from './agent-session-journal-position'
import { agentJournalLinkageFields } from './agent-session-journal-producer'
import type { NativeChatMessage } from './native-chat-types'
@@ -12,7 +12,7 @@ import {
sendNativeChatMessageVerified,
resetNativeChatPtySendQueuesForTests
} from '../../src/renderer/src/components/native-chat/native-chat-runtime-send'
import { buildAskAnswerKeys } from '../../src/shared/native-chat-ask'
import { buildAskAnswerKeys } from '../../src/shared/native-chat-ask-answer'
import { sendRuntimePtyInputVerified } from '@/runtime/runtime-terminal-verified-input'
import { RpcDispatcher } from '../../src/main/runtime/rpc/dispatcher'
import { TERMINAL_METHODS } from '../../src/main/runtime/rpc/methods/terminal'