文件历史

12 次代码提交

作者 SHA1 备注 提交日期
Rohit C Prasad efb0701edf connectors: wire outlook to the managed microsoft OAuth path
One-click connect failed with "outlook has no managed OAuth path" — the
connector→provider map never got an outlook entry, though the descriptor,
broker provider, and scopes were all ready. Guard test now asserts every
managed connector has a mapping.
2026-07-19 14:56:15 -07:00
Rohit C Prasad 0f514d34fb Rebrand user-facing surfaces to OpenWorker
App name, bundle identifier (com.openworker.desktop), publisher, updater
endpoint + release artifact names, DMG background art, GUI/server copy,
scratch dir default, README + quickstart. Auth0 tenant domain and API
audience keep their registered legacy identifiers on purpose; internal
ids (ocw event names, env vars, relay stage) are unchanged.
2026-07-17 13:56:06 -07:00
Rohit C Prasad 8704339d5b Fix five owner-reported UX issues: boot splash, sign-in latency, onboarding, drag-drop
- 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).
2026-07-16 12:50:28 -07:00
Rohit C Prasad 9553e0c0c1 Apply black formatting repo-wide 2026-07-14 22:11:09 -07:00
Rohit C Prasad e0f8bac9f1 Squash commit with multiple features and fixes.
Short list of changes -
- Automations quickstart
- Slack mentions router
- Live turns keep narration inside. Add commentary for tasks.
- Approvals card UI enhancements
- Newer models - Fable, Sol, Terra, etc added to list
2026-07-14 16:51:52 -07:00
Rohit C Prasad 68b58222ed Sign-in: token exchange must present the same redirect_uri as authorize
The broker-bounce change (eda23c9, 07-09) pointed the authorize leg's
redirect_uri at the broker's stable callback but left the token
exchange sending the old loopback URI. RFC 6749 requires the exchange
redirect_uri to byte-match the authorize one, so the auth server
rejected every exchange — all cloud sign-ins since 07-09 failed with
'token exchange failed' after a successful browser leg (caught by the
owner's fresh-install walkthrough; also explains the earlier onboarding
Slack-connect failure, which begins with sign-in).

The unit test now derives the redirect_uri from begin_login's authorize
URL and pins the exchange to it — the old test mocked the POST without
asserting redirect_uri, which is exactly how this slipped.

