copilot-session-usage 0.6.0__tar.gz → 0.6.2__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.
Files changed (115) hide show
  1. copilot_session_usage-0.6.2/.github/skills/gh-release-notes/SKILL.md +314 -0
  2. copilot_session_usage-0.6.2/.github/workflows/refresh-pricing.yml +72 -0
  3. copilot_session_usage-0.6.2/.github/workflows/release-notes.yml +127 -0
  4. copilot_session_usage-0.6.2/.github/workflows/release.yml +195 -0
  5. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/AGENTS.md +10 -0
  6. copilot_session_usage-0.6.2/CONTRIBUTING.md +65 -0
  7. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/PKG-INFO +1 -1
  8. copilot_session_usage-0.6.2/docs/internal/automated_release_proces.md +497 -0
  9. copilot_session_usage-0.6.2/knowledge/findings/2026.07.13-14.27-release-notes-overreported-maintainer-changes.md +34 -0
  10. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/findings/index.md +1 -0
  11. copilot_session_usage-0.6.0/.github/skills/gh-release-notes/SKILL.md +0 -255
  12. copilot_session_usage-0.6.0/CONTRIBUTING.md +0 -49
  13. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/.editorconfig +0 -0
  14. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/.gitattributes +0 -0
  15. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  16. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  17. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/.github/changes/requests/skill-breakdown/01-request.md +0 -0
  18. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/.github/guidelines/git-commit-message.guideline.md +0 -0
  19. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/.github/guidelines/knowledge-base.guidelines.md +0 -0
  20. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/.github/pull_request_template.md +0 -0
  21. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/.github/skills/consolidate-knowledge-base/SKILL.md +0 -0
  22. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/.github/skills/record-finding/SKILL.md +0 -0
  23. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/.github/workflows/ci.yml +0 -0
  24. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/.github/workflows/publish.yml +0 -0
  25. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/.gitignore +0 -0
  26. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/.readthedocs.yaml +0 -0
  27. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/CHANGELOG.md +0 -0
  28. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/LICENSE +0 -0
  29. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/README.md +0 -0
  30. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/_static/changelog.js +0 -0
  31. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/_static/custom.css +0 -0
  32. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/changelog.md +0 -0
  33. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/conf.py +0 -0
  34. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/explanation/how-cost-estimation-works.md +0 -0
  35. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/explanation/index.md +0 -0
  36. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/how-to/add-commit-trailer.md +0 -0
  37. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/how-to/analyze-specific-session.md +0 -0
  38. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/how-to/batch-and-spending.md +0 -0
  39. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/how-to/export-json.md +0 -0
  40. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/how-to/index.md +0 -0
  41. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/how-to/wsl2.md +0 -0
  42. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/index.md +0 -0
  43. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/installation.md +0 -0
  44. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/reference/api.md +0 -0
  45. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/reference/cli.md +0 -0
  46. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/reference/index.md +0 -0
  47. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/reference/pricing.md +0 -0
  48. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/tutorials/getting-started.md +0 -0
  49. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/docs/source/tutorials/index.md +0 -0
  50. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/justfile +0 -0
  51. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/_schema/Base.schema.yaml +0 -0
  52. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/_schema/Concept.schema.yaml +0 -0
  53. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/_schema/Experiment.schema.yaml +0 -0
  54. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/_schema/Finding.schema.yaml +0 -0
  55. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/_schema/Hypothesis.schema.yaml +0 -0
  56. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/_schema/Outcome.schema.yaml +0 -0
  57. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/_schema/Playbook.schema.yaml +0 -0
  58. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/_schema/Principle.schema.yaml +0 -0
  59. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/_schema/Reference.schema.yaml +0 -0
  60. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/_schema/Structure.schema.yaml +0 -0
  61. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/concepts/copilot-cli.md +0 -0
  62. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/concepts/index.md +0 -0
  63. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/concepts/overview.md +0 -0
  64. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/concepts/session-cost-analysis.md +0 -0
  65. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/concepts/threshold-based-pricing.md +0 -0
  66. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/experiments/index.md +0 -0
  67. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/experiments/verify-subagent-cost-attribution.md +0 -0
  68. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/findings/2026.07.02-00.00-subagent-logs-runsubagent-prefix.md +0 -0
  69. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/findings/2026.07.02-22.00-title-generation-not-counted-as-model-turn.md +0 -0
  70. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/findings/2026.07.02-23.00-cache-write-approximation.md +0 -0
  71. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/guides/automation-scripts.md +0 -0
  72. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/guides/cost-optimization.md +0 -0
  73. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/guides/index.md +0 -0
  74. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/guides/wsl2-setup.md +0 -0
  75. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/ideas/index.md +0 -0
  76. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/ideas/multi-session-efficiency-analytics.md +0 -0
  77. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/index.md +0 -0
  78. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/log.md +0 -0
  79. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/principles/findings-are-immutable.md +0 -0
  80. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/principles/index.md +0 -0
  81. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/reference/debug-log-format.md +0 -0
  82. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/reference/index.md +0 -0
  83. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/reference/pricing-formats.md +0 -0
  84. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/structures/cache-cost-approximation.md +0 -0
  85. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/structures/index.md +0 -0
  86. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/structures/knowledge-base-information-types.md +0 -0
  87. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/structures/session-discovery-algorithm.md +0 -0
  88. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/structures/subagent-cost-tracking.md +0 -0
  89. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/knowledge/structures/vscode-copilot-extension.md +0 -0
  90. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/pyproject.toml +0 -0
  91. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/scripts/refresh_pricing.py +0 -0
  92. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/skills/copilot-session-usage/SKILL.md +0 -0
  93. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/src/copilot_session_usage/__init__.py +0 -0
  94. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/src/copilot_session_usage/_internal/__init__.py +0 -0
  95. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/src/copilot_session_usage/_internal/copilot_cli.py +0 -0
  96. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/src/copilot_session_usage/_internal/core.py +0 -0
  97. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/src/copilot_session_usage/_internal/git.py +0 -0
  98. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/src/copilot_session_usage/_internal/vscode.py +0 -0
  99. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/src/copilot_session_usage/api.py +0 -0
  100. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/src/copilot_session_usage/cli.py +0 -0
  101. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/src/copilot_session_usage/data/__init__.py +0 -0
  102. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/src/copilot_session_usage/data/custom-models-pricing.yml +0 -0
  103. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/src/copilot_session_usage/data/models-and-pricing.lock +0 -0
  104. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/src/copilot_session_usage/data/models-and-pricing.yml +0 -0
  105. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/tests/conftest.py +0 -0
  106. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/tests/test_api.py +0 -0
  107. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/tests/test_cli.py +0 -0
  108. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/tests/test_core.py +0 -0
  109. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/tests/test_coverage_gaps.py +0 -0
  110. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/tests/test_git.py +0 -0
  111. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/tests/test_rendering.py +0 -0
  112. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/tests/test_vscode.py +0 -0
  113. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/tests/test_vscode_platform.py +0 -0
  114. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/uv.lock +0 -0
  115. {copilot_session_usage-0.6.0 → copilot_session_usage-0.6.2}/uv.toml +0 -0
