@meltstudio/meltctl 4.38.0 → 4.38.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 (81) hide show
  1. package/dist/index.js +2178 -210
  2. package/package.json +4 -3
  3. package/dist/commands/audit.d.ts +0 -10
  4. package/dist/commands/audit.js +0 -191
  5. package/dist/commands/audit.test.d.ts +0 -1
  6. package/dist/commands/audit.test.js +0 -324
  7. package/dist/commands/coins.d.ts +0 -5
  8. package/dist/commands/coins.js +0 -51
  9. package/dist/commands/coins.test.d.ts +0 -1
  10. package/dist/commands/coins.test.js +0 -113
  11. package/dist/commands/feedback.d.ts +0 -7
  12. package/dist/commands/feedback.js +0 -90
  13. package/dist/commands/feedback.test.d.ts +0 -1
  14. package/dist/commands/feedback.test.js +0 -177
  15. package/dist/commands/init.d.ts +0 -8
  16. package/dist/commands/init.js +0 -520
  17. package/dist/commands/init.test.d.ts +0 -1
  18. package/dist/commands/init.test.js +0 -478
  19. package/dist/commands/login.d.ts +0 -1
  20. package/dist/commands/login.js +0 -90
  21. package/dist/commands/login.test.d.ts +0 -1
  22. package/dist/commands/login.test.js +0 -194
  23. package/dist/commands/logout.d.ts +0 -1
  24. package/dist/commands/logout.js +0 -12
  25. package/dist/commands/logout.test.d.ts +0 -1
  26. package/dist/commands/logout.test.js +0 -59
  27. package/dist/commands/plan.d.ts +0 -6
  28. package/dist/commands/plan.js +0 -123
  29. package/dist/commands/plan.test.d.ts +0 -1
  30. package/dist/commands/plan.test.js +0 -246
  31. package/dist/commands/standup.d.ts +0 -7
  32. package/dist/commands/standup.js +0 -74
  33. package/dist/commands/standup.test.d.ts +0 -1
  34. package/dist/commands/standup.test.js +0 -218
  35. package/dist/commands/templates.d.ts +0 -1
  36. package/dist/commands/templates.js +0 -37
  37. package/dist/commands/templates.test.d.ts +0 -1
  38. package/dist/commands/templates.test.js +0 -89
  39. package/dist/commands/update.d.ts +0 -2
  40. package/dist/commands/update.js +0 -74
  41. package/dist/commands/update.test.d.ts +0 -1
  42. package/dist/commands/update.test.js +0 -93
  43. package/dist/commands/version.d.ts +0 -1
  44. package/dist/commands/version.js +0 -43
  45. package/dist/commands/version.test.d.ts +0 -1
  46. package/dist/commands/version.test.js +0 -86
  47. package/dist/index.d.ts +0 -2
  48. package/dist/utils/analytics.d.ts +0 -1
  49. package/dist/utils/analytics.js +0 -54
  50. package/dist/utils/analytics.test.d.ts +0 -1
  51. package/dist/utils/analytics.test.js +0 -91
  52. package/dist/utils/api.d.ts +0 -3
  53. package/dist/utils/api.js +0 -23
  54. package/dist/utils/api.test.d.ts +0 -1
  55. package/dist/utils/api.test.js +0 -76
  56. package/dist/utils/auth.d.ts +0 -12
  57. package/dist/utils/auth.js +0 -54
  58. package/dist/utils/auth.test.d.ts +0 -1
  59. package/dist/utils/auth.test.js +0 -165
  60. package/dist/utils/banner.d.ts +0 -1
  61. package/dist/utils/banner.js +0 -22
  62. package/dist/utils/banner.test.d.ts +0 -1
  63. package/dist/utils/banner.test.js +0 -34
  64. package/dist/utils/debug.d.ts +0 -1
  65. package/dist/utils/debug.js +0 -6
  66. package/dist/utils/git.d.ts +0 -9
  67. package/dist/utils/git.js +0 -76
  68. package/dist/utils/git.test.d.ts +0 -1
  69. package/dist/utils/git.test.js +0 -184
  70. package/dist/utils/package-manager.d.ts +0 -7
  71. package/dist/utils/package-manager.js +0 -55
  72. package/dist/utils/package-manager.test.d.ts +0 -1
  73. package/dist/utils/package-manager.test.js +0 -76
  74. package/dist/utils/templates.d.ts +0 -2
  75. package/dist/utils/templates.js +0 -5
  76. package/dist/utils/templates.test.d.ts +0 -1
  77. package/dist/utils/templates.test.js +0 -38
  78. package/dist/utils/version-check.d.ts +0 -7
  79. package/dist/utils/version-check.js +0 -139
  80. package/dist/utils/version-check.test.d.ts +0 -1
  81. package/dist/utils/version-check.test.js +0 -189
