Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"typecheck": "tsc --noEmit",
"preview": "vite preview",
"test": "bun test --isolate && bun run test:interaction",
"test:interaction": "bun test --isolate ./src/routes/root-layout.interaction.tsx ./src/routes/project-todos.interaction.tsx ./src/context/workbench-layout.interaction.tsx ./src/components/primitives/IconAction.interaction.tsx ./src/components/primitives/StatusTransition.interaction.tsx ./src/components/features/ResizeHandle.interaction.tsx ./src/components/features/TodoProgressButton.interaction.tsx ./src/components/features/DiffTab.interaction.tsx ./src/components/features/ContextInspector.interaction.tsx ./src/components/features/InspectorToggleButton.interaction.tsx ./src/components/features/SettingsDialog.interaction.tsx ./src/components/features/EditAutomationDialog.interaction.tsx ./src/components/features/SessionComposerDock.interaction.tsx ./src/components/features/ComposerQueueList.interaction.tsx ./src/components/features/SessionGoalSummaryRow.interaction.tsx ./src/components/features/HitlBell.interaction.tsx ./src/components/features/AddProjectModal.interaction.tsx ./src/components/features/Sidebar.interaction.tsx ./src/components/composite/ExecutionWorkstream.interaction.tsx ./src/components/composite/ToolCard.interaction.tsx"
"test:interaction": "bun test --isolate ./src/routes/root-layout.interaction.tsx ./src/routes/project-todos.interaction.tsx ./src/context/workbench-layout.interaction.tsx ./src/components/primitives/IconAction.interaction.tsx ./src/components/primitives/StatusTransition.interaction.tsx ./src/components/features/ResizeHandle.interaction.tsx ./src/components/features/TodoProgressButton.interaction.tsx ./src/components/features/DiffTab.interaction.tsx ./src/components/features/ContextInspector.interaction.tsx ./src/components/features/InspectorToggleButton.interaction.tsx ./src/components/features/SidebarToggleButton.interaction.tsx ./src/components/features/SettingsDialog.interaction.tsx ./src/components/features/EditAutomationDialog.interaction.tsx ./src/components/features/SessionComposerDock.interaction.tsx ./src/components/features/ComposerQueueList.interaction.tsx ./src/components/features/SessionGoalSummaryRow.interaction.tsx ./src/components/features/HitlBell.interaction.tsx ./src/components/features/AddProjectModal.interaction.tsx ./src/components/features/Sidebar.interaction.tsx ./src/components/composite/ExecutionWorkstream.interaction.tsx ./src/components/composite/ToolCard.interaction.tsx"
},
"dependencies": {
"@archcode/protocol": "workspace:*",
Expand Down
17 changes: 11 additions & 6 deletions apps/web/src/components/features/ChatHeader.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
__resetWebSessionStoresForTest,
getWebSessionStore,
} from "../../store/session-store";
import { WorkbenchLayoutProvider } from "../../context/workbench-layout";

