copilot-session-usage 0.2.0__tar.gz → 0.2.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 (111) hide show
  1. copilot_session_usage-0.2.2/CHANGELOG.md +19 -0
  2. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/PKG-INFO +5 -2
  3. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/README.md +3 -0
  4. copilot_session_usage-0.2.2/docs/source/_static/changelog.js +25 -0
  5. copilot_session_usage-0.2.2/docs/source/_static/custom.css +142 -0
  6. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/docs/source/conf.py +4 -0
  7. copilot_session_usage-0.2.2/docs/source/explanation/how-cost-estimation-works.md +138 -0
  8. copilot_session_usage-0.2.2/docs/source/explanation/index.md +9 -0
  9. copilot_session_usage-0.2.2/docs/source/how-to/analyze-specific-session.md +46 -0
  10. copilot_session_usage-0.2.2/docs/source/how-to/batch-and-spending.md +64 -0
  11. copilot_session_usage-0.2.2/docs/source/how-to/export-json.md +65 -0
  12. copilot_session_usage-0.2.2/docs/source/how-to/index.md +12 -0
  13. copilot_session_usage-0.2.2/docs/source/how-to/wsl2.md +37 -0
  14. copilot_session_usage-0.2.2/docs/source/index.md +66 -0
  15. copilot_session_usage-0.2.2/docs/source/installation.md +42 -0
  16. copilot_session_usage-0.2.2/docs/source/reference/api.md +18 -0
  17. copilot_session_usage-0.2.2/docs/source/reference/index.md +11 -0
  18. copilot_session_usage-0.2.2/docs/source/reference/pricing.md +122 -0
  19. copilot_session_usage-0.2.2/docs/source/tutorials/getting-started.md +129 -0
  20. copilot_session_usage-0.2.2/docs/source/tutorials/index.md +9 -0
  21. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/justfile +15 -0
  22. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/_schema/Base.schema.yaml +10 -1
  23. copilot_session_usage-0.2.2/knowledge/_schema/Experiment.schema.yaml +44 -0
  24. copilot_session_usage-0.2.2/knowledge/_schema/Finding.schema.yaml +49 -0
  25. copilot_session_usage-0.2.2/knowledge/_schema/Principle.schema.yaml +25 -0
  26. copilot_session_usage-0.2.2/knowledge/_schema/Structure.schema.yaml +26 -0
  27. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/concepts/copilot-cli.md +3 -0
  28. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/concepts/index.md +3 -1
  29. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/concepts/overview.md +5 -3
  30. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/concepts/session-cost-analysis.md +3 -1
  31. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/concepts/threshold-based-pricing.md +3 -1
  32. copilot_session_usage-0.2.2/knowledge/experiments/index.md +5 -0
  33. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/experiments/verify-subagent-cost-attribution.md +8 -5
  34. copilot_session_usage-0.2.2/knowledge/findings/cache-write-cost-not-tracked.md +83 -0
  35. copilot_session_usage-0.2.2/knowledge/findings/index.md +7 -0
  36. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/findings/subagent-logs-use-runsubagent-prefix.md +2 -0
  37. copilot_session_usage-0.2.2/knowledge/findings/title-jsonl-not-counted-as-model-turn.md +50 -0
  38. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/guides/automation-scripts.md +2 -0
  39. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/guides/cost-optimization.md +2 -0
  40. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/guides/index.md +3 -1
  41. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/guides/wsl2-setup.md +3 -1
  42. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/ideas/index.md +3 -1
  43. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/ideas/multi-session-efficiency-analytics.md +3 -1
  44. copilot_session_usage-0.2.2/knowledge/index.md +16 -0
  45. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/principles/findings-are-immutable.md +3 -1
  46. copilot_session_usage-0.2.2/knowledge/principles/index.md +5 -0
  47. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/reference/debug-log-format.md +9 -3
  48. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/reference/index.md +3 -1
  49. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/reference/pricing-formats.md +3 -1
  50. copilot_session_usage-0.2.2/knowledge/structures/cache-cost-approximation.md +86 -0
  51. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/structures/index.md +4 -1
  52. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/structures/knowledge-base-information-types.md +3 -1
  53. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/structures/session-discovery-algorithm.md +3 -1
  54. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/structures/subagent-cost-tracking.md +16 -5
  55. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/structures/vscode-copilot-extension.md +12 -1
  56. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/pyproject.toml +4 -2
  57. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/_internal/core.py +53 -14
  58. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/_internal/vscode.py +54 -0
  59. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/api.py +7 -1
  60. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/cli.py +5 -0
  61. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/data/custom-models-pricing.yml +3 -2
  62. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/tests/conftest.py +4 -6
  63. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/tests/test_api.py +100 -109
  64. copilot_session_usage-0.2.2/tests/test_cli.py +280 -0
  65. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/tests/test_coverage_gaps.py +32 -33
  66. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/tests/test_vscode.py +42 -0
  67. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/uv.lock +56 -4
  68. copilot_session_usage-0.2.0/CHANGELOG.md +0 -9
  69. copilot_session_usage-0.2.0/docs/source/api.md +0 -19
  70. copilot_session_usage-0.2.0/docs/source/index.md +0 -41
  71. copilot_session_usage-0.2.0/knowledge/_schema/Experiment.schema.yaml +0 -55
  72. copilot_session_usage-0.2.0/knowledge/_schema/Finding.schema.yaml +0 -64
  73. copilot_session_usage-0.2.0/knowledge/_schema/Principle.schema.yaml +0 -40
  74. copilot_session_usage-0.2.0/knowledge/_schema/Structure.schema.yaml +0 -41
  75. copilot_session_usage-0.2.0/knowledge/experiments/index.md +0 -3
  76. copilot_session_usage-0.2.0/knowledge/findings/index.md +0 -3
  77. copilot_session_usage-0.2.0/knowledge/index.md +0 -14
  78. copilot_session_usage-0.2.0/knowledge/principles/index.md +0 -3
  79. copilot_session_usage-0.2.0/tests/test_cli.py +0 -274
  80. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.editorconfig +0 -0
  81. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  82. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  83. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.github/guidelines/knowledge-base.guidelines.md +0 -0
  84. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.github/pull_request_template.md +0 -0
  85. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.github/skills/consolidate-knowledge-base/SKILL.md +0 -0
  86. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.github/skills/record-finding/SKILL.md +0 -0
  87. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.github/workflows/ci.yml +0 -0
  88. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.github/workflows/publish.yml +0 -0
  89. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.gitignore +0 -0
  90. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.readthedocs.yaml +0 -0
  91. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/AGENTS.md +0 -0
  92. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/CONTRIBUTING.md +0 -0
  93. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/LICENSE +0 -0
  94. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/docs/source/changelog.md +0 -0
  95. {copilot_session_usage-0.2.0/docs/source → copilot_session_usage-0.2.2/docs/source/reference}/cli.md +0 -0
  96. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/_schema/Concept.schema.yaml +0 -0
  97. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/_schema/Playbook.schema.yaml +0 -0
  98. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/_schema/Reference.schema.yaml +0 -0
  99. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/log.md +0 -0
  100. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/scripts/refresh_pricing.py +0 -0
  101. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/skills/copilot-session-usage/SKILL.md +0 -0
  102. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/__init__.py +0 -0
  103. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/_internal/__init__.py +0 -0
  104. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/_internal/copilot_cli.py +0 -0
  105. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/data/__init__.py +0 -0
  106. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/data/models-and-pricing.lock +0 -0
  107. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/data/models-and-pricing.yml +0 -0
  108. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/tests/test_core.py +0 -0
  109. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/tests/test_rendering.py +0 -0
  110. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/tests/test_vscode_platform.py +0 -0
  111. {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/uv.toml +0 -0
@@ -0,0 +1,19 @@
1
+ ## Unreleased
2
+
3
+ ### Feat
4
+
5
+ - accurate AIC cost computation using nanoAiu and cache_write
6
+
7
+ ## v0.2.1 (2026-07-02)
8
+
9
+ ## v0.2.0 (2026-07-02)
10
+
11
+ ### Fix
12
+
13
+ - bad cost compuation for Opus 4.8
14
+
15
+ ## v0.1.0 (2026-07-02)
16
+
17
+ ### Feat
18
+
19
+ - 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.2
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,12 +20,15 @@ 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)
26
27
 
