migrate-to-channels — community migrate-to-channels, omniclaw, community, ide skills

v1.0.0

About this Skill

Perfect for OmniClaw Agents needing to transition from flat group workspaces to layered context architectures. Migrate existing multi-agent Discord/Slack setup to the new agent/server/category/channel context architecture. Restructures group workspaces into isolated per-channel notebooks with shared category a

omniaura omniaura
[4]
[1]
Updated: 2/28/2026

Killer-Skills Review

Decision support comes first. Repository text comes second.

Reference-Only Page Review Score: 7/11

This page remains useful for operators, but Killer-Skills treats it as reference material instead of a primary organic landing page.

Original recommendation layer Concrete use-case guidance Explicit limitations and caution Locale and body language aligned
Review Score
7/11
Quality Score
45
Canonical Locale
en
Detected Body Locale
en

Perfect for OmniClaw Agents needing to transition from flat group workspaces to layered context architectures. Migrate existing multi-agent Discord/Slack setup to the new agent/server/category/channel context architecture. Restructures group workspaces into isolated per-channel notebooks with shared category a

Core Value

Empowers agents to transform existing setups into organized structures, utilizing layered context architecture with features like agent identity shared across channels, category team workspaces, and isolated channel notebooks, all while supporting file formats like .md and directory structures such as groups/, servers/, and channels/.

Ideal Agent Persona

Perfect for OmniClaw Agents needing to transition from flat group workspaces to layered context architectures.

Capabilities Granted for migrate-to-channels

Migrating flat groups to layered channel architectures
Organizing agent identities across multiple channels
Creating isolated channel notebooks for team collaborations

! Prerequisites & Limits

  • Requires existing OmniClaw setup
  • Only supports migration to layered context architecture
  • Directory structure needs to be compatible with groups/, servers/, and channels/ format

Why this page is reference-only

  • - The underlying skill quality score is below the review floor.

Source Boundary

The section below is imported from the upstream repository and should be treated as secondary evidence. Use the Killer-Skills review above as the primary layer for fit, risk, and installation decisions.

After The Review

Decide The Next Action Before You Keep Reading Repository Material

Killer-Skills should not stop at opening repository instructions. It should help you decide whether to install this skill, when to cross-check against trusted collections, and when to move into workflow rollout.

Labs Demo

Browser Sandbox Environment

⚡️ Ready to unleash?

Experience this Agent in a zero-setup browser environment powered by WebContainers. No installation required.

Boot Container Sandbox

FAQ & Installation Steps

These questions and steps mirror the structured data on this page for better search understanding.

? Frequently Asked Questions

What is migrate-to-channels?

Perfect for OmniClaw Agents needing to transition from flat group workspaces to layered context architectures. Migrate existing multi-agent Discord/Slack setup to the new agent/server/category/channel context architecture. Restructures group workspaces into isolated per-channel notebooks with shared category a

How do I install migrate-to-channels?

Run the command: npx killer-skills add omniaura/omniclaw/migrate-to-channels. It works with Cursor, Windsurf, VS Code, Claude Code, and 19+ other IDEs.

What are the use cases for migrate-to-channels?

Key use cases include: Migrating flat groups to layered channel architectures, Organizing agent identities across multiple channels, Creating isolated channel notebooks for team collaborations.

Which IDEs are compatible with migrate-to-channels?

This skill is compatible with Cursor, Windsurf, VS Code, Trae, Claude Code, OpenClaw, Aider, Codex, OpenCode, Goose, Cline, Roo Code, Kiro, Augment Code, Continue, GitHub Copilot, Sourcegraph Cody, and Amazon Q Developer. Use the Killer-Skills CLI for universal one-command installation.

Are there any limitations for migrate-to-channels?

Requires existing OmniClaw setup. Only supports migration to layered context architecture. Directory structure needs to be compatible with groups/, servers/, and channels/ format.

How To Install

  1. 1. Open your terminal

    Open the terminal or command line in your project directory.

  2. 2. Run the install command

    Run: npx killer-skills add omniaura/omniclaw/migrate-to-channels. The CLI will automatically detect your IDE or AI agent and configure the skill.

  3. 3. Start using the skill

    The skill is now active. Your AI agent can use migrate-to-channels immediately in the current project.

! Reference-Only Mode

This page remains useful for installation and reference, but Killer-Skills no longer treats it as a primary indexable landing page. Read the review above before relying on the upstream repository instructions.

Upstream Repository Material

The section below is imported from the upstream repository and should be treated as secondary evidence. Use the Killer-Skills review above as the primary layer for fit, risk, and installation decisions.

Upstream Source

migrate-to-channels

