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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*{box-sizing:border-box}html,body{margin:0;min-height:100%;font-family:Aptos,Segoe UI Variable,Segoe UI,Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,sans-serif;font-size:14px;line-height:1.45;background:#090d14;color:#d7dde7;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased}html[data-theme=light],html[data-theme=light] body{background:#f4f7fb;color:#182536}html[data-theme=dark],html[data-theme=dark] body{background:#090d14;color:#d7dde7}button,input,select{font:inherit}code{border:1px solid color-mix(in srgb,var(--accent, #6f5cff) 18%,var(--line, #d7e1ea));border-radius:5px;padding:1px 5px;background:color-mix(in srgb,var(--accent, #6f5cff) 8%,transparent);color:var(--text-strong, #182536);font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,monospace;font-size:.92em}.data-refresh{display:grid;justify-items:end;min-width:0}.data-refresh-button{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:32px;border:1px solid var(--line);border-radius:9px;padding:5px 10px;background:var(--control-bg);color:var(--text-strong);font-size:12px;font-weight:760;cursor:pointer;box-shadow:var(--shadow-soft)}.data-refresh-button:hover:not(:disabled){border-color:var(--accent);color:var(--accent)}.data-refresh-button:disabled{cursor:progress;opacity:.72}.refresh-icon{display:grid;place-items:center;width:16px;height:16px;font-size:17px;line-height:1;transform-origin:50% 50%}.refresh-icon.spinning{animation:refresh-spin .8s linear infinite}.data-refresh-status{max-width:190px;overflow:hidden;color:var(--muted-2);font-size:10px;line-height:1.2;text-overflow:ellipsis;white-space:nowrap}.data-refresh.error .data-refresh-status{color:var(--danger-text)}.host-vscode .data-refresh-status{display:none}@keyframes refresh-spin{to{transform:rotate(360deg)}}@media(max-width:760px){.data-refresh-status{display:none}}@media(max-width:520px){.data-refresh-button>span:last-child{display:none}.data-refresh-button{padding-inline:5px}}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Copilot Memory
|
|
2
|
+
|
|
3
|
+
Copilot Usage Studio indexes locally saved GitHub Copilot memories and plans so a developer can see what Copilot has stored across VS Code workspaces.
|
|
4
|
+
|
|
5
|
+
## Observed storage
|
|
6
|
+
|
|
7
|
+
Workspace-scoped files:
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
<VS Code User>/workspaceStorage/<workspace-id>/GitHub.copilot-chat/memory-tool/memories/
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Global files:
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
<VS Code User>/globalStorage/github.copilot-chat/memory-tool/memories/
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Observed workspace layouts include:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
memories/repo/<topic>.md
|
|
23
|
+
memories/<base64-session-id>/plan.md
|
|
24
|
+
memories/<base64-session-id>/<research>.md
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The base64 directory decodes to the same session UUID used by Agent Debug Logs and transcripts. This gives the app a source-backed link between a saved plan or research note and the run that created it.
|
|
28
|
+
|
|
29
|
+
## Normalized record
|
|
30
|
+
|
|
31
|
+
Each indexed Markdown file records:
|
|
32
|
+
|
|
33
|
+
- stable local id derived from its absolute path
|
|
34
|
+
- `kind`: `memory` or `plan`
|
|
35
|
+
- `scope`: `global`, `repository`, `session`, or `workspace`
|
|
36
|
+
- title, excerpt, and full Markdown content
|
|
37
|
+
- workspace name when applicable
|
|
38
|
+
- decoded session id when applicable
|
|
39
|
+
- absolute and relative source paths
|
|
40
|
+
- created and modified timestamps
|
|
41
|
+
- byte, character, and line counts
|
|
42
|
+
|
|
43
|
+
The scanner reads Markdown files once during the normal local scan. It skips files larger than 1 MiB and caps each memory root at 5,000 files. These limits protect refresh performance without affecting normal observed memory stores, whose files are small.
|
|
44
|
+
|
|
45
|
+
## Product boundary
|
|
46
|
+
|
|
47
|
+
Version one is a read-only knowledge library:
|
|
48
|
+
|
|
49
|
+
- search all saved memory content
|
|
50
|
+
- filter by plan/memory, scope, and workspace
|
|
51
|
+
- read the Markdown source
|
|
52
|
+
- link session-scoped files to imported runs
|
|
53
|
+
- show observed recall frequency, time, session, returned content size, and the following model request
|
|
54
|
+
- open the file or reveal it through the local runtime
|
|
55
|
+
|
|
56
|
+
The browser does not receive arbitrary filesystem access. Open/reveal actions identify a memory by its scanner-generated id, and the runtime accepts only files present in the current scanned snapshot.
|
|
57
|
+
|
|
58
|
+
## Observed recall evidence
|
|
59
|
+
|
|
60
|
+
Agent Debug Logs provide a useful distinction between a memory being available and actually being recalled:
|
|
61
|
+
|
|
62
|
+
- VS Code injects a memory inventory into model input. The observed inventory names available user, session, and repository memory files, but does not include every file's full contents.
|
|
63
|
+
- When the agent calls the `memory` tool with `command: "view"`, the tool event records the requested memory path and returned content.
|
|
64
|
+
- That tool result is then present in the following model request. The app can therefore say that a specific memory was loaded before a specific model call.
|
|
65
|
+
- The following model call exposes exact total input, cached input, output, and source usage when those fields are present. It does not expose a separate token total or cost for the memory text alone.
|
|
66
|
+
|
|
67
|
+
In the June 15, 2026 local log sample, 46 JSONL files contained 127 model requests with a memory inventory and 18 explicit memory-tool operations across 11 sessions. Fifteen operations were reads, including repeated reads of the repository memory. These counts establish that recall is observable, but they are only a local sample and not a VS Code API contract.
|
|
68
|
+
|
|
69
|
+
The recall view shows:
|
|
70
|
+
|
|
71
|
+
- which memory path was read
|
|
72
|
+
- when and in which session it was read
|
|
73
|
+
- the returned content size
|
|
74
|
+
- the next model call and that call's total token/usage facts
|
|
75
|
+
|
|
76
|
+
It must not label the entire following request as memory cost or derive an exact memory-only token charge from character count.
|
|
77
|
+
|
|
78
|
+
## What the app does not claim
|
|
79
|
+
|
|
80
|
+
A saved memory is evidence that Copilot wrote a local file. A matching `memory view` tool event is evidence that Copilot later recalled it and included the returned content in the request chain.
|
|
81
|
+
|
|
82
|
+
Therefore the first version does not label memories as useful, stale, harmful, or token-consuming. Those conclusions require a matching Agent Debug Log or request side-file showing that the memory was included in a model request.
|
|
83
|
+
|
|
84
|
+
Future evidence-backed opportunities:
|
|
85
|
+
|
|
86
|
+
- flag conflicting or old memories for review
|
|
87
|
+
- compare request input before and after a memory is edited or removed
|
|
88
|
+
- help turn a proven durable memory into repository instructions
|
|
89
|
+
- map repository memories to code/domain areas when paths or content provide a reliable relationship
|
|
90
|
+
|
|
91
|
+
Editing and deletion remain later work. The files are technically accessible, but VS Code's indexing and lifecycle contract is not documented strongly enough to make destructive management a first-release feature.
|
package/docs/local-deployment.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
The app is intended to run locally, near the VS Code data it reads. It should not require a hosted SaaS backend for the core workflow.
|
|
4
4
|
|
|
5
|
-
Current release posture: early
|
|
5
|
+
Current release posture: early VS Code extension preview. Version `0.2.0` exists on npm as the development/fallback host, but the VS Code extension is the product path.
|
|
6
6
|
|
|
7
|
-
Packaging foundation now available: the scanner exposes an in-memory Node API through `lib/scanner-api.mjs`. The existing scan command
|
|
7
|
+
Packaging foundation now available: the scanner exposes an in-memory Node API through `lib/scanner-api.mjs`. The existing scan command, local runtime, npm host, and VS Code extension preview use the same scanner/runtime core so behavior stays aligned across hosts.
|
|
8
8
|
|
|
9
9
|
Supported source today: VS Code GitHub Copilot Chat and Agent local storage. Visual Studio, JetBrains IDEs, Copilot CLI, GitHub.com chat, and GitHub billing exports are outside the current importer scope.
|
|
10
10
|
|
|
@@ -33,7 +33,7 @@ http://127.0.0.1:4200/
|
|
|
33
33
|
|
|
34
34
|
Why: this is the fastest loop while the UI and scanner are changing. `npm start` launches the Angular dev server and the local runtime together. The runtime serves the last valid snapshot immediately, performs a background startup scan, and powers the in-app refresh action.
|
|
35
35
|
|
|
36
|
-
##
|
|
36
|
+
## Install From npm
|
|
37
37
|
|
|
38
38
|
The npm package is configured for a one-command local launch:
|
|
39
39
|
|
|
@@ -41,7 +41,7 @@ The npm package is configured for a one-command local launch:
|
|
|
41
41
|
npx copilot-usage-studio
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
This
|
|
44
|
+
This starts the packaged production UI and scanner runtime on `http://127.0.0.1:4312/` by default. It downloads the latest published npm version rather than the current GitHub `main` branch.
|
|
45
45
|
|
|
46
46
|
Useful packaged commands:
|
|
47
47
|
|
|
@@ -54,10 +54,10 @@ npx copilot-usage-studio --help
|
|
|
54
54
|
|
|
55
55
|
The CLI requires Node.js 22.5 or newer because optional VS Code `state.vscdb` enrichment uses Node's built-in SQLite support.
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
For development or the current GitHub source, use the repository flow:
|
|
58
58
|
|
|
59
59
|
```bash
|
|
60
|
-
git clone
|
|
60
|
+
git clone https://github.com/fortunes-guardian/copilot-usage-studio.git
|
|
61
61
|
cd copilot-usage-studio
|
|
62
62
|
npm install
|
|
63
63
|
npm start
|
|
@@ -76,7 +76,7 @@ npm run test:scripts
|
|
|
76
76
|
npm run build
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
Release copy should describe the app as a local Copilot usage
|
|
79
|
+
Release copy should describe the app as a local Copilot usage inspector for VS Code, now available as a local VSIX preview. The strongest promise is: "VS Code already logs useful usage data locally; this app makes it understandable for developers who do not have billing-console access."
|
|
80
80
|
|
|
81
81
|
### Packaged Data Location
|
|
82
82
|
|
|
@@ -88,7 +88,72 @@ The packaged CLI stores its current normalized snapshot outside the npm installa
|
|
|
88
88
|
|
|
89
89
|
The npm tarball contains the compiled UI, scanner, pricing table, and runtime code. It must never contain `public/data/sessions.json` or any other developer's imported session data.
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
## Automated Releases
|
|
92
|
+
|
|
93
|
+
GitHub Actions is the release control plane:
|
|
94
|
+
|
|
95
|
+
- `.github/workflows/ci.yml` runs the full release gate and packages a VSIX artifact for every pushed branch, plus pull requests to `main`.
|
|
96
|
+
- `.github/workflows/release.yml` runs automatically for version tags such as `v0.1.1`, with a manual existing-tag mode for repair and backfill.
|
|
97
|
+
- The release workflow verifies that the tag matches `package.json`, runs the release gate, packages the VS Code extension VSIX, generates release notes from `CHANGELOG.md`, and creates the matching GitHub Release.
|
|
98
|
+
- After maintainer smoke testing and Marketplace credentials are configured, public extension releases should be published to the VS Code Marketplace so users can install without manually downloading a VSIX.
|
|
99
|
+
- A failed workflow can be rerun safely: an existing npm version is accepted only when its published `gitHead` matches the exact tagged commit. Conflicting or unverifiable versions are refused.
|
|
100
|
+
- New versions must pass the full release gate before publication. An exact-commit backfill of an already-published historical version skips its old test suite and only repairs the missing GitHub Release.
|
|
101
|
+
|
|
102
|
+
This keeps GitHub, release artifacts, release notes, and the source tag tied to the same commit. Ordinary pushes never publish.
|
|
103
|
+
|
|
104
|
+
### Branch Validation
|
|
105
|
+
|
|
106
|
+
For feature work, push the branch and let CI run:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
git push -u origin your-branch
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The CI run proves the npm app and VS Code extension package from that branch. Download the `copilot-usage-studio-vsix` artifact from the workflow run when you want to test exactly what GitHub built. For a solo-maintainer flow, a pull request is useful for review and history, but branch CI is enough for a pre-merge smoke test.
|
|
113
|
+
|
|
114
|
+
### One-Time npm Setup
|
|
115
|
+
|
|
116
|
+
Commit and push the workflow files first, then configure npm Trusted Publishing for the existing `copilot-usage-studio` package:
|
|
117
|
+
|
|
118
|
+
1. Open the package settings on npm and add a GitHub Actions trusted publisher.
|
|
119
|
+
2. Set organization or user to `fortunes-guardian`.
|
|
120
|
+
3. Set repository to `copilot-usage-studio`.
|
|
121
|
+
4. Set workflow filename to `release.yml`.
|
|
122
|
+
5. Allow the `npm publish` action.
|
|
123
|
+
6. Leave the environment blank unless the workflow is later changed to use a protected GitHub environment.
|
|
124
|
+
|
|
125
|
+
The workflow uses GitHub's OIDC identity, so no long-lived `NPM_TOKEN` repository secret is required. npm automatically adds provenance for a public package published from a public repository through Trusted Publishing.
|
|
126
|
+
|
|
127
|
+
### Publishing a Version
|
|
128
|
+
|
|
129
|
+
Start from an up-to-date, clean `main` branch. Choose the semantic-version bump that matches the change:
|
|
130
|
+
|
|
131
|
+
First, make sure `CHANGELOG.md` has a useful human summary under `Unreleased` or under the exact version heading you are about to publish. The GitHub Release body is generated from that curated changelog text, with commits included only as an audit trail.
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
git switch main
|
|
135
|
+
git pull --ff-only
|
|
136
|
+
npm run release:check
|
|
137
|
+
npm version patch
|
|
138
|
+
git push origin main --follow-tags
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
`npm version patch` updates both `package.json` and `package-lock.json`, creates a version commit, and creates an annotated `vX.Y.Z` tag. Use `npm version minor` for a backward-compatible feature release or `npm version major` for a breaking release.
|
|
142
|
+
|
|
143
|
+
After the tag is pushed:
|
|
144
|
+
|
|
145
|
+
1. Watch the **Release** workflow in GitHub Actions.
|
|
146
|
+
2. Confirm the new version appears on npm.
|
|
147
|
+
3. Confirm GitHub created a Release for the same tag.
|
|
148
|
+
4. Confirm the release notes read well and include the curated highlights.
|
|
149
|
+
5. Download the attached VSIX if the extension should be tested or shared.
|
|
150
|
+
6. Run `npx copilot-usage-studio@X.Y.Z --version` from a clean directory as a final smoke test.
|
|
151
|
+
|
|
152
|
+
If CI or release validation fails, fix the issue on `main` and publish a new version. Do not move or reuse a public release tag, and do not overwrite an npm version; both are immutable release coordinates.
|
|
153
|
+
|
|
154
|
+
The workflow also has a manual **Run workflow** action with a required existing tag. Use this to repair or backfill the GitHub Release for an exact tag. For the already-published first version, ensure `v0.1.0` exists on GitHub, then run the workflow once with `v0.1.0`; it will verify npm's published `gitHead`, skip the historical release gate and npm publication, and create the missing GitHub Release.
|
|
155
|
+
|
|
156
|
+
### Manual Emergency Fallback
|
|
92
157
|
|
|
93
158
|
Run the full package gate:
|
|
94
159
|
|
|
@@ -102,7 +167,7 @@ Inspect the tarball list, confirm no local session data or absolute paths are pr
|
|
|
102
167
|
npm publish --access public
|
|
103
168
|
```
|
|
104
169
|
|
|
105
|
-
Publishing
|
|
170
|
+
Use this only if Trusted Publishing or GitHub Actions is unavailable. The normal path is the tag-driven workflow above.
|
|
106
171
|
|
|
107
172
|
If the browser shows updated markup with stale component styles, stop the dev server and restart it with a cache reset:
|
|
108
173
|
|
|
@@ -126,7 +191,7 @@ Then serve the generated `dist/` output with a small local static server.
|
|
|
126
191
|
|
|
127
192
|
Why: Angular production output is just static assets plus the generated `public/data/sessions.json` copy. This is a good first packaging target because it avoids an app server and keeps the data model simple.
|
|
128
193
|
|
|
129
|
-
Current build status: `npm run build` passes. There
|
|
194
|
+
Current build status: `npm run build` passes. There are still Angular budget warnings for the initial bundle and `src/app/app.css`; they do not block the local preview release.
|
|
130
195
|
|
|
131
196
|
For day-to-day development, use the in-app **Refresh** action. `npm run refresh:data` remains the explicit command-line scan plus verification path.
|
|
132
197
|
|
|
@@ -140,13 +205,38 @@ npm run runtime
|
|
|
140
205
|
|
|
141
206
|
It listens on `http://127.0.0.1:4312/` by default and exposes:
|
|
142
207
|
|
|
143
|
-
- `GET /api/status`: scan state, timestamps, last error, and session count
|
|
208
|
+
- `GET /api/status`: scan state, timestamps, current progress, recent log lines, last error, and session count
|
|
209
|
+
- `GET /api/logs`: bounded in-memory runtime logs and the local log-file path
|
|
144
210
|
- `GET /api/sessions`: the current normalized in-memory `SessionData`
|
|
145
211
|
- `POST /api/scan`: run a scan, persist the new snapshot, and return it
|
|
146
212
|
- `GET /data/sessions.json`: compatibility route backed by the current in-memory snapshot
|
|
147
213
|
|
|
148
214
|
The runtime seeds itself from `public/data/sessions.json` when needed, then keeps its live cache under `tmp/local-runtime/`. This avoids triggering an Angular development rebuild every time the user refreshes data. It serves cached data while a scan is running, and a failed scan does not replace the last valid snapshot.
|
|
149
215
|
|
|
216
|
+
Runtime scans run in a child process. This keeps `/api/status` and `/api/logs` responsive even when a large VS Code profile is being imported or a workspace has unusually heavy local data.
|
|
217
|
+
|
|
218
|
+
### Startup Diagnostics
|
|
219
|
+
|
|
220
|
+
If the app appears stuck on startup, there are three places to inspect:
|
|
221
|
+
|
|
222
|
+
1. The app loading screen shows the current scan step, recent runtime log messages, cached session count, and the runtime log-file path.
|
|
223
|
+
2. The terminal running `npm start` or `npx copilot-usage-studio` prints scan progress such as discovered workspace folders and debug-log folder counts.
|
|
224
|
+
3. The status endpoint can be queried directly:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
npx copilot-usage-studio status
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
For packaged `npx` runs, the runtime log file is stored beside the local session cache:
|
|
231
|
+
|
|
232
|
+
- Windows: `%LOCALAPPDATA%\Copilot Usage Studio\runtime.log`
|
|
233
|
+
- macOS: `~/Library/Application Support/Copilot Usage Studio/runtime.log`
|
|
234
|
+
- Linux: `${XDG_DATA_HOME:-~/.local/share}/copilot-usage-studio/runtime.log`
|
|
235
|
+
|
|
236
|
+
For repository development with `npm start`, the log is written to `tmp/local-runtime/runtime.log`.
|
|
237
|
+
|
|
238
|
+
The scanner is intentionally bounded. It scans known VS Code Copilot storage locations plus targeted `.github/instructions`, `.github/skills`, `.github/prompts`, and `.github/hooks` folders for the workspace. Recursive Markdown scans have depth and directory-count caps and skip common dependency/build folders such as `node_modules`, `.git`, `dist`, `build`, `target`, and virtual environments. It should not crawl arbitrary project directories.
|
|
239
|
+
|
|
150
240
|
To build the production UI and serve the complete local app with one command:
|
|
151
241
|
|
|
152
242
|
```bash
|
|
@@ -183,9 +273,25 @@ Why: this keeps the project local and scriptable without committing to a desktop
|
|
|
183
273
|
|
|
184
274
|
The shared scanner API, runtime, and npm executable are complete. The same runtime can be embedded by Electron later.
|
|
185
275
|
|
|
186
|
-
##
|
|
276
|
+
## VS Code Companion Extension Preview
|
|
277
|
+
|
|
278
|
+
A thin VS Code extension now calls the shared scanner from the local extension host and shows the existing UI in a webview. It remains a host, not a fork of the pricing and parsing logic.
|
|
279
|
+
|
|
280
|
+
Build a local preview VSIX:
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
npm run vscode:package
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Install it locally:
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
code --install-extension tmp/copilot-usage-studio-vscode-0.2.0.vsix --force
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
The extension exposes the full app inside VS Code: Usage, Sessions, Memory, Customizations preview, Compare, Insights, and Prices. The npm/browser host remains useful for development and fallback testing, but the extension is the primary product surface.
|
|
187
293
|
|
|
188
|
-
|
|
294
|
+
The VSIX is a separate distribution artifact from the npm package. It is built from the same source tree. After Marketplace release is configured, the VS Code Marketplace should be the normal install route; `npx copilot-usage-studio` remains a development/fallback host.
|
|
189
295
|
|
|
190
296
|
Why not move the whole product into an extension: keeping the scanner and analysis core editor-independent preserves a path to a desktop app and possible Visual Studio support if Visual Studio exposes equivalent local evidence later.
|
|
191
297
|
|
package/docs/pricing.md
CHANGED
|
@@ -17,10 +17,10 @@ https://docs.github.com/en/copilot/concepts/billing/usage-based-billing-for-orga
|
|
|
17
17
|
Current version:
|
|
18
18
|
|
|
19
19
|
```text
|
|
20
|
-
github-copilot-usage-pricing-2026-
|
|
20
|
+
github-copilot-usage-pricing-2026-07-05
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
The source table says prices are per 1 million tokens. The committed snapshot was checked against GitHub Docs on
|
|
23
|
+
The source table says prices are per 1 million tokens. The committed snapshot was checked against GitHub Docs on July 5, 2026.
|
|
24
24
|
|
|
25
25
|
## Where Pricing Lives
|
|
26
26
|
|
|
@@ -40,7 +40,7 @@ This should be a deliberate maintainer update, not a runtime web fetch.
|
|
|
40
40
|
|
|
41
41
|
1. Open GitHub's official model pricing page and record the check date.
|
|
42
42
|
2. Update `data/github-copilot-pricing.json`, including model availability, all token buckets, and request-size tiers.
|
|
43
|
-
3. Keep tier thresholds machine-readable. Apply
|
|
43
|
+
3. Keep tier thresholds and raw-model aliases machine-readable. Apply tiers per model call using normal plus cached input, never aggregated session tokens.
|
|
44
44
|
4. Update the pricing version and snapshot date.
|
|
45
45
|
5. Add or update threshold boundary tests and verify that several smaller calls do not accidentally trigger a long-context tier.
|
|
46
46
|
6. Run `npm run refresh:data` to recalculate the local development snapshot.
|
package/docs/scanner-api.md
CHANGED
|
@@ -26,7 +26,7 @@ import { scanVsCodeSessions } from './lib/scanner-api.mjs';
|
|
|
26
26
|
const sessionData = await scanVsCodeSessions();
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
The result is the normalized `SessionData` document consumed by the Angular UI. No file is created or changed.
|
|
29
|
+
The result is the normalized `SessionData` document consumed by the Angular UI. It contains imported `sessions` plus a sibling `memories` collection for observed Copilot Markdown memories and plans. No file is created or changed.
|
|
30
30
|
|
|
31
31
|
This is the intended path for:
|
|
32
32
|
|
|
@@ -42,23 +42,51 @@ This is the intended path for:
|
|
|
42
42
|
const sessionData = await scanVsCodeSessions({
|
|
43
43
|
roots: ['/custom/Code/User'],
|
|
44
44
|
sqlite: true,
|
|
45
|
+
includeCustomizations: true,
|
|
45
46
|
generatedAt: new Date(),
|
|
47
|
+
onProgress: (event) => console.log(event.message),
|
|
46
48
|
});
|
|
47
49
|
```
|
|
48
50
|
|
|
49
51
|
- `roots`: optional array of VS Code `User` directories or individual workspace-storage directories. Defaults to stable VS Code and VS Code Insiders paths for the current operating system.
|
|
50
52
|
- `sqlite`: set to `false` to skip optional `state.vscdb` metadata enrichment. Debug-log token and usage import still works.
|
|
53
|
+
- `includeCustomizations`: set to `false` to skip instruction/skill/prompt/hook/agent inventory and evidence matching. The VS Code extension normally leaves this enabled because it exposes the Customizations view.
|
|
54
|
+
- `includeSystemCustomizations`: set to `true` to include customizations contributed by installed VS Code extensions or VS Code application extension folders. The default is `false` so startup focuses on user/repo customizations and avoids expensive evidence matching for system-provided skills.
|
|
51
55
|
- `generatedAt`: optional `Date` or date-compatible value, primarily for deterministic hosts and tests.
|
|
52
56
|
- `usdToEur`: legacy generated-contract conversion value. The product UI is USD-first and callers should normally leave this unset.
|
|
57
|
+
- `onProgress`: optional callback for host diagnostics. It receives scan-stage events such as root discovery, workspace discovery, debug-log folder counts, memory indexing, and completion. Hosts should treat these as user-facing diagnostics, not stable analytics data.
|
|
53
58
|
|
|
54
59
|
Duplicate roots are normalized and scanned once. Each call receives fresh ingestion diagnostics; counters and warnings do not leak from earlier scans in a long-running process.
|
|
55
60
|
|
|
56
61
|
Only one scan may run at a time within one Node process. Hosts should debounce filesystem events and await the current scan instead of starting overlapping work.
|
|
57
62
|
|
|
63
|
+
## Internal Scanner Modules
|
|
64
|
+
|
|
65
|
+
The public host boundary remains `lib/scanner-api.mjs`, but the scanner implementation is being decomposed so large-profile performance issues are easier to diagnose.
|
|
66
|
+
|
|
67
|
+
Current internal split:
|
|
68
|
+
|
|
69
|
+
- `scripts/scanner-traversal.mjs`: VS Code user-data root discovery, workspace-storage entry discovery, bounded recursive file traversal, dependency/build-folder skips, and root normalization.
|
|
70
|
+
- `scripts/scanner-workspace.mjs`: per-storage-entry orchestration for state DB enrichment, customization inventory/evidence, debug-log imports, chat-snapshot imports, memory imports, progress events, and per-entry diagnostics.
|
|
71
|
+
- `scripts/scanner-customization-inventory.mjs`: bounded discovery of user, workspace, repo, and configured Copilot customization files without crawling arbitrary repositories.
|
|
72
|
+
- `scripts/scanner-customization-evidence.mjs`: request-payload and side-file text matching for whether customization content is visible in local model-request logs.
|
|
73
|
+
- `scripts/scanner-memory.mjs`: Copilot memory/plan Markdown import plus memory recall linking from debug-log tool events.
|
|
74
|
+
- `scripts/scanner-session-parser.mjs`: Agent Debug Log and chat-snapshot session parsing, token/cache fields, model breakdowns, request payload summaries, trace events, source usage, and fallback chat estimates.
|
|
75
|
+
- `scripts/scan-vscode-sessions.mjs`: scan lifecycle, diagnostics lifetime, SQLite enrichment, workspace aggregation, final normalized session-data assembly, CLI argument parsing, and JSON persistence.
|
|
76
|
+
|
|
77
|
+
Traversal is intentionally separate because broad filesystem walking is the highest-risk performance path. The scanner should scan known VS Code Copilot storage plus targeted Copilot customization/memory roots; it must not crawl arbitrary repositories or home directories.
|
|
78
|
+
|
|
79
|
+
Next decomposition targets:
|
|
80
|
+
|
|
81
|
+
- pricing/token normalization
|
|
82
|
+
- SQLite/state enrichment helpers
|
|
83
|
+
|
|
58
84
|
## Local Runtime Host
|
|
59
85
|
|
|
60
86
|
`lib/local-runtime.mjs` is the first shared API host. It keeps the last valid `SessionData` snapshot in memory, serves it while scans run, and persists successful refreshes.
|
|
61
87
|
|
|
88
|
+
The local runtime runs the scanner in a child process by default. This keeps the HTTP status/log endpoints responsive while large local VS Code profiles are being imported.
|
|
89
|
+
|
|
62
90
|
The runtime intentionally keeps scanner and transport concerns separate:
|
|
63
91
|
|
|
64
92
|
- the scanner knows how to read and normalize VS Code data
|
|
@@ -96,7 +124,7 @@ There is one parser and pricing implementation. Future hosts should not copy sca
|
|
|
96
124
|
|
|
97
125
|
## Privacy And Source Rules
|
|
98
126
|
|
|
99
|
-
The API reads local VS Code Copilot storage and can encounter prompts, file paths, repository context, tool schemas, and
|
|
127
|
+
The API reads local VS Code Copilot storage and can encounter prompts, file paths, repository context, tool schemas, tool results, saved memories, and saved plans. Hosts must keep results local unless a user explicitly exports them.
|
|
100
128
|
|
|
101
129
|
The API does not change evidence rules:
|
|
102
130
|
|
|
@@ -105,5 +133,6 @@ The API does not change evidence rules:
|
|
|
105
133
|
- cached input remains separate from normal input and output
|
|
106
134
|
- chat snapshots remain fallback data
|
|
107
135
|
- SQLite is metadata enrichment, not a billing source
|
|
136
|
+
- saved memory files are indexed as local artifacts; their presence does not prove they were recalled into a model request
|
|
108
137
|
|
|
109
|
-
See [data-ingestion.md](data-ingestion.md), [debug-log-schema.md](debug-log-schema.md), and [pricing.md](pricing.md) for those contracts.
|
|
138
|
+
See [data-ingestion.md](data-ingestion.md), [copilot-memory.md](copilot-memory.md), [debug-log-schema.md](debug-log-schema.md), and [pricing.md](pricing.md) for those contracts.
|
package/lib/cli.mjs
CHANGED
|
@@ -98,7 +98,21 @@ export async function runCli(args = process.argv.slice(2), dependencies = {}) {
|
|
|
98
98
|
}
|
|
99
99
|
if (options.command === 'status') {
|
|
100
100
|
const fetchStatus = dependencies.fetch ?? globalThis.fetch;
|
|
101
|
-
const
|
|
101
|
+
const timeoutMs = Number(dependencies.statusTimeoutMs ?? 5000);
|
|
102
|
+
const signal = Number.isFinite(timeoutMs) && timeoutMs > 0 && typeof AbortSignal !== 'undefined'
|
|
103
|
+
? AbortSignal.timeout(timeoutMs)
|
|
104
|
+
: undefined;
|
|
105
|
+
let response;
|
|
106
|
+
try {
|
|
107
|
+
response = await fetchStatus(`http://${options.host}:${options.port}/api/status`, { signal });
|
|
108
|
+
} catch (error) {
|
|
109
|
+
const timedOut = error instanceof Error && error.name === 'TimeoutError';
|
|
110
|
+
throw new Error(
|
|
111
|
+
timedOut
|
|
112
|
+
? `Local runtime did not respond on ${options.host}:${options.port} within ${timeoutMs}ms.`
|
|
113
|
+
: `Could not reach local runtime on ${options.host}:${options.port}.`,
|
|
114
|
+
);
|
|
115
|
+
}
|
|
102
116
|
if (!response.ok) {
|
|
103
117
|
throw new Error(`Local runtime returned ${response.status}.`);
|
|
104
118
|
}
|