Skip to content

Commit 7de513d

Browse files
feat: Add npm package with CLI wrapper, programmatic API, TypeScript types, and npm publish workflow.
1 parent 4f15fae commit 7de513d

File tree

15 files changed

+575
-23
lines changed

15 files changed

+575
-23
lines changed

.github/workflows/npm-publish.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Publish to npm
2+
3+
on:
4+
release:
5+
types: [published]
6+
workflow_dispatch:
7+
inputs:
8+
tag:
9+
description: 'npm tag (default: latest, use beta for pre-releases)'
10+
required: false
11+
default: 'latest'
12+
13+
defaults:
14+
run:
15+
working-directory: npm-package
16+
17+
jobs:
18+
publish:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Checkout repository
22+
uses: actions/checkout@v4
23+
24+
- name: Setup Node.js
25+
uses: actions/setup-node@v4
26+
with:
27+
node-version: '20'
28+
registry-url: 'https://registry.npmjs.org'
29+
30+
- name: Install dependencies
31+
run: npm ci --ignore-scripts || npm install --ignore-scripts
32+
33+
- name: Determine npm tag
34+
id: tag
35+
run: |
36+
VERSION=$(node -p "require('./package.json').version")
37+
if [[ "$VERSION" == *"beta"* ]] || [[ "$VERSION" == *"alpha"* ]] || [[ "$VERSION" == *"rc"* ]]; then
38+
echo "tag=beta" >> $GITHUB_OUTPUT
39+
else
40+
echo "tag=${{ github.event.inputs.tag || 'latest' }}" >> $GITHUB_OUTPUT
41+
fi
42+
echo "version=$VERSION" >> $GITHUB_OUTPUT
43+
44+
- name: Publish to npm
45+
run: npm publish --tag ${{ steps.tag.outputs.tag }} --access public
46+
env:
47+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
48+
49+
- name: Create summary
50+
run: |
51+
echo "## npm Package Published" >> $GITHUB_STEP_SUMMARY
52+
echo "" >> $GITHUB_STEP_SUMMARY
53+
echo "- **Package:** git-chronoscope" >> $GITHUB_STEP_SUMMARY
54+
echo "- **Version:** ${{ steps.tag.outputs.version }}" >> $GITHUB_STEP_SUMMARY
55+
echo "- **Tag:** ${{ steps.tag.outputs.tag }}" >> $GITHUB_STEP_SUMMARY
56+
echo "" >> $GITHUB_STEP_SUMMARY
57+
echo "Install with:" >> $GITHUB_STEP_SUMMARY
58+
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
59+
echo "npm install -g git-chronoscope@${{ steps.tag.outputs.tag }}" >> $GITHUB_STEP_SUMMARY
60+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.9.0-beta.2] - 2026-01-02
11+
12+
npm package release for JavaScript ecosystem distribution.
13+
14+
### Added
15+
- npm package for Node.js users (`npm install -g git-chronoscope` or `npx git-chronoscope`)
16+
- Programmatic JavaScript/TypeScript API for integration
17+
- TypeScript type definitions
18+
- npm publish workflow for automated releases
19+
20+
### Technical Details
21+
The npm package is a wrapper that requires Python and the git-chronoscope Python package to be installed. It provides:
22+
- CLI wrapper that passes through all arguments to the Python CLI
23+
- Programmatic API via `require('git-chronoscope')`
24+
- Dependency checking utilities (Python version, FFmpeg, etc.)
25+
- Helpful error messages when prerequisites are missing
26+
1027
## [0.9.0-beta.1] - 2026-01-02
1128

1229
First public beta release establishing distribution foundation.

INSTALL.md

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ brew install git-chronoscope
2929
docker pull southpawriter02/git-chronoscope
3030
```
3131

32+
### npm (Node.js)
33+
34+
```bash
35+
npm install -g git-chronoscope
36+
# or run directly with npx
37+
npx git-chronoscope --help
38+
```
39+
3240
---
3341

3442
## Detailed Installation Instructions
@@ -107,7 +115,30 @@ docker run -v /path/to/repo:/repo -v /path/to/output:/output \
107115
--format gif --resolution 720p --fps 5
108116
```
109117

