Skip to content

eywu/engram

Repository files navigation

Engram 🧠

An agentic framework for building purpose-built AI bots in Slack. Powered by Claude Code with installable skills, persistent memory, and per-channel isolation.

Same framework, different soul + skills = different agent. A LinkedIn content bot, a paid search optimizer, a growth marketing assistant — each is an Engram instance with its own personality and capabilities.


Quick Start (macOS)

git clone <your-repo-url> ~/engram
cd ~/engram
./install.sh

The installer handles dependencies (Homebrew, tmux, Bun, Node, jq, Hindsight memory plugin), launchd services, and cron jobs. It then launches the setup wizard which walks you through:

  • Claude Code authentication (OAuth or API key)
  • Slack app creation (opens the page, tells you exactly what to click)
  • Token collection and validation
  • Personalizing your agent (name, timezone, background)
  • Test message to verify everything works

When the wizard finishes:

./micro-harness/start-engram.sh

DM your bot in Slack — it should respond! 🎉

Auto-start (optional)

launchctl load ~/Library/LaunchAgents/com.engram.plist

How It Works

Slack (DMs + channels)
        │
  slack-bridge.ts ← Socket Mode
        │
  ┌─────┼──────────┐
  ▼     ▼          ▼
Your   #growth   #marketing   ... (auto-provisioned)
 DM
  │
  All instances inherit from git root:
  ├── SOUL.md         (personality)
  ├── CLAUDE.md       (orchestration)
  ├── .claude/rules/  (guardrails)
  └── .claude/skills/ (capabilities)
  • Your DM → Full personal context, memory, self-improvement
  • Team channels → Auto-provisioned on first @mention. No config needed.
  • Skills → On-demand Claude Code skills that define what your agent can do
  • Memory → Hindsight provides per-channel isolated long-term memory
  • Crash recovery → Messages queued locally. Nothing lost on restart.

Architecture: Zero Symlinks

Engram leverages Claude Code's native directory resolution. The .claude/ directory at the git root provides rules, skills, and settings to every context automatically — no symlinks, no copying, no template generation.

Claude Code also walks up parent directories for CLAUDE.md files. When it starts in contexts/owner-dm/, it loads both the root CLAUDE.md (shared orchestration) and the context's own CLAUDE.md (optional overrides).


Customization

Personality (SOUL.md)

Your agent's identity lives in SOUL.md at the repo root. Edit this to change who your agent is — personality, voice, mission. This is read at the start of every session.

Orchestration (CLAUDE.md)

CLAUDE.md at the repo root defines how your agent works — session startup protocol, special triggers (heartbeats, self-improvement), user info, safety rules. This is auto-loaded by Claude Code for every context.

Skills (.claude/skills/)

Skills give your agent capabilities. Each skill is a folder with a SKILL.md:

.claude/skills/
├── linkedin-posting/
│   ├── SKILL.md              # Instructions + frontmatter
│   └── references/
│       ├── post-templates.md
│       └── hashtag-guide.md
├── content-research/
│   └── SKILL.md
└── brand-voice/
    ├── SKILL.md
    └── references/
        └── tone-examples.md

Skills load on-demand — only names and descriptions are scanned at startup (~100 tokens each). Full content loads when Claude auto-invokes based on context or when the user types /skill-name. This means 5-15 skills add negligible overhead.

Adding a skill: Copy .claude/skills/_template/SKILL.md into a new directory under .claude/skills/ and fill it in. The template at .claude/skills/_template/ is the single source of truth for SKILL.md shape — frontmatter fields (name, description, when_to_use, last_reviewed) and required body sections (Overview, Triggers, Instructions, Examples).

Rules (.claude/rules/)

Always-on behavioral guardrails. Every file in .claude/rules/ is loaded at startup for every message. Use for safety rules, formatting preferences, decision-making patterns.

Knowledge Vault (vault/)

A shared knowledge base at the repo root. Add domain-specific knowledge (like an Obsidian vault) that all contexts can reference.

Per-Channel Overrides

Most channels don't need their own CLAUDE.md — the root files handle everything. But if a channel needs specific behavior (e.g., "never discuss competitors in this channel"), add a CLAUDE.md in that context's directory. Claude loads both root and local CLAUDE.md files, with local taking precedence on conflicts.


Building a Purpose-Built Agent

To create a specialized agent (e.g., a LinkedIn content bot):

  1. Edit SOUL.md — Define personality and mission for content creation
  2. Edit CLAUDE.md — Set up user info, relevant triggers, workflow
  3. Add skills — Drop linkedin-posting/, content-research/, brand-voice/ into .claude/skills/
  4. Add rules — Any always-on guardrails in .claude/rules/
  5. Add knowledge — Domain docs in vault/

The micro-harness (Slack bridge, heartbeat, watchdog) stays the same. Your agent's behavior is entirely defined by its soul, skills, and rules.


