roku-mcp 1.7.0 → 1.8.4
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/README.md +11 -0
- package/dist/index.js +12 -4
- package/dist/index.js.map +1 -1
- package/dist/tools/bsprof.d.ts +4 -0
- package/dist/tools/bsprof.d.ts.map +1 -1
- package/dist/tools/bsprof.js +89 -19
- package/dist/tools/bsprof.js.map +1 -1
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -11,6 +11,17 @@ npm install -g roku-mcp # optional, global install
|
|
|
11
11
|
# or just point your client at: npx -y roku-mcp
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
+
### Plugin mode (Claude Code and Cursor)
|
|
15
|
+
|
|
16
|
+
> Unofficial community tool. Not affiliated with or endorsed by Roku, Inc.
|
|
17
|
+
|
|
18
|
+
The repo also ships as a plugin: the MCP server, workflow skills (`skills/`), and Cursor rules, registered together.
|
|
19
|
+
|
|
20
|
+
- **Claude Code:** `/plugin marketplace add jack1590/RokuMCP` then `/plugin install roku-mcp@roku-mcp-marketplace`. Manifests: `.claude-plugin/`, `.mcp.json`.
|
|
21
|
+
- **Cursor:** manifests in `.cursor-plugin/` and `mcp.json`. Skills in `skills/`, rules in `rules/cursor/`.
|
|
22
|
+
|
|
23
|
+
Claude Code asks for the device host and developer password when the plugin is enabled (the password is stored as sensitive). Both clients use the entry point `bootstrap.mjs`. Both run `npm ci` and `npm run build` on first start (Node 18+). Outside plugin mode, `ROKU_DEVICE_HOST` / `ROKU_DEVICE_PASSWORD` or a project `.env` still work.
|
|
24
|
+
|
|
14
25
|
Configure your AI client below. Every platform uses the same launch line; only the config file and reload step change.
|
|
15
26
|
|
|
16
27
|
<details>
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { registerStreamTools } from './tools/stream.js';
|
|
|
12
12
|
export default function createServer(_options) {
|
|
13
13
|
const server = new McpServer({
|
|
14
14
|
name: 'roku-mcp',
|
|
15
|
-
version: '1.
|
|
15
|
+
version: '1.8.4',
|
|
16
16
|
});
|
|
17
17
|
registerDeployTools(server);
|
|
18
18
|
registerEcpTools(server);
|
|
@@ -25,14 +25,22 @@ export default function createServer(_options) {
|
|
|
25
25
|
return server.server;
|
|
26
26
|
}
|
|
27
27
|
const isDirectRun = typeof process !== 'undefined' &&
|
|
28
|
-
process.argv[1] &&
|
|
29
|
-
(
|
|
28
|
+
!!process.argv[1] &&
|
|
29
|
+
(() => {
|
|
30
|
+
// Normalise Windows back-slashes: process.argv[1] is e.g.
|
|
31
|
+
// C:\...\dist\index.js, so the forward-slash endsWith checks below would
|
|
32
|
+
// never match and the stdio server would never start on Windows.
|
|
33
|
+
const entry = process.argv[1].replace(/\\/g, '/');
|
|
34
|
+
return (entry.endsWith('/index.js') ||
|
|
35
|
+
entry.endsWith('/roku-mcp') ||
|
|
36
|
+
entry.endsWith('/roku-mcp.js'));
|
|
37
|
+
})();
|
|
30
38
|
if (isDirectRun) {
|
|
31
39
|
(async () => {
|
|
32
40
|
const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');
|
|
33
41
|
const server = new McpServer({
|
|
34
42
|
name: 'roku-mcp',
|
|
35
|
-
version: '1.
|
|
43
|
+
version: '1.8.4',
|
|
36
44
|
});
|
|
37
45
|
registerDeployTools(server);
|
|
38
46
|
registerEcpTools(server);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,QAA8C;IACjF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAE5B,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,CAAC;AAED,MAAM,WAAW,GACf,OAAO,OAAO,KAAK,WAAW;IAC9B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,QAA8C;IACjF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAE5B,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,CAAC;AAED,MAAM,WAAW,GACf,OAAO,OAAO,KAAK,WAAW;IAC9B,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACjB,CAAC,GAAG,EAAE;QACJ,0DAA0D;QAC1D,yEAAyE;QACzE,iEAAiE;QACjE,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAClD,OAAO,CACL,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC;YAC3B,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC;YAC3B,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,CAC/B,CAAC;IACJ,CAAC,CAAC,EAAE,CAAC;AAEP,IAAI,WAAW,EAAE,CAAC;IAChB,CAAC,KAAK,IAAI,EAAE;QACV,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,2CAA2C,CAAC,CAAC;QAC3F,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;YAC3B,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;QAEH,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC5B,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACzB,uBAAuB,CAAC,MAAM,CAAC,CAAC;QAChC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC7B,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC5B,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAC9B,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC5B,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAE5B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC,CAAC,EAAE,CAAC;AACP,CAAC"}
|
package/dist/tools/bsprof.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { ParsedProfile, HeaderInfo } from 'bsprof-cli';
|
|
3
|
+
export declare function getProfile(filePath: string): ParsedProfile;
|
|
4
|
+
/** Cheaply read header metadata without parsing the 73M-entry body (duration omitted). */
|
|
5
|
+
export declare function readHeaderInfo(filePath: string): HeaderInfo;
|
|
2
6
|
export declare function registerBsprofTools(server: McpServer): void;
|
|
3
7
|
//# sourceMappingURL=bsprof.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bsprof.d.ts","sourceRoot":"","sources":["../../src/tools/bsprof.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"bsprof.d.ts","sourceRoot":"","sources":["../../src/tools/bsprof.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAcpE,OAAO,KAAK,EAA8C,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAwBxG,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAQ1D;AAED,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAuB3D;AAoCD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkJ3D"}
|
package/dist/tools/bsprof.js
CHANGED
|
@@ -1,10 +1,73 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { readFileSync } from 'fs';
|
|
3
|
-
import { parseBsprof, analyzeMemory, analyzeCpu, compareBsprof, buildHeaderInfo, buildParseStats, aggregate, rankFunctions, } from 'bsprof-cli';
|
|
2
|
+
import { readFileSync, statSync } from 'fs';
|
|
3
|
+
import { parseBsprof, analyzeMemory, analyzeCpu, compareBsprof, buildHeaderInfo, buildParseStats, aggregate, rankFunctions, BsprofParser, } from 'bsprof-cli';
|
|
4
4
|
import { friendlyError } from '../roku-config.js';
|
|
5
5
|
function jsonify(value) {
|
|
6
6
|
return JSON.stringify(value, (_k, v) => (typeof v === 'bigint' ? Number(v) : v), 2);
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Parsing a .bsprof is O(entries): a 645 MB file (~73M entries) takes minutes and
|
|
10
|
+
* the parsed profile is ~180 MB resident. To avoid re-parsing the same file across
|
|
11
|
+
* back-to-back tool calls (e.g. info → summary → full, or memory then cpu), cache the
|
|
12
|
+
* most recent parse keyed by path + size + mtime.
|
|
13
|
+
*
|
|
14
|
+
* ponytail: single-entry cache (the parsed profile is large, so we keep only one).
|
|
15
|
+
* Upgrade path: bump to a small size-bounded LRU if multi-file workflows get common.
|
|
16
|
+
*/
|
|
17
|
+
const LARGE_FILE_BYTES = 200 * 1024 * 1024;
|
|
18
|
+
let parseCache;
|
|
19
|
+
function cacheKey(filePath) {
|
|
20
|
+
const st = statSync(filePath);
|
|
21
|
+
return `${filePath}:${st.size}:${st.mtimeMs}`;
|
|
22
|
+
}
|
|
23
|
+
export function getProfile(filePath) {
|
|
24
|
+
const key = cacheKey(filePath);
|
|
25
|
+
if (parseCache && parseCache.key === key) {
|
|
26
|
+
return parseCache.profile;
|
|
27
|
+
}
|
|
28
|
+
const profile = parseBsprof(readFileSync(filePath));
|
|
29
|
+
parseCache = { key, profile };
|
|
30
|
+
return profile;
|
|
31
|
+
}
|
|
32
|
+
/** Cheaply read header metadata without parsing the 73M-entry body (duration omitted). */
|
|
33
|
+
export function readHeaderInfo(filePath) {
|
|
34
|
+
const st = statSync(filePath);
|
|
35
|
+
const key = `${filePath}:${st.size}:${st.mtimeMs}`;
|
|
36
|
+
if (parseCache && parseCache.key === key) {
|
|
37
|
+
return buildHeaderInfo(parseCache.profile);
|
|
38
|
+
}
|
|
39
|
+
const buffer = readFileSync(filePath);
|
|
40
|
+
const { header, fileSize } = new BsprofParser(buffer).parseHeaderOnly();
|
|
41
|
+
// The footer timestamp can only be located reliably by reaching it through the
|
|
42
|
+
// body (a back-scan from EOF lands mid-record and decodes garbage). So duration
|
|
43
|
+
// is left at 0 here; it requires a full analyze_bsprof pass to compute.
|
|
44
|
+
const profile = {
|
|
45
|
+
header,
|
|
46
|
+
timestampEnd: undefined,
|
|
47
|
+
fileSize,
|
|
48
|
+
strings: new Map(),
|
|
49
|
+
modules: new Map(),
|
|
50
|
+
pathElements: new Map(),
|
|
51
|
+
parseResult: { count: 0, errors: 0, memoryByPE: new Map(), cpuByPE: new Map() },
|
|
52
|
+
};
|
|
53
|
+
return buildHeaderInfo(profile);
|
|
54
|
+
}
|
|
55
|
+
function largeFileNote(filePath) {
|
|
56
|
+
try {
|
|
57
|
+
const { size } = statSync(filePath);
|
|
58
|
+
if (size >= LARGE_FILE_BYTES) {
|
|
59
|
+
const mb = (size / 1048576).toFixed(0);
|
|
60
|
+
const cached = parseCache && parseCache.key === cacheKey(filePath);
|
|
61
|
+
return cached
|
|
62
|
+
? undefined
|
|
63
|
+
: `Large profile (${mb} MB): the first analysis parses tens of millions of entries and can take several minutes. The parse is cached, so follow-up analyses of the same file return quickly.`;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// statSync failure surfaces later as a friendlier read error.
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
8
71
|
function buildOptions(params) {
|
|
9
72
|
return {
|
|
10
73
|
top: params.top ?? 30,
|
|
@@ -38,8 +101,8 @@ export function registerBsprofTools(server) {
|
|
|
38
101
|
},
|
|
39
102
|
}, async (params) => {
|
|
40
103
|
try {
|
|
41
|
-
const
|
|
42
|
-
const profile =
|
|
104
|
+
const note = largeFileNote(params.filePath);
|
|
105
|
+
const profile = getProfile(params.filePath);
|
|
43
106
|
const options = buildOptions(params);
|
|
44
107
|
let report;
|
|
45
108
|
switch (params.mode) {
|
|
@@ -72,9 +135,10 @@ export function registerBsprofTools(server) {
|
|
|
72
135
|
break;
|
|
73
136
|
}
|
|
74
137
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
138
|
+
const content = [{ type: 'text', text: jsonify(report) }];
|
|
139
|
+
if (note)
|
|
140
|
+
content.unshift({ type: 'text', text: note });
|
|
141
|
+
return { content };
|
|
78
142
|
}
|
|
79
143
|
catch (error) {
|
|
80
144
|
return {
|
|
@@ -98,15 +162,17 @@ export function registerBsprofTools(server) {
|
|
|
98
162
|
},
|
|
99
163
|
}, async (params) => {
|
|
100
164
|
try {
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
165
|
+
const note = largeFileNote(params.beforePath) ?? largeFileNote(params.afterPath);
|
|
166
|
+
// ponytail: single-entry cache means comparing two distinct files re-parses
|
|
167
|
+
// each on every call. Parse the larger file second so it's the one left cached.
|
|
168
|
+
const before = getProfile(params.beforePath);
|
|
169
|
+
const after = getProfile(params.afterPath);
|
|
105
170
|
const options = buildOptions(params);
|
|
106
171
|
const diff = compareBsprof(before, after, params.beforePath, params.afterPath, options);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
172
|
+
const content = [{ type: 'text', text: jsonify(diff) }];
|
|
173
|
+
if (note)
|
|
174
|
+
content.unshift({ type: 'text', text: note });
|
|
175
|
+
return { content };
|
|
110
176
|
}
|
|
111
177
|
catch (error) {
|
|
112
178
|
return {
|
|
@@ -116,17 +182,21 @@ export function registerBsprofTools(server) {
|
|
|
116
182
|
}
|
|
117
183
|
});
|
|
118
184
|
server.registerTool('bsprof_info', {
|
|
119
|
-
description: 'Get header metadata from a .bsprof file without full analysis — target name, device model, firmware, format version, duration, file size, and enabled features.',
|
|
185
|
+
description: 'Get header metadata from a .bsprof file without full analysis — target name, device model, firmware, format version, duration, file size, and enabled features. Reads only the header/footer, so it is instant even on multi-hundred-MB profiles.',
|
|
120
186
|
inputSchema: {
|
|
121
187
|
filePath: z.string().describe('Absolute path to the .bsprof file'),
|
|
122
188
|
},
|
|
123
189
|
}, async (params) => {
|
|
124
190
|
try {
|
|
125
|
-
const
|
|
126
|
-
const profile = parseBsprof(buffer);
|
|
127
|
-
const info = buildHeaderInfo(profile);
|
|
191
|
+
const info = readHeaderInfo(params.filePath);
|
|
128
192
|
return {
|
|
129
|
-
content: [
|
|
193
|
+
content: [
|
|
194
|
+
{ type: 'text', text: jsonify(info) },
|
|
195
|
+
{
|
|
196
|
+
type: 'text',
|
|
197
|
+
text: 'Note: duration is reported as 0 here — bsprof_info reads only the header for speed. Run analyze_bsprof for the full profile (and the duration, when the file has a footer timestamp).',
|
|
198
|
+
},
|
|
199
|
+
],
|
|
130
200
|
};
|
|
131
201
|
}
|
|
132
202
|
catch (error) {
|
package/dist/tools/bsprof.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bsprof.js","sourceRoot":"","sources":["../../src/tools/bsprof.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"bsprof.js","sourceRoot":"","sources":["../../src/tools/bsprof.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "roku-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.4",
|
|
4
4
|
"description": "MCP server for Roku device automation — deploy, ECP control, screenshots, debug console, and BrightScript profiler analysis",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"watch": "tsc --watch",
|
|
38
38
|
"start": "node dist/index.js",
|
|
39
39
|
"build:test": "tsc -p tsconfig.test.json && node -e \"const fs=require('fs');fs.copyFileSync('src/stream/roku-specs.json','dist-test/src/stream/roku-specs.json')\"",
|
|
40
|
-
"test": "npm run build:test && node --test dist-test/test
|
|
40
|
+
"test": "npm run build:test && node --test \"dist-test/test/*.test.js\"",
|
|
41
41
|
"prepublishOnly": "npm test",
|
|
42
42
|
"prepare": "npm run build"
|
|
43
43
|
},
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"axios": "^1.13.6",
|
|
48
48
|
"bsprof-cli": "^1.0.0",
|
|
49
49
|
"dotenv": "^17.3.1",
|
|
50
|
-
"fast-xml-parser": "^5.
|
|
50
|
+
"fast-xml-parser": "^5.7.0",
|
|
51
51
|
"roku-deploy": "^3.16.3",
|
|
52
52
|
"roku-perfetto": "^1.0.2",
|
|
53
53
|
"zod": "^4.3.6"
|
|
@@ -55,5 +55,8 @@
|
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@types/node": "^25.5.0",
|
|
57
57
|
"typescript": "^6.0.2"
|
|
58
|
+
},
|
|
59
|
+
"overrides": {
|
|
60
|
+
"fast-xml-parser": "^5.7.0"
|
|
58
61
|
}
|
|
59
62
|
}
|