diff --git a/app/shared/package.json b/app/shared/package.json index bb4d4bccc..d555eb5a9 100644 --- a/app/shared/package.json +++ b/app/shared/package.json @@ -28,8 +28,7 @@ "./ui/*": "./src/ui/*.tsx", "./ui/*.css": "./src/ui/*.module.css", "./lib/utils": "./src/lib/utils.ts", - "./shadcn/ui/*": "./src/shadcn/ui/*.tsx", - "./shadcn/ai-elements/*": "./src/shadcn/ai-elements/*.tsx" + "./shadcn/ui/*": "./src/shadcn/ui/*.tsx" }, "scripts": { "test": "vitest run", diff --git a/app/workbench/README.md b/app/workbench/README.md index a6af53379..8dfea2adf 100644 --- a/app/workbench/README.md +++ b/app/workbench/README.md @@ -8,6 +8,23 @@ docs/projects/tasks/settings 页面、mainchain 状态条、terminal host、floa `workbench` 是端级 shell 层;`shared` 是跨端原语层, workbench 是端级巨石,两者拆包后依赖方向固定为 **workbench → shared 单向**。 +## 目录 + +根目录只放 shell 与跨域件:`AgentHubWorkbench*`、`WorkbenchFrame*`、 +`WorkspaceHeader`、`GlobalRail`、`WorkbenchRoutes`、`index.ts` 入口、图标 +registry、preferences/layout、以及 `pages/`、`auxPanel/`、`terminal/`、 +`team/`、`floating/`、`mainchain/`、`sessionImport/`、`__tests__/`。 + +| 目录 | 内容 | +|---|---| +| `composer/` | UnifiedComposer 与其 picker / 附件 / mention / 审批 / dispatch queue 子件、纯 helper | +| `transcript/` | 会话转录与工程列:ConversationHost/Sidebar、ChatViewBridge、transcript chrome、goal banner、mainchain 状态条 | +| `routes/` | 每个 route 的 view + hook + helpers/planners/model(agents、tasks、docs、projects、settings、usage) | +| `inspector/` | 右侧 Inspector 面板、resizer、模式面板、自动展开 hook | + +模块与测试同目录;移动文件时改相对导入即可,包外消费者只认 +`package.json` 的 exports,不认内部路径。 + ## 边界 - 依赖方向:`workbench` 可以 import `shared`(深导入走 `@shared/*` 别名, diff --git a/app/workbench/src/AgentHubWorkbench.tsx b/app/workbench/src/AgentHubWorkbench.tsx index 200ed1e4d..e5f5e4c3d 100644 --- a/app/workbench/src/AgentHubWorkbench.tsx +++ b/app/workbench/src/AgentHubWorkbench.tsx @@ -7,21 +7,21 @@ import type { GlobalRailPage } from './GlobalRail'; import styles from './AgentHubWorkbench.module.css'; import { useWorkbenchPanelLayout } from './useWorkbenchPanelLayout'; import { useWorkbenchProfileChrome } from './useWorkbenchProfileChrome'; -import { useWorkbenchSessionChrome } from './useWorkbenchSessionChrome'; -import { useWorkbenchTranscriptChrome } from './useWorkbenchTranscriptChrome'; +import { useWorkbenchSessionChrome } from './transcript/useWorkbenchSessionChrome'; +import { useWorkbenchTranscriptChrome } from './transcript/useWorkbenchTranscriptChrome'; import { useWorkbenchGlobalShortcuts } from './useWorkbenchGlobalShortcuts'; import { useWorkbenchTaskDeepLinks } from './useWorkbenchTaskDeepLinks'; -import { WorkbenchTaskDeepLinkProvider } from './workbenchTaskDeepLinks'; +import { WorkbenchTaskDeepLinkProvider } from './routes/workbenchTaskDeepLinks'; import { GlobalSearchDialog } from './GlobalSearchDialog'; import { WORKBENCH_INSPECTOR_QUICK_OPEN_EVENT } from './desktopChromeEvents'; -import { isEditableKeyboardTarget } from './workbenchSessionChromeHelpers'; +import { isEditableKeyboardTarget } from './transcript/workbenchSessionChromeHelpers'; import { WorkbenchFrame } from './WorkbenchFrame'; import { engineeringColumnActivitySignal, useEngineeringColumnAutoOpen, -} from './useEngineeringColumnAutoOpen'; +} from './inspector/useEngineeringColumnAutoOpen'; import { WorkbenchProfileOverlays } from './WorkbenchProfileOverlays'; -import { WorkbenchTranscriptOverlays } from './WorkbenchTranscriptOverlays'; +import { WorkbenchTranscriptOverlays } from './transcript/WorkbenchTranscriptOverlays'; import { buildProfileChromeOptions, buildProfileOverlaysProps, diff --git a/app/workbench/src/AgentHubWorkbenchHelpers.test.ts b/app/workbench/src/AgentHubWorkbenchHelpers.test.ts index 7537e81bd..012558c1f 100644 --- a/app/workbench/src/AgentHubWorkbenchHelpers.test.ts +++ b/app/workbench/src/AgentHubWorkbenchHelpers.test.ts @@ -2,8 +2,8 @@ import { describe, expect, it, vi } from 'vitest'; import type { AgentHubPlatform, WorkbenchConversation } from '@shared/platform'; import type { TranscriptBlock } from '@shared/transcript'; import type { GlobalRailPage } from './GlobalRail'; -import type { WorkbenchSessionChrome } from './workbenchSessionChromeHelpers'; -import type { WorkbenchTranscriptChrome } from './useWorkbenchTranscriptChrome'; +import type { WorkbenchSessionChrome } from './transcript/workbenchSessionChromeHelpers'; +import type { WorkbenchTranscriptChrome } from './transcript/useWorkbenchTranscriptChrome'; import type { WorkbenchProfileChrome } from './useWorkbenchProfileChrome'; import type { WorkbenchPanelLayout } from './useWorkbenchPanelLayout'; import type { AgentHubWorkbenchProps } from './AgentHubWorkbenchTypes'; diff --git a/app/workbench/src/AgentHubWorkbenchHelpers.ts b/app/workbench/src/AgentHubWorkbenchHelpers.ts index 4b2327ece..35cc54855 100644 --- a/app/workbench/src/AgentHubWorkbenchHelpers.ts +++ b/app/workbench/src/AgentHubWorkbenchHelpers.ts @@ -2,17 +2,17 @@ import type { Dispatch, SetStateAction } from 'react'; import type { WorkbenchConversation } from '@shared/platform'; import type { GlobalRailPage } from './GlobalRail'; import type { WorkbenchFrameProps } from './workbenchFrameTypes'; -import type { UseWorkbenchSessionChromeOptions, WorkbenchSessionChrome } from './workbenchSessionChromeHelpers'; +import type { UseWorkbenchSessionChromeOptions, WorkbenchSessionChrome } from './transcript/workbenchSessionChromeHelpers'; import type { UseWorkbenchTranscriptChromeOptions, WorkbenchTranscriptChrome, -} from './useWorkbenchTranscriptChrome'; +} from './transcript/useWorkbenchTranscriptChrome'; import type { UseWorkbenchProfileChromeOptions, WorkbenchProfileChrome, } from './useWorkbenchProfileChrome'; import type { WorkbenchPanelLayout } from './useWorkbenchPanelLayout'; -import type { WorkbenchTranscriptOverlaysProps } from './WorkbenchTranscriptOverlays'; +import type { WorkbenchTranscriptOverlaysProps } from './transcript/WorkbenchTranscriptOverlays'; import type { WorkbenchProfileOverlaysProps } from './WorkbenchProfileOverlays'; import type { AgentHubWorkbenchProps } from './AgentHubWorkbenchTypes'; diff --git a/app/workbench/src/AgentHubWorkbenchTypes.ts b/app/workbench/src/AgentHubWorkbenchTypes.ts index 6a76b688e..6dce3ccee 100644 --- a/app/workbench/src/AgentHubWorkbenchTypes.ts +++ b/app/workbench/src/AgentHubWorkbenchTypes.ts @@ -5,14 +5,14 @@ import type { } from '@shared/platform'; import type { TranscriptBlock, ApprovalDecisionAction } from '@shared/transcript'; import type { ConnectionStatusKind } from './GlobalRail'; -import type { RuntimeEvidenceSnapshot } from './RightInspector'; +import type { RuntimeEvidenceSnapshot } from './inspector/RightInspector'; import type { WorkbenchAgentProfilesStatus, WorkbenchContactsData, WorkbenchContactsActions, WorkbenchDocumentsActions, } from './WorkbenchRoutes'; -import type { AgentConfig, ProjectDraft, DocRow } from './pages'; +import type { AgentConfig, ProjectDraft, DocRow } from './pages/index'; import type { SkillMarketItem, MCPMarketItem } from './pages/AgentsPage'; import type { ProjectInfo } from './pages/ProjectsPage'; import type { WorkbenchAttentionInput } from './workbenchAttentionModel'; diff --git a/app/workbench/src/GlobalRail.tsx b/app/workbench/src/GlobalRail.tsx index 58d8623f4..16dcb4d19 100644 --- a/app/workbench/src/GlobalRail.tsx +++ b/app/workbench/src/GlobalRail.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { ProfilePopover, DemoToast } from './floating'; +import { ProfilePopover, DemoToast } from './floating/index'; import { DesignNavIcon, type DesignNavIconName } from './designIcons'; import { CHATVIEW_I18N_NAMESPACE } from '@shared/chatview/i18n/resources'; import { Tooltip } from '@shared/ui/Tooltip'; diff --git a/app/workbench/src/SplitConversationPane.test.tsx b/app/workbench/src/SplitConversationPane.test.tsx index da53eac35..d3d889de8 100644 --- a/app/workbench/src/SplitConversationPane.test.tsx +++ b/app/workbench/src/SplitConversationPane.test.tsx @@ -14,7 +14,7 @@ beforeAll(async () => { await useTestI18nLanguage('en'); }); -vi.mock('./ChatViewBridge', () => ({ +vi.mock('./transcript/ChatViewBridge', () => ({ ChatViewBridge: (props: { displayTranscript: TranscriptBlock[] }) => (
), diff --git a/app/workbench/src/SplitConversationPane.tsx b/app/workbench/src/SplitConversationPane.tsx index d1aab269d..f7fc5e79b 100644 --- a/app/workbench/src/SplitConversationPane.tsx +++ b/app/workbench/src/SplitConversationPane.tsx @@ -14,7 +14,7 @@ import { useTranslation } from 'react-i18next'; import type { WorkbenchConversation } from '@shared/platform'; import type { TranscriptBlock } from '@shared/transcript'; import { CHATVIEW_I18N_NAMESPACE } from '@shared/chatview/i18n/resources'; -import { ChatViewBridge } from './ChatViewBridge'; +import { ChatViewBridge } from './transcript/ChatViewBridge'; import { DesignNavIcon } from './designIcons'; import { ContextMenu, type ContextMenuItem } from './floating/ContextMenu'; import type { ConversationLiveStatus } from './workbenchAttentionModel'; diff --git a/app/workbench/src/UnifiedComposerParts.tsx b/app/workbench/src/UnifiedComposerParts.tsx deleted file mode 100644 index e441b0bf0..000000000 --- a/app/workbench/src/UnifiedComposerParts.tsx +++ /dev/null @@ -1,28 +0,0 @@ -/* ═══════════════════════════════════════════════════════════════════════ - UnifiedComposer presentational subpanels — barrel module (#706). - - Subcomponents live in ComposerContextParts / ComposerAttachmentParts / - ComposerControlParts. Pure helpers in ComposerPartsHelpers. Visuals use the - shadcn/Tailwind token bridge; no composer chrome remains in the CSS module. - ═══════════════════════════════════════════════════════════════════════ */ - -export { - ComposerMentionChips, - ComposerQuoteBar, - ComposerReplyBar, - ComposerEditBar, - ComposerStatusStrip, -} from './ComposerContextParts'; - -export { - ComposerAttachmentBar, - ComposerAttachmentChip, -} from './ComposerAttachmentParts'; - -export { - ComposerAgentPicker, - ComposerApprovalModePicker, - ComposerAttachButton, - ComposerSendButton, - ComposerTargetPicker, -} from './ComposerControlParts'; diff --git a/app/workbench/src/WorkbenchFrame.attention.test.tsx b/app/workbench/src/WorkbenchFrame.attention.test.tsx index 673f570f4..ffe7ecba0 100644 --- a/app/workbench/src/WorkbenchFrame.attention.test.tsx +++ b/app/workbench/src/WorkbenchFrame.attention.test.tsx @@ -32,12 +32,12 @@ vi.mock('./WorkbenchFrameParts', () => ({ WorkspaceLoadingState: () =>
, })); -vi.mock('./terminal', () => ({ +vi.mock('./terminal/index', () => ({ TerminalPanel: () =>
, })); // The real strip would need i18n; the wiring contract is what this file pins. -vi.mock('./MainchainStatusStrip', () => ({ +vi.mock('./transcript/MainchainStatusStrip', () => ({ MainchainStatusStrip: (props: { attention?: WorkbenchAttentionCounts; onOpenRunningQueue?: () => void; diff --git a/app/workbench/src/WorkbenchFrame.split.test.tsx b/app/workbench/src/WorkbenchFrame.split.test.tsx index 83c971466..52e968389 100644 --- a/app/workbench/src/WorkbenchFrame.split.test.tsx +++ b/app/workbench/src/WorkbenchFrame.split.test.tsx @@ -36,11 +36,11 @@ vi.mock('./GlobalRail', () => ({ GlobalRail: () =>
, })); -vi.mock('./MainchainStatusStrip', () => ({ +vi.mock('./transcript/MainchainStatusStrip', () => ({ MainchainStatusStrip: () =>
, })); -vi.mock('./terminal', () => ({ +vi.mock('./terminal/index', () => ({ TerminalPanel: () =>
, })); diff --git a/app/workbench/src/WorkbenchFrame.terminalDock.test.tsx b/app/workbench/src/WorkbenchFrame.terminalDock.test.tsx index 3c999e0e1..f2b2e170a 100644 --- a/app/workbench/src/WorkbenchFrame.terminalDock.test.tsx +++ b/app/workbench/src/WorkbenchFrame.terminalDock.test.tsx @@ -17,7 +17,7 @@ vi.mock('./WorkbenchFrameParts', () => ({ WorkspaceLoadingState: () =>
, })); -vi.mock('./terminal', () => ({ +vi.mock('./terminal/index', () => ({ TerminalPanel: (props: { localTerminal?: boolean; terminal?: unknown }) => (
({ last: null as Record | null })); -vi.mock('./ConversationSidebar', () => ({ +vi.mock('./transcript/ConversationSidebar', () => ({ ConversationSidebar: (props: Record) => (
({ ), })); -vi.mock('./ConversationHost', () => ({ +vi.mock('./transcript/ConversationHost', () => ({ ConversationHost: (props: Record) => { hostPropsLog.last = props; return ( @@ -47,7 +47,7 @@ vi.mock('./ConversationHost', () => ({ }, })); -vi.mock('./RightInspector', () => ({ +vi.mock('./inspector/RightInspector', () => ({ RightInspector: (props: Record) => (
({ ), })); -vi.mock('./ChatEngineeringColumn', () => ({ +vi.mock('./transcript/ChatEngineeringColumn', () => ({ ChatEngineeringColumn: (props: Record) => (
{ }); }); -/* ═══════════════════ Draft persistence ═══════════════════ */ - const draftComposer: ComposerState = { conversationId: 'hub-session-draft', text: '', diff --git a/app/workbench/src/UnifiedComposer.tsx b/app/workbench/src/composer/UnifiedComposer.tsx similarity index 91% rename from app/workbench/src/UnifiedComposer.tsx rename to app/workbench/src/composer/UnifiedComposer.tsx index d85c208fc..4446a1fce 100644 --- a/app/workbench/src/UnifiedComposer.tsx +++ b/app/workbench/src/composer/UnifiedComposer.tsx @@ -27,7 +27,7 @@ import { filterAvailableMentionOptions, partitionAttachmentsBySize, } from './unifiedComposerHelpers'; -import styles from './AgentHubWorkbench.module.css'; +import styles from '../AgentHubWorkbench.module.css'; import { ComposerAgentPicker, ComposerApprovalModePicker, @@ -42,12 +42,7 @@ import { ComposerTargetPicker as ComposerTargetPickerBase, } from './UnifiedComposerParts'; -/* #21 性能:composer 状态每次击键都变(textarea 值必要更新),UnifiedComposer - 自身每击键重渲染不可避免;但子面板的 props 在击键时大多保持稳定(数据来自 - composer 状态的稳定引用 + useCallback 稳定的回调),包一层 React.memo 跳过 - 不必要的子树重渲染。 - ─ ComposerAgentPicker / ComposerStatusStrip 未包:availableMentionOptions / - statusItems 每次渲染由纯函数重建(新引用),memo 无效。 */ +// Every keystroke re-renders the composer; memo the subpanels whose props stay stable. const ComposerReplyBar = React.memo(ComposerReplyBarBase); const ComposerQuoteBar = React.memo(ComposerQuoteBarBase); const ComposerEditBar = React.memo(ComposerEditBarBase); @@ -113,8 +108,6 @@ export function UnifiedComposer({ const { chromeModel } = view; const fileInputRef = useRef(null); - /* #21 性能:稳定回调(依赖仅 dispatchComposer —— useReducer dispatch 跨渲染 - 稳定),配合上方子组件 React.memo,跳过击键时子面板的不必要重渲染。 */ const handleCancelReply = useCallback(() => dispatchComposer(cancelReplyAction()), [dispatchComposer]); const handleCancelQuote = useCallback(() => dispatchComposer(cancelQuoteAction()), [dispatchComposer]); const handleCancelEdit = useCallback(() => dispatchComposer(cancelEditAction()), [dispatchComposer]); @@ -154,14 +147,6 @@ export function UnifiedComposer({ onExecutionTargetChange?.(''); }, [runtime.executionTargetId, executionTargets, onExecutionTargetChange]); - /* ═══════════════ @mention inline popover ═══════════════ - The textarea reports every text/cursor change to evaluateTrigger; an - active '@' before the caret (preceded by whitespace, no whitespace in - the query segment) opens the popover. The popover reuses the existing - mentionableAgents data + planAddMentionAction so dispatchRole ('context' - vs 'dispatch') semantics flow through unchanged. IME composition is - guarded via compositionRef so '@' detection never fires mid-composition. */ - const [mentionTrigger, setMentionTrigger] = useState(null); const [mentionActiveIndex, setMentionActiveIndex] = useState(0); const [popoverCoords, setPopoverCoords] = useState(null); @@ -170,14 +155,6 @@ export function UnifiedComposer({ const textareaRef = useRef(null); const listboxId = useId(); - /* ═══════════════ Draft persistence ═══════════════ - Save composer draft per conversationId via requestIdleCallback - batching, load on mount, flush on hidden, clear on submit (empty - state). #1822: the persisted payload now also carries uploaded - attachment refs and the reply/quote context; in-flight attachments - are additionally kept in a memory cache so a same-session - conversation switch restores them fully. */ - const draftLoadedRef = useRef(null); const pendingDraftRef = useRef<{ conversationId: string; @@ -236,7 +213,6 @@ export function UnifiedComposer({ flushDraft(); } - // ══ Load draft (first time per conversationId) ══ if (draftLoadedRef.current !== cid) { draftLoadedRef.current = cid; // Only load when the composer is empty (fresh mount / conversation switch). @@ -297,7 +273,6 @@ export function UnifiedComposer({ } } - // ══ Save / clear draft ══ if ( composer.text === '' && composer.mentions.length === 0 && @@ -350,10 +325,6 @@ export function UnifiedComposer({ }; }, []); - /* ═══════════════ Auto-grow (#1822) ═══════════════ - The composer textarea is rows=1; grow it to fit the content up to - the CSS max-height instead of scrolling forever at one line. */ - useEffect(() => { const textarea = textareaRef.current; if (!textarea) return; @@ -535,15 +506,6 @@ export function UnifiedComposer({ if (effect.kind === 'submit') event.currentTarget.form?.requestSubmit(); } - /* ═══════════════ onPaste / onDrop attachment ═══════════════ - Extract File objects from clipboard paste or file drag-and-drop, convert - to ComposerAttachment (via browserFilesToComposerAttachments for content - preview + hash), and dispatch into the composer store. Upload is deferred - to ConversationHost on submit. Orthogonal to @mention popover — no - interaction with evaluateTrigger / compositionRef. - Size gate: files over MAX_ATTACHMENT_BYTES are - rejected up front with a toast instead of failing mid-upload. */ - async function handleAttachFiles(files: File[]): Promise { if (files.length === 0 || view.isSubmitting) return; const { accepted, rejected } = partitionAttachmentsBySize(files); diff --git a/app/workbench/src/composer/UnifiedComposerParts.tsx b/app/workbench/src/composer/UnifiedComposerParts.tsx new file mode 100644 index 000000000..53653c2a6 --- /dev/null +++ b/app/workbench/src/composer/UnifiedComposerParts.tsx @@ -0,0 +1,20 @@ +export { + ComposerMentionChips, + ComposerQuoteBar, + ComposerReplyBar, + ComposerEditBar, + ComposerStatusStrip, +} from './ComposerContextParts'; + +export { + ComposerAttachmentBar, + ComposerAttachmentChip, +} from './ComposerAttachmentParts'; + +export { + ComposerAgentPicker, + ComposerApprovalModePicker, + ComposerAttachButton, + ComposerSendButton, + ComposerTargetPicker, +} from './ComposerControlParts'; diff --git a/app/workbench/src/composerApprovalMode.test.ts b/app/workbench/src/composer/composerApprovalMode.test.ts similarity index 100% rename from app/workbench/src/composerApprovalMode.test.ts rename to app/workbench/src/composer/composerApprovalMode.test.ts diff --git a/app/workbench/src/composerApprovalMode.ts b/app/workbench/src/composer/composerApprovalMode.ts similarity index 64% rename from app/workbench/src/composerApprovalMode.ts rename to app/workbench/src/composer/composerApprovalMode.ts index 1fe82938f..52234fc81 100644 --- a/app/workbench/src/composerApprovalMode.ts +++ b/app/workbench/src/composer/composerApprovalMode.ts @@ -2,22 +2,9 @@ import type { ApprovalMode } from '@shared/composer'; import type { PermissionModeOption } from '@shared/ui'; /** - * #1816 — composer approval-mode picker mapping. - * - * Semantics (documented, matching both platform dispatchers): - * - 'suggest' (default): no override — the agent applies its own permission - * policy. Web sends approval_mode: "suggest"; desktop's edgePermissionMode - * returns no permissionMode override. - * - 'workspace-write': desktop maps to Edge permissionMode 'acceptEdits'. - * - 'read-only': desktop maps to Edge permissionMode 'plan'. - * - * The shared PermissionModePicker uses Edge permission-mode vocabulary for - * its option values ('acceptEdits' / 'plan') so the option icons stay - * meaningful; 'suggest' keeps a Settings glyph. - * - * `APPROVAL_MODE_ROWS` is the single source for the mode → picker-value → - * label-key mapping, and every function below is a lookup on it, so a mode - * can no longer be present in one mapping and missing from another. + * Composer approval mode → picker value + label key. `suggest` is a no-op + * override; the other two reuse the Edge vocabulary (`acceptEdits` / `plan`) + * so the shared picker icons stay meaningful. */ interface ApprovalModeRow { diff --git a/app/workbench/src/composerDocumentFileDrop.test.ts b/app/workbench/src/composer/composerDocumentFileDrop.test.ts similarity index 100% rename from app/workbench/src/composerDocumentFileDrop.test.ts rename to app/workbench/src/composer/composerDocumentFileDrop.test.ts diff --git a/app/workbench/src/composerDocumentFileDrop.ts b/app/workbench/src/composer/composerDocumentFileDrop.ts similarity index 75% rename from app/workbench/src/composerDocumentFileDrop.ts rename to app/workbench/src/composer/composerDocumentFileDrop.ts index a182272ac..6d1b5d8cb 100644 --- a/app/workbench/src/composerDocumentFileDrop.ts +++ b/app/workbench/src/composer/composerDocumentFileDrop.ts @@ -7,16 +7,6 @@ import { } from './unifiedComposerHelpers'; import { dispatchComposerAttachmentAdds } from './unifiedComposerHostHelpers'; -/* ═══════════════════════════════════════════════════════════════════════ - composerDocumentFileDrop — document-level file drop routing (#1822). - - Files dragged onto the transcript/sidebar/headers used to open in the - browser. These handlers intercept any Files drag outside the composer - form and route it to the composer attachment chips instead. Extracted - from ConversationHost so the routing decisions are unit-testable; - ConversationHost only owns listener registration and the dragging flag. - ═══════════════════════════════════════════════════════════════════════ */ - export interface ComposerDocumentFileDropCallbacks { dispatchComposer: Dispatch; onToast: (message: string) => void; diff --git a/app/workbench/src/composerMentionPopoverHelpers.test.ts b/app/workbench/src/composer/composerMentionPopoverHelpers.test.ts similarity index 100% rename from app/workbench/src/composerMentionPopoverHelpers.test.ts rename to app/workbench/src/composer/composerMentionPopoverHelpers.test.ts diff --git a/app/workbench/src/composerMentionPopoverHelpers.ts b/app/workbench/src/composer/composerMentionPopoverHelpers.ts similarity index 82% rename from app/workbench/src/composerMentionPopoverHelpers.ts rename to app/workbench/src/composer/composerMentionPopoverHelpers.ts index ced1ed680..b531b5505 100644 --- a/app/workbench/src/composerMentionPopoverHelpers.ts +++ b/app/workbench/src/composer/composerMentionPopoverHelpers.ts @@ -1,18 +1,3 @@ -/* ═══════════════════════════════════════════════════════════════════════ - composerMentionPopoverHelpers — pure + DOM plumbing for the @mention - popover: keyboard navigation plan, viewport-clamped - positioning, and best-effort caret coordinate measurement. - - - `planMentionPopoverKeyDown` / `clampPopoverPosition` are pure and - fully unit-testable. - - `measureCaretCoords` is a defensive DOM measurement (mirror-div - technique) that returns null in environments without layout (jsdom), - letting the host fall back to an anchored position. - - No React. The host wires these into the textarea keydown handler and - a layout effect that positions the popover. - ═══════════════════════════════════════════════════════════════════════ */ - /** Keyboard effect the host should apply while the mention popover is open. */ export type MentionPopoverKeyEffect = | { kind: 'none' } diff --git a/app/workbench/src/composerMentionTrigger.test.ts b/app/workbench/src/composer/composerMentionTrigger.test.ts similarity index 100% rename from app/workbench/src/composerMentionTrigger.test.ts rename to app/workbench/src/composer/composerMentionTrigger.test.ts diff --git a/app/workbench/src/composerMentionTrigger.ts b/app/workbench/src/composer/composerMentionTrigger.ts similarity index 74% rename from app/workbench/src/composerMentionTrigger.ts rename to app/workbench/src/composer/composerMentionTrigger.ts index 42b4ff256..bdef9388c 100644 --- a/app/workbench/src/composerMentionTrigger.ts +++ b/app/workbench/src/composer/composerMentionTrigger.ts @@ -1,19 +1,5 @@ import type { ComposerMention } from '@shared/composer'; -/* ═══════════════════════════════════════════════════════════════════════ - composerMentionTrigger — pure @mention trigger detection for the - UnifiedComposer textarea. - - Detects an active '@' trigger immediately preceding the caret, extracts - the query segment, filters mentionable candidates, and computes the text - slice that must be removed when a candidate is inserted as a chip. - - Pure + framework-agnostic: no React, no DOM. The host (UnifiedComposer) - wires these into textarea onChange/onSelect and the popover selection - handler. Mention data + dispatchRole semantics flow unchanged through - the existing `addMention` reducer action — see planAddMentionAction. - ═══════════════════════════════════════════════════════════════════════ */ - export interface MentionTrigger { /** Offset of the '@' trigger char in the composer text. */ atOffset: number; diff --git a/app/workbench/src/unifiedComposerHelpers.test.ts b/app/workbench/src/composer/unifiedComposerHelpers.test.ts similarity index 100% rename from app/workbench/src/unifiedComposerHelpers.test.ts rename to app/workbench/src/composer/unifiedComposerHelpers.test.ts diff --git a/app/workbench/src/unifiedComposerHelpers.ts b/app/workbench/src/composer/unifiedComposerHelpers.ts similarity index 93% rename from app/workbench/src/unifiedComposerHelpers.ts rename to app/workbench/src/composer/unifiedComposerHelpers.ts index 1ea2ba108..7c1c6afe6 100644 --- a/app/workbench/src/unifiedComposerHelpers.ts +++ b/app/workbench/src/composer/unifiedComposerHelpers.ts @@ -1,13 +1,6 @@ import type { ComposerAttachment, ComposerMention, ComposerState } from '@shared/composer'; import { canSubmitComposer, formatComposerAttachmentSize } from '@shared/composer'; -import type { ComposerSubmitBehavior } from './workbenchPreferences'; - -/* ═══════════════════════════════════════════════════════════════════════ - unifiedComposerHelpers — pure helpers for UnifiedComposer (#638). - - Status/label builders, mention filtering, and submit-key planners. - No React hooks. - ═══════════════════════════════════════════════════════════════════════ */ +import type { ComposerSubmitBehavior } from '../workbenchPreferences'; export interface AttachmentUploadState { percent: number; diff --git a/app/workbench/src/unifiedComposerHostActions.test.ts b/app/workbench/src/composer/unifiedComposerHostActions.test.ts similarity index 100% rename from app/workbench/src/unifiedComposerHostActions.test.ts rename to app/workbench/src/composer/unifiedComposerHostActions.test.ts diff --git a/app/workbench/src/unifiedComposerHostActions.ts b/app/workbench/src/composer/unifiedComposerHostActions.ts similarity index 81% rename from app/workbench/src/unifiedComposerHostActions.ts rename to app/workbench/src/composer/unifiedComposerHostActions.ts index 883613fe8..7691d20e7 100644 --- a/app/workbench/src/unifiedComposerHostActions.ts +++ b/app/workbench/src/composer/unifiedComposerHostActions.ts @@ -6,13 +6,6 @@ import type { } from '@shared/composer'; import { findMentionById } from './unifiedComposerHelpers'; -/* ═══════════════════════════════════════════════════════════════════════ - unifiedComposerHostActions — pure action builders (#780). - - Mention/attachment/text/reply/quote action builders and attachment - dispatch helpers. No React hooks. - ═══════════════════════════════════════════════════════════════════════ */ - /** Plan mention add action from a picker selection. */ export function planAddMentionAction( mentionableAgents: ComposerMention[], diff --git a/app/workbench/src/unifiedComposerHostFilePick.test.ts b/app/workbench/src/composer/unifiedComposerHostFilePick.test.ts similarity index 100% rename from app/workbench/src/unifiedComposerHostFilePick.test.ts rename to app/workbench/src/composer/unifiedComposerHostFilePick.test.ts diff --git a/app/workbench/src/unifiedComposerHostFilePick.ts b/app/workbench/src/composer/unifiedComposerHostFilePick.ts similarity index 87% rename from app/workbench/src/unifiedComposerHostFilePick.ts rename to app/workbench/src/composer/unifiedComposerHostFilePick.ts index 6e42c4e71..dffac6fdf 100644 --- a/app/workbench/src/unifiedComposerHostFilePick.ts +++ b/app/workbench/src/composer/unifiedComposerHostFilePick.ts @@ -1,12 +1,5 @@ import type { ComposerAttachment } from '@shared/composer'; -/* ═══════════════════════════════════════════════════════════════════════ - unifiedComposerHostFilePick — pure file-picker planners (#780). - - File-input / native-picker planners and attachment resolution. - No React hooks. - ═══════════════════════════════════════════════════════════════════════ */ - export type ComposerFilePickPlan = | { kind: 'noop' } | { kind: 'native' } diff --git a/app/workbench/src/unifiedComposerHostHelpers.test.ts b/app/workbench/src/composer/unifiedComposerHostHelpers.test.ts similarity index 100% rename from app/workbench/src/unifiedComposerHostHelpers.test.ts rename to app/workbench/src/composer/unifiedComposerHostHelpers.test.ts diff --git a/app/workbench/src/unifiedComposerHostHelpers.ts b/app/workbench/src/composer/unifiedComposerHostHelpers.ts similarity index 69% rename from app/workbench/src/unifiedComposerHostHelpers.ts rename to app/workbench/src/composer/unifiedComposerHostHelpers.ts index bbfe9386a..d9457e130 100644 --- a/app/workbench/src/unifiedComposerHostHelpers.ts +++ b/app/workbench/src/composer/unifiedComposerHostHelpers.ts @@ -1,17 +1,3 @@ -/* ═══════════════════════════════════════════════════════════════════════ - unifiedComposerHostHelpers — stable public surface for UnifiedComposer - host pure helpers (#718 / helper module #780). - - Implementation lives in: - - unifiedComposerHostViewModel - - unifiedComposerHostKeyDown - - unifiedComposerHostActions - - unifiedComposerHostFilePick - - Re-exports keep import paths stable for UnifiedComposer and tests. - No React hooks. - ═══════════════════════════════════════════════════════════════════════ */ - export type { AttachmentUploadState, ComposerExecutionTarget, diff --git a/app/workbench/src/unifiedComposerHostKeyDown.test.ts b/app/workbench/src/composer/unifiedComposerHostKeyDown.test.ts similarity index 100% rename from app/workbench/src/unifiedComposerHostKeyDown.test.ts rename to app/workbench/src/composer/unifiedComposerHostKeyDown.test.ts diff --git a/app/workbench/src/unifiedComposerHostKeyDown.ts b/app/workbench/src/composer/unifiedComposerHostKeyDown.ts similarity index 89% rename from app/workbench/src/unifiedComposerHostKeyDown.ts rename to app/workbench/src/composer/unifiedComposerHostKeyDown.ts index 0ee45a24c..07f7dd7db 100644 --- a/app/workbench/src/unifiedComposerHostKeyDown.ts +++ b/app/workbench/src/composer/unifiedComposerHostKeyDown.ts @@ -1,5 +1,5 @@ import type { ComposerAction, ComposerAttachment } from '@shared/composer'; -import type { ComposerSubmitBehavior } from './workbenchPreferences'; +import type { ComposerSubmitBehavior } from '../workbenchPreferences'; import { buildTextWithNewline, canSubmitFromKeyDown, @@ -7,13 +7,6 @@ import { } from './unifiedComposerHelpers'; import { setComposerTextAction } from './unifiedComposerHostActions'; -/* ═══════════════════════════════════════════════════════════════════════ - unifiedComposerHostKeyDown — pure keydown planners (#780). - - Keydown event field readers, submit/newline planners, and host effect - mappers. No React hooks. - ═══════════════════════════════════════════════════════════════════════ */ - export type ComposerHostKeyDownPlan = | { kind: 'none' } | { kind: 'insert-newline'; nextText: string; caret: number } diff --git a/app/workbench/src/unifiedComposerHostViewModel.test.ts b/app/workbench/src/composer/unifiedComposerHostViewModel.test.ts similarity index 100% rename from app/workbench/src/unifiedComposerHostViewModel.test.ts rename to app/workbench/src/composer/unifiedComposerHostViewModel.test.ts diff --git a/app/workbench/src/unifiedComposerHostViewModel.ts b/app/workbench/src/composer/unifiedComposerHostViewModel.ts similarity index 91% rename from app/workbench/src/unifiedComposerHostViewModel.ts rename to app/workbench/src/composer/unifiedComposerHostViewModel.ts index 428925af5..ed5635f75 100644 --- a/app/workbench/src/unifiedComposerHostViewModel.ts +++ b/app/workbench/src/composer/unifiedComposerHostViewModel.ts @@ -11,7 +11,7 @@ import type { QuoteContext, ReplyToContext, } from '@shared/composer'; -import type { ComposerSubmitBehavior } from './workbenchPreferences'; +import type { ComposerSubmitBehavior } from '../workbenchPreferences'; import { COMPOSER_FILE_ACCEPT, deriveUnifiedComposerState, @@ -22,16 +22,6 @@ import { type UnifiedComposerDerivedState, } from './unifiedComposerHelpers'; -/* ═══════════════════════════════════════════════════════════════════════ - unifiedComposerHostViewModel — pure host view/chrome builders (#780). - - Props types, runtime defaults, chrome visibility, chrome render model, - and combined host view-model builders. - No React hooks. - exactOptionalPropertyTypes: only assign `?: T` fields when defined, - unless the public field type explicitly allows `| undefined`. - ═══════════════════════════════════════════════════════════════════════ */ - export type { AttachmentUploadState, ComposerExecutionTarget, diff --git a/app/workbench/src/hubDataMapping.test.ts b/app/workbench/src/hubDataMapping.test.ts index f4b475de1..34ff02687 100644 --- a/app/workbench/src/hubDataMapping.test.ts +++ b/app/workbench/src/hubDataMapping.test.ts @@ -1,6 +1,6 @@ import { beforeAll, describe, expect, it } from 'vitest'; import { useTestI18nLanguage } from '@shared/testing/i18n'; -import type { ProjectInfo } from './pages'; +import type { ProjectInfo } from './pages/index'; import { contactInfoToMember, hubDocumentToDocRow, diff --git a/app/workbench/src/hubDataMapping.ts b/app/workbench/src/hubDataMapping.ts index 98db69bf2..84bdd1517 100644 --- a/app/workbench/src/hubDataMapping.ts +++ b/app/workbench/src/hubDataMapping.ts @@ -11,7 +11,7 @@ import { appDateLocaleTag } from '@shared/i18n/locale'; import { SHARED_WORKBENCH_I18N_NAMESPACE } from '@shared/i18n'; import { getI18n } from 'react-i18next'; -import type { ContactMember, ProjectInfo } from './pages'; +import type { ContactMember, ProjectInfo } from './pages/index'; import type { WorkbenchContactsData } from './WorkbenchRoutes'; import type { DocRow } from './pages/DocsPage'; import type { WorkbenchConversation } from '@shared/platform'; diff --git a/app/workbench/src/index.ts b/app/workbench/src/index.ts index 2ee4d1c93..c8b9e8548 100644 --- a/app/workbench/src/index.ts +++ b/app/workbench/src/index.ts @@ -1,10 +1,10 @@ export { AgentHubWorkbench } from './AgentHubWorkbench'; -export { ChatViewBridge } from './ChatViewBridge'; -export { ConversationSidebar } from './ConversationSidebar'; +export { ChatViewBridge } from './transcript/ChatViewBridge'; +export { ConversationSidebar } from './transcript/ConversationSidebar'; export { GlobalRail } from './GlobalRail'; -export { RightInspector } from './RightInspector'; -export { UnifiedComposer } from './UnifiedComposer'; -export { WorkbenchGoalBanner } from './WorkbenchGoalBanner'; +export { RightInspector } from './inspector/RightInspector'; +export { UnifiedComposer } from './composer/UnifiedComposer'; +export { WorkbenchGoalBanner } from './transcript/WorkbenchGoalBanner'; export { WorkbenchRoutes } from './WorkbenchRoutes'; export { WorkspaceHeader } from './WorkspaceHeader'; export { @@ -22,8 +22,8 @@ export { export { buildMainchainSummary, runtimeEvidenceSourceSummary, -} from './mainchain'; -export { MainchainStatusStrip } from './MainchainStatusStrip'; +} from './mainchain/index'; +export { MainchainStatusStrip } from './transcript/MainchainStatusStrip'; export { buildActiveConversationAttention, deriveConversationLiveStatus, @@ -31,7 +31,7 @@ export { isRunActive, summarizeWorkbenchAttention, } from './workbenchAttentionModel'; -export { GOAL_TOOL_NAMES, deriveGoalSummary } from './workbenchGoalSummary'; +export { GOAL_TOOL_NAMES, deriveGoalSummary } from './transcript/workbenchGoalSummary'; export type { TranscriptContextMenuEvent, TranscriptPointerEvent } from './transcriptEventTypes'; export { buildAgentCapabilityContractFromConfig, @@ -84,18 +84,18 @@ export { /* ── Types ── */ export type { AgentHubWorkbenchProps } from './AgentHubWorkbench'; -export type { ChatViewBridgeProps } from './ChatViewBridge'; -export type { ConversationSidebarProps } from './ConversationSidebar'; +export type { ChatViewBridgeProps } from './transcript/ChatViewBridge'; +export type { ConversationSidebarProps } from './transcript/ConversationSidebar'; export type { GlobalRailProps, GlobalRailPage, ConnectionStatusKind } from './GlobalRail'; -export type { RightInspectorProps, RuntimeEvidenceSnapshot } from './RightInspector'; -export type { UnifiedComposerProps } from './UnifiedComposer'; +export type { RightInspectorProps, RuntimeEvidenceSnapshot } from './inspector/RightInspector'; +export type { UnifiedComposerProps } from './composer/UnifiedComposer'; export type { MainchainNode, MainchainSummary, MainchainStatusKind, MainchainWorkbenchStatus, -} from './mainchain'; -export type { MainchainStatusStripProps } from './MainchainStatusStrip'; +} from './mainchain/index'; +export type { MainchainStatusStripProps } from './transcript/MainchainStatusStrip'; export type { ActiveConversationAttentionInput, ConversationLiveStatus, @@ -103,8 +103,8 @@ export type { WorkbenchAttentionInput, WorkbenchAttentionSummary, } from './workbenchAttentionModel'; -export type { WorkbenchGoalBannerProps } from './WorkbenchGoalBanner'; -export type { WorkbenchGoalStatus, WorkbenchGoalSummary } from './workbenchGoalSummary'; +export type { WorkbenchGoalBannerProps } from './transcript/WorkbenchGoalBanner'; +export type { WorkbenchGoalStatus, WorkbenchGoalSummary } from './transcript/workbenchGoalSummary'; export type { WorkbenchAgentProfilesStatus, WorkbenchContactsData, @@ -126,7 +126,7 @@ export { TasksPage, DevicesPage, TokenUsagePage, -} from './pages'; +} from './pages/index'; export type { AgentsPageProps, AgentConfig, @@ -170,31 +170,31 @@ export type { TokenUsagePageProps, TokenUsagePageTeam, TokenUsagePageRun, -} from './pages'; +} from './pages/index'; /* ═══ Inspector panels ═══ */ export { OverviewPanel, FilePreview, BrowserPreview, -} from './inspector'; +} from './inspector/index'; export type { OverviewPanelProps, TaskItem as InspectorTaskItem, FileItem, FilePreviewProps, BrowserPreviewProps, -} from './inspector'; +} from './inspector/index'; /* ═══ Terminal host shell (#1174) ═══ */ export { TerminalPanel, isLocalTerminalEnabled, -} from './terminal'; +} from './terminal/index'; export type { TerminalPanelLabels, TerminalPanelProps, -} from './terminal'; +} from './terminal/index'; /* ═══ Floating components ═══ */ export { @@ -203,7 +203,7 @@ export { PersonPanel, ProfilePopover, DemoToast, -} from './floating'; +} from './floating/index'; export type { ContextMenuProps, ContextMenuItem, @@ -212,11 +212,11 @@ export type { PersonPanelProps, ProfilePopoverProps, DemoToastProps, -} from './floating'; +} from './floating/index'; -export * from './auxPanel'; +export * from './auxPanel/index'; -export * from './sessionImport'; +export * from './sessionImport/index'; /* ═══ Team subagent stream (#1478 / #1406) ═══ */ export { @@ -228,7 +228,7 @@ export { type SubagentStreamListener, type TeamSubagentStreamEvent, type SubagentStreamOverlayProps, -} from './team'; +} from './team/index'; /* ═══ Inline message delegation (#1406) ═══ */ export { @@ -241,4 +241,4 @@ export { type DelegationEntry, type DelegationStatus, type MessageDelegationListener, -} from './team'; +} from './team/index'; diff --git a/app/workbench/src/RightInspector.tsx b/app/workbench/src/inspector/RightInspector.tsx similarity index 98% rename from app/workbench/src/RightInspector.tsx rename to app/workbench/src/inspector/RightInspector.tsx index f549c2b84..cf66ff28d 100644 --- a/app/workbench/src/RightInspector.tsx +++ b/app/workbench/src/inspector/RightInspector.tsx @@ -11,9 +11,9 @@ import { defaultVisibleTabs, getInspectorTabs, type InspectorMode, -} from './inspector'; -import { WORKBENCH_INSPECTOR_QUICK_OPEN_EVENT } from './desktopChromeEvents'; -import styles from './AgentHubWorkbench.module.css'; +} from './index'; +import { WORKBENCH_INSPECTOR_QUICK_OPEN_EVENT } from '../desktopChromeEvents'; +import styles from '../AgentHubWorkbench.module.css'; import { RightInspectorModePanel } from './RightInspectorModePanel'; import { RightInspectorResizer } from './RightInspectorResizer'; import { diff --git a/app/workbench/src/RightInspectorModePanel.tsx b/app/workbench/src/inspector/RightInspectorModePanel.tsx similarity index 98% rename from app/workbench/src/RightInspectorModePanel.tsx rename to app/workbench/src/inspector/RightInspectorModePanel.tsx index 7af0d95c8..a8dcc6a95 100644 --- a/app/workbench/src/RightInspectorModePanel.tsx +++ b/app/workbench/src/inspector/RightInspectorModePanel.tsx @@ -11,12 +11,12 @@ import { type PreviewFile, type RunResultInfo, type TaskItem, -} from './inspector'; +} from './index'; import type { DagNode } from '@shared/ui/DagTree'; import type { FileDiff } from '@shared/types/chat'; import { useTranslation } from 'react-i18next'; import { CHATVIEW_I18N_NAMESPACE } from '@shared/chatview/i18n/resources'; -import styles from './AgentHubWorkbench.module.css'; +import styles from '../AgentHubWorkbench.module.css'; /* ═══════════════════════════════════════════════════════════════════════ RightInspectorModePanel — mode tabpanel bodies for RightInspector (#661). diff --git a/app/workbench/src/RightInspectorResizer.tsx b/app/workbench/src/inspector/RightInspectorResizer.tsx similarity index 96% rename from app/workbench/src/RightInspectorResizer.tsx rename to app/workbench/src/inspector/RightInspectorResizer.tsx index 538386d8d..daf2f2ed5 100644 --- a/app/workbench/src/RightInspectorResizer.tsx +++ b/app/workbench/src/inspector/RightInspectorResizer.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { CHATVIEW_I18N_NAMESPACE } from '@shared/chatview/i18n/resources'; -import styles from './AgentHubWorkbench.module.css'; +import styles from '../AgentHubWorkbench.module.css'; /* ═══════════════════════════════════════════════════════════════════════ RightInspectorResizer — keyboard/pointer vertical resizer chrome for diff --git a/app/workbench/src/rightInspectorHelpers.test.ts b/app/workbench/src/inspector/rightInspectorHelpers.test.ts similarity index 100% rename from app/workbench/src/rightInspectorHelpers.test.ts rename to app/workbench/src/inspector/rightInspectorHelpers.test.ts diff --git a/app/workbench/src/rightInspectorHelpers.ts b/app/workbench/src/inspector/rightInspectorHelpers.ts similarity index 94% rename from app/workbench/src/rightInspectorHelpers.ts rename to app/workbench/src/inspector/rightInspectorHelpers.ts index a70c66aa5..d7adf0a8f 100644 --- a/app/workbench/src/rightInspectorHelpers.ts +++ b/app/workbench/src/inspector/rightInspectorHelpers.ts @@ -4,20 +4,20 @@ import type { RuntimeEvidenceSnapshot } from '@shared/inspector'; import type { FileDiff } from '@shared/types/chat'; import type { DagNode } from '@shared/ui/DagTree'; import { buildDagNodesFromTranscript } from '@shared/ui/DagTree'; -import { isThemedBlankPreviewUrl } from './inspector/BrowserPreview'; -import type { PreviewFile } from './inspector/FilePreviewRouter'; +import { isThemedBlankPreviewUrl } from './BrowserPreview'; +import type { PreviewFile } from './FilePreviewRouter'; import { evidenceOverviewFiles, evidenceOverviewTasks, -} from './inspector/InspectorModePanels'; -import type { InspectorTranslator } from './inspector/InspectorModePanelHelpers'; -import type { InspectorMode, InspectorTabDef } from './inspector/InspectorTabChrome'; -import type { FileItem, TaskItem } from './inspector/OverviewPanel'; +} from './InspectorModePanels'; +import type { InspectorTranslator } from './InspectorModePanelHelpers'; +import type { InspectorMode, InspectorTabDef } from './InspectorTabChrome'; +import type { FileItem, TaskItem } from './OverviewPanel'; import { runtimeDiffPreviewFile, runtimeEvidenceOverviewFiles, runtimeEvidenceOverviewTasks, -} from './inspector/RuntimeEvidencePanel'; +} from './RuntimeEvidencePanel'; /* ═══════════════════════════════════════════════════════════════════════ rightInspectorHelpers — pure helpers for RightInspector (#661). diff --git a/app/workbench/src/rightInspectorTypes.ts b/app/workbench/src/inspector/rightInspectorTypes.ts similarity index 94% rename from app/workbench/src/rightInspectorTypes.ts rename to app/workbench/src/inspector/rightInspectorTypes.ts index 7c72fb0dd..477abed09 100644 --- a/app/workbench/src/rightInspectorTypes.ts +++ b/app/workbench/src/inspector/rightInspectorTypes.ts @@ -8,8 +8,8 @@ import type { SubagentTranscriptBlock, SubtaskTranscriptBlock, } from '@shared/transcript'; -import type { FileItem, RunResultInfo } from './inspector/OverviewPanel'; -import type { BrowserPreviewFocusRequest } from './workbenchSessionChromeHelpers'; +import type { FileItem, RunResultInfo } from './OverviewPanel'; +import type { BrowserPreviewFocusRequest } from '../transcript/workbenchSessionChromeHelpers'; /* ═══════════════════════════════════════════════════════════════════════ rightInspectorTypes — public props / shared types for diff --git a/app/workbench/src/useEngineeringColumnAutoOpen.test.tsx b/app/workbench/src/inspector/useEngineeringColumnAutoOpen.test.tsx similarity index 97% rename from app/workbench/src/useEngineeringColumnAutoOpen.test.tsx rename to app/workbench/src/inspector/useEngineeringColumnAutoOpen.test.tsx index 8bf764d88..80fc00e70 100644 --- a/app/workbench/src/useEngineeringColumnAutoOpen.test.tsx +++ b/app/workbench/src/inspector/useEngineeringColumnAutoOpen.test.tsx @@ -1,6 +1,6 @@ import { act, renderHook, waitFor } from '@testing-library/react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import type { WorkbenchPanelLayout } from './useWorkbenchPanelLayout'; +import type { WorkbenchPanelLayout } from '../useWorkbenchPanelLayout'; import { canAutoOpenEngineeringColumn, engineeringColumnActivitySignal, @@ -9,7 +9,7 @@ import { import { readEngineeringColumnPreference, writeEngineeringColumnPreference, -} from './workbenchPreferences'; +} from '../workbenchPreferences'; function layoutMock(collapsed: boolean) { return { diff --git a/app/workbench/src/useEngineeringColumnAutoOpen.ts b/app/workbench/src/inspector/useEngineeringColumnAutoOpen.ts similarity index 95% rename from app/workbench/src/useEngineeringColumnAutoOpen.ts rename to app/workbench/src/inspector/useEngineeringColumnAutoOpen.ts index 3d874cd88..cdb40cf35 100644 --- a/app/workbench/src/useEngineeringColumnAutoOpen.ts +++ b/app/workbench/src/inspector/useEngineeringColumnAutoOpen.ts @@ -1,12 +1,12 @@ import { useCallback, useEffect, useMemo, useRef } from 'react'; import type { RuntimeEvidenceSnapshot } from '@shared/inspector'; import type { AgentHubPlatform } from '@shared/platform'; -import type { WorkbenchPanelLayout } from './useWorkbenchPanelLayout'; +import type { WorkbenchPanelLayout } from '../useWorkbenchPanelLayout'; import { readEngineeringColumnPreference, writeEngineeringColumnPreference, -} from './workbenchPreferences'; -import { WORKSPACE_MOUNT_COLLAPSE_INSPECTOR_WIDTH } from './workbenchLayoutConstants'; +} from '../workbenchPreferences'; +import { WORKSPACE_MOUNT_COLLAPSE_INSPECTOR_WIDTH } from '../workbenchLayoutConstants'; export interface EngineeringColumnActivityInput { isAgentRunning?: boolean | undefined; diff --git a/app/workbench/src/mainchain/buildMainchainSummary.ts b/app/workbench/src/mainchain/buildMainchainSummary.ts index db73ae120..93e094b3e 100644 --- a/app/workbench/src/mainchain/buildMainchainSummary.ts +++ b/app/workbench/src/mainchain/buildMainchainSummary.ts @@ -1,6 +1,6 @@ import type { AgentHubPlatform } from '@shared/platform'; import type { EvidenceRef, TranscriptBlock } from '@shared/transcript'; -import type { RuntimeEvidenceSnapshot } from '../RightInspector'; +import type { RuntimeEvidenceSnapshot } from '../inspector/RightInspector'; import type { MainchainNode, MainchainSummary } from './types'; export type MainchainWorkbenchStatus = { diff --git a/app/workbench/src/pages/AgentsPage.tsx b/app/workbench/src/pages/AgentsPage.tsx index b466b75ab..f62d5c105 100644 --- a/app/workbench/src/pages/AgentsPage.tsx +++ b/app/workbench/src/pages/AgentsPage.tsx @@ -18,11 +18,11 @@ import { AgentModelsView, AgentAuditView, DataSourceBadge, -} from './agents'; +} from './agents/index'; import type { AgentsPaneId, AgentsPageProps, -} from './agents'; +} from './agents/index'; /* ═══════════════════════════════════════════════════════════════════════ AgentsPage — AgentHub v4 @@ -61,7 +61,7 @@ export type { CCSwitchStatusInfo, CCSwitchProviderInfo, AgentsPageProps, -} from './agents'; +} from './agents/index'; /* ═══════════════════════════════════════════════════════════════════════ AgentsPage diff --git a/app/workbench/src/pages/ContactsPage.tsx b/app/workbench/src/pages/ContactsPage.tsx index fadda1f94..cac50bd46 100644 --- a/app/workbench/src/pages/ContactsPage.tsx +++ b/app/workbench/src/pages/ContactsPage.tsx @@ -6,8 +6,8 @@ import { AddContactModal, ContactMain, ContactNav, -} from './contacts'; -import type { ContactsPageProps } from './contacts'; +} from './contacts/index'; +import type { ContactsPageProps } from './contacts/index'; /* ═══════════════════════════════════════════════════════════════════════ ContactsPage — pure presentational workbench page @@ -30,7 +30,7 @@ export type { ContactModalTab, ContactProfile, ContactsPageProps, -} from './contacts'; +} from './contacts/index'; // ── Main component ── diff --git a/app/workbench/src/pages/DocsPage.tsx b/app/workbench/src/pages/DocsPage.tsx index 0afe13d20..649c18fc4 100644 --- a/app/workbench/src/pages/DocsPage.tsx +++ b/app/workbench/src/pages/DocsPage.tsx @@ -3,8 +3,8 @@ import styles from './DocsPage.module.css'; import { DocMain, DocsNav, -} from './docs'; -import type { DocsPageProps } from './docs'; +} from './docs/index'; +import type { DocsPageProps } from './docs/index'; /* ═══════════════════════════════════════════════════════════════════════ DocsPage — pure presentational workbench page @@ -21,7 +21,7 @@ export type { DocsPane, DocsPageNavItem, DocsPageProps, -} from './docs'; +} from './docs/index'; // ── Main component ── diff --git a/app/workbench/src/pages/ProjectsPage.test.tsx b/app/workbench/src/pages/ProjectsPage.test.tsx index 353d56858..8eaf88c85 100644 --- a/app/workbench/src/pages/ProjectsPage.test.tsx +++ b/app/workbench/src/pages/ProjectsPage.test.tsx @@ -3,7 +3,7 @@ import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest'; import { fireEvent, render, screen, within } from '../__tests__/setup'; import { ProjectsPage } from './ProjectsPage'; import { WORKBENCH_MOCK_PROJECTS } from '../mockData'; -import type { ProjectInfo, ProjectsPageProps } from './projects'; +import type { ProjectInfo, ProjectsPageProps } from './projects/index'; // Projects copy resolves via the sharedWorkbench namespace; opt into the zh // bundle of the shared test i18next instance (Issue #1717). diff --git a/app/workbench/src/pages/ProjectsPage.tsx b/app/workbench/src/pages/ProjectsPage.tsx index 52b381898..8fff49cf8 100644 --- a/app/workbench/src/pages/ProjectsPage.tsx +++ b/app/workbench/src/pages/ProjectsPage.tsx @@ -5,8 +5,8 @@ import { ProjectMain, ProjectNav, useProjectEditor, -} from './projects'; -import type { ProjectsPageProps } from './projects'; +} from './projects/index'; +import type { ProjectsPageProps } from './projects/index'; /* ═══════════════════════════════════════════════════════════════════════ ProjectsPage — pure presentational workbench page @@ -26,7 +26,7 @@ export type { ProjectDraft, ProjectTab, ProjectsPageProps, -} from './projects'; +} from './projects/index'; // ── Main component ── diff --git a/app/workbench/src/pages/SettingsPage.tsx b/app/workbench/src/pages/SettingsPage.tsx index 9804ff2a3..630a75529 100644 --- a/app/workbench/src/pages/SettingsPage.tsx +++ b/app/workbench/src/pages/SettingsPage.tsx @@ -3,8 +3,8 @@ import styles from './SettingsPage.module.css'; import { SettingsMain, SettingsNav, -} from './settings'; -import type { SettingsPageProps } from './settings'; +} from './settings/index'; +import type { SettingsPageProps } from './settings/index'; /* ═══════════════════════════════════════════════════════════════════════ SettingsPage — AgentHub v4 @@ -20,7 +20,7 @@ export type { SettingsPageProps, SettingsPaneId, StatePanelKind, -} from './settings'; +} from './settings/index'; /* ═══════════════════════════════════════════════════════════════════════ Main export diff --git a/app/workbench/src/pages/TasksPage.tsx b/app/workbench/src/pages/TasksPage.tsx index f5c96f98c..f3be957b4 100644 --- a/app/workbench/src/pages/TasksPage.tsx +++ b/app/workbench/src/pages/TasksPage.tsx @@ -3,8 +3,8 @@ import styles from './TasksPage.module.css'; import { TaskMain, TaskNav, -} from './tasks'; -import type { TasksPageProps } from './tasks'; +} from './tasks/index'; +import type { TasksPageProps } from './tasks/index'; /* ═══════════════════════════════════════════════════════════════════════ TasksPage — pure presentational workbench page @@ -24,7 +24,7 @@ export type { TaskGroup, TaskEditDraft, TasksPageProps, -} from './tasks'; +} from './tasks/index'; // ── Main component ── diff --git a/app/workbench/src/pages/contacts/ContactMainParts.tsx b/app/workbench/src/pages/contacts/ContactMainParts.tsx index 81e87edbf..a330f8c24 100644 --- a/app/workbench/src/pages/contacts/ContactMainParts.tsx +++ b/app/workbench/src/pages/contacts/ContactMainParts.tsx @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'; import { SHARED_WORKBENCH_I18N_NAMESPACE } from '@shared/i18n'; import { StatusNotice } from '@shared/ui'; import { DesignNavIcon } from '../../designIcons'; -import { ProfilePopover } from '../../floating'; +import { ProfilePopover } from '../../floating/index'; import styles from '../ContactsPage.module.css'; import { QuickActionGrid } from './ContactRows'; import { diff --git a/app/workbench/src/pages/docs/DocTableViews.tsx b/app/workbench/src/pages/docs/DocTableViews.tsx index 4da3a1534..d41993a8c 100644 --- a/app/workbench/src/pages/docs/DocTableViews.tsx +++ b/app/workbench/src/pages/docs/DocTableViews.tsx @@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next'; import { SHARED_WORKBENCH_I18N_NAMESPACE } from '@shared/i18n'; import { DesignNavIcon } from '../../designIcons'; import type { WorkbenchDocumentPreview } from '../../documentPreview'; -import { FilePreview } from '../../inspector'; +import { FilePreview } from '../../inspector/index'; import { resolveWorkbenchProfile, type WorkbenchProfileSource, diff --git a/app/workbench/src/pages/projects/ProjectPanelParts.tsx b/app/workbench/src/pages/projects/ProjectPanelParts.tsx index 049ac34d7..457ed0b73 100644 --- a/app/workbench/src/pages/projects/ProjectPanelParts.tsx +++ b/app/workbench/src/pages/projects/ProjectPanelParts.tsx @@ -11,7 +11,7 @@ import { useTranslation } from 'react-i18next'; import { SHARED_WORKBENCH_I18N_NAMESPACE } from '@shared/i18n'; import { DesignFileIcon } from '../../designIcons'; import type { WorkbenchDocumentPreview } from '../../documentPreview'; -import { FilePreview } from '../../inspector'; +import { FilePreview } from '../../inspector/index'; import { resolveWorkbenchProfile, type WorkbenchProfileSource, diff --git a/app/workbench/src/pages/settings/SettingsPanes.tsx b/app/workbench/src/pages/settings/SettingsPanes.tsx index 2713df29a..5a7479fc7 100644 --- a/app/workbench/src/pages/settings/SettingsPanes.tsx +++ b/app/workbench/src/pages/settings/SettingsPanes.tsx @@ -20,9 +20,9 @@ import { LocalCliDiscoveryStatus, StatePreviewSection, } from './SettingsPaneParts'; -import { SessionImportList } from '../../sessionImport'; +import { SessionImportList } from '../../sessionImport/index'; import { ThemePresetPicker } from './ThemePresetPicker'; -import { writeClipboardText } from '../../workbenchTranscriptChromeStateHelpers'; +import { writeClipboardText } from '../../transcript/workbenchTranscriptChromeStateHelpers'; import { resolvePermissionValue } from './SettingsPaneHelpers'; import { PERMISSION_ROWS } from './types'; import type { SettingsPageProps, SettingsPaneId } from './types'; diff --git a/app/workbench/src/pages/tasks/TaskMainViews.tsx b/app/workbench/src/pages/tasks/TaskMainViews.tsx index d5ea297d9..f4873a5bd 100644 --- a/app/workbench/src/pages/tasks/TaskMainViews.tsx +++ b/app/workbench/src/pages/tasks/TaskMainViews.tsx @@ -15,7 +15,7 @@ import styles from '../TasksPage.module.css'; import { TaskSelectionStrip, TaskTable } from './TaskTableViews'; import { buildViewModes, paneTitle, StatCard } from './shared'; import type { TasksPageProps } from './types'; -import { needsHubOnlyMergeNotice } from '../../workbenchBoardColumns'; +import { needsHubOnlyMergeNotice } from '../../routes/workbenchBoardColumns'; export type TaskMainProps = Pick< TasksPageProps, diff --git a/app/workbench/src/pages/tasks/TaskReviewMerge.test.tsx b/app/workbench/src/pages/tasks/TaskReviewMerge.test.tsx index 9c22d62d3..ef1270ff8 100644 --- a/app/workbench/src/pages/tasks/TaskReviewMerge.test.tsx +++ b/app/workbench/src/pages/tasks/TaskReviewMerge.test.tsx @@ -4,7 +4,7 @@ import { fireEvent, render, screen, within } from '../../__tests__/setup'; import { useTestI18nLanguage } from '@shared/testing/i18n'; import { TaskMain } from './TaskMainViews'; import type { TasksPageProps, TaskGroup, TaskItem } from './types'; -import type { TaskReviewMergePort } from '../../workbenchBoardColumns'; +import type { TaskReviewMergePort } from '../../routes/workbenchBoardColumns'; /* ═══════════════════════════════════════════════════════════════════════ review-before-merge behavior (#1999): diff --git a/app/workbench/src/pages/tasks/TaskTableParts.tsx b/app/workbench/src/pages/tasks/TaskTableParts.tsx index ed216cdbe..44e326a07 100644 --- a/app/workbench/src/pages/tasks/TaskTableParts.tsx +++ b/app/workbench/src/pages/tasks/TaskTableParts.tsx @@ -28,7 +28,7 @@ import { resolveReviewMergeDecision, type BoardColumnTone, type TaskReviewMergePort, -} from '../../workbenchBoardColumns'; +} from '../../routes/workbenchBoardColumns'; /* ═══════════════════════════════════════════════════════════════════════ TaskTableParts — presentational parts for TaskTableViews diff --git a/app/workbench/src/pages/tasks/types.ts b/app/workbench/src/pages/tasks/types.ts index 05c35e368..5ff38a022 100644 --- a/app/workbench/src/pages/tasks/types.ts +++ b/app/workbench/src/pages/tasks/types.ts @@ -3,7 +3,7 @@ ═══════════════════════════════════════════════════════════════════════ */ import type { WorkbenchProfileSource } from '../../profileRegistry'; -import type { BoardColumnTone, TaskReviewMergePort } from '../../workbenchBoardColumns'; +import type { BoardColumnTone, TaskReviewMergePort } from '../../routes/workbenchBoardColumns'; import type { AgentHubSurface } from '@shared/platform'; export type TaskStatus = diff --git a/app/workbench/src/WorkbenchAgentsRouteView.tsx b/app/workbench/src/routes/WorkbenchAgentsRouteView.tsx similarity index 94% rename from app/workbench/src/WorkbenchAgentsRouteView.tsx rename to app/workbench/src/routes/WorkbenchAgentsRouteView.tsx index a9cf13f2f..311716986 100644 --- a/app/workbench/src/WorkbenchAgentsRouteView.tsx +++ b/app/workbench/src/routes/WorkbenchAgentsRouteView.tsx @@ -1,13 +1,13 @@ import React, { useMemo } from 'react'; import type { WorkbenchAgent } from '@shared/platform'; -import type { AgentConfig, SkillMarketItem, MCPMarketItem } from './pages/AgentsPage'; -import { AgentsPage } from './pages/AgentsPage'; +import type { AgentConfig, SkillMarketItem, MCPMarketItem } from '../pages/AgentsPage'; +import { AgentsPage } from '../pages/AgentsPage'; import { WORKBENCH_MOCK_AGENT_AUDIT_ROWS, WORKBENCH_MOCK_AGENT_MODEL_HEALTH, WORKBENCH_MOCK_AGENT_POLICY_RULES, WORKBENCH_MOCK_AGENT_TOOL_OPTIONS, -} from './mockData'; +} from '../mockData'; import type { WorkbenchAgentsRoute, WorkbenchAgentsRouteStatus, @@ -26,8 +26,8 @@ export interface WorkbenchAgentsRouteViewProps { mcpMarketItems?: MCPMarketItem[] | undefined; mcpMarketLoading?: boolean | undefined; mcpMarketError?: string | undefined; - ccSwitchStatus?: import('./pages/AgentsPage').CCSwitchStatusInfo | undefined; - ccSwitchProviders?: import('./pages/AgentsPage').CCSwitchProviderInfo[] | undefined; + ccSwitchStatus?: import('../pages/AgentsPage').CCSwitchStatusInfo | undefined; + ccSwitchProviders?: import('../pages/AgentsPage').CCSwitchProviderInfo[] | undefined; } /** Thin agents route shell: pure model + AgentsPage prop wiring. */ diff --git a/app/workbench/src/WorkbenchContactsRouteView.tsx b/app/workbench/src/routes/WorkbenchContactsRouteView.tsx similarity index 91% rename from app/workbench/src/WorkbenchContactsRouteView.tsx rename to app/workbench/src/routes/WorkbenchContactsRouteView.tsx index eb77c7264..1a20ee883 100644 --- a/app/workbench/src/WorkbenchContactsRouteView.tsx +++ b/app/workbench/src/routes/WorkbenchContactsRouteView.tsx @@ -1,5 +1,5 @@ import React, { useMemo } from 'react'; -import { ContactsPage } from './pages/ContactsPage'; +import { ContactsPage } from '../pages/ContactsPage'; import type { WorkbenchContactsRoute } from './useWorkbenchContactsRoute'; import { buildContactsPageProps } from './workbenchRoutesHelpers'; diff --git a/app/workbench/src/WorkbenchDevicesRouteView.test.tsx b/app/workbench/src/routes/WorkbenchDevicesRouteView.test.tsx similarity index 100% rename from app/workbench/src/WorkbenchDevicesRouteView.test.tsx rename to app/workbench/src/routes/WorkbenchDevicesRouteView.test.tsx diff --git a/app/workbench/src/WorkbenchDevicesRouteView.tsx b/app/workbench/src/routes/WorkbenchDevicesRouteView.tsx similarity index 91% rename from app/workbench/src/WorkbenchDevicesRouteView.tsx rename to app/workbench/src/routes/WorkbenchDevicesRouteView.tsx index 508378f32..bf8a41b12 100644 --- a/app/workbench/src/WorkbenchDevicesRouteView.tsx +++ b/app/workbench/src/routes/WorkbenchDevicesRouteView.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { DevicesPage } from './pages/DevicesPage'; -import type { DevicesPageTarget } from './pages/DevicesPage'; +import { DevicesPage } from '../pages/DevicesPage'; +import type { DevicesPageTarget } from '../pages/DevicesPage'; /* ═══════════════════════════════════════════════════════════════════════ WorkbenchDevicesRouteView — thin route shell for the Devices page (#1819). diff --git a/app/workbench/src/WorkbenchDocsRouteView.tsx b/app/workbench/src/routes/WorkbenchDocsRouteView.tsx similarity index 84% rename from app/workbench/src/WorkbenchDocsRouteView.tsx rename to app/workbench/src/routes/WorkbenchDocsRouteView.tsx index 0a3291350..85bbe32a5 100644 --- a/app/workbench/src/WorkbenchDocsRouteView.tsx +++ b/app/workbench/src/routes/WorkbenchDocsRouteView.tsx @@ -1,6 +1,6 @@ import React, { useMemo } from 'react'; -import type { WorkbenchProfileSource } from './profileRegistry'; -import { DocsPage } from './pages/DocsPage'; +import type { WorkbenchProfileSource } from '../profileRegistry'; +import { DocsPage } from '../pages/DocsPage'; import type { WorkbenchDocsRoute } from './useWorkbenchDocsRoute'; import { buildDocsPageProps } from './workbenchRoutesHelpers'; diff --git a/app/workbench/src/WorkbenchProjectsRouteView.tsx b/app/workbench/src/routes/WorkbenchProjectsRouteView.tsx similarity index 85% rename from app/workbench/src/WorkbenchProjectsRouteView.tsx rename to app/workbench/src/routes/WorkbenchProjectsRouteView.tsx index c394f37b2..b1ebec2fc 100644 --- a/app/workbench/src/WorkbenchProjectsRouteView.tsx +++ b/app/workbench/src/routes/WorkbenchProjectsRouteView.tsx @@ -1,6 +1,6 @@ import React, { useMemo } from 'react'; -import type { WorkbenchProfileSource } from './profileRegistry'; -import { ProjectsPage } from './pages/ProjectsPage'; +import type { WorkbenchProfileSource } from '../profileRegistry'; +import { ProjectsPage } from '../pages/ProjectsPage'; import type { WorkbenchProjectsRoute } from './useWorkbenchProjectsRoute'; import { buildProjectsPageProps } from './workbenchRoutesHelpers'; diff --git a/app/workbench/src/WorkbenchSettingsRouteView.tsx b/app/workbench/src/routes/WorkbenchSettingsRouteView.tsx similarity index 96% rename from app/workbench/src/WorkbenchSettingsRouteView.tsx rename to app/workbench/src/routes/WorkbenchSettingsRouteView.tsx index 670cc03b7..09f5fa217 100644 --- a/app/workbench/src/WorkbenchSettingsRouteView.tsx +++ b/app/workbench/src/routes/WorkbenchSettingsRouteView.tsx @@ -1,6 +1,6 @@ import React, { useMemo } from 'react'; import type { LocalCliDiscoveryManifest, RuntimeSessionSummary } from '@shared/platform'; -import { SettingsPage } from './pages/SettingsPage'; +import { SettingsPage } from '../pages/SettingsPage'; import type { WorkbenchSettingsRoute } from './useWorkbenchSettingsRoute'; import { buildSettingsPageProps } from './workbenchRoutesHelpers'; diff --git a/app/workbench/src/WorkbenchTasksRouteView.test.tsx b/app/workbench/src/routes/WorkbenchTasksRouteView.test.tsx similarity index 97% rename from app/workbench/src/WorkbenchTasksRouteView.test.tsx rename to app/workbench/src/routes/WorkbenchTasksRouteView.test.tsx index 6d59e7479..bf1554f8b 100644 --- a/app/workbench/src/WorkbenchTasksRouteView.test.tsx +++ b/app/workbench/src/routes/WorkbenchTasksRouteView.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'; -import { fireEvent, render, screen } from './__tests__/setup'; -import type { TaskItem } from './pages'; +import { fireEvent, render, screen } from '../__tests__/setup'; +import type { TaskItem } from '../pages/index'; import type { WorkbenchTasksRoute } from './useWorkbenchTasksRoute'; import { WorkbenchTasksRouteView } from './WorkbenchTasksRouteView'; import { diff --git a/app/workbench/src/WorkbenchTasksRouteView.tsx b/app/workbench/src/routes/WorkbenchTasksRouteView.tsx similarity index 96% rename from app/workbench/src/WorkbenchTasksRouteView.tsx rename to app/workbench/src/routes/WorkbenchTasksRouteView.tsx index ed92fa0a6..c9076ab7a 100644 --- a/app/workbench/src/WorkbenchTasksRouteView.tsx +++ b/app/workbench/src/routes/WorkbenchTasksRouteView.tsx @@ -2,9 +2,9 @@ import React, { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { CHATVIEW_I18N_NAMESPACE } from '@shared/chatview/i18n/resources'; import { SHARED_WORKBENCH_I18N_NAMESPACE } from '@shared/i18n'; -import type { WorkbenchProfileSource } from './profileRegistry'; -import { DesignNavIcon } from './designIcons'; -import { TasksPage } from './pages/TasksPage'; +import type { WorkbenchProfileSource } from '../profileRegistry'; +import { DesignNavIcon } from '../designIcons'; +import { TasksPage } from '../pages/TasksPage'; import type { WorkbenchTasksRoute } from './useWorkbenchTasksRoute'; import { buildTasksPageDerivedModel } from './workbenchTasksPageModel'; import type { TaskReviewMergePort } from './workbenchBoardColumns'; @@ -13,7 +13,7 @@ import { useWorkbenchTaskDeepLinkActions, useWorkbenchTaskDeepLinkSnapshot, } from './workbenchTaskDeepLinks'; -import styles from './AgentHubWorkbench.module.css'; +import styles from '../AgentHubWorkbench.module.css'; export interface WorkbenchTasksRouteViewProps { tasksRoute: WorkbenchTasksRoute; diff --git a/app/workbench/src/WorkbenchUsageRouteView.test.tsx b/app/workbench/src/routes/WorkbenchUsageRouteView.test.tsx similarity index 100% rename from app/workbench/src/WorkbenchUsageRouteView.test.tsx rename to app/workbench/src/routes/WorkbenchUsageRouteView.test.tsx diff --git a/app/workbench/src/WorkbenchUsageRouteView.tsx b/app/workbench/src/routes/WorkbenchUsageRouteView.tsx similarity index 89% rename from app/workbench/src/WorkbenchUsageRouteView.tsx rename to app/workbench/src/routes/WorkbenchUsageRouteView.tsx index 929e4e1c4..1fcd6ac7c 100644 --- a/app/workbench/src/WorkbenchUsageRouteView.tsx +++ b/app/workbench/src/routes/WorkbenchUsageRouteView.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { TokenUsagePage } from './pages/TokenUsagePage'; -import type { TokenUsagePageTeam } from './pages/TokenUsagePage'; +import { TokenUsagePage } from '../pages/TokenUsagePage'; +import type { TokenUsagePageTeam } from '../pages/TokenUsagePage'; /* ═══════════════════════════════════════════════════════════════════════ WorkbenchUsageRouteView — thin route shell for the Token usage board (#1819). diff --git a/app/workbench/src/useWorkbenchAgentsRoute.test.ts b/app/workbench/src/routes/useWorkbenchAgentsRoute.test.ts similarity index 99% rename from app/workbench/src/useWorkbenchAgentsRoute.test.ts rename to app/workbench/src/routes/useWorkbenchAgentsRoute.test.ts index 1503ef0a7..fe50bacf8 100644 --- a/app/workbench/src/useWorkbenchAgentsRoute.test.ts +++ b/app/workbench/src/routes/useWorkbenchAgentsRoute.test.ts @@ -8,7 +8,7 @@ import { WORKBENCH_MOCK_AGENT_MODELS, WORKBENCH_MOCK_AGENT_SKILL_OPTIONS, WORKBENCH_MOCK_AGENT_TOOL_OPTIONS, -} from './mockData'; +} from '../mockData'; import { useWorkbenchAgentsRoute, type UseWorkbenchAgentsRouteOptions, diff --git a/app/workbench/src/useWorkbenchAgentsRoute.ts b/app/workbench/src/routes/useWorkbenchAgentsRoute.ts similarity index 98% rename from app/workbench/src/useWorkbenchAgentsRoute.ts rename to app/workbench/src/routes/useWorkbenchAgentsRoute.ts index f9a49703b..145bbcf69 100644 --- a/app/workbench/src/useWorkbenchAgentsRoute.ts +++ b/app/workbench/src/routes/useWorkbenchAgentsRoute.ts @@ -1,7 +1,7 @@ import { useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { SHARED_WORKBENCH_I18N_NAMESPACE } from '@shared/i18n'; -import type { AgentsPaneId, AgentConfig } from './pages/AgentsPage'; +import type { AgentsPaneId, AgentConfig } from '../pages/AgentsPage'; import { buildWorkbenchAgentsRouteHandlers, isAgentBusyWith, diff --git a/app/workbench/src/useWorkbenchContactsRoute.test.ts b/app/workbench/src/routes/useWorkbenchContactsRoute.test.ts similarity index 99% rename from app/workbench/src/useWorkbenchContactsRoute.test.ts rename to app/workbench/src/routes/useWorkbenchContactsRoute.test.ts index 5b0b852c3..57a237595 100644 --- a/app/workbench/src/useWorkbenchContactsRoute.test.ts +++ b/app/workbench/src/routes/useWorkbenchContactsRoute.test.ts @@ -3,7 +3,7 @@ import { describe, expect, it } from 'vitest'; import { WORKBENCH_MOCK_CONTACT_MEMBER_POOL, WORKBENCH_MOCK_PAGE_SIZE, -} from './mockData'; +} from '../mockData'; import { useWorkbenchContactsRoute } from './useWorkbenchContactsRoute'; describe('useWorkbenchContactsRoute mock cursor pagination ', () => { diff --git a/app/workbench/src/useWorkbenchContactsRoute.ts b/app/workbench/src/routes/useWorkbenchContactsRoute.ts similarity index 99% rename from app/workbench/src/useWorkbenchContactsRoute.ts rename to app/workbench/src/routes/useWorkbenchContactsRoute.ts index fa90ee9a0..51ac92639 100644 --- a/app/workbench/src/useWorkbenchContactsRoute.ts +++ b/app/workbench/src/routes/useWorkbenchContactsRoute.ts @@ -4,7 +4,7 @@ import type { ContactGroup, ContactMember, ServiceDesk, -} from './pages'; +} from '../pages/index'; import { WORKBENCH_MOCK_CONTACT_GROUPS, WORKBENCH_MOCK_CONTACT_MEMBER_POOL, @@ -15,7 +15,7 @@ import { WORKBENCH_MOCK_PENDING_CONTACTS, WORKBENCH_MOCK_SERVICE_DESKS, readMockCursorPage, -} from './mockData'; +} from '../mockData'; /** Contact mutation callbacks wired to Hub API. */ export interface WorkbenchContactsActions { diff --git a/app/workbench/src/useWorkbenchDocsRoute.test.ts b/app/workbench/src/routes/useWorkbenchDocsRoute.test.ts similarity index 98% rename from app/workbench/src/useWorkbenchDocsRoute.test.ts rename to app/workbench/src/routes/useWorkbenchDocsRoute.test.ts index c68b602a9..6fc6c771f 100644 --- a/app/workbench/src/useWorkbenchDocsRoute.test.ts +++ b/app/workbench/src/routes/useWorkbenchDocsRoute.test.ts @@ -1,8 +1,8 @@ // real_tested=true import { act, renderHook } from '@testing-library/react'; import { describe, expect, it, vi } from 'vitest'; -import type { DocRow } from './pages'; -import { WORKBENCH_MOCK_DOC_ROWS, WORKBENCH_MOCK_DOC_SHORTCUTS } from './mockData'; +import type { DocRow } from '../pages/index'; +import { WORKBENCH_MOCK_DOC_ROWS, WORKBENCH_MOCK_DOC_SHORTCUTS } from '../mockData'; import { useWorkbenchDocsRoute } from './useWorkbenchDocsRoute'; /* ═══════════════════════════════════════════════════════════════════════ diff --git a/app/workbench/src/useWorkbenchDocsRoute.ts b/app/workbench/src/routes/useWorkbenchDocsRoute.ts similarity index 95% rename from app/workbench/src/useWorkbenchDocsRoute.ts rename to app/workbench/src/routes/useWorkbenchDocsRoute.ts index a8e06312c..8b68b6bd6 100644 --- a/app/workbench/src/useWorkbenchDocsRoute.ts +++ b/app/workbench/src/routes/useWorkbenchDocsRoute.ts @@ -1,7 +1,7 @@ import { useState } from 'react'; -import type { DocRow, DocsPane } from './pages'; -import type { WorkbenchDocumentPreview } from './documentPreview'; -import { WORKBENCH_MOCK_DOC_ROWS, WORKBENCH_MOCK_DOC_SHORTCUTS } from './mockData'; +import type { DocRow, DocsPane } from '../pages/index'; +import type { WorkbenchDocumentPreview } from '../documentPreview'; +import { WORKBENCH_MOCK_DOC_ROWS, WORKBENCH_MOCK_DOC_SHORTCUTS } from '../mockData'; import { createDocPreview } from './workbenchDocPreview'; /** Document mutation callbacks wired to Hub Documents API. */ diff --git a/app/workbench/src/useWorkbenchProjectsRoute.test.ts b/app/workbench/src/routes/useWorkbenchProjectsRoute.test.ts similarity index 98% rename from app/workbench/src/useWorkbenchProjectsRoute.test.ts rename to app/workbench/src/routes/useWorkbenchProjectsRoute.test.ts index ae33bd9ff..2b4cd9040 100644 --- a/app/workbench/src/useWorkbenchProjectsRoute.test.ts +++ b/app/workbench/src/routes/useWorkbenchProjectsRoute.test.ts @@ -1,6 +1,6 @@ import { renderHook } from '@testing-library/react'; import { describe, expect, it } from 'vitest'; -import type { ProjectDraft, ProjectInfo } from './pages'; +import type { ProjectDraft, ProjectInfo } from '../pages/index'; import { useWorkbenchProjectsRoute, type WorkbenchProjectsStatus, diff --git a/app/workbench/src/useWorkbenchProjectsRoute.ts b/app/workbench/src/routes/useWorkbenchProjectsRoute.ts similarity index 96% rename from app/workbench/src/useWorkbenchProjectsRoute.ts rename to app/workbench/src/routes/useWorkbenchProjectsRoute.ts index 423277df0..2bf9ad5fe 100644 --- a/app/workbench/src/useWorkbenchProjectsRoute.ts +++ b/app/workbench/src/routes/useWorkbenchProjectsRoute.ts @@ -4,9 +4,9 @@ import type { ProjectDraft, ProjectInfo, ProjectTab, -} from './pages'; -import { WORKBENCH_MOCK_PROJECTS } from './mockData'; -import type { WorkbenchDocumentPreview } from './documentPreview'; +} from '../pages/index'; +import { WORKBENCH_MOCK_PROJECTS } from '../mockData'; +import type { WorkbenchDocumentPreview } from '../documentPreview'; import { createProjectArtifactPreview } from './workbenchProjectPreview'; export interface WorkbenchProjectsStatus { diff --git a/app/workbench/src/useWorkbenchSettingsRoute.test.ts b/app/workbench/src/routes/useWorkbenchSettingsRoute.test.ts similarity index 98% rename from app/workbench/src/useWorkbenchSettingsRoute.test.ts rename to app/workbench/src/routes/useWorkbenchSettingsRoute.test.ts index c37c9919b..7a52050b7 100644 --- a/app/workbench/src/useWorkbenchSettingsRoute.test.ts +++ b/app/workbench/src/routes/useWorkbenchSettingsRoute.test.ts @@ -2,9 +2,9 @@ import { act, renderHook } from '@testing-library/react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import type { SettingsPort } from '@shared/platform/types'; -import { WORKBENCH_MOCK_SETTINGS_DEFAULTS } from './mockData'; -import { createSettingsService } from './settingsService'; -import type { SettingsService } from './settingsService'; +import { WORKBENCH_MOCK_SETTINGS_DEFAULTS } from '../mockData'; +import { createSettingsService } from '../settingsService'; +import type { SettingsService } from '../settingsService'; import { createSettingsDefaults, useWorkbenchSettingsRoute, @@ -12,7 +12,7 @@ import { import { WORKBENCH_COMPOSER_SUBMIT_BEHAVIOR_KEY, readComposerSubmitBehavior, -} from './workbenchPreferences'; +} from '../workbenchPreferences'; /** * Controllable SettingsService double: same surface as the real service but diff --git a/app/workbench/src/useWorkbenchSettingsRoute.ts b/app/workbench/src/routes/useWorkbenchSettingsRoute.ts similarity index 96% rename from app/workbench/src/useWorkbenchSettingsRoute.ts rename to app/workbench/src/routes/useWorkbenchSettingsRoute.ts index 7bf8f5296..7a1328e45 100644 --- a/app/workbench/src/useWorkbenchSettingsRoute.ts +++ b/app/workbench/src/routes/useWorkbenchSettingsRoute.ts @@ -5,10 +5,10 @@ import { composerSubmitBehaviorLabel, readComposerSubmitBehavior, writeComposerSubmitBehavior, -} from './workbenchPreferences'; -import { WORKBENCH_MOCK_SETTINGS_DEFAULTS } from './mockData'; -import type { SettingsService } from './settingsService'; -import type { SettingsPaneId } from './pages'; +} from '../workbenchPreferences'; +import { WORKBENCH_MOCK_SETTINGS_DEFAULTS } from '../mockData'; +import type { SettingsService } from '../settingsService'; +import type { SettingsPaneId } from '../pages/index'; export type WorkbenchSettingsValues = typeof WORKBENCH_MOCK_SETTINGS_DEFAULTS; export type WorkbenchSettingsErrorKind = 'init' | 'write'; diff --git a/app/workbench/src/useWorkbenchTasksRoute.test.ts b/app/workbench/src/routes/useWorkbenchTasksRoute.test.ts similarity index 99% rename from app/workbench/src/useWorkbenchTasksRoute.test.ts rename to app/workbench/src/routes/useWorkbenchTasksRoute.test.ts index 0e4cd4f43..cda90bb92 100644 --- a/app/workbench/src/useWorkbenchTasksRoute.test.ts +++ b/app/workbench/src/routes/useWorkbenchTasksRoute.test.ts @@ -3,7 +3,7 @@ import { beforeEach, beforeAll, describe, expect, it } from 'vitest'; import { WORKBENCH_MOCK_PAGE_SIZE, WORKBENCH_MOCK_TASK_POOL, -} from './mockData'; +} from '../mockData'; import { flattenTaskGroups } from './workbenchTaskGroups'; import { useWorkbenchTasksRoute } from './useWorkbenchTasksRoute'; import { useTestI18nLanguage } from '@shared/testing/i18n'; diff --git a/app/workbench/src/useWorkbenchTasksRoute.ts b/app/workbench/src/routes/useWorkbenchTasksRoute.ts similarity index 98% rename from app/workbench/src/useWorkbenchTasksRoute.ts rename to app/workbench/src/routes/useWorkbenchTasksRoute.ts index f235bd86d..ec9a44004 100644 --- a/app/workbench/src/useWorkbenchTasksRoute.ts +++ b/app/workbench/src/routes/useWorkbenchTasksRoute.ts @@ -1,13 +1,13 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { SHARED_WORKBENCH_I18N_NAMESPACE } from '@shared/i18n'; -import type { TaskGroup, TaskItem, TasksPane, ViewMode } from './pages'; -import type { TaskEditDraft } from './pages/TasksPage'; +import type { TaskGroup, TaskItem, TasksPane, ViewMode } from '../pages/index'; +import type { TaskEditDraft } from '../pages/TasksPage'; import { WORKBENCH_MOCK_PAGE_SIZE, WORKBENCH_MOCK_TASK_POOL, readMockCursorPage, -} from './mockData'; +} from '../mockData'; import { type TaskGroupMode, type TaskSortMode, diff --git a/app/workbench/src/workbenchAgentsPageModel.test.ts b/app/workbench/src/routes/workbenchAgentsPageModel.test.ts similarity index 98% rename from app/workbench/src/workbenchAgentsPageModel.test.ts rename to app/workbench/src/routes/workbenchAgentsPageModel.test.ts index f110f8572..b9ed9c85c 100644 --- a/app/workbench/src/workbenchAgentsPageModel.test.ts +++ b/app/workbench/src/routes/workbenchAgentsPageModel.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import type { AgentConfig } from './pages/AgentsPage'; +import type { AgentConfig } from '../pages/AgentsPage'; import { buildAgentRecentShortcuts, buildAgentsPageDerivedModel, diff --git a/app/workbench/src/workbenchAgentsPageModel.ts b/app/workbench/src/routes/workbenchAgentsPageModel.ts similarity index 97% rename from app/workbench/src/workbenchAgentsPageModel.ts rename to app/workbench/src/routes/workbenchAgentsPageModel.ts index 77770745e..4f4932005 100644 --- a/app/workbench/src/workbenchAgentsPageModel.ts +++ b/app/workbench/src/routes/workbenchAgentsPageModel.ts @@ -3,11 +3,11 @@ import type { MarketTemplate, ModelRoute, ToolMatrixAgent, -} from './pages/AgentsPage'; +} from '../pages/AgentsPage'; import { WORKBENCH_MOCK_AGENT_MARKET_TEMPLATES, -} from './mockData'; -import { workbenchAgentColor, workbenchProfileInitials } from './profileRegistry'; +} from '../mockData'; +import { workbenchAgentColor, workbenchProfileInitials } from '../profileRegistry'; export interface AgentsPageDerivedModel { confirmCount: number; diff --git a/app/workbench/src/workbenchAgentsRouteHelpers.test.ts b/app/workbench/src/routes/workbenchAgentsRouteHelpers.test.ts similarity index 99% rename from app/workbench/src/workbenchAgentsRouteHelpers.test.ts rename to app/workbench/src/routes/workbenchAgentsRouteHelpers.test.ts index 3ec44d008..3a806f3fb 100644 --- a/app/workbench/src/workbenchAgentsRouteHelpers.test.ts +++ b/app/workbench/src/routes/workbenchAgentsRouteHelpers.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from 'vitest'; import { SHARED_WORKBENCH_I18N_NAMESPACE } from '@shared/i18n'; import { createTestI18n } from '@shared/testing/i18n'; -import type { AgentConfig } from './pages/AgentsPage'; +import type { AgentConfig } from '../pages/AgentsPage'; import { buildAgentFieldPatch, buildWorkbenchAgentsRouteHandlers, @@ -292,7 +292,7 @@ describe('workbenchAgentsRouteHelpers', () => { }); it('builds route handlers that apply add/save/delete plans to state setters', async () => { - let agentsPane: import('./pages/AgentsPage').AgentsPaneId = 'market'; + let agentsPane: import('../pages/AgentsPage').AgentsPaneId = 'market'; let selectedAgentId: string | undefined = 'a1'; let agentDrafts: Record = {}; let draftAgentIds: string[] = []; diff --git a/app/workbench/src/workbenchAgentsRouteHelpers.ts b/app/workbench/src/routes/workbenchAgentsRouteHelpers.ts similarity index 99% rename from app/workbench/src/workbenchAgentsRouteHelpers.ts rename to app/workbench/src/routes/workbenchAgentsRouteHelpers.ts index a3dc9a8f3..331440bb3 100644 --- a/app/workbench/src/workbenchAgentsRouteHelpers.ts +++ b/app/workbench/src/routes/workbenchAgentsRouteHelpers.ts @@ -1,17 +1,17 @@ import type { TFunction } from 'i18next'; import type { WorkbenchAgent } from '@shared/platform'; -import type { AgentConfig, AgentsPaneId, ModelInfo, ModelState, ToolPermission } from './pages/AgentsPage'; +import type { AgentConfig, AgentsPaneId, ModelInfo, ModelState, ToolPermission } from '../pages/AgentsPage'; import { WORKBENCH_MOCK_AGENT_CONFIGS, WORKBENCH_MOCK_AGENT_MODELS, WORKBENCH_MOCK_AGENT_SKILL_OPTIONS, WORKBENCH_MOCK_AGENT_TOOL_OPTIONS, -} from './mockData'; +} from '../mockData'; import { createMarketInstalledAgent, workbenchAgentToAgentConfig, -} from './workbenchAgentMapping'; -import { uniqueSorted } from './agentProfileCatalogHelpers'; +} from '../workbenchAgentMapping'; +import { uniqueSorted } from '../agentProfileCatalogHelpers'; /* ═══════════════════════════════════════════════════════════════════════ workbenchAgentsRouteHelpers — pure helpers for diff --git a/app/workbench/src/workbenchBoardColumns.test.ts b/app/workbench/src/routes/workbenchBoardColumns.test.ts similarity index 100% rename from app/workbench/src/workbenchBoardColumns.test.ts rename to app/workbench/src/routes/workbenchBoardColumns.test.ts diff --git a/app/workbench/src/workbenchBoardColumns.ts b/app/workbench/src/routes/workbenchBoardColumns.ts similarity index 99% rename from app/workbench/src/workbenchBoardColumns.ts rename to app/workbench/src/routes/workbenchBoardColumns.ts index 7fbf6ac0c..2446633b1 100644 --- a/app/workbench/src/workbenchBoardColumns.ts +++ b/app/workbench/src/routes/workbenchBoardColumns.ts @@ -17,7 +17,7 @@ ═══════════════════════════════════════════════════════════════════════ */ import type { AgentHubSurface } from '@shared/platform'; -import type { TaskStatus } from './pages'; +import type { TaskStatus } from '../pages/index'; export type BoardColumnTone = 'idle' | 'running' | 'review' | 'confirm' | 'done'; diff --git a/app/workbench/src/workbenchDocPreview.test.ts b/app/workbench/src/routes/workbenchDocPreview.test.ts similarity index 96% rename from app/workbench/src/workbenchDocPreview.test.ts rename to app/workbench/src/routes/workbenchDocPreview.test.ts index 54ec93fcb..c58309e82 100644 --- a/app/workbench/src/workbenchDocPreview.test.ts +++ b/app/workbench/src/routes/workbenchDocPreview.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import type { DocRow } from './pages'; +import type { DocRow } from '../pages/index'; import { createDocPreview } from './workbenchDocPreview'; function doc(overrides: Partial = {}): DocRow { diff --git a/app/workbench/src/workbenchDocPreview.ts b/app/workbench/src/routes/workbenchDocPreview.ts similarity index 93% rename from app/workbench/src/workbenchDocPreview.ts rename to app/workbench/src/routes/workbenchDocPreview.ts index 49aa025d7..3ab92662b 100644 --- a/app/workbench/src/workbenchDocPreview.ts +++ b/app/workbench/src/routes/workbenchDocPreview.ts @@ -2,8 +2,8 @@ import { fileTypeFromPreviewName, previewFilenameFromTitle, type WorkbenchDocumentPreview, -} from './documentPreview'; -import type { DocRow } from './pages'; +} from '../documentPreview'; +import type { DocRow } from '../pages/index'; export function createDocPreview(doc: DocRow): WorkbenchDocumentPreview { const filename = previewFilenameFromTitle(doc.title); diff --git a/app/workbench/src/workbenchProjectPreview.test.ts b/app/workbench/src/routes/workbenchProjectPreview.test.ts similarity index 97% rename from app/workbench/src/workbenchProjectPreview.test.ts rename to app/workbench/src/routes/workbenchProjectPreview.test.ts index 62575fe1c..634f1979f 100644 --- a/app/workbench/src/workbenchProjectPreview.test.ts +++ b/app/workbench/src/routes/workbenchProjectPreview.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import type { ProjectArtifact } from './pages'; +import type { ProjectArtifact } from '../pages/index'; import { createProjectArtifactPreview, projectArtifactContent, diff --git a/app/workbench/src/workbenchProjectPreview.ts b/app/workbench/src/routes/workbenchProjectPreview.ts similarity index 96% rename from app/workbench/src/workbenchProjectPreview.ts rename to app/workbench/src/routes/workbenchProjectPreview.ts index 9e57311fb..8cad6bf44 100644 --- a/app/workbench/src/workbenchProjectPreview.ts +++ b/app/workbench/src/routes/workbenchProjectPreview.ts @@ -1,8 +1,8 @@ import { fileTypeFromPreviewName, type WorkbenchDocumentPreview, -} from './documentPreview'; -import type { ProjectArtifact } from './pages'; +} from '../documentPreview'; +import type { ProjectArtifact } from '../pages/index'; export function createProjectArtifactPreview( projectId: string, diff --git a/app/workbench/src/workbenchRoutesHelpers.test.ts b/app/workbench/src/routes/workbenchRoutesHelpers.test.ts similarity index 100% rename from app/workbench/src/workbenchRoutesHelpers.test.ts rename to app/workbench/src/routes/workbenchRoutesHelpers.test.ts diff --git a/app/workbench/src/workbenchRoutesHelpers.ts b/app/workbench/src/routes/workbenchRoutesHelpers.ts similarity index 95% rename from app/workbench/src/workbenchRoutesHelpers.ts rename to app/workbench/src/routes/workbenchRoutesHelpers.ts index ca7288a00..b504d8139 100644 --- a/app/workbench/src/workbenchRoutesHelpers.ts +++ b/app/workbench/src/routes/workbenchRoutesHelpers.ts @@ -1,10 +1,10 @@ import type { LocalCliDiscoveryManifest, RuntimeSessionSummary } from '@shared/platform'; -import type { ContactsPageProps } from './pages/ContactsPage'; -import type { DocsPageProps } from './pages/DocsPage'; -import type { ProjectsPageProps } from './pages/ProjectsPage'; -import type { SettingsPageProps } from './pages/SettingsPage'; -import type { WorkbenchProfileSource } from './profileRegistry'; -import { hubEmptyContacts } from './hubDataMapping'; +import type { ContactsPageProps } from '../pages/ContactsPage'; +import type { DocsPageProps } from '../pages/DocsPage'; +import type { ProjectsPageProps } from '../pages/ProjectsPage'; +import type { SettingsPageProps } from '../pages/SettingsPage'; +import type { WorkbenchProfileSource } from '../profileRegistry'; +import { hubEmptyContacts } from '../hubDataMapping'; import type { WorkbenchContactsRoute } from './useWorkbenchContactsRoute'; import type { WorkbenchDocsRoute } from './useWorkbenchDocsRoute'; import type { WorkbenchProjectsRoute } from './useWorkbenchProjectsRoute'; diff --git a/app/workbench/src/workbenchRoutesTypes.ts b/app/workbench/src/routes/workbenchRoutesTypes.ts similarity index 92% rename from app/workbench/src/workbenchRoutesTypes.ts rename to app/workbench/src/routes/workbenchRoutesTypes.ts index bb892b1ff..86b9fe49d 100644 --- a/app/workbench/src/workbenchRoutesTypes.ts +++ b/app/workbench/src/routes/workbenchRoutesTypes.ts @@ -3,10 +3,10 @@ import type { DocRow, ProjectDraft, ProjectInfo, -} from './pages'; -import type { AgentConfig, SkillMarketItem, MCPMarketItem } from './pages/AgentsPage'; -import type { GlobalRailPage } from './GlobalRail'; -import type { SettingsService } from './settingsService'; +} from '../pages/index'; +import type { AgentConfig, SkillMarketItem, MCPMarketItem } from '../pages/AgentsPage'; +import type { GlobalRailPage } from '../GlobalRail'; +import type { SettingsService } from '../settingsService'; import type { WorkbenchContactsActions, WorkbenchContactsData, @@ -80,9 +80,9 @@ export interface WorkbenchRoutesProps { tags?: string[]; }> | undefined; /** cc-switch transparent proxy status from Edge API. */ - ccSwitchStatus?: import('./pages/AgentsPage').CCSwitchStatusInfo | undefined; + ccSwitchStatus?: import('../pages/AgentsPage').CCSwitchStatusInfo | undefined; /** cc-switch provider model alias mappings. */ - ccSwitchProviders?: import('./pages/AgentsPage').CCSwitchProviderInfo[] | undefined; + ccSwitchProviders?: import('../pages/AgentsPage').CCSwitchProviderInfo[] | undefined; /** Settings service for persistent user preferences. When provided, * settings are read from / written to the backend adapter. */ settingsService?: SettingsService | null | undefined; @@ -113,7 +113,7 @@ export interface WorkbenchRoutesProps { userDisplayName?: string | undefined; /* ── Devices / execution-target management (#1819) ── */ /** Registered execution targets; undefined = shell not Hub-connected. */ - devicesTargets?: import('./pages/DevicesPage').DevicesPageTarget[] | undefined; + devicesTargets?: import('../pages/DevicesPage').DevicesPageTarget[] | undefined; devicesLoading?: boolean | undefined; devicesError?: string | null | undefined; onDevicesRetry?: (() => void) | undefined; @@ -122,7 +122,7 @@ export interface WorkbenchRoutesProps { onDevicePing?: ((targetId: string) => void) | undefined; /* ── Token / cost usage board (#1819) ── */ /** Per-team runs with recorded token counters; undefined = not Hub-connected. */ - usageTeams?: import('./pages/TokenUsagePage').TokenUsagePageTeam[] | undefined; + usageTeams?: import('../pages/TokenUsagePage').TokenUsagePageTeam[] | undefined; usageLoading?: boolean | undefined; usageError?: string | null | undefined; onUsageRetry?: (() => void) | undefined; diff --git a/app/workbench/src/workbenchTaskDeepLinks.lifecycle.test.tsx b/app/workbench/src/routes/workbenchTaskDeepLinks.lifecycle.test.tsx similarity index 97% rename from app/workbench/src/workbenchTaskDeepLinks.lifecycle.test.tsx rename to app/workbench/src/routes/workbenchTaskDeepLinks.lifecycle.test.tsx index 0e6f92e85..7c1ab3026 100644 --- a/app/workbench/src/workbenchTaskDeepLinks.lifecycle.test.tsx +++ b/app/workbench/src/routes/workbenchTaskDeepLinks.lifecycle.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; import { describe, expect, it } from 'vitest'; -import type { TaskItem } from './pages'; +import type { TaskItem } from '../pages/index'; import { WorkbenchTaskDeepLinkProvider, useWorkbenchTaskDeepLinkSnapshot, diff --git a/app/workbench/src/workbenchTaskDeepLinks.test.ts b/app/workbench/src/routes/workbenchTaskDeepLinks.test.ts similarity index 99% rename from app/workbench/src/workbenchTaskDeepLinks.test.ts rename to app/workbench/src/routes/workbenchTaskDeepLinks.test.ts index 87ffa58d9..ee1920e0b 100644 --- a/app/workbench/src/workbenchTaskDeepLinks.test.ts +++ b/app/workbench/src/routes/workbenchTaskDeepLinks.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import type { TaskItem } from './pages'; +import type { TaskItem } from '../pages/index'; import { backFromTaskDeepLink, consumeWorkbenchTaskDeepLinkIntent, diff --git a/app/workbench/src/workbenchTaskDeepLinks.ts b/app/workbench/src/routes/workbenchTaskDeepLinks.ts similarity index 99% rename from app/workbench/src/workbenchTaskDeepLinks.ts rename to app/workbench/src/routes/workbenchTaskDeepLinks.ts index c1bc77283..6c62b00cc 100644 --- a/app/workbench/src/workbenchTaskDeepLinks.ts +++ b/app/workbench/src/routes/workbenchTaskDeepLinks.ts @@ -8,7 +8,7 @@ import { type ReactElement, type ReactNode, } from 'react'; -import type { TaskItem, TaskStatus } from './pages'; +import type { TaskItem, TaskStatus } from '../pages/index'; /* Task ↔ conversation deep links (#1963). * diff --git a/app/workbench/src/workbenchTaskGroups.test.ts b/app/workbench/src/routes/workbenchTaskGroups.test.ts similarity index 97% rename from app/workbench/src/workbenchTaskGroups.test.ts rename to app/workbench/src/routes/workbenchTaskGroups.test.ts index ec2a76444..b7a8b0431 100644 --- a/app/workbench/src/workbenchTaskGroups.test.ts +++ b/app/workbench/src/routes/workbenchTaskGroups.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import type { TaskGroup, TaskItem } from './pages'; +import type { TaskGroup, TaskItem } from '../pages/index'; import { boardColumnDisplayLabels } from './workbenchBoardColumns'; import { DESIGN_DONE_TASK, diff --git a/app/workbench/src/workbenchTaskGroups.ts b/app/workbench/src/routes/workbenchTaskGroups.ts similarity index 99% rename from app/workbench/src/workbenchTaskGroups.ts rename to app/workbench/src/routes/workbenchTaskGroups.ts index f75786312..23671e514 100644 --- a/app/workbench/src/workbenchTaskGroups.ts +++ b/app/workbench/src/routes/workbenchTaskGroups.ts @@ -1,4 +1,4 @@ -import type { TaskGroup, TaskItem, TasksPane, ViewMode } from './pages'; +import type { TaskGroup, TaskItem, TasksPane, ViewMode } from '../pages/index'; import { BOARD_COLUMNS_IN_DISPLAY_ORDER, TASK_STATUS_SEQUENCE, diff --git a/app/workbench/src/workbenchTasksPageModel.test.ts b/app/workbench/src/routes/workbenchTasksPageModel.test.ts similarity index 98% rename from app/workbench/src/workbenchTasksPageModel.test.ts rename to app/workbench/src/routes/workbenchTasksPageModel.test.ts index 06b86b269..7cd7b4809 100644 --- a/app/workbench/src/workbenchTasksPageModel.test.ts +++ b/app/workbench/src/routes/workbenchTasksPageModel.test.ts @@ -2,7 +2,7 @@ import { beforeAll, describe, expect, it } from 'vitest'; import { getI18n } from 'react-i18next'; import { SHARED_WORKBENCH_I18N_NAMESPACE } from '@shared/i18n'; import { useTestI18nLanguage } from '@shared/testing/i18n'; -import type { TaskItem } from './pages'; +import type { TaskItem } from '../pages/index'; import { buildTaskFieldConfigLabel, buildTaskGroupLabel, diff --git a/app/workbench/src/workbenchTasksPageModel.ts b/app/workbench/src/routes/workbenchTasksPageModel.ts similarity index 98% rename from app/workbench/src/workbenchTasksPageModel.ts rename to app/workbench/src/routes/workbenchTasksPageModel.ts index 6e2ff3ec5..456726e97 100644 --- a/app/workbench/src/workbenchTasksPageModel.ts +++ b/app/workbench/src/routes/workbenchTasksPageModel.ts @@ -1,5 +1,5 @@ import type { TFunction } from 'i18next'; -import type { TaskItem, ViewMode } from './pages'; +import type { TaskItem, ViewMode } from '../pages/index'; import type { TaskGroupMode, TaskSortMode } from './workbenchTaskGroups'; export interface TasksPageDerivedModel { diff --git a/app/workbench/src/workbenchTasksRouteGroupHelpers.test.ts b/app/workbench/src/routes/workbenchTasksRouteGroupHelpers.test.ts similarity index 98% rename from app/workbench/src/workbenchTasksRouteGroupHelpers.test.ts rename to app/workbench/src/routes/workbenchTasksRouteGroupHelpers.test.ts index 795024739..cf0f976c6 100644 --- a/app/workbench/src/workbenchTasksRouteGroupHelpers.test.ts +++ b/app/workbench/src/routes/workbenchTasksRouteGroupHelpers.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest'; import { SHARED_WORKBENCH_I18N_NAMESPACE } from '@shared/i18n'; import { createTestI18n } from '@shared/testing/i18n'; -import type { TaskGroup, TaskItem } from './pages'; +import type { TaskGroup, TaskItem } from '../pages/index'; import { appendCustomTaskGroup, buildTaskEditDraft, diff --git a/app/workbench/src/workbenchTasksRouteGroupHelpers.ts b/app/workbench/src/routes/workbenchTasksRouteGroupHelpers.ts similarity index 97% rename from app/workbench/src/workbenchTasksRouteGroupHelpers.ts rename to app/workbench/src/routes/workbenchTasksRouteGroupHelpers.ts index 27879ac5d..e375b3057 100644 --- a/app/workbench/src/workbenchTasksRouteGroupHelpers.ts +++ b/app/workbench/src/routes/workbenchTasksRouteGroupHelpers.ts @@ -1,7 +1,7 @@ import type { TFunction } from 'i18next'; -import type { TaskGroup, TaskItem, TaskStatus, TasksPane } from './pages'; -import type { TaskEditDraft } from './pages/TasksPage'; -import { WORKBENCH_MOCK_TASK_GROUPS } from './mockData'; +import type { TaskGroup, TaskItem, TaskStatus, TasksPane } from '../pages/index'; +import type { TaskEditDraft } from '../pages/TasksPage'; +import { WORKBENCH_MOCK_TASK_GROUPS } from '../mockData'; import { TASK_STATUS_SEQUENCE, type TaskGroupMode, diff --git a/app/workbench/src/workbenchTasksRouteHelpers.test.ts b/app/workbench/src/routes/workbenchTasksRouteHelpers.test.ts similarity index 98% rename from app/workbench/src/workbenchTasksRouteHelpers.test.ts rename to app/workbench/src/routes/workbenchTasksRouteHelpers.test.ts index 29712f65f..bc74b9a80 100644 --- a/app/workbench/src/workbenchTasksRouteHelpers.test.ts +++ b/app/workbench/src/routes/workbenchTasksRouteHelpers.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it } from 'vitest'; import { SHARED_WORKBENCH_I18N_NAMESPACE } from '@shared/i18n'; import { createTestI18n } from '@shared/testing/i18n'; -import type { TaskGroup, TaskItem, TasksPane, ViewMode } from './pages'; -import type { TaskEditDraft } from './pages/TasksPage'; +import type { TaskGroup, TaskItem, TasksPane, ViewMode } from '../pages/index'; +import type { TaskEditDraft } from '../pages/TasksPage'; import type { TaskGroupMode, TaskSortMode } from './workbenchTaskGroups'; import { buildTaskEditDraft, @@ -47,8 +47,8 @@ describe('workbenchTasksRouteHelpers handlers', () => { let editingTaskDraft = null as ReturnType | null; let taskActionLabel = '筛选已启用'; let localTaskCounter = 1; - let tasksPane: import('./pages').TasksPane = 'owned'; - let taskViewMode: import('./pages').ViewMode = 'list'; + let tasksPane: import('../pages/index').TasksPane = 'owned'; + let taskViewMode: import('../pages/index').ViewMode = 'list'; let taskFilterActive = true; let taskSortMode: 'custom' | 'due' = 'custom'; let taskGroupMode: 'custom' | 'project' | 'status' = 'custom'; diff --git a/app/workbench/src/workbenchTasksRouteHelpers.ts b/app/workbench/src/routes/workbenchTasksRouteHelpers.ts similarity index 99% rename from app/workbench/src/workbenchTasksRouteHelpers.ts rename to app/workbench/src/routes/workbenchTasksRouteHelpers.ts index 7c28eb6b8..4afd3193d 100644 --- a/app/workbench/src/workbenchTasksRouteHelpers.ts +++ b/app/workbench/src/routes/workbenchTasksRouteHelpers.ts @@ -1,6 +1,6 @@ -import type { TaskGroup, TaskItem, TasksPane, ViewMode } from './pages'; +import type { TaskGroup, TaskItem, TasksPane, ViewMode } from '../pages/index'; import type { WorkbenchTaskQueueSource } from './workbenchTaskDeepLinks'; -import type { TaskEditDraft } from './pages/TasksPage'; +import type { TaskEditDraft } from '../pages/TasksPage'; import { type TaskGroupMode, type TaskSortMode, diff --git a/app/workbench/src/workbenchTasksRoutePlanners.test.ts b/app/workbench/src/routes/workbenchTasksRoutePlanners.test.ts similarity index 99% rename from app/workbench/src/workbenchTasksRoutePlanners.test.ts rename to app/workbench/src/routes/workbenchTasksRoutePlanners.test.ts index 361203beb..9bcb18b4f 100644 --- a/app/workbench/src/workbenchTasksRoutePlanners.test.ts +++ b/app/workbench/src/routes/workbenchTasksRoutePlanners.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest'; import { SHARED_WORKBENCH_I18N_NAMESPACE } from '@shared/i18n'; import { createTestI18n } from '@shared/testing/i18n'; -import type { TaskItem } from './pages'; +import type { TaskItem } from '../pages/index'; import { buildTaskEditDraft } from './workbenchTasksRouteGroupHelpers'; import { buildTaskPaneChangeLabel, diff --git a/app/workbench/src/workbenchTasksRoutePlanners.ts b/app/workbench/src/routes/workbenchTasksRoutePlanners.ts similarity index 98% rename from app/workbench/src/workbenchTasksRoutePlanners.ts rename to app/workbench/src/routes/workbenchTasksRoutePlanners.ts index e58ec36bc..e5d561688 100644 --- a/app/workbench/src/workbenchTasksRoutePlanners.ts +++ b/app/workbench/src/routes/workbenchTasksRoutePlanners.ts @@ -1,5 +1,5 @@ -import type { TaskItem, TaskStatus, TasksPane } from './pages'; -import type { TaskEditDraft } from './pages/TasksPage'; +import type { TaskItem, TaskStatus, TasksPane } from '../pages/index'; +import type { TaskEditDraft } from '../pages/TasksPage'; import { type TaskSortMode, createLocalTask, diff --git a/app/workbench/src/workbenchUsageSummary.test.ts b/app/workbench/src/routes/workbenchUsageSummary.test.ts similarity index 95% rename from app/workbench/src/workbenchUsageSummary.test.ts rename to app/workbench/src/routes/workbenchUsageSummary.test.ts index b076c486c..e85f25882 100644 --- a/app/workbench/src/workbenchUsageSummary.test.ts +++ b/app/workbench/src/routes/workbenchUsageSummary.test.ts @@ -3,7 +3,7 @@ // (chip hidden), never a fake 0; pre-counter runs contribute nothing. import { describe, expect, it } from 'vitest'; import { sumUsageTeamTokens } from './workbenchUsageSummary'; -import type { TokenUsagePageTeam } from './pages/TokenUsagePage'; +import type { TokenUsagePageTeam } from '../pages/TokenUsagePage'; function team(runs: Array<{ tokenUsageTotal?: number }>): TokenUsagePageTeam { return { diff --git a/app/workbench/src/workbenchUsageSummary.ts b/app/workbench/src/routes/workbenchUsageSummary.ts similarity index 94% rename from app/workbench/src/workbenchUsageSummary.ts rename to app/workbench/src/routes/workbenchUsageSummary.ts index 56f9dac2f..17f0755c8 100644 --- a/app/workbench/src/workbenchUsageSummary.ts +++ b/app/workbench/src/routes/workbenchUsageSummary.ts @@ -7,7 +7,7 @@ * "current session" number — the chip's semantics match the board exactly. */ -import type { TokenUsagePageTeam } from './pages/TokenUsagePage'; +import type { TokenUsagePageTeam } from '../pages/TokenUsagePage'; /** * Sum the recorded token counters across every team run. diff --git a/app/workbench/src/ChatEngineeringColumn.module.css b/app/workbench/src/transcript/ChatEngineeringColumn.module.css similarity index 100% rename from app/workbench/src/ChatEngineeringColumn.module.css rename to app/workbench/src/transcript/ChatEngineeringColumn.module.css diff --git a/app/workbench/src/ChatEngineeringColumn.test.tsx b/app/workbench/src/transcript/ChatEngineeringColumn.test.tsx similarity index 98% rename from app/workbench/src/ChatEngineeringColumn.test.tsx rename to app/workbench/src/transcript/ChatEngineeringColumn.test.tsx index aeecbc7b5..9f0e1ad62 100644 --- a/app/workbench/src/ChatEngineeringColumn.test.tsx +++ b/app/workbench/src/transcript/ChatEngineeringColumn.test.tsx @@ -10,8 +10,8 @@ import { engineeringPreviewSignal, resolveEngineeringPreview, } from './ChatEngineeringColumn'; -import { WORKBENCH_INSPECTOR_QUICK_OPEN_EVENT } from './desktopChromeEvents'; -import { WORKBENCH_ENGINEERING_PREVIEW_FOCUS_EVENT } from './workbenchPreviewEvents'; +import { WORKBENCH_INSPECTOR_QUICK_OPEN_EVENT } from '../desktopChromeEvents'; +import { WORKBENCH_ENGINEERING_PREVIEW_FOCUS_EVENT } from '../workbenchPreviewEvents'; beforeAll(async () => { await useTestI18nLanguage('zh'); diff --git a/app/workbench/src/ChatEngineeringColumn.tsx b/app/workbench/src/transcript/ChatEngineeringColumn.tsx similarity index 97% rename from app/workbench/src/ChatEngineeringColumn.tsx rename to app/workbench/src/transcript/ChatEngineeringColumn.tsx index 46f29218c..afd2b9bef 100644 --- a/app/workbench/src/ChatEngineeringColumn.tsx +++ b/app/workbench/src/transcript/ChatEngineeringColumn.tsx @@ -14,17 +14,17 @@ import { FilePreviewRouter, runtimeEvidenceOverviewFiles, type PreviewFile, -} from './inspector'; +} from '../inspector/index'; import { AuxPanel, resolveAvailableAuxTabs, resolveEffectiveAuxTab, type AuxPanelTab, -} from './auxPanel'; -import { WORKBENCH_INSPECTOR_QUICK_OPEN_EVENT } from './desktopChromeEvents'; -import type { InspectorTranslator } from './inspector/InspectorModePanelHelpers'; -import { WORKBENCH_ENGINEERING_PREVIEW_FOCUS_EVENT, type EngineeringPreviewFocusDetail } from './workbenchPreviewEvents'; -import shellStyles from './AgentHubWorkbench.module.css'; +} from '../auxPanel/index'; +import { WORKBENCH_INSPECTOR_QUICK_OPEN_EVENT } from '../desktopChromeEvents'; +import type { InspectorTranslator } from '../inspector/InspectorModePanelHelpers'; +import { WORKBENCH_ENGINEERING_PREVIEW_FOCUS_EVENT, type EngineeringPreviewFocusDetail } from '../workbenchPreviewEvents'; +import shellStyles from '../AgentHubWorkbench.module.css'; import styles from './ChatEngineeringColumn.module.css'; export type ChatEngineeringColumnProps = { diff --git a/app/workbench/src/ChatViewBridge.checkpoint.test.tsx b/app/workbench/src/transcript/ChatViewBridge.checkpoint.test.tsx similarity index 100% rename from app/workbench/src/ChatViewBridge.checkpoint.test.tsx rename to app/workbench/src/transcript/ChatViewBridge.checkpoint.test.tsx diff --git a/app/workbench/src/ChatViewBridge.tsx b/app/workbench/src/transcript/ChatViewBridge.tsx similarity index 97% rename from app/workbench/src/ChatViewBridge.tsx rename to app/workbench/src/transcript/ChatViewBridge.tsx index 4b09b0152..88c7596f2 100644 --- a/app/workbench/src/ChatViewBridge.tsx +++ b/app/workbench/src/transcript/ChatViewBridge.tsx @@ -9,14 +9,14 @@ import React, { useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import type { TranscriptBlock } from '@shared/transcript'; import type { WorkbenchConversation } from '@shared/platform'; -import type { ConnectionStatusKind } from './GlobalRail'; +import type { ConnectionStatusKind } from '../GlobalRail'; import { ChatViewTranscript } from '@shared/chatview/components/ChatViewTranscript'; import type { TranscriptUserItem } from '@shared/chatview/transcript-item'; import type { UnreadDividerDescriptor } from '@shared/chatview'; import { CHATVIEW_I18N_NAMESPACE } from '@shared/chatview/i18n/resources'; import { useTypingPresence } from '@shared/chatview/typingPresence'; -import { SubagentStreamOverlay } from './team/SubagentStreamOverlay'; -import { InlineDelegationCard } from './team/InlineDelegationCard'; +import { SubagentStreamOverlay } from '../team/SubagentStreamOverlay'; +import { InlineDelegationCard } from '../team/InlineDelegationCard'; export interface ChatViewBridgeProps { /** Filtered + optimistic transcript blocks to render. */ diff --git a/app/workbench/src/ConversationHost.checkpoint.test.tsx b/app/workbench/src/transcript/ConversationHost.checkpoint.test.tsx similarity index 96% rename from app/workbench/src/ConversationHost.checkpoint.test.tsx rename to app/workbench/src/transcript/ConversationHost.checkpoint.test.tsx index 1fbde1524..cf1463aee 100644 --- a/app/workbench/src/ConversationHost.checkpoint.test.tsx +++ b/app/workbench/src/transcript/ConversationHost.checkpoint.test.tsx @@ -13,7 +13,7 @@ import { createInitialComposerState } from '@shared/composer'; import { createMockPlatform } from '@shared/platform/createMockPlatform'; import type { CheckpointPort } from '@shared/platform'; import type { RowItem } from '@shared/chatview/types'; -import { WORKBENCH_ENGINEERING_PREVIEW_FOCUS_EVENT } from './workbenchPreviewEvents'; +import { WORKBENCH_ENGINEERING_PREVIEW_FOCUS_EVENT } from '../workbenchPreviewEvents'; import { useTestI18nLanguage } from '@shared/testing/i18n'; beforeAll(async () => { @@ -30,20 +30,20 @@ vi.mock('./ChatViewBridge', () => ({ }, })); -vi.mock('./WorkspaceHeader', () => ({ +vi.mock('../WorkspaceHeader', () => ({ WorkspaceHeader: () =>
, })); -vi.mock('./ComposerDispatchQueue', () => ({ +vi.mock('../composer/ComposerDispatchQueue', () => ({ ComposerDispatchQueue: () => null, })); -vi.mock('./MessageSearchPanel', () => ({ +vi.mock('../MessageSearchPanel', () => ({ default: () => null, })); -vi.mock('./UnifiedComposer', () => ({ +vi.mock('../composer/UnifiedComposer', () => ({ UnifiedComposer: () =>
, })); diff --git a/app/workbench/src/ConversationHost.goalBanner.test.tsx b/app/workbench/src/transcript/ConversationHost.goalBanner.test.tsx similarity index 96% rename from app/workbench/src/ConversationHost.goalBanner.test.tsx rename to app/workbench/src/transcript/ConversationHost.goalBanner.test.tsx index 8baae162e..99107764f 100644 --- a/app/workbench/src/ConversationHost.goalBanner.test.tsx +++ b/app/workbench/src/transcript/ConversationHost.goalBanner.test.tsx @@ -24,19 +24,19 @@ vi.mock('./ChatViewBridge', () => ({ ChatViewBridge: () =>
, })); -vi.mock('./WorkspaceHeader', () => ({ +vi.mock('../WorkspaceHeader', () => ({ WorkspaceHeader: () =>
, })); -vi.mock('./ComposerDispatchQueue', () => ({ +vi.mock('../composer/ComposerDispatchQueue', () => ({ ComposerDispatchQueue: () => null, })); -vi.mock('./MessageSearchPanel', () => ({ +vi.mock('../MessageSearchPanel', () => ({ default: () => null, })); -vi.mock('./UnifiedComposer', () => ({ +vi.mock('../composer/UnifiedComposer', () => ({ UnifiedComposer: () =>
, })); diff --git a/app/workbench/src/ConversationHost.tsx b/app/workbench/src/transcript/ConversationHost.tsx similarity index 97% rename from app/workbench/src/ConversationHost.tsx rename to app/workbench/src/transcript/ConversationHost.tsx index 52d332a00..642064bf6 100644 --- a/app/workbench/src/ConversationHost.tsx +++ b/app/workbench/src/transcript/ConversationHost.tsx @@ -1,6 +1,6 @@ import React, { FormEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { WORKBENCH_APPROVAL_JUMP_EVENT } from './workbenchApprovalEvents'; +import { WORKBENCH_APPROVAL_JUMP_EVENT } from '../workbenchApprovalEvents'; import type { TFunction } from 'i18next'; import type { TranscriptBlock, TextTranscriptBlock } from '@shared/transcript'; import { @@ -22,7 +22,7 @@ import { handleDocumentDragOver, handleDocumentDrop, type ComposerDocumentFileDropCallbacks, -} from './composerDocumentFileDrop'; +} from '../composer/composerDocumentFileDrop'; import { describePendingIntent, enqueuePendingIntent, @@ -38,34 +38,34 @@ import { retryPendingIntent, type PendingDispatchIntent, type PendingIntentMove, -} from './composer/pendingIntents'; +} from '../composer/pendingIntents'; import type { AgentHubPlatform, WorkbenchConversation } from '@shared/platform'; import { AppError } from '@shared/errors'; import { resolveFailedToastKey } from '@shared/chatview/failedToastKey'; import { CHATVIEW_I18N_NAMESPACE } from '@shared/chatview/i18n/resources'; -import type { AttachmentUploadState } from './UnifiedComposer'; -import type { FileItem } from './inspector'; -import type { ConnectionStatusKind } from './GlobalRail'; +import type { AttachmentUploadState } from '../composer/UnifiedComposer'; +import type { FileItem } from '../inspector/index'; +import type { ConnectionStatusKind } from '../GlobalRail'; import { ChatViewBridge } from './ChatViewBridge'; -import { ComposerDispatchQueue } from './ComposerDispatchQueue'; +import { ComposerDispatchQueue } from '../composer/ComposerDispatchQueue'; import { countPendingApprovals, firstPendingApprovalBlockId, -} from './workbenchApprovalSummary'; -import { UnifiedComposer } from './UnifiedComposer'; -import { WorkspaceHeader } from './WorkspaceHeader'; -import type { WorkbenchSplitControls } from './workbenchFrameTypes'; +} from '../workbenchApprovalSummary'; +import { UnifiedComposer } from '../composer/UnifiedComposer'; +import { WorkspaceHeader } from '../WorkspaceHeader'; +import type { WorkbenchSplitControls } from '../workbenchFrameTypes'; import { WorkbenchGoalBanner } from './WorkbenchGoalBanner'; import { deriveGoalSummary } from './workbenchGoalSummary'; import type { UnreadDividerDescriptor } from '@shared/chatview'; import type { RowItem } from '@shared/chatview/types'; -import { WORKBENCH_ENGINEERING_PREVIEW_FOCUS_EVENT } from './workbenchPreviewEvents'; -import MessageSearchPanel from './MessageSearchPanel'; -import { PageErrorBoundary } from './PageErrorBoundary'; -import { useComposerSubmitBehavior } from './workbenchPreferences'; -import styles from './AgentHubWorkbench.module.css'; +import { WORKBENCH_ENGINEERING_PREVIEW_FOCUS_EVENT } from '../workbenchPreviewEvents'; +import MessageSearchPanel from '../MessageSearchPanel'; +import { PageErrorBoundary } from '../PageErrorBoundary'; +import { useComposerSubmitBehavior } from '../workbenchPreferences'; +import styles from '../AgentHubWorkbench.module.css'; -export type { MainchainSummary } from './mainchain'; +export type { MainchainSummary } from '../mainchain/index'; /** * Map a platform/API failure to user-facing toast copy (#1826). diff --git a/app/workbench/src/ConversationSidebar.test.tsx b/app/workbench/src/transcript/ConversationSidebar.test.tsx similarity index 99% rename from app/workbench/src/ConversationSidebar.test.tsx rename to app/workbench/src/transcript/ConversationSidebar.test.tsx index db6586a8b..f846baa85 100644 --- a/app/workbench/src/ConversationSidebar.test.tsx +++ b/app/workbench/src/transcript/ConversationSidebar.test.tsx @@ -4,7 +4,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vite import type { ReactNode } from 'react'; import type { WorkbenchConversation } from '@shared/platform'; import { ConversationSidebar } from './ConversationSidebar'; -import type { TaskItem } from './pages'; +import type { TaskItem } from '../pages/index'; import { backFromTaskDeepLink, consumeWorkbenchTaskDeepLinkIntent, @@ -12,7 +12,7 @@ import { openConversationForTask, publishWorkbenchTaskQueue, resetWorkbenchTaskDeepLinksForTest, -} from './workbenchTaskDeepLinks'; +} from '../routes/workbenchTaskDeepLinks'; /* ────────────────────────────────────────────────────────────────────── ConversationSidebar actions tests (#1508): rename / copy link / delete. diff --git a/app/workbench/src/ConversationSidebar.tsx b/app/workbench/src/transcript/ConversationSidebar.tsx similarity index 99% rename from app/workbench/src/ConversationSidebar.tsx rename to app/workbench/src/transcript/ConversationSidebar.tsx index 3887c27a2..37c511f72 100644 --- a/app/workbench/src/ConversationSidebar.tsx +++ b/app/workbench/src/transcript/ConversationSidebar.tsx @@ -2,17 +2,17 @@ import React, { useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Virtualizer, type VirtualizerHandle } from 'virtua'; import type { WorkbenchConversation } from '@shared/platform'; -import { DesignNavIcon } from './designIcons'; -import { ContextMenu, type ContextMenuItem } from './floating'; +import { DesignNavIcon } from '../designIcons'; +import { ContextMenu, type ContextMenuItem } from '../floating/index'; import { CHATVIEW_I18N_NAMESPACE } from '@shared/chatview/i18n/resources'; import Modal from '@shared/ui/Modal'; import { Tooltip } from '@shared/ui/Tooltip'; -import type { ConversationLiveStatus } from './workbenchAttentionModel'; +import type { ConversationLiveStatus } from '../workbenchAttentionModel'; import { useWorkbenchTaskDeepLinkActions, useWorkbenchTaskDeepLinkSnapshot, -} from './workbenchTaskDeepLinks'; -import styles from './AgentHubWorkbench.module.css'; +} from '../routes/workbenchTaskDeepLinks'; +import styles from '../AgentHubWorkbench.module.css'; const SORT_STORAGE_KEY = 'agenthub.conversationSort'; diff --git a/app/workbench/src/MainchainStatusStrip.test.tsx b/app/workbench/src/transcript/MainchainStatusStrip.test.tsx similarity index 98% rename from app/workbench/src/MainchainStatusStrip.test.tsx rename to app/workbench/src/transcript/MainchainStatusStrip.test.tsx index 1740faec8..8dce300fb 100644 --- a/app/workbench/src/MainchainStatusStrip.test.tsx +++ b/app/workbench/src/transcript/MainchainStatusStrip.test.tsx @@ -2,7 +2,7 @@ import { fireEvent, render, screen } from '@testing-library/react'; import { beforeAll, describe, expect, it, vi } from 'vitest'; import { useTestI18nLanguage } from '@shared/testing/i18n'; import { MainchainStatusStrip } from './MainchainStatusStrip'; -import type { MainchainSummary } from './mainchain'; +import type { MainchainSummary } from '../mainchain/index'; // Chip copy resolves through the real zh/en bundles (sharedWorkbench ns), // so opt into a real language instead of the key-echo default (#1717). diff --git a/app/workbench/src/MainchainStatusStrip.tsx b/app/workbench/src/transcript/MainchainStatusStrip.tsx similarity index 97% rename from app/workbench/src/MainchainStatusStrip.tsx rename to app/workbench/src/transcript/MainchainStatusStrip.tsx index ea90f04eb..7e0be3fd5 100644 --- a/app/workbench/src/MainchainStatusStrip.tsx +++ b/app/workbench/src/transcript/MainchainStatusStrip.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { CHATVIEW_I18N_NAMESPACE } from '@shared/chatview/i18n/resources'; -import styles from './AgentHubWorkbench.module.css'; -import { connectionStatusLabel, type ConnectionStatusKind } from './GlobalRail'; -import type { MainchainSummary } from './mainchain'; -import type { WorkbenchAttentionCounts } from './workbenchAttentionModel'; +import styles from '../AgentHubWorkbench.module.css'; +import { connectionStatusLabel, type ConnectionStatusKind } from '../GlobalRail'; +import type { MainchainSummary } from '../mainchain/index'; +import type { WorkbenchAttentionCounts } from '../workbenchAttentionModel'; // #2154: shared token formatter (same units as the usage board and the // inspector overview) instead of the page-local formatTokenCount. import { formatTokens } from '@shared/context/breakdown'; diff --git a/app/workbench/src/WorkbenchGoalBanner.module.css b/app/workbench/src/transcript/WorkbenchGoalBanner.module.css similarity index 100% rename from app/workbench/src/WorkbenchGoalBanner.module.css rename to app/workbench/src/transcript/WorkbenchGoalBanner.module.css diff --git a/app/workbench/src/WorkbenchGoalBanner.test.tsx b/app/workbench/src/transcript/WorkbenchGoalBanner.test.tsx similarity index 100% rename from app/workbench/src/WorkbenchGoalBanner.test.tsx rename to app/workbench/src/transcript/WorkbenchGoalBanner.test.tsx diff --git a/app/workbench/src/WorkbenchGoalBanner.tsx b/app/workbench/src/transcript/WorkbenchGoalBanner.tsx similarity index 97% rename from app/workbench/src/WorkbenchGoalBanner.tsx rename to app/workbench/src/transcript/WorkbenchGoalBanner.tsx index b58f86fdf..5f28435cd 100644 --- a/app/workbench/src/WorkbenchGoalBanner.tsx +++ b/app/workbench/src/transcript/WorkbenchGoalBanner.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { CHATVIEW_I18N_NAMESPACE } from '@shared/chatview/i18n/resources'; -import chipStyles from './AgentHubWorkbench.module.css'; +import chipStyles from '../AgentHubWorkbench.module.css'; import styles from './WorkbenchGoalBanner.module.css'; import type { WorkbenchGoalStatus, WorkbenchGoalSummary } from './workbenchGoalSummary'; diff --git a/app/workbench/src/WorkbenchTranscriptOverlays.tsx b/app/workbench/src/transcript/WorkbenchTranscriptOverlays.tsx similarity index 99% rename from app/workbench/src/WorkbenchTranscriptOverlays.tsx rename to app/workbench/src/transcript/WorkbenchTranscriptOverlays.tsx index ec3475dcb..e55849dc4 100644 --- a/app/workbench/src/WorkbenchTranscriptOverlays.tsx +++ b/app/workbench/src/transcript/WorkbenchTranscriptOverlays.tsx @@ -7,7 +7,7 @@ import { DemoToast, type ContextMenuItem, type MultiSelectBarAction, -} from './floating'; +} from '../floating/index'; import type { DeleteConfirmRequest, WorkbenchContextMenuState, diff --git a/app/workbench/src/useWorkbenchSessionChrome.test.ts b/app/workbench/src/transcript/useWorkbenchSessionChrome.test.ts similarity index 99% rename from app/workbench/src/useWorkbenchSessionChrome.test.ts rename to app/workbench/src/transcript/useWorkbenchSessionChrome.test.ts index f82c0a668..122ebfa15 100644 --- a/app/workbench/src/useWorkbenchSessionChrome.test.ts +++ b/app/workbench/src/transcript/useWorkbenchSessionChrome.test.ts @@ -9,8 +9,8 @@ import type { WorkbenchConversation, } from '@shared/platform'; import type { TranscriptBlock } from '@shared/transcript'; -import { INSPECTOR_DEFAULT_COLLAPSE_EVENT } from './workbenchLayoutConstants'; -import { WORKBENCH_MOCK_SETTINGS_DEFAULTS } from './mockData'; +import { INSPECTOR_DEFAULT_COLLAPSE_EVENT } from '../workbenchLayoutConstants'; +import { WORKBENCH_MOCK_SETTINGS_DEFAULTS } from '../mockData'; import { LOCAL_CLI_DISCOVERY_FALLBACK, useWorkbenchSessionChrome, diff --git a/app/workbench/src/useWorkbenchSessionChrome.ts b/app/workbench/src/transcript/useWorkbenchSessionChrome.ts similarity index 98% rename from app/workbench/src/useWorkbenchSessionChrome.ts rename to app/workbench/src/transcript/useWorkbenchSessionChrome.ts index e92f4c0ff..632443d15 100644 --- a/app/workbench/src/useWorkbenchSessionChrome.ts +++ b/app/workbench/src/transcript/useWorkbenchSessionChrome.ts @@ -15,14 +15,14 @@ import { } from '@shared/composer'; import { toggleAppliedAgentHubTheme } from '@shared/theme'; import { collectTranscriptEvidence } from '@shared/transcript'; -import { buildMainchainSummary } from './mainchain'; -import type { FileItem } from './inspector'; -import { WORKBENCH_MOCK_SETTINGS_DEFAULTS } from './mockData'; -import { createSettingsService, type SettingsService } from './settingsService'; +import { buildMainchainSummary } from '../mainchain/index'; +import type { FileItem } from '../inspector/index'; +import { WORKBENCH_MOCK_SETTINGS_DEFAULTS } from '../mockData'; +import { createSettingsService, type SettingsService } from '../settingsService'; import { INSPECTOR_DEFAULT_COLLAPSE_EVENT, type InspectorDefaultCollapseDetail, -} from './workbenchLayoutConstants'; +} from '../workbenchLayoutConstants'; import { LOCAL_CLI_DISCOVERY_FALLBACK, buildInspectorTranscriptViews, diff --git a/app/workbench/src/useWorkbenchTranscriptChrome.test.ts b/app/workbench/src/transcript/useWorkbenchTranscriptChrome.test.ts similarity index 99% rename from app/workbench/src/useWorkbenchTranscriptChrome.test.ts rename to app/workbench/src/transcript/useWorkbenchTranscriptChrome.test.ts index c46557cc2..53a40a190 100644 --- a/app/workbench/src/useWorkbenchTranscriptChrome.test.ts +++ b/app/workbench/src/transcript/useWorkbenchTranscriptChrome.test.ts @@ -4,7 +4,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest'; import type { ReactElement } from 'react'; import type { WorkbenchConversation } from '@shared/platform'; import type { TranscriptBlock } from '@shared/transcript'; -import type { TranscriptContextMenuEvent, TranscriptPointerEvent } from './transcriptEventTypes'; +import type { TranscriptContextMenuEvent, TranscriptPointerEvent } from '../transcriptEventTypes'; import { SELECTION_HOLD_CANCEL_DISTANCE, SELECTION_HOLD_DELAY_MS, diff --git a/app/workbench/src/useWorkbenchTranscriptChrome.ts b/app/workbench/src/transcript/useWorkbenchTranscriptChrome.ts similarity index 98% rename from app/workbench/src/useWorkbenchTranscriptChrome.ts rename to app/workbench/src/transcript/useWorkbenchTranscriptChrome.ts index 52b932f4a..152a4f0be 100644 --- a/app/workbench/src/useWorkbenchTranscriptChrome.ts +++ b/app/workbench/src/transcript/useWorkbenchTranscriptChrome.ts @@ -9,8 +9,8 @@ import { } from 'react'; import type { ComposerAction } from '@shared/composer'; import type { ApprovalDecisionAction, TranscriptBlock } from '@shared/transcript'; -import type { ContextMenuItem, MultiSelectBarAction } from './floating'; -import type { TranscriptContextMenuEvent, TranscriptPointerEvent } from './transcriptEventTypes'; +import type { ContextMenuItem, MultiSelectBarAction } from '../floating/index'; +import type { TranscriptContextMenuEvent, TranscriptPointerEvent } from '../transcriptEventTypes'; import { createTranscriptChromeController, type DeleteConfirmRequest, diff --git a/app/workbench/src/workbenchGoalSummary.test.ts b/app/workbench/src/transcript/workbenchGoalSummary.test.ts similarity index 100% rename from app/workbench/src/workbenchGoalSummary.test.ts rename to app/workbench/src/transcript/workbenchGoalSummary.test.ts diff --git a/app/workbench/src/workbenchGoalSummary.ts b/app/workbench/src/transcript/workbenchGoalSummary.ts similarity index 100% rename from app/workbench/src/workbenchGoalSummary.ts rename to app/workbench/src/transcript/workbenchGoalSummary.ts diff --git a/app/workbench/src/workbenchSessionChromeHelpers.test.ts b/app/workbench/src/transcript/workbenchSessionChromeHelpers.test.ts similarity index 100% rename from app/workbench/src/workbenchSessionChromeHelpers.test.ts rename to app/workbench/src/transcript/workbenchSessionChromeHelpers.test.ts diff --git a/app/workbench/src/workbenchSessionChromeHelpers.ts b/app/workbench/src/transcript/workbenchSessionChromeHelpers.ts similarity index 98% rename from app/workbench/src/workbenchSessionChromeHelpers.ts rename to app/workbench/src/transcript/workbenchSessionChromeHelpers.ts index 420c80bd2..9b5ac7435 100644 --- a/app/workbench/src/workbenchSessionChromeHelpers.ts +++ b/app/workbench/src/transcript/workbenchSessionChromeHelpers.ts @@ -25,10 +25,10 @@ import type { ChildAgentTranscriptBlock, EvidenceRef, } from '@shared/transcript'; -import type { MainchainSummary } from './mainchain'; -import type { FileItem, RunResultInfo } from './inspector'; -import type { SettingsService } from './settingsService'; -import type { GlobalRailPage } from './GlobalRail'; +import type { MainchainSummary } from '../mainchain/index'; +import type { FileItem, RunResultInfo } from '../inspector/index'; +import type { SettingsService } from '../settingsService'; +import type { GlobalRailPage } from '../GlobalRail'; import { matchesShortcut } from '@shared/utils/keyboardUtils'; import type { KeyboardEventLike } from '@shared/utils/keyboardUtils'; import { getResolvedBinding } from '@shared/utils/keyboardShortcuts'; diff --git a/app/workbench/src/workbenchTranscriptChromeActionMappers.test.ts b/app/workbench/src/transcript/workbenchTranscriptChromeActionMappers.test.ts similarity index 100% rename from app/workbench/src/workbenchTranscriptChromeActionMappers.test.ts rename to app/workbench/src/transcript/workbenchTranscriptChromeActionMappers.test.ts diff --git a/app/workbench/src/workbenchTranscriptChromeActionMappers.ts b/app/workbench/src/transcript/workbenchTranscriptChromeActionMappers.ts similarity index 99% rename from app/workbench/src/workbenchTranscriptChromeActionMappers.ts rename to app/workbench/src/transcript/workbenchTranscriptChromeActionMappers.ts index 814a36fb9..f3446f0de 100644 --- a/app/workbench/src/workbenchTranscriptChromeActionMappers.ts +++ b/app/workbench/src/transcript/workbenchTranscriptChromeActionMappers.ts @@ -3,8 +3,8 @@ import type { ComposerAction } from '@shared/composer'; import type { WorkbenchConversation } from '@shared/platform'; import type { ApprovalDecisionAction, TranscriptBlock } from '@shared/transcript'; import { resolveFailedToastKey } from '@shared/chatview/failedToastKey'; -import type { ContextMenuItem, MultiSelectBarAction } from './floating'; -import { ForwardConversationPicker } from './floating/ForwardConversationPicker'; +import type { ContextMenuItem, MultiSelectBarAction } from '../floating/index'; +import { ForwardConversationPicker } from '../floating/ForwardConversationPicker'; import { blockTitle, buildPermissionApprovalDecision, diff --git a/app/workbench/src/workbenchTranscriptChromeHelpers.test.ts b/app/workbench/src/transcript/workbenchTranscriptChromeHelpers.test.ts similarity index 100% rename from app/workbench/src/workbenchTranscriptChromeHelpers.test.ts rename to app/workbench/src/transcript/workbenchTranscriptChromeHelpers.test.ts diff --git a/app/workbench/src/workbenchTranscriptChromeHelpers.ts b/app/workbench/src/transcript/workbenchTranscriptChromeHelpers.ts similarity index 99% rename from app/workbench/src/workbenchTranscriptChromeHelpers.ts rename to app/workbench/src/transcript/workbenchTranscriptChromeHelpers.ts index 372f66dc2..42d8393d7 100644 --- a/app/workbench/src/workbenchTranscriptChromeHelpers.ts +++ b/app/workbench/src/transcript/workbenchTranscriptChromeHelpers.ts @@ -1,7 +1,7 @@ import type { ComposerAction } from '@shared/composer'; import type { WorkbenchConversation } from '@shared/platform'; import type { ApprovalDecisionAction, TranscriptBlock } from '@shared/transcript'; -import type { ContextMenuItem, MultiSelectBarAction } from './floating'; +import type { ContextMenuItem, MultiSelectBarAction } from '../floating/index'; import { applyTranscriptChromeSideEffects, buildTranscriptContextMenuGroups, diff --git a/app/workbench/src/workbenchTranscriptChromeLabels.test.ts b/app/workbench/src/transcript/workbenchTranscriptChromeLabels.test.ts similarity index 100% rename from app/workbench/src/workbenchTranscriptChromeLabels.test.ts rename to app/workbench/src/transcript/workbenchTranscriptChromeLabels.test.ts diff --git a/app/workbench/src/workbenchTranscriptChromeLabels.ts b/app/workbench/src/transcript/workbenchTranscriptChromeLabels.ts similarity index 100% rename from app/workbench/src/workbenchTranscriptChromeLabels.ts rename to app/workbench/src/transcript/workbenchTranscriptChromeLabels.ts diff --git a/app/workbench/src/workbenchTranscriptChromeStateHelpers.test.ts b/app/workbench/src/transcript/workbenchTranscriptChromeStateHelpers.test.ts similarity index 100% rename from app/workbench/src/workbenchTranscriptChromeStateHelpers.test.ts rename to app/workbench/src/transcript/workbenchTranscriptChromeStateHelpers.test.ts diff --git a/app/workbench/src/workbenchTranscriptChromeStateHelpers.ts b/app/workbench/src/transcript/workbenchTranscriptChromeStateHelpers.ts similarity index 100% rename from app/workbench/src/workbenchTranscriptChromeStateHelpers.ts rename to app/workbench/src/transcript/workbenchTranscriptChromeStateHelpers.ts diff --git a/app/workbench/src/useWorkbenchGlobalShortcuts.ts b/app/workbench/src/useWorkbenchGlobalShortcuts.ts index 2c4f8b700..498198c74 100644 --- a/app/workbench/src/useWorkbenchGlobalShortcuts.ts +++ b/app/workbench/src/useWorkbenchGlobalShortcuts.ts @@ -1,7 +1,7 @@ import { useEffect, useRef } from 'react'; import { getResolvedShortcutGroups } from '@shared/utils/keyboardShortcuts'; import { matchesShortcut } from '@shared/utils/keyboardUtils'; -import { isEditableKeyboardTarget } from './workbenchSessionChromeHelpers'; +import { isEditableKeyboardTarget } from './transcript/workbenchSessionChromeHelpers'; /* ═══════════════════════════════════════════════════════════════════════ useWorkbenchGlobalShortcuts — shared global keyboard dispatcher (#1822). diff --git a/app/workbench/src/useWorkbenchTaskDeepLinks.test.ts b/app/workbench/src/useWorkbenchTaskDeepLinks.test.ts index 105c7eaac..a39ef0530 100644 --- a/app/workbench/src/useWorkbenchTaskDeepLinks.test.ts +++ b/app/workbench/src/useWorkbenchTaskDeepLinks.test.ts @@ -1,6 +1,6 @@ import { act, renderHook } from '@testing-library/react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import type { TaskItem } from './pages'; +import type { TaskItem } from './pages/index'; import { backFromTaskDeepLink, getWorkbenchTaskDeepLinkSnapshot, @@ -9,7 +9,7 @@ import { openTaskDetailForConversation, publishWorkbenchTaskQueue, resetWorkbenchTaskDeepLinksForTest, -} from './workbenchTaskDeepLinks'; +} from './routes/workbenchTaskDeepLinks'; import { useWorkbenchTaskDeepLinks } from './useWorkbenchTaskDeepLinks'; function makeTask(overrides: Partial = {}): TaskItem { diff --git a/app/workbench/src/useWorkbenchTaskDeepLinks.ts b/app/workbench/src/useWorkbenchTaskDeepLinks.ts index eeeb45b0d..36a334f31 100644 --- a/app/workbench/src/useWorkbenchTaskDeepLinks.ts +++ b/app/workbench/src/useWorkbenchTaskDeepLinks.ts @@ -7,7 +7,7 @@ import { useWorkbenchTaskDeepLinkStore, type WorkbenchTaskDeepLinkIntent, type WorkbenchTaskQueueSource, -} from './workbenchTaskDeepLinks'; +} from './routes/workbenchTaskDeepLinks'; export interface UseWorkbenchTaskDeepLinksOptions { setActivePage: (page: GlobalRailPage) => void; diff --git a/app/workbench/src/workbenchFramePartsHelpers.ts b/app/workbench/src/workbenchFramePartsHelpers.ts index 5eb05958b..587a059f8 100644 --- a/app/workbench/src/workbenchFramePartsHelpers.ts +++ b/app/workbench/src/workbenchFramePartsHelpers.ts @@ -1,8 +1,8 @@ import { useMemo } from 'react'; -import type { ConversationHostProps } from './ConversationHost'; -import type { ConversationSidebarProps } from './ConversationSidebar'; -import type { RightInspectorProps } from './rightInspectorTypes'; -import type { WorkbenchRoutesProps } from './workbenchRoutesTypes'; +import type { ConversationHostProps } from './transcript/ConversationHost'; +import type { ConversationSidebarProps } from './transcript/ConversationSidebar'; +import type { RightInspectorProps } from './inspector/rightInspectorTypes'; +import type { WorkbenchRoutesProps } from './routes/workbenchRoutesTypes'; import type { ChatConversationHostFrameProps, ChatInspectorFrameProps, diff --git a/app/workbench/src/workbenchFrameTypes.ts b/app/workbench/src/workbenchFrameTypes.ts index 4503d6b49..f14920313 100644 --- a/app/workbench/src/workbenchFrameTypes.ts +++ b/app/workbench/src/workbenchFrameTypes.ts @@ -6,14 +6,14 @@ import type { } from '@shared/platform'; import type { TranscriptBlock } from '@shared/transcript'; import type { ConnectionStatusKind, GlobalRailPage } from './GlobalRail'; -import type { RuntimeEvidenceSnapshot } from './RightInspector'; +import type { RuntimeEvidenceSnapshot } from './inspector/RightInspector'; import type { WorkbenchAgentProfilesStatus, WorkbenchContactsActions, WorkbenchContactsData, WorkbenchDocumentsActions, } from './WorkbenchRoutes'; -import type { AgentConfig, DocRow, ProjectDraft } from './pages'; +import type { AgentConfig, DocRow, ProjectDraft } from './pages/index'; import type { CCSwitchStatusInfo, CCSwitchProviderInfo, @@ -22,8 +22,8 @@ import type { } from './pages/AgentsPage'; import type { ProjectInfo } from './pages/ProjectsPage'; import type { WorkbenchPanelLayout } from './useWorkbenchPanelLayout'; -import type { WorkbenchSessionChrome } from './useWorkbenchSessionChrome'; -import type { WorkbenchTranscriptChrome } from './useWorkbenchTranscriptChrome'; +import type { WorkbenchSessionChrome } from './transcript/useWorkbenchSessionChrome'; +import type { WorkbenchTranscriptChrome } from './transcript/useWorkbenchTranscriptChrome'; import type { WorkbenchProfileChrome } from './useWorkbenchProfileChrome'; import type { ConversationLiveStatus } from './workbenchAttentionModel'; import type { diff --git a/docs/architecture/07-design-system-ssot.md b/docs/architecture/07-design-system-ssot.md index fce02a88b..ec410c27e 100644 --- a/docs/architecture/07-design-system-ssot.md +++ b/docs/architecture/07-design-system-ssot.md @@ -113,7 +113,7 @@ Applied first to AuxPanel and TerminalPanel. Respect `prefers-reduced-motion`. | HiDPI glass | `@media (min-resolution: 192dpi)` in tokens + themes | blur ~1.4×, stronger hairline borders, focus ring 3–4px | | Breakpoint definitions | `app/shared/src/styles/tokens-base.css` 的 `--bp-*` 变量即 SSOT,`tokens-base.test.ts` 断言取值 | minimal 420 / mobile 480 / compact 720 / narrow 768 / medium 1024 / standard 1280 / wide 1440 / xwide 1920 / ultra 2560 | -响应式断点只定义在 `tokens-base.css` 的 `--bp-*`;剩余非 SSOT `@media` 仅 `app/shared/src/ui/Input.module.css` 与 `app/web/src/components/AuthPage.module.css` 的 legacy 760、`app/workbench/src/WorkbenchGoalBanner.module.css` 的 900,以及 Desktop `App.module.css` 的 1023/1279 成对窗口约定。 +响应式断点只定义在 `tokens-base.css` 的 `--bp-*`;剩余非 SSOT `@media` 仅 `app/shared/src/ui/Input.module.css` 与 `app/web/src/components/AuthPage.module.css` 的 legacy 760、`app/workbench/src/transcript/WorkbenchGoalBanner.module.css` 的 900,以及 Desktop `App.module.css` 的 1023/1279 成对窗口约定。 ## 9. Acceptance mapping