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

changenarrator

v1.0.11

Published

An AI-powered tool that watches code changes and automatically generates human-readable changelogs from GitHub PRs

Readme

ChangeNarator

npm version License Node.js Version

ChangeNarrator - An AI-powered tool that watches code changes and automatically generates human-readable changelogs from GitHub PRs, published as a newsletter or release note.

Features

  • 🔍 PR Metadata Fetcher: Fetch complete PR context from GitHub including:
    • Base and head SHA
    • PR title and number
    • All commit messages
    • Changed files with patches
    • Addition/deletion statistics

Installation

Via npm (Recommended)

npm install -g changenarrator

Or using npx (no installation required):

npx changenarrator init

From Source

If you want to contribute or run from source:

  1. Clone the repository

    git clone <repository-url>
    cd ChangeNarator
  2. Install dependencies

    bun install

Prerequisites

  • Node.js >= 20
  • GitHub Personal Access Token with appropriate permissions
  • IBM WatsonX API credentials (for AI-powered changelog generation)
  • Notion Integration Token (for publishing changelogs)

Quick Start

  1. Install ChangeNarator:

    npm install -g changenarrator
  2. Initialize configuration:

    changenarator init

    This interactive wizard will guide you through setting up:

    • GitHub Personal Access Token
    • IBM WatsonX API credentials
    • Notion integration
    • Local repository directory
  3. Analyze a PR:

    changenarator <owner> <repo> <pr_number> <local_repo_path>

    Example:

    changenarator facebook react 12345 ~/repos/react

Setup

  1. Configure ChangeNarator

    Run the interactive setup wizard:

    changenarator init

    This will prompt you for:

    • GitHub Personal Access Token - For fetching PR data
    • IBM WatsonX API Key - For AI-powered changelog generation
    • WatsonX Project ID - Your WatsonX project identifier
    • WatsonX Region URL - Default: https://us-south.ml.cloud.ibm.com
    • Notion Integration Token - For publishing changelogs
    • Notion Parent Page ID - Where changelogs will be published
    • Local repos directory - Where repositories will be cloned (default: ~/repos)

    Configuration is saved to config.json (automatically added to .gitignore).

    Creating Required Tokens:

    • GitHub Token: GitHub Settings > Tokens
      • Select scopes: repo (private repos) or public_repo (public only)
    • WatsonX Credentials: IBM Cloud
      • Create a WatsonX.ai instance
      • Get your API key and project ID
    • Notion Token: Notion Integrations
      • Create a new integration
      • Share a page with your integration to get the page ID

    Alternative: Manual Configuration

    You can also manually create config.json based on config.example.json:

    cp config.example.json config.json
    # Edit config.json with your credentials
  2. Configure ChangeNarator

    Run the interactive setup wizard:

    bun run cli init

    This will prompt you for:

    • GitHub Personal Access Token - For fetching PR data
    • IBM WatsonX API Key - For AI-powered changelog generation
    • WatsonX Project ID - Your WatsonX project identifier
    • WatsonX Region URL - Default: https://us-south.ml.cloud.ibm.com
    • Notion Integration Token - For publishing changelogs
    • Notion Parent Page ID - Where changelogs will be published
    • Local repos directory - Where repositories will be cloned (default: ~/repos)

    Configuration is saved to config.json (automatically added to .gitignore).

    Creating Required Tokens:

    • GitHub Token: GitHub Settings > Tokens
      • Select scopes: repo (private repos) or public_repo (public only)
    • WatsonX Credentials: IBM Cloud
      • Create a WatsonX.ai instance
      • Get your API key and project ID
    • Notion Token: Notion Integrations
      • Create a new integration
      • Share a page with your integration to get the page ID

    Alternative: Manual Configuration

    You can also manually create config.json based on config.example.json:

    cp config.example.json config.json
    # Edit config.json with your credentials

    Legacy: Environment Variables

    For backward compatibility, you can still use .env file:

    cp .env.example .env
    # Edit .env with your credentials

Usage

CLI Commands

Initialize Configuration:

changenarator init

Run Analysis (Default Command):

changenarator <owner> <repo> <pr_number> <local_repo_path>
bun run cli init

Run Analysis:

bun run start <owner> <repo> <pr_number> <local_repo_path>

Example:

changenarator facebook react 12345 ~/repos/react

Alternative (Explicit Command):

changenarator analyze facebook react 12345 ~/repos/react
bun run start facebook react 12345 ~/repos/react

