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

@llipe.com/memo-cli

v1.1.0

Published

Agent-first CLI for capturing and querying development decisions via Qdrant vector store

Readme

memo-cli

Agent-first CLI for capturing and querying development decisions via a Qdrant vector store.

GitHub: https://github.com/llipe/memo-cli

@llipe.com/memo-cli lets AI agents and developers record architectural decisions, integration points, and structural choices during development — then retrieve them semantically at any time.


Table of Contents


Requirements

| Tool | Version | Notes | | -------------- | -------- | ---------------------------------------------------------------------------------------------------------------------- | | Node.js | ≥ 24 LTS | Required for native ESM support | | Qdrant | ≥ 1.7 | Local Docker or Qdrant Cloud (free tier) | | OpenAI API key | — | For text embeddings (text-embedding-3-small) |


Installation

From npm (recommended)

npm install -g @llipe.com/memo-cli
memo --version

From source

git clone https://github.com/llipe/memo-cli.git
cd memo-cli
pnpm install
pnpm run build
./dist/index.js --help

Getting Started

1. Start Qdrant

Run Qdrant locally with Docker:

docker run -p 6333:6333 qdrant/qdrant

Or use Qdrant Cloud (free tier available).

2. Set environment variables

Create a .env file in your project root (or export the vars in your shell):

QDRANT_URL=http://localhost:6333
QDRANT_API_KEY=                   # leave empty for local unauthenticated Qdrant
EMBEDDINGS_PROVIDER=openai
EMBEDDINGS_API_KEY=sk-...         # your OpenAI API key

3. Initialize your repository

memo setup init

This launches an interactive wizard that creates a memo.config.json in the current directory, establishing the repository's identity (repo name, organization, domain).

4. Write a decision

memo write \
  --rationale "Chose Qdrant over Pinecone for self-hosting flexibility and payload filtering." \
  --tags "architecture,storage,qdrant" \
  --entry-type decision \
  --source agent

5. Retrieve it later

memo search "why did we choose the vector database"

That's it — the core loop is write decisions → search them later.


Usage Guide

Step 1: Initialize a Repository

Every repository using memo needs a memo.config.json file. The setup command creates it.

Interactive mode (recommended)

memo setup init

The wizard will prompt for:

  • Repository name — auto-detected from git remote if available
  • Organization — your team or company identifier
  • Domain — product area (e.g., payments, auth, frontend)
  • Related repos — other repositories this repo integrates with (optional)

Non-interactive mode (for CI/agents)

memo setup init \
  --repo my-service \
  --org my-company \
  --domain backend \
  --relates-to "auth-service,api-gateway"

Verify your config

memo setup show        # display effective config
memo setup validate    # check config validity (exit 0 = valid)

Example memo.config.json

{
  "schema_version": "1",
  "repo": "my-service",
  "org": "my-company",
  "domain": "backend",
  "relates_to": ["auth-service", "api-gateway"],
  "defaults": {}
}

Step 2: Write Your First Decision

The write command captures a decision and stores it in Qdrant with a vector embedding for semantic retrieval.

Basic write

memo write \
  --rationale "Adopted JWT with RS256 for service-to-service auth. Short-lived tokens (15 min) with refresh rotation." \
  --tags "auth,jwt,security" \
  --entry-type decision \
  --source agent

All write flags

| Flag | Required | Default | Description | | ------------------ | -------- | ----------- | ------------------------------------------------------------------------ | | --rationale | Yes | — | Decision text (1–5000 chars) | | --tags | Yes | — | Comma-separated tags (2–5, kebab-case) | | --entry-type | No | decision | decision | integration_point | structure | | --source | No | from config | agent | scan | manual | | --commit | No | — | Associated git commit SHA | | --story | No | — | Associated story/task identifier | | --files-modified | No | — | Comma-separated file paths | | --relates-to | No | — | Comma-separated related repos | | --on-duplicate | No | — | Duplicate action: consolidate | update | replace | create-new | | --json | No | false | Output as JSON |

Duplicate detection

If you write an entry with the same repo + commit + story + entry_type + source combination, memo detects the duplicate:

  • Interactive (TTY): prompts you to choose an action (consolidate, update, replace, create new)
  • Agent/JSON mode: requires --on-duplicate flag to resolve programmatically
# Agent mode: automatically merge duplicates
memo write \
  --rationale "Updated JWT decision to include ECDSA as fallback." \
  --tags "auth,jwt,security,ecdsa" \
  --entry-type decision \
  --source agent \
  --commit abc1234 \
  --on-duplicate consolidate \
  --json

Entry types explained

