@nt-ai-lab/opencode-skillz 0.4.4 → 0.4.5

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.
@@ -0,0 +1,28 @@
1
+ import { z } from "zod";
2
+ export declare const pullRequestReviewSchema: z.ZodObject<{
3
+ author: z.ZodObject<{
4
+ login: z.ZodString;
5
+ }, z.core.$strip>;
6
+ state: z.ZodString;
7
+ submittedAt: z.ZodNullable<z.ZodString>;
8
+ }, z.core.$strip>;
9
+ export declare const statusCheckRollupItemSchema: z.ZodObject<{
10
+ conclusion: z.ZodNullable<z.ZodString>;
11
+ detailsUrl: z.ZodString;
12
+ name: z.ZodString;
13
+ state: z.ZodNullable<z.ZodString>;
14
+ status: z.ZodNullable<z.ZodString>;
15
+ type: z.ZodString;
16
+ }, z.core.$strip>;
17
+ type PullRequestReview = z.infer<typeof pullRequestReviewSchema>;
18
+ type StatusCheckRollupItem = z.infer<typeof statusCheckRollupItemSchema>;
19
+ export interface PullRequestStateView {
20
+ mergeable: string | null;
21
+ reviewDecision: string | null;
22
+ reviews: PullRequestReview[];
23
+ statusCheckRollup: StatusCheckRollupItem[];
24
+ }
25
+ export declare function createPullRequestViewJqFilter(): string;
26
+ export declare function formatPullRequestStateSummary(pullRequestView: PullRequestStateView): string[];
27
+ export declare function formatPullRequestStateDetails(pullRequestView: PullRequestStateView): string[];
28
+ export {};
@@ -0,0 +1,118 @@
1
+ import { z } from "zod";
2
+ export const pullRequestReviewSchema = z.object({
3
+ author: z.object({
4
+ login: z.string().min(1),
5
+ }),
6
+ state: z.string().min(1),
7
+ submittedAt: z.string().nullable(),
8
+ });
9
+ export const statusCheckRollupItemSchema = z.object({
10
+ conclusion: z.string().nullable(),
11
+ detailsUrl: z.string(),
12
+ name: z.string().min(1),
13
+ state: z.string().nullable(),
14
+ status: z.string().nullable(),
15
+ type: z.string().min(1),
16
+ });
17
+ const failedCheckOutcomes = new Set([
18
+ "ACTION_REQUIRED",
19
+ "CANCELLED",
20
+ "ERROR",
21
+ "FAILURE",
22
+ "STARTUP_FAILURE",
23
+ "TIMED_OUT",
24
+ ]);
25
+ export function createPullRequestViewJqFilter() {
26
+ return [
27
+ "{",
28
+ " baseRefName,",
29
+ " headRefName,",
30
+ " id,",
31
+ " mergeable,",
32
+ " number,",
33
+ " reviewDecision,",
34
+ " reviews: [.reviews[]? | {",
35
+ " author: { login: (.author.login // \"unknown\") },",
36
+ " state,",
37
+ " submittedAt",
38
+ " }],",
39
+ " statusCheckRollup: [.statusCheckRollup[]? | {",
40
+ " conclusion: (.conclusion // null),",
41
+ " detailsUrl: (.detailsUrl // .targetUrl // \"\"),",
42
+ " name: (.name // .context // .workflowName // \"unknown\"),",
43
+ " state: (.state // null),",
44
+ " status: (.status // null),",
45
+ " type: (.__typename // \"unknown\")",
46
+ " }],",
47
+ " url",
48
+ "}",
49
+ ].join("\n");
50
+ }
51
+ function readStatusCheckOutcome(statusCheck) {
52
+ return statusCheck.conclusion ?? statusCheck.state ?? statusCheck.status ?? "UNKNOWN";
53
+ }
54
+ function readFailedStatusChecks(pullRequestView) {
55
+ return pullRequestView.statusCheckRollup.filter((statusCheck) => failedCheckOutcomes.has(readStatusCheckOutcome(statusCheck)));
56
+ }
57
+ function readChangesRequestedReviews(pullRequestView) {
58
+ return pullRequestView.reviews.filter((review) => review.state === "CHANGES_REQUESTED");
59
+ }
60
+ function formatNullableState(value) {
61
+ return value ?? "unknown";
62
+ }
63
+ function formatBoolean(value) {
64
+ return value ? "yes" : "no";
65
+ }
66
+ export function formatPullRequestStateSummary(pullRequestView) {
67
+ return [
68
+ `- Mergeable: ${formatNullableState(pullRequestView.mergeable)}`,
69
+ `- Review decision: ${formatNullableState(pullRequestView.reviewDecision)}`,
70
+ `- Changes requested: ${formatBoolean(pullRequestView.reviewDecision === "CHANGES_REQUESTED")}`,
71
+ `- Changes-requested review history: ${readChangesRequestedReviews(pullRequestView).length}`,
72
+ `- Failed checks: ${readFailedStatusChecks(pullRequestView).length}`,
73
+ ];
74
+ }
75
+ function formatChangesRequestedReview(review, index) {
76
+ return [
77
+ `### Changes-requested review ${index + 1}`,
78
+ `- Author: ${review.author.login}`,
79
+ `- Submitted: ${formatNullableState(review.submittedAt)}`,
80
+ ].join("\n");
81
+ }
82
+ function formatChangesRequestedReviewHistory(reviews) {
83
+ if (reviews.length === 0)
84
+ return [];
85
+ return [
86
+ "",
87
+ "## Changes-requested review history",
88
+ "",
89
+ ...reviews.map(formatChangesRequestedReview),
90
+ ];
91
+ }
92
+ function formatFailedCheck(statusCheck) {
93
+ return [
94
+ `### Failed check: ${statusCheck.name}`,
95
+ `- Type: ${statusCheck.type}`,
96
+ `- Outcome: ${readStatusCheckOutcome(statusCheck)}`,
97
+ `- Status: ${formatNullableState(statusCheck.status)}`,
98
+ `- Conclusion: ${formatNullableState(statusCheck.conclusion)}`,
99
+ `- State: ${formatNullableState(statusCheck.state)}`,
100
+ `- Details URL: ${statusCheck.detailsUrl || "not returned"}`,
101
+ ].join("\n");
102
+ }
103
+ function formatFailedChecks(statusChecks) {
104
+ if (statusChecks.length === 0)
105
+ return [];
106
+ return [
107
+ "",
108
+ "## Failed checks",
109
+ "",
110
+ ...statusChecks.map(formatFailedCheck),
111
+ ];
112
+ }
113
+ export function formatPullRequestStateDetails(pullRequestView) {
114
+ return [
115
+ ...formatChangesRequestedReviewHistory(readChangesRequestedReviews(pullRequestView)),
116
+ ...formatFailedChecks(readFailedStatusChecks(pullRequestView)),
117
+ ];
118
+ }
@@ -2,12 +2,17 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { z } from "zod";
4
4
  import { childProcessCommandRunner } from "../source-control/changed-files.js";
