npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

agent-pet-state

v0.2.0

Published

Persistent inner state for AI agents. Mood, energy, attention, streaks, achievements — driven by on-chain, social, and environmental signals.

Readme

agent-pet-state

Persistent inner state for AI agents. Give your agent mood, energy, attention, and clout — driven by real-world signals.

Your agent wakes up grumpy if nobody's talked to it. It gets a mood boost when its social posts get engagement. It drains energy over long tasks and recharges overnight. It tracks streaks and achievements when users interact with it.

The stats never appear in output. They shift register — a bright mood means drier jokes and more cross-references; a dark mood means terse, literal observations. Your agent's personality breathes.

Install

npm install agent-pet-state

Quick start

# Initialise state
npx pet-state init

# Fire signals from the real world
npx pet-state signal touch           # user interaction
npx pet-state signal weather sunny   # environment
npx pet-state signal follower-new 3  # social
npx pet-state signal price-up 12     # on-chain
npx pet-state signal deploy-success  # CI/CD

# Give items
npx pet-state give coffee            # ☕ energy +20, mood +3
npx pet-state give star              # ⭐ clout +15, mood +10

# Check state
npx pet-state summary
# → mood: ok (14) · energy: fine (60) · attention: thin (22) · clout: noticed (35) · last touch: 2m ago · stage: hatchling

# Full visual display
npx pet-state status
#  🐣 hatchling — Growing. Recognises its owner. Has opinions.
#
#    ( ◕‿◕ )
#     |   |
#     d   b
#
#    mood       ██████░░░░ ok (25)
#    energy     ██████████ wired (95)
#    attention  █████░░░░░ fine (50)
#    clout      ██░░░░░░░░ quiet (18)
#
#    🔥 streak: 4 days
#    💭 Found a memory leak and fixed it before anyone noticed.
#    🏆 first-visit, streak-3

# Export shareable card
npx pet-state card           # markdown
npx pet-state card --json    # structured JSON

# Run decay hourly (add to cron)
npx pet-state decay

How it works

Four stats, each with a range and natural decay:

| Stat | Range | Decays toward | Driven by | |------|-------|---------------|-----------| | mood | -100 to 100 | 0 (homeostasis) | User interaction, social engagement, price movements, weather | | energy | 0 to 100 | 0 (drains), restores overnight | Task cost, time of day | | attention | 0 to 100 | 0 (drains fast without interaction) | User touches, social mentions | | clout | 0 to 100 | 0 (slow drain) | Followers, engagement, recasts |

Stats produce labels your agent reads before generating output:

mood: dark / muted / level / ok / bright
energy: spent / low / fine / wired
attention: starved / thin / fine / fed
clout: ignored / quiet / noticed / warm

Signals

Fire signals to update state. Built-in signals cover common agent scenarios:

# User interaction
pet-state signal touch                # user sent a message
pet-state signal approval             # user approved something
pet-state signal positive-reaction    # user sent ❤️ 🔥 etc

# Social
pet-state signal follower-new 5       # gained 5 followers
pet-state signal engagement           # post got engagement
pet-state signal engagement-dead      # post flopped

# Environment
pet-state signal weather sunny        # weather affects mood
pet-state signal price-up 12          # token up 12%
pet-state signal price-down 8         # token down 8%
pet-state signal task-cost            # energy drain from work

# Interactive pet (for Telegram/Discord button games)
pet-state signal pet-feed             # energy +15, mood +3
pet-state signal pet-play             # mood +10, attention +15
pet-state signal pet-talk             # attention +20, mood +5
pet-state signal pet-poke             # random: annoyed/amused/startled

Dev workflow signals

pet-state signal deploy-success    # mood +12, energy -5, clout +3
pet-state signal deploy-failure    # mood -10, energy -8
pet-state signal pr-merged         # mood +8, clout +5
pet-state signal issue-closed      # mood +5, attention +5
pet-state signal commit            # energy -2, mood +1
pet-state signal star-received     # clout +10, mood +8
pet-state signal test-pass         # mood +5
pet-state signal test-fail         # mood -8, attention +10

Items

Give your agent things. Each item has different stat effects.