| Type | When to use | | ------------------- | ------------------------------------------------------------------ | | decision | Architectural or technical decisions made during a task | | integration_point | How another system, service, or module is integrated | | structure | Module-level or architectural structure (typically from bootstrap) |


Step 3: Search Decisions

Find decisions using natural language queries. Memo embeds your query and performs semantic vector search against all stored entries.

Basic search

memo search "how do we handle authentication"

Search with filters

# Only search within this repo (default)
memo search "database connection pooling" --scope repo

# Include related repos defined in config
memo search "how does the auth service validate tokens" --scope related

# Require specific tags (AND semantics)
memo search "API rate limiting" --tags "api,rate-limit"

# Filter by entry type
memo search "module boundaries" --entry-type structure

# Limit results
memo search "caching strategy" --limit 5

# Combine filters
memo search "event publishing" \
  --scope related \
  --tags "events,kafka" \
  --entry-type integration_point \
  --limit 3

All search flags

| Flag | Default | Description | | -------------- | ------- | ----------------------------------------------------------------- | | --scope | repo | repo (this repo only) or related (include relates_to repos) | | --tags | — | Comma-separated tags to require (AND semantics) | | --entry-type | — | Filter: decision | integration_point | structure | | --source | — | Filter: agent | scan | manual | | --limit | 5 | Maximum results to return | | --json | false | Output as JSON |

Reading search results

Human mode output shows:

  1.  (94%) Adopted JWT with RS256 for service-to-service auth...
      repo: my-service  tags: auth, jwt, security  type: decision
      source: agent  confidence: high  2026-04-10T15:30:00Z

  2.  (87%) Auth service exposes /validate endpoint for token...
      repo: auth-service  tags: auth, api, validation  type: integration_point
      source: agent  confidence: high  2026-04-09T10:00:00Z

JSON mode (--json) returns the full machine-readable payload:

{
  "query": "how do we handle authentication",
  "filters": { "scope": "repo", "repos": ["my-service"] },
  "results": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "repo": "my-service",
      "org": "my-company",
      "rationale": "Adopted JWT with RS256...",
      "tags": ["auth", "jwt", "security"],
      "entry_type": "decision",
      "similarity": 0.94,
      ...
    }
  ],
  "count": 2
}

Step 4: List Decisions

Browse entries chronologically (newest first) with optional date-range filtering.

Basic listing

memo list                    # last 20 entries for this repo
memo list --limit 50         # last 50 entries

Filter by date range

# Entries from a specific date
memo list --from 2026-04-01

# Entries in a date range
memo list --from 2026-04-01 --to 2026-04-10

# Full ISO 8601 timestamps also work
memo list --from 2026-04-01T00:00:00Z --to 2026-04-10T23:59:59Z

Filter by tags and type

memo list --tags "auth,jwt"
memo list --entry-type decision
memo list --source agent --limit 10

All list flags

| Flag | Default | Description | | -------------- | ------- | ------------------------------------- | | --scope | repo | repo or related | | --tags | — | Comma-separated tag filter | | --entry-type | — | Filter by entry type | | --source | — | Filter by source | | --from | — | Start date (YYYY-MM-DD or ISO 8601) | | --to | — | End date (YYYY-MM-DD or ISO 8601) | | --limit | 20 | Maximum entries | | --json | false | Output as JSON |


Step 5: Manage Config

Show effective configuration

memo setup show          # human-readable
memo setup show --json   # JSON output

Validate configuration

memo setup validate
# Exit code 0 = valid, 1 = errors found

Re-initialize (overwrite existing config)

memo setup init --force

Step 6: Discover Tags

Browse all unique tags stored in your knowledge base, with counts and flexible scope.

List all tags in the current repo

memo tags list

Scope and sorting options

# Include related repos from config
memo tags list --scope related

# Sort alphabetically (default: frequency)
memo tags list --sort alpha

# JSON output for agent consumption
memo tags list --json

All tags list flags

| Flag | Default | Description | | --------- | ----------- | ---------------------------------------- | | --scope | repo | repo or related | | --sort | frequency | frequency (count desc) or alpha | | --json | false | Output as JSON |


Step 7: Inspect the Knowledge Base

Discover what organizations, repositories, and domains have entries in your Qdrant collection — without any scope restriction.

Show everything

memo inspect

Outputs three grouped sections: Organizations, Repositories (with org and domain annotations), and Domains.

Filter to specific facets

# Only repositories
memo inspect --repos

# Only organizations
memo inspect --orgs

# Only domains
memo inspect --domains

# JSON output
memo inspect --json

All inspect flags

| Flag | Default | Description | | ----------- | ------- | ---------------------------------------- | | --orgs | — | Show only organizations | | --repos | — | Show only repositories | | --domains | — | Show only domains | | --json | false | Output as JSON |

