@oss-autopilot/core 3.6.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 +94 -1
- package/dist/cli.bundle.cjs +99 -91
- 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 +3 -1
- package/dist/commands/index.js +2 -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 +52 -6
- package/dist/commands/vet-list.js +21 -5
- package/dist/commands/vet.js +3 -1
- 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/formatters/json.d.ts +224 -35
- package/dist/formatters/json.js +28 -0
- package/package.json +2 -2
|
@@ -23,7 +23,35 @@ export interface LinkedPR {
|
|
|
23
23
|
login: string;
|
|
24
24
|
} | null;
|
|
25
25
|
state: LinkedPRState;
|
|
26
|
+
/**
|
|
27
|
+
* ISO timestamp of the linked PR's last update, surfaced from scout's
|
|
28
|
+
* timeline-event metadata when available (#97). Optional so existing
|
|
29
|
+
* callers and fixtures that don't carry the field continue to type-check.
|
|
30
|
+
* Used by `isLinkedPRStalled` to flag open PRs that haven't been touched
|
|
31
|
+
* in the last `STALLED_PR_THRESHOLD_DAYS` days.
|
|
32
|
+
*/
|
|
33
|
+
updatedAt?: string;
|
|
26
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Days of inactivity that classify an open linked PR as "stalled" — kept
|
|
37
|
+
* in sync with scout's `STALLED_PR_THRESHOLD_DAYS` so the autopilot helper
|
|
38
|
+
* and scout's own annotation use the same boundary.
|
|
39
|
+
*/
|
|
40
|
+
export declare const STALLED_PR_THRESHOLD_DAYS = 30;
|
|
41
|
+
/**
|
|
42
|
+
* Determine whether an autopilot-shaped `LinkedPR` is stalled.
|
|
43
|
+
*
|
|
44
|
+
* True when:
|
|
45
|
+
* - the PR is open, AND
|
|
46
|
+
* - `updatedAt` is set, AND
|
|
47
|
+
* - the elapsed time since `updatedAt` is at least `thresholdDays`.
|
|
48
|
+
*
|
|
49
|
+
* Returns false for closed/merged PRs, missing `updatedAt`, or invalid
|
|
50
|
+
* timestamps. Reimplemented locally rather than delegating to scout's
|
|
51
|
+
* helper so this module owns autopilot's `LinkedPR` shape contract end
|
|
52
|
+
* to end (avoids a runtime import dependency on scout's internal type).
|
|
53
|
+
*/
|
|
54
|
+
export declare function isLinkedPRStalled(linkedPR: LinkedPR | null | undefined, now?: Date, thresholdDays?: number): boolean;
|
|
27
55
|
export declare function classifyLinkedPR(params: {
|
|
28
56
|
linkedPR: LinkedPR | null;
|
|
29
57
|
userLogin: string;
|
|
@@ -11,6 +11,38 @@
|
|
|
11
11
|
* linked PR themselves (e.g. via Octokit) and hand the shape to this
|
|
12
12
|
* function. See #978 for the upstream data-contract work.
|
|
13
13
|
*/
|
|
14
|
+
/**
|
|
15
|
+
* Days of inactivity that classify an open linked PR as "stalled" — kept
|
|
16
|
+
* in sync with scout's `STALLED_PR_THRESHOLD_DAYS` so the autopilot helper
|
|
17
|
+
* and scout's own annotation use the same boundary.
|
|
18
|
+
*/
|
|
19
|
+
export const STALLED_PR_THRESHOLD_DAYS = 30;
|
|
20
|
+
/**
|
|
21
|
+
* Determine whether an autopilot-shaped `LinkedPR` is stalled.
|
|
22
|
+
*
|
|
23
|
+
* True when:
|
|
24
|
+
* - the PR is open, AND
|
|
25
|
+
* - `updatedAt` is set, AND
|
|
26
|
+
* - the elapsed time since `updatedAt` is at least `thresholdDays`.
|
|
27
|
+
*
|
|
28
|
+
* Returns false for closed/merged PRs, missing `updatedAt`, or invalid
|
|
29
|
+
* timestamps. Reimplemented locally rather than delegating to scout's
|
|
30
|
+
* helper so this module owns autopilot's `LinkedPR` shape contract end
|
|
31
|
+
* to end (avoids a runtime import dependency on scout's internal type).
|
|
32
|
+
*/
|
|
33
|
+
export function isLinkedPRStalled(linkedPR, now = new Date(), thresholdDays = STALLED_PR_THRESHOLD_DAYS) {
|
|
34
|
+
if (!linkedPR)
|
|
35
|
+
return false;
|
|
36
|
+
if (linkedPR.state !== 'open')
|
|
37
|
+
return false;
|
|
38
|
+
if (!linkedPR.updatedAt)
|
|
39
|
+
return false;
|
|
40
|
+
const updatedMs = Date.parse(linkedPR.updatedAt);
|
|
41
|
+
if (!Number.isFinite(updatedMs))
|
|
42
|
+
return false;
|
|
43
|
+
const ageDays = (now.getTime() - updatedMs) / (1000 * 60 * 60 * 24);
|
|
44
|
+
return ageDays >= thresholdDays;
|
|
45
|
+
}
|
|
14
46
|
/**
|
|
15
47
|
* Normalize a state value from either REST (lowercase `open`/`closed`
|
|
16
48
|
* plus a separate `merged` boolean) or GraphQL (uppercase `OPEN`/
|
|
@@ -509,11 +509,137 @@ export declare const SearchOutputSchema: z.ZodObject<{
|
|
|
509
509
|
isResponsive: z.ZodBoolean;
|
|
510
510
|
lastMergedAt: z.ZodOptional<z.ZodString>;
|
|
511
511
|
}, z.core.$strip>>;
|
|
512
|
+
linkedPR: z.ZodOptional<z.ZodObject<{
|
|
513
|
+
number: z.ZodNumber;
|
|
514
|
+
state: z.ZodEnum<{
|
|
515
|
+
closed: "closed";
|
|
516
|
+
open: "open";
|
|
517
|
+
merged: "merged";
|
|
518
|
+
}>;
|
|
519
|
+
url: z.ZodString;
|
|
520
|
+
updatedAt: z.ZodOptional<z.ZodString>;
|
|
521
|
+
isStalled: z.ZodBoolean;
|
|
522
|
+
}, z.core.$strip>>;
|
|
512
523
|
}, z.core.$strip>>;
|
|
513
524
|
excludedRepos: z.ZodArray<z.ZodString>;
|
|
514
525
|
aiPolicyBlocklist: z.ZodArray<z.ZodString>;
|
|
515
526
|
rateLimitWarning: z.ZodOptional<z.ZodString>;
|
|
516
527
|
}, z.core.$strip>;
|
|
528
|
+
export declare const FeaturesOutputSchema: z.ZodObject<{
|
|
529
|
+
quickWins: z.ZodArray<z.ZodObject<{
|
|
530
|
+
issue: z.ZodObject<{
|
|
531
|
+
repo: z.ZodString;
|
|
532
|
+
repoUrl: z.ZodString;
|
|
533
|
+
number: z.ZodNumber;
|
|
534
|
+
title: z.ZodString;
|
|
535
|
+
url: z.ZodString;
|
|
536
|
+
labels: z.ZodArray<z.ZodString>;
|
|
537
|
+
}, z.core.$strip>;
|
|
538
|
+
recommendation: z.ZodEnum<{
|
|
539
|
+
approve: "approve";
|
|
540
|
+
skip: "skip";
|
|
541
|
+
needs_review: "needs_review";
|
|
542
|
+
}>;
|
|
543
|
+
reasonsToApprove: z.ZodArray<z.ZodString>;
|
|
544
|
+
reasonsToSkip: z.ZodArray<z.ZodString>;
|
|
545
|
+
searchPriority: z.ZodEnum<{
|
|
546
|
+
normal: "normal";
|
|
547
|
+
merged_pr: "merged_pr";
|
|
548
|
+
preferred_org: "preferred_org";
|
|
549
|
+
starred: "starred";
|
|
550
|
+
}>;
|
|
551
|
+
viabilityScore: z.ZodNumber;
|
|
552
|
+
grade: z.ZodObject<{
|
|
553
|
+
letter: z.ZodEnum<{
|
|
554
|
+
A: "A";
|
|
555
|
+
B: "B";
|
|
556
|
+
C: "C";
|
|
557
|
+
F: "F";
|
|
558
|
+
}>;
|
|
559
|
+
reason: z.ZodString;
|
|
560
|
+
}, z.core.$strip>;
|
|
561
|
+
repoScore: z.ZodOptional<z.ZodObject<{
|
|
562
|
+
score: z.ZodNumber;
|
|
563
|
+
mergedPRCount: z.ZodNumber;
|
|
564
|
+
closedWithoutMergeCount: z.ZodNumber;
|
|
565
|
+
isResponsive: z.ZodBoolean;
|
|
566
|
+
lastMergedAt: z.ZodOptional<z.ZodString>;
|
|
567
|
+
}, z.core.$strip>>;
|
|
568
|
+
linkedPR: z.ZodOptional<z.ZodObject<{
|
|
569
|
+
number: z.ZodNumber;
|
|
570
|
+
state: z.ZodEnum<{
|
|
571
|
+
closed: "closed";
|
|
572
|
+
open: "open";
|
|
573
|
+
merged: "merged";
|
|
574
|
+
}>;
|
|
575
|
+
url: z.ZodString;
|
|
576
|
+
updatedAt: z.ZodOptional<z.ZodString>;
|
|
577
|
+
isStalled: z.ZodBoolean;
|
|
578
|
+
}, z.core.$strip>>;
|
|
579
|
+
horizon: z.ZodEnum<{
|
|
580
|
+
"quick-win": "quick-win";
|
|
581
|
+
"bigger-bet": "bigger-bet";
|
|
582
|
+
}>;
|
|
583
|
+
}, z.core.$strip>>;
|
|
584
|
+
biggerBets: z.ZodArray<z.ZodObject<{
|
|
585
|
+
issue: z.ZodObject<{
|
|
586
|
+
repo: z.ZodString;
|
|
587
|
+
repoUrl: z.ZodString;
|
|
588
|
+
number: z.ZodNumber;
|
|
589
|
+
title: z.ZodString;
|
|
590
|
+
url: z.ZodString;
|
|
591
|
+
labels: z.ZodArray<z.ZodString>;
|
|
592
|
+
}, z.core.$strip>;
|
|
593
|
+
recommendation: z.ZodEnum<{
|
|
594
|
+
approve: "approve";
|
|
595
|
+
skip: "skip";
|
|
596
|
+
needs_review: "needs_review";
|
|
597
|
+
}>;
|
|
598
|
+
reasonsToApprove: z.ZodArray<z.ZodString>;
|
|
599
|
+
reasonsToSkip: z.ZodArray<z.ZodString>;
|
|
600
|
+
searchPriority: z.ZodEnum<{
|
|
601
|
+
normal: "normal";
|
|
602
|
+
merged_pr: "merged_pr";
|
|
603
|
+
preferred_org: "preferred_org";
|
|
604
|
+
starred: "starred";
|
|
605
|
+
}>;
|
|
606
|
+
viabilityScore: z.ZodNumber;
|
|
607
|
+
grade: z.ZodObject<{
|
|
608
|
+
letter: z.ZodEnum<{
|
|
609
|
+
A: "A";
|
|
610
|
+
B: "B";
|
|
611
|
+
C: "C";
|
|
612
|
+
F: "F";
|
|
613
|
+
}>;
|
|
614
|
+
reason: z.ZodString;
|
|
615
|
+
}, z.core.$strip>;
|
|
616
|
+
repoScore: z.ZodOptional<z.ZodObject<{
|
|
617
|
+
score: z.ZodNumber;
|
|
618
|
+
mergedPRCount: z.ZodNumber;
|
|
619
|
+
closedWithoutMergeCount: z.ZodNumber;
|
|
620
|
+
isResponsive: z.ZodBoolean;
|
|
621
|
+
lastMergedAt: z.ZodOptional<z.ZodString>;
|
|
622
|
+
}, z.core.$strip>>;
|
|
623
|
+
linkedPR: z.ZodOptional<z.ZodObject<{
|
|
624
|
+
number: z.ZodNumber;
|
|
625
|
+
state: z.ZodEnum<{
|
|
626
|
+
closed: "closed";
|
|
627
|
+
open: "open";
|
|
628
|
+
merged: "merged";
|
|
629
|
+
}>;
|
|
630
|
+
url: z.ZodString;
|
|
631
|
+
updatedAt: z.ZodOptional<z.ZodString>;
|
|
632
|
+
isStalled: z.ZodBoolean;
|
|
633
|
+
}, z.core.$strip>>;
|
|
634
|
+
horizon: z.ZodEnum<{
|
|
635
|
+
"quick-win": "quick-win";
|
|
636
|
+
"bigger-bet": "bigger-bet";
|
|
637
|
+
}>;
|
|
638
|
+
}, z.core.$strip>>;
|
|
639
|
+
anchorRepos: z.ZodArray<z.ZodString>;
|
|
640
|
+
message: z.ZodNullable<z.ZodString>;
|
|
641
|
+
rateLimitWarning: z.ZodOptional<z.ZodString>;
|
|
642
|
+
}, z.core.$strip>;
|
|
517
643
|
export declare const DoctorOutputSchema: z.ZodObject<{
|
|
518
644
|
checks: z.ZodArray<z.ZodObject<{
|
|
519
645
|
name: z.ZodString;
|
|
@@ -846,46 +972,95 @@ export declare const LocalReposOutputSchema: z.ZodObject<{
|
|
|
846
972
|
cachedAt: z.ZodString;
|
|
847
973
|
fromCache: z.ZodBoolean;
|
|
848
974
|
}, z.core.$strip>;
|
|
975
|
+
/**
|
|
976
|
+
* Compact summary of an issue's first linked PR, surfaced on candidate
|
|
977
|
+
* outputs (#97 / scout 0.9.0). `isStalled` is `true` when the PR is open
|
|
978
|
+
* and has not been updated for `STALLED_PR_THRESHOLD_DAYS` (default 30) —
|
|
979
|
+
* a revive-opportunity signal callers can render or filter on.
|
|
980
|
+
*
|
|
981
|
+
* `state` mirrors autopilot's existing tri-state classifier (`'merged'` is
|
|
982
|
+
* folded in from scout's `merged: true` boolean), not scout's raw enum.
|
|
983
|
+
*/
|
|
984
|
+
export interface CandidateLinkedPR {
|
|
985
|
+
number: number;
|
|
986
|
+
state: 'open' | 'closed' | 'merged';
|
|
987
|
+
url: string;
|
|
988
|
+
/** ISO timestamp of the PR's last update (when scout surfaces it). */
|
|
989
|
+
updatedAt?: string;
|
|
990
|
+
/** True when the PR is open AND `updatedAt` is more than 30 days old. */
|
|
991
|
+
isStalled: boolean;
|
|
992
|
+
}
|
|
993
|
+
/**
|
|
994
|
+
* One candidate row in `SearchOutput`/`FeaturesOutput`. Extracted so the
|
|
995
|
+
* features command can reuse the exact contract `runSearch` already
|
|
996
|
+
* publishes — keeping the two outputs structurally identical for everything
|
|
997
|
+
* except the bucket-specific `horizon` annotation.
|
|
998
|
+
*/
|
|
999
|
+
export interface SearchCandidate {
|
|
1000
|
+
issue: {
|
|
1001
|
+
repo: string;
|
|
1002
|
+
repoUrl: string;
|
|
1003
|
+
number: number;
|
|
1004
|
+
title: string;
|
|
1005
|
+
url: string;
|
|
1006
|
+
labels: string[];
|
|
1007
|
+
};
|
|
1008
|
+
recommendation: 'approve' | 'skip' | 'needs_review';
|
|
1009
|
+
reasonsToApprove: string[];
|
|
1010
|
+
reasonsToSkip: string[];
|
|
1011
|
+
searchPriority: SearchPriority;
|
|
1012
|
+
/** 0-100 scale composite viability score. Sanitized on the boundary (#1043): out-of-contract values are coerced to 0 and logged. */
|
|
1013
|
+
viabilityScore: number;
|
|
1014
|
+
/**
|
|
1015
|
+
* Letter grade (A/B/C/F) computed from the autopilot-tracked repoScore.
|
|
1016
|
+
* Scout's `search` does not emit per-candidate projectHealth, so scout-side
|
|
1017
|
+
* signals are treated as unknown; unscored repos grade 'F'. See #1043.
|
|
1018
|
+
*/
|
|
1019
|
+
grade: {
|
|
1020
|
+
letter: 'A' | 'B' | 'C' | 'F';
|
|
1021
|
+
reason: string;
|
|
1022
|
+
};
|
|
1023
|
+
repoScore?: {
|
|
1024
|
+
/** 1-10 scale repository quality score */
|
|
1025
|
+
score: number;
|
|
1026
|
+
mergedPRCount: number;
|
|
1027
|
+
closedWithoutMergeCount: number;
|
|
1028
|
+
isResponsive: boolean;
|
|
1029
|
+
lastMergedAt?: string;
|
|
1030
|
+
};
|
|
1031
|
+
/**
|
|
1032
|
+
* First linked PR on the issue, when scout surfaced one. Optional —
|
|
1033
|
+
* absent when no linked PR exists. `isStalled` flags revive
|
|
1034
|
+
* opportunities (open PR + no updates for 30+ days, scout 0.9.0 #97).
|
|
1035
|
+
*/
|
|
1036
|
+
linkedPR?: CandidateLinkedPR;
|
|
1037
|
+
}
|
|
849
1038
|
export interface SearchOutput {
|
|
850
|
-
candidates:
|
|
851
|
-
issue: {
|
|
852
|
-
repo: string;
|
|
853
|
-
repoUrl: string;
|
|
854
|
-
number: number;
|
|
855
|
-
title: string;
|
|
856
|
-
url: string;
|
|
857
|
-
labels: string[];
|
|
858
|
-
};
|
|
859
|
-
recommendation: 'approve' | 'skip' | 'needs_review';
|
|
860
|
-
reasonsToApprove: string[];
|
|
861
|
-
reasonsToSkip: string[];
|
|
862
|
-
searchPriority: SearchPriority;
|
|
863
|
-
/** 0-100 scale composite viability score. Sanitized on the boundary (#1043): out-of-contract values are coerced to 0 and logged. */
|
|
864
|
-
viabilityScore: number;
|
|
865
|
-
/**
|
|
866
|
-
* Letter grade (A/B/C/F) computed from the autopilot-tracked repoScore.
|
|
867
|
-
* Scout's `search` does not emit per-candidate projectHealth, so scout-side
|
|
868
|
-
* signals are treated as unknown; unscored repos grade 'F'. See #1043.
|
|
869
|
-
*/
|
|
870
|
-
grade: {
|
|
871
|
-
letter: 'A' | 'B' | 'C' | 'F';
|
|
872
|
-
reason: string;
|
|
873
|
-
};
|
|
874
|
-
repoScore?: {
|
|
875
|
-
/** 1-10 scale repository quality score */
|
|
876
|
-
score: number;
|
|
877
|
-
mergedPRCount: number;
|
|
878
|
-
closedWithoutMergeCount: number;
|
|
879
|
-
isResponsive: boolean;
|
|
880
|
-
lastMergedAt?: string;
|
|
881
|
-
};
|
|
882
|
-
}>;
|
|
1039
|
+
candidates: SearchCandidate[];
|
|
883
1040
|
excludedRepos: string[];
|
|
884
1041
|
/** Repos with known anti-AI contribution policies, filtered from search results (#108). */
|
|
885
1042
|
aiPolicyBlocklist: string[];
|
|
886
1043
|
/** Present when rate limits affected the search — either low pre-flight quota or mid-search rate limit hits (#100). */
|
|
887
1044
|
rateLimitWarning?: string;
|
|
888
1045
|
}
|
|
1046
|
+
/** Horizon classification stamped on each features-mode candidate. */
|
|
1047
|
+
export type FeaturesHorizon = 'quick-win' | 'bigger-bet';
|
|
1048
|
+
/** A `SearchCandidate` augmented with its features-mode horizon. */
|
|
1049
|
+
export type FeaturesCandidate = SearchCandidate & {
|
|
1050
|
+
horizon: FeaturesHorizon;
|
|
1051
|
+
};
|
|
1052
|
+
export interface FeaturesOutput {
|
|
1053
|
+
/** "Quick-win" bucket: feature-scoped issues without strong commitment markers (no milestone, no roadmap, no bigger-bet labels). */
|
|
1054
|
+
quickWins: FeaturesCandidate[];
|
|
1055
|
+
/** "Bigger-bet" bucket: feature-scoped issues that carry maintainer-commitment signals (milestone, roadmap, bigger-bet label). */
|
|
1056
|
+
biggerBets: FeaturesCandidate[];
|
|
1057
|
+
/** Repos that qualified as anchors for this run (3+ merged PRs, configurable). Empty when the user has no anchor repos yet. */
|
|
1058
|
+
anchorRepos: string[];
|
|
1059
|
+
/** Human-friendly explainer shown when neither bucket has results (no anchors, or anchors but no open feature opportunities). `null` on success. */
|
|
1060
|
+
message: string | null;
|
|
1061
|
+
/** Present when rate limits affected the search. Mirrors `SearchOutput.rateLimitWarning`. */
|
|
1062
|
+
rateLimitWarning?: string;
|
|
1063
|
+
}
|
|
889
1064
|
export interface TrackOutput {
|
|
890
1065
|
pr: {
|
|
891
1066
|
repo: string;
|
|
@@ -991,8 +1166,14 @@ export interface CheckIntegrationOutput {
|
|
|
991
1166
|
newFiles: NewFileInfo[];
|
|
992
1167
|
unreferencedCount: number;
|
|
993
1168
|
}
|
|
994
|
-
/**
|
|
995
|
-
|
|
1169
|
+
/**
|
|
1170
|
+
* Status of a re-vetted issue from the curated list (#764).
|
|
1171
|
+
*
|
|
1172
|
+
* `has_stalled_pr` (scout 0.9.0 #97) distinguishes open-but-stalled linked
|
|
1173
|
+
* PRs from cleanly-claimed `has_pr` issues — the issue is still actionable
|
|
1174
|
+
* as a revive opportunity rather than something to drop.
|
|
1175
|
+
*/
|
|
1176
|
+
export type VetListItemStatus = 'still_available' | 'claimed' | 'closed' | 'has_pr' | 'has_stalled_pr' | 'error';
|
|
996
1177
|
/** Output of the vet-list command (#764). */
|
|
997
1178
|
export interface VetListOutput {
|
|
998
1179
|
results: Array<VetOutput & {
|
|
@@ -1005,6 +1186,8 @@ export interface VetListOutput {
|
|
|
1005
1186
|
claimed: number;
|
|
1006
1187
|
closed: number;
|
|
1007
1188
|
hasPR: number;
|
|
1189
|
+
/** Open linked PRs that haven't been touched in 30+ days (scout 0.9.0 #97). Surfaced as revive opportunities, not auto-dropped. */
|
|
1190
|
+
hasStalledPR: number;
|
|
1008
1191
|
errors: number;
|
|
1009
1192
|
};
|
|
1010
1193
|
pruneResult?: {
|
|
@@ -1042,6 +1225,12 @@ export interface VetOutput {
|
|
|
1042
1225
|
* already has work in flight vs. a competing contributor.
|
|
1043
1226
|
*/
|
|
1044
1227
|
linkedPRClassification?: 'none' | 'user_open' | 'user_closed' | 'user_merged' | 'other_open' | 'other_closed' | 'other_merged';
|
|
1228
|
+
/**
|
|
1229
|
+
* Compact linked-PR summary (#97 / scout 0.9.0). Present when the issue
|
|
1230
|
+
* has a linked PR; absent otherwise. `isStalled` flags open PRs that
|
|
1231
|
+
* haven't been touched in 30+ days as revive opportunities.
|
|
1232
|
+
*/
|
|
1233
|
+
linkedPR?: CandidateLinkedPR;
|
|
1045
1234
|
/**
|
|
1046
1235
|
* Optional SLM pre-triage classification (#1122). Populated when the
|
|
1047
1236
|
* user has set `slmTriageModel` and a local Ollama instance answered
|
package/dist/formatters/json.js
CHANGED
|
@@ -284,6 +284,17 @@ export const CompactDailyOutputSchema = z.object({
|
|
|
284
284
|
});
|
|
285
285
|
// ── Search output schema (#1147) ─────────────────────────────────────
|
|
286
286
|
const SearchPrioritySchema = z.enum(['merged_pr', 'preferred_org', 'starred', 'normal']);
|
|
287
|
+
/**
|
|
288
|
+
* Schema for the compact linked-PR annotation surfaced on candidate
|
|
289
|
+
* outputs (#97 / scout 0.9.0). Mirrors {@link CandidateLinkedPR}.
|
|
290
|
+
*/
|
|
291
|
+
const CandidateLinkedPRSchema = z.object({
|
|
292
|
+
number: z.number().int().positive(),
|
|
293
|
+
state: z.enum(['open', 'closed', 'merged']),
|
|
294
|
+
url: z.string(),
|
|
295
|
+
updatedAt: z.string().optional(),
|
|
296
|
+
isStalled: z.boolean(),
|
|
297
|
+
});
|
|
287
298
|
const SearchCandidateSchema = z.object({
|
|
288
299
|
issue: z.object({
|
|
289
300
|
repo: z.string(),
|
|
@@ -311,6 +322,7 @@ const SearchCandidateSchema = z.object({
|
|
|
311
322
|
lastMergedAt: z.string().optional(),
|
|
312
323
|
})
|
|
313
324
|
.optional(),
|
|
325
|
+
linkedPR: CandidateLinkedPRSchema.optional(),
|
|
314
326
|
});
|
|
315
327
|
export const SearchOutputSchema = z.object({
|
|
316
328
|
candidates: z.array(SearchCandidateSchema),
|
|
@@ -318,6 +330,22 @@ export const SearchOutputSchema = z.object({
|
|
|
318
330
|
aiPolicyBlocklist: z.array(z.string()),
|
|
319
331
|
rateLimitWarning: z.string().optional(),
|
|
320
332
|
});
|
|
333
|
+
// ── Features output schema (scout 0.9.0 #97/#98/#99) ─────────────────
|
|
334
|
+
//
|
|
335
|
+
// `SearchCandidateSchema` augmented with the horizon literal that scout
|
|
336
|
+
// stamps in features mode. Reusing the search candidate keeps the two
|
|
337
|
+
// envelopes structurally identical apart from the bucket annotation.
|
|
338
|
+
const FeaturesHorizonSchema = z.enum(['quick-win', 'bigger-bet']);
|
|
339
|
+
const FeaturesCandidateSchema = SearchCandidateSchema.extend({
|
|
340
|
+
horizon: FeaturesHorizonSchema,
|
|
341
|
+
});
|
|
342
|
+
export const FeaturesOutputSchema = z.object({
|
|
343
|
+
quickWins: z.array(FeaturesCandidateSchema),
|
|
344
|
+
biggerBets: z.array(FeaturesCandidateSchema),
|
|
345
|
+
anchorRepos: z.array(z.string()),
|
|
346
|
+
message: z.string().nullable(),
|
|
347
|
+
rateLimitWarning: z.string().optional(),
|
|
348
|
+
});
|
|
321
349
|
// ── Doctor / skip-add / list-move-tier output schemas (#1148) ────────
|
|
322
350
|
const DoctorCheckSchema = z.object({
|
|
323
351
|
name: z.string(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oss-autopilot/core",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0",
|
|
4
4
|
"description": "CLI and core library for managing open source contributions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@octokit/plugin-throttling": "^11.0.3",
|
|
56
56
|
"@octokit/rest": "^22.0.1",
|
|
57
|
-
"@oss-scout/core": "^0.
|
|
57
|
+
"@oss-scout/core": "^0.9.0",
|
|
58
58
|
"commander": "^14.0.3",
|
|
59
59
|
"zod": "^4.4.3"
|
|
60
60
|
},
|