surshar / claude-code
Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.
Built by Anthropic · github.com/anthropics
| 1 | /* @jsxRuntime classic */ |
| 2 | /* @jsx h */ |
| 3 | /* @jsxFrag Fragment */ |
| 4 | import type { RenderElement } from 'claude-code' |
| 5 | |
| 6 | import type PaneState from '../../pane-state' |
| 7 | import type { Kit } from '../kit' |
| 8 | import { present } from './present' |
| 9 | |
| 10 | /** |
| 11 | * The pickers under the header: the source (`Current`, then `T<n>` per |
| 12 | * turn with edits, newest first) and, for the current source, the base. |
| 13 | * |
| 14 | * The source picker draws only when a turn exists, as DiffDialog hides its |
| 15 | * tabs; the base picker is the built-in's ctrl+x b cycle as a Select over |
| 16 | * the modes the backend offers, uncommitted mode naming the base as the |
| 17 | * base line does (modeLabelOf). |
| 18 | * |
| 19 | * @param kit the elements and the handlers |
| 20 | * @param model what is picked now and the turns to pick from |
| 21 | * @returns the row, or null when neither picker applies |
| 22 | */ |
| 23 | export function controlsView( |
| 24 | kit: Kit, |
| 25 | model: Pick< |
| 26 | PaneState.PaneModel, |
| 27 | 'source' | 'requestedMode' | 'turns' | 'baseModes' | 'words' | 'data' |
| 28 | >, |
| 29 | ): RenderElement | null { |
| 30 | const { Box, Select } = kit.ui |
| 31 | const { source, turns } = model |
| 32 | const hasTurns = turns.length > 0 |
| 33 | const sourcePicker = hasTurns ? ( |
| 34 | <Select |
| 35 | key="source" |
| 36 | label="source" |
| 37 | options={[ |
| 38 | { value: 'current', label: 'Current' }, |
| 39 | ...turns.map(turn => ({ |
| 40 | value: String(turn.index), |
| 41 | label: `T${turn.index}`, |
| 42 | })), |
| 43 | ]} |
| 44 | value={source.kind === 'current' ? 'current' : String(source.index)} |
| 45 | onSelect={value => kit.actions.chooseSource(value)} |
| 46 | /> |
| 47 | ) : null |
| 48 | const isCurrent = source.kind === 'current' |
| 49 | const fetchedSource = model.data?.source |
| 50 | const base = |
| 51 | fetchedSource?.kind === 'working-tree' |
| 52 | ? fetchedSource.base |
| 53 | : model.words.base |
| 54 | const basePicker = isCurrent ? ( |
| 55 | <Select |
| 56 | key="base" |
| 57 | label="base" |
| 58 | options={model.baseModes.map(mode => ({ |
| 59 | value: mode, |
| 60 | label: |
| 61 | mode === 'uncommitted' |
| 62 | ? `uncommitted (vs ${base})` |
| 63 | : mode === 'session' |
| 64 | ? 'this session' |
| 65 | : mode, |
| 66 | }))} |
| 67 | value={model.requestedMode} |
| 68 | onSelect={value => kit.actions.chooseBase(value)} |
| 69 | /> |
| 70 | ) : null |
| 71 | const pickers = present([sourcePicker, basePicker]) |
| 72 | const row = ( |
| 73 | <Box flexDirection="row" gap={2}> |
| 74 | {pickers} |
| 75 | </Box> |
| 76 | ) |
| 77 | |
| 78 | return pickers.length === 0 ? null : row |
| 79 | } |