@electriccitizen/bolt 0.1.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 +361 -0
- package/dist/adapters/ddev.d.ts +16 -0
- package/dist/adapters/ddev.js +75 -0
- package/dist/adapters/ddev.js.map +1 -0
- package/dist/adapters/index.d.ts +1 -0
- package/dist/adapters/index.js +2 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +167 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/doctor.d.ts +4 -0
- package/dist/commands/doctor.js +263 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +12 -0
- package/dist/commands/init.js +319 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/pr.d.ts +20 -0
- package/dist/commands/pr.js +282 -0
- package/dist/commands/pr.js.map +1 -0
- package/dist/commands/refresh.d.ts +22 -0
- package/dist/commands/refresh.js +375 -0
- package/dist/commands/refresh.js.map +1 -0
- package/dist/commands/suppress.d.ts +10 -0
- package/dist/commands/suppress.js +86 -0
- package/dist/commands/suppress.js.map +1 -0
- package/dist/commands/test.d.ts +5 -0
- package/dist/commands/test.js +106 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/update.d.ts +26 -0
- package/dist/commands/update.js +573 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/config.d.ts +47 -0
- package/dist/config.js +187 -0
- package/dist/config.js.map +1 -0
- package/dist/formatters/index.d.ts +2 -0
- package/dist/formatters/index.js +3 -0
- package/dist/formatters/index.js.map +1 -0
- package/dist/formatters/json.d.ts +5 -0
- package/dist/formatters/json.js +7 -0
- package/dist/formatters/json.js.map +1 -0
- package/dist/formatters/markdown.d.ts +5 -0
- package/dist/formatters/markdown.js +144 -0
- package/dist/formatters/markdown.js.map +1 -0
- package/dist/formatters/text.d.ts +5 -0
- package/dist/formatters/text.js +123 -0
- package/dist/formatters/text.js.map +1 -0
- package/dist/plugins/accessibility.d.ts +5 -0
- package/dist/plugins/accessibility.js +116 -0
- package/dist/plugins/accessibility.js.map +1 -0
- package/dist/plugins/browser-smoke.d.ts +6 -0
- package/dist/plugins/browser-smoke.js +331 -0
- package/dist/plugins/browser-smoke.js.map +1 -0
- package/dist/plugins/field-interaction.d.ts +6 -0
- package/dist/plugins/field-interaction.js +570 -0
- package/dist/plugins/field-interaction.js.map +1 -0
- package/dist/plugins/index.d.ts +6 -0
- package/dist/plugins/index.js +28 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/linkit.d.ts +8 -0
- package/dist/plugins/linkit.js +170 -0
- package/dist/plugins/linkit.js.map +1 -0
- package/dist/plugins/media-browser.d.ts +6 -0
- package/dist/plugins/media-browser.js +257 -0
- package/dist/plugins/media-browser.js.map +1 -0
- package/dist/plugins/structural-smoke.d.ts +6 -0
- package/dist/plugins/structural-smoke.js +90 -0
- package/dist/plugins/structural-smoke.js.map +1 -0
- package/dist/plugins/visual-regression.d.ts +8 -0
- package/dist/plugins/visual-regression.js +214 -0
- package/dist/plugins/visual-regression.js.map +1 -0
- package/dist/plugins/wysiwyg.d.ts +8 -0
- package/dist/plugins/wysiwyg.js +221 -0
- package/dist/plugins/wysiwyg.js.map +1 -0
- package/dist/runner.d.ts +21 -0
- package/dist/runner.js +293 -0
- package/dist/runner.js.map +1 -0
- package/dist/suppression.d.ts +55 -0
- package/dist/suppression.js +223 -0
- package/dist/suppression.js.map +1 -0
- package/dist/types.d.ts +178 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/modules/bolt_inspect/bolt_inspect.info.yml +6 -0
- package/modules/bolt_inspect/bolt_inspect.services.yml +22 -0
- package/modules/bolt_inspect/composer.json +16 -0
- package/modules/bolt_inspect/drush.services.yml +10 -0
- package/modules/bolt_inspect/src/Drush/Commands/BoltInspectCommands.php +203 -0
- package/modules/bolt_inspect/src/Service/ContentGenerator.php +586 -0
- package/modules/bolt_inspect/src/Service/SiteProfiler.php +362 -0
- package/modules/bolt_inspect/src/Service/TestEntityTracker.php +98 -0
- package/package.json +46 -0
- package/scripts/setup.sh +34 -0
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bolt refresh — sync local environment to match production.
|
|
3
|
+
*
|
|
4
|
+
* Ensures the local codebase and (optionally) database are current
|
|
5
|
+
* before running updates. Exits early on any step failure.
|
|
6
|
+
*/
|
|
7
|
+
import { execFile } from 'child_process';
|
|
8
|
+
import { promisify } from 'util';
|
|
9
|
+
import { createInterface } from 'readline';
|
|
10
|
+
const execFileAsync = promisify(execFile);
|
|
11
|
+
/** Write progress messages to stderr. */
|
|
12
|
+
function log(msg) {
|
|
13
|
+
process.stderr.write(` ${msg}\n`);
|
|
14
|
+
}
|
|
15
|
+
function logOk(msg, durationMs) {
|
|
16
|
+
const timing = durationMs !== undefined ? ` (${formatDuration(durationMs)})` : '';
|
|
17
|
+
process.stderr.write(` ✓ ${msg}${timing}\n`);
|
|
18
|
+
}
|
|
19
|
+
function logFail(msg) {
|
|
20
|
+
process.stderr.write(` ✗ ${msg}\n`);
|
|
21
|
+
}
|
|
22
|
+
function logSkip(msg) {
|
|
23
|
+
process.stderr.write(` ⊘ ${msg}\n`);
|
|
24
|
+
}
|
|
25
|
+
function logWarn(msg) {
|
|
26
|
+
process.stderr.write(` ⚠ ${msg}\n`);
|
|
27
|
+
}
|
|
28
|
+
function formatDuration(ms) {
|
|
29
|
+
if (ms < 1000)
|
|
30
|
+
return `${ms}ms`;
|
|
31
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Run a shell command and return the result.
|
|
35
|
+
*/
|
|
36
|
+
async function exec(command, args, timeoutMs = 300_000) {
|
|
37
|
+
try {
|
|
38
|
+
const { stdout, stderr } = await execFileAsync(command, args, {
|
|
39
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
40
|
+
timeout: timeoutMs,
|
|
41
|
+
});
|
|
42
|
+
return { stdout, stderr, exitCode: 0 };
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
if (err instanceof Error) {
|
|
46
|
+
const execErr = err;
|
|
47
|
+
return {
|
|
48
|
+
stdout: execErr.stdout ?? '',
|
|
49
|
+
stderr: execErr.stderr ?? err.message,
|
|
50
|
+
exitCode: typeof execErr.code === 'number' ? execErr.code : 1,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return { stdout: '', stderr: String(err), exitCode: 1 };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Prompt the user for a yes/no answer. Returns true for yes.
|
|
58
|
+
*/
|
|
59
|
+
async function confirm(question) {
|
|
60
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
61
|
+
return new Promise((resolve) => {
|
|
62
|
+
rl.question(` ${question} (y/N) `, (answer) => {
|
|
63
|
+
rl.close();
|
|
64
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Run a timed step. Returns the step result and aborts if it fails
|
|
70
|
+
* (unless the caller handles it).
|
|
71
|
+
*/
|
|
72
|
+
async function timedStep(name, fn) {
|
|
73
|
+
const start = Date.now();
|
|
74
|
+
const { ok, detail } = await fn();
|
|
75
|
+
const duration = Date.now() - start;
|
|
76
|
+
return {
|
|
77
|
+
step: name,
|
|
78
|
+
status: ok ? 'pass' : 'fail',
|
|
79
|
+
duration,
|
|
80
|
+
detail,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
export async function refreshCommand(options) {
|
|
84
|
+
const steps = [];
|
|
85
|
+
const startTime = Date.now();
|
|
86
|
+
process.stderr.write('\nbolt refresh\n');
|
|
87
|
+
process.stderr.write('━'.repeat(50) + '\n\n');
|
|
88
|
+
// Resolve base branch from options → config → default.
|
|
89
|
+
const baseBranch = options.branch ||
|
|
90
|
+
options.boltConfig?.refresh?.base_branch ||
|
|
91
|
+
'main';
|
|
92
|
+
// --- Step 1: Git safety checks ---
|
|
93
|
+
// 1a. Check for uncommitted changes.
|
|
94
|
+
const statusResult = await exec('git', ['status', '--porcelain']);
|
|
95
|
+
if (statusResult.exitCode !== 0) {
|
|
96
|
+
logFail('Not a git repository or git not available');
|
|
97
|
+
process.exit(2);
|
|
98
|
+
}
|
|
99
|
+
if (statusResult.stdout.trim()) {
|
|
100
|
+
if (!options.yes) {
|
|
101
|
+
logWarn('Uncommitted changes detected:');
|
|
102
|
+
// Show abbreviated file list (max 10 lines).
|
|
103
|
+
const lines = statusResult.stdout.trim().split('\n');
|
|
104
|
+
const shown = lines.slice(0, 10);
|
|
105
|
+
for (const line of shown) {
|
|
106
|
+
process.stderr.write(` ${line}\n`);
|
|
107
|
+
}
|
|
108
|
+
if (lines.length > 10) {
|
|
109
|
+
process.stderr.write(` ... and ${lines.length - 10} more\n`);
|
|
110
|
+
}
|
|
111
|
+
process.stderr.write('\n');
|
|
112
|
+
const proceed = await confirm('Continue anyway? Uncommitted changes will be preserved but may cause conflicts.');
|
|
113
|
+
if (!proceed) {
|
|
114
|
+
log('Aborted. Commit or stash your changes first.');
|
|
115
|
+
process.exit(2);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
logWarn('Uncommitted changes detected (continuing with --yes)');
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
logOk('Working tree clean');
|
|
124
|
+
}
|
|
125
|
+
// 1b. Check for unpushed commits on current branch.
|
|
126
|
+
const currentBranchResult = await exec('git', ['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
127
|
+
const currentBranch = currentBranchResult.stdout.trim();
|
|
128
|
+
if (currentBranch !== baseBranch) {
|
|
129
|
+
log(`Currently on "${currentBranch}", will checkout "${baseBranch}"`);
|
|
130
|
+
}
|
|
131
|
+
const unpushedResult = await exec('git', [
|
|
132
|
+
'log', `origin/${baseBranch}..HEAD`, '--oneline',
|
|
133
|
+
]);
|
|
134
|
+
if (unpushedResult.stdout.trim()) {
|
|
135
|
+
logWarn(`Unpushed commits on current branch (will be left behind after checkout):\n`);
|
|
136
|
+
const commits = unpushedResult.stdout.trim().split('\n').slice(0, 5);
|
|
137
|
+
for (const c of commits) {
|
|
138
|
+
process.stderr.write(` ${c}\n`);
|
|
139
|
+
}
|
|
140
|
+
process.stderr.write('\n');
|
|
141
|
+
}
|
|
142
|
+
// --- Step 2: Checkout base branch ---
|
|
143
|
+
const checkoutStep = await timedStep('checkout', async () => {
|
|
144
|
+
if (currentBranch === baseBranch) {
|
|
145
|
+
logOk(`Already on ${baseBranch}`);
|
|
146
|
+
return { ok: true };
|
|
147
|
+
}
|
|
148
|
+
const result = await exec('git', ['checkout', baseBranch]);
|
|
149
|
+
if (result.exitCode !== 0) {
|
|
150
|
+
logFail(`Failed to checkout ${baseBranch}: ${result.stderr.trim()}`);
|
|
151
|
+
return { ok: false, detail: result.stderr.trim() };
|
|
152
|
+
}
|
|
153
|
+
logOk(`Checked out ${baseBranch}`);
|
|
154
|
+
return { ok: true };
|
|
155
|
+
});
|
|
156
|
+
steps.push(checkoutStep);
|
|
157
|
+
if (checkoutStep.status === 'fail') {
|
|
158
|
+
printSummary(steps, startTime);
|
|
159
|
+
process.exit(2);
|
|
160
|
+
}
|
|
161
|
+
// --- Step 3: Git pull ---
|
|
162
|
+
const pullStep = await timedStep('git pull', async () => {
|
|
163
|
+
log('Pulling latest changes...');
|
|
164
|
+
const result = await exec('git', ['pull', 'origin', baseBranch]);
|
|
165
|
+
if (result.exitCode !== 0) {
|
|
166
|
+
logFail(`git pull failed: ${result.stderr.trim()}`);
|
|
167
|
+
return { ok: false, detail: result.stderr.trim() };
|
|
168
|
+
}
|
|
169
|
+
logOk('git pull');
|
|
170
|
+
return { ok: true };
|
|
171
|
+
});
|
|
172
|
+
steps.push(pullStep);
|
|
173
|
+
if (pullStep.status === 'fail') {
|
|
174
|
+
printSummary(steps, startTime);
|
|
175
|
+
process.exit(2);
|
|
176
|
+
}
|
|
177
|
+
// --- Step 4: Ensure DDEV is running ---
|
|
178
|
+
const ddevStep = await timedStep('ddev check', async () => {
|
|
179
|
+
const describe = await exec('ddev', ['describe', '-j']);
|
|
180
|
+
if (describe.exitCode === 0) {
|
|
181
|
+
logOk('DDEV running');
|
|
182
|
+
return { ok: true };
|
|
183
|
+
}
|
|
184
|
+
// Try to start it.
|
|
185
|
+
log('DDEV not running, starting...');
|
|
186
|
+
const start = await exec('ddev', ['start'], 120_000);
|
|
187
|
+
if (start.exitCode !== 0) {
|
|
188
|
+
logFail(`DDEV start failed: ${start.stderr.trim()}`);
|
|
189
|
+
return { ok: false, detail: start.stderr.trim() };
|
|
190
|
+
}
|
|
191
|
+
logOk('DDEV started');
|
|
192
|
+
return { ok: true };
|
|
193
|
+
});
|
|
194
|
+
steps.push(ddevStep);
|
|
195
|
+
if (ddevStep.status === 'fail') {
|
|
196
|
+
printSummary(steps, startTime);
|
|
197
|
+
process.exit(2);
|
|
198
|
+
}
|
|
199
|
+
// --- Step 5: Composer install ---
|
|
200
|
+
const composerStep = await timedStep('composer install', async () => {
|
|
201
|
+
log('Running composer install...');
|
|
202
|
+
const result = await exec('ddev', ['composer', 'install'], 300_000);
|
|
203
|
+
if (result.exitCode !== 0) {
|
|
204
|
+
logFail(`composer install failed: ${result.stderr.trim()}`);
|
|
205
|
+
return { ok: false, detail: result.stderr.trim() };
|
|
206
|
+
}
|
|
207
|
+
logOk('composer install');
|
|
208
|
+
return { ok: true };
|
|
209
|
+
});
|
|
210
|
+
steps.push(composerStep);
|
|
211
|
+
if (composerStep.status === 'fail') {
|
|
212
|
+
printSummary(steps, startTime);
|
|
213
|
+
process.exit(2);
|
|
214
|
+
}
|
|
215
|
+
// --- Step 6: Database pull (optional) ---
|
|
216
|
+
let pullDb = options.db;
|
|
217
|
+
if (!pullDb && !options.skipDb) {
|
|
218
|
+
// Neither --db nor --skip-db: prompt unless --yes (which defaults to skip).
|
|
219
|
+
if (options.yes) {
|
|
220
|
+
pullDb = false;
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
const dbSource = options.source ||
|
|
224
|
+
options.boltConfig?.refresh?.db?.pantheon_env ||
|
|
225
|
+
'live';
|
|
226
|
+
pullDb = await confirm(`Pull fresh database from ${dbSource}?`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (pullDb) {
|
|
230
|
+
const dbStep = await timedStep('database pull', async () => {
|
|
231
|
+
const dbConfig = options.boltConfig?.refresh?.db;
|
|
232
|
+
const source = dbConfig?.source ?? 'pantheon';
|
|
233
|
+
if (source === 'file') {
|
|
234
|
+
// Import from file.
|
|
235
|
+
const filePath = dbConfig?.file_path;
|
|
236
|
+
if (!filePath) {
|
|
237
|
+
logFail('refresh.db.file_path not set in .bolt.yml');
|
|
238
|
+
return { ok: false, detail: 'No file path configured' };
|
|
239
|
+
}
|
|
240
|
+
log(`Importing database from ${filePath}...`);
|
|
241
|
+
const result = await exec('ddev', ['import-db', `--file=${filePath}`], 600_000);
|
|
242
|
+
if (result.exitCode !== 0) {
|
|
243
|
+
logFail(`Database import failed: ${result.stderr.trim()}`);
|
|
244
|
+
return { ok: false, detail: result.stderr.trim() };
|
|
245
|
+
}
|
|
246
|
+
logOk('Database imported from file');
|
|
247
|
+
return { ok: true };
|
|
248
|
+
}
|
|
249
|
+
// Default: ddev pull <provider> (e.g., ddev pull pantheon).
|
|
250
|
+
// The provider name matches the .ddev/providers/<name>.yaml config.
|
|
251
|
+
const provider = source;
|
|
252
|
+
log(`Pulling database via ddev pull ${provider}...`);
|
|
253
|
+
const result = await exec('ddev', ['pull', provider, '-y'], 600_000);
|
|
254
|
+
if (result.exitCode !== 0) {
|
|
255
|
+
logFail(`ddev pull ${provider} failed: ${result.stderr.trim()}`);
|
|
256
|
+
log('Ensure your DDEV provider is configured in .ddev/providers/');
|
|
257
|
+
return { ok: false, detail: result.stderr.trim() };
|
|
258
|
+
}
|
|
259
|
+
logOk('Database pulled');
|
|
260
|
+
return { ok: true };
|
|
261
|
+
});
|
|
262
|
+
steps.push(dbStep);
|
|
263
|
+
if (dbStep.status === 'fail') {
|
|
264
|
+
printSummary(steps, startTime);
|
|
265
|
+
process.exit(2);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
steps.push({ step: 'database pull', status: 'skip', duration: 0, detail: 'Skipped' });
|
|
270
|
+
logSkip('Database pull skipped');
|
|
271
|
+
}
|
|
272
|
+
// --- Step 7: Cache rebuild (pre-updb) ---
|
|
273
|
+
const cr1Step = await timedStep('cache rebuild', async () => {
|
|
274
|
+
log('Clearing caches...');
|
|
275
|
+
const result = await exec('ddev', ['drush', 'cr']);
|
|
276
|
+
if (result.exitCode !== 0) {
|
|
277
|
+
logFail(`drush cr failed: ${result.stderr.trim()}`);
|
|
278
|
+
return { ok: false, detail: result.stderr.trim() };
|
|
279
|
+
}
|
|
280
|
+
logOk('Cache cleared');
|
|
281
|
+
return { ok: true };
|
|
282
|
+
});
|
|
283
|
+
steps.push(cr1Step);
|
|
284
|
+
if (cr1Step.status === 'fail') {
|
|
285
|
+
printSummary(steps, startTime);
|
|
286
|
+
process.exit(2);
|
|
287
|
+
}
|
|
288
|
+
// --- Step 8: Database updates ---
|
|
289
|
+
const updbStep = await timedStep('database updates', async () => {
|
|
290
|
+
log('Running database updates...');
|
|
291
|
+
const result = await exec('ddev', ['drush', 'updb', '-y']);
|
|
292
|
+
if (result.exitCode !== 0) {
|
|
293
|
+
logFail(`drush updb failed: ${result.stderr.trim()}`);
|
|
294
|
+
return { ok: false, detail: result.stderr.trim() };
|
|
295
|
+
}
|
|
296
|
+
// Check if any updates were applied.
|
|
297
|
+
if (result.stdout.includes('No pending updates')) {
|
|
298
|
+
logOk('No pending database updates');
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
logOk('Database updates applied');
|
|
302
|
+
}
|
|
303
|
+
return { ok: true };
|
|
304
|
+
});
|
|
305
|
+
steps.push(updbStep);
|
|
306
|
+
if (updbStep.status === 'fail') {
|
|
307
|
+
printSummary(steps, startTime);
|
|
308
|
+
process.exit(2);
|
|
309
|
+
}
|
|
310
|
+
// --- Step 9: Config import ---
|
|
311
|
+
const cimStep = await timedStep('config import', async () => {
|
|
312
|
+
log('Importing configuration...');
|
|
313
|
+
const result = await exec('ddev', ['drush', 'cim', '-y']);
|
|
314
|
+
if (result.exitCode !== 0) {
|
|
315
|
+
// cim returns non-zero if there are no config changes to import — that's ok.
|
|
316
|
+
if (result.stderr.includes('There are no changes to import') ||
|
|
317
|
+
result.stdout.includes('There are no changes to import') ||
|
|
318
|
+
result.stderr.includes('already up to date')) {
|
|
319
|
+
logOk('Configuration already in sync');
|
|
320
|
+
return { ok: true };
|
|
321
|
+
}
|
|
322
|
+
logFail(`drush cim failed: ${result.stderr.trim()}`);
|
|
323
|
+
return { ok: false, detail: result.stderr.trim() };
|
|
324
|
+
}
|
|
325
|
+
logOk('Configuration imported');
|
|
326
|
+
return { ok: true };
|
|
327
|
+
});
|
|
328
|
+
steps.push(cimStep);
|
|
329
|
+
if (cimStep.status === 'fail') {
|
|
330
|
+
printSummary(steps, startTime);
|
|
331
|
+
process.exit(2);
|
|
332
|
+
}
|
|
333
|
+
// --- Step 10: Final cache rebuild ---
|
|
334
|
+
const cr2Step = await timedStep('final cache rebuild', async () => {
|
|
335
|
+
const result = await exec('ddev', ['drush', 'cr']);
|
|
336
|
+
if (result.exitCode !== 0) {
|
|
337
|
+
logFail(`Final drush cr failed: ${result.stderr.trim()}`);
|
|
338
|
+
return { ok: false, detail: result.stderr.trim() };
|
|
339
|
+
}
|
|
340
|
+
logOk('Final cache cleared');
|
|
341
|
+
return { ok: true };
|
|
342
|
+
});
|
|
343
|
+
steps.push(cr2Step);
|
|
344
|
+
if (cr2Step.status === 'fail') {
|
|
345
|
+
printSummary(steps, startTime);
|
|
346
|
+
process.exit(2);
|
|
347
|
+
}
|
|
348
|
+
// --- Summary ---
|
|
349
|
+
process.stderr.write('\n');
|
|
350
|
+
printSummary(steps, startTime);
|
|
351
|
+
process.stderr.write('\nEnvironment refreshed. Next steps:\n');
|
|
352
|
+
process.stderr.write(' bolt doctor — verify environment health\n');
|
|
353
|
+
process.stderr.write(' bolt test — run test suite\n');
|
|
354
|
+
process.stderr.write(' bolt update — run module updates\n');
|
|
355
|
+
process.stderr.write('\n');
|
|
356
|
+
}
|
|
357
|
+
function printSummary(steps, startTime) {
|
|
358
|
+
const total = Date.now() - startTime;
|
|
359
|
+
const passed = steps.filter((s) => s.status === 'pass').length;
|
|
360
|
+
const failed = steps.filter((s) => s.status === 'fail').length;
|
|
361
|
+
const skipped = steps.filter((s) => s.status === 'skip').length;
|
|
362
|
+
process.stderr.write(`Refresh: ${passed} passed`);
|
|
363
|
+
if (skipped > 0)
|
|
364
|
+
process.stderr.write(`, ${skipped} skipped`);
|
|
365
|
+
if (failed > 0)
|
|
366
|
+
process.stderr.write(`, ${failed} failed`);
|
|
367
|
+
process.stderr.write(` (${formatDuration(total)})\n`);
|
|
368
|
+
if (failed > 0) {
|
|
369
|
+
const failedStep = steps.find((s) => s.status === 'fail');
|
|
370
|
+
if (failedStep?.detail) {
|
|
371
|
+
process.stderr.write(`\nFailed at "${failedStep.step}": ${failedStep.detail}\n`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
//# sourceMappingURL=refresh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../src/commands/refresh.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAA0B,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAG3C,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAwB1C,yCAAyC;AACzC,SAAS,GAAG,CAAC,GAAW;IACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,KAAK,CAAC,GAAW,EAAE,UAAmB;IAC7C,MAAM,MAAM,GAAG,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAClF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,MAAM,IAAI,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,cAAc,CAAC,EAAU;IAChC,IAAI,EAAE,GAAG,IAAI;QAAE,OAAO,GAAG,EAAE,IAAI,CAAC;IAChC,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,IAAI,CACjB,OAAe,EACf,IAAc,EACd,SAAS,GAAG,OAAO;IAEnB,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE;YAC5D,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;YAC3B,OAAO,EAAE,SAAS;SACnB,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACzC,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,GAA+D,CAAC;YAChF,OAAO;gBACL,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;gBAC5B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO;gBACrC,QAAQ,EAAE,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aAC9D,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IAC1D,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,OAAO,CAAC,QAAgB;IACrC,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,KAAK,QAAQ,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;YAC7C,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,GAAG,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,SAAS,CACtB,IAAY,EACZ,EAAmD;IAEnD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;IACpC,OAAO;QACL,IAAI,EAAE,IAAI;QACV,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;QAC5B,QAAQ;QACR,MAAM;KACP,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAuB;IAC1D,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACzC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC;IAE9C,uDAAuD;IACvD,MAAM,UAAU,GACd,OAAO,CAAC,MAAM;QACd,OAAO,CAAC,UAAU,EAAE,OAAO,EAAE,WAAW;QACxC,MAAM,CAAC;IAET,oCAAoC;IAEpC,qCAAqC;IACrC,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC;IAClE,IAAI,YAAY,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,2CAA2C,CAAC,CAAC;QACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YACjB,OAAO,CAAC,+BAA+B,CAAC,CAAC;YACzC,6CAA6C;YAC7C,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACrD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;YACxC,CAAC;YACD,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;gBACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,KAAK,CAAC,MAAM,GAAG,EAAE,SAAS,CAAC,CAAC;YAClE,CAAC;YACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,iFAAiF,CAAC,CAAC;YACjH,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,GAAG,CAAC,8CAA8C,CAAC,CAAC;gBACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,sDAAsD,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC9B,CAAC;IAED,oDAAoD;IACpD,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;IACrF,MAAM,aAAa,GAAG,mBAAmB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAExD,IAAI,aAAa,KAAK,UAAU,EAAE,CAAC;QACjC,GAAG,CAAC,iBAAiB,aAAa,qBAAqB,UAAU,GAAG,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE;QACvC,KAAK,EAAE,UAAU,UAAU,QAAQ,EAAE,WAAW;KACjD,CAAC,CAAC;IACH,IAAI,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACjC,OAAO,CAAC,4EAA4E,CAAC,CAAC;QACtF,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACrE,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,uCAAuC;IACvC,MAAM,YAAY,GAAG,MAAM,SAAS,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE;QAC1D,IAAI,aAAa,KAAK,UAAU,EAAE,CAAC;YACjC,KAAK,CAAC,cAAc,UAAU,EAAE,CAAC,CAAC;YAClC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACtB,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;QAC3D,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,sBAAsB,UAAU,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACrE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACrD,CAAC;QACD,KAAK,CAAC,eAAe,UAAU,EAAE,CAAC,CAAC;QACnC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACzB,IAAI,YAAY,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QACnC,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,2BAA2B;IAC3B,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE;QACtD,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;QACjE,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,oBAAoB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACpD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACrD,CAAC;QACD,KAAK,CAAC,UAAU,CAAC,CAAC;QAClB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrB,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC/B,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,yCAAyC;IACzC,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;QACxD,IAAI,QAAQ,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC5B,KAAK,CAAC,cAAc,CAAC,CAAC;YACtB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACtB,CAAC;QACD,mBAAmB;QACnB,GAAG,CAAC,+BAA+B,CAAC,CAAC;QACrC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;QACrD,IAAI,KAAK,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,sBAAsB,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACrD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACpD,CAAC;QACD,KAAK,CAAC,cAAc,CAAC,CAAC;QACtB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrB,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC/B,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,mCAAmC;IACnC,MAAM,YAAY,GAAG,MAAM,SAAS,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;QAClE,GAAG,CAAC,6BAA6B,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;QACpE,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,4BAA4B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC5D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACrD,CAAC;QACD,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAC1B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACzB,IAAI,YAAY,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QACnC,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,2CAA2C;IAC3C,IAAI,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;IACxB,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QAC/B,4EAA4E;QAC5E,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YAChB,MAAM,GAAG,KAAK,CAAC;QACjB,CAAC;aAAM,CAAC;YACN,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM;gBAC7B,OAAO,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY;gBAC7C,MAAM,CAAC;YACT,MAAM,GAAG,MAAM,OAAO,CAAC,4BAA4B,QAAQ,GAAG,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;YACzD,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;YACjD,MAAM,MAAM,GAAG,QAAQ,EAAE,MAAM,IAAI,UAAU,CAAC;YAE9C,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBACtB,oBAAoB;gBACpB,MAAM,QAAQ,GAAG,QAAQ,EAAE,SAAS,CAAC;gBACrC,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,OAAO,CAAC,2CAA2C,CAAC,CAAC;oBACrD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;gBAC1D,CAAC;gBACD,GAAG,CAAC,2BAA2B,QAAQ,KAAK,CAAC,CAAC;gBAC9C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,UAAU,QAAQ,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;gBAChF,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;oBAC1B,OAAO,CAAC,2BAA2B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;oBAC3D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;gBACrD,CAAC;gBACD,KAAK,CAAC,6BAA6B,CAAC,CAAC;gBACrC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;YACtB,CAAC;YAED,4DAA4D;YAC5D,oEAAoE;YACpE,MAAM,QAAQ,GAAG,MAAM,CAAC;YACxB,GAAG,CAAC,kCAAkC,QAAQ,KAAK,CAAC,CAAC;YACrD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;YACrE,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;gBAC1B,OAAO,CAAC,aAAa,QAAQ,YAAY,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACjE,GAAG,CAAC,6DAA6D,CAAC,CAAC;gBACnE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YACrD,CAAC;YACD,KAAK,CAAC,iBAAiB,CAAC,CAAC;YACzB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnB,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC7B,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QACtF,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACnC,CAAC;IAED,2CAA2C;IAC3C,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;QAC1D,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAC1B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QACnD,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,oBAAoB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACpD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACrD,CAAC;QACD,KAAK,CAAC,eAAe,CAAC,CAAC;QACvB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpB,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC9B,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,mCAAmC;IACnC,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;QAC9D,GAAG,CAAC,6BAA6B,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;QAC3D,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,sBAAsB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACtD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACrD,CAAC;QACD,qCAAqC;QACrC,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;YACjD,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,0BAA0B,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrB,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC/B,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,gCAAgC;IAChC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;QAC1D,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QAC1D,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,6EAA6E;YAC7E,IACE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,gCAAgC,CAAC;gBACxD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,gCAAgC,CAAC;gBACxD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAC5C,CAAC;gBACD,KAAK,CAAC,+BAA+B,CAAC,CAAC;gBACvC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;YACtB,CAAC;YACD,OAAO,CAAC,qBAAqB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACrD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACrD,CAAC;QACD,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAChC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpB,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC9B,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,uCAAuC;IACvC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QACnD,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,0BAA0B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC1D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACrD,CAAC;QACD,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAC7B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpB,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC9B,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,kBAAkB;IAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3B,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAE/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC/D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACvE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAC5D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAChE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,YAAY,CAAC,KAAmB,EAAE,SAAiB;IAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IACrC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAC/D,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAC/D,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAEhE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,MAAM,SAAS,CAAC,CAAC;IAClD,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,OAAO,UAAU,CAAC,CAAC;IAC9D,IAAI,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,MAAM,SAAS,CAAC,CAAC;IAC3D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAEtD,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;QAC1D,IAAI,UAAU,EAAE,MAAM,EAAE,CAAC;YACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,UAAU,CAAC,IAAI,MAAM,UAAU,CAAC,MAAM,IAAI,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bolt suppress — capture current failures as a suppression baseline.
|
|
3
|
+
*/
|
|
4
|
+
import type { ExecutionMode } from '../types.js';
|
|
5
|
+
export interface SuppressOptions {
|
|
6
|
+
url?: string;
|
|
7
|
+
dryRun: boolean;
|
|
8
|
+
mode: ExecutionMode;
|
|
9
|
+
}
|
|
10
|
+
export declare function suppressCommand(opts: SuppressOptions): Promise<void>;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bolt suppress — capture current failures as a suppression baseline.
|
|
3
|
+
*/
|
|
4
|
+
import { existsSync } from 'fs';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import { DdevAdapter } from '../adapters/ddev.js';
|
|
7
|
+
import { runTests } from '../runner.js';
|
|
8
|
+
import { loadConfig } from '../config.js';
|
|
9
|
+
import { generateSuppressionConfig, writeSuppressionConfig } from '../suppression.js';
|
|
10
|
+
export async function suppressCommand(opts) {
|
|
11
|
+
const config = loadConfig();
|
|
12
|
+
const adapter = new DdevAdapter();
|
|
13
|
+
// Verify DDEV connectivity.
|
|
14
|
+
const connected = await adapter.canConnect();
|
|
15
|
+
if (!connected) {
|
|
16
|
+
process.stderr.write('Error: Cannot connect to DDEV. Is it running?\n' +
|
|
17
|
+
'Run this command from your Drupal project directory where DDEV is configured.\n');
|
|
18
|
+
process.exit(2);
|
|
19
|
+
}
|
|
20
|
+
// Auto-detect URL from DDEV if not provided.
|
|
21
|
+
let url = opts.url ?? '';
|
|
22
|
+
if (!url) {
|
|
23
|
+
const detected = await adapter.getSiteUrl();
|
|
24
|
+
if (!detected) {
|
|
25
|
+
process.stderr.write('Error: Could not detect site URL from DDEV. Pass --url explicitly.\n');
|
|
26
|
+
process.exit(2);
|
|
27
|
+
}
|
|
28
|
+
url = detected;
|
|
29
|
+
}
|
|
30
|
+
// Validate URL.
|
|
31
|
+
try {
|
|
32
|
+
new URL(url);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
process.stderr.write(`Error: Invalid URL "${url}". Expected format: https://site.ddev.site\n`);
|
|
36
|
+
process.exit(2);
|
|
37
|
+
}
|
|
38
|
+
// Run tests with suppression disabled — we need raw failures to build the baseline.
|
|
39
|
+
process.stderr.write('Running tests to capture baseline...\n');
|
|
40
|
+
const testOptions = {
|
|
41
|
+
url,
|
|
42
|
+
mode: opts.mode,
|
|
43
|
+
output: 'json',
|
|
44
|
+
exitCode: false,
|
|
45
|
+
failOn: 'critical',
|
|
46
|
+
headed: false,
|
|
47
|
+
configSkip: config.plugins.skip.length > 0 ? config.plugins.skip : undefined,
|
|
48
|
+
boltConfig: config,
|
|
49
|
+
skipSuppression: true,
|
|
50
|
+
};
|
|
51
|
+
let report;
|
|
52
|
+
try {
|
|
53
|
+
report = await runTests(adapter, testOptions);
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
process.stderr.write(`Error running tests: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
57
|
+
process.exit(2);
|
|
58
|
+
}
|
|
59
|
+
// Collect failures (only raw failures, not already-suppressed).
|
|
60
|
+
const failures = report.results.filter((r) => r.status === 'fail');
|
|
61
|
+
if (failures.length === 0) {
|
|
62
|
+
process.stderr.write('No failures found — nothing to suppress.\n');
|
|
63
|
+
process.stderr.write(`${report.summary.passed} tests passed, ${report.summary.skipped} skipped.\n`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
// Generate suppression config.
|
|
67
|
+
const content = generateSuppressionConfig(failures);
|
|
68
|
+
if (opts.dryRun) {
|
|
69
|
+
process.stderr.write(`\nDry run — would create .boltrc.yml with ${failures.length} suppression(s):\n\n`);
|
|
70
|
+
process.stdout.write(content);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// Write .boltrc.yml.
|
|
74
|
+
const cwd = process.cwd();
|
|
75
|
+
const existingPath = join(cwd, '.boltrc.yml');
|
|
76
|
+
const existed = existsSync(existingPath);
|
|
77
|
+
const path = writeSuppressionConfig(cwd, content);
|
|
78
|
+
if (existed) {
|
|
79
|
+
process.stderr.write(`Updated ${path} with ${failures.length} suppression(s).\n`);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
process.stderr.write(`Created ${path} with ${failures.length} suppression(s).\n`);
|
|
83
|
+
}
|
|
84
|
+
process.stderr.write('Next run of `bolt test` will show these as suppressed instead of failed.\n');
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=suppress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suppress.js","sourceRoot":"","sources":["../../src/commands/suppress.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bolt test — run tests against a Drupal site.
|
|
3
|
+
*/
|
|
4
|
+
import { writeFileSync, mkdirSync } from 'fs';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import { DdevAdapter } from '../adapters/ddev.js';
|
|
7
|
+
import { runTests } from '../runner.js';
|
|
8
|
+
import { formatText } from '../formatters/text.js';
|
|
9
|
+
import { formatJson } from '../formatters/json.js';
|
|
10
|
+
import { formatMarkdown } from '../formatters/markdown.js';
|
|
11
|
+
import { loadConfig } from '../config.js';
|
|
12
|
+
export async function testCommand(options) {
|
|
13
|
+
const config = loadConfig();
|
|
14
|
+
const adapter = new DdevAdapter();
|
|
15
|
+
// Apply .bolt.yml plugin skips to the user's plugin selection.
|
|
16
|
+
if (config.plugins.skip.length > 0 && !options.plugins) {
|
|
17
|
+
// No explicit --plugins flag: pass skips to runner via config.
|
|
18
|
+
options.configSkip = config.plugins.skip;
|
|
19
|
+
}
|
|
20
|
+
// Pass config to options for runner access.
|
|
21
|
+
options.boltConfig = config;
|
|
22
|
+
// Verify DDEV connectivity.
|
|
23
|
+
const connected = await adapter.canConnect();
|
|
24
|
+
if (!connected) {
|
|
25
|
+
process.stderr.write('Error: Cannot connect to DDEV. Is it running?\n' +
|
|
26
|
+
'Run this command from your Drupal project directory where DDEV is configured.\n');
|
|
27
|
+
process.exit(2);
|
|
28
|
+
}
|
|
29
|
+
// Auto-detect URL from DDEV if not provided.
|
|
30
|
+
if (!options.url) {
|
|
31
|
+
const detected = await adapter.getSiteUrl();
|
|
32
|
+
if (!detected) {
|
|
33
|
+
process.stderr.write('Error: Could not detect site URL from DDEV. Pass --url explicitly.\n');
|
|
34
|
+
process.exit(2);
|
|
35
|
+
}
|
|
36
|
+
options.url = detected;
|
|
37
|
+
}
|
|
38
|
+
// Validate URL.
|
|
39
|
+
try {
|
|
40
|
+
new URL(options.url);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
process.stderr.write(`Error: Invalid URL "${options.url}". Expected format: https://site.ddev.site\n`);
|
|
44
|
+
process.exit(2);
|
|
45
|
+
}
|
|
46
|
+
// Run tests.
|
|
47
|
+
let report;
|
|
48
|
+
try {
|
|
49
|
+
report = await runTests(adapter, options);
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
53
|
+
process.exit(2);
|
|
54
|
+
}
|
|
55
|
+
// Format output.
|
|
56
|
+
let formatted;
|
|
57
|
+
switch (options.output) {
|
|
58
|
+
case 'json':
|
|
59
|
+
formatted = formatJson(report);
|
|
60
|
+
break;
|
|
61
|
+
case 'markdown':
|
|
62
|
+
formatted = formatMarkdown(report, options.failOn);
|
|
63
|
+
break;
|
|
64
|
+
default:
|
|
65
|
+
formatted = formatText(report, options.failOn);
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
// Write to stdout.
|
|
69
|
+
process.stdout.write(formatted + '\n');
|
|
70
|
+
// Write report file if requested.
|
|
71
|
+
if (options.report) {
|
|
72
|
+
writeFileSync(options.report, formatted, 'utf-8');
|
|
73
|
+
if (options.output !== 'json') {
|
|
74
|
+
process.stderr.write(`Report written to ${options.report}\n`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Auto-log every run to .bolt/logs/ with timestamped markdown + JSON.
|
|
78
|
+
const logDir = join(process.cwd(), '.bolt', 'logs');
|
|
79
|
+
try {
|
|
80
|
+
mkdirSync(logDir, { recursive: true });
|
|
81
|
+
const ts = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
|
|
82
|
+
const mdPath = join(logDir, `${ts}.md`);
|
|
83
|
+
const jsonPath = join(logDir, `${ts}.json`);
|
|
84
|
+
writeFileSync(mdPath, formatMarkdown(report, options.failOn), 'utf-8');
|
|
85
|
+
writeFileSync(jsonPath, formatJson(report), 'utf-8');
|
|
86
|
+
process.stderr.write(` Log saved to .bolt/logs/${ts}.md\n`);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Non-fatal — don't block test results if logging fails.
|
|
90
|
+
}
|
|
91
|
+
// Exit code: fail only if unsuppressed failures meet or exceed --fail-on threshold.
|
|
92
|
+
if (options.exitCode) {
|
|
93
|
+
const severityRank = {
|
|
94
|
+
critical: 3,
|
|
95
|
+
major: 2,
|
|
96
|
+
minor: 1,
|
|
97
|
+
info: 0,
|
|
98
|
+
};
|
|
99
|
+
const threshold = severityRank[options.failOn];
|
|
100
|
+
const qualifying = report.results.filter((r) => r.status === 'fail' && severityRank[r.severity] >= threshold);
|
|
101
|
+
if (qualifying.length > 0) {
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bolt update — automated Drupal module/core updates with per-module testing.
|
|
3
|
+
*
|
|
4
|
+
* For each outdated package: creates a branch, updates, tests, and
|
|
5
|
+
* commits (or rolls back). Produces a summary report at the end.
|
|
6
|
+
*/
|
|
7
|
+
import type { BoltConfig } from '../config.js';
|
|
8
|
+
export interface UpdateOptions {
|
|
9
|
+
/** Update a specific module (Composer package name). */
|
|
10
|
+
module?: string;
|
|
11
|
+
/** Update all outdated packages. */
|
|
12
|
+
all: boolean;
|
|
13
|
+
/** Only security updates. */
|
|
14
|
+
securityOnly: boolean;
|
|
15
|
+
/** Show what would be updated without doing it. */
|
|
16
|
+
dryRun: boolean;
|
|
17
|
+
/** Skip the pre-update refresh step. */
|
|
18
|
+
skipRefresh: boolean;
|
|
19
|
+
/** Skip baseline test. */
|
|
20
|
+
skipTest: boolean;
|
|
21
|
+
/** Skip confirmation prompts. */
|
|
22
|
+
yes: boolean;
|
|
23
|
+
/** Resolved .bolt.yml config. */
|
|
24
|
+
boltConfig?: BoltConfig;
|
|
25
|
+
}
|
|
26
|
+
export declare function updateCommand(options: UpdateOptions): Promise<void>;
|