copilot-session-usage 0.6.0__tar.gz → 0.6.4__tar.gz
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.
- copilot_session_usage-0.6.4/.github/skills/gh-release-notes/SKILL.md +325 -0
- copilot_session_usage-0.6.4/.github/workflows/refresh-pricing.yml +72 -0
- copilot_session_usage-0.6.4/.github/workflows/release-notes.yml +134 -0
- copilot_session_usage-0.6.4/.github/workflows/release.yml +208 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/AGENTS.md +10 -0
- copilot_session_usage-0.6.4/CONTRIBUTING.md +66 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/PKG-INFO +1 -1
- copilot_session_usage-0.6.4/docs/internal/automated_release_proces.md +504 -0
- copilot_session_usage-0.6.4/knowledge/findings/2026.07.13-14.27-release-notes-overreported-maintainer-changes.md +34 -0
- copilot_session_usage-0.6.4/knowledge/findings/2026.07.24-15.01-actions-token-cannot-create-pr.md +31 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/findings/index.md +2 -0
- copilot_session_usage-0.6.4/scripts/validate_release_notes.py +101 -0
- copilot_session_usage-0.6.4/src/copilot_session_usage/data/models-and-pricing.lock +7 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/src/copilot_session_usage/data/models-and-pricing.yml +19 -0
- copilot_session_usage-0.6.4/tests/test_release_notes.py +94 -0
- copilot_session_usage-0.6.0/.github/skills/gh-release-notes/SKILL.md +0 -255
- copilot_session_usage-0.6.0/CONTRIBUTING.md +0 -49
- copilot_session_usage-0.6.0/src/copilot_session_usage/data/models-and-pricing.lock +0 -7
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/.editorconfig +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/.gitattributes +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/.github/changes/requests/skill-breakdown/01-request.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/.github/guidelines/git-commit-message.guideline.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/.github/guidelines/knowledge-base.guidelines.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/.github/pull_request_template.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/.github/skills/consolidate-knowledge-base/SKILL.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/.github/skills/record-finding/SKILL.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/.github/workflows/ci.yml +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/.github/workflows/publish.yml +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/.gitignore +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/.readthedocs.yaml +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/CHANGELOG.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/LICENSE +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/README.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/_static/changelog.js +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/_static/custom.css +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/changelog.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/conf.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/explanation/how-cost-estimation-works.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/explanation/index.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/how-to/add-commit-trailer.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/how-to/analyze-specific-session.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/how-to/batch-and-spending.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/how-to/export-json.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/how-to/index.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/how-to/wsl2.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/index.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/installation.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/reference/api.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/reference/cli.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/reference/index.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/reference/pricing.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/tutorials/getting-started.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/docs/source/tutorials/index.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/justfile +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/_schema/Base.schema.yaml +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/_schema/Concept.schema.yaml +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/_schema/Experiment.schema.yaml +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/_schema/Finding.schema.yaml +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/_schema/Hypothesis.schema.yaml +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/_schema/Outcome.schema.yaml +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/_schema/Playbook.schema.yaml +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/_schema/Principle.schema.yaml +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/_schema/Reference.schema.yaml +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/_schema/Structure.schema.yaml +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/concepts/copilot-cli.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/concepts/index.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/concepts/overview.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/concepts/session-cost-analysis.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/concepts/threshold-based-pricing.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/experiments/index.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/experiments/verify-subagent-cost-attribution.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/findings/2026.07.02-00.00-subagent-logs-runsubagent-prefix.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/findings/2026.07.02-22.00-title-generation-not-counted-as-model-turn.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/findings/2026.07.02-23.00-cache-write-approximation.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/guides/automation-scripts.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/guides/cost-optimization.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/guides/index.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/guides/wsl2-setup.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/ideas/index.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/ideas/multi-session-efficiency-analytics.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/index.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/log.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/principles/findings-are-immutable.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/principles/index.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/reference/debug-log-format.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/reference/index.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/reference/pricing-formats.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/structures/cache-cost-approximation.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/structures/index.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/structures/knowledge-base-information-types.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/structures/session-discovery-algorithm.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/structures/subagent-cost-tracking.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/knowledge/structures/vscode-copilot-extension.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/pyproject.toml +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/scripts/refresh_pricing.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/skills/copilot-session-usage/SKILL.md +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/src/copilot_session_usage/__init__.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/src/copilot_session_usage/_internal/__init__.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/src/copilot_session_usage/_internal/copilot_cli.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/src/copilot_session_usage/_internal/core.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/src/copilot_session_usage/_internal/git.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/src/copilot_session_usage/_internal/vscode.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/src/copilot_session_usage/api.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/src/copilot_session_usage/cli.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/src/copilot_session_usage/data/__init__.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/src/copilot_session_usage/data/custom-models-pricing.yml +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/tests/conftest.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/tests/test_api.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/tests/test_cli.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/tests/test_core.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/tests/test_coverage_gaps.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/tests/test_git.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/tests/test_rendering.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/tests/test_vscode.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/tests/test_vscode_platform.py +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/uv.lock +0 -0
- {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.4}/uv.toml +0 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gh-release-notes
|
|
3
|
+
description: Generate end-user-friendly GitHub release notes from the actual diff between releases, including user impact, examples, breaking changes, and public documentation links.
|
|
4
|
+
argument-hint: "from_tag=... to_tag=... repo_path=..."
|
|
5
|
+
user-invocable: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Release Notes Generator (Git Diff Based)
|
|
9
|
+
|
|
10
|
+
Generate **end-user-friendly, user-impact-only** release notes by analyzing the actual changes between releases.
|
|
11
|
+
No scripts required — use git commands to understand what changed and why it matters to someone using the product.
|
|
12
|
+
|
|
13
|
+
The output is meant to be **copy-pasted into a GitHub Release**. It must contain release-note sections only: never add a document title, preamble, file summary, commit summary, or closing separator.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
Provide your repository and range:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
Generate release notes from v1.0.0 to v1.1.0 in /path/to/repo
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or reference the last release:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
What changed since the last release tag?
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## What It Does
|
|
34
|
+
|
|
35
|
+
1. **Reads actual diffs** — examines code changes, not just commit messages
|
|
36
|
+
3. **Applies a user-impact gate** — includes a change only when a user-visible behavior, supported interface, user workflow, output, compatibility guarantee, or public documentation experience changed
|
|
37
|
+
4. **Interprets for end-users** — no technical jargon, functions, variable names, file paths, or implementation summaries
|
|
38
|
+
5. **Categorizes intelligently** — Features, Enhancements, Bug Fixes, Breaking Changes, or a no-product-impact classification
|
|
39
|
+
6. **Adds concrete examples** — shows what users see or can do after a qualifying change
|
|
40
|
+
7. **Links to public docs** — points to published documentation, not repo paths
|
|
41
|
+
8. **Consolidates related changes** — groups related diffs and eliminates back-and-forth noise
|
|
42
|
+
9. **Outputs clean markdown** — ready to paste into a GitHub Release note
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Input
|
|
47
|
+
|
|
48
|
+
Accept either:
|
|
49
|
+
|
|
50
|
+
- **Natural language**: "Show release notes from v1.2.0 to v1.3.0"
|
|
51
|
+
- **Range spec**: `from_tag=v1.2.0 to_tag=v1.3.0 repo_path=/path/to/repo`
|
|
52
|
+
- **Last release**: `since_tag=v1.2.0` (everything from tag to HEAD)
|
|
53
|
+
|
|
54
|
+
Required:
|
|
55
|
+
- Repository path (optional: defaults to current directory)
|
|
56
|
+
- Range: `from_tag` + `to_tag`, OR `since_tag`, OR `last_n_commits`
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Analysis Process
|
|
61
|
+
|
|
62
|
+
### Step 0: Apply the release-worthiness gate
|
|
63
|
+
|
|
64
|
+
Before writing any bullet, ask: **What can a user do, observe, configure, rely on, or learn differently after this change?** Require evidence from the diff, public CLI/API help, supported configuration, user-facing output, migration behavior, or published documentation.
|
|
65
|
+
|
|
66
|
+
Include a change only if it has at least one of these effects:
|
|
67
|
+
|
|
68
|
+
- Adds, removes, fixes, or changes a user-facing feature, command, API, configuration option, output, error message, compatibility guarantee, or supported platform.
|
|
69
|
+
- Changes runtime behavior in a way users can observe, such as performance, reliability, pricing data, security behavior, or data handling.
|
|
70
|
+
- Changes public documentation that users actually consume to operate the product, including a new guide, changed instructions, or migration guidance.
|
|
71
|
+
|
|
72
|
+
Do **not** infer user impact from a commit type, changed filename, test coverage, or the fact that a change is large. If the evidence does not show a user consequence, exclude it.
|
|
73
|
+
|
|
74
|
+
### Step 1: Collect Commits
|
|
75
|
+
```bash
|
|
76
|
+
git log v1.0.0..v1.1.0 --oneline --no-merges
|
|
77
|
+
```
|
|
78
|
+
Gather all commits in the specified range with their messages.
|
|
79
|
+
|
|
80
|
+
### Step 2: Examine relevant diffs
|
|
81
|
+
```bash
|
|
82
|
+
git diff v1.0.0..v1.1.0 -- . ':(exclude).github' ':(exclude)skills' ':(exclude)guidelines'
|
|
83
|
+
```
|
|
84
|
+
Read actual code changes line-by-line to understand behavior. Inspect excluded paths only when needed to verify whether they caused a direct user-visible consequence; never report the paths themselves.
|
|
85
|
+
|
|
86
|
+
Treat these as non-release content by default:
|
|
87
|
+
|
|
88
|
+
- CI/CD workflows, automation, release jobs, repository settings, and bot configuration
|
|
89
|
+
- Internal skills, agent prompts, contributor guidelines, engineering process, and maintainer runbooks
|
|
90
|
+
- Tests, fixtures, formatting, linting, refactors, type annotations, and code organization
|
|
91
|
+
- Dependency, lockfile, build, packaging, or development-environment changes without a user-visible runtime consequence
|
|
92
|
+
- File counts, changed-file lists, commit counts, authors, implementation details, and internal URLs
|
|
93
|
+
|
|
94
|
+
These exclusions can be overridden only when the diff proves a direct user impact, such as a packaging change that changes the installable artifact or a security fix that changes behavior for users.
|
|
95
|
+
|
|
96
|
+
### Step 3: Interpret qualifying changes
|
|
97
|
+
|
|
98
|
+
Translate technical changes into user impact:
|
|
99
|
+
|
|
100
|
+
| Code Change | User Impact |
|
|
101
|
+
|-------------|------------|
|
|
102
|
+
| `+ const darkMode = true` in settings | "Dark mode toggle now available in settings" |
|
|
103
|
+
| Deleted login retry logic | "Removed automatic retry on login timeout" |
|
|
104
|
+
| `+ validateEmail()` function | "Email validation improved during signup" |
|
|
105
|
+
| Updated database schema version | "Database schema upgraded (run migration)" |
|
|
106
|
+
| Added 10+ calls to cache layer | "Improved performance on large operations" |
|
|
107
|
+
| Removed old CSV export code | "CSV export removed; use Excel or PDF instead" |
|
|
108
|
+
|
|
109
|
+
**Key: Focus on the user's experience, not the code implementation.**
|
|
110
|
+
|
|
111
|
+
Never turn a repository change into a release note merely by paraphrasing it. For example, “added CI workflow,” “updated contributor guidelines,” “improved project metadata,” and “7 files changed” are not release notes.
|
|
112
|
+
|
|
113
|
+
### Step 4: Identify Breaking Changes
|
|
114
|
+
|
|
115
|
+
Breaking changes come from:
|
|
116
|
+
- **Commit messages** containing: "BREAKING", "Breaking", "!:"
|
|
117
|
+
- **Diffs showing**: removed public APIs, changed file formats, data migrations
|
|
118
|
+
- **Config changes**: renamed settings, changed defaults
|
|
119
|
+
|
|
120
|
+
### Step 5: Consolidate
|
|
121
|
+
- If a feature was added then removed → don't mention it
|
|
122
|
+
- If something changed multiple times → only note the final state
|
|
123
|
+
- If multiple commits fix the same issue → merge into one bullet
|
|
124
|
+
|
|
125
|
+
### Step 6: Categorize & Format
|
|
126
|
+
|
|
127
|
+
Organize qualifying changes into buckets. **Only include sections that have content.** Omit empty sections entirely. Do not add a title heading.
|
|
128
|
+
|
|
129
|
+
If there are no qualifying product changes, use exactly one concise fallback block. Keep its structure consistent across releases while adapting the wording to the evidence:
|
|
130
|
+
|
|
131
|
+
- `**Maintenance**` for a maintenance release containing internal upkeep, CI, release automation, dependency/build work, refactors, or other operational changes
|
|
132
|
+
- `**Documentation**` for a documentation-update release whose meaningful outcome is public user documentation, even when no runtime behavior changed
|
|
133
|
+
- `**Internal**` for an internal release containing changes intentionally limited to maintainers, contributors, or internal tooling
|
|
134
|
+
|
|
135
|
+
Choose the most accurate fallback; do not list the underlying files or tasks. Follow the label with one short paragraph that says what was maintained or documented and whether core product functionality changed. Do not manufacture examples or links for either.
|
|
136
|
+
For a no-product-impact fallback, do not name CI, workflows, release automation,
|
|
137
|
+
internal guidelines, tests, commits, pull requests, or individual files. Keep the
|
|
138
|
+
paragraph generic and focused on the absence of user-facing behavior changes.
|
|
139
|
+
|
|
140
|
+
```markdown
|
|
141
|
+
## New Features
|
|
142
|
+
- Added dark mode toggle in settings
|
|
143
|
+
- New PDF export option
|
|
144
|
+
|
|
145
|
+
## Enhancements
|
|
146
|
+
- Improved search performance (now supports partial matches)
|
|
147
|
+
- Faster file opening for large documents
|
|
148
|
+
|
|
149
|
+
## Bug Fixes
|
|
150
|
+
- Fixed login failures on slow connections
|
|
151
|
+
- Resolved crash when uploading 10MB+ files
|
|
152
|
+
|
|
153
|
+
## Breaking Changes
|
|
154
|
+
- Database schema updated — run migration before upgrading
|
|
155
|
+
- CSV export removed; use Excel or PDF instead
|
|
156
|
+
|
|
157
|
+
## Examples
|
|
158
|
+
- Dark mode can be enabled in Settings → Appearance → Theme
|
|
159
|
+
- CSV export is no longer available; choose Excel or PDF from Export menu
|
|
160
|
+
|
|
161
|
+
## Documentation
|
|
162
|
+
- [Dark mode guide](https://docs.example.com/settings#dark-mode)
|
|
163
|
+
- [Migration notes](https://docs.example.com/upgrade#database)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Workflow for Agent
|
|
169
|
+
|
|
170
|
+
1. **Parse input** — extract `from_tag`, `to_tag`, `repo_path`, and optional filters
|
|
171
|
+
2. **Discover public docs URL** — inspect `README.md`, `pyproject.toml`, `mkdocs.yml`, `docs/conf.py`, or `.readthedocs.yml` for the published documentation URL. Prefer ReadTheDocs, GitHub Pages, or the project's public docs site. If none is found, omit doc links.
|
|
172
|
+
3. **Fetch commits** — run `git log` with range, collect hashes and messages
|
|
173
|
+
4. **Read diffs per file** — use `git show <hash>` for each relevant commit and examine changed behavior, not just filenames
|
|
174
|
+
5. **Apply the user-impact gate** — discard CI, internal, process, and implementation-only changes unless the diff proves direct user impact
|
|
175
|
+
6. **Interpret impact** — state what users can do, observe, configure, rely on, or learn differently
|
|
176
|
+
7. **Detect breaking changes** — scan for BREAKING markers, public API removals, format changes, migrations, and changed defaults
|
|
177
|
+
8. **Group by category** — assign each qualifying change to **New Features**, **Enhancements**, **Bug Fixes**, **Breaking Changes**, **Examples**, or **Documentation**
|
|
178
|
+
9. **Build examples** — for each user-facing change, use README, public docs, tests, or CLI help as evidence and add a short example only when it clarifies the user outcome
|
|
179
|
+
10. **Consolidate** — merge related items, remove duplicates and flip-flops
|
|
180
|
+
11. **Use a fallback** — if no product change qualifies, emit exactly one of **Maintenance**, **Documentation**, or **Internal**
|
|
181
|
+
12. **Format markdown** — generate clean section headings and bullets with no title, preamble, footer, file summary, or commit summary
|
|
182
|
+
13. **Use public docs links** — every Documentation bullet and every feature/enhancement docs reference must use the public URL with a fragment identifier, not a repo-relative path
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Output Format
|
|
187
|
+
|
|
188
|
+
**Clean markdown** for a GitHub Release body:
|
|
189
|
+
|
|
190
|
+
```markdown
|
|
191
|
+
## New Features
|
|
192
|
+
- Added dark mode toggle in settings
|
|
193
|
+
- New PDF export option
|
|
194
|
+
|
|
195
|
+
## Enhancements
|
|
196
|
+
- Improved search performance (supports partial matches)
|
|
197
|
+
- Faster file opening for large documents
|
|
198
|
+
|
|
199
|
+
## Bug Fixes
|
|
200
|
+
- Fixed login failures on slow connections
|
|
201
|
+
- Resolved crash when uploading 10MB+ files
|
|
202
|
+
|
|
203
|
+
## Breaking Changes
|
|
204
|
+
- Database schema updated — run migration before upgrading
|
|
205
|
+
|
|
206
|
+
## Examples
|
|
207
|
+
- Enable dark mode from Settings → Appearance → Theme
|
|
208
|
+
- Export a report as PDF from the File → Export menu
|
|
209
|
+
|
|
210
|
+
## Documentation
|
|
211
|
+
- [Dark mode guide](https://docs.example.com/settings#dark-mode)
|
|
212
|
+
- [Upgrade instructions](https://docs.example.com/upgrade#database)
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
For a release with no runtime product impact, use this consistent shape:
|
|
216
|
+
|
|
217
|
+
```markdown
|
|
218
|
+
**Maintenance**
|
|
219
|
+
|
|
220
|
+
This release primarily includes updates to the knowledge base documentation and internal repository structure. No changes to the core product functionality or user-facing features.
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**Key Rules:**
|
|
224
|
+
- One line per bullet point
|
|
225
|
+
- No sub-bullets or elaborate descriptions
|
|
226
|
+
- User impact only (not implementation details, changed-file summaries, CI, internal process, or contributor guidance)
|
|
227
|
+
- Do not include a title heading; the GitHub Release supplies the title
|
|
228
|
+
- Use public documentation URLs; never use repo-relative paths like `docs/...` or `README.md`
|
|
229
|
+
- Use fragment identifiers (`#section-name`) to point to specific docs sections
|
|
230
|
+
- Add an **Examples** section when the diff shows a CLI command, API call, config snippet, or before/after behavior
|
|
231
|
+
- Add a **Documentation** section only when public user documentation changed in a way users need or benefit from; never report internal guidelines or maintainer documentation
|
|
232
|
+
- Multiple links OK if they point to different topics
|
|
233
|
+
- Omit any section that has no bullets
|
|
234
|
+
- If no user-facing change qualifies, emit exactly one concise bold `Maintenance`, `Documentation`, or `Internal` block followed by one explanatory paragraph
|
|
235
|
+
- Never include file counts, changed-file lists, commit metadata, CI/workflow summaries, or a closing separator
|
|
236
|
+
- Do not add a "Notes", "Miscellaneous", or "Other" catch-all section
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Non-interactive automation mode
|
|
241
|
+
|
|
242
|
+
When this skill is invoked by a CI job with an explicit output-file request:
|
|
243
|
+
|
|
244
|
+
- Honor the requested tag range and repository path exactly.
|
|
245
|
+
- Treat the requested output file as mandatory. Writing it is the only successful completion condition.
|
|
246
|
+
- Use the `create` file tool when the requested file does not exist, or the `edit` file tool when it already exists.
|
|
247
|
+
- After writing, use the `read` file tool to verify that the requested file exists and contains the final release-note Markdown.
|
|
248
|
+
- Do not modify, commit, or push any other repository files.
|
|
249
|
+
- The output file must contain only the final release-note Markdown, without an explanation, title heading, or code fence.
|
|
250
|
+
- The first line must be exactly one of: `## New Features`, `## Enhancements`, `## Bug Fixes`, `## Breaking Changes`, `## Examples`, `## Documentation`, `**Maintenance**`, `**Documentation**`, or `**Internal**`.
|
|
251
|
+
- Do not write a preamble, title, code fence, or explanatory text before the first release-note section or fallback label.
|
|
252
|
+
- Never use the Copilot response stream as output. The caller may discard it after the file is written.
|
|
253
|
+
- Do not report the release notes only in the response. If the file cannot be written or verified, the task has failed.
|
|
254
|
+
- Preserve the user-impact categories, examples, breaking-change detection, and public documentation links described above.
|
|
255
|
+
|
|
256
|
+
## How to Use This Skill in a Session
|
|
257
|
+
|
|
258
|
+
**User Query:**
|
|
259
|
+
```
|
|
260
|
+
Generate release notes from v2.1.0 to v2.2.0 for /path/to/my-app
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
**Agent Workflow:**
|
|
264
|
+
1. Navigate to repo: `cd /path/to/my-app`
|
|
265
|
+
2. Fetch commits: `git log v2.1.0..v2.2.0 --oneline --no-merges`
|
|
266
|
+
3. For each commit, examine changes: `git show <hash>`
|
|
267
|
+
4. Interpret: What's the user impact? (not the code details)
|
|
268
|
+
5. Categorize: Feature? Bug fix? Breaking change?
|
|
269
|
+
6. Consolidate: Merge similar items
|
|
270
|
+
7. Format: Clean markdown with categories
|
|
271
|
+
8. Output: Save to the requested output file, such as `release-notes.md`
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Best Practices
|
|
276
|
+
|
|
277
|
+
✅ **Do:**
|
|
278
|
+
- Read actual diffs to understand changes
|
|
279
|
+
- Use end-user language ("improved performance" not "optimized O(n) loop")
|
|
280
|
+
- Require evidence of a user-visible consequence before including a change
|
|
281
|
+
- Include breaking changes prominently
|
|
282
|
+
- Group related changes
|
|
283
|
+
- Add concrete examples drawn from README, docs, tests, or CLI help in the diff
|
|
284
|
+
- Link to the project's public documentation site (ReadTheDocs, GitHub Pages, etc.)
|
|
285
|
+
- Omit empty sections
|
|
286
|
+
|
|
287
|
+
❌ **Don't:**
|
|
288
|
+
- Copy commit messages verbatim
|
|
289
|
+
- Include function/variable names
|
|
290
|
+
- Mention internal refactors users won't notice
|
|
291
|
+
- Include dependency bumps or build changes unless they are user-visible
|
|
292
|
+
- Include secrets, passwords, or internal URLs
|
|
293
|
+
- Use repo-relative paths like `docs/source/how-to/...` or `README.md`
|
|
294
|
+
- Report CI, workflows, internal skills, contributor guidelines, maintainer process, file counts, or changed-file lists as release content
|
|
295
|
+
- Add a title heading to the generated body
|
|
296
|
+
- Make up changes not shown in diffs
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Common Patterns
|
|
301
|
+
|
|
302
|
+
**Performance improvements:**
|
|
303
|
+
> "Improved search speed when filtering 1000+ records"
|
|
304
|
+
|
|
305
|
+
**New integrations:**
|
|
306
|
+
> "Added support for OAuth login via GitHub"
|
|
307
|
+
|
|
308
|
+
**Data format changes:**
|
|
309
|
+
> "Settings file now uses JSON instead of YAML (auto-converted on first run)"
|
|
310
|
+
|
|
311
|
+
**Removed features:**
|
|
312
|
+
> "Removed IE 11 support to modernize codebase"
|
|
313
|
+
|
|
314
|
+
**API changes:**
|
|
315
|
+
> "Changed user profile endpoint response format (see migration guide)"
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Limitations
|
|
320
|
+
|
|
321
|
+
- Requires a git repository with proper tags
|
|
322
|
+
- Complex changes may need human interpretation
|
|
323
|
+
- Very large diffs should be reduced to their evidenced user impact; never summarize them by file count
|
|
324
|
+
- Works best with semantic versioning (v1.0.0 format)
|
|
325
|
+
- Needs meaningful commit messages for best results, but commit messages alone are never evidence of user impact
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
name: Refresh GitHub model pricing
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
# Run once a day, shortly after GitHub's documentation refresh window.
|
|
6
|
+
- cron: "17 2 * * *"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: refresh-pricing
|
|
11
|
+
cancel-in-progress: false
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: write
|
|
15
|
+
pull-requests: write
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
refresh-pricing:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- name: Check out repository
|
|
23
|
+
uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- name: Install uv
|
|
26
|
+
uses: astral-sh/setup-uv@v5
|
|
27
|
+
with:
|
|
28
|
+
enable-cache: true
|
|
29
|
+
python-version: "3.12"
|
|
30
|
+
|
|
31
|
+
- name: Install just
|
|
32
|
+
uses: extractions/setup-just@v2
|
|
33
|
+
|
|
34
|
+
- name: Install dependencies
|
|
35
|
+
run: uv sync --frozen --all-groups
|
|
36
|
+
|
|
37
|
+
- name: Refresh pricing
|
|
38
|
+
run: just refresh-pricing
|
|
39
|
+
|
|
40
|
+
- name: Check for upstream pricing changes
|
|
41
|
+
id: changes
|
|
42
|
+
shell: bash
|
|
43
|
+
run: |
|
|
44
|
+
pricing_file="src/copilot_session_usage/data/models-and-pricing.yml"
|
|
45
|
+
if git diff --quiet -- "$pricing_file"; then
|
|
46
|
+
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
47
|
+
echo "No pricing YAML changes detected."
|
|
48
|
+
else
|
|
49
|
+
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
50
|
+
echo "Pricing YAML changed:"
|
|
51
|
+
git diff --stat -- "$pricing_file"
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
- name: Create or update pull request
|
|
55
|
+
if: steps.changes.outputs.changed == 'true'
|
|
56
|
+
uses: peter-evans/create-pull-request@v7
|
|
57
|
+
with:
|
|
58
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
59
|
+
base: main
|
|
60
|
+
branch: automation/refresh-pricing
|
|
61
|
+
delete-branch: true
|
|
62
|
+
commit-message: "chore(pricing): refresh GitHub model pricing"
|
|
63
|
+
title: "chore(pricing): refresh GitHub model pricing"
|
|
64
|
+
body: |
|
|
65
|
+
This automated pull request updates the bundled GitHub Copilot model pricing data.
|
|
66
|
+
|
|
67
|
+
Source: https://raw.githubusercontent.com/github/docs/main/data/tables/copilot/models-and-pricing.yml
|
|
68
|
+
|
|
69
|
+
The update was generated by running `just refresh-pricing`.
|
|
70
|
+
add-paths: |
|
|
71
|
+
src/copilot_session_usage/data/models-and-pricing.yml
|
|
72
|
+
src/copilot_session_usage/data/models-and-pricing.lock
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
name: Generate release notes (manual)
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
tag:
|
|
7
|
+
description: "Existing version tag to generate a draft release for"
|
|
8
|
+
required: true
|
|
9
|
+
type: string
|
|
10
|
+
|
|
11
|
+
concurrency:
|
|
12
|
+
group: release-notes-${{ github.ref }}
|
|
13
|
+
cancel-in-progress: false
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: write
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
generate-release-notes:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- name: Check out tagged source
|
|
24
|
+
uses: actions/checkout@v4
|
|
25
|
+
with:
|
|
26
|
+
fetch-depth: 0
|
|
27
|
+
ref: ${{ inputs.tag || github.ref }}
|
|
28
|
+
|
|
29
|
+
- name: Resolve release range
|
|
30
|
+
id: range
|
|
31
|
+
shell: bash
|
|
32
|
+
env:
|
|
33
|
+
TARGET_TAG: ${{ inputs.tag || github.ref_name }}
|
|
34
|
+
run: |
|
|
35
|
+
set -euo pipefail
|
|
36
|
+
|
|
37
|
+
if [[ ! "$TARGET_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+([.-].*)?$ ]]; then
|
|
38
|
+
echo "::error::Expected a semantic-version tag such as v0.7.0, got '$TARGET_TAG'."
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
previous_tag="$(git tag --sort=-v:refname --merged "$TARGET_TAG" \
|
|
43
|
+
| awk -v current="$TARGET_TAG" '$0 != current { print; exit }')"
|
|
44
|
+
|
|
45
|
+
if [[ -z "$previous_tag" ]]; then
|
|
46
|
+
echo "::error::Could not find a previous release tag for $TARGET_TAG."
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
echo "target_tag=$TARGET_TAG" >> "$GITHUB_OUTPUT"
|
|
51
|
+
echo "previous_tag=$previous_tag" >> "$GITHUB_OUTPUT"
|
|
52
|
+
echo "Generating notes from $previous_tag to $TARGET_TAG."
|
|
53
|
+
|
|
54
|
+
- name: Verify release-note skill
|
|
55
|
+
env:
|
|
56
|
+
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
|
|
57
|
+
run: |
|
|
58
|
+
set -euo pipefail
|
|
59
|
+
|
|
60
|
+
if [[ -z "${COPILOT_GITHUB_TOKEN:-}" ]]; then
|
|
61
|
+
echo "::error::The COPILOT_GITHUB_TOKEN repository secret is not configured."
|
|
62
|
+
echo "Create a fine-grained PAT with the Copilot Requests permission and add it as a repository secret."
|
|
63
|
+
exit 1
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
if ! gh copilot -- skill list | grep -Fq 'gh-release-notes'; then
|
|
67
|
+
echo "::error::The gh-release-notes skill was not discovered by GitHub CLI."
|
|
68
|
+
exit 1
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
- name: Generate release notes with the skill
|
|
72
|
+
env:
|
|
73
|
+
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
|
|
74
|
+
PREVIOUS_TAG: ${{ steps.range.outputs.previous_tag }}
|
|
75
|
+
TARGET_TAG: ${{ steps.range.outputs.target_tag }}
|
|
76
|
+
run: |
|
|
77
|
+
set -euo pipefail
|
|
78
|
+
|
|
79
|
+
output_file="release-notes.md"
|
|
80
|
+
rm -f "$output_file"
|
|
81
|
+
|
|
82
|
+
prompt="Use the /gh-release-notes skill.
|
|
83
|
+
|
|
84
|
+
Generate the final release notes for ${TARGET_TAG}, covering the actual changes from ${PREVIOUS_TAG} to ${TARGET_TAG} in ${GITHUB_WORKSPACE}.
|
|
85
|
+
|
|
86
|
+
Follow the skill's diff-based analysis process. Include only changes with a proven user-facing consequence; exclude CI, workflows, release automation, internal skills, guidelines, tests, file lists, and other repository housekeeping unless the diff proves direct product impact. If there is no product impact, write exactly this fallback block and no other wording: **Maintenance** followed by a blank line and This release primarily includes updates to the knowledge base documentation and internal repository structure. No changes to the core product functionality or user-facing features. Write the final release-note Markdown directly to ${output_file} in the current workspace using the file-writing tool. Do not put the release notes in your response because the response stream is discarded. Do not modify, commit, or push any other repository files."
|
|
87
|
+
|
|
88
|
+
gh copilot -- \
|
|
89
|
+
--prompt "$prompt" \
|
|
90
|
+
--silent \
|
|
91
|
+
--no-ask-user \
|
|
92
|
+
--no-auto-update \
|
|
93
|
+
--no-color \
|
|
94
|
+
--output-format text \
|
|
95
|
+
--disable-builtin-mcps \
|
|
96
|
+
--available-tools='read,create,edit,bash' \
|
|
97
|
+
--allow-tool='read' \
|
|
98
|
+
--allow-tool='write' \
|
|
99
|
+
--allow-tool='shell(git:*)' \
|
|
100
|
+
--allow-url='https://github.com' \
|
|
101
|
+
--allow-url='https://copilot-session-usage.readthedocs.io' \
|
|
102
|
+
> /dev/null
|
|
103
|
+
|
|
104
|
+
if [[ ! -s "$output_file" ]]; then
|
|
105
|
+
echo "::error::The gh-release-notes skill did not create $output_file."
|
|
106
|
+
exit 1
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
python scripts/validate_release_notes.py "$output_file"
|
|
110
|
+
|
|
111
|
+
- name: Upload generated notes for review
|
|
112
|
+
uses: actions/upload-artifact@v4
|
|
113
|
+
with:
|
|
114
|
+
name: release-notes-${{ steps.range.outputs.target_tag }}
|
|
115
|
+
path: release-notes.md
|
|
116
|
+
|
|
117
|
+
- name: Create draft GitHub release
|
|
118
|
+
env:
|
|
119
|
+
GH_TOKEN: ${{ github.token }}
|
|
120
|
+
TARGET_TAG: ${{ steps.range.outputs.target_tag }}
|
|
121
|
+
run: |
|
|
122
|
+
set -euo pipefail
|
|
123
|
+
|
|
124
|
+
if gh release view "$TARGET_TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
|
|
125
|
+
echo "::error::A GitHub Release already exists for $TARGET_TAG."
|
|
126
|
+
exit 1
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
gh release create "$TARGET_TAG" \
|
|
130
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
131
|
+
--verify-tag \
|
|
132
|
+
--draft \
|
|
133
|
+
--title "$TARGET_TAG" \
|
|
134
|
+
--notes-file release-notes.md
|