27
28
  Extract VS Code Copilot session cost KPIs (tokens, estimated USD, model, duration) from local debug logs.
28
29
 
30
+ **Full documentation:** [copilot-session-usage.readthedocs.io](https://copilot-session-usage.readthedocs.io/)
31
+
29
32
  ## Installation
30
33
 
31
34
  ```bash
@@ -4,12 +4,15 @@
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)
10
11
 
11
12
  Extract VS Code Copilot session cost KPIs (tokens, estimated USD, model, duration) from local debug logs.
12
13
 
14
+ **Full documentation:** [copilot-session-usage.readthedocs.io](https://copilot-session-usage.readthedocs.io/)
15
+
13
16
  ## Installation
14
17
 
15
18
  ```bash
@@ -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,138 @@
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
+ The VS Code debug log reports `inputTokens` as the **total** prompt sent
66
+ (cached + non-cached combined). `cachedTokens` is the subset served from
67
+ the provider's cache. The non-cached portion is `inputTokens − cachedTokens`.
68
+
69
+ Each `llm_request` event also carries `copilotUsageNanoAiu` — VS Code's own
70
+ cost for that call in nano-AI Credits (nanoAIU). It is present for all
71
+ Copilot-plan models (Claude, GPT, and others). It is absent for Azure-hosted
72
+ models not billed via Copilot AIC — `Kimi-K2.6-azure` is one such model:
73
+ it is billed through Azure separately and correctly reports $0 AIC.
74
+
75
+ When `copilotUsageNanoAiu` is present and non-zero, the tool uses it directly:
76
+
77
+ ```
78
+ cost_usd = copilotUsageNanoAiu / 100_000_000_000 (1 nanoAIU = 1e-11 USD)
79
+ ```
80
+
81
+ For models that do not report `copilotUsageNanoAiu` — Azure-hosted models billed
82
+ outside the Copilot plan — the tool falls back to token-based computation
83
+ (or $0 when the model has no Copilot pricing entry):
84
+
85
+ ```
86
+ cost_usd = (
87
+ (inputTokens - cachedTokens) × rate.input # fresh tokens
88
+ + cachedTokens × rate.cached_input # cache-read tokens
89
+ + outputTokens × rate.output
90
+ ) / 1_000_000
91
+ ```
92
+
93
+ plus the Anthropic cache-write approximation when applicable.
94
+
95
+ Verified on a real session: `copilotUsageNanoAiu`-based cost matches the
96
+ VS Code AIC panel at **0.000% error** for Claude models.
97
+
98
+ ---
99
+
100
+ ## Subagent attribution
101
+
102
+ `runSubagent` calls appear in the JSONL as a distinct event type. The tool
103
+ tracks them separately so `--detail full` can show which fraction of tokens
104
+ was consumed by subagents vs. the main conversation.
105
+
106
+ ---
107
+
108
+ ## Accuracy
109
+
110
+ For Copilot-plan models (Claude, GPT, etc.), the tool reads
111
+ `copilotUsageNanoAiu` — VS Code's own per-call cost field — directly from the
112
+ JSONL, so the session total matches the VS Code AIC panel at **0% error**.
113
+
114
+ For Azure-hosted models billed outside the Copilot plan (`Kimi-K2.6-azure` is
115
+ the current example), `copilotUsageNanoAiu` is absent. The tool falls back to
116
+ token-based pricing using rates in `custom-models-pricing.yml`. These models
117
+ are billed through Azure separately; setting their prices to `$0.00` in
118
+ `custom-models-pricing.yml` correctly reflects that they do not consume AIC.
119
+
120
+ ### Why the LLM-call count differs by 1 from the panel
121
+
122
+ The VS Code Agent Debug panel excludes the `title-*.jsonl` file (background
123
+ title-generation calls). `copilot-session-usage` counts them because they
124
+ consume real tokens. A session with one title-generation call will show one
125
+ more LLM call and the corresponding (small) token counts compared to the panel.
126
+
127
+ ### Why token counts can differ between tool and panel
128
+
129
+ Token counts in the tool include `title-*.jsonl`; the VS Code panel does not.
130
+ For session `438d24a8`, the delta is exactly one Kimi call: +441 input, +1,245
131
+ output.
132
+
133
+ ### Pricing table updates
134
+
135
+ The bundled pricing table (`data/models-and-pricing.yml`) is updated with each
136
+ release. Run `just refresh-pricing` to pull the latest rates. Stale rates only
137
+ affect the token-based fallback path; `copilotUsageNanoAiu`-based costs are
138
+ unaffected by the table.
@@ -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
+ ```