@jojonax/codex-copilot 1.3.0 → 1.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jojonax/codex-copilot",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "PRD-driven automated development orchestrator for CodeX / Cursor",
5
5
  "bin": {
6
6
  "codex-copilot": "./bin/cli.js"
@@ -317,21 +317,27 @@ async function reviewLoop(projectDir, task, prInfo, { maxRounds: _maxRounds, pol
317
317
 
318
318
  log.info('Checking for review feedback...');
319
319
 
320
- // Always proactively check for existing reviews first.
321
320
  let gotReview = false;
322
- const existingReviews = github.getReviews(projectDir, prInfo.number);
323
- const existingComments = github.getIssueComments(projectDir, prInfo.number);
324
- const hasReview = existingReviews.some(r => r.state !== 'PENDING');
325
- const hasBotComment = existingComments.some(c =>
326
- c.user?.type === 'Bot' || c.user?.login?.includes('bot')
327
- );
328
321
 
329
- if (hasReview || hasBotComment) {
330
- log.info('Review found processing immediately');
331
- gotReview = true;
332
- } else {
333
- // No reviews yet — enter polling mode
334
- log.info(`No review yet, polling... (timeout: ${waitTimeout}s)`);
322
+ // Round 1 (or resume): proactively check for existing reviews.
323
+ // After a fix push (round > 1): ONLY wait for NEW reviews
324
+ // to avoid re-processing the same stale feedback in a loop.
325
+ if (round <= 1 || round === startRound) {
326
+ const existingReviews = github.getReviews(projectDir, prInfo.number);
327
+ const existingComments = github.getIssueComments(projectDir, prInfo.number);
328
+ const hasReview = existingReviews.some(r => r.state !== 'PENDING');
329
+ const hasBotComment = existingComments.some(c =>
330
+ c.user?.type === 'Bot' || c.user?.login?.includes('bot')
331
+ );
332
+
333
+ if (hasReview || hasBotComment) {
334
+ log.info('Review found — processing immediately');
335
+ gotReview = true;
336
+ }
337
+ }
338
+
339
+ if (!gotReview) {
340
+ log.info(`Waiting for ${round > 1 ? 'new ' : ''}review... (timeout: ${waitTimeout}s)`);
335
341
  gotReview = await waitForReview(projectDir, prInfo.number, pollInterval, waitTimeout);
336
342
  }
337
343
 
@@ -429,10 +435,16 @@ async function reviewLoop(projectDir, task, prInfo, { maxRounds: _maxRounds, pol
429
435
 
430
436
  // Push fix — only if there are actual changes
431
437
  if (!git.isClean(projectDir)) {
432
- git.commitAll(projectDir, `fix(task-${task.id}): address review comments (round ${round})`);
438
+ const skipCI = github.isPrivateRepo(projectDir) ? ' [skip ci]' : '';
439
+ git.commitAll(projectDir, `fix(task-${task.id}): address review comments (round ${round})${skipCI}`);
433
440
  git.pushBranch(projectDir, task.branch);
434
- log.info('Fix pushed, waiting for next review round...');
435
- // Brief wait for review bot to react
441
+ log.info('Fix pushed');
442
+
443
+ // Request bot to re-review the updated code
444
+ log.info('Requesting re-review...');
445
+ github.requestReReview(projectDir, prInfo.number);
446
+
447
+ // Wait for review bot to react
436
448
  await sleep(15000);
437
449
  } else {
438
450
  // AI fix produced no code changes — it cannot resolve this issue
@@ -292,9 +292,36 @@ export function collectReviewFeedback(cwd, prNumber) {
292
292
  return feedback.trim();
293
293
  }
294
294
 
295
+ /**
296
+ * Check if the current repo is private
297
+ * @returns {boolean} true if private, false if public or unknown
298
+ */
299
+ export function isPrivateRepo(cwd) {
300
+ try {
301
+ const result = ghJSON('repo view --json isPrivate', cwd);
302
+ return result?.isPrivate === true;
303
+ } catch {
304
+ return false; // Default to public behavior if detection fails
305
+ }
306
+ }
307
+
308
+ /**
309
+ * Request bots to re-review the PR by posting a /review comment.
310
+ * Triggers Gemini Code Assist and similar bots to run a fresh review.
311
+ */
312
+ export function requestReReview(cwd, prNumber) {
313
+ try {
314
+ gh(`pr comment ${prNumber} --body "/review"`, cwd);
315
+ return true;
316
+ } catch {
317
+ return false;
318
+ }
319
+ }
320
+
295
321
  export const github = {
296
322
  checkGhAuth, createPR, createPRWithRecovery, findExistingPR,
297
323
  ensureRemoteBranch, hasCommitsBetween,
298
324
  getReviews, getReviewComments, getIssueComments,
299
325
  getLatestReviewState, mergePR, collectReviewFeedback,
326
+ isPrivateRepo, requestReReview,
300
327
  };