From 592140f22148191ee84ee24367e51274134926fb Mon Sep 17 00:00:00 2001 From: oratis Date: Thu, 28 May 2026 15:23:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20M6-rest=20part=202=20+=20M8=20voice=20?= =?UTF-8?q?=E2=80=94=204=20more=20desktop=20screens=20+=20whisper.cpp=20wr?= =?UTF-8?q?apper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two parallel pieces of polish. Core: · packages/core/src/voice/index.ts (NEW) — VoiceProvider interface + WhisperCppProvider (spawns whisper CLI, parses timestamped output) + StubVoiceProvider for tests / unconfigured installs. parseWhisperOutput is exported so format expectations are pinned. · 7 unit tests covering output parsing + spawn-via-fake + missing-file + non-zero-exit cases. Desktop: · apps/desktop/src/components/Nav.tsx (NEW) — top tab bar for REPL/Chat/Sessions/MCP/Settings. · apps/desktop/src/screens/Sessions.tsx — list + filter + new-session button (IPC wired in next M6-rest PR). · apps/desktop/src/screens/Settings.tsx — flat-key view of settings.json with filter. · apps/desktop/src/screens/MCPManager.tsx — list of connected servers + JSON snippet for adding one. · apps/desktop/src/screens/Chat.tsx — REPL + (hidden lg-only) file panel placeholder pointing at M7. · apps/desktop/src/App.tsx — routes to the active screen. · apps/desktop/src/index.css — additional utility classes for the new layouts (lg:block, w-1/3, border-l, hover:*, font-mono, table). Tests: core 438 → 445 (+7 voice); cli 47 unchanged; scripts 16 unchanged. Total 501 → 508 passing. Build clean across all 4 packages. Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/desktop/src/App.tsx | 22 +++- apps/desktop/src/components/Nav.tsx | 39 +++++++ apps/desktop/src/index.css | 24 +++++ apps/desktop/src/screens/Chat.tsx | 27 ++++- apps/desktop/src/screens/MCPManager.tsx | 90 +++++++++++++++- apps/desktop/src/screens/Sessions.tsx | 91 +++++++++++++++- apps/desktop/src/screens/Settings.tsx | 86 ++++++++++++++- packages/core/src/index.ts | 11 ++ packages/core/src/voice/index.test.ts | 95 +++++++++++++++++ packages/core/src/voice/index.ts | 133 ++++++++++++++++++++++++ 10 files changed, 596 insertions(+), 22 deletions(-) create mode 100644 apps/desktop/src/components/Nav.tsx create mode 100644 packages/core/src/voice/index.test.ts create mode 100644 packages/core/src/voice/index.ts diff --git a/apps/desktop/src/App.tsx b/apps/desktop/src/App.tsx index 5250e15..846b117 100644 --- a/apps/desktop/src/App.tsx +++ b/apps/desktop/src/App.tsx @@ -1,17 +1,23 @@ // Top-level React component for desktop client. // Spec: docs/VISUAL_DESIGN.html -// Milestone: M6 skeleton — onboarding + REPL placeholder + update banner +// Milestone: M6-rest — Onboarding gate + Nav + 5 screens import { useEffect, useState } from 'react'; +import { Nav, type ScreenName } from './components/Nav.js'; +import { UpdateBanner } from './components/UpdateBanner.js'; +import { ChatScreen } from './screens/Chat.js'; +import { MCPManagerScreen } from './screens/MCPManager.js'; import { OnboardingScreen } from './screens/Onboarding.js'; import { ReplScreen } from './screens/Repl.js'; -import { UpdateBanner } from './components/UpdateBanner.js'; +import { SessionsScreen } from './screens/Sessions.js'; +import { SettingsScreen } from './screens/Settings.js'; import type { UpdateInfo } from './types/global.js'; export function App(): JSX.Element { const [version, setVersion] = useState(''); const [hasKey, setHasKey] = useState(null); const [update, setUpdate] = useState(null); + const [screen, setScreen] = useState('repl'); useEffect(() => { void window.deepcode.version().then(setVersion); @@ -35,9 +41,21 @@ export function App(): JSX.Element { DeepCode v{version} + {hasKey &&