Catalog npm
Back to packageRELEASE DETAILS

0.1.0

npm

2context

Turn your git history into structured knowledge — for your team and your AI tools.

aiclicontext-engineeringdeveloper-toolsknowledge-graph
Published21 Apr 2026
Direct dependencies31
Transitive dependenciesNot calculated

README

Current package documentation

2context

A file-based knowledge graph for coding agents. Extracts decisions, conventions, and patterns from your git history and writes them as plain Markdown files that agents like Claude Code read directly.

npm version License: MIT Node.js ≥22


What it is

A CLI that builds and maintains a Markdown knowledge graph in your repo.

Coding agents are stateless: they re-derive your conventions every session. 2context processes that context once (currently from your git commit history), classifies it, and writes it to disk where the agent can grep and read it with the tools it already has. No MCP server, no daemon, no API.

Output is plain files committed alongside your code:

  • .2context/KNOWLEDGE_GRAPH.md is the entry point. The agent is instructed to read this first.
  • .2context/graph/{category}/ holds the central knowledge as a self-balancing tree, organized into four categories: architecture, convention, decision, pattern. Each folder contains an _index.md summarizing its children, plus leaf .md files that group related findings together.
  • KNOWLEDGE.md files sit next to the source folders they describe (e.g. src/auth/KNOWLEDGE.md).
  • A ## Knowledge Context section is added to CLAUDE.md or AGENTS.md pointing the agent at the index.

Sources

The current build ships with one adapter: git-commits. The pipeline is built around a generic adapter interface, so additional sources can feed the same graph without changing how the agent consumes it. Pull requests, ADRs, issue threads, and custom sources are on the roadmap.


Quickstart

npm install -g 2context
cd /path/to/your-repo
2context init

First run walks you through provider selection (Anthropic, OpenAI, or Google) and API key entry, then ingests your full history. Keys are stored in ~/.2context/keys.json (chmod 600).

After the first run, use 2context ingest to pick up new commits incrementally.


How it works

Each ingest run goes through these phases:

  1. Fetch. Read commits since the last cursor (or all commits with --force). Skip merges, dependency bumps, and formatting-only diffs.
  2. Cluster and extract. An LLM groups related commits into feature units, then reads the diffs and produces KnowledgeItems with category, summary, content, and source provenance (commit SHAs, files touched).
  3. Insert into the index. Each general-scope item is routed top-down through the central tree by an LLM at every branch — using each child's summary to pick the next hop, or to create a new sibling when nothing fits. The item lands in a leaf .md file alongside other related findings. Co-located items go straight to the matching source-tree KNOWLEDGE.md.
  4. Self-balance on insert. After each insertion, the index walks back up to the root: leaves that exceed the per-leaf threshold (item count or rendered byte size) are split into topical sibling leaves; branches that exceed the per-branch child cap are split into intermediate sub-branches. Every touched node has its summary regenerated so subsequent routing stays accurate. The standalone 2context rebalance command runs the same checks across the whole tree on demand.
  5. Update agent file. The ## Knowledge Context section in CLAUDE.md / AGENTS.md is regenerated, telling the agent to read .2context/KNOWLEDGE_GRAPH.md before starting any task.

State for each adapter lives in .2context/sources/{adapter-id}/state.json so the next run only processes what is new.


Commands

2context init

Configure the AI provider, scaffold .2context/, and run the first ingest.

-b, --branch <name>   Branch to analyze (default: main/master)
-v, --verbose         Verbose output

2context ingest

Run the ingestion pipeline. Incremental by default.

-b, --branch <name>   Branch to analyze
-f, --force           Wipe items and reprocess from scratch
-s, --source <id>     Run a single adapter only (e.g. git-commits)
    --no-rebalance    Skip the post-ingest rebalance step
-v, --verbose         Verbose output

2context status

Print configuration, item counts per category, source cursor positions, and co-located files.

2context validate

Check stored items against their sources. For git-commits, this verifies referenced files still exist and source commits are reachable. Items get marked stale on a miss and removed after two consecutive stale verdicts. Rebuilds the index on completion.

--dry-run    Report removals without writing
-v, --verbose

2context rebalance

Sweep the entire central tree: re-cluster overfull leaves and branches, regenerate every node's summary. The index already self-balances on every insert during ingest; this command is for manual reorganization, e.g. after threshold changes.

--dry-run    Show proposed splits/merges without changing anything
-v, --verbose

