PDFs attach as OpenAI file parts; Anthropic/Gemini convert to their
native blocks. Models without native PDF support get a local fallback
at send time — pypdf text extraction or pypdfium2 page images, chosen
in Settings -> Token savings. Attach-time page/size thresholds
(default 20 pages / 10 MB) reject oversized PDFs with a notice.
Updater plugin with signed artifacts (minisign), latest.json composed by
release CI, update prompt in-app. Endpoints: download.opencoworker.app
with GitHub Releases fallback. Version 0.1.2.
- Boot: sidecar ships as a onedir bundle via the resources slot (onefile
self-extraction cost ~7s of splash every launch; now ~0.5s warm); build
scripts stage+sign the folder; splash wordmark aligned to the traffic
lights; minimumSystemVersion 12.0 (whisper.cpp build floor).
- Cloud sign-in: connection restore runs in the background after the
callback responds; GUI polls fast (500ms) while a sign-in is in flight.
- Onboarding: provider page keeps unsaved drafts across switches and shows
the connected state on the form; tools page rebuilt to the owner design
(value headline, Secure-by-design card, single primary action).
- Composer: OS file drags reach the existing drop handlers in the desktop
shell (native drag-drop interception disabled + window drop guards).
Notarization adds a minutes-long round-trip that local iteration doesn't
need — locally built DMGs carry no quarantine flag, so Gatekeeper never
prompts on the building machine. The flag signs (seconds) and skips
submit/staple with a do-not-distribute banner; unset identity remains the
fully-unsigned path.
Signing alone still leaves downloads facing macOS's 'Move to Trash' malware
dialog — notarization is what removes it (learned live 2026-07-15; spctl
rejected a signed-but-unstapled DMG). When APPLE_SIGNING_IDENTITY is set,
step 5 now signs the .dmg container, submits via notarytool with App Store
Connect API-key vars (exported, $OCW_NOTARY_ENV, or .ocw-notary.env one
directory above the repo — shared across clones/worktrees, never committed),
staples, and runs the same spctl assessment Gatekeeper runs on download,
failing the build rather than shipping the dialog. Missing vars degrade to
a signed DMG with a loud warning; unsigned dev builds are untouched.
A clean clone had no runnable backend and no instructions to create one —
the GUI README assumed platform/.venv existed and still described the
desktop shell as future work. Add setup_dev_env.sh (venv + editable
coworker install + the aisuite .pth this checkout's import wiring needs,
verified by booting the server to a 200 health check) and rewrite the
README's from-source flows: browser two-terminal dev and tauri dev, which
already falls back to the venv server when no packaged sidecar exists.
cp writes through a symlink at the destination. A dev-convenience
symlink left in binaries/ routed the freshly frozen sidecar into a
sibling worktree's venv, clobbering its console script; the bundle
stayed correct only because Tauri resolved the same link. rm -f first
makes the slot always end up a real file.
The relay client lazy-imports websockets inside connect(), so
PyInstaller's static analysis never bundled it — in the packaged app the
relay adapter failed to open its socket (no relay-conns, WS Lambdas never
invoked), while the OAuth install + relay-mode flip worked fine. Collect
websockets in the spec and declare it a runtime dependency.
The styled window never persisted into the image — earlier it only
looked right because THIS Mac's Finder remembered the layout per volume
name; a fresh mount (or a different machine) got the default bare window.
Two causes, both fixed:
- A stale "OpenCoworker" volume left mounted made our RW image mount as
"OpenCoworker 1", so the hardcoded `tell disk "OpenCoworker"` styled
the wrong volume and ours got no .DS_Store. Pre-detach the stale mount
and target the ACTUAL mounted volume name.
- Finder writes .DS_Store asynchronously; detaching too soon dropped it.
Do the close/open/update dance and poll until .DS_Store lands before
detaching. Background set via the relative .background:bg.tiff alias so
it survives a rename. Verified: .DS_Store is now inside the image.
The 1x PNG background was upscaled on Retina → hazy text, pixelated
arrow. Ship a HiDPI TIFF instead (1x + a natively-rendered 2x rep via
tiffutil -cathidpicheck), so Finder picks the sharp rep. Also dial the
proportions back per feedback: lighter/smaller title + subtitle, a thin
2px arrow with a small head, and 96px (was 128px) icons — a cleaner,
more Apple-like install window.
The plain `hdiutil create` opened the installer as Finder's default
oversized bare window with no guidance. Now build a laid-out window: a
background image (Install title + 'Drag the app onto the Applications
folder' + arrow), fixed 640x400 window, 128px icons with the app on the
left and Applications on the right, toolbar/statusbar hidden. Done via a
RW image + Finder AppleScript, then converted to compressed UDZO; falls
back to the plain image if Finder is unavailable (headless CI). Background
set by POSIX path (the HFS `file ".background:bg.png"` form errors -10006).
Building surfaced two undocumented prereqs the Windows script already
notes: a platform/.venv with pyinstaller + tzdata + typer (typer is
build-only — PyInstaller walks mcp.cli, which sys.exit()s without it and
aborts the freeze), and the APPLE_SIGNING_IDENTITY env var that makes
tauri sign the .app + bundled sidecar. Added the notarytool submit/staple
steps for finishing a public release. No behavior change.
Lint / build_and_test (3.10) (push) Has been cancelled
Lint / build_and_test (3.11) (push) Has been cancelled
Lint / build_and_test (3.12) (push) Has been cancelled
WhatsApp ships as a normal outbound-only connector (send message / send
template, both approval-gated) with the 24-hour window explained in the
wizard. The gating framework adds an experimental flag + risk_notice to
descriptors, an opt-in setting that hides experimental connectors until
enabled, a per-connector risk acknowledgment required at connect time,
and a separate connectors/experimental package that release builds strip
via the PyInstaller spec (COWORKER_EXPERIMENTAL=1 to self-build with it).
.github/workflows/release.yml builds the desktop installers by calling
the same packaging scripts developers run locally:
- matrix: macos-latest (Apple Silicon .dmg), macos-13 (Intel .dmg),
windows-latest (.msi + NSIS setup .exe)
- provisions Node 20, stable Rust (+ cache), Python 3.12 venv at
platform/.venv with the package, PyInstaller, typer/tzdata, and a
.pth for the repo-root aisuite package (mirrors local dev)
- tag push v* -> draft GitHub Release with all installers attached;
manual runs upload workflow artifacts only
- every installer is also uploaded under a stable name so the website
can deep-link releases/latest/download/<name>
- builds remain unsigned; signing/notarization slots in later without
touching the build scripts
build_dmg.sh now derives VERSION from tauri.conf.json (single source
of truth) instead of hardcoding it.
Cross-platform fixes so the desktop app and server run on Windows:
- Platform-native state dir (%APPDATA%) and OS-native secrets path surfaced in
the GUI/onboarding.
- Secrets file restricted to the current user on Windows.
- OS-native shell so the executor works on Windows; correct schedule timezones.
- Build and package the desktop app for Windows (NSIS + MSI).
Co-authored-by: Devika <dr.drp8226@gmail.com>
An agent harness built on aisuite's agent framework. Adds a coworker engine
with pluggable connectors (browser automation, integration tools), session
management, audit logging, and a permissions model, alongside a desktop GUI
surface (Tauri + React) and a multi-provider model layer with Ollama support.
Co-authored-by: Devika <dr.drp8226@gmail.com>