@oss-autopilot/core 3.13.4 → 3.14.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.
Files changed (88) hide show
  1. package/README.md +3 -3
  2. package/dist/cli-registry.js +59 -84
  3. package/dist/cli.bundle.cjs +112 -109
  4. package/dist/cli.js +5 -4
  5. package/dist/commands/comments.js +44 -10
  6. package/dist/commands/config.d.ts +2 -0
  7. package/dist/commands/config.js +50 -2
  8. package/dist/commands/curated-list.d.ts +17 -0
  9. package/dist/commands/curated-list.js +25 -0
  10. package/dist/commands/daily.d.ts +7 -1
  11. package/dist/commands/daily.js +136 -57
  12. package/dist/commands/dashboard-cache.d.ts +69 -0
  13. package/dist/commands/dashboard-cache.js +219 -0
  14. package/dist/commands/dashboard-data.d.ts +18 -10
  15. package/dist/commands/dashboard-data.js +58 -8
  16. package/dist/commands/dashboard-gist-sync.d.ts +93 -0
  17. package/dist/commands/dashboard-gist-sync.js +237 -0
  18. package/dist/commands/dashboard-server.d.ts +6 -10
  19. package/dist/commands/dashboard-server.js +181 -347
  20. package/dist/commands/features.js +6 -0
  21. package/dist/commands/guidelines.d.ts +6 -0
  22. package/dist/commands/guidelines.js +7 -0
  23. package/dist/commands/index.d.ts +2 -5
  24. package/dist/commands/index.js +2 -4
  25. package/dist/commands/init.d.ts +2 -0
  26. package/dist/commands/init.js +7 -1
  27. package/dist/commands/list-mark-done.js +6 -21
  28. package/dist/commands/list-move-tier.js +3 -5
  29. package/dist/commands/locate-issue-list.d.ts +25 -0
  30. package/dist/commands/locate-issue-list.js +67 -0
  31. package/dist/commands/merge-loop.d.ts +63 -0
  32. package/dist/commands/merge-loop.js +157 -0
  33. package/dist/commands/repo-vet.js +40 -1
  34. package/dist/commands/scout-bridge.d.ts +35 -2
  35. package/dist/commands/scout-bridge.js +65 -13
  36. package/dist/commands/search.d.ts +4 -6
  37. package/dist/commands/search.js +58 -11
  38. package/dist/commands/setup.d.ts +2 -0
  39. package/dist/commands/setup.js +56 -2
  40. package/dist/commands/skip-file-parser.d.ts +23 -0
  41. package/dist/commands/skip-file-parser.js +23 -10
  42. package/dist/commands/startup.d.ts +1 -6
  43. package/dist/commands/startup.js +25 -59
  44. package/dist/commands/track.d.ts +2 -2
  45. package/dist/commands/track.js +2 -2
  46. package/dist/commands/vet-list.d.ts +6 -6
  47. package/dist/commands/vet-list.js +194 -65
  48. package/dist/core/config-registry.js +36 -0
  49. package/dist/core/daily-logic.d.ts +25 -2
  50. package/dist/core/daily-logic.js +58 -3
  51. package/dist/core/gist-health.d.ts +81 -0
  52. package/dist/core/gist-health.js +39 -0
  53. package/dist/core/gist-state-store.d.ts +3 -1
  54. package/dist/core/gist-state-store.js +7 -2
  55. package/dist/core/github-stats.d.ts +2 -2
  56. package/dist/core/github-stats.js +20 -4
  57. package/dist/core/index.d.ts +5 -4
  58. package/dist/core/index.js +5 -4
  59. package/dist/core/issue-conversation.js +8 -2
  60. package/dist/core/issue-grading.d.ts +9 -0
  61. package/dist/core/issue-grading.js +9 -0
  62. package/dist/core/issue-verification.d.ts +39 -0
  63. package/dist/core/issue-verification.js +48 -0
  64. package/dist/core/pagination.d.ts +27 -0
  65. package/dist/core/pagination.js +23 -5
  66. package/dist/core/pr-comments-fetcher.d.ts +7 -0
  67. package/dist/core/pr-comments-fetcher.js +19 -8
  68. package/dist/core/pr-monitor.d.ts +2 -0
  69. package/dist/core/pr-monitor.js +26 -9
  70. package/dist/core/repo-score-manager.d.ts +2 -2
  71. package/dist/core/repo-score-manager.js +3 -3
  72. package/dist/core/repo-vet.d.ts +2 -2
  73. package/dist/core/repo-vet.js +1 -1
  74. package/dist/core/review-analysis.d.ts +19 -0
  75. package/dist/core/review-analysis.js +28 -0
  76. package/dist/core/state-schema.d.ts +43 -6
  77. package/dist/core/state-schema.js +81 -4
  78. package/dist/core/state.d.ts +36 -5
  79. package/dist/core/state.js +177 -28
  80. package/dist/core/strategy.js +6 -5
  81. package/dist/core/types.d.ts +8 -0
  82. package/dist/core/untrusted-content.d.ts +45 -0
  83. package/dist/core/untrusted-content.js +54 -0
  84. package/dist/formatters/json.d.ts +120 -12
  85. package/dist/formatters/json.js +55 -2
  86. package/package.json +2 -2
  87. package/dist/commands/shelve.d.ts +0 -45
  88. package/dist/commands/shelve.js +0 -54
