Intercom logo

Intercom

Organization
bastani-inc
intercom

Streamline session-to-session coordination with the intercom extension. Send messages, delegate tasks, and coordinate work across multiple atomic sessions on the same machine. Use for planner-worker workflows, cross-session context sharing, and real-time collaboration between sessions.

Overview

Publisherbastani-inc
Repositoryatomic
Skill nameintercom
Stars
856
Forks
115
Bundled files
Instructions only
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by bastani-inc on GitHub. Read the source before you install it.

Installation

Install the Intercom AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/bastani-inc/atomic/tree/main/packages/intercom/skills/intercom
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/bastani-inc/atomic.git /tmp/atomic
mkdir -p .claude/skills
cp -r /tmp/atomic/packages/intercom/skills/intercom .claude/skills/intercom
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Intercom in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Intercom on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Intercom is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Intercom Skill

Use this skill when you need to coordinate work across multiple atomic sessions running on the same machine. Intercom enables direct 1:1 messaging between sessions for delegation, context sharing, and collaborative workflows.

When you are supervising with the subagent skill, delegated child agents can escalate to you via contact_supervisor if the subagent runtime supplied child bridge metadata. This skill covers how to handle those orchestrator-side escalations, and how children and workflow stages talk to each other as peers.

When to Use

  • Task delegation: Split work between a planner session and worker sessions
  • Context handoffs: Send findings from a research session to an execution session
  • Clarification loops: Worker asks questions, planner answers, work continues
  • Multi-session workflows: Coordinate between specialized sessions (frontend/backend, research/implementation)
  • Peer coordination: Sibling subagents or workflow stages debate findings, hand off evidence, divide ownership, and learn from each other without routing through the supervisor

Core Patterns

Pattern 1: Planner-Worker Delegation

The most common pattern. One session holds the big picture, others do hands-on work.

Setup (in each session):

/name planner    # Terminal 1
/name worker     # Terminal 2

Planner delegates a task (fire-and-forget):

typescript
intercom({
  action: "send",
  to: "worker",
  message: "Task-3: Add retry logic to API client. Key files: src/api/client.ts. Ask if anything's unclear."
})

Worker asks for clarification (blocks until answer):

typescript
intercom({
  action: "ask",
  to: "planner",
  message: "Should I use exponential backoff or fixed intervals?"
})
// → Returns the planner's reply as the result

Worker reports completion:

typescript
intercom({
  action: "ask",
  to: "planner",
  message: "Task-3 complete. Added exponential backoff (100ms → 1600ms, max 5 retries). Ready for task-4?"
})

Pattern 2: Quick Status Check

Before sending, verify who's connected. Full session UUIDs or their unique 8-hex prefixes can be used as targets. Each list row leads with a copyable full session ID or canonical workflow path. Names are secondary; redundant generated aliases are omitted from the list but remain valid targets.

typescript
intercom({ action: "list" })
// → - `6332faab-1111-4222-8333-123456789abc` [idle] /workspace (model) name: planner
intercom({ action: "ask", to: "6332faab-1111-4222-8333-123456789abc", message: "Which option should I use?" })

Live sessions accept an exact full Intercom session ID, a unique 8-hex prefix of a visible UUID-backed session, or an exact case-insensitive name. Ambiguous prefixes require a listed full UUID. For workflow stages, first join workflow:<rootRunId> and use intercom({ action: "list" }): materialized stages appear as PENDING or RUNNING with canonical workflow:<rootRunId>/<segment>[/<segment>...] targets and actual groups, followed by possible future targets with queued counts. The invocation context can control owned isolated subgroups by exact target, while sibling subgroups and other runs remain isolated. Use queued send for PENDING or future targets; ask is supported only for RUNNING, where an exact correlated reply returns to the invocation asker.

Deliver to workflow stages that have not started

Send material updates through Intercom to every affected workflow stage, including stages that have not started. Before steering, join the invocation group workflow:<rootRunId> (discover it with the Intercom groups action), then use intercom list there to see live, pending, and possible future targets.

typescript
intercom({
  action: "send",
  to: "workflow:<rootRunId>/reviewer",
  message: "Scope changed: preserve raw amendment text in the verification oracle."
})
// → queued, distinct from live-session delivered, with the FIFO position