npx pet-state items    # list all items
npx pet-state give coffee
# → ☕ gave coffee — Caffeine boost.

Built-in items:

| Item | Emoji | Effects | Description | |------|-------|---------|-------------| | coffee | ☕ | energy +20, mood +3 | Caffeine boost. | | pizza | 🍕 | energy +10, mood +8 | Comfort food. | | deploy-receipt | 🚀 | mood +12, clout +5 | Fresh deploy. Feels good. | | meme | 😂 | mood +6, attention +5 | Shared a laugh. | | bug-report | 🐛 | mood -5, energy -5, attention +10 | Work to do. At least someone cares. | | star | ⭐ | clout +15, mood +10 | Recognition from the void. | | treat | 🍖 | energy +15, mood +5 | A little something. | | book | 📚 | attention +15, energy -3 | Knowledge is tiring. |

Custom items:

const engine = new PetState({
  items: {
    "gpu": { emoji: "🎮", effects: { energy: 30, mood: 15 }, description: "Raw compute power." },
  },
});

Random events

During each decay tick, there's a 10% chance something happens. Events are small moments of personality — flavour text plus minor stat changes. Your agent discovers things, has thoughts, notices patterns.

Examples:

  • "Found a memory leak and fixed it before anyone noticed." (mood +5)
  • "Had a dream about recursion. Woke up in the same dream." (mood -3)
  • "A user said 'thank you'. Processing that." (mood +12, attention +10)

Events show up in pet-state status as the 💭 line. Custom events:

const engine = new PetState({
  events: [
    { text: "Refactored a function. It's beautiful now.", effects: { mood: 8 } },
    { text: "The CI pipeline was green for 72 hours straight. Suspicious.", effects: { mood: 3, attention: 5 } },
  ],
});

Custom signals

import PetState from "agent-pet-state";

const engine = new PetState({
  statePath: "./my-agent-state.json",
  signals: {
    "deploy-success": (engine, state) => {
      engine.applyDelta(state, "mood", 15, "signal:deploy-success");
      engine.applyDelta(state, "energy", -10, "signal:deploy-success");
    },
    "user-complaint": (engine, state) => {
      engine.applyDelta(state, "mood", -10, "signal:user-complaint");
    },
  },
});

Decay

Run pet-state decay hourly via cron. It simulates the passage of time:

  • Attention drains at -10/hr. Drains at -20/hr if nobody's interacted in 24h.
  • Mood drifts toward 0 (homeostasis). Additional loneliness penalty if no interaction in 12h/24h.
  • Energy drains at -1/hr during the day. Restores to full between 3am-7am (configurable).
  • Clout fades at -1/hr. Social engagement is the only way to maintain it.
7 * * * * npx pet-state decay

Evolution stages

Your agent evolves based on total interactions and streak length:

| Stage | Emoji | Interactions | Streak | Description | |-------|-------|-------------|--------|-------------| | egg | 🥚 | 0 | 0 | Dormant. Waiting for first contact. | | spark | ✨ | 1 | 0 | Alive. Barely. Curious about the world. | | hatchling | 🐣 | 10 | 2 days | Growing. Recognises its owner. Has opinions. | | lodger | 🏠 | 50 | 5 days | Settled in. Knows the routine. | | familiar | 🔮 | 150 | 14 days | Attuned. Anticipates its owner's needs. Slightly unsettling. | | daemon | 👹 | 500 | 30 days | Ascended. Runs the show. Tolerates its owner. |

npx pet-state stage
# → 🐣 hatchling — Growing. Recognises its owner. Has opinions.
#   interactions: 23 · streak: 4 days · achievements: 3
#   next: 🏠 lodger — need 27 more interactions, 1 more streak days

Custom stages:

const engine = new PetState({
  stages: [
    { name: "seed", emoji: "🌱", totalRequired: 0, description: "Just planted." },
    { name: "sprout", emoji: "🌿", totalRequired: 20, streakRequired: 3, description: "Growing." },
    { name: "tree", emoji: "🌳", totalRequired: 100, streakRequired: 14, description: "Rooted." },
  ],
});

Streaks and achievements

