@local-labs-jpollock/local-cli 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/addon-dist/bin/mcp-stdio.js +2808 -0
  2. package/addon-dist/lib/common/constants.d.ts +22 -0
  3. package/addon-dist/lib/common/constants.js +26 -0
  4. package/addon-dist/lib/common/theme.d.ts +68 -0
  5. package/addon-dist/lib/common/theme.js +126 -0
  6. package/addon-dist/lib/common/types.d.ts +298 -0
  7. package/addon-dist/lib/common/types.js +6 -0
  8. package/addon-dist/lib/main/config/ConnectionInfo.d.ts +25 -0
  9. package/addon-dist/lib/main/config/ConnectionInfo.js +82 -0
  10. package/addon-dist/lib/main/index.d.ts +12 -0
  11. package/addon-dist/lib/main/index.js +3322 -0
  12. package/addon-dist/lib/main/mcp/McpAuth.d.ts +37 -0
  13. package/addon-dist/lib/main/mcp/McpAuth.js +87 -0
  14. package/addon-dist/lib/main/mcp/McpServer.d.ts +67 -0
  15. package/addon-dist/lib/main/mcp/McpServer.js +343 -0
  16. package/addon-dist/lib/main/mcp/tools/changePhpVersion.d.ts +7 -0
  17. package/addon-dist/lib/main/mcp/tools/changePhpVersion.js +81 -0
  18. package/addon-dist/lib/main/mcp/tools/cloneSite.d.ts +7 -0
  19. package/addon-dist/lib/main/mcp/tools/cloneSite.js +66 -0
  20. package/addon-dist/lib/main/mcp/tools/createSite.d.ts +7 -0
  21. package/addon-dist/lib/main/mcp/tools/createSite.js +137 -0
  22. package/addon-dist/lib/main/mcp/tools/deleteSite.d.ts +7 -0
  23. package/addon-dist/lib/main/mcp/tools/deleteSite.js +72 -0
  24. package/addon-dist/lib/main/mcp/tools/exportDatabase.d.ts +7 -0
  25. package/addon-dist/lib/main/mcp/tools/exportDatabase.js +72 -0
  26. package/addon-dist/lib/main/mcp/tools/exportSite.d.ts +7 -0
  27. package/addon-dist/lib/main/mcp/tools/exportSite.js +103 -0
  28. package/addon-dist/lib/main/mcp/tools/getLocalInfo.d.ts +7 -0
  29. package/addon-dist/lib/main/mcp/tools/getLocalInfo.js +72 -0
  30. package/addon-dist/lib/main/mcp/tools/getSite.d.ts +7 -0
  31. package/addon-dist/lib/main/mcp/tools/getSite.js +68 -0
  32. package/addon-dist/lib/main/mcp/tools/getSiteLogs.d.ts +7 -0
  33. package/addon-dist/lib/main/mcp/tools/getSiteLogs.js +149 -0
  34. package/addon-dist/lib/main/mcp/tools/helpers.d.ts +59 -0
  35. package/addon-dist/lib/main/mcp/tools/helpers.js +179 -0
  36. package/addon-dist/lib/main/mcp/tools/importDatabase.d.ts +7 -0
  37. package/addon-dist/lib/main/mcp/tools/importDatabase.js +109 -0
  38. package/addon-dist/lib/main/mcp/tools/importSite.d.ts +7 -0
  39. package/addon-dist/lib/main/mcp/tools/importSite.js +149 -0
  40. package/addon-dist/lib/main/mcp/tools/index.d.ts +26 -0
  41. package/addon-dist/lib/main/mcp/tools/index.js +117 -0
  42. package/addon-dist/lib/main/mcp/tools/listBlueprints.d.ts +7 -0
  43. package/addon-dist/lib/main/mcp/tools/listBlueprints.js +54 -0
  44. package/addon-dist/lib/main/mcp/tools/listServices.d.ts +7 -0
  45. package/addon-dist/lib/main/mcp/tools/listServices.js +112 -0
  46. package/addon-dist/lib/main/mcp/tools/listSites.d.ts +7 -0
  47. package/addon-dist/lib/main/mcp/tools/listSites.js +62 -0
  48. package/addon-dist/lib/main/mcp/tools/openAdminer.d.ts +7 -0
  49. package/addon-dist/lib/main/mcp/tools/openAdminer.js +59 -0
  50. package/addon-dist/lib/main/mcp/tools/openSite.d.ts +7 -0
  51. package/addon-dist/lib/main/mcp/tools/openSite.js +62 -0
  52. package/addon-dist/lib/main/mcp/tools/renameSite.d.ts +7 -0
  53. package/addon-dist/lib/main/mcp/tools/renameSite.js +70 -0
  54. package/addon-dist/lib/main/mcp/tools/restartSite.d.ts +7 -0
  55. package/addon-dist/lib/main/mcp/tools/restartSite.js +56 -0
  56. package/addon-dist/lib/main/mcp/tools/saveBlueprint.d.ts +7 -0
  57. package/addon-dist/lib/main/mcp/tools/saveBlueprint.js +89 -0
  58. package/addon-dist/lib/main/mcp/tools/startSite.d.ts +7 -0
  59. package/addon-dist/lib/main/mcp/tools/startSite.js +54 -0
  60. package/addon-dist/lib/main/mcp/tools/stopSite.d.ts +7 -0
  61. package/addon-dist/lib/main/mcp/tools/stopSite.js +54 -0
  62. package/addon-dist/lib/main/mcp/tools/toggleXdebug.d.ts +7 -0
  63. package/addon-dist/lib/main/mcp/tools/toggleXdebug.js +69 -0
  64. package/addon-dist/lib/main/mcp/tools/trustSsl.d.ts +7 -0
  65. package/addon-dist/lib/main/mcp/tools/trustSsl.js +59 -0
  66. package/addon-dist/lib/main/mcp/tools/wpCli.d.ts +7 -0
  67. package/addon-dist/lib/main/mcp/tools/wpCli.js +110 -0
  68. package/addon-dist/lib/main.d.ts +1 -0
  69. package/addon-dist/lib/main.js +10 -0
  70. package/addon-dist/lib/renderer/index.d.ts +7 -0
  71. package/addon-dist/lib/renderer/index.js +479 -0
  72. package/addon-dist/package.json +73 -0
  73. package/bin/lwp.js +10 -0
  74. package/lib/bootstrap/index.d.ts +98 -0
  75. package/lib/bootstrap/index.js +493 -0
  76. package/lib/bootstrap/paths.d.ts +28 -0
  77. package/lib/bootstrap/paths.js +96 -0
  78. package/lib/client/GraphQLClient.d.ts +38 -0
  79. package/lib/client/GraphQLClient.js +71 -0
  80. package/lib/client/index.d.ts +4 -0
  81. package/lib/client/index.js +10 -0
  82. package/lib/formatters/index.d.ts +75 -0
  83. package/lib/formatters/index.js +139 -0
  84. package/lib/index.d.ts +8 -0
  85. package/lib/index.js +1173 -0
  86. package/package.json +72 -0