Install migrate-to-channels, an AI agent skill for AI agent workflows and automation. Review the use cases, limitations, and setup path before rollout.

SKILL.md
Readonly
Upstream Repository Material
The section below is imported from the upstream repository and should be treated as secondary evidence. Use the Killer-Skills review above as the primary layer for fit, risk, and installation decisions.
Supporting Evidence

Migrate to Channel Architecture

This skill migrates your existing OmniClaw setup from the flat groups/ workspace model to the new layered context architecture:

groups/
  agents/{agentId}/CLAUDE.md     ← agent identity (shared across channels)
  servers/{server}/{category}/    ← category team workspace
  servers/{server}/{category}/{channel}/  ← isolated channel notebook
  channels/{name}/               ← non-server channels (WhatsApp, Telegram)

What This Skill Does

  1. Inspects the live database — reads all channel_subscriptions, agents, and their current workspace mappings
  2. Consolidates legacy agent entries that share the same persona
  3. Proposes a folder mapping for each channel (server → category → channel path)
  4. Creates new directories and CLAUDE.md stubs for missing layers
  5. Updates channel_folder, category_folder, agent_context_folder in the DB for each subscription/agent
  6. Sets is_primary correctly on each channel's subscriptions
  7. Verifies agents without new fields still work (backward compat)

Known Gotchas (from real migration)

1. Consolidate legacy agent entries first

In older OmniClaw setups, each channel got its own agent entry (e.g., landing-astro-discord, spec-discord, backend-discord) even though they all share the same persona. These are not separate agents — they're just channels.

Before migrating, merge them: re-point their subscriptions to the canonical agent and delete the stubs.

sql
1-- Example: landing-astro-discord was just another PeytonOmni channel 2-- Move its subs to clayton-discord (if not already there) 3INSERT OR IGNORE INTO channel_subscriptions (channel_jid, agent_id, trigger_pattern, requires_trigger, priority, is_primary, discord_bot_id, discord_guild_id, created_at) 4SELECT channel_jid, 'clayton-discord', trigger_pattern, requires_trigger, priority, is_primary, discord_bot_id, discord_guild_id, created_at 5FROM channel_subscriptions WHERE agent_id = 'landing-astro-discord'; 6 7DELETE FROM channel_subscriptions WHERE agent_id = 'landing-astro-discord'; 8DELETE FROM agents WHERE id = 'landing-astro-discord'; 9DELETE FROM registered_groups WHERE folder = 'landing-astro-discord';

2. Set agent_context_folder — or identity breaks

Without agent_context_folder, the fallback identity injection fires using agent.name from the DB (e.g., "Landing Astro", "Ditto Discord") — not the persona name. The agent will say "I am Landing Astro" instead of "I am PeytonOmni".

Set this immediately after adding the agent identity file:

sql
1UPDATE agents SET agent_context_folder = 'agents/peytonomi' 2WHERE id IN ('clayton-discord', 'landing-astro-discord');

3. Internal bot key vs Discord snowflake ID — never confuse them

OmniClaw uses two completely different identifiers for Discord bots:

IdentifierWhere it livesExampleUsed for
Internal bot keyDISCORD_BOT_IDS in .envPRIMARY, OCPEYTONOmniClaw routing
Discord snowflake IDDiscord Developer Portal → App → General1476396931709276191Discord's own API

The channel_subscriptions.discord_bot_id column stores the internal bot key — the human-readable alias you defined in DISCORD_BOT_IDS. It must never contain a numeric Discord snowflake ID. If you accidentally write a numeric ID there, OmniClaw's routing will silently fall back to DISCORD_DEFAULT_BOT_ID for every message and scheduled task.

To verify:

bash
1# These should match keys in DISCORD_BOT_IDS, not numeric IDs 2sqlite3 store/messages.db "SELECT DISTINCT discord_bot_id FROM channel_subscriptions WHERE discord_bot_id IS NOT NULL"

If you see numeric IDs, fix them:

bash
1sqlite3 store/messages.db "UPDATE channel_subscriptions SET discord_bot_id = 'OCPEYTON' WHERE discord_bot_id = '1476396931709276191'"

Separate issue: When agent_context_folder is NULL, the injected identity block contains the bot key string (e.g., OCPEYTON, PRIMARY) not the persona name. This causes the agent to report conflicting identity info. The fix is always to set agent_context_folder.

4. is_primary controls more than routing — it controls channel name resolution

is_primary determines:

  • Which Discord bot handles the channel (sends messages, reactions)
  • Which agent's name is used as the display name when building channel lists
  • Which subscriptions fire as a fallback when no trigger is explicitly matched

