@vibe-validate/cli 0.17.6-rc.2 → 0.18.0-rc.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/bin/vibe-validate +4 -0
- package/dist/bin/vibe-validate.js +4 -0
- package/dist/bin/vibe-validate.js.map +1 -1
- package/dist/bin/vv +4 -0
- package/dist/commands/cleanup.d.ts.map +1 -1
- package/dist/commands/cleanup.js +5 -2
- package/dist/commands/cleanup.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +3 -1
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/create-extractor.d.ts.map +1 -1
- package/dist/commands/create-extractor.js +3 -1
- package/dist/commands/create-extractor.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +11 -5
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/generate-workflow.d.ts.map +1 -1
- package/dist/commands/generate-workflow.js +6 -2
- package/dist/commands/generate-workflow.js.map +1 -1
- package/dist/commands/history.d.ts.map +1 -1
- package/dist/commands/history.js +23 -13
- package/dist/commands/history.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +3 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/pre-commit.d.ts.map +1 -1
- package/dist/commands/pre-commit.js +5 -2
- package/dist/commands/pre-commit.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +12 -10
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/state.d.ts.map +1 -1
- package/dist/commands/state.js +15 -10
- package/dist/commands/state.js.map +1 -1
- package/dist/commands/sync-check.js +5 -5
- package/dist/commands/sync-check.js.map +1 -1
- package/dist/commands/watch-pr.d.ts +16 -0
- package/dist/commands/watch-pr.d.ts.map +1 -1
- package/dist/commands/watch-pr.js +572 -318
- package/dist/commands/watch-pr.js.map +1 -1
- package/dist/schemas/watch-pr-result.schema.d.ts +2010 -0
- package/dist/schemas/watch-pr-result.schema.d.ts.map +1 -0
- package/dist/schemas/watch-pr-result.schema.js +335 -0
- package/dist/schemas/watch-pr-result.schema.js.map +1 -0
- package/dist/schemas/watch-pr-schema.d.ts +6 -6
- package/dist/services/cache-manager.d.ts +113 -0
- package/dist/services/cache-manager.d.ts.map +1 -0
- package/dist/services/cache-manager.js +211 -0
- package/dist/services/cache-manager.js.map +1 -0
- package/dist/services/ci-providers/github-actions.d.ts.map +1 -1
- package/dist/services/ci-providers/github-actions.js +10 -16
- package/dist/services/ci-providers/github-actions.js.map +1 -1
- package/dist/services/external-check-extractor.d.ts +66 -0
- package/dist/services/external-check-extractor.d.ts.map +1 -0
- package/dist/services/external-check-extractor.js +114 -0
- package/dist/services/external-check-extractor.js.map +1 -0
- package/dist/services/extraction-mode-detector.d.ts +85 -0
- package/dist/services/extraction-mode-detector.d.ts.map +1 -0
- package/dist/services/extraction-mode-detector.js +200 -0
- package/dist/services/extraction-mode-detector.js.map +1 -0
- package/dist/services/github-fetcher.d.ts +210 -0
- package/dist/services/github-fetcher.d.ts.map +1 -0
- package/dist/services/github-fetcher.js +412 -0
- package/dist/services/github-fetcher.js.map +1 -0
- package/dist/services/history-summary-builder.d.ts +74 -0
- package/dist/services/history-summary-builder.d.ts.map +1 -0
- package/dist/services/history-summary-builder.js +199 -0
- package/dist/services/history-summary-builder.js.map +1 -0
- package/dist/services/watch-pr-orchestrator.d.ts +119 -0
- package/dist/services/watch-pr-orchestrator.d.ts.map +1 -0
- package/dist/services/watch-pr-orchestrator.js +420 -0
- package/dist/services/watch-pr-orchestrator.js.map +1 -0
- package/dist/utils/command-name.d.ts +21 -0
- package/dist/utils/command-name.d.ts.map +1 -0
- package/dist/utils/command-name.js +45 -0
- package/dist/utils/command-name.js.map +1 -0
- package/dist/utils/pid-lock.d.ts.map +1 -1
- package/dist/utils/pid-lock.js +3 -3
- package/dist/utils/pid-lock.js.map +1 -1
- package/dist/utils/secret-scanning.d.ts +1 -1
- package/dist/utils/secret-scanning.d.ts.map +1 -1
- package/dist/utils/secret-scanning.js +32 -4
- package/dist/utils/secret-scanning.js.map +1 -1
- package/dist/utils/temp-files.d.ts.map +1 -1
- package/dist/utils/temp-files.js +2 -2
- package/dist/utils/temp-files.js.map +1 -1
- package/dist/utils/validate-workflow.js +7 -7
- package/dist/utils/validate-workflow.js.map +1 -1
- package/package.json +7 -7
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WatchPROrchestrator - Coordinate all components to build complete WatchPRResult
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* - Coordinate data fetching (PR metadata, checks, history, changes)
|
|
6
|
+
* - Extract errors from check logs (matrix + non-matrix modes)
|
|
7
|
+
* - Extract external check details (codecov, SonarCloud, etc.)
|
|
8
|
+
* - Build complete WatchPRResult with validation
|
|
9
|
+
* - Generate intelligent guidance
|
|
10
|
+
* - Handle caching (save/retrieve results)
|
|
11
|
+
* - Select output format (YAML on failure, text on success)
|
|
12
|
+
*
|
|
13
|
+
* @packageDocumentation
|
|
14
|
+
*/
|
|
15
|
+
import { CacheManager } from './cache-manager.js';
|
|
16
|
+
import { CodecovExtractor, ExternalExtractorRegistry, SonarCloudExtractor, } from './external-check-extractor.js';
|
|
17
|
+
import { ExtractionModeDetector } from './extraction-mode-detector.js';
|
|
18
|
+
import { GitHubFetcher } from './github-fetcher.js';
|
|
19
|
+
import { HistorySummaryBuilder } from './history-summary-builder.js';
|
|
20
|
+
/**
|
|
21
|
+
* WatchPROrchestrator - Build complete WatchPRResult
|
|
22
|
+
*/
|
|
23
|
+
export class WatchPROrchestrator {
|
|
24
|
+
owner;
|
|
25
|
+
repo;
|
|
26
|
+
fetcher;
|
|
27
|
+
historyBuilder;
|
|
28
|
+
extractionDetector;
|
|
29
|
+
externalCheckExtractor;
|
|
30
|
+
cacheManager;
|
|
31
|
+
constructor(owner, repo) {
|
|
32
|
+
this.owner = owner;
|
|
33
|
+
this.repo = repo;
|
|
34
|
+
this.fetcher = new GitHubFetcher(owner, repo);
|
|
35
|
+
this.historyBuilder = new HistorySummaryBuilder(owner, repo);
|
|
36
|
+
this.extractionDetector = new ExtractionModeDetector();
|
|
37
|
+
// Initialize external check extractor registry
|
|
38
|
+
this.externalCheckExtractor = new ExternalExtractorRegistry();
|
|
39
|
+
this.externalCheckExtractor.register(new CodecovExtractor());
|
|
40
|
+
this.externalCheckExtractor.register(new SonarCloudExtractor());
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build complete WatchPRResult
|
|
44
|
+
*
|
|
45
|
+
* @param prNumber - PR number
|
|
46
|
+
* @param options - Options (useCache, forceFetch)
|
|
47
|
+
* @returns Complete WatchPRResult
|
|
48
|
+
*/
|
|
49
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
50
|
+
async buildResult(prNumber, options = {}) {
|
|
51
|
+
const { useCache = true } = options;
|
|
52
|
+
// Initialize cache manager if caching enabled (for logs only)
|
|
53
|
+
if (useCache && !this.cacheManager) {
|
|
54
|
+
this.cacheManager = new CacheManager(`${this.owner}/${this.repo}`, prNumber);
|
|
55
|
+
}
|
|
56
|
+
// Always fetch fresh PR metadata and checks from GitHub
|
|
57
|
+
// Cache is ONLY used for expensive log downloads, NOT for status
|
|
58
|
+
const prMetadata = await this.fetcher.fetchPRDetails(prNumber);
|
|
59
|
+
// Fetch checks
|
|
60
|
+
const checks = await this.fetcher.fetchChecks(prNumber);
|
|
61
|
+
// Classify checks into GitHub Actions vs external
|
|
62
|
+
const githubActions = [];
|
|
63
|
+
const rawExternalChecks = [];
|
|
64
|
+
for (const check of checks) {
|
|
65
|
+
if (check.type === 'github_action') {
|
|
66
|
+
// GitHub Action check - may have extraction
|
|
67
|
+
if (!check.run_id ||
|
|
68
|
+
!check.workflow ||
|
|
69
|
+
!check.started_at ||
|
|
70
|
+
!check.duration) {
|
|
71
|
+
continue; // Skip invalid checks
|
|
72
|
+
}
|
|
73
|
+
const actionCheck = {
|
|
74
|
+
name: check.name,
|
|
75
|
+
status: check.status,
|
|
76
|
+
conclusion: check.conclusion,
|
|
77
|
+
run_id: check.run_id,
|
|
78
|
+
workflow: check.workflow,
|
|
79
|
+
started_at: check.started_at,
|
|
80
|
+
duration: check.duration,
|
|
81
|
+
};
|
|
82
|
+
// Try to extract errors if check failed
|
|
83
|
+
if (check.conclusion === 'failure' && check.run_id) {
|
|
84
|
+
// Use retry logic to handle GitHub API race condition (Issue #4)
|
|
85
|
+
const logs = await this.fetchLogsWithRetry(check.run_id);
|
|
86
|
+
if (logs) {
|
|
87
|
+
const extraction = await this.extractionDetector.detectAndExtract(actionCheck, logs);
|
|
88
|
+
if (extraction) {
|
|
89
|
+
actionCheck.extraction = extraction;
|
|
90
|
+
}
|
|
91
|
+
// Save logs to cache
|
|
92
|
+
if (this.cacheManager) {
|
|
93
|
+
await this.cacheManager.saveLog(check.run_id, logs);
|
|
94
|
+
if (extraction) {
|
|
95
|
+
await this.cacheManager.saveExtraction(check.run_id, extraction);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// If logs are null, gracefully continue without extraction
|
|
100
|
+
// No noisy error output (Issue #4 fix)
|
|
101
|
+
}
|
|
102
|
+
githubActions.push(actionCheck);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
// External check - will extract later
|
|
106
|
+
if (!check.url) {
|
|
107
|
+
continue; // Skip invalid checks
|
|
108
|
+
}
|
|
109
|
+
rawExternalChecks.push({
|
|
110
|
+
name: check.name,
|
|
111
|
+
status: check.status,
|
|
112
|
+
conclusion: check.conclusion,
|
|
113
|
+
url: check.url,
|
|
114
|
+
provider: check.provider,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Extract details from external checks (all at once)
|
|
119
|
+
const externalChecks = await this.externalCheckExtractor.extractAll(rawExternalChecks);
|
|
120
|
+
// Order checks: failed first (newspaper philosophy)
|
|
121
|
+
const orderedGitHubActions = this.orderChecks(githubActions);
|
|
122
|
+
const orderedExternalChecks = this.orderExternalChecks(externalChecks);
|
|
123
|
+
// Calculate check counts
|
|
124
|
+
const totalChecks = githubActions.length + externalChecks.length;
|
|
125
|
+
const passedChecks = githubActions.filter((c) => c.conclusion === 'success').length +
|
|
126
|
+
externalChecks.filter((c) => c.conclusion === 'success').length;
|
|
127
|
+
const failedChecks = githubActions.filter((c) => c.conclusion === 'failure').length +
|
|
128
|
+
externalChecks.filter((c) => c.conclusion === 'failure').length;
|
|
129
|
+
const pendingChecks = githubActions.filter((c) => c.status !== 'completed').length +
|
|
130
|
+
externalChecks.filter((c) => c.status !== 'completed').length;
|
|
131
|
+
// Fetch history summary
|
|
132
|
+
const historySummary = await this.historyBuilder.buildSummary(prMetadata.branch);
|
|
133
|
+
// Fetch file changes
|
|
134
|
+
const changes = await this.fetcher.fetchFileChanges(prNumber);
|
|
135
|
+
// Determine overall status
|
|
136
|
+
let status = 'passed';
|
|
137
|
+
if (failedChecks > 0) {
|
|
138
|
+
status = 'failed';
|
|
139
|
+
}
|
|
140
|
+
else if (pendingChecks > 0) {
|
|
141
|
+
status = 'pending';
|
|
142
|
+
}
|
|
143
|
+
// Generate guidance
|
|
144
|
+
const guidance = this.generateGuidance(status, orderedGitHubActions, orderedExternalChecks, prMetadata.mergeable);
|
|
145
|
+
// Build result
|
|
146
|
+
const result = {
|
|
147
|
+
pr: prMetadata,
|
|
148
|
+
status,
|
|
149
|
+
checks: {
|
|
150
|
+
total: totalChecks,
|
|
151
|
+
passed: passedChecks,
|
|
152
|
+
failed: failedChecks,
|
|
153
|
+
pending: pendingChecks,
|
|
154
|
+
history_summary: historySummary.total_runs > 0 ? historySummary : undefined,
|
|
155
|
+
github_actions: orderedGitHubActions,
|
|
156
|
+
external_checks: orderedExternalChecks,
|
|
157
|
+
},
|
|
158
|
+
changes,
|
|
159
|
+
guidance,
|
|
160
|
+
// Note: cache field removed - will be added back when actually needed
|
|
161
|
+
};
|
|
162
|
+
// Note: We do NOT cache the result itself - only logs are cached
|
|
163
|
+
// This ensures PR status is always fresh from GitHub
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Build result for a specific run ID
|
|
168
|
+
*
|
|
169
|
+
* Useful for watching specific failed runs to test extraction.
|
|
170
|
+
* Does not use history summary (since it's a single run).
|
|
171
|
+
*
|
|
172
|
+
* @param prNumber - PR number
|
|
173
|
+
* @param runId - GitHub run ID
|
|
174
|
+
* @param options - Options (useCache)
|
|
175
|
+
* @returns WatchPRResult with single check
|
|
176
|
+
*/
|
|
177
|
+
async buildResultForRun(prNumber, runId, options = {}) {
|
|
178
|
+
const { useCache = false } = options;
|
|
179
|
+
// Initialize cache manager if caching enabled
|
|
180
|
+
if (useCache && !this.cacheManager) {
|
|
181
|
+
this.cacheManager = new CacheManager(`${this.owner}/${this.repo}`, prNumber);
|
|
182
|
+
}
|
|
183
|
+
// Fetch PR metadata (still needed for context)
|
|
184
|
+
const prMetadata = await this.fetcher.fetchPRDetails(prNumber);
|
|
185
|
+
// Fetch specific run details
|
|
186
|
+
const runDetails = await this.fetcher.fetchRunDetails(runId);
|
|
187
|
+
// Build GitHub Action check from run details
|
|
188
|
+
const actionCheck = {
|
|
189
|
+
name: runDetails.name,
|
|
190
|
+
status: runDetails.status,
|
|
191
|
+
conclusion: runDetails.conclusion,
|
|
192
|
+
run_id: runDetails.run_id,
|
|
193
|
+
workflow: runDetails.workflow,
|
|
194
|
+
started_at: runDetails.started_at,
|
|
195
|
+
duration: runDetails.duration,
|
|
196
|
+
};
|
|
197
|
+
// Try to extract errors from logs (with retry logic for Issue #4)
|
|
198
|
+
const logs = await this.fetchLogsWithRetry(runId);
|
|
199
|
+
if (logs) {
|
|
200
|
+
const extraction = await this.extractionDetector.detectAndExtract(actionCheck, logs);
|
|
201
|
+
if (extraction) {
|
|
202
|
+
actionCheck.extraction = extraction;
|
|
203
|
+
}
|
|
204
|
+
// Save logs to cache (extraction can be re-run later)
|
|
205
|
+
if (this.cacheManager) {
|
|
206
|
+
await this.cacheManager.saveLog(runId, logs);
|
|
207
|
+
if (extraction) {
|
|
208
|
+
await this.cacheManager.saveExtraction(runId, extraction);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// If logs are null, gracefully continue without extraction
|
|
213
|
+
// No noisy error output (Issue #4 fix)
|
|
214
|
+
// Fetch file changes (for context)
|
|
215
|
+
const changes = await this.fetcher.fetchFileChanges(prNumber);
|
|
216
|
+
// Determine status from the single check
|
|
217
|
+
let status = 'passed';
|
|
218
|
+
if (actionCheck.conclusion === 'failure') {
|
|
219
|
+
status = 'failed';
|
|
220
|
+
}
|
|
221
|
+
else if (actionCheck.status === 'in_progress' || actionCheck.status === 'queued') {
|
|
222
|
+
status = 'pending';
|
|
223
|
+
}
|
|
224
|
+
// Calculate check counts (single check)
|
|
225
|
+
const totalChecks = 1;
|
|
226
|
+
const passedChecks = actionCheck.conclusion === 'success' ? 1 : 0;
|
|
227
|
+
const failedChecks = actionCheck.conclusion === 'failure' ? 1 : 0;
|
|
228
|
+
const pendingChecks = actionCheck.status === 'in_progress' || actionCheck.status === 'queued' ? 1 : 0;
|
|
229
|
+
// Generate guidance (simplified for single run)
|
|
230
|
+
const guidance = this.generateGuidance(status, [actionCheck], [], prMetadata.mergeable);
|
|
231
|
+
// Build result
|
|
232
|
+
const result = {
|
|
233
|
+
pr: prMetadata,
|
|
234
|
+
status,
|
|
235
|
+
checks: {
|
|
236
|
+
total: totalChecks,
|
|
237
|
+
passed: passedChecks,
|
|
238
|
+
failed: failedChecks,
|
|
239
|
+
pending: pendingChecks,
|
|
240
|
+
github_actions: [actionCheck],
|
|
241
|
+
external_checks: [],
|
|
242
|
+
},
|
|
243
|
+
changes,
|
|
244
|
+
guidance,
|
|
245
|
+
// Note: cache field removed - will be added back when actually needed
|
|
246
|
+
};
|
|
247
|
+
// Don't cache metadata for single-run mode (historical runs are immutable)
|
|
248
|
+
// But logs and extractions are already cached above
|
|
249
|
+
return result;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Get priority for check ordering (lower is higher priority)
|
|
253
|
+
*/
|
|
254
|
+
getCheckPriority(conclusion, status) {
|
|
255
|
+
if (conclusion === 'failure')
|
|
256
|
+
return 0;
|
|
257
|
+
if (status !== 'completed')
|
|
258
|
+
return 1;
|
|
259
|
+
if (conclusion === 'success')
|
|
260
|
+
return 2;
|
|
261
|
+
return 3;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Order checks: failed first, then pending, then passed
|
|
265
|
+
*
|
|
266
|
+
* @param checks - GitHub Action checks
|
|
267
|
+
* @returns Ordered checks
|
|
268
|
+
*/
|
|
269
|
+
orderChecks(checks) {
|
|
270
|
+
return checks.sort((a, b) => {
|
|
271
|
+
return this.getCheckPriority(a.conclusion, a.status) - this.getCheckPriority(b.conclusion, b.status);
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Order external checks: failed first, then pending, then passed
|
|
276
|
+
*
|
|
277
|
+
* @param checks - External checks
|
|
278
|
+
* @returns Ordered checks
|
|
279
|
+
*/
|
|
280
|
+
// eslint-disable-next-line sonarjs/no-identical-functions
|
|
281
|
+
orderExternalChecks(checks) {
|
|
282
|
+
return checks.sort((a, b) => {
|
|
283
|
+
return this.getCheckPriority(a.conclusion, a.status) - this.getCheckPriority(b.conclusion, b.status);
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Generate intelligent guidance based on check results
|
|
288
|
+
*
|
|
289
|
+
* @param status - Overall status
|
|
290
|
+
* @param githubActions - GitHub Action checks
|
|
291
|
+
* @param externalChecks - External checks
|
|
292
|
+
* @param mergeable - Is PR mergeable?
|
|
293
|
+
* @returns Guidance with next steps
|
|
294
|
+
*/
|
|
295
|
+
generateGuidance(status, githubActions, externalChecks, mergeable) {
|
|
296
|
+
const nextSteps = [];
|
|
297
|
+
if (status === 'failed') {
|
|
298
|
+
// Find failed checks
|
|
299
|
+
const failedGitHubActions = githubActions.filter((c) => c.conclusion === 'failure');
|
|
300
|
+
const failedExternalChecks = externalChecks.filter((c) => c.conclusion === 'failure');
|
|
301
|
+
// Add next steps for failed GitHub Actions
|
|
302
|
+
for (const check of failedGitHubActions) {
|
|
303
|
+
nextSteps.push({
|
|
304
|
+
action: `Fix ${check.name} failure`,
|
|
305
|
+
url: `https://github.com/${this.owner}/${this.repo}/actions/runs/${check.run_id}`,
|
|
306
|
+
severity: 'error',
|
|
307
|
+
reason: check.extraction
|
|
308
|
+
? `${check.extraction.totalErrors} error(s) detected`
|
|
309
|
+
: 'Check failed',
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
// Add next steps for failed external checks
|
|
313
|
+
for (const check of failedExternalChecks) {
|
|
314
|
+
nextSteps.push({
|
|
315
|
+
action: `Fix ${check.name} failure`,
|
|
316
|
+
url: check.url,
|
|
317
|
+
severity: check.extracted?.severity ?? 'error',
|
|
318
|
+
reason: check.extracted?.summary ?? 'Check failed',
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
return {
|
|
322
|
+
status: 'failed',
|
|
323
|
+
blocking: !mergeable,
|
|
324
|
+
severity: 'error',
|
|
325
|
+
summary: `${failedGitHubActions.length + failedExternalChecks.length} check(s) failed`,
|
|
326
|
+
next_steps: nextSteps,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
if (status === 'pending') {
|
|
330
|
+
return {
|
|
331
|
+
status: 'pending',
|
|
332
|
+
blocking: false,
|
|
333
|
+
severity: 'info',
|
|
334
|
+
summary: 'Checks are still running',
|
|
335
|
+
next_steps: [
|
|
336
|
+
{
|
|
337
|
+
action: 'Wait for checks to complete',
|
|
338
|
+
severity: 'info',
|
|
339
|
+
},
|
|
340
|
+
],
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
// Passed
|
|
344
|
+
return {
|
|
345
|
+
status: 'passed',
|
|
346
|
+
blocking: false,
|
|
347
|
+
severity: 'info',
|
|
348
|
+
summary: 'All checks passed',
|
|
349
|
+
next_steps: mergeable
|
|
350
|
+
? [
|
|
351
|
+
{
|
|
352
|
+
action: 'Ready to merge',
|
|
353
|
+
severity: 'info',
|
|
354
|
+
},
|
|
355
|
+
]
|
|
356
|
+
: [
|
|
357
|
+
{
|
|
358
|
+
action: 'Resolve merge conflicts',
|
|
359
|
+
severity: 'warning',
|
|
360
|
+
reason: 'PR is not mergeable',
|
|
361
|
+
},
|
|
362
|
+
],
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
// buildCacheInfo() removed - cache field will be added back when actually needed
|
|
366
|
+
/**
|
|
367
|
+
* Fetch logs with retry logic for race conditions
|
|
368
|
+
*
|
|
369
|
+
* When GitHub marks a check as complete, logs may not be immediately available.
|
|
370
|
+
* This method retries with exponential backoff to handle the race condition.
|
|
371
|
+
*
|
|
372
|
+
* Retry schedule: 2s, 4s, 8s (total 3 attempts over ~14 seconds)
|
|
373
|
+
*
|
|
374
|
+
* @param runId - GitHub run ID
|
|
375
|
+
* @param maxRetries - Maximum number of retry attempts (default: 3)
|
|
376
|
+
* @returns Log content, or null if all retries failed
|
|
377
|
+
*/
|
|
378
|
+
async fetchLogsWithRetry(runId, maxRetries = 3) {
|
|
379
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
380
|
+
try {
|
|
381
|
+
return await this.fetcher.fetchRunLogs(runId);
|
|
382
|
+
}
|
|
383
|
+
catch {
|
|
384
|
+
// Intentionally suppress error (Issue #4 fix: no noisy output)
|
|
385
|
+
// If this was the last attempt, break without sleeping
|
|
386
|
+
if (attempt === maxRetries) {
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
389
|
+
// Exponential backoff: 2s, 4s, 8s
|
|
390
|
+
const delayMs = Math.pow(2, attempt) * 1000;
|
|
391
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
// All retries failed - return null (graceful degradation)
|
|
395
|
+
// Logs can be inspected with debug mode if needed
|
|
396
|
+
return null;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Fetch all workflow runs for a PR (for --history flag)
|
|
400
|
+
*
|
|
401
|
+
* @param prNumber - PR number
|
|
402
|
+
* @returns List of workflow runs with basic metadata
|
|
403
|
+
*/
|
|
404
|
+
async fetchRunsForPR(prNumber) {
|
|
405
|
+
return await this.fetcher.fetchRunsForPR(prNumber);
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Determine if output should be YAML format
|
|
409
|
+
*
|
|
410
|
+
* Auto-YAML on failure (consistent with validate command)
|
|
411
|
+
*
|
|
412
|
+
* @param status - Overall status
|
|
413
|
+
* @param forceYAML - Force YAML output
|
|
414
|
+
* @returns True if should output YAML
|
|
415
|
+
*/
|
|
416
|
+
shouldOutputYAML(status, forceYAML) {
|
|
417
|
+
return forceYAML || status === 'failed';
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
//# sourceMappingURL=watch-pr-orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch-pr-orchestrator.js","sourceRoot":"","sources":["../../src/services/watch-pr-orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command name detection utilities
|
|
3
|
+
*
|
|
4
|
+
* Detects the actual command name used to invoke vibe-validate (e.g., "vv" vs "vibe-validate")
|
|
5
|
+
* so error messages and usage examples reflect what the user actually typed.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Get the command name that was used to invoke the CLI
|
|
9
|
+
*
|
|
10
|
+
* @returns The command name (e.g., "vv", "vibe-validate", or fallback "vibe-validate")
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const cmd = getCommandName();
|
|
15
|
+
* console.error(`Usage: ${cmd} watch-pr <pr-number>`);
|
|
16
|
+
* // If invoked with "vv": "Usage: vv watch-pr <pr-number>"
|
|
17
|
+
* // If invoked with "vibe-validate": "Usage: vibe-validate watch-pr <pr-number>"
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function getCommandName(): string;
|
|
21
|
+
//# sourceMappingURL=command-name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-name.d.ts","sourceRoot":"","sources":["../../src/utils/command-name.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,IAAI,MAAM,CA4BvC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command name detection utilities
|
|
3
|
+
*
|
|
4
|
+
* Detects the actual command name used to invoke vibe-validate (e.g., "vv" vs "vibe-validate")
|
|
5
|
+
* so error messages and usage examples reflect what the user actually typed.
|
|
6
|
+
*/
|
|
7
|
+
import { basename } from 'node:path';
|
|
8
|
+
/**
|
|
9
|
+
* Get the command name that was used to invoke the CLI
|
|
10
|
+
*
|
|
11
|
+
* @returns The command name (e.g., "vv", "vibe-validate", or fallback "vibe-validate")
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const cmd = getCommandName();
|
|
16
|
+
* console.error(`Usage: ${cmd} watch-pr <pr-number>`);
|
|
17
|
+
* // If invoked with "vv": "Usage: vv watch-pr <pr-number>"
|
|
18
|
+
* // If invoked with "vibe-validate": "Usage: vibe-validate watch-pr <pr-number>"
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export function getCommandName() {
|
|
22
|
+
// Check if the wrapper passed the command name via environment variable
|
|
23
|
+
// This is set by the smart wrapper (bin/vibe-validate.ts) when it spawns bin.js
|
|
24
|
+
const envCommandName = process.env.VV_COMMAND_NAME;
|
|
25
|
+
if (envCommandName === 'vv' || envCommandName === 'vibe-validate') {
|
|
26
|
+
return envCommandName;
|
|
27
|
+
}
|
|
28
|
+
// Fallback: extract from process.argv[1] (for direct invocation or dev mode)
|
|
29
|
+
// process.argv[0] is node executable
|
|
30
|
+
// process.argv[1] is the script being executed (e.g., /path/to/vv or /path/to/vibe-validate)
|
|
31
|
+
const scriptPath = process.argv[1];
|
|
32
|
+
if (!scriptPath) {
|
|
33
|
+
return 'vibe-validate'; // Fallback
|
|
34
|
+
}
|
|
35
|
+
// Extract basename (e.g., "vv" from "/usr/local/bin/vv")
|
|
36
|
+
const commandName = basename(scriptPath);
|
|
37
|
+
// Handle common cases: vv, vibe-validate, or .js/.ts extensions in dev mode
|
|
38
|
+
if (commandName === 'vv' || commandName === 'vibe-validate') {
|
|
39
|
+
return commandName;
|
|
40
|
+
}
|
|
41
|
+
// Dev mode: might be bin.js, bin.ts, vibe-validate.js, etc.
|
|
42
|
+
// Fall back to "vibe-validate" for consistency
|
|
43
|
+
return 'vibe-validate';
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=command-name.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-name.js","sourceRoot":"","sources":["../../src/utils/command-name.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc;IAC5B,wEAAwE;IACxE,gFAAgF;IAChF,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACnD,IAAI,cAAc,KAAK,IAAI,IAAI,cAAc,KAAK,eAAe,EAAE,CAAC;QAClE,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,6EAA6E;IAC7E,qCAAqC;IACrC,6FAA6F;IAC7F,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEnC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,eAAe,CAAC,CAAC,WAAW;IACrC,CAAC;IAED,yDAAyD;IACzD,MAAM,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IAEzC,4EAA4E;IAC5E,IAAI,WAAW,KAAK,IAAI,IAAI,WAAW,KAAK,eAAe,EAAE,CAAC;QAC5D,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,4DAA4D;IAC5D,+CAA+C;IAC/C,OAAO,eAAe,CAAC;AACzB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pid-lock.d.ts","sourceRoot":"","sources":["../../src/utils/pid-lock.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"pid-lock.d.ts","sourceRoot":"","sources":["../../src/utils/pid-lock.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,6CAA6C;IAC7C,QAAQ,EAAE,OAAO,CAAC;IAClB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,QAAQ,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,KAAK,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAChC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8DD;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC,CAyCrB;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjE;AAED;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAuBtG;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,cAAc,GAAE,MAAY,EAC5B,cAAc,GAAE,MAAa,EAC7B,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,QAAQ,GAAG,IAAI,CAAA;CAAE,CAAC,CA6B/E"}
|
package/dist/utils/pid-lock.js
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* Cross-platform (Node.js), works on Windows, macOS, Linux.
|
|
6
6
|
*/
|
|
7
7
|
import { readFileSync, writeFileSync, unlinkSync, existsSync } from 'node:fs';
|
|
8
|
-
import { tmpdir } from 'node:os';
|
|
9
8
|
import { join } from 'node:path';
|
|
9
|
+
import { normalizedTmpdir } from '@vibe-validate/utils';
|
|
10
10
|
/**
|
|
11
11
|
* Encode directory path for use in lock file name
|
|
12
12
|
*
|
|
@@ -40,11 +40,11 @@ function getLockFilePath(directory, options = {}) {
|
|
|
40
40
|
throw new Error('projectId is required when scope is "project"');
|
|
41
41
|
}
|
|
42
42
|
// Project-scoped: /tmp/vibe-validate-project-{projectId}.lock
|
|
43
|
-
return join(
|
|
43
|
+
return join(normalizedTmpdir(), `vibe-validate-project-${options.projectId}.lock`);
|
|
44
44
|
}
|
|
45
45
|
// Directory-scoped (default): /tmp/vibe-validate-{encoded-dir}.lock
|
|
46
46
|
const encoded = encodeDirectoryPath(directory);
|
|
47
|
-
return join(
|
|
47
|
+
return join(normalizedTmpdir(), `vibe-validate-${encoded}.lock`);
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
50
|
* Check if a process is running
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pid-lock.js","sourceRoot":"","sources":["../../src/utils/pid-lock.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"pid-lock.js","sourceRoot":"","sources":["../../src/utils/pid-lock.ts"],"names":[],"mappings":"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"}
|
|
@@ -60,7 +60,7 @@ export declare function formatToolName(tool: SecretScanningTool): string;
|
|
|
60
60
|
/**
|
|
61
61
|
* Show performance warning if scan was slow
|
|
62
62
|
*/
|
|
63
|
-
export declare function showPerformanceWarning(tool: SecretScanningTool, duration: number, threshold: number): void;
|
|
63
|
+
export declare function showPerformanceWarning(tool: SecretScanningTool, duration: number, threshold: number, hasExplicitCommand?: boolean): void;
|
|
64
64
|
/**
|
|
65
65
|
* Show error message when secrets are detected
|
|
66
66
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-scanning.d.ts","sourceRoot":"","sources":["../../src/utils/secret-scanning.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,YAAY,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,kBAAkB,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAKtE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAExE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,GAAE,MAAsB,GAAG,aAAa,EAAE,CAmBtF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,GAAG,GAAE,MAAsB,GAC1B;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,CAoCjD;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,kBAAkB,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,OAAe,GACvB,UAAU,
|
|
1
|
+
{"version":3,"file":"secret-scanning.d.ts","sourceRoot":"","sources":["../../src/utils/secret-scanning.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,YAAY,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,kBAAkB,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAKtE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAExE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,GAAE,MAAsB,GAAG,aAAa,EAAE,CAmBtF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,GAAG,GAAE,MAAsB,GAC1B;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,CAoCjD;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,kBAAkB,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,OAAe,GACvB,UAAU,CA0FZ;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAE/D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,kBAAkB,EACxB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,kBAAkB,GAAE,OAAe,GAClC,IAAI,CAmBN;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAsBpE"}
|
|
@@ -40,7 +40,7 @@ export function detectSecretScanningTools(cwd = process.cwd()) {
|
|
|
40
40
|
tool: 'secretlint',
|
|
41
41
|
available: true, // Always available via npx
|
|
42
42
|
hasConfig: secretlintConfigured,
|
|
43
|
-
defaultCommand: 'npx secretlint
|
|
43
|
+
defaultCommand: 'npx secretlint .', // No glob patterns - safeExecFromString rejects them
|
|
44
44
|
},
|
|
45
45
|
];
|
|
46
46
|
}
|
|
@@ -85,7 +85,8 @@ export function selectToolsToRun(scanCommand, cwd = process.cwd()) {
|
|
|
85
85
|
*/
|
|
86
86
|
export function runSecretScan(tool, command, verbose = false) {
|
|
87
87
|
const startTime = Date.now();
|
|
88
|
-
// Special handling for gitleaks -
|
|
88
|
+
// Special handling for gitleaks - skip if not installed (native binary, optional)
|
|
89
|
+
// secretlint is ALWAYS available via npx - never skip, always fail loud if error
|
|
89
90
|
if (tool === 'gitleaks' && !isToolAvailable('gitleaks')) {
|
|
90
91
|
return {
|
|
91
92
|
tool,
|
|
@@ -96,6 +97,28 @@ export function runSecretScan(tool, command, verbose = false) {
|
|
|
96
97
|
};
|
|
97
98
|
}
|
|
98
99
|
try {
|
|
100
|
+
// Parse and execute scanCommand string
|
|
101
|
+
//
|
|
102
|
+
// SECURITY: scanCommand comes from user config (vibe-validate.config.yaml)
|
|
103
|
+
// Same trust model as npm scripts - users control their own config files.
|
|
104
|
+
//
|
|
105
|
+
// LIMITATIONS:
|
|
106
|
+
// - Simple commands work: "gitleaks protect --staged"
|
|
107
|
+
// - Glob patterns FAIL: "npx secretlint **/*" (prevented by safeExecFromString)
|
|
108
|
+
// - Shell operators FAIL: "cmd1 && cmd2" (prevented by safeExecFromString)
|
|
109
|
+
// - Complex quoting FAILS: nested quotes, escapes (prevented by safeExecFromString)
|
|
110
|
+
//
|
|
111
|
+
// WHY safeExecFromString:
|
|
112
|
+
// - Handles simple quoted args: 'gitleaks protect --config ".gitleaks.toml"'
|
|
113
|
+
// - Fails fast on complex shell syntax (prevents silent bugs)
|
|
114
|
+
// - More robust than naive .split() which breaks with ANY quotes
|
|
115
|
+
//
|
|
116
|
+
// RECOMMENDATION for complex commands (globs, operators, etc):
|
|
117
|
+
// Move to package.json script and reference it:
|
|
118
|
+
// Bad: scanCommand: "npx secretlint **/*" (glob patterns rejected)
|
|
119
|
+
// Bad: scanCommand: "cmd1 && cmd2" (shell operators rejected)
|
|
120
|
+
// Good: scanCommand: "npm run scan:secrets"
|
|
121
|
+
// package.json: { "scan:secrets": "npx secretlint '**/*'" }
|
|
99
122
|
const result = safeExecFromString(command, {
|
|
100
123
|
encoding: 'utf8',
|
|
101
124
|
stdio: 'pipe',
|
|
@@ -154,7 +177,7 @@ export function formatToolName(tool) {
|
|
|
154
177
|
/**
|
|
155
178
|
* Show performance warning if scan was slow
|
|
156
179
|
*/
|
|
157
|
-
export function showPerformanceWarning(tool, duration, threshold) {
|
|
180
|
+
export function showPerformanceWarning(tool, duration, threshold, hasExplicitCommand = false) {
|
|
158
181
|
if (duration <= threshold) {
|
|
159
182
|
return;
|
|
160
183
|
}
|
|
@@ -164,7 +187,12 @@ export function showPerformanceWarning(tool, duration, threshold) {
|
|
|
164
187
|
console.warn(chalk.gray(' Consider installing gitleaks for faster scanning:'));
|
|
165
188
|
console.warn(chalk.gray(' • macOS: brew install gitleaks'));
|
|
166
189
|
console.warn(chalk.gray(' • Linux: See https://github.com/gitleaks/gitleaks#installation'));
|
|
167
|
-
|
|
190
|
+
if (hasExplicitCommand) {
|
|
191
|
+
console.warn(chalk.gray(''));
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
console.warn(chalk.gray(' • Or add explicit scanCommand in config\n'));
|
|
195
|
+
}
|
|
168
196
|
}
|
|
169
197
|
}
|
|
170
198
|
/**
|