let dom: JSDOM;
let root: Root;
Expand Down Expand Up @@ -83,18 +84,22 @@ describe("ChatHeader", () => {
});
await act(async () =>
root.render(
<ChatHeader
slug="demo"
sessionId="session"
inspectorExpanded={false}
onToggleInspector={() => {}}
/>,
<WorkbenchLayoutProvider>
<ChatHeader
slug="demo"
sessionId="session"
inspectorExpanded={false}
onToggleInspector={() => {}}
/>
</WorkbenchLayoutProvider>,
),
);
const status = container.querySelector(
'[data-testid="session-execution-status"]',
);
expect(status?.textContent).toContain("Needs you");
expect(status?.getAttribute("data-product-status")).toBe("needs_you");
expect(container.querySelector('header > button[aria-label="Collapse project sidebar"]')).not.toBeNull();
expect(container.querySelector('header button[aria-label="Expand context inspector"]')).not.toBeNull();
});
});
4 changes: 2 additions & 2 deletions apps/web/src/components/features/ChatHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Link } from "react-router-dom";
import { useSessionStore } from "../../store/session-store";
import { TodoProgressButton } from "./TodoProgressButton";
import { InspectorToggleButton } from "./InspectorToggleButton";
import { SidebarToggleButton } from "./SidebarToggleButton";
import {
executionVisualKind,
presentExecutionStatus,
Expand Down Expand Up @@ -65,6 +66,7 @@ export function ChatHeader({

return (
<header className="flex min-h-16 shrink-0 items-center gap-3 border-b border-border-default bg-bg-surface px-4 py-2.5 sm:px-6">
<SidebarToggleButton />
<div className="min-w-0 flex-1">
<div className="flex min-w-0 items-center gap-2">
<h1 className="min-w-0 truncate text-[20px] font-semibold leading-7 tracking-[-0.025em] text-text-primary">
Expand Down Expand Up @@ -147,8 +149,6 @@ export function ChatHeader({
<InspectorToggleButton
expanded={inspectorExpanded}
onToggle={onToggleInspector}
iconSize={16}
className="flex h-8 w-8 shrink-0 items-center justify-center rounded-sm border border-border-default bg-transparent text-text-tertiary transition-colors hover:border-border-strong hover:bg-bg-hover hover:text-text-primary [@media(pointer:coarse)]:h-11 [@media(pointer:coarse)]:w-11"
/>
</div>
</header>
Expand Down
3 changes: 0 additions & 3 deletions apps/web/src/components/features/ChatInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
getWebSessionStore,
useSessionStore,
} from "../../store/session-store";
import { useSettingsModal } from "../../context/settings-modal";
import { ModelPicker } from "./ModelPicker";
import { coherentModelRuntime } from "../../lib/model-runtime-coherence";
import { createClientUuid } from "../../lib/client-uuid";
Expand Down Expand Up @@ -109,7 +108,6 @@ export function ChatInput({
nextModelSelection,
isModelRuntimeFetching,
);
const { openSettingsModal } = useSettingsModal();
const postMessage = usePostMessage();
const patchModelSelection = usePatchSessionModelSelection();
const stopSession = useStopSessionFamily();
Expand Down Expand Up @@ -583,7 +581,6 @@ export function ChatInput({
next={nextModelSelection}
active={activeModelBinding}
onSelect={selectModel}
onManageModels={() => openSettingsModal("models")}
disabled={patchModelSelection.isPending}
/> : <span className="block max-w-[180px] truncate">Loading model…</span>}
</div>
Expand Down
20 changes: 1 addition & 19 deletions apps/web/src/components/features/ContextInspector.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { ReactNode } from "react";
import { PanelRightClose } from "lucide-react";
import { useSearchParams } from "react-router-dom";
import type { InspectorKind } from "../../lib/workbench-layout";
import { SessionInspector, type SessionInspectorTab } from "./context-inspector/SessionInspector";
Expand All @@ -18,26 +17,22 @@ const SESSION_TABS = [
export function ContextInspector({
kind,
id = "context-inspector",
onCollapse,
}: {
kind: InspectorKind;
id?: string;
onCollapse?: () => void;
}) {
return <InspectorShell key="session" id={id} kind={kind} tabs={SESSION_TABS} onCollapse={onCollapse} renderPanel={(activeTab) => <SessionInspector activeTab={activeTab} />} />;
return <InspectorShell key="session" id={id} kind={kind} tabs={SESSION_TABS} renderPanel={(activeTab) => <SessionInspector activeTab={activeTab} />} />;
}

function InspectorShell<T extends string>({
kind,
id,
tabs,
onCollapse,
renderPanel,
}: {
kind: InspectorKind;
id: string;
tabs: readonly [InspectorTab<T>, ...InspectorTab<T>[]];
onCollapse?: () => void;
renderPanel: (activeTab: T) => ReactNode;
}) {
const [searchParams, setSearchParams] = useSearchParams();
Expand All @@ -62,19 +57,6 @@ function InspectorShell<T extends string>({
<div className="text-[14px] font-semibold leading-5 text-text-primary">Context inspector</div>
<div className="text-[12px] leading-4 capitalize text-text-tertiary">{kind}</div>
</div>
{onCollapse && (
<button
type="button"
aria-label="Collapse context inspector from overlay"
aria-controls={id}
aria-expanded="true"
title="Collapse context inspector"
className="hidden h-7 w-7 shrink-0 items-center justify-center rounded-sm text-text-tertiary transition-colors duration-[var(--motion-hover)] hover:bg-bg-hover hover:text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand min-[761px]:flex min-[1181px]:hidden"
onClick={onCollapse}
>
<PanelRightClose size={15} aria-hidden="true" />
</button>
)}
</header>
<div className="flex shrink-0 border-b border-border-subtle px-2" role="tablist" aria-label={`${kind} context sections`}>
{tabs.map((tab, index) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ describe("InspectorToggleButton", () => {
let button = container.querySelector("button")!;
expect(button.getAttribute("aria-label")).toBe("Collapse context inspector");
expect(button.getAttribute("data-state")).toBe("expanded");
expect(button.className).toContain("max-[799px]:hidden");
expect(button.className).toContain("h-8");
expect(button.className).toContain("max-[760px]:hidden");
expect(button.className).not.toContain("border-border-default");
expect(button.querySelector(".lucide-panel-right-close")).not.toBeNull();

await act(async () => root.render(<InspectorToggleButton expanded={false} onToggle={() => {}} />));
Expand Down
27 changes: 11 additions & 16 deletions apps/web/src/components/features/InspectorToggleButton.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { PanelRightClose, PanelRightOpen } from "lucide-react";
import { PanelToggleButton, WORKBENCH_PANEL_TOGGLE_CLASS } from "./PanelToggleButton";

export function InspectorToggleButton({
expanded,
onToggle,
className = "flex h-8 w-8 shrink-0 items-center justify-center rounded-sm border border-border-default text-text-tertiary transition-colors hover:bg-bg-hover hover:text-text-primary max-[799px]:hidden",
iconSize = 15,
className = WORKBENCH_PANEL_TOGGLE_CLASS,
iconSize = 16,
}: {
expanded: boolean;
onToggle: () => void;
Expand All @@ -13,19 +13,14 @@ export function InspectorToggleButton({
}) {
const label = expanded ? "Collapse context inspector" : "Expand context inspector";
return (
<button
type="button"
data-state={expanded ? "expanded" : "collapsed"}
title={label}
aria-label={label}
aria-controls="context-inspector mobile-context-inspector"
aria-expanded={expanded}
<PanelToggleButton
side="right"
expanded={expanded}
label={label}
controls="context-inspector mobile-context-inspector"
className={className}
onClick={onToggle}
>
{expanded
? <PanelRightClose size={iconSize} aria-hidden="true" />
: <PanelRightOpen size={iconSize} aria-hidden="true" />}
</button>
iconSize={iconSize}
onToggle={onToggle}
/>
);
}
Loading