package/README.md CHANGED
@@ -30,10 +30,10 @@ oss-autopilot daily --json
30
30
  # Check PR status
31
31
  oss-autopilot status --json
32
32
 
33
- # Search for contributable issues
34
- oss-autopilot search "react" --json
33
+ # Search for contributable issues (positional arg = max result count)
34
+ oss-autopilot search 10 --json
35
35
 
36
- # Track a new PR
36
+ # Inspect a PR (read-only metadata lookup — nothing persists)
37
37
  oss-autopilot track https://github.com/owner/repo/pull/123
38
38
 
39
39
  # View help
@@ -34,6 +34,35 @@ export function handleCommandError(err, json) {
34
34
  * duplicated in every command action. Commands with non-standard output
35
35
  * modes (e.g. `--compact`, `--markdown`, `--badge`) inline their own
36
36
  * branching rather than squeezing through this helper.
37
+ *
38
+ * ── `--json` output validation tiers (#1453) ──────────────────────────────
39
+ *
40
+ * Two tiers gate the shape of `--json` output. When adding a command, pick
41
+ * a tier consciously:
42
+ *
43
+ * 1. **Runtime-validated**: the registration passes an exported Zod schema
44
+ * (from `formatters/json.ts`) as `executeAction`'s 4th argument — or
45
+ * calls `outputJsonValidated` directly — so a drifted shape throws at
46
+ * the `--json` boundary instead of silently shipping (#1105).
47
+ * Commands: manifest, daily, status, strategy, search, features,
48
+ * verify-issue, skip-add, list-move-tier, list-mark-done,
49
+ * compliance-score, post, claim, config, init, setup, checkSetup,
50
+ * parse-issue-list, orphan-files, doctor, local-repos, move,
51
+ * pr-template, repo-vet, detect-formatters.
52
+ *
53
+ * 2. **Goldens-only**: no Zod schema exists; the command returns a TS
54
+ * interface and its `*.contract.test.ts` golden snapshot is the only
55
+ * shape gate. Nothing fires at runtime if the producer drifts after
56
+ * the goldens were last updated.
57
+ * Commands: state (show/sync/unlink), vet, vet-list, track, comments,
58
+ * startup, dismiss, undismiss, stats, and the five
59
+ * guidelines subcommands (list/view/store/reset/fetch-corpus).
60
+ *
61
+ * (`dashboard serve` is exempt: it has no `--json` mode.)
62
+ *
63
+ * To promote a command to tier 1: export a Zod schema from
64
+ * `formatters/json.ts`, assert it in the command's contract test alongside
65
+ * the goldens, and pass it to `executeAction` here.
37
66
  */
38
67
  async function executeAction(options, run, display,
39
68
  /** Optional Zod schema. When provided, the JSON output is validated against
@@ -509,7 +538,9 @@ export const commands = [
509
538
  }, (data) => {
510
539
  console.log(`\nRe-vetted ${data.summary.total} issues:\n`);
511
540
  console.log(` Still available: ${data.summary.stillAvailable}`);
541
+ console.log(` At risk: ${data.summary.atRisk}`);
512
542
  console.log(` Claimed: ${data.summary.claimed}`);
543
+ console.log(` Own open PR: ${data.summary.ownOpenPr}`);
513
544
  console.log(` Closed: ${data.summary.closed}`);
514
545
  console.log(` Has PR: ${data.summary.hasPR}`);
515
546
  console.log(` Stalled PR: ${data.summary.hasStalledPR}`);
@@ -521,7 +552,13 @@ export const commands = [
521
552
  : result.listStatus === 'error'
522
553
  ? '\u274c'
523
554
  : '\u26a0\ufe0f';
524
- const annotation = result.listStatus === 'has_stalled_pr' ? ' (stalled PR, revive opportunity)' : '';
555
+ const annotation = result.listStatus === 'has_stalled_pr'
556
+ ? ' (stalled PR, revive opportunity)'
557
+ : result.listStatus === 'at_risk'
558
+ ? ' (at risk, mention only)'
559
+ : result.listStatus === 'own_open_pr'
560
+ ? ' (you already have an open PR)'
561
+ : '';
525
562
  console.log(`${status} [${result.listStatus}] ${result.issue.repo}#${result.issue.number}: ${result.issue.title}${annotation}`);
526
563
  if (result.errorMessage) {
527
564
  console.log(` Error: ${result.errorMessage}`);
@@ -643,7 +680,7 @@ export const commands = [
643
680
  register(program) {
644
681
  program
645
682
  .command('track <pr-url>')
646
- .description('Fetch metadata for a PR (informationalv2 does not maintain a local tracking list)')
683
+ .description('Inspect a PR (read-only metadata lookup nothing is persisted; v2 has no local tracking list)')
647
684
  .option('--json', 'Output as JSON')
648
685
  .action((prUrl, options) => executeAction(options, async () => (await import('./commands/track.js')).runTrack({ prUrl }), (data) => {
649
686
  console.log(`\nPR: ${data.pr.repo}#${data.pr.number} - ${data.pr.title}`);
@@ -653,8 +690,9 @@ export const commands = [
653
690
  },
654
691
  },
655
692
  // The v1→v2 `untrack` and `read` stubs were removed in v4 (#1133). Use
656
- // `shelve`/`unshelve` to hide PRs from the daily digest. Scripts that hard-
657
- // coded these commands now get an "unknown command" error from commander.
693
+ // `move <pr-url> shelved|auto` to hide/restore PRs in the daily digest.
694
+ // Scripts that hard-coded these commands now get an "unknown command"
695
+ // error from commander.
658
696
  // ── Compliance Score ───────────────────────────────────────────────────
659
697
  {
660
698
  name: 'compliance-score',
@@ -1122,39 +1160,8 @@ export const commands = [
1122
1160
  });
1123
1161
  },
1124
1162
  },
1125
- // ── Shelve ─────────────────────────────────────────────────────────────
1126
- // Delegates to runShelve so the CLI emits the same `ShelveOutput`
1127
- // ({shelved, url}) as the library export + MCP tool. Previously it called
1128
- // runMove and emitted `MoveOutput` ({url, target, description}), which
1129
- // drifted from the pinned contract test and broke plugin consumers
1130
- // reading `data.shelved`. See issue #1037.
1131
- {
1132
- name: 'shelve',
1133
- localOnly: true,
1134
- register(program) {
1135
- program
1136
- .command('shelve <pr-url>')
1137
- .description('Shelve a PR (exclude from capacity and actionable issues)')
1138
- .option('--json', 'Output as JSON')
1139
- .action((prUrl, options) => executeAction(options, async () => (await import('./commands/shelve.js')).runShelve({ prUrl }), (data) => {
1140
- console.log(data.shelved ? `Shelved ${data.url}` : `Already shelved: ${data.url}`);
1141
- }));
1142
- },
1143
- },
1144
- // ── Unshelve ───────────────────────────────────────────────────────────
1145
- {
1146
- name: 'unshelve',
1147
- localOnly: true,
1148
- register(program) {
1149
- program
1150
- .command('unshelve <pr-url>')
1151
- .description('Unshelve a PR (include in capacity and actionable issues again)')
1152
- .option('--json', 'Output as JSON')
1153
- .action((prUrl, options) => executeAction(options, async () => (await import('./commands/shelve.js')).runUnshelve({ prUrl }), (data) => {
1154
- console.log(data.unshelved ? `Unshelved ${data.url}` : `Not currently shelved: ${data.url}`);
1155
- }));
1156
- },
1157
- },
1163
+ // The `shelve`/`unshelve` command aliases were retired in #1466 — they
1164
+ // duplicated `move <pr-url> shelved|auto`. Use `move` directly.
1158
1165
  // ── Move ───────────────────────────────────────────────────────────
1159
1166
  {
1160
1167
  name: 'move',
@@ -1164,9 +1171,12 @@ export const commands = [
1164
1171
  .command('move <pr-url> <target>')
1165
1172
  .description('Move a PR between states: attention, waiting, shelved, or auto (reset to computed)')
1166
1173
  .option('--json', 'Output as JSON')
1167
- .action((prUrl, target, options) => executeAction(options, async () => (await import('./commands/move.js')).runMove({ prUrl, target }), (data) => {
1168
- console.log(data.description);
1169
- }));
1174
+ .action(async (prUrl, target, options) => {
1175
+ const { MoveOutputSchema } = await import('./formatters/json.js');
1176
+ await executeAction(options, async () => (await import('./commands/move.js')).runMove({ prUrl, target }), (data) => {
1177
+ console.log(data.description);
1178
+ }, MoveOutputSchema);
1179
+ });
1170
1180
  },
1171
1181
  },
1172
1182
  // ── Dismiss ────────────────────────────────────────────────────────────
@@ -1210,48 +1220,8 @@ export const commands = [
1210
1220
  }));
1211
1221
  },
1212
1222
  },
1213
- // ── Override Status ────────────────────────────────────────────────────
1214
- {
1215
- name: 'override',
1216
- localOnly: true,
1217
- register(program) {
1218
- program
1219
- .command('override <pr-url> <status>')
1220
- .description('Manually override PR status (needs_addressing or waiting_on_maintainer)')
1221
- .option('--json', 'Output as JSON')
1222
- .action(async (prUrl, status, options) => {
1223
- const { MoveOutputSchema } = await import('./formatters/json.js');
1224
- await executeAction(options, async () => {
1225
- const validStatuses = ['needs_addressing', 'waiting_on_maintainer'];
1226
- if (!validStatuses.includes(status)) {
1227
- throw new Error(`Invalid status "${status}". Must be one of: ${validStatuses.join(', ')}`);
1228
- }
1229
- const target = status === 'needs_addressing' ? 'attention' : 'waiting';
1230
- const { runMove } = await import('./commands/move.js');
1231
- return runMove({ prUrl, target });
1232
- }, (data) => {
1233
- console.log(data.description);
1234
- }, MoveOutputSchema);
1235
- });
1236
- },
1237
- },
1238
- // ── Clear Override ────────────────────────────────────────────────────
1239
- {
1240
- name: 'clear-override',
1241
- localOnly: true,
1242
- register(program) {
1243
- program
1244
- .command('clear-override <pr-url>')
1245
- .description('Clear a manual status override for a PR')
1246
- .option('--json', 'Output as JSON')
1247
- .action(async (prUrl, options) => {
1248
- const { MoveOutputSchema } = await import('./formatters/json.js');
1249
- await executeAction(options, async () => (await import('./commands/move.js')).runMove({ prUrl, target: 'auto' }), (data) => {
1250
- console.log(data.description);
1251
- }, MoveOutputSchema);
1252
- });
1253
- },
1254
- },
1223
+ // The `override`/`clear-override` command aliases were retired in #1466 —
1224
+ // they wrapped `move <pr-url> attention|waiting|auto`. Use `move` directly.
1255
1225
  // ── PR Template ──────────────────────────────────────────────────────
1256
1226
  {
1257
1227
  name: 'pr-template',
@@ -1283,7 +1253,7 @@ export const commands = [
1283
1253
  register(program) {
1284
1254
  program
1285
1255
  .command('repo-vet <repo>')
1286
- .description('Compute repo health rubric (1–10 score + verdict) for `owner/repo`')
1256
+ .description('Compute the fresh repo health rubric (1–10 score + verdict) for `owner/repo`; includes the cached history score when one exists')
1287
1257
  .option('--json', 'Output as JSON')
1288
1258
  .action(async (repo, options) => {
1289
1259
  const { RepoVetOutputSchema } = await import('./formatters/json.js');
@@ -1293,7 +1263,12 @@ export const commands = [
1293
1263
  : data.rubricVerdict === 'proceed_with_caution'
1294
1264
  ? '⚠️'
1295
1265
  : '❌';
1296
- console.log(`\n${verdictEmoji} ${data.repoSlug}: ${data.rubricScore.toFixed(1)}/10 — ${data.rubricVerdict}`);
1266
+ console.log(`\n${verdictEmoji} ${data.repoSlug}: health ${data.rubricScore.toFixed(1)}/10 — ${data.rubricVerdict}`);
1267
+ if (data.historyScore !== undefined) {
1268
+ // Two different 1–10 scores (#1465) — label both so neither
1269
+ // reads as "the" repo score. See docs/repo-scores.md.
1270
+ console.log(` History score (your past PRs here): ${data.historyScore}/10 — cached, distinct from the fresh health score above`);
1271
+ }
1297
1272
  console.log(` Stars: ${data.repoMeta.stars} Last push: ${data.repoMeta.lastPushed}`);
1298
1273
  if (data.prMergeTime.medianDays !== null) {
1299
1274
  console.log(` Median merge time (90d): ${data.prMergeTime.medianDays.toFixed(1)} days (${data.prMergeTime.sampleSize} samples)`);