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.
- copilot_session_usage-0.2.2/CHANGELOG.md +19 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/PKG-INFO +5 -2
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/README.md +3 -0
- copilot_session_usage-0.2.2/docs/source/_static/changelog.js +25 -0
- copilot_session_usage-0.2.2/docs/source/_static/custom.css +142 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/docs/source/conf.py +4 -0
- copilot_session_usage-0.2.2/docs/source/explanation/how-cost-estimation-works.md +138 -0
- copilot_session_usage-0.2.2/docs/source/explanation/index.md +9 -0
- copilot_session_usage-0.2.2/docs/source/how-to/analyze-specific-session.md +46 -0
- copilot_session_usage-0.2.2/docs/source/how-to/batch-and-spending.md +64 -0
- copilot_session_usage-0.2.2/docs/source/how-to/export-json.md +65 -0
- copilot_session_usage-0.2.2/docs/source/how-to/index.md +12 -0
- copilot_session_usage-0.2.2/docs/source/how-to/wsl2.md +37 -0
- copilot_session_usage-0.2.2/docs/source/index.md +66 -0
- copilot_session_usage-0.2.2/docs/source/installation.md +42 -0
- copilot_session_usage-0.2.2/docs/source/reference/api.md +18 -0
- copilot_session_usage-0.2.2/docs/source/reference/index.md +11 -0
- copilot_session_usage-0.2.2/docs/source/reference/pricing.md +122 -0
- copilot_session_usage-0.2.2/docs/source/tutorials/getting-started.md +129 -0
- copilot_session_usage-0.2.2/docs/source/tutorials/index.md +9 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/justfile +15 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/_schema/Base.schema.yaml +10 -1
- copilot_session_usage-0.2.2/knowledge/_schema/Experiment.schema.yaml +44 -0
- copilot_session_usage-0.2.2/knowledge/_schema/Finding.schema.yaml +49 -0
- copilot_session_usage-0.2.2/knowledge/_schema/Principle.schema.yaml +25 -0
- copilot_session_usage-0.2.2/knowledge/_schema/Structure.schema.yaml +26 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/concepts/copilot-cli.md +3 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/concepts/index.md +3 -1
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/concepts/overview.md +5 -3
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/concepts/session-cost-analysis.md +3 -1
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/concepts/threshold-based-pricing.md +3 -1
- copilot_session_usage-0.2.2/knowledge/experiments/index.md +5 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/experiments/verify-subagent-cost-attribution.md +8 -5
- copilot_session_usage-0.2.2/knowledge/findings/cache-write-cost-not-tracked.md +83 -0
- copilot_session_usage-0.2.2/knowledge/findings/index.md +7 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/findings/subagent-logs-use-runsubagent-prefix.md +2 -0
- copilot_session_usage-0.2.2/knowledge/findings/title-jsonl-not-counted-as-model-turn.md +50 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/guides/automation-scripts.md +2 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/guides/cost-optimization.md +2 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/guides/index.md +3 -1
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/guides/wsl2-setup.md +3 -1
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/ideas/index.md +3 -1
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/ideas/multi-session-efficiency-analytics.md +3 -1
- copilot_session_usage-0.2.2/knowledge/index.md +16 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/principles/findings-are-immutable.md +3 -1
- copilot_session_usage-0.2.2/knowledge/principles/index.md +5 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/reference/debug-log-format.md +9 -3
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/reference/index.md +3 -1
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/reference/pricing-formats.md +3 -1
- copilot_session_usage-0.2.2/knowledge/structures/cache-cost-approximation.md +86 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/structures/index.md +4 -1
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/structures/knowledge-base-information-types.md +3 -1
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/structures/session-discovery-algorithm.md +3 -1
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/structures/subagent-cost-tracking.md +16 -5
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/structures/vscode-copilot-extension.md +12 -1
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/pyproject.toml +4 -2
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/_internal/core.py +53 -14
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/_internal/vscode.py +54 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/api.py +7 -1
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/cli.py +5 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/data/custom-models-pricing.yml +3 -2
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/tests/conftest.py +4 -6
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/tests/test_api.py +100 -109
- copilot_session_usage-0.2.2/tests/test_cli.py +280 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/tests/test_coverage_gaps.py +32 -33
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/tests/test_vscode.py +42 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/uv.lock +56 -4
- copilot_session_usage-0.2.0/CHANGELOG.md +0 -9
- copilot_session_usage-0.2.0/docs/source/api.md +0 -19
- copilot_session_usage-0.2.0/docs/source/index.md +0 -41
- copilot_session_usage-0.2.0/knowledge/_schema/Experiment.schema.yaml +0 -55
- copilot_session_usage-0.2.0/knowledge/_schema/Finding.schema.yaml +0 -64
- copilot_session_usage-0.2.0/knowledge/_schema/Principle.schema.yaml +0 -40
- copilot_session_usage-0.2.0/knowledge/_schema/Structure.schema.yaml +0 -41
- copilot_session_usage-0.2.0/knowledge/experiments/index.md +0 -3
- copilot_session_usage-0.2.0/knowledge/findings/index.md +0 -3
- copilot_session_usage-0.2.0/knowledge/index.md +0 -14
- copilot_session_usage-0.2.0/knowledge/principles/index.md +0 -3
- copilot_session_usage-0.2.0/tests/test_cli.py +0 -274
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.editorconfig +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.github/guidelines/knowledge-base.guidelines.md +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.github/pull_request_template.md +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.github/skills/consolidate-knowledge-base/SKILL.md +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.github/skills/record-finding/SKILL.md +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.github/workflows/ci.yml +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.github/workflows/publish.yml +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.gitignore +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/.readthedocs.yaml +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/AGENTS.md +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/CONTRIBUTING.md +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/LICENSE +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/docs/source/changelog.md +0 -0
- {copilot_session_usage-0.2.0/docs/source → copilot_session_usage-0.2.2/docs/source/reference}/cli.md +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/_schema/Concept.schema.yaml +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/_schema/Playbook.schema.yaml +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/_schema/Reference.schema.yaml +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/knowledge/log.md +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/scripts/refresh_pricing.py +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/skills/copilot-session-usage/SKILL.md +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/__init__.py +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/_internal/__init__.py +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/_internal/copilot_cli.py +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/data/__init__.py +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/data/models-and-pricing.lock +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/src/copilot_session_usage/data/models-and-pricing.yml +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/tests/test_core.py +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/tests/test_rendering.py +0 -0
- {copilot_session_usage-0.2.0 → copilot_session_usage-0.2.2}/tests/test_vscode_platform.py +0 -0
- {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.
|
|
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
|
[](https://codecov.io/gh/gsemet/copilot-session-usage)
|
|
21
21
|
[](https://pypi.org/project/copilot-session-usage/)
|
|
22
22
|
[](https://pypi.org/project/copilot-session-usage/)
|
|
23
|
+
[](https://copilot-session-usage.readthedocs.io/en/stable/)
|
|
23
24
|
[](https://github.com/astral-sh/ruff)
|
|
24
25
|
[](./)
|
|
25
26
|
[](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
|
[](https://codecov.io/gh/gsemet/copilot-session-usage)
|
|
5
5
|
[](https://pypi.org/project/copilot-session-usage/)
|
|
6
6
|
[](https://pypi.org/project/copilot-session-usage/)
|
|
7
|
+
[](https://copilot-session-usage.readthedocs.io/en/stable/)
|
|
7
8
|
[](https://github.com/astral-sh/ruff)
|
|
8
9
|
[](./)
|
|
9
10
|
[](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,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,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
|
+
```
|