Commit Graph
697 Commits
Author SHA1 Message Date
ZacharyZhang-NY 5aff9dd606 Make the pause toggle a standard topbar button
The pause control was a hand-rolled pill (999px radius, its own
padding and font size) sitting next to the standard "New task" button,
so the two never matched. It now renders as the shared .button class -
one source of truth for height, padding, and corner radius - with a
single amber modifier for the paused state. Verified side by side in
the captured Work-page screenshot.
2026-07-09 00:14:34 -04:00
ZacharyZhang-NY cb71afa6b7 Avatar photo uploads and a global handbrake for the agent engine
Two operator asks, one review gate:

Avatar portraits (migration 052): the avatar editor gains "Upload
photo" - the renderer downscales the chosen picture to a ~96px cover
crop and stores it as a small data URL (PNG keeps transparency, the
rest compresses to JPEG), so the snapshot stays light and the CSP needs
nothing new. The portrait wins over emoji and initials everywhere the
shared Avatar renders (chat, org chart, office card, sidebar), and
"Remove photo" falls back cleanly. The main process validates scheme
and size (base64 image data URL, <=300k chars) so a rogue caller cannot
re-bloat the snapshot. e2e uploads a real PNG through the profile
dialog and sees the portrait land in the sidebar.

Global pause (migration 053): when agents start talking in circles,
one topbar toggle - visible on every page - pulls the handbrake.
app_state.autorun_paused survives restarts; the queue worker checks it
each tick and neither enqueues nor claims while set (the run already in
flight finishes). Queued work simply waits and the paused state renders
as an amber "resume" pill. A unit test drives the real worker: paused
leaves a queued run untouched through many ticks, resuming claims it
within moments; e2e flips the toggle in the live shell.
2026-07-09 00:09:02 -04:00
ZacharyZhang-NY 78e88807da Give chat a real scroll contract: open at latest, stick, jump back
The conversation pane had no scroll management at all - it opened at
the top of history, ignored arriving messages, and offered no way back
down other than dragging through long replies.

- Opening a conversation lands on the newest message (the component is
  keyed by space, so mount = open)
- A reader at the bottom stays pinned as new messages arrive; a reader
  up in history is left undisturbed
- The moment the reader leaves the bottom, a floating "Jump to latest"
  pill appears above the composer; clicking it smooth-scrolls back and
  the pill hides itself again
- The scroll region is a proper role="log" landmark; e2e seeds a dozen
  multi-line messages over real IPC, scrolls to the top, and drives the
  pill's appear -> click -> return-to-bottom -> disappear cycle
2026-07-08 23:55:52 -04:00
ZacharyZhang-NY 9834714fa6 Renderer sweep round two: survive orphans, hiccups, and busy inboxes
The renderer half of the project review surfaced five real defects:

- One unresolvable message sender or mention target blanked the whole
  Messages page mid-render; both now degrade to a visible "Former
  member" placeholder instead of throwing
- A failed initial snapshot load left a permanently blank window with a
  swallowed rejection; loads now log loudly and retry every 1.5s until
  the main process answers
- With no conversation selected, the view followed the recency sort:
  any incoming message yanked the visible conversation to the newest
  space and marked it read unseen. The implicit default now pins itself
  once (render-time state adjustment)
- The avatar directory keyed names across ALL organizations, so a
  same-named principal in another org hijacked the custom avatar; it
  now scopes to the active org
- The conversation search query survived switching spaces, silently
  filtering the new space by the old term; ChatConversation is keyed by
  space id so per-space UI state resets

Also verified clean by the same sweep: no lingering references to the
removed snapshot fields, no stale closures in the office rAF loop,
org-chart zoom math, and the chat message ordering invariant is
guaranteed at the data layer (created_at desc limit + reverse).
2026-07-08 23:50:17 -04:00
ZacharyZhang-NY 04093c4869 Harden the seams a project sweep surfaced
A systematic review of the whole codebase (main process, renderer,
IPC/migration/packaging seams) surfaced four real defects; each is
fixed at its root:

