@noice-tech/pi-changelog 1.0.0 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -1
- package/extensions/changelog/index.ts +63 -10
- package/extensions/changelog/rules.md +55 -21
- package/extensions/changelog/worker-prompt.md +27 -21
- package/package.json +2 -2
- package/prompts/release-notes.md +9 -8
- package/prompts/unreleased.md +13 -11
package/README.md
CHANGED
|
@@ -32,7 +32,31 @@ Pi packages run with the permissions granted to Pi. **Only use this package when
|
|
|
32
32
|
|
|
33
33
|
`auto` is accepted only as `/commit` inference input. Changelog and PR classifications are `feat`, `fix`, `improve`, or `internal`.
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
`/commit` runs its worker on a side branch of the current session at low thinking, then restores your previous thinking level when it finishes. If you invoke it during an active agent turn, the change-type selector opens immediately; after your selection, the command waits for that turn to settle before starting the worker.
|
|
36
|
+
|
|
37
|
+
### PR title package scopes
|
|
38
|
+
|
|
39
|
+
Commit messages always keep the unscoped form:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
internal: update PR title generation
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
PR titles stay unscoped in single-package repositories and workspaces. In a multi-package workspace, the title identifies one primary package by its workspace directory basename:
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
internal(changelog): update PR title generation
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The worker determines the primary package from the PR's intent and full branch against its base. Incidental shared files such as a lockfile do not override a clear primary package. Root-only, cross-cutting, or ambiguous multi-package changes use `monorepo`:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
internal(monorepo): centralize release tooling
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Both scoped and unscoped PR titles are valid changelog inputs. Package scopes are metadata and are not included in public changelog copy.
|
|
58
|
+
|
|
59
|
+
The canonical shared classification and package-scope rules live in `extensions/changelog/rules.md`.
|
|
36
60
|
|
|
37
61
|
## Repository-specific release-note style
|
|
38
62
|
|
|
@@ -30,7 +30,7 @@ const CHANGE_TYPE_OPTIONS: Array<{ type: ChangeType; label: string }> = [
|
|
|
30
30
|
|
|
31
31
|
const MESSAGE_TYPE = 'noice-changelog-commit-result'
|
|
32
32
|
const PROMPT_MESSAGE_TYPE = 'noice-changelog-commit-worker-prompt'
|
|
33
|
-
const
|
|
33
|
+
const COMMIT_WORKER_WIDGET_KEY = 'noice-changelog-commit-worker'
|
|
34
34
|
|
|
35
35
|
type CommitDisplayStatus = 'ok' | 'cancelled' | 'failed'
|
|
36
36
|
|
|
@@ -41,6 +41,7 @@ interface CommitResultDetails {
|
|
|
41
41
|
status?: CommitDisplayStatus
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
let commitCommandPending = false
|
|
44
45
|
let commitWorkerRunning = false
|
|
45
46
|
let agentEndWaiter: ((messages: unknown[]) => void) | undefined
|
|
46
47
|
let latestCommitWorkerMessages: unknown[] | undefined
|
|
@@ -154,26 +155,40 @@ export default function noiceChangelogExtension(pi: ExtensionAPI) {
|
|
|
154
155
|
'Commit changes and create/update PR. Usage: /commit <changeType> <what was done>',
|
|
155
156
|
getArgumentCompletions: getCommitArgumentCompletions,
|
|
156
157
|
handler: async (args, ctx) => {
|
|
157
|
-
if (commitWorkerRunning) {
|
|
158
|
-
ctx.ui.notify('Commit
|
|
158
|
+
if (commitCommandPending || commitWorkerRunning) {
|
|
159
|
+
ctx.ui.notify('Commit command is already active', 'warning')
|
|
159
160
|
return
|
|
160
161
|
}
|
|
161
162
|
|
|
162
|
-
|
|
163
|
+
commitCommandPending = true
|
|
164
|
+
let prepared: Awaited<ReturnType<typeof prepareCommit>>
|
|
165
|
+
try {
|
|
166
|
+
prepared = await prepareCommit(args, ctx)
|
|
167
|
+
} catch (error) {
|
|
168
|
+
commitCommandPending = false
|
|
169
|
+
throw error
|
|
170
|
+
}
|
|
163
171
|
|
|
164
|
-
|
|
165
|
-
|
|
172
|
+
if (!prepared) {
|
|
173
|
+
commitCommandPending = false
|
|
166
174
|
return
|
|
167
175
|
}
|
|
168
176
|
|
|
177
|
+
const { parsed, prompt } = prepared
|
|
169
178
|
const startLeafId = ctx.sessionManager.getLeafId()
|
|
170
|
-
const
|
|
179
|
+
const previousThinkingLevel = pi.getThinkingLevel()
|
|
171
180
|
|
|
181
|
+
// Establish the running guard before releasing the pending guard. Keeping
|
|
182
|
+
// this transition synchronous prevents a re-entrant command from starting
|
|
183
|
+
// a second worker and overwriting the singleton agent-end waiter.
|
|
172
184
|
commitWorkerRunning = true
|
|
173
|
-
|
|
174
|
-
ctx.ui.notify(`Starting commit worker (${parsed.changeType})`, 'info')
|
|
185
|
+
commitCommandPending = false
|
|
175
186
|
|
|
176
187
|
try {
|
|
188
|
+
showCommitWorkerBanner(ctx)
|
|
189
|
+
ctx.ui.notify(`Starting commit worker (${parsed.changeType})`, 'info')
|
|
190
|
+
pi.setThinkingLevel('low')
|
|
191
|
+
|
|
177
192
|
const agentEnd = waitForNextAgentEndAfterIdle(ctx)
|
|
178
193
|
latestCommitWorkerMessages = undefined
|
|
179
194
|
pi.sendMessage(
|
|
@@ -302,7 +317,8 @@ export default function noiceChangelogExtension(pi: ExtensionAPI) {
|
|
|
302
317
|
})
|
|
303
318
|
ctx.ui.notify(`Commit worker failed:\n${message}`, 'error')
|
|
304
319
|
} finally {
|
|
305
|
-
|
|
320
|
+
pi.setThinkingLevel(previousThinkingLevel)
|
|
321
|
+
ctx.ui.setWidget(COMMIT_WORKER_WIDGET_KEY, undefined)
|
|
306
322
|
commitWorkerRunning = false
|
|
307
323
|
latestCommitWorkerMessages = undefined
|
|
308
324
|
}
|
|
@@ -310,6 +326,20 @@ export default function noiceChangelogExtension(pi: ExtensionAPI) {
|
|
|
310
326
|
})
|
|
311
327
|
}
|
|
312
328
|
|
|
329
|
+
function showCommitWorkerBanner(ctx: ExtensionCommandContext) {
|
|
330
|
+
const message = 'Commit worker running on a side branch of this session…'
|
|
331
|
+
|
|
332
|
+
if (ctx.mode !== 'tui') {
|
|
333
|
+
ctx.ui.setWidget(COMMIT_WORKER_WIDGET_KEY, [message])
|
|
334
|
+
return
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
ctx.ui.setWidget(
|
|
338
|
+
COMMIT_WORKER_WIDGET_KEY,
|
|
339
|
+
(_tui, theme) => new Text(theme.fg('warning', message), 1, 0)
|
|
340
|
+
)
|
|
341
|
+
}
|
|
342
|
+
|
|
313
343
|
function getCommitArgumentCompletions(prefix: string) {
|
|
314
344
|
const trimmedStart = prefix.trimStart()
|
|
315
345
|
const leadingWhitespace = prefix.slice(0, prefix.length - trimmedStart.length)
|
|
@@ -341,6 +371,29 @@ function getCommitArgumentCompletions(prefix: string) {
|
|
|
341
371
|
]
|
|
342
372
|
}
|
|
343
373
|
|
|
374
|
+
async function prepareCommit(
|
|
375
|
+
args: string | undefined,
|
|
376
|
+
ctx: ExtensionCommandContext
|
|
377
|
+
) {
|
|
378
|
+
const parsed = await resolveChangeTypeAndContext(args, ctx)
|
|
379
|
+
if (!parsed) return null
|
|
380
|
+
|
|
381
|
+
if (!ctx.isIdle()) {
|
|
382
|
+
ctx.ui.notify(
|
|
383
|
+
'Commit queued; waiting for the current agent turn to finish',
|
|
384
|
+
'info'
|
|
385
|
+
)
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
await ctx.waitForIdle()
|
|
389
|
+
const prompt = await buildWorkerPrompt(parsed.changeType, parsed.context)
|
|
390
|
+
// Prompt loading is asynchronous. Re-check idle so another user turn cannot
|
|
391
|
+
// slip in between the original wait and worker startup.
|
|
392
|
+
await ctx.waitForIdle()
|
|
393
|
+
|
|
394
|
+
return { parsed, prompt }
|
|
395
|
+
}
|
|
396
|
+
|
|
344
397
|
async function resolveChangeTypeAndContext(
|
|
345
398
|
args: string | undefined,
|
|
346
399
|
ctx: ExtensionCommandContext
|
|
@@ -6,42 +6,74 @@ Changelogs should show that products are moving without turning every release in
|
|
|
6
6
|
|
|
7
7
|
GitHub Releases are internal shipping records. Public changelog/social text is derived from PR changelog summaries and must stand alone because repositories may be private.
|
|
8
8
|
|
|
9
|
-
## PR title
|
|
9
|
+
## PR title format
|
|
10
10
|
|
|
11
|
-
Every PR title should start with exactly one
|
|
11
|
+
Every PR title should start with exactly one change type. The title format depends on the repository's package layout:
|
|
12
12
|
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
- `improve:` user-facing refinement, UX, performance, or reliability improvement
|
|
16
|
-
- `internal:` infra, CI, tooling, refactor, tests, dependencies, logging, or other non-user-facing work
|
|
13
|
+
- Single-package repository or workspace: `type: description`
|
|
14
|
+
- Multi-package workspace: `type(package): description`
|
|
17
15
|
|
|
18
|
-
|
|
16
|
+
The supported change types are:
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
- `feat` — new user-facing capability
|
|
19
|
+
- `fix` — user-facing bug fix
|
|
20
|
+
- `improve` — user-facing refinement, UX, performance, or reliability improvement
|
|
21
|
+
- `internal` — infra, CI, tooling, refactor, tests, dependencies, logging, or other non-user-facing work
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
- `fix:` means a user-visible bug or broken behavior was corrected.
|
|
24
|
-
- `improve:` means an existing user-facing workflow became clearer, faster, smoother, more reliable, or easier to use.
|
|
25
|
-
- `internal:` means the work may matter to development/release/reliability but is not a public product change.
|
|
23
|
+
These types express release intent. They are not Conventional Commits.
|
|
26
24
|
|
|
27
|
-
|
|
25
|
+
## Package scope rules
|
|
28
26
|
|
|
29
|
-
|
|
27
|
+
- First inspect the repository's workspace configuration and package roots. Count distinct package roots declared by the workspace configuration or its ecosystem equivalent. If there is no formal workspace configuration, count independently built or published package roots identified by the repository's manifests.
|
|
28
|
+
- A private root manifest used only to coordinate workspace tooling does not count as a package. A root that is itself an independently built or published package does count.
|
|
29
|
+
- If the repository contains zero or one package root, omit the scope. If it contains two or more, treat it as a multi-package workspace.
|
|
30
|
+
- In a multi-package workspace, use the primary package's workspace directory basename as the scope. For example, work primarily in `packages/renderer` uses `renderer` even if its manifest name is `@example/pi-renderer`.
|
|
31
|
+
- Determine the primary package from the PR's intent and the full branch diff against the detected PR base. Resolve the title from the resulting branch after the current change is committed, not from only the previous branch state, current worktree, or latest commit.
|
|
32
|
+
- Incidental shared-file changes, such as a root lockfile updated alongside one package, do not override a clear primary package.
|
|
33
|
+
- When multi-package work is root-only, cross-cutting, or has no clear primary package, use `monorepo`.
|
|
34
|
+
- Use exactly one scope. Do not list several package names.
|
|
30
35
|
|
|
31
|
-
|
|
36
|
+
Examples:
|
|
32
37
|
|
|
33
|
-
|
|
38
|
+
- Single-package repository: `feat: add branded end cards for free exports`
|
|
39
|
+
- Primary package: `fix(renderer): prevent hidden tracks from rendering`
|
|
40
|
+
- Cross-cutting multi-package work: `internal(monorepo): centralize release deployment workflow`
|
|
41
|
+
|
|
42
|
+
## Commit message format
|
|
43
|
+
|
|
44
|
+
Commit messages always remain unscoped, regardless of repository layout:
|
|
34
45
|
|
|
35
46
|
- `feat: add branded end cards for free exports`
|
|
36
47
|
- `fix: prevent hidden tracks from rendering`
|
|
37
|
-
- `improve: speed up waveform rendering for long projects`
|
|
38
48
|
- `internal: centralize release deployment workflow`
|
|
39
49
|
|
|
50
|
+
Do not add package scopes to commit messages and do not rewrite existing commits merely to match a PR title.
|
|
51
|
+
|
|
52
|
+
## Change type rules
|
|
53
|
+
|
|
54
|
+
- `feat` means users can do something new.
|
|
55
|
+
- `fix` means a user-visible bug or broken behavior was corrected.
|
|
56
|
+
- `improve` means an existing user-facing workflow became clearer, faster, smoother, more reliable, or easier to use.
|
|
57
|
+
- `internal` means the work may matter to development/release/reliability but is not a public product change.
|
|
58
|
+
|
|
59
|
+
Do not use `fix` for technical-only fixes. Use `internal` for TypeScript fixes, build fixes, CI fixes, test fixes, dependency fixes, refactor corrections, and internal error handling unless the corrected behavior is directly user-visible.
|
|
60
|
+
|
|
61
|
+
## PR titles vs public summaries
|
|
62
|
+
|
|
63
|
+
PR titles are classification, package, and review metadata. They are not the public changelog source.
|
|
64
|
+
|
|
65
|
+
Good PR titles are concrete:
|
|
66
|
+
|
|
67
|
+
- `feat: add branded end cards for free exports`
|
|
68
|
+
- `fix(renderer): prevent hidden tracks from rendering`
|
|
69
|
+
- `improve(editor): speed up waveform rendering for long projects`
|
|
70
|
+
- `internal(monorepo): centralize release deployment workflow`
|
|
71
|
+
|
|
40
72
|
Avoid vague value-prop titles:
|
|
41
73
|
|
|
42
74
|
- `feat: help users create better results`
|
|
43
|
-
- `improve: improve editor experience`
|
|
44
|
-
- `fix: make rendering better`
|
|
75
|
+
- `improve(editor): improve editor experience`
|
|
76
|
+
- `fix(renderer): make rendering better`
|
|
45
77
|
|
|
46
78
|
## PR changelog section
|
|
47
79
|
|
|
@@ -59,9 +91,9 @@ Context:
|
|
|
59
91
|
- ...
|
|
60
92
|
```
|
|
61
93
|
|
|
62
|
-
For `feat
|
|
94
|
+
For `feat`, `fix`, and `improve`, `Public summary` should contain one specific standalone user-facing sentence. Write it as if it may become one bullet in a public release post.
|
|
63
95
|
|
|
64
|
-
For `internal
|
|
96
|
+
For `internal`, write exactly:
|
|
65
97
|
|
|
66
98
|
```md
|
|
67
99
|
Public summary:
|
|
@@ -83,6 +115,8 @@ Release changelog generation should use sources in this order:
|
|
|
83
115
|
|
|
84
116
|
If `Public summary` is `None`, skip that PR for public changelog output unless there is clear user-visible impact elsewhere in the release notes.
|
|
85
117
|
|
|
118
|
+
Package scopes in PR titles are metadata only. Do not copy them into public changelog text; use the canonical public summary instead.
|
|
119
|
+
|
|
86
120
|
## Public changelog output rules
|
|
87
121
|
|
|
88
122
|
Public changelog/social text:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
You are the changelog commit worker.
|
|
2
2
|
|
|
3
|
-
You are running in a temporary branch of the user's active Pi session. Use the provided change type and short user description as the primary source for commit
|
|
3
|
+
You are running in a temporary branch of the user's active Pi session. Use the provided change type and short user description as the primary source for the current commit wording and for PR changelog text about the current change. Use the current diff only to verify that description and catch important omissions; do not try to rediscover or guess the current change from the diff when a description is provided. Resolve the PR title separately from the cumulative full branch as described below.
|
|
4
4
|
|
|
5
5
|
Task:
|
|
6
6
|
Commit current changes and create or update the GitHub PR.
|
|
@@ -20,29 +20,35 @@ Before choosing commit messages, PR title, or PR changelog text, read and follow
|
|
|
20
20
|
|
|
21
21
|
Workflow:
|
|
22
22
|
|
|
23
|
-
1. Inspect git status, current branch,
|
|
23
|
+
1. Inspect git status, current branch, staged and unstaged changes, branch commits, candidate base branch, existing PR, and repository workspace/package layout.
|
|
24
24
|
2. If a PR exists, read its current title, base branch, and full body before deciding what to change.
|
|
25
|
-
3.
|
|
26
|
-
4. If
|
|
27
|
-
5.
|
|
28
|
-
6.
|
|
29
|
-
7.
|
|
30
|
-
8. If PR exists
|
|
31
|
-
9.
|
|
32
|
-
10. When
|
|
25
|
+
3. Determine whether there are changes to commit or useful PR metadata updates to make. If there are neither, report no-op.
|
|
26
|
+
4. If there are changes to commit and the current branch is main, create a branch.
|
|
27
|
+
5. If there are changes to commit, commit them with a good unscoped prefixed commit message.
|
|
28
|
+
6. Resolve the PR title format and, for a multi-package workspace, its one primary package from the PR's cumulative intent and the resulting full branch diff against the detected or preserved PR base. Resolve this after committing the current changes so the diff includes them; do not use only the latest commit.
|
|
29
|
+
7. Push the branch if needed.
|
|
30
|
+
8. If no PR exists for the branch, create one against the detected base branch.
|
|
31
|
+
9. If a PR exists, update its title/body to reflect the full branch while preserving useful existing PR description content and its existing base branch.
|
|
32
|
+
10. When creating a PR body, always write the final markdown body to a file in a temporary directory and pass it to GitHub CLI with `--body-file`; do not pass markdown through `--body`.
|
|
33
|
+
11. When updating an existing PR, avoid `gh pr edit`; it can fail on some repositories because GitHub CLI queries deprecated Projects Classic GraphQL fields. Use the REST API fallback described below instead.
|
|
33
34
|
|
|
34
35
|
Rules:
|
|
35
36
|
|
|
36
|
-
- Use the selected change type as user intent, unless it clearly contradicts the provided description and diff.
|
|
37
|
-
- If selected type is `auto`, infer the type from the provided description first, then session context and diff, using the changelog rules.
|
|
38
|
-
- Treat `whatWasDoneShort` as the user's rough wording. Convert awkward, terse, or informal language into clear
|
|
39
|
-
- Prefer the user's description over diff-derived wording. Use the diff to verify accuracy and specificity, not to invent a different story.
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
- PR title
|
|
45
|
-
-
|
|
37
|
+
- Use the selected change type as user intent for the current commit, unless it clearly contradicts the provided description and diff.
|
|
38
|
+
- If selected type is `auto`, infer the current commit's type from the provided description first, then session context and diff, using the changelog rules.
|
|
39
|
+
- Treat `whatWasDoneShort` as the user's rough wording for the current change. Convert awkward, terse, or informal language into a clear commit message and changelog wording according to the changelog rules.
|
|
40
|
+
- Prefer the user's description over diff-derived wording for the current commit. Use the current diff to verify accuracy and specificity, not to invent a different story.
|
|
41
|
+
- The PR title must describe the cumulative full branch. Use the user's description for it only when that description represents the full branch; otherwise use the existing PR title/body, branch commits, session context, and full branch diff to preserve the established branch intent. Do not let the latest delta replace a broader PR purpose.
|
|
42
|
+
- If the user's description is missing or too vague for the current change, use session context and the current diff as fallback.
|
|
43
|
+
- `fix` is only for user-visible bug fixes. Technical-only fixes must use `internal`.
|
|
44
|
+
- Commit messages always use the unscoped `type: description` format, including in multi-package workspaces. Do not add a package scope to a commit message or rewrite existing commits to match the PR title.
|
|
45
|
+
- Derive the PR title from the cumulative full-branch sources described above, not by defaulting to the latest current-change description.
|
|
46
|
+
- In a single-package repository or workspace, the PR title uses `type: description`.
|
|
47
|
+
- In a multi-package workspace, the PR title uses `type(package): description`, where `package` is the primary package's workspace directory basename.
|
|
48
|
+
- For root-only or cross-cutting work in a multi-package workspace, or when no one package is clearly primary, use `type(monorepo): description`.
|
|
49
|
+
- Incidental shared files such as a root lockfile do not override a clear primary package. Use exactly one package scope rather than listing every affected package.
|
|
50
|
+
- When updating an existing PR, preserve its package scope only if it still matches the repository layout and full branch; otherwise correct the title.
|
|
51
|
+
- PR title type and package scope are classification/review metadata, not the public changelog summary.
|
|
46
52
|
- PR body `## Changelog` → `Public summary` is the canonical source for future public changelog generation.
|
|
47
53
|
- Do not use vague value-prop titles.
|
|
48
54
|
- Do not modify source files unless absolutely required to complete commit/PR metadata.
|
|
@@ -76,7 +82,7 @@ PR body handling:
|
|
|
76
82
|
```sh
|
|
77
83
|
repo=$(gh repo view --json nameWithOwner --jq .nameWithOwner)
|
|
78
84
|
pr_number=$(gh pr view --json number --jq .number)
|
|
79
|
-
title=
|
|
85
|
+
title="$resolved_pr_title"
|
|
80
86
|
title_json=$(jq -Rn --arg value "$title" '$value')
|
|
81
87
|
body_json=$(jq -Rs . < "$body_file")
|
|
82
88
|
gh api "repos/$repo/pulls/$pr_number" \
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noice-tech/pi-changelog",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Pi changelog workflow for commits, pull requests, and public release notes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -48,6 +48,6 @@
|
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"typecheck": "tsc --noEmit --allowImportingTsExtensions --moduleResolution bundler --module ESNext --target ES2022 --skipLibCheck extensions/changelog/index.ts",
|
|
51
|
-
"test": "node ../../scripts/smoke-pack.mjs @noice-tech/pi-changelog packages/changelog"
|
|
51
|
+
"test": "node --test test/*.test.mjs && node ../../scripts/smoke-pack.mjs @noice-tech/pi-changelog packages/changelog"
|
|
52
52
|
}
|
|
53
53
|
}
|
package/prompts/release-notes.md
CHANGED
|
@@ -25,13 +25,14 @@ If `.pi/release-notes-style.md` exists, read it before writing public copy. It i
|
|
|
25
25
|
|
|
26
26
|
## Shared changelog rules
|
|
27
27
|
|
|
28
|
-
PR
|
|
29
|
-
|
|
30
|
-
- `feat
|
|
31
|
-
- `fix
|
|
32
|
-
- `improve
|
|
33
|
-
- `internal
|
|
34
|
-
- Technical-only TypeScript, build, CI, test, dependency, refactor, and internal error-handling fixes are `internal
|
|
28
|
+
Valid PR titles use either unscoped `type: description` or package-scoped `type(package): description` form. The change types are `feat`, `fix`, `improve`, and `internal`.
|
|
29
|
+
|
|
30
|
+
- `feat` means users can do something new.
|
|
31
|
+
- `fix` means a user-visible bug or broken behavior was corrected.
|
|
32
|
+
- `improve` means an existing user-facing workflow became clearer, faster, smoother, more reliable, or easier to use.
|
|
33
|
+
- `internal` means the work may matter to development, release, or reliability but is not a public product change.
|
|
34
|
+
- Technical-only TypeScript, build, CI, test, dependency, refactor, and internal error-handling fixes are `internal` unless corrected behavior is directly user-visible.
|
|
35
|
+
- A package scope, including `monorepo`, is metadata. It does not change the change type and must not be copied into public changelog text.
|
|
35
36
|
- PR titles classify work; they are not the public changelog source.
|
|
36
37
|
- PR body `## Changelog` → `Public summary` is the canonical public changelog atom.
|
|
37
38
|
|
|
@@ -45,7 +46,7 @@ Use sources in this order:
|
|
|
45
46
|
4. PR title, only for classification or fallback
|
|
46
47
|
5. Commit messages, only as a last fallback
|
|
47
48
|
|
|
48
|
-
Include meaningful `feat
|
|
49
|
+
Include meaningful `feat`, `fix`, and `improve` changes, whether scoped or unscoped, whose public summary is not `None`. Skip `internal` changes and summaries of `None`. Be conservative with fixes.
|
|
49
50
|
|
|
50
51
|
## Public copy
|
|
51
52
|
|
package/prompts/unreleased.md
CHANGED
|
@@ -12,12 +12,14 @@ Ignore arguments if provided. This command previews the current unreleased state
|
|
|
12
12
|
|
|
13
13
|
Follow these shared changelog rules exactly:
|
|
14
14
|
|
|
15
|
-
- PR
|
|
16
|
-
- `feat
|
|
17
|
-
- `
|
|
18
|
-
- `
|
|
19
|
-
- `
|
|
20
|
-
-
|
|
15
|
+
- Valid PR titles use either unscoped `type: description` or package-scoped `type(package): description` form.
|
|
16
|
+
- The change types are `feat`, `fix`, `improve`, and `internal`.
|
|
17
|
+
- `feat` means users can do something new.
|
|
18
|
+
- `fix` means a user-visible bug or broken behavior was corrected.
|
|
19
|
+
- `improve` means an existing user-facing workflow became clearer, faster, smoother, more reliable, or easier to use.
|
|
20
|
+
- `internal` means the work may matter to development/release/reliability but is not a public product change.
|
|
21
|
+
- Do not use technical-only fixes as public fixes. TypeScript, build, CI, test, dependency, refactor, and internal error-handling fixes are `internal` unless the corrected behavior is directly user-visible.
|
|
22
|
+
- A package scope, including `monorepo`, is metadata. It does not change the change type and must not be copied into public changelog text.
|
|
21
23
|
- PR titles are classification/review metadata. They are not the public changelog source.
|
|
22
24
|
- PR body `## Changelog` → `Public summary` is the canonical public changelog atom.
|
|
23
25
|
|
|
@@ -41,10 +43,10 @@ Workflow:
|
|
|
41
43
|
|
|
42
44
|
Public candidate rules:
|
|
43
45
|
|
|
44
|
-
- Include `feat
|
|
45
|
-
- Skip `internal
|
|
46
|
+
- Include `feat`, `fix`, and `improve` PRs, whether scoped or unscoped, when `Public summary` contains a meaningful user-facing summary.
|
|
47
|
+
- Skip `internal` PRs by default, whether scoped or unscoped.
|
|
46
48
|
- Skip PRs where `Public summary` is `None`.
|
|
47
|
-
- Be conservative with `fix
|
|
49
|
+
- Be conservative with `fix`. Include only user-visible fixes, not technical/build/CI/test/refactor/dependency fixes.
|
|
48
50
|
- Use `Public summary` text as the candidate release bullet when available.
|
|
49
51
|
- If the PR appears user-facing but lacks a usable public summary, put it under `Needs cleanup`, not `Public candidates`.
|
|
50
52
|
|
|
@@ -55,8 +57,8 @@ Flag PRs that may affect release quality, especially:
|
|
|
55
57
|
- missing `## Changelog` section
|
|
56
58
|
- missing `Public summary`
|
|
57
59
|
- vague public summary such as “Improved experience” or “Bug fixes”
|
|
58
|
-
- `feat
|
|
59
|
-
- title
|
|
60
|
+
- `feat`, `fix`, or `improve` PR, whether scoped or unscoped, with `Public summary: None`
|
|
61
|
+
- title change type appears inconsistent with the changelog body
|
|
60
62
|
- possible user-facing change only discoverable from title/commits, not from `Public summary`
|
|
61
63
|
|
|
62
64
|
Output format:
|