copilot-session-usage 0.3.0__tar.gz → 0.5.0__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 (113) hide show
  1. copilot_session_usage-0.5.0/.github/changes/requests/skill-breakdown/01-request.md +163 -0
  2. copilot_session_usage-0.5.0/.github/guidelines/git-commit-message.guideline.md +99 -0
  3. copilot_session_usage-0.5.0/.github/skills/gh-release-notes/SKILL.md +234 -0
  4. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/AGENTS.md +1 -0
  5. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/CHANGELOG.md +13 -0
  6. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/PKG-INFO +105 -4
  7. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/README.md +103 -3
  8. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/docs/source/explanation/how-cost-estimation-works.md +18 -0
  9. copilot_session_usage-0.5.0/docs/source/how-to/add-commit-trailer.md +133 -0
  10. copilot_session_usage-0.5.0/docs/source/how-to/analyze-specific-session.md +101 -0
  11. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/docs/source/how-to/batch-and-spending.md +30 -0
  12. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/docs/source/how-to/index.md +1 -0
  13. copilot_session_usage-0.5.0/docs/source/reference/cli.md +11 -0
  14. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/docs/source/tutorials/getting-started.md +54 -0
  15. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/justfile +3 -0
  16. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/pyproject.toml +1 -0
  17. copilot_session_usage-0.5.0/skills/copilot-session-usage/SKILL.md +327 -0
  18. copilot_session_usage-0.5.0/src/copilot_session_usage/_internal/core.py +2237 -0
  19. copilot_session_usage-0.5.0/src/copilot_session_usage/_internal/git.py +126 -0
  20. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/src/copilot_session_usage/_internal/vscode.py +43 -0
  21. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/src/copilot_session_usage/api.py +26 -2
  22. copilot_session_usage-0.5.0/src/copilot_session_usage/cli.py +741 -0
  23. copilot_session_usage-0.5.0/tests/test_cli.py +734 -0
  24. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/tests/test_core.py +708 -5
  25. copilot_session_usage-0.5.0/tests/test_git.py +176 -0
  26. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/tests/test_rendering.py +130 -10
  27. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/uv.lock +35 -0
  28. copilot_session_usage-0.3.0/docs/source/how-to/analyze-specific-session.md +0 -46
  29. copilot_session_usage-0.3.0/docs/source/reference/cli.md +0 -7
  30. copilot_session_usage-0.3.0/skills/copilot-session-usage/SKILL.md +0 -131
  31. copilot_session_usage-0.3.0/src/copilot_session_usage/_internal/core.py +0 -1169
  32. copilot_session_usage-0.3.0/src/copilot_session_usage/cli.py +0 -287
  33. copilot_session_usage-0.3.0/tests/test_cli.py +0 -280
  34. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/.editorconfig +0 -0
  35. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  36. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  37. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/.github/guidelines/knowledge-base.guidelines.md +0 -0
  38. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/.github/pull_request_template.md +0 -0
  39. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/.github/skills/consolidate-knowledge-base/SKILL.md +0 -0
  40. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/.github/skills/record-finding/SKILL.md +0 -0
  41. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/.github/workflows/ci.yml +0 -0
  42. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/.github/workflows/publish.yml +0 -0
  43. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/.gitignore +0 -0
  44. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/.readthedocs.yaml +0 -0
  45. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/CONTRIBUTING.md +0 -0
  46. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/LICENSE +0 -0
  47. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/docs/source/_static/changelog.js +0 -0
  48. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/docs/source/_static/custom.css +0 -0
  49. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/docs/source/changelog.md +0 -0
  50. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/docs/source/conf.py +0 -0
  51. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/docs/source/explanation/index.md +0 -0
  52. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/docs/source/how-to/export-json.md +0 -0
  53. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/docs/source/how-to/wsl2.md +0 -0
  54. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/docs/source/index.md +0 -0
  55. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/docs/source/installation.md +0 -0
  56. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/docs/source/reference/api.md +0 -0
  57. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/docs/source/reference/index.md +0 -0
  58. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/docs/source/reference/pricing.md +0 -0
  59. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/docs/source/tutorials/index.md +0 -0
  60. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/_schema/Base.schema.yaml +0 -0
  61. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/_schema/Concept.schema.yaml +0 -0
  62. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/_schema/Experiment.schema.yaml +0 -0
  63. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/_schema/Finding.schema.yaml +0 -0
  64. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/_schema/Hypothesis.schema.yaml +0 -0
  65. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/_schema/Outcome.schema.yaml +0 -0
  66. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/_schema/Playbook.schema.yaml +0 -0
  67. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/_schema/Principle.schema.yaml +0 -0
  68. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/_schema/Reference.schema.yaml +0 -0
  69. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/_schema/Structure.schema.yaml +0 -0
  70. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/concepts/copilot-cli.md +0 -0
  71. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/concepts/index.md +0 -0
  72. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/concepts/overview.md +0 -0
  73. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/concepts/session-cost-analysis.md +0 -0
  74. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/concepts/threshold-based-pricing.md +0 -0
  75. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/experiments/index.md +0 -0
  76. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/experiments/verify-subagent-cost-attribution.md +0 -0
  77. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/findings/2026.07.02-00.00-subagent-logs-runsubagent-prefix.md +0 -0
  78. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/findings/2026.07.02-22.00-title-generation-not-counted-as-model-turn.md +0 -0
  79. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/findings/2026.07.02-23.00-cache-write-approximation.md +0 -0
  80. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/findings/index.md +0 -0
  81. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/guides/automation-scripts.md +0 -0
  82. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/guides/cost-optimization.md +0 -0
  83. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/guides/index.md +0 -0
  84. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/guides/wsl2-setup.md +0 -0
  85. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/ideas/index.md +0 -0
  86. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/ideas/multi-session-efficiency-analytics.md +0 -0
  87. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/index.md +0 -0
  88. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/log.md +0 -0
  89. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/principles/findings-are-immutable.md +0 -0
  90. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/principles/index.md +0 -0
  91. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/reference/debug-log-format.md +0 -0
  92. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/reference/index.md +0 -0
  93. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/reference/pricing-formats.md +0 -0
  94. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/structures/cache-cost-approximation.md +0 -0
  95. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/structures/index.md +0 -0
  96. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/structures/knowledge-base-information-types.md +0 -0
  97. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/structures/session-discovery-algorithm.md +0 -0
  98. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/structures/subagent-cost-tracking.md +0 -0
  99. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/knowledge/structures/vscode-copilot-extension.md +0 -0
  100. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/scripts/refresh_pricing.py +0 -0
  101. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/src/copilot_session_usage/__init__.py +0 -0
  102. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/src/copilot_session_usage/_internal/__init__.py +0 -0
  103. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/src/copilot_session_usage/_internal/copilot_cli.py +0 -0
  104. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/src/copilot_session_usage/data/__init__.py +0 -0
  105. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/src/copilot_session_usage/data/custom-models-pricing.yml +0 -0
  106. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/src/copilot_session_usage/data/models-and-pricing.lock +0 -0
  107. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/src/copilot_session_usage/data/models-and-pricing.yml +0 -0
  108. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/tests/conftest.py +0 -0
  109. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/tests/test_api.py +0 -0
  110. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/tests/test_coverage_gaps.py +0 -0
  111. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/tests/test_vscode.py +0 -0
  112. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/tests/test_vscode_platform.py +0 -0
  113. {copilot_session_usage-0.3.0 → copilot_session_usage-0.5.0}/uv.toml +0 -0