When no filter flags are passed, all three facets are shown.


Step 8: Delete Entries

Safely delete individual entries or bulk-delete by repository or organization. Always confirms before deleting.

Delete a single entry by ID

memo delete --id 550e8400-e29b-41d4-a716-446655440000

Memo shows a preview of the matching entry and asks for confirmation.

Bulk delete by repository or organization

# Delete all entries for a repository
memo delete --all-by-repo my-service

# Delete all entries for an organization
memo delete --all-by-org my-company

Memo shows a count of matching entries and asks for confirmation.

Skip confirmation (automation)

memo delete --id <id> --yes
memo delete --all-by-repo my-service --yes

Agent mode note

In agent mode (--source agent or when --json is used for single deletes), bulk flags are not available via --json. Single-entry deletion supports --json output:

memo delete --id <id> --json
# outputs: { "deleted": true, "id": "...", "scope": "single", "count": 1 }

All delete flags

| Flag | Default | Description | | ---------------- | ------- | -------------------------------------------------------- | | --id | — | Delete a single entry by UUID | | --all-by-repo | — | Delete all entries for the given repo name | | --all-by-org | — | Delete all entries for the given organization | | --yes | false | Skip confirmation prompt | | --json | false | JSON output (single-delete only) |

--id, --all-by-repo, and --all-by-org are mutually exclusive.


Command Reference

| Command | Purpose | Key Flags | | --------------------- | ----------------------------- | ------------------------------------------------------------------------------- | | memo setup init | Create memo.config.json | --repo, --org, --domain, --relates-to, --force | | memo setup show | Display current config | --json | | memo setup validate | Check config validity | — | | memo write | Capture a decision | --rationale, --tags, --entry-type, --source, --on-duplicate, --json | | memo search <query> | Semantic search | --scope, --tags, --entry-type, --limit, --json | | memo list | Chronological listing | --from, --to, --tags, --limit, --json | | memo tags list | Browse unique tags | --scope, --sort, --json | | memo inspect | Discover orgs/repos/domains | --orgs, --repos, --domains, --json | | memo delete | Delete entries | --id, --all-by-repo, --all-by-org, --yes, --json |

Global flags

| Flag | Description | | ----------- | -------------------- | | --version | Print version number | | --help | Show help text |

Exit codes

| Code | Meaning | | ---- | ---------------------------------------------- | | 0 | Success | | 1 | User error (bad input, missing config) | | 2 | System error (Qdrant unreachable, API failure) |


Agent Integration

Memo is designed to be used by AI coding agents as part of their workflow. All commands support --json for machine-readable output.

Recommended agent workflow

# 1. Before starting a task — search for prior decisions
memo search "authentication strategy for microservices" --json

# 2. After completing a task — write the decision
memo write \
  --rationale "Implemented OAuth2 with PKCE for the mobile client. Chose this over implicit flow for security." \
  --tags "auth,oauth2,mobile" \
  --entry-type decision \
  --source agent \
  --commit "$(git rev-parse HEAD)" \
  --story "PROJ-123" \
  --on-duplicate consolidate \
  --json

# 3. Verify the write
memo search "OAuth2 mobile client" --json | jq '.count'

Environment setup for agents

Agents need these environment variables set:

export QDRANT_URL=http://localhost:6333
export EMBEDDINGS_API_KEY=sk-...

No .env file needed — agents should inject variables directly into the process environment.

Agent Skill (memo-cli-usage)

This repository ships a reusable agent skill at .github/skills/memo-cli-usage/SKILL.md that teaches AI agents (and developers) how to operate memo-cli correctly and consistently.

The skill is self-contained and installable — copy the memo-cli-usage/ folder into any repository's .github/skills/ directory and reference it from that repo's agent registry.

What the skill covers

| Section | Description | |---------|-------------| | When to write / when to search | Precise trigger tables — which moment calls for a memo write, which calls for a memo search first | | repo, org, domain explained | What each identity field means, how to choose values, and why they matter for scoping | | relates_to explained | When to add a repo, how cross-repo queries work, and how to avoid over-populating the list | | Tag strategy | Five-layer taxonomy (domain, technology, entry nature, story ref, scope), naming rules, and ready-made examples | | Writing quality | The context + decision + rationale formula with side-by-side good/bad examples | | Intent & outcome entries | How to narrate agent work as it happens — write before starting, write after finishing | | Recording file changes | How to annotate which files changed and explain why those were the right files | | Recording config decisions | Env vars, storage layout, feature flags, schema versions — what to capture and why | | Multi-developer & cross-session | Shared KB, session continuity for stateless agents, multi-day work pattern | | Memory scope decision tree | When to use IDE/agent memory (/memories/) vs. memo-cli | | Safe operation guardrails | Non-destructive defaults, --json mode rules, error handling, credential safety |

