@meltstudio/meltctl 4.8.0 → 4.9.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/README.md +5 -2
- package/dist/commands/init.js +13 -14
- package/dist/commands/templates.d.ts +1 -0
- package/dist/commands/templates.js +37 -0
- package/dist/index.js +7 -0
- package/dist/utils/templates.d.ts +4 -0
- package/dist/utils/templates.js +9 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,6 +25,9 @@ meltctl project init --claude --cursor # Both
|
|
|
25
25
|
# Re-initialize
|
|
26
26
|
meltctl project init --force
|
|
27
27
|
|
|
28
|
+
# Fetch latest templates (used by /melt-update)
|
|
29
|
+
meltctl project templates
|
|
30
|
+
|
|
28
31
|
# Other commands
|
|
29
32
|
meltctl logout
|
|
30
33
|
meltctl version --check
|
|
@@ -34,8 +37,8 @@ meltctl version --check
|
|
|
34
37
|
|
|
35
38
|
- `AGENTS.md` — AI agent instructions and project standards
|
|
36
39
|
- `.claude/settings.json` — Claude Code permissions
|
|
37
|
-
- `.claude/skills/melt-{setup,plan
|
|
38
|
-
- `.cursor/commands/melt-{setup,plan
|
|
40
|
+
- `.claude/skills/melt-{setup,plan,...,update}/SKILL.md` — Claude Code workflow skills
|
|
41
|
+
- `.cursor/commands/melt-{setup,plan,...,update}.md` — Cursor workflow commands
|
|
39
42
|
- `.mcp.json` — MCP server configuration (Chrome DevTools)
|
|
40
43
|
|
|
41
44
|
## Requirements
|
package/dist/commands/init.js
CHANGED
|
@@ -2,7 +2,8 @@ import chalk from 'chalk';
|
|
|
2
2
|
import { checkbox, confirm } from '@inquirer/prompts';
|
|
3
3
|
import fs from 'fs-extra';
|
|
4
4
|
import path from 'path';
|
|
5
|
-
import {
|
|
5
|
+
import { isAuthenticated } from '../utils/auth.js';
|
|
6
|
+
import { fetchTemplates } from '../utils/templates.js';
|
|
6
7
|
const SKILL_FRONTMATTER = {
|
|
7
8
|
setup: `---
|
|
8
9
|
user-invocable: true
|
|
@@ -39,17 +40,15 @@ user-invocable: true
|
|
|
39
40
|
description: Run a project compliance audit against team standards
|
|
40
41
|
---
|
|
41
42
|
|
|
43
|
+
`,
|
|
44
|
+
update: `---
|
|
45
|
+
user-invocable: true
|
|
46
|
+
description: Update Melt skills and standards to the latest version
|
|
47
|
+
---
|
|
48
|
+
|
|
42
49
|
`,
|
|
43
50
|
};
|
|
44
51
|
const GITIGNORE_ENTRIES = ['.env.local', '.claude/settings.local.json'];
|
|
45
|
-
async function fetchTemplates() {
|
|
46
|
-
const response = await authenticatedFetch('/templates');
|
|
47
|
-
if (!response.ok) {
|
|
48
|
-
throw new Error(`Failed to fetch templates: ${response.statusText}`);
|
|
49
|
-
}
|
|
50
|
-
const data = (await response.json());
|
|
51
|
-
return data.files;
|
|
52
|
-
}
|
|
53
52
|
function detectExistingTools(cwd) {
|
|
54
53
|
return {
|
|
55
54
|
claude: fs.pathExistsSync(path.join(cwd, '.claude/settings.json')),
|
|
@@ -147,7 +146,7 @@ export async function initCommand(options) {
|
|
|
147
146
|
console.log(chalk.bold('Initializing Melt development tools...'));
|
|
148
147
|
console.log();
|
|
149
148
|
const createdFiles = [];
|
|
150
|
-
const workflows = ['setup', 'plan', 'review', 'pr', 'debug', 'audit'];
|
|
149
|
+
const workflows = ['setup', 'plan', 'review', 'pr', 'debug', 'audit', 'update'];
|
|
151
150
|
// Shared files (skip on re-init)
|
|
152
151
|
if (!isReInit) {
|
|
153
152
|
const agentsMd = templates['agents-md.md'];
|
|
@@ -179,7 +178,7 @@ export async function initCommand(options) {
|
|
|
179
178
|
await fs.writeFile(path.join(skillDir, 'SKILL.md'), skillContent, 'utf-8');
|
|
180
179
|
}
|
|
181
180
|
}
|
|
182
|
-
createdFiles.push('.claude/skills/melt-{setup,plan,review,pr,debug,audit}/SKILL.md');
|
|
181
|
+
createdFiles.push('.claude/skills/melt-{setup,plan,review,pr,debug,audit,update}/SKILL.md');
|
|
183
182
|
}
|
|
184
183
|
// Cursor files
|
|
185
184
|
if (tools.cursor) {
|
|
@@ -190,7 +189,7 @@ export async function initCommand(options) {
|
|
|
190
189
|
await fs.writeFile(path.join(cwd, `.cursor/commands/melt-${name}.md`), workflowContent, 'utf-8');
|
|
191
190
|
}
|
|
192
191
|
}
|
|
193
|
-
createdFiles.push('.cursor/commands/melt-{setup,plan,review,pr,debug,audit}.md');
|
|
192
|
+
createdFiles.push('.cursor/commands/melt-{setup,plan,review,pr,debug,audit,update}.md');
|
|
194
193
|
}
|
|
195
194
|
// Print summary
|
|
196
195
|
console.log(chalk.green('Created files:'));
|
|
@@ -203,11 +202,11 @@ export async function initCommand(options) {
|
|
|
203
202
|
console.log();
|
|
204
203
|
}
|
|
205
204
|
if (tools.claude) {
|
|
206
|
-
const skills = '/melt-setup, /melt-plan, /melt-review, /melt-pr, /melt-debug, /melt-audit';
|
|
205
|
+
const skills = '/melt-setup, /melt-plan, /melt-review, /melt-pr, /melt-debug, /melt-audit, /melt-update';
|
|
207
206
|
console.log(chalk.dim(`Available skills: ${skills}`));
|
|
208
207
|
}
|
|
209
208
|
if (tools.cursor) {
|
|
210
|
-
console.log(chalk.dim('Available commands: melt-setup, melt-plan, melt-review, melt-pr, melt-debug, melt-audit'));
|
|
209
|
+
console.log(chalk.dim('Available commands: melt-setup, melt-plan, melt-review, melt-pr, melt-debug, melt-audit, melt-update'));
|
|
211
210
|
}
|
|
212
211
|
if (tools.claude || tools.cursor) {
|
|
213
212
|
console.log();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function templatesCommand(): Promise<void>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import { isAuthenticated } from '../utils/auth.js';
|
|
6
|
+
import { fetchTemplates } from '../utils/templates.js';
|
|
7
|
+
export async function templatesCommand() {
|
|
8
|
+
if (!(await isAuthenticated())) {
|
|
9
|
+
console.error(chalk.red('Not authenticated. Run `npx @meltstudio/meltctl@latest login` first.'));
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
let templates;
|
|
13
|
+
try {
|
|
14
|
+
templates = await fetchTemplates();
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
if (error instanceof Error && error.message.includes('expired')) {
|
|
18
|
+
console.error(chalk.red('Session expired. Run `npx @meltstudio/meltctl@latest login` to re-authenticate.'));
|
|
19
|
+
}
|
|
20
|
+
else if (error instanceof Error && error.message.includes('fetch')) {
|
|
21
|
+
console.error(chalk.red('Could not reach Melt API. Check your connection.'));
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
console.error(chalk.red(`Failed to fetch templates: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
25
|
+
}
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
const tmpDir = path.join(os.tmpdir(), `melt-templates-${Date.now()}`);
|
|
29
|
+
await fs.ensureDir(tmpDir);
|
|
30
|
+
for (const [filePath, content] of Object.entries(templates)) {
|
|
31
|
+
const fullPath = path.join(tmpDir, filePath);
|
|
32
|
+
await fs.ensureDir(path.dirname(fullPath));
|
|
33
|
+
await fs.writeFile(fullPath, content, 'utf-8');
|
|
34
|
+
}
|
|
35
|
+
// Print only the temp dir path to stdout (agent parses this)
|
|
36
|
+
console.log(tmpDir);
|
|
37
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { readFileSync } from 'fs';
|
|
|
5
5
|
import { join, dirname } from 'path';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
7
|
import { initCommand } from './commands/init.js';
|
|
8
|
+
import { templatesCommand } from './commands/templates.js';
|
|
8
9
|
import { loginCommand } from './commands/login.js';
|
|
9
10
|
import { logoutCommand } from './commands/logout.js';
|
|
10
11
|
import { printBanner } from './utils/banner.js';
|
|
@@ -48,6 +49,12 @@ project
|
|
|
48
49
|
.action(options => {
|
|
49
50
|
return initCommand({ force: options.force, claude: options.claude, cursor: options.cursor });
|
|
50
51
|
});
|
|
52
|
+
project
|
|
53
|
+
.command('templates')
|
|
54
|
+
.description('fetch latest templates to a temp directory (for /melt-update)')
|
|
55
|
+
.action(async () => {
|
|
56
|
+
await templatesCommand();
|
|
57
|
+
});
|
|
51
58
|
program
|
|
52
59
|
.command('version')
|
|
53
60
|
.description('show current version')
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { authenticatedFetch } from './auth.js';
|
|
2
|
+
export async function fetchTemplates() {
|
|
3
|
+
const response = await authenticatedFetch('/templates');
|
|
4
|
+
if (!response.ok) {
|
|
5
|
+
throw new Error(`Failed to fetch templates: ${response.statusText}`);
|
|
6
|
+
}
|
|
7
|
+
const data = (await response.json());
|
|
8
|
+
return data.files;
|
|
9
|
+
}
|
package/package.json
CHANGED