@newrelic/preflight 1.15.6 → 1.16.0
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/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -0
- package/dist/config.js.map +1 -1
- package/dist/dashboard/dashboard-server.d.ts.map +1 -1
- package/dist/dashboard/dashboard-server.js +15 -0
- package/dist/dashboard/dashboard-server.js.map +1 -1
- package/dist/dashboard/routes/api-handler.d.ts +26 -18
- package/dist/dashboard/routes/api-handler.d.ts.map +1 -1
- package/dist/dashboard/routes/api-handler.js +23 -15
- package/dist/dashboard/routes/api-handler.js.map +1 -1
- package/dist/data/copilot-pricing/README.md +42 -0
- package/dist/data/copilot-pricing/pricing.json +54 -0
- package/dist/data/copilot-sdk-extension/extension.mjs +123 -0
- package/dist/deploy/data-paths.d.ts +6 -4
- package/dist/deploy/data-paths.d.ts.map +1 -1
- package/dist/deploy/data-paths.js +5 -3
- package/dist/deploy/data-paths.js.map +1 -1
- package/dist/hooks/collector-script.d.ts +12 -3
- package/dist/hooks/collector-script.d.ts.map +1 -1
- package/dist/hooks/collector-script.js +70 -18
- package/dist/hooks/collector-script.js.map +1 -1
- package/dist/hooks/copilot-sdk-usage-mapper.d.ts +45 -0
- package/dist/hooks/copilot-sdk-usage-mapper.d.ts.map +1 -0
- package/dist/hooks/copilot-sdk-usage-mapper.js +73 -0
- package/dist/hooks/copilot-sdk-usage-mapper.js.map +1 -0
- package/dist/hooks/copilot-usage-watcher.d.ts +109 -0
- package/dist/hooks/copilot-usage-watcher.d.ts.map +1 -0
- package/dist/hooks/copilot-usage-watcher.js +436 -0
- package/dist/hooks/copilot-usage-watcher.js.map +1 -0
- package/dist/index.d.ts +11 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +162 -70
- package/dist/index.js.map +1 -1
- package/dist/metrics/copilot-pricing-overlay.d.ts +42 -0
- package/dist/metrics/copilot-pricing-overlay.d.ts.map +1 -0
- package/dist/metrics/copilot-pricing-overlay.js +97 -0
- package/dist/metrics/copilot-pricing-overlay.js.map +1 -0
- package/dist/metrics/git-efficiency-tracker.d.ts +12 -1
- package/dist/metrics/git-efficiency-tracker.d.ts.map +1 -1
- package/dist/metrics/git-efficiency-tracker.js +18 -3
- package/dist/metrics/git-efficiency-tracker.js.map +1 -1
- package/dist/metrics/local-session-aggregator.d.ts +164 -0
- package/dist/metrics/local-session-aggregator.d.ts.map +1 -0
- package/dist/metrics/local-session-aggregator.js +444 -0
- package/dist/metrics/local-session-aggregator.js.map +1 -0
- package/dist/platforms/copilot-adapter.d.ts +1 -1
- package/dist/platforms/copilot-adapter.d.ts.map +1 -1
- package/dist/platforms/copilot-adapter.js +64 -10
- package/dist/platforms/copilot-adapter.js.map +1 -1
- package/dist/platforms/copilot-sdk-adapter.d.ts +24 -0
- package/dist/platforms/copilot-sdk-adapter.d.ts.map +1 -0
- package/dist/platforms/copilot-sdk-adapter.js +173 -0
- package/dist/platforms/copilot-sdk-adapter.js.map +1 -0
- package/dist/platforms/index.d.ts +1 -0
- package/dist/platforms/index.d.ts.map +1 -1
- package/dist/platforms/index.js +1 -0
- package/dist/platforms/index.js.map +1 -1
- package/dist/platforms/platform-registry.d.ts.map +1 -1
- package/dist/platforms/platform-registry.js +13 -11
- package/dist/platforms/platform-registry.js.map +1 -1
- package/dist/storage/session-store.d.ts +9 -0
- package/dist/storage/session-store.d.ts.map +1 -1
- package/dist/storage/session-store.js +213 -20
- package/dist/storage/session-store.js.map +1 -1
- package/dist/web/assets/{index-BasTEtUs.js → index-Bwc4qaqj.js} +1 -1
- package/dist/web/assets/index-DwdSz9gz.css +2 -0
- package/dist/web/index.html +2 -2
- package/package.json +2 -2
- package/dist/web/assets/index-BI-2ELf2.css +0 -2
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-real-session aggregation for `--local` (and other unscoped) dashboard
|
|
3
|
+
* processes.
|
|
4
|
+
*
|
|
5
|
+
* Background: a session's own MCP engine normally owns `buffer-<sessionId>.jsonl`
|
|
6
|
+
* (announced via an `active-<sessionId>.pid` heartbeat) and persists that
|
|
7
|
+
* session itself. A `--local` dashboard has no such ownership — it drains every
|
|
8
|
+
* *unowned* buffer destructively and folds the events into trackers keyed by its
|
|
9
|
+
* own synthetic `local-<ts>` identity, which `persistSession()` deliberately
|
|
10
|
+
* skips. Under Claude Code that is fine, because every session has an engine.
|
|
11
|
+
*
|
|
12
|
+
* Under GitHub Copilot it is not: VS Code runs one MCP server per *window* and
|
|
13
|
+
* that engine pins a single session id at startup, while a window has many chat
|
|
14
|
+
* sessions. Tool calls made in any other chat land in an unowned buffer, get
|
|
15
|
+
* drained by the dashboard, and are therefore never written to disk — the live
|
|
16
|
+
* view is correct and rich while `sessions/` stays empty or all-zero.
|
|
17
|
+
*
|
|
18
|
+
* Every drained record already carries its true `sessionId` (that is how
|
|
19
|
+
* `/api/sessions/live` reconstructs per-session timelines), so the dashboard has
|
|
20
|
+
* everything it needs to persist real sessions itself. This module keeps a
|
|
21
|
+
* lightweight per-session rollup so it can do exactly that.
|
|
22
|
+
*/
|
|
23
|
+
import { spawnSync } from 'node:child_process';
|
|
24
|
+
import { QualityProxyTracker } from './quality-proxy-tracker.js';
|
|
25
|
+
import { toToolSelectionSummary } from './tool-selection-scorer.js';
|
|
26
|
+
/** Matches SessionTracker's own cap so session files stay bounded. */
|
|
27
|
+
const MAX_TIMELINE_ENTRIES = 10_000;
|
|
28
|
+
const GIT_OPTS = {
|
|
29
|
+
encoding: 'utf-8',
|
|
30
|
+
timeout: 2000,
|
|
31
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
32
|
+
// GIT_DIR/GIT_WORK_TREE (set by git for hook subprocesses, among other
|
|
33
|
+
// cases) override `-C <dir>`, silently redirecting these calls to whatever
|
|
34
|
+
// repo the ambient env points at instead of the target directory.
|
|
35
|
+
get env() {
|
|
36
|
+
return { ...process.env, GIT_DIR: undefined, GIT_WORK_TREE: undefined };
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
/** Parse `owner/name` out of a git remote URL. Null when it isn't recognizable. */
|
|
40
|
+
export function repoNameFromRemote(remote) {
|
|
41
|
+
if (typeof remote !== 'string')
|
|
42
|
+
return null;
|
|
43
|
+
const match = remote.trim().match(/[/:]([^/]+\/[^/]+?)(?:\.git)?$/);
|
|
44
|
+
return match?.[1] ?? null;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Strips heredoc bodies from a shell command so its *text* is not mistaken for
|
|
48
|
+
* its *actions*. Agents routinely pipe scripts inline (`python3 - <<'PY' ...`),
|
|
49
|
+
* and a body that merely mentions git words made the command classify as a real
|
|
50
|
+
* `push`/`log` and made a `cd` inside the script hijack repo attribution.
|
|
51
|
+
*
|
|
52
|
+
* The line introducing the heredoc is kept — `git commit -F- <<'MSG'` is still
|
|
53
|
+
* a commit.
|
|
54
|
+
*/
|
|
55
|
+
export function stripHeredocBodies(command) {
|
|
56
|
+
if (!command.includes('<<'))
|
|
57
|
+
return command;
|
|
58
|
+
const startRe = /<<(-?)\s*(?:'([^']+)'|"([^"]+)"|\\?([A-Za-z_][A-Za-z0-9_]*))/g;
|
|
59
|
+
const kept = [];
|
|
60
|
+
const pending = [];
|
|
61
|
+
for (const line of command.split('\n')) {
|
|
62
|
+
if (pending.length > 0) {
|
|
63
|
+
const current = pending[0];
|
|
64
|
+
const candidate = current.stripTabs ? line.replace(/^\t+/, '') : line;
|
|
65
|
+
if (candidate.trim() === current.tag)
|
|
66
|
+
pending.shift();
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
kept.push(line);
|
|
70
|
+
startRe.lastIndex = 0;
|
|
71
|
+
let match;
|
|
72
|
+
while ((match = startRe.exec(line)) !== null) {
|
|
73
|
+
const tag = match[2] ?? match[3] ?? match[4];
|
|
74
|
+
if (tag)
|
|
75
|
+
pending.push({ tag, stripTabs: match[1] === '-' });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return kept.join('\n');
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Directory a git command actually acts on. Work is often driven from one
|
|
82
|
+
* workspace but targeted at another repo (`git -C <path>`, or `cd <path> &&
|
|
83
|
+
* git ...`), so the tool call's cwd alone would mislabel those events with the
|
|
84
|
+
* driving repo instead of the one being changed.
|
|
85
|
+
*/
|
|
86
|
+
export function gitCommandTargetDir(rawCommand, cwd) {
|
|
87
|
+
const command = stripHeredocBodies(rawCommand);
|
|
88
|
+
const dashC = /(?:^|[|&;]\s*)git\s+(?:-c\s+\S+\s+)*-C\s+(?:"([^"]+)"|'([^']+)'|(\S+))/.exec(command);
|
|
89
|
+
if (dashC)
|
|
90
|
+
return dashC[1] ?? dashC[2] ?? dashC[3] ?? null;
|
|
91
|
+
// `cd <path> && git ...` — the last cd before the git call wins.
|
|
92
|
+
const cd = /(?:^|[|&;]\s*)cd\s+(?:"([^"]+)"|'([^']+)'|(\S+))\s*(?:&&|;)/.exec(command);
|
|
93
|
+
if (cd) {
|
|
94
|
+
const dir = cd[1] ?? cd[2] ?? cd[3] ?? null;
|
|
95
|
+
if (dir && !dir.startsWith('-'))
|
|
96
|
+
return dir;
|
|
97
|
+
}
|
|
98
|
+
return typeof cwd === 'string' && cwd.length > 0 ? cwd : null;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Resolves a directory to its repo's `owner/name`, shelling out at most once per
|
|
102
|
+
* distinct directory. Returns null for non-repos and for repos with no origin.
|
|
103
|
+
*/
|
|
104
|
+
export class RepoNameResolver {
|
|
105
|
+
cache = new Map();
|
|
106
|
+
resolve(dir) {
|
|
107
|
+
if (typeof dir !== 'string' || dir.length === 0)
|
|
108
|
+
return null;
|
|
109
|
+
const cached = this.cache.get(dir);
|
|
110
|
+
if (cached !== undefined)
|
|
111
|
+
return cached;
|
|
112
|
+
let repoName = null;
|
|
113
|
+
try {
|
|
114
|
+
const remote = spawnSync('git', ['-C', dir, 'remote', 'get-url', 'origin'], GIT_OPTS);
|
|
115
|
+
if (remote.status === 0 && typeof remote.stdout === 'string') {
|
|
116
|
+
repoName = repoNameFromRemote(remote.stdout);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
repoName = null;
|
|
121
|
+
}
|
|
122
|
+
this.cache.set(dir, repoName);
|
|
123
|
+
return repoName;
|
|
124
|
+
}
|
|
125
|
+
/** Repo root (`git rev-parse --show-toplevel`) for a directory, or null. */
|
|
126
|
+
root(dir) {
|
|
127
|
+
if (typeof dir !== 'string' || dir.length === 0)
|
|
128
|
+
return null;
|
|
129
|
+
try {
|
|
130
|
+
const result = spawnSync('git', ['-C', dir, 'rev-parse', '--show-toplevel'], GIT_OPTS);
|
|
131
|
+
if (result.status === 0 && typeof result.stdout === 'string') {
|
|
132
|
+
const root = result.stdout.trim();
|
|
133
|
+
return root.length > 0 ? root : null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
/* not a repo */
|
|
138
|
+
}
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Accumulates tool-call and token activity per real session id. Synthetic ids
|
|
144
|
+
* (`local-`, `proxy-`, `pending-`) are rejected: they are MCP-internal
|
|
145
|
+
* bookkeeping, not real sessions, and persisting them produces the confusing
|
|
146
|
+
* duplicate rows `persistSession()` already guards against.
|
|
147
|
+
*/
|
|
148
|
+
export class LocalSessionAggregator {
|
|
149
|
+
sessions = new Map();
|
|
150
|
+
/** Repo dirs targeted by git commands but never entered as a cwd. */
|
|
151
|
+
gitTargetDirs = new Set();
|
|
152
|
+
static isReal(sessionId) {
|
|
153
|
+
if (typeof sessionId !== 'string' || sessionId.length === 0)
|
|
154
|
+
return false;
|
|
155
|
+
return (!sessionId.startsWith('local-') &&
|
|
156
|
+
!sessionId.startsWith('proxy-') &&
|
|
157
|
+
!sessionId.startsWith('pending-'));
|
|
158
|
+
}
|
|
159
|
+
ensure(sessionId, timestamp) {
|
|
160
|
+
let rollup = this.sessions.get(sessionId);
|
|
161
|
+
if (!rollup) {
|
|
162
|
+
rollup = {
|
|
163
|
+
sessionId,
|
|
164
|
+
startTime: timestamp,
|
|
165
|
+
endTime: timestamp,
|
|
166
|
+
toolCallCount: 0,
|
|
167
|
+
toolBreakdown: {},
|
|
168
|
+
filesRead: new Set(),
|
|
169
|
+
filesModified: new Set(),
|
|
170
|
+
cwd: null,
|
|
171
|
+
timeline: [],
|
|
172
|
+
records: [],
|
|
173
|
+
quality: new QualityProxyTracker(),
|
|
174
|
+
modelBreakdown: new Map(),
|
|
175
|
+
costUsd: 0,
|
|
176
|
+
tokensInput: 0,
|
|
177
|
+
tokensOutput: 0,
|
|
178
|
+
tokensCacheRead: 0,
|
|
179
|
+
tokensCacheCreation: 0,
|
|
180
|
+
models: new Set(),
|
|
181
|
+
successCount: 0,
|
|
182
|
+
};
|
|
183
|
+
this.sessions.set(sessionId, rollup);
|
|
184
|
+
}
|
|
185
|
+
if (timestamp < rollup.startTime)
|
|
186
|
+
rollup.startTime = timestamp;
|
|
187
|
+
if (timestamp > rollup.endTime)
|
|
188
|
+
rollup.endTime = timestamp;
|
|
189
|
+
return rollup;
|
|
190
|
+
}
|
|
191
|
+
recordToolCall(record) {
|
|
192
|
+
if (!LocalSessionAggregator.isReal(record.sessionId))
|
|
193
|
+
return;
|
|
194
|
+
const timestamp = record.timestamp ?? Date.now();
|
|
195
|
+
const rollup = this.ensure(record.sessionId, timestamp);
|
|
196
|
+
rollup.toolCallCount += 1;
|
|
197
|
+
if (record.success !== false)
|
|
198
|
+
rollup.successCount += 1;
|
|
199
|
+
const tool = record.toolName ?? 'unknown';
|
|
200
|
+
rollup.toolBreakdown[tool] = (rollup.toolBreakdown[tool] ?? 0) + 1;
|
|
201
|
+
if (typeof record.cwd === 'string' && record.cwd.length > 0)
|
|
202
|
+
rollup.cwd = record.cwd;
|
|
203
|
+
// A `git -C <path>` / `cd <path> && git` command works on a repo that the
|
|
204
|
+
// cwd never names, so without this the repo would be invisible to commit
|
|
205
|
+
// hydration — the whole point of driving other repos from one workspace.
|
|
206
|
+
if (typeof record.command === 'string' && /(?:^|[|&;]\s*)(?:cd\s|git\s)/.test(record.command)) {
|
|
207
|
+
const target = gitCommandTargetDir(record.command, record.cwd);
|
|
208
|
+
if (target)
|
|
209
|
+
this.gitTargetDirs.add(target);
|
|
210
|
+
}
|
|
211
|
+
// Matches TaskDetector's Read-vs-Write/Edit split (task-detector.ts) —
|
|
212
|
+
// without gating by tool, a read-only exploration session would come
|
|
213
|
+
// back as filesModified: [...everything it opened], which misclassifies
|
|
214
|
+
// it in cost-per-outcome (classifySessionOutcome branches on
|
|
215
|
+
// filesModified.length > 0) and, once merged into a real engine's own
|
|
216
|
+
// accurate list via mergeSummaries()'s union, permanently pollutes it.
|
|
217
|
+
if (typeof record.filePath === 'string' && record.filePath.length > 0) {
|
|
218
|
+
if (tool === 'Read') {
|
|
219
|
+
rollup.filesRead.add(record.filePath);
|
|
220
|
+
}
|
|
221
|
+
else if (tool === 'Write' || tool === 'Edit') {
|
|
222
|
+
rollup.filesModified.add(record.filePath);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// Persisting the per-call timeline is what lets a restarted process replay
|
|
226
|
+
// this session (git activity, anti-pattern analysis). Capped the same way
|
|
227
|
+
// SessionTracker caps its own timeline so a long session can't grow the
|
|
228
|
+
// session file without bound.
|
|
229
|
+
if (rollup.timeline.length < MAX_TIMELINE_ENTRIES) {
|
|
230
|
+
rollup.timeline.push({
|
|
231
|
+
timestamp,
|
|
232
|
+
toolName: tool,
|
|
233
|
+
durationMs: record.durationMs ?? null,
|
|
234
|
+
success: record.success !== false,
|
|
235
|
+
...(typeof record.filePath === 'string' && { filePath: record.filePath }),
|
|
236
|
+
...(typeof record.command === 'string' && { command: record.command }),
|
|
237
|
+
...(record.isTestCommand === true && { isTestCommand: true }),
|
|
238
|
+
...(record.isBuildCommand === true && { isBuildCommand: true }),
|
|
239
|
+
...(record.isLintCommand === true && { isLintCommand: true }),
|
|
240
|
+
...(typeof record.errorType === 'string' && { errorType: record.errorType }),
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
// Feed the real trackers rather than reimplementing their heuristics, so a
|
|
244
|
+
// rehydrated panel shows exactly what the live one would have shown.
|
|
245
|
+
const fullRecord = record;
|
|
246
|
+
rollup.quality.recordToolCall(fullRecord);
|
|
247
|
+
if (rollup.records.length < MAX_TIMELINE_ENTRIES)
|
|
248
|
+
rollup.records.push(fullRecord);
|
|
249
|
+
}
|
|
250
|
+
recordTokenUsage(sessionId, usage) {
|
|
251
|
+
if (!LocalSessionAggregator.isReal(sessionId))
|
|
252
|
+
return;
|
|
253
|
+
const rollup = this.ensure(sessionId, usage.timestamp ?? Date.now());
|
|
254
|
+
rollup.costUsd += usage.costUsd ?? 0;
|
|
255
|
+
rollup.tokensInput += usage.inputTokens ?? 0;
|
|
256
|
+
rollup.tokensOutput += usage.outputTokens ?? 0;
|
|
257
|
+
rollup.tokensCacheRead += usage.cacheReadTokens ?? 0;
|
|
258
|
+
rollup.tokensCacheCreation += usage.cacheCreationTokens ?? 0;
|
|
259
|
+
if (usage.model) {
|
|
260
|
+
rollup.models.add(usage.model);
|
|
261
|
+
const entry = rollup.modelBreakdown.get(usage.model) ?? {
|
|
262
|
+
requestCount: 0,
|
|
263
|
+
input: 0,
|
|
264
|
+
output: 0,
|
|
265
|
+
cost: 0,
|
|
266
|
+
};
|
|
267
|
+
entry.requestCount += 1;
|
|
268
|
+
entry.input += usage.inputTokens ?? 0;
|
|
269
|
+
entry.output += usage.outputTokens ?? 0;
|
|
270
|
+
entry.cost += usage.costUsd ?? 0;
|
|
271
|
+
rollup.modelBreakdown.set(usage.model, entry);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/** Distinct working directories seen across all sessions. */
|
|
275
|
+
cwds() {
|
|
276
|
+
const out = new Set(this.gitTargetDirs);
|
|
277
|
+
for (const rollup of this.sessions.values()) {
|
|
278
|
+
if (rollup.cwd)
|
|
279
|
+
out.add(rollup.cwd);
|
|
280
|
+
}
|
|
281
|
+
return [...out];
|
|
282
|
+
}
|
|
283
|
+
size() {
|
|
284
|
+
return this.sessions.size;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Session summaries ready for `SessionStore.saveSession()`. Only sessions with
|
|
288
|
+
* observed tool calls are returned — a token-only rollup would be filtered out
|
|
289
|
+
* of `/api/sessions` anyway (it requires `toolCallCount > 0`), and writing it
|
|
290
|
+
* would burn a file that the empty-summary guard then has to defend.
|
|
291
|
+
*/
|
|
292
|
+
toSummaries(context) {
|
|
293
|
+
const out = [];
|
|
294
|
+
for (const rollup of this.sessions.values()) {
|
|
295
|
+
if (rollup.toolCallCount === 0)
|
|
296
|
+
continue;
|
|
297
|
+
const models = [...rollup.models];
|
|
298
|
+
out.push({
|
|
299
|
+
sessionId: rollup.sessionId,
|
|
300
|
+
sessionName: null,
|
|
301
|
+
repoName: context.repoResolver.resolve(rollup.cwd),
|
|
302
|
+
startTime: rollup.startTime,
|
|
303
|
+
endTime: rollup.endTime,
|
|
304
|
+
durationMs: Math.max(0, rollup.endTime - rollup.startTime),
|
|
305
|
+
toolCallCount: rollup.toolCallCount,
|
|
306
|
+
toolBreakdown: { ...rollup.toolBreakdown },
|
|
307
|
+
developer: context.developer,
|
|
308
|
+
model: models.length === 1 ? models[0] : null,
|
|
309
|
+
filesRead: [...rollup.filesRead],
|
|
310
|
+
filesModified: [...rollup.filesModified],
|
|
311
|
+
timeline: rollup.timeline.length > 0 ? [...rollup.timeline] : undefined,
|
|
312
|
+
// These three fields are what let the dashboard rebuild its
|
|
313
|
+
// Model Usage / Quality / Tool Selection panels after a restart: the
|
|
314
|
+
// API combines them across today's persisted sessions. Without them a
|
|
315
|
+
// restarted process shows empty panels despite having the history.
|
|
316
|
+
modelBreakdown: modelBreakdownOf(rollup),
|
|
317
|
+
qualityProxy: rollup.quality.getRawCounts(),
|
|
318
|
+
toolSelectionMetrics: rollup.records.length > 0
|
|
319
|
+
? toToolSelectionSummary(context.toolSelectionScorer.scoreSession(rollup.records))
|
|
320
|
+
: null,
|
|
321
|
+
linesAdded: 0,
|
|
322
|
+
linesRemoved: 0,
|
|
323
|
+
bashCommandCount: 0,
|
|
324
|
+
testRunCount: 0,
|
|
325
|
+
testPassCount: 0,
|
|
326
|
+
buildRunCount: 0,
|
|
327
|
+
buildPassCount: 0,
|
|
328
|
+
estimatedCostUsd: rollup.costUsd > 0 ? rollup.costUsd : null,
|
|
329
|
+
subagentCostUsd: 0,
|
|
330
|
+
tokensInput: rollup.tokensInput,
|
|
331
|
+
tokensOutput: rollup.tokensOutput,
|
|
332
|
+
tokensThinking: 0,
|
|
333
|
+
tokensCacheRead: rollup.tokensCacheRead,
|
|
334
|
+
tokensCacheCreation: rollup.tokensCacheCreation,
|
|
335
|
+
cacheSavingsUsd: 0,
|
|
336
|
+
efficiencyScore: null,
|
|
337
|
+
antiPatterns: [],
|
|
338
|
+
taskCount: 0,
|
|
339
|
+
taskSuccessRate: null,
|
|
340
|
+
toolSuccessRate: rollup.toolCallCount > 0 ? rollup.successCount / rollup.toolCallCount : null,
|
|
341
|
+
contextCompressions: 0,
|
|
342
|
+
agentSpawns: 0,
|
|
343
|
+
userMessages: 0,
|
|
344
|
+
assistantMessages: 0,
|
|
345
|
+
userCorrections: 0,
|
|
346
|
+
outcome: context.outcome,
|
|
347
|
+
platform: context.platform ?? null,
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
return out;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Build a browsable GitHub commit URL from a git remote. Handles both SSH
|
|
355
|
+
* (`git@github.com:owner/repo.git`) and HTTPS remotes, and returns null for
|
|
356
|
+
* hosts we can't confidently map so the UI degrades to plain text rather than
|
|
357
|
+
* rendering a broken link.
|
|
358
|
+
*/
|
|
359
|
+
export function commitUrlFromRemote(remote, hash) {
|
|
360
|
+
if (!remote || !hash)
|
|
361
|
+
return null;
|
|
362
|
+
const trimmed = remote.trim().replace(/\.git$/, '');
|
|
363
|
+
const ssh = /^(?:ssh:\/\/)?[^@]+@([^:/]+)[:/](.+)$/.exec(trimmed);
|
|
364
|
+
const https = /^https?:\/\/(?:[^@/]+@)?([^/]+)\/(.+)$/.exec(trimmed);
|
|
365
|
+
const match = ssh ?? https;
|
|
366
|
+
if (!match)
|
|
367
|
+
return null;
|
|
368
|
+
const [, host, path] = match;
|
|
369
|
+
if (!host || !path)
|
|
370
|
+
return null;
|
|
371
|
+
return `https://${host}/${path}/commit/${hash}`;
|
|
372
|
+
}
|
|
373
|
+
function gitOut(root, args) {
|
|
374
|
+
try {
|
|
375
|
+
const result = spawnSync('git', ['-C', root, ...args], GIT_OPTS);
|
|
376
|
+
if (result.status !== 0 || typeof result.stdout !== 'string')
|
|
377
|
+
return null;
|
|
378
|
+
const out = result.stdout.trim();
|
|
379
|
+
return out.length > 0 ? out : null;
|
|
380
|
+
}
|
|
381
|
+
catch {
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
export function collectCommitsAcrossRepos(repoRoots, since, authorEmail) {
|
|
386
|
+
const seen = new Set();
|
|
387
|
+
const commits = [];
|
|
388
|
+
for (const root of repoRoots) {
|
|
389
|
+
// %x1f (unit separator) can't appear in a hash, epoch, or subject, so it is
|
|
390
|
+
// a safe delimiter where a space would break on multi-word subjects.
|
|
391
|
+
const args = ['log', `--since=${since}T00:00:00`, '--format=%H%x1f%ct%x1f%s'];
|
|
392
|
+
if (authorEmail)
|
|
393
|
+
args.push(`--author=${authorEmail}`);
|
|
394
|
+
const stdout = gitOut(root, args);
|
|
395
|
+
if (stdout === null)
|
|
396
|
+
continue;
|
|
397
|
+
const remote = gitOut(root, ['remote', 'get-url', 'origin']);
|
|
398
|
+
const repo = repoNameFromRemote(remote);
|
|
399
|
+
for (const line of stdout.split('\n')) {
|
|
400
|
+
if (!line)
|
|
401
|
+
continue;
|
|
402
|
+
const [hash, epochStr, subject] = line.split('\x1f');
|
|
403
|
+
if (!hash || seen.has(hash))
|
|
404
|
+
continue;
|
|
405
|
+
seen.add(hash);
|
|
406
|
+
commits.push({
|
|
407
|
+
hash,
|
|
408
|
+
timestamp: parseInt(epochStr ?? '0', 10) * 1000,
|
|
409
|
+
repo,
|
|
410
|
+
subject: subject ?? null,
|
|
411
|
+
url: commitUrlFromRemote(remote, hash),
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return commits;
|
|
416
|
+
}
|
|
417
|
+
/** Current git identity, used to keep other contributors' commits out of the count. */
|
|
418
|
+
export function resolveAuthorEmail(dir) {
|
|
419
|
+
try {
|
|
420
|
+
const result = spawnSync('git', ['-C', dir, 'config', 'user.email'], GIT_OPTS);
|
|
421
|
+
if (result.status === 0 && typeof result.stdout === 'string') {
|
|
422
|
+
const email = result.stdout.trim();
|
|
423
|
+
return email.length > 0 ? email : null;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
catch {
|
|
427
|
+
/* no git identity */
|
|
428
|
+
}
|
|
429
|
+
return null;
|
|
430
|
+
}
|
|
431
|
+
/** Shape the per-model tallies the way `combineBreakdowns()` expects them. */
|
|
432
|
+
function modelBreakdownOf(rollup) {
|
|
433
|
+
const out = {};
|
|
434
|
+
for (const [model, e] of rollup.modelBreakdown) {
|
|
435
|
+
out[model] = {
|
|
436
|
+
requestCount: e.requestCount,
|
|
437
|
+
totalInputTokens: e.input,
|
|
438
|
+
totalOutputTokens: e.output,
|
|
439
|
+
totalCostUsd: e.cost,
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
return out;
|
|
443
|
+
}
|
|
444
|
+
//# sourceMappingURL=local-session-aggregator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-session-aggregator.js","sourceRoot":"","sources":["../../src/metrics/local-session-aggregator.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,7 +26,7 @@ export interface CopilotUsageRecord {
|
|
|
26
26
|
export declare function parseCopilotUsageResponse(raw: unknown): CopilotUsageRecord[];
|
|
27
27
|
export declare class CopilotAdapter implements PlatformAdapter {
|
|
28
28
|
readonly platformName = "copilot";
|
|
29
|
-
readonly visibilityLevel: "
|
|
29
|
+
readonly visibilityLevel: "full-hooks";
|
|
30
30
|
readonly capabilities: {
|
|
31
31
|
instructionFilePaths: readonly [];
|
|
32
32
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copilot-adapter.d.ts","sourceRoot":"","sources":["../../src/platforms/copilot-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EACX,WAAW,GAAG,WAAW,GAAG,aAAa,GAAG,aAAa,GAAG,kBAAkB,GAAG,MAAM,CAAC;IAC1F,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;
|
|
1
|
+
{"version":3,"file":"copilot-adapter.d.ts","sourceRoot":"","sources":["../../src/platforms/copilot-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EACX,WAAW,GAAG,WAAW,GAAG,aAAa,GAAG,aAAa,GAAG,kBAAkB,GAAG,MAAM,CAAC;IAC1F,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAiED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAC1C,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAC1C,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,OAAO,GAAG,kBAAkB,EAAE,CAM5E;AAED,qBAAa,cAAe,YAAW,eAAe;IACpD,QAAQ,CAAC,YAAY,aAAa;IAKlC,QAAQ,CAAC,eAAe,EAAG,YAAY,CAAU;IACjD,QAAQ,CAAC,YAAY;;MAAyC;IAExD,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxD,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,kBAAkB;IA2BnD,WAAW,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM;IAM7C,kBAAkB,IAAI,uBAAuB;IAU7C,0BAA0B,IAAI,MAAM;IA2BpC,WAAW,IAAI,OAAO;CAGvB"}
|
|
@@ -21,6 +21,40 @@ const COPILOT_EVENT_TYPE_MAP = {
|
|
|
21
21
|
terminal_command: 'Bash',
|
|
22
22
|
task: 'Bash',
|
|
23
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* Maps VS Code Copilot tool names (carried in hook `tool_name`) to the
|
|
26
|
+
* normalized Claude Code tool vocabulary. VS Code agent hooks send VS Code's
|
|
27
|
+
* own tool names, not Claude Code's — documented in the hooks FAQ
|
|
28
|
+
* (https://code.visualstudio.com/docs/copilot/customization/hooks, "Tool
|
|
29
|
+
* names: ... VS Code uses tool names like `create_file` and
|
|
30
|
+
* `replace_string_in_file`"). The full name inventory is the `ToolName` enum
|
|
31
|
+
* in microsoft/vscode `extensions/copilot/src/extension/tools/common/toolNames.ts`.
|
|
32
|
+
* `editFiles` appears in the hooks reference example payloads
|
|
33
|
+
* (https://code.visualstudio.com/docs/agents/reference/hooks-reference).
|
|
34
|
+
* This map is VS Code-specific — the GitHub Copilot CLI/SDK runtime is a
|
|
35
|
+
* separate adapter (copilot-sdk) with its own tool-name vocabulary. Names
|
|
36
|
+
* without a clear canonical correspondence (semantic_search, get_errors,
|
|
37
|
+
* ...) are deliberately left unmapped so the original name is preserved
|
|
38
|
+
* downstream.
|
|
39
|
+
*/
|
|
40
|
+
const COPILOT_TOOL_MAP = {
|
|
41
|
+
read_file: 'Read',
|
|
42
|
+
create_file: 'Write',
|
|
43
|
+
replace_string_in_file: 'Edit',
|
|
44
|
+
multi_replace_string_in_file: 'Edit',
|
|
45
|
+
insert_edit_into_file: 'Edit',
|
|
46
|
+
apply_patch: 'Edit',
|
|
47
|
+
edit_files: 'Edit',
|
|
48
|
+
editFiles: 'Edit',
|
|
49
|
+
run_in_terminal: 'Bash',
|
|
50
|
+
grep_search: 'Grep',
|
|
51
|
+
file_search: 'Glob',
|
|
52
|
+
list_dir: 'Glob',
|
|
53
|
+
runSubagent: 'Agent',
|
|
54
|
+
search_subagent: 'Agent',
|
|
55
|
+
explore_subagent: 'Agent',
|
|
56
|
+
execution_subagent: 'Agent',
|
|
57
|
+
};
|
|
24
58
|
export function parseCopilotUsageResponse(raw) {
|
|
25
59
|
if (!Array.isArray(raw))
|
|
26
60
|
return [];
|
|
@@ -28,11 +62,15 @@ export function parseCopilotUsageResponse(raw) {
|
|
|
28
62
|
}
|
|
29
63
|
export class CopilotAdapter {
|
|
30
64
|
platformName = 'copilot';
|
|
31
|
-
|
|
65
|
+
// Full-hooks since VS Code agent hooks (PreToolUse/PostToolUse et al.,
|
|
66
|
+
// https://code.visualstudio.com/docs/copilot/customization/hooks) fire on
|
|
67
|
+
// every built-in tool call and are parsed by collector-script.ts's uniform
|
|
68
|
+
// branch. The HTTP-push extension path below remains as a legacy fallback.
|
|
69
|
+
visibilityLevel = 'full-hooks';
|
|
32
70
|
capabilities = { instructionFilePaths: [] };
|
|
33
71
|
async initialize(_config) {
|
|
34
|
-
//
|
|
35
|
-
//
|
|
72
|
+
// Tool calls arrive via VS Code agent hooks (collector script), or
|
|
73
|
+
// legacy HTTP push from a Copilot-compatible extension.
|
|
36
74
|
}
|
|
37
75
|
normalizeToolCall(raw) {
|
|
38
76
|
const event = isCopilotToolCallEvent(raw) ? raw : undefined;
|
|
@@ -58,7 +96,7 @@ export class CopilotAdapter {
|
|
|
58
96
|
};
|
|
59
97
|
}
|
|
60
98
|
mapToolName(platformToolName) {
|
|
61
|
-
return COPILOT_EVENT_TYPE_MAP[platformToolName] ?? 'Unknown';
|
|
99
|
+
return (COPILOT_TOOL_MAP[platformToolName] ?? COPILOT_EVENT_TYPE_MAP[platformToolName] ?? 'Unknown');
|
|
62
100
|
}
|
|
63
101
|
getSessionMetadata() {
|
|
64
102
|
return {
|
|
@@ -71,12 +109,28 @@ export class CopilotAdapter {
|
|
|
71
109
|
}
|
|
72
110
|
getHookInstallInstructions() {
|
|
73
111
|
return [
|
|
74
|
-
'GitHub Copilot Observability Setup:',
|
|
75
|
-
'1.
|
|
76
|
-
'
|
|
77
|
-
'
|
|
78
|
-
'
|
|
79
|
-
'
|
|
112
|
+
'GitHub Copilot Observability Setup (VS Code agent hooks):',
|
|
113
|
+
'1. Create a hooks file — user-level ~/.copilot/hooks/preflight.json (applies to',
|
|
114
|
+
' all workspaces) or workspace-level .github/hooks/preflight.json:',
|
|
115
|
+
' {',
|
|
116
|
+
' "version": 1,',
|
|
117
|
+
' "hooks": {',
|
|
118
|
+
' "PreToolUse": [{ "type": "command", "command": "preflight-collector pre-tool" }],',
|
|
119
|
+
' "PostToolUse": [{ "type": "command", "command": "preflight-collector post-tool" }]',
|
|
120
|
+
' }',
|
|
121
|
+
' }',
|
|
122
|
+
' (VS Code also reads Claude-format hooks from ~/.claude/settings.json by',
|
|
123
|
+
' default — if preflight hooks are installed there for Claude Code, either',
|
|
124
|
+
' rely on those or disable that location via chat.hookFilesLocations to',
|
|
125
|
+
' avoid double capture.)',
|
|
126
|
+
'2. Ensure preflight-collector is on PATH (npm install -g @newrelic/preflight).',
|
|
127
|
+
'3. Register the Preflight MCP server for nr_observe_* tools with env',
|
|
128
|
+
' MCP_CLIENT=copilot, NEW_RELIC_LICENSE_KEY, NEW_RELIC_ACCOUNT_ID.',
|
|
129
|
+
'4. For the GitHub Copilot CLI/SDK runtime instead of VS Code, use the',
|
|
130
|
+
" copilot-sdk adapter's own setup — Copilot CLI's native lowerCamelCase",
|
|
131
|
+
' hooks are not compatible with this adapter.',
|
|
132
|
+
'Legacy fallback: a Copilot-compatible extension may instead push events to',
|
|
133
|
+
'http://localhost:9847 ("preflight.endpoint" in VS Code settings).',
|
|
80
134
|
].join('\n');
|
|
81
135
|
}
|
|
82
136
|
isSupported() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copilot-adapter.js","sourceRoot":"","sources":["../../src/platforms/copilot-adapter.ts"],"names":[],"mappings":"AAyBA,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAS;IAC1C,WAAW;IACX,WAAW;IACX,aAAa;IACb,aAAa;IACb,kBAAkB;IAClB,MAAM;CACP,CAAC,CAAC;AAEH,SAAS,sBAAsB,CAAC,CAAU;IACxC,OAAO,CACL,OAAO,CAAC,KAAK,QAAQ;QACrB,CAAC,KAAK,IAAI;QACV,MAAM,IAAI,CAAC;QACX,OAAQ,CAAuB,CAAC,IAAI,KAAK,QAAQ;QACjD,mBAAmB,CAAC,GAAG,CAAE,CAAsB,CAAC,IAAI,CAAC,CACtD,CAAC;AACJ,CAAC;AAED,MAAM,sBAAsB,GAA2B;IACrD,SAAS,EAAE,MAAM;IACjB,SAAS,EAAE,MAAM;IACjB,WAAW,EAAE,OAAO;IACpB,WAAW,EAAE,QAAQ;IACrB,gBAAgB,EAAE,MAAM;IACxB,IAAI,EAAE,MAAM;CACb,CAAC;AAWF,MAAM,UAAU,yBAAyB,CAAC,GAAY;IACpD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,OAAO,GAAG,CAAC,MAAM,CACf,CAAC,IAAI,EAA8B,EAAE,CACnC,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,CAC5E,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,cAAc;IAChB,YAAY,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"copilot-adapter.js","sourceRoot":"","sources":["../../src/platforms/copilot-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { NormalizedToolCall, PlatformAdapter, PlatformConfig, PlatformSessionMetadata } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Adapter for the GitHub Copilot SDK / agent-host runtime — distinct from the
|
|
4
|
+
* VS Code Copilot Chat adapter (`CopilotAdapter`): different session-id space
|
|
5
|
+
* (no `workspaceStorage`; sessions live in `~/.copilot/session-state/<id>/`),
|
|
6
|
+
* and different tool-name vocabulary (`bash`/`edit`/`grep` rather than VS
|
|
7
|
+
* Code's `run_in_terminal`/`replace_string_in_file`). The Copilot CLI is the
|
|
8
|
+
* confirmed host of this runtime; the same SDK extension mechanism plausibly
|
|
9
|
+
* hosts elsewhere (e.g. the desktop app), untested.
|
|
10
|
+
*/
|
|
11
|
+
export declare class CopilotSdkAdapter implements PlatformAdapter {
|
|
12
|
+
readonly platformName = "copilot-sdk";
|
|
13
|
+
readonly visibilityLevel: "full-hooks";
|
|
14
|
+
readonly capabilities: {
|
|
15
|
+
instructionFilePaths: readonly ["AGENTS.md", "CLAUDE.md", "GEMINI.md", ".github/copilot-instructions.md"];
|
|
16
|
+
};
|
|
17
|
+
initialize(_config: PlatformConfig): Promise<void>;
|
|
18
|
+
normalizeToolCall(raw: unknown): NormalizedToolCall;
|
|
19
|
+
mapToolName(platformToolName: string): string;
|
|
20
|
+
getSessionMetadata(): PlatformSessionMetadata;
|
|
21
|
+
getHookInstallInstructions(): string;
|
|
22
|
+
isSupported(): boolean;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=copilot-sdk-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-sdk-adapter.d.ts","sourceRoot":"","sources":["../../src/platforms/copilot-sdk-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAkFpB;;;;;;;;GAQG;AACH,qBAAa,iBAAkB,YAAW,eAAe;IACvD,QAAQ,CAAC,YAAY,iBAAiB;IAWtC,QAAQ,CAAC,eAAe,EAAG,YAAY,CAAU;IAYjD,QAAQ,CAAC,YAAY;;MAOnB;IAEI,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxD,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,kBAAkB;IAsBnD,WAAW,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM;IAI7C,kBAAkB,IAAI,uBAAuB;IAM7C,0BAA0B,IAAI,MAAM;IAgCpC,WAAW,IAAI,OAAO;CAMvB"}
|