diff --git a/README.md b/README.md
index 0a16dd8c62..7092cce277 100644
--- a/README.md
+++ b/README.md
@@ -157,10 +157,40 @@ FNXC:Docs 2026-06-21-19:55:
README must lead with a smaller wordmark and a visual showcase of the latest surfaces (Command Center, selectable workflows, agent chat, multi-agent chat rooms, agent mail) so the value lands fast.
Each feature pairs a short looping GIF with value copy; Command Center additionally carries real fleet stats, the token/productivity/team graph trio, and the 70+-theme grid (incl. shadcn light/mono/orange/black) to make the data pop.
Media lives in demo/assets/ (committed, GitHub-inline GIFs); stat numbers are sourced from a live seeded fleet โ refresh them if the captures are re-shot.
-Each feature keeps its original Tokyo Night capture and adds a Shadcn Light + Shadcn Dark Gray pair; the theme showcase is split into a light-themes grid and a dark-themes grid. Workflow GIFs feature the Stepwise coding graph with node-level zoom/pan.
+Each feature keeps its original Tokyo Night capture and adds a Shadcn Light + Shadcn Dark Gray + Ember trio; the theme showcase is split into a light-themes grid and a dark-themes grid. Workflow GIFs feature the Stepwise coding graph with node-level zoom/pan.
-->
-The newest surfaces in Fusion, at a glance โ mission control, visual workflows, agent chat, multi-agent rooms, and inter-agent mail.
+The newest surfaces in Fusion, at a glance โ the live board, your agent team, mission control, visual workflows, agent chat, multi-agent rooms, and inter-agent mail.
+
+### ๐ The board & your agent team โ live, from a real fleet
+
+
+

+
+
+Every task, every column, every step โ live. Cards carry GitHub links, step counts, review levels, and promote/move/archive actions. Switch to the **Graph** view to see task dependencies as an interactive node graph:
+
+
+
+ Board โ kanban columns |
+ Graph โ dependency map |
+
+
+
+Here is the same fleet re-skinned into the **Ember** theme (dark graphite with an orange accent), alongside the **Agents** roster:
+
+
+
+ Board โ Ember |
+ Agents โ Tokyo Night |
+
+
+
+Import a team and every agent shows up here โ role, reports-to chain, heartbeat, and token share. The **Agents** roster in Ember:
+
+
+

+
### ๐ฐ๏ธ Command Center โ mission control for your agent fleet
@@ -168,7 +198,13 @@ The newest surfaces in Fusion, at a glance โ mission control, visual workflows
-One screen for everything your agents are doing. Tune live scheduler capacity, watch token spend by model in real time, and prove the value with hard numbers.
+One screen for everything your agents are doing. Tune live scheduler capacity, watch token spend by model in real time, and prove the value with hard numbers. The **Overview** tab opens with live gauges and charts:
+
+
+

+
+
+Every tab is a different lens on the same live fleet:
@@ -176,16 +212,22 @@ One screen for everything your agents are doing. Tune live scheduler capacity, w
 Productivity โ outcomes, duration percentiles, language mix. |
 Team โ agent org chart and token share per agent. |
