@oss-autopilot/core 1.6.0 → 1.6.2
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/commands/startup.js
CHANGED
|
@@ -139,6 +139,31 @@ export function openInBrowser(url) {
|
|
|
139
139
|
}
|
|
140
140
|
});
|
|
141
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Trigger a data refresh on a running dashboard server.
|
|
144
|
+
* Hits POST /api/refresh so the SPA picks up fresh data on its next poll.
|
|
145
|
+
* Non-fatal: errors are logged but don't propagate (#830).
|
|
146
|
+
*/
|
|
147
|
+
async function triggerDashboardRefresh(port) {
|
|
148
|
+
try {
|
|
149
|
+
const res = await fetch(`http://127.0.0.1:${port}/api/refresh`, {
|
|
150
|
+
method: 'POST',
|
|
151
|
+
headers: { Origin: `http://oss.localhost:${port}` },
|
|
152
|
+
signal: AbortSignal.timeout(5000),
|
|
153
|
+
});
|
|
154
|
+
if (!res.ok) {
|
|
155
|
+
const body = await res.text().catch(() => '');
|
|
156
|
+
console.error(`[STARTUP] Dashboard refresh returned ${res.status}: ${body}`);
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
await res.text().catch(() => { });
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
console.error(`[STARTUP] Could not trigger dashboard refresh: ${errorMessage(error)}`);
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
142
167
|
/**
|
|
143
168
|
* Run startup checks and return structured output.
|
|
144
169
|
* Returns StartupOutput with one of three shapes:
|
|
@@ -184,14 +209,20 @@ export async function runStartup() {
|
|
|
184
209
|
// 4. Launch interactive SPA dashboard
|
|
185
210
|
// Skip opening on first run (0 PRs) — the welcome flow handles onboarding
|
|
186
211
|
let dashboardUrl;
|
|
187
|
-
let
|
|
212
|
+
let dashboardStatus;
|
|
188
213
|
if (daily.digest.summary.totalActivePRs > 0) {
|
|
189
214
|
try {
|
|
190
215
|
const spaResult = await launchDashboardServer();
|
|
191
216
|
if (spaResult) {
|
|
192
217
|
dashboardUrl = spaResult.url;
|
|
193
|
-
|
|
194
|
-
|
|
218
|
+
if (spaResult.alreadyRunning) {
|
|
219
|
+
const refreshed = await triggerDashboardRefresh(spaResult.port);
|
|
220
|
+
dashboardStatus = refreshed ? 'refreshed' : 'running';
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
openInBrowser(spaResult.url);
|
|
224
|
+
dashboardStatus = 'opened';
|
|
225
|
+
}
|
|
195
226
|
}
|
|
196
227
|
else {
|
|
197
228
|
console.error('[STARTUP] Dashboard SPA assets not found. Build with: cd packages/dashboard && pnpm run build');
|
|
@@ -201,10 +232,16 @@ export async function runStartup() {
|
|
|
201
232
|
console.error('[STARTUP] SPA dashboard launch failed:', errorMessage(error));
|
|
202
233
|
}
|
|
203
234
|
}
|
|
204
|
-
// Append dashboard status to brief summary
|
|
205
|
-
if (
|
|
235
|
+
// Append dashboard status to brief summary
|
|
236
|
+
if (dashboardStatus === 'opened') {
|
|
206
237
|
daily.briefSummary += ' | Dashboard opened in browser';
|
|
207
238
|
}
|
|
239
|
+
else if (dashboardStatus === 'refreshed') {
|
|
240
|
+
daily.briefSummary += ' | Dashboard refreshed';
|
|
241
|
+
}
|
|
242
|
+
else if (dashboardStatus === 'running') {
|
|
243
|
+
daily.briefSummary += ' | Dashboard running';
|
|
244
|
+
}
|
|
208
245
|
// 5. Detect issue list
|
|
209
246
|
const issueList = detectIssueList();
|
|
210
247
|
return {
|
|
@@ -47,6 +47,12 @@ export declare function isAllSelfReplies(reviewId: number, reviewComments: Revie
|
|
|
47
47
|
* synthetic placeholders (#199).
|
|
48
48
|
*/
|
|
49
49
|
export declare function getInlineCommentBody(reviewId: number, reviewComments: ReviewComment[]): string | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Check whether a review has any associated inline comments.
|
|
52
|
+
* Used to prevent the acknowledgment filter from discarding reviews
|
|
53
|
+
* that also posted inline comments (#829).
|
|
54
|
+
*/
|
|
55
|
+
export declare function reviewHasInlineComments(reviewId: number, reviewComments: ReviewComment[]): boolean;
|
|
50
56
|
/**
|
|
51
57
|
* Check if there are unresponded comments from maintainers.
|
|
52
58
|
* Combines issue comments and review comments into a timeline,
|
|
@@ -89,6 +89,14 @@ export function isAllSelfReplies(reviewId, reviewComments) {
|
|
|
89
89
|
export function getInlineCommentBody(reviewId, reviewComments) {
|
|
90
90
|
return reviewComments.find((c) => c.pull_request_review_id === reviewId && c.body?.trim())?.body?.trim();
|
|
91
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Check whether a review has any associated inline comments.
|
|
94
|
+
* Used to prevent the acknowledgment filter from discarding reviews
|
|
95
|
+
* that also posted inline comments (#829).
|
|
96
|
+
*/
|
|
97
|
+
export function reviewHasInlineComments(reviewId, reviewComments) {
|
|
98
|
+
return reviewComments.some((c) => c.pull_request_review_id === reviewId);
|
|
99
|
+
}
|
|
92
100
|
/**
|
|
93
101
|
* Check if there are unresponded comments from maintainers.
|
|
94
102
|
* Combines issue comments and review comments into a timeline,
|
|
@@ -136,6 +144,7 @@ export function checkUnrespondedComments(comments, reviews, reviewComments, user
|
|
|
136
144
|
body: resolvedBody,
|
|
137
145
|
createdAt: review.submitted_at,
|
|
138
146
|
isUser: author.toLowerCase() === usernameLower,
|
|
147
|
+
reviewId: review.id,
|
|
139
148
|
});
|
|
140
149
|
}
|
|
141
150
|
// Sort by date
|
|
@@ -149,6 +158,7 @@ export function checkUnrespondedComments(comments, reviews, reviewComments, user
|
|
|
149
158
|
}
|
|
150
159
|
// Find maintainer comments after the user's last comment
|
|
151
160
|
let lastMaintainerComment;
|
|
161
|
+
let lastMaintainerReviewId;
|
|
152
162
|
for (const item of timeline) {
|
|
153
163
|
if (item.isUser)
|
|
154
164
|
continue; // Skip user's own comments
|
|
@@ -163,10 +173,14 @@ export function checkUnrespondedComments(comments, reviews, reviewComments, user
|
|
|
163
173
|
body: item.body.slice(0, 200) + (item.body.length > 200 ? '...' : ''),
|
|
164
174
|
createdAt: item.createdAt,
|
|
165
175
|
};
|
|
176
|
+
lastMaintainerReviewId = item.reviewId;
|
|
166
177
|
}
|
|
167
178
|
}
|
|
168
|
-
// Filter out pure acknowledgment comments that don't require a response
|
|
169
|
-
|
|
179
|
+
// Filter out pure acknowledgment comments that don't require a response.
|
|
180
|
+
// Skip the filter when the review has inline comments — those indicate
|
|
181
|
+
// feedback beyond the summary body that likely needs a response (#829).
|
|
182
|
+
const lastReviewHasInlineComments = lastMaintainerReviewId != null && reviewHasInlineComments(lastMaintainerReviewId, reviewComments);
|
|
183
|
+
if (lastMaintainerComment && isAcknowledgmentComment(lastMaintainerComment.body) && !lastReviewHasInlineComments) {
|
|
170
184
|
lastMaintainerComment = undefined;
|
|
171
185
|
}
|
|
172
186
|
return {
|