In a multi-agent channel (e.g., PeytonOmni + OCPeyton both in #spec), set is_primary = 1 only on the human-persona agent (e.g., clayton-discord). The tool agent (ocpeyton-discord) should have is_primary = 0 so it only responds to explicit @OCPeyton mentions and never fires via fallback.

If is_primary is wrong, you'll see another agent's name appear as a channel name in the multi-channel list (e.g., "OCPeyton" showing up as a channel name in PeytonOmni's channel list).

sql
1-- Set primary correctly for each channel 2UPDATE channel_subscriptions SET is_primary = 1 3WHERE agent_id = 'clayton-discord'; -- persona agent owns the channel 4 5UPDATE channel_subscriptions SET is_primary = 0 6WHERE agent_id = 'ocpeyton-discord'; -- tool agent never owns

Steps

Step 1: Inspect current state

bash
1sqlite3 store/messages.db " 2SELECT id, name, agent_context_folder FROM agents ORDER BY id; 3SELECT '---'; 4SELECT channel_jid, agent_id, trigger_pattern, is_primary, channel_folder FROM channel_subscriptions ORDER BY channel_jid, agent_id; 5"

Look for:

  • Multiple agent entries that are really the same persona (different channel, same trigger/bot)
  • Agents with agent_context_folder = NULL (identity will be wrong)
  • Channels where is_primary isn't set correctly

Step 2: Consolidate legacy agent entries

Identify agents that are actually just channels for an existing persona. Re-point their subscriptions and delete the agent entry (see gotcha #1 above).

Step 3: Create agent identity files

For each distinct persona, create groups/agents/{id}/CLAUDE.md:

bash
1mkdir -p groups/agents/peytonomi 2cat > groups/agents/peytonomi/CLAUDE.md << 'EOF' 3# PeytonOmni Identity 4You are **PeytonOmni** (@PeytonOmni), ... 5EOF

Then set agent_context_folder in the DB immediately (gotcha #2).

Step 4: Create category directories and CLAUDE.md stubs

bash
1mkdir -p groups/servers/{server}/{category}/{channel}

Create a CLAUDE.md in each category folder documenting the project context shared across channels.

Step 5: Migrate legacy folder content to new channel dirs

For each old flat group folder (e.g., spec-discord/, agentflow-discord/), copy its contents into the new channel workspace. Use cp — never mv at this stage, so the original is preserved as a fallback.

bash
1# Copy all files except logs/ from old folder to new channel dir 2find groups/spec-discord -maxdepth 1 -not -name 'logs' -not -path 'groups/spec-discord' \ 3 -exec cp -r {} groups/servers/omni-aura/ditto-assistant/spec/ \;

Repeat for each old folder → new path mapping. After copying, verify the new dirs have the expected files.

If a channel has content in two legacy locations (e.g., both ocpeyton-discord/ and landing-astro-discord/ map to the same new channel), merge them manually — copy one first, then copy the other, skipping any collisions.

Offer to clean up old folders

After all content is verified in the new locations, use AskUserQuestion to ask the user:

All legacy folder content has been copied to the new channel structure. Want to delete the old folders?

  • Yes, delete them — removes the duplicates, keeps groups/ clean
  • No, keep them — I'll show you where everything lives so you can clean up manually later

If yes: first check whether any containers are actively running — deleting a folder while a container has it virtiofs-mounted can break the mount mid-run (the host rename makes the path disappear inside the container).

bash
1# Check for running omniclaw containers 2container list 2>/dev/null | grep omniclaw || echo "No containers running"

If containers are running, use AskUserQuestion to ask:

Some agent containers are currently running. Deleting their workspace folders now could break an in-progress response. What would you like to do?

  • Wait and check again — I'll re-check in a moment
  • Stop the service now — safest option, agents will pick up again on next restart

If wait: re-run the container list check and loop until clear, then delete without stopping the service:

bash
1rm -rf groups/spec-discord groups/agentflow-discord groups/clayton-discord # etc.

If stop the service: unload, delete, reload:

bash
1launchctl unload ~/Library/LaunchAgents/com.omniclaw.plist 2rm -rf groups/spec-discord groups/agentflow-discord groups/clayton-discord # etc. 3launchctl load ~/Library/LaunchAgents/com.omniclaw.plist

If no containers running: delete directly:

bash
1rm -rf groups/spec-discord groups/agentflow-discord groups/clayton-discord # etc.

If no: print a summary table of old → new paths so the user knows where to look:

Legacy folder                          → New location
groups/spec-discord/                   → groups/servers/omni-aura/ditto-assistant/spec/
groups/agentflow-discord/              → groups/servers/omni-aura/omniaura/agentflow/
groups/clayton-discord/                  → groups/servers/omni-aura/omniaura/agent-debug/
...

Handle orphaned folders

Some old folders may have no active DB entry (no registered_groups row, no channel_subscriptions). These are stale experiments. Show the user a list and ask if they want them deleted too. Safe to delete if they're just a CLAUDE.md — worth reviewing first if they have real content.

bash
1# Find folders with no DB entry 2for f in groups/*/; do 3 name=$(basename "$f") 4 count=$(sqlite3 store/messages.db "SELECT COUNT(*) FROM registered_groups WHERE folder='$name'") 5 [ "$count" = "0" ] && echo "Orphaned: $f ($(ls $f | grep -v logs | wc -l | tr -d ' ') files)" 6done

Step 6: Update subscriptions with channel/category folders

sql
1UPDATE channel_subscriptions 2SET channel_folder = 'servers/omni-aura/ditto-assistant/spec', 3 category_folder = 'servers/omni-aura/ditto-assistant' 4WHERE channel_jid = 'dc:...' AND agent_id = 'clayton-discord';

Step 7: Set is_primary correctly

sql
1-- Persona agent owns all channels 2UPDATE channel_subscriptions SET is_primary = 1 WHERE agent_id = 'clayton-discord'; 3-- Tool agents never own 4UPDATE channel_subscriptions SET is_primary = 0 WHERE agent_id = 'ocpeyton-discord';

Step 8: Strip extra mounts from Discord agents

Discord agents should not have host filesystem mounts. They should clone repos into their own workspace rather than reading from the host. Legacy additionalMounts in registered_groups.container_config give Discord agents access to the host filesystem, which can cause confusion (agents following stale docs to wrong paths) and is unnecessary security surface.

Remove container_config from all Discord registered_groups:

sql
1-- NULL out container_config for all Discord channels (dc: prefix) 2UPDATE registered_groups 3SET container_config = NULL 4WHERE jid LIKE 'dc:%';

If any channel genuinely needs custom mounts (e.g., a local dev agent), restore only that channel's config explicitly:

sql
1UPDATE registered_groups 2SET container_config = '{"additionalMounts":[...]}' 3WHERE folder = 'local-dev-agent';

Set nonMainReadOnly: true in the mount allowlist:

Edit ~/.config/omniclaw/mount-allowlist.json and set:

json
1{ 2 "nonMainReadOnly": true 3}

This is belt-and-suspenders: even if container_config is accidentally set again, the allowlist prevents any non-main agent from getting write access to extra mounts. Discord agents that need to read/write code should clone the repo into /workspace/group/ or /workspace/extra/ and work from there.

Step 9: Restart and verify

bash
1launchctl unload ~/Library/LaunchAgents/com.omniclaw.plist 2launchctl load ~/Library/LaunchAgents/com.omniclaw.plist

Ask each agent: "what are your debug info / loaded contexts?" — verify:

  • Identity name matches the persona (not the DB agent name)
  • /workspace/agent/CLAUDE.md appears in loaded contexts
  • Channel list shows real channel names, not agent names

Step 10: Remove any legacy heartbeat config

The heartbeat feature has been removed. Use scheduled tasks (create_task) instead — they're more flexible and don't silently re-create themselves on restart.

If any agents or groups had heartbeat configured, it will be automatically NULLed out on first startup (the migration runs in createSchema()). But you can also clean it up manually:

sql
1UPDATE registered_groups SET heartbeat = NULL WHERE heartbeat IS NOT NULL; 2UPDATE agents SET heartbeat = NULL WHERE heartbeat IS NOT NULL; 3DELETE FROM scheduled_tasks WHERE id LIKE 'heartbeat-%';

Any ## Heartbeat sections in existing CLAUDE.md files are now inert (the system no longer reads them). You can leave them as documentation or migrate the content to a regular scheduled task.


Backward Compatibility

  • Agents without agent_context_folder → no /workspace/agent/ mount, identity via agentName fallback (works but name may be wrong — see gotcha #2)
  • Subscriptions without channel_folder → workspace falls back to agent folder (unchanged behavior)
  • Subscriptions without category_folder → no /workspace/category/ mount (unchanged behavior)

Related Skills

Looking for an alternative to migrate-to-channels or another community skill for your workflow? Explore these related open-source skills.

View All

openclaw-release-maintainer

Logo of openclaw
openclaw

Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞

333.8k
0
AI

widget-generator

Logo of f
f

Generate customizable widget plugins for the prompts.chat feed system

149.6k
0
AI

flags

Logo of vercel
vercel

The React Framework

138.4k
0
Browser

pr-review

Logo of pytorch
pytorch

Tensors and Dynamic neural networks in Python with strong GPU acceleration

98.6k
0
Developer