No behavior change. What was written out two to four times now has one
name:
- AppWindow::new and AppWindow::hidden_for_download, window_builder,
placed_position (the corner tao places, which the frame save and the
pop-out cascade both read; cfg! instead of two attribute pairs),
file_name_of and UNNAMED_FILE for the download toast.
- page_sender, which in_background, attach_to_run and both install
starts use; plan_message and remote_install_failed for the connect
page's answers; open_external_raw for the two OpenExternal commands;
choosing() for the four phase checks.
- An accepted probe (Ok, or a password to change) runs one set of steps.
- macos::install runs inside build_webview, so no web view can be built
without the dialog and login handlers.
- ProbeDone no longer carries the Authorization header beside the
username and password it is made from; basic_auth makes it.
- Load::ConnectPage loses its manual flag, which was never true there.
- MIN_SIZE reads config's limits, the default username is
setup::DEFAULT_USERNAME, and the repository and wiki addresses live
in menu.rs.
- The module doc names the modules as they are now, and two doc comments
that had slid onto the wrong item are back on theirs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
main.rs was the only source file without tests, and it held three decisions
with real failure modes:
- Which login a connect goes out with. The choice was a closure body inside
the probe worker; it is now choose_login, tested for every row: typed wins,
then the Keychain, then the local Codeman's own login, which is used only
when no saved password was expected and only for the same username.
- What the Keychain keeps afterwards (update_keychain): saved or deleted by
Remember, never a copy of the local server's login, never a password the
server wants changed, and the old user's item deleted before the new save.
The in-memory Keychain store moves out of credentials' test module so other
test modules can use it.
- When a commit in the main window means the server page is loaded.
The connect page had only substring checks in the repository; the checks that
drove it lived in a scratch script. They are now
test/desktop-connect-page.browser.test.ts: Chromium, the page's real CSP, a
stubbed native side, five ordered walks through every state of both tabs
(first run, logins, failures, redirects, Start, the install wait, the SSH
install, layout, double clicks, keys, a starting server, a WebKit too old).
Listed in BROWSER_TEST_GLOBS, so the nightly browser suite runs it and
`npm test` does not.
Also pins the install one-liner the page shows to the one Copy copies.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds packages/desktop, a small native app (Rust: tao, wry/WKWebView, muda,
objc2) that opens Codeman in its own window. The universal app is about 5 MB
(3.2 MB as a DMG) and runs on macOS 11.3 or later.
- Connect screen with two tabs. This Mac finds the local Codeman and offers
Open, Start or Install. Start uses launchd for a LaunchAgent install and
codeman web -d otherwise. It never starts a second server while one runs,
because two servers on one data dir share live sessions. Another machine
connects by address (recent servers, Keychain logins) and can install
Codeman there over SSH.
- Installs run Codeman's install.sh in Terminal from a self-deleting
.command script. The installer needs a terminal for sudo, Homebrew and
ssh. A local install uses --local --service and the first free port from
3000, and the app opens Codeman once it answers.
- The local Codeman's login is read from its LaunchAgent or
~/.codeman/.env. It is sent only to 127.0.0.1 on that port, only while
the user's own Codeman process holds it, and is never saved.
- Native JS dialogs (alert, confirm, prompt) and HTTP Basic challenge
answers, both scoped to Codeman's own pages, so the page keeps working
after a server restart. App cookies are cleared before every connect.
- Pop-outs through window.CodemanHost, with an allowlist (webview/ never
opens a window), external links in the default browser, downloads to
~/Downloads, real full screen and window state that is remembered.
- The connect page refuses a WebKit older than Safari 16.4, which Codeman's
terminal needs.
Codeman side: viewSubagentTranscript shows a toast when the pop-up is
refused instead of failing, with zh-CN strings and a test that pins them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>