copilot-usage-studio 0.1.0 → 0.2.1
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.
- package/CHANGELOG.md +29 -4
- package/README.md +206 -150
- package/data/github-copilot-pricing.json +34 -6
- package/dist/copilot-usage-studio/browser/chunk-2SAR2Q6M.js +1 -0
- package/dist/copilot-usage-studio/browser/chunk-5JYQJM5G.js +1 -0
- package/dist/copilot-usage-studio/browser/chunk-7FKLWMFH.js +1 -0
- package/dist/copilot-usage-studio/browser/chunk-EWN3YOHT.js +1 -0
- package/dist/copilot-usage-studio/browser/chunk-KS5W2HMH.js +1 -0
- package/dist/copilot-usage-studio/browser/chunk-OS2XPCVW.js +2 -0
- package/dist/copilot-usage-studio/browser/chunk-U4H425LY.js +1 -0
- package/dist/copilot-usage-studio/browser/chunk-VEKXIM47.js +1 -0
- package/dist/copilot-usage-studio/browser/chunk-WOIYAEKB.js +4 -0
- package/dist/copilot-usage-studio/browser/chunk-XHID4XVE.js +1 -0
- package/dist/copilot-usage-studio/browser/index.html +11 -11
- package/dist/copilot-usage-studio/browser/main-OZIMQRXC.js +1 -0
- package/dist/copilot-usage-studio/browser/styles-7RDDQXQV.css +1 -0
- package/docs/copilot-memory.md +91 -0
- package/docs/local-deployment.md +119 -13
- package/docs/pricing.md +3 -3
- package/docs/scanner-api.md +32 -3
- package/lib/cli.mjs +15 -1
- package/lib/local-runtime.mjs +530 -19
- package/lib/scanner-worker.mjs +25 -0
- package/package.json +95 -78
- package/scripts/pricing-utils.mjs +5 -0
- package/scripts/scan-vscode-sessions.mjs +418 -1204
- package/scripts/scanner-customization-evidence.mjs +576 -0
- package/scripts/scanner-customization-inventory.mjs +1021 -0
- package/scripts/scanner-memory.mjs +229 -0
- package/scripts/scanner-session-parser.mjs +1237 -0
- package/scripts/scanner-traversal.mjs +203 -0
- package/scripts/scanner-workspace.mjs +209 -0
- package/dist/copilot-usage-studio/browser/chunk-C6VWIY5S.js +0 -1
- package/dist/copilot-usage-studio/browser/chunk-DLWQO3VR.js +0 -1
- package/dist/copilot-usage-studio/browser/chunk-F6TIG2GE.js +0 -4
- package/dist/copilot-usage-studio/browser/chunk-JIP7ONRZ.js +0 -1
- package/dist/copilot-usage-studio/browser/chunk-RNKEPBEU.js +0 -1
- package/dist/copilot-usage-studio/browser/chunk-Z3XIAKMM.js +0 -1
- package/dist/copilot-usage-studio/browser/main-C6XOJRSH.js +0 -2
- package/dist/copilot-usage-studio/browser/styles-GZOQ5QIH.css +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,11 +4,33 @@ All notable changes to Copilot Usage Studio are recorded here.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
7
|
+
- Add a read-only Copilot Memory library for global, repository, workspace, and session-scoped memories and plans.
|
|
8
|
+
- Link session-scoped memory files to the imported run that created them.
|
|
9
|
+
- Add guarded local-runtime actions to open or reveal an indexed memory file.
|
|
10
|
+
- Show source-backed memory recall history from explicit VS Code `memory view` events, linked to the following model request without inventing memory-only cost.
|
|
11
|
+
- Compact the Memory page into an IDE-style file browser with filename search, copy-content action, collapsed source view, and scope help.
|
|
12
|
+
- Make startup loading a stable page state and clarify that the runtime URL shown during `npm start` is backend-only.
|
|
13
|
+
- Add GitHub Actions CI for pull requests, `main`, and pushed feature branches.
|
|
14
|
+
- Add tag-driven npm Trusted Publishing with automatic provenance.
|
|
15
|
+
- Create the matching GitHub Release from the same version tag.
|
|
16
|
+
- Support safe workflow reruns and manual backfill of an existing tagged release.
|
|
17
|
+
- Add a VS Code extension preview for Usage, Sessions, Memory, Customizations preview, Compare, Insights, and Prices.
|
|
18
|
+
- Build and upload a VSIX artifact from CI for every pushed branch.
|
|
19
|
+
- Position the VS Code extension as the primary product path, with Marketplace publication planned after maintainer smoke testing.
|
|
20
|
+
- Generate detailed release notes from the changelog and commits for tagged releases.
|
|
21
|
+
- Tighten Customizations evidence wording around visible local-log text matches.
|
|
22
|
+
- Trust explicit VS Code customization file settings, directories, and globs for file kind while keeping scans bounded by safe file type.
|
|
23
|
+
- Add regression coverage for `copilot-instructions.md`, explicit configured customization files, and broad user-profile folders not being scanned by default.
|
|
24
|
+
- Compact global scan status so detailed workspace diagnostics stay behind `View details`.
|
|
25
|
+
- Report user-stopped scans as stopped while keeping the last valid snapshot visible.
|
|
26
|
+
- Make Customizations evidence rows quieter by keeping raw VS Code source fields inside `Proof details` and marking partial evidence as minimum counts.
|
|
27
|
+
- Preserve existing Customizations evidence when a normal top-right Refresh runs a quick scan that skips customization indexing.
|
|
28
|
+
- Mark Customizations as a preview surface in both docs and the app navigation.
|
|
29
|
+
- Purge public roadmap links from README and release-facing docs.
|
|
30
|
+
- Refresh GitHub Copilot model pricing from the July 5, 2026 GitHub Docs table, including Claude Sonnet 5, Claude Opus 4.8 fast mode, Kimi K2.7 Code, and updated model statuses.
|
|
31
|
+
- Add raw model-id alias support so newly observed VS Code ids can map to the matching GitHub pricing row without hidden fallback pricing.
|
|
10
32
|
|
|
11
|
-
## 0.1.0 - 2026-06-
|
|
33
|
+
## 0.1.0 - 2026-06-14
|
|
12
34
|
|
|
13
35
|
Initial local developer preview.
|
|
14
36
|
|
|
@@ -20,5 +42,8 @@ Initial local developer preview.
|
|
|
20
42
|
- Compare selected runs and review the GitHub pricing rows used by the app.
|
|
21
43
|
- Run the complete local application with `npx copilot-usage-studio`.
|
|
22
44
|
- Keep imported session data on the developer's machine.
|
|
45
|
+
- Use the GitHub Copilot model rate card checked on June 14, 2026.
|
|
46
|
+
- Apply GPT-5.4, GPT-5.5, and Gemini 3.1 Pro long-context rates per model call rather than to aggregated session tokens.
|
|
47
|
+
- Preserve the selected pricing tier and per-bucket model costs in generated session data.
|
|
23
48
|
|
|
24
49
|
Copilot Usage Studio is an independent open-source developer tool and is not affiliated with or endorsed by GitHub or Microsoft.
|
package/README.md
CHANGED
|
@@ -1,150 +1,206 @@
|
|
|
1
|
-
# Copilot Usage Studio
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
npm install
|
|
41
|
-
npm
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
npm
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
-
|
|
96
|
-
-
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
1
|
+
# Copilot Usage Studio
|
|
2
|
+
|
|
3
|
+
Extension-first usage, memory, customization, and cost insights for VS Code GitHub Copilot chat and agent sessions.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/copilot-usage-studio)
|
|
6
|
+
[](https://github.com/fortunes-guardian/copilot-usage-studio/actions/workflows/ci.yml)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
Independent open-source developer tool. Not affiliated with or endorsed by GitHub or Microsoft.
|
|
10
|
+
|
|
11
|
+
Status: early VS Code extension preview. Test locally before relying on it for daily use.
|
|
12
|
+
|
|
13
|
+
Supported scope today: VS Code GitHub Copilot Chat and Agent sessions on the local machine. This does not currently support Visual Studio, JetBrains IDEs, Copilot CLI, GitHub.com chat, or GitHub billing exports.
|
|
14
|
+
|
|
15
|
+
Supported local VS Code storage locations for the standalone/npm host:
|
|
16
|
+
|
|
17
|
+
- Windows: `%APPDATA%\Code\User`
|
|
18
|
+
- macOS: `~/Library/Application Support/Code/User`
|
|
19
|
+
- Linux: `~/.config/Code/User`
|
|
20
|
+
|
|
21
|
+
VS Code Insiders paths are scanned too by the standalone/npm host. The VS Code extension preview uses the VS Code user-data root for the VS Code installation it is running inside.
|
|
22
|
+
|
|
23
|
+
The app helps answer three practical questions:
|
|
24
|
+
|
|
25
|
+
> How much GitHub Copilot usage did I burn today, this week, and this month?
|
|
26
|
+
>
|
|
27
|
+
> Did Copilot actually send my local instructions, skills, prompts, hooks, or agents to the model?
|
|
28
|
+
>
|
|
29
|
+
> Why did this Copilot run cost what it cost?
|
|
30
|
+
|
|
31
|
+
It scans local VS Code data, uses GitHub source usage when VS Code logs it, falls back to GitHub published model prices when it has to, and shows which models, token categories, and model calls drove the usage. It also indexes Copilot's locally saved memories/plans. The Customizations page is a preview for inspecting local instructions, skills, prompts, hooks, and agents with evidence from visible VS Code request logs.
|
|
32
|
+
|
|
33
|
+
## Start Here
|
|
34
|
+
|
|
35
|
+
Recommended path: build and install the local VS Code extension preview.
|
|
36
|
+
|
|
37
|
+
Requirements for building the preview: Node.js 22.5 or newer, npm, VS Code, and local VS Code GitHub Copilot session data.
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm install
|
|
41
|
+
npm run vscode:package
|
|
42
|
+
code --install-extension tmp/copilot-usage-studio-vscode-0.2.0.vsix --force
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Then run `Copilot Usage Studio: Open` from the VS Code command palette.
|
|
46
|
+
|
|
47
|
+
The npm/browser host remains available for development and fallback testing:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npx copilot-usage-studio
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Then open `http://127.0.0.1:4312/`.
|
|
54
|
+
|
|
55
|
+
`npx` downloads the latest published package from npm. To run this exact release:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npx copilot-usage-studio@0.2.0
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
To contribute or run the current GitHub source:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
git clone https://github.com/fortunes-guardian/copilot-usage-studio.git
|
|
65
|
+
cd copilot-usage-studio
|
|
66
|
+
npm install
|
|
67
|
+
npm start
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Open the local Angular URL printed by the dev server, usually:
|
|
71
|
+
|
|
72
|
+
```text
|
|
73
|
+
http://127.0.0.1:4200/
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Read [docs/how-to-read-the-app.md](docs/how-to-read-the-app.md) if the UI terms are not obvious yet.
|
|
77
|
+
|
|
78
|
+
`npm start` now launches both the Angular development UI and the local scanner runtime. It serves cached data immediately, refreshes from VS Code in the background, and enables the **Refresh** action in the app. The app stays local because the useful source data can contain prompts, file paths, repository context, and tool results.
|
|
79
|
+
|
|
80
|
+
The packaged CLI stores its cache in the current user's application-data directory. It does not write session data into the npm installation and does not include the maintainer's generated session data in the package.
|
|
81
|
+
|
|
82
|
+
If startup appears stuck, keep the terminal open and check the loading screen diagnostics. The runtime now reports the current scan step, recent log lines, and a local log-file path. You can also run:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npx copilot-usage-studio status
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## What Works Now
|
|
89
|
+
|
|
90
|
+
- **Usage**: the default home for last session, today, this week, current calendar month, selected workspace/model scope, and recent daily usage in GitHub AI credits.
|
|
91
|
+
- **Sessions**: selected-run debugging with Overview, Cost, Calls, and Trace views.
|
|
92
|
+
- **Memory**: read-only search and inspection for global, repository, workspace, and session-scoped Copilot memories and saved plans.
|
|
93
|
+
- **Customizations preview**: read-only inventory and local-log text-match evidence for Copilot instructions, skills, prompts, hooks, and agents. Absence of a text match does not prove Copilot ignored a file.
|
|
94
|
+
- **Cost**: source usage when VS Code logs it, fallback pricing when it does not, and separate normal input, cached input, cache write, and output buckets.
|
|
95
|
+
- **Calls**: model-call timeline, context-load timeline, setup-footprint clues, and links back to the raw Trace event.
|
|
96
|
+
- **Trace**: filterable raw log timeline with clickable event inspection.
|
|
97
|
+
- **Compare**: baseline/candidate run comparison with cost, token, model, and same-prompt cues.
|
|
98
|
+
- **Insights**: multi-session model mix, trends, run-size distribution, and outlier signals without repeating the Usage dashboard.
|
|
99
|
+
- **Prices**: GitHub pricing rows used by the app plus Copilot Business/Enterprise AI-credit allowance context.
|
|
100
|
+
|
|
101
|
+
If the dev server ever shows new markup with old component styles, stop it and restart with a cache reset:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
npm run start:clean
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
For a local production build:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm run scan
|
|
111
|
+
npm run verify:data
|
|
112
|
+
npm run build
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
See [docs/local-deployment.md](docs/local-deployment.md) for packaging options and why the app stays local-first.
|
|
116
|
+
|
|
117
|
+
Build the VS Code extension preview:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
npm run vscode:package
|
|
121
|
+
code --install-extension tmp/copilot-usage-studio-vscode-0.2.0.vsix --force
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The extension opens the full app inside VS Code: Usage, Sessions, Memory, Customizations preview, Compare, Insights, and Prices.
|
|
125
|
+
For pre-release testing, prefer the VSIX artifact produced by branch CI when available. After maintainer testing, the release target is the VS Code Marketplace so users can install without downloading a VSIX manually.
|
|
126
|
+
|
|
127
|
+
## Releasing
|
|
128
|
+
|
|
129
|
+
Releases are tag-driven. After a change is merged to `main`, the maintainer bumps the version and pushes the generated tag:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
npm version patch
|
|
133
|
+
git push origin main --follow-tags
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Use `minor` or `major` instead of `patch` when appropriate. GitHub Actions tests and packages that exact tagged commit, builds the VS Code extension artifact, and creates release notes from `CHANGELOG.md`. See [docs/local-deployment.md](docs/local-deployment.md#automated-releases) for release mechanics.
|
|
137
|
+
|
|
138
|
+
## Current Boundaries
|
|
139
|
+
|
|
140
|
+
- Local app, not SaaS.
|
|
141
|
+
- Developer usage visibility, not enterprise billing-console access.
|
|
142
|
+
- Local VS Code sessions, not Visual Studio, JetBrains, Copilot CLI, GitHub.com chat, or billing exports.
|
|
143
|
+
|
|
144
|
+
The app is a local developer visibility tool. It shows what can be understood from local VS Code Copilot data.
|
|
145
|
+
|
|
146
|
+
## Docs
|
|
147
|
+
|
|
148
|
+
- [docs/how-to-read-the-app.md](docs/how-to-read-the-app.md): plain-English guide to the UI.
|
|
149
|
+
- [docs/pricing.md](docs/pricing.md): GitHub price source, calculation rules, AI-credit allowances, and real-world caveats.
|
|
150
|
+
- [docs/local-deployment.md](docs/local-deployment.md): local run, build, and release mechanics.
|
|
151
|
+
- [docs/vscode-extension.md](docs/vscode-extension.md): local VSIX preview architecture, build, and smoke-test flow.
|
|
152
|
+
- [docs/scanner-api.md](docs/scanner-api.md): reusable Node scanner contract for local hosts, desktop packaging, and extensions.
|
|
153
|
+
- [docs/data-ingestion.md](docs/data-ingestion.md): where the data comes from and what it means.
|
|
154
|
+
- [docs/copilot-memory.md](docs/copilot-memory.md): observed Copilot memory storage, normalized fields, and evidence boundaries.
|
|
155
|
+
- [docs/customization-evidence.md](docs/customization-evidence.md): how instruction/skill evidence is detected and what it proves.
|
|
156
|
+
- [docs/debug-log-schema.md](docs/debug-log-schema.md): observed VS Code Agent Debug Log schema and generated app data contract.
|
|
157
|
+
|
|
158
|
+
## License
|
|
159
|
+
|
|
160
|
+
MIT. See [LICENSE](LICENSE).
|
|
161
|
+
|
|
162
|
+
## Refresh Local Session Data
|
|
163
|
+
|
|
164
|
+
The app reads `public/data/sessions.json`. Running `npm run scan` regenerates that file from local VS Code data.
|
|
165
|
+
|
|
166
|
+
Normal refresh:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
npm run refresh:data
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
That runs the scan and verifier together.
|
|
173
|
+
|
|
174
|
+
The scanner also has an in-memory Node API for future local-server, desktop, and extension hosts. See [docs/scanner-api.md](docs/scanner-api.md). The existing `npm run scan` command is now a thin CLI host over the same API.
|
|
175
|
+
|
|
176
|
+
## Pricing
|
|
177
|
+
|
|
178
|
+
Prices are copied from GitHub's published Copilot usage-based pricing table:
|
|
179
|
+
|
|
180
|
+
https://docs.github.com/en/copilot/reference/copilot-billing/models-and-pricing
|
|
181
|
+
|
|
182
|
+
Rates are USD per 1 million tokens. The app also converts USD into GitHub AI credits using GitHub's fixed conversion of `1 AI credit = $0.01 USD`.
|
|
183
|
+
|
|
184
|
+
See [docs/pricing.md](docs/pricing.md) for the exact calculation rules, source usage behavior, and known limits.
|
|
185
|
+
|
|
186
|
+
## Useful Commands
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
npm run scan
|
|
190
|
+
npm run refresh:data
|
|
191
|
+
npm run runtime
|
|
192
|
+
npm run preview:local
|
|
193
|
+
npm run cli -- --help
|
|
194
|
+
npm run verify:data
|
|
195
|
+
npm run schema:audit
|
|
196
|
+
npm test -- --watch=false
|
|
197
|
+
npm run build
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
You can scan a custom VS Code user directory or workspace storage folder:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
node scripts/scan-vscode-sessions.mjs public/data/sessions.json "%APPDATA%\Code\User"
|
|
204
|
+
node scripts/scan-vscode-sessions.mjs public/data/sessions.json "$HOME/Library/Application Support/Code/User"
|
|
205
|
+
node scripts/scan-vscode-sessions.mjs public/data/sessions.json "%APPDATA%\Code\User\workspaceStorage\<workspace-id>"
|
|
206
|
+
```
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "github-copilot-usage-pricing-2026-
|
|
2
|
+
"version": "github-copilot-usage-pricing-2026-07-05",
|
|
3
3
|
"sourceUrl": "https://docs.github.com/en/copilot/reference/copilot-billing/models-and-pricing",
|
|
4
4
|
"sourceLabel": "GitHub Docs: Models and pricing for GitHub Copilot",
|
|
5
|
-
"snapshotDate": "2026-
|
|
6
|
-
"importedAt": "2026-
|
|
5
|
+
"snapshotDate": "2026-07-05",
|
|
6
|
+
"importedAt": "2026-07-05",
|
|
7
7
|
"fallbackModel": "GPT-5.4",
|
|
8
8
|
"models": {
|
|
9
9
|
"GPT-5 mini": {
|
|
@@ -152,7 +152,17 @@
|
|
|
152
152
|
"cacheWrite": 6.25,
|
|
153
153
|
"output": 25
|
|
154
154
|
},
|
|
155
|
-
"Claude
|
|
155
|
+
"Claude Sonnet 5": {
|
|
156
|
+
"provider": "Anthropic",
|
|
157
|
+
"releaseStatus": "GA",
|
|
158
|
+
"category": "Versatile",
|
|
159
|
+
"input": 2,
|
|
160
|
+
"cachedInput": 0.2,
|
|
161
|
+
"cacheWrite": 2.5,
|
|
162
|
+
"output": 10,
|
|
163
|
+
"note": "GitHub documents this promotional pricing through August 31, 2026."
|
|
164
|
+
},
|
|
165
|
+
"Claude Opus 4.8 (fast mode)": {
|
|
156
166
|
"provider": "Anthropic",
|
|
157
167
|
"releaseStatus": "GA",
|
|
158
168
|
"category": "Powerful",
|
|
@@ -160,7 +170,17 @@
|
|
|
160
170
|
"cachedInput": 1,
|
|
161
171
|
"cacheWrite": 12.5,
|
|
162
172
|
"output": 50,
|
|
163
|
-
"
|
|
173
|
+
"aliases": ["Claude Opus 4.8 fast", "claude-opus-4.8-fast"],
|
|
174
|
+
"note": "GitHub's table includes '(preview)' in the model label."
|
|
175
|
+
},
|
|
176
|
+
"Claude Fable 5": {
|
|
177
|
+
"provider": "Anthropic",
|
|
178
|
+
"releaseStatus": "GA",
|
|
179
|
+
"category": "Powerful",
|
|
180
|
+
"input": 10,
|
|
181
|
+
"cachedInput": 1,
|
|
182
|
+
"cacheWrite": 12.5,
|
|
183
|
+
"output": 50
|
|
164
184
|
},
|
|
165
185
|
"Gemini 2.5 Pro": {
|
|
166
186
|
"provider": "Google",
|
|
@@ -209,7 +229,7 @@
|
|
|
209
229
|
},
|
|
210
230
|
"Raptor mini": {
|
|
211
231
|
"provider": "Fine-tuned (GitHub)",
|
|
212
|
-
"releaseStatus": "
|
|
232
|
+
"releaseStatus": "GA",
|
|
213
233
|
"category": "Versatile",
|
|
214
234
|
"input": 0.25,
|
|
215
235
|
"cachedInput": 0.025,
|
|
@@ -222,6 +242,14 @@
|
|
|
222
242
|
"input": 0.75,
|
|
223
243
|
"cachedInput": 0.075,
|
|
224
244
|
"output": 4.5
|
|
245
|
+
},
|
|
246
|
+
"Kimi K2.7 Code": {
|
|
247
|
+
"provider": "Moonshot AI",
|
|
248
|
+
"releaseStatus": "GA",
|
|
249
|
+
"category": "Versatile",
|
|
250
|
+
"input": 0.95,
|
|
251
|
+
"cachedInput": 0.19,
|
|
252
|
+
"output": 4
|
|
225
253
|
}
|
|
226
254
|
}
|
|
227
255
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{f as Q}from"./chunk-KS5W2HMH.js";import{i as S,r as U,s as W}from"./chunk-VEKXIM47.js";import{$a as f,Ca as P,Da as h,Ea as T,Fa as y,Ga as M,Ha as g,Ia as o,Ja as i,Ka as F,O as E,Oa as I,P as D,Qa as x,Sa as _,Ta as V,U as A,Ua as B,Va as s,Wa as m,Xa as N,Ya as w,Z as v,Za as z,_a as l,ab as b,db as C,ka as r,nb as L,ob as R,sa as $,sb as Y,ub as j,vb as H,wb as G,xb as q,yb as J,zb as K}from"./chunk-WOIYAEKB.js";var X=(n,t)=>t.id,ae=(n,t)=>t.key;function ie(n,t){if(n&1&&(o(0,"option",6),s(1),i()),n&2){let e=t.$implicit;g("value",e),r(),m(e==="all"?"All workspaces":e)}}function oe(n,t){if(n&1&&(o(0,"option",6),s(1),i()),n&2){let e=t.$implicit;g("value",e),r(),m(e==="all"?"All models":e)}}function re(n,t){if(n&1&&(o(0,"option",6),s(1),i()),n&2){let e=t.$implicit;g("value",e.id),r(),m(e.label)}}function se(n,t){if(n&1){let e=I();o(0,"button",17),x("click",function(){E(e);let p=_();return D(p.resetScope())}),s(1,"Reset scope"),i()}}function le(n,t){if(n&1&&(s(0),l(1,"number")),n&2){let e=_().$implicit;w(" \xB7 ",f(1,2,e.fallbackCount)," fallback",e.fallbackCount===1?"":"s"," ")}}function pe(n,t){if(n&1&&(o(0,"span",23),s(1),i()),n&2){let e=_().$implicit;r(),m(e.actionLabel)}}function ce(n,t){if(n&1){let e=I();o(0,"button",18),x("click",function(){let p=E(e).$implicit,c=_();return D(c.emitOpenSession(p.session))}),o(1,"span",19),s(2),i(),o(3,"strong"),s(4),l(5,"number"),i(),o(6,"em",20),s(7),i(),o(8,"em"),s(9),l(10,"number"),i(),o(11,"i",21),F(12,"b"),i(),o(13,"small",22)(14,"span"),s(15),l(16,"number"),P(17,le,2,4),i(),P(18,pe,2,1,"span",23),i()()}if(n&2){let e=t.$implicit,a=_();B("primary",e.id==="last-session")("can-open",a.canOpenSession&&e.session)("empty",!e.session),g("disabled",!a.canOpenSession||!e.session),r(2),m(e.label),r(2),N("",b(5,18,e.credits,"1.0-2")," credits"),r(3),m(e.period),r(2),w("$",b(10,21,e.usd,"1.2-4")," \xB7 ",e.detail),r(3),V("width",e.allowanceShare>100?100:e.allowanceShare,"%"),r(3),w(" ",b(16,24,e.allowanceShare,"1.0-1"),"% of ",a.selectedAllowance().shortLabel," "),r(2),h(e.fallbackCount?17:-1),r(),h(a.canOpenSession?18:-1)}}function de(n,t){if(n&1&&(o(0,"span"),s(1),l(2,"number"),l(3,"number"),i()),n&2){let e=t;r(),w("",f(2,2,e.sourceCount)," source \xB7 ",f(3,4,e.fallbackCount)," fallback")}}function ge(n,t){if(n&1&&(s(0),l(1,"number")),n&2){let e=_().$implicit;w(" \xB7 ",f(1,2,e.fallbackCount)," fallback",e.fallbackCount===1?"":"s"," ")}}function ue(n,t){if(n&1){let e=I();o(0,"button",24),x("click",function(){let p=E(e).$implicit,c=_();return D(c.emitOpenSession(p.topSession))}),o(1,"span"),s(2),l(3,"date"),i(),o(4,"strong"),s(5),l(6,"number"),i(),o(7,"em"),s(8),l(9,"number"),l(10,"number"),P(11,ge,2,4),i()()}if(n&2){let e=t.$implicit,a=_();B("can-open",a.canOpenSession&&e.topSession)("empty",!e.topSession),g("disabled",!a.canOpenSession||!e.topSession),r(2),m(b(3,11,e.date,"EEE, MMM d")),r(3),N("",b(6,14,e.credits,"1.0-2")," credits"),r(3),z(" ",f(9,17,e.count)," session",e.count===1?"":"s"," \xB7 $",b(10,19,e.usd,"1.2-4")," "),r(3),h(e.fallbackCount?11:-1)}}var Z=class n{sessionsInput=v([]);allowancePlanInput=v("business-standard");workspaceFilter=v("all");modelFilter=v("all");set sessions(t){this.sessionsInput.set(t??[])}set allowancePlan(t){this.allowancePlanInput.set(t??"business-standard")}canOpenSession=!0;allowancePlanChange=new A;openSession=new A;allowancePlans=S;help={scope:"Usage is calculated from imported local VS Code sessions. When VS Code reports Copilot usage units, the app uses those. Otherwise it estimates from token buckets and GitHub model prices.",allowance:"Compares your local imported usage with the included monthly AI credits for the selected Copilot plan."};selectedAllowance=C(()=>S.find(t=>t.id===this.allowancePlanInput())??S[0]);currentAllowancePlan=C(()=>this.selectedAllowance().id);workspaceOptions=C(()=>["all",...[...new Set(this.sessionsInput().map(t=>t.workspace).filter(Boolean))].sort()]);modelOptions=C(()=>["all",...[...new Set(this.sessionsInput().map(t=>t.model).filter(Boolean))].sort()]);scopedSessions=C(()=>this.sessionsInput().filter(t=>(this.workspaceFilter()==="all"||t.workspace===this.workspaceFilter())&&(this.modelFilter()==="all"||t.model===this.modelFilter())));scopeActive=C(()=>this.workspaceFilter()!=="all"||this.modelFilter()!=="all");usageWindows=C(()=>Q(this.scopedSessions(),this.selectedAllowance().creditsPerUserMonthly));dailyRows=C(()=>this.buildDailyRows(this.scopedSessions(),14));sourceCoverage=C(()=>{let t=this.scopedSessions(),e=t.filter(a=>a.sourceUsage).length;return{sourceCount:e,fallbackCount:t.length-e,total:t.length}});setAllowancePlan(t){if(!S.some(a=>a.id===t))return;let e=t;this.allowancePlanInput.set(e),this.allowancePlanChange.emit(e)}setWorkspaceFilter(t){this.workspaceFilter.set(t)}setModelFilter(t){this.modelFilter.set(t)}resetScope(){this.workspaceFilter.set("all"),this.modelFilter.set("all")}emitOpenSession(t){this.canOpenSession&&t&&this.openSession.emit(t)}buildDailyRows(t,e){let a=me(new Date);return Array.from({length:e},(p,c)=>{let k=ee(a,-c),te=ee(k,1),O=t.filter(d=>{let u=Date.parse(d.startedAt);return Number.isFinite(u)&&u>=k.getTime()&&u<te.getTime()}),ne=O.reduce((d,u)=>!d||U(u)>U(d)?u:d,null);return{date:k,key:Ce(k),credits:O.reduce((d,u)=>d+W(u),0),usd:O.reduce((d,u)=>d+U(u),0),count:O.length,topSession:ne,fallbackCount:O.filter(d=>!d.sourceUsage).length}})}static \u0275fac=function(e){return new(e||n)};static \u0275cmp=$({type:n,selectors:[["app-usage-page"]],inputs:{sessions:"sessions",allowancePlan:"allowancePlan",canOpenSession:"canOpenSession"},outputs:{allowancePlanChange:"allowancePlanChange",openSession:"openSession"},decls:55,vars:15,consts:[[1,"usage-page"],[1,"usage-header"],[1,"eyebrow"],["label","Explain usage scope",3,"text"],[1,"usage-controls"],[3,"ngModelChange","ngModel"],[3,"value"],["label","Explain allowance",3,"text"],[1,"usage-scope"],["type","button"],["aria-label","Usage answer cards",1,"usage-answer-grid"],["type","button",1,"usage-answer-card",3,"primary","can-open","empty","disabled"],[1,"usage-panels"],[1,"usage-panel"],[1,"panel-heading"],[1,"daily-usage-list"],["type","button",3,"can-open","empty","disabled"],["type","button",3,"click"],["type","button",1,"usage-answer-card",3,"click","disabled"],[1,"usage-card-label"],[1,"usage-card-period"],["aria-hidden","true"],[1,"usage-card-footer"],[1,"usage-card-action"],["type","button",3,"click","disabled"]],template:function(e,a){if(e&1&&(o(0,"section",0)(1,"header",1)(2,"div")(3,"p",2),s(4,"Usage home"),i(),o(5,"h2"),s(6,"Your Copilot usage"),i(),o(7,"p"),s(8," Today, this week, this month, and recent activity across imported VS Code sessions. "),F(9,"app-help-popover",3),i()(),o(10,"div",4)(11,"label")(12,"span"),s(13,"Workspace"),i(),o(14,"select",5),x("ngModelChange",function(c){return a.setWorkspaceFilter(c)}),y(15,ie,2,2,"option",6,T),i()(),o(17,"label")(18,"span"),s(19,"Model"),i(),o(20,"select",5),x("ngModelChange",function(c){return a.setModelFilter(c)}),y(21,oe,2,2,"option",6,T),i()(),o(23,"label")(24,"span"),s(25," Monthly allowance "),F(26,"app-help-popover",7),i(),o(27,"select",5),x("ngModelChange",function(c){return a.setAllowancePlan(c)}),y(28,re,2,2,"option",6,X),i()()()(),o(30,"div",8)(31,"span"),s(32),l(33,"number"),l(34,"number"),i(),o(35,"span"),s(36),i(),o(37,"span"),s(38),i(),P(39,se,2,0,"button",9),i(),o(40,"section",10),y(41,ce,19,27,"button",11,X),i(),o(43,"section",12)(44,"article",13)(45,"div",14)(46,"div")(47,"h3"),s(48,"Recent days"),i(),o(49,"p"),s(50,"Last 14 local calendar days from imported VS Code sessions."),i()(),P(51,de,4,6,"span"),i(),o(52,"div",15),y(53,ue,12,22,"button",16,ae),i()()()()),e&2){let p;r(9),g("text",a.help.scope),r(5),g("ngModel",a.workspaceFilter()),r(),M(a.workspaceOptions()),r(5),g("ngModel",a.modelFilter()),r(),M(a.modelOptions()),r(5),g("text",a.help.allowance),r(),g("ngModel",a.currentAllowancePlan()),r(),M(a.allowancePlans),r(4),w("",f(33,11,a.scopedSessions().length)," of ",f(34,13,a.sessionsInput().length)," sessions"),r(4),m(a.workspaceFilter()==="all"?"All workspaces":a.workspaceFilter()),r(2),m(a.modelFilter()==="all"?"All models":a.modelFilter()),r(),h(a.scopeActive()?39:-1),r(2),M(a.usageWindows()),r(10),h((p=a.sourceCoverage())?51:-1,p),r(2),M(a.dailyRows())}},dependencies:[K,q,J,G,j,H,Y,L,R],styles:["[_nghost-%COMP%]{display:block}.usage-page[_ngcontent-%COMP%]{display:grid;gap:12px}.usage-header[_ngcontent-%COMP%]{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;border:1px solid color-mix(in srgb,var(--accent-2) 24%,var(--line));border-radius:18px;padding:16px;background:var(--header-gradient);box-shadow:var(--shadow)}.eyebrow[_ngcontent-%COMP%]{margin:0;color:var(--muted-2);font-size:10px;font-weight:820;letter-spacing:.08em;text-transform:uppercase}.usage-header[_ngcontent-%COMP%] h2[_ngcontent-%COMP%]{margin:3px 0 0;color:var(--text-strong);font-size:26px;font-weight:820;letter-spacing:0}.usage-header[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{display:inline-flex;align-items:center;flex-wrap:wrap;gap:4px;max-width:720px;margin:7px 0 0;color:var(--muted);font-size:13px;line-height:1.45}.usage-controls[_ngcontent-%COMP%]{display:grid;grid-template-columns:repeat(3,minmax(150px,1fr));gap:8px;width:min(720px,58vw)}.usage-controls[_ngcontent-%COMP%] label[_ngcontent-%COMP%]{display:grid;gap:6px;min-width:0;color:var(--muted);font-size:11px;font-weight:760}.usage-controls[_ngcontent-%COMP%] label[_ngcontent-%COMP%] > span[_ngcontent-%COMP%]{display:inline-flex;align-items:center;gap:4px}.usage-controls[_ngcontent-%COMP%] select[_ngcontent-%COMP%]{width:100%;min-height:34px;border:1px solid var(--line);border-radius:9px;padding:7px 10px;background:var(--surface-soft);color:var(--text);font:inherit;font-size:13px;font-weight:760}.usage-scope[_ngcontent-%COMP%]{display:flex;flex-wrap:wrap;align-items:center;gap:7px;color:var(--muted);font-size:11px}.usage-scope[_ngcontent-%COMP%] > span[_ngcontent-%COMP%], .usage-scope[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{border:1px solid var(--line);border-radius:999px;padding:4px 8px;background:var(--surface-soft)}.usage-scope[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{color:var(--accent);font:inherit;font-weight:800;cursor:pointer}.usage-answer-grid[_ngcontent-%COMP%]{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:9px}.usage-answer-card[_ngcontent-%COMP%], .usage-panel[_ngcontent-%COMP%]{border:1px solid var(--line);border-radius:15px;background:var(--surface);box-shadow:var(--shadow-soft)}.usage-answer-card[_ngcontent-%COMP%]{display:grid;gap:6px;min-width:0;padding:13px;color:var(--text);text-align:left;cursor:default}.usage-answer-card.primary[_ngcontent-%COMP%]{border-color:#0c9f8347;background:linear-gradient(135deg,#0c9f831f,#6f5cff0d),var(--surface)}.usage-answer-card.empty[_ngcontent-%COMP%]:disabled{cursor:default;opacity:.72}.usage-answer-card.can-open[_ngcontent-%COMP%]{cursor:pointer}.usage-answer-card.can-open[_ngcontent-%COMP%]:hover{border-color:color-mix(in srgb,var(--accent) 42%,var(--line));transform:translateY(-1px)}.usage-answer-card[_ngcontent-%COMP%] span[_ngcontent-%COMP%], .usage-answer-card[_ngcontent-%COMP%] em[_ngcontent-%COMP%], .usage-answer-card[_ngcontent-%COMP%] small[_ngcontent-%COMP%], .daily-usage-list[_ngcontent-%COMP%] span[_ngcontent-%COMP%], .daily-usage-list[_ngcontent-%COMP%] em[_ngcontent-%COMP%], .usage-panel[_ngcontent-%COMP%] p[_ngcontent-%COMP%], .usage-panel[_ngcontent-%COMP%] li[_ngcontent-%COMP%], .panel-heading[_ngcontent-%COMP%] p[_ngcontent-%COMP%], .panel-heading[_ngcontent-%COMP%] > span[_ngcontent-%COMP%]{color:var(--muted);font-size:12px;font-style:normal;line-height:1.35}.usage-answer-card[_ngcontent-%COMP%] .usage-card-label[_ngcontent-%COMP%]{color:var(--muted-2);font-size:10px;font-weight:820;letter-spacing:.08em;text-transform:uppercase}.usage-answer-card[_ngcontent-%COMP%] strong[_ngcontent-%COMP%]{color:var(--text-strong);font-size:21px;font-weight:820;line-height:1.05;overflow-wrap:anywhere}.usage-card-period[_ngcontent-%COMP%]{color:var(--text)!important;font-size:12px!important;font-weight:760}.usage-answer-card[_ngcontent-%COMP%] i[_ngcontent-%COMP%]{display:block;width:100%;height:5px;overflow:hidden;border-radius:999px;background:#61708524}.usage-answer-card[_ngcontent-%COMP%] b[_ngcontent-%COMP%]{display:block;height:100%;border-radius:inherit;background:linear-gradient(90deg,var(--accent),var(--accent-2))}.usage-card-footer[_ngcontent-%COMP%]{display:flex;align-items:center;justify-content:space-between;gap:8px}.usage-card-footer[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{min-width:0}.usage-card-action[_ngcontent-%COMP%]{flex:0 0 auto;color:var(--accent-strong, var(--accent))!important;font-size:11px!important;font-weight:820}.usage-answer-card[_ngcontent-%COMP%]:disabled .usage-card-action[_ngcontent-%COMP%]{color:var(--muted-2)!important}.usage-panels[_ngcontent-%COMP%]{display:grid;grid-template-columns:1fr;gap:12px;align-items:start}.usage-panel[_ngcontent-%COMP%]{display:grid;gap:10px;padding:13px}.panel-heading[_ngcontent-%COMP%]{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.panel-heading[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], .usage-panel[_ngcontent-%COMP%] h3[_ngcontent-%COMP%]{margin:0;color:var(--text-strong);font-size:16px;font-weight:800}.panel-heading[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{margin:3px 0 0}.panel-heading[_ngcontent-%COMP%] > span[_ngcontent-%COMP%]{flex:0 0 auto;border:1px solid var(--line);border-radius:999px;padding:4px 8px;background:var(--surface-soft);font-weight:760}.daily-usage-list[_ngcontent-%COMP%]{display:grid;gap:6px}.daily-usage-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{display:grid;grid-template-columns:minmax(120px,.45fr) minmax(110px,.35fr) minmax(0,1fr);gap:10px;align-items:center;border:1px solid var(--line);border-radius:10px;padding:8px 10px;background:var(--surface-soft);color:var(--text);text-align:left;cursor:default}.daily-usage-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:disabled{cursor:default}.daily-usage-list[_ngcontent-%COMP%] button.empty[_ngcontent-%COMP%]:disabled{opacity:.64}.daily-usage-list[_ngcontent-%COMP%] button.can-open[_ngcontent-%COMP%]{cursor:pointer}.daily-usage-list[_ngcontent-%COMP%] button.can-open[_ngcontent-%COMP%]:hover{border-color:var(--line-strong)}.daily-usage-list[_ngcontent-%COMP%] strong[_ngcontent-%COMP%]{color:var(--text-strong);font-size:14px;font-weight:800}@media(max-width:1200px){.usage-answer-grid[_ngcontent-%COMP%]{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(max-width:850px){.usage-header[_ngcontent-%COMP%], .panel-heading[_ngcontent-%COMP%]{display:grid}.usage-controls[_ngcontent-%COMP%]{grid-template-columns:1fr;width:100%}.usage-answer-grid[_ngcontent-%COMP%]{grid-template-columns:repeat(2,minmax(0,1fr))}.daily-usage-list[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{grid-template-columns:1fr;gap:4px}}@media(max-width:560px){.usage-answer-grid[_ngcontent-%COMP%]{grid-template-columns:1fr}}"]})};function me(n){return new Date(n.getFullYear(),n.getMonth(),n.getDate())}function ee(n,t){let e=new Date(n);return e.setDate(e.getDate()+t),e}function Ce(n){let t=n.getFullYear(),e=String(n.getMonth()+1).padStart(2,"0"),a=String(n.getDate()).padStart(2,"0");return`${t}-${e}-${a}`}export{Z as UsagePageComponent};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as N,d as D}from"./chunk-OS2XPCVW.js";import{$a as _,Ca as g,Da as u,Ea as F,Fa as O,Ga as S,Ha as h,Ia as i,J as k,Ja as n,Ka as T,O as y,Oa as b,P as M,Qa as x,Sa as c,U as E,Ua as V,Va as o,Wa as p,Xa as C,Ya as P,Z as f,_a as d,ab as w,db as v,ka as l,nb as z,ob as B,sa as I,sb as j,tb as q,ub as R,vb as $,wb as A,xb as L,yb as K,zb as W}from"./chunk-WOIYAEKB.js";var Q=(r,t)=>t.id;function G(r,t){if(r&1&&(i(0,"option",15),o(1),n()),r&2){let e=t.$implicit;h("value",e),l(),p(e==="all"?"All workspaces":e)}}function U(r,t){if(r&1){let e=b();i(0,"button",23),x("click",function(){y(e);let s=c(2);return M(s.resetFilters())}),o(1,"Reset"),n()}}function J(r,t){if(r&1&&(i(0,"em"),o(1),d(2,"number"),n()),r&2){let e=c().$implicit;l(),P(" ",_(2,2,e.recalls==null?null:e.recalls.length)," ",(e.recalls==null?null:e.recalls.length)===1?"read":"reads"," ")}}function X(r,t){if(r&1&&(i(0,"time"),o(1),d(2,"date"),n()),r&2){let e=c().$implicit;l(),p(w(2,1,e.modifiedAt,"MMM d"))}}function Y(r,t){if(r&1){let e=b();i(0,"button",24),x("click",function(){let s=y(e).$implicit,m=c(2);return M(m.selectMemory(s))}),i(1,"span",25),o(2),n(),i(3,"span",26)(4,"small"),o(5),n(),i(6,"strong"),o(7),n()(),i(8,"span",27)(9,"b"),o(10),n(),g(11,J,3,4,"em")(12,X,3,4,"time"),n()()}if(r&2){let e=t.$implicit,a=c(2);V("active",a.selectedMemory().id===e.id)("plan",e.kind==="plan"),l(2),C(" ",e.kind==="plan"?"P":"M"," "),l(3),p(a.fileName(e)),l(2),p(e.title),l(3),p(e.kind==="plan"?"Plan":a.scopeLabel(e.scope)),l(),u(e.recalls!=null&&e.recalls.length?11:12)}}function Z(r,t){if(r&1){let e=b();i(0,"button",23),x("click",function(){y(e);let s=c(2),m=c(2);return M(m.emitOpenSession(s))}),o(1),n()}if(r&2){let e=c();l(),C(" Created in: ",e.title," ")}}function ee(r,t){if(r&1&&(i(0,"span"),o(1),n()),r&2){let e=c();l(),C("Created in: ",e.title)}}function te(r,t){if(r&1&&g(0,Z,2,1,"button",20)(1,ee,2,1,"span"),r&2){let e=c(3);u(e.canOpenSession?0:1)}}function ne(r,t){if(r&1&&(i(0,"span"),o(1),n()),r&2){let e=c();l(),C("Session ",e.sessionId.slice(0,8))}}function oe(r,t){if(r&1&&(i(0,"p",34),o(1),n()),r&2){let e=c(3);l(),p(e.actionStatus())}}function ie(r,t){if(r&1){let e=b();i(0,"button",23),x("click",function(){y(e);let s=c(2).$implicit,m=c(4);return M(m.emitRecallSession(s.sessionId))}),o(1),n()}if(r&2){let e=c();l(),C(" ",e.title," ")}}function re(r,t){if(r&1&&(i(0,"span"),o(1),n()),r&2){let e=c();l(),p(e.title)}}function ae(r,t){if(r&1&&g(0,ie,2,1,"button",20)(1,re,2,1,"span"),r&2){let e=c(5);u(e.canOpenSession?0:1)}}function le(r,t){if(r&1&&(i(0,"span"),o(1),n()),r&2){let e=c().$implicit;l(),C("Session ",e.sessionId.slice(0,8))}}function se(r,t){if(r&1&&(o(0),d(1,"number")),r&2){let e=c();C(" \xB7 ",_(1,1,e.cachedInputTokens)," cached ")}}function ce(r,t){if(r&1&&(i(0,"span"),o(1),d(2,"number"),g(3,se,2,3),n()),r&2){let e=t,a=c().$implicit,s=c(4);l(),P(" ",s.recallRequestLabel(a)," \xB7 ",_(2,3,e.inputTokens)," input "),l(2),u(e.cachedInputTokens?3:-1)}}function me(r,t){if(r&1&&(i(0,"article",40)(1,"div")(2,"time"),o(3),d(4,"date"),n(),g(5,ae,2,1)(6,le,2,1,"span"),n(),i(7,"div",42)(8,"span"),o(9),d(10,"number"),n(),g(11,ce,4,5,"span"),n()()),r&2){let e,a,s=t.$implicit,m=c(4);l(3),p(w(4,4,s.timestamp,"medium")),l(2),u((e=m.recallSession(s.sessionId))?5:6,e),l(4),C("",_(10,7,s.returnedCharacterCount)," characters loaded"),l(2),u((a=s.followingModelCall)?11:-1,a)}}function pe(r,t){if(r&1&&(i(0,"section",35)(1,"header")(2,"div")(3,"span",29),o(4,"Observed use"),n(),i(5,"h4"),o(6),d(7,"number"),n()(),i(8,"p"),o(9,"These are explicit memory reads recorded by VS Code."),n()(),i(10,"div",39),O(11,me,12,9,"article",40,Q),n(),i(13,"p",41),o(14," Request totals include the complete prompt and context, not only this memory. "),n()()),r&2){let e=c();l(6),P(" Read ",_(7,2,e.recalls==null?null:e.recalls.length)," ",(e.recalls==null?null:e.recalls.length)===1?"time":"times"," "),l(5),S(e.recalls)}}function de(r,t){if(r&1){let e=b();i(0,"article",22)(1,"header",28)(2,"div")(3,"span",29),o(4),n(),i(5,"h3"),o(6),n(),i(7,"p"),o(8),d(9,"date"),n()(),i(10,"div",30)(11,"button",23),x("click",function(){let s=y(e),m=c(2);return M(m.copyContent(s))}),o(12,"Copy"),n(),i(13,"button",23),x("click",function(){let s=y(e),m=c(2);return M(m.runMemoryAction(s,"open"))}),o(14,"Open file"),n(),i(15,"button",23),x("click",function(){let s=y(e),m=c(2);return M(m.runMemoryAction(s,"reveal"))}),o(16,"Show in folder"),n(),i(17,"button",23),x("click",function(){let s=y(e),m=c(2);return M(m.copyPath(s))}),o(18,"Copy path"),n()()(),i(19,"div",31)(20,"span",32)(21,"b"),o(22),n(),o(23," scope "),T(24,"app-help-popover",33),n(),i(25,"span")(26,"b"),o(27),d(28,"number"),n(),o(29," characters"),n(),i(30,"span")(31,"b"),o(32),d(33,"number"),n(),o(34," lines"),n(),i(35,"span")(36,"b"),o(37),n()(),g(38,te,2,1)(39,ne,2,1,"span"),n(),g(40,oe,2,1,"p",34),g(41,pe,15,4,"section",35),i(42,"details",36)(43,"summary")(44,"span"),o(45,"Markdown source"),n(),i(46,"small"),o(47),d(48,"number"),d(49,"number"),n()(),i(50,"pre",37),o(51),n()(),i(52,"footer",38)(53,"span"),o(54,"Local file"),n(),i(55,"code"),o(56),n()()()}if(r&2){let e,a=t,s=c(2);l(4),C(" ",a.kind==="plan"?"Saved plan":s.scopeLabel(a.scope)+" memory"," "),l(2),p(a.title),l(2),P(" ",a.workspace||"Available across workspaces"," \xB7 updated ",w(9,16,a.modifiedAt,"medium")," "),l(14),p(s.scopeLabel(a.scope)),l(2),h("text",s.scopeHelp(a.scope)),l(3),p(_(28,19,a.characterCount)),l(5),p(_(33,21,a.lineCount)),l(5),p(s.fileName(a)),l(),u((e=s.linkedSession(a))?38:a.sessionId?39:-1,e),l(2),u(s.actionStatus()?40:-1),l(),u(a.recalls!=null&&a.recalls.length?41:-1),l(6),P("",_(48,23,a.lineCount)," lines \xB7 ",_(49,25,a.characterCount)," characters"),l(4),p(a.content),l(5),p(a.sourcePath)}}function _e(r,t){if(r&1&&(i(0,"section",16)(1,"aside",18)(2,"div",19)(3,"span"),o(4),d(5,"number"),n(),g(6,U,2,0,"button",20),n(),O(7,Y,13,9,"button",21,Q),n(),g(9,de,57,27,"article",22),n()),r&2){let e,a=c();l(4),C("",_(5,3,a.filteredMemories().length)," shown"),l(2),u(a.query()||a.scopeFilter()!=="all"||a.kindFilter()!=="all"||a.workspaceFilter()!=="all"?6:-1),l(),S(a.filteredMemories()),l(2),u((e=a.selectedMemory())?9:-1,e)}}function ge(r,t){if(r&1){let e=b();i(0,"button",23),x("click",function(){y(e);let s=c(2);return M(s.resetFilters())}),o(1,"Reset filters"),n()}}function ue(r,t){if(r&1&&(i(0,"section",17)(1,"h3"),o(2),n(),i(3,"p"),o(4),n(),g(5,ge,2,0,"button",20),n()),r&2){let e=c();l(2),p(e.memoriesInput().length?"No memories match these filters":"No Copilot memories found"),l(2),C(" ",e.memoriesInput().length?"Try a broader search or reset the filters.":"Create a saved memory or plan in VS Code, then refresh the local scan."," "),l(),u(e.memoriesInput().length?5:-1)}}var H=class r{http=k(N);memoriesInput=f([]);sessionsInput=f([]);query=f("");scopeFilter=f("all");kindFilter=f("all");workspaceFilter=f("all");selectedId=f(null);actionStatus=f("");set memories(t){let e=t??[];this.memoriesInput.set(e),(!this.selectedId()||!e.some(a=>a.id===this.selectedId()))&&this.selectedId.set(e[0]?.id??null)}set sessions(t){this.sessionsInput.set(t??[])}canOpenSession=!0;openSession=new E;workspaceOptions=v(()=>["all",...[...new Set(this.memoriesInput().map(t=>t.workspace).filter(Boolean))].sort()]);filteredMemories=v(()=>{let t=this.query().trim().toLowerCase();return this.memoriesInput().filter(e=>(!t||[e.title,e.excerpt,e.content,e.relativePath,e.sourcePath,this.fileName(e),e.workspace,e.scope,e.kind].join(" ").toLowerCase().includes(t))&&(this.scopeFilter()==="all"||e.scope===this.scopeFilter())&&(this.kindFilter()==="all"||e.kind===this.kindFilter())&&(this.workspaceFilter()==="all"||e.workspace===this.workspaceFilter()))});selectedMemory=v(()=>{let t=this.filteredMemories();return t.find(e=>e.id===this.selectedId())??t[0]??null});summary=v(()=>{let t=this.memoriesInput();return{total:t.length,plans:t.filter(e=>e.kind==="plan").length,recalls:t.reduce((e,a)=>e+(a.recalls?.length??0),0),repositories:new Set(t.map(e=>e.workspace).filter(Boolean)).size}});recallSession(t){return this.sessionsInput().find(e=>e.id===t)??null}emitRecallSession(t){let e=this.recallSession(t);this.canOpenSession&&e&&this.openSession.emit(e)}recallRequestLabel(t){let e=t.followingModelCall?.number,a=e?`request ${e}`:"request";return t.sourceLog==="main.jsonl"?`Before model ${a}`:`Before subagent model ${a}`}selectMemory(t){this.selectedId.set(t.id),this.actionStatus.set("")}setScopeFilter(t){this.scopeFilter.set(t),this.actionStatus.set(""),this.ensureVisibleSelection()}setKindFilter(t){this.kindFilter.set(t),this.actionStatus.set(""),this.ensureVisibleSelection()}setWorkspaceFilter(t){this.workspaceFilter.set(t),this.actionStatus.set(""),this.ensureVisibleSelection()}setQuery(t){this.query.set(t),this.actionStatus.set(""),this.ensureVisibleSelection()}resetFilters(){this.query.set(""),this.scopeFilter.set("all"),this.kindFilter.set("all"),this.workspaceFilter.set("all"),this.ensureVisibleSelection()}fileName(t){return(t.relativePath||t.sourcePath).split(/[\\/]+/).filter(Boolean).at(-1)??t.title}scopeHelp(t){return{session:"Session-scoped memory is tied to one Copilot session. It is useful for saved plans or temporary research from that run.",repository:"Repository memory is saved for a workspace repository and can be available to future Copilot sessions in that workspace.",workspace:"Workspace memory belongs to this VS Code workspace but is not clearly tied to one repository or session.",global:"Global memory is stored in VS Code user storage and can apply across workspaces on this machine."}[t]}ensureVisibleSelection(){let t=this.filteredMemories();if(!t.length){this.selectedId.set(null);return}t.some(e=>e.id===this.selectedId())||this.selectedId.set(t[0].id)}linkedSession(t){return t.sessionId?this.sessionsInput().find(e=>e.id===t.sessionId)??null:null}emitOpenSession(t){let e=this.linkedSession(t);this.canOpenSession&&e&&this.openSession.emit(e)}runMemoryAction(t,e){this.actionStatus.set(e==="open"?"Opening file\u2026":"Showing file\u2026"),this.http.post(D(`/api/memories/${t.id}/open`),{action:e}).subscribe({next:()=>this.actionStatus.set(e==="open"?"Opened file":"Shown in folder"),error:()=>this.actionStatus.set("File actions require the local runtime")})}async copyPath(t){try{await globalThis.navigator?.clipboard?.writeText(t.sourcePath),this.actionStatus.set("Path copied")}catch{this.actionStatus.set("Could not copy the path")}}async copyContent(t){try{await globalThis.navigator?.clipboard?.writeText(t.content),this.actionStatus.set("Memory copied")}catch{this.actionStatus.set("Could not copy the memory")}}scopeLabel(t){return{global:"Global",repository:"Repository",session:"Session",workspace:"Workspace"}[t]}static \u0275fac=function(e){return new(e||r)};static \u0275cmp=I({type:r,selectors:[["app-memory-page"]],inputs:{memories:"memories",sessions:"sessions",canOpenSession:"canOpenSession"},outputs:{openSession:"openSession"},decls:69,vars:17,consts:[[1,"memory-page"],[1,"memory-header"],[1,"eyebrow"],["aria-label","Memory summary",1,"memory-header-meta"],["aria-label","Memory filters",1,"memory-controls"],[1,"memory-search"],["type","search","placeholder","Search title, filename, content, or path",3,"ngModelChange","ngModel"],[3,"ngModelChange","ngModel"],["value","all"],["value","memory"],["value","plan"],["value","global"],["value","repository"],["value","session"],["value","workspace"],[3,"value"],[1,"memory-workspace"],[1,"memory-empty"],["aria-label","Saved memories",1,"memory-list"],[1,"memory-list-heading"],["type","button"],["type","button",1,"memory-card",3,"active","plan"],[1,"memory-detail"],["type","button",3,"click"],["type","button",1,"memory-card",3,"click"],["aria-hidden","true",1,"memory-file-icon"],[1,"memory-card-main"],[1,"memory-card-side"],[1,"memory-detail-header"],[1,"memory-kicker"],[1,"memory-actions"],[1,"memory-facts"],[1,"scope-fact"],["label","Explain memory scope",3,"text"],["aria-live","polite",1,"memory-action-status"],["aria-label","Observed memory use",1,"memory-recalls"],[1,"memory-source"],[1,"memory-content"],[1,"memory-path"],[1,"memory-recall-list"],[1,"memory-recall-row"],[1,"memory-recall-note"],[1,"memory-recall-facts"]],template:function(e,a){e&1&&(i(0,"section",0)(1,"header",1)(2,"div")(3,"p",2),o(4,"Copilot memory"),n(),i(5,"h2"),o(6,"What Copilot remembers"),n(),i(7,"p"),o(8,"Saved plans and memories from local VS Code Copilot storage."),n()(),i(9,"div",3)(10,"span")(11,"strong"),o(12),d(13,"number"),n(),o(14," files"),n(),i(15,"span")(16,"strong"),o(17),d(18,"number"),n(),o(19," plans"),n(),i(20,"span")(21,"strong"),o(22),d(23,"number"),n(),o(24," reads"),n(),i(25,"span")(26,"strong"),o(27),d(28,"number"),n(),o(29," workspaces"),n(),i(30,"b"),o(31,"Read-only"),n()()(),i(32,"section",4)(33,"label",5)(34,"span"),o(35,"Search memories"),n(),i(36,"input",6),x("ngModelChange",function(m){return a.setQuery(m)}),n()(),i(37,"label")(38,"span"),o(39,"Type"),n(),i(40,"select",7),x("ngModelChange",function(m){return a.setKindFilter(m)}),i(41,"option",8),o(42,"Memories and plans"),n(),i(43,"option",9),o(44,"Memories"),n(),i(45,"option",10),o(46,"Plans"),n()()(),i(47,"label")(48,"span"),o(49,"Scope"),n(),i(50,"select",7),x("ngModelChange",function(m){return a.setScopeFilter(m)}),i(51,"option",8),o(52,"All scopes"),n(),i(53,"option",11),o(54,"Global"),n(),i(55,"option",12),o(56,"Repository"),n(),i(57,"option",13),o(58,"Session"),n(),i(59,"option",14),o(60,"Workspace"),n()()(),i(61,"label")(62,"span"),o(63,"Workspace"),n(),i(64,"select",7),x("ngModelChange",function(m){return a.setWorkspaceFilter(m)}),O(65,G,2,2,"option",15,F),n()()(),g(67,_e,10,5,"section",16)(68,ue,6,3,"section",17),n()),e&2&&(l(12),p(_(13,9,a.summary().total)),l(5),p(_(18,11,a.summary().plans)),l(5),p(_(23,13,a.summary().recalls)),l(5),p(_(28,15,a.summary().repositories)),l(9),h("ngModel",a.query()),l(4),h("ngModel",a.kindFilter()),l(10),h("ngModel",a.scopeFilter()),l(14),h("ngModel",a.workspaceFilter()),l(),S(a.workspaceOptions()),l(2),u(a.filteredMemories().length?67:68))},dependencies:[W,L,K,q,A,R,$,j,z,B],styles:['[_nghost-%COMP%]{display:block}.memory-page[_ngcontent-%COMP%]{display:grid;grid-template-rows:auto auto minmax(0,1fr);gap:8px;min-height:calc(100vh - 96px)}.memory-header[_ngcontent-%COMP%], .memory-controls[_ngcontent-%COMP%], .memory-list[_ngcontent-%COMP%], .memory-detail[_ngcontent-%COMP%], .memory-empty[_ngcontent-%COMP%]{border:1px solid var(--line);background:var(--surface);box-shadow:var(--shadow-soft)}.memory-header[_ngcontent-%COMP%]{display:flex;align-items:center;justify-content:space-between;gap:14px;border-color:color-mix(in srgb,var(--accent-2) 18%,var(--line));border-radius:14px;padding:12px 14px;background:var(--header-gradient)}.eyebrow[_ngcontent-%COMP%], .memory-kicker[_ngcontent-%COMP%]{margin:0;color:var(--muted-2);font-size:9px;font-weight:820;letter-spacing:.08em;text-transform:uppercase}.memory-header[_ngcontent-%COMP%] h2[_ngcontent-%COMP%], .memory-detail[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], .memory-empty[_ngcontent-%COMP%] h3[_ngcontent-%COMP%]{margin:2px 0 0;color:var(--text-strong);letter-spacing:0}.memory-header[_ngcontent-%COMP%] h2[_ngcontent-%COMP%]{font-size:21px;line-height:1.15}.memory-header[_ngcontent-%COMP%] p[_ngcontent-%COMP%], .memory-detail-header[_ngcontent-%COMP%] p[_ngcontent-%COMP%], .memory-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{margin:4px 0 0;color:var(--muted);font-size:12px;line-height:1.35}.memory-header-meta[_ngcontent-%COMP%]{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:5px}.memory-header-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%], .memory-header-meta[_ngcontent-%COMP%] b[_ngcontent-%COMP%]{display:inline-flex;align-items:center;min-height:24px;border:1px solid var(--line);border-radius:999px;padding:3px 8px;background:color-mix(in srgb,var(--surface) 74%,transparent);color:var(--muted);font-size:11px;font-weight:720;white-space:nowrap}.memory-header-meta[_ngcontent-%COMP%] strong[_ngcontent-%COMP%]{margin-right:4px;color:var(--text-strong)}.memory-header-meta[_ngcontent-%COMP%] b[_ngcontent-%COMP%]{border-color:color-mix(in srgb,var(--accent) 28%,var(--line));color:var(--accent)}.memory-controls[_ngcontent-%COMP%]{display:grid;grid-template-columns:minmax(260px,1.8fr) repeat(3,minmax(130px,.8fr));gap:7px;border-radius:12px;padding:8px}.memory-controls[_ngcontent-%COMP%] label[_ngcontent-%COMP%]{display:grid;gap:4px}.memory-controls[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{color:var(--muted);font-size:10px;font-weight:760}.memory-controls[_ngcontent-%COMP%] input[_ngcontent-%COMP%], .memory-controls[_ngcontent-%COMP%] select[_ngcontent-%COMP%]{width:100%;min-height:32px;border:1px solid var(--line);border-radius:8px;padding:6px 9px;background:var(--surface-soft);color:var(--text);font:inherit;font-size:12px}.memory-workspace[_ngcontent-%COMP%]{display:grid;grid-template-columns:minmax(320px,380px) minmax(0,1fr);gap:10px;align-items:start;min-height:0}.memory-list[_ngcontent-%COMP%], .memory-detail[_ngcontent-%COMP%], .memory-empty[_ngcontent-%COMP%]{border-radius:13px}.memory-list[_ngcontent-%COMP%]{position:sticky;top:70px;display:grid;align-content:start;gap:3px;max-height:calc(100vh - 150px);overflow:auto;padding:7px}.memory-list-heading[_ngcontent-%COMP%]{position:sticky;top:0;z-index:1;display:flex;align-items:center;justify-content:space-between;min-height:28px;padding:2px 4px 5px;background:var(--surface);color:var(--muted);font-size:11px}.memory-list-heading[_ngcontent-%COMP%] button[_ngcontent-%COMP%], .memory-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%], .memory-facts[_ngcontent-%COMP%] button[_ngcontent-%COMP%], .memory-empty[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{border:1px solid var(--line);border-radius:7px;padding:5px 8px;background:var(--surface-soft);color:var(--text);font:inherit;font-size:11px;font-weight:760;cursor:pointer}.memory-card[_ngcontent-%COMP%]{display:grid;grid-template-columns:22px minmax(0,1fr) auto;align-items:center;gap:8px;width:100%;min-height:47px;border:1px solid transparent;border-radius:8px;padding:7px 8px;background:transparent;color:var(--text);text-align:left;cursor:pointer}.memory-card[_ngcontent-%COMP%]:hover, .memory-card.active[_ngcontent-%COMP%]{border-color:color-mix(in srgb,var(--accent) 34%,var(--line));background:color-mix(in srgb,var(--accent) 6%,var(--surface-soft))}.memory-card.plan.active[_ngcontent-%COMP%]{border-color:color-mix(in srgb,var(--accent-2) 42%,var(--line));background:color-mix(in srgb,var(--accent-2) 7%,var(--surface-soft))}.memory-file-icon[_ngcontent-%COMP%]{display:grid;place-items:center;width:22px;height:22px;border-radius:6px;background:color-mix(in srgb,var(--accent) 12%,var(--surface-soft));color:var(--accent);font-size:10px;font-weight:850}.memory-card.plan[_ngcontent-%COMP%] .memory-file-icon[_ngcontent-%COMP%]{background:color-mix(in srgb,var(--accent-2) 14%,var(--surface-soft));color:var(--accent-2)}.memory-card-main[_ngcontent-%COMP%], .memory-card-side[_ngcontent-%COMP%]{display:grid;gap:2px;min-width:0}.memory-card-main[_ngcontent-%COMP%] strong[_ngcontent-%COMP%]{overflow:hidden;color:var(--text-strong);font-size:13px;font-weight:760;line-height:1.22;text-overflow:ellipsis;white-space:nowrap}.memory-card-main[_ngcontent-%COMP%] small[_ngcontent-%COMP%]{overflow:hidden;color:var(--muted-2);font-size:10px;line-height:1.15;text-overflow:ellipsis;white-space:nowrap}.memory-card-side[_ngcontent-%COMP%]{justify-items:end;color:var(--muted-2);font-size:10px;white-space:nowrap}.memory-card-side[_ngcontent-%COMP%] b[_ngcontent-%COMP%]{color:var(--muted);font-size:10px;text-transform:uppercase}.memory-card-side[_ngcontent-%COMP%] em[_ngcontent-%COMP%]{border-radius:999px;padding:2px 6px;background:color-mix(in srgb,var(--accent) 10%,var(--surface));color:var(--accent);font-style:normal;font-weight:760}.memory-detail[_ngcontent-%COMP%]{min-width:0;padding:14px}.memory-detail-header[_ngcontent-%COMP%]{display:flex;align-items:flex-start;justify-content:space-between;gap:14px}.memory-detail[_ngcontent-%COMP%] h3[_ngcontent-%COMP%]{font-size:20px;line-height:1.2}.memory-actions[_ngcontent-%COMP%], .memory-facts[_ngcontent-%COMP%]{display:flex;flex-wrap:wrap;gap:6px}.memory-actions[_ngcontent-%COMP%]{justify-content:flex-end}.memory-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%]:first-child{border-color:var(--accent);background:var(--accent);color:#fff}.memory-facts[_ngcontent-%COMP%]{margin-top:10px}.memory-facts[_ngcontent-%COMP%] > span[_ngcontent-%COMP%], .memory-facts[_ngcontent-%COMP%] > button[_ngcontent-%COMP%]{display:inline-flex;align-items:center;gap:5px;min-height:25px;border:1px solid var(--line);border-radius:999px;padding:4px 8px;background:var(--surface-soft);color:var(--muted);font-size:11px}.memory-facts[_ngcontent-%COMP%] b[_ngcontent-%COMP%]{color:var(--text-strong)}.memory-facts[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{color:var(--accent)}.memory-action-status[_ngcontent-%COMP%]{margin:9px 0 0;color:var(--accent);font-size:11px}.memory-recalls[_ngcontent-%COMP%]{display:grid;gap:8px;margin-top:12px;border:1px solid color-mix(in srgb,var(--accent) 22%,var(--line));border-radius:10px;padding:10px;background:color-mix(in srgb,var(--accent) 4%,var(--surface-soft))}.memory-recalls[_ngcontent-%COMP%] > header[_ngcontent-%COMP%]{display:flex;align-items:end;justify-content:space-between;gap:10px}.memory-recalls[_ngcontent-%COMP%] h4[_ngcontent-%COMP%]{margin:2px 0 0;color:var(--text-strong);font-size:14px}.memory-recalls[_ngcontent-%COMP%] > header[_ngcontent-%COMP%] p[_ngcontent-%COMP%], .memory-recall-note[_ngcontent-%COMP%]{margin:0;color:var(--muted);font-size:11px}.memory-recall-list[_ngcontent-%COMP%]{display:grid;gap:5px}.memory-recall-row[_ngcontent-%COMP%]{display:grid;grid-template-columns:minmax(180px,.8fr) minmax(230px,1.2fr);gap:10px;border-top:1px solid var(--line);padding-top:7px}.memory-recall-row[_ngcontent-%COMP%] > div[_ngcontent-%COMP%], .memory-recall-facts[_ngcontent-%COMP%]{display:grid;gap:2px}.memory-recall-row[_ngcontent-%COMP%] time[_ngcontent-%COMP%], .memory-recall-row[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{color:var(--muted);font-size:11px}.memory-recall-row[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{width:fit-content;border:0;padding:0;background:none;color:var(--accent);font:inherit;font-size:12px;font-weight:760;text-align:left;cursor:pointer}.memory-source[_ngcontent-%COMP%]{margin-top:12px;border:1px solid var(--line);border-radius:10px;background:var(--surface-soft)}.memory-source[_ngcontent-%COMP%] summary[_ngcontent-%COMP%]{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:38px;padding:8px 11px;color:var(--text-strong);cursor:pointer;list-style:none}.memory-source[_ngcontent-%COMP%] summary[_ngcontent-%COMP%]::-webkit-details-marker{display:none}.memory-source[_ngcontent-%COMP%] summary[_ngcontent-%COMP%]:before{content:"";flex:0 0 auto;width:7px;height:7px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(-45deg);transition:transform .14s ease}.memory-source[open][_ngcontent-%COMP%] summary[_ngcontent-%COMP%]:before{transform:rotate(45deg)}.memory-source[_ngcontent-%COMP%] summary[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{flex:1;font-size:12px;font-weight:780}.memory-source[_ngcontent-%COMP%] summary[_ngcontent-%COMP%] small[_ngcontent-%COMP%]{color:var(--muted);font-size:11px}.memory-content[_ngcontent-%COMP%]{max-height:48vh;margin:0;border-top:1px solid var(--line);padding:14px;overflow:auto;color:var(--text);font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace;font-size:12px;line-height:1.58;white-space:pre-wrap;overflow-wrap:anywhere}.memory-path[_ngcontent-%COMP%]{display:grid;gap:4px;margin-top:10px;color:var(--muted-2);font-size:10px;text-transform:uppercase}.memory-path[_ngcontent-%COMP%] code[_ngcontent-%COMP%]{display:block;border:1px solid var(--line);border-radius:8px;padding:7px 9px;background:var(--surface-soft);color:var(--muted);font-size:11px;text-transform:none;overflow-wrap:anywhere;-webkit-user-select:text;user-select:text}.memory-empty[_ngcontent-%COMP%]{display:grid;justify-items:start;padding:28px}@media(max-width:1050px){.memory-controls[_ngcontent-%COMP%]{grid-template-columns:repeat(2,minmax(0,1fr))}.memory-search[_ngcontent-%COMP%]{grid-column:1 / -1}}@media(max-width:820px){.memory-page[_ngcontent-%COMP%]{min-height:auto}.memory-detail-header[_ngcontent-%COMP%]{display:grid}.memory-workspace[_ngcontent-%COMP%]{grid-template-columns:1fr}.memory-header[_ngcontent-%COMP%]{align-items:flex-start;padding:10px}.memory-header[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{display:none}.memory-header-meta[_ngcontent-%COMP%]{display:grid;grid-template-columns:repeat(2,max-content);justify-content:end;gap:4px}.memory-header-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%], .memory-header-meta[_ngcontent-%COMP%] b[_ngcontent-%COMP%]{min-height:21px;padding:2px 6px;font-size:10px}.memory-controls[_ngcontent-%COMP%]{grid-template-columns:repeat(3,minmax(0,1fr))}.memory-search[_ngcontent-%COMP%]{grid-column:1 / -1}.memory-list[_ngcontent-%COMP%]{position:static;max-height:420px}.memory-actions[_ngcontent-%COMP%]{justify-content:flex-start}.memory-recalls[_ngcontent-%COMP%] > header[_ngcontent-%COMP%], .memory-recall-row[_ngcontent-%COMP%]{display:grid;grid-template-columns:1fr}}@media(max-width:480px){.memory-header[_ngcontent-%COMP%]{display:grid}.memory-header-meta[_ngcontent-%COMP%]{justify-content:start}.memory-controls[_ngcontent-%COMP%] input[_ngcontent-%COMP%], .memory-controls[_ngcontent-%COMP%] select[_ngcontent-%COMP%]{padding-inline:6px;font-size:11px}.memory-controls[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{font-size:9px}}']})};export{H as MemoryPageComponent};
|