@@ -0,0 +1,163 @@
1
+ # Skill-aware cost attribution and faster session lookup
2
+
3
+ ## Context
4
+
5
+ `copilot-session-usage` extracts VS Code Copilot session cost KPIs from local debug logs. It already supports per-model pricing, subagent attribution, and multiple output formats.
6
+
7
+ However, when a user invokes a skill (e.g. `/compendium-generic get-session-costs`), the CLI has no first-class way to report:
8
+
9
+ - which skill(s) were active in a session,
10
+ - how much each skill cost,
11
+ - which tool calls each skill triggered,
12
+ - or how to find a session by its title without manually scanning `copilot-session-usage list` output.
13
+
14
+ Investigating a single skill's cost currently requires ad-hoc Python scripts that grep raw JSONL files for slash-command names, skill discovery events, and tool-call records. This is slow, token-heavy, error-prone, and not reproducible.
15
+
16
+ ## Problem
17
+
18
+ 1. **No skill cost attribution.** A session may be dominated by one skill, but the CLI only reports per-model and per-subagent totals.
19
+ 2. **Session lookup by title is manual.** Users must run `list`, visually scan titles, copy the UUID, then run `id <uuid>`.
20
+ 3. **Subagent names are often `unknown`.** The subagent spawned by `runSubagent` is reported as `unknown` even though its name appears in the debug-log filename.
21
+ 4. **No tool-call attribution.** It is impossible to see which tools a skill consumed tokens on.
22
+ 5. **No stable, concise report format.** Full JSON dumps are large; users often only need skill + cost + token counts.
23
+
24
+ ## Goals
25
+
26
+ Make `copilot-session-usage` **faster, safer, cheaper, and more reproducible** for skill-centric cost analysis by:
27
+
28
+ - detecting skills from system prompts, tool definitions, and user messages,
29
+ - attributing LLM calls and tool calls to the active skill,
30
+ - allowing users to filter sessions by title and skill,
31
+ - fixing subagent name extraction,
32
+ - providing a concise, stable output mode.
33
+
34
+ ## Proposed features
35
+
36
+ ### 1. Skill cost breakdown
37
+
38
+ Add a `--skill-breakdown` flag to `id` and `analyze` that emits a per-skill table:
39
+
40
+ ```markdown
41
+ | Skill | Input Tokens | Output Tokens | Cached Tokens | LLM Calls | Cost |
42
+ |-------|--------------|---------------|---------------|-----------|------|
43
+ | /compendium-generic get-session-costs | 1,137,864 | 15,729 | 1,015,825 | 24 | $0.3636 |
44
+ ```
45
+
46
+ Implementation notes:
47
+
48
+ - Parse `system_prompt_0.json` for loaded skill lists.
49
+ - Parse `tools_0.json` for the `skill` tool definition and any skill-related slash commands.
50
+ - Parse `user_message` events for slash-command invocations (`/<skill-name> ...`).
51
+ - Parse `discovery` events of type `Skill Discovery` as a fallback.
52
+ - Attribute each turn to the most recently invoked skill.
53
+
54
+ ### 2. Filter sessions by title
55
+
56
+ Add `--title <substring>` to `list` and `analyze`:
57
+
58
+ ```bash
59
+ copilot-session-usage list --title "get-session-costs"
60
+ copilot-session-usage analyze --title "grill-me" --latest
61
+ ```
62
+
63
+ This avoids analyzing irrelevant sessions and reduces token consumption.
64
+
65
+ ### 3. Filter analysis by skill
66
+
67
+ Add `--skill <name>` to `id` and `analyze`:
68
+
69
+ ```bash
70
+ copilot-session-usage id <uuid> --skill "/compendium-generic get-session-costs"
71
+ ```
72
+
73
+ When combined with `--format json --minimal`, this returns only the numbers the user asked for.
74
+
75
+ ### 4. Tool-call attribution per skill
76
+
77
+ Add `--tool-breakdown` to `id` and `analyze`:
78
+
79
+ ```markdown
80
+ | Tool | Calls | Skill | Subagent |
81
+ |------|-------|-------|----------|
82
+ | read_file | 25 | /compendium-generic get-session-costs | main, Explore |
83
+ | vscode_askQuestions | 3 | /compendium-generic get-session-costs | main |
84
+ | runSubagent | 1 | /compendium-generic get-session-costs | main |
85
+ ```
86
+
87
+ ### 5. Fix subagent name extraction
88
+
89
+ The subagent log file is named `runSubagent-Explore-functions.runSubagent:4.jsonl`. The CLI should extract `Explore` from the filename instead of reporting `unknown`.
90
+
91
+ Also handle `child_session_ref` events in `main.jsonl` as an additional source of subagent metadata.
92
+
93
+ ### 6. Concise / minimal output mode
94
+
95
+ Add `--minimal` (or extend `--detail minimal`) to return only essential fields:
96
+
97
+ ```bash
98
+ copilot-session-usage id <uuid> --skill "/compendium-generic get-session-costs" --format json --minimal
99
+ ```
100
+
101
+ ```json
102
+ {
103
+ "skill": "/compendium-generic get-session-costs",
104
+ "cost_usd": 0.3636,
105
+ "input_tokens": 1137864,
106
+ "output_tokens": 15729,
107
+ "llm_calls": 24
108
+ }
109
+ ```
110
+
111
+ ### 7. Skill discovery across sessions
112
+
113
+ Add a `skills` command to list skills used over a time window:
114
+
115
+ ```bash
116
+ copilot-session-usage skills --last 7d
117
+ ```
118
+
119
+ Output:
120
+
121
+ ```markdown
122
+ | Skill | Sessions | LLM Calls | Cost |
123
+ |-------|----------|-----------|------|
124
+ | /compendium-generic get-session-costs | 3 | 42 | $0.89 |
125
+ ```
126
+
127
+ ### 8. Metadata cache for faster repeated queries
128
+
129
+ Cache session metadata (title, created_at, has_debug_logs, debug_log_dir) in a small local index keyed by workspace hash. Invalidate when `state.vscdb` mtime changes. This makes `list --title` and `batch` operations near-instant.
130
+
131
+ ## Acceptance criteria
132
+
133
+ - [ ] `copilot-session-usage id <uuid> --skill-breakdown` prints a per-skill cost table.
134
+ - [ ] `copilot-session-usage list --title <substring>` returns only matching sessions.
135
+ - [ ] `copilot-session-usage analyze --title <substring> --latest` analyzes the most recent matching session.
136
+ - [ ] `copilot-session-usage id <uuid> --skill "<name>"` filters the report to that skill.
137
+ - [ ] Subagents spawned by `runSubagent` show their real name, not `unknown`.
138
+ - [ ] `copilot-session-usage id <uuid> --tool-breakdown` prints per-skill/per-subagent tool-call counts.
139
+ - [ ] `copilot-session-usage id <uuid> --format json --minimal` returns a small, stable JSON object.
140
+ - [ ] `copilot-session-usage skills --last 7d` lists skills with aggregated cost.
141
+ - [ ] All new features are covered by unit tests.
142
+ - [ ] `just preflight` passes.
143
+
144
+ ## Non-goals
145
+
146
+ - Do not modify pricing data or model detection logic.
147
+ - Do not add support for non-VS-Code providers (CLI provider remains planned).
148
+ - Do not persist raw debug logs or user message content in the metadata cache.
149
+
150
+ ## Suggested first slice
151
+
152
+ 1. Add `--title` filter to `list` and `analyze`.
153
+ 2. Add `--skill-breakdown` to `id` / `analyze`.
154
+ 3. Fix subagent name extraction (`unknown` → real name).
155
+
156
+ These three changes alone remove the most common manual steps and make skill-cost investigations reproducible from a single CLI command.
157
+
158
+ ## Reference session
159
+
160
+ - Session ID: `44f6a978-243c-4115-aa90-d11c2ccf56e0`
161
+ - Title: `/compendium-generic grill-me here are proposal of improvement in copilot-session-usage, to make its use even way more token efficient:`
162
+ - Skill invoked: `/compendium-generic get-session-costs`
163
+ - Total cost: $0.3636 | 1,137,864 input + 15,729 output tokens | 24 LLM calls
@@ -0,0 +1,99 @@
1
+ ---
2
+ name: Git Commit Message Guideline 1.0
3
+ description: Guidelines for writing conventional commits that communicate intent and user impact
4
+ metadata:
5
+ owner: Gaetan Semet <gaetan.semet@ampere.cars>
6
+ keywords: [git, commit, conventional, message, changelog]
7
+ guideline-id: 45c42e46-0781-4954-a410-1f380f5553f3
8
+ ---
9
+
10
+ # Git Commit Message Guideline
11
+
12
+ Write clear, focused commit messages following Conventional Commits format. Commit messages communicate *why* changes were made—enabling automated changelog generation, bug investigation, and decision-making during upgrades. Focus on user impact, not implementation details.
13
+
14
+ ## Core Rules
15
+
16
+ ### Rule 1: Use Conventional Commit Format
17
+
18
+ **Apply:** Format every title as `type(scope): description`
19
+
20
+ **Why:** Enables automated changelog generation and consistent pattern parsing.
21
+
22
+ **Types:** `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `ci`, `chore`, `build`, `revert`
23
+
24
+ **Examples:**
25
+ ```
26
+ feat(auth): add two-factor authentication support
27
+ fix(api): resolve request timeout in user endpoint
28
+ docs(readme): update installation instructions
29
+ perf(cache): optimize query performance by 40%
30
+ test(validators): add email format validation tests
31
+ ```
32
+
33
+ ---
34
+
35
+ ### Rule 2: Keep Title Under 50 Characters, Body Under 72 Per Line
36
+
37
+ **Apply:** Enforce character limits for scannability and terminal compatibility.
38
+
39
+ **Why:** Short titles force clarity; wrapped body text maintains readability in terminals and email clients.
40
+
41
+ **Example:**
42
+ ```
43
+ feat(cache): implement LRU eviction policy
44
+
45
+ Reduces memory usage in long-running processes by
46
+ automatically removing least-recently-used items.
47
+
48
+ Changes:
49
+ - Cache drops oldest accessed items upon limit
50
+ - Configurable cache size (default 1000)
51
+ - < 2% performance overhead on reads
52
+
53
+ Users can set CACHE_SIZE environment variable.
54
+ ```
55
+
56
+ ---
57
+
58
+ ### Rule 3: Focus Body on User Impact, Not Implementation Details
59
+
60
+ **Apply:** Describe what users gain and must know; exclude refactoring details, internal functions, and test additions.
61
+
62
+ **Why:** Users deciding whether to upgrade, developers integrating changes, and bug investigators need user-level context—not code structure details.
63
+
64
+ **Example:**
65
+ ```
66
+ fix(api): allow null values in optional response fields
67
+
68
+ Optional fields now omitted from JSON when empty,
69
+ reducing response payload by ~15% for sparse data.
70
+
71
+ Migration:
72
+ - Check `field in response` instead of `field != null`
73
+ - Response schema updated in API reference
74
+ ```
75
+
76
+ ---
77
+
78
+ ### Rule 4: Include Breaking Changes with Migration Guidance
79
+
80
+ **Apply:** Use `!` in title and `BREAKING CHANGE:` section. Provide explicit migration steps.
81
+
82
+ **Why:** Breaking changes require user action; clear guidance reduces upgrade confusion.
83
+
84
+ **Example:**
85
+ ```
86
+ feat(api)!: change pagination to cursor-based tokens
87
+
88
+ Cursors improve performance with large datasets.
89
+
90
+ BREAKING CHANGE: Replaced `pagination_offset` and
91
+ `pagination_limit` with `pagination.cursor`.
92
+
93
+ Migration:
94
+ Old: GET /users?limit=10&offset=20
95
+ New: GET /users?limit=10&cursor=xyz123
96
+
97
+ Update code to use `response.pagination.cursor`
98
+ in next request instead of offset/limit.
99
+ ```
@@ -0,0 +1,234 @@
1
+ # Release Notes Generator (Git Diff Based)
2
+
3
+ Generate **end-user friendly** release notes by analyzing actual code changes between releases.
4
+ No scripts required — uses git commands to understand what changed and why it matters.
5
+
6
+ ---
7
+
8
+ ## Quick Start
9
+
10
+ Provide your repository and range:
11
+
12
+ ```
13
+ Generate release notes from v1.0.0 to v1.1.0 in /path/to/repo
14
+ ```
15
+
16
+ Or reference the last release:
17
+
18
+ ```
19
+ What changed since the last release tag?
20
+ ```
21
+
22
+ ---
23
+
24
+ ## What It Does
25
+
26
+ 1. **Reads actual diffs** — examines code changes, not just commit messages
27
+ 2. **Interprets for end-users** — no technical jargon, functions, or variable names
28
+ 3. **Categorizes intelligently** — Features, Enhancements, Bug Fixes, Breaking Changes
29
+ 4. **Consolidates related changes** — groups related diffs, eliminates back-and-forth noise
30
+ 5. **Outputs clean markdown** — Slack-ready format suitable for announcements
31
+
32
+ ---
33
+
34
+ ## Input
35
+
36
+ Accept either:
37
+
38
+ - **Natural language**: "Show release notes from v1.2.0 to v1.3.0"
39
+ - **Range spec**: `from_tag=v1.2.0 to_tag=v1.3.0 repo_path=/path/to/repo`
40
+ - **Last release**: `since_tag=v1.2.0` (everything from tag to HEAD)
41
+
42
+ Required:
43
+ - Repository path (optional: defaults to current directory)
44
+ - Range: `from_tag` + `to_tag`, OR `since_tag`, OR `last_n_commits`
45
+
46
+ ---
47
+
48
+ ## Analysis Process
49
+
50
+ ### Step 1: Collect Commits
51
+ ```bash
52
+ git log v1.0.0..v1.1.0 --oneline --no-merges
53
+ ```
54
+ Gather all commits in the specified range with their messages.
55
+
56
+ ### Step 2: Examine Diffs
57
+ ```bash
58
+ git diff v1.0.0..v1.1.0 -- src/
59
+ ```
60
+ Read actual code changes line-by-line to understand what changed.
61
+
62
+ ### Step 3: Interpret Changes
63
+
64
+ Translate technical changes into user impact:
65
+
66
+ | Code Change | User Impact |
67
+ |-------------|------------|
68
+ | `+ const darkMode = true` in settings | "Dark mode toggle now available in settings" |
69
+ | Deleted login retry logic | "Removed automatic retry on login timeout" |
70
+ | `+ validateEmail()` function | "Email validation improved during signup" |
71
+ | Updated database schema version | "Database schema upgraded (run migration)" |
72
+ | Added 10+ calls to cache layer | "Improved performance on large operations" |
73
+ | Removed old CSV export code | "CSV export removed; use Excel or PDF instead" |
74
+
75
+ **Key: Focus on the user's experience, not the code implementation.**
76
+
77
+ ### Step 4: Identify Breaking Changes
78
+
79
+ Breaking changes come from:
80
+ - **Commit messages** containing: "BREAKING", "Breaking", "!:"
81
+ - **Diffs showing**: removed public APIs, changed file formats, data migrations
82
+ - **Config changes**: renamed settings, changed defaults
83
+
84
+ ### Step 5: Consolidate
85
+ - If a feature was added then removed → don't mention it
86
+ - If something changed multiple times → only note the final state
87
+ - If multiple commits fix the same issue → merge into one bullet
88
+
89
+ ### Step 6: Categorize & Format
90
+
91
+ Organize changes into buckets:
92
+
93
+ ```markdown
94
+ # Release Notes - v1.1.0
95
+
96
+ ## New Features
97
+ - Added dark mode toggle in settings
98
+ - New PDF export option
99
+
100
+ ## Enhancements
101
+ - Improved search performance (now supports partial matches)
102
+ - Faster file opening for large documents
103
+
104
+ ## Bug Fixes
105
+ - Fixed login failures on slow connections
106
+ - Resolved crash when uploading 10MB+ files
107
+
108
+ ## Breaking Changes
109
+ - Database schema updated — run migration before upgrading
110
+ - CSV export removed; use Excel or PDF instead
111
+
112
+ ---
113
+ **Notes:**
114
+ - Dark mode requires display driver update on Windows 7
115
+ - Migration tool available at: docs/migrate-db.md
116
+ ```
117
+
118
+ ---
119
+
120
+ ## Workflow for Agent
121
+
122
+ 1. **Parse input** — extract `from_tag`, `to_tag`, `repo_path`, and optional filters
123
+ 2. **Fetch commits** — run `git log` with range, collect hashes & messages
124
+ 3. **Read diffs per file** — `git show <hash>` for each commit, examine changed files
125
+ 4. **Interpret impact** — what does each change mean to users?
126
+ 5. **Detect breaking changes** — scan for BREAKING markers, API removals, schema changes
127
+ 6. **Group by category** — assign each change to Features/Enhancements/Bug Fixes/Breaking/Other
128
+ 7. **Consolidate** — merge related items, remove duplicates and flip-flops
129
+ 8. **Format markdown** — generate clean bullet points with proper headings
130
+ 9. **Add footnotes** — include migration notes, setup requirements, important links
131
+
132
+ ---
133
+
134
+ ## Output Format
135
+
136
+ **Ultra-concise markdown** (aim for 100-200 words total):
137
+
138
+ ```markdown
139
+ # Release Notes - v1.1.0
140
+
141
+ ## New Features
142
+ - Dark mode toggle in settings
143
+ - PDF export option
144
+
145
+ ## Enhancements
146
+ - Improved search performance (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
+
156
+ **Learn more:**
157
+ - [Dark Mode Guide](https://docs.example.com/settings#dark-mode)
158
+ - [Upgrade Instructions](https://docs.example.com/upgrade#database)
159
+ ```
160
+
161
+ **Key Rules:**
162
+ - One line per bullet point
163
+ - No sub-bullets or elaborate descriptions
164
+ - Total length: <200 words
165
+ - User impact only (not implementation details)
166
+ - Use fragment identifiers (`#section-name`) to point to specific docs sections
167
+ - Multiple links OK if they point to different topics (Skill Analysis, Aggregation, etc.)
168
+ - Link from feature description → to exact readthedocs section where users will find details
169
+
170
+ ---
171
+
172
+ ## How to Use This Skill in a Session
173
+
174
+ **User Query:**
175
+ ```
176
+ Generate release notes from v2.1.0 to v2.2.0 for /path/to/my-app
177
+ ```
178
+
179
+ **Agent Workflow:**
180
+ 1. Navigate to repo: `cd /path/to/my-app`
181
+ 2. Fetch commits: `git log v2.1.0..v2.2.0 --oneline --no-merges`
182
+ 3. For each commit, examine changes: `git show <hash>`
183
+ 4. Interpret: What's the user impact? (not the code details)
184
+ 5. Categorize: Feature? Bug fix? Breaking change?
185
+ 6. Consolidate: Merge similar items
186
+ 7. Format: Clean markdown with categories
187
+ 8. Output: Save to RELEASE_NOTES.md
188
+
189
+ ---
190
+
191
+ ## Best Practices
192
+
193
+ ✅ **Do:**
194
+ - Read actual diffs to understand changes
195
+ - Use end-user language ("improved performance" not "optimized O(n) loop")
196
+ - Include breaking changes prominently
197
+ - Group related changes
198
+ - Add notes about migrations or setup
199
+
200
+ ❌ **Don't:**
201
+ - Copy commit messages verbatim
202
+ - Include function/variable names
203
+ - Mention internal refactors users won't notice
204
+ - Include secrets, passwords, or internal URLs
205
+ - Make up changes not shown in diffs
206
+
207
+ ---
208
+
209
+ ## Common Patterns
210
+
211
+ **Performance improvements:**
212
+ > "Improved search speed when filtering 1000+ records"
213
+
214
+ **New integrations:**
215
+ > "Added support for OAuth login via GitHub"
216
+
217
+ **Data format changes:**
218
+ > "Settings file now uses JSON instead of YAML (auto-converted on first run)"
219
+
220
+ **Removed features:**
221
+ > "Removed IE 11 support to modernize codebase"
222
+
223
+ **API changes:**
224
+ > "Changed user profile endpoint response format (see migration guide)"
225
+
226
+ ---
227
+
228
+ ## Limitations
229
+
230
+ - Requires git repository with proper tags
231
+ - Complex changes may need human interpretation
232
+ - Very large diffs (1000+ files) summarized by file count
233
+ - Works best with semantic versioning (v1.0.0 format)
234
+ - Needs meaningful commit messages for best results
@@ -7,6 +7,7 @@
7
7
  - **[README](README.md)** — User-facing overview and quickstart
8
8
  - **[CONTRIBUTING](CONTRIBUTING.md)** — Developer setup and conventions
9
9
  - **[.github/guidelines/knowledge-base.guidelines.md](.github/guidelines/knowledge-base.guidelines.md)** - How to use, update and maintain the knowledge base
10
+ - **[.github/guidelines/git-commit-message.guideline.md](.github/guidelines/git-commit-message.guideline.md)** — Commit message conventions
10
11
 
11
12
  ## Technology Stack
12
13
 
@@ -1,5 +1,18 @@
1
1
  ## Unreleased
2
2
 
3
+ ### Feat
4
+
5
+ - **cli**: add amend-commit command to inject session cost trailers
6
+
7
+ ## v0.4.0 (2026-07-08)
8
+
9
+ ### Feat
10
+
11
+ - skill-aware cost attribution and tool-call tracking
12
+ - add session filtering/aggregation/summaries/field extraction
13
+
14
+ ## v0.3.0 (2026-07-06)
15
+
3
16
  ## v0.2.3 (2026-07-03)
4
17
 
5
18
  ## v0.2.2 (2026-07-03)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: copilot-session-usage
3
- Version: 0.3.0
3
+ Version: 0.5.0
4
4
  Summary: Usage and cost analytics for GitHub Copilot and Copilot-CLI session logs
5
5
  Project-URL: Homepage, https://github.com/gsemet/copilot-session-usage
6
6
  Project-URL: Documentation, https://copilot-session-usage.readthedocs.io/en/stable/
@@ -11,6 +11,7 @@ License-Expression: MIT
11
11
  License-File: LICENSE
12
12
  Requires-Python: >=3.10
13
13
  Requires-Dist: click>=8.0
14
+ Requires-Dist: gitpython>=3.1.0
14
15
  Requires-Dist: ruamel-yaml>=0.18.0
15
16
  Description-Content-Type: text/markdown
16
17
 
@@ -49,6 +50,12 @@ copilot-session-usage list
49
50
 
50
51
  # Batch analyze the last 10 sessions
51
52
  copilot-session-usage batch 10
53
+
54
+ # Aggregate cost across all sessions matching a PRD path
55
+ copilot-session-usage analyze --name "PRD: /path/to/prd" --aggregate --format table
56
+
57
+ # List sessions in a debug-logs folder with cost columns
58
+ copilot-session-usage list --dir /path/to/debug-logs --format table
52
59
  ```
53
60
 
54
61
  ## Features
@@ -61,6 +68,14 @@ copilot-session-usage batch 10
61
68
  - **Three output formats** — `json` (default), `table`, `detailed`
62
69
  - **Three detail levels** — `minimal`, `compact`, `full`
63
70
  - **JSON and table output** — machine-readable or human-friendly
71
+ - **Session filtering** — regex match by name, date-range filtering
72
+ - **Aggregation** — roll up costs across many sessions in one command
73
+ - **Skill-aware cost attribution** — detect skills, attribute LLM and tool calls to the active skill
74
+ - **Skill cost breakdown** — per-skill token counts and estimated cost
75
+ - **Tool-call attribution** — per-skill/per-subagent tool-call counts
76
+ - **Title filtering** — find sessions by title substring
77
+ - **Efficiency summaries** — cache ratio, model split, cost per 1M tokens
78
+ - **Field extraction** — pull specific values with `--query`
64
79
 
65
80
  ## How it works
66
81
 
@@ -92,12 +107,30 @@ just knowledge-validate
92
107
 
93
108
  | Command | Description |
94
109
  |---------|-------------|
95
- | `analyze PATH` | Analyze one session by its debug-log directory |
110
+ | `analyze [PATH]` | Analyze one session by PATH, or many by `--name` regex |
96
111
  | `latest` | Analyze the most recently modified session |
97
112
  | `find TITLE` | Find and analyze a session by title (fuzzy match) |
98
113
  | `id SESSION_ID` | Analyze a session by exact UUID |
99
- | `list` | List recent sessions (metadata only, no cost) |
114
+ | `list` | List recent sessions (metadata only by default) |
100
115
  | `batch N` | Analyze the N most recent sessions in one pass |
116
+ | `skills` | List skills used across sessions with aggregated cost |
117
+
118
+ ### Analysis options
119
+
120
+ | Option | Description |
121
+ |--------|-------------|
122
+ | `--name REGEX` | Filter sessions by title/ID regex (case-insensitive) |
123
+ | `--title SUBSTRING` | Filter sessions by title substring (case-insensitive) |
124
+ | `--since DATE` | Only sessions created after DATE (ISO 8601 with timezone) |
125
+ | `--until DATE` | Only sessions created before DATE (ISO 8601 with timezone) |
126
+ | `--workspace PATH` | Only sessions from this workspace folder |
127
+ | `--aggregate` | Aggregate all matching sessions into one summary |
128
+ | `--summary` | Output a cost-efficiency summary |
129
+ | `--skill-breakdown` | Emit a per-skill cost breakdown |
130
+ | `--tool-breakdown` | Emit a per-skill/per-subagent tool-call count breakdown |
131
+ | `--skill NAME` | Filter the report to a single skill |
132
+ | `--query PATH` | Extract a single field with dot notation |
133
+ | `--query-help` | Print all `--query` field paths |
101
134
 
102
135
  ### Global options
103
136
 
@@ -143,10 +176,62 @@ Output: 22,166 tokens
143
176
  Cached: 1,224,340 (86%)
144
177
  LLM calls: 28
145
178
  Est. cost: $1.0880
179
+ # Per-skill cost breakdown
180
+ $ copilot-session-usage id 19e03be0-9cfa-4f21-a19a-4bdb754b3965 --skill-breakdown --format table
181
+ Per-Skill Breakdown:
182
+ Skill Input Cached Output Calls Cost
183
+ ----------------------------------------------------------------------------
184
+ /compendium-generic get-session-costs 1,137,864 1,015,825 15,729 24 $0.3636
185
+
186
+ # Per-skill/per-subagent tool-call counts
187
+ $ copilot-session-usage id 19e03be0-9cfa-4f21-a19a-4bdb754b3965 --tool-breakdown --format table
188
+ Tool Breakdown:
189
+ Tool Calls Skill Subagent
190
+ ---------------------------------------------------------------------------
191
+ read_file 25 /compendium-generic get-session-costs main
192
+ vscode_askQuestions 3 /compendium-generic get-session-costs main
193
+ runSubagent 1 /compendium-generic get-session-costs main
194
+
195
+ # Concise skill cost (great for scripts)
196
+ $ copilot-session-usage id 19e03be0-9cfa-4f21-a19a-4bdb754b3965 \
197
+ --skill "/compendium-generic get-session-costs" \
198
+ --format json --detail minimal
199
+ {
200
+ "skill": "/compendium-generic get-session-costs",
201
+ "cost_usd": 0.3636,
202
+ "input_tokens": 1137864,
203
+ "output_tokens": 15729,
204
+ "cached_tokens": 1015825,
205
+ "llm_calls": 24
206
+ }
207
+
208
+ # List skills used across the last 7 days
209
+ $ copilot-session-usage skills --last 7d --format table
210
+ Skills across 23 sessions:
211
+ Skill Sessions Input Output Cached Calls Cost
212
+ ---------------------------------------------------------------------------------------------------
213
+ /compendium-generic get-session-costs 3 1137864 15729 1015825 24 $0.3636
146
214
 
215
+ # Filter sessions by title substring
216
+ $ copilot-session-usage list --title "get-session-costs"
217
+ $ copilot-session-usage analyze --title "grill-me" --latest
147
218
  # Batch analyze last 5 sessions since July 1st
148
219
  copilot-session-usage batch 5 --since 2026-07-01
149
220
 
221
+ # Aggregate all PRD-related sessions from the last week
222
+ copilot-session-usage analyze \
223
+ --name "PRD: /path/to/prd" \
224
+ --since 2026-06-30T00:00:00Z \
225
+ --until 2026-07-07T00:00:00Z \
226
+ --aggregate \
227
+ --format table
228
+
229
+ # Cost-efficiency summary for a single session
230
+ copilot-session-usage analyze /path/to/debug-logs --summary --format table
231
+
232
+ # Extract just the total cost from a session
233
+ copilot-session-usage analyze /path/to/debug-logs --query .total.estimated_usd
234
+
150
235
  # WSL2: point to Windows host workspaceStorage
151
236
  copilot-session-usage latest \
152
237
  --workspace-storage /mnt/c/Users/$USER/AppData/Roaming/Code/User/workspaceStorage
@@ -155,7 +240,13 @@ copilot-session-usage latest \
155
240
  ## Python API
156
241
 
157
242
  ```python
158
- from copilot_session_usage.api import analyze_session, analyze_latest, batch_analyze
243
+ from copilot_session_usage.api import (
244
+ analyze_session,
245
+ analyze_latest,
246
+ batch_analyze,
247
+ aggregate_sessions,
248
+ list_sessions,
249
+ )
159
250
 
160
251
  # Analyze a session by path
161
252
  result = analyze_session(Path("/path/to/debug-logs"), detail="full")
@@ -165,6 +256,16 @@ result = analyze_latest(detail="compact")
165
256
 
166
257
  # Batch analyze the last 10 sessions
167
258
  batch = batch_analyze(10, detail="minimal")
259
+
260
+ # Aggregate multiple full analyses into one efficiency summary
261
+ aggregate = aggregate_sessions([result1, result2])
262
+
263
+ # List sessions with regex and date-range filtering
264
+ sessions = list_sessions(
265
+ name_pattern=r"PRD",
266
+ since="2026-07-01T00:00:00Z",
267
+ until="2026-07-07T00:00:00Z",
268
+ )
168
269
  ```
169
270
 
170
271
  ## Development