@kolatts/pncli 1.25.1 → 1.26.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/{chunk-ABHLES5M.js → chunk-AGELHQKO.js} +4 -1
- package/dist/chunk-AGELHQKO.js.map +1 -0
- package/dist/cli.js +423 -4
- package/dist/cli.js.map +1 -1
- package/dist/{http-WCK6AZW6.js → http-WCDXXCKQ.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-ABHLES5M.js.map +0 -1
- /package/dist/{http-WCK6AZW6.js.map → http-WCDXXCKQ.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
success,
|
|
21
21
|
warn,
|
|
22
22
|
writeRawOutput
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-AGELHQKO.js";
|
|
24
24
|
import {
|
|
25
25
|
AdoCoreClient
|
|
26
26
|
} from "./chunk-VDL32PSG.js";
|
|
@@ -2368,6 +2368,232 @@ var GitHubClient = class {
|
|
|
2368
2368
|
const data = await this.http.githubGraphQL(mutation, { threadId });
|
|
2369
2369
|
return data.resolveReviewThread.thread;
|
|
2370
2370
|
}
|
|
2371
|
+
// ── Auto-merge ─────────────────────────────────────────────────────
|
|
2372
|
+
/** Returns the GraphQL node ID of a PR, needed for mutations. */
|
|
2373
|
+
async getPRNodeId(owner, repo, pullNumber) {
|
|
2374
|
+
const pr = await this.getPR(owner, repo, pullNumber);
|
|
2375
|
+
return pr.node_id;
|
|
2376
|
+
}
|
|
2377
|
+
async enableAutoMerge(opts) {
|
|
2378
|
+
const nodeId = await this.getPRNodeId(opts.owner, opts.repo, opts.pullNumber);
|
|
2379
|
+
const mutation = `
|
|
2380
|
+
mutation($pullRequestId: ID!, $mergeMethod: PullRequestMergeMethod, $expectedHeadOid: GitObjectID) {
|
|
2381
|
+
enablePullRequestAutoMerge(input: {
|
|
2382
|
+
pullRequestId: $pullRequestId
|
|
2383
|
+
mergeMethod: $mergeMethod
|
|
2384
|
+
expectedHeadOid: $expectedHeadOid
|
|
2385
|
+
}) {
|
|
2386
|
+
pullRequest {
|
|
2387
|
+
number
|
|
2388
|
+
autoMergeRequest {
|
|
2389
|
+
mergeMethod
|
|
2390
|
+
enabledAt
|
|
2391
|
+
enabledBy { login }
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
`;
|
|
2397
|
+
const variables = { pullRequestId: nodeId };
|
|
2398
|
+
if (opts.mergeMethod) variables.mergeMethod = opts.mergeMethod;
|
|
2399
|
+
if (opts.expectedHeadOid) variables.expectedHeadOid = opts.expectedHeadOid;
|
|
2400
|
+
const data = await this.http.githubGraphQL(mutation, variables);
|
|
2401
|
+
return data.enablePullRequestAutoMerge.pullRequest;
|
|
2402
|
+
}
|
|
2403
|
+
async disableAutoMerge(owner, repo, pullNumber) {
|
|
2404
|
+
const nodeId = await this.getPRNodeId(owner, repo, pullNumber);
|
|
2405
|
+
const mutation = `
|
|
2406
|
+
mutation($pullRequestId: ID!) {
|
|
2407
|
+
disablePullRequestAutoMerge(input: { pullRequestId: $pullRequestId }) {
|
|
2408
|
+
pullRequest {
|
|
2409
|
+
number
|
|
2410
|
+
autoMergeRequest {
|
|
2411
|
+
mergeMethod
|
|
2412
|
+
enabledAt
|
|
2413
|
+
enabledBy { login }
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
}
|
|
2418
|
+
`;
|
|
2419
|
+
const data = await this.http.githubGraphQL(mutation, { pullRequestId: nodeId });
|
|
2420
|
+
return data.disablePullRequestAutoMerge.pullRequest;
|
|
2421
|
+
}
|
|
2422
|
+
async enqueuePR(opts) {
|
|
2423
|
+
const nodeId = await this.getPRNodeId(opts.owner, opts.repo, opts.pullNumber);
|
|
2424
|
+
const mutation = `
|
|
2425
|
+
mutation($pullRequestId: ID!, $expectedHeadOid: GitObjectID, $mergeMethod: PullRequestMergeMethod) {
|
|
2426
|
+
addPullRequestToMergeQueue(input: {
|
|
2427
|
+
pullRequestId: $pullRequestId
|
|
2428
|
+
expectedHeadOid: $expectedHeadOid
|
|
2429
|
+
mergeMethod: $mergeMethod
|
|
2430
|
+
}) {
|
|
2431
|
+
mergeQueue {
|
|
2432
|
+
url
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
`;
|
|
2437
|
+
const variables = { pullRequestId: nodeId };
|
|
2438
|
+
if (opts.expectedHeadOid) variables.expectedHeadOid = opts.expectedHeadOid;
|
|
2439
|
+
if (opts.mergeMethod) variables.mergeMethod = opts.mergeMethod;
|
|
2440
|
+
const data = await this.http.githubGraphQL(mutation, variables);
|
|
2441
|
+
return { mergeQueueUrl: data.addPullRequestToMergeQueue.mergeQueue.url };
|
|
2442
|
+
}
|
|
2443
|
+
// ── PR status aggregation ──────────────────────────────────────────
|
|
2444
|
+
async getPRStatus(owner, repo, pullNumber) {
|
|
2445
|
+
const query = `
|
|
2446
|
+
query($owner: String!, $repo: String!, $number: Int!) {
|
|
2447
|
+
repository(owner: $owner, name: $repo) {
|
|
2448
|
+
pullRequest(number: $number) {
|
|
2449
|
+
number
|
|
2450
|
+
title
|
|
2451
|
+
state
|
|
2452
|
+
isDraft
|
|
2453
|
+
merged
|
|
2454
|
+
mergeable
|
|
2455
|
+
mergeStateStatus
|
|
2456
|
+
reviewDecision
|
|
2457
|
+
autoMergeRequest {
|
|
2458
|
+
mergeMethod
|
|
2459
|
+
enabledAt
|
|
2460
|
+
enabledBy { login }
|
|
2461
|
+
}
|
|
2462
|
+
commits(last: 1) {
|
|
2463
|
+
nodes {
|
|
2464
|
+
commit {
|
|
2465
|
+
statusCheckRollup {
|
|
2466
|
+
contexts(first: 100) {
|
|
2467
|
+
nodes {
|
|
2468
|
+
... on CheckRun {
|
|
2469
|
+
__typename
|
|
2470
|
+
name
|
|
2471
|
+
status
|
|
2472
|
+
conclusion
|
|
2473
|
+
}
|
|
2474
|
+
... on StatusContext {
|
|
2475
|
+
__typename
|
|
2476
|
+
context
|
|
2477
|
+
state
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
`;
|
|
2489
|
+
const data = await this.http.githubGraphQL(query, { owner, repo, number: pullNumber });
|
|
2490
|
+
const pr = data.repository.pullRequest;
|
|
2491
|
+
const checkNodes = pr.commits.nodes[0]?.commit.statusCheckRollup?.contexts.nodes ?? [];
|
|
2492
|
+
const details = checkNodes.map((n) => {
|
|
2493
|
+
if (n.__typename === "CheckRun") {
|
|
2494
|
+
return { name: n.name, status: n.status, conclusion: n.conclusion };
|
|
2495
|
+
}
|
|
2496
|
+
return { name: n.context, status: n.state, conclusion: null };
|
|
2497
|
+
});
|
|
2498
|
+
const passed = details.filter((d) => d.conclusion === "success" || d.status === "success").length;
|
|
2499
|
+
const failed = details.filter(
|
|
2500
|
+
(d) => d.conclusion === "failure" || d.conclusion === "timed_out" || d.conclusion === "action_required" || d.status === "failure" || d.status === "error"
|
|
2501
|
+
).length;
|
|
2502
|
+
const pending = details.filter(
|
|
2503
|
+
(d) => d.status === "queued" || d.status === "in_progress" || d.status === "pending"
|
|
2504
|
+
).length;
|
|
2505
|
+
const other = details.length - passed - failed - pending;
|
|
2506
|
+
return {
|
|
2507
|
+
number: pr.number,
|
|
2508
|
+
title: pr.title,
|
|
2509
|
+
state: pr.state,
|
|
2510
|
+
isDraft: pr.isDraft,
|
|
2511
|
+
merged: pr.merged,
|
|
2512
|
+
mergeable: pr.mergeable,
|
|
2513
|
+
mergeStateStatus: pr.mergeStateStatus,
|
|
2514
|
+
reviewDecision: pr.reviewDecision,
|
|
2515
|
+
autoMergeRequest: pr.autoMergeRequest ? {
|
|
2516
|
+
mergeMethod: pr.autoMergeRequest.mergeMethod,
|
|
2517
|
+
enabledAt: pr.autoMergeRequest.enabledAt,
|
|
2518
|
+
enabledBy: pr.autoMergeRequest.enabledBy.login
|
|
2519
|
+
} : null,
|
|
2520
|
+
checks: { total: details.length, passed, failed, pending, other, details }
|
|
2521
|
+
};
|
|
2522
|
+
}
|
|
2523
|
+
// ── Draft / ready-for-review ───────────────────────────────────────
|
|
2524
|
+
async convertToDraft(owner, repo, pullNumber) {
|
|
2525
|
+
const nodeId = await this.getPRNodeId(owner, repo, pullNumber);
|
|
2526
|
+
const mutation = `
|
|
2527
|
+
mutation($pullRequestId: ID!) {
|
|
2528
|
+
convertPullRequestToDraft(input: { pullRequestId: $pullRequestId }) {
|
|
2529
|
+
pullRequest { number isDraft }
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
`;
|
|
2533
|
+
const data = await this.http.githubGraphQL(mutation, { pullRequestId: nodeId });
|
|
2534
|
+
return data.convertPullRequestToDraft.pullRequest;
|
|
2535
|
+
}
|
|
2536
|
+
async markReadyForReview(owner, repo, pullNumber) {
|
|
2537
|
+
const nodeId = await this.getPRNodeId(owner, repo, pullNumber);
|
|
2538
|
+
const mutation = `
|
|
2539
|
+
mutation($pullRequestId: ID!) {
|
|
2540
|
+
markPullRequestReadyForReview(input: { pullRequestId: $pullRequestId }) {
|
|
2541
|
+
pullRequest { number isDraft }
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
`;
|
|
2545
|
+
const data = await this.http.githubGraphQL(mutation, { pullRequestId: nodeId });
|
|
2546
|
+
return data.markPullRequestReadyForReview.pullRequest;
|
|
2547
|
+
}
|
|
2548
|
+
// ── Reopen ─────────────────────────────────────────────────────────
|
|
2549
|
+
async reopenPR(owner, repo, pullNumber) {
|
|
2550
|
+
return this.updatePR({ owner, repo, pullNumber, state: "open" });
|
|
2551
|
+
}
|
|
2552
|
+
// ── Labels ─────────────────────────────────────────────────────────
|
|
2553
|
+
async addLabels(owner, repo, issueNumber, labels) {
|
|
2554
|
+
return this.http.github(
|
|
2555
|
+
`/repos/${owner}/${repo}/issues/${issueNumber}/labels`,
|
|
2556
|
+
{ method: "POST", body: { labels } }
|
|
2557
|
+
);
|
|
2558
|
+
}
|
|
2559
|
+
async removeLabel(owner, repo, issueNumber, label) {
|
|
2560
|
+
await this.http.github(
|
|
2561
|
+
`/repos/${owner}/${repo}/issues/${issueNumber}/labels/${label}`,
|
|
2562
|
+
{ method: "DELETE" }
|
|
2563
|
+
);
|
|
2564
|
+
}
|
|
2565
|
+
// ── Reviewers ──────────────────────────────────────────────────────
|
|
2566
|
+
async addReviewers(opts) {
|
|
2567
|
+
const body = {};
|
|
2568
|
+
if (opts.reviewers?.length) body.reviewers = opts.reviewers;
|
|
2569
|
+
if (opts.teamReviewers?.length) body.team_reviewers = opts.teamReviewers;
|
|
2570
|
+
return this.http.github(
|
|
2571
|
+
`/repos/${opts.owner}/${opts.repo}/pulls/${opts.pullNumber}/requested_reviewers`,
|
|
2572
|
+
{ method: "POST", body }
|
|
2573
|
+
);
|
|
2574
|
+
}
|
|
2575
|
+
async removeReviewers(opts) {
|
|
2576
|
+
const body = {};
|
|
2577
|
+
if (opts.reviewers?.length) body.reviewers = opts.reviewers;
|
|
2578
|
+
if (opts.teamReviewers?.length) body.team_reviewers = opts.teamReviewers;
|
|
2579
|
+
await this.http.github(
|
|
2580
|
+
`/repos/${opts.owner}/${opts.repo}/pulls/${opts.pullNumber}/requested_reviewers`,
|
|
2581
|
+
{ method: "DELETE", body }
|
|
2582
|
+
);
|
|
2583
|
+
}
|
|
2584
|
+
// ── Assignees ─────────────────────────────────────────────────────
|
|
2585
|
+
async addAssignees(owner, repo, issueNumber, assignees) {
|
|
2586
|
+
return this.http.github(
|
|
2587
|
+
`/repos/${owner}/${repo}/issues/${issueNumber}/assignees`,
|
|
2588
|
+
{ method: "POST", body: { assignees } }
|
|
2589
|
+
);
|
|
2590
|
+
}
|
|
2591
|
+
async removeAssignees(owner, repo, issueNumber, assignees) {
|
|
2592
|
+
return this.http.github(
|
|
2593
|
+
`/repos/${owner}/${repo}/issues/${issueNumber}/assignees`,
|
|
2594
|
+
{ method: "DELETE", body: { assignees } }
|
|
2595
|
+
);
|
|
2596
|
+
}
|
|
2371
2597
|
};
|
|
2372
2598
|
|
|
2373
2599
|
// src/services/github/commands.ts
|
|
@@ -2506,7 +2732,7 @@ function registerGitHubCommands(program2) {
|
|
|
2506
2732
|
fail(err, "github", "update-pr", start);
|
|
2507
2733
|
}
|
|
2508
2734
|
});
|
|
2509
|
-
gh.command("merge-pr").description("Merge a pull request").requiredOption("--number <n>", "Pull request number").addOption(new Option("--method <method>", "Merge method").choices(["merge", "squash", "rebase"]).default("merge")).option("--commit-title <title>", "Commit title for merge/squash").option("--commit-message <msg>", "Commit message for merge/squash").action(async (opts) => {
|
|
2735
|
+
gh.command("merge-pr").description("Merge a pull request (immediate merge \u2014 use enable-auto-merge for auto-merge)").requiredOption("--number <n>", "Pull request number").addOption(new Option("--method <method>", "Merge method").choices(["merge", "squash", "rebase"]).default("merge")).option("--commit-title <title>", "Commit title for merge/squash").option("--commit-message <msg>", "Commit message for merge/squash").action(async (opts) => {
|
|
2510
2736
|
const start = Date.now();
|
|
2511
2737
|
try {
|
|
2512
2738
|
const { client, owner, repo } = getClient3(gh);
|
|
@@ -2523,6 +2749,48 @@ function registerGitHubCommands(program2) {
|
|
|
2523
2749
|
fail(err, "github", "merge-pr", start);
|
|
2524
2750
|
}
|
|
2525
2751
|
});
|
|
2752
|
+
gh.command("enable-auto-merge").description("Enable auto-merge on a pull request (merges automatically when all requirements are met)").requiredOption("--number <n>", "Pull request number").addOption(new Option("--method <method>", "Merge method").choices(["merge", "squash", "rebase"])).option("--match-head-commit <sha>", "Only enable if the PR head matches this SHA (prevents race conditions)").action(async (opts) => {
|
|
2753
|
+
const start = Date.now();
|
|
2754
|
+
try {
|
|
2755
|
+
const { client, owner, repo } = getClient3(gh);
|
|
2756
|
+
const data = await client.enableAutoMerge({
|
|
2757
|
+
owner,
|
|
2758
|
+
repo,
|
|
2759
|
+
pullNumber: parseInt(opts.number, 10),
|
|
2760
|
+
mergeMethod: opts.method?.toUpperCase(),
|
|
2761
|
+
expectedHeadOid: opts.matchHeadCommit
|
|
2762
|
+
});
|
|
2763
|
+
success(data, "github", "enable-auto-merge", start);
|
|
2764
|
+
} catch (err) {
|
|
2765
|
+
fail(err, "github", "enable-auto-merge", start);
|
|
2766
|
+
}
|
|
2767
|
+
});
|
|
2768
|
+
gh.command("disable-auto-merge").description("Disable auto-merge on a pull request").requiredOption("--number <n>", "Pull request number").action(async (opts) => {
|
|
2769
|
+
const start = Date.now();
|
|
2770
|
+
try {
|
|
2771
|
+
const { client, owner, repo } = getClient3(gh);
|
|
2772
|
+
const data = await client.disableAutoMerge(owner, repo, parseInt(opts.number, 10));
|
|
2773
|
+
success(data, "github", "disable-auto-merge", start);
|
|
2774
|
+
} catch (err) {
|
|
2775
|
+
fail(err, "github", "disable-auto-merge", start);
|
|
2776
|
+
}
|
|
2777
|
+
});
|
|
2778
|
+
gh.command("enqueue-pr").description("Add a pull request to the repository merge queue").requiredOption("--number <n>", "Pull request number").addOption(new Option("--method <method>", "Merge method").choices(["merge", "squash", "rebase"])).option("--match-head-commit <sha>", "Only enqueue if the PR head matches this SHA (prevents race conditions)").action(async (opts) => {
|
|
2779
|
+
const start = Date.now();
|
|
2780
|
+
try {
|
|
2781
|
+
const { client, owner, repo } = getClient3(gh);
|
|
2782
|
+
const data = await client.enqueuePR({
|
|
2783
|
+
owner,
|
|
2784
|
+
repo,
|
|
2785
|
+
pullNumber: parseInt(opts.number, 10),
|
|
2786
|
+
mergeMethod: opts.method?.toUpperCase(),
|
|
2787
|
+
expectedHeadOid: opts.matchHeadCommit
|
|
2788
|
+
});
|
|
2789
|
+
success(data, "github", "enqueue-pr", start);
|
|
2790
|
+
} catch (err) {
|
|
2791
|
+
fail(err, "github", "enqueue-pr", start);
|
|
2792
|
+
}
|
|
2793
|
+
});
|
|
2526
2794
|
gh.command("close-pr").description("Close a pull request").requiredOption("--number <n>", "Pull request number").action(async (opts) => {
|
|
2527
2795
|
const start = Date.now();
|
|
2528
2796
|
try {
|
|
@@ -2724,6 +2992,148 @@ function registerGitHubCommands(program2) {
|
|
|
2724
2992
|
fail(err, "github", "list-checks", start);
|
|
2725
2993
|
}
|
|
2726
2994
|
});
|
|
2995
|
+
gh.command("pr-status").description("Aggregated PR status: review decision, checks, mergeability, draft state, and auto-merge").requiredOption("--number <n>", "Pull request number").action(async (opts) => {
|
|
2996
|
+
const start = Date.now();
|
|
2997
|
+
try {
|
|
2998
|
+
const { client, owner, repo } = getClient3(gh);
|
|
2999
|
+
const data = await client.getPRStatus(owner, repo, parseInt(opts.number, 10));
|
|
3000
|
+
success(data, "github", "pr-status", start);
|
|
3001
|
+
} catch (err) {
|
|
3002
|
+
fail(err, "github", "pr-status", start);
|
|
3003
|
+
}
|
|
3004
|
+
});
|
|
3005
|
+
gh.command("convert-to-draft").description("Convert an open pull request to a draft").requiredOption("--number <n>", "Pull request number").action(async (opts) => {
|
|
3006
|
+
const start = Date.now();
|
|
3007
|
+
try {
|
|
3008
|
+
const { client, owner, repo } = getClient3(gh);
|
|
3009
|
+
const data = await client.convertToDraft(owner, repo, parseInt(opts.number, 10));
|
|
3010
|
+
success(data, "github", "convert-to-draft", start);
|
|
3011
|
+
} catch (err) {
|
|
3012
|
+
fail(err, "github", "convert-to-draft", start);
|
|
3013
|
+
}
|
|
3014
|
+
});
|
|
3015
|
+
gh.command("ready-for-review").description("Mark a draft pull request as ready for review").requiredOption("--number <n>", "Pull request number").action(async (opts) => {
|
|
3016
|
+
const start = Date.now();
|
|
3017
|
+
try {
|
|
3018
|
+
const { client, owner, repo } = getClient3(gh);
|
|
3019
|
+
const data = await client.markReadyForReview(owner, repo, parseInt(opts.number, 10));
|
|
3020
|
+
success(data, "github", "ready-for-review", start);
|
|
3021
|
+
} catch (err) {
|
|
3022
|
+
fail(err, "github", "ready-for-review", start);
|
|
3023
|
+
}
|
|
3024
|
+
});
|
|
3025
|
+
gh.command("reopen-pr").description("Reopen a closed pull request").requiredOption("--number <n>", "Pull request number").action(async (opts) => {
|
|
3026
|
+
const start = Date.now();
|
|
3027
|
+
try {
|
|
3028
|
+
const { client, owner, repo } = getClient3(gh);
|
|
3029
|
+
const data = await client.reopenPR(owner, repo, parseInt(opts.number, 10));
|
|
3030
|
+
success(data, "github", "reopen-pr", start);
|
|
3031
|
+
} catch (err) {
|
|
3032
|
+
fail(err, "github", "reopen-pr", start);
|
|
3033
|
+
}
|
|
3034
|
+
});
|
|
3035
|
+
gh.command("add-labels").description("Add labels to a pull request or issue").requiredOption("--number <n>", "PR or issue number").option("--label <label>", "Label to add (repeatable)", (v, acc) => {
|
|
3036
|
+
acc.push(v);
|
|
3037
|
+
return acc;
|
|
3038
|
+
}, []).action(async (opts) => {
|
|
3039
|
+
const start = Date.now();
|
|
3040
|
+
try {
|
|
3041
|
+
const { client, owner, repo } = getClient3(gh);
|
|
3042
|
+
if (!opts.label.length) throw new PncliError("At least one --label is required", 1);
|
|
3043
|
+
const data = await client.addLabels(owner, repo, parseInt(opts.number, 10), opts.label);
|
|
3044
|
+
success(data, "github", "add-labels", start);
|
|
3045
|
+
} catch (err) {
|
|
3046
|
+
fail(err, "github", "add-labels", start);
|
|
3047
|
+
}
|
|
3048
|
+
});
|
|
3049
|
+
gh.command("remove-label").description("Remove a label from a pull request or issue").requiredOption("--number <n>", "PR or issue number").requiredOption("--label <label>", "Label name to remove").action(async (opts) => {
|
|
3050
|
+
const start = Date.now();
|
|
3051
|
+
try {
|
|
3052
|
+
const { client, owner, repo } = getClient3(gh);
|
|
3053
|
+
await client.removeLabel(owner, repo, parseInt(opts.number, 10), opts.label);
|
|
3054
|
+
success({ removed: true, label: opts.label }, "github", "remove-label", start);
|
|
3055
|
+
} catch (err) {
|
|
3056
|
+
fail(err, "github", "remove-label", start);
|
|
3057
|
+
}
|
|
3058
|
+
});
|
|
3059
|
+
gh.command("add-reviewers").description("Request reviewers on a pull request").requiredOption("--number <n>", "Pull request number").option("--reviewer <login>", "User reviewer login (repeatable)", (v, acc) => {
|
|
3060
|
+
acc.push(v);
|
|
3061
|
+
return acc;
|
|
3062
|
+
}, []).option("--team-reviewer <slug>", "Team slug to request (repeatable)", (v, acc) => {
|
|
3063
|
+
acc.push(v);
|
|
3064
|
+
return acc;
|
|
3065
|
+
}, []).action(async (opts) => {
|
|
3066
|
+
const start = Date.now();
|
|
3067
|
+
try {
|
|
3068
|
+
const { client, owner, repo } = getClient3(gh);
|
|
3069
|
+
if (!opts.reviewer.length && !opts.teamReviewer.length) {
|
|
3070
|
+
throw new PncliError("At least one --reviewer or --team-reviewer is required", 1);
|
|
3071
|
+
}
|
|
3072
|
+
const data = await client.addReviewers({
|
|
3073
|
+
owner,
|
|
3074
|
+
repo,
|
|
3075
|
+
pullNumber: parseInt(opts.number, 10),
|
|
3076
|
+
reviewers: opts.reviewer.length ? opts.reviewer : void 0,
|
|
3077
|
+
teamReviewers: opts.teamReviewer.length ? opts.teamReviewer : void 0
|
|
3078
|
+
});
|
|
3079
|
+
success(data, "github", "add-reviewers", start);
|
|
3080
|
+
} catch (err) {
|
|
3081
|
+
fail(err, "github", "add-reviewers", start);
|
|
3082
|
+
}
|
|
3083
|
+
});
|
|
3084
|
+
gh.command("remove-reviewers").description("Remove requested reviewers from a pull request").requiredOption("--number <n>", "Pull request number").option("--reviewer <login>", "User reviewer login to remove (repeatable)", (v, acc) => {
|
|
3085
|
+
acc.push(v);
|
|
3086
|
+
return acc;
|
|
3087
|
+
}, []).option("--team-reviewer <slug>", "Team slug to remove (repeatable)", (v, acc) => {
|
|
3088
|
+
acc.push(v);
|
|
3089
|
+
return acc;
|
|
3090
|
+
}, []).action(async (opts) => {
|
|
3091
|
+
const start = Date.now();
|
|
3092
|
+
try {
|
|
3093
|
+
const { client, owner, repo } = getClient3(gh);
|
|
3094
|
+
if (!opts.reviewer.length && !opts.teamReviewer.length) {
|
|
3095
|
+
throw new PncliError("At least one --reviewer or --team-reviewer is required", 1);
|
|
3096
|
+
}
|
|
3097
|
+
await client.removeReviewers({
|
|
3098
|
+
owner,
|
|
3099
|
+
repo,
|
|
3100
|
+
pullNumber: parseInt(opts.number, 10),
|
|
3101
|
+
reviewers: opts.reviewer.length ? opts.reviewer : void 0,
|
|
3102
|
+
teamReviewers: opts.teamReviewer.length ? opts.teamReviewer : void 0
|
|
3103
|
+
});
|
|
3104
|
+
success({ removed: true }, "github", "remove-reviewers", start);
|
|
3105
|
+
} catch (err) {
|
|
3106
|
+
fail(err, "github", "remove-reviewers", start);
|
|
3107
|
+
}
|
|
3108
|
+
});
|
|
3109
|
+
gh.command("add-assignees").description("Add assignees to a pull request or issue").requiredOption("--number <n>", "PR or issue number").option("--assignee <login>", "Assignee login (repeatable)", (v, acc) => {
|
|
3110
|
+
acc.push(v);
|
|
3111
|
+
return acc;
|
|
3112
|
+
}, []).action(async (opts) => {
|
|
3113
|
+
const start = Date.now();
|
|
3114
|
+
try {
|
|
3115
|
+
const { client, owner, repo } = getClient3(gh);
|
|
3116
|
+
if (!opts.assignee.length) throw new PncliError("At least one --assignee is required", 1);
|
|
3117
|
+
const data = await client.addAssignees(owner, repo, parseInt(opts.number, 10), opts.assignee);
|
|
3118
|
+
success(data, "github", "add-assignees", start);
|
|
3119
|
+
} catch (err) {
|
|
3120
|
+
fail(err, "github", "add-assignees", start);
|
|
3121
|
+
}
|
|
3122
|
+
});
|
|
3123
|
+
gh.command("remove-assignees").description("Remove assignees from a pull request or issue").requiredOption("--number <n>", "PR or issue number").option("--assignee <login>", "Assignee login to remove (repeatable)", (v, acc) => {
|
|
3124
|
+
acc.push(v);
|
|
3125
|
+
return acc;
|
|
3126
|
+
}, []).action(async (opts) => {
|
|
3127
|
+
const start = Date.now();
|
|
3128
|
+
try {
|
|
3129
|
+
const { client, owner, repo } = getClient3(gh);
|
|
3130
|
+
if (!opts.assignee.length) throw new PncliError("At least one --assignee is required", 1);
|
|
3131
|
+
const data = await client.removeAssignees(owner, repo, parseInt(opts.number, 10), opts.assignee);
|
|
3132
|
+
success(data, "github", "remove-assignees", start);
|
|
3133
|
+
} catch (err) {
|
|
3134
|
+
fail(err, "github", "remove-assignees", start);
|
|
3135
|
+
}
|
|
3136
|
+
});
|
|
2727
3137
|
}
|
|
2728
3138
|
|
|
2729
3139
|
// src/services/confluence/commands.ts
|
|
@@ -8172,7 +8582,7 @@ function registerAdoRepoCommands(ado) {
|
|
|
8172
8582
|
const config = lc({ configPath: globalOpts.config });
|
|
8173
8583
|
const { collection, project, repo: repo2, gitClient } = getAdoContext(ado, true);
|
|
8174
8584
|
const { AdoCoreClient: AdoCoreClient2 } = await import("./core-SWYVXOQ4.js");
|
|
8175
|
-
const { createHttpClient: createHttpClient2 } = await import("./http-
|
|
8585
|
+
const { createHttpClient: createHttpClient2 } = await import("./http-WCDXXCKQ.js");
|
|
8176
8586
|
const http = createHttpClient2(config, Boolean(globalOpts.dryRun));
|
|
8177
8587
|
const coreClient = new AdoCoreClient2(http);
|
|
8178
8588
|
const me = await coreClient.getConnectionData(collection);
|
|
@@ -10526,7 +10936,7 @@ function podAge(creationTimestamp) {
|
|
|
10526
10936
|
}
|
|
10527
10937
|
function registerOpenShiftCommands(program2) {
|
|
10528
10938
|
const oc = program2.command("openshift").description("OpenShift / Kubernetes operations");
|
|
10529
|
-
oc.command("pods").description("List pod health summary for a namespace \u2014 pre-processed for LLM analysis").requiredOption("--namespace <ns>", "Kubernetes namespace").option("--label-selector <selector>", "Label selector (e.g. app=my-app)").action(async (opts) => {
|
|
10939
|
+
oc.command("pods").description("List pod health summary for a namespace \u2014 pre-processed for LLM analysis. Use --raw to return the full unmodified Kubernetes pod objects.").requiredOption("--namespace <ns>", "Kubernetes namespace").option("--label-selector <selector>", "Label selector (e.g. app=my-app)").option("--raw", "Return full Kubernetes pod objects without summarization (includes env vars, images, node name, annotations, resources, etc.)", false).action(async (opts) => {
|
|
10530
10940
|
const start = Date.now();
|
|
10531
10941
|
try {
|
|
10532
10942
|
const http = getHttp2(program2);
|
|
@@ -10536,6 +10946,15 @@ function registerOpenShiftCommands(program2) {
|
|
|
10536
10946
|
`/api/v1/namespaces/${encodeURIComponent(opts.namespace)}/pods`,
|
|
10537
10947
|
{ params }
|
|
10538
10948
|
);
|
|
10949
|
+
if (opts.raw) {
|
|
10950
|
+
success(
|
|
10951
|
+
{ namespace: opts.namespace, count: podList.items.length, pods: podList.items },
|
|
10952
|
+
"openshift",
|
|
10953
|
+
"pods",
|
|
10954
|
+
start
|
|
10955
|
+
);
|
|
10956
|
+
return;
|
|
10957
|
+
}
|
|
10539
10958
|
const summaryCounters = {
|
|
10540
10959
|
total: podList.items.length,
|
|
10541
10960
|
running: 0,
|