copilot-session-usage 0.2.0__tar.gz → 0.2.1__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 (102) hide show
  1. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/CHANGELOG.md +7 -3
  2. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/PKG-INFO +5 -2
  3. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/README.md +3 -0
  4. copilot_session_usage-0.2.1/docs/source/_static/changelog.js +25 -0
  5. copilot_session_usage-0.2.1/docs/source/_static/custom.css +142 -0
  6. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/docs/source/conf.py +4 -0
  7. copilot_session_usage-0.2.1/docs/source/explanation/how-cost-estimation-works.md +96 -0
  8. copilot_session_usage-0.2.1/docs/source/explanation/index.md +9 -0
  9. copilot_session_usage-0.2.1/docs/source/how-to/analyze-specific-session.md +46 -0
  10. copilot_session_usage-0.2.1/docs/source/how-to/batch-and-spending.md +64 -0
  11. copilot_session_usage-0.2.1/docs/source/how-to/export-json.md +65 -0
  12. copilot_session_usage-0.2.1/docs/source/how-to/index.md +12 -0
  13. copilot_session_usage-0.2.1/docs/source/how-to/wsl2.md +37 -0
  14. copilot_session_usage-0.2.1/docs/source/index.md +66 -0
  15. copilot_session_usage-0.2.1/docs/source/installation.md +42 -0
  16. copilot_session_usage-0.2.1/docs/source/reference/api.md +18 -0
  17. copilot_session_usage-0.2.1/docs/source/reference/index.md +11 -0
  18. copilot_session_usage-0.2.1/docs/source/reference/pricing.md +62 -0
  19. copilot_session_usage-0.2.1/docs/source/tutorials/getting-started.md +129 -0
  20. copilot_session_usage-0.2.1/docs/source/tutorials/index.md +9 -0
  21. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/justfile +14 -0
  22. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/concepts/copilot-cli.md +3 -0
  23. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/concepts/index.md +3 -1
  24. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/concepts/overview.md +3 -1
  25. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/concepts/session-cost-analysis.md +3 -1
  26. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/concepts/threshold-based-pricing.md +3 -1
  27. copilot_session_usage-0.2.1/knowledge/experiments/index.md +5 -0
  28. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/experiments/verify-subagent-cost-attribution.md +6 -4
  29. copilot_session_usage-0.2.1/knowledge/findings/index.md +5 -0
  30. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/findings/subagent-logs-use-runsubagent-prefix.md +2 -0
  31. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/guides/automation-scripts.md +2 -0
  32. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/guides/cost-optimization.md +2 -0
  33. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/guides/index.md +3 -1
  34. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/guides/wsl2-setup.md +3 -1
  35. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/ideas/index.md +3 -1
  36. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/ideas/multi-session-efficiency-analytics.md +3 -1
  37. copilot_session_usage-0.2.1/knowledge/index.md +16 -0
  38. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/principles/findings-are-immutable.md +3 -1
  39. copilot_session_usage-0.2.1/knowledge/principles/index.md +5 -0
  40. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/reference/debug-log-format.md +6 -1
  41. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/reference/index.md +3 -1
  42. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/reference/pricing-formats.md +3 -1
  43. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/structures/index.md +3 -1
  44. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/structures/knowledge-base-information-types.md +3 -1
  45. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/structures/session-discovery-algorithm.md +3 -1
  46. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/structures/subagent-cost-tracking.md +4 -1
  47. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/structures/vscode-copilot-extension.md +4 -1
  48. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/pyproject.toml +4 -2
  49. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/uv.lock +56 -4
  50. copilot_session_usage-0.2.0/docs/source/api.md +0 -19
  51. copilot_session_usage-0.2.0/docs/source/index.md +0 -41
  52. copilot_session_usage-0.2.0/knowledge/experiments/index.md +0 -3
  53. copilot_session_usage-0.2.0/knowledge/findings/index.md +0 -3
  54. copilot_session_usage-0.2.0/knowledge/index.md +0 -14
  55. copilot_session_usage-0.2.0/knowledge/principles/index.md +0 -3
  56. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/.editorconfig +0 -0
  57. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  58. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  59. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/.github/guidelines/knowledge-base.guidelines.md +0 -0
  60. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/.github/pull_request_template.md +0 -0
  61. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/.github/skills/consolidate-knowledge-base/SKILL.md +0 -0
  62. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/.github/skills/record-finding/SKILL.md +0 -0
  63. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/.github/workflows/ci.yml +0 -0
  64. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/.github/workflows/publish.yml +0 -0
  65. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/.gitignore +0 -0
  66. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/.readthedocs.yaml +0 -0
  67. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/AGENTS.md +0 -0
  68. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/CONTRIBUTING.md +0 -0
  69. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/LICENSE +0 -0
  70. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/docs/source/changelog.md +0 -0
  71. {copilot_session_usage-0.2.0/docs/source → copilot_session_usage-0.2.1/docs/source/reference}/cli.md +0 -0
  72. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/_schema/Base.schema.yaml +0 -0
  73. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/_schema/Concept.schema.yaml +0 -0
  74. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/_schema/Experiment.schema.yaml +0 -0
  75. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/_schema/Finding.schema.yaml +0 -0
  76. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/_schema/Playbook.schema.yaml +0 -0
  77. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/_schema/Principle.schema.yaml +0 -0
  78. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/_schema/Reference.schema.yaml +0 -0
  79. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/_schema/Structure.schema.yaml +0 -0
  80. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/knowledge/log.md +0 -0
  81. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/scripts/refresh_pricing.py +0 -0
  82. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/skills/copilot-session-usage/SKILL.md +0 -0
  83. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/src/copilot_session_usage/__init__.py +0 -0
  84. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/src/copilot_session_usage/_internal/__init__.py +0 -0
  85. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/src/copilot_session_usage/_internal/copilot_cli.py +0 -0
  86. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/src/copilot_session_usage/_internal/core.py +0 -0
  87. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/src/copilot_session_usage/_internal/vscode.py +0 -0
  88. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/src/copilot_session_usage/api.py +0 -0
  89. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/src/copilot_session_usage/cli.py +0 -0
  90. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/src/copilot_session_usage/data/__init__.py +0 -0
  91. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/src/copilot_session_usage/data/custom-models-pricing.yml +0 -0
  92. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/src/copilot_session_usage/data/models-and-pricing.lock +0 -0
  93. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/src/copilot_session_usage/data/models-and-pricing.yml +0 -0
  94. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/tests/conftest.py +0 -0
  95. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/tests/test_api.py +0 -0
  96. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/tests/test_cli.py +0 -0
  97. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/tests/test_core.py +0 -0
  98. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/tests/test_coverage_gaps.py +0 -0
  99. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/tests/test_rendering.py +0 -0
  100. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/tests/test_vscode.py +0 -0
  101. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/tests/test_vscode_platform.py +0 -0
  102. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.1}/uv.toml +0 -0