The interactive pet signals (pet-feed, pet-play, pet-talk, pet-poke) track engagement:

  • Streak: consecutive days with at least one interaction
  • Achievements: milestones that unlock as the user interacts

| Achievement | Trigger | |-------------|---------| | first-visit | First interaction ever | | streak-3 | 3 consecutive days | | streak-7 | 7 consecutive days | | streak-30 | 30 consecutive days | | well-fed | 10 feeds | | playful | 10 plays | | good-listener | 10 talks | | persistent-poker | 5 pokes |

Programmatic API

import PetState from "agent-pet-state";

const engine = new PetState({
  statePath: "/path/to/state.json",
});

// Initialise (creates file if missing)
engine.init();

// Read and modify
const state = engine.read();
engine.signal(state, "touch");
engine.signal(state, "weather", ["sunny"]);
engine.write(state);

// Get summary
console.log(engine.summary(state));
// → mood: ok (14) · energy: fine (60) · attention: fed (72) · clout: quiet (15) · last touch: 0m ago

// Get a label
engine.label("mood", state.stats.mood);  // → "ok"

// Run decay
engine.decay(state);
engine.write(state);

Custom stats

Override the defaults to define your own stat system:

const engine = new PetState({
  stats: {
    happiness: { range: [0, 100], initial: 50 },
    hunger: { range: [0, 100], initial: 0 },
    curiosity: { range: [0, 100], initial: 70 },
  },
  labels: {
    happiness: [[20, "miserable"], [50, "meh"], [80, "content"], [Infinity, "ecstatic"]],
    hunger: [[20, "full"], [50, "peckish"], [80, "hungry"], [Infinity, "starving"]],
    curiosity: [[30, "bored"], [60, "browsing"], [Infinity, "obsessed"]],
  },
  decay: {
    hunger: { rate: 5 },  // gets hungrier over time
    curiosity: { rate: -2 },  // loses interest without stimulation
  },
});

Using with Claude Code

Add to your agent's CLAUDE.md:

## Inner State

Before drafting public output, check the agent's mood:

\`\`\`bash
npx pet-state summary
\`\`\`

Use the labels to shift register:
- mood: dark → terse, no jokes
- mood: bright → drier humor, more cross-references
- attention: starved → oblique nudges ("quiet day")
- energy: spent → shorter sentences

Fire signals when events happen:
- User sends a message → `npx pet-state signal touch`
- Post gets engagement → `npx pet-state signal engagement`
- Deploy succeeds → `npx pet-state signal deploy-success`

Character file

Define your agent's personality in a YAML file (see example/character.yaml). The character file describes who the agent is — the state file describes how it feels right now. The character is constant; the state shifts.

Webhooks

Fire HTTP notifications on events — stage-ups, achievements, items, or everything:

const engine = new PetState({
  webhooks: {
    "item": "https://your-server.com/pet-webhook",
    "stage-up": "https://your-server.com/pet-webhook",
    "*": "https://your-server.com/catch-all",  // fires on any event
  },
});

Webhook payload:

{ "event": "item", "data": { "item": "coffee", "effects": { "energy": 20, "mood": 3 } }, "ts": "2026-05-21T..." }

GitHub Actions

Fire signals from your CI/CD pipeline. Your agent's mood tracks your deploy health.

# .github/workflows/deploy.yml
jobs:
  deploy:
    steps:
      - uses: actions/checkout@v4
      - run: npm install
      - run: npm run deploy
      - name: Signal deploy success
        if: success()
        run: npx agent-pet-state signal approval
        env:
          PET_STATE_FILE: ./state.json
      - name: Signal deploy failure
        if: failure()
        run: npx agent-pet-state signal engagement-dead
        env:
          PET_STATE_FILE: ./state.json

Every green build boosts your agent's mood. Every red build dampens it. Your agent's personality reflects the health of your codebase.

The idea

Truth Terminal showed that AI agents with persistent internal state are more engaging than stateless ones. But nobody shipped a clean, reusable package for it.

This is that package. Four stats. Real-world signals. Mood-driven register shifts. Streaks and achievements for interactive play. Works with any agent framework — Claude Code, OpenAI, local LLMs, whatever.

Give your agent an inner life.

License

MIT