110-
### Option 5: From Source
118+
### Option 5: npm Package (Node.js)
119+
120+
For JavaScript/TypeScript developers:
121+
122+
```bash
123+
# Install globally
124+
npm install -g git-chronoscope
125+
126+
# Or run directly without installing
127+
npx git-chronoscope /path/to/repo output.mp4
128+
129+
# Use programmatically in your Node.js code
130+
const chronoscope = require('git-chronoscope');
131+
await chronoscope.generate('/path/to/repo', 'output.mp4', { format: 'mp4' });
132+
```
133+
134+
**Requirements:**
135+
- Node.js 14.0.0 or higher
136+
- Python 3.7+ with git-chronoscope installed (`pip install git-chronoscope`)
137+
- FFmpeg installed and in PATH
138+
139+
The npm package wraps the Python CLI, providing a convenient interface for Node.js projects and CI/CD pipelines that use JavaScript tooling.
140+
141+
### Option 6: From Source
111142
112143
For development or to get the latest changes:
113144
@@ -131,7 +162,7 @@ pip install -e .
131162
git-chronoscope /path/to/repo output.mp4
132163
```
133164
134-
### Option 6: GitHub Actions
165+
### Option 7: GitHub Actions
135166
136167
Use git-chronoscope directly in your CI/CD pipeline:
137168
@@ -216,6 +247,11 @@ brew uninstall git-chronoscope
216247
brew untap southpawriter02/git-chronoscope
217248
```
218249
250+
### npm
251+
```bash
252+
npm uninstall -g git-chronoscope
253+
```
254+
219255
### Docker
220256
```bash
221257
docker rmi southpawriter02/git-chronoscope

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# git-chronoscope
22

33
[![PyPI version](https://badge.fury.io/py/git-chronoscope.svg)](https://badge.fury.io/py/git-chronoscope)
4+
[![npm version](https://badge.fury.io/js/git-chronoscope.svg)](https://badge.fury.io/js/git-chronoscope)
45
[![Docker Pulls](https://img.shields.io/docker/pulls/southpawriter02/git-chronoscope)](https://hub.docker.com/r/southpawriter02/git-chronoscope)
56
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
67

@@ -26,6 +27,9 @@ pip install git-chronoscope
2627
# Homebrew (macOS/Linux)
2728
brew tap southpawriter02/git-chronoscope && brew install git-chronoscope
2829

30+
# npm (Node.js)
31+
npm install -g git-chronoscope
32+
2933
# Docker
3034
docker pull southpawriter02/git-chronoscope
3135
```

npm-package/.npmignore

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Development files
2+
.git/
3+
.github/
4+
test/
5+
*.test.js
6+
.eslintrc*
7+
.prettierrc*
8+
jest.config.js
9+
10+
# Build artifacts
11+
*.log
12+
.DS_Store
13+
Thumbs.db
14+
15+
# IDE
16+
.vscode/
17+
.idea/
18+
*.swp
19+
*.swo
20+
21+
# Coverage
22+
coverage/
23+
.nyc_output/

