Files
shiro-neko/scripts/make-release-notes.ts
T
Muhammad Zakir Ramadhan f8c3cc2d8e Ship the batch: undo, parallel subagents, lazy MCP, hot-reloaded skills; docs and CI/CD
Loop and ergonomics batch across Now/Next and Maintenance:
- /undo and /redo via pre-prompt file snapshots (snapshot.ts)
- task takes a tasks[] array and runs investigations concurrently (subagent.ts)
- lazy MCP tools: mcp_list/mcp_inspect/mcp_call meta-tools, eager opt-in (mcp.ts, config.ts)
- skill tool reads its list live so a mid-session install is callable next turn (skills.ts)
- tool-name lists (tool-kinds.ts) derived from a mutating() marker; gates previously ungated writes
- prune/session recovery path summarized, and step-back doom-loop primitive (step-back.ts)
- @file completion re-walks on a slow cooldown; estimateTokens and pricing labeled as estimates

Docs: README, CHANGELOG, docs/{mcp,architecture,development} updated to match.
CI/CD: bun install-store cache and concurrency gates on both workflows; release.yml now
composes file-based release notes via scripts/make-release-notes.ts and verifies every binary.
2026-09-17 17:49:19 +07:00

50 lines
1.9 KiB
TypeScript

#!/usr/bin/env bun
/**
* Writes `release_notes.md` for a release tag, extracting the tag's prose from
* CHANGELOG.md and appending the artifact inventory. Used by .github/workflows/
* release.yml so the release page reads like a hand-written one instead of the raw
* PR list.
*
* Reads the tag from $RELEASE_TAG (GITHUB_REF_NAME, e.g. `v1.2.3`) and fails loudly
* when CHANGELOG.md has no matching `## [<version>]` section, because a release with
* an empty body is worse than one that refused to publish.
*/
const tag = process.env['RELEASE_TAG'] ?? 'v0.0.0-local';
const version = tag.replace(/^v/, '');
const changelog = await Bun.file('CHANGELOG.md').text();
const start = changelog.indexOf(`## [${version}]`);
if (start === -1) {
console.error(`CHANGELOG.md has no "## [${version}]" heading for ${tag}`);
process.exit(1);
}
// The section runs from its heading to the next `## [` heading, or to the file end.
// Drop the heading itself: the release title already carries the version, so keeping
// `## [1.0.0]` under `## What's in v1.0.0` would read twice.
let body = changelog.slice(start);
const next = body.indexOf('\n## [', 1);
if (next !== -1) body = body.slice(0, next);
body = body.replace(/^## \[.*\]\n+/, '').trim();
// ESM, so top-level await is fine; this file is only ever run as the entry script.
await Bun.write(
'release_notes.md',
[
`## What's in ${tag}`,
'',
body,
'',
'### Artifacts',
'- `shiro-linux-x64`, `shiro-linux-arm64` - Linux',
'- `shiro-darwin-x64`, `shiro-darwin-arm64` - macOS',
'- `shiro-windows-x64.exe` - Windows',
'- `SHA256SUMS` - verify any of the above',
'',
'Install with `scripts/install.sh` (macOS/Linux) or `scripts/install.ps1` (Windows);',
'both verify the download against `SHA256SUMS`.',
].join('\n'),
);
console.log(`composed release_notes.md from the ${version} changelog section (${body.split('\n').length} prose lines)`);
process.exit(0);