@codingame/monaco-vscode-telemetry-service-override 32.0.2 → 34.0.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.
Files changed (50) hide show
  1. package/index.js +2 -0
  2. package/package.json +3 -3
  3. package/vscode/src/vs/platform/telemetry/common/telemetryLogAppender.js +1 -1
  4. package/vscode/src/vs/platform/telemetry/common/telemetryService.d.ts +1 -1
  5. package/vscode/src/vs/platform/telemetry/common/telemetryService.js +21 -21
  6. package/vscode/src/vs/workbench/contrib/bracketPairColorizer2Telemetry/browser/bracketPairColorizer2Telemetry.contribution.d.ts +1 -0
  7. package/vscode/src/vs/workbench/contrib/bracketPairColorizer2Telemetry/browser/bracketPairColorizer2Telemetry.contribution.js +34 -0
  8. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/aiContributionFeature.d.ts +15 -0
  9. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/aiContributionFeature.js +97 -0
  10. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/editStats/aiStatsChart.d.ts +24 -0
  11. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/editStats/aiStatsChart.js +236 -0
  12. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/editStats/aiStatsFeature.d.ts +24 -0
  13. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/editStats/aiStatsFeature.js +213 -0
  14. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/editStats/aiStatsStatusBar.d.ts +27 -0
  15. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/editStats/aiStatsStatusBar.js +250 -0
  16. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/editStats/media.css +127 -0
  17. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/editTelemetry.contribution.d.ts +1 -0
  18. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/editTelemetry.contribution.js +75 -0
  19. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/editTelemetryContribution.d.ts +8 -0
  20. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/editTelemetryContribution.js +82 -0
  21. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/helpers/annotatedDocuments.d.ts +30 -0
  22. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/helpers/annotatedDocuments.js +79 -0
  23. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/helpers/documentWithAnnotatedEdits.d.ts +128 -0
  24. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/helpers/documentWithAnnotatedEdits.js +297 -0
  25. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/helpers/observableWorkspace.d.ts +31 -0
  26. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/helpers/observableWorkspace.js +66 -0
  27. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/helpers/utils.d.ts +9 -0
  28. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/helpers/utils.js +47 -0
  29. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/helpers/vscodeObservableWorkspace.d.ts +26 -0
  30. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/helpers/vscodeObservableWorkspace.js +84 -0
  31. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/settingIds.d.ts +2 -0
  32. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/settingIds.js +6 -0
  33. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/settings.d.ts +3 -0
  34. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/settings.js +7 -0
  35. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/arcTelemetryReporter.d.ts +37 -0
  36. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/arcTelemetryReporter.js +80 -0
  37. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/arcTelemetrySender.d.ts +20 -0
  38. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/arcTelemetrySender.js +173 -0
  39. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/editSourceTrackingFeature.d.ts +23 -0
  40. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/editSourceTrackingFeature.js +232 -0
  41. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/editSourceTrackingImpl.d.ts +48 -0
  42. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/editSourceTrackingImpl.js +292 -0
  43. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/editTracker.d.ts +41 -0
  44. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/editTracker.js +99 -0
  45. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/scmAdapter.d.ts +18 -0
  46. package/vscode/src/vs/workbench/contrib/editTelemetry/browser/telemetry/scmAdapter.js +44 -0
  47. package/vscode/src/vs/workbench/contrib/editTelemetry/common/arcTracker.d.ts +29 -0
  48. package/vscode/src/vs/workbench/contrib/editTelemetry/common/arcTracker.js +64 -0
  49. package/vscode/src/vs/workbench/contrib/telemetry/browser/telemetry.contribution.js +1 -1
  50. package/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.d.ts +1 -1