@@ -0,0 +1,479 @@
1
+ "use strict";
2
+ /**
3
+ * MCP Server Addon - Renderer Entry Point
4
+ * Adds MCP Server preferences panel to Local
5
+ *
6
+ * Uses class components for compatibility with Local's Electron environment.
7
+ */
8
+ var __importDefault = (this && this.__importDefault) || function (mod) {
9
+ return (mod && mod.__esModule) ? mod : { "default": mod };
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const react_1 = __importDefault(require("react"));
13
+ const theme_1 = require("../common/theme");
14
+ // MCP Preferences Panel Component (Class-based for Local compatibility)
15
+ class McpPreferencesPanel extends react_1.default.Component {
16
+ constructor() {
17
+ super(...arguments);
18
+ this.state = {
19
+ status: null,
20
+ connectionInfo: null,
21
+ loading: true,
22
+ copied: false,
23
+ actionInProgress: false,
24
+ activeTab: 'status',
25
+ colors: (0, theme_1.getThemeColors)(),
26
+ };
27
+ this.fetchStatus = async () => {
28
+ try {
29
+ const result = (await this.props.electron?.ipcRenderer?.invoke('mcp:getStatus'));
30
+ if (result) {
31
+ this.setState({ status: result });
32
+ }
33
+ }
34
+ catch (error) {
35
+ console.error('Failed to fetch MCP status:', error);
36
+ }
37
+ };
38
+ this.fetchConnectionInfo = async () => {
39
+ try {
40
+ const result = (await this.props.electron?.ipcRenderer?.invoke('mcp:getConnectionInfo'));
41
+ if (result) {
42
+ this.setState({ connectionInfo: result });
43
+ }
44
+ }
45
+ catch (error) {
46
+ console.error('Failed to fetch connection info:', error);
47
+ }
48
+ };
49
+ this.handleCopyStdioConfig = () => {
50
+ const config = {
51
+ mcpServers: {
52
+ local: {
53
+ type: 'stdio',
54
+ command: 'node',
55
+ args: ['/path/to/local-addon-mcp-server/bin/mcp-stdio.js'],
56
+ },
57
+ },
58
+ };
59
+ navigator.clipboard.writeText(JSON.stringify(config, null, 2));
60
+ this.setState({ copied: true });
61
+ setTimeout(() => this.setState({ copied: false }), 2000);
62
+ };
63
+ this.handleCopySseConfig = () => {
64
+ const { connectionInfo } = this.state;
65
+ if (connectionInfo) {
66
+ const config = {
67
+ mcpServers: {
68
+ local: {
69
+ url: `${connectionInfo.url}/mcp/sse`,
70
+ transport: 'sse',
71
+ headers: {
72
+ Authorization: `Bearer ${connectionInfo.authToken}`,
73
+ },
74
+ },
75
+ },
76
+ };
77
+ navigator.clipboard.writeText(JSON.stringify(config, null, 2));
78
+ this.setState({ copied: true });
79
+ setTimeout(() => this.setState({ copied: false }), 2000);
80
+ }
81
+ };
82
+ this.handleTestConnection = async () => {
83
+ const { connectionInfo } = this.state;
84
+ try {
85
+ const response = await fetch(`http://127.0.0.1:${connectionInfo?.port}/health`);
86
+ const data = await response.json();
87
+ if (data.status === 'ok') {
88
+ alert('Connection successful! MCP server is healthy.');
89
+ }
90
+ else {
91
+ alert('Connection failed: Server returned unexpected response');
92
+ }
93
+ }
94
+ catch (error) {
95
+ const message = error instanceof Error ? error.message : 'Unknown error';
96
+ alert(`Connection failed: ${message}`);
97
+ }
98
+ };
99
+ this.handleStartStop = async () => {
100
+ const { status } = this.state;
101
+ this.setState({ actionInProgress: true });
102
+ try {
103
+ if (status?.running) {
104
+ await this.props.electron?.ipcRenderer?.invoke('mcp:stop');
105
+ }
106
+ else {
107
+ await this.props.electron?.ipcRenderer?.invoke('mcp:start');
108
+ }
109
+ await this.fetchStatus();
110
+ await this.fetchConnectionInfo();
111
+ }
112
+ catch (error) {
113
+ const message = error instanceof Error ? error.message : 'Unknown error';
114
+ alert(`Action failed: ${message}`);
115
+ }
116
+ finally {
117
+ this.setState({ actionInProgress: false });
118
+ }
119
+ };
120
+ this.handleRestart = async () => {
121
+ this.setState({ actionInProgress: true });
122
+ try {
123
+ await this.props.electron?.ipcRenderer?.invoke('mcp:restart');
124
+ await this.fetchStatus();
125
+ await this.fetchConnectionInfo();
126
+ }
127
+ catch (error) {
128
+ const message = error instanceof Error ? error.message : 'Unknown error';
129
+ alert(`Restart failed: ${message}`);
130
+ }
131
+ finally {
132
+ this.setState({ actionInProgress: false });
133
+ }
134
+ };
135
+ this.handleRegenerateToken = async () => {
136
+ if (!confirm('Regenerate authentication token? You will need to update your AI tool configuration.')) {
137
+ return;
138
+ }
139
+ this.setState({ actionInProgress: true });
140
+ try {
141
+ const result = (await this.props.electron?.ipcRenderer?.invoke('mcp:regenerateToken'));
142
+ if (result?.success) {
143
+ await this.fetchConnectionInfo();
144
+ alert('Token regenerated successfully. Please update your AI tool configuration.');
145
+ }
146
+ else {
147
+ alert(`Failed to regenerate token: ${result?.error}`);
148
+ }
149
+ }
150
+ catch (error) {
151
+ const message = error instanceof Error ? error.message : 'Unknown error';
152
+ alert(`Failed to regenerate token: ${message}`);
153
+ }
154
+ finally {
155
+ this.setState({ actionInProgress: false });
156
+ }
157
+ };
158
+ }
159
+ componentDidMount() {
160
+ this.init();
161
+ this.statusInterval = setInterval(() => this.fetchStatus(), 5000);
162
+ this.themeCleanup = (0, theme_1.onThemeChange)(() => {
163
+ this.setState({ colors: (0, theme_1.getThemeColors)() });
164
+ });
165
+ }
166
+ componentWillUnmount() {
167
+ if (this.statusInterval) {
168
+ clearInterval(this.statusInterval);
169
+ }
170
+ if (this.themeCleanup) {
171
+ this.themeCleanup();
172
+ }
173
+ }
174
+ async init() {
175
+ await Promise.all([this.fetchStatus(), this.fetchConnectionInfo()]);
176
+ this.setState({ loading: false });
177
+ }
178
+ getStatusColor() {
179
+ const { status, colors } = this.state;
180
+ if (!status)
181
+ return colors.textMuted;
182
+ if (status.running)
183
+ return colors.successText;
184
+ return colors.errorText;
185
+ }
186
+ getStatusText() {
187
+ const { loading, status } = this.state;
188
+ if (loading)
189
+ return 'Loading...';
190
+ if (!status)
191
+ return 'Unknown';
192
+ if (status.running)
193
+ return 'Running';
194
+ return 'Stopped';
195
+ }
196
+ formatUptime(seconds) {
197
+ if (seconds < 60)
198
+ return `${Math.floor(seconds)}s`;
199
+ if (seconds < 3600)
200
+ return `${Math.floor(seconds / 60)}m`;
201
+ return `${Math.floor(seconds / 3600)}h ${Math.floor((seconds % 3600) / 60)}m`;
202
+ }
203
+ getTabStyle(isActive) {
204
+ const { colors } = this.state;
205
+ return {
206
+ padding: '8px 16px',
207
+ border: 'none',
208
+ borderBottom: isActive ? `2px solid ${colors.primary}` : '2px solid transparent',
209
+ backgroundColor: 'transparent',
210
+ color: isActive ? colors.primary : colors.textSecondary,
211
+ cursor: 'pointer',
212
+ fontSize: '14px',
213
+ fontWeight: isActive ? 600 : 400,
214
+ };
215
+ }
216
+ getButtonStyle(bgColor, disabled) {
217
+ return {
218
+ padding: '8px 16px',
219
+ backgroundColor: bgColor,
220
+ color: 'white',
221
+ border: 'none',
222
+ borderRadius: '4px',
223
+ cursor: disabled ? 'not-allowed' : 'pointer',
224
+ fontSize: '13px',
225
+ opacity: disabled ? 0.5 : 1,
226
+ };
227
+ }
228
+ renderStatusTab() {
229
+ const { status, connectionInfo, actionInProgress, colors } = this.state;
230
+ return (react_1.default.createElement(react_1.default.Fragment, null,
231
+ react_1.default.createElement("div", { style: { marginBottom: '24px' } },
232
+ react_1.default.createElement("h3", { style: {
233
+ fontSize: '14px',
234
+ fontWeight: 600,
235
+ marginBottom: '12px',
236
+ color: colors.textPrimary,
237
+ } }, "Server Status"),
238
+ react_1.default.createElement("div", { style: {
239
+ display: 'flex',
240
+ alignItems: 'center',
241
+ gap: '12px',
242
+ padding: '12px',
243
+ backgroundColor: colors.panelBgSecondary,
244
+ borderRadius: '6px',
245
+ } },
246
+ react_1.default.createElement("span", { style: {
247
+ width: '12px',
248
+ height: '12px',
249
+ borderRadius: '50%',
250
+ backgroundColor: this.getStatusColor(),
251
+ } }),
252
+ react_1.default.createElement("span", { style: { fontWeight: 500, color: colors.textPrimary } }, this.getStatusText()),
253
+ status?.running && (react_1.default.createElement(react_1.default.Fragment, null,
254
+ react_1.default.createElement("span", { style: { color: colors.textSecondary } }, "|"),
255
+ react_1.default.createElement("span", { style: { color: colors.textSecondary } },
256
+ "Port: ",
257
+ status.port),
258
+ react_1.default.createElement("span", { style: { color: colors.textSecondary } }, "|"),
259
+ react_1.default.createElement("span", { style: { color: colors.textSecondary } },
260
+ "Uptime: ",
261
+ this.formatUptime(status.uptime)))))),
262
+ react_1.default.createElement("div", { style: { marginBottom: '24px' } },
263
+ react_1.default.createElement("h3", { style: {
264
+ fontSize: '14px',
265
+ fontWeight: 600,
266
+ marginBottom: '12px',
267
+ color: colors.textPrimary,
268
+ } }, "Server Controls"),
269
+ react_1.default.createElement("div", { style: { display: 'flex', gap: '12px', flexWrap: 'wrap' } },
270
+ react_1.default.createElement("button", { onClick: this.handleStartStop, disabled: actionInProgress, style: this.getButtonStyle(status?.running ? colors.errorText : colors.successText, actionInProgress) }, status?.running ? 'Stop Server' : 'Start Server'),
271
+ react_1.default.createElement("button", { onClick: this.handleRestart, disabled: actionInProgress || !status?.running, style: this.getButtonStyle('#6c757d', actionInProgress || !status?.running) }, "Restart Server"),
272
+ react_1.default.createElement("button", { onClick: this.handleTestConnection, disabled: !status?.running, style: this.getButtonStyle(status?.running ? '#17a2b8' : colors.textMuted, !status?.running) }, "Test Connection"))),
273
+ connectionInfo && (react_1.default.createElement("div", { style: { marginBottom: '24px' } },
274
+ react_1.default.createElement("h3", { style: {
275
+ fontSize: '14px',
276
+ fontWeight: 600,
277
+ marginBottom: '12px',
278
+ color: colors.textPrimary,
279
+ } }, "Connection Info"),
280
+ react_1.default.createElement("div", { style: {
281
+ padding: '12px',
282
+ backgroundColor: colors.panelBgSecondary,
283
+ borderRadius: '6px',
284
+ fontFamily: 'monospace',
285
+ fontSize: '12px',
286
+ color: colors.textPrimary,
287
+ } },
288
+ react_1.default.createElement("div", { style: { marginBottom: '8px' } },
289
+ react_1.default.createElement("strong", null, "URL:"),
290
+ " ",
291
+ connectionInfo.url),
292
+ react_1.default.createElement("div", { style: { marginBottom: '8px' } },
293
+ react_1.default.createElement("strong", null, "stdio script:"),
294
+ " bin/mcp-stdio.js"),
295
+ react_1.default.createElement("div", { style: { marginBottom: '8px' } },
296
+ react_1.default.createElement("strong", null, "Version:"),
297
+ " ",
298
+ connectionInfo.version),
299
+ react_1.default.createElement("div", null,
300
+ react_1.default.createElement("strong", null, "Tools:"),
301
+ " ",
302
+ connectionInfo.tools.join(', '))))),
303
+ react_1.default.createElement("div", { style: { marginBottom: '24px' } },
304
+ react_1.default.createElement("h3", { style: {
305
+ fontSize: '14px',
306
+ fontWeight: 600,
307
+ marginBottom: '12px',
308
+ color: colors.textPrimary,
309
+ } }, "Security"),
310
+ react_1.default.createElement("div", { style: { display: 'flex', gap: '12px', flexWrap: 'wrap' } },
311
+ react_1.default.createElement("button", { onClick: this.handleRegenerateToken, disabled: actionInProgress || !status?.running, style: {
312
+ padding: '8px 16px',
313
+ backgroundColor: '#ffc107',
314
+ color: '#212529',
315
+ border: 'none',
316
+ borderRadius: '4px',
317
+ cursor: actionInProgress || !status?.running ? 'not-allowed' : 'pointer',
318
+ fontSize: '13px',
319
+ opacity: actionInProgress || !status?.running ? 0.5 : 1,
320
+ } }, "Regenerate Token")),
321
+ react_1.default.createElement("p", { style: { fontSize: '12px', color: colors.textSecondary, marginTop: '8px' } }, "Regenerating the token will require you to update your AI tool configuration."))));
322
+ }
323
+ renderSetupTab() {
324
+ const { connectionInfo, copied, colors } = this.state;
325
+ return (react_1.default.createElement(react_1.default.Fragment, null,
326
+ react_1.default.createElement("div", { style: { marginBottom: '24px' } },
327
+ react_1.default.createElement("h3", { style: {
328
+ fontSize: '14px',
329
+ fontWeight: 600,
330
+ marginBottom: '12px',
331
+ color: colors.textPrimary,
332
+ } }, "Claude Code (Recommended)"),
333
+ react_1.default.createElement("div", { style: {
334
+ padding: '16px',
335
+ backgroundColor: colors.panelBgSecondary,
336
+ borderRadius: '6px',
337
+ } },
338
+ react_1.default.createElement("p", { style: { margin: '0 0 12px 0', fontSize: '13px', color: colors.textPrimary } },
339
+ "Add the following to your",
340
+ ' ',
341
+ react_1.default.createElement("code", { style: {
342
+ backgroundColor: colors.panelBgCode,
343
+ padding: '2px 4px',
344
+ borderRadius: '3px',
345
+ color: '#f8f8f2',
346
+ } }, "~/.claude.json"),
347
+ ' ',
348
+ "file:"),
349
+ react_1.default.createElement("pre", { style: {
350
+ backgroundColor: colors.panelBgCode,
351
+ color: '#f8f8f2',
352
+ padding: '12px',
353
+ borderRadius: '4px',
354
+ fontSize: '11px',
355
+ overflow: 'auto',
356
+ margin: '0 0 12px 0',
357
+ } }, `{
358
+ "mcpServers": {
359
+ "local": {
360
+ "type": "stdio",
361
+ "command": "node",
362
+ "args": ["/path/to/local-addon-mcp-server/bin/mcp-stdio.js"]
363
+ }
364
+ }
365
+ }`),
366
+ react_1.default.createElement("button", { onClick: this.handleCopyStdioConfig, style: this.getButtonStyle(colors.primary) }, copied ? 'Copied!' : 'Copy Config'))),
367
+ react_1.default.createElement("div", { style: { marginBottom: '24px' } },
368
+ react_1.default.createElement("h3", { style: {
369
+ fontSize: '14px',
370
+ fontWeight: 600,
371
+ marginBottom: '12px',
372
+ color: colors.textPrimary,
373
+ } }, "Claude.ai / ChatGPT / Other AI Tools"),
374
+ react_1.default.createElement("div", { style: {
375
+ padding: '16px',
376
+ backgroundColor: colors.panelBgSecondary,
377
+ borderRadius: '6px',
378
+ } },
379
+ react_1.default.createElement("p", { style: { margin: '0 0 12px 0', fontSize: '13px', color: colors.textPrimary } }, "For tools that support SSE transport, use this configuration:"),
380
+ react_1.default.createElement("pre", { style: {
381
+ backgroundColor: colors.panelBgCode,
382
+ color: '#f8f8f2',
383
+ padding: '12px',
384
+ borderRadius: '4px',
385
+ fontSize: '11px',
386
+ overflow: 'auto',
387
+ margin: '0 0 12px 0',
388
+ } }, connectionInfo
389
+ ? `{
390
+ "mcpServers": {
391
+ "local": {
392
+ "url": "${connectionInfo.url}/mcp/sse",
393
+ "transport": "sse",
394
+ "headers": {
395
+ "Authorization": "Bearer ${connectionInfo.authToken.substring(0, 20)}..."
396
+ }
397
+ }
398
+ }
399
+ }`
400
+ : 'Server not running'),
401
+ react_1.default.createElement("button", { onClick: this.handleCopySseConfig, disabled: !connectionInfo, style: this.getButtonStyle(connectionInfo ? colors.primary : colors.textMuted, !connectionInfo) }, copied ? 'Copied!' : 'Copy SSE Config'))),
402
+ react_1.default.createElement("div", { style: { marginBottom: '24px' } },
403
+ react_1.default.createElement("h3", { style: {
404
+ fontSize: '14px',
405
+ fontWeight: 600,
406
+ marginBottom: '12px',
407
+ color: colors.textPrimary,
408
+ } }, "Example Commands"),
409
+ react_1.default.createElement("div", { style: {
410
+ padding: '16px',
411
+ backgroundColor: colors.infoBg,
412
+ borderRadius: '6px',
413
+ border: `1px solid ${colors.infoBorder}`,
414
+ } },
415
+ react_1.default.createElement("p", { style: {
416
+ margin: '0 0 8px 0',
417
+ fontSize: '13px',
418
+ fontWeight: 500,
419
+ color: colors.infoText,
420
+ } }, "Try saying to your AI assistant:"),
421
+ react_1.default.createElement("ul", { style: { margin: 0, paddingLeft: '20px', fontSize: '13px', color: colors.infoText } },
422
+ react_1.default.createElement("li", null, "\"List my Local sites\""),
423
+ react_1.default.createElement("li", null, "\"Start the blog site\""),
424
+ react_1.default.createElement("li", null, "\"Create a new site called test-project\""),
425
+ react_1.default.createElement("li", null, "\"Run wp plugin list on my-site\""),
426
+ react_1.default.createElement("li", null, "\"Stop all running sites\""),
427
+ react_1.default.createElement("li", null, "\"What plugins are installed on my-site?\""))))));
428
+ }
429
+ render() {
430
+ const { activeTab, colors } = this.state;
431
+ return (react_1.default.createElement("div", { style: { padding: '20px', color: colors.textPrimary } },
432
+ react_1.default.createElement("h2", { style: {
433
+ marginBottom: '20px',
434
+ fontSize: '18px',
435
+ fontWeight: 600,
436
+ color: colors.textPrimary,
437
+ } }, "MCP Server"),
438
+ react_1.default.createElement("p", { style: { color: colors.textSecondary, marginBottom: '24px' } }, "The MCP (Model Context Protocol) server enables AI tools like Claude Code to control your Local sites."),
439
+ react_1.default.createElement("div", { style: { borderBottom: `1px solid ${colors.border}`, marginBottom: '24px' } },
440
+ react_1.default.createElement("button", { style: this.getTabStyle(activeTab === 'status'), onClick: () => this.setState({ activeTab: 'status' }) }, "Status & Controls"),
441
+ react_1.default.createElement("button", { style: this.getTabStyle(activeTab === 'setup'), onClick: () => this.setState({ activeTab: 'setup' }) }, "AI Tool Setup")),
442
+ activeTab === 'status' && this.renderStatusTab(),
443
+ activeTab === 'setup' && this.renderSetupTab()));
444
+ }
445
+ }
446
+ // Export as a constructor function that Local can instantiate
447
+ module.exports = function McpServerRenderer(context) {
448
+ // CLI-only mode - preferences panel disabled
449
+ // To enable MCP preferences UI, uncomment the following:
450
+ /*
451
+ const { hooks, electron } = context as {
452
+ hooks: { addFilter: (name: string, callback: (items: unknown[]) => unknown[]) => void };
453
+ electron: McpPreferencesPanelProps['electron'];
454
+ };
455
+
456
+ console.log('[MCP Server] Renderer loading...');
457
+
458
+ // Add MCP Server to preferences menu
459
+ hooks.addFilter('preferencesMenuItems', (menuItems: unknown[]) => {
460
+ console.log('[MCP Server] Adding MCP Server to preferences');
461
+
462
+ (menuItems as Array<Record<string, unknown>>).push({
463
+ path: 'mcp-server',
464
+ displayName: 'MCP Server',
465
+ sections: () => <McpPreferencesPanel electron={electron} />,
466
+ onApply: () => {
467
+ // No apply action needed for read-only display
468
+ },
469
+ });
470
+
471
+ return menuItems;
472
+ });
473
+
474
+ console.log('[MCP Server] Renderer setup complete');
475
+ */
476
+ // Silence unused variable warnings
477
+ void context;
478
+ };
479
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVuZGVyZXIvaW5kZXgudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7R0FLRzs7Ozs7QUFFSCxrREFBMEI7QUFDMUIsMkNBQTZFO0FBb0M3RSx3RUFBd0U7QUFDeEUsTUFBTSxtQkFBb0IsU0FBUSxlQUFLLENBQUMsU0FHdkM7SUFIRDs7UUFPRSxVQUFLLEdBQTZCO1lBQ2hDLE1BQU0sRUFBRSxJQUFJO1lBQ1osY0FBYyxFQUFFLElBQUk7WUFDcEIsT0FBTyxFQUFFLElBQUk7WUFDYixNQUFNLEVBQUUsS0FBSztZQUNiLGdCQUFnQixFQUFFLEtBQUs7WUFDdkIsU0FBUyxFQUFFLFFBQVE7WUFDbkIsTUFBTSxFQUFFLElBQUEsc0JBQWMsR0FBRTtTQUN6QixDQUFDO1FBd0JNLGdCQUFXLEdBQUcsS0FBSyxJQUFtQixFQUFFO1lBQzlDLElBQUksQ0FBQztnQkFDSCxNQUFNLE1BQU0sR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FFbEUsQ0FBQztnQkFDZCxJQUFJLE1BQU0sRUFBRSxDQUFDO29CQUNYLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztnQkFDcEMsQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsNkJBQTZCLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDdEQsQ0FBQztRQUNILENBQUMsQ0FBQztRQUVNLHdCQUFtQixHQUFHLEtBQUssSUFBbUIsRUFBRTtZQUN0RCxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxNQUFNLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLFdBQVcsRUFBRSxNQUFNLENBQUMsdUJBQXVC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LGlCQUdFO1lBRUwscUNBQUcsS0FBSyxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxhQUFhLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSw2R0FHM0Q7WUFHSix1Q0FBSyxLQUFLLEVBQUUsRUFBRSxZQUFZLEVBQUUsYUFBYSxNQUFNLENBQUMsTUFBTSxFQUFFLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRTtnQkFDOUUsMENBQ0UsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxLQUFLLFFBQVEsQ0FBQyxFQUMvQyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsQ0FBQyx3QkFHOUM7Z0JBQ1QsMENBQ0UsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxLQUFLLE9BQU8sQ0FBQyxFQUM5QyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxvQkFHN0MsQ0FDTDtZQUVMLFNBQVMsS0FBSyxRQUFRLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUNoRCxTQUFTLEtBQUssT0FBTyxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FDM0MsQ0FDUCxDQUFDO0lBQ0osQ0FBQztDQUNGO0FBRUQsOERBQThEO0FBQzlELE1BQU0sQ0FBQyxPQUFPLEdBQUcsU0FBUyxpQkFBaUIsQ0FBQyxPQUE4QztJQUN4Riw2Q0FBNkM7SUFDN0MseURBQXlEO0lBQ3pEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O01BeUJFO0lBRUYsbUNBQW1DO0lBQ25DLEtBQUssT0FBTyxDQUFDO0FBQ2YsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNQ1AgU2VydmVyIEFkZG9uIC0gUmVuZGVyZXIgRW50cnkgUG9pbnRcbiAqIEFkZHMgTUNQIFNlcnZlciBwcmVmZXJlbmNlcyBwYW5lbCB0byBMb2NhbFxuICpcbiAqIFVzZXMgY2xhc3MgY29tcG9uZW50cyBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIExvY2FsJ3MgRWxlY3Ryb24gZW52aXJvbm1lbnQuXG4gKi9cblxuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IGdldFRoZW1lQ29sb3JzLCBvblRoZW1lQ2hhbmdlLCBUaGVtZUNvbG9ycyB9IGZyb20gJy4uL2NvbW1vbi90aGVtZSc7XG5cbi8vIFR5cGUgZGVmaW5pdGlvbnNcbmludGVyZmFjZSBNY3BTdGF0dXMge1xuICBydW5uaW5nOiBib29sZWFuO1xuICBwb3J0OiBudW1iZXI7XG4gIHVwdGltZTogbnVtYmVyO1xuICBlcnJvcj86IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIENvbm5lY3Rpb25JbmZvIHtcbiAgdXJsOiBzdHJpbmc7XG4gIGF1dGhUb2tlbjogc3RyaW5nO1xuICBwb3J0OiBudW1iZXI7XG4gIHZlcnNpb246IHN0cmluZztcbiAgdG9vbHM6IHN0cmluZ1tdO1xufVxuXG5pbnRlcmZhY2UgTWNwUHJlZmVyZW5jZXNQYW5lbFByb3BzIHtcbiAgZWxlY3Ryb246IHtcbiAgICBpcGNSZW5kZXJlcj86IHtcbiAgICAgIGludm9rZTogKGNoYW5uZWw6IHN0cmluZywgLi4uYXJnczogdW5rbm93bltdKSA9PiBQcm9taXNlPHVua25vd24+O1xuICAgIH07XG4gIH07XG59XG5cbmludGVyZmFjZSBNY3BQcmVmZXJlbmNlc1BhbmVsU3RhdGUge1xuICBzdGF0dXM6IE1jcFN0YXR1cyB8IG51bGw7XG4gIGNvbm5lY3Rpb25JbmZvOiBDb25uZWN0aW9uSW5mbyB8IG51bGw7XG4gIGxvYWRpbmc6IGJvb2xlYW47XG4gIGNvcGllZDogYm9vbGVhbjtcbiAgYWN0aW9uSW5Qcm9ncmVzczogYm9vbGVhbjtcbiAgYWN0aXZlVGFiOiAnc3RhdHVzJyB8ICdzZXR1cCc7XG4gIGNvbG9yczogVGhlbWVDb2xvcnM7XG59XG5cbi8vIE1DUCBQcmVmZXJlbmNlcyBQYW5lbCBDb21wb25lbnQgKENsYXNzLWJhc2VkIGZvciBMb2NhbCBjb21wYXRpYmlsaXR5KVxuY2xhc3MgTWNwUHJlZmVyZW5jZXNQYW5lbCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudDxcbiAgTWNwUHJlZmVyZW5jZXNQYW5lbFByb3BzLFxuICBNY3BQcmVmZXJlbmNlc1BhbmVsU3RhdGVcbj4ge1xuICBwcml2YXRlIHN0YXR1c0ludGVydmFsPzogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0SW50ZXJ2YWw+O1xuICBwcml2YXRlIHRoZW1lQ2xlYW51cD86ICgpID0+IHZvaWQ7XG5cbiAgc3RhdGU6IE1jcFByZWZlcmVuY2VzUGFuZWxTdGF0ZSA9IHtcbiAgICBzdGF0dXM6IG51bGwsXG4gICAgY29ubmVjdGlvbkluZm86IG51bGwsXG4gICAgbG9hZGluZzogdHJ1ZSxcbiAgICBjb3BpZWQ6IGZhbHNlLFxuICAgIGFjdGlvbkluUHJvZ3Jlc3M6IGZhbHNlLFxuICAgIGFjdGl2ZVRhYjogJ3N0YXR1cycsXG4gICAgY29sb3JzOiBnZXRUaGVtZUNvbG9ycygpLFxuICB9O1xuXG4gIGNvbXBvbmVudERpZE1vdW50KCk6IHZvaWQge1xuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMuc3RhdHVzSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB0aGlzLmZldGNoU3RhdHVzKCksIDUwMDApO1xuICAgIHRoaXMudGhlbWVDbGVhbnVwID0gb25UaGVtZUNoYW5nZSgoKSA9PiB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgY29sb3JzOiBnZXRUaGVtZUNvbG9ycygpIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgY29tcG9uZW50V2lsbFVubW91bnQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc3RhdHVzSW50ZXJ2YWwpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5zdGF0dXNJbnRlcnZhbCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnRoZW1lQ2xlYW51cCkge1xuICAgICAgdGhpcy50aGVtZUNsZWFudXAoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGluaXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoW3RoaXMuZmV0Y2hTdGF0dXMoKSwgdGhpcy5mZXRjaENvbm5lY3Rpb25JbmZvKCldKTtcbiAgICB0aGlzLnNldFN0YXRlKHsgbG9hZGluZzogZmFsc2UgfSk7XG4gIH1cblxuICBwcml2YXRlIGZldGNoU3RhdHVzID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSAoYXdhaXQgdGhpcy5wcm9wcy5lbGVjdHJvbj8uaXBjUmVuZGVyZXI/Lmludm9rZSgnbWNwOmdldFN0YXR1cycpKSBhc1xuICAgICAgICB8IE1jcFN0YXR1c1xuICAgICAgICB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHN0YXR1czogcmVzdWx0IH0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gZmV0Y2ggTUNQIHN0YXR1czonLCBlcnJvcik7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgZmV0Y2hDb25uZWN0aW9uSW5mbyA9IGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gKGF3YWl0IHRoaXMucHJvcHMuZWxlY3Ryb24/LmlwY1JlbmRlcmVyPy5pbnZva2UoJ21jcDpnZXRDb25uZWN0aW9uSW5mbycpKSBhc1xuICAgICAgICB8IENvbm5lY3Rpb25JbmZvXG4gICAgICAgIHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgY29ubmVjdGlvbkluZm86IHJlc3VsdCB9KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGZldGNoIGNvbm5lY3Rpb24gaW5mbzonLCBlcnJvcik7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQ29weVN0ZGlvQ29uZmlnID0gKCk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIG1jcFNlcnZlcnM6IHtcbiAgICAgICAgbG9jYWw6IHtcbiAgICAgICAgICB0eXBlOiAnc3RkaW8nLFxuICAgICAgICAgIGNvbW1hbmQ6ICdub2RlJyxcbiAgICAgICAgICBhcmdzOiBbJy9wYXRoL3RvL2xvY2FsLWFkZG9uLW1jcC1zZXJ2ZXIvYmluL21jcC1zdGRpby5qcyddLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICAgIG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KEpTT04uc3RyaW5naWZ5KGNvbmZpZywgbnVsbCwgMikpO1xuICAgIHRoaXMuc2V0U3RhdGUoeyBjb3BpZWQ6IHRydWUgfSk7XG4gICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnNldFN0YXRlKHsgY29waWVkOiBmYWxzZSB9KSwgMjAwMCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVDb3B5U3NlQ29uZmlnID0gKCk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IHsgY29ubmVjdGlvbkluZm8gfSA9IHRoaXMuc3RhdGU7XG4gICAgaWYgKGNvbm5lY3Rpb25JbmZvKSB7XG4gICAgICBjb25zdCBjb25maWcgPSB7XG4gICAgICAgIG1jcFNlcnZlcnM6IHtcbiAgICAgICAgICBsb2NhbDoge1xuICAgICAgICAgICAgdXJsOiBgJHtjb25uZWN0aW9uSW5mby51cmx9L21jcC9zc2VgLFxuICAgICAgICAgICAgdHJhbnNwb3J0OiAnc3NlJyxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke2Nvbm5lY3Rpb25JbmZvLmF1dGhUb2tlbn1gLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KEpTT04uc3RyaW5naWZ5KGNvbmZpZywgbnVsbCwgMikpO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNvcGllZDogdHJ1ZSB9KTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zZXRTdGF0ZSh7IGNvcGllZDogZmFsc2UgfSksIDIwMDApO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZVRlc3RDb25uZWN0aW9uID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGNvbnN0IHsgY29ubmVjdGlvbkluZm8gfSA9IHRoaXMuc3RhdGU7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYGh0dHA6Ly8xMjcuMC4wLjE6JHtjb25uZWN0aW9uSW5mbz8ucG9ydH0vaGVhbHRoYCk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgaWYgKGRhdGEuc3RhdHVzID09PSAnb2snKSB7XG4gICAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIHN1Y2Nlc3NmdWwhIE1DUCBzZXJ2ZXIgaXMgaGVhbHRoeS4nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGZhaWxlZDogU2VydmVyIHJldHVybmVkIHVuZXhwZWN0ZWQgcmVzcG9uc2UnKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogJ1Vua25vd24gZXJyb3InO1xuICAgICAgYWxlcnQoYENvbm5lY3Rpb24gZmFpbGVkOiAke21lc3NhZ2V9YCk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlU3RhcnRTdG9wID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGNvbnN0IHsgc3RhdHVzIH0gPSB0aGlzLnN0YXRlO1xuICAgIHRoaXMuc2V0U3RhdGUoeyBhY3Rpb25JblByb2dyZXNzOiB0cnVlIH0pO1xuICAgIHRyeSB7XG4gICAgICBpZiAoc3RhdHVzPy5ydW5uaW5nKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucHJvcHMuZWxlY3Ryb24/LmlwY1JlbmRlcmVyPy5pbnZva2UoJ21jcDpzdG9wJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhd2FpdCB0aGlzLnByb3BzLmVsZWN0cm9uPy5pcGNSZW5kZXJlcj8uaW52b2tlKCdtY3A6c3RhcnQnKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHRoaXMuZmV0Y2hTdGF0dXMoKTtcbiAgICAgIGF3YWl0IHRoaXMuZmV0Y2hDb25uZWN0aW9uSW5mbygpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiAnVW5rbm93biBlcnJvcic7XG4gICAgICBhbGVydChgQWN0aW9uIGZhaWxlZDogJHttZXNzYWdlfWApO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgYWN0aW9uSW5Qcm9ncmVzczogZmFsc2UgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlUmVzdGFydCA9IGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKHsgYWN0aW9uSW5Qcm9ncmVzczogdHJ1ZSB9KTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5wcm9wcy5lbGVjdHJvbj8uaXBjUmVuZGVyZXI/Lmludm9rZSgnbWNwOnJlc3RhcnQnKTtcbiAgICAgIGF3YWl0IHRoaXMuZmV0Y2hTdGF0dXMoKTtcbiAgICAgIGF3YWl0IHRoaXMuZmV0Y2hDb25uZWN0aW9uSW5mbygpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiAnVW5rbm93biBlcnJvcic7XG4gICAgICBhbGVydChgUmVzdGFydCBmYWlsZWQ6ICR7bWVzc2FnZX1gKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGFjdGlvbkluUHJvZ3Jlc3M6IGZhbHNlIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZVJlZ2VuZXJhdGVUb2tlbiA9IGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBpZiAoXG4gICAgICAhY29uZmlybShcbiAgICAgICAgJ1JlZ2VuZXJhdGUgYXV0aGVudGljYXRpb24gdG9rZW4/IFlvdSB3aWxsIG5lZWQgdG8gdXBkYXRlIHlvdXIgQUkgdG9vbCBjb25maWd1cmF0aW9uLidcbiAgICAgIClcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zZXRTdGF0ZSh7IGFjdGlvbkluUHJvZ3Jlc3M6IHRydWUgfSk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IChhd2FpdCB0aGlzLnByb3BzLmVsZWN0cm9uPy5pcGNSZW5kZXJlcj8uaW52b2tlKCdtY3A6cmVnZW5lcmF0ZVRva2VuJykpIGFzIHtcbiAgICAgICAgc3VjY2Vzcz86IGJvb2xlYW47XG4gICAgICAgIGVycm9yPzogc3RyaW5nO1xuICAgICAgfTtcbiAgICAgIGlmIChyZXN1bHQ/LnN1Y2Nlc3MpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5mZXRjaENvbm5lY3Rpb25JbmZvKCk7XG4gICAgICAgIGFsZXJ0KCdUb2tlbiByZWdlbmVyYXRlZCBzdWNjZXNzZnVsbHkuIFBsZWFzZSB1cGRhdGUgeW91ciBBSSB0b29sIGNvbmZpZ3VyYXRpb24uJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhbGVydChgRmFpbGVkIHRvIHJlZ2VuZXJhdGUgdG9rZW46ICR7cmVzdWx0Py5lcnJvcn1gKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogJ1Vua25vd24gZXJyb3InO1xuICAgICAgYWxlcnQoYEZhaWxlZCB0byByZWdlbmVyYXRlIHRva2VuOiAke21lc3NhZ2V9YCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBhY3Rpb25JblByb2dyZXNzOiBmYWxzZSB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBnZXRTdGF0dXNDb2xvcigpOiBzdHJpbmcge1xuICAgIGNvbnN0IHsgc3RhdHVzLCBjb2xvcnMgfSA9IHRoaXMuc3RhdGU7XG4gICAgaWYgKCFzdGF0dXMpIHJldHVybiBjb2xvcnMudGV4dE11dGVkO1xuICAgIGlmIChzdGF0dXMucnVubmluZykgcmV0dXJuIGNvbG9ycy5zdWNjZXNzVGV4dDtcbiAgICByZXR1cm4gY29sb3JzLmVycm9yVGV4dDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U3RhdHVzVGV4dCgpOiBzdHJpbmcge1xuICAgIGNvbnN0IHsgbG9hZGluZywgc3RhdHVzIH0gPSB0aGlzLnN0YXRlO1xuICAgIGlmIChsb2FkaW5nKSByZXR1cm4gJ0xvYWRpbmcuLi4nO1xuICAgIGlmICghc3RhdHVzKSByZXR1cm4gJ1Vua25vd24nO1xuICAgIGlmIChzdGF0dXMucnVubmluZykgcmV0dXJuICdSdW5uaW5nJztcbiAgICByZXR1cm4gJ1N0b3BwZWQnO1xuICB9XG5cbiAgcHJpdmF0ZSBmb3JtYXRVcHRpbWUoc2Vjb25kczogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBpZiAoc2Vjb25kcyA8IDYwKSByZXR1cm4gYCR7TWF0aC5mbG9vcihzZWNvbmRzKX1zYDtcbiAgICBpZiAoc2Vjb25kcyA8IDM2MDApIHJldHVybiBgJHtNYXRoLmZsb29yKHNlY29uZHMgLyA2MCl9bWA7XG4gICAgcmV0dXJuIGAke01hdGguZmxvb3Ioc2Vjb25kcyAvIDM2MDApfWggJHtNYXRoLmZsb29yKChzZWNvbmRzICUgMzYwMCkgLyA2MCl9bWA7XG4gIH1cblxuICBwcml2YXRlIGdldFRhYlN0eWxlKGlzQWN0aXZlOiBib29sZWFuKTogUmVhY3QuQ1NTUHJvcGVydGllcyB7XG4gICAgY29uc3QgeyBjb2xvcnMgfSA9IHRoaXMuc3RhdGU7XG4gICAgcmV0dXJuIHtcbiAgICAgIHBhZGRpbmc6ICc4cHggMTZweCcsXG4gICAgICBib3JkZXI6ICdub25lJyxcbiAgICAgIGJvcmRlckJvdHRvbTogaXNBY3RpdmUgPyBgMnB4IHNvbGlkICR7Y29sb3JzLnByaW1hcnl9YCA6ICcycHggc29saWQgdHJhbnNwYXJlbnQnLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiAndHJhbnNwYXJlbnQnLFxuICAgICAgY29sb3I6IGlzQWN0aXZlID8gY29sb3JzLnByaW1hcnkgOiBjb2xvcnMudGV4dFNlY29uZGFyeSxcbiAgICAgIGN1cnNvcjogJ3BvaW50ZXInLFxuICAgICAgZm9udFNpemU6ICcxNHB4JyxcbiAgICAgIGZvbnRXZWlnaHQ6IGlzQWN0aXZlID8gNjAwIDogNDAwLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGdldEJ1dHRvblN0eWxlKGJnQ29sb3I6IHN0cmluZywgZGlzYWJsZWQ/OiBib29sZWFuKTogUmVhY3QuQ1NTUHJvcGVydGllcyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHBhZGRpbmc6ICc4cHggMTZweCcsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IGJnQ29sb3IsXG4gICAgICBjb2xvcjogJ3doaXRlJyxcbiAgICAgIGJvcmRlcjogJ25vbmUnLFxuICAgICAgYm9yZGVyUmFkaXVzOiAnNHB4JyxcbiAgICAgIGN1cnNvcjogZGlzYWJsZWQgPyAnbm90LWFsbG93ZWQnIDogJ3BvaW50ZXInLFxuICAgICAgZm9udFNpemU6ICcxM3B4JyxcbiAgICAgIG9wYWNpdHk6IGRpc2FibGVkID8gMC41IDogMSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJTdGF0dXNUYWIoKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgICBjb25zdCB7IHN0YXR1cywgY29ubmVjdGlvbkluZm8sIGFjdGlvbkluUHJvZ3Jlc3MsIGNvbG9ycyB9ID0gdGhpcy5zdGF0ZTtcblxuICAgIHJldHVybiAoXG4gICAgICA8PlxuICAgICAgICB7LyogU3RhdHVzIFNlY3Rpb24gKi99XG4gICAgICAgIDxkaXYgc3R5bGU9e3sgbWFyZ2luQm90dG9tOiAnMjRweCcgfX0+XG4gICAgICAgICAgPGgzXG4gICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICBmb250U2l6ZTogJzE0cHgnLFxuICAgICAgICAgICAgICBmb250V2VpZ2h0OiA2MDAsXG4gICAgICAgICAgICAgIG1hcmdpbkJvdHRvbTogJzEycHgnLFxuICAgICAgICAgICAgICBjb2xvcjogY29sb3JzLnRleHRQcmltYXJ5LFxuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICBTZXJ2ZXIgU3RhdHVzXG4gICAgICAgICAgPC9oMz5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICBkaXNwbGF5OiAnZmxleCcsXG4gICAgICAgICAgICAgIGFsaWduSXRlbXM6ICdjZW50ZXInLFxuICAgICAgICAgICAgICBnYXA6ICcxMnB4JyxcbiAgICAgICAgICAgICAgcGFkZGluZzogJzEycHgnLFxuICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGNvbG9ycy5wYW5lbEJnU2Vjb25kYXJ5LFxuICAgICAgICAgICAgICBib3JkZXJSYWRpdXM6ICc2cHgnLFxuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICAgIHdpZHRoOiAnMTJweCcsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiAnMTJweCcsXG4gICAgICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnNTAlJyxcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuZ2V0U3RhdHVzQ29sb3IoKSxcbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8c3BhbiBzdHlsZT17eyBmb250V2VpZ2h0OiA1MDAsIGNvbG9yOiBjb2xvcnMudGV4dFByaW1hcnkgfX0+XG4gICAgICAgICAgICAgIHt0aGlzLmdldFN0YXR1c1RleHQoKX1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIHtzdGF0dXM/LnJ1bm5pbmcgJiYgKFxuICAgICAgICAgICAgICA8PlxuICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPXt7IGNvbG9yOiBjb2xvcnMudGV4dFNlY29uZGFyeSB9fT58PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPXt7IGNvbG9yOiBjb2xvcnMudGV4dFNlY29uZGFyeSB9fT5Qb3J0OiB7c3RhdHVzLnBvcnR9PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPXt7IGNvbG9yOiBjb2xvcnMudGV4dFNlY29uZGFyeSB9fT58PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPXt7IGNvbG9yOiBjb2xvcnMudGV4dFNlY29uZGFyeSB9fT5cbiAgICAgICAgICAgICAgICAgIFVwdGltZToge3RoaXMuZm9ybWF0VXB0aW1lKHN0YXR1cy51cHRpbWUpfVxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgPC8+XG4gICAgICAgICAgICApfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICB7LyogU2VydmVyIENvbnRyb2xzICovfVxuICAgICAgICA8ZGl2IHN0eWxlPXt7IG1hcmdpbkJvdHRvbTogJzI0cHgnIH19PlxuICAgICAgICAgIDxoM1xuICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgZm9udFNpemU6ICcxNHB4JyxcbiAgICAgICAgICAgICAgZm9udFdlaWdodDogNjAwLFxuICAgICAgICAgICAgICBtYXJnaW5Cb3R0b206ICcxMnB4JyxcbiAgICAgICAgICAgICAgY29sb3I6IGNvbG9ycy50ZXh0UHJpbWFyeSxcbiAgICAgICAgICAgIH19XG4gICAgICAgICAgPlxuICAgICAgICAgICAgU2VydmVyIENvbnRyb2xzXG4gICAgICAgICAgPC9oMz5cbiAgICAgICAgICA8ZGl2IHN0eWxlPXt7IGRpc3BsYXk6ICdmbGV4JywgZ2FwOiAnMTJweCcsIGZsZXhXcmFwOiAnd3JhcCcgfX0+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMuaGFuZGxlU3RhcnRTdG9wfVxuICAgICAgICAgICAgICBkaXNhYmxlZD17YWN0aW9uSW5Qcm9ncmVzc31cbiAgICAgICAgICAgICAgc3R5bGU9e3RoaXMuZ2V0QnV0dG9uU3R5bGUoXG4gICAgICAgICAgICAgICAgc3RhdHVzPy5ydW5uaW5nID8gY29sb3JzLmVycm9yVGV4dCA6IGNvbG9ycy5zdWNjZXNzVGV4dCxcbiAgICAgICAgICAgICAgICBhY3Rpb25JblByb2dyZXNzXG4gICAgICAgICAgICAgICl9XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHtzdGF0dXM/LnJ1bm5pbmcgPyAnU3RvcCBTZXJ2ZXInIDogJ1N0YXJ0IFNlcnZlcid9XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5oYW5kbGVSZXN0YXJ0fVxuICAgICAgICAgICAgICBkaXNhYmxlZD17YWN0aW9uSW5Qcm9ncmVzcyB8fCAhc3RhdHVzPy5ydW5uaW5nfVxuICAgICAgICAgICAgICBzdHlsZT17dGhpcy5nZXRCdXR0b25TdHlsZSgnIzZjNzU3ZCcsIGFjdGlvbkluUHJvZ3Jlc3MgfHwgIXN0YXR1cz8ucnVubmluZyl9XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIFJlc3RhcnQgU2VydmVyXG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5oYW5kbGVUZXN0Q29ubmVjdGlvbn1cbiAgICAgICAgICAgICAgZGlzYWJsZWQ9eyFzdGF0dXM/LnJ1bm5pbmd9XG4gICAgICAgICAgICAgIHN0eWxlPXt0aGlzLmdldEJ1dHRvblN0eWxlKFxuICAgICAgICAgICAgICAgIHN0YXR1cz8ucnVubmluZyA/ICcjMTdhMmI4JyA6IGNvbG9ycy50ZXh0TXV0ZWQsXG4gICAgICAgICAgICAgICAgIXN0YXR1cz8ucnVubmluZ1xuICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICBUZXN0IENvbm5lY3Rpb25cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICB7LyogQ29ubmVjdGlvbiBJbmZvIFNlY3Rpb24gKi99XG4gICAgICAgIHtjb25uZWN0aW9uSW5mbyAmJiAoXG4gICAgICAgICAgPGRpdiBzdHlsZT17eyBtYXJnaW5Cb3R0b206ICcyNHB4JyB9fT5cbiAgICAgICAgICAgIDxoM1xuICAgICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAnMTRweCcsXG4gICAgICAgICAgICAgICAgZm9udFdlaWdodDogNjAwLFxuICAgICAgICAgICAgICAgIG1hcmdpbkJvdHRvbTogJzEycHgnLFxuICAgICAgICAgICAgICAgIGNvbG9yOiBjb2xvcnMudGV4dFByaW1hcnksXG4gICAgICAgICAgICAgIH19XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIENvbm5lY3Rpb24gSW5mb1xuICAgICAgICAgICAgPC9oMz5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICBwYWRkaW5nOiAnMTJweCcsXG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBjb2xvcnMucGFuZWxCZ1NlY29uZGFyeSxcbiAgICAgICAgICAgICAgICBib3JkZXJSYWRpdXM6ICc2cHgnLFxuICAgICAgICAgICAgICAgIGZvbnRGYW1pbHk6ICdtb25vc3BhY2UnLFxuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAnMTJweCcsXG4gICAgICAgICAgICAgICAgY29sb3I6IGNvbG9ycy50ZXh0UHJpbWFyeSxcbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPGRpdiBzdHlsZT17eyBtYXJnaW5Cb3R0b206ICc4cHgnIH19PlxuICAgICAgICAgICAgICAgIDxzdHJvbmc+VVJMOjwvc3Ryb25nPiB7Y29ubmVjdGlvbkluZm8udXJsfVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBzdHlsZT17eyBtYXJnaW5Cb3R0b206ICc4cHgnIH19PlxuICAgICAgICAgICAgICAgIDxzdHJvbmc+c3RkaW8gc2NyaXB0Ojwvc3Ryb25nPiBiaW4vbWNwLXN0ZGlvLmpzXG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IHN0eWxlPXt7IG1hcmdpbkJvdHRvbTogJzhweCcgfX0+XG4gICAgICAgICAgICAgICAgPHN0cm9uZz5WZXJzaW9uOjwvc3Ryb25nPiB7Y29ubmVjdGlvbkluZm8udmVyc2lvbn1cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPHN0cm9uZz5Ub29sczo8L3N0cm9uZz4ge2Nvbm5lY3Rpb25JbmZvLnRvb2xzLmpvaW4oJywgJyl9XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICl9XG5cbiAgICAgICAgey8qIFNlY3VyaXR5IFNlY3Rpb24gKi99XG4gICAgICAgIDxkaXYgc3R5bGU9e3sgbWFyZ2luQm90dG9tOiAnMjRweCcgfX0+XG4gICAgICAgICAgPGgzXG4gICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICBmb250U2l6ZTogJzE0cHgnLFxuICAgICAgICAgICAgICBmb250V2VpZ2h0OiA2MDAsXG4gICAgICAgICAgICAgIG1hcmdpbkJvdHRvbTogJzEycHgnLFxuICAgICAgICAgICAgICBjb2xvcjogY29sb3JzLnRleHRQcmltYXJ5LFxuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICBTZWN1cml0eVxuICAgICAgICAgIDwvaDM+XG4gICAgICAgICAgPGRpdiBzdHlsZT17eyBkaXNwbGF5OiAnZmxleCcsIGdhcDogJzEycHgnLCBmbGV4V3JhcDogJ3dyYXAnIH19PlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICBvbkNsaWNrPXt0aGlzLmhhbmRsZVJlZ2VuZXJhdGVUb2tlbn1cbiAgICAgICAgICAgICAgZGlzYWJsZWQ9e2FjdGlvbkluUHJvZ3Jlc3MgfHwgIXN0YXR1cz8ucnVubmluZ31cbiAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICBwYWRkaW5nOiAnOHB4IDE2cHgnLFxuICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJyNmZmMxMDcnLFxuICAgICAgICAgICAgICAgIGNvbG9yOiAnIzIxMjUyOScsXG4gICAgICAgICAgICAgICAgYm9yZGVyOiAnbm9uZScsXG4gICAgICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnNHB4JyxcbiAgICAgICAgICAgICAgICBjdXJzb3I6IGFjdGlvbkluUHJvZ3Jlc3MgfHwgIXN0YXR1cz8ucnVubmluZyA/ICdub3QtYWxsb3dlZCcgOiAncG9pbnRlcicsXG4gICAgICAgICAgICAgICAgZm9udFNpemU6ICcxM3B4JyxcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiBhY3Rpb25JblByb2dyZXNzIHx8ICFzdGF0dXM/LnJ1bm5pbmcgPyAwLjUgOiAxLFxuICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICBSZWdlbmVyYXRlIFRva2VuXG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8cCBzdHlsZT17eyBmb250U2l6ZTogJzEycHgnLCBjb2xvcjogY29sb3JzLnRleHRTZWNvbmRhcnksIG1hcmdpblRvcDogJzhweCcgfX0+XG4gICAgICAgICAgICBSZWdlbmVyYXRpbmcgdGhlIHRva2VuIHdpbGwgcmVxdWlyZSB5b3UgdG8gdXBkYXRlIHlvdXIgQUkgdG9vbCBjb25maWd1cmF0aW9uLlxuICAgICAgICAgIDwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8Lz5cbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJTZXR1cFRhYigpOiBSZWFjdC5SZWFjdE5vZGUge1xuICAgIGNvbnN0IHsgY29ubmVjdGlvbkluZm8sIGNvcGllZCwgY29sb3JzIH0gPSB0aGlzLnN0YXRlO1xuXG4gICAgcmV0dXJuIChcbiAgICAgIDw+XG4gICAgICAgIHsvKiBDbGF1ZGUgQ29kZSBTZXR1cCAqL31cbiAgICAgICAgPGRpdiBzdHlsZT17eyBtYXJnaW5Cb3R0b206ICcyNHB4JyB9fT5cbiAgICAgICAgICA8aDNcbiAgICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICAgIGZvbnRTaXplOiAnMTRweCcsXG4gICAgICAgICAgICAgIGZvbnRXZWlnaHQ6IDYwMCxcbiAgICAgICAgICAgICAgbWFyZ2luQm90dG9tOiAnMTJweCcsXG4gICAgICAgICAgICAgIGNvbG9yOiBjb2xvcnMudGV4dFByaW1hcnksXG4gICAgICAgICAgICB9fVxuICAgICAgICAgID5cbiAgICAgICAgICAgIENsYXVkZSBDb2RlIChSZWNvbW1lbmRlZClcbiAgICAgICAgICA8L2gzPlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICAgIHBhZGRpbmc6ICcxNnB4JyxcbiAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBjb2xvcnMucGFuZWxCZ1NlY29uZGFyeSxcbiAgICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnNnB4JyxcbiAgICAgICAgICAgIH19XG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHAgc3R5bGU9e3sgbWFyZ2luOiAnMCAwIDEycHggMCcsIGZvbnRTaXplOiAnMTNweCcsIGNvbG9yOiBjb2xvcnMudGV4dFByaW1hcnkgfX0+XG4gICAgICAgICAgICAgIEFkZCB0aGUgZm9sbG93aW5nIHRvIHlvdXJ7JyAnfVxuICAgICAgICAgICAgICA8Y29kZVxuICAgICAgICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGNvbG9ycy5wYW5lbEJnQ29kZSxcbiAgICAgICAgICAgICAgICAgIHBhZGRpbmc6ICcycHggNHB4JyxcbiAgICAgICAgICAgICAgICAgIGJvcmRlclJhZGl1czogJzNweCcsXG4gICAgICAgICAgICAgICAgICBjb2xvcjogJyNmOGY4ZjInLFxuICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICB+Ly5jbGF1ZGUuanNvblxuICAgICAgICAgICAgICA8L2NvZGU+eycgJ31cbiAgICAgICAgICAgICAgZmlsZTpcbiAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgIDxwcmVcbiAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGNvbG9ycy5wYW5lbEJnQ29kZSxcbiAgICAgICAgICAgICAgICBjb2xvcjogJyNmOGY4ZjInLFxuICAgICAgICAgICAgICAgIHBhZGRpbmc6ICcxMnB4JyxcbiAgICAgICAgICAgICAgICBib3JkZXJSYWRpdXM6ICc0cHgnLFxuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAnMTFweCcsXG4gICAgICAgICAgICAgICAgb3ZlcmZsb3c6ICdhdXRvJyxcbiAgICAgICAgICAgICAgICBtYXJnaW46ICcwIDAgMTJweCAwJyxcbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge2B7XG4gIFwibWNwU2VydmVyc1wiOiB7XG4gICAgXCJsb2NhbFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdGRpb1wiLFxuICAgICAgXCJjb21tYW5kXCI6IFwibm9kZVwiLFxuICAgICAgXCJhcmdzXCI6IFtcIi9wYXRoL3RvL2xvY2FsLWFkZG9uLW1jcC1zZXJ2ZXIvYmluL21jcC1zdGRpby5qc1wiXVxuICAgIH1cbiAgfVxufWB9XG4gICAgICAgICAgICA8L3ByZT5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5oYW5kbGVDb3B5U3RkaW9Db25maWd9XG4gICAgICAgICAgICAgIHN0eWxlPXt0aGlzLmdldEJ1dHRvblN0eWxlKGNvbG9ycy5wcmltYXJ5KX1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge2NvcGllZCA/ICdDb3BpZWQhJyA6ICdDb3B5IENvbmZpZyd9XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgey8qIENsYXVkZS5haSAvIENoYXRHUFQgU2V0dXAgKi99XG4gICAgICAgIDxkaXYgc3R5bGU9e3sgbWFyZ2luQm90dG9tOiAnMjRweCcgfX0+XG4gICAgICAgICAgPGgzXG4gICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICBmb250U2l6ZTogJzE0cHgnLFxuICAgICAgICAgICAgICBmb250V2VpZ2h0OiA2MDAsXG4gICAgICAgICAgICAgIG1hcmdpbkJvdHRvbTogJzEycHgnLFxuICAgICAgICAgICAgICBjb2xvcjogY29sb3JzLnRleHRQcmltYXJ5LFxuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICBDbGF1ZGUuYWkgLyBDaGF0R1BUIC8gT3RoZXIgQUkgVG9vbHNcbiAgICAgICAgICA8L2gzPlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICAgIHBhZGRpbmc6ICcxNnB4JyxcbiAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBjb2xvcnMucGFuZWxCZ1NlY29uZGFyeSxcbiAgICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnNnB4JyxcbiAgICAgICAgICAgIH19XG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHAgc3R5bGU9e3sgbWFyZ2luOiAnMCAwIDEycHggMCcsIGZvbnRTaXplOiAnMTNweCcsIGNvbG9yOiBjb2xvcnMudGV4dFByaW1hcnkgfX0+XG4gICAgICAgICAgICAgIEZvciB0b29scyB0aGF0IHN1cHBvcnQgU1NFIHRyYW5zcG9ydCwgdXNlIHRoaXMgY29uZmlndXJhdGlvbjpcbiAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgIDxwcmVcbiAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGNvbG9ycy5wYW5lbEJnQ29kZSxcbiAgICAgICAgICAgICAgICBjb2xvcjogJyNmOGY4ZjInLFxuICAgICAgICAgICAgICAgIHBhZGRpbmc6ICcxMnB4JyxcbiAgICAgICAgICAgICAgICBib3JkZXJSYWRpdXM6ICc0cHgnLFxuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAnMTFweCcsXG4gICAgICAgICAgICAgICAgb3ZlcmZsb3c6ICdhdXRvJyxcbiAgICAgICAgICAgICAgICBtYXJnaW46ICcwIDAgMTJweCAwJyxcbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge2Nvbm5lY3Rpb25JbmZvXG4gICAgICAgICAgICAgICAgPyBge1xuICBcIm1jcFNlcnZlcnNcIjoge1xuICAgIFwibG9jYWxcIjoge1xuICAgICAgXCJ1cmxcIjogXCIke2Nvbm5lY3Rpb25JbmZvLnVybH0vbWNwL3NzZVwiLFxuICAgICAgXCJ0cmFuc3BvcnRcIjogXCJzc2VcIixcbiAgICAgIFwiaGVhZGVyc1wiOiB7XG4gICAgICAgIFwiQXV0aG9yaXphdGlvblwiOiBcIkJlYXJlciAke2Nvbm5lY3Rpb25JbmZvLmF1dGhUb2tlbi5zdWJzdHJpbmcoMCwgMjApfS4uLlwiXG4gICAgICB9XG4gICAgfVxuICB9XG59YFxuICAgICAgICAgICAgICAgIDogJ1NlcnZlciBub3QgcnVubmluZyd9XG4gICAgICAgICAgICA8L3ByZT5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5oYW5kbGVDb3B5U3NlQ29uZmlnfVxuICAgICAgICAgICAgICBkaXNhYmxlZD17IWNvbm5lY3Rpb25JbmZvfVxuICAgICAgICAgICAgICBzdHlsZT17dGhpcy5nZXRCdXR0b25TdHlsZShcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uSW5mbyA/IGNvbG9ycy5wcmltYXJ5IDogY29sb3JzLnRleHRNdXRlZCxcbiAgICAgICAgICAgICAgICAhY29ubmVjdGlvbkluZm9cbiAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge2NvcGllZCA/ICdDb3BpZWQhJyA6ICdDb3B5IFNTRSBDb25maWcnfVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIHsvKiBBdmFpbGFibGUgQ29tbWFuZHMgKi99XG4gICAgICAgIDxkaXYgc3R5bGU9e3sgbWFyZ2luQm90dG9tOiAnMjRweCcgfX0+XG4gICAgICAgICAgPGgzXG4gICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICBmb250U2l6ZTogJzE0cHgnLFxuICAgICAgICAgICAgICBmb250V2VpZ2h0OiA2MDAsXG4gICAgICAgICAgICAgIG1hcmdpbkJvdHRvbTogJzEycHgnLFxuICAgICAgICAgICAgICBjb2xvcjogY29sb3JzLnRleHRQcmltYXJ5LFxuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICBFeGFtcGxlIENvbW1hbmRzXG4gICAgICAgICAgPC9oMz5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICBwYWRkaW5nOiAnMTZweCcsXG4gICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogY29sb3JzLmluZm9CZyxcbiAgICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnNnB4JyxcbiAgICAgICAgICAgICAgYm9yZGVyOiBgMXB4IHNvbGlkICR7Y29sb3JzLmluZm9Cb3JkZXJ9YCxcbiAgICAgICAgICAgIH19XG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHBcbiAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICBtYXJnaW46ICcwIDAgOHB4IDAnLFxuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAnMTNweCcsXG4gICAgICAgICAgICAgICAgZm9udFdlaWdodDogNTAwLFxuICAgICAgICAgICAgICAgIGNvbG9yOiBjb2xvcnMuaW5mb1RleHQsXG4gICAgICAgICAgICAgIH19XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIFRyeSBzYXlpbmcgdG8geW91ciBBSSBhc3Npc3RhbnQ6XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICA8dWxcbiAgICAgICAgICAgICAgc3R5bGU9e3sgbWFyZ2luOiAwLCBwYWRkaW5nTGVmdDogJzIwcHgnLCBmb250U2l6ZTogJzEzcHgnLCBjb2xvcjogY29sb3JzLmluZm9UZXh0IH19XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxsaT4mcXVvdDtMaXN0IG15IExvY2FsIHNpdGVzJnF1b3Q7PC9saT5cbiAgICAgICAgICAgICAgPGxpPiZxdW90O1N0YXJ0IHRoZSBibG9nIHNpdGUmcXVvdDs8L2xpPlxuICAgICAgICAgICAgICA8bGk+JnF1b3Q7Q3JlYXRlIGEgbmV3IHNpdGUgY2FsbGVkIHRlc3QtcHJvamVjdCZxdW90OzwvbGk+XG4gICAgICAgICAgICAgIDxsaT4mcXVvdDtSdW4gd3AgcGx1Z2luIGxpc3Qgb24gbXktc2l0ZSZxdW90OzwvbGk+XG4gICAgICAgICAgICAgIDxsaT4mcXVvdDtTdG9wIGFsbCBydW5uaW5nIHNpdGVzJnF1b3Q7PC9saT5cbiAgICAgICAgICAgICAgPGxpPiZxdW90O1doYXQgcGx1Z2lucyBhcmUgaW5zdGFsbGVkIG9uIG15LXNpdGU/JnF1b3Q7PC9saT5cbiAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC8+XG4gICAgKTtcbiAgfVxuXG4gIHJlbmRlcigpOiBSZWFjdC5SZWFjdE5vZGUge1xuICAgIGNvbnN0IHsgYWN0aXZlVGFiLCBjb2xvcnMgfSA9IHRoaXMuc3RhdGU7XG5cbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBzdHlsZT17eyBwYWRkaW5nOiAnMjBweCcsIGNvbG9yOiBjb2xvcnMudGV4dFByaW1hcnkgfX0+XG4gICAgICAgIDxoMlxuICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICBtYXJnaW5Cb3R0b206ICcyMHB4JyxcbiAgICAgICAgICAgIGZvbnRTaXplOiAnMThweCcsXG4gICAgICAgICAgICBmb250V2VpZ2h0OiA2MDAsXG4gICAgICAgICAgICBjb2xvcjogY29sb3JzLnRleHRQcmltYXJ5LFxuICAgICAgICAgIH19XG4gICAgICAgID5cbiAgICAgICAgICBNQ1AgU2VydmVyXG4gICAgICAgIDwvaDI+XG5cbiAgICAgICAgPHAgc3R5bGU9e3sgY29sb3I6IGNvbG9ycy50ZXh0U2Vjb25kYXJ5LCBtYXJnaW5Cb3R0b206ICcyNHB4JyB9fT5cbiAgICAgICAgICBUaGUgTUNQIChNb2RlbCBDb250ZXh0IFByb3RvY29sKSBzZXJ2ZXIgZW5hYmxlcyBBSSB0b29scyBsaWtlIENsYXVkZSBDb2RlIHRvIGNvbnRyb2wgeW91clxuICAgICAgICAgIExvY2FsIHNpdGVzLlxuICAgICAgICA8L3A+XG5cbiAgICAgICAgey8qIFRhYiBOYXZpZ2F0aW9uICovfVxuICAgICAgICA8ZGl2IHN0eWxlPXt7IGJvcmRlckJvdHRvbTogYDFweCBzb2xpZCAke2NvbG9ycy5ib3JkZXJ9YCwgbWFyZ2luQm90dG9tOiAnMjRweCcgfX0+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgc3R5bGU9e3RoaXMuZ2V0VGFiU3R5bGUoYWN0aXZlVGFiID09PSAnc3RhdHVzJyl9XG4gICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiB0aGlzLnNldFN0YXRlKHsgYWN0aXZlVGFiOiAnc3RhdHVzJyB9KX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICBTdGF0dXMgJmFtcDsgQ29udHJvbHNcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBzdHlsZT17dGhpcy5nZXRUYWJTdHlsZShhY3RpdmVUYWIgPT09ICdzZXR1cCcpfVxuICAgICAgICAgICAgb25DbGljaz17KCkgPT4gdGhpcy5zZXRTdGF0ZSh7IGFjdGl2ZVRhYjogJ3NldHVwJyB9KX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICBBSSBUb29sIFNldHVwXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIHthY3RpdmVUYWIgPT09ICdzdGF0dXMnICYmIHRoaXMucmVuZGVyU3RhdHVzVGFiKCl9XG4gICAgICAgIHthY3RpdmVUYWIgPT09ICdzZXR1cCcgJiYgdGhpcy5yZW5kZXJTZXR1cFRhYigpfVxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufVxuXG4vLyBFeHBvcnQgYXMgYSBjb25zdHJ1Y3RvciBmdW5jdGlvbiB0aGF0IExvY2FsIGNhbiBpbnN0YW50aWF0ZVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBNY3BTZXJ2ZXJSZW5kZXJlcihjb250ZXh0OiB7IGhvb2tzOiB1bmtub3duOyBlbGVjdHJvbjogdW5rbm93biB9KTogdm9pZCB7XG4gIC8vIENMSS1vbmx5IG1vZGUgLSBwcmVmZXJlbmNlcyBwYW5lbCBkaXNhYmxlZFxuICAvLyBUbyBlbmFibGUgTUNQIHByZWZlcmVuY2VzIFVJLCB1bmNvbW1lbnQgdGhlIGZvbGxvd2luZzpcbiAgLypcbiAgY29uc3QgeyBob29rcywgZWxlY3Ryb24gfSA9IGNvbnRleHQgYXMge1xuICAgIGhvb2tzOiB7IGFkZEZpbHRlcjogKG5hbWU6IHN0cmluZywgY2FsbGJhY2s6IChpdGVtczogdW5rbm93bltdKSA9PiB1bmtub3duW10pID0+IHZvaWQgfTtcbiAgICBlbGVjdHJvbjogTWNwUHJlZmVyZW5jZXNQYW5lbFByb3BzWydlbGVjdHJvbiddO1xuICB9O1xuXG4gIGNvbnNvbGUubG9nKCdbTUNQIFNlcnZlcl0gUmVuZGVyZXIgbG9hZGluZy4uLicpO1xuXG4gIC8vIEFkZCBNQ1AgU2VydmVyIHRvIHByZWZlcmVuY2VzIG1lbnVcbiAgaG9va3MuYWRkRmlsdGVyKCdwcmVmZXJlbmNlc01lbnVJdGVtcycsIChtZW51SXRlbXM6IHVua25vd25bXSkgPT4ge1xuICAgIGNvbnNvbGUubG9nKCdbTUNQIFNlcnZlcl0gQWRkaW5nIE1DUCBTZXJ2ZXIgdG8gcHJlZmVyZW5jZXMnKTtcblxuICAgIChtZW51SXRlbXMgYXMgQXJyYXk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KS5wdXNoKHtcbiAgICAgIHBhdGg6ICdtY3Atc2VydmVyJyxcbiAgICAgIGRpc3BsYXlOYW1lOiAnTUNQIFNlcnZlcicsXG4gICAgICBzZWN0aW9uczogKCkgPT4gPE1jcFByZWZlcmVuY2VzUGFuZWwgZWxlY3Ryb249e2VsZWN0cm9ufSAvPixcbiAgICAgIG9uQXBwbHk6ICgpID0+IHtcbiAgICAgICAgLy8gTm8gYXBwbHkgYWN0aW9uIG5lZWRlZCBmb3IgcmVhZC1vbmx5IGRpc3BsYXlcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICByZXR1cm4gbWVudUl0ZW1zO1xuICB9KTtcblxuICBjb25zb2xlLmxvZygnW01DUCBTZXJ2ZXJdIFJlbmRlcmVyIHNldHVwIGNvbXBsZXRlJyk7XG4gICovXG5cbiAgLy8gU2lsZW5jZSB1bnVzZWQgdmFyaWFibGUgd2FybmluZ3NcbiAgdm9pZCBjb250ZXh0O1xufTtcbiJdfQ==
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@local-labs-jpollock/local-addon-cli",
3
+ "productName": "Local CLI",
4
+ "version": "0.0.1",
5
+ "description": "Command-line interface for Local WordPress development",
6
+ "main": "lib/main/index.js",
7
+ "renderer": "lib/renderer/index.js",
8
+ "bin": {
9
+ "local-mcp": "./bin/mcp-stdio.js"
10
+ },
11
+ "scripts": {
12
+ "build": "npm run clean && tsc",
13
+ "watch": "tsc --watch",
14
+ "clean": "rm -rf lib coverage",
15
+ "lint": "eslint src --ext .ts,.tsx --max-warnings=0",
16
+ "lint:fix": "eslint src --ext .ts,.tsx --fix",
17
+ "format": "prettier --write \"src/**/*.{ts,tsx}\"",
18
+ "format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
19
+ "typecheck": "tsc --noEmit",
20
+ "test": "jest",
21
+ "test:watch": "jest --watch",
22
+ "test:coverage": "jest --coverage"
23
+ },
24
+ "keywords": [
25
+ "local",
26
+ "addon",
27
+ "cli",
28
+ "wordpress",
29
+ "development"
30
+ ],
31
+ "author": "Jeremy Pollock <jpollock911@gmail.com>",
32
+ "license": "MIT",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "https://github.com/jpollock/local-addon-cli.git",
36
+ "directory": "packages/addon"
37
+ },
38
+ "engines": {
39
+ "node": ">=18.0.0"
40
+ },
41
+ "files": [
42
+ "lib/",
43
+ "bin/",
44
+ "README.md",
45
+ "LICENSE"
46
+ ],
47
+ "devDependencies": {
48
+ "@getflywheel/local": "^9.0.0",
49
+ "@types/fs-extra": "^11.0.4",
50
+ "@types/jest": "^29.5.12",
51
+ "@types/node": "^20.0.0",
52
+ "@types/react": "^19.2.10",
53
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
54
+ "@typescript-eslint/parser": "^7.0.0",
55
+ "eslint": "^8.57.0",
56
+ "eslint-config-prettier": "^9.1.0",
57
+ "eslint-plugin-react": "^7.34.0",
58
+ "eslint-plugin-react-hooks": "^4.6.0",
59
+ "graphql-tag": "^2.12.6",
60
+ "jest": "^29.7.0",
61
+ "prettier": "^3.2.5",
62
+ "ts-jest": "^29.1.2",
63
+ "typescript": "^5.0.0"
64
+ },
65
+ "localAddon": {
66
+ "minimumLocalVersion": "9.0.0",
67
+ "type": "addon",
68
+ "category": "developer-tools"
69
+ },
70
+ "dependencies": {
71
+ "node-stream-zip": "^1.15.0"
72
+ }
73
+ }