@@ -1,520 +0,0 @@
1
- import chalk from 'chalk';
2
- import { checkbox, confirm } from '@inquirer/prompts';
3
- import fs from 'fs-extra';
4
- import path from 'path';
5
- import { isAuthenticated } from '../utils/auth.js';
6
- import { fetchTemplates } from '../utils/templates.js';
7
- const SKILL_FRONTMATTER = {
8
- setup: `---
9
- user-invocable: true
10
- description: >-
11
- Analyze the project and customize AGENTS.md for this codebase.
12
- Use when setting up a new project, after running meltctl init,
13
- or when AGENTS.md has placeholder markers. Detects tech stack,
14
- fills in project-specific sections, and merges existing standards.
15
- ---
16
-
17
- `,
18
- plan: `---
19
- user-invocable: true
20
- description: >-
21
- Design an implementation approach before writing code. Use when
22
- starting a feature, tackling a complex task, or when the developer
23
- says "plan this" or "how should we approach this". Gathers requirements,
24
- explores codebase, and presents a step-by-step plan for approval.
25
- ---
26
-
27
- `,
28
- review: `---
29
- user-invocable: true
30
- description: >-
31
- Review code changes against project standards and address PR feedback.
32
- Use when the developer asks to review changes, check code quality,
33
- or respond to PR reviewer comments. Categorizes findings as must-fix,
34
- should-fix, or suggestions.
35
- ---
36
-
37
- `,
38
- pr: `---
39
- user-invocable: true
40
- description: >-
41
- Create a well-structured pull request from current changes. Use when
42
- the developer is ready to submit work, says "create a PR", or "open
43
- a pull request". Analyzes changes, runs pre-flight checks, drafts
44
- description, and creates the PR via gh CLI.
45
- ---
46
-
47
- `,
48
- debug: `---
49
- user-invocable: true
50
- description: >-
51
- Systematically investigate and fix bugs. Use when the developer
52
- reports a bug, encounters an error, or says "debug this" or "why
53
- is this failing". Reproduces the issue, isolates root cause, writes
54
- regression test, and implements minimal fix.
55
- ---
56
-
57
- `,
58
- audit: `---
59
- user-invocable: true
60
- description: >-
61
- Run a comprehensive project compliance audit against team standards.
62
- Use when the developer wants to assess project health, check compliance,
63
- or says "audit this project". Checks 15 categories including documentation,
64
- testing, CI/CD, security, and AI tool setup. Produces a structured
65
- report with scores and actionable fixes.
66
- ---
67
-
68
- `,
69
- 'ux-audit': `---
70
- user-invocable: true
71
- description: >-
72
- Review the project's UI against usability heuristics using Chrome DevTools
73
- MCP. Use when the developer wants to check UX quality, says "review the UI",
74
- or "UX audit". In full audit mode, crawls the entire app. During an active
75
- plan, scopes to the current feature and appends results to the plan file.
76
- ---
77
-
78
- `,
79
- 'security-audit': `---
80
- user-invocable: true
81
- description: >-
82
- Run a comprehensive security posture audit across the entire platform.
83
- Use when the developer wants to assess security, says "security audit",
84
- or "check our security posture". Covers infrastructure, encryption, auth,
85
- application security, data protection, CI/CD, and compliance readiness.
86
- Investigates all platform repositories for a holistic view.
87
- ---
88
-
89
- `,
90
- validate: `---
91
- user-invocable: true
92
- description: >-
93
- Run the validation plan from the plan document after implementation.
94
- Use when the developer says "validate this", "test the feature", or
95
- after finishing implementation. Validates end-to-end using browser,
96
- API, or CLI testing, suggests test coverage improvements, then prompts
97
- the developer for mandatory manual sign-off.
98
- ---
99
-
100
- `,
101
- update: `---
102
- user-invocable: true
103
- description: >-
104
- Update Melt skills and standards to the latest version. Use when the
105
- developer wants the latest skill templates, says "update melt", or
106
- after a new meltctl version is released. Fetches latest templates,
107
- preserves project customizations in AGENTS.md, and merges changes.
108
- ---
109
-
110
- `,
111
- help: `---
112
- user-invocable: true
113
- description: >-
114
- Answer questions about the AI-First Development Playbook and team
115
- workflow. Use when the developer asks about the development process,
116
- what step they're on, how validation works, or any workflow question.
117
- This is a reference skill — it explains the process, not executes it.
118
- ---
119
-
120
- `,
121
- link: `---
122
- user-invocable: true
123
- description: >-
124
- Connect and verify required integrations (ticket tracker, browser
125
- testing). Use after melt-setup, when tools aren't working, or when
126
- a skill reports missing MCP connections. Guides setup, verifies
127
- each tool works, and updates AGENTS.md connection status.
128
- ---
129
-
130
- `,
131
- };
132
- const OPENCODE_COMMAND_FRONTMATTER = {
133
- setup: `---
134
- description: Analyze the project and customize AGENTS.md for this codebase.
135
- ---
136
-
137
- `,
138
- plan: `---
139
- description: Design an implementation approach before writing code.
140
- ---
141
-
142
- `,
143
- review: `---
144
- description: Review code changes against project standards and address PR feedback.
145
- ---
146
-
147
- `,
148
- pr: `---
149
- description: Create a well-structured pull request from current changes.
150
- ---
151
-
152
- `,
153
- debug: `---
154
- description: Systematically investigate and fix bugs.
155
- ---
156
-
157
- `,
158
- audit: `---
159
- description: Run a comprehensive project compliance audit against team standards.
160
- ---
161
-
162
- `,
163
- 'ux-audit': `---
164
- description: Review the project's UI against usability heuristics using Chrome DevTools MCP.
165
- ---
166
-
167
- `,
168
- 'security-audit': `---
169
- description: Run a comprehensive security posture audit across the entire platform.
170
- ---
171
-
172
- `,
173
- validate: `---
174
- description: Run the validation plan from the plan document after implementation.
175
- ---
176
-
177
- `,
178
- update: `---
179
- description: Update Melt skills and standards to the latest version.
180
- ---
181
-
182
- `,
183
- help: `---
184
- description: Answer questions about the AI-First Development Playbook and team workflow.
185
- ---
186
-
187
- `,
188
- link: `---
189
- description: Connect and verify required integrations (ticket tracker, browser testing).
190
- ---
191
-
192
- `,
193
- };
194
- const GITIGNORE_ENTRIES = ['.env.local', '.claude/settings.local.json'];
195
- function detectExistingTools(cwd) {
196
- return {
197
- claude: fs.pathExistsSync(path.join(cwd, '.claude/settings.json')),
198
- cursor: fs.pathExistsSync(path.join(cwd, '.cursor/commands')),
199
- opencode: fs.pathExistsSync(path.join(cwd, '.opencode/commands')),
200
- };
201
- }
202
- async function promptToolSelection(existingTools) {
203
- const choices = [];
204
- if (!existingTools?.claude) {
205
- choices.push({ name: 'Claude Code', value: 'claude', checked: true });
206
- }
207
- if (!existingTools?.cursor) {
208
- choices.push({ name: 'Cursor', value: 'cursor', checked: true });
209
- }
210
- if (!existingTools?.opencode) {
211
- choices.push({ name: 'OpenCode', value: 'opencode', checked: true });
212
- }
213
- choices.push({
214
- name: 'Other — contact us in #dev on Slack to request support',
215
- value: 'other',
216
- });
217
- const selected = await checkbox({
218
- message: 'Which AI coding tools do you use?',
219
- choices,
220
- });
221
- return {
222
- claude: selected.includes('claude'),
223
- cursor: selected.includes('cursor'),
224
- opencode: selected.includes('opencode'),
225
- other: selected.includes('other'),
226
- };
227
- }
228
- export async function initCommand(options) {
229
- // Check authentication before anything else to avoid wasted prompts
230
- if (!(await isAuthenticated())) {
231
- console.error(chalk.red('Not authenticated. Run `npx @meltstudio/meltctl@latest login` first.'));
232
- process.exit(1);
233
- }
234
- const cwd = process.cwd();
235
- // Warn if not in a git repository — likely the wrong directory
236
- const isGitRepo = await fs.pathExists(path.join(cwd, '.git'));
237
- if (!isGitRepo) {
238
- console.log(chalk.yellow(`Warning: ${cwd} is not a git repository.`));
239
- console.log(chalk.dim('meltctl init should be run from the root of your project.'));
240
- console.log();
241
- const proceed = await confirm({
242
- message: 'Continue initializing here anyway?',
243
- default: false,
244
- });
245
- if (!proceed) {
246
- console.log(chalk.dim('Aborted. cd into your project root and try again.'));
247
- return;
248
- }
249
- console.log();
250
- }
251
- const alreadyInitialized = await fs.pathExists(path.join(cwd, 'AGENTS.md'));
252
- let isReInit = false;
253
- let tools;
254
- if (alreadyInitialized && !options.force) {
255
- // Re-init scenario: project already set up, developer wants to add another tool
256
- const existing = detectExistingTools(cwd);
257
- const existingNames = [
258
- existing.claude ? 'Claude Code' : '',
259
- existing.cursor ? 'Cursor' : '',
260
- existing.opencode ? 'OpenCode' : '',
261
- ]
262
- .filter(Boolean)
263
- .join(', ');
264
- if (existing.claude && existing.cursor && existing.opencode) {
265
- console.log(chalk.yellow('Project already initialized with all tools. Use --force to overwrite.'));
266
- process.exit(1);
267
- }
268
- console.log(chalk.dim(`Project already initialized${existingNames ? ` with ${existingNames}` : ''}.`));
269
- isReInit = true;
270
- if (options.claude || options.cursor || options.opencode) {
271
- // Non-interactive: use flags directly, skip confirm prompt
272
- tools = {
273
- claude: !!options.claude,
274
- cursor: !!options.cursor,
275
- opencode: !!options.opencode,
276
- other: false,
277
- };
278
- }
279
- else {
280
- const addMore = await confirm({
281
- message: 'Add configuration for another tool?',
282
- default: true,
283
- });
284
- if (!addMore) {
285
- process.exit(0);
286
- }
287
- tools = await promptToolSelection(existing);
288
- }
289
- }
290
- else {
291
- // Fresh init or --force
292
- if (options.claude || options.cursor || options.opencode) {
293
- tools = {
294
- claude: !!options.claude,
295
- cursor: !!options.cursor,
296
- opencode: !!options.opencode,
297
- other: false,
298
- };
299
- }
300
- else {
301
- tools = await promptToolSelection();
302
- }
303
- }
304
- if (!tools.claude && !tools.cursor && !tools.opencode && !tools.other) {
305
- console.log(chalk.yellow('No tools selected. Nothing to do.'));
306
- process.exit(0);
307
- }
308
- let templates;
309
- try {
310
- templates = await fetchTemplates();
311
- }
312
- catch (error) {
313
- if (error instanceof Error && error.message.includes('expired')) {
314
- console.error(chalk.red('Session expired. Run `npx @meltstudio/meltctl@latest login` to re-authenticate.'));
315
- }
316
- else if (error instanceof Error && error.message.includes('fetch')) {
317
- console.error(chalk.red('Could not reach Melt API. Check your connection.'));
318
- }
319
- else {
320
- console.error(chalk.red(`Failed to fetch templates: ${error instanceof Error ? error.message : 'Unknown error'}`));
321
- }
322
- process.exit(1);
323
- }
324
- console.log(chalk.bold('Initializing Melt development tools...'));
325
- console.log();
326
- const createdFiles = [];
327
- const workflows = [
328
- 'setup',
329
- 'plan',
330
- 'validate',
331
- 'review',
332
- 'pr',
333
- 'debug',
334
- 'audit',
335
- 'ux-audit',
336
- 'security-audit',
337
- 'update',
338
- 'help',
339
- 'link',
340
- ];
341
- // Shared files (skip on re-init)
342
- if (!isReInit) {
343
- const agentsMd = templates['agents-md.md'];
344
- if (agentsMd) {
345
- await fs.writeFile(path.join(cwd, 'AGENTS.md'), agentsMd, 'utf-8');
346
- createdFiles.push('AGENTS.md');
347
- }
348
- const mcpConfig = templates['mcp-configs/base.json'];
349
- if (mcpConfig) {
350
- await mergeMcpConfig(cwd, mcpConfig);
351
- createdFiles.push('.mcp.json');
352
- }
353
- await updateGitignore(cwd);
354
- }
355
- // Claude Code files
356
- if (tools.claude) {
357
- const claudeSettings = templates['claude-settings.json'];
358
- if (claudeSettings) {
359
- await fs.ensureDir(path.join(cwd, '.claude'));
360
- await mergeClaudeSettings(cwd, claudeSettings);
361
- createdFiles.push('.claude/settings.json');
362
- }
363
- for (const name of workflows) {
364
- const workflowContent = templates[`workflows/${name}.md`];
365
- if (workflowContent) {
366
- const skillDir = path.join(cwd, `.claude/skills/melt-${name}`);
367
- await fs.ensureDir(skillDir);
368
- const skillContent = SKILL_FRONTMATTER[name] + workflowContent;
369
- await fs.writeFile(path.join(skillDir, 'SKILL.md'), skillContent, 'utf-8');
370
- }
371
- }
372
- createdFiles.push('.claude/skills/melt-{setup,plan,validate,review,pr,debug,audit,ux-audit,security-audit,update,help}/SKILL.md');
373
- }
374
- // Cursor files
375
- if (tools.cursor) {
376
- await fs.ensureDir(path.join(cwd, '.cursor/commands'));
377
- for (const name of workflows) {
378
- const workflowContent = templates[`workflows/${name}.md`];
379
- if (workflowContent) {
380
- await fs.writeFile(path.join(cwd, `.cursor/commands/melt-${name}.md`), workflowContent, 'utf-8');
381
- }
382
- }
383
- createdFiles.push('.cursor/commands/melt-{setup,plan,validate,review,pr,debug,audit,ux-audit,security-audit,update,help}.md');
384
- }
385
- // OpenCode files
386
- if (tools.opencode) {
387
- await fs.ensureDir(path.join(cwd, '.opencode/commands'));
388
- for (const name of workflows) {
389
- const workflowContent = templates[`workflows/${name}.md`];
390
- if (workflowContent) {
391
- const commandContent = OPENCODE_COMMAND_FRONTMATTER[name] + workflowContent;
392
- await fs.writeFile(path.join(cwd, `.opencode/commands/melt-${name}.md`), commandContent, 'utf-8');
393
- }
394
- }
395
- createdFiles.push('.opencode/commands/melt-{setup,plan,validate,review,pr,debug,audit,ux-audit,security-audit,update,help}.md');
396
- }
397
- // Print summary
398
- console.log(chalk.green('Created files:'));
399
- for (const file of createdFiles) {
400
- console.log(chalk.dim(` ${file}`));
401
- }
402
- console.log();
403
- if (tools.other) {
404
- console.log(chalk.cyan('Want support for your tool? Let us know in #dev on Slack'));
405
- console.log();
406
- }
407
- const commandNames = 'melt-setup, melt-plan, melt-validate, melt-review, melt-pr, melt-debug, melt-audit, melt-ux-audit, melt-security-audit, melt-update, melt-help';
408
- if (tools.claude) {
409
- console.log(chalk.dim(`Available skills: /${commandNames.replace(/, /g, ', /')}`));
410
- }
411
- if (tools.cursor) {
412
- console.log(chalk.dim(`Available Cursor commands: ${commandNames}`));
413
- }
414
- if (tools.opencode) {
415
- console.log(chalk.dim(`Available OpenCode commands: /${commandNames.replace(/, /g, ', /')}`));
416
- }
417
- if (tools.claude || tools.cursor || tools.opencode) {
418
- console.log();
419
- }
420
- if (!isReInit) {
421
- console.log(chalk.bold.cyan(' Next step: run /melt-setup to customize AGENTS.md for your project'));
422
- console.log();
423
- const toolInstructions = [];
424
- if (tools.claude) {
425
- toolInstructions.push({
426
- name: 'Claude Code',
427
- steps: [
428
- 'Type /melt-setup in the chat prompt, or',
429
- 'Open the skills menu and select melt-setup',
430
- ],
431
- });
432
- }
433
- if (tools.cursor) {
434
- toolInstructions.push({
435
- name: 'Cursor',
436
- steps: ['Open the command menu (Cmd+K) and search for melt-setup'],
437
- });
438
- }
439
- if (tools.opencode) {
440
- toolInstructions.push({
441
- name: 'OpenCode',
442
- steps: ['Type /melt-setup in the chat prompt'],
443
- });
444
- }
445
- if (toolInstructions.length === 1 && toolInstructions[0]) {
446
- console.log(chalk.dim(` In ${toolInstructions[0].name}:`));
447
- for (const step of toolInstructions[0].steps) {
448
- console.log(chalk.dim(` - ${step}`));
449
- }
450
- }
451
- else {
452
- for (const tool of toolInstructions) {
453
- console.log(chalk.dim(` ${tool.name}:`));
454
- for (const step of tool.steps) {
455
- console.log(chalk.dim(` - ${step}`));
456
- }
457
- console.log();
458
- }
459
- }
460
- console.log();
461
- console.log(chalk.dim(' The setup skill will analyze your project and fill in AGENTS.md.'));
462
- console.log(chalk.dim(' Then run /melt-link to connect your ticket tracker and browser testing tools.'));
463
- console.log();
464
- }
465
- console.log(chalk.green('Done!'));
466
- }
467
- async function mergeMcpConfig(cwd, templateContent) {
468
- const mcpPath = path.join(cwd, '.mcp.json');
469
- const templateConfig = JSON.parse(templateContent);
470
- if (await fs.pathExists(mcpPath)) {
471
- const existingContent = await fs.readFile(mcpPath, 'utf-8');
472
- const existingConfig = JSON.parse(existingContent);
473
- // Merge: add our servers without overwriting existing ones
474
- existingConfig.mcpServers = {
475
- ...existingConfig.mcpServers,
476
- ...templateConfig.mcpServers,
477
- };
478
- await fs.writeFile(mcpPath, JSON.stringify(existingConfig, null, 2) + '\n', 'utf-8');
479
- }
480
- else {
481
- await fs.writeFile(mcpPath, templateContent, 'utf-8');
482
- }
483
- }
484
- async function mergeClaudeSettings(cwd, templateContent) {
485
- const settingsPath = path.join(cwd, '.claude/settings.json');
486
- const templateConfig = JSON.parse(templateContent);
487
- if (await fs.pathExists(settingsPath)) {
488
- const existingContent = await fs.readFile(settingsPath, 'utf-8');
489
- const existingConfig = JSON.parse(existingContent);
490
- // Merge permissions: combine allow/deny lists, deduplicate
491
- const existingAllow = existingConfig.permissions?.allow ?? [];
492
- const existingDeny = existingConfig.permissions?.deny ?? [];
493
- const templateAllow = templateConfig.permissions?.allow ?? [];
494
- const templateDeny = templateConfig.permissions?.deny ?? [];
495
- existingConfig.permissions = {
496
- ...existingConfig.permissions,
497
- allow: [...new Set([...existingAllow, ...templateAllow])],
498
- deny: [...new Set([...existingDeny, ...templateDeny])],
499
- };
500
- await fs.writeFile(settingsPath, JSON.stringify(existingConfig, null, 2) + '\n', 'utf-8');
501
- }
502
- else {
503
- await fs.writeFile(settingsPath, templateContent, 'utf-8');
504
- }
505
- }
506
- async function updateGitignore(cwd) {
507
- const gitignorePath = path.join(cwd, '.gitignore');
508
- let content = '';
509
- if (await fs.pathExists(gitignorePath)) {
510
- content = await fs.readFile(gitignorePath, 'utf-8');
511
- }
512
- const missingEntries = GITIGNORE_ENTRIES.filter(entry => !content.includes(entry));
513
- if (missingEntries.length > 0) {
514
- const suffix = content.endsWith('\n') || content === '' ? '' : '\n';
515
- const section = missingEntries.length > 0
516
- ? `${suffix}\n# Melt - local settings\n${missingEntries.join('\n')}\n`
517
- : '';
518
- await fs.writeFile(gitignorePath, content + section, 'utf-8');
519
- }
520
- }
@@ -1 +0,0 @@
1
- export {};