# devoidsloth/ccanvas architecture

> Architecture diagram of the GitHub repository devoidsloth/ccanvas, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/devoidsloth/ccanvas
- Repository: https://github.com/devoidsloth/ccanvas

## Overview

ccanvas is a desktop-first, browser-capable infinite canvas for arranging real terminals, Claude agents, and live viewers into interactive workspaces. The principal workflow is to create or reopen a folder-bound canvas, place widgets, run agents, optionally connect them with logic arrows, inspect their output in viewers, and save or export the workspace. The graph preserves documented capabilities, but some subsystem wiring is based on the README and tree rather than sampled implementation; uncertain links are omitted.

Main entry points: [`src/store/workspace.ts`](https://github.com/devoidsloth/ccanvas/blob/main/src/store/workspace.ts) (Workspace state), [`src/widgets/TerminalBody.tsx`](https://github.com/devoidsloth/ccanvas/blob/main/src/widgets/TerminalBody.tsx) (Terminal and agent), [`src/lib/backend.ts`](https://github.com/devoidsloth/ccanvas/blob/main/src/lib/backend.ts) (Backend client), [`src/widgets/WidgetFrame.tsx`](https://github.com/devoidsloth/ccanvas/blob/main/src/widgets/WidgetFrame.tsx) (Widget container)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_canvas["Canvas workspace"]
  node_app["Application shell<br/>[App.tsx]"]
  node_canvas_view["Infinite canvas<br/>[Canvas.tsx]"]
  node_workspace_store["Workspace state<br/>[workspace.ts]"]
  node_canvas_controls["Canvas controls<br/>[Toolbar.tsx]"]
  node_search["Canvas search<br/>[CanvasSearch.tsx]"]
end

subgraph group_agents["Agent operations"]
  node_agents_runtime["Agent runtime<br/>[agents.ts]"]
  node_flow_logic["Agent flow logic<br/>[flow.ts]"]
  node_terminal["Terminal and agent<br/>[TerminalBody.tsx]"]
  node_roster["Agent roster<br/>[Roster.tsx]"]
  node_tracking["Tracking camera<br/>[TrackingBar.tsx]"]
  node_follow["Follow controller"]
  node_transcript["Agent transcript<br/>[TranscriptBody.tsx]"]
end

subgraph group_widgets["Content widgets"]
  node_widget_frame["Widget container<br/>[WidgetFrame.tsx]"]
  node_file_viewers["File and code viewers<br/>[FilesBody.tsx]"]
  node_data_viewer["Structured data viewer<br/>[DataBody.tsx]"]
  node_data_parser["Data format parser<br/>[dataformats.ts]"]
  node_media_viewer["Media viewer<br/>[VideoBody.tsx]"]
  node_github_widgets["GitHub widgets<br/>[PrBody.tsx]"]
end

subgraph group_workspace_data["Workspace data"]
  node_persistence["Workspace persistence<br/>[persistence.ts]"]
  node_checkpoints["Git checkpoints<br/>[checkpoints.ts]"]
  node_export["Canvas export<br/>[export.ts]"]
end

subgraph group_runtime["Runtime integrations"]
  node_backend_client["Backend client<br/>[backend.ts]"]
  node_web_backend["Web backend<br/>[pty-server.mjs]"]
  node_desktop_backend["Desktop commands<br/>[lib.rs]"]
  node_filesystem[("Workspace files")]
  node_shell["Shell and Claude CLI"]
  node_github["GitHub CLI"]
  node_media_tools["Media tools"]
end

node_user(("User"))

node_user -->|"uses"| node_app
node_app -->|"renders"| node_canvas_view
node_app -->|"renders"| node_canvas_controls
node_app -->|"renders"| node_search
node_canvas_view -->|"reads and updates"| node_workspace_store
node_canvas_controls -->|"updates"| node_workspace_store
node_search -->|"searches and focuses"| node_workspace_store
node_workspace_store -->|"loads and saves"| node_persistence
node_workspace_store -->|"saves workspace"| node_backend_client
node_canvas_view -->|"displays widgets"| node_widget_frame
node_widget_frame -->|"hosts"| node_terminal
node_widget_frame -->|"hosts"| node_file_viewers
node_widget_frame -->|"hosts"| node_data_viewer
node_widget_frame -->|"hosts"| node_media_viewer
node_terminal -->|"updates status"| node_agents_runtime
node_terminal -->|"cleans output"| node_flow_logic
node_terminal -->|"resolves paths"| node_backend_client
node_terminal -->|"starts and writes"| node_shell
node_flow_logic -->|"coordinates agents"| node_terminal
node_roster -->|"reads agent status"| node_agents_runtime
node_tracking -->|"tracks file activity"| node_transcript
node_follow -->|"observes status"| node_agents_runtime
node_follow -->|"moves camera"| node_workspace_store
node_transcript -->|"reads session transcript"| node_filesystem
node_data_viewer -->|"parses data"| node_data_parser
node_file_viewers -->|"reads files"| node_backend_client
node_media_viewer -->|"requests media"| node_backend_client
node_github_widgets -.->|"uses CLI"| node_github
node_workspace_store -->|"manages snapshots"| node_checkpoints
node_workspace_store -->|"exports canvas"| node_export
node_backend_client -.->|"calls local backend"| node_web_backend
node_backend_client -.->|"invokes desktop commands"| node_desktop_backend
node_web_backend -->|"reads and writes"| node_filesystem
node_desktop_backend -->|"reads and writes"| node_filesystem
node_web_backend -->|"spawns PTYs"| node_shell
node_desktop_backend -->|"manages PTYs"| node_shell
node_web_backend -->|"probes and transcodes"| node_media_tools
node_desktop_backend -->|"starts media service"| node_media_tools

click node_app "https://github.com/devoidsloth/ccanvas/blob/main/src/App.tsx"
click node_canvas_view "https://github.com/devoidsloth/ccanvas/blob/main/src/canvas/Canvas.tsx"
click node_workspace_store "https://github.com/devoidsloth/ccanvas/blob/main/src/store/workspace.ts"
click node_canvas_controls "https://github.com/devoidsloth/ccanvas/blob/main/src/ui/Toolbar.tsx"
click node_search "https://github.com/devoidsloth/ccanvas/blob/main/src/ui/CanvasSearch.tsx"
click node_agents_runtime "https://github.com/devoidsloth/ccanvas/blob/main/src/lib/agents.ts"
click node_flow_logic "https://github.com/devoidsloth/ccanvas/blob/main/src/lib/flow.ts"
click node_terminal "https://github.com/devoidsloth/ccanvas/blob/main/src/widgets/TerminalBody.tsx"
click node_roster "https://github.com/devoidsloth/ccanvas/blob/main/src/ui/Roster.tsx"
click node_tracking "https://github.com/devoidsloth/ccanvas/blob/main/src/ui/TrackingBar.tsx"
click node_follow "https://github.com/devoidsloth/ccanvas/blob/main/src/ui/FollowController.tsx"
click node_transcript "https://github.com/devoidsloth/ccanvas/blob/main/src/widgets/TranscriptBody.tsx"
click node_widget_frame "https://github.com/devoidsloth/ccanvas/blob/main/src/widgets/WidgetFrame.tsx"
click node_file_viewers "https://github.com/devoidsloth/ccanvas/blob/main/src/widgets/FilesBody.tsx"
click node_data_viewer "https://github.com/devoidsloth/ccanvas/blob/main/src/widgets/DataBody.tsx"
click node_data_parser "https://github.com/devoidsloth/ccanvas/blob/main/src/lib/dataformats.ts"
click node_media_viewer "https://github.com/devoidsloth/ccanvas/blob/main/src/widgets/VideoBody.tsx"
click node_github_widgets "https://github.com/devoidsloth/ccanvas/blob/main/src/widgets/PrBody.tsx"
click node_persistence "https://github.com/devoidsloth/ccanvas/blob/main/src/lib/persistence.ts"
click node_checkpoints "https://github.com/devoidsloth/ccanvas/blob/main/src/lib/checkpoints.ts"
click node_export "https://github.com/devoidsloth/ccanvas/blob/main/src/lib/export.ts"
click node_backend_client "https://github.com/devoidsloth/ccanvas/blob/main/src/lib/backend.ts"
click node_web_backend "https://github.com/devoidsloth/ccanvas/blob/main/server/pty-server.mjs"
click node_desktop_backend "https://github.com/devoidsloth/ccanvas/blob/main/src-tauri/src/lib.rs"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_canvas_view,node_workspace_store,node_canvas_controls,node_search,node_user toneBlue
class node_agents_runtime,node_flow_logic,node_terminal,node_roster,node_tracking,node_follow,node_transcript toneAmber
class node_widget_frame,node_file_viewers,node_data_viewer,node_data_parser,node_media_viewer,node_github_widgets toneMint
class node_persistence,node_checkpoints,node_export toneRose
class node_backend_client,node_web_backend,node_desktop_backend,node_filesystem,node_shell,node_github,node_media_tools toneIndigo
```

## Components

### Canvas workspace

- [Application shell](https://github.com/devoidsloth/ccanvas/blob/main/src/App.tsx): `src/App.tsx`
- [Infinite canvas](https://github.com/devoidsloth/ccanvas/blob/main/src/canvas/Canvas.tsx): `src/canvas/Canvas.tsx`
- [Workspace state](https://github.com/devoidsloth/ccanvas/blob/main/src/store/workspace.ts): `src/store/workspace.ts`
- [Canvas controls](https://github.com/devoidsloth/ccanvas/blob/main/src/ui/Toolbar.tsx): `src/ui/Toolbar.tsx`
- [Canvas search](https://github.com/devoidsloth/ccanvas/blob/main/src/ui/CanvasSearch.tsx): `src/ui/CanvasSearch.tsx`

### Agent operations

- [Agent runtime](https://github.com/devoidsloth/ccanvas/blob/main/src/lib/agents.ts): `src/lib/agents.ts`
- [Agent flow logic](https://github.com/devoidsloth/ccanvas/blob/main/src/lib/flow.ts): `src/lib/flow.ts`
- [Terminal and agent](https://github.com/devoidsloth/ccanvas/blob/main/src/widgets/TerminalBody.tsx): `src/widgets/TerminalBody.tsx`
- [Agent roster](https://github.com/devoidsloth/ccanvas/blob/main/src/ui/Roster.tsx): `src/ui/Roster.tsx`
- [Tracking camera](https://github.com/devoidsloth/ccanvas/blob/main/src/ui/TrackingBar.tsx): `src/ui/TrackingBar.tsx`
- [Follow controller](https://github.com/devoidsloth/ccanvas/blob/main/src/ui/FollowController.tsx): `src/ui/FollowController.tsx`
- [Agent transcript](https://github.com/devoidsloth/ccanvas/blob/main/src/widgets/TranscriptBody.tsx): `src/widgets/TranscriptBody.tsx`

### Content widgets

- [Widget container](https://github.com/devoidsloth/ccanvas/blob/main/src/widgets/WidgetFrame.tsx): `src/widgets/WidgetFrame.tsx`
- [File and code viewers](https://github.com/devoidsloth/ccanvas/blob/main/src/widgets/FilesBody.tsx): `src/widgets/FilesBody.tsx`
- [Structured data viewer](https://github.com/devoidsloth/ccanvas/blob/main/src/widgets/DataBody.tsx): `src/widgets/DataBody.tsx`
- [Data format parser](https://github.com/devoidsloth/ccanvas/blob/main/src/lib/dataformats.ts): `src/lib/dataformats.ts`
- [Media viewer](https://github.com/devoidsloth/ccanvas/blob/main/src/widgets/VideoBody.tsx): `src/widgets/VideoBody.tsx`
- [GitHub widgets](https://github.com/devoidsloth/ccanvas/blob/main/src/widgets/PrBody.tsx): `src/widgets/PrBody.tsx`

### Workspace data

- [Workspace persistence](https://github.com/devoidsloth/ccanvas/blob/main/src/lib/persistence.ts): `src/lib/persistence.ts`
- [Git checkpoints](https://github.com/devoidsloth/ccanvas/blob/main/src/lib/checkpoints.ts): `src/lib/checkpoints.ts`
- [Canvas export](https://github.com/devoidsloth/ccanvas/blob/main/src/lib/export.ts): `src/lib/export.ts`

### Runtime integrations

- [Backend client](https://github.com/devoidsloth/ccanvas/blob/main/src/lib/backend.ts): `src/lib/backend.ts`
- [Web backend](https://github.com/devoidsloth/ccanvas/blob/main/server/pty-server.mjs): `server/pty-server.mjs`
- [Desktop commands](https://github.com/devoidsloth/ccanvas/blob/main/src-tauri/src/lib.rs): `src-tauri/src/lib.rs`
- **Workspace files**
- **Shell and Claude CLI**
- **GitHub CLI**
- **Media tools**

### Other components

- **User**

## Connections

- User → Application shell: uses
- Application shell → Infinite canvas: renders
- Application shell → Canvas controls: renders
- Application shell → Canvas search: renders
- Infinite canvas → Workspace state: reads and updates
- Canvas controls → Workspace state: updates
- Canvas search → Workspace state: searches and focuses
- Workspace state → Workspace persistence: loads and saves
- Workspace state → Backend client: saves workspace
- Infinite canvas → Widget container: displays widgets
- Widget container → Terminal and agent: hosts
- Widget container → File and code viewers: hosts
- Widget container → Structured data viewer: hosts
- Widget container → Media viewer: hosts
- Terminal and agent → Agent runtime: updates status
- Terminal and agent → Agent flow logic: cleans output
- Terminal and agent → Backend client: resolves paths
- Terminal and agent → Shell and Claude CLI: starts and writes
- Agent flow logic → Terminal and agent: coordinates agents
- Agent roster → Agent runtime: reads agent status
- Tracking camera → Agent transcript: tracks file activity
- Follow controller → Agent runtime: observes status
- Follow controller → Workspace state: moves camera
- Agent transcript → Workspace files: reads session transcript
- Structured data viewer → Data format parser: parses data
- File and code viewers → Backend client: reads files
- Media viewer → Backend client: requests media
- GitHub widgets → GitHub CLI: uses CLI
- Workspace state → Git checkpoints: manages snapshots
- Workspace state → Canvas export: exports canvas
- Backend client → Web backend: calls local backend
- Backend client → Desktop commands: invokes desktop commands
- Web backend → Workspace files: reads and writes
- Desktop commands → Workspace files: reads and writes
- Web backend → Shell and Claude CLI: spawns PTYs
- Desktop commands → Shell and Claude CLI: manages PTYs
- Web backend → Media tools: probes and transcodes
- Desktop commands → Media tools: starts media service
