jwulf/release-notes-concierge

Urban app: turn merged PRs into human-approved GitHub Releases (Nano delegation loop test)

★ 0Forks 0TypeScriptGitHub ↗Compare

README

Release Notes Concierge

An Urban app that turns a stream of merged pull requests into polished, human-approved GitHub Releases — with an AI agent doing the drafting and a person staying in the loop for the final say.

Why

Cutting a release note by hand is tedious and easy to get wrong: you scrape the merged PRs since the last tag, guess at categories, write a summary, and hope you didn't miss a breaking change. The Concierge automates the toil and keeps the judgment where it belongs — with a human reviewer.

The flow

The whole thing is a BPMN process (visible and editable in the Nano modeller):

collect merged PRs ──▶ draft notes (agent) ──▶ await approval ──┬─(approve)─▶ publish release
        ▲                                                        │
        └──────────────────── revise (agent) ◀──────(request changes)
  1. Collect — gather PRs merged since the last release tag for a target repo.
  2. Draft — an agent service task categorizes changes (Features / Fixes / Breaking / Chore) and writes a summary + highlights.
  3. Await approval — the draft parks in the Urban page for a human to approve or send back with change requests (a message catch event).
  4. Revise loop — on "request changes", the agent re-drafts with the feedback; back to await approval.
  5. Publish — on approval, create the GitHub Release with the finalized notes.

Status

Early scaffold. The build-out is tracked by the planning epic and its sub-issues in this repo. This app is also a live test of the Nano delegation -> PR-convergence -> merge loop.

Develop

npm install        # installs deps and wires git hooks (via the `prepare` script)
npm run gen        # derive typed artifacts from nano.app.json (never committed)
npm run lint       # biome check (lint + format) over main.ts/app/workers/pages/actions/tests
npm run typecheck  # tsc --noEmit -p tsconfig.check.json
npm run test       # node --test (--experimental-strip-types) over tests/unit/*.test.ts
npm run check      # urban manifest + model validation
npm start          # run against a Nano engine (CAMUNDA_REST_ADDRESS, default http://localhost:8080/v2)

The dev workflow: gen → lint → typecheck → test → check

Every change goes through the same five gates, aggregated by a single command:

npm run verify     # gen && lint && typecheck && test && check
  • gen — urban gen regenerates the typed SDK under nano-generated/ from nano.app.json. It is derived, never committed (see .gitignore); run it first.
  • lint — biome check (config in biome.json, the c8ctl recommended + strict ruleset), scoped to main.ts, app/, workers/, pages/, actions/, tests/ and excluding generated dirs (nano-generated/, templates/). Use npm run lint:fix to auto-apply safe fixes and formatting.
  • typecheck — tsc --noEmit -p tsconfig.check.json.
  • test — the Node built-in runner (node --experimental-strip-types --test).
  • check — urban check validates the manifest and models.

The app targets Node only (minimum >=22.13, the first release to expose node:sqlite unflagged). CI runs the full Node pipeline on every PR (.github/workflows/ci.yml) across the minimum and latest Node versions, so all sub-issue PRs are gated by these same conventions.

Git hooks

npm install runs a prepare script that points core.hooksPath at .githooks/:

  • pre-commit — lint/format staged *.ts (via Biome), then typecheck the whole project (tsc -p tsconfig.check.json is project-wide, not staged-scoped).
  • pre-push — the full verify aggregate.

Hooks degrade gracefully (skip, non-fatal) when tooling isn't installed yet.

Testing

Tests live under tests/ and run on the Node built-in test runner:

  • tests/unit/*.test.ts — fast unit tests (npm run test).
  • tests/integration/*.test.ts — integration tests (npm run test:integration).

Write tests with node:test + node:assert/strict (keep imports to node: builtins and the app's own modules). Feature sub-issues (#2–#5) add their own tests here — drop a *.test.ts file directly into tests/unit/ and npm run test (and CI, which runs that script) picks it up automatically. The globs are non-recursive and per-directory: files under tests/integration/ run via npm run test:integration (not part of CI by default), and nested subdirectories aren't matched. See tests/unit/scaffold.test.ts for the shape.

One scaffold, then feature waves

This repo is built in waves. Sub-issue #7 (this scaffold) is the only task that scaffolds the app or configures tooling — it must merge before any feature work starts. Every later sub-issue (#2–#5) builds on the merged skeleton and MUST NOT re-scaffold or change the lint/test/CI configuration; it only adds its own code under the existing layout and its own tests under tests/, gated by the conventions established here.

Conventions

  • Commits are DCO signed-off (git commit -s).
  • Dev workflow and CI gates: gen → lint → typecheck → test → check — all enforced on every PR.

Contributors

jwulf

Issues