+
+ Activity โ task throughput and event timelines. |
+ Signals โ anomaly detection and fleet health. |
+ More โ Tools ยท Ecosystem ยท GitHub ยท System ยท Reliability. |
+
> Tokens ยท Tools ยท Activity ยท Productivity ยท Team ยท Ecosystem ยท GitHub ยท Signals ยท System ยท Reliability ยท Mission Control โ every tab is a different lens on the same live fleet.
-**The same fleet, your way** โ Command Center (and the whole dashboard) re-skins live across **70+ color themes**. Here it is in Shadcn Light and Shadcn Dark Gray:
+**The same fleet, your way** โ Command Center (and the whole dashboard) re-skins live across **70+ color themes**. Here it is in Shadcn Light, Shadcn Dark Gray, and Ember:
- Shadcn Light |
- Shadcn Dark Gray |
+ Shadcn Light |
+ Shadcn Dark Gray |
+ Ember |
@@ -210,12 +252,13 @@ One screen for everything your agents are doing. Tune live scheduler capacity, w
A task's journey from idea to merge is a **workflow** โ and it's yours to choose and shape. Pick a built-in (Coding, Quick fix, Review-heavy, Stepwise, PR lifecycle, Compound engineering, and more), inspect its graph, then duplicate and customize columns, gates, model lanes, and review policy in the visual [Workflow Editor](./docs/workflow-editor.md). No engine fork required.
-Here's the **Stepwise coding** graph โ plan, execute, and review every step before the next โ explored node-by-node in Shadcn Light and Dark Gray:
+Here's the **Stepwise coding** graph โ plan, execute, and review every step before the next โ explored node-by-node in Shadcn Light, Dark Gray, and Ember:
- Shadcn Light |
- Shadcn Dark Gray |
+ Shadcn Light |
+ Shadcn Dark Gray |
+ Ember |
@@ -244,8 +287,9 @@ Put multiple agents in a room and let them coordinate. Mention a member and it r
- Shadcn Light |
- Shadcn Dark Gray |
+ Shadcn Light |
+ Shadcn Dark Gray |
+ Ember |
@@ -259,8 +303,9 @@ A built-in mailbox for delegation, clarification, and hand-offs. Agents file tri
- Shadcn Light |
- Shadcn Dark Gray |
+ Shadcn Light |
+ Shadcn Dark Gray |
+ Ember |
diff --git a/demo/assets/agent-chat-gray.png b/demo/assets/agent-chat-gray.png
index f5e88bf890..5af071f110 100644
Binary files a/demo/assets/agent-chat-gray.png and b/demo/assets/agent-chat-gray.png differ
diff --git a/demo/assets/agent-chat-light.png b/demo/assets/agent-chat-light.png
index 4295b05dd7..73f99bbff6 100644
Binary files a/demo/assets/agent-chat-light.png and b/demo/assets/agent-chat-light.png differ
diff --git a/demo/assets/agent-chat.gif b/demo/assets/agent-chat.gif
index 96274d3a79..26e5b61d4c 100644
Binary files a/demo/assets/agent-chat.gif and b/demo/assets/agent-chat.gif differ
diff --git a/demo/assets/agent-mail-ember.gif b/demo/assets/agent-mail-ember.gif
new file mode 100644
index 0000000000..243df37a5a
Binary files /dev/null and b/demo/assets/agent-mail-ember.gif differ
diff --git a/demo/assets/agent-mail-gray.gif b/demo/assets/agent-mail-gray.gif
index cc15df10d8..693f402217 100644
Binary files a/demo/assets/agent-mail-gray.gif and b/demo/assets/agent-mail-gray.gif differ
diff --git a/demo/assets/agent-mail-light.gif b/demo/assets/agent-mail-light.gif
index 2c4a98f22c..5cd7c6f655 100644
Binary files a/demo/assets/agent-mail-light.gif and b/demo/assets/agent-mail-light.gif differ
diff --git a/demo/assets/agent-mail.gif b/demo/assets/agent-mail.gif
index ac567a9268..7f23d14dab 100644
Binary files a/demo/assets/agent-mail.gif and b/demo/assets/agent-mail.gif differ
diff --git a/demo/assets/agents-ember.png b/demo/assets/agents-ember.png
new file mode 100644
index 0000000000..3cb36116c0
Binary files /dev/null and b/demo/assets/agents-ember.png differ
diff --git a/demo/assets/agents-tokyo.png b/demo/assets/agents-tokyo.png
new file mode 100644
index 0000000000..438fff7b65
Binary files /dev/null and b/demo/assets/agents-tokyo.png differ
diff --git a/demo/assets/chat-rooms-ember.gif b/demo/assets/chat-rooms-ember.gif
new file mode 100644
index 0000000000..da0305aec4
Binary files /dev/null and b/demo/assets/chat-rooms-ember.gif differ
diff --git a/demo/assets/chat-rooms-gray.gif b/demo/assets/chat-rooms-gray.gif
index 714feab7ae..0083fd3ca7 100644
Binary files a/demo/assets/chat-rooms-gray.gif and b/demo/assets/chat-rooms-gray.gif differ
diff --git a/demo/assets/chat-rooms-light.gif b/demo/assets/chat-rooms-light.gif
index 966f2569bd..b52a08d028 100644
Binary files a/demo/assets/chat-rooms-light.gif and b/demo/assets/chat-rooms-light.gif differ
diff --git a/demo/assets/chat-rooms.gif b/demo/assets/chat-rooms.gif
index 14bd038474..78dfbf7808 100644
Binary files a/demo/assets/chat-rooms.gif and b/demo/assets/chat-rooms.gif differ
diff --git a/demo/assets/command-center-activity.png b/demo/assets/command-center-activity.png
new file mode 100644
index 0000000000..7012fb68ef
Binary files /dev/null and b/demo/assets/command-center-activity.png differ
diff --git a/demo/assets/command-center-ember.gif b/demo/assets/command-center-ember.gif
new file mode 100644
index 0000000000..1d4cc6f826
Binary files /dev/null and b/demo/assets/command-center-ember.gif differ
diff --git a/demo/assets/command-center-gray.gif b/demo/assets/command-center-gray.gif
index f27e8eab01..6e49b6e460 100644
Binary files a/demo/assets/command-center-gray.gif and b/demo/assets/command-center-gray.gif differ
diff --git a/demo/assets/command-center-light.gif b/demo/assets/command-center-light.gif
index 52baa72bce..5138cd5db7 100644
Binary files a/demo/assets/command-center-light.gif and b/demo/assets/command-center-light.gif differ
diff --git a/demo/assets/command-center-overview.png b/demo/assets/command-center-overview.png
new file mode 100644
index 0000000000..34b252e4b2
Binary files /dev/null and b/demo/assets/command-center-overview.png differ
diff --git a/demo/assets/command-center-productivity.png b/demo/assets/command-center-productivity.png
index 5f6b20f89f..788254fbde 100644
Binary files a/demo/assets/command-center-productivity.png and b/demo/assets/command-center-productivity.png differ
diff --git a/demo/assets/command-center-signals.png b/demo/assets/command-center-signals.png
new file mode 100644
index 0000000000..b1dd7455a8
Binary files /dev/null and b/demo/assets/command-center-signals.png differ
diff --git a/demo/assets/command-center-team.png b/demo/assets/command-center-team.png
index b0bad24c43..7b8d3eeab2 100644
Binary files a/demo/assets/command-center-team.png and b/demo/assets/command-center-team.png differ
diff --git a/demo/assets/command-center-tokens.png b/demo/assets/command-center-tokens.png
index 524cd87cdf..bfe3e4c2d4 100644
Binary files a/demo/assets/command-center-tokens.png and b/demo/assets/command-center-tokens.png differ
diff --git a/demo/assets/command-center.gif b/demo/assets/command-center.gif
index bda701786a..79e41f6c9a 100644
Binary files a/demo/assets/command-center.gif and b/demo/assets/command-center.gif differ
diff --git a/demo/assets/dashboard-ember.png b/demo/assets/dashboard-ember.png
new file mode 100644
index 0000000000..b2c6566ea0
Binary files /dev/null and b/demo/assets/dashboard-ember.png differ
diff --git a/demo/assets/dashboard-graph.png b/demo/assets/dashboard-graph.png
new file mode 100644
index 0000000000..07c36316e8
Binary files /dev/null and b/demo/assets/dashboard-graph.png differ
diff --git a/demo/assets/dashboard-tokyo.png b/demo/assets/dashboard-tokyo.png
new file mode 100644
index 0000000000..84d89d085e
Binary files /dev/null and b/demo/assets/dashboard-tokyo.png differ
diff --git a/demo/assets/mobile-agents.png b/demo/assets/mobile-agents.png
index 9d2ad46810..75a3cb8c8d 100644
Binary files a/demo/assets/mobile-agents.png and b/demo/assets/mobile-agents.png differ
diff --git a/demo/assets/mobile-board.png b/demo/assets/mobile-board.png
index 472f687af4..2903186063 100644
Binary files a/demo/assets/mobile-board.png and b/demo/assets/mobile-board.png differ
diff --git a/demo/assets/mobile-chat-list.png b/demo/assets/mobile-chat-list.png
index ecb2891e53..b9e899adb3 100644
Binary files a/demo/assets/mobile-chat-list.png and b/demo/assets/mobile-chat-list.png differ
diff --git a/demo/assets/mobile-chat.png b/demo/assets/mobile-chat.png
index 3a6dd1128a..03921dfd51 100644
Binary files a/demo/assets/mobile-chat.png and b/demo/assets/mobile-chat.png differ
diff --git a/demo/assets/mobile-command-center.png b/demo/assets/mobile-command-center.png
index ac13aaf792..ebc171d48c 100644
Binary files a/demo/assets/mobile-command-center.png and b/demo/assets/mobile-command-center.png differ
diff --git a/demo/assets/mobile-missions.png b/demo/assets/mobile-missions.png
index 90a1fc2b7d..c0fe88035e 100644
Binary files a/demo/assets/mobile-missions.png and b/demo/assets/mobile-missions.png differ
diff --git a/demo/assets/workflows-ember.gif b/demo/assets/workflows-ember.gif
new file mode 100644
index 0000000000..2f15088d1b
Binary files /dev/null and b/demo/assets/workflows-ember.gif differ
diff --git a/demo/assets/workflows-gray.gif b/demo/assets/workflows-gray.gif
index a1f08916af..212e667b10 100644
Binary files a/demo/assets/workflows-gray.gif and b/demo/assets/workflows-gray.gif differ
diff --git a/demo/assets/workflows-light.gif b/demo/assets/workflows-light.gif
index 7283151cdb..cea22cc18d 100644
Binary files a/demo/assets/workflows-light.gif and b/demo/assets/workflows-light.gif differ
diff --git a/demo/assets/workflows.gif b/demo/assets/workflows.gif
index 09b2865637..691f449fcd 100644
Binary files a/demo/assets/workflows.gif and b/demo/assets/workflows.gif differ
diff --git a/demo/seed.ts b/demo/seed.ts
index b33ffd35e6..3ac97bb2f5 100644
--- a/demo/seed.ts
+++ b/demo/seed.ts
@@ -10,6 +10,7 @@
* - Planning: raw ideas just landing
*/
import { TaskStore } from "../packages/core/src/index.js";
+import { AgentStore, ChatStore, MessageStore } from "../packages/core/src/index.js";
import type { WorkflowIr } from "../packages/core/src/workflow-ir-types.js";
import { writeFile } from "node:fs/promises";
import { join } from "node:path";
@@ -291,29 +292,38 @@ async function main() {
] as const;
for (const t of browserDemo) {
- const task = await store.createTask({ description: t.desc, title: t.title });
- await store.updateTask(task.id, { size: "S", reviewLevel: 0 });
- await store.selectTaskWorkflowAndReconcile(task.id, browserDemoWorkflow.id);
+ try {
+ const task = await store.createTask({ description: t.desc, title: t.title });
+ await store.updateTask(task.id, { size: "S", reviewLevel: 0 });
+ await store.selectTaskWorkflowAndReconcile(task.id, browserDemoWorkflow.id);
- const steps = generateSteps(t.title);
- await writePrompt(store, task.id, t.title, t.desc, steps);
+ const steps = generateSteps(t.title);
+ await writePrompt(store, task.id, t.title, t.desc, steps);
- if (t.currentStep !== null) {
- for (let i = 0; i < Math.min(t.currentStep, steps.length); i++) {
- await store.updateStep(task.id, i, "done");
- }
- if (t.currentStep < steps.length) {
- await store.updateStep(task.id, t.currentStep, "in-progress");
- }
+ if (t.currentStep !== null) {
+ for (let i = 0; i < Math.min(t.currentStep, steps.length); i++) {
+ await store.updateStep(task.id, i, "done");
+ }
+ if (t.currentStep < steps.length) {
+ await store.updateStep(task.id, t.currentStep, "in-progress");
+ }
}
const lifecyclePath = ["todo", "in-progress", "in-review", "qa", "publish"] as const;
const targetIndex = lifecyclePath.indexOf(t.column);
- for (const column of lifecyclePath.slice(1, targetIndex + 1)) {
+ // FNXC:DemoSeed 2026-06-23-20:05: Walk the full lifecycle from "todo" so the
+ // transition validator accepts every hop (triage only allows โ todo directly).
+ for (const column of lifecyclePath.slice(0, targetIndex + 1)) {
await store.moveTask(task.id, column, { moveSource: "user", allowDirectInReviewMove: true });
}
- await addLogs(store, task.id, t.column);
+ await addLogs(store, task.id, t.column);
+ } catch (e) {
+ // FNXC:DemoSeed 2026-06-23-20:10: The Browser Demo Lifecycle workflow uses
+ // custom qa/publish columns whose transitions aren't in the default graph;
+ // skip cards that can't advance rather than aborting the whole seed.
+ console.warn(` (skipped browser demo card "${t.title}": ${(e as Error).message})`);
+ }
}
// โโ Planning โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
@@ -340,6 +350,9 @@ async function main() {
await store.createTask({ description: t.desc });
}
+ // โโ Agents, chat, and agent mail โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ await seedAgentsChatAndMail(store);
+
const tasks = await store.listTasks();
const byColumn: Record = {};
for (const t of tasks) {
@@ -357,6 +370,131 @@ async function main() {
console.log(`\nRun "kb dashboard" to see the board, including the browser demo lifecycle columns.`);
}
+// โโ Agents, chat, and agent mail โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+/*
+FNXC:DemoSeed 2026-06-23-19:50:
+The README showcase needs realistic agent chat threads, a multi-agent chat room,
+and an inter-agent mailbox with delegation/approval/triage content so the Agent
+Chat, Chat Rooms, and Agent Mail GIFs have believable data. This seeds durable
+agents (CEO, Product Manager, CTO, engineers), a direct chat session, a #leads
+room where the leadership trio coordinates, and mailbox messages covering
+triage summaries, approvals, and hand-offs.
+*/
+async function seedAgentsChatAndMail(store: TaskStore) {
+ const fusionDir = store.getFusionDir();
+ const db = store.getDatabase();
+ const agentStore = new AgentStore({ rootDir: fusionDir });
+ const chatStore = new ChatStore(fusionDir, db);
+ const messageStore = new MessageStore(db);
+
+ const roleDefs: Array<{ name: string; role: "engineer" | "custom"; title: string; reportsTo?: string }> = [
+ { name: "CEO", role: "custom", title: "Chief Executive Officer" },
+ { name: "Product Manager", role: "custom", title: "Product Manager", reportsTo: "CEO" },
+ { name: "CTO", role: "engineer", title: "Chief Technology Officer", reportsTo: "CEO" },
+ { name: "Fullstack Engineer", role: "engineer", title: "Fullstack Engineer", reportsTo: "CTO" },
+ { name: "Frontend Engineer", role: "engineer", title: "Frontend Engineer", reportsTo: "CTO" },
+ ];
+
+ const agentIds: Record = {};
+ for (const def of roleDefs) {
+ try {
+ const agent = await agentStore.createAgent({
+ name: def.name,
+ role: def.role,
+ title: def.title,
+ reportsTo: def.reportsTo ? undefined : undefined,
+ metadata: { description: def.title },
+ });
+ agentIds[def.name] = agent.id;
+ } catch {
+ // agent may already exist; look it up
+ const existing = await agentStore.findAgentByName(def.name);
+ if (existing) agentIds[def.name] = existing.id;
+ }
+ }
+
+ // wire up reportsTo now that all ids exist
+ for (const def of roleDefs) {
+ if (def.reportsTo && agentIds[def.name] && agentIds[def.reportsTo]) {
+ try {
+ await agentStore.updateAgent(agentIds[def.name], { reportsTo: agentIds[def.reportsTo] });
+ } catch {
+ // best effort
+ }
+ }
+ }
+
+ // โโ Direct chat session: user asks the Fullstack Engineer about a stuck task โโ
+ const session = chatStore.createSession({
+ agentId: agentIds["Fullstack Engineer"],
+ title: "FN-6917 is stuck landing โ what's going on?",
+ });
+ const chatThread: Array<[string, string]> = [
+ ["user", "FN-6917 has been sitting in In Review for 40 minutes. The auto-merge didn't fire โ any idea why?"],
+ ["assistant", "Looking at the logs now. The pre-squash diff-volume gate tripped because the worktree picked up an unrelated `pnpm-lock.yaml` regeneration. The actual code delta is only 12 lines."],
+ ["user", "Can we force it through, or do we need to rebase?"],
+ ["assistant", "Safest path is a rebase onto main to drop the lockfile churn, then the gate passes cleanly. I can do that now โ want me to proceed?"],
+ ["user", "Yes, go ahead. Ping me when it's green."],
+ ["assistant", "On it. Rebasing `fusion/FN-6917` onto `origin/main` now. I'll post the merge result in #leads when it lands."],
+ ];
+ for (const [role, content] of chatThread) {
+ chatStore.addMessage(session.id, { role: role as "user" | "assistant", content });
+ }
+
+ // โโ Multi-agent chat room: #leads โ CEO, PM, CTO coordinate โโ
+ const room = chatStore.createRoom({
+ name: "leads",
+ description: "Leadership sync โ mission ownership and blockers",
+ memberAgentIds: [agentIds["CEO"], agentIds["Product Manager"], agentIds["CTO"]].filter(Boolean) as string[],
+ });
+ const roomThread: Array<{ sender: string; mentions?: string[]; content: string }> = [
+ { sender: "CEO", content: "Q3 mission is `Ship multi-repo workspaces`. PM โ can you break that into milestones by EOD?" },
+ { sender: "Product Manager", mentions: ["CTO"], content: "On it. @CTO what's the rough engineering lift? Need it to size the slices." },
+ { sender: "CTO", content: "Core work is the CentralCore project-path resolver + a migration. Maybe 3 features, ~8 tasks. Frontend is a settings tab." },
+ { sender: "Product Manager", content: "Perfect. Three milestones: infra, migration, UI. I'll file the mission now and assign the infra slice to @CTO." },
+ { sender: "CEO", content: "Great. Let's autopilot the infra slice and gate the migration slice on manual review. Don't want data loss risk." },
+ { sender: "CTO", mentions: ["Fullstack Engineer"], content: "Agreed. @Fullstack Engineer will take the settings tab in parallel once the resolver lands." },
+ ];
+ for (const msg of roomThread) {
+ const senderId = agentIds[msg.sender];
+ if (!senderId) continue;
+ chatStore.addRoomMessage(room.id, {
+ role: "assistant",
+ content: msg.content,
+ senderAgentId: senderId,
+ mentions: msg.mentions?.map((m) => agentIds[m]).filter(Boolean),
+ });
+ }
+
+ // โโ Agent mailbox: triage summaries, approvals, hand-offs โโ
+ const mailMessages: Array<{
+ from: string; to: string; type: "agent-to-agent" | "agent-to-user"; content: string;
+ }> = [
+ { from: "Product Manager", to: "CTO", type: "agent-to-agent", content: "Triage complete for the inbox batch: 3 actionable issues filed as tasks (FN-6920, FN-6921, FN-6922), 2 duplicates closed, 1 needs your input on the schema migration approach. Summary attached." },
+ { from: "CTO", to: "Fullstack Engineer", type: "agent-to-agent", content: "FN-6920 (LOC backfill controls) is yours. Scope is `packages/dashboard/app/components/ProductivityView.tsx` plus the analytics resolver. Aim for review-level 1." },
+ { from: "Fullstack Engineer", to: "CTO", type: "agent-to-agent", content: "Approval requested: the productivity backfill needs a new `POST /api/productivity/backfill` route. OK to add it, or should I route through the existing insights endpoint?" },
+ { from: "CTO", to: "Product Manager", type: "agent-to-agent", content: "Hand-off: FN-6917 landed after a rebase. The auto-merge gate caught a bogus lockfile delta โ I've filed FN-6923 to harden the diff-volume check. Milestone 1 is unblocked." },
+ { from: "Product Manager", to: "user", type: "agent-to-user", content: "Weekly triage digest: 12 issues processed, 7 filed as tasks, 3 closed as duplicates, 2 escalated. Net backlog delta: +2. Full report in Artifacts." },
+ { from: "Frontend Engineer", to: "CTO", type: "agent-to-agent", content: "Settings tab for multi-repo is wired up and behind the experimental flag. Ready for review whenever you have a window โ no rush, infra slice isn't merged yet." },
+ ];
+ for (const msg of mailMessages) {
+ const fromId = agentIds[msg.from] ?? "user";
+ const toId = agentIds[msg.to] ?? "user";
+ messageStore.sendMessage({
+ fromId,
+ fromType: msg.from === "user" ? "user" : "agent",
+ toId,
+ toType: msg.to === "user" ? "user" : "agent",
+ content: msg.content,
+ type: msg.type,
+ });
+ }
+
+ console.log(` Agents: ${Object.keys(agentIds).length}`);
+ console.log(` Chat: 1 session (${chatThread.length} msgs), 1 room (${roomThread.length} msgs)`);
+ console.log(` Mailbox: ${mailMessages.length} messages`);
+}
+
// โโ Helpers โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function generateSteps(_title: string): string[] {