Output structure

your-repo/
├── .2context/
│   ├── KNOWLEDGE_GRAPH.md             # Entry point. Agent reads this first.
│   ├── graph/
│   │   ├── architecture/
│   │   │   ├── _index.md              # Folder summary + child outline
│   │   │   ├── api-design/            # Sub-branch created on insert when siblings cluster
│   │   │   │   ├── _index.md
│   │   │   │   └── versioning.md      # Leaf — multiple findings grouped by topic
│   │   │   └── caching.md             # Leaf — sits directly under architecture/
│   │   ├── convention/
│   │   │   └── _index.md
│   │   ├── decision/
│   │   │   └── _index.md
│   │   └── pattern/
│   │       └── _index.md
│   └── sources/
│       └── git-commits/state.json     # Cursor (gitignored)
├── src/
│   ├── auth/
│   │   ├── KNOWLEDGE.md               # Co-located items for this folder
│   │   └── jwt.ts
│   └── db/
│       └── KNOWLEDGE.md
└── CLAUDE.md                          # Auto-updated Knowledge Context section

Every _index.md and leaf .md carries YAML frontmatter (id, summary, keywords, parent, children/items) so a navigating agent can drill down a level at a time using only summaries — no need to read the full graph.

Commit: .2context/KNOWLEDGE_GRAPH.md, .2context/graph/, src/**/KNOWLEDGE.md, CLAUDE.md / AGENTS.md. Don't commit: .2context/sources/ (cursor state, already gitignored).


Configuration

Resolution order: env vars → ~/.2context/keys.json → interactive wizard.

export TWOCONTEXT_PROVIDER=anthropic        # anthropic | openai | google
export ANTHROPIC_API_KEY=sk-ant-...
export OPENAI_API_KEY=sk-...
export GOOGLE_GENERATIVE_AI_API_KEY=...

# Optional
export TWOCONTEXT_MODEL=anthropic/claude-opus-4-7
export TWOCONTEXT_CI=true                   # plain-text output, no prompts
ProviderDefaultOther models
Anthropicclaude-sonnet-4-6claude-haiku-4-5, claude-opus-4-7
OpenAIgpt-4ogpt-4o-mini, o3-mini
Googlegemini-2.5-flashgemini-2.5-pro, gemini-2.0-flash

CI usage

- name: Update knowledge graph
  env:
    ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
  run: |
    npm install -g 2context
    2context ingest
    git add .2context CLAUDE.md src/**/KNOWLEDGE.md
    git commit -m "chore: update knowledge graph" || true
    git push

Contributing

git clone https://github.com/fabian-emilius/2context-cli
cd 2context-cli
npm install
npm run start:dev -- init        # dev mode (tsx)
npm run build && npm run start:prod -- status
npm run lint && npm run format

Pull requests welcome. Open an issue first for significant changes, especially new adapters.


MIT · Copyright (c) 2026 Fabian Emilius

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 31