@@ -0,0 +1,314 @@
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
+ 2. **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 section:
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. A maintenance release may say only that it contains maintenance updates. An internal release may say only that it contains internal updates. Do not manufacture examples or links for either.
136
+
137
+ ```markdown
138
+ ## New Features
139
+ - Added dark mode toggle in settings
140
+ - New PDF export option
141
+
142
+ ## Enhancements
143
+ - Improved search performance (now supports partial matches)
144
+ - Faster file opening for large documents
145
+
146
+ ## Bug Fixes
147
+ - Fixed login failures on slow connections
148
+ - Resolved crash when uploading 10MB+ files
149
+
150
+ ## Breaking Changes
151
+ - Database schema updated — run migration before upgrading
152
+ - CSV export removed; use Excel or PDF instead
153
+
154
+ ## Examples
155
+ - Dark mode can be enabled in Settings → Appearance → Theme
156
+ - CSV export is no longer available; choose Excel or PDF from Export menu
157
+
158
+ ## Documentation
159
+ - [Dark mode guide](https://docs.example.com/settings#dark-mode)
160
+ - [Migration notes](https://docs.example.com/upgrade#database)
161
+ ```
162
+
163
+ ---
164
+
165
+ ## Workflow for Agent
166
+
167
+ 1. **Parse input** — extract `from_tag`, `to_tag`, `repo_path`, and optional filters
168
+ 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.
169
+ 3. **Fetch commits** — run `git log` with range, collect hashes and messages
170
+ 4. **Read diffs per file** — use `git show <hash>` for each relevant commit and examine changed behavior, not just filenames
171
+ 5. **Apply the user-impact gate** — discard CI, internal, process, and implementation-only changes unless the diff proves direct user impact
172
+ 6. **Interpret impact** — state what users can do, observe, configure, rely on, or learn differently
173
+ 7. **Detect breaking changes** — scan for BREAKING markers, public API removals, format changes, migrations, and changed defaults
174
+ 8. **Group by category** — assign each qualifying change to **New Features**, **Enhancements**, **Bug Fixes**, **Breaking Changes**, **Examples**, or **Documentation**
175
+ 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
176
+ 10. **Consolidate** — merge related items, remove duplicates and flip-flops
177
+ 11. **Use a fallback** — if no product change qualifies, emit exactly one of **Maintenance**, **Documentation**, or **Internal**
178
+ 12. **Format markdown** — generate clean section headings and bullets with no title, preamble, footer, file summary, or commit summary
179
+ 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
180
+
181
+ ---
182
+
183
+ ## Output Format
184
+
185
+ **Clean markdown** for a GitHub Release body:
186
+
187
+ ```markdown
188
+ ## New Features
189
+ - Added dark mode toggle in settings
190
+ - New PDF export option
191
+
192
+ ## Enhancements
193
+ - Improved search performance (supports partial matches)
194
+ - Faster file opening for large documents
195
+
196
+ ## Bug Fixes
197
+ - Fixed login failures on slow connections
198
+ - Resolved crash when uploading 10MB+ files
199
+
200
+ ## Breaking Changes
201
+ - Database schema updated — run migration before upgrading
202
+
203
+ ## Examples
204
+ - Enable dark mode from Settings → Appearance → Theme
205
+ - Export a report as PDF from the File → Export menu
206
+
207
+ ## Documentation
208
+ - [Dark mode guide](https://docs.example.com/settings#dark-mode)
209
+ - [Upgrade instructions](https://docs.example.com/upgrade#database)
210
+ ```
211
+
212
+ For a release with no runtime product impact, use a short note such as:
213
+
214
+ ```markdown
215
+ ## Maintenance
216
+ - Maintenance release with no user-facing behavior changes.
217
+ ```
218
+
219
+ **Key Rules:**
220
+ - One line per bullet point
221
+ - No sub-bullets or elaborate descriptions
222
+ - User impact only (not implementation details, changed-file summaries, CI, internal process, or contributor guidance)
223
+ - Do not include a title heading; the GitHub Release supplies the title
224
+ - Use public documentation URLs; never use repo-relative paths like `docs/...` or `README.md`
225
+ - Use fragment identifiers (`#section-name`) to point to specific docs sections
226
+ - Add an **Examples** section when the diff shows a CLI command, API call, config snippet, or before/after behavior
227
+ - 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
228
+ - Multiple links OK if they point to different topics
229
+ - Omit any section that has no bullets
230
+ - If no user-facing change qualifies, emit exactly one concise `Maintenance`, `Documentation`, or `Internal` section
231
+ - Never include file counts, changed-file lists, commit metadata, CI/workflow summaries, or a closing separator
232
+ - Do not add a "Notes", "Miscellaneous", or "Other" catch-all section
233
+
234
+ ---
235
+
236
+ ## Non-interactive automation mode
237
+
238
+ When this skill is invoked by a CI job with an explicit request for machine-readable output:
239
+
240
+ - Honor the requested tag range and repository path exactly.
241
+ - Do not modify, commit, or push repository files unless the caller explicitly requests it.
242
+ - Return only the final release-note Markdown, without an explanation, title heading, or code fence.
243
+ - Preserve the user-impact categories, examples, breaking-change detection, and public documentation links described above.
244
+
245
+ ## How to Use This Skill in a Session
246
+
247
+ **User Query:**
248
+ ```
249
+ Generate release notes from v2.1.0 to v2.2.0 for /path/to/my-app
250
+ ```
251
+
252
+ **Agent Workflow:**
253
+ 1. Navigate to repo: `cd /path/to/my-app`
254
+ 2. Fetch commits: `git log v2.1.0..v2.2.0 --oneline --no-merges`
255
+ 3. For each commit, examine changes: `git show <hash>`
256
+ 4. Interpret: What's the user impact? (not the code details)
257
+ 5. Categorize: Feature? Bug fix? Breaking change?
258
+ 6. Consolidate: Merge similar items
259
+ 7. Format: Clean markdown with categories
260
+ 8. Output: Save to RELEASE_NOTES.md
261
+
262
+ ---
263
+
264
+ ## Best Practices
265
+
266
+ ✅ **Do:**
267
+ - Read actual diffs to understand changes
268
+ - Use end-user language ("improved performance" not "optimized O(n) loop")
269
+ - Require evidence of a user-visible consequence before including a change
270
+ - Include breaking changes prominently
271
+ - Group related changes
272
+ - Add concrete examples drawn from README, docs, tests, or CLI help in the diff
273
+ - Link to the project's public documentation site (ReadTheDocs, GitHub Pages, etc.)
274
+ - Omit empty sections
275
+
276
+ ❌ **Don't:**
277
+ - Copy commit messages verbatim
278
+ - Include function/variable names
279
+ - Mention internal refactors users won't notice
280
+ - Include dependency bumps or build changes unless they are user-visible
281
+ - Include secrets, passwords, or internal URLs
282
+ - Use repo-relative paths like `docs/source/how-to/...` or `README.md`
283
+ - Report CI, workflows, internal skills, contributor guidelines, maintainer process, file counts, or changed-file lists as release content
284
+ - Add a title heading to the generated body
285
+ - Make up changes not shown in diffs
286
+
287
+ ---
288
+
289
+ ## Common Patterns
290
+
291
+ **Performance improvements:**
292
+ > "Improved search speed when filtering 1000+ records"
293
+
294
+ **New integrations:**
295
+ > "Added support for OAuth login via GitHub"
296
+
297
+ **Data format changes:**
298
+ > "Settings file now uses JSON instead of YAML (auto-converted on first run)"
299
+
300
+ **Removed features:**
301
+ > "Removed IE 11 support to modernize codebase"
302
+
303
+ **API changes:**
304
+ > "Changed user profile endpoint response format (see migration guide)"
305
+
306
+ ---
307
+
308
+ ## Limitations
309
+
310
+ - Requires a git repository with proper tags
311
+ - Complex changes may need human interpretation
312
+ - Very large diffs should be reduced to their evidenced user impact; never summarize them by file count
313
+ - Works best with semantic versioning (v1.0.0 format)
314
+ - 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,127 @@
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
+ prompt="Use the /gh-release-notes skill.
80
+
81
+ Generate the final release notes for ${TARGET_TAG}, covering the actual changes from ${PREVIOUS_TAG} to ${TARGET_TAG} in ${GITHUB_WORKSPACE}.
82
+
83
+ 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, emit one concise Maintenance, Documentation, or Internal section. Return only the final release-note Markdown, with no title heading, introduction, explanation, file summary, or code fence. Do not modify any repository files."
84
+
85
+ gh copilot -- \
86
+ --prompt "$prompt" \
87
+ --silent \
88
+ --no-ask-user \
89
+ --no-auto-update \
90
+ --no-color \
91
+ --disable-builtin-mcps \
92
+ --available-tools='read,shell' \
93
+ --allow-tool='read' \
94
+ --allow-tool='shell(git:*)' \
95
+ --allow-url='https://github.com' \
96
+ --allow-url='https://copilot-session-usage.readthedocs.io' \
97
+ > release-notes.md
98
+
99
+ if [[ ! -s release-notes.md ]]; then
100
+ echo "::error::The release-note skill returned an empty document."
101
+ exit 1
102
+ fi
103
+
104
+ - name: Upload generated notes for review
105
+ uses: actions/upload-artifact@v4
106
+ with:
107
+ name: release-notes-${{ steps.range.outputs.target_tag }}
108
+ path: release-notes.md
109
+
110
+ - name: Create draft GitHub release
111
+ env:
112
+ GH_TOKEN: ${{ github.token }}
113
+ TARGET_TAG: ${{ steps.range.outputs.target_tag }}
114
+ run: |
115
+ set -euo pipefail
116
+
117
+ if gh release view "$TARGET_TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
118
+ echo "::error::A GitHub Release already exists for $TARGET_TAG."
119
+ exit 1
120
+ fi
121
+
122
+ gh release create "$TARGET_TAG" \
123
+ --repo "$GITHUB_REPOSITORY" \
124
+ --verify-tag \
125
+ --draft \
126
+ --title "$TARGET_TAG" \
127
+ --notes-file release-notes.md