.claude/skills/channel-management/SKILL.md
Manage Claude Code --channels sessions (start/stop/status/health) via channel-manager.cjs and terminal-tracker.cjs.
npx skillsauth add oimiragieo/agent-studio channel-managementInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill manages the full lifecycle of a Claude Code --channels session (Telegram bot, Discord bot, or any plugin-based channel integration). It wraps the CLI tools at .claude/tools/cli/channel-manager.cjs and .claude/tools/cli/terminal-tracker.cjs and provides a repeatable, observable workflow for:
Skill({ skill: 'channel-management' });
Invoke when:
CHANNEL_AUTO_START=true is set and session startup must be verified on agent bootNEVER start a channel session without checking isChannelRunning() first.
NEVER assume a tracked PID is alive without calling isPidAlive(pid).
NEVER restart after a crash without calling killOrphaned() to prune stale entries.
Before executing any lifecycle action, read memory to check for known issues:
node -e "const fs=require('fs');const p='.claude/context/memory/learnings.md';if(fs.existsSync(p))console.log(fs.readFileSync(p,'utf8').split(/\r?\n/).slice(0,80).join('\n'));"
Check .claude/context/memory/issues.md for any known channel startup problems:
node -e "const fs=require('fs');const p='.claude/context/memory/issues.md';if(fs.existsSync(p))console.log(fs.readFileSync(p,'utf8').split(/\r?\n/).slice(0,60).join('\n'));"
Command:
node -e "
const { isChannelRunning, getChannelPid } = require('./.claude/tools/cli/channel-manager.cjs');
const running = isChannelRunning();
const pid = getChannelPid();
console.log(JSON.stringify({ running, pid }));
"
Expected output: {"running":false,"pid":null} (not running) or {"running":true,"pid":12345} (running)
Verify: Exit code 0 and valid JSON printed to stdout.
Decision gate:
running: true → Skip Step 2 (already running), proceed to Step 4 (health check)running: false → Continue to Step 2Pre-condition: Confirm TELEGRAM_BOT_TOKEN is set:
node -e "
require('dotenv').config({ path: '.env' });
const token = process.env.TELEGRAM_BOT_TOKEN;
console.log(token ? 'TOKEN_PRESENT' : 'TOKEN_MISSING');
"
If TOKEN_MISSING: Log to issues.md and abort — channel cannot start without credentials.
Start command:
node -e "
const { startChannel } = require('./.claude/tools/cli/channel-manager.cjs');
const result = startChannel();
console.log(JSON.stringify(result));
"
Expected output: {"ok":true,"pid":12345,"reason":"started"} on success, or {"ok":false,"pid":null,"reason":"TELEGRAM_BOT_TOKEN not set — skipped"} when token missing.
Verify: ok: true in JSON output. Exit code 0.
After a successful start, confirm the PID is registered in the tracker:
node -e "
const { listTracked } = require('./.claude/tools/cli/terminal-tracker.cjs');
const sessions = listTracked();
const channel = sessions.filter(s => s.purpose === 'channel-session');
console.log(JSON.stringify(channel, null, 2));
"
Expected output: Array containing at least one entry with "status": "active" and a numeric "pid".
Verify: Entry exists with status: "active".
Confirm the session is alive after startup (or as a standalone health probe):
node -e "
const { isChannelRunning, getChannelPid } = require('./.claude/tools/cli/channel-manager.cjs');
const { listTracked } = require('./.claude/tools/cli/terminal-tracker.cjs');
const running = isChannelRunning();
const pid = getChannelPid();
const tracked = listTracked().find(s => s.purpose === 'channel-session' && s.status === 'active');
console.log(JSON.stringify({
health: running ? 'OK' : 'DEGRADED',
pid,
trackerEntry: tracked || null
}));
"
Expected output: {"health":"OK","pid":12345,"trackerEntry":{...}} when healthy.
Verify: health: "OK" in JSON. If health: "DEGRADED", proceed to Step 5 (restart).
Use when explicitly stopping the channel or before a clean restart:
node -e "
const { stopChannel } = require('./.claude/tools/cli/channel-manager.cjs');
const result = stopChannel();
console.log(JSON.stringify(result));
"
Expected output: {"ok":true,"reason":"stopped"} or {"ok":true,"reason":"not-running"}.
Verify: ok: true.
After a crash or unexpected shutdown, clean up stale PID entries:
node -e "
const { killOrphaned } = require('./.claude/tools/cli/terminal-tracker.cjs');
killOrphaned();
console.log('Orphan prune complete');
"
Expected output: Orphan prune complete
Verify: Exit code 0. Re-run Step 1 to confirm running: false after prune.
After any lifecycle action, append a brief note:
# Append to learnings.md (adjust message as appropriate)
node -e "
const fs = require('fs');
const ts = new Date().toISOString();
const entry = '\n## ' + ts + ' — channel-management\n- Channel session lifecycle action completed. PID: <PID>. Status: <STATUS>.\n';
fs.appendFileSync('.claude/context/memory/learnings.md', entry, 'utf8');
console.log('Memory updated');
"
When CHANNEL_AUTO_START=true is set in .env, agents should execute this skill at startup:
// In agent Step 0 or heartbeat-orchestrator boot sequence
if (process.env.CHANNEL_AUTO_START === 'true') {
Skill({ skill: 'channel-management' });
}
The skill is idempotent — calling it when the session is already running is a safe no-op.
| Variable | Required | Default | Purpose |
| --------------------- | -------- | ----------------------------------------- | ---------------------------------------------------------- |
| TELEGRAM_BOT_TOKEN | YES | — | Telegram bot credentials |
| CHANNEL_AUTO_START | NO | false | Auto-start on agent boot |
| CHANNEL_PLUGINS | NO | plugin:telegram@claude-plugins-official | Space-separated plugin list |
| CHANNEL_PERMISSIONS | NO | — | Extra claude flags (e.g. --dangerously-skip-permissions) |
Input validated against schemas/input.schema.json before execution.
Output contract defined in schemas/output.schema.json.
Pre-execution hook validates that the action field is a known enum value and that a TELEGRAM_BOT_TOKEN guard is in place for start actions.
startChannel() in a tight loop without checking isChannelRunning() first — each call spawns a new Windows Terminal tabisPidAlive()CHANNEL_AUTO_START=true without monitoring — silent crashes will not be detected without a health-check cronshell: true in any child process spawned from this skill — use array arguments with shell: false (already enforced in channel-manager.cjs).claude/tools/cli/channel-manager.cjs — Core lifecycle API (startChannel, stopChannel, isChannelRunning, getChannelPid).claude/tools/cli/terminal-tracker.cjs — PID registry (registerSpawn, listTracked, killOrphaned, cleanup).claude/context/runtime/terminal-pids.json — Live PID tracker state fileBefore starting: Read .claude/context/memory/learnings.md and .claude/context/memory/issues.md for known channel startup problems.
After completing: Append outcome to .claude/context/memory/learnings.md with timestamp and action taken.
ASSUME INTERRUPTION: Your context may reset. If it's not in memory, it didn't happen.
tools
Comprehensive biosignal processing toolkit for analyzing physiological data including ECG, EEG, EDA, RSP, PPG, EMG, and EOG signals. Use this skill when processing cardiovascular signals, brain activity, electrodermal responses, respiratory patterns, muscle activity, or eye movements. Applicable for heart rate variability analysis, event-related potentials, complexity measures, autonomic nervous system assessment, psychophysiology research, and multi-modal physiological signal integration.
tools
Comprehensive toolkit for creating, analyzing, and visualizing complex networks and graphs in Python. Use when working with network/graph data structures, analyzing relationships between entities, computing graph algorithms (shortest paths, centrality, clustering), detecting communities, generating synthetic networks, or visualizing network topologies. Applicable to social networks, biological networks, transportation systems, citation networks, and any domain involving pairwise relationships.
data-ai
Molecular featurization for ML (100+ featurizers). ECFP, MACCS, descriptors, pretrained models (ChemBERTa), convert SMILES to features, for QSAR and molecular ML.
development
Run Python code in the cloud with serverless containers, GPUs, and autoscaling. Use when deploying ML models, running batch processing jobs, scheduling compute-intensive tasks, or serving APIs that require GPU acceleration or dynamic scaling.