Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/<added|changed|fixed>-<slug>.md` fragment is included
- [ ] If the change is user-visible: a `changelog.d/<added|changed|stricter|fixed>-<slug>.md` fragment is included
- [ ] Behavior changes include tests or verification notes
- [ ] Commits are signed off (`git commit -s`)
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ npm test

## Changelog fragments

For a user-visible change, add one Markdown file to `changelog.d/` named `<category>-<slug>.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 `<category>-<slug>.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

Expand Down
1 change: 0 additions & 1 deletion changelog.d/fixed-311-subcommand-stray-args.md

This file was deleted.

1 change: 0 additions & 1 deletion changelog.d/fixed-322-no-interactive-missing-value.md

This file was deleted.

1 change: 0 additions & 1 deletion changelog.d/fixed-switch-value-and-unknown-flags.md

This file was deleted.

1 change: 0 additions & 1 deletion changelog.d/fixed-ui-unknown-flags.md

This file was deleted.

1 change: 1 addition & 0 deletions changelog.d/stricter-311-subcommand-stray-args.md
Original file line number Diff line number Diff line change
@@ -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: <arg>`. (#311)
1 change: 1 addition & 0 deletions changelog.d/stricter-313-switch-value-and-unknown-flags.md
Original file line number Diff line number Diff line change
@@ -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 --<switch>: --<switch> takes no value` or `Unknown flag --<name>: ...`. (#313)
1 change: 1 addition & 0 deletions changelog.d/stricter-317-ui-unknown-flags.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/stricter-322-no-interactive-missing-value.md
Original file line number Diff line number Diff line change
@@ -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)
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
1 change: 1 addition & 0 deletions scripts/release-notes.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { fileURLToPath } from 'node:url';
const CATEGORIES = [
['added', 'Added'],
['changed', 'Changed'],
['stricter', 'Stricter parsing'],
['fixed', 'Fixed'],
];

Expand Down
12 changes: 11 additions & 1 deletion scripts/release-notes.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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-'))), '');
});
Expand Down Expand Up @@ -61,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+/, '');
Expand Down
Loading