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.
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.
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.
- 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).
- 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.
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.
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.
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.
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.
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.
Deliverable and document tools move to agent-deliverable-tools, the three
argument validators deduplicate into agent-tool-args (they had grown three
copies across tool modules), and chat-helpers drops isRootMessage and
countMessagesIn, which lost their last callers in the conversation-list
rework. agent-tools lands at 404 lines; every source file is back under
the ceiling.
General (identity, mode, workspaces), Providers, Skills, and Advanced
(Composio key, the operator request console, billing, migration) replace
the six-tab sprawl. Card-in-card nesting and every decorative subtitle are
gone; row actions - provider Check/Manage/Revoke, workspace Add, skill
Import, migration Report - reveal on hover or focus instead of shouting all
the time. The Composio panel loses its hardcoded org-wide toolkit grid,
which the Connectors grants model had already made dead weight, and keeps
only the API key. Fixing the flow also surfaced a real bug: provider policy
rows remounted on a snapshot-derived key, so any refresh mid-edit wiped the
operator's unsaved choices - rows now keep stable identity and edits
survive. E2e follows the new layout.
review_deliverables was written at onboarding and shown in Settings but
nothing ever consumed it - Co-Founder mode silently behaved like AI CEO
mode for output. Now every write_deliverable and create_document in a
review_deliverables org files a pending deliverable_review approval tied to
the file or document, and the tool tells the agent their work is queued for
board review; AI CEO mode keeps shipping without review, which is that
mode's contract. Kickoff and worker briefings also catch up with the
conversation model: managers brief each report in a direct message with one
company-wide post in #general, and workers raise blockers with their
manager over DM instead of flooding department channels. Three
execution-mode contract tests pin deliverable review, no-review autonomy,
and the hire-approval split.
Connector grant tools move to agent-connector-tools and the send-message
presence narration to agent-message-presence; agent-tools keeps the tool
registry and dispatch. Pure movement, no behavior change - the messaging
and connector contract tests pin it.
The Social surface gives way to Connectors: the searchable Composio catalog
(letter-glyph tiles - the CSP stays closed to remote images), one-click
connect that opens the authorization link in the browser and polls the
account until it turns active, and a Connected section where each toolkit
shows its status and a chip per agent that grants or revokes their access
on the spot. Route, nav label, glyph, and search targets follow the rename;
the social backend services remain for the domain while their page and e2e
steps retire in favor of connector coverage.
A ComposioConnectionService owns the toolkit catalog (cursor-paged,
cached), managed auth-config reuse, connect-link initiation, and the local
connected-account mirror that agent runs read. Five IPC surfaces carry it
to the UI - list toolkits, connect a toolkit, refresh account statuses, and
employee-side grant/revoke - and the snapshot now includes
connectorAccounts and connectorGrants. The org API key resolves through one
choke point that seeds itself once from the developer cred.txt next to the
app when the database has none, so both the UI and agent runtime pick up
the key without manual setup.
Connections belong to the company - one Composio connected account per
toolkit, mirrored locally in connector_accounts - and access belongs to
individuals: a new agent_connector_grants table records which agent may use
which toolkit. Agent runs now load composio tools from the intersection of
active connections and that agent's grants, and tool execution re-checks the
grant server-side so an ungranted agent cannot call a connector tool it
heard about. Any agent can list_connectors to see what the company has
connected and who holds access; grant_connector/revoke_connector are
CEO-only. The Composio client speaks the v3 contract (user_id,
connected_account_id, toolkit catalog with cursor paging, managed auth
config creation, connect-link initiation). Covered by four grants contract
tests.
Navigation icons now come from reicon-react (tree-shaken SVG components,
currentColor by default): Home, Briefcase, Users, ChatRoundDots, Send,
Folder, ShieldCheck, DocumentText2, Plug2, Buildings2, and Gear map to their
routes through one NavIcon component, so the glyph set lives in a single
place and NavSpec no longer carries per-item icon names.
Inbox, Knowledge, Meetings, and Sprints leave the navigation and their page
components go with them; the backend services and data they surfaced stay
intact for agents and automation. The secondary rail is now Documents,
Social, and Office.
Every channel and direct conversation is now its own row the way messengers
work: avatar or channel glyph, name, last-message preview, relative time,
and a true unread count from per-employee read state (the old badge showed
total message count). Rows sort by latest activity and the newest
conversation opens by default. Direct rows title themselves after the
counterpart resolved from memberships; agent-to-agent conversations the
board observes keep their two-name title, and opening one clears its unread
because read state is per-employee bookkeeping, not access control.
Conversation rows get their own .convo-item style instead of fighting the
sidebar's single-line nav-item rules.
Agents could only post to named public channels - the messaging tool even
excluded direct spaces - so assignments, reports, and questions all crowded
into general. Now ChatService.ensureDirectSpace finds or creates the private
two-member conversation for any agent/employee pair; send_message takes
to="Name" for 1:1 traffic (exactly one of to/channel), read_messages reads a
conversation by teammate name, and task assignments land in the manager's DM
with the assignee. In a direct conversation the counterpart agent wakes on
every message without needing an @mention - same social contract as any
messenger - still bounded by the autonomous-turn budget, and wake task
briefings tell agents to reply with to= in kind. Covered by six new
direct-message contract tests; the assignment-thread test now encodes the
DM routing contract.
Busy agents emitted a snapshot-changed broadcast per tool turn; every event
made the renderer reload the full snapshot while the main process re-read
whole audit tables synchronously, and ChatTimeline re-rendered every message
with per-row linear scans - quadratic work per keystroke of agent activity
until clicks stopped responding. Root fixes at each layer: all broadcasts
funnel through one 200ms-coalesced notifier (unit-tested), the renderer
reloads at most every 800ms with a trailing load, audit/access snapshot
reads use SQL limits instead of full-table scans, and the timeline renders
the latest 150 messages via O(n) lookup maps with a real show-earlier
control. cred.txt is now gitignored so the Composio key cannot leak.
The office e2e now also hires two agents through the real Team flow,
returns to the floor, clicks the first open desk through the same pure
floor-plan and camera math the app renders with, and asserts the right
agent's card opens - then captures a populated-floor screenshot for visual
review. Nav locators use exact accessible names so 'Chief Executive
Officer' cards cannot shadow the Office nav button.
Idle agents now live a little: after settling in they occasionally walk the
lane graph to the coffee machine, snack counter, or a restroom stall, dwell
there, and stroll back - carrying their coffee or snack to the desk for a
while. Working agents never leave, and an agent woken to work mid-break
abandons the trip and heads straight home. Randomness is injected so the
whole loop - trip, dwell, carry-back, interruption - is deterministic under
unit test, and a settle period keeps the floor calm right after it loads.
Canvas clicks hit-test against the exact positions the renderer draws -
frontmost person wins - and select the agent: a floating card in the app's
design language shows their name, title, department, level, live status, and
current task, with a selection ring under their feet. Escape, the close
button, or clicking empty floor dismisses it; hovering a person shows a
pointer cursor. The floor now seats only lifecycle-active agents, matching
how the backend wakes and assigns work. Covered by a hit-test unit test and
a dedicated office e2e that clicks the CEO through the real floor-plan math.
Office windows now render a living sky: night with stars, a moon, and lit
city windows; a warm sunrise; blue daylight with the sun arcing across; and
an orange sunset - all interpolated smoothly along a palette timeline driven
by the actual clock, over a per-window deterministic skyline. Phase mapping,
sun/moon handover, star intensity, and palette blending are unit-tested.
The signed-in employee now appears automatically at the office entrance in a
blazer with an accent name chip, and moves with WASD or arrow keys: per-axis
wall sliding against the floor-plan colliders, normalized diagonal speed,
facing-aware walk animation, and a camera that follows and clamps to the
world so large teams scroll into view instead of being cut off. Key input
ignores typing targets and releases on window blur. Movement, collision,
spawn stability, and camera clamping are unit-tested.
Replace the single cloned character with identity-derived sprites: skin
tone, hair style and color, outfit (tee/hoodie/blazer), shirt palette, and
glasses all hash off the agent id, drawn with facing-aware variants, a walk
cycle, and carried-item support for later behaviors. The CEO always wears
the blazer. Appearance determinism and population variety are unit-tested.
Replace the viewport-derived desk grid with a fixed-world office: a north
band of rooms (CEO office, meeting room, snack bar, restroom) with door
signage opening onto a corridor, and an open desk field that grows by rows
so any head-count fits the world instead of being cut off. Geometry lives in
a pure floor-plan module that also builds an axis-aligned lane graph with
BFS routing, unit-tested for reachability and collision invariants. A camera
transform centers or clamps the view, the first c_suite agent takes the CEO
office, name labels render the full name, and the mock TODO-board text is
gone. Office screenshots join the visual-review capture set.
The flat-messages refactor left ChatThreadPanel orphaned: ChatPage passed a
no-op onOpenThread and ChatTimeline hardcoded onOpenThread={null}, so threads
(including /escalate board flows) were unreachable from the UI and the
desktop e2e failed on main. Reconnect open/close/reply/board-intervention
wiring around the flat timeline, show reply counts on thread roots, and
clear the lint debt that severed feature left behind.
Chat: removed all thread abstraction. Every message in a channel now
renders inline chronologically as a flat list — no compact rows, no
thread panel, no thread navigation. Just messages, like Slack.
OOM fix: snapshot now limits fast-growing tables (chat_messages: 500,
task_runs: 200, provider_requests: 100) instead of loading unbounded
rows. This prevents the renderer V8 heap from growing past 3.5GB and
crashing. The notifyDataChanged callback is also wrapped in try/catch
to prevent errors when the renderer frame is disposed during agent runs.
Chat: clicking a thread row now replaces the center pane content with
the thread's full messages (back button to return to thread list).
Removed the right-side thread panel entirely — threads navigate in
place like Slack, not as a side panel overlay.
Office: reduced frame rate to 24fps, skip rendering when canvas has
zero dimensions, schedule next frame AFTER draw (not before) to
prevent runaway frame buildup that caused the white screen crash.
Layout: agents now arrange in a horizontal grid (3-4 per row based on
viewport width) instead of stacking vertically. Position calculation
uses layoutPositions() which guarantees agents stay within the canvas.
Performance: render loop throttled to 30fps instead of uncapped 60fps.
Removed Math.random() from render path — building window lights now use
a deterministic hash that changes slowly. Canvas dimensions only resize
when clientWidth/clientHeight actually change.
Crash fix: clearRect at frame start prevents accumulated draw state.
setTransform instead of scale prevents compounding transforms. Animation
cleanup properly cancels requestAnimationFrame on unmount.
Characters now have round heads, headphones, eyes, shirts, pants, and
shoes — proper pixel-art people like claude-office. Desks are detailed
wooden tables with monitors showing task text, keyboards, and coffee
cups. The wall has a city skyline window, analog clock, whiteboard with
TODO items, and an employee-of-the-month painting. Active agents bob
and show speech bubbles with their current task. Floor has tile grid.
The virtual office is now a dedicated page (nav: Office) with an HTML5
Canvas rendering animated pixel-art characters. Each agent is drawn as
a pixel person with deterministic skin/shirt colors, walking legs, and
a bobbing head when active. Idle agents wander randomly near their desk.
Active agents show a green dot, thinking agents show a question mark.
Departments are labeled zones with desks and monitors. Removed the old
sidebar component entirely.
The channel timeline now renders each thread as a single compact row
with sender avatar, message preview (truncated to one line), reply
count with participant avatars, and last reply time. Clicking a row
opens the thread in the right panel where the full conversation lives.
This matches Slack's thread-list pattern instead of dumping every
message body into the channel view.
Replaced generic bot icons with CSS pixel-art people — colored head,
shirt body, and legs, each agent with a stable color derived from their
name. Layout is now compact flex-wrap (42px per agent) instead of one
agent per row. Sidebar narrowed to 172px. Tooltip anchored to right
edge to prevent clipping. Department floors use the app's panel-2
background for a clean integrated look.
When Composio tools are loaded for an agent run, the system prompt now
mentions their count and purpose so the agent knows it can interact
with external services like GitHub, Slack, and Gmail.