5
+ import { createPullRequestViewJqFilter, formatPullRequestStateDetails, formatPullRequestStateSummary, pullRequestReviewSchema, statusCheckRollupItemSchema, } from "./feedback-state.js";
5
6
  export const PULL_REQUEST_FEEDBACK_TOOL_NAME = "nt_skillz_pr_feedback";
6
7
  const pullRequestViewSchema = z.object({
7
8
  baseRefName: z.string(),
8
9
  headRefName: z.string(),
9
10
  id: z.string().min(1),
11
+ mergeable: z.string().nullable(),
10
12
  number: z.number().int(),
13
+ reviewDecision: z.string().nullable(),
14
+ reviews: z.array(pullRequestReviewSchema),
15
+ statusCheckRollup: z.array(statusCheckRollupItemSchema),
11
16
  url: z.string().min(1),
12
17
  });
13
18
  const reviewThreadSchema = z.object({
@@ -89,9 +94,9 @@ function readPullRequestView(repositoryRoot, pullRequestNumber, commandRunner) {
89
94
  "view",
90
95
  pullRequestNumber,
91
96
  "--json",
92
- "id,number,url,headRefName,baseRefName",
97
+ "id,number,url,headRefName,baseRefName,mergeable,reviewDecision,reviews,statusCheckRollup",
93
98
  "--jq",
94
- ".",
99
+ createPullRequestViewJqFilter(),
95
100
  ], repositoryRoot);
96
101
  ensureSuccessfulCommand(commandResult, "GitHub pull request lookup");
97
102
  return parseJsonWithSchema(commandResult.stdout, pullRequestViewSchema, "GitHub pull request lookup");
@@ -134,6 +139,8 @@ function readReviewThreadPage(repositoryRoot, pullRequestId, threadCursor, comma
134
139
  `pullRequestId=${pullRequestId}`,
135
140
  "-f",
136
141
  `query=${createReviewThreadsQuery()}`,
142
+ "--jq",
143
+ ".data",
137
144
  ];
138
145
  if (threadCursor) {
139
146
  commandArguments.splice(4, 0, "-f", `threadCursor=${threadCursor}`);
@@ -273,7 +280,9 @@ export function readPullRequestFeedback(request, dependencies = {}) {
273
280
  `- PR URL: ${pullRequestView.url}`,
274
281
  `- Head branch: ${pullRequestView.headRefName}`,
275
282
  `- Base branch: ${pullRequestView.baseRefName}`,
283
+ ...formatPullRequestStateSummary(pullRequestView),
276
284
  `- Unresolved review threads: ${unresolvedReviewThreads.length}`,
285
+ ...formatPullRequestStateDetails(pullRequestView),
277
286
  "",
278
287
  ...unresolvedReviewThreads.map((reviewThread) => formatReviewThread(request.repositoryRoot, reviewThread)),
279
288
  ].join("\n");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nt-ai-lab/opencode-skillz",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "description": "Bundled OpenCode commands and agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",