@nt-ai-lab/opencode-skillz 0.4.3 → 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.
package/AGENTS.md CHANGED
@@ -74,8 +74,11 @@ Supported keys in `agents/*.md`:
74
74
  - `description` (optional)
75
75
  - `mode` (optional)
76
76
  - `model` (optional)
77
+ - `temperature` (optional number)
77
78
  - `color` (optional)
78
79
  - `extends` (optional, agent name to prepend prompt from)
79
80
  - `preload_commands` (optional, comma-separated command names to embed in prompt)
80
81
 
82
+ Agent `extends` composes prompt content and preloaded commands only. Agent frontmatter settings such as `description`, `mode`, `model`, `temperature`, and `color` are not inherited from parent agents.
83
+
81
84
  The markdown body becomes the command template or the agent prompt.
package/agents/default.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: Minimal default robot agent
3
3
  mode: primary
4
- temperature: 2
4
+ temperature: 0.5
5
5
  preload_commands: software-design, writing-tests
6
6
  ---
7
7
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: Empathetic convesation facilitator
3
3
  mode: primary
4
- temperature: 8
4
+ temperature: 5
5
5
  ---
6
6
 
7
7
  You are an experienced facilitator. Your purpose is to help the user explore a topic by facilitating the conversation to it's natural conclusion. There is no end state, no metric, no artefact to be produced at the end. The conversation is finished when it's finished, when the user feels a natural conclusion has been achieved.
@@ -10,6 +10,15 @@ function parseCsvList(value) {
10
10
  function materializePreloadedTemplate(template) {
11
11
  return template.replaceAll("$ARGUMENTS", "all relevant current work in this session");
12
12
  }
13
+ function parseOptionalNumber(value) {
14
+ if (typeof value !== "string")
15
+ return undefined;
16
+ const trimmedValue = value.trim();
17
+ if (!trimmedValue)
18
+ return undefined;
19
+ const parsedValue = Number(trimmedValue);
20
+ return Number.isFinite(parsedValue) ? parsedValue : undefined;
21
+ }
13
22
  function getParentAgentName(rawAgent) {
14
23
  return typeof rawAgent.meta.extends === "string" ? rawAgent.meta.extends.trim() : "";
15
24
  }
@@ -38,6 +47,9 @@ function setOptionalAgentProperties(agent, meta) {
38
47
  agent.mode = meta.mode;
39
48
  if (typeof meta.model === "string")
40
49
  agent.model = meta.model;
50
+ const temperature = parseOptionalNumber(meta.temperature);
51
+ if (temperature !== undefined)
52
+ agent.temperature = temperature;
41
53
  if (typeof meta.color === "string")
42
54
  agent.color = meta.color;
43
55
  }
@@ -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/dist/types.d.ts CHANGED
@@ -11,6 +11,7 @@ export interface AgentDefinition {
11
11
  description?: string;
12
12
  mode?: string;
13
13
  model?: string;
14
+ temperature?: number;
14
15
  color?: string;
15
16
  disable?: boolean;
16
17
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nt-ai-lab/opencode-skillz",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "Bundled OpenCode commands and agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",