@meltstudio/meltctl 4.35.0 → 4.36.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.
- package/dist/commands/audit.js +66 -111
- package/dist/commands/audit.test.js +118 -209
- package/dist/commands/coins.js +30 -28
- package/dist/commands/coins.test.js +23 -43
- package/dist/commands/feedback.js +8 -17
- package/dist/commands/feedback.test.js +38 -103
- package/dist/commands/login.js +15 -20
- package/dist/commands/plan.js +21 -51
- package/dist/commands/plan.test.js +95 -132
- package/dist/commands/standup.js +10 -14
- package/dist/commands/standup.test.js +66 -100
- package/dist/utils/analytics.js +9 -19
- package/dist/utils/api.d.ts +2 -1
- package/dist/utils/api.js +4 -12
- package/dist/utils/api.test.js +25 -45
- package/dist/utils/templates.d.ts +2 -4
- package/dist/utils/templates.js +3 -7
- package/dist/utils/templates.test.js +14 -26
- package/package.json +3 -2
package/dist/commands/audit.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import fs from 'fs-extra';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import {
|
|
4
|
+
import { getClient } from '../utils/api.js';
|
|
5
5
|
import { getGitBranch, getGitCommit, getGitRepository, getProjectName, findMdFiles, } from '../utils/git.js';
|
|
6
6
|
function detectAuditType(filename) {
|
|
7
7
|
const lower = filename.toLowerCase();
|
|
@@ -28,7 +28,7 @@ async function autoDetectAuditFile() {
|
|
|
28
28
|
return null;
|
|
29
29
|
}
|
|
30
30
|
export async function auditSubmitCommand(file) {
|
|
31
|
-
const
|
|
31
|
+
const client = await getClient();
|
|
32
32
|
let filePath;
|
|
33
33
|
if (file) {
|
|
34
34
|
filePath = path.resolve(file);
|
|
@@ -53,62 +53,33 @@ export async function auditSubmitCommand(file) {
|
|
|
53
53
|
const branch = getGitBranch();
|
|
54
54
|
const commit = getGitCommit();
|
|
55
55
|
const repo = getGitRepository();
|
|
56
|
-
const payload = {
|
|
57
|
-
type: auditType,
|
|
58
|
-
project,
|
|
59
|
-
repository: repo?.slug ?? null,
|
|
60
|
-
repositoryUrl: repo?.url ?? null,
|
|
61
|
-
branch,
|
|
62
|
-
commit,
|
|
63
|
-
content,
|
|
64
|
-
metadata: { filename },
|
|
65
|
-
};
|
|
66
56
|
try {
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
57
|
+
const result = await client.audits.submit({
|
|
58
|
+
type: auditType,
|
|
59
|
+
project,
|
|
60
|
+
repository: repo?.slug ?? null,
|
|
61
|
+
repositoryUrl: repo?.url ?? null,
|
|
62
|
+
branch,
|
|
63
|
+
commit,
|
|
64
|
+
content,
|
|
65
|
+
metadata: { filename },
|
|
71
66
|
});
|
|
72
|
-
|
|
73
|
-
const body = (await res.json());
|
|
74
|
-
console.log(chalk.green(`\n ✓ Audit submitted! ID: ${body.id}\n`));
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
const body = (await res.json());
|
|
78
|
-
console.error(chalk.red(`\nFailed to submit audit: ${body.error ?? res.statusText}`));
|
|
79
|
-
process.exit(1);
|
|
80
|
-
}
|
|
67
|
+
console.log(chalk.green(`\n ✓ Audit submitted! ID: ${result.id}\n`));
|
|
81
68
|
}
|
|
82
69
|
catch (error) {
|
|
83
|
-
console.error(chalk.red(
|
|
70
|
+
console.error(chalk.red(`\nFailed to submit audit: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
84
71
|
process.exit(1);
|
|
85
72
|
}
|
|
86
73
|
}
|
|
87
74
|
export async function auditListCommand(options) {
|
|
88
|
-
const
|
|
89
|
-
const params = new URLSearchParams();
|
|
90
|
-
if (options.type)
|
|
91
|
-
params.set('type', options.type);
|
|
92
|
-
if (options.repository)
|
|
93
|
-
params.set('repository', options.repository);
|
|
94
|
-
if (options.latest)
|
|
95
|
-
params.set('latest', 'true');
|
|
96
|
-
if (options.limit)
|
|
97
|
-
params.set('limit', options.limit);
|
|
98
|
-
const query = params.toString();
|
|
99
|
-
const urlPath = `/audits${query ? `?${query}` : ''}`;
|
|
75
|
+
const client = await getClient();
|
|
100
76
|
try {
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const body = (await res.json());
|
|
108
|
-
console.error(chalk.red(`Failed to list audits: ${body.error ?? res.statusText}`));
|
|
109
|
-
process.exit(1);
|
|
110
|
-
}
|
|
111
|
-
const body = (await res.json());
|
|
77
|
+
const body = await client.audits.list({
|
|
78
|
+
type: options.type,
|
|
79
|
+
repository: options.repository,
|
|
80
|
+
latest: options.latest,
|
|
81
|
+
limit: options.limit ? parseInt(options.limit, 10) : undefined,
|
|
82
|
+
});
|
|
112
83
|
if (body.audits.length === 0) {
|
|
113
84
|
console.log(chalk.dim('\n No audits found.\n'));
|
|
114
85
|
return;
|
|
@@ -123,34 +94,7 @@ export async function auditListCommand(options) {
|
|
|
123
94
|
console.log(chalk.dim(` ${'ID'.padEnd(10)} ${'TYPE'.padEnd(12)} ${'REPOSITORY'.padEnd(40)} ${'AGE'.padEnd(10)} ${'AUTHOR'.padEnd(30)} DATE`));
|
|
124
95
|
console.log();
|
|
125
96
|
for (const r of body.audits) {
|
|
126
|
-
|
|
127
|
-
const daysAgo = Math.floor((Date.now() - createdAt.getTime()) / (1000 * 60 * 60 * 24));
|
|
128
|
-
const date = createdAt.toLocaleDateString('en-US', {
|
|
129
|
-
month: 'short',
|
|
130
|
-
day: 'numeric',
|
|
131
|
-
year: 'numeric',
|
|
132
|
-
});
|
|
133
|
-
const repo = r.repository ?? r.project;
|
|
134
|
-
const label = typeLabels[r.type] ?? r.type;
|
|
135
|
-
const typeColor = r.type === 'ux-audit'
|
|
136
|
-
? chalk.yellow
|
|
137
|
-
: r.type === 'security-audit'
|
|
138
|
-
? chalk.red
|
|
139
|
-
: chalk.magenta;
|
|
140
|
-
const ageText = daysAgo === 0 ? 'today' : `${daysAgo}d ago`;
|
|
141
|
-
const isSecurityAudit = r.type === 'security-audit';
|
|
142
|
-
const ageColor = isSecurityAudit
|
|
143
|
-
? daysAgo <= 30
|
|
144
|
-
? chalk.green
|
|
145
|
-
: daysAgo <= 90
|
|
146
|
-
? chalk.yellow
|
|
147
|
-
: chalk.red
|
|
148
|
-
: daysAgo <= 7
|
|
149
|
-
? chalk.green
|
|
150
|
-
: daysAgo <= 30
|
|
151
|
-
? chalk.yellow
|
|
152
|
-
: chalk.red;
|
|
153
|
-
console.log(` ${chalk.dim(r.id.slice(0, 8).padEnd(10))} ${typeColor(label.padEnd(12))} ${chalk.white(repo.padEnd(40))} ${ageColor(ageText.padEnd(10))} ${chalk.dim(r.author.padEnd(30))} ${chalk.dim(date)}`);
|
|
97
|
+
printLatestAuditRow(r, typeLabels);
|
|
154
98
|
}
|
|
155
99
|
}
|
|
156
100
|
else {
|
|
@@ -159,24 +103,7 @@ export async function auditListCommand(options) {
|
|
|
159
103
|
console.log(chalk.dim(hdr));
|
|
160
104
|
console.log();
|
|
161
105
|
for (const r of body.audits) {
|
|
162
|
-
|
|
163
|
-
month: 'short',
|
|
164
|
-
day: 'numeric',
|
|
165
|
-
year: 'numeric',
|
|
166
|
-
hour: '2-digit',
|
|
167
|
-
minute: '2-digit',
|
|
168
|
-
});
|
|
169
|
-
const repo = r.repository ?? r.project;
|
|
170
|
-
const label = typeLabels[r.type] ?? r.type;
|
|
171
|
-
const typeColor = r.type === 'ux-audit'
|
|
172
|
-
? chalk.yellow
|
|
173
|
-
: r.type === 'security-audit'
|
|
174
|
-
? chalk.red
|
|
175
|
-
: chalk.magenta;
|
|
176
|
-
console.log(` ${chalk.dim(r.id.slice(0, 8).padEnd(10))} ${typeColor(label.padEnd(12))} ${chalk.white(repo.padEnd(40))} ${chalk.dim(r.author.padEnd(30))} ${chalk.dim(date)}`);
|
|
177
|
-
if (r.branch && r.branch !== 'main') {
|
|
178
|
-
console.log(` ${' '.padEnd(10)} ${' '.padEnd(12)} ${chalk.dim(`branch: ${r.branch} commit: ${r.commit ?? 'N/A'}`)}`);
|
|
179
|
-
}
|
|
106
|
+
printAuditRow(r, typeLabels);
|
|
180
107
|
}
|
|
181
108
|
}
|
|
182
109
|
console.log();
|
|
@@ -186,24 +113,52 @@ export async function auditListCommand(options) {
|
|
|
186
113
|
process.exit(1);
|
|
187
114
|
}
|
|
188
115
|
}
|
|
116
|
+
function printLatestAuditRow(r, typeLabels) {
|
|
117
|
+
const createdAt = new Date(r.created_at ?? r.createdAt);
|
|
118
|
+
const daysAgo = Math.floor((Date.now() - createdAt.getTime()) / (1000 * 60 * 60 * 24));
|
|
119
|
+
const date = createdAt.toLocaleDateString('en-US', {
|
|
120
|
+
month: 'short',
|
|
121
|
+
day: 'numeric',
|
|
122
|
+
year: 'numeric',
|
|
123
|
+
});
|
|
124
|
+
const repo = r.repository ?? r.project;
|
|
125
|
+
const label = typeLabels[r.type] ?? r.type;
|
|
126
|
+
const typeColor = r.type === 'ux-audit' ? chalk.yellow : r.type === 'security-audit' ? chalk.red : chalk.magenta;
|
|
127
|
+
const ageText = daysAgo === 0 ? 'today' : `${daysAgo}d ago`;
|
|
128
|
+
const isSecurityAudit = r.type === 'security-audit';
|
|
129
|
+
const ageColor = isSecurityAudit
|
|
130
|
+
? daysAgo <= 30
|
|
131
|
+
? chalk.green
|
|
132
|
+
: daysAgo <= 90
|
|
133
|
+
? chalk.yellow
|
|
134
|
+
: chalk.red
|
|
135
|
+
: daysAgo <= 7
|
|
136
|
+
? chalk.green
|
|
137
|
+
: daysAgo <= 30
|
|
138
|
+
? chalk.yellow
|
|
139
|
+
: chalk.red;
|
|
140
|
+
console.log(` ${chalk.dim(r.id.slice(0, 8).padEnd(10))} ${typeColor(label.padEnd(12))} ${chalk.white(repo.padEnd(40))} ${ageColor(ageText.padEnd(10))} ${chalk.dim(r.author.padEnd(30))} ${chalk.dim(date)}`);
|
|
141
|
+
}
|
|
142
|
+
function printAuditRow(r, typeLabels) {
|
|
143
|
+
const date = new Date(r.createdAt).toLocaleDateString('en-US', {
|
|
144
|
+
month: 'short',
|
|
145
|
+
day: 'numeric',
|
|
146
|
+
year: 'numeric',
|
|
147
|
+
hour: '2-digit',
|
|
148
|
+
minute: '2-digit',
|
|
149
|
+
});
|
|
150
|
+
const repo = r.repository ?? r.project;
|
|
151
|
+
const label = typeLabels[r.type] ?? r.type;
|
|
152
|
+
const typeColor = r.type === 'ux-audit' ? chalk.yellow : r.type === 'security-audit' ? chalk.red : chalk.magenta;
|
|
153
|
+
console.log(` ${chalk.dim(r.id.slice(0, 8).padEnd(10))} ${typeColor(label.padEnd(12))} ${chalk.white(repo.padEnd(40))} ${chalk.dim(r.author.padEnd(30))} ${chalk.dim(date)}`);
|
|
154
|
+
if (r.branch && r.branch !== 'main') {
|
|
155
|
+
console.log(` ${' '.padEnd(10)} ${' '.padEnd(12)} ${chalk.dim(`branch: ${r.branch} commit: ${r.commit ?? 'N/A'}`)}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
189
158
|
export async function auditViewCommand(id, options) {
|
|
190
|
-
const
|
|
159
|
+
const client = await getClient();
|
|
191
160
|
try {
|
|
192
|
-
const
|
|
193
|
-
if (res.status === 403) {
|
|
194
|
-
console.error(chalk.red('Access denied. Only Team Managers can view audits.'));
|
|
195
|
-
process.exit(1);
|
|
196
|
-
}
|
|
197
|
-
if (res.status === 404) {
|
|
198
|
-
console.error(chalk.red(`Audit not found: ${id}`));
|
|
199
|
-
process.exit(1);
|
|
200
|
-
}
|
|
201
|
-
if (!res.ok) {
|
|
202
|
-
const body = (await res.json());
|
|
203
|
-
console.error(chalk.red(`Failed to fetch audit: ${body.error ?? res.statusText}`));
|
|
204
|
-
process.exit(1);
|
|
205
|
-
}
|
|
206
|
-
const audit = (await res.json());
|
|
161
|
+
const audit = await client.audits.get(id);
|
|
207
162
|
if (options.output) {
|
|
208
163
|
const outputPath = path.resolve(options.output);
|
|
209
164
|
await fs.ensureDir(path.dirname(outputPath));
|