mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-14 18:39:33 +01:00
The Mac app showed one server at a time, and moving to another machine meant Switch Server and a fresh connect. Now every server gets a tab in the title bar, and every tab stays live. - Tab strip: a small bundled page (assets/tabs.html) in its own web view across the top of the window, with the traffic lights inset into it. Each tab has a colour and a status badge: a red count when sessions need you, an amber dot when they are waiting, a blue ring while they work, a dashed circle while the server does not answer. - The status comes from the app, not from the page: one thread per tab reads GET /api/sessions every 2 seconds (macOS stalls hidden web views), backs off for 60 s on a 429 and stops on 401/403, so a wrong password is never retried in a loop. - + or ⌘T opens the connect screen in a new tab. A server that is already open just brings its tab forward instead of opening twice, also when two connects race (checked again when the probe ends). - Double-click or the right-click menu renames a tab; the same menu sets the colour, reloads, reconnects, closes, or closes the others. Tabs can be dragged. A new Server menu carries ⌘T, ⌘W, ⇧⌘T (reopen closed tab, last 10), ⌘0, ⇧⌘[ / ⇧⌘] and ⌘1 to ⌘8 (⌘9 is the last tab once there are nine). Close Window moves to ⇧⌘W. Ctrl+Tab and Alt+1..9 stay with Codeman's own session switching. - ⌘0 shows every server at once (assets/overview.html): the ones that need you first, up to four sessions each with what they ask, and a click on a session opens its tab and selects it. - Tabs are saved in desktop.json (tabs, activeTab) and come back at launch, connecting by themselves when auto-connect is on. - Logins: each tab keeps its own Basic credentials, and a challenge is answered only with the login of the tab whose web view asked (macos.rs binds each WKWebView to its tab). - Cookies: on macOS 14 and later every server gets its own WebKit data store (WKWebsiteDataStore dataStoreForIdentifier, with a stable id hashed from the server URL), so a server on port 3000 and a beta on 5000 of the same host cannot log each other out. Before macOS 14 a second tab on a host that is already open is refused with a message. The server used last before this change keeps the default store, so its per-device settings (font size, skin) survive; every other server starts those fresh once. - The lid logo blink watches all open servers, and Keep This Mac Awake follows the tab that runs on this Mac. New pure model in src/tabs.rs (names, colours, order, shortcuts, strip and overview state) with unit tests; agents.rs reads the per-session detail for the badges and the overview; policy.rs parses the strip and overview IPC and refuses it from any other frame. Browser tests drive both bundled pages (test/desktop-tabs-pages.browser.test.ts) and the connect page's restored-tab path. Not yet run in a real window: the Mac mini has no screen session. The owner checks the traffic-light placement, clicks under the transparent title bar, window drag and zoom from the strip, keyboard focus after strip clicks, and two logged-in servers side by side. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
89 lines
4.0 KiB
TypeScript
89 lines
4.0 KiB
TypeScript
/**
|
|
* The test suites that `npm test` deliberately does NOT run, in one place.
|
|
*
|
|
* Why this file exists: the exclusion list used to live only in
|
|
* config/vitest.ci.config.ts, as literals. Anything excluded there was
|
|
* therefore reachable only by running the everything-config by hand and reading
|
|
* past its failures — and a newly excluded file was reachable by nothing at
|
|
* all, silently, because nothing pointed at it. Both configs now derive their
|
|
* globs from the arrays below, so adding a suite here puts it in exactly one
|
|
* runner and takes it out of exactly one gate.
|
|
*
|
|
* Adding a new test that cannot run in CI: put its glob in the array that
|
|
* describes WHY it cannot, not in whichever one is shortest.
|
|
*/
|
|
|
|
/**
|
|
* Playwright-driven: needs chromium and, in most cases, a live Codeman server
|
|
* on a real port. Deterministic where the environment provides both, which is
|
|
* why these are a runnable suite (`npm run test:browser`) rather than skipped.
|
|
*/
|
|
export const BROWSER_TEST_GLOBS = [
|
|
'test/wrapped-file-paths.browser.test.ts',
|
|
'test/command-palette-agent-arrows.browser.test.ts',
|
|
'test/voice-input.browser.test.ts',
|
|
'test/tmux-capture-sgr.browser.test.ts',
|
|
'test/tab-rail-resize.browser.test.ts',
|
|
'test/tab-activation.browser.test.ts',
|
|
'test/tab-layout-editing.browser.test.ts',
|
|
'test/tab-rail-search.browser.test.ts',
|
|
'test/tab-focus.browser.test.ts',
|
|
'test/session-sidebar-ux.browser.test.ts',
|
|
'test/header-divider.browser.test.ts',
|
|
'test/tab-strip-corner.browser.test.ts',
|
|
'test/header-host-sensors.browser.test.ts',
|
|
'test/session-options-responsive.browser.test.ts',
|
|
'test/inline-rename.test.ts',
|
|
'test/opencode-resize.test.ts',
|
|
'test/webgl-fallback.test.ts',
|
|
'test/terminal-copy-shortcut.test.ts',
|
|
'test/terminal-keycode229-recovery.browser.test.ts',
|
|
'test/capture-load-window.browser.test.ts',
|
|
'test/capture-geometry-retry.browser.test.ts',
|
|
'test/codex-predictive-echo.test.ts', // also needs a real codex binary
|
|
'test/split-pane-terminal.browser.test.ts',
|
|
'test/terminal-tile-scroll.browser.test.ts',
|
|
'test/codex-wheel-routing.browser.test.ts',
|
|
'test/terminal-touch-paging.browser.test.ts',
|
|
'test/shift-enter-keypress.browser.test.ts',
|
|
'test/key-tester.browser.test.ts',
|
|
'test/webhook-settings.browser.test.ts',
|
|
'test/case-custom-path.browser.test.ts',
|
|
'test/doctor-settings.browser.test.ts',
|
|
'test/git-status.browser.test.ts',
|
|
'test/edit-history.browser.test.ts',
|
|
'test/sync-case-state.browser.test.ts',
|
|
'test/split-pane-orchestration.browser.test.ts',
|
|
'test/split-pane-auto-collapse.browser.test.ts',
|
|
'test/spreadsheet-preview.browser.test.ts',
|
|
'test/mobile-ime-preview.browser.test.ts',
|
|
'test/run-mode-menu-scroll.browser.test.ts',
|
|
'test/markdown-anchor-links.browser.test.ts',
|
|
'test/fullscreen-tab-switch-capture.browser.test.ts',
|
|
'test/terminal-touch-swipe-axis.browser.test.ts',
|
|
'test/phone-press-feedback.browser.test.ts',
|
|
'test/desktop-connect-page.browser.test.ts', // no server: the page is served by request interception
|
|
'test/desktop-tabs-pages.browser.test.ts', // no server: the pages are served by request interception
|
|
'test/local-model-ui.browser.test.ts',
|
|
'test/home-breakpoint-swap.browser.test.ts',
|
|
'test/log-viewer-reconnect.browser.test.ts',
|
|
];
|
|
|
|
/**
|
|
* Wall-clock benchmarks. They assert on durations, so a loaded shared runner
|
|
* fails them for reasons that have nothing to do with the diff under test.
|
|
*/
|
|
export const PERF_TEST_GLOBS = ['test/perf-*.test.ts'];
|
|
|
|
/**
|
|
* Browser + visual regression: chromium AND environment-specific PNG baselines
|
|
* that are generated per machine. Has its own config
|
|
* (test/mobile/vitest.config.ts) because it needs serial execution, a longer
|
|
* timeout and the `pretest:mobile` vendor step — run it with
|
|
* `npm run test:mobile`, not through the configs here.
|
|
*/
|
|
export const MOBILE_TEST_GLOBS = ['test/mobile/**'];
|
|
|
|
/** Everything `npm test` skips. */
|
|
export const NON_CI_TEST_GLOBS = [...MOBILE_TEST_GLOBS, ...PERF_TEST_GLOBS, ...BROWSER_TEST_GLOBS];
|