@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
@@ -8,6 +8,7 @@ import type { FetchedPR, DailyDigest, AgentState, RepoGroup, CommentedIssue, She
8
8
  import type { ContributionStats } from '../core/stats.js';
9
9
  import type { PRCheckFailure } from '../core/pr-monitor.js';
10
10
  import type { CIFormatterDiagnosis, FormatterDetectionResult } from '../core/formatter-detection.js';
11
+ import type { IssueAvailabilityVerdict, IssueVerification, VerifiedLinkedPR } from '../core/issue-verification.js';
11
12
  export type { CapacityAssessment, ActionableIssue, ActionableIssueType, CompactActionableIssue, ActionMenuItem, ActionMenu, };
12
13
  export type ErrorCode = 'AUTH_REQUIRED' | 'RATE_LIMITED' | 'VALIDATION' | 'CONFIGURATION' | 'NETWORK' | 'NOT_FOUND' | 'STATE_CORRUPTED' | 'CONCURRENCY' | 'UNKNOWN';
13
14
  export interface JsonOutput<T = unknown> {
@@ -20,7 +21,13 @@ export interface JsonOutput<T = unknown> {
20
21
  * (#1433): machine consumers of mutating --json commands must see that
21
22
  * the mutation will not sync. Set once per process from the CLI bootstrap
22
23
  * via {@link setEnvelopeGistWarning}; envelope-level (not data-level) so
23
- * per-command output schemas are untouched. */
24
+ * per-command output schemas are untouched.
25
+ *
26
+ * Omitted when the command's own payload already carries the same
27
+ * condition as a structured `warnings[{phase:'gist-init'}]` entry (#1444):
28
+ * commands that own a warnings[] array (`daily`) report gist degradation
29
+ * exactly once, there. Consumers should check `data.warnings` first and
30
+ * fall back to this field for commands without a warnings array. */
24
31
  gistInitWarning?: string;
25
32
  }
26
33
  /** Set (or clear) the gist degradation warning carried by every subsequent
@@ -60,12 +67,12 @@ export interface CompactRepoGroup {
60
67
  * See `DailyWarning` and issue #1042 for the rationale — keeping this a
61
68
  * fixed union so downstream consumers can switch on it without drift.
62
69
  */
63
- export type DailyWarningPhase = 'fetch' | 'repo-scores' | 'analytics' | 'scout-sync' | 'partition' | 'dismiss-filter' | 'gist-init' | 'gist-checkpoint' | 'gist-staleness' | 'state-load';
70
+ export type DailyWarningPhase = 'fetch' | 'repo-scores' | 'analytics' | 'merge-loop' | 'partition' | 'dismiss-filter' | 'gist-init' | 'gist-checkpoint' | 'gist-staleness' | 'state-load';
64
71
  /**
65
72
  * A single non-fatal failure surfaced from the `daily` pipeline. Unlike
66
73
  * `PRCheckFailure` (which is scoped to per-PR fetch errors), this covers
67
74
  * ancillary fetches that previously demoted to a log-only `warn()` — repo
68
- * metadata, monthly analytics, scout sync, Gist checkpoint, etc.
75
+ * metadata, monthly analytics, Gist checkpoint, etc.
69
76
  *
70
77
  * `timestamp` and `details` are optional structured extensions added in
71
78
  * #1193 so staleness warnings can carry `lastSuccessfulRefresh` /
@@ -91,6 +98,23 @@ export interface StalenessLike {
91
98
  detectedAt: string;
92
99
  }
93
100
  export declare function buildStalenessWarning(info: StalenessLike): DailyWarning;
101
+ /**
102
+ * One curated-list entry auto-marked done because its PR merged (#1463).
103
+ * Produced by the daily merge-loop reconciliation (commands/merge-loop.ts):
104
+ * a recently merged PR's URL was found inside a list entry's block (the
105
+ * entry line or an indented sub-bullet), and the entry was struck through
106
+ * via the same transform `list-mark-done` uses.
107
+ */
108
+ export interface MergedPRListUpdate {
109
+ /** The merged PR whose detection triggered the auto-mark. */
110
+ prUrl: string;
111
+ /** URL on the struck entry line (usually the issue URL the PR resolved). */
112
+ issueUrl: string;
113
+ /** Curated-list file that was updated. */
114
+ listPath: string;
115
+ /** True if the parent `### repo/name` heading was also struck through. */
116
+ repoHeadingStruck: boolean;
117
+ }
94
118
  export interface DailyOutput {
95
119
  digest: DailyDigestCompact;
96
120
  capacity: CapacityAssessment;
@@ -105,7 +129,7 @@ export interface DailyOutput {
105
129
  failures: PRCheckFailure[];
106
130
  /**
107
131
  * Non-fatal warnings from ancillary pipeline phases (repo metadata,
108
- * analytics, scout sync, Gist checkpoint, etc.). Always an array — empty
132
+ * analytics, Gist checkpoint, etc.). Always an array — empty
109
133
  * on clean runs. See #1042.
110
134
  */
111
135
  warnings: DailyWarning[];
@@ -116,6 +140,13 @@ export interface DailyOutput {
116
140
  * absent or null on runs where the gate stays silent.
117
141
  */
118
142
  strategySummary?: import('../core/strategy.js').StrategyResult | null;
143
+ /**
144
+ * Curated-list entries auto-marked done this run because their PR merged
145
+ * (#1463). Present only when at least one entry was actually struck —
146
+ * merge-free runs (and runs with no curated list / no matching entry)
147
+ * omit the field entirely so existing consumers and goldens see no change.
148
+ */
149
+ listUpdates?: MergedPRListUpdate[];
119
150
  }
120
151
  /**
121
152
  * Compact version of DailyOutput for reduced JSON payload size (#763).
@@ -145,6 +176,8 @@ export interface CompactDailyOutput {
145
176
  warnings: DailyWarning[];
146
177
  /** Periodic strategy snapshot, threaded through compact mode for parity. See {@link DailyOutput.strategySummary}. */
147
178
  strategySummary?: import('../core/strategy.js').StrategyResult | null;
179
+ /** Curated-list entries auto-marked done this run (#1463). See {@link DailyOutput.listUpdates}. */
180
+ listUpdates?: MergedPRListUpdate[];
148
181
  }
149
182
  /**
150
183
  * Strip a full DailyOutput down to the compact subset (#763).
@@ -185,7 +218,7 @@ export declare const StatusOutputSchema: z.ZodObject<{
185
218
  fetch: "fetch";
186
219
  "repo-scores": "repo-scores";
187
220
  analytics: "analytics";
188
- "scout-sync": "scout-sync";
221
+ "merge-loop": "merge-loop";
189
222
  partition: "partition";
190
223
  "dismiss-filter": "dismiss-filter";
191
224
  "gist-init": "gist-init";
@@ -401,7 +434,7 @@ export declare const DailyOutputSchema: z.ZodObject<{
401
434
  fetch: "fetch";
402
435
  "repo-scores": "repo-scores";
403
436
  analytics: "analytics";
404
- "scout-sync": "scout-sync";
437
+ "merge-loop": "merge-loop";
405
438
  partition: "partition";
406
439
  "dismiss-filter": "dismiss-filter";
407
440
  "gist-init": "gist-init";
@@ -458,6 +491,12 @@ export declare const DailyOutputSchema: z.ZodObject<{
458
491
  avoidPatterns: z.ZodArray<z.ZodString>;
459
492
  }, z.core.$loose>;
460
493
  }, z.core.$loose>>>;
494
+ listUpdates: z.ZodOptional<z.ZodArray<z.ZodObject<{
495
+ prUrl: z.ZodString;
496
+ issueUrl: z.ZodString;
497
+ listPath: z.ZodString;
498
+ repoHeadingStruck: z.ZodBoolean;
499
+ }, z.core.$strip>>>;
461
500
  }, z.core.$strip>;
462
501
  export declare const CompactDailyOutputSchema: z.ZodObject<{
463
502
  digest: z.ZodObject<{
@@ -549,7 +588,7 @@ export declare const CompactDailyOutputSchema: z.ZodObject<{
549
588
  fetch: "fetch";
550
589
  "repo-scores": "repo-scores";
551
590
  analytics: "analytics";
552
- "scout-sync": "scout-sync";
591
+ "merge-loop": "merge-loop";
553
592
  partition: "partition";
554
593
  "dismiss-filter": "dismiss-filter";
555
594
  "gist-init": "gist-init";
@@ -606,6 +645,12 @@ export declare const CompactDailyOutputSchema: z.ZodObject<{
606
645
  avoidPatterns: z.ZodArray<z.ZodString>;
607
646
  }, z.core.$loose>;
608
647
  }, z.core.$loose>>>;
648
+ listUpdates: z.ZodOptional<z.ZodArray<z.ZodObject<{
649
+ prUrl: z.ZodString;
650
+ issueUrl: z.ZodString;
651
+ listPath: z.ZodString;
652
+ repoHeadingStruck: z.ZodBoolean;
653
+ }, z.core.$strip>>>;
609
654
  }, z.core.$strip>;
610
655
  export declare const SearchOutputSchema: z.ZodObject<{
611
656
  candidates: z.ZodArray<z.ZodObject<{
@@ -666,6 +711,7 @@ export declare const SearchOutputSchema: z.ZodObject<{
666
711
  aiPolicyBlocklist: z.ZodArray<z.ZodString>;
667
712
  hiddenOwnPRCount: z.ZodNumber;
668
713
  rateLimitWarning: z.ZodOptional<z.ZodString>;
714
+ skipListUnavailable: z.ZodOptional<z.ZodBoolean>;
669
715
  }, z.core.$strip>;
670
716
  export declare const FeaturesOutputSchema: z.ZodObject<{
671
717
  quickWins: z.ZodArray<z.ZodObject<{
@@ -887,10 +933,12 @@ export declare const ClaimOutputSchema: z.ZodObject<{
887
933
  commentUrl: z.ZodString;
888
934
  issueUrl: z.ZodString;
889
935
  gistSyncWarning: z.ZodOptional<z.ZodString>;
936
+ stateSaveWarning: z.ZodOptional<z.ZodString>;
890
937
  }, z.core.$strip>;
891
938
  export declare const InitOutputSchema: z.ZodObject<{
892
939
  username: z.ZodString;
893
940
  message: z.ZodString;
941
+ gistSyncWarning: z.ZodOptional<z.ZodString>;
894
942
  }, z.core.$strip>;
895
943
  export declare const ManifestOutputSchema: z.ZodObject<{
896
944
  schemaVersion: z.ZodLiteral<1>;
@@ -908,6 +956,7 @@ export declare const SetupOutputSchema: z.ZodUnion<readonly [z.ZodObject<{
908
956
  success: z.ZodLiteral<true>;
909
957
  settings: z.ZodRecord<z.ZodString, z.ZodString>;
910
958
  warnings: z.ZodOptional<z.ZodArray<z.ZodString>>;
959
+ gistSyncWarning: z.ZodOptional<z.ZodString>;
911
960
  }, z.core.$strip>, z.ZodObject<{
912
961
  setupComplete: z.ZodLiteral<true>;
913
962
  config: z.ZodObject<{
@@ -942,6 +991,7 @@ export declare const ConfigCommandOutputSchema: z.ZodUnion<readonly [z.ZodObject
942
991
  success: z.ZodLiteral<true>;
943
992
  key: z.ZodString;
944
993
  value: z.ZodString;
994
+ gistSyncWarning: z.ZodOptional<z.ZodString>;
945
995
  }, z.core.$strip>, z.ZodObject<{
946
996
  keys: z.ZodArray<z.ZodObject<{}, z.core.$loose>>;
947
997
  }, z.core.$strip>]>;
@@ -1004,6 +1054,7 @@ export declare const RepoVetOutputSchema: z.ZodObject<{
1004
1054
  proceed_with_caution: "proceed_with_caution";
1005
1055
  avoid: "avoid";
1006
1056
  }>;
1057
+ historyScore: z.ZodOptional<z.ZodNumber>;
1007
1058
  }, z.core.$strip>;
1008
1059
  /**
1009
1060
  * The CLI wrapper renames the core function's `repo` metadata object to
@@ -1248,6 +1299,12 @@ export interface SearchOutput {
1248
1299
  hiddenOwnPRCount: number;
1249
1300
  /** Present when rate limits affected the search — either low pre-flight quota or mid-search rate limit hits (#100). */
1250
1301
  rateLimitWarning?: string;
1302
+ /**
1303
+ * Set when the configured skipped-issues file exists but could not be read
1304
+ * (#1448). The search ran with an EMPTY skip list, so explicitly-skipped
1305
+ * issues may appear in `candidates`. Absent on success.
1306
+ */
1307
+ skipListUnavailable?: boolean;
1251
1308
  }
1252
1309
  /** Horizon classification stamped on each features-mode candidate. */
1253
1310
  export type FeaturesHorizon = 'quick-win' | 'bigger-bet';
@@ -1285,6 +1342,13 @@ export interface IssueListInfo {
1285
1342
  availableCount: number;
1286
1343
  completedCount: number;
1287
1344
  skippedIssuesPath?: string;
1345
+ /**
1346
+ * Set when the issue list file was detected but could not be read (#1448).
1347
+ * In that case `availableCount`/`completedCount` are 0 because the content
1348
+ * was unreadable, NOT because the list is empty — consumers should not
1349
+ * treat the counts as authoritative. Absent on success.
1350
+ */
1351
+ readError?: string;
1288
1352
  }
1289
1353
  /**
1290
1354
  * Output of the startup command (combines auth, setup, daily, dashboard, issue list).
@@ -1373,18 +1437,47 @@ export interface CheckIntegrationOutput {
1373
1437
  unreferencedCount: number;
1374
1438
  }
1375
1439
  /**
1376
- * Status of a re-vetted issue from the curated list (#764).
1440
+ * Status of a re-vetted issue from the curated list (#764, #1494).
1441
+ *
1442
+ * As of #1494 the status is driven by the deterministic verify-issue verdict
1443
+ * (closing-vs-mention aware) rather than scout's substring heuristic:
1444
+ * - `at_risk` — verify found an open *mention* (cross-reference, not a closing
1445
+ * PR) or a merged closing PR awaiting issue close. Previously collapsed into
1446
+ * `claimed`/`has_pr`; the point of #1353.
1447
+ * - `own_open_pr` — the authenticated user already has an open closing PR.
1377
1448
  *
1378
- * `has_stalled_pr` (scout 0.9.0 #97) distinguishes open-but-stalled linked
1379
- * PRs from cleanly-claimed `has_pr` issues the issue is still actionable
1380
- * as a revive opportunity rather than something to drop.
1449
+ * `has_pr` / `has_stalled_pr` (scout 0.9.0 #97) now only arise on the fallback
1450
+ * path when verify itself errored and we drop back to scout's heuristic; they
1451
+ * are kept for back-compat.
1381
1452
  */
1382
- export type VetListItemStatus = 'still_available' | 'claimed' | 'closed' | 'has_pr' | 'has_stalled_pr' | 'error';
1453
+ export type VetListItemStatus = 'still_available' | 'claimed' | 'closed' | 'has_pr' | 'has_stalled_pr' | 'at_risk' | 'own_open_pr' | 'error';
1383
1454
  /** Output of the vet-list command (#764). */
1384
1455
  export interface VetListOutput {
1385
1456
  results: Array<VetOutput & {
1386
1457
  listStatus: VetListItemStatus;
1387
1458
  errorMessage?: string;
1459
+ /**
1460
+ * Set when the deterministic verify-issue check itself failed for this
1461
+ * entry (#1494). Its presence is the explicit signal that `listStatus`
1462
+ * is NOT authoritative — it came from the scout heuristic fallback (or is
1463
+ * `error`), and the row should be re-verified before acting on it. Pairs
1464
+ * with an absent `verification`; never set when `verification` is present.
1465
+ */
1466
+ verifyError?: string;
1467
+ /**
1468
+ * The deterministic verify-issue facts behind `listStatus` (#1494).
1469
+ * Present whenever verification succeeded for the entry; absent only when
1470
+ * verify itself errored (then `listStatus` comes from the scout fallback
1471
+ * and `verifyError` records why).
1472
+ */
1473
+ verification?: {
1474
+ verdict: IssueAvailabilityVerdict;
1475
+ verdictReason: string;
1476
+ state: IssueVerification['state'];
1477
+ stateReason: IssueVerification['stateReason'];
1478
+ assignees: string[];
1479
+ linkedPRs: VerifiedLinkedPR[];
1480
+ };
1388
1481
  }>;
1389
1482
  summary: {
1390
1483
  total: number;
@@ -1394,10 +1487,19 @@ export interface VetListOutput {
1394
1487
  hasPR: number;
1395
1488
  /** Open linked PRs that haven't been touched in 30+ days (scout 0.9.0 #97). Surfaced as revive opportunities, not auto-dropped. */
1396
1489
  hasStalledPR: number;
1490
+ /** Open mention-only cross-references or a merged closing PR awaiting issue close (#1494 / #1353). */
1491
+ atRisk: number;
1492
+ /** The authenticated user already has an open closing PR (#1494 / #1354). */
1493
+ ownOpenPr: number;
1397
1494
  errors: number;
1398
1495
  };
1399
1496
  pruneResult?: {
1400
1497
  removedCount: number;
1498
+ /**
1499
+ * Set when the prune read/write failed (#1448); `removedCount` is 0 in
1500
+ * that case and the list file is unchanged. Absent on a successful prune.
1501
+ */
1502
+ error?: string;
1401
1503
  };
1402
1504
  }
1403
1505
  /** Output of the vet command */
@@ -1500,6 +1602,12 @@ export interface ClaimOutput {
1500
1602
  issueUrl: string;
1501
1603
  /** Set when the post-mutation Gist checkpoint failed; the local mutation succeeded (#1370). */
1502
1604
  gistSyncWarning?: string;
1605
+ /**
1606
+ * Set when the claim comment posted to GitHub but saving the tracked issue
1607
+ * to local state threw (#1448) — the claim is live but UNTRACKED, so daily
1608
+ * runs will not monitor it. Absent on success.
1609
+ */
1610
+ stateSaveWarning?: string;
1503
1611
  }
1504
1612
  /** Info about a local git clone (#84) */
1505
1613
  export interface LocalRepoInfo {
@@ -42,6 +42,7 @@ export function toCompactDailyOutput(output) {
42
42
  failureCount: output.failures.length,
43
43
  warnings: output.warnings,
44
44
  strategySummary: output.strategySummary,
45
+ listUpdates: output.listUpdates,
45
46
  };
46
47
  }
47
48
  /**
@@ -96,7 +97,7 @@ const DailyWarningPhaseSchema = z.enum([
96
97
  'fetch',
97
98
  'repo-scores',
98
99
  'analytics',
99
- 'scout-sync',
100
+ 'merge-loop',
100
101
  'partition',
101
102
  'dismiss-filter',
102
103
  'gist-init',
@@ -292,6 +293,13 @@ export const AttentionSummarySchema = z.object({
292
293
  dormantFollowup: z.number().int().nonnegative(),
293
294
  waiting: z.number().int().nonnegative(),
294
295
  });
296
+ /** Mirrors {@link MergedPRListUpdate} (#1463). */
297
+ const MergedPRListUpdateSchema = z.object({
298
+ prUrl: z.string(),
299
+ issueUrl: z.string(),
300
+ listPath: z.string(),
301
+ repoHeadingStruck: z.boolean(),
302
+ });
295
303
  export const DailyOutputSchema = z.object({
296
304
  digest: DailyDigestCompactSchema,
297
305
  capacity: CapacityAssessmentSchema,
@@ -305,6 +313,7 @@ export const DailyOutputSchema = z.object({
305
313
  failures: z.array(PRCheckFailurePassthroughSchema),
306
314
  warnings: z.array(DailyWarningSchema),
307
315
  strategySummary: StrategyResultSchema.nullable().optional(),
316
+ listUpdates: z.array(MergedPRListUpdateSchema).optional(),
308
317
  });
309
318
  export const CompactDailyOutputSchema = z.object({
310
319
  digest: DailyDigestCompactSchema,
@@ -317,6 +326,7 @@ export const CompactDailyOutputSchema = z.object({
317
326
  failureCount: z.number().int().nonnegative(),
318
327
  warnings: z.array(DailyWarningSchema),
319
328
  strategySummary: StrategyResultSchema.nullable().optional(),
329
+ listUpdates: z.array(MergedPRListUpdateSchema).optional(),
320
330
  });
321
331
  // ── Search output schema (#1147) ─────────────────────────────────────
322
332
  const SearchPrioritySchema = z.enum(['merged_pr', 'preferred_org', 'starred', 'normal']);
@@ -377,6 +387,9 @@ export const SearchOutputSchema = z.object({
377
387
  aiPolicyBlocklist: z.array(z.string()),
378
388
  hiddenOwnPRCount: z.number().int().nonnegative(),
379
389
  rateLimitWarning: z.string().optional(),
390
+ // Skip file unreadable — search ran with an empty skip list (#1448).
391
+ // Optional: absent on clean runs.
392
+ skipListUnavailable: z.boolean().optional(),
380
393
  });
381
394
  // ── Features output schema (scout 0.9.0 #97/#98/#99) ─────────────────
382
395
  //
@@ -482,10 +495,15 @@ export const ClaimOutputSchema = z.object({
482
495
  issueUrl: z.string(),
483
496
  // Post-mutation Gist checkpoint failure (#1370). Optional: absent on clean runs.
484
497
  gistSyncWarning: z.string().optional(),
498
+ // Claim comment posted but local state save threw — claim is live but
499
+ // untracked (#1448). Optional: absent on clean runs.
500
+ stateSaveWarning: z.string().optional(),
485
501
  });
486
502
  export const InitOutputSchema = z.object({
487
503
  username: z.string(),
488
504
  message: z.string(),
505
+ // Post-mutation Gist checkpoint failure (#1440). Optional: absent on clean runs.
506
+ gistSyncWarning: z.string().optional(),
489
507
  });
490
508
  // ── #1190: plugin → CLI contract ─────────────────────────────────────
491
509
  //
@@ -508,6 +526,8 @@ const SetupSetOutputSchema = z.object({
508
526
  success: z.literal(true),
509
527
  settings: z.record(z.string(), z.string()),
510
528
  warnings: z.array(z.string()).optional(),
529
+ // Post-mutation Gist checkpoint failure (#1440). Optional: absent on clean runs.
530
+ gistSyncWarning: z.string().optional(),
511
531
  });
512
532
  const SetupCompleteOutputSchema = z.object({
513
533
  setupComplete: z.literal(true),
@@ -544,6 +564,8 @@ const ConfigSetOutputSchema = z.object({
544
564
  success: z.literal(true),
545
565
  key: z.string(),
546
566
  value: z.string(),
567
+ // Post-mutation Gist checkpoint failure (#1440). Optional: absent on clean runs.
568
+ gistSyncWarning: z.string().optional(),
547
569
  });
548
570
  const ConfigListKeysOutputSchema = z.object({
549
571
  keys: z.array(ConfigKeyDefSchema),
@@ -626,6 +648,21 @@ export const RepoVetOutputSchema = z.object({
626
648
  }),
627
649
  rubricScore: z.number(),
628
650
  rubricVerdict: z.enum(['recommended', 'proceed_with_caution', 'avoid']),
651
+ /**
652
+ * Score components (#1465): two distinct 1–10 numbers share this envelope.
653
+ * `rubricScore` above is the fresh HEALTH score (the repo's current public
654
+ * signals, weighted per docs/repo-scores.md §Health score — the name
655
+ * predates the split and is kept for back-compat). `historyScore` is the
656
+ * cached HISTORY score: the user's own merge outcomes in this repo, from
657
+ * `state.repoScores` (repo-score-manager.ts). Absent when the user has no
658
+ * cached score for the repo. They diverge whenever repo health changed
659
+ * since the user's last merge there — consumers must never present one as
660
+ * the other. Deliberately unbounded like the persisted RepoScore.score
661
+ * source (state-schema validates plain z.number(); v1-era state was
662
+ * migrated verbatim) — bounds here would turn a legacy out-of-range
663
+ * stored score into a hard --json contract throw (#1465 review).
664
+ */
665
+ historyScore: z.number().optional(),
629
666
  });
630
667
  const ComplianceCheckSchema = z.object({
631
668
  status: z.enum(['pass', 'warn', 'fail']),
@@ -730,6 +767,22 @@ export function toCompactStartupOutput(output) {
730
767
  issueList: output.issueList,
731
768
  };
732
769
  }
770
+ /**
771
+ * True when the command's own payload already reports gist-init degradation
772
+ * as a structured `warnings[{phase:'gist-init'}]` entry (#1444). The same
773
+ * condition used to be double-reported in a single `daily --json` payload —
774
+ * `envelope.gistInitWarning` AND `data.warnings` carried it in two prose
775
+ * variants — so the envelope suppresses its duplicate when the structured
776
+ * entry is present. Keyed on the warning's phase (not its prose) so the two
777
+ * surfaces cannot drift apart again.
778
+ */
779
+ function dataCarriesGistInitWarning(data) {
780
+ if (data === null || typeof data !== 'object')
781
+ return false;
782
+ const warnings = data.warnings;
783
+ return (Array.isArray(warnings) &&
784
+ warnings.some((w) => w !== null && typeof w === 'object' && w.phase === 'gist-init'));
785
+ }
733
786
  /**
734
787
  * Wrap data in a standard JSON output envelope
735
788
  */
@@ -738,7 +791,7 @@ export function jsonSuccess(data) {
738
791
  success: true,
739
792
  data,
740
793
  timestamp: new Date().toISOString(),
741
- ...(envelopeGistWarning ? { gistInitWarning: envelopeGistWarning } : {}),
794
+ ...(envelopeGistWarning && !dataCarriesGistInitWarning(data) ? { gistInitWarning: envelopeGistWarning } : {}),
742
795
  };
743
796
  }
744
797
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oss-autopilot/core",
3
- "version": "3.13.4",
3
+ "version": "3.14.1",
4
4
  "description": "CLI and core library for managing open source contributions",
5
5
  "type": "module",
6
6
  "bin": {
@@ -61,7 +61,7 @@
61
61
  "devDependencies": {
62
62
  "@types/node": "^25.9.3",
63
63
  "@vitest/coverage-v8": "^4.1.8",
64
- "esbuild": "^0.28.0",
64
+ "esbuild": "^0.28.1",
65
65
  "tsx": "^4.22.4",
66
66
  "typedoc": "^0.28.19",
67
67
  "typescript": "^5.9.3",
@@ -1,45 +0,0 @@
1
- /**
2
- * Shelve/Unshelve commands
3
- * Manages shelving PRs to exclude them from capacity and actionable issues.
4
- * Shelved PRs are auto-unshelved when a maintainer engages.
5
- *
6
- * Note: The CLI and MCP shelve/unshelve commands delegate to runMove(),
7
- * which also clears status overrides. These functions match that behavior
8
- * to keep the library API consistent.
9
- */
10
- import { PR_URL_PATTERN } from './validation.js';
11
- export interface ShelveOutput {
12
- shelved: boolean;
13
- url: string;
14
- /** Set when the post-mutation Gist checkpoint failed; the local mutation succeeded (#1370). */
15
- gistSyncWarning?: string;
16
- }
17
- export interface UnshelveOutput {
18
- unshelved: boolean;
19
- url: string;
20
- /** Set when the post-mutation Gist checkpoint failed; the local mutation succeeded (#1370). */
21
- gistSyncWarning?: string;
22
- }
23
- export { PR_URL_PATTERN };
24
- /**
25
- * Shelve a PR, hiding it from daily digest and capacity calculations.
26
- *
27
- * @param options - Shelve options
28
- * @param options.prUrl - Full GitHub PR URL
29
- * @returns Whether the PR was newly shelved (false if already shelved)
30
- * @throws {ValidationError} If the URL is not a valid GitHub PR URL
31
- */
32
- export declare function runShelve(options: {
33
- prUrl: string;
34
- }): Promise<ShelveOutput>;
35
- /**
36
- * Unshelve a PR, restoring it to the daily digest.
37
- *
38
- * @param options - Unshelve options
39
- * @param options.prUrl - Full GitHub PR URL
40
- * @returns Whether the PR was removed from the shelf (false if not shelved)
41
- * @throws {ValidationError} If the URL is not a valid GitHub PR URL
42
- */
43
- export declare function runUnshelve(options: {
44
- prUrl: string;
45
- }): Promise<UnshelveOutput>;
@@ -1,54 +0,0 @@
1
- /**
2
- * Shelve/Unshelve commands
3
- * Manages shelving PRs to exclude them from capacity and actionable issues.
4
- * Shelved PRs are auto-unshelved when a maintainer engages.
5
- *
6
- * Note: The CLI and MCP shelve/unshelve commands delegate to runMove(),
7
- * which also clears status overrides. These functions match that behavior
8
- * to keep the library API consistent.
9
- */
10
- import { getStateManager, maybeCheckpoint } from '../core/index.js';
11
- import { PR_URL_PATTERN, validateGitHubUrl, validateUrl } from './validation.js';
12
- const MODULE = 'shelve';
13
- // Re-export for backward compatibility with tests
14
- export { PR_URL_PATTERN };
15
- /**
16
- * Shelve a PR, hiding it from daily digest and capacity calculations.
17
- *
18
- * @param options - Shelve options
19
- * @param options.prUrl - Full GitHub PR URL
20
- * @returns Whether the PR was newly shelved (false if already shelved)
21
- * @throws {ValidationError} If the URL is not a valid GitHub PR URL
22
- */
23
- export async function runShelve(options) {
24
- validateUrl(options.prUrl);
25
- validateGitHubUrl(options.prUrl, PR_URL_PATTERN, 'PR');
26
- const stateManager = getStateManager();
27
- let added = false;
28
- stateManager.batch(() => {
29
- added = stateManager.shelvePR(options.prUrl);
30
- stateManager.clearStatusOverride(options.prUrl);
31
- });
32
- const gistSyncWarning = await maybeCheckpoint(stateManager, MODULE);
33
- return { shelved: added, url: options.prUrl, ...(gistSyncWarning ? { gistSyncWarning } : {}) };
34
- }
35
- /**
36
- * Unshelve a PR, restoring it to the daily digest.
37
- *
38
- * @param options - Unshelve options
39
- * @param options.prUrl - Full GitHub PR URL
40
- * @returns Whether the PR was removed from the shelf (false if not shelved)
41
- * @throws {ValidationError} If the URL is not a valid GitHub PR URL
42
- */
43
- export async function runUnshelve(options) {
44
- validateUrl(options.prUrl);
45
- validateGitHubUrl(options.prUrl, PR_URL_PATTERN, 'PR');
46
- const stateManager = getStateManager();
47
- let removed = false;
48
- stateManager.batch(() => {
49
- removed = stateManager.unshelvePR(options.prUrl);
50
- stateManager.clearStatusOverride(options.prUrl);
51
- });
52
- const gistSyncWarning = await maybeCheckpoint(stateManager, MODULE);
53
- return { unshelved: removed, url: options.prUrl, ...(gistSyncWarning ? { gistSyncWarning } : {}) };
54
- }