npm-package/README.md

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# git-chronoscope
2+
3+
[![npm version](https://badge.fury.io/js/git-chronoscope.svg)](https://badge.fury.io/js/git-chronoscope)
4+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5+
6+
Generate time-lapse visualizations of Git repository evolution.
7+
8+
This is the official npm wrapper for [git-chronoscope](https://github.com/southpawriter02/git-chronoscope). It provides both a CLI and a programmatic API for Node.js.
9+
10+
## Prerequisites
11+
12+
This package requires the following to be installed:
13+
14+
- **Python 3.7+** - [Download](https://www.python.org/downloads/)
15+
- **git-chronoscope Python package** - `pip install git-chronoscope`
16+
- **FFmpeg** - [Download](https://ffmpeg.org/download.html)
17+
- **Git** - [Download](https://git-scm.com/downloads)
18+
19+
## Installation
20+
21+
```bash
22+
# Global installation (recommended for CLI usage)
23+
npm install -g git-chronoscope
24+
25+
# Project dependency
26+
npm install git-chronoscope
27+
28+
# Or use without installing
29+
npx git-chronoscope
30+
```
31+
32+
## CLI Usage
33+
34+
```bash
35+
# Basic usage
36+
git-chronoscope /path/to/repo output.mp4
37+
38+
# Generate a GIF
39+
git-chronoscope /path/to/repo output.gif --format gif
40+
41+
# Custom resolution and FPS
42+
git-chronoscope /path/to/repo output.mp4 --resolution 720p --fps 5
43+
44+
# Filter by branch
45+
git-chronoscope /path/to/repo output.mp4 --branch main
46+
47+
# Author highlighting
48+
git-chronoscope /path/to/repo output.mp4 --author-colors
49+
50+
# Include only specific files
51+
git-chronoscope /path/to/repo output.mp4 --include "*.py" --include "*.js"
52+
53+
# Dry run (preview without generating)
54+
git-chronoscope /path/to/repo output.mp4 --dry-run
55+
```
56+
57+
## Programmatic API
58+
59+
```javascript
60+
const { generate, checkInstallation, version } = require('git-chronoscope');
61+
62+
// Check if dependencies are installed
63+
const { ok, errors } = await checkInstallation();
64+
if (!ok) {
65+
console.error('Missing dependencies:', errors);
66+
process.exit(1);
67+
}
68+
69+
// Generate a time-lapse
70+
const result = await generate('/path/to/repo', 'output.mp4', {
71+
format: 'mp4',
72+
resolution: '1080p',
73+
fps: 2,
74+
authorColors: true,
75+
include: ['src/**/*.js'],
76+
exclude: ['node_modules/**']
77+
});
78+
79+
if (result.success) {
80+
console.log('Video generated successfully!');
81+
console.log(result.output);
82+
} else {
83+
console.error('Generation failed:', result.error);
84+
}
85+
86+
// Get wrapper version
87+
console.log('Version:', version());
88+
```
89+
90+
## API Reference
91+
92+
### `generate(repoPath, outputPath, options?)`
93+
94+
Generate a time-lapse visualization.
95+
96+
**Parameters:**
97+
- `repoPath` (string) - Path to the Git repository
98+
- `outputPath` (string) - Path for the output file
99+
- `options` (object, optional):
100+
- `format` - Output format: `'mp4'`, `'gif'`, or `'html'`
101+
- `branch` - Git branch to visualize
102+
- `fps` - Frames per second (default: 2)
103+
- `resolution` - `'720p'`, `'1080p'`, or `'4k'`
104+
- `bgColor` - Background color (hex)
105+
- `textColor` - Text color (hex)
106+
- `include` - Array of glob patterns to include
107+
- `exclude` - Array of glob patterns to exclude
108+
- `authorColors` - Enable author color highlighting
109+
- `noEmail` - Hide author emails
110+
- `redactSecrets` - Redact sensitive data
111+
- `dryRun` - Preview without generating
112+
- `sampleRate` - Process every Nth commit
113+
- `maxCommits` - Limit to N commits
114+
- `since` - Start date (YYYY-MM-DD)
115+
- `until` - End date (YYYY-MM-DD)
116+
117+
**Returns:** `Promise<{ success: boolean, output: string, error: string }>`
118+
119+
### `checkInstallation()`
120+
121+
Check if all required dependencies are installed.
122+
123+
**Returns:** `Promise<{ ok: boolean, errors: string[] }>`
124+
125+
### `version()`
126+
127+
Get the npm wrapper version.
128+
129+
**Returns:** `string`
130+
131+
## TypeScript Support
132+
133+
TypeScript type definitions are included. Import types:
134+
135+
```typescript
136+
import { generate, GenerateOptions, GenerateResult } from 'git-chronoscope';
137+
138+
const options: GenerateOptions = {
139+
format: 'mp4',
140+
resolution: '1080p'
141+
};
142+
143+
const result: GenerateResult = await generate('/repo', 'output.mp4', options);
144+
```
145+
146+
## Troubleshooting
147+
148+
### "Python is not installed"
149+
150+
Install Python 3.7+ from [python.org](https://www.python.org/downloads/) and ensure it's in your PATH.
151+
152+
### "git-chronoscope Python package not installed"
153+
154+
Install the Python package:
155+
```bash
156+
pip install git-chronoscope
157+
```
158+
159+
### "FFmpeg is not installed"
160+
161+
Install FFmpeg:
162+
- **macOS**: `brew install ffmpeg`
163+
- **Ubuntu/Debian**: `sudo apt install ffmpeg`
164+
- **Windows**: Download from [ffmpeg.org](https://ffmpeg.org/download.html)
165+
166+
## Links
167+
168+
- [GitHub Repository](https://github.com/southpawriter02/git-chronoscope)
169+
- [Full Documentation](https://github.com/southpawriter02/git-chronoscope#readme)
170+
- [PyPI Package](https://pypi.org/project/git-chronoscope/)
171+
- [Issue Tracker](https://github.com/southpawriter02/git-chronoscope/issues)
172+
173+
## License
174+
175+
MIT

0 commit comments

Comments
 (0)