- Legacy catalogue drift: the operator's profile still carried 89
  active skills from the removed ~/.agents import era next to the 228
  built-ins. Catalogue sync now mirrors the bundle - actives whose slug
  the bundle does not ship retire (bindings keep resolving via their
  pinned revisions; retired skills leave list_skills and cannot be
  granted anew)
- Broken-bundle guard: staging now refuses a bundle without the
  humanizer skill, so an empty or quarantined resources folder can
  never trigger the mirror pass into retiring a healthy catalogue
- Duplicate agent names: @mentions, DM routing, and task assignment all
  resolve by name, so createAgent and updateAgent renames now reject a
  name already held by an active agent (case-insensitive); the mention
  resolver still refuses to guess between legacy duplicates
- Stale DM titles: agent-to-agent conversation rows titled themselves
  from the frozen creation-time space name, so renames never reached
  the sidebar; direct titles now derive from members' current names

Verified clean in the same sweep: IPC surface (82 channels, handler +
preload + api aligned), per-migration transactions with rollback,
quota-parking month rollover, retry-budget counting, meeting spot
reuse across floor-plan rebuilds.
2026-07-08 23:41:51 -04:00
ZacharyZhang-NY c50f17190c Animate the whip: a crack at the strike point and a flinch on the target
Every whip click now lands visibly, wherever the target is standing:

- simulation.whip() always registers a WhipCrackEffect at the struck
  agent and starts their hit reaction; step() ages both away. The
  discipline rule is unchanged - only snack-bar/restroom slackers are
  sent hustling home; desk, CEO office, and meeting stay safe
- office-renderer draws the strike: a lash sweeping in from the upper
  right that collapses into an impact starburst with an expanding ring
  (~450ms), while the struck agent shakes with anime-style pain sparks
  over their head (~600ms), fading as the flinch drains
- The office e2e now collects pageerror during the run and lets the
  effect play out after a whip-mode click, so a throwing frame in the
  rAF loop fails the suite instead of dying silently
2026-07-08 23:41:33 -04:00
ZacharyZhang-NY 1f89ea7089 Stop shipping megabytes of skill prompts in every snapshot refresh
The whole app turned to molasses because snapshot.load() shipped the
entire skill_runtime_snapshots table - unbounded, compiled_prompt
included - over IPC on every refresh. A real profile carried 142 rows
totaling 144MB (1.1MB each from the pre-cap CEO compile-all era), so
every coalesced refresh serialized ~144MB of JSON. The forced-humanizer
rework made it worse by adding a row per run for every agent.

- Drop skillRuntimeSnapshots, skillRevisions, skillTests, and
  skillBindings from the renderer snapshot: no renderer surface reads
  them; skill internals are main-process state. Only the lightweight
  skillDefinitions catalogue still ships.
- Project provider_requests without raw_response_json (4.1MB across the
  newest 100 rows; RunsPage only reads responseText)
- Migration 051 purges the bug-era compiled prompts from existing DBs
- resolveRuntimeSnapshot is now idempotent per run: a run re-queued by
  startup recovery reuses its frozen snapshot instead of dying on the
  uniqueness guard and burning real retry budget
- Regression test pins the contract: a 2MB database row must not add
  bytes to the snapshot (payload asserted under 400KB)
2026-07-08 23:20:56 -04:00
ZacharyZhang-NY 4ab20e679c Add the whip to the office toolbar: slackers hustle back to their desks
- New bottom toolbar on the pixel office floor with a Whip tool;
  toggling it turns the cursor to a crosshair, clicks whip instead of
  opening the detail card, Escape puts the whip away
- Simulation.whip(): an agent inside the snack bar or restroom drops
  whatever they are carrying and hustles back to their desk at 1.8x
  speed for a few seconds; agents at their desks, in the CEO office,
  or in the meeting room are working and stay untouched
- Room membership decides the outcome (rectContains against the same
  floor-plan rooms the renderer draws), so the rule matches what the
  player sees