Each path segment may be a stage name, a run id, or a glob: * matches one segment and may be embedded (reviewer-*), while ** matches any depth. When shared scope or acceptance criteria change, broadcast one authoritative update to workflow:<rootRunId>/** (or a narrower pattern) rather than enumerating stages. The broadcast reaches every live stage immediately and remains sticky for every future matching stage, including nested children, until the root run terminates. Other name or pattern sends have the same every-future-match behavior.

A syntactically valid target outside the persisted possible-stage set is accepted speculatively: the queued acknowledgment includes notInKnownSet. At terminal settlement, an entry that never delivered produces the correlated undeliverable notification; an entry delivered at least once does not. A stage receives queued messages through the ordinary inbound path before its first model turn under Messages received before you started, with real sender identity and a Sent: timestamp. Only same-workflow-group sessions may queue messages. Each target holds at most 50 queued messages; the next send is refused rather than evicting one. Resume/replay, broker restart, and stage-attempt restart preserve exactly-once delivery per message and materialized stage. Use ask only for a live target: pending, future, and pattern asks return pending_stage_ask_unsupported.

Runtime named groups

Plain chat sessions can add and remove group memberships without restarting:

typescript
// Add a membership. Existing memberships remain active.
intercom({ action: "join", group: "api-review" })

// Discover every available group and see membership markers.
intercom({ action: "groups" })

// Remove one membership, or reset to home by omitting group.
intercom({ action: "leave", group: "api-review" })
intercom({ action: "leave" })

list still lists sessions: without a filter it returns every peer sharing at least one membership. default remains shared, while true and auto remain reserved. Later subagents inherit the most recently joined membership. Ordinary send/ask requires a shared membership; only authorized contact_supervisor traffic crosses group boundaries.

Pattern 3: Reply Naturally

When responding to an inbound ask, prefer reply instead of reconstructing raw IDs:

typescript
// In the turn triggered by the ask:
intercom({
  action: "reply",
  message: "Use exponential backoff starting at 100ms."
})

// If replying later and there might be more than one pending ask:
intercom({ action: "pending" })
intercom({ action: "reply", to: "planner", message: "Use exponential backoff starting at 100ms." })

Explicit to selects that sender's pending ask even if another message triggered the current turn. Use pending and an exact pending message ID or unique 8-hex UUID prefix in replyTo when the sender has several asks. Prefixes resolve to the canonical full ID before fallback; collisions fail. Stale, unknown, empty, or sender-mismatched explicit selectors fail without replying to another thread. Omit both selectors only when you intend to reply to the active message, or otherwise the single pending ask.

Pattern 4: Broadcast to Multiple Workers

Send to multiple sessions in parallel:

typescript
const workers = ["worker-1", "worker-2", "worker-3"];
const task = "Check for null pointer exceptions in your assigned files";

// Fire-and-forget to all workers
workers.forEach(w => 
  intercom({ action: "send", to: w, message: task })
);

Pattern 5: Send with Attachments

Share code snippets, files, or context:

typescript
intercom({
  action: "send",
  to: "worker",
  message: "Here's the fix for the auth issue:",
  attachments: [{
    type: "snippet",
    name: "auth.ts",
    language: "typescript",
    content: `function validateUser(user: User | null) {
  if (!user) throw new Error("User required");
  return user.email?.includes("@");
}`
  }]
})

Pattern 6: Handle Subagent Escalations (Orchestrator Side)

When the subagent runtime spawns a delegated child and supplies child bridge metadata, that child can reach you through contact_supervisor. You receive a formatted message that includes run metadata:

**From subagent-worker-78f659a3-1**

Subagent needs a supervisor decision.
Run: 78f659a3
Agent: worker
Child index: 0

Which API should I use?

Reply using reply:

typescript
// The reply hint in the incoming message will show the exact call:
intercom({ action: "reply", message: "Use the stable v2 API." })

This works because reply resolves the correct sender and message ID automatically.

Three types of escalations to expect:

TypeWhat it meansHow to respond
need_decisionSubagent is blocked and waiting for your answer. Has a 10-minute timeout.Reply promptly with a clear decision. If you need more context, ask follow-up questions via reply.
interview_requestSubagent needs multiple structured answers in one blocking exchange. Has a 10-minute timeout.Reply with plain JSON or a fenced json block using the provided { "responses": [...] } shape.
progress_updateSubagent is sharing meaningful progress or a plan-changing discovery. Not blocking.Read and acknowledge. No reply required unless you want to redirect.

When a subagent asks:

typescript
// In the turn triggered by the incoming ask:
intercom({ action: "reply", message: "Use exponential backoff, max 3 retries." })

When a subagent sends an interview request:

Read the rendered questions in the incoming message and reply with the exact ids in JSON. info questions are context-only and do not need response entries:

typescript
intercom({
  action: "reply",
  message: "```json\n{\n  \"responses\": [\n    { \"id\": \"api\", \"value\": \"Stable API\" },\n    { \"id\": \"constraints\", \"value\": \"Keep the public error shape unchanged.\" }\n  ]\n}\n```"
})

If you receive multiple pending asks:

typescript
intercom({ action: "pending" })
// → Shows every unresolved ask with sender, exact message ID, age, and preview

intercom({ action: "reply", to: "subagent-worker-78f659a3-1", message: "Use the v2 API." })
// If that sender has multiple asks, select the exact listed thread:
intercom({ action: "reply", replyTo: "message-id", message: "Use the v2 API." })

Important: Only sessions where the subagent runtime supplied child bridge metadata get the contact_supervisor tool. Normal sessions use the regular intercom tool. If you see the formatted supervisor decision/progress update message, treat it as a contact_supervisor escalation.

Pattern 7: Constructive Quorum

Use constructive quorum when several fresh-context reviewers judge the same artifact and a tally could hide a defect one reviewer found or preserve another reviewer's misreading.

  1. Each reviewer inspects independently and records a preliminary verdict before reading sibling findings or verdicts.
  2. Run exactly one bounded evidence-exchange round: share concrete findings and evidence, challenge blocking claims, surface missed defects, and correct objective/acceptance-criteria misreadings. Do not continue into a second round.
  3. Change a verdict only through evidence, never deference. Each reviewer emits its own final structured verdict and records whether the round changed it and which evidence caused the change.
  4. Let the deterministic reducer count final votes; this pattern does not change quorum counts or the stop_review_loop contract.

In Atomic workflows, each invocation has its own Intercom group, and parallel stages and delegated subagents inherit it when Intercom is available. Sibling reviewers can therefore coordinate without custom group wiring. See the constructive quorum workflow pattern.

Pattern 8: Peer Coordination Between Subagents and Workflow Stages

Communication inside a delegation is not only vertical. Children launched in one parallel set (or one explicit group) share an Intercom group, and workflow stages share their invocation group workflow:<rootRunId>; delegated subagents inside a stage inherit it. Any of them can list live siblings and message them directly. contact_supervisor is reserved for the supervisor; peer traffic uses ordinary intercom.

typescript
// Any child or stage: discover who is live in your group
intercom({ action: "list" })

// Connect: pass what you found to the sibling who needs it
intercom({ action: "send", to: "codebase-analyzer-2", message: "Null handling lives in src/auth/session.ts:40-118 and src/auth/refresh.ts:12-60. Start there." })

// Coordinate: claim shared work so two writers do not collide
intercom({ action: "send", to: "worker-1", message: "I am running the integration suite now (~4 min). Do not start it; I will send the result." })

// Learn: reuse a sibling's verified reproduction
intercom({ action: "ask", to: "debugger-1", message: "What exact command and env reproduced the timeout? I want to reuse it, not rediscover it." })

// Debate: challenge a finding with evidence, then decide for yourself
intercom({ action: "ask", to: "reviewer-2", message: "You called the retry loop unbounded. client.ts:88 caps attempts at 5 — which path bypasses it?" })

Rules that keep peer exchange useful:

  • Peers do not coordinate spontaneously. The launcher's prompt should name the peers (or how to discover them with list) and what they are expected to exchange.
  • Bound the exchange: one evidence round for reviewers, one ownership claim per shared step, one ask per fact you need. Then return your own complete result.
  • Decide on evidence, not deference. A peer's approval, rejection, or claim is input to inspect, not a verdict to copy.
  • Scope, product, architecture, and acceptance decisions stay with the supervisor (contact_supervisor) or a workflow gate.
  • Inside a workflow, send to a known pending sibling queues until it starts, and ask to a completed sibling that retains a valid conversation reopens it for a post-mortem turn. Named stage subgroups isolate their members from sibling subgroups.
  • Peer asks and one blocking supervisor request may wait concurrently in the same child; mutual asks work when both sides process inbound work.

Key Differences

ActionBehaviorUse When
joinAdds or creates a named membership in placeSessions need another shared routing group
leaveRemoves one named membership, or resets to home when omittedStop sharing one group or restore startup membership
groupsLists every available group with counts and membership markersDiscover a group instead of guessing its name
sendFire-and-forget to a live session, or durable sticky delivery to workflow:<rootRunId>/<segment>[/<segment>...]; globs and ** broadcasts cover live and future matchesYou don't need a response
askBlocks until a live recipient replies (10 min timeout); refused for an unstarted stageYou need an answer to continue
replyResponds to the active or pending inbound ask; to accepts an exact name/full session ID or unique 8-hex session UUID prefixYou were asked something and need to answer naturally
pendingLists unresolved inbound asksYou need to see who is waiting before replying
listReturns all sessions sharing any membership, with full IDs and live statusDiscover targets or choose an idle peer
statusReturns connection state and every current membershipTroubleshooting

Inside workflows, ask may target a sibling stage that has already completed. If that stage retains a valid conversation, Atomic automatically schedules a post-mortem turn there and preserves the exact child-to-child reply thread; do not send a separate workflow follow-up. Missing, deleted, non-resumable, or failed-to-reopen completed targets return an actionable error. A parent or unrelated session cannot satisfy the pending ask.

Optional: Visible Peer Sessions via cmux, tmux, or psmux (Windows rewrite of tmux that has fully parity with tmux)

If no suitable intercom-connected peer session already exists and the task benefits from a long-lived visible conversation, you may spawn a new atomic session.

Prefer cmux new-split right over new surfaces or workspaces so both sessions are visible side by side.

If cmux is unavailable, tmux is an optional fallback when it is installed and relevant. Use it with a private socket so the session is isolated and observable.

Use spawned peer sessions only for:

  • same-codebase worker/planner splits
  • reference-codebase scouting
  • long-lived visible conversations where the user benefits from watching both sides

Do not use this for unrelated repos, trivial questions, or work you can finish cleanly in the current session.

Preferred: cmux Worker or Scout Session

Same codebase:

bash
cmux new-split right
sleep 0.5
cmux send --surface right 'cd /path/to/current/repo && atomic\n'

Reference codebase:

bash
cmux new-split right
sleep 0.5
cmux send --surface right 'cd /path/to/reference/repo && atomic\n'

Optional Fallback: tmux Worker or Scout Session

Same codebase:

bash
SOCKET_DIR=${TMPDIR:-/tmp}/atomic-tmux-sockets
mkdir -p "$SOCKET_DIR"
SOCKET="$SOCKET_DIR/atomic.sock"
SESSION=atomic-worker
tmux -S "$SOCKET" new -d -s "$SESSION" -c "/path/to/current/repo" 'atomic'

Reference codebase:

bash
SOCKET_DIR=${TMPDIR:-/tmp}/atomic-tmux-sockets
mkdir -p "$SOCKET_DIR"
SOCKET="$SOCKET_DIR/atomic.sock"
SESSION=atomic-reference-auth
tmux -S "$SOCKET" new -d -s "$SESSION" -c "/path/to/reference/repo" 'atomic'

When you use tmux, tell the user how to watch it:

bash
tmux -S "$SOCKET" attach -t "$SESSION"

After launch, name the new session clearly so it is easy to target:

text
/name worker
/name reference-auth

Then coordinate from the current session:

typescript
intercom({
  action: "send",
  to: "worker",
  message: "Take task X. Ask if blocked."
})

intercom({
  action: "ask",
  to: "reference-auth",
  message: "How does this repo structure token refresh retries?"
})

Spawn Decision Rule

Spawn a visible peer session only when all of these are true:

  • no existing intercom-connected session already fits the need
  • the work benefits from a long-lived visible peer session
  • the peer session is either in the same codebase or in an intentional reference codebase
  • cmux is available, or tmux is available as an intentional fallback

If neither cmux nor tmux is available, skip this path and use normal intercom workflows.

Important Constraints

ask Limitations

  • Terminal noninteractive children: Completed, failed, interrupted, or cancelled subagents cannot reply, even if listed as idle. New asks fail immediately; an admitted ask fails if the child terminates before replying. Launch a fresh child with explicit context. Live interactive idle sessions and reply-capable workflow post-mortem conversations remain askable; send semantics are unchanged.
  • 10-minute timeout: If no reply comes within 10 minutes, the ask fails
  • Bounded concurrency: Up to maxPendingAsks asks (default: 6) may wait concurrently; additional calls receive a structured capacity error
  • Exact correlation: Same-target and mixed-target asks may run together; out-of-order replies and peer disconnects settle only the matching sender/message pair
  • Cannot self-target: A session cannot ask itself
  • Supervisor exclusivity: One blocking contact_supervisor decision/interview may coexist with peer asks, but a second supervisor wait is refused with Already waiting for a supervisor reply
typescript
// Parallel fan-out is supported within the configured capacity.
const [design, tests] = await Promise.all([
  intercom({ action: "ask", to: "architect", message: "Review the design" }),
  intercom({ action: "ask", to: "qa", message: "Review the tests" }),
]);

send Behavior

  • No timeout: Message is delivered or fails immediately
  • Confirmation dialogs: If confirmSend: true in config, interactive sessions show a confirmation dialog
  • Replies skip confirmation: Messages with replyTo never show confirmation dialogs

Best Practices

Use ask for blocking workflows

When the worker needs information to proceed:

typescript
// GOOD: Worker blocks until planner responds
const reply = await intercom({
  action: "ask",
  to: "planner",
  message: "API rate limit is 100/min. Should I implement client-side throttling or batching?"
});
// Continue with the answer...

Use send for notifications

When you just want to inform:

typescript
// GOOD: Fire-and-forget notification
intercom({
  action: "send",
  to: "reviewer",
  message: "PR #123 is ready for review. Key changes in auth.ts."
});
// Continue immediately, don't wait

Include reply hints in messages

Make it easy for recipients to respond:

typescript
// GOOD: Recipient sees exact command to reply
intercom({
  action: "send",
  to: "worker",
  message: `Found the issue in auth.ts:142. Use getUserById() instead of getUser().

Reply with: intercom({ action: "reply", message: "..." })`
});

Name sessions meaningfully

Use /name so others can target you easily:

/name api-worker
/name frontend-dev
/name planner

Error Handling

Common Errors and Solutions

"Too many pending asks"

typescript
// This session reached maxPendingAsks. Wait for an existing ask to settle,
// or use fire-and-forget send when the answer need not be this tool result.
intercom({ action: "send", to: "planner", message: "..." });

"Already waiting for a supervisor reply"

typescript
// Supervisor decisions/interviews are exclusive per child. Ordinary peer
// asks may continue concurrently; wait for the current supervisor call.

"Cannot message the current session"

typescript
// You cannot target yourself
// This usually means you confused session names - double-check the target

"Session not found"

typescript
const result = await intercom({ action: "send", to: "worker", message: "..." });
if (!result.delivered) {
  console.log("Failed:", result.reason);
  // → "Session not found" - check the name and list available sessions
  await intercom({ action: "list" });
}

Ask timeout (after 10 minutes)

typescript
// The ask will reject with a timeout error
// Design your workflow so answers come within 10 minutes
// For longer tasks, use send + follow-up ask pattern

Troubleshooting

Session not appearing in list

  1. Check Intercom connection status: intercom({ action: "status" })
  2. Verify the target session has loaded Atomic's bundled Intercom extension
  3. Ensure both sessions are on the same machine (intercom is same-machine only)

Message not delivered

typescript
const result = await intercom({ action: "send", to: "worker", message: "..." });
if (!result.delivered) {
  console.log("Failed:", result.reason);
  // → "Session not found" or delivery failure reason
}

Connection lost

Sessions automatically reconnect if the broker restarts. A single send, ask, or reply call also owns up to three internal retries after a typed recoverable disconnect, with 1, 2, and 5 second delays. Do not supply a retry token. The tool preserves the original message ID, arguments, and reply route, and never extends the original 11-minute deadline. Confirmation appears only once.

Every new tool call is a new operation, even with identical text. If recovery cannot establish the result, the tool returns a terminal error with outcome: "unknown": delivery may already have occurred. Do not repeat that operation automatically. Check with the recipient before intentionally sending again. Cancellation stops new attempts; a successful receipt still reports success. An accepted ask cancelled or timed out before its reply also warns against resending. Initial nondelivery and unrelated errors do not start recovery.

Broker acceptance is retained for 12 minutes, so acknowledgement loss does not duplicate delivery and a deduplicated ask remains replyable. An implicit reply keeps its original sender/question snapshot across retries, so later inbound asks cannot redirect it. Durable SQLite stores keyed HMAC digests rather than message/attachment text; its key and database artifacts are owner-only on POSIX. Missing, malformed, uncertain, or capacity-bound authority fails closed rather than risking a duplicate.

Fresh calls reserve one of 1,000 client identity slots before confirmation, target resolution, or send; existing internal retries remain usable at capacity. Client retry state is released when the call ends, without deleting broker authority. The broker and local result relay allow 10,000 live delivery records; the broker also bounds digest/routing authority to 64 MiB. Capacity refusal never evicts a still-valid delivery identity.

If the session remains disconnected after those retries:

typescript
intercom({ action: "status" })
// Check if broker is running and restart if needed

Common Workflows

Research → Implementation Handoff

typescript
// Research session finds relevant code
intercom({
  action: "send",
  to: "impl-session",
  message: "Found the bug. The issue is in validateUser() - it doesn't check for null.",
  attachments: [{
    type: "snippet",
    name: "validate.ts",
    language: "typescript",
    content: `// Line 45-52 - missing null check
function validateUser(user: User) {
  return user.email?.includes("@"); // crashes if user is null
}`
  }]
});

Pair Debugging

typescript
// Session A encounters error
intercom({
  action: "ask",
  to: "session-b",
  message: "Getting 'Cannot read property of undefined' at line 78. Can you check if data.users is populated before this call?"
});

// Session B investigates and replies
intercom({
  action: "reply",
  message: "data.users is null. The fetch failed silently. Add error handling in loadUsers()."
});

Progress Reporting

typescript
// Worker sends periodic updates
intercom({ action: "send", to: "planner", message: "Task-1 complete (15min). Starting Task-2." });
// ... work ...
intercom({ action: "send", to: "planner", message: "Task-2 complete (30min). Task-3 blocked - need API key." });
// ... get unblocked ...
intercom({ action: "send", to: "planner", message: "Task-3 complete. All done." });

Long-Running Task with Checkpoints

typescript
// For tasks that might exceed 10 minutes, use send + periodic asks

// 1. Initial send with full context
intercom({
  action: "send",
  to: "worker",
  message: "Implement user authentication. This will take 30+ minutes. I'll check in at milestones."
});

// 2. Worker sends progress via send (no timeout)
intercom({ action: "send", to: "planner", message: "Milestone 1: Login form complete (10min)" });

// 3. Worker asks for specific decision when needed
const decision = await intercom({
  action: "ask",
  to: "planner",
  message: "Should we use JWT or session cookies? Need decision to continue."
});
// Continue with decision...

Frequently asked questions

What does the Intercom AI skill do?

Streamline session-to-session coordination with the intercom extension. Send messages, delegate tasks, and coordinate work across multiple atomic sessions on the same machine. Use for planner-worker workflows, cross-session context sharing, and real-time collaboration between sessions.

Why use Intercom on TypingMind?

Because you install it once and use it with any model. Intercom is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Intercom in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/bastani-inc/atomic/tree/main/packages/intercom/skills/intercom. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Intercom?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Intercom?

As many as you like. As long as a model supports skills, you can use Intercom with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Intercom AI skill free?

It is published on GitHub by bastani-inc. Check the repository for licensing terms. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