This will:

  1. Fetch PR metadata from GitHub
  2. Checkout the PR's head SHA locally
  3. Run Bob analysis on the code changes
  4. Generate changelogs for 3 audiences (developers, PMs, users)
  5. Publish results to Notion

Get Help:

changenarator help
# or
changenarator --help
bun run cli help

Check Version:

changenarator version
# or
changenarator --version
bun run cli version

Programmatic Usage

Import and use the fetchPRContext function in your code:

import { fetchPRContext } from './src/index';

const prContext = await fetchPRContext('facebook', 'react', 12345);

console.log(prContext);
// {
//   repo: "facebook/react",
//   pr_number: 12345,
//   pr_title: "Add new feature",
//   base_sha: "abc123...",
//   head_sha: "def456...",
//   commit_messages: ["commit 1", "commit 2"],
//   files_changed: [...],
//   stats: { total_files: 3, total_commits: 2 }
// }

Data Structure

PRContext Interface

interface PRContext {
  repo: string;                    // "owner/repo"
  pr_number: number;               // PR number
  pr_title: string;                // PR title
  base_sha: string;                // Base commit SHA
  head_sha: string;                // Head commit SHA
  commit_messages: string[];       // All commit messages
  files_changed: FileChange[];     // Array of changed files
  stats: {
    total_files: number;           // Total files changed
    total_commits: number;         // Total commits in PR
  };
}

FileChange Interface

interface FileChange {
  filename: string;                           // File path
  status: 'added' | 'modified' | 'removed' | 'renamed';
  additions: number;                          // Lines added
  deletions: number;                          // Lines deleted
  patch: string | null;                       // Git diff patch
}

Development

Available Scripts

  • bun run dev - Run in watch mode (auto-reload on changes)
  • bun run start - Run the application

Testing

The project includes a comprehensive test suite using Bun's built-in test runner.

Running Tests

# Run all tests
bun test

# Run tests in watch mode (auto-rerun on file changes)
bun test:watch

# Run tests with coverage report
bun test:coverage

Test Structure

src/
├── github-client.test.ts    # Unit tests for GitHub API client
├── pr-fetcher.test.ts       # Unit tests for PR fetching logic
└── index.test.ts            # Integration tests for main function

Test Coverage

The test suite includes:

  • GitHubClient Tests (11 tests)

    • Constructor validation
    • PR metadata fetching
    • Commit message retrieval
    • Compare diff fetching
    • Error handling for API failures
  • PRFetcher Tests (10 tests)

    • Data shaping and transformation
    • Input validation
    • File status mapping
    • Error propagation
    • Edge cases (empty PRs, etc.)
  • Integration Tests (5 tests)

    • Environment variable handling
    • CLI argument parsing
    • End-to-end flow validation

Test Results

26 pass
0 fail
47 expect() calls

Writing New Tests

To add new tests, create a file with .test.ts extension:

import { describe, test, expect } from 'bun:test';

describe('My Feature', () => {
  test('should work correctly', () => {
    expect(true).toBe(true);
  });
});

Bun will automatically discover and run all *.test.ts files.

  • bun run build - Build for production
  • bun run typecheck - Check TypeScript types

Project Structure

src/
├── index.ts           # CLI entry point and main export
├── types.ts           # TypeScript type definitions
├── github-client.ts   # GitHub API wrapper using Octokit
├── pr-fetcher.ts      # Main PR fetching and data shaping logic

Error Handling

The script handles various error scenarios:

  • ❌ Missing GitHub token
  • ❌ Invalid repository or PR number
  • ❌ PR not found (404)
  • ❌ API rate limits
  • ❌ Network errors
  • ❌ Invalid input parameters

Examples

Analyze a PR from a public repository

changenarator vercel next.js 50000 ~/repos/nextjs

Analyze a PR from a private repository

Ensure your GitHub token (configured via changenarator init) has repo scope:

changenarator your-org your-private-repo 123 ~/repos/your-private-repo

Using npm scripts (for development)

bun run start vercel next.js 50000 ~/repos/nextjs

Use in your own script

import { fetchPRContext } from './src/index';
import type { PRContext } from './src/types';

async function analyzePR() {
  try {
    const context: PRContext = await fetchPRContext('owner', 'repo', 123);
    
    // Process the PR context
    console.log(`Analyzing ${context.stats.total_files} files...`);
    
    for (const file of context.files_changed) {
      console.log(`${file.status}: ${file.filename}`);
      console.log(`  +${file.additions} -${file.deletions}`);
    }
  } catch (error) {
    console.error('Failed to fetch PR:', error);
  }
}

analyzePR();

License

See LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.


Made with ❤️ by Bob