A single-file, client-side web app that turns Jira CSV exports into a polished,
professionally-written release notes document using an AI provider of your
choice (Google Gemini or OpenAI). No backend, build step, or install required
— just open index.html in a browser.
The app works end-to-end for its core flow (configure → upload CSVs → generate → export), provided you supply a valid API key. All three listed providers — Gemini, OpenAI, and DeepSeek — are now implemented. See Known Issues below for remaining caveats.
Changelog: DeepSeek support was added, a Model field now lets you pick or type any model ID per provider (instead of a hardcoded one), and you can now export the generated notes as raw .md in addition to .docx and .pdf. Markdown parsing now uses
marked.jsinstead of a regex converter, PDF export produces real selectable text instead of a screenshot, uploaded CSVs get a quick sanity check before generation, and the RAG context field now supports a local file upload (avoiding CORS entirely) with URL fetch failures surfaced as a single non-blocking warning instead of a pop-up alert.
The app is a 3-step wizard:
- Release Version/Name, Build Number, Release Date — metadata used in the generated document header.
- AI Provider — dropdown for Google Gemini, OpenAI ChatGPT, or DeepSeek.
- Model — a text field (with a dropdown of suggestions) for the exact
model ID to call, e.g.
gemini-2.5-flash,gpt-4.1-mini,deepseek-chat. Switching provider updates the suggestions and default; you can also type any model ID your provider supports, since provider lineups change often. - API Key — your personal key for the chosen provider, entered directly in the browser.
- Optional context (improves accuracy of categorization):
- A Knowledge Base JSON file — upload it directly, or provide a link to one (the link is only used if no file is uploaded). A "Download Template" button generates a starter JSON file showing the expected schema.
- A RAG context file (
.txt) — same pattern: upload directly, or provide a link as a fallback. Uploading avoids CORS issues entirely (see below); a link only works if the remote server allows cross-origin requests from the browser.
Upload up to 5 separate Jira CSV exports (all optional, but at least one is required):
- Epics
- Stories
- Bug Fixes
- Support Escalations
- Known Issues
These should be standard Jira CSV exports (e.g., via a Jira filter export or
the "Jira Cloud for Google Sheets" add-on) with columns like Issue key,
Summary, Description, Labels, etc. Before generating, the app checks
each uploaded file's header row for expected columns (Issue key,
Summary) and — if something looks off — shows a warning listing which
file(s) don't look like a standard export, letting you cancel and re-check
your files or continue anyway. This is a quick sanity check, not full schema
validation.
- Sends a detailed prompt (release metadata + your CSVs + any optional context) to the selected AI provider and model, instructing it to act as a technical writer and produce release notes following a Microsoft-style writing guide: active voice, present tense, no marketing fluff, and specific Markdown section rules for New Features / Bug Fixes / Known Issues.
- The AI's raw Markdown response is kept as-is for the
.mdexport, and is parsed withmarked.js(a proper Markdown parser — handles nested lists, tables, code spans, etc.) both for the live HTML preview and for building the PDF. - From there you can export the result as:
- .md — the raw AI output, unmodified.
- .docx — the rendered HTML preview converted to Word via
html-docx-js. - .pdf — real, selectable text built directly from the parsed Markdown structure (headings, paragraphs, bullet lists, and a basic table fallback), not a screenshot.
- Or click Start Over to reset the whole form.
- A modern web browser (uses ES modules,
fetch,FileReader). - An active internet connection (loads Tailwind, Google Fonts, jsPDF, html2canvas, and html-docx-js from public CDNs).
- A valid API key for Gemini or OpenAI (see limitations — DeepSeek is listed but not implemented).
- Optional: your own KB JSON / RAG text file if you want higher-quality, product-aware output.
- Open
index.htmlin a browser (double-click, or serve it with any static file server). - Fill in Release Version, Release Date, pick an AI provider, and paste in your API key.
- Click Next: Import Data and upload one or more Jira CSV files.
- Click Generate Notes and wait for the AI response.
- Review the formatted notes, then download as .docx or .pdf.
- API keys are exposed client-side. The key you enter is used directly
in a browser-side
fetch()call to the AI provider's API and is visible in the browser's network tab / page memory. There is no backend proxy. Don't use a key with broader permissions/budget than you're comfortable exposing, and don't share this file (or a hosted copy of it) with your key pre-filled. - Model suggestions can go stale. The dropdown of suggested model IDs is a convenience, not a live list from the provider — AI providers rename, retire, and add models frequently. If a suggested ID errors out, check your provider's current model list and type the correct ID directly into the Model field (it accepts any value).
- DeepSeek uses OpenAI-compatible calling conventions. This should work
for the current
deepseek-chat/deepseek-reasoner/deepseek-v4-*model family, but if DeepSeek changes its API shape in the future the request/response handling incallAI()may need updating. - CORS-dependent link fetching. Both optional-context fields (RAG and KB) now default to a local file upload, which never touches CORS. The URL fields are still there as a fallback for cases where you'd rather link to hosted content, but that fetch still happens from the browser, so it only succeeds if the remote server sends permissive CORS headers. When a link fetch fails, it no longer interrupts you with a pop-up — it's folded into the same one-time warning dialog as the CSV sanity check, so you can review everything at once and choose whether to proceed.
- PDF text formatting is simplified. The PDF export now uses real,
selectable text (built from the parsed Markdown tokens) instead of a
screenshot, which fixes searchability and page-break quality. The
trade-off: inline emphasis (
**bold**,`code`) is stripped rather than rendered as styled text within a line, since mixing bold/normal runs on one line requires manual text-segment splitting that wasn't worth the added complexity here. Tables render as plain pipe-separated lines rather than a formatted grid (the HTML preview and .docx export do render tables properly, since they use the browser's own rendering). - No persistence. All state lives in memory; refreshing or clicking
"Start Over" discards everything. There's no save/load of a
work-in-progress release. (The one exception is the dark/light theme
toggle, which is remembered via
localStorage.) - CSV validation is a light sanity check, not full validation. The app
looks for
Issue key/Summary-like text in each file's header row and warns if a file doesn't look like a Jira export, but it doesn't validate the full schema or catch subtler formatting issues — it's meant to catch "wrong file uploaded" mistakes, not guarantee data quality.
- Tailwind CSS (via CDN, no build step)
- Vanilla JavaScript (ES module, no framework)
- marked.js for Markdown parsing (preview + PDF structure)
- jsPDF for native text PDF export
- html-docx-js for Word export
- Google Fonts (Inter)