@meltstudio/meltctl 2.4.1 โ 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.js +149 -0
- package/dist/commands/login.d.ts +1 -0
- package/dist/commands/login.js +90 -0
- package/dist/commands/logout.d.ts +1 -0
- package/dist/commands/logout.js +12 -0
- package/dist/index.js +28 -31
- package/dist/utils/auth.d.ts +12 -0
- package/dist/utils/auth.js +52 -0
- package/dist/utils/banner.d.ts +1 -0
- package/dist/utils/banner.js +22 -0
- package/package.json +8 -7
- package/dist/commands/project/clean.d.ts +0 -5
- package/dist/commands/project/clean.js +0 -243
- package/dist/commands/project/init.d.ts +0 -5
- package/dist/commands/project/init.js +0 -158
- package/dist/commands/project/update.d.ts +0 -1
- package/dist/commands/project/update.js +0 -107
- package/templates/cursor-commands/melt-complete.md +0 -55
- package/templates/cursor-commands/melt-debug.md +0 -43
- package/templates/cursor-commands/melt-docs.md +0 -44
- package/templates/cursor-commands/melt-implement.md +0 -43
- package/templates/cursor-commands/melt-plan.md +0 -60
- package/templates/cursor-commands/melt-pr.md +0 -53
- package/templates/cursor-commands/melt-review.md +0 -43
- package/templates/cursor-commands/melt-test-plan.md +0 -50
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
import { intro, outro, confirm, spinner } from '@clack/prompts';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import fs from 'fs-extra';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
// List of Melt-generated command files to remove
|
|
6
|
-
const MELT_COMMAND_FILES = [
|
|
7
|
-
'melt-plan.md',
|
|
8
|
-
'melt-test-plan.md',
|
|
9
|
-
'melt-docs.md',
|
|
10
|
-
'melt-implement.md',
|
|
11
|
-
'melt-pr.md',
|
|
12
|
-
'melt-review.md',
|
|
13
|
-
'melt-complete.md',
|
|
14
|
-
'melt-debug.md',
|
|
15
|
-
];
|
|
16
|
-
export async function cleanCommand(options = {}) {
|
|
17
|
-
intro(chalk.blue('๐งน Melt Project - Clean'));
|
|
18
|
-
const currentDir = process.cwd();
|
|
19
|
-
const meltDir = path.join(currentDir, '.melt');
|
|
20
|
-
const cursorCommandsDir = path.join(currentDir, '.cursor', 'commands');
|
|
21
|
-
// Check if this is a Melt workspace
|
|
22
|
-
const hasMeltWorkspace = await fs.pathExists(meltDir);
|
|
23
|
-
const hasCursorCommands = await fs.pathExists(cursorCommandsDir);
|
|
24
|
-
if (!hasMeltWorkspace && !hasCursorCommands) {
|
|
25
|
-
console.log(chalk.yellow('โ ๏ธ No Melt workspace found in this directory.'));
|
|
26
|
-
console.log("This project doesn't appear to have Melt tools installed.");
|
|
27
|
-
outro(chalk.gray('Nothing to clean.'));
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
// Analyze what will be cleaned
|
|
31
|
-
const analysisResult = await analyzeCleanupTarget(currentDir);
|
|
32
|
-
if (analysisResult.removedFiles.length === 0 && analysisResult.removedDirs.length === 0) {
|
|
33
|
-
console.log(chalk.yellow('โ ๏ธ No Melt files found to clean.'));
|
|
34
|
-
outro(chalk.gray('Nothing to clean.'));
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
// Show what will be cleaned
|
|
38
|
-
displayCleanupPlan(analysisResult);
|
|
39
|
-
// Get confirmation (skip if --yes flag is provided)
|
|
40
|
-
let shouldProceed = options.yes || false;
|
|
41
|
-
if (!shouldProceed) {
|
|
42
|
-
const confirmResult = await confirm({
|
|
43
|
-
message: 'Do you want to proceed with cleaning? This action cannot be undone.',
|
|
44
|
-
});
|
|
45
|
-
if (confirmResult !== true) {
|
|
46
|
-
outro(chalk.gray('Clean operation cancelled.'));
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
shouldProceed = true;
|
|
50
|
-
}
|
|
51
|
-
// Perform the cleanup
|
|
52
|
-
const s = spinner();
|
|
53
|
-
s.start('Cleaning Melt workspace...');
|
|
54
|
-
try {
|
|
55
|
-
const cleanResult = await performCleanup(currentDir);
|
|
56
|
-
s.stop('โ
Cleanup completed!');
|
|
57
|
-
displayCleanupResults(cleanResult);
|
|
58
|
-
outro(chalk.green('๐ Melt workspace cleaned successfully!'));
|
|
59
|
-
}
|
|
60
|
-
catch (error) {
|
|
61
|
-
s.stop('โ Cleanup failed');
|
|
62
|
-
console.error(chalk.red('Error during cleanup:'), error);
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
async function analyzeCleanupTarget(baseDir) {
|
|
67
|
-
const result = {
|
|
68
|
-
removedFiles: [],
|
|
69
|
-
removedDirs: [],
|
|
70
|
-
preservedFiles: [],
|
|
71
|
-
errors: [],
|
|
72
|
-
};
|
|
73
|
-
const meltDir = path.join(baseDir, '.melt');
|
|
74
|
-
const cursorCommandsDir = path.join(baseDir, '.cursor', 'commands');
|
|
75
|
-
try {
|
|
76
|
-
// Check .melt directory (remove entirely)
|
|
77
|
-
if (await fs.pathExists(meltDir)) {
|
|
78
|
-
result.removedDirs.push('.melt/');
|
|
79
|
-
}
|
|
80
|
-
// Check .cursor/commands directory (selective removal)
|
|
81
|
-
if (await fs.pathExists(cursorCommandsDir)) {
|
|
82
|
-
const commandFiles = await fs.readdir(cursorCommandsDir);
|
|
83
|
-
for (const file of commandFiles) {
|
|
84
|
-
const filePath = path.join(cursorCommandsDir, file);
|
|
85
|
-
const stat = await fs.stat(filePath);
|
|
86
|
-
if (stat.isFile()) {
|
|
87
|
-
if (MELT_COMMAND_FILES.includes(file)) {
|
|
88
|
-
result.removedFiles.push(path.join('.cursor/commands', file));
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
result.preservedFiles.push(path.join('.cursor/commands', file));
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
// Check if .cursor/commands will be empty after cleaning
|
|
96
|
-
const meltFiles = commandFiles.filter(file => MELT_COMMAND_FILES.includes(file));
|
|
97
|
-
const nonMeltFiles = commandFiles.filter(file => !MELT_COMMAND_FILES.includes(file));
|
|
98
|
-
if (meltFiles.length > 0 && nonMeltFiles.length === 0) {
|
|
99
|
-
result.removedDirs.push('.cursor/commands/');
|
|
100
|
-
// Also check if .cursor itself would be empty
|
|
101
|
-
const cursorDir = path.join(baseDir, '.cursor');
|
|
102
|
-
const cursorContents = await fs.readdir(cursorDir);
|
|
103
|
-
if (cursorContents.length === 1 && cursorContents[0] === 'commands') {
|
|
104
|
-
result.removedDirs.push('.cursor/');
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
catch (error) {
|
|
110
|
-
result.errors.push(`Failed to analyze cleanup target: ${error instanceof Error ? error.message : String(error)}`);
|
|
111
|
-
}
|
|
112
|
-
return result;
|
|
113
|
-
}
|
|
114
|
-
async function performCleanup(baseDir) {
|
|
115
|
-
const result = {
|
|
116
|
-
removedFiles: [],
|
|
117
|
-
removedDirs: [],
|
|
118
|
-
preservedFiles: [],
|
|
119
|
-
errors: [],
|
|
120
|
-
};
|
|
121
|
-
const meltDir = path.join(baseDir, '.melt');
|
|
122
|
-
const cursorCommandsDir = path.join(baseDir, '.cursor', 'commands');
|
|
123
|
-
try {
|
|
124
|
-
// Remove .melt directory entirely
|
|
125
|
-
if (await fs.pathExists(meltDir)) {
|
|
126
|
-
await fs.remove(meltDir);
|
|
127
|
-
result.removedDirs.push('.melt/');
|
|
128
|
-
}
|
|
129
|
-
// Remove Melt command files from .cursor/commands
|
|
130
|
-
if (await fs.pathExists(cursorCommandsDir)) {
|
|
131
|
-
const commandFiles = await fs.readdir(cursorCommandsDir);
|
|
132
|
-
let hasNonMeltFiles = false;
|
|
133
|
-
for (const file of commandFiles) {
|
|
134
|
-
const filePath = path.join(cursorCommandsDir, file);
|
|
135
|
-
const stat = await fs.stat(filePath);
|
|
136
|
-
if (stat.isFile()) {
|
|
137
|
-
if (MELT_COMMAND_FILES.includes(file)) {
|
|
138
|
-
try {
|
|
139
|
-
await fs.remove(filePath);
|
|
140
|
-
result.removedFiles.push(path.join('.cursor/commands', file));
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
result.errors.push(`Failed to remove ${file}: ${error instanceof Error ? error.message : String(error)}`);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
hasNonMeltFiles = true;
|
|
148
|
-
result.preservedFiles.push(path.join('.cursor/commands', file));
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
// Remove empty directories if no user files remain
|
|
153
|
-
if (!hasNonMeltFiles) {
|
|
154
|
-
try {
|
|
155
|
-
await fs.remove(cursorCommandsDir);
|
|
156
|
-
result.removedDirs.push('.cursor/commands/');
|
|
157
|
-
// Check if .cursor directory is now empty
|
|
158
|
-
const cursorDir = path.join(baseDir, '.cursor');
|
|
159
|
-
if (await fs.pathExists(cursorDir)) {
|
|
160
|
-
const cursorContents = await fs.readdir(cursorDir);
|
|
161
|
-
if (cursorContents.length === 0) {
|
|
162
|
-
await fs.remove(cursorDir);
|
|
163
|
-
result.removedDirs.push('.cursor/');
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
catch (error) {
|
|
168
|
-
result.errors.push(`Failed to remove empty directories: ${error instanceof Error ? error.message : String(error)}`);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
catch (error) {
|
|
174
|
-
result.errors.push(`Cleanup failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
175
|
-
}
|
|
176
|
-
return result;
|
|
177
|
-
}
|
|
178
|
-
function displayCleanupPlan(result) {
|
|
179
|
-
console.log();
|
|
180
|
-
console.log(chalk.cyan('๐ Cleanup Plan:'));
|
|
181
|
-
console.log();
|
|
182
|
-
if (result.removedDirs.length > 0) {
|
|
183
|
-
console.log(chalk.yellow('Directories to be removed:'));
|
|
184
|
-
result.removedDirs.forEach(dir => {
|
|
185
|
-
console.log(` โข ${chalk.red(dir)}`);
|
|
186
|
-
});
|
|
187
|
-
console.log();
|
|
188
|
-
}
|
|
189
|
-
if (result.removedFiles.length > 0) {
|
|
190
|
-
console.log(chalk.yellow('Files to be removed:'));
|
|
191
|
-
result.removedFiles.forEach(file => {
|
|
192
|
-
console.log(` โข ${chalk.red(file)}`);
|
|
193
|
-
});
|
|
194
|
-
console.log();
|
|
195
|
-
}
|
|
196
|
-
if (result.preservedFiles.length > 0) {
|
|
197
|
-
console.log(chalk.green('Files to be preserved:'));
|
|
198
|
-
result.preservedFiles.forEach(file => {
|
|
199
|
-
console.log(` โข ${chalk.cyan(file)}`);
|
|
200
|
-
});
|
|
201
|
-
console.log();
|
|
202
|
-
}
|
|
203
|
-
if (result.errors.length > 0) {
|
|
204
|
-
console.log(chalk.red('Analysis errors:'));
|
|
205
|
-
result.errors.forEach(error => {
|
|
206
|
-
console.log(` โ ๏ธ ${error}`);
|
|
207
|
-
});
|
|
208
|
-
console.log();
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
function displayCleanupResults(result) {
|
|
212
|
-
console.log();
|
|
213
|
-
console.log(chalk.green('๐ฏ Cleanup Summary:'));
|
|
214
|
-
console.log();
|
|
215
|
-
if (result.removedDirs.length > 0) {
|
|
216
|
-
console.log(chalk.green(`โ
Removed ${result.removedDirs.length} directories:`));
|
|
217
|
-
result.removedDirs.forEach(dir => {
|
|
218
|
-
console.log(` โข ${dir}`);
|
|
219
|
-
});
|
|
220
|
-
console.log();
|
|
221
|
-
}
|
|
222
|
-
if (result.removedFiles.length > 0) {
|
|
223
|
-
console.log(chalk.green(`โ
Removed ${result.removedFiles.length} files:`));
|
|
224
|
-
result.removedFiles.forEach(file => {
|
|
225
|
-
console.log(` โข ${file}`);
|
|
226
|
-
});
|
|
227
|
-
console.log();
|
|
228
|
-
}
|
|
229
|
-
if (result.preservedFiles.length > 0) {
|
|
230
|
-
console.log(chalk.cyan(`๐ Preserved ${result.preservedFiles.length} user files:`));
|
|
231
|
-
result.preservedFiles.forEach(file => {
|
|
232
|
-
console.log(` โข ${file}`);
|
|
233
|
-
});
|
|
234
|
-
console.log();
|
|
235
|
-
}
|
|
236
|
-
if (result.errors.length > 0) {
|
|
237
|
-
console.log(chalk.red(`โ Errors encountered (${result.errors.length}):`));
|
|
238
|
-
result.errors.forEach(error => {
|
|
239
|
-
console.log(` โข ${error}`);
|
|
240
|
-
});
|
|
241
|
-
console.log();
|
|
242
|
-
}
|
|
243
|
-
}
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import { intro, outro, select, confirm, spinner } from '@clack/prompts';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import { existsSync, readFileSync } from 'fs';
|
|
4
|
-
import fs from 'fs-extra';
|
|
5
|
-
import { join, dirname } from 'path';
|
|
6
|
-
import { platform } from 'os';
|
|
7
|
-
import { fileURLToPath } from 'url';
|
|
8
|
-
const SHELL_CHOICES = {
|
|
9
|
-
sh: 'POSIX Shell (bash/zsh)',
|
|
10
|
-
ps: 'PowerShell',
|
|
11
|
-
};
|
|
12
|
-
export async function initCommand(options = {}) {
|
|
13
|
-
intro(chalk.blue('๐ Melt Project - Initialize'));
|
|
14
|
-
const currentDir = process.cwd();
|
|
15
|
-
// Check if directories already exist
|
|
16
|
-
const cursorDir = join(currentDir, '.cursor', 'commands');
|
|
17
|
-
const meltDir = join(currentDir, '.melt');
|
|
18
|
-
const existingPaths = [];
|
|
19
|
-
if (existsSync(cursorDir))
|
|
20
|
-
existingPaths.push('.cursor/commands/');
|
|
21
|
-
if (existsSync(meltDir))
|
|
22
|
-
existingPaths.push('.melt/');
|
|
23
|
-
if (existingPaths.length > 0) {
|
|
24
|
-
console.log(chalk.yellow('โ ๏ธ The following directories already exist:'));
|
|
25
|
-
existingPaths.forEach(path => console.log(` โข ${path}`));
|
|
26
|
-
console.log();
|
|
27
|
-
const shouldContinue = await confirm({
|
|
28
|
-
message: 'Do you want to continue? This may overwrite existing files.',
|
|
29
|
-
});
|
|
30
|
-
if (!shouldContinue) {
|
|
31
|
-
outro(chalk.gray('Operation cancelled.'));
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
// Shell selection (explicit, auto-detect, or interactive)
|
|
36
|
-
let selectedShell;
|
|
37
|
-
if (options.shell && options.shell !== 'auto') {
|
|
38
|
-
selectedShell = options.shell;
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
// Auto-detect based on platform
|
|
42
|
-
const defaultShell = platform() === 'win32' ? 'ps' : 'sh';
|
|
43
|
-
if (options.shell === 'auto') {
|
|
44
|
-
selectedShell = defaultShell;
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
// Interactive selection with default
|
|
48
|
-
selectedShell = (await select({
|
|
49
|
-
message: 'Choose script type:',
|
|
50
|
-
options: [
|
|
51
|
-
{ value: 'sh', label: SHELL_CHOICES.sh, hint: defaultShell === 'sh' ? 'default' : '' },
|
|
52
|
-
{ value: 'ps', label: SHELL_CHOICES.ps, hint: defaultShell === 'ps' ? 'default' : '' },
|
|
53
|
-
],
|
|
54
|
-
initialValue: defaultShell,
|
|
55
|
-
}));
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
console.log(chalk.cyan(`Selected shell: ${SHELL_CHOICES[selectedShell]}`));
|
|
59
|
-
console.log();
|
|
60
|
-
const s = spinner();
|
|
61
|
-
s.start('Setting up Melt development workspace...');
|
|
62
|
-
try {
|
|
63
|
-
// Create directory structures
|
|
64
|
-
createDirectoryStructure(currentDir, selectedShell);
|
|
65
|
-
// Copy templates
|
|
66
|
-
await copyTemplates(currentDir, selectedShell);
|
|
67
|
-
// Create version file
|
|
68
|
-
createVersionFile(meltDir);
|
|
69
|
-
s.stop('โ
Workspace setup complete!');
|
|
70
|
-
console.log();
|
|
71
|
-
console.log(chalk.green('๐ Melt development workspace initialized!'));
|
|
72
|
-
console.log();
|
|
73
|
-
console.log('Created directories:');
|
|
74
|
-
console.log(` โข ${chalk.cyan('.cursor/commands/')}`);
|
|
75
|
-
console.log(` โข ${chalk.cyan('.melt/memory/')}`);
|
|
76
|
-
console.log(` โข ${chalk.cyan('.melt/outputs/plans/')}`);
|
|
77
|
-
console.log(` โข ${chalk.cyan('.melt/outputs/implementations/')}`);
|
|
78
|
-
console.log(` โข ${chalk.cyan('.melt/outputs/reviews/')}`);
|
|
79
|
-
console.log(` โข ${chalk.cyan('.melt/scripts/sh/')}`);
|
|
80
|
-
console.log(` โข ${chalk.cyan('.melt/scripts/ps/')}`);
|
|
81
|
-
console.log(` โข ${chalk.cyan('.melt/templates/')}`);
|
|
82
|
-
console.log();
|
|
83
|
-
console.log('Next steps:');
|
|
84
|
-
console.log(' 1. Open Cursor IDE');
|
|
85
|
-
console.log(` 2. Run ${chalk.cyan('/melt-plan')} to start planning a feature`);
|
|
86
|
-
console.log(' 3. Follow the workflow: Plan โ Test โ Implement โ Review');
|
|
87
|
-
console.log();
|
|
88
|
-
console.log(`See docs: ${chalk.cyan('https://melt-development-prompts.vercel.app')}`);
|
|
89
|
-
outro(chalk.green('Happy coding with Melt! ๐'));
|
|
90
|
-
}
|
|
91
|
-
catch (error) {
|
|
92
|
-
s.stop('โ Setup failed');
|
|
93
|
-
console.error(chalk.red('Error during setup:'), error);
|
|
94
|
-
process.exit(1);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
function createDirectoryStructure(baseDir, shell) {
|
|
98
|
-
const dirs = [
|
|
99
|
-
'.cursor/commands',
|
|
100
|
-
'.melt/memory',
|
|
101
|
-
'.melt/outputs/plans',
|
|
102
|
-
'.melt/outputs/implementations',
|
|
103
|
-
'.melt/outputs/reviews',
|
|
104
|
-
'.melt/scripts/sh',
|
|
105
|
-
'.melt/scripts/ps',
|
|
106
|
-
'.melt/templates',
|
|
107
|
-
];
|
|
108
|
-
dirs.forEach(dir => {
|
|
109
|
-
const fullPath = join(baseDir, dir);
|
|
110
|
-
fs.ensureDirSync(fullPath);
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
async function copyTemplates(baseDir, shell) {
|
|
114
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
115
|
-
const __dirname = dirname(__filename);
|
|
116
|
-
// In dist, we need to go back to the CLI package root and find templates (from dist/commands/project to CLI root)
|
|
117
|
-
const templatesDir = join(__dirname, '../../../templates');
|
|
118
|
-
// Copy cursor commands
|
|
119
|
-
const cursorCommandsTemplateDir = join(templatesDir, 'cursor-commands');
|
|
120
|
-
const cursorCommandsDestDir = join(baseDir, '.cursor', 'commands');
|
|
121
|
-
if (existsSync(cursorCommandsTemplateDir)) {
|
|
122
|
-
fs.copySync(cursorCommandsTemplateDir, cursorCommandsDestDir);
|
|
123
|
-
}
|
|
124
|
-
// Create initial context file from memory
|
|
125
|
-
const contextSourcePath = join(__dirname, '../../../memory', 'context.md');
|
|
126
|
-
const contextDestPath = join(baseDir, '.melt', 'memory', 'context.md');
|
|
127
|
-
if (existsSync(contextSourcePath)) {
|
|
128
|
-
let contextContent = readFileSync(contextSourcePath, 'utf8');
|
|
129
|
-
// Replace timestamp placeholders
|
|
130
|
-
const timestamp = new Date().toISOString();
|
|
131
|
-
contextContent = contextContent.replace(/{{timestamp}}/g, timestamp);
|
|
132
|
-
fs.writeFileSync(contextDestPath, contextContent, 'utf8');
|
|
133
|
-
}
|
|
134
|
-
// Copy shell scripts from CLI package (copy both sh and ps scripts)
|
|
135
|
-
const scriptsBaseDir = join(__dirname, '../../../scripts');
|
|
136
|
-
const shellTypes = ['sh', 'ps'];
|
|
137
|
-
for (const shellType of shellTypes) {
|
|
138
|
-
const scriptsSourceDir = join(scriptsBaseDir, shellType);
|
|
139
|
-
const scriptsDestDir = join(baseDir, '.melt', 'scripts', shellType);
|
|
140
|
-
if (existsSync(scriptsSourceDir)) {
|
|
141
|
-
fs.copySync(scriptsSourceDir, scriptsDestDir);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
function createVersionFile(meltDir) {
|
|
146
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
147
|
-
const __dirname = dirname(__filename);
|
|
148
|
-
// In dist, we need to go back to the CLI package root (from dist/commands/project to CLI root)
|
|
149
|
-
const packageJsonPath = join(__dirname, '../../../package.json');
|
|
150
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
151
|
-
const versionData = {
|
|
152
|
-
cliVersion: packageJson.version,
|
|
153
|
-
initialized: new Date().toISOString(),
|
|
154
|
-
lastUpdate: new Date().toISOString(),
|
|
155
|
-
};
|
|
156
|
-
const versionPath = join(meltDir, 'version.json');
|
|
157
|
-
fs.writeFileSync(versionPath, JSON.stringify(versionData, null, 2), 'utf8');
|
|
158
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function updateCommand(): Promise<void>;
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { intro, outro, spinner, confirm } from '@clack/prompts';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import { execSync } from 'child_process';
|
|
4
|
-
import fs from 'fs-extra';
|
|
5
|
-
import path from 'path';
|
|
6
|
-
import { fileURLToPath } from 'url';
|
|
7
|
-
import { getCurrentCliVersion, getLatestCliVersion, compareVersions, } from '../../utils/version-check.js';
|
|
8
|
-
import { detectPackageManager } from '../../utils/package-manager.js';
|
|
9
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
-
async function updateCliPackage() {
|
|
11
|
-
const s = spinner();
|
|
12
|
-
s.start('Updating @meltstudio/meltctl package...');
|
|
13
|
-
try {
|
|
14
|
-
const { updateCommand } = detectPackageManager();
|
|
15
|
-
execSync(updateCommand, {
|
|
16
|
-
stdio: 'pipe',
|
|
17
|
-
});
|
|
18
|
-
s.stop('CLI package updated successfully!');
|
|
19
|
-
}
|
|
20
|
-
catch (error) {
|
|
21
|
-
s.stop('Failed to update CLI package');
|
|
22
|
-
throw error;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
async function updateCursorCommands() {
|
|
26
|
-
const s = spinner();
|
|
27
|
-
s.start('Updating .cursor/commands/ with latest prompts...');
|
|
28
|
-
try {
|
|
29
|
-
const templatesDir = path.join(__dirname, '../../../templates/cursor-commands');
|
|
30
|
-
const targetDir = path.join(process.cwd(), '.cursor', 'commands');
|
|
31
|
-
if (await fs.pathExists(templatesDir)) {
|
|
32
|
-
await fs.ensureDir(targetDir);
|
|
33
|
-
await fs.copy(templatesDir, targetDir, { overwrite: true });
|
|
34
|
-
s.stop('Cursor commands updated successfully!');
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
s.stop('No cursor templates found to update');
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
catch (error) {
|
|
41
|
-
s.stop('Failed to update cursor commands');
|
|
42
|
-
throw error;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
async function migrateMeltWorkspace() {
|
|
46
|
-
const s = spinner();
|
|
47
|
-
s.start('Checking .melt/ workspace migration...');
|
|
48
|
-
try {
|
|
49
|
-
const meltDir = path.join(process.cwd(), '.melt');
|
|
50
|
-
if (await fs.pathExists(meltDir)) {
|
|
51
|
-
s.stop('Melt workspace found - no migration needed');
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
s.stop('No melt workspace found - consider running meltctl project init');
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
s.stop('Failed to check melt workspace');
|
|
59
|
-
throw error;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
export async function updateCommand() {
|
|
63
|
-
intro(chalk.blue('๐ Melt Project - Update'));
|
|
64
|
-
try {
|
|
65
|
-
const currentVersion = await getCurrentCliVersion();
|
|
66
|
-
const latestVersion = await getLatestCliVersion();
|
|
67
|
-
if (!latestVersion) {
|
|
68
|
-
console.log(chalk.yellow('โ ๏ธ Unable to check for updates (network error)'));
|
|
69
|
-
console.log(chalk.gray(`Current CLI version: ${currentVersion}`));
|
|
70
|
-
console.log();
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
console.log(chalk.gray(`Current CLI version: ${currentVersion}`));
|
|
74
|
-
console.log(chalk.gray(`Latest CLI version: ${latestVersion}`));
|
|
75
|
-
console.log();
|
|
76
|
-
if (compareVersions(currentVersion, latestVersion)) {
|
|
77
|
-
console.log(chalk.yellow(`๐ฆ New version available: ${latestVersion}`));
|
|
78
|
-
const shouldUpdate = await confirm({
|
|
79
|
-
message: 'Would you like to update the CLI package?',
|
|
80
|
-
});
|
|
81
|
-
if (shouldUpdate) {
|
|
82
|
-
await updateCliPackage();
|
|
83
|
-
console.log();
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
console.log(chalk.green('โ
CLI package is up to date'));
|
|
88
|
-
console.log();
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
const shouldUpdateCommands = await confirm({
|
|
92
|
-
message: 'Would you like to update .cursor/commands/ with latest prompts?',
|
|
93
|
-
});
|
|
94
|
-
if (shouldUpdateCommands) {
|
|
95
|
-
await updateCursorCommands();
|
|
96
|
-
console.log();
|
|
97
|
-
}
|
|
98
|
-
await migrateMeltWorkspace();
|
|
99
|
-
outro(chalk.green('โ
Update process completed!'));
|
|
100
|
-
}
|
|
101
|
-
catch (error) {
|
|
102
|
-
console.error();
|
|
103
|
-
console.error(chalk.red('โ Update failed:'), error instanceof Error ? error.message : String(error));
|
|
104
|
-
outro(chalk.red('Update process failed'));
|
|
105
|
-
process.exit(1);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Complete story implementation, handle deployment, and update Linear status
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Complete the story implementation and handle all post-development tasks:
|
|
6
|
-
|
|
7
|
-
1. **Verify Completion**:
|
|
8
|
-
- Read `.melt/outputs/plans/` to check all planned tasks completed
|
|
9
|
-
- Review `.melt/outputs/implementations/` for implementation status
|
|
10
|
-
- Ensure all tests pass and coverage targets met
|
|
11
|
-
- Verify documentation is updated and accurate
|
|
12
|
-
|
|
13
|
-
2. **Linear Story Update**:
|
|
14
|
-
- Update Linear story status to "Ready for Review" or "Complete"
|
|
15
|
-
- Add implementation notes and links to PR
|
|
16
|
-
- Update story with actual effort vs. estimated effort
|
|
17
|
-
- Link any follow-up stories or technical debt identified
|
|
18
|
-
|
|
19
|
-
3. **Deployment Process**:
|
|
20
|
-
- Verify PR is approved and merged
|
|
21
|
-
- Monitor deployment pipeline for success
|
|
22
|
-
- Validate feature works in staging/production
|
|
23
|
-
- Check monitoring and logging for any issues
|
|
24
|
-
|
|
25
|
-
4. **Feature Validation**:
|
|
26
|
-
- Test feature functionality end-to-end
|
|
27
|
-
- Verify acceptance criteria are fully met
|
|
28
|
-
- Check performance metrics if applicable
|
|
29
|
-
- Validate accessibility compliance
|
|
30
|
-
|
|
31
|
-
5. **Documentation & Handoff**:
|
|
32
|
-
- Ensure user-facing documentation is updated
|
|
33
|
-
- Share feature with stakeholders if needed
|
|
34
|
-
- Document any lessons learned or technical debt
|
|
35
|
-
- Update architectural decision records if applicable
|
|
36
|
-
|
|
37
|
-
6. **Cleanup Tasks**:
|
|
38
|
-
- Remove feature flags if no longer needed
|
|
39
|
-
- Archive implementation planning materials
|
|
40
|
-
- Update project roadmap or backlog
|
|
41
|
-
- Share knowledge with team members
|
|
42
|
-
|
|
43
|
-
7. **Post-Completion Analysis**:
|
|
44
|
-
- Document actual vs. estimated effort
|
|
45
|
-
- Note any process improvements identified
|
|
46
|
-
- Record architectural patterns that worked well
|
|
47
|
-
- Identify any technical debt for future sprints
|
|
48
|
-
|
|
49
|
-
8. **Save Completion Records**:
|
|
50
|
-
- Update Linear story with final status and notes
|
|
51
|
-
- Save completion summary to `.melt/outputs/implementations/[timestamp]-complete.md`
|
|
52
|
-
- Update `.melt/memory/context.md` with completion details
|
|
53
|
-
- Archive relevant planning and implementation files
|
|
54
|
-
|
|
55
|
-
Focus on thorough validation and knowledge capture for continuous improvement.
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Debug issues using systematic approach and Melt development patterns
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Debug the issue systematically following our structured approach:
|
|
6
|
-
|
|
7
|
-
1. **Issue Analysis**:
|
|
8
|
-
- Document the problem clearly in `.melt/memory/context.md`
|
|
9
|
-
- Identify affected domains and components
|
|
10
|
-
- Gather error messages, stack traces, and reproduction steps
|
|
11
|
-
- Check recent changes in `.melt/outputs/implementations/`
|
|
12
|
-
|
|
13
|
-
2. **Domain-Specific Debugging**:
|
|
14
|
-
- Review component hierarchy and props flow
|
|
15
|
-
- Check custom hooks for state management issues
|
|
16
|
-
- Validate service layer API calls and data transformation
|
|
17
|
-
- Examine TypeScript types and Zod schema validation
|
|
18
|
-
|
|
19
|
-
3. **Tool-Assisted Debugging**:
|
|
20
|
-
- Use React DevTools for component inspection
|
|
21
|
-
- Leverage TypeScript compiler for type checking
|
|
22
|
-
- Check browser console for runtime errors
|
|
23
|
-
- Use network tab for API debugging
|
|
24
|
-
|
|
25
|
-
4. **Testing & Validation**:
|
|
26
|
-
- Run existing tests to identify regression
|
|
27
|
-
- Write minimal reproduction test case
|
|
28
|
-
- Check test coverage for the affected area
|
|
29
|
-
- Validate fix with comprehensive testing
|
|
30
|
-
|
|
31
|
-
5. **Root Cause Analysis**:
|
|
32
|
-
- Document the underlying cause
|
|
33
|
-
- Identify if it's architectural, implementation, or configuration
|
|
34
|
-
- Check if similar issues exist elsewhere
|
|
35
|
-
- Plan preventive measures
|
|
36
|
-
|
|
37
|
-
6. **Resolution Documentation**:
|
|
38
|
-
- Save debug session to `.melt/outputs/implementations/[timestamp]-debug.md`
|
|
39
|
-
- Update context with lessons learned
|
|
40
|
-
- Document any architectural improvements needed
|
|
41
|
-
- Share findings with team if applicable
|
|
42
|
-
|
|
43
|
-
Remember: Focus on understanding the problem deeply before implementing solutions.
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Update project documentation and README based on implementation changes
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Update project documentation to reflect implementation changes and maintain accuracy:
|
|
6
|
-
|
|
7
|
-
1. **Analyze Changes**:
|
|
8
|
-
- Review recent implementation in `.melt/outputs/implementations/`
|
|
9
|
-
- Check `.melt/outputs/plans/` for planned changes
|
|
10
|
-
- Identify new features, APIs, or architectural changes
|
|
11
|
-
- Review `.melt/memory/context.md` for context
|
|
12
|
-
|
|
13
|
-
2. **Documentation Updates**:
|
|
14
|
-
- **README.md**: Update installation, usage, and examples
|
|
15
|
-
- **API Documentation**: Document new endpoints or changed interfaces
|
|
16
|
-
- **Component Documentation**: Add JSDoc comments and usage examples
|
|
17
|
-
- **Architecture Docs**: Update domain structure if changed
|
|
18
|
-
- **Deployment Docs**: Update if new environment variables or configs added
|
|
19
|
-
|
|
20
|
-
3. **Documentation Patterns**:
|
|
21
|
-
- Use clear, concise language focused on developers
|
|
22
|
-
- Include code examples for new features
|
|
23
|
-
- Document breaking changes and migration steps
|
|
24
|
-
- Add troubleshooting sections for common issues
|
|
25
|
-
- Include links to relevant domain documentation
|
|
26
|
-
|
|
27
|
-
4. **Code Documentation**:
|
|
28
|
-
- Add/update JSDoc comments for public APIs
|
|
29
|
-
- Document complex business logic with inline comments
|
|
30
|
-
- Update TypeScript interfaces with proper descriptions
|
|
31
|
-
- Ensure prop types are documented for components
|
|
32
|
-
|
|
33
|
-
5. **Validation**:
|
|
34
|
-
- Verify all links work correctly
|
|
35
|
-
- Test code examples to ensure they're accurate
|
|
36
|
-
- Check that documentation matches actual implementation
|
|
37
|
-
- Ensure consistent formatting and style
|
|
38
|
-
|
|
39
|
-
6. **Save Documentation Updates**:
|
|
40
|
-
- Update relevant documentation files
|
|
41
|
-
- Save documentation notes to `.melt/outputs/implementations/[timestamp]-docs.md`
|
|
42
|
-
- Update `.melt/memory/context.md` with documentation decisions
|
|
43
|
-
|
|
44
|
-
Focus on keeping documentation current, accurate, and developer-focused.
|