Skip to content

Commit 4d37f78

Browse files
rajbosCopilot
andauthored
feat: annotate automatic tools and exclude from fluency scoring (#529)
* feat: annotate automatic tools and exclude from fluency scoring Add automaticTools.json with a curated list of tool IDs that Copilot calls autonomously (file reads, codebase searches, error checks, confirmations, etc.). These tools do not require user configuration and should not inflate fluency scores. Changes: - New vscode-extension/src/automaticTools.json: list of automatic tool IDs - maturityScoring.ts: compute nonAutoToolCount and use it for tuStage/agStage thresholds; evidence text now distinguishes intentional vs automatic tools - webview/usage/main.ts: show 'auto' badge on automatic tools in tool tables - cli/esbuild.js: include automaticTools.json in the bundled data files - docs/FLUENCY-LEVELS.md: document the automatic vs intentional tool distinction Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: update fluency viewer thresholds and agent docs for automatic tools - maturityScoring.ts getFluencyLevelData(): update threshold text in Agentic and Tool Usage levels to say 'intentional tools' instead of 'unique tools', and explain that automatic tools are excluded (Stage 1 description, Stage 2 now lists examples of intentional tools) - .github/agents/tool-names.agent.md: add automaticTools.json as a key file, add Automatic vs. Intentional Tools guidance section, update checklist - sync-toolnames prompts (both copies): update constraints to also modify automaticTools.json and classify new tools as automatic or intentional Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent aea2e2c commit 4d37f78

File tree

8 files changed

+196
-22
lines changed

8 files changed

+196
-22
lines changed

.github/agents/tool-names.agent.md

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ Trigger this agent when:
1515
- New MCP tools appear in user session logs without display labels
1616
- The sync-toolnames workflow detects new upstream tools from `microsoft/vscode-copilot-chat`
1717

18-
## Key File
18+
## Key Files
1919

2020
**`src/toolNames.json`** — The single mapping file from raw tool identifiers to human-readable display names. Every tool the extension encounters gets looked up here; missing entries show as "Unknown" in the UI.
2121

22+
**`src/automaticTools.json`** — An array of tool IDs that Copilot calls *automatically* on its own (file reads, directory listings, searches, error checks, confirmations, memory, etc.). These tools are excluded from fluency scoring because they don't reflect intentional user configuration. When adding new tool entries to `toolNames.json`, you **must also decide** whether each tool is automatic or intentional and add it to `automaticTools.json` if automatic.
23+
2224
## MCP Tool Name Conventions
2325

2426
MCP tools follow predictable naming patterns. The raw tool identifier encodes the MCP server origin and the action:
@@ -95,7 +97,34 @@ Use these repos to look up tool definitions when needed:
9597
| Context7 | [upstash/context7](https://github.com/upstash/context7) | TypeScript | Library documentation retrieval |
9698
| Chrome DevTools MCP | [ChromeDevTools/chrome-devtools-mcp](https://github.com/ChromeDevTools/chrome-devtools-mcp) | TypeScript | Browser debugging tools |
9799

98-
## Editing `src/toolNames.json`
100+
## Automatic vs. Intentional Tools
101+
102+
When adding a new tool to `toolNames.json`, also determine if it belongs in `automaticTools.json`.
103+
104+
**Add to `automaticTools.json` (automatic)** — tools the agent calls by itself without any user configuration:
105+
- File system reads: `read_file`, `list_dir`, `view`, `glob`, `grep`, file search variants
106+
- Codebase search: `semantic_search`, `code_search`, `search_workspace_symbols`
107+
- Project info: `get_errors`, `get_changed_files`, `read_project_structure`, `get_vscode_api`
108+
- Terminal reads (not execution): `terminal_selection`, `terminal_last_command`, `get_terminal_output`
109+
- Internal/session: `memory`, `detect_memories`, `tool_replay`, `vscode_get_confirmation*`, `ask_questions`, `switch_agent`, `bash`
110+
111+
**Do NOT add to `automaticTools.json` (intentional)** — tools that require explicit user setup or represent deliberate action:
112+
- Terminal execution: `run_in_terminal`, `run_build`, `run_task`
113+
- File writing/editing: `edit_files`, `write_file`, `create_file`, `apply_patch`
114+
- Tests & runs: `runTests`, `run_notebook_cell`, `run_vscode_command`
115+
- External integrations: `fetch_webpage`, `websearch`, `webfetch`
116+
- MCP tools (all — user must configure the server)
117+
- GitHub integrations: `github_pull_request`, `github_repo`
118+
119+
**Rule of thumb:** If the user must explicitly enable, configure, or consciously invoke the tool, it's intentional. If the agent just uses it as background context gathering, it's automatic.
120+
121+
## Editing `src/automaticTools.json`
122+
123+
- The file is a plain JSON array of tool ID strings
124+
- Add new entries at the end of the array (before the closing `]`)
125+
- Keep related tool variants together (e.g., all variants of `read_file`)
126+
127+
99128

100129
### Style Rules
101130

@@ -124,5 +153,6 @@ The `sync-toolnames` workflow (`.github/workflows/sync-toolnames.yml`) automatic
124153
- [ ] For MCP tools, match the prefix to a known server or research the source
125154
- [ ] Generate friendly names following the conventions above
126155
- [ ] Add entries to `src/toolNames.json` in the correct location
156+
- [ ] For each new tool, decide if it is **automatic** or **intentional** — add automatic tools to `src/automaticTools.json`
127157
- [ ] Run `npm run compile` to validate
128158
- [ ] Run `npm run test:node` to confirm tests pass

.github/prompts/sync-toolnames.prompt.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ Scan `microsoft/vscode-copilot-chat` repo for model-facing tool identifiers, com
4040
8. Also print (as plain text, after the delta or NO_DELTA) the upstream commit SHA used for the scan and the exact file path scanned in upstream, for traceability.
4141

4242
## Constraints
43-
- Only modify our toolNames.json file.
43+
- Only modify `toolNames.json` and `automaticTools.json`.
4444
- Do not open a PR.
4545
- Do not include tools in the list that are not model-facing (only those defined in upstream `ToolName` / `ContributedToolName` string values).
4646
- Be resilient to minor refactors (enum order changes, added comments, etc.).
47+
- For each new tool added to `toolNames.json`, also determine if it is **automatic** (agent calls it on its own: file reads, searches, error checks, confirmations) or **intentional** (user configures it: terminal execution, file editing, websearch, MCP tools). Add automatic tools to `automaticTools.json`.

.github/workflows/prompts/sync-toolnames-prompt.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ Scan `microsoft/vscode-copilot-chat` repo for model-facing tool identifiers, com
3434
8. Also print (as plain text, after the delta or NO_DELTA) the upstream commit SHA used for the scan and the exact file path scanned in upstream, for traceability.
3535

3636
## Constraints
37-
- Only modify our toolNames.json file.
37+
- Only modify `toolNames.json` and `automaticTools.json`.
3838
- Do not open a PR.
3939
- Do not include tools in the list that are not model-facing (only those defined in upstream `ToolName` / `ContributedToolName` string values).
4040
- Be resilient to minor refactors (enum order changes, added comments, etc.).
41+
- For each new tool added to `toolNames.json`, also determine if it is **automatic** (agent calls it on its own: file reads, searches, error checks, confirmations) or **intentional** (user configures it: terminal execution, file editing, websearch, MCP tools). Add automatic tools to `automaticTools.json`.

cli/esbuild.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ async function main() {
1010
"tokenEstimators.json",
1111
"modelPricing.json",
1212
"toolNames.json",
13+
"automaticTools.json",
1314
];
1415

1516
for (const file of dataFiles) {

docs/FLUENCY-LEVELS.md

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,16 @@ Measures adoption of autonomous, multi-step agent mode workflows.
6464
|-------|----------|
6565
| 1 | No agent-mode interactions |
6666
| 2 | At least 1 agent-mode interaction |
67-
| 3 | 10+ agent-mode interactions **and** 3+ unique tools used |
68-
| 4 | 50+ agent-mode interactions **and** 5+ unique tools used |
67+
| 3 | 10+ agent-mode interactions **and** 3+ unique intentional tools used |
68+
| 4 | 50+ agent-mode interactions **and** 5+ unique intentional tools used |
6969

7070
**Boosters:**
7171
- Multi-file edit sessions detected → at least Stage 2
7272
- Average 3+ files per edit session → at least Stage 3
7373
- 20+ multi-file edits with average 3+ files per session → Stage 4
7474

75+
> **Note:** Only *intentional* tools count toward the unique tool thresholds — tools that Copilot calls automatically (file reads, searches, error lookups, confirmations, memory, etc.) are excluded. See [Automatic vs. Intentional Tools](#automatic-vs-intentional-tools) below.
76+
7577
---
7678

7779
### 4. 🔧 Tool Usage
@@ -80,15 +82,39 @@ Measures breadth and depth of tool integration, including MCP servers.
8082

8183
| Stage | Criteria |
8284
|-------|----------|
83-
| 1 | No tools used |
84-
| 2 | At least 1 unique tool used |
85+
| 1 | No intentional tools used |
86+
| 2 | At least 1 intentional tool used |
8587
| 3 | 2+ advanced tools used, **or** `@workspace` agent sessions detected, **or** any MCP server usage |
8688
| 4 | 2+ MCP servers used |
8789

8890
**Recognised advanced tools:** GitHub Pull Request, GitHub Repository, Run In Terminal, Edit Files, List Files
8991

92+
> **Note:** Only *intentional* tools count toward Stage 2. Automatic tools are still shown in the tool-usage table with an `auto` badge, but are not counted for scoring. See [Automatic vs. Intentional Tools](#automatic-vs-intentional-tools) below.
93+
9094
---
9195

96+
### Automatic vs. Intentional Tools
97+
98+
Copilot calls many tools on its own during agentic sessions to gather context — reading files, searching the codebase, checking errors, etc. These are called **automatic tools** and do **not** count toward fluency scoring because they do not reflect deliberate configuration choices by the user.
99+
100+
**Automatic tools** (excluded from fluency scoring):
101+
- File operations: `read_file`, `list_dir`, `ls`, `view`, `find_files`, `glob`, `grep`, `grep_search`, `file_search`, `file_glob_search`
102+
- Codebase search: `semantic_search`, `code_search`, `search_workspace_symbols`, `get_symbols_by_name`
103+
- Project info: `get_errors`, `get_changed_files`, `read_project_structure`, `get_project_setup_info`, `get_vscode_api`, `get_doc_info`
104+
- Terminal reads: `terminal_selection`, `terminal_last_command`, `get_terminal_output`, `await_terminal`
105+
- Internal/session: `memory`, `detect_memories`, `tool_replay`, `vscode_get_confirmation*`, `ask_questions`, `switch_agent`, `bash`
106+
107+
**Intentional tools** (count toward fluency scoring) include:
108+
- Terminal execution: `run_in_terminal`, `run_build`, `run_task`
109+
- File writing/editing: `edit_files`, `write_file`, `create_file`, `apply_patch`, `insert_edit_into_file`, `replace_string_in_file`
110+
- Tests and runs: `runTests`, `run_notebook_cell`, `run_vscode_command`, `create_and_run_task`
111+
- External integrations: `fetch_webpage`, `webfetch`, `websearch`, MCP tools (all)
112+
- GitHub: `github_pull_request`, `github_repo`
113+
- Browser: `open_integrated_browser`, `renderMermaidDiagram`
114+
- Extensions and packages: `install_extension`, `install_python_packages`
115+
116+
The full list of automatic tool IDs is maintained in `vscode-extension/src/automaticTools.json`.
117+
92118
### 5. ⚙️ Customization
93119

94120
Measures how you tailor Copilot to your projects (custom instructions, model selection).
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
[
2+
"read_file",
3+
"copilot_readFile",
4+
"read",
5+
"view",
6+
"view_image",
7+
"copilot_viewImage",
8+
9+
"list_dir",
10+
"ls",
11+
"copilot_listDirectory",
12+
13+
"find_files",
14+
"file_search",
15+
"file_glob_search",
16+
"copilot_findFiles",
17+
"opilot_findFiles",
18+
"copilot_findTextInFiles",
19+
"copilot_findTestFiles",
20+
"test_search",
21+
22+
"grep_search",
23+
"grep",
24+
"glob",
25+
26+
"semantic_search",
27+
"copilot_searchCodebase",
28+
"code_search",
29+
"copilot_getSearchResults",
30+
"get_search_view_results",
31+
"search_workspace_symbols",
32+
"copilot_searchWorkspaceSymbols",
33+
"vscode_listCodeUsages",
34+
"get_symbols_by_name",
35+
36+
"get_errors",
37+
"copilot_getErrors",
38+
39+
"get_changed_files",
40+
"copilot_getChangedFiles",
41+
42+
"read_project_structure",
43+
"copilot_readProjectStructure",
44+
45+
"get_doc_info",
46+
"copilot_getDocInfo",
47+
48+
"get_vscode_api",
49+
"copilot_getVSCodeAPI",
50+
51+
"get_project_setup_info",
52+
"copilot_getProjectSetupInfo",
53+
54+
"get_projects_in_solution",
55+
"get_python_executable_details",
56+
57+
"get_currentfile",
58+
"get_file",
59+
60+
"vscode_get_confirmation",
61+
"vscode_get_confirmation_with_options",
62+
"vscode_get_terminal_confirmation",
63+
"vscode_get_modified_files_confirmation",
64+
65+
"memory",
66+
"copilot_memory",
67+
"detect_memories",
68+
69+
"tool_replay",
70+
"copilot_toolReplay",
71+
"tool_search",
72+
73+
"get_task_output",
74+
"job_output",
75+
"get_terminal_output",
76+
"await_terminal",
77+
78+
"terminal_selection",
79+
"terminal_last_command",
80+
81+
"read_notebook_cell_output",
82+
"copilot_readNotebookCellOutput",
83+
"copilot_getNotebookSummary",
84+
85+
"test_failure",
86+
"copilot_testFailure",
87+
88+
"ask_questions",
89+
"copilot_askQuestions",
90+
91+
"switch_agent",
92+
"copilot_switchAgent",
93+
94+
"bash",
95+
96+
"vscode_editFile_internal",
97+
"vscode_fetchWebPage_internal",
98+
"vscode_searchExtensions_internal"
99+
]

vscode-extension/src/maturityScoring.ts

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ import type {
88
WorkspaceCustomizationMatrix,
99
UsageAnalysisPeriod,
1010
} from './types';
11+
import automaticToolIds from './automaticTools.json';
12+
13+
/** Set of tool IDs that Copilot uses autonomously (reading files, searching, etc.).
14+
* These are excluded from fluency scoring since the user doesn't configure them. */
15+
const AUTOMATIC_TOOL_SET = new Set<string>(automaticToolIds);
1116

1217
/** Format a number with thousand separators for display. */
1318
function fmt(n: number): string {
@@ -195,7 +200,7 @@ export function getFluencyLevelData(isDebugMode: boolean): {
195200
label: "Stage 3: AI Collaborator",
196201
description: "Regular use of agent mode with diverse tools",
197202
thresholds: [
198-
"At least 10 agent-mode interactions AND 3+ unique tools used OR",
203+
"At least 10 agent-mode interactions AND 3+ intentional tools used OR",
199204
"Average 3+ files per edit session OR",
200205
"Using edits agent for focused editing tasks",
201206
],
@@ -209,7 +214,7 @@ export function getFluencyLevelData(isDebugMode: boolean): {
209214
label: "Stage 4: AI Strategist",
210215
description: "Heavy, strategic use of autonomous features",
211216
thresholds: [
212-
"At least 50 agent-mode interactions AND 5+ tool types used OR",
217+
"At least 50 agent-mode interactions AND 5+ intentional tools used OR",
213218
"At least 20 multi-file edits with 3+ files per session average",
214219
"Demonstrates mastery of agent orchestration",
215220
],
@@ -229,7 +234,7 @@ export function getFluencyLevelData(isDebugMode: boolean): {
229234
label: "Stage 1: AI Skeptic",
230235
description: "Not using tools beyond basic chat",
231236
thresholds: [
232-
"Zero unique tools used",
237+
"Zero intentional tools used (automatic tools like file reads and searches are excluded)",
233238
"No MCP servers configured",
234239
"No workspace agent sessions",
235240
],
@@ -243,8 +248,8 @@ export function getFluencyLevelData(isDebugMode: boolean): {
243248
label: "Stage 2: AI Explorer",
244249
description: "Beginning to use basic tools",
245250
thresholds: [
246-
"At least 1 unique tool used",
247-
"Using basic agent mode tools",
251+
"At least 1 intentional tool used (e.g. run_in_terminal, editFiles, websearch, MCP tools)",
252+
"Automatic tools (file reads, searches, error checks) do not count",
248253
],
249254
tips: [
250255
"Set up [MCP servers](https://code.visualstudio.com/docs/copilot/customization/mcp-servers) to connect Copilot to external tools (databases, APIs, cloud services) — [▶ MCP with Azure and GitHub](https://tech.hub.ms/github-copilot/videos/mcp-with-azure-and-github)",
@@ -440,6 +445,7 @@ export function calculateFluencyScoreForTeamMember(fd: {
440445
const hasModelSwitching = fd.mixedTierSessions > 0 || switchingFrequency > 0;
441446
const hasAgentMode = fd.agentModeCount > 0;
442447
const toolCount = Object.keys(fd.toolCallsByTool).length;
448+
const nonAutoToolCount = Object.keys(fd.toolCallsByTool).filter(t => !AUTOMATIC_TOOL_SET.has(t)).length;
443449
const avgFilesPerSession = fd.filesPerEditCount > 0 ? fd.filesPerEditSum / fd.filesPerEditCount : 0;
444450
const avgApplyRate = fd.applyRateCount > 0 ? fd.applyRateSum / fd.applyRateCount : 0;
445451
const totalContextRefs = fd.ctxFile + fd.ctxSelection + fd.ctxSymbol + fd.ctxCodebase + fd.ctxWorkspace;
@@ -528,8 +534,8 @@ export function calculateFluencyScoreForTeamMember(fd: {
528534
if (fd.multiFileEdits > 0) { agStage = Math.max(agStage, 2); }
529535
if (avgFilesPerSession >= 3) { agStage = Math.max(agStage, 3); }
530536
if (fd.editsAgentCount > 0) { agStage = Math.max(agStage, 2); }
531-
if (fd.agentModeCount >= 10 && toolCount >= 3) { agStage = Math.max(agStage, 3); }
532-
if (fd.agentModeCount >= 50 && toolCount >= 5) { agStage = 4; }
537+
if (fd.agentModeCount >= 10 && nonAutoToolCount >= 3) { agStage = Math.max(agStage, 3); }
538+
if (fd.agentModeCount >= 50 && nonAutoToolCount >= 5) { agStage = 4; }
533539
if (fd.multiFileEdits >= 20 && avgFilesPerSession >= 3) { agStage = Math.max(agStage, 4); }
534540
const agTips: string[] = [];
535541
if (agStage < 2) { agTips.push("Try agent mode — it can run terminal commands, edit files, and explore codebases autonomously"); }
@@ -538,7 +544,7 @@ export function calculateFluencyScoreForTeamMember(fd: {
538544

539545
// 4. Tool Usage
540546
let tuStage = 1;
541-
if (toolCount > 0) { tuStage = 2; }
547+
if (nonAutoToolCount > 0) { tuStage = 2; }
542548
if (fd.workspaceAgentCount > 0) { tuStage = Math.max(tuStage, 3); }
543549
const advancedToolIds = ["github_pull_request", "github_repo", "run_in_terminal", "editFiles", "listFiles"];
544550
const usedAdvancedCount = advancedToolIds.filter(t => (fd.toolCallsByTool[t] ?? 0) > 0).length;
@@ -855,12 +861,13 @@ export async function calculateMaturityScores(lastCustomizationMatrix: Workspace
855861

856862
// Diverse tool usage in agent mode
857863
const toolCount = Object.keys(p.toolCalls.byTool).length;
858-
if (p.modeUsage.agent >= 10 && toolCount >= 3) {
864+
const nonAutoToolCount = Object.keys(p.toolCalls.byTool).filter(t => !AUTOMATIC_TOOL_SET.has(t)).length;
865+
if (p.modeUsage.agent >= 10 && nonAutoToolCount >= 3) {
859866
agStage = 3;
860867
}
861868

862869
// Heavy agentic use with many tool types or high multi-file edit rate
863-
if (p.modeUsage.agent >= 50 && toolCount >= 5) {
870+
if (p.modeUsage.agent >= 50 && nonAutoToolCount >= 5) {
864871
agStage = 4;
865872
}
866873
if (p.editScope && p.editScope.multiFileEdits >= 20 && p.editScope.avgFilesPerSession >= 3) {
@@ -876,10 +883,14 @@ export async function calculateMaturityScores(lastCustomizationMatrix: Workspace
876883
const tuTips: string[] = [];
877884
let tuStage = 1;
878885

879-
// Basic tool usage (primarily from agent mode)
880-
if (toolCount > 0) {
881-
tuEvidence.push(`${fmt(toolCount)} unique tools used`);
886+
// Basic tool usage — only count tools the user intentionally enables/configures (not automatic agent tools)
887+
if (nonAutoToolCount > 0) {
888+
const autoCount = toolCount - nonAutoToolCount;
889+
const autoNote = autoCount > 0 ? ` (+ ${fmt(autoCount)} automatic)` : '';
890+
tuEvidence.push(`${fmt(nonAutoToolCount)} intentional tools used${autoNote}`);
882891
tuStage = 2;
892+
} else if (toolCount > 0) {
893+
tuEvidence.push(`${fmt(toolCount)} tools used (all automatic — agent reads/searches)`);
883894
}
884895

885896
// Agent type distribution (workspace agent shows advanced tool usage)

vscode-extension/src/webview/usage/main.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,10 @@ function escapeHtml(text: string): string {
125125
}
126126

127127
import toolNames from '../../toolNames.json';
128+
import automaticToolIds from '../../automaticTools.json';
128129

129130
let TOOL_NAME_MAP: { [key: string]: string } | null = toolNames || null;
131+
const AUTOMATIC_TOOL_SET_WV = new Set<string>(automaticToolIds as string[]);
130132

131133
function lookupToolName(id: string): string {
132134
if (!TOOL_NAME_MAP) {
@@ -256,10 +258,13 @@ function renderToolsTable(byTool: { [key: string]: number }, limit = 10, nameRes
256258
const rows = sortedTools.map(([tool, count], idx) => {
257259
const friendly = escapeHtml(nameResolver(tool));
258260
const idEscaped = escapeHtml(tool);
261+
const autoBadge = AUTOMATIC_TOOL_SET_WV.has(tool)
262+
? `<span title="Automatic tool — Copilot uses this internally and it does not count toward fluency scoring" style="margin-left:6px; padding:1px 5px; font-size:10px; border-radius:3px; background:var(--bg-secondary); color:var(--text-muted); border:1px solid var(--border-subtle); vertical-align:middle;">auto</span>`
263+
: '';
259264
return `
260265
<tr>
261266
<td style="padding:8px 12px; border-bottom:1px solid var(--border-subtle); width:40px; max-width:40px; text-align:center;">${idx + 1}</td>
262-
<td style="padding:8px 12px; border-bottom:1px solid var(--border-subtle); word-break:break-word; overflow-wrap:break-word; max-width:0;"> <strong title="${idEscaped}">${friendly}</strong></td>
267+
<td style="padding:8px 12px; border-bottom:1px solid var(--border-subtle); word-break:break-word; overflow-wrap:break-word; max-width:0;"> <strong title="${idEscaped}">${friendly}</strong>${autoBadge}</td>
263268
<td style="padding:8px 12px; border-bottom:1px solid var(--border-subtle); text-align:right; width:90px; white-space:nowrap;">${formatNumber(count)}</td>
264269
</tr>`;
265270
}).join('');

0 commit comments

Comments
 (0)