New Feature·Pushed May 1, 2026·M
GitPulse gains AI story generator from commits
GitPulse can now automatically generate readable editorial stories from raw git commits — feeding commit metadata to an AI model and outputting structured stories with headlines and body text.
Git commits are notoriously hard to read in bulk. A diff stat and subject line tell you *what* changed, but not *why* it matters. GitPulse now bridges that gap with a pipeline that reads local git history and generates editorial stories automatically.
The new analyzer walks commits on the default branch, sends each one's metadata (author, date, file changes, message) to an OpenAI-compatible LLM, and writes out Story JSON containing a headline, standfirst, and body. These stories can then be rendered on a dev log or changelog.
The LLM uses structured output via Zod to guarantee consistent JSON shape, and a deliberate system prompt enforces a "dry, slightly literary" editorial voice — no marketing speak, no emoji. Trivial commits like typo fixes are acknowledged plainly rather than dramatized.
The workflow supports any OpenAI-compatible provider out of the box: set [[code]]ai-base-url[[/code]] to MiniMax, Groq, OpenRouter, or Together, and the same [[code]]OPENAI_API_KEY[[/code]] secret works. This replaces the previous [[code]]openai-model[[/code]] input with provider-neutral naming.
In the [[code]]action[[/code]] workspace, the pipeline runs locally or in CI via [[code]]yarn workspace @gitpulse/action analyze[[/code]]. Phase 2.1 will add merged-PR classification via GitHub's GraphQL API.
Technical description
This commit adds Phase 2 of the GitPulse action: a complete local git → LLM → story JSON pipeline.
**The Pipeline**
The flow runs in [[code ref=1]]src/index.ts[[/code]] orchestration. Config loads from environment vars via [[code ref=4]]src/config.ts[[/code]], which now supports provider-agnostic AI endpoints. Commits are read from local git via [[code ref=2]]src/git.ts[[/code]], which walks the default branch and parses diff stats (files changed, insertions, deletions). Each commit goes to [[code ref=3]]src/llm.ts[[/code]], a LangChain ChatOpenAI wrapper that uses Zod structured output with a named schema [[code]]gitpulse_story[[/code]]. The LLM receives a system prompt specifying the editorial voice ("precise, dry, slightly literary") and a user prompt rendering the commit metadata. Output stories write via [[code ref=5]]src/render.ts[[/code]] to [[code]]site/src/content/stories/[[/code]] as JSON.
````mermaid
graph LR
A[git log] --> B[walkCommits]
B --> C[CommitRecord]
C --> D[createSummarizer]
D --> E[LLM / Structured Output]
E --> F[buildStoryFromCommit]
F --> G[writeStory JSON]
````
**Type System**
[[code ref=6]]src/types.ts[[/code]] defines three core interfaces: [[code]]CommitRecord[[/code]] (raw git data + diff stats), [[code]]AISummary[[/code]] (headline, standfirst, body from LLM), and [[code]]Story[[/code]] (the final output including commit URL, author, and kind). The [[code]]kind[[/code]] field distinguishes [[code]]'pr'[[/code]] from [[code]]'direct-push'[[/code]] — Phase 1 marks all as direct-push; PR association comes in Phase 2.1.
**Provider Neutrality**
The GitHub Actions workflow in [[code]].github/workflows/analyze.yml[[/code]] now exposes three inputs:
- [[code]]ai-model[[/code]] (renamed from [[code]]openai-model[[/code]])
- [[code]]ai-base-url[[/code]] (new, defaults to empty/OpenAI)
- [[code]]ai-temperature[[/code]] (new, default 0.7)
The secret stays as [[code]]OPENAI_API_KEY[[/code]], the de facto convention for OpenAI-compatible endpoints.
**Files at a Glance**
- [[code]]action/src/types.ts[[/code]] — Story / CommitRecord / AISummary type definitions
- [[code]]action/src/git.ts[[/code]] — git log walker + diff stat parsing
- [[code]]action/src/llm.ts[[/code]] — LangChain ChatOpenAI with Zod structured output
- [[code]]action/src/config.ts[[/code]] — env-driven runtime config
- [[code]]action/src/render.ts[[/code]] — write Story JSON to filesystem
- [[code]]action/src/index.ts[[/code]] — orchestration entrypoint
- [[code]].github/workflows/analyze.yml[[/code]] — updated workflow inputs (provider-neutral naming)
- [[code]]action/package.json[[/code]] — added [[code]]analyze[[/code]] script
Categories
- New Feature (90%) — Core change: new local git → LLM → story JSON analysis pipeline for generating editorial content from commits
- Configuration (10%) — GitHub Actions workflow inputs renamed to provider-neutral names (ai-model, ai-base-url, ai-temperature)