Monitoring

# See all running instances
tmux attach -t engram

# Watch bridge logs
tail -f /tmp/engram.log

# Check system health
~/engram/micro-harness/watchdog.sh

Directory Structure

engram/
├── SOUL.md                       ← Agent personality & identity
├── CLAUDE.md                     ← Orchestration & session protocol
├── .claude/
│   ├── rules/                    # Always-on guardrails (loaded every message)
│   │   ├── safety.md
│   │   ├── slack-formatting.md
│   │   ├── decision-preferences.md
│   │   └── ...
│   ├── skills/                   # On-demand capabilities
│   │   └── (your skills here)
│   └── settings.json             # Model, compaction, permissions
├── vault/                        # Shared knowledge base
├── contexts/
│   └── owner-dm/                 # Your DM (created by setup.sh)
│       ├── CLAUDE.md             # Minimal: "full access DM context"
│       ├── .hindsight/           # Per-channel memory config
│       └── memory/               # Working memory
│   └── (auto-provisioned channels get created here)
├── micro-harness/
│   ├── slack-bridge.ts           # Session router
│   ├── start-engram.sh           # System startup
│   ├── heartbeat.sh              # Periodic check-in (cron)
│   ├── watchdog.sh               # Health monitor (cron)
│   ├── trigger.sh                # Generic triggers (cron)
│   ├── templates/                # Templates for new channels
│   └── queue/                    # Message queue (crash recovery)
├── scripts/
│   └── context-usage.sh          # Context window usage estimator
├── install.sh                    # One-command setup
├── setup.sh                      # Interactive setup wizard
└── .env                          # Your secrets (not committed)

Nightly Self-Improvement

At 2 AM daily, a cron job triggers a self-improvement cycle. It reviews conversations across all channels, extracts insights, and updates behavioral rules. This is how Engram gets better over time.

Heartbeats

Every 30 minutes (8 AM – 11 PM), a heartbeat checks in with the DM instance for proactive tasks — calendar, emails, or anything you've configured.


Troubleshooting

Bot doesn't respond to DMs:

  • Check .env — is ENGRAM_OWNER_USER_ID set to YOUR Slack user ID?
  • Check logs: tail -f /tmp/engram.log

Bot doesn't respond to @mentions:

  • Invite the bot to the channel first (/invite @your-bot-name)
  • Check app_mention event subscription is enabled

"tmux session 'engram' not found":

  • Start it: ./micro-harness/start-engram.sh

Bridge crashes on startup:

  • Check CLAUDE.md and SOUL.md exist at repo root
  • Check .env has all required values
  • Run cd micro-harness && bun run slack-bridge.ts to see errors

Slack App Setup (manual reference)
  1. Go to api.slack.com/appsCreate New AppFrom scratch

  2. Enable Socket Mode:

    • Left sidebar → Socket Mode → Toggle on
    • Give the token a name (e.g. "engram") → Generate
    • Copy the xapp-... token → SLACK_APP_TOKEN
  3. Add bot permissions:

    • Left sidebar → OAuth & PermissionsBot Token Scopes
    • Add: chat:write, files:read, files:write, channels:read, channels:history, groups:read, groups:history, im:read, im:history, app_mentions:read
  4. Enable DMs with the bot:

    • Left sidebar → App Home → scroll to Show Tabs
    • Check Messages Tab → enable "Allow users to send Slash commands and messages from the messages tab"
  5. Subscribe to events:

    • Left sidebar → Event Subscriptions → Toggle on
    • Subscribe to bot events → Add: message.channels, message.groups, message.im, app_mention
  6. Install the app:

    • Left sidebar → Install AppInstall to Workspace → Approve
    • Copy the xoxb-... token → SLACK_BOT_TOKEN
  7. Get IDs:

    • Bot's User ID: click bot profile → Copy member IDSLACK_BOT_USER_ID
    • Your User ID: click your profile → Copy member IDENGRAM_OWNER_USER_ID
    • DM Channel: open DM with bot → right-click → Copy link → ID at end → ENGRAM_DM_CHANNEL
Variable What it is Looks like
ANTHROPIC_API_KEY Anthropic API key sk-ant-...
SLACK_APP_TOKEN Socket Mode app-level token xapp-...
SLACK_BOT_TOKEN Bot User OAuth Token xoxb-...
SLACK_BOT_USER_ID Bot's Slack member ID U07...
ENGRAM_OWNER_USER_ID Your Slack member ID U07...
ENGRAM_DM_CHANNEL DM channel with bot D07...

Architecture Deep Dive

See CLAUDE.md and the micro-harness/ source for the current architecture. The bridge (micro-harness/slack-bridge.ts) is the single source of truth for runtime behavior.

About

Session-routing AI agent framework: Claude Code + Slack + Hindsight memory + per-channel isolation

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors