From 4813ddfdeb03a93941a7dbd41e7c8e6437c488fd Mon Sep 17 00:00:00 2001 From: scanner <280983584+hivecommons-hive[bot]@users.noreply.github.com> Date: Sun, 25 Oct 2026 22:30:58 -0400 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=8C=B1=20release:=200.9.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: scanner <280983584+hivecommons-hive[bot]@users.noreply.github.com> --- changelog.d/fixed-311-subcommand-stray-args.md | 1 - changelog.d/fixed-322-no-interactive-missing-value.md | 1 - changelog.d/fixed-switch-value-and-unknown-flags.md | 1 - changelog.d/fixed-ui-unknown-flags.md | 1 - changelog.d/stricter-311-subcommand-stray-args.md | 1 + .../stricter-313-switch-value-and-unknown-flags.md | 1 + changelog.d/stricter-317-ui-unknown-flags.md | 1 + .../stricter-322-no-interactive-missing-value.md | 1 + package-lock.json | 4 ++-- package.json | 2 +- scripts/release-notes.mjs | 1 + scripts/release-notes.test.mjs | 10 ++++++++++ 12 files changed, 18 insertions(+), 7 deletions(-) delete mode 100644 changelog.d/fixed-311-subcommand-stray-args.md delete mode 100644 changelog.d/fixed-322-no-interactive-missing-value.md delete mode 100644 changelog.d/fixed-switch-value-and-unknown-flags.md delete mode 100644 changelog.d/fixed-ui-unknown-flags.md create mode 100644 changelog.d/stricter-311-subcommand-stray-args.md create mode 100644 changelog.d/stricter-313-switch-value-and-unknown-flags.md create mode 100644 changelog.d/stricter-317-ui-unknown-flags.md create mode 100644 changelog.d/stricter-322-no-interactive-missing-value.md diff --git a/changelog.d/fixed-311-subcommand-stray-args.md b/changelog.d/fixed-311-subcommand-stray-args.md deleted file mode 100644 index 1c14b05..0000000 --- a/changelog.d/fixed-311-subcommand-stray-args.md +++ /dev/null @@ -1 +0,0 @@ -`promptargs list`, `init`, `env` and `show` now reject trailing arguments and flags with `Unexpected argument: ` instead of silently ignoring them. (#311) diff --git a/changelog.d/fixed-322-no-interactive-missing-value.md b/changelog.d/fixed-322-no-interactive-missing-value.md deleted file mode 100644 index b1c4649..0000000 --- a/changelog.d/fixed-322-no-interactive-missing-value.md +++ /dev/null @@ -1 +0,0 @@ -`promptargs` now exits 1 with `Missing value for {{name}}: ...` when a blank has no value under `--no-interactive` (or piped stdin) instead of printing the unfilled `{{name}}` placeholder and exiting 0. (#322) diff --git a/changelog.d/fixed-switch-value-and-unknown-flags.md b/changelog.d/fixed-switch-value-and-unknown-flags.md deleted file mode 100644 index 753636b..0000000 --- a/changelog.d/fixed-switch-value-and-unknown-flags.md +++ /dev/null @@ -1 +0,0 @@ -A switch given a value (`--json=false`, `--cross=0`) is now rejected with `Invalid --: -- takes no value`, and a flag that names no blank in the template is rejected with `Unknown flag --: ...` instead of being silently ignored. (#313) diff --git a/changelog.d/fixed-ui-unknown-flags.md b/changelog.d/fixed-ui-unknown-flags.md deleted file mode 100644 index 532bd96..0000000 --- a/changelog.d/fixed-ui-unknown-flags.md +++ /dev/null @@ -1 +0,0 @@ -promptargs ui now rejects flags other than --port instead of silently ignoring them (#317) \ No newline at end of file diff --git a/changelog.d/stricter-311-subcommand-stray-args.md b/changelog.d/stricter-311-subcommand-stray-args.md new file mode 100644 index 0000000..11a8623 --- /dev/null +++ b/changelog.d/stricter-311-subcommand-stray-args.md @@ -0,0 +1 @@ +`promptargs list`, `init`, `env` and `show` with trailing arguments or flags (`list --json`, `init --force`, `env extra`). Old: silently ignored, exit 0. New: exit 1 with `Unexpected argument: `. (#311) diff --git a/changelog.d/stricter-313-switch-value-and-unknown-flags.md b/changelog.d/stricter-313-switch-value-and-unknown-flags.md new file mode 100644 index 0000000..cc3cb0a --- /dev/null +++ b/changelog.d/stricter-313-switch-value-and-unknown-flags.md @@ -0,0 +1 @@ +Template runs given a switch with a value (`--json=false`, `--cross=0`) or a flag that names no blank (`--fiel=main.go`). Old: the switch was enabled whatever the value and the unknown flag was silently dropped, exit 0. New: exit 1 with `Invalid --: -- takes no value` or `Unknown flag --: ...`. (#313) diff --git a/changelog.d/stricter-317-ui-unknown-flags.md b/changelog.d/stricter-317-ui-unknown-flags.md new file mode 100644 index 0000000..25b7257 --- /dev/null +++ b/changelog.d/stricter-317-ui-unknown-flags.md @@ -0,0 +1 @@ +`promptargs ui` given any flag other than `--port` (`--prot=3700`, `--json`). Old: silently ignored, the server started on the default port. New: exit 1 with an `Unknown flag` error. (#317) diff --git a/changelog.d/stricter-322-no-interactive-missing-value.md b/changelog.d/stricter-322-no-interactive-missing-value.md new file mode 100644 index 0000000..67cd8f2 --- /dev/null +++ b/changelog.d/stricter-322-no-interactive-missing-value.md @@ -0,0 +1 @@ +A template run with `--no-interactive` (or piped stdin) where a blank has no flag, autodetected value or default. Old: printed the literal `{{name}}` placeholder and exited 0. New: exit 1 with `Missing value for {{name}}: ...`. (#322) diff --git a/package-lock.json b/package-lock.json index f016710..f27b0b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@hivecommons/promptargs", - "version": "0.8.0", + "version": "0.9.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@hivecommons/promptargs", - "version": "0.8.0", + "version": "0.9.0", "license": "Apache-2.0", "dependencies": { "mustache": "^4.2.0" diff --git a/package.json b/package.json index 991bc06..152a203 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@hivecommons/promptargs", - "version": "0.8.0", + "version": "0.9.0", "description": "Template arguments for AI prompts — variable substitution for Claude Code, Copilot, Goose, Bob, and more", "type": "module", "main": "dist/index.js", diff --git a/scripts/release-notes.mjs b/scripts/release-notes.mjs index f422cbc..30f8999 100644 --- a/scripts/release-notes.mjs +++ b/scripts/release-notes.mjs @@ -5,6 +5,7 @@ import { fileURLToPath } from 'node:url'; const CATEGORIES = [ ['added', 'Added'], ['changed', 'Changed'], + ['stricter', 'Stricter parsing'], ['fixed', 'Fixed'], ]; diff --git a/scripts/release-notes.test.mjs b/scripts/release-notes.test.mjs index cb3535b..f786b67 100644 --- a/scripts/release-notes.test.mjs +++ b/scripts/release-notes.test.mjs @@ -18,6 +18,16 @@ test('groups fragments by category and normalises bullets', () => { ); }); +test('renders stricter fragments under a Stricter parsing heading', () => { + const dir = mkdtempSync(join(tmpdir(), 'notes-')); + writeFileSync(join(dir, 'stricter-s.md'), 'Old: ignored. New: rejected. (#5)\n'); + writeFileSync(join(dir, 'fixed-b.md'), 'Fixed b (#2)\n'); + assert.equal( + renderReleaseNotes(dir), + '### Stricter parsing\n\n- Old: ignored. New: rejected. (#5)\n\n### Fixed\n\n- Fixed b (#2)\n', + ); +}); + test('returns an empty string when there are no fragments', () => { assert.equal(renderReleaseNotes(mkdtempSync(join(tmpdir(), 'notes-'))), ''); }); From d7367d18be3bfa5408c5652abe037f815d426888 Mon Sep 17 00:00:00 2001 From: scanner <280983584+hivecommons-hive[bot]@users.noreply.github.com> Date: Sun, 25 Oct 2026 22:43:21 -0400 Subject: [PATCH 2/2] test: accept the stricter changelog category in the fragment contract test Signed-off-by: scanner <280983584+hivecommons-hive[bot]@users.noreply.github.com> --- .github/pull_request_template.md | 2 +- CONTRIBUTING.md | 2 +- scripts/release-notes.test.mjs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 4bb560b..d5ed82a 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -14,6 +14,6 @@ See [CONTRIBUTING.md](https://github.com/hivecommons/promptargs/blob/main/CONTRI - [ ] `npm run lint`, `npm run build` and `npm test` pass locally - [ ] If `src/` changed: the rebuilt `dist/` is committed (CI fails when `dist/` is out of sync) -- [ ] If the change is user-visible: a `changelog.d/-.md` fragment is included +- [ ] If the change is user-visible: a `changelog.d/-.md` fragment is included - [ ] Behavior changes include tests or verification notes - [ ] Commits are signed off (`git commit -s`) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 98deb12..c267e81 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ npm test ## Changelog fragments -For a user-visible change, add one Markdown file to `changelog.d/` named `-.md`, where the category is `added`, `changed`, or `fixed`. The file holds a single user-facing line describing the change, ending with the PR or issue number, for example `(#86)`. See the existing files in `changelog.d/` for the style. `scripts/release-notes.mjs` renders these fragments, grouped by category, into the GitHub release notes when `auto-release.yml` publishes a release. Fragments stay in place and are not deleted; only fragments added since the previous tag appear in a release's notes (all fragments if there is no previous tag). +For a user-visible change, add one Markdown file to `changelog.d/` named `-.md`, where the category is `added`, `changed`, `stricter` (a parsing change that now rejects input previously accepted — state old and new behavior), or `fixed`. The file holds a single user-facing line describing the change, ending with the PR or issue number, for example `(#86)`. See the existing files in `changelog.d/` for the style. `scripts/release-notes.mjs` renders these fragments, grouped by category, into the GitHub release notes when `auto-release.yml` publishes a release. Fragments stay in place and are not deleted; only fragments added since the previous tag appear in a release's notes (all fragments if there is no previous tag). ## Releases diff --git a/scripts/release-notes.test.mjs b/scripts/release-notes.test.mjs index f786b67..b6b4bcf 100644 --- a/scripts/release-notes.test.mjs +++ b/scripts/release-notes.test.mjs @@ -71,7 +71,7 @@ test('every committed changelog.d fragment is rendered', () => { assert.ok(names.length > 0, 'expected at least one fragment'); const rendered = renderReleaseNotes(dir); for (const name of names) { - assert.match(name, /^(added|changed|fixed)-[a-z0-9][a-z0-9-]*\.md$/, name); + assert.match(name, /^(added|changed|stricter|fixed)-[a-z0-9][a-z0-9-]*\.md$/, name); const lines = readFileSync(join(dir, name), 'utf8').trim().split('\n'); assert.equal(lines.length, 1, `${name} must hold a single line`); const text = lines[0].replace(/^[-*]\s+/, '');