/chatgroup-architecture
ChatGroup architecture — how conversation data flows from raw JSONL to rendered chat groups. Use when working on UserGroup, AIGroup, SystemGroup, display items, tool linking, chunks, or the rendering hierarchy.
How it fires
How this command gets triggered: by you, by Claude, or both.
- Fires itselfClaude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/chatgroup-architecture
Context preview
What this command does when you run it.
ChatGroup architecture — how conversation data flows from raw JSONL to rendered chat groups. Use when working on UserGroup, AIGroup, SystemGroup, display items, tool linking, chunks, or the rendering hierarchy.
Command definition
chatgroup-architecture.mdname: claude-devtools:chatgroup-architecture
description: ChatGroup architecture — how conversation data flows from raw JSONL to rendered chat groups. Use when working on UserGroup, AIGroup, SystemGroup, display items, tool linking, chunks, or the rendering hierarchy.
ChatGroup Architecture
How conversation data flows from raw JSONL messages to rendered chat groups.
Core Design Principle
Chat groups are **independent items in a flat chronological list**, not paired turns. There is no UserTurn/AITurn pairing — each group stands alone.
// src/renderer/types/groups.ts
export type ChatItem =
| { type: 'user'; group: UserGroup }
| { type: 'system'; group: SystemGroup }
| { type: 'ai'; group: AIGroup }
| { type: 'compact'; group: CompactGroup };
export interface SessionConversation {
sessionId: string;
items: ChatItem[]; // Flat chronological list
totalUserGroups: number;
totalSystemGroups: number;
totalAIGroups: number;
totalCompactGroups: number;
}Pipeline Overview
Raw JSONL messages
→ MessageClassifier (classify into user/system/ai/hardNoise)
→ ChunkBuilder (buffer AI messages, flush on user/system boundary)
→ ChunkFactory (build EnhancedAIChunk with SemanticSteps)
→ groupTransformer (chunks → flat ChatItem[] conversation)
→ aiGroupEnhancer (AIGroup → EnhancedAIGroup with displayItems, linkedTools, lastOutput)
→ React components render
Primary source files:
- `src/main/services/parsing/MessageClassifier.ts`
- `src/main/services/analysis/ChunkBuilder.ts`
- `src/main/services/analysis/ChunkFactory.ts`
- `src/renderer/utils/groupTransformer.ts`
- `src/renderer/utils/aiGroupEnhancer.ts`
- `src/renderer/utils/displayItemBuilder.ts`
- `src/renderer/types/groups.ts`
- `src/main/types/chunks.ts`
Data Models
UserGroup
// src/renderer/types/groups.ts
interface UserGroup {
id: string;
message: ParsedMessage;
timestamp: Date;
content: UserGroupContent;
index: number; // Ordering index within session
}
interface UserGroupContent {
text?: string; // Plain text (commands removed)
rawText?: string; // Original text
commands: CommandInfo[]; // Extracted /commands
images: ImageData[]; // Attached images
fileReferences: FileReference[]; // @file.ts mentions
}Renders right-aligned blue bubble. Contains markdown text, slash commands, images, and file references.
AIGroup
interface AIGroup {
id: string;
turnIndex: number; // 0-based (for turn navigation)
startTime: Date;
endTime: Date;
durationMs: number;
steps: SemanticStep[]; // Core semantic steps
tokens: AIGroupTokens;
summary: AIGroupSummary; // For collapsed view
status: AIGroupStatus; // 'complete' | 'interrupted' | 'error' | 'in_progress'
processes: Process[]; // Subagent processes
chunkId: string;
metrics: SessionMetrics;
responses: ParsedMessage[]; // All assistant + internal messages
isOngoing?: boolean; // True for last group in ongoing session
}EnhancedAIGroup
The renderer enhances `AIGroup` before rendering:
interface EnhancedAIGroup extends AIGroup {
lastOutput: AIGroupLastOutput | null; // Always-visible output
displayItems: AIGroupDisplayItem[]; // Flattened chronological items
linkedTools: Map<string, LinkedToolItem>; // Tool call/result pairs
itemsSummary: string; // "2 thinking, 4 tool calls, 3 subagents"
mainModel: ModelInfo | null;
subagentModels: ModelInfo[];
claudeMdStats: ClaudeMdStats | null;
}Enhancement happens in `src/renderer/utils/aiGroupEnhancer.ts`:
1. `findLastOutput` — extracts the final visible output (text, tool result, interruption, plan exit, ongoing) 2. `linkToolCallsToResults` — pairs tool calls with their results into `LinkedToolItem` 3. `buildDisplayItems` — flattens steps into chronological `AIGroupDisplayItem[]` 4. `buildSummary` — generates human-readable summary string 5. `extractMainModel` / `extractSubagentModels` — extracts model info
AIGroupDisplayItem
type AIGroupDisplayItem =
| { type: 'thinking'; content: string; timestamp: Date; tokenCount?: number }
| { type: 'tool'; tool: LinkedToolItem }
| { type: 'subagent'; subagent: Process }
| { type: 'output'; content: string; timestamp: Date; tokenCount?: number }
| { type: 'slash'; slash: SlashItem }
| { type: 'teammate_message'; teammateMessage: TeammateMessage };Display items are sorted chronologically in `src/renderer/utils/displayItemBuilder.ts`.
LinkedToolItem
interface LinkedToolItem {
id: string;
name: string;
input: Record<string, unknown>;
callTokens?: number;
result?: {
content: string | unknown[];
isError: boolean;
toolUseResult?: ToolUseResultData;
tokenCount?: number;
};
inputPreview: string; // First 100 chars
outputPreview?: string; // First 200 chars
startTime: Date;
endTime?: Date;
durationMs?: number;
isOrphaned: boolean; // No result received
sourceModel?: string;
skillInstructions?: string; // For Skill tool calls
skillInstructionsTokenCount?: number;
}AIGroupLastOutput
Always-visible output below the AI group header:
interface AIGroupLastOutput {
type: 'text' | 'tool_result' | 'interruption' | 'ongoing' | 'plan_exit';
text?: string;
toolName?: string;
toolResult?: string;
isError?: boolean;
interruptionMessage?: string;
planContent?: string;
planPreamble?: string;
timestamp: Date;
}SystemGroup
interface SystemGroup {
id: string;
message: ParsedMessage;
timestamp: Date;
commandOutput: string;
commandName?: string;
}Renders left-aligned with neutral gray styling. Monospace pre with ANSI escape codes cleaned.
CompactGroup
interface CompactGroup {
id: sRead more
name: claude-devtools:chatgroup-architecture description: ChatGroup architecture — how conversation data flows from raw JSONL to rendered chat groups. Use when working on UserGroup, AIGroup, SystemGroup, display items, tool linking, chunks, or the rendering hierarchy.
ChatGroup Architecture
How conversation data flows from raw JSONL messages to rendered chat groups.
Core Design Principle
Chat groups are **independent items in a flat chronological list**, not paired turns. There is no UserTurn/AITurn pairing — each group stands alone.
// src/renderer/types/groups.ts
export type ChatItem =
| { type: 'user'; group: UserGroup }
| { type: 'system'; group: SystemGroup }
| { type: 'ai'; group: AIGroup }
| { type: 'compact'; group: CompactGroup };
export interface SessionConversation {
sessionId: string;
items: ChatItem[]; // Flat chronological list
totalUserGroups: number;
totalSystemGroups: number;
totalAIGroups: number;
totalCompactGroups: number;
}Pipeline Overview
Raw JSONL messages → MessageClassifier (classify into user/system/ai/hardNoise) → ChunkBuilder (buffer AI messages, flush on user/system boundary) → ChunkFactory (build EnhancedAIChunk with SemanticSteps) → groupTransformer (chunks → flat ChatItem[] conversation) → aiGroupEnhancer (AIGroup → EnhancedAIGroup with displayItems, linkedTools, lastOutput) → React components render
Primary source files:
- `src/main/services/parsing/MessageClassifier.ts`
- `src/main/services/analysis/ChunkBuilder.ts`
- `src/main/services/analysis/ChunkFactory.ts`
- `src/renderer/utils/groupTransformer.ts`
- `src/renderer/utils/aiGroupEnhancer.ts`
- `src/renderer/utils/displayItemBuilder.ts`
- `src/renderer/types/groups.ts`
- `src/main/types/chunks.ts`
Data Models
UserGroup
// src/renderer/types/groups.ts
interface UserGroup {
id: string;
message: ParsedMessage;
timestamp: Date;
content: UserGroupContent;
index: number; // Ordering index within session
}
interface UserGroupContent {
text?: string; // Plain text (commands removed)
rawText?: string; // Original text
commands: CommandInfo[]; // Extracted /commands
images: ImageData[]; // Attached images
fileReferences: FileReference[]; // @file.ts mentions
}Renders right-aligned blue bubble. Contains markdown text, slash commands, images, and file references.
AIGroup
interface AIGroup {
id: string;
turnIndex: number; // 0-based (for turn navigation)
startTime: Date;
endTime: Date;
durationMs: number;
steps: SemanticStep[]; // Core semantic steps
tokens: AIGroupTokens;
summary: AIGroupSummary; // For collapsed view
status: AIGroupStatus; // 'complete' | 'interrupted' | 'error' | 'in_progress'
processes: Process[]; // Subagent processes
chunkId: string;
metrics: SessionMetrics;
responses: ParsedMessage[]; // All assistant + internal messages
isOngoing?: boolean; // True for last group in ongoing session
}EnhancedAIGroup
The renderer enhances `AIGroup` before rendering:
interface EnhancedAIGroup extends AIGroup {
lastOutput: AIGroupLastOutput | null; // Always-visible output
displayItems: AIGroupDisplayItem[]; // Flattened chronological items
linkedTools: Map<string, LinkedToolItem>; // Tool call/result pairs
itemsSummary: string; // "2 thinking, 4 tool calls, 3 subagents"
mainModel: ModelInfo | null;
subagentModels: ModelInfo[];
claudeMdStats: ClaudeMdStats | null;
}Enhancement happens in `src/renderer/utils/aiGroupEnhancer.ts`:
1. `findLastOutput` — extracts the final visible output (text, tool result, interruption, plan exit, ongoing) 2. `linkToolCallsToResults` — pairs tool calls with their results into `LinkedToolItem` 3. `buildDisplayItems` — flattens steps into chronological `AIGroupDisplayItem[]` 4. `buildSummary` — generates human-readable summary string 5. `extractMainModel` / `extractSubagentModels` — extracts model info
AIGroupDisplayItem
type AIGroupDisplayItem =
| { type: 'thinking'; content: string; timestamp: Date; tokenCount?: number }
| { type: 'tool'; tool: LinkedToolItem }
| { type: 'subagent'; subagent: Process }
| { type: 'output'; content: string; timestamp: Date; tokenCount?: number }
| { type: 'slash'; slash: SlashItem }
| { type: 'teammate_message'; teammateMessage: TeammateMessage };Display items are sorted chronologically in `src/renderer/utils/displayItemBuilder.ts`.
LinkedToolItem
interface LinkedToolItem {
id: string;
name: string;
input: Record<string, unknown>;
callTokens?: number;
result?: {
content: string | unknown[];
isError: boolean;
toolUseResult?: ToolUseResultData;
tokenCount?: number;
};
inputPreview: string; // First 100 chars
outputPreview?: string; // First 200 chars
startTime: Date;
endTime?: Date;
durationMs?: number;
isOrphaned: boolean; // No result received
sourceModel?: string;
skillInstructions?: string; // For Skill tool calls
skillInstructionsTokenCount?: number;
}AIGroupLastOutput
Always-visible output below the AI group header:
interface AIGroupLastOutput {
type: 'text' | 'tool_result' | 'interruption' | 'ongoing' | 'plan_exit';
text?: string;
toolName?: string;
toolResult?: string;
isError?: boolean;
interruptionMessage?: string;
planContent?: string;
planPreamble?: string;
timestamp: Date;
}SystemGroup
interface SystemGroup {
id: string;
message: ParsedMessage;
timestamp: Date;
commandOutput: string;
commandName?: string;
}Renders left-aligned with neutral gray styling. Monospace pre with ANSI escape codes cleaned.
CompactGroup
interface CompactGroup {
id: sThe missing DevTools for Claude Code — inspect session logs, tool calls, token usage, subagents, and context window in a visual UI. Free, open source.
Repo: matt1398/claude-devtools
Other commands on claude-devtools.
- /design-system
Design system and visual language — theming, CSS variables, Tailwind config, component styling patterns, icon usage, animations, and z-index layers. Use when creating or modifying UI components, working with the dark/light theme, or debugging visual issues.
Open command - /explain-visible-context
Explains what "Visible Context" is — the 6 trackable token categories, what falls outside tracking, how it's displayed, and why it matters. Use when someone asks about visible context, token attribution, or context window usage.
Open command - /markdown-search-logic
Markdown search logic — how in-session and cross-session search works. Use when working on SearchBar, search highlighting, searchHighlightUtils, markdownTextSearch, or SessionSearcher.
Open command - /navigation-scroll
Navigation and scroll orchestration — tab navigation, error highlights, search scrolling, auto-scroll coordination, and common bug patterns. Use when working on useTabNavigationController, scroll restore, or navigation requests.
Open command