@@ -0,0 +1,213 @@
1
+
2
+ import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
3
+ import { sumBy } from '@codingame/monaco-vscode-api/vscode/vs/base/common/arrays';
4
+ import { TaskQueue, timeout } from '@codingame/monaco-vscode-api/vscode/vs/base/common/async';
5
+ import { Lazy } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lazy';
6
+ import { Disposable, toDisposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
7
+ import '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/index';
8
+ import { AnnotatedStringEdit } from '@codingame/monaco-vscode-api/vscode/vs/editor/common/core/edits/stringEdit';
9
+ import { isAiEdit, isUserEdit } from '@codingame/monaco-vscode-api/vscode/vs/editor/common/textModelEditSource';
10
+ import { IInstantiationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation';
11
+ import { StorageScope, StorageTarget } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage';
12
+ import { IStorageService } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage.service';
13
+ import { AiStatsStatusBar } from './aiStatsStatusBar.js';
14
+ import { observableValue } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/observableValue';
15
+ import { derived } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/derived';
16
+ import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
17
+ import { mapObservableArrayCached } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/utils/utils';
18
+ import { runOnChange } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/utils/runOnChange';
19
+
20
+ let AiStatsFeature = class AiStatsFeature extends Disposable {
21
+ constructor(annotatedDocuments, _storageService, _instantiationService) {
22
+ super();
23
+ this._storageService = _storageService;
24
+ this._instantiationService = _instantiationService;
25
+ this._dataVersion = observableValue(this, 0);
26
+ this.aiRate = ( this._dataVersion.map(() => {
27
+ const val = this._data.getValue();
28
+ if (!val) {
29
+ return 0;
30
+ }
31
+ const r = average(val.sessions, session => {
32
+ const sum = session.typedCharacters + session.aiCharacters;
33
+ if (sum === 0) {
34
+ return 0;
35
+ }
36
+ return session.aiCharacters / sum;
37
+ });
38
+ return r;
39
+ }));
40
+ this.sessionCount = derived(this, r => {
41
+ this._dataVersion.read(r);
42
+ const val = this._data.getValue();
43
+ if (!val) {
44
+ return 0;
45
+ }
46
+ return val.sessions.length;
47
+ });
48
+ this.sessions = derived(this, r => {
49
+ this._dataVersion.read(r);
50
+ const val = this._data.getValue();
51
+ if (!val) {
52
+ return [];
53
+ }
54
+ return val.sessions;
55
+ });
56
+ this.acceptedInlineSuggestionsToday = derived(this, r => {
57
+ this._dataVersion.read(r);
58
+ const val = this._data.getValue();
59
+ if (!val) {
60
+ return 0;
61
+ }
62
+ const startOfToday = ( new Date());
63
+ startOfToday.setHours(0, 0, 0, 0);
64
+ const sessionsToday = val.sessions.filter(s => s.startTime > startOfToday.getTime());
65
+ return sumBy(sessionsToday, s => s.acceptedInlineSuggestions ?? 0);
66
+ });
67
+ const storedValue = getStoredValue(
68
+ this._storageService,
69
+ "aiStats",
70
+ StorageScope.WORKSPACE,
71
+ StorageTarget.USER
72
+ );
73
+ this._data = rateLimitWrite(storedValue, 1 / 60, this._store);
74
+ this.aiRate.recomputeInitiallyAndOnChange(this._store);
75
+ this._register(autorun(reader => {
76
+ reader.store.add(
77
+ this._instantiationService.createInstance(AiStatsStatusBar.hot.read(reader), this)
78
+ );
79
+ }));
80
+ const lastRequestIds = [];
81
+ const obs = mapObservableArrayCached(this, annotatedDocuments.documents, (doc, store) => {
82
+ store.add(runOnChange(doc.documentWithAnnotations.value, (_val, _prev, edit) => {
83
+ const e = AnnotatedStringEdit.compose(( edit.map(e => e.edit)));
84
+ const curSession = ( new Lazy(() => this._getDataAndSession()));
85
+ for (const r of e.replacements) {
86
+ if (isAiEdit(r.data.editSource)) {
87
+ curSession.value.currentSession.aiCharacters += r.newText.length;
88
+ } else if (isUserEdit(r.data.editSource)) {
89
+ curSession.value.currentSession.typedCharacters += r.newText.length;
90
+ }
91
+ }
92
+ if (e.replacements.length > 0) {
93
+ const sessionToUpdate = curSession.value.currentSession;
94
+ const s = e.replacements[0].data.editSource;
95
+ if (s.metadata.source === "inlineCompletionAccept") {
96
+ if (sessionToUpdate.acceptedInlineSuggestions === undefined) {
97
+ sessionToUpdate.acceptedInlineSuggestions = 0;
98
+ }
99
+ sessionToUpdate.acceptedInlineSuggestions += 1;
100
+ }
101
+ if (s.metadata.source === "Chat.applyEdits" && s.metadata.$$requestId !== undefined) {
102
+ const didSeeRequestId = lastRequestIds.includes(s.metadata.$$requestId);
103
+ if (!didSeeRequestId) {
104
+ lastRequestIds.push(s.metadata.$$requestId);
105
+ if (lastRequestIds.length > 10) {
106
+ lastRequestIds.shift();
107
+ }
108
+ if (sessionToUpdate.chatEditCount === undefined) {
109
+ sessionToUpdate.chatEditCount = 0;
110
+ }
111
+ sessionToUpdate.chatEditCount += 1;
112
+ }
113
+ }
114
+ }
115
+ if (curSession.hasValue) {
116
+ this._data.writeValue(curSession.value.data);
117
+ this._dataVersion.set(this._dataVersion.get() + 1, undefined);
118
+ }
119
+ }));
120
+ });
121
+ obs.recomputeInitiallyAndOnChange(this._store);
122
+ }
123
+ _getDataAndSession() {
124
+ const state = this._data.getValue() ?? {
125
+ sessions: []
126
+ };
127
+ const sessionLengthMs = 5 * 60 * 1000;
128
+ let lastSession = state.sessions.at(-1);
129
+ const nowTime = Date.now();
130
+ if (!lastSession || nowTime - lastSession.startTime > sessionLengthMs) {
131
+ state.sessions.push({
132
+ startTime: nowTime,
133
+ typedCharacters: 0,
134
+ aiCharacters: 0,
135
+ acceptedInlineSuggestions: 0,
136
+ chatEditCount: 0
137
+ });
138
+ lastSession = state.sessions.at(-1);
139
+ const dayMs = 24 * 60 * 60 * 1000;
140
+ while (state.sessions.length > dayMs / sessionLengthMs) {
141
+ state.sessions.shift();
142
+ }
143
+ }
144
+ return {
145
+ data: state,
146
+ currentSession: lastSession
147
+ };
148
+ }
149
+ };
150
+ AiStatsFeature = ( __decorate([( __param(1, IStorageService)), ( __param(2, IInstantiationService))], AiStatsFeature));
151
+ function average(arr, selector) {
152
+ if (arr.length === 0) {
153
+ return 0;
154
+ }
155
+ const s = sumBy(arr, selector);
156
+ return s / arr.length;
157
+ }
158
+ function rateLimitWrite(targetValue, maxWritesPerSecond, store) {
159
+ const queue = ( new TaskQueue());
160
+ let _value = undefined;
161
+ let valueVersion = 0;
162
+ let savedVersion = 0;
163
+ store.add(toDisposable(() => {
164
+ if (valueVersion !== savedVersion) {
165
+ targetValue.writeValue(_value);
166
+ savedVersion = valueVersion;
167
+ }
168
+ }));
169
+ return {
170
+ writeValue(value) {
171
+ valueVersion++;
172
+ const v = valueVersion;
173
+ _value = value;
174
+ queue.clearPending();
175
+ queue.schedule(async () => {
176
+ targetValue.writeValue(value);
177
+ savedVersion = v;
178
+ await timeout(5000);
179
+ });
180
+ },
181
+ getValue() {
182
+ if (valueVersion > 0) {
183
+ return _value;
184
+ }
185
+ return targetValue.getValue();
186
+ }
187
+ };
188
+ }
189
+ function getStoredValue(service, key, scope, target) {
190
+ let lastValue = undefined;
191
+ let hasLastValue = false;
192
+ return {
193
+ writeValue(value) {
194
+ if (value === undefined) {
195
+ service.remove(key, scope);
196
+ } else {
197
+ service.store(key, JSON.stringify(value), scope, target);
198
+ }
199
+ lastValue = value;
200
+ },
201
+ getValue() {
202
+ if (hasLastValue) {
203
+ return lastValue;
204
+ }
205
+ const strVal = service.get(key, scope);
206
+ lastValue = strVal === undefined ? undefined : JSON.parse(strVal);
207
+ hasLastValue = true;
208
+ return lastValue;
209
+ }
210
+ };
211
+ }
212
+
213
+ export { AiStatsFeature };
@@ -0,0 +1,27 @@
1
+ import { Disposable } from "@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle";
2
+ import { IObservable } from "@codingame/monaco-vscode-api/vscode/vs/base/common/observable";
3
+ import { ICommandService } from "@codingame/monaco-vscode-api/vscode/vs/platform/commands/common/commands.service";
4
+ import { ITelemetryService } from "@codingame/monaco-vscode-api/vscode/vs/platform/telemetry/common/telemetry.service";
5
+ import { IStatusbarService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/statusbar/browser/statusbar.service";
6
+ import type { AiStatsFeature } from "./aiStatsFeature.js";
7
+ import { ISessionData } from "./aiStatsChart.js";
8
+ export declare class AiStatsStatusBar extends Disposable {
9
+ private readonly _aiStatsFeature;
10
+ private readonly _statusbarService;
11
+ private readonly _commandService;
12
+ private readonly _telemetryService;
13
+ static readonly hot: IObservable<typeof AiStatsStatusBar>;
14
+ constructor(_aiStatsFeature: AiStatsFeature, _statusbarService: IStatusbarService, _commandService: ICommandService, _telemetryService: ITelemetryService);
15
+ private _sendHoverTelemetry;
16
+ private _createStatusBar;
17
+ }
18
+ export interface IAiStatsHoverData {
19
+ readonly aiRate: IObservable<number>;
20
+ readonly acceptedInlineSuggestionsToday: IObservable<number>;
21
+ readonly sessions: IObservable<readonly ISessionData[]>;
22
+ }
23
+ export interface IAiStatsHoverOptions {
24
+ readonly data: IAiStatsHoverData;
25
+ readonly onOpenSettings?: () => void;
26
+ }
27
+ export declare function createAiStatsHover(options: IAiStatsHoverOptions): import("@codingame/monaco-vscode-api/vscode/vs/base/browser/dom").ObserverNode<HTMLDivElement>;
@@ -0,0 +1,250 @@
1
+
2
+ import { registerCss } from '@codingame/monaco-vscode-api/css';
3
+ import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
4
+ import { n } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/dom';
5
+ import { ActionBar } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/ui/actionbar/actionbar';
6
+ import { Codicon } from '@codingame/monaco-vscode-api/vscode/vs/base/common/codicons';
7
+ import { createHotClass } from '@codingame/monaco-vscode-api/vscode/vs/base/common/hotReloadHelpers';
8
+ import { Disposable, DisposableStore } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
9
+ import '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/index';
10
+ import { ThemeIcon } from '@codingame/monaco-vscode-api/vscode/vs/base/common/themables';
11
+ import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
12
+ import { ICommandService } from '@codingame/monaco-vscode-api/vscode/vs/platform/commands/common/commands.service';
13
+ import { nativeHoverDelegate } from '@codingame/monaco-vscode-api/vscode/vs/platform/hover/browser/hover';
14
+ import { ITelemetryService } from '@codingame/monaco-vscode-api/vscode/vs/platform/telemetry/common/telemetry.service';
15
+ import { StatusbarAlignment } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/statusbar/browser/statusbar';
16
+ import { IStatusbarService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/statusbar/browser/statusbar.service';
17
+ import { AI_STATS_SETTING_ID } from '../settingIds.js';
18
+ import { createAiStatsChart } from './aiStatsChart.js';
19
+ import * as media from './media.css';
20
+ import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
21
+ import { observableValue } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/observableValue';
22
+ import { derived } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/derived';
23
+
24
+ registerCss(media);
25
+ let AiStatsStatusBar = class AiStatsStatusBar extends Disposable {
26
+ static {
27
+ this.hot = createHotClass(this);
28
+ }
29
+ constructor(_aiStatsFeature, _statusbarService, _commandService, _telemetryService) {
30
+ super();
31
+ this._aiStatsFeature = _aiStatsFeature;
32
+ this._statusbarService = _statusbarService;
33
+ this._commandService = _commandService;
34
+ this._telemetryService = _telemetryService;
35
+ this._register(autorun(reader => {
36
+ const statusBarItem = this._createStatusBar().keepUpdated(reader.store);
37
+ const store = this._register(( new DisposableStore()));
38
+ reader.store.add(this._statusbarService.addEntry({
39
+ name: ( localize(9597, "Inline Suggestions")),
40
+ ariaLabel: ( localize(9598, "Inline suggestions status bar")),
41
+ text: "",
42
+ tooltip: {
43
+ element: async _token => {
44
+ this._sendHoverTelemetry();
45
+ store.clear();
46
+ const elem = createAiStatsHover({
47
+ data: this._aiStatsFeature,
48
+ onOpenSettings: () => openSettingsCommand({
49
+ ids: [AI_STATS_SETTING_ID]
50
+ }).run(this._commandService)
51
+ });
52
+ return elem.keepUpdated(store).element;
53
+ },
54
+ markdownNotSupportedFallback: undefined
55
+ },
56
+ content: statusBarItem.element
57
+ }, "aiStatsStatusBar", StatusbarAlignment.RIGHT, 100));
58
+ }));
59
+ }
60
+ _sendHoverTelemetry() {
61
+ this._telemetryService.publicLog2("aiStatsStatusBar.hover", {
62
+ aiRate: this._aiStatsFeature.aiRate.get()
63
+ });
64
+ }
65
+ _createStatusBar() {
66
+ return n.div({
67
+ style: {
68
+ height: "100%",
69
+ display: "flex",
70
+ alignItems: "center",
71
+ justifyContent: "center",
72
+ marginLeft: "3px",
73
+ marginRight: "3px"
74
+ }
75
+ }, [n.div({
76
+ class: "ai-stats-status-bar",
77
+ style: {
78
+ display: "flex",
79
+ flexDirection: "column",
80
+ width: 50,
81
+ height: 6,
82
+ borderRadius: 6,
83
+ borderWidth: "1px",
84
+ borderStyle: "solid"
85
+ }
86
+ }, [n.div({
87
+ style: {
88
+ flex: 1,
89
+ display: "flex",
90
+ overflow: "hidden",
91
+ borderRadius: 6,
92
+ border: "1px solid transparent"
93
+ }
94
+ }, [n.div({
95
+ style: {
96
+ width: ( this._aiStatsFeature.aiRate.map(v => `${v * 100}%`)),
97
+ backgroundColor: "currentColor"
98
+ }
99
+ })])])]);
100
+ }
101
+ };
102
+ AiStatsStatusBar = ( __decorate([( __param(1, IStatusbarService)), ( __param(2, ICommandService)), ( __param(3, ITelemetryService))], AiStatsStatusBar));
103
+ function createAiStatsHover(options) {
104
+ const chartViewMode = observableValue("chartViewMode", "days");
105
+ const aiRatePercent = ( options.data.aiRate.map(r => `${Math.round(r * 100)}%`));
106
+ const createToggleButton = (mode, tooltip, icon) => {
107
+ return derived(reader => {
108
+ const currentMode = chartViewMode.read(reader);
109
+ const isActive = currentMode === mode;
110
+ return n.div({
111
+ class: ["chart-toggle-button", isActive ? "active" : ""],
112
+ style: {
113
+ padding: "2px 4px",
114
+ borderRadius: "3px",
115
+ cursor: "pointer",
116
+ display: "flex",
117
+ alignItems: "center",
118
+ justifyContent: "center"
119
+ },
120
+ onclick: () => {
121
+ chartViewMode.set(mode, undefined);
122
+ },
123
+ title: tooltip
124
+ }, [n.div({
125
+ class: ThemeIcon.asClassName(icon),
126
+ style: {
127
+ fontSize: "14px"
128
+ }
129
+ })]);
130
+ });
131
+ };
132
+ return n.div({
133
+ class: "ai-stats-status-bar"
134
+ }, [n.div({
135
+ class: "header",
136
+ style: {
137
+ minWidth: "280px"
138
+ }
139
+ }, [n.div({
140
+ style: {
141
+ flex: 1
142
+ }
143
+ }, [( localize(9599, "AI Usage Statistics"))]), n.div({
144
+ style: {
145
+ marginLeft: "auto"
146
+ }
147
+ }, options.onOpenSettings ? actionBar([{
148
+ action: {
149
+ id: "aiStats.statusBar.settings",
150
+ label: "",
151
+ enabled: true,
152
+ run: options.onOpenSettings,
153
+ class: ThemeIcon.asClassName(Codicon.gear),
154
+ tooltip: ( localize(9600, "Configure"))
155
+ },
156
+ options: {
157
+ icon: true,
158
+ label: false,
159
+ hoverDelegate: nativeHoverDelegate
160
+ }
161
+ }]) : [])]), n.div({
162
+ style: {
163
+ display: "flex"
164
+ }
165
+ }, [n.div({
166
+ style: {
167
+ flex: 1,
168
+ paddingRight: "4px"
169
+ }
170
+ }, [( localize(9601, "AI vs Typing Average: {0}", aiRatePercent.get()))])]), n.div({
171
+ style: {
172
+ flex: 1,
173
+ paddingRight: "4px"
174
+ }
175
+ }, [( localize(
176
+ 9602,
177
+ "Accepted inline suggestions today: {0}",
178
+ options.data.acceptedInlineSuggestionsToday.get()
179
+ ))]),
180
+ n.div({
181
+ style: {
182
+ marginTop: "8px",
183
+ borderTop: "1px solid var(--vscode-widget-border)",
184
+ paddingTop: "8px"
185
+ }
186
+ }, [
187
+ n.div({
188
+ class: "header",
189
+ style: {
190
+ display: "flex",
191
+ alignItems: "center",
192
+ marginBottom: "4px"
193
+ }
194
+ }, [n.div({
195
+ style: {
196
+ flex: 1
197
+ }
198
+ }, [( chartViewMode.map(mode => mode === "days" ? ( localize(9603, "AI Rate by Day")) : ( localize(9604, "AI Rate by Session"))))]), n.div({
199
+ class: "chart-view-toggle",
200
+ style: {
201
+ marginLeft: "auto",
202
+ display: "flex",
203
+ gap: "2px"
204
+ }
205
+ }, [createToggleButton("days", ( localize(9605, "Days")), Codicon.calendar), createToggleButton("sessions", ( localize(9606, "Sessions")), Codicon.listFlat)])]),
206
+ derived(reader => {
207
+ const sessions = options.data.sessions.read(reader);
208
+ const viewMode = chartViewMode.read(reader);
209
+ return n.div({
210
+ ref: container => {
211
+ const chart = createAiStatsChart({
212
+ sessions,
213
+ viewMode
214
+ });
215
+ container.appendChild(chart);
216
+ }
217
+ });
218
+ })])]);
219
+ }
220
+ function actionBar(actions, options) {
221
+ return derived(_reader => n.div({
222
+ class: [],
223
+ style: {},
224
+ ref: elem => {
225
+ const actionBar = _reader.store.add(( new ActionBar(elem, options)));
226
+ for (const {
227
+ action,
228
+ options
229
+ } of actions) {
230
+ actionBar.push(action, options);
231
+ }
232
+ }
233
+ }));
234
+ }
235
+ class CommandWithArgs {
236
+ constructor(commandId, args = []) {
237
+ this.commandId = commandId;
238
+ this.args = args;
239
+ }
240
+ run(commandService) {
241
+ commandService.executeCommand(this.commandId, ...this.args);
242
+ }
243
+ }
244
+ function openSettingsCommand(options = {}) {
245
+ return ( new CommandWithArgs("workbench.action.openSettings", [{
246
+ query: options.ids ? ( options.ids.map(id => `@id:${id}`)).join(" ") : undefined
247
+ }]));
248
+ }
249
+
250
+ export { AiStatsStatusBar, createAiStatsHover };
@@ -0,0 +1,127 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+
6
+ /* Overall */
7
+
8
+ .ai-stats-status-bar {
9
+ margin-top: 4px;
10
+ margin-bottom: 4px;
11
+
12
+ hr {
13
+ margin-top: 8px;
14
+ margin-bottom: 8px;
15
+ }
16
+
17
+ div.header {
18
+ display: flex;
19
+ align-items: center;
20
+ color: var(--vscode-descriptionForeground);
21
+ margin-bottom: 4px;
22
+ font-size: 12px;
23
+ font-weight: 600;
24
+ }
25
+
26
+ div.description {
27
+ font-size: 11px;
28
+ color: var(--vscode-descriptionForeground);
29
+ }
30
+
31
+ .monaco-button {
32
+ margin-top: 5px;
33
+ margin-bottom: 5px;
34
+ }
35
+
36
+ /* Chart toggle buttons */
37
+ .chart-view-toggle {
38
+ display: flex;
39
+ gap: 2px;
40
+ }
41
+
42
+ .chart-toggle-button {
43
+ padding: 2px 6px;
44
+ border-radius: 3px;
45
+ cursor: pointer;
46
+ opacity: 0.6;
47
+ transition: opacity 0.15s, background-color 0.15s;
48
+ }
49
+
50
+ .chart-toggle-button:hover {
51
+ opacity: 1;
52
+ background-color: var(--vscode-toolbar-hoverBackground);
53
+ }
54
+
55
+ .chart-toggle-button.active {
56
+ opacity: 1;
57
+ background-color: var(--vscode-toolbar-activeBackground);
58
+ }
59
+
60
+ /* Chart container */
61
+ .ai-stats-chart-container {
62
+ margin-top: 4px;
63
+ }
64
+
65
+ .ai-stats-chart-container svg {
66
+ overflow: visible;
67
+ }
68
+
69
+ /* Setup for New User */
70
+
71
+ .setup .chat-feature-container {
72
+ display: flex;
73
+ align-items: center;
74
+ gap: 5px;
75
+ padding: 4px;
76
+ }
77
+
78
+ /* Settings */
79
+
80
+ .settings {
81
+ display: flex;
82
+ flex-direction: column;
83
+ gap: 5px;
84
+ }
85
+
86
+ .settings .setting {
87
+ display: flex;
88
+ align-items: center;
89
+ }
90
+
91
+ .settings .setting .monaco-checkbox {
92
+ height: 14px;
93
+ width: 14px;
94
+ margin-right: 5px;
95
+ }
96
+
97
+ .settings .setting .setting-label {
98
+ cursor: pointer;
99
+ }
100
+
101
+ .settings .setting.disabled .setting-label {
102
+ color: var(--vscode-disabledForeground);
103
+ }
104
+
105
+
106
+ /* Contributions */
107
+
108
+ .contribution .body {
109
+ display: flex;
110
+ flex-direction: row;
111
+ align-items: center;
112
+ gap: 5px;
113
+
114
+ .description,
115
+ .detail-item {
116
+ display: flex;
117
+ align-items: center;
118
+ gap: 3px;
119
+ }
120
+
121
+ .detail-item,
122
+ .detail-item a {
123
+ margin-left: auto;
124
+ color: var(--vscode-descriptionForeground);
125
+ }
126
+ }
127
+ }