dev-loops 0.2.6 → 0.3.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/.claude/.claude-plugin/plugin.json +1 -1
- package/.claude/agents/dev-loop.md +2 -1
- package/.claude/agents/developer.md +1 -0
- package/.claude/agents/fixer.md +1 -0
- package/.claude/agents/review.md +30 -0
- package/.claude/skills/copilot-pr-followup/SKILL.md +57 -3
- package/.claude/skills/dev-loop/SKILL.md +5 -5
- package/.claude/skills/docs/anti-patterns.md +2 -0
- package/.claude/skills/docs/copilot-loop-operations.md +2 -2
- package/.claude/skills/local-implementation/SKILL.md +17 -3
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +60 -0
- package/agents/dev-loop.agent.md +5 -1
- package/agents/developer.agent.md +1 -0
- package/agents/fixer.agent.md +1 -0
- package/agents/review.agent.md +30 -0
- package/cli/index.mjs +42 -7
- package/package.json +2 -2
- package/scripts/README.md +6 -5
- package/scripts/_cli-primitives.mjs +2 -0
- package/scripts/_core-helpers.mjs +1 -0
- package/scripts/claude/generate-claude-assets.mjs +12 -2
- package/scripts/claude/headless-dev-loop.mjs +53 -13
- package/scripts/claude/headless-info-smoke.mjs +45 -11
- package/scripts/docs/validate-links.mjs +20 -11
- package/scripts/github/build-adjacent-bundle.mjs +448 -0
- package/scripts/github/capture-review-threads.mjs +32 -14
- package/scripts/github/{create-draft-pr.mjs → create-pr.mjs} +28 -12
- package/scripts/github/detect-checkpoint-evidence.mjs +123 -15
- package/scripts/github/detect-linked-issue-pr.mjs +22 -10
- package/scripts/github/manage-sub-issues.mjs +37 -16
- package/scripts/github/post-gate-findings.mjs +392 -0
- package/scripts/github/probe-copilot-review.mjs +24 -12
- package/scripts/github/ready-for-review.mjs +17 -8
- package/scripts/github/reconcile-draft-gate.mjs +24 -12
- package/scripts/github/reply-resolve-review-threads.mjs +34 -15
- package/scripts/github/request-copilot-review.mjs +97 -19
- package/scripts/github/resolve-tracker-local-spec.mjs +29 -12
- package/scripts/github/stage-reviewer-draft.mjs +32 -14
- package/scripts/github/upsert-checkpoint-verdict.mjs +646 -41
- package/scripts/github/verify-fresh-review-context.mjs +12 -1
- package/scripts/github/write-gate-context.mjs +634 -0
- package/scripts/github/write-gate-findings-log.mjs +42 -21
- package/scripts/loop/build-handoff-envelope.mjs +32 -14
- package/scripts/loop/conductor-monitor.mjs +25 -9
- package/scripts/loop/conductor.mjs +31 -12
- package/scripts/loop/copilot-pr-handoff.mjs +31 -14
- package/scripts/loop/debt-remediate.mjs +28 -11
- package/scripts/loop/detect-change-scope.mjs +36 -11
- package/scripts/loop/detect-copilot-loop-state.mjs +29 -12
- package/scripts/loop/detect-copilot-session-activity.mjs +29 -12
- package/scripts/loop/detect-initial-copilot-pr-state.mjs +26 -10
- package/scripts/loop/detect-internal-only-pr.mjs +31 -13
- package/scripts/loop/detect-issue-refinement-artifact.mjs +29 -12
- package/scripts/loop/detect-pr-gate-coordination-state.mjs +56 -28
- package/scripts/loop/detect-reviewer-loop-state.mjs +35 -16
- package/scripts/loop/detect-stale-runner.mjs +32 -14
- package/scripts/loop/detect-tracker-first-loop-state.mjs +38 -11
- package/scripts/loop/detect-tracker-pr-state.mjs +23 -8
- package/scripts/loop/info.mjs +28 -10
- package/scripts/loop/inspect-run-viewer/cli.mjs +44 -21
- package/scripts/loop/inspect-run.mjs +35 -16
- package/scripts/loop/outer-loop.mjs +35 -16
- package/scripts/loop/pr-runner-coordination.mjs +31 -12
- package/scripts/loop/pre-commit-branch-guard.mjs +26 -9
- package/scripts/loop/pre-flight-gate.mjs +25 -9
- package/scripts/loop/pre-pr-ready-gate.mjs +24 -8
- package/scripts/loop/pre-push-main-guard.mjs +19 -5
- package/scripts/loop/pre-write-remote-freshness-guard.mjs +23 -7
- package/scripts/loop/resolve-dev-loop-startup.mjs +29 -12
- package/scripts/loop/run-conductor-cycle.mjs +23 -8
- package/scripts/loop/run-queue.mjs +87 -15
- package/scripts/loop/run-refinement-audit.mjs +44 -22
- package/scripts/loop/run-watch-cycle.mjs +28 -12
- package/scripts/loop/steer-loop.mjs +122 -62
- package/scripts/loop/watch-initial-copilot-pr.mjs +28 -12
- package/scripts/projects/add-queue-item.mjs +60 -43
- package/scripts/projects/archive-done-items.mjs +506 -0
- package/scripts/projects/ensure-queue-board.mjs +65 -64
- package/scripts/projects/list-queue-items.mjs +57 -56
- package/scripts/projects/move-queue-item.mjs +123 -124
- package/scripts/projects/reorder-queue-item.mjs +384 -108
- package/scripts/projects/sync-item-status.mjs +198 -0
- package/scripts/refine/_refine-helpers.mjs +21 -9
- package/scripts/refine/verify.mjs +31 -13
- package/skills/copilot-pr-followup/SKILL.md +57 -3
- package/skills/dev-loop/SKILL.md +9 -5
- package/skills/dev-loop/scripts/log-bash-exit-1.mjs +2 -2
- package/skills/dev-loop/scripts/phase-files.mjs +2 -2
- package/skills/docs/anti-patterns.md +2 -0
- package/skills/docs/copilot-loop-operations.md +2 -2
- package/skills/local-implementation/SKILL.md +17 -3
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { parseArgs } from "node:util";
|
|
2
3
|
import {
|
|
3
4
|
buildParseError,
|
|
4
5
|
formatCliError,
|
|
5
6
|
isCopilotLogin,
|
|
6
7
|
isDirectCliRun,
|
|
7
8
|
parseReviewThreads,
|
|
9
|
+
resolveDraftGateRoundResetMs,
|
|
8
10
|
summarizeCopilotReviews,
|
|
11
|
+
summarizeGateReviewComments,
|
|
9
12
|
} from "../_core-helpers.mjs";
|
|
10
|
-
import { parsePrNumber,
|
|
13
|
+
import { parsePrNumber, requireTokenValue, runChild } from "../_cli-primitives.mjs";
|
|
11
14
|
import { fetchGithubReviewThreadsPayload } from "./capture-review-threads.mjs";
|
|
12
15
|
import { parseRepoSlug } from "@dev-loops/core/github/repo-slug";
|
|
13
16
|
import { buildSnapshotFromPrFacts, interpretLoopState } from "@dev-loops/core/loop/copilot-loop-state";
|
|
@@ -52,32 +55,48 @@ Exit codes:
|
|
|
52
55
|
1 Argument error or gh failure`.trim();
|
|
53
56
|
const parseError = buildParseError(USAGE);
|
|
54
57
|
export function parseRequestCliArgs(argv) {
|
|
55
|
-
const
|
|
58
|
+
const { tokens } = parseArgs({
|
|
59
|
+
args: [...argv],
|
|
60
|
+
options: {
|
|
61
|
+
help: { type: "boolean", short: "h" },
|
|
62
|
+
"force-rerequest-review": { type: "boolean" },
|
|
63
|
+
repo: { type: "string" },
|
|
64
|
+
pr: { type: "string" },
|
|
65
|
+
},
|
|
66
|
+
allowPositionals: true,
|
|
67
|
+
strict: false,
|
|
68
|
+
tokens: true,
|
|
69
|
+
});
|
|
56
70
|
const options = {
|
|
57
71
|
help: false,
|
|
58
72
|
repo: undefined,
|
|
59
73
|
pr: undefined,
|
|
60
74
|
forceRerequestReview: false,
|
|
61
75
|
};
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
76
|
+
for (const token of tokens) {
|
|
77
|
+
if (token.kind === "positional") {
|
|
78
|
+
throw parseError(`Unknown argument: ${token.value}`);
|
|
79
|
+
}
|
|
80
|
+
if (token.kind !== "option") {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (token.name === "help") {
|
|
65
84
|
options.help = true;
|
|
66
85
|
return options;
|
|
67
86
|
}
|
|
68
|
-
if (token === "
|
|
87
|
+
if (token.name === "force-rerequest-review") {
|
|
69
88
|
options.forceRerequestReview = true;
|
|
70
89
|
continue;
|
|
71
90
|
}
|
|
72
|
-
if (token === "
|
|
73
|
-
options.repo =
|
|
91
|
+
if (token.name === "repo") {
|
|
92
|
+
options.repo = requireTokenValue(token, parseError).trim();
|
|
74
93
|
continue;
|
|
75
94
|
}
|
|
76
|
-
if (token === "
|
|
77
|
-
options.pr = parsePrNumber(
|
|
95
|
+
if (token.name === "pr") {
|
|
96
|
+
options.pr = parsePrNumber(requireTokenValue(token, parseError), parseError);
|
|
78
97
|
continue;
|
|
79
98
|
}
|
|
80
|
-
throw parseError(`Unknown argument: ${token}`);
|
|
99
|
+
throw parseError(`Unknown argument: ${token.rawName}`);
|
|
81
100
|
}
|
|
82
101
|
if (options.repo === undefined || options.pr === undefined) {
|
|
83
102
|
throw parseError("Requesting Copilot review requires both --repo <owner/name> and --pr <number>");
|
|
@@ -104,7 +123,7 @@ function parseRequestedReviewersPayload(text) {
|
|
|
104
123
|
requested: users.some((user) => isCopilotLogin(user?.login)),
|
|
105
124
|
};
|
|
106
125
|
}
|
|
107
|
-
function parseReviewsPayload(text) {
|
|
126
|
+
function parseReviewsPayload(text, { draftGateResetAtMs = null } = {}) {
|
|
108
127
|
let payload;
|
|
109
128
|
try {
|
|
110
129
|
payload = JSON.parse(text);
|
|
@@ -114,7 +133,10 @@ function parseReviewsPayload(text) {
|
|
|
114
133
|
const headSha = typeof payload?.headRefOid === "string" && payload.headRefOid.trim().length > 0
|
|
115
134
|
? payload.headRefOid.trim()
|
|
116
135
|
: null;
|
|
117
|
-
|
|
136
|
+
// Apply the draft-gate round reset so the completed round count matches what
|
|
137
|
+
// detect-pr-gate-coordination-state computes (#896): when the draft gate has
|
|
138
|
+
// re-passed clean on an earlier head, only reviews after that re-pass count.
|
|
139
|
+
const reviewSummary = summarizeCopilotReviews(payload?.reviews, { headSha, draftGateResetAtMs });
|
|
118
140
|
return {
|
|
119
141
|
prData: payload,
|
|
120
142
|
headSha,
|
|
@@ -149,6 +171,51 @@ async function fetchCopilotReviewIds({ repo, pr }, { env = process.env, ghComman
|
|
|
149
171
|
}
|
|
150
172
|
return parseReviewsPayload(result.stdout);
|
|
151
173
|
}
|
|
174
|
+
|
|
175
|
+
// Re-derive the completed Copilot round count with the draft-gate round reset
|
|
176
|
+
// applied, mirroring detect-pr-gate-coordination-state so both scripts agree on the
|
|
177
|
+
// completed count and therefore on round-cap-reached (#896). A clean draft_gate
|
|
178
|
+
// re-pass on an earlier head resets the count, so post-reset reviews must not be
|
|
179
|
+
// counted toward the cap.
|
|
180
|
+
//
|
|
181
|
+
// Queried lazily — only when the raw (un-reset) count has already hit the cap — so
|
|
182
|
+
// the common (under-cap) request path keeps its existing gh-call contract and adds
|
|
183
|
+
// no API round-trip. Uses a single issue-comments fetch (the same source the gate
|
|
184
|
+
// detector uses for the latest clean draft_gate marker), not the full checkpoint-
|
|
185
|
+
// evidence pipeline, to keep the added surface minimal. Best-effort: a fetch failure
|
|
186
|
+
// falls back to the raw count, so the cap is never silently disabled.
|
|
187
|
+
async function resolveDraftGateAdjustedRounds(options, { env = process.env, ghCommand = "gh" } = {}, before) {
|
|
188
|
+
try {
|
|
189
|
+
const currentHeadSha = typeof before?.prData?.headRefOid === "string" && before.prData.headRefOid.trim().length > 0
|
|
190
|
+
? before.prData.headRefOid.trim()
|
|
191
|
+
: null;
|
|
192
|
+
const result = await runChild(
|
|
193
|
+
ghCommand,
|
|
194
|
+
["api", "--paginate", "--slurp", `repos/${options.repo}/issues/${options.pr}/comments?per_page=100`],
|
|
195
|
+
env,
|
|
196
|
+
);
|
|
197
|
+
if (result.code !== 0) {
|
|
198
|
+
return before.completedCopilotReviewRounds ?? 0;
|
|
199
|
+
}
|
|
200
|
+
let comments;
|
|
201
|
+
try {
|
|
202
|
+
const payload = JSON.parse(result.stdout);
|
|
203
|
+
comments = Array.isArray(payload) ? payload.flat() : [];
|
|
204
|
+
} catch {
|
|
205
|
+
return before.completedCopilotReviewRounds ?? 0;
|
|
206
|
+
}
|
|
207
|
+
const gateSummary = summarizeGateReviewComments(comments);
|
|
208
|
+
const draftGateResetAtMs = resolveDraftGateRoundResetMs({ draftGate: gateSummary?.draft_gate, currentHeadSha });
|
|
209
|
+
if (draftGateResetAtMs == null) {
|
|
210
|
+
return before.completedCopilotReviewRounds ?? 0;
|
|
211
|
+
}
|
|
212
|
+
const adjusted = parseReviewsPayload(JSON.stringify(before.prData ?? {}), { draftGateResetAtMs });
|
|
213
|
+
return adjusted.completedCopilotReviewRounds ?? 0;
|
|
214
|
+
} catch {
|
|
215
|
+
return before.completedCopilotReviewRounds ?? 0;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
152
219
|
async function fetchCopilotReviewState(options, runtime) {
|
|
153
220
|
const requestedReviewers = await fetchRequestedReviewers(options, runtime);
|
|
154
221
|
const reviews = await fetchCopilotReviewIds(options, runtime);
|
|
@@ -417,7 +484,18 @@ export async function performCopilotReviewRequest(options, { env = process.env,
|
|
|
417
484
|
}
|
|
418
485
|
} catch {
|
|
419
486
|
}
|
|
420
|
-
|
|
487
|
+
// Reconcile the completed-round count with detect-pr-gate-coordination-state (#896):
|
|
488
|
+
// when the raw count has reached the cap, re-derive it with the draft-gate round
|
|
489
|
+
// reset applied. A clean draft_gate re-pass on an earlier head resets the count, so
|
|
490
|
+
// a post-reset PR that detect reports as under-cap must NOT be refused here as
|
|
491
|
+
// cap-reached. Only query checkpoint evidence on this (at/over-cap) path.
|
|
492
|
+
let completedRounds = before.completedCopilotReviewRounds ?? 0;
|
|
493
|
+
if (completedRounds >= maxRounds
|
|
494
|
+
&& !before.requested
|
|
495
|
+
&& !before.hasPendingReviewOnCurrentHead) {
|
|
496
|
+
completedRounds = await resolveDraftGateAdjustedRounds(options, { env, ghCommand }, before);
|
|
497
|
+
}
|
|
498
|
+
if (completedRounds >= maxRounds
|
|
421
499
|
&& !before.requested
|
|
422
500
|
&& !before.hasPendingReviewOnCurrentHead) {
|
|
423
501
|
if (!options.forceRerequestReview) {
|
|
@@ -434,9 +512,9 @@ export async function performCopilotReviewRequest(options, { env = process.env,
|
|
|
434
512
|
repo: options.repo,
|
|
435
513
|
pr: options.pr,
|
|
436
514
|
reviewer: "Copilot",
|
|
437
|
-
completedRounds
|
|
515
|
+
completedRounds,
|
|
438
516
|
maxRounds,
|
|
439
|
-
detail: `Round cap of ${maxRounds} reached with ${
|
|
517
|
+
detail: `Round cap of ${maxRounds} reached with ${completedRounds} completed rounds. No further re-requests will be made.`,
|
|
440
518
|
};
|
|
441
519
|
}
|
|
442
520
|
}
|
|
@@ -454,8 +532,8 @@ export async function performCopilotReviewRequest(options, { env = process.env,
|
|
|
454
532
|
repo: options.repo,
|
|
455
533
|
pr: options.pr,
|
|
456
534
|
reviewer: "Copilot",
|
|
457
|
-
detail: `Round cap of ${maxRounds} reached with ${
|
|
458
|
-
completedRounds
|
|
535
|
+
detail: `Round cap of ${maxRounds} reached with ${completedRounds} completed rounds. --force-rerequest-review was supplied but commit SHA data is unavailable, so change-since-last-review could not be evaluated.`,
|
|
536
|
+
completedRounds,
|
|
459
537
|
maxRounds,
|
|
460
538
|
};
|
|
461
539
|
}
|
|
@@ -467,7 +545,7 @@ export async function performCopilotReviewRequest(options, { env = process.env,
|
|
|
467
545
|
pr: options.pr,
|
|
468
546
|
reviewer: "Copilot",
|
|
469
547
|
detail: "No changes since last Copilot review. --force-rerequest-review requires new commits on the PR head.",
|
|
470
|
-
completedRounds
|
|
548
|
+
completedRounds,
|
|
471
549
|
maxRounds,
|
|
472
550
|
};
|
|
473
551
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { parseArgs } from "node:util";
|
|
2
3
|
import { buildParseError, formatCliError, isDirectCliRun, parseJsonText } from "../_core-helpers.mjs";
|
|
3
|
-
import { parseIssueNumber,
|
|
4
|
+
import { parseIssueNumber, requireTokenValue, runChild } from "../_cli-primitives.mjs";
|
|
4
5
|
import { parseRepoSlug } from "@dev-loops/core/github/repo-slug";
|
|
5
6
|
const ISSUE_JSON_FIELDS = "number,title,body,url,state";
|
|
6
7
|
const USAGE = `Usage: resolve-tracker-local-spec.mjs (--repo <owner/name> --issue <number> | --issue-url <github-issue-url>)
|
|
@@ -60,32 +61,48 @@ export function parseGitHubIssueUrl(value) {
|
|
|
60
61
|
};
|
|
61
62
|
}
|
|
62
63
|
export function parseResolveTrackerLocalSpecCliArgs(argv) {
|
|
63
|
-
const
|
|
64
|
+
const { tokens } = parseArgs({
|
|
65
|
+
args: [...argv],
|
|
66
|
+
options: {
|
|
67
|
+
help: { type: "boolean", short: "h" },
|
|
68
|
+
repo: { type: "string" },
|
|
69
|
+
issue: { type: "string" },
|
|
70
|
+
"issue-url": { type: "string" },
|
|
71
|
+
},
|
|
72
|
+
allowPositionals: true,
|
|
73
|
+
strict: false,
|
|
74
|
+
tokens: true,
|
|
75
|
+
});
|
|
64
76
|
const options = {
|
|
65
77
|
help: false,
|
|
66
78
|
repo: undefined,
|
|
67
79
|
issue: undefined,
|
|
68
80
|
issueUrl: undefined,
|
|
69
81
|
};
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
82
|
+
for (const token of tokens) {
|
|
83
|
+
if (token.kind === "positional") {
|
|
84
|
+
throw parseError(`Unknown argument: ${token.value}`);
|
|
85
|
+
}
|
|
86
|
+
if (token.kind !== "option") {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (token.name === "help") {
|
|
73
90
|
options.help = true;
|
|
74
91
|
return options;
|
|
75
92
|
}
|
|
76
|
-
if (token === "
|
|
77
|
-
options.repo =
|
|
93
|
+
if (token.name === "repo") {
|
|
94
|
+
options.repo = requireTokenValue(token, parseError).trim();
|
|
78
95
|
continue;
|
|
79
96
|
}
|
|
80
|
-
if (token === "
|
|
81
|
-
options.issue = parseIssueNumber(
|
|
97
|
+
if (token.name === "issue") {
|
|
98
|
+
options.issue = parseIssueNumber(requireTokenValue(token, parseError), parseError);
|
|
82
99
|
continue;
|
|
83
100
|
}
|
|
84
|
-
if (token === "
|
|
85
|
-
options.issueUrl =
|
|
101
|
+
if (token.name === "issue-url") {
|
|
102
|
+
options.issueUrl = requireTokenValue(token, parseError).trim();
|
|
86
103
|
continue;
|
|
87
104
|
}
|
|
88
|
-
throw parseError(`Unknown argument: ${token}`);
|
|
105
|
+
throw parseError(`Unknown argument: ${token.rawName}`);
|
|
89
106
|
}
|
|
90
107
|
const usingIssueUrl = typeof options.issueUrl === "string";
|
|
91
108
|
const usingRepoIssue = options.repo !== undefined || options.issue !== undefined;
|
|
@@ -3,7 +3,8 @@ import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
5
5
|
import { formatCliError, isDirectCliRun, parseJsonText } from "../_core-helpers.mjs";
|
|
6
|
-
import {
|
|
6
|
+
import { parseArgs } from "node:util";
|
|
7
|
+
import { parsePositiveInteger, requireTokenValue } from "../_cli-primitives.mjs";
|
|
7
8
|
import { parseRepoSlug } from "@dev-loops/core/github/repo-slug";
|
|
8
9
|
import { buildDraftReviewPayload } from "@dev-loops/core/loop/reviewer-loop-state";
|
|
9
10
|
const HELP = `Usage: stage-reviewer-draft.mjs --repo <owner/name> --pr <number> --review-file <path> [--local-state-output <path>]
|
|
@@ -19,7 +20,19 @@ Exit codes:
|
|
|
19
20
|
1 Error
|
|
20
21
|
`;
|
|
21
22
|
export function parseStageDraftCliArgs(argv) {
|
|
22
|
-
const
|
|
23
|
+
const { tokens } = parseArgs({
|
|
24
|
+
args: [...argv],
|
|
25
|
+
options: {
|
|
26
|
+
help: { type: "boolean", short: "h" },
|
|
27
|
+
repo: { type: "string" },
|
|
28
|
+
pr: { type: "string" },
|
|
29
|
+
"review-file": { type: "string" },
|
|
30
|
+
"local-state-output": { type: "string" },
|
|
31
|
+
},
|
|
32
|
+
allowPositionals: true,
|
|
33
|
+
strict: false,
|
|
34
|
+
tokens: true,
|
|
35
|
+
});
|
|
23
36
|
const options = {
|
|
24
37
|
repo: undefined,
|
|
25
38
|
pr: undefined,
|
|
@@ -27,29 +40,34 @@ export function parseStageDraftCliArgs(argv) {
|
|
|
27
40
|
localStateOutput: undefined,
|
|
28
41
|
help: false,
|
|
29
42
|
};
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
43
|
+
for (const token of tokens) {
|
|
44
|
+
if (token.kind === "positional") {
|
|
45
|
+
throw new Error(`Unknown argument: ${token.value}`);
|
|
46
|
+
}
|
|
47
|
+
if (token.kind !== "option") {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (token.name === "help") {
|
|
33
51
|
options.help = true;
|
|
34
52
|
return options;
|
|
35
53
|
}
|
|
36
|
-
if (token === "
|
|
37
|
-
options.repo =
|
|
54
|
+
if (token.name === "repo") {
|
|
55
|
+
options.repo = requireTokenValue(token).trim();
|
|
38
56
|
continue;
|
|
39
57
|
}
|
|
40
|
-
if (token === "
|
|
41
|
-
options.pr = parsePositiveInteger(
|
|
58
|
+
if (token.name === "pr") {
|
|
59
|
+
options.pr = parsePositiveInteger(requireTokenValue(token), "--pr");
|
|
42
60
|
continue;
|
|
43
61
|
}
|
|
44
|
-
if (token === "
|
|
45
|
-
options.reviewFile =
|
|
62
|
+
if (token.name === "review-file") {
|
|
63
|
+
options.reviewFile = requireTokenValue(token);
|
|
46
64
|
continue;
|
|
47
65
|
}
|
|
48
|
-
if (token === "
|
|
49
|
-
options.localStateOutput =
|
|
66
|
+
if (token.name === "local-state-output") {
|
|
67
|
+
options.localStateOutput = requireTokenValue(token);
|
|
50
68
|
continue;
|
|
51
69
|
}
|
|
52
|
-
throw new Error(`Unknown argument: ${token}`);
|
|
70
|
+
throw new Error(`Unknown argument: ${token.rawName}`);
|
|
53
71
|
}
|
|
54
72
|
if (!options.repo || !options.pr || !options.reviewFile) {
|
|
55
73
|
throw new Error(
|