@@ -1,9 +1,13 @@
1
1
  ## Unreleased
2
2
 
3
- ### Feat
4
-
5
- - initial implementation
3
+ ## v0.2.0 (2026-07-02)
6
4
 
7
5
  ### Fix
8
6
 
9
7
  - bad cost compuation for Opus 4.8
8
+
9
+ ## v0.1.0 (2026-07-02)
10
+
11
+ ### Feat
12
+
13
+ - initial implementation
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: copilot-session-usage
3
- Version: 0.2.0
3
+ Version: 0.2.1
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
- Project-URL: Documentation, https://copilot-session-usage.readthedocs.io
6
+ Project-URL: Documentation, https://copilot-session-usage.readthedocs.io/en/stable/
7
7
  Project-URL: Repository, https://github.com/gsemet/copilot-session-usage
8
8
  Project-URL: Issues, https://github.com/gsemet/copilot-session-usage/issues
9
9
  Author-email: Gaetan Semet <gaetan@xeberon.net>
@@ -20,6 +20,7 @@ Description-Content-Type: text/markdown
20
20
  [![Coverage](https://img.shields.io/codecov/c/github/gsemet/copilot-session-usage)](https://codecov.io/gh/gsemet/copilot-session-usage)
21
21
  [![PyPI](https://img.shields.io/pypi/v/copilot-session-usage)](https://pypi.org/project/copilot-session-usage/)
22
22
  [![Python Versions](https://img.shields.io/pypi/pyversions/copilot-session-usage)](https://pypi.org/project/copilot-session-usage/)
23
+ [![Docs](https://readthedocs.org/projects/copilot-session-usage/badge/?version=stable)](https://copilot-session-usage.readthedocs.io/en/stable/)
23
24
  [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
24
25
  [![Type checked](https://img.shields.io/badge/type%20checked-mypy%2Fty-blue.svg)](./)
25
26
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
@@ -182,6 +183,8 @@ just docs
182
183
  just docs-serve
183
184
  ```
184
185
 
186
+ **Full documentation:** [copilot-session-usage.readthedocs.io](https://copilot-session-usage.readthedocs.io/)
187
+
185
188
  ## License
186
189
 
187
190
  MIT — see [LICENSE](LICENSE).
@@ -4,6 +4,7 @@
4
4
  [![Coverage](https://img.shields.io/codecov/c/github/gsemet/copilot-session-usage)](https://codecov.io/gh/gsemet/copilot-session-usage)
5
5
  [![PyPI](https://img.shields.io/pypi/v/copilot-session-usage)](https://pypi.org/project/copilot-session-usage/)
6
6
  [![Python Versions](https://img.shields.io/pypi/pyversions/copilot-session-usage)](https://pypi.org/project/copilot-session-usage/)
7
+ [![Docs](https://readthedocs.org/projects/copilot-session-usage/badge/?version=stable)](https://copilot-session-usage.readthedocs.io/en/stable/)
7
8
  [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
8
9
  [![Type checked](https://img.shields.io/badge/type%20checked-mypy%2Fty-blue.svg)](./)
9
10
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
@@ -166,6 +167,8 @@ just docs
166
167
  just docs-serve
167
168
  ```
168
169
 
170
+ **Full documentation:** [copilot-session-usage.readthedocs.io](https://copilot-session-usage.readthedocs.io/)
171
+
169
172
  ## License
170
173
 
171
174
  MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,25 @@
1
+ /* Rewrite changelog category headings */
2
+ document.addEventListener('DOMContentLoaded', function () {
3
+ const map = {
4
+ 'Feat': '✨ Features',
5
+ 'Fix': '🔧 Bug Fixes',
6
+ 'Docs': '📚 Documentation',
7
+ 'Chore': '🧹 Chores',
8
+ 'Refactor': '🛠 Refactors',
9
+ 'Test': '🧪 Tests',
10
+ 'CI': '🤖 CI',
11
+ 'Perf': '⚡ Performance',
12
+ 'Build': '🏗 Build',
13
+ 'Style': '🎨 Styles',
14
+ };
15
+
16
+ document.querySelectorAll('h3').forEach(function (h3) {
17
+ const text = h3.childNodes[0];
18
+ if (text && text.nodeType === Node.TEXT_NODE) {
19
+ const trimmed = text.textContent.trim();
20
+ if (map[trimmed]) {
21
+ text.textContent = ' ' + map[trimmed] + ' ';
22
+ }
23
+ }
24
+ });
25
+ });
@@ -0,0 +1,142 @@
1
+ /* Custom styles for copilot-session-usage documentation */
2
+
3
+ /* ── Changelog ── */
4
+ #changelog h2 {
5
+ font-size: 1.4em;
6
+ font-weight: 600;
7
+ margin-top: 2.5em;
8
+ padding-bottom: 0.4em;
9
+ border-bottom: 1px solid var(--color-background-border);
10
+ }
11
+
12
+ #changelog h2:first-of-type {
13
+ margin-top: 0.5em;
14
+ }
15
+
16
+ #changelog h2#unreleased {
17
+ color: var(--color-brand-primary);
18
+ }
19
+
20
+ #changelog h3 {
21
+ font-size: 0.8em;
22
+ font-weight: 600;
23
+ text-transform: uppercase;
24
+ letter-spacing: 0.08em;
25
+ margin: 1.5em 0 0.6em;
26
+ padding: 0.3rem 0.6rem;
27
+ display: inline-block;
28
+ }
29
+
30
+ /* Features */
31
+ #changelog section[id="feat"] > h3,
32
+ #changelog section[id="id1"] > h3,
33
+ #changelog section[id="id4"] > h3,
34
+ #changelog section[id="id6"] > h3,
35
+ #changelog section[id="id8"] > h3,
36
+ #changelog section[id="id10"] > h3 {
37
+ font-size: 0;
38
+ color: transparent;
39
+ background: rgba(26, 127, 55, 0.08);
40
+ }
41
+
42
+ #changelog section[id="feat"] > h3::before,
43
+ #changelog section[id="id1"] > h3::before,
44
+ #changelog section[id="id4"] > h3::before,
45
+ #changelog section[id="id6"] > h3::before,
46
+ #changelog section[id="id8"] > h3::before,
47
+ #changelog section[id="id10"] > h3::before {
48
+ content: "✨ Features";
49
+ font-size: 0.8rem;
50
+ color: #1a7f37;
51
+ }
52
+
53
+ /* Bug Fixes */
54
+ #changelog section[id="fix"] > h3,
55
+ #changelog section[id="id2"] > h3,
56
+ #changelog section[id="id3"] > h3,
57
+ #changelog section[id="id5"] > h3,
58
+ #changelog section[id="id7"] > h3,
59
+ #changelog section[id="id9"] > h3 {
60
+ font-size: 0;
61
+ color: transparent;
62
+ background: rgba(154, 103, 0, 0.08);
63
+ }
64
+
65
+ #changelog section[id="fix"] > h3::before,
66
+ #changelog section[id="id2"] > h3::before,
67
+ #changelog section[id="id3"] > h3::before,
68
+ #changelog section[id="id5"] > h3::before,
69
+ #changelog section[id="id7"] > h3::before,
70
+ #changelog section[id="id9"] > h3::before {
71
+ content: "🔧 Bug Fixes";
72
+ font-size: 0.8rem;
73
+ color: #9a6700;
74
+ }
75
+
76
+ #changelog ul {
77
+ margin-top: 0.5em;
78
+ padding-left: 1.2em;
79
+ }
80
+
81
+ #changelog li {
82
+ margin-bottom: 0.35em;
83
+ line-height: 1.6;
84
+ }
85
+
86
+ /* ── Landing page cards ── */
87
+ .sd-card {
88
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
89
+ }
90
+
91
+ .sd-card:hover {
92
+ transform: translateY(-2px);
93
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
94
+ }
95
+
96
+ /* ── Copy button ── */
97
+ button.copybtn {
98
+ opacity: 0.6;
99
+ transition: opacity 0.2s;
100
+ }
101
+
102
+ button.copybtn:hover {
103
+ opacity: 1;
104
+ }
105
+
106
+ /* ── CLI tables ── */
107
+ table.docutils {
108
+ font-size: 0.95em;
109
+ }
110
+
111
+ table.docutils th {
112
+ background: var(--color-background-secondary);
113
+ }
114
+
115
+ /* ── API signatures ── */
116
+ dl.py.function,
117
+ dl.py.class,
118
+ dl.py.method {
119
+ margin: 1.5em 0;
120
+ }
121
+
122
+ dl.py.function > dd,
123
+ dl.py.class > dd,
124
+ dl.py.method > dd {
125
+ margin-left: 0;
126
+ padding-left: 1em;
127
+ }
128
+
129
+ dt.sig.sig-object.py {
130
+ background: var(--color-background-secondary);
131
+ border-left: 3px solid var(--color-brand-primary);
132
+ border-radius: 0;
133
+ margin-left: 0;
134
+ margin-right: 0;
135
+ padding: 0.6em 0.8em;
136
+ line-height: 1.6;
137
+ text-indent: 0;
138
+ }
139
+
140
+ dl.py.class > dt.sig.sig-object.py {
141
+ border-left-color: var(--color-brand-content);
142
+ }
@@ -17,6 +17,8 @@ extensions = [
17
17
  "sphinx.ext.napoleon",
18
18
  "sphinx_click",
19
19
  "sphinx_autodoc_typehints",
20
+ "sphinx_design",
21
+ "sphinx_copybutton",
20
22
  ]
21
23
 
22
24
  myst_enable_extensions = ["colon_fence", "deflist"]
@@ -24,6 +26,8 @@ myst_enable_extensions = ["colon_fence", "deflist"]
24
26
  html_theme = "furo"
25
27
  html_title = f"copilot-session-usage {version}"
26
28
  html_static_path = ["_static"]
29
+ html_css_files = ["custom.css"]
30
+ html_js_files = ["changelog.js"]
27
31
 
28
32
  autodoc_member_order = "bysource"
29
33
  autodoc_typehints = "description"
@@ -0,0 +1,96 @@
1
+ # How Cost Estimation Works
2
+
3
+ `copilot-session-usage` estimates session costs from VS Code debug logs.
4
+ This page explains each step.
5
+
6
+ ---
7
+
8
+ ## Where the logs live
9
+
10
+ VS Code stores one directory per workspace under `workspaceStorage`. Inside
11
+ each workspace directory, the Copilot extension writes debug logs:
12
+
13
+ ```
14
+ workspaceStorage/
15
+ └── <workspace-hash>/
16
+ └── GitHub.copilot-chat/
17
+ └── debug-logs/
18
+ └── <session-uuid>/
19
+ ├── *.jsonl ← token events
20
+ └── ...
21
+ ```
22
+
23
+ Default locations by platform:
24
+
25
+ | Platform | Path |
26
+ |----------|------|
27
+ | macOS | `~/Library/Application Support/Code/User/workspaceStorage/` |
28
+ | Linux | `~/.config/Code/User/workspaceStorage/` |
29
+ | Windows | `%APPDATA%\Code\User\workspaceStorage\` |
30
+ | WSL2 (remote) | `~/.vscode-server/data/User/workspaceStorage/` |
31
+
32
+ The tool also checks `Code - Insiders` variants automatically.
33
+
34
+ ---
35
+
36
+ ## How sessions are discovered
37
+
38
+ The tool reads the session title from VS Code's SQLite workspace database
39
+ (`state.vscdb`). Sessions are sorted by the last-modified time of their
40
+ debug-log directory, most recent first.
41
+
42
+ The `list` command reads only metadata (no JSONL parsing). The `analyze`,
43
+ `id`, and `batch` commands parse the full JSONL files.
44
+
45
+ ---
46
+
47
+ ## Parsing JSONL logs
48
+
49
+ Each `.jsonl` file contains one JSON object per line. The tool extracts
50
+ token-count events emitted by the Copilot extension for each LLM call:
51
+
52
+ - `input_tokens` — tokens sent to the model
53
+ - `output_tokens` — tokens generated by the model
54
+ - `cached_tokens` — input tokens served from the provider's prompt cache
55
+ - `model` — the model name as reported by the provider
56
+
57
+ A single session may call multiple models (e.g., Claude Sonnet for the main
58
+ request and Claude Haiku for a subagent). Each model's tokens are summed
59
+ separately, then costs are computed per model and aggregated.
60
+
61
+ ---
62
+
63
+ ## Cost calculation
64
+
65
+ For each model, cost is computed as:
66
+
67
+ ```
68
+ cost = (input_tokens - cached_tokens) / 1_000_000 × input_price
69
+ + cached_tokens / 1_000_000 × cached_input_price
70
+ + output_tokens / 1_000_000 × output_price
71
+ ```
72
+
73
+ Prices come from the bundled `models-and-pricing.yml`. For models with
74
+ long-context tier switching (e.g., GPT-5.4 above 272K tokens), the tool
75
+ selects the correct price row automatically.
76
+
77
+ ---
78
+
79
+ ## Subagent attribution
80
+
81
+ `runSubagent` calls appear in the JSONL as a distinct event type. The tool
82
+ tracks them separately so `--detail full` can show which fraction of tokens
83
+ was consumed by subagents vs. the main conversation.
84
+
85
+ ---
86
+
87
+ ## Accuracy
88
+
89
+ Prices match the published GitHub Copilot per-token rates for each model.
90
+ The tool applies the same formula GitHub uses: input tokens (minus cached)
91
+ at the full input rate, cached tokens at the cache-hit rate, output tokens
92
+ at the output rate. Long-context tier switching is automatic.
93
+
94
+ The main source of variance is pricing lag: the bundled table is updated
95
+ manually with each release. Run `just refresh-pricing` to pull the latest
96
+ rates.
@@ -0,0 +1,9 @@
1
+ # How It Works
2
+
3
+ Background and design notes.
4
+
5
+ ```{toctree}
6
+ :maxdepth: 1
7
+
8
+ how-cost-estimation-works
9
+ ```
@@ -0,0 +1,46 @@
1
+ # Analyze a Specific Session
2
+
3
+ Use this when you know the path to a session's debug-log directory or its UUID,
4
+ and `latest` would pick the wrong session.
5
+
6
+ ## By debug-log path
7
+
8
+ Each session is a directory inside VS Code's `workspaceStorage`:
9
+
10
+ ```bash
11
+ copilot-session-usage analyze \
12
+ "/path/to/workspaceStorage/<hash>/GitHub.copilot-chat/debug-logs/<session-uuid>"
13
+ ```
14
+
15
+ The path always ends in a UUID directory. Use `list` to find the right one if
16
+ you're unsure.
17
+
18
+ ## By UUID
19
+
20
+ If you have a session ID from a previous `list` or `find` run:
21
+
22
+ ```bash
23
+ copilot-session-usage id 3a91c012-1b4e-4c8a-9f72-ab12cd34ef56
24
+ ```
25
+
26
+ The tool searches all workspaceStorage roots automatically.
27
+
28
+ ## By title substring
29
+
30
+ ```bash
31
+ copilot-session-usage find "CI pipeline"
32
+ ```
33
+
34
+ Matching is case-insensitive substring search. If multiple sessions match,
35
+ the tool lists them and exits without analyzing — then use `id` to pick one.
36
+
37
+ ## Locating workspaceStorage manually
38
+
39
+ | Platform | Default path |
40
+ |----------|-------------|
41
+ | macOS | `~/Library/Application Support/Code/User/workspaceStorage/` |
42
+ | Linux | `~/.config/Code/User/workspaceStorage/` |
43
+ | Windows | `%APPDATA%\Code\User\workspaceStorage\` |
44
+
45
+ Each subdirectory under `workspaceStorage/` corresponds to one VS Code workspace.
46
+ Inside it, `GitHub.copilot-chat/debug-logs/` contains one directory per session.
@@ -0,0 +1,64 @@
1
+ # Track Spending Over Time
2
+
3
+ Use `batch` with `--since` to aggregate costs for a time window.
4
+
5
+ ## Daily cost report
6
+
7
+ ```bash
8
+ # All sessions today
9
+ copilot-session-usage batch 50 --since $(date +%Y-%m-%d)
10
+ ```
11
+
12
+ ## Weekly report
13
+
14
+ ```bash
15
+ copilot-session-usage batch 100 --since 2026-06-25
16
+ ```
17
+
18
+ Sample output:
19
+
20
+ ```
21
+ Sessions analyzed: 23
22
+ Total input: 8,412,304 tokens
23
+ Total output: 142,887 tokens
24
+ Total cached: 7,103,220 (84%)
25
+ Total LLM calls: 312
26
+ Est. total cost: $11.74
27
+
28
+ Session Started Cost
29
+ Implement new feature X 2026-07-02 09:14Z $0.42
30
+ Debug failing CI pipeline 2026-07-01 18:03Z $1.87
31
+ ...
32
+ ```
33
+
34
+ ## Save to a file and diff
35
+
36
+ ```bash
37
+ copilot-session-usage batch 100 --since 2026-07-01 \
38
+ --format json --output july-costs.json
39
+ ```
40
+
41
+ Then open `july-costs.json` in any tool that understands JSON arrays.
42
+
43
+ ## Filter by workspace
44
+
45
+ If you work in multiple repositories, limit the report to one workspace:
46
+
47
+ ```bash
48
+ copilot-session-usage batch 50 \
49
+ --since 2026-07-01 \
50
+ --workspace-filter myproject
51
+ ```
52
+
53
+ `--workspace-filter` matches against the workspace folder name (substring,
54
+ case-insensitive).
55
+
56
+ ## Automate with cron (macOS/Linux)
57
+
58
+ ```bash
59
+ # ~/.zshrc or crontab -e
60
+ # Run every Sunday at 23:55, append weekly cost to a log
61
+ 55 23 * * 0 copilot-session-usage batch 200 \
62
+ --since $(date -v-7d +%Y-%m-%d) \
63
+ --format json >> ~/copilot-costs.jsonl
64
+ ```
@@ -0,0 +1,65 @@
1
+ # Export to JSON
2
+
3
+ Use `--format json` to get machine-readable output for scripting, dashboards,
4
+ or storage.
5
+
6
+ ## Write to stdout
7
+
8
+ ```bash
9
+ copilot-session-usage latest --format json
10
+ ```
11
+
12
+ ## Write to a file
13
+
14
+ ```bash
15
+ copilot-session-usage latest --format json --output session.json
16
+ ```
17
+
18
+ ## Extract a single field with jq
19
+
20
+ ```bash
21
+ # Estimated cost
22
+ copilot-session-usage latest --format json | jq '.estimated_cost_usd'
23
+
24
+ # All model names called in the session
25
+ copilot-session-usage latest --format json | jq '[.models[].model]'
26
+
27
+ # Total cached tokens
28
+ copilot-session-usage latest --format json | jq '.total_cached_tokens'
29
+ ```
30
+
31
+ ## Batch export
32
+
33
+ Export the last 20 sessions as a single JSON document:
34
+
35
+ ```bash
36
+ copilot-session-usage batch 20 --format json --output week.json
37
+ ```
38
+
39
+ The document has two top-level keys: `summary` (aggregate) and `sessions`
40
+ (per-session list).
41
+
42
+ ```bash
43
+ # Total cost across all sessions
44
+ cat week.json | jq '.summary.estimated_cost_usd'
45
+
46
+ # Cost per session, sorted descending
47
+ cat week.json | jq '[.sessions[] | {title, cost: .estimated_cost_usd}] | sort_by(-.cost)'
48
+ ```
49
+
50
+ ## Use with the Python API
51
+
52
+ ```python
53
+ from pathlib import Path
54
+ from copilot_session_usage.api import analyze_latest, batch_analyze
55
+ import json
56
+
57
+ # Latest session as a dict
58
+ result = analyze_latest(detail="full")
59
+ print(json.dumps(result, indent=2))
60
+
61
+ # Last 10 sessions
62
+ batch = batch_analyze(10, detail="compact")
63
+ for s in batch["sessions"]:
64
+ print(f"{s['title']}: ${s['estimated_cost_usd']:.4f}")
65
+ ```
@@ -0,0 +1,12 @@
1
+ # How-To Guides
2
+
3
+ Task-oriented recipes for common workflows.
4
+
5
+ ```{toctree}
6
+ :maxdepth: 1
7
+
8
+ analyze-specific-session
9
+ export-json
10
+ batch-and-spending
11
+ wsl2
12
+ ```
@@ -0,0 +1,37 @@
1
+ # Use from WSL2
2
+
3
+ On WSL2, VS Code runs on Windows and stores debug logs in the Windows filesystem.
4
+ Point the tool at the Windows path via `/mnt/c/`.
5
+
6
+ ## Basic usage
7
+
8
+ ```bash
9
+ copilot-session-usage latest \
10
+ --workspace-storage "/mnt/c/Users/$USER/AppData/Roaming/Code/User/workspaceStorage"
11
+ ```
12
+
13
+ ## Make it permanent
14
+
15
+ Add an alias to `~/.bashrc` or `~/.zshrc`:
16
+
17
+ ```bash
18
+ alias copilot-session-usage='copilot-session-usage \
19
+ --workspace-storage "/mnt/c/Users/$USER/AppData/Roaming/Code/User/workspaceStorage"'
20
+ ```
21
+
22
+ ## Verify the path
23
+
24
+ If the Windows username differs from your WSL username, substitute it directly:
25
+
26
+ ```bash
27
+ ls "/mnt/c/Users/MyWindowsName/AppData/Roaming/Code/User/workspaceStorage"
28
+ ```
29
+
30
+ You should see directories named with long hex hashes.
31
+
32
+ ## VS Code Server (Remote - WSL extension)
33
+
34
+ When using the VS Code Remote - WSL extension, VS Code runs in WSL and stores
35
+ logs in the Linux filesystem at the default location
36
+ (`~/.config/Code/User/workspaceStorage/`). No `--workspace-storage` override
37
+ is needed in this case.
@@ -0,0 +1,66 @@
1
+ # copilot-session-usage
2
+
3
+ **copilot-session-usage** reads VS Code Copilot debug logs and tells you
4
+ how much each AI coding session cost in USD.
5
+
6
+ VS Code does not show session costs in its UI. The debug logs contain
7
+ token counts per model. This tool reads those logs, applies the real
8
+ published pricing (with cache discounts and long-context tiers), and
9
+ prints a cost report in seconds.
10
+
11
+ The most common use: after a heavy agentic session, run
12
+ `copilot-session-usage latest` to see what it cost.
13
+
14
+ ::::{grid} 1 1 2 2
15
+ :gutter: 3
16
+
17
+ :::{grid-item-card} 📦 Installation
18
+ :link: installation
19
+ :link-type: doc
20
+
21
+ Install `copilot-session-usage` with uv or pip.
22
+ :::
23
+
24
+ :::{grid-item-card} 🚀 Getting Started
25
+ :link: tutorials/getting-started
26
+ :link-type: doc
27
+
28
+ Analyze your first session and understand the output in under 5 minutes.
29
+ :::
30
+
31
+ :::{grid-item-card} 📖 How-To Guides
32
+ :link: how-to/index
33
+ :link-type: doc
34
+
35
+ Export to JSON, track spending over time, integrate in scripts,
36
+ and configure WSL2.
37
+ :::
38
+
39
+ :::{grid-item-card} 📚 Reference
40
+ :link: reference/index
41
+ :link-type: doc
42
+
43
+ Complete CLI and Python API documentation.
44
+ :::
45
+
46
+ :::{grid-item-card} 💡 How It Works
47
+ :link: explanation/how-cost-estimation-works
48
+ :link-type: doc
49
+
50
+ Where the logs live, how tokens are counted,
51
+ and how pricing tiers are applied.
52
+ :::
53
+
54
+ ::::
55
+
56
+ ```{toctree}
57
+ :maxdepth: 2
58
+ :hidden:
59
+
60
+ Installation <installation>
61
+ Tutorials <tutorials/index>
62
+ How-To <how-to/index>
63
+ Reference <reference/index>
64
+ How It Works <explanation/index>
65
+ Changelog <changelog>
66
+ ```
@@ -0,0 +1,42 @@
1
+ # Installation
2
+
3
+ **copilot-session-usage** is published to PyPI and works on macOS, Linux, and Windows.
4
+
5
+ ## With uv (recommended)
6
+
7
+ ```bash
8
+ uv tool install copilot-session-usage
9
+ ```
10
+
11
+ ## With pip
12
+
13
+ ```bash
14
+ pip install copilot-session-usage
15
+ ```
16
+
17
+ ## Verify
18
+
19
+ ```bash
20
+ copilot-session-usage --version
21
+ ```
22
+
23
+ ## Upgrade (uv)
24
+
25
+ ```bash
26
+ uv tool install --upgrade copilot-session-usage
27
+ ```
28
+
29
+ ## As a library
30
+
31
+ Install as a Python library for use in scripts or notebooks:
32
+
33
+ ```bash
34
+ uv add copilot-session-usage
35
+ # or
36
+ pip install copilot-session-usage
37
+ ```
38
+
39
+ ## Next steps
40
+
41
+ - [Getting Started](tutorials/getting-started) — analyze your first session
42
+ - [How-To Guides](how-to/index) — export to JSON, track spending over time