Install into another repository

# 1. Copy the skill
cp -r .github/skills/memo-cli-usage /path/to/your-repo/.github/skills/

# 2. Register it in your AGENTS.md or skill registry:
# | memo-cli-usage | .github/skills/memo-cli-usage/ | Agent guidance for memo-cli | Any agent |

# 3. Install memo-cli
pnpm add -D @llipe.com/memo-cli

# 4. Initialize the repo
npx memo setup init --repo <name> --org <org> --domain <domain>

Once the skill is registered, any agent (GitHub Copilot, Claude, GPT-4, etc.) that loads it will know how to record decisions, restore session context, tag consistently, and stay safe.


Bootstrap Workflow

To populate memo with decisions from an existing codebase, use the bootstrap workflow:

  1. Feed key artifacts (README, architecture docs, config files) to an AI agent with the bootstrap prompt template
  2. The agent produces JSON entries conforming to the entry schema
  3. Validate the JSON with the included validation script
  4. Write entries via memo write

See docs/bootstrap-guide.md for the full prompt template, JSON conversion examples, and validation steps.

Quick validation example

# Validate a bootstrap JSON file
node --loader ts-node/esm scripts/validate-bootstrap.ts ./my-bootstrap.json

Development

Setup

git clone https://github.com/llipe/memo-cli.git
cd memo-cli
pnpm install
cp .env.example .env   # configure credentials

Scripts

| Script | Description | | -------------------------- | -------------------------------------------- | | pnpm run build | Compile TypeScript to dist/ | | pnpm run build:watch | Compile in watch mode | | pnpm run typecheck | Type-check without emitting | | pnpm run lint | ESLint (v9 flat config, strict type-checked) | | pnpm run lint:fix | ESLint with auto-fix | | pnpm run format | Prettier format | | pnpm run format:check | Check formatting without writing | | pnpm run test | Run Jest test suite | | pnpm run test:coverage | Run Jest with coverage report |

Testing

pnpm run test                          # all tests
pnpm run test -- --testPathPattern=write   # specific module
pnpm run test:coverage                 # with coverage report

202+ test cases across unit and integration layers. Coverage threshold: 80% lines/functions/statements.

CI/CD

  • CI runs on every push: typecheck → lint → test → build → audit
  • Publish triggers on semver tag push (v*.*.*) → npm publish

Project Structure

src/
├── index.ts              # CLI entry point (Commander root)
├── commands/
│   ├── setup.ts          # memo setup (init / show / validate)
│   ├── write.ts          # memo write (with duplicate detection)
│   ├── search.ts         # memo search (semantic + pre-filters)
│   ├── list.ts           # memo list (chronological + date range)
│   ├── tags.ts           # memo tags list (unique tags with counts)
│   ├── inspect.ts        # memo inspect (org/repo/domain facets)
│   └── delete.ts         # memo delete (safe single + bulk delete)
├── lib/
│   ├── qdrant.ts         # Qdrant collection management & queries
│   ├── facets.ts         # Scroll-based facet aggregation
│   ├── embeddings.ts     # Embeddings adapter interface & factory
│   ├── config.ts         # Config file I/O & validation
│   ├── registry.ts       # Related-repo resolution
│   ├── output.ts         # Human/JSON output formatting
│   ├── errors.ts         # Typed error hierarchy
│   ├── dedupe.ts         # Deduplication & merge strategies
│   ├── search-filters.ts # Search pre-filter builder
│   ├── list-filters.ts   # List pre-filter builder (date range)
│   ├── retry.ts          # Exponential backoff retry
│   └── debug.ts          # Debug logging (MEMO_DEBUG)
├── adapters/
│   └── openai-embeddings.ts  # OpenAI text-embedding-3-small
└── types/
    ├── entry.ts           # EntryPayload Zod schema
    ├── config.ts          # MemoConfig Zod schema
    └── cli.ts             # Shared CLI interfaces
tests/
├── unit/                  # Unit tests (lib, adapters, commands)
└── integration/           # Integration tests (commands, qdrant)
scripts/
├── run-jest.mjs           # Jest argument forwarder
└── validate-bootstrap.ts  # Bootstrap JSON validator
docs/
├── product-context.md     # Product strategy & roadmap
├── technical-guidelines.md # Technical standards
├── system-overview.md     # Architecture overview
├── data-model.md          # Data entities & schema
├── bootstrap-guide.md     # Bootstrap prompt & workflow
└── requirements/
    └── prd-001-mvp.md     # MVP product requirements

License

MIT