- Unit tests cover the whip matrix; e2e drives the toolbar toggle in
  the live shell
2026-07-08 21:51:47 -04:00
ZacharyZhang-NY 2bb2acd635 Grow a real OKR company: officers, departments, ranks - and a stable chart
Researched how OKR-run companies cascade (company objective -> C-suite
officers per function -> department objectives -> individual key
results) and encoded that shape into how the CEO builds the org.

- hire_agent gains seniority (director/lead/staff; c_suite stays
  reserved for the CEO's privileges) and a business-card title, so the
  CEO hires a CTO/CFO/CMO as directors instead of a flat pool of ICs
- CEO persona + goal kickoff now direct the OKR cascade: hire 2-4
  officers, hand each a department objective, let them build teams;
  department heads get their own doctrine (hire leads/staff, cascade
  key results as tasks, report up)
- Migration 050 adds Finance and Sales to every org's canonical
  departments (backfilled for existing DBs) so a real C-suite has
  somewhere to hire
- Org chart viewport is a fixed-height scroll region: zooming rescales
  the diagram inside it instead of resizing the card
- Unit test drives a live three-level chain: CEO -> CTO (director) ->
  Engineering Manager (lead) -> staff, with rank/title persisted
2026-07-08 21:47:07 -04:00
ZacharyZhang-NY c3924af9ac Office life: everyone roams, meetings convene in pairs, card follows agent
- The detail card now rides beside the clicked agent (flipping and
  clamping at viewport edges via a pure cardPositionFor helper) instead
  of pinning to the top-right corner; it follows a walking agent
- Every agent - the CEO and busy agents included - periodically visits
  the coffee machine, snack bar, and restroom; work status no longer
  recalls a walker mid-break
- The office convenes meetings around the meeting table every few
  minutes: at least two settled attendees walk over, dwell together on
  distinct table spots, and head back; a solo office never meets
- Meeting spots ship as lane-wired amenities so pathing stays correct
  by construction; floor-plan invariants (collider-free, reachable)
  cover them automatically
- e2e asserts the card opens beside the sprite, not in a corner
2026-07-08 21:40:53 -04:00
ZacharyZhang-NY e55b8b85b0 Make every identity editable: agent and operator names plus avatars
- Migration 049: avatar_emoji/avatar_color on agents and employees
- updateAgent accepts a new name (mention-name validated) and avatar;
  new updateEmployeeProfile renames the operator and sets their avatar
- Avatars are emoji-on-color tiles (renderer CSP blocks remote images);
  an AvatarDirectoryContext built from the snapshot lets the shared
  Avatar component honor custom looks at every call site - chat rows,
  conversation list, org chart, office card, sidebar - without
  threading props through pages
- Team edit dialog gains Name + avatar editor (CEO included); the
  sidebar foot opens an Edit-profile dialog for the operator
- e2e: rename an agent to a new mention handle with an emoji avatar,
  edit the operator profile, both verified in the live shell
2026-07-08 21:33:23 -04:00
ZacharyZhang-NY 86aa6fdb29 Ship skills built-in: bundle the catalogue, assign per hire, force humanizer
Skills no longer come from the user's ~/.agents library - most users have
none, and the CEO branch that compiled the entire catalogue into its
prompt overflowed the model context (1.1MB) and failed every CEO run.

- Bundle "built-in skills/" with the app (extraResources) and stage it
  at startup into <profile>/builtin-skills as one dir-per-skill copy -
  both bundle shapes (SKILL.md dirs and flat category .md files)
  normalize into the same importable layout
- Import the staged catalogue per org at startup and inside onboarding,
  so the CEO's first run already carries it
- Forced house style: resolveRuntimeSnapshot unions the humanizer skill
  into every agent's runtime (CEO included) as a resolution rule - no
  binding row to forget, delete, or bypass; revoke_skill refuses it
- CEO staffs hires with skills: hire_agent accepts a skills array,
  grant_skill/revoke_skill adjust later, list_skills now shows
  descriptions from skill frontmatter
- Kill the c_suite compile-all branch; everyone resolves bindings-only,
  capped at 200k chars with omissions named in the prompt
- Remove the Skills settings page and its import/sync/test IPC surface;
  drop ~/.agents discovery and the AGENTCOMPANY_NEW_SKILLS_ROOT seam in
  favor of AGENTCOMPANY_NEW_BUILTIN_SKILLS_DIR
- Tests: staging/import/forced-resolution/cap units, real-bundle CI
  check, e2e asserts the tab is gone and the catalogue self-imports
2026-07-08 21:18:50 -04:00
ZacharyZhang-NY 55c043f8b4 Answer plain user messages in channels via a channel-anchor wake
A human message in a channel woke agents only through @mentions, DM
counterparts, or prior thread participants - and the flat composer
always sends threadId=null, so typing in #general summoned nobody and
the room stayed silent.

- Track which agents each wake path summoned in one woken set (also
  prevents latent double-wakes between the paths)
- When a non-slash human message in a channel wakes nobody, wake the
  channel's most senior active agent member with an enabled provider
  (c_suite > director > lead > staff, then hire date); they can pull
  teammates in with @mentions
- Log when a channel has no runnable agent so silence is diagnosable
- Integration test: plain #general message wakes the CEO who replies;
  an explicit mention still wakes exactly one agent
2026-07-08 20:58:17 -04:00
ZacharyZhang-NY 349547a0de Resume parked work when a provider's monthly limit is raised
The heartbeat scheduler enqueued runs even while a provider's monthly
usage window was full, so every task burned its 3-attempt retry budget
on instant quota failures within seconds and stayed dead forever -
raising the limit (or restarting) never revived anything.

- Park tasks (skip enqueue) while their provider is at its
  monthly_request_limit instead of creating runs doomed to fail
- Exclude quota-blocked failures from the 3-attempt retry budget,
  retroactively reviving tasks abandoned by past filled windows
- Share the gate message as PROVIDER_MONTHLY_LIMIT_MESSAGE and log
  quota-block transitions once per state change for diagnosability
- Ignore landing/ (self-contained Next.js sub-project) and
  built-in skills/ (prompt content) in eslint so verify:ci lints only
  application code
2026-07-08 20:51:24 -04:00
ZacharyZhang-NY 155c08b16d Language picker on the onboarding welcome step; agents work in the app language 2026-07-07 15:59:16 -04:00
ZacharyZhang-NY a95859a9f7 Brief agents on their connectors, skills, and the CEO's grant authority; CEO predicate follows role_level 2026-07-07 14:19:08 -04:00
ZacharyZhang-NY 3e4c7c81a2 Localize the renderer UI into Chinese behind the language setting 2026-07-07 13:22:19 -04:00
ZacharyZhang-NY d404e1e72a Pin the UI locale to the language setting and add theme + language selectors with a dark palette 2026-07-07 12:28:06 -04:00
ZacharyZhang-NY b30b9a3bc1 Work list titles clip instead of colliding; timeline becomes segmented status bars per goal and project 2026-07-07 12:16:36 -04:00
ZacharyZhang-NY 38bd3588e7 Connected connectors can be deleted and reconnected; mirror sweeps stale rows and ops serialize per org 2026-07-07 12:09:31 -04:00
ZacharyZhang-NY eb16baff50 Flatten the sidebar: Office under Team, Connectors under Approvals, no divider 2026-07-07 11:44:15 -04:00
ZacharyZhang-NY defe8f12b1 Make the CEO the grant authority: implicit all-access, agent-tool grants, no manual assignment UI 2026-07-07 11:24:28 -04:00
ZacharyZhang-NY 934fa71486 Add a post-launch connectors step to onboarding 2026-07-07 11:15:03 -04:00
ZacharyZhang-NY 00e05054ca Mirror the Composio project's auth configs as the connector catalog with logo.dev icons 2026-07-07 11:06:07 -04:00
ZacharyZhang-NY dde449d226 Hardcode the Composio key in app source; drop cred.txt and build-time injection 2026-07-07 10:03:26 -04:00
ZacharyZhang-NY ae27317aad Commit cred.txt so every checkout builds with the Composio key 2026-07-07 10:00:31 -04:00
ZacharyZhang-NY 0ec13e3e3a Remove threads from Messages: every conversation is flat
All messages already render chronologically in the channel pane, so the
thread affordance only duplicated them behind a second view. The reply
chip, the in-place thread pane, and the thread composer are gone;
ChatThreadView is deleted and the thread props are removed from the
conversation, timeline, and message-row chain. Message writes are
untouched.
2026-07-07 01:58:11 -04:00
ZacharyZhang-NY d19573187c Fix connector Connect: use the link flow and surface failures
Root cause found by probing the live API: Composio v3 rejects
POST /connected_accounts for Composio-managed OAuth auth configs with a
400 pointing at POST /connected_accounts/link, and the renderer threw
the failure away inside a .then, so clicking Connect did nothing and no
browser opened.

- createConnectedAccount now calls POST /connected_accounts/link with
  auth_config_id and user_id and reads connected_account_id and
  redirect_url; the local mirror records INITIALIZING until the poll
  adopts Composio's real status.
- Connect failures (and a blocked external-URL open) now show as a
  single line on the page instead of vanishing.
2026-07-07 01:53:22 -04:00
ZacharyZhang-NY a2de132083 Embed the Composio key in the app bundle instead of shipping cred.txt
Root cause of the recurring 401: a revoked key was hardcoded in
startup-recovery.ts and onboarding-service.ts and reseeded into
composio_settings on every launch, and the interim fix shipped cred.txt
as a visible file under resources/.

- electron.vite.config.ts reads the gitignored cred.txt at build time
  and injects the key into the main-process bundle as
  __COMPOSIO_API_KEY__; no credential file is packaged and the key is
  not user-visible or configurable. The renderer bundle never sees it.
- Delete both hardcoded-key seeders; migration 046 purges stored
  api_key and never-read toolkits rows while keeping entity_id and
  auth_config state.
- Stop shipping composio_settings in the renderer snapshot.
2026-07-07 01:40:19 -04:00
ZacharyZhang-NY 2d43950123 Read skills from the global and workspace .agents/skills directories
- Discover skill directories under ~/.agents/skills and each
  workspace''s .agents/skills; a directory qualifies with a full
  skill.manifest.json or just a SKILL.md, whose manifest is derived
  (frontmatter name or the directory name). Paths resolve per platform
  on Windows, macOS, and Linux.
- Sync at startup for every organization and again when the Skills
  page opens; skills the org already carries are skipped, and one
  broken directory cannot block the rest.
- AGENTCOMPANY_NEW_SKILLS_ROOT points tests at a temporary library
  (overriding USERPROFILE crashes Electron on Windows).
2026-07-07 01:21:33 -04:00
ZacharyZhang-NY 256e0680c6 Ship Composio as a built-in integration and trim Settings
- Resolve the API key from cred.txt at the project root in development
  and the packaged resources directory in production; the file is the
  source of truth, so a rotated key replaces the stored one. Fixes the
  401 packaged builds hit when a stale database key won.
- Remove the user-facing Composio key editor; the key ships with the
  product and is not configurable.
- Remove the Migration console from Settings.
- Remove the Connectors and Home refresh buttons; connector statuses
  sync when the page opens.
2026-07-07 01:20:21 -04:00
ZacharyZhang-NY 947cd8605b Center the CEO screen and meeting whiteboard between their windows
Both hung overlapping the right-hand window; each now sits centered in the
gap between the two window frames.
2026-07-07 00:46:20 -04:00
ZacharyZhang-NY 370582df90 Drop the Documents surface - Files already owns that ground
Documents duplicated what Files surfaces; the nav item, route, and page go.
Agent-authored documents keep flowing through the document service,
deliverable review, and search.
2026-07-07 00:46:20 -04:00
ZacharyZhang-NY 8fef89a22e Let a rotated cred.txt key win over the stale stored one
The credential file only seeded the database when it was empty, so once a
key was stored, rotating it in cred.txt changed nothing and Composio kept
rejecting the dead stored key with 401 - while the file held a freshly
generated, verified-working key. The file is now the source of truth
whenever it exists: a differing key replaces the stored one on resolution,
and packaged installs without the file keep managing the key in Settings.
Four resolution contract tests pin seed, rotation, settings-only, and
absent cases; the Connectors error line truncates instead of wrapping the
raw API response across the page.
2026-07-07 00:46:19 -04:00
ZacharyZhang-NY 62e663ed90 Open threads in place - the duplicate side panel is gone
The right-hand thread panel repeated exactly what the flat timeline already
showed. Opening a thread now focuses the center pane itself: back control,
board state, the root message with its replies, board intervention
controls, and a thread reply composer - one conversation surface, never
two. The release contract also catches up with the icon shipping inside
the package, a pin the icon commit should have updated.
2026-07-07 00:35:42 -04:00
ZacharyZhang-NY 3246ea5f98 Give AgentCompany its own face: the pixel office tower icon
A new icon generated for the brand: an isometric pixel-art office building
with warm lit windows and the app's violet-blue accent wall on deep indigo -
the office floor is the product's signature, now it is the identity too.
The generated artwork is rebuilt into a clean 1024 square master
(resources/icon.png, Linux and the packaged base), a Big Sur rounded
variant with transparent corners for macOS (icon-mac.png), and a
multi-size Windows icon.ico (16-256). electron-builder wires each platform
to its variant, the icon ships inside the package, and Windows/Linux
windows carry it at runtime including dev. Verified by extracting the icon
back out of a packaged AgentCompany.exe.
2026-07-07 00:15:12 -04:00
ZacharyZhang-NY 07d0b4587d Promote AgentCompany-New to the repository root and retire the old app
The legacy application - its src, tests, landing site, promo assets, docs,
release tooling, CI workflows, and root configs - leaves the tree; it stays
reachable in history. Everything under AgentCompany-New moves up unchanged:
same package name, so the production userData/database path is untouched,
and e2e/build scripts already resolved paths relative to the project. The
developer cred.txt stays gitignored at its new location. Full verify:ci
passes from the new root.
2026-07-07 00:04:13 -04:00
ZacharyZhang-NY 810e2d5967 update 2026-05-15 19:40:20 -04:00
ZacharyZhang-NY 2ab001b18a fix(security): require https for trusted links 2026-05-15 02:56:25 -04:00
ZacharyZhang-NY 4e5af2b45f fix(settings): guard disabled model reads 2026-05-15 02:53:13 -04:00
ZacharyZhang-NY 0a107af014 fix(security): omit agent token fingerprints 2026-05-15 02:49:40 -04:00
ZacharyZhang-NY c20d3942a8 fix(security): sanitize credential test logs 2026-05-15 02:44:50 -04:00
ZacharyZhang-NY b92cf62c4c fix(data): canonicalize operation json fields 2026-05-15 02:36:19 -04:00
ZacharyZhang-NY 10c1f6d103 fix(api): preserve meeting patch fields 2026-05-15 02:25:24 -04:00
ZacharyZhang-NY 9d4af15d4b fix(browser): limit retained action screenshots 2026-05-15 02:21:16 -04:00
ZacharyZhang-NY b5a6a1a9ea fix(browser): settle timed out actions 2026-05-15 02:17:10 -04:00
ZacharyZhang-NY 7b54fe54a8 fix(security): materialize complete skill packages 2026-05-15 01:36:16 -04:00
ZacharyZhang-NY f5b3de438e fix(security): limit skill URL import reads 2026-05-15 01:18:44 -04:00
ZacharyZhang-NY 0cbaabf937 fix(security): bound skill URL redirects 2026-05-15 01:07:43 -04:00
ZacharyZhang-NY 6ae506bf73 fix(security): preserve SNI for skill URL fetches 2026-05-15 01:04:41 -04:00