fix(sync): regenerate rpc catalog and locale runtime catalogs; drop retired zh keys; split ProjectCombobox keys/props under max-lines; arming a cloud row closes the Add project cascade

This commit is contained in:
Neil
2026-11-12 04:10:20 -08:00
parent 3091a87385
commit 4498fffc35
8 changed files with 159 additions and 100 deletions
-1
View File
@@ -1485,7 +1485,6 @@
"updateDesktop": "请更新 {{desktop}} 上的 Orca,以使用自动化。"
},
"emptyState": {
"connectedDescription": "桌面将显示在这里。所有数据均采用端到端加密",
"connectedTitle": "已连接",
"description": "与电脑上的 Orca 配对,即可在手机上查看智能体、进入任意终端并推进工作",
"openDesktopDescription": "前往“设置” → “移动端”,生成配对二维码",
@@ -5,7 +5,6 @@ import { isWithinAddProjectMenu } from '@/components/sidebar/project-admission/m
import { Popover, PopoverAnchor, PopoverContent } from '@/components/ui/popover'
import { cn } from '@/lib/class-names'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import type { NewWorkspaceProjectOption } from '@/lib/workspace/creation/new-workspace-project-options'
import { useTranslate } from '@/i18n/use-translate'
import {
getAmbiguousProjectOptionIds,
@@ -13,19 +12,21 @@ import {
sectionProjectOptions
} from './project-combobox-matching'
import {
focusCascadedAddProjectMenuFirstItem,
ProjectComboboxAddProjectOption,
type ProjectComboboxAddProjectMenu
} from './ProjectComboboxAddProjectOption'
import {
handleProjectComboboxKeyDown,
PROJECT_COMBOBOX_ADD_PROJECT_KEY
} from './project-combobox-keydown'
import { ProjectOptionMark, ProjectOptionRow } from './ProjectComboboxRow'
import { useRecentProjectIds } from './use-recent-project-ids'
import { isWithinComboboxRoot, useTypeAheadCombobox } from './use-type-ahead-combobox'
import type { ProjectComboboxProps } from './project-combobox-props'
import { COMBOBOX_FIELD_SHELL, COMBOBOX_POPOVER_SURFACE } from './type-ahead-combobox-styles'
import type { OrcaCloudGitHubRepository } from '@/lib/orca-cloud/use-orca-cloud-github-repositories'
import {
CLOUD_REPO_MORE_KEY,
CLOUD_REPO_SHOW_MORE_KEY,
cloudRepoKey,
cloudRowKeys,
commitCloudRow,
filterCloudRepos,
ProjectComboboxCloudSection,
@@ -34,35 +35,7 @@ import {
export type { ProjectComboboxAddProjectMenu }
type ProjectComboboxProps = {
options: readonly NewWorkspaceProjectOption[]
value: string | null
onValueChange: (projectId: string) => void
onValueSelected?: (projectId: string) => void
onAddProject?: () => void
addProjectMenu?: ProjectComboboxAddProjectMenu
placeholder?: string
triggerClassName?: string
invalid?: boolean
describedBy?: string
/** D4: GitHub repositories with no clone here, listed while Orca Cloud is the Run on target. */
cloudRepos?: readonly OrcaCloudGitHubRepository[] | null
/** The picked cloud-only repository (owner/name); it replaces the project in the field. */
cloudRepoValue?: string | null
onCloudRepoSelected?: (fullName: string) => void
onMoreCloudAccess?: () => void
/** Present while GitHub has more repositories than are listed. */
onShowMoreCloudRepos?: (() => void) | null
/** Bumped to open the list at its cloud-only section ("Choose a GitHub repository"). */
openSignal?: number
/**
* Bumped to move focus here quietly (RR-c1: a stopped Create points at the field's error): no
* path tooltip on that focus, since the error is already speaking. Hover and Tab still show it.
*/
focusSignal?: number
}
const ADD_PROJECT_KEY = 'add-project'
const ADD_PROJECT_KEY = PROJECT_COMBOBOX_ADD_PROJECT_KEY
const ROOT_ATTRIBUTE = 'data-project-combobox-root'
/** Use one search field and one shared pointer/keyboard cursor; pin Add project so empty/long lists keep it reachable. */
@@ -101,11 +74,7 @@ export default function ProjectCombobox({
query,
recentIds
).flatMap((section) => section.items.map((match) => match.option.id)),
...(cloudRepos
? filterCloudRepos(cloudRepos, query).map((repo) => cloudRepoKey(repo.fullName))
: []),
...(cloudRepos && onShowMoreCloudRepos ? [CLOUD_REPO_SHOW_MORE_KEY] : []),
...(cloudRepos && onMoreCloudAccess ? [CLOUD_REPO_MORE_KEY] : []),
...cloudRowKeys(cloudRepos, query, onShowMoreCloudRepos, onMoreCloudAccess),
...(hasAddProjectRow ? [ADD_PROJECT_KEY] : [])
],
[cloudRepos, hasAddProjectRow, onMoreCloudAccess, onShowMoreCloudRepos, options, recentIds]
@@ -199,53 +168,30 @@ export default function ProjectCombobox({
onValueSelected?.(key)
}
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>): void => {
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
event.preventDefault()
setCascadeOpen(false)
setOpen(true)
moveArm(event.key === 'ArrowDown' ? 1 : -1)
return
}
if (
(event.key === 'Enter' || event.key === 'ArrowRight') &&
open &&
armedKey === ADD_PROJECT_KEY &&
addProjectMenu
) {
event.preventDefault()
setCascadeAutoFocus(true)
if (cascadeOpen) {
focusCascadedAddProjectMenuFirstItem()
} else {
setCascadeOpen(true)
}
return
}
if (event.key === 'Enter' && open) {
event.preventDefault()
commit(armedKey)
return
}
// Handle Escape even while closed to clear stranded queries; bubble only when there is no committed display to restore.
if (event.key === 'Escape' && (open || query.length > 0)) {
event.preventDefault()
event.stopPropagation()
if (cascadeOpen) {
setCascadeOpen(false)
return
}
close()
return
}
if (event.key === 'Backspace' && committed) {
event.preventDefault()
setCascadeOpen(false)
setQuery(committedName)
setOpen(true)
}
// Arming a list row closes an open Add project cascade beside it.
const armClosingCascade = (key: string): void => {
setCascadeOpen(false)
arm(key)
}
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>): void =>
handleProjectComboboxKeyDown(event, {
open,
armedKey,
query,
committed,
committedName,
cascadeOpen,
hasAddProjectMenu: Boolean(addProjectMenu),
setOpen,
setQuery,
setCascadeOpen,
setCascadeAutoFocus,
moveArm,
commit,
close
})
return (
<Popover open={open} onOpenChange={handleOpenChange}>
<Tooltip
@@ -434,12 +380,7 @@ export default function ProjectCombobox({
current={scored.option.id === value}
ambiguous={ambiguous.has(scored.option.id)}
optionId={armedKey === scored.option.id ? `${listId}-armed` : undefined}
onArm={() => {
if (cascadeOpen) {
setCascadeOpen(false)
}
arm(scored.option.id)
}}
onArm={() => armClosingCascade(scored.option.id)}
onCommit={() => commit(scored.option.id)}
/>
))}
@@ -451,7 +392,7 @@ export default function ProjectCombobox({
value={cloudRepoValue ? cloudRepoKey(cloudRepoValue) : null}
armedKey={armedKey}
armedId={`${listId}-armed`}
onArm={arm}
onArm={armClosingCascade}
onCommit={commit}
showMoreAccess={Boolean(onMoreCloudAccess)}
showMoreRepos={Boolean(onShowMoreCloudRepos)}
@@ -60,6 +60,23 @@ export function commitCloudRow(
}
/** Case-insensitive substring match; the list is short and names are owner/repo. */
/** The cloud-only rows' keys, in list order, for the shared keyboard cursor. */
export function cloudRowKeys(
cloudRepos: readonly OrcaCloudGitHubRepository[] | null,
query: string,
onShowMoreCloudRepos: (() => void) | null,
onMoreCloudAccess: (() => void) | undefined
): string[] {
if (!cloudRepos) {
return []
}
return [
...filterCloudRepos(cloudRepos, query).map((repo) => cloudRepoKey(repo.fullName)),
...(onShowMoreCloudRepos ? [CLOUD_REPO_SHOW_MORE_KEY] : []),
...(onMoreCloudAccess ? [CLOUD_REPO_MORE_KEY] : [])
]
}
export function filterCloudRepos(
repos: readonly OrcaCloudGitHubRepository[],
query: string
@@ -0,0 +1,72 @@
import type React from 'react'
import { focusCascadedAddProjectMenuFirstItem } from './ProjectComboboxAddProjectOption'
export const PROJECT_COMBOBOX_ADD_PROJECT_KEY = 'add-project'
export type ProjectComboboxKeyDownState = {
open: boolean
armedKey: string | null
query: string
committed: boolean
committedName: string
cascadeOpen: boolean
hasAddProjectMenu: boolean
setOpen: (open: boolean) => void
setQuery: (query: string) => void
setCascadeOpen: (open: boolean) => void
setCascadeAutoFocus: (autoFocus: boolean) => void
moveArm: (step: number) => void
commit: (key: string | null) => void
close: () => void
}
/** The project field's keys: arrows move the shared cursor, Enter/→ on Add project opens its cascade. */
export function handleProjectComboboxKeyDown(
event: React.KeyboardEvent<HTMLInputElement>,
state: ProjectComboboxKeyDownState
): void {
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
event.preventDefault()
state.setCascadeOpen(false)
state.setOpen(true)
state.moveArm(event.key === 'ArrowDown' ? 1 : -1)
return
}
if (
(event.key === 'Enter' || event.key === 'ArrowRight') &&
state.open &&
state.armedKey === PROJECT_COMBOBOX_ADD_PROJECT_KEY &&
state.hasAddProjectMenu
) {
event.preventDefault()
state.setCascadeAutoFocus(true)
if (state.cascadeOpen) {
focusCascadedAddProjectMenuFirstItem()
} else {
state.setCascadeOpen(true)
}
return
}
if (event.key === 'Enter' && state.open) {
event.preventDefault()
state.commit(state.armedKey)
return
}
// Handle Escape even while closed to clear stranded queries; bubble only when there is no committed display to restore.
if (event.key === 'Escape' && (state.open || state.query.length > 0)) {
event.preventDefault()
event.stopPropagation()
if (state.cascadeOpen) {
state.setCascadeOpen(false)
return
}
state.close()
return
}
if (event.key === 'Backspace' && state.committed) {
event.preventDefault()
state.setCascadeOpen(false)
state.setQuery(state.committedName)
state.setOpen(true)
}
}
@@ -0,0 +1,31 @@
import type { NewWorkspaceProjectOption } from '@/lib/workspace/creation/new-workspace-project-options'
import type { OrcaCloudGitHubRepository } from '@/lib/orca-cloud/use-orca-cloud-github-repositories'
import type { ProjectComboboxAddProjectMenu } from './ProjectComboboxAddProjectOption'
export type ProjectComboboxProps = {
options: readonly NewWorkspaceProjectOption[]
value: string | null
onValueChange: (projectId: string) => void
onValueSelected?: (projectId: string) => void
onAddProject?: () => void
addProjectMenu?: ProjectComboboxAddProjectMenu
placeholder?: string
triggerClassName?: string
invalid?: boolean
describedBy?: string
/** D4: GitHub repositories with no clone here, listed while Orca Cloud is the Run on target. */
cloudRepos?: readonly OrcaCloudGitHubRepository[] | null
/** The picked cloud-only repository (owner/name); it replaces the project in the field. */
cloudRepoValue?: string | null
onCloudRepoSelected?: (fullName: string) => void
onMoreCloudAccess?: () => void
/** Present while GitHub has more repositories than are listed. */
onShowMoreCloudRepos?: (() => void) | null
/** Bumped to open the list at its cloud-only section ("Choose a GitHub repository"). */
openSignal?: number
/**
* Bumped to move focus here quietly (RR-c1: a stopped Create points at the field's error): no
* path tooltip on that focus, since the error is already speaking. Hover and Tab still show it.
*/
focusSignal?: number
}
+4 -4
View File
@@ -1472,14 +1472,14 @@
"symlink": "Symbolic links cannot be attached.",
"unsupported": "Unsupported file type."
},
"orcaCloudSession": {
"sandboxRestartsInMinutes_one": "Sandbox for {{name}} restarts in {{count}} minute",
"sandboxRestartsInMinutes_other": "Sandbox for {{name}} restarts in {{count}} minutes"
},
"emulator": {
"androidSdkNotFound": "Android SDK not found. Install Android Studio and set ANDROID_HOME.",
"xcodeSimulatorToolsUnavailable": "Xcode Simulator tools are unavailable. Install full Xcode, open it once, then select it with `sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer`."
},
"orcaCloudSession": {
"sandboxRestartsInMinutes_one": "Sandbox for {{name}} restarts in {{count}} minute",
"sandboxRestartsInMinutes_other": "Sandbox for {{name}} restarts in {{count}} minutes"
},
"rateLimits": {
"errors": {
"chatgptAuthRequired": "ChatGPT authentication required to read rate limits",
-4
View File
@@ -2317,7 +2317,6 @@
"hostConnectionFailed": "连接失败",
"defaultBranchUpdateFailed": "无法更新项目的默认分支,请重试",
"setLocation": "设置项目位置",
"setLocationOnHost": "设置项目在 {{host}} 上的位置",
"setLocationTooltip": "选择文件夹,或将此项目克隆到 {{host}}",
"connect": "连接",
"reconnect": "重新连接",
@@ -3404,7 +3403,6 @@
"dabd226118": "关闭",
"34dd5ee38b": "重试",
"532aea14ce": "取消",
"767951265d": "创建工作树时出现问题",
"cancelProvisioning": "取消"
}
}
@@ -18046,7 +18044,6 @@
"signout": {
"confirm": {
"title": "退出 Orca?",
"description": "重新登录前,产物和 Orca Relay 将不可用,本地项目和工作树不会受到影响",
"cancel": "取消",
"action": "退出登录"
}
@@ -20470,7 +20467,6 @@
"startInTerminal": "在终端中启动 {{value0}}"
},
"newWorkspace": {
"agentOptional": "代理 [可选]",
"createDescription": "选择项目和工作区名称,如果想启动代理,请选择一个",
"directSetup": {
"run": "Run setup",
+3
View File
@@ -44,6 +44,7 @@ import {
LocalCommandSettleParamsSchema
} from '../local-commands/local-command-contract'
import { MobileWebBundleChunkParamsSchema } from '../mobile-web-bundle/bundle-rpc-contract'
import { MobileWebBundleLocaleCatalogParamsSchema } from '../mobile-web-bundle/locale-catalog-contract'
import { OrcaCloudEnrollDeviceParamsSchema } from '../orca-cloud-device-enrollment-contract'
import { OrcadDiskUsageParamsSchema } from '../orcad-disk-usage'
import { OrcadMigrationBlobChunkRequestSchema } from '../orcad-migration/orcad-migration-blob-transfer'
@@ -1421,6 +1422,7 @@ export const RPC_PARAMS_BY_METHOD = {
'orcad.migration.stageSnapshotChunk': OrcadMigrationSnapshotChunkRequestSchema,
'orcad.terminalCensus': OrcadTerminalCensusParamsSchema,
'orcad.workVerdict': OrcadWorkVerdictParamsSchema,
'orchestration.approvalAnswer': ApprovalAnswerParams,
'orchestration.ask': AskParams,
'orchestration.callerShow': null,
'orchestration.check': CheckParams,
@@ -1701,6 +1703,7 @@ export const RPC_PARAMS_BY_METHOD = {
'updater.download': null,
'updater.getStatus': null,
'updater.install': null,
'workspaceCleanup.scan': WorkspaceCleanupScanParams,
'workspacePorts.forwardTunnel': WorkspacePortForwardTunnelParams,
'workspacePorts.kill': WorkspacePortKillParams,
'workspacePorts.killHost': WorkspacePortKillHostParams,