@oss-autopilot/core 3.5.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-registry.js +143 -1
- package/dist/cli.bundle.cjs +120 -108
- package/dist/commands/daily.d.ts +8 -0
- package/dist/commands/daily.js +21 -0
- package/dist/commands/dashboard-lifecycle.d.ts +7 -0
- package/dist/commands/dashboard-lifecycle.js +12 -2
- package/dist/commands/dashboard-process.d.ts +8 -0
- package/dist/commands/dashboard-process.js +20 -0
- package/dist/commands/features.d.ts +50 -0
- package/dist/commands/features.js +131 -0
- package/dist/commands/index.d.ts +5 -1
- package/dist/commands/index.js +4 -0
- package/dist/commands/scout-bridge.d.ts +12 -0
- package/dist/commands/scout-bridge.js +42 -2
- package/dist/commands/search.js +3 -1
- package/dist/commands/startup.js +75 -7
- package/dist/commands/vet-list.js +21 -5
- package/dist/commands/vet.js +3 -1
- package/dist/core/anti-llm-policy.d.ts +42 -13
- package/dist/core/anti-llm-policy.js +102 -13
- package/dist/core/ci-analysis.d.ts +32 -1
- package/dist/core/ci-analysis.js +92 -0
- package/dist/core/errors.d.ts +19 -0
- package/dist/core/errors.js +54 -0
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/linked-pr-classification.d.ts +28 -0
- package/dist/core/linked-pr-classification.js +32 -0
- package/dist/core/pr-monitor.d.ts +1 -1
- package/dist/core/pr-monitor.js +31 -11
- package/dist/core/state-schema.d.ts +1 -0
- package/dist/core/state-schema.js +9 -0
- package/dist/core/state.d.ts +7 -0
- package/dist/core/state.js +10 -0
- package/dist/core/strategy.d.ts +21 -1
- package/dist/core/strategy.js +44 -0
- package/dist/core/types.d.ts +49 -0
- package/dist/formatters/json.d.ts +329 -35
- package/dist/formatters/json.js +102 -0
- package/package.json +2 -2
package/dist/cli-registry.js
CHANGED
|
@@ -284,6 +284,97 @@ export const commands = [
|
|
|
284
284
|
});
|
|
285
285
|
},
|
|
286
286
|
},
|
|
287
|
+
// ── Features ───────────────────────────────────────────────────────────
|
|
288
|
+
// scout 0.9.0 (#97/#98/#99): feature-scoped opportunities in repos with
|
|
289
|
+
// 3+ merged PRs, split into quick-wins / bigger-bets buckets.
|
|
290
|
+
{
|
|
291
|
+
name: 'features',
|
|
292
|
+
register(program) {
|
|
293
|
+
program
|
|
294
|
+
.command('features [count]')
|
|
295
|
+
.description('Find feature-scoped opportunities in repos with 3+ merged PRs')
|
|
296
|
+
.option('--json', 'Output as JSON')
|
|
297
|
+
.option('--anchor-threshold <n>', 'Override featuresAnchorThreshold (1-50)')
|
|
298
|
+
.option('--split-ratio <r>', 'Override featuresSplitRatio (0-1)')
|
|
299
|
+
.action(async (count, options) => {
|
|
300
|
+
const { FeaturesOutputSchema } = await import('./formatters/json.js');
|
|
301
|
+
await executeAction(options, async () => {
|
|
302
|
+
const { runFeatures, MAX_FEATURES_RESULTS } = await import('./commands/features.js');
|
|
303
|
+
let maxResults = 10;
|
|
304
|
+
if (count !== undefined) {
|
|
305
|
+
const parsed = Number(count);
|
|
306
|
+
if (!Number.isFinite(parsed) || parsed < 1 || !Number.isInteger(parsed)) {
|
|
307
|
+
throw new Error(`Invalid count "${count}". Must be a positive integer.`);
|
|
308
|
+
}
|
|
309
|
+
maxResults = parsed;
|
|
310
|
+
}
|
|
311
|
+
if (maxResults > MAX_FEATURES_RESULTS) {
|
|
312
|
+
console.warn(`Capping features to ${MAX_FEATURES_RESULTS} results (requested: ${maxResults})`);
|
|
313
|
+
maxResults = MAX_FEATURES_RESULTS;
|
|
314
|
+
}
|
|
315
|
+
let anchorThreshold;
|
|
316
|
+
if (options.anchorThreshold !== undefined) {
|
|
317
|
+
const parsed = Number(options.anchorThreshold);
|
|
318
|
+
if (!Number.isFinite(parsed) || !Number.isInteger(parsed) || parsed < 1 || parsed > 50) {
|
|
319
|
+
throw new Error(`Invalid --anchor-threshold "${options.anchorThreshold}". Must be an integer in [1, 50].`);
|
|
320
|
+
}
|
|
321
|
+
anchorThreshold = parsed;
|
|
322
|
+
}
|
|
323
|
+
let splitRatio;
|
|
324
|
+
if (options.splitRatio !== undefined) {
|
|
325
|
+
const parsed = Number(options.splitRatio);
|
|
326
|
+
if (!Number.isFinite(parsed) || parsed < 0 || parsed > 1) {
|
|
327
|
+
throw new Error(`Invalid --split-ratio "${options.splitRatio}". Must be a number in [0, 1].`);
|
|
328
|
+
}
|
|
329
|
+
splitRatio = parsed;
|
|
330
|
+
}
|
|
331
|
+
if (!options.json) {
|
|
332
|
+
console.log(`\nSearching for feature opportunities (max ${maxResults})...\n`);
|
|
333
|
+
}
|
|
334
|
+
return runFeatures({ maxResults, anchorThreshold, splitRatio });
|
|
335
|
+
}, (data) => {
|
|
336
|
+
if (data.anchorRepos.length > 0) {
|
|
337
|
+
console.log(`Anchor repos (${data.anchorRepos.length}): ${data.anchorRepos.join(', ')}`);
|
|
338
|
+
console.log('');
|
|
339
|
+
}
|
|
340
|
+
if (data.quickWins.length === 0 && data.biggerBets.length === 0) {
|
|
341
|
+
if (data.rateLimitWarning) {
|
|
342
|
+
console.warn(`\n${data.rateLimitWarning}\n`);
|
|
343
|
+
}
|
|
344
|
+
else if (data.message) {
|
|
345
|
+
console.log(data.message);
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
console.log('No feature opportunities found.');
|
|
349
|
+
}
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
if (data.rateLimitWarning) {
|
|
353
|
+
console.warn(`\n${data.rateLimitWarning}\n`);
|
|
354
|
+
}
|
|
355
|
+
const printBucket = (heading, candidates) => {
|
|
356
|
+
if (candidates.length === 0)
|
|
357
|
+
return;
|
|
358
|
+
console.log(`${heading} (${candidates.length}):\n`);
|
|
359
|
+
for (const candidate of candidates) {
|
|
360
|
+
const { issue, recommendation, reasonsToApprove, reasonsToSkip, viabilityScore } = candidate;
|
|
361
|
+
console.log(`[${recommendation.toUpperCase()}] ${issue.repo}#${issue.number}: ${issue.title}`);
|
|
362
|
+
console.log(` URL: ${issue.url}`);
|
|
363
|
+
console.log(` Viability: ${viabilityScore}/100`);
|
|
364
|
+
if (reasonsToApprove.length > 0)
|
|
365
|
+
console.log(` Approve: ${reasonsToApprove.join(', ')}`);
|
|
366
|
+
if (reasonsToSkip.length > 0)
|
|
367
|
+
console.log(` Skip: ${reasonsToSkip.join(', ')}`);
|
|
368
|
+
console.log('---');
|
|
369
|
+
}
|
|
370
|
+
console.log('');
|
|
371
|
+
};
|
|
372
|
+
printBucket('Quick wins', data.quickWins);
|
|
373
|
+
printBucket('Bigger bets', data.biggerBets);
|
|
374
|
+
}, FeaturesOutputSchema);
|
|
375
|
+
});
|
|
376
|
+
},
|
|
377
|
+
},
|
|
287
378
|
// ── Vet ────────────────────────────────────────────────────────────────
|
|
288
379
|
{
|
|
289
380
|
name: 'vet',
|
|
@@ -329,6 +420,7 @@ export const commands = [
|
|
|
329
420
|
console.log(` Claimed: ${data.summary.claimed}`);
|
|
330
421
|
console.log(` Closed: ${data.summary.closed}`);
|
|
331
422
|
console.log(` Has PR: ${data.summary.hasPR}`);
|
|
423
|
+
console.log(` Stalled PR: ${data.summary.hasStalledPR}`);
|
|
332
424
|
console.log(` Errors: ${data.summary.errors}`);
|
|
333
425
|
console.log('');
|
|
334
426
|
for (const result of data.results) {
|
|
@@ -337,7 +429,8 @@ export const commands = [
|
|
|
337
429
|
: result.listStatus === 'error'
|
|
338
430
|
? '\u274c'
|
|
339
431
|
: '\u26a0\ufe0f';
|
|
340
|
-
|
|
432
|
+
const annotation = result.listStatus === 'has_stalled_pr' ? ' (stalled PR, revive opportunity)' : '';
|
|
433
|
+
console.log(`${status} [${result.listStatus}] ${result.issue.repo}#${result.issue.number}: ${result.issue.title}${annotation}`);
|
|
341
434
|
if (result.errorMessage) {
|
|
342
435
|
console.log(` Error: ${result.errorMessage}`);
|
|
343
436
|
}
|
|
@@ -411,6 +504,55 @@ export const commands = [
|
|
|
411
504
|
});
|
|
412
505
|
},
|
|
413
506
|
},
|
|
507
|
+
// ── List Mark Done ─────────────────────────────────────────────────────
|
|
508
|
+
{
|
|
509
|
+
name: 'list-mark-done',
|
|
510
|
+
localOnly: true,
|
|
511
|
+
register(program) {
|
|
512
|
+
program
|
|
513
|
+
.command('list-mark-done <issue-url>')
|
|
514
|
+
.description('Mark an issue line in a curated list as done with strikethrough + Done sub-bullet (#1299)')
|
|
515
|
+
.requiredOption('--pr-url <url>', 'PR URL to record on the Done sub-bullet')
|
|
516
|
+
.requiredOption('--pr-status <text>', 'Trailing status, e.g. "merged" or "CI passing"')
|
|
517
|
+
.requiredOption('--list-path <file>', 'Path to the markdown issue list')
|
|
518
|
+
.option('--json', 'Output as JSON')
|
|
519
|
+
.action(async (issueUrl, options) => {
|
|
520
|
+
const { ListMarkDoneOutputSchema } = await import('./formatters/json.js');
|
|
521
|
+
await executeAction(options, async () => {
|
|
522
|
+
const result = await (await import('./commands/list-mark-done.js')).runMarkIssueListItemDone({
|
|
523
|
+
issueUrl,
|
|
524
|
+
prUrl: options.prUrl,
|
|
525
|
+
prStatus: options.prStatus,
|
|
526
|
+
listPath: options.listPath,
|
|
527
|
+
});
|
|
528
|
+
// Convert "URL not in list" into a real CLI error so the JSON
|
|
529
|
+
// envelope reports `success: false` and the process exits non-zero.
|
|
530
|
+
// The pure transform's success-shaped not-found return is fine for
|
|
531
|
+
// library consumers, but as a CLI command "I asked you to mark X
|
|
532
|
+
// and you couldn't find X" is a failure the caller must see.
|
|
533
|
+
// The "already marked done" case stays as a success-shape return
|
|
534
|
+
// (it's idempotent — the caller's intent was achieved).
|
|
535
|
+
if (!result.marked && result.reason === 'issue URL not found in the list') {
|
|
536
|
+
throw new Error(`Issue URL not found in ${result.filePath}: ${result.url}. ` +
|
|
537
|
+
`Verify --list-path and the issue URL.`);
|
|
538
|
+
}
|
|
539
|
+
return result;
|
|
540
|
+
}, (data) => {
|
|
541
|
+
if (data.marked) {
|
|
542
|
+
const headingNote = data.repoHeadingStruck ? ' (repo heading also struck)' : '';
|
|
543
|
+
console.log(`Marked ${data.url} done${headingNote}`);
|
|
544
|
+
console.log(` File: ${data.filePath}`);
|
|
545
|
+
console.log(` Remaining under repo: ${data.remainingUnderRepo}`);
|
|
546
|
+
}
|
|
547
|
+
else {
|
|
548
|
+
// Reach here only on the idempotent "already marked done" path.
|
|
549
|
+
console.log(`No mark: ${data.url} — ${data.reason ?? 'unchanged'}`);
|
|
550
|
+
console.log(` File: ${data.filePath}`);
|
|
551
|
+
}
|
|
552
|
+
}, ListMarkDoneOutputSchema);
|
|
553
|
+
});
|
|
554
|
+
},
|
|
555
|
+
},
|
|
414
556
|
// ── Track ──────────────────────────────────────────────────────────────
|
|
415
557
|
{
|
|
416
558
|
name: 'track',
|