Native requirements
31 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
ink
Environment
{
  "local_name": "ink",
  "alias": false,
  "peer_metadata": null
}
^4.4.1runtime
zod
Environment
{
  "local_name": "zod",
  "alias": false,
  "peer_metadata": null
}
^3.24.0runtime
rxjs
Environment
{
  "local_name": "rxjs",
  "alias": false,
  "peer_metadata": null
}
^7.8.1runtime
react
Environment
{
  "local_name": "react",
  "alias": false,
  "peer_metadata": null
}
^18.3.1runtime
jsonrepair
Environment
{
  "local_name": "jsonrepair",
  "alias": false,
  "peer_metadata": null
}
^3.13.3runtime
simple-git
Environment
{
  "local_name": "simple-git",
  "alias": false,
  "peer_metadata": null
}
^3.27.0runtime
@mastra/core
Environment
{
  "local_name": "@mastra/core",
  "alias": false,
  "peer_metadata": null
}
^1.10.0runtime
@nestjs/core
Environment
{
  "local_name": "@nestjs/core",
  "alias": false,
  "peer_metadata": null
}
^11.0.0runtime
@ai-sdk/google
Environment
{
  "local_name": "@ai-sdk/google",
  "alias": false,
  "peer_metadata": null
}
^1.0.0runtime
@ai-sdk/openai
Environment
{
  "local_name": "@ai-sdk/openai",
  "alias": false,
  "peer_metadata": null
}
^1.0.0runtime
@nestjs/common
Environment
{
  "local_name": "@nestjs/common",
  "alias": false,
  "peer_metadata": null
}
^11.0.0runtime
ink-text-input
Environment
{
  "local_name": "ink-text-input",
  "alias": false,
  "peer_metadata": null
}
^5.0.1runtime
nest-commander
Environment
{
  "local_name": "nest-commander",
  "alias": false,
  "peer_metadata": null
}
^3.15.0runtime
ink-select-input
Environment
{
  "local_name": "ink-select-input",
  "alias": false,
  "peer_metadata": null
}
^5.0.0runtime
reflect-metadata
Environment
{
  "local_name": "reflect-metadata",
  "alias": false,
  "peer_metadata": null
}
^0.2.2runtime
@ai-sdk/anthropic
Environment
{
  "local_name": "@ai-sdk/anthropic",
  "alias": false,
  "peer_metadata": null
}
^1.0.0runtime
tsx
Environment
{
  "local_name": "tsx",
  "alias": false,
  "peer_metadata": null
}
^4.21.0development
eslint
Environment
{
  "local_name": "eslint",
  "alias": false,
  "peer_metadata": null
}
^8.57.1development
@swc/cli
Environment
{
  "local_name": "@swc/cli",
  "alias": false,
  "peer_metadata": null
}
^0.6.0development
prettier
Environment
{
  "local_name": "prettier",
  "alias": false,
  "peer_metadata": null
}
^3.8.1development
@swc/core
Environment
{
  "local_name": "@swc/core",
  "alias": false,
  "peer_metadata": null
}
^1.11.0development
typescript
Environment
{
  "local_name": "typescript",
  "alias": false,
  "peer_metadata": null
}
^5.7.0development
@nestjs/cli
Environment
{
  "local_name": "@nestjs/cli",
  "alias": false,
  "peer_metadata": null
}
^11.0.0development
@types/node
Environment
{
  "local_name": "@types/node",
  "alias": false,
  "peer_metadata": null
}
^22.0.0development
@types/react
Environment
{
  "local_name": "@types/react",
  "alias": false,
  "peer_metadata": null
}
^18.3.28development
eslint-config-prettier
Environment
{
  "local_name": "eslint-config-prettier",
  "alias": false,
  "peer_metadata": null
}
^10.1.8development
eslint-plugin-prettier
Environment
{
  "local_name": "eslint-plugin-prettier",
  "alias": false,
  "peer_metadata": null
}
^5.5.5development
@typescript-eslint/parser
Environment
{
  "local_name": "@typescript-eslint/parser",
  "alias": false,
  "peer_metadata": null
}
^8.57.2development
eslint-plugin-unused-imports
Environment
{
  "local_name": "eslint-plugin-unused-imports",
  "alias": false,
  "peer_metadata": null
}
^4.4.1development
@typescript-eslint/eslint-plugin
Environment
{
  "local_name": "@typescript-eslint/eslint-plugin",
  "alias": false,
  "peer_metadata": null
}
^8.57.2development
eslint-plugin-simple-import-sort
Environment
{
  "local_name": "eslint-plugin-simple-import-sort",
  "alias": false,
  "peer_metadata": null
}
^12.1.1development

Distribution files

1 collected
Distribution 1

Source distribution

Source file
Checksums from source
{
  "shasum": "033d050dc4c38de86e0276f8d49abc8cfea39817",
  "tarball": "https://registry.npmjs.org/2context/-/2context-0.1.0.tgz",
  "fileCount": 137,
  "integrity": "sha512-wfdZkfoMKYse/KpDA9Bnt5w7DgUt33Spx9v9Ojoz6NEB8jFLsqK4+zHKS8FuAXtV0K+Y+q/qrzOqb49Hi2w0oA==",
  "signatures": [
    {
      "sig": "MEYCIQDoJfpvJgiAy9sccjdC9hTFhhQkjQ73uZIOTaDVbyFJWgIhAKj5iOADog8yBkyKg9kjE2UQ5tYspcASWMSLgxh4JVJg",
      "keyid": "SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"
    }
  ],
  "unpackedSize": 598899
}

Repository

PENDING
fabian-emilius/2context-cli

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 19:09 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:f82fe808e517386d2ccf6ba65854fd39240c430503b21858e3cfa267a7267a4e

Other collected versions

0.2.028 AprView all collected versions →