708 pytest green.
2026-07-13 12:51:20 -07:00
Rohit C Prasad e49e07f02f Sign-in: route the Auth0 callback through the broker bounce
begin_login used config.port (8765) for the loopback redirect, but the
packaged shell runs the sidecar on a random free port — Auth0 finished
and the browser hit a port nobody was listening on ("Firefox can't
connect"), the same bug the connector flow fixed via COWORKER_PORT.
Loopback can't simply follow the real port because Auth0 rejects
unregistered ports, so the redirect now targets the broker's stable
/v1/auth/callback and the actual port rides as state's `.port` suffix;
the broker bounces the browser home and GET /auth/callback completes
PKCE unchanged.
2026-07-13 12:21:12 -07:00
Rohit C Prasad 9be6e881c9 Desktop GitHub relay: shared-hub adapter, minted tokens, reply/review tools (MG3a)
The desktop half of the GitHub App relay (github-relay-spec §13 Step 3):

- relay_client.py: extract RelayHub — ONE authenticated cloud socket owns
  the transport/read-loop/reconnect watchdog; frames fan out by provider
  tag. SlackRelayAdapter becomes its first consumer (public surface
  unchanged); GitHubRelayAdapter its second. Also pin the relay tests'
  name resolution to a dead loopback port — unstubbed lookups were
  reaching slack.com and intermittently blowing the 2s dispatch window.
- github_relay.py: GitHubRelayAdapter — github:owner/repo#N addressing,
  installation_id rides source.team_id so the gateway's per-team
  allow-list (park → allow & deliver) applies per installation unchanged;
  missed/revoked frames handled; send() posts an issue/PR comment with a
  minted installation token.
- github_installs.py: github:install:<id> profiles (metadata ONLY — no
  token field by design), default pointer + per-installation allow-lists
  on the profile; last-removal turns relay off without resurrecting a
  stored manual PAT.
- cloud.py: github_installation_token — memory-only ~50-min cache, force
  re-mint for the 401 path, never written to the secret store;
  per-installation cloud disconnect; managed-connect flow passthrough.
- Managed OAuth callback branch (token-less by design, so it precedes the
  access_token check) + gateway hot-add; per-installation disconnect and
  status routes; allow-list edits target github:install:<id>.
- Tools: _github_call resolves auth per repo owner — manual PAT wins
  untouched, managed profiles mint and re-mint once on 401; new
  github_reply + github_review (approval-gated). The §12.5 write ceiling
  is enforced by what exists: no push/delete/settings tools on any path.
- github descriptor: two_way + managed.

655 pytest + 23 vitest green; 13 new tests cover install callback,
per-installation allow-lists, hub fan-out, missed/revoked, addressing,
send, token cache/re-mint, tool auth on both paths.
2026-07-13 12:21:12 -07:00
Rohit C Prasad 83cbe9688a Gmail multi-account + Never-show-agents privacy filters
Accounts: each sign-in lands in its own gmail:account:<email> profile;
gmail:default shrinks to the default pointer + filters. A legacy token-bearing
default migrates lazily into one account (no user action). The three gmail
tools take an optional account argument (default fallback), name the mailbox
in results and approval args, and broker refresh targets account-keyed
profiles.

Filters: senders (addr or @domain) and label names, enforced in the DESKTOP
tool layer - matching messages silently omitted from search, a direct fetch
reads like a real 404, no tombstone an agent could probe. The hidden count
rides a _display sidecar on the tool-result message (mirroring source):
persisted for the GUI, stripped from every provider feed, audited as
rule+count, and shown on the tool card / step-group line.

GUI: GmailDetail page (Accounts with Default badge + per-account disconnect,
one-click add, filter chip rows, collapsed Tools); routes for account
disconnect/default and PATCH filters.
2026-07-13 12:21:12 -07:00
Rohit C Prasad 3ebda97473 Managed OAuth: redirect to the sidecar's actual port, not config.port
The desktop shell runs the sidecar on a random free port (to coexist
with a hand-run server on 8765), but begin_managed_connect built the
loopback redirect from config.port (default 8765). In the packaged app
the OAuth callback therefore hit port 8765 — a different process (or
nothing) — instead of this sidecar, so managed connect failed for every
connector. run.py now publishes the real bound port as COWORKER_PORT and
the redirect follows it. Regression test added.
2026-07-13 12:17:13 -07:00
Rohit C Prasad 4c699e62c0 Persona gallery. Tests, and squashed other changes. 2026-07-13 08:30:31 -07:00
Rohit C Prasad 293c0e2929 Cloud sign-in + managed one-click connectors (desktop side)
Phase 3 of the cloud platform spec. The sidecar gains the two loopback
routes: GET /auth/callback completes Auth0 PKCE sign-in (started via
POST /v1/cloud/login, which opens the system browser), and
POST /oauth/callback receives the broker's form-POSTed token payload and
writes a connector profile through the managed setup path. Profiles are
field-compatible with manual paste; managed extras (refresh_token,
connection_id) enable broker refresh — hooked into the tools' _profile
choke point so managed tokens renew just before expiry — and best-effort
cloud metadata disconnect.

Sign-in is strictly optional: manual token paste works signed out and
stays available after sign-in (one-click is an addition, never a
replacement). Managed capability ships for gmail + google_calendar;
other providers join with their Phase 4 waves.

GUI: cloud account card on Integrations ▸ Connectors, one-click connect
button on managed connectors when signed in, manual fields always
rendered. Cloud endpoints are config values (cloud_base_url etc.), never
constants. Tests: 18 python + 2 e2e.
2026-07-13 08:27:26 -07:00