opencodekit 0.20.7 → 0.21.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/index.js +1 -1
- package/dist/template/.opencode/AGENTS.md +60 -0
- package/dist/template/.opencode/agent/build.md +3 -2
- package/dist/template/.opencode/agent/explore.md +14 -14
- package/dist/template/.opencode/agent/general.md +1 -1
- package/dist/template/.opencode/agent/plan.md +1 -1
- package/dist/template/.opencode/agent/review.md +1 -1
- package/dist/template/.opencode/agent/vision.md +0 -9
- package/dist/template/.opencode/memory.db +0 -0
- package/dist/template/.opencode/memory.db-shm +0 -0
- package/dist/template/.opencode/memory.db-wal +0 -0
- package/dist/template/.opencode/opencode.json +83 -614
- package/dist/template/.opencode/opencodex-fast.jsonc +1 -1
- package/dist/template/.opencode/package.json +1 -1
- package/dist/template/.opencode/plugin/copilot-auth.ts +27 -12
- package/dist/template/.opencode/plugin/prompt-leverage.ts +193 -0
- package/dist/template/.opencode/plugin/prompt-leverage.ts.bak +228 -0
- package/dist/template/.opencode/plugin/sdk/copilot/copilot-provider.ts +14 -2
- package/dist/template/.opencode/plugin/sdk/copilot/index.ts +2 -2
- package/dist/template/.opencode/plugin/sdk/copilot/responses/convert-to-openai-responses-input.ts +335 -0
- package/dist/template/.opencode/plugin/sdk/copilot/responses/map-openai-responses-finish-reason.ts +22 -0
- package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-config.ts +18 -0
- package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-error.ts +22 -0
- package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-responses-api-types.ts +214 -0
- package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-responses-language-model.ts +1770 -0
- package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-responses-prepare-tools.ts +173 -0
- package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-responses-settings.ts +1 -0
- package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/code-interpreter.ts +87 -0
- package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/file-search.ts +127 -0
- package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/image-generation.ts +114 -0
- package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/local-shell.ts +64 -0
- package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/web-search-preview.ts +103 -0
- package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/web-search.ts +102 -0
- package/dist/template/.opencode/pnpm-lock.yaml +791 -9
- package/dist/template/.opencode/skill/api-and-interface-design/SKILL.md +162 -0
- package/dist/template/.opencode/skill/beads/SKILL.md +10 -9
- package/dist/template/.opencode/skill/beads/references/MULTI_AGENT.md +10 -10
- package/dist/template/.opencode/skill/ci-cd-and-automation/SKILL.md +202 -0
- package/dist/template/.opencode/skill/code-search-patterns/SKILL.md +253 -0
- package/dist/template/.opencode/skill/code-simplification/SKILL.md +211 -0
- package/dist/template/.opencode/skill/condition-based-waiting/SKILL.md +12 -0
- package/dist/template/.opencode/skill/defense-in-depth/SKILL.md +16 -6
- package/dist/template/.opencode/skill/deprecation-and-migration/SKILL.md +189 -0
- package/dist/template/.opencode/skill/development-lifecycle/SKILL.md +12 -48
- package/dist/template/.opencode/skill/documentation-and-adrs/SKILL.md +220 -0
- package/dist/template/.opencode/skill/gh-address-comments/SKILL.md +29 -0
- package/dist/template/.opencode/skill/gh-address-comments/scripts/fetch_comments.py +237 -0
- package/dist/template/.opencode/skill/gh-fix-ci/SKILL.md +38 -0
- package/dist/template/.opencode/skill/gh-fix-ci/scripts/inspect_pr_checks.py +509 -0
- package/dist/template/.opencode/skill/incremental-implementation/SKILL.md +191 -0
- package/dist/template/.opencode/skill/performance-optimization/SKILL.md +236 -0
- package/dist/template/.opencode/skill/prompt-leverage/SKILL.md +90 -0
- package/dist/template/.opencode/skill/prompt-leverage/references/framework.md +91 -0
- package/dist/template/.opencode/skill/prompt-leverage/scripts/augment_prompt.py +157 -0
- package/dist/template/.opencode/skill/receiving-code-review/SKILL.md +11 -0
- package/dist/template/.opencode/skill/screenshot/SKILL.md +48 -0
- package/dist/template/.opencode/skill/screenshot/scripts/ensure_macos_permissions.sh +54 -0
- package/dist/template/.opencode/skill/screenshot/scripts/macos_display_info.swift +22 -0
- package/dist/template/.opencode/skill/screenshot/scripts/macos_permissions.swift +40 -0
- package/dist/template/.opencode/skill/screenshot/scripts/macos_window_info.swift +126 -0
- package/dist/template/.opencode/skill/screenshot/scripts/take_screenshot.ps1 +163 -0
- package/dist/template/.opencode/skill/screenshot/scripts/take_screenshot.py +585 -0
- package/dist/template/.opencode/skill/security-and-hardening/SKILL.md +296 -0
- package/dist/template/.opencode/skill/security-threat-model/SKILL.md +36 -0
- package/dist/template/.opencode/skill/security-threat-model/references/prompt-template.md +255 -0
- package/dist/template/.opencode/skill/security-threat-model/references/security-controls-and-assets.md +32 -0
- package/dist/template/.opencode/skill/skill-installer/SKILL.md +58 -0
- package/dist/template/.opencode/skill/skill-installer/scripts/github_utils.py +21 -0
- package/dist/template/.opencode/skill/skill-installer/scripts/install-skill-from-github.py +313 -0
- package/dist/template/.opencode/skill/skill-installer/scripts/list-skills.py +106 -0
- package/dist/template/.opencode/skill/structured-edit/SKILL.md +10 -0
- package/dist/template/.opencode/skill/swarm-coordination/SKILL.md +66 -1
- package/package.json +1 -1
- package/dist/template/.opencode/skill/beads-bridge/SKILL.md +0 -321
- package/dist/template/.opencode/skill/code-navigation/SKILL.md +0 -130
- package/dist/template/.opencode/skill/mqdh/SKILL.md +0 -171
- package/dist/template/.opencode/skill/obsidian/SKILL.md +0 -192
- package/dist/template/.opencode/skill/obsidian/mcp.json +0 -22
- package/dist/template/.opencode/skill/pencil/SKILL.md +0 -72
- package/dist/template/.opencode/skill/ralph/SKILL.md +0 -296
- package/dist/template/.opencode/skill/tilth-cli/SKILL.md +0 -207
- package/dist/template/.opencode/skill/tool-priority/SKILL.md +0 -299
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Fetch all PR conversation comments + reviews + review threads (inline threads)
|
|
4
|
+
for the PR associated with the current git branch, by shelling out to:
|
|
5
|
+
|
|
6
|
+
gh api graphql
|
|
7
|
+
|
|
8
|
+
Requires:
|
|
9
|
+
- `gh auth login` already set up
|
|
10
|
+
- current branch has an associated (open) PR
|
|
11
|
+
|
|
12
|
+
Usage:
|
|
13
|
+
python fetch_comments.py > pr_comments.json
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
import subprocess
|
|
20
|
+
import sys
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
QUERY = """\
|
|
24
|
+
query(
|
|
25
|
+
$owner: String!,
|
|
26
|
+
$repo: String!,
|
|
27
|
+
$number: Int!,
|
|
28
|
+
$commentsCursor: String,
|
|
29
|
+
$reviewsCursor: String,
|
|
30
|
+
$threadsCursor: String
|
|
31
|
+
) {
|
|
32
|
+
repository(owner: $owner, name: $repo) {
|
|
33
|
+
pullRequest(number: $number) {
|
|
34
|
+
number
|
|
35
|
+
url
|
|
36
|
+
title
|
|
37
|
+
state
|
|
38
|
+
|
|
39
|
+
# Top-level "Conversation" comments (issue comments on the PR)
|
|
40
|
+
comments(first: 100, after: $commentsCursor) {
|
|
41
|
+
pageInfo { hasNextPage endCursor }
|
|
42
|
+
nodes {
|
|
43
|
+
id
|
|
44
|
+
body
|
|
45
|
+
createdAt
|
|
46
|
+
updatedAt
|
|
47
|
+
author { login }
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# Review submissions (Approve / Request changes / Comment), with body if present
|
|
52
|
+
reviews(first: 100, after: $reviewsCursor) {
|
|
53
|
+
pageInfo { hasNextPage endCursor }
|
|
54
|
+
nodes {
|
|
55
|
+
id
|
|
56
|
+
state
|
|
57
|
+
body
|
|
58
|
+
submittedAt
|
|
59
|
+
author { login }
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# Inline review threads (grouped), includes resolved state
|
|
64
|
+
reviewThreads(first: 100, after: $threadsCursor) {
|
|
65
|
+
pageInfo { hasNextPage endCursor }
|
|
66
|
+
nodes {
|
|
67
|
+
id
|
|
68
|
+
isResolved
|
|
69
|
+
isOutdated
|
|
70
|
+
path
|
|
71
|
+
line
|
|
72
|
+
diffSide
|
|
73
|
+
startLine
|
|
74
|
+
startDiffSide
|
|
75
|
+
originalLine
|
|
76
|
+
originalStartLine
|
|
77
|
+
resolvedBy { login }
|
|
78
|
+
comments(first: 100) {
|
|
79
|
+
nodes {
|
|
80
|
+
id
|
|
81
|
+
body
|
|
82
|
+
createdAt
|
|
83
|
+
updatedAt
|
|
84
|
+
author { login }
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _run(cmd: list[str], stdin: str | None = None) -> str:
|
|
96
|
+
p = subprocess.run(cmd, input=stdin, capture_output=True, text=True)
|
|
97
|
+
if p.returncode != 0:
|
|
98
|
+
raise RuntimeError(f"Command failed: {' '.join(cmd)}\n{p.stderr}")
|
|
99
|
+
return p.stdout
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _run_json(cmd: list[str], stdin: str | None = None) -> dict[str, Any]:
|
|
103
|
+
out = _run(cmd, stdin=stdin)
|
|
104
|
+
try:
|
|
105
|
+
return json.loads(out)
|
|
106
|
+
except json.JSONDecodeError as e:
|
|
107
|
+
raise RuntimeError(f"Failed to parse JSON from command output: {e}\nRaw:\n{out}") from e
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _ensure_gh_authenticated() -> None:
|
|
111
|
+
try:
|
|
112
|
+
_run(["gh", "auth", "status"])
|
|
113
|
+
except RuntimeError:
|
|
114
|
+
print("run `gh auth login` to authenticate the GitHub CLI", file=sys.stderr)
|
|
115
|
+
raise RuntimeError("gh auth status failed; run `gh auth login` to authenticate the GitHub CLI") from None
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def gh_pr_view_json(fields: str) -> dict[str, Any]:
|
|
119
|
+
# fields is a comma-separated list like: "number,headRepositoryOwner,headRepository"
|
|
120
|
+
return _run_json(["gh", "pr", "view", "--json", fields])
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def get_current_pr_ref() -> tuple[str, str, int]:
|
|
124
|
+
"""
|
|
125
|
+
Resolve the PR for the current branch (whatever gh considers associated).
|
|
126
|
+
Works for cross-repo PRs too, by reading head repository owner/name.
|
|
127
|
+
"""
|
|
128
|
+
pr = gh_pr_view_json("number,headRepositoryOwner,headRepository")
|
|
129
|
+
owner = pr["headRepositoryOwner"]["login"]
|
|
130
|
+
repo = pr["headRepository"]["name"]
|
|
131
|
+
number = int(pr["number"])
|
|
132
|
+
return owner, repo, number
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def gh_api_graphql(
|
|
136
|
+
owner: str,
|
|
137
|
+
repo: str,
|
|
138
|
+
number: int,
|
|
139
|
+
comments_cursor: str | None = None,
|
|
140
|
+
reviews_cursor: str | None = None,
|
|
141
|
+
threads_cursor: str | None = None,
|
|
142
|
+
) -> dict[str, Any]:
|
|
143
|
+
"""
|
|
144
|
+
Call `gh api graphql` using -F variables, avoiding JSON blobs with nulls.
|
|
145
|
+
Query is passed via stdin using query=@- to avoid shell newline/quoting issues.
|
|
146
|
+
"""
|
|
147
|
+
cmd = [
|
|
148
|
+
"gh",
|
|
149
|
+
"api",
|
|
150
|
+
"graphql",
|
|
151
|
+
"-F",
|
|
152
|
+
"query=@-",
|
|
153
|
+
"-F",
|
|
154
|
+
f"owner={owner}",
|
|
155
|
+
"-F",
|
|
156
|
+
f"repo={repo}",
|
|
157
|
+
"-F",
|
|
158
|
+
f"number={number}",
|
|
159
|
+
]
|
|
160
|
+
if comments_cursor:
|
|
161
|
+
cmd += ["-F", f"commentsCursor={comments_cursor}"]
|
|
162
|
+
if reviews_cursor:
|
|
163
|
+
cmd += ["-F", f"reviewsCursor={reviews_cursor}"]
|
|
164
|
+
if threads_cursor:
|
|
165
|
+
cmd += ["-F", f"threadsCursor={threads_cursor}"]
|
|
166
|
+
|
|
167
|
+
return _run_json(cmd, stdin=QUERY)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def fetch_all(owner: str, repo: str, number: int) -> dict[str, Any]:
|
|
171
|
+
conversation_comments: list[dict[str, Any]] = []
|
|
172
|
+
reviews: list[dict[str, Any]] = []
|
|
173
|
+
review_threads: list[dict[str, Any]] = []
|
|
174
|
+
|
|
175
|
+
comments_cursor: str | None = None
|
|
176
|
+
reviews_cursor: str | None = None
|
|
177
|
+
threads_cursor: str | None = None
|
|
178
|
+
|
|
179
|
+
pr_meta: dict[str, Any] | None = None
|
|
180
|
+
|
|
181
|
+
while True:
|
|
182
|
+
payload = gh_api_graphql(
|
|
183
|
+
owner=owner,
|
|
184
|
+
repo=repo,
|
|
185
|
+
number=number,
|
|
186
|
+
comments_cursor=comments_cursor,
|
|
187
|
+
reviews_cursor=reviews_cursor,
|
|
188
|
+
threads_cursor=threads_cursor,
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
if "errors" in payload and payload["errors"]:
|
|
192
|
+
raise RuntimeError(f"GitHub GraphQL errors:\n{json.dumps(payload['errors'], indent=2)}")
|
|
193
|
+
|
|
194
|
+
pr = payload["data"]["repository"]["pullRequest"]
|
|
195
|
+
if pr_meta is None:
|
|
196
|
+
pr_meta = {
|
|
197
|
+
"number": pr["number"],
|
|
198
|
+
"url": pr["url"],
|
|
199
|
+
"title": pr["title"],
|
|
200
|
+
"state": pr["state"],
|
|
201
|
+
"owner": owner,
|
|
202
|
+
"repo": repo,
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
c = pr["comments"]
|
|
206
|
+
r = pr["reviews"]
|
|
207
|
+
t = pr["reviewThreads"]
|
|
208
|
+
|
|
209
|
+
conversation_comments.extend(c.get("nodes") or [])
|
|
210
|
+
reviews.extend(r.get("nodes") or [])
|
|
211
|
+
review_threads.extend(t.get("nodes") or [])
|
|
212
|
+
|
|
213
|
+
comments_cursor = c["pageInfo"]["endCursor"] if c["pageInfo"]["hasNextPage"] else None
|
|
214
|
+
reviews_cursor = r["pageInfo"]["endCursor"] if r["pageInfo"]["hasNextPage"] else None
|
|
215
|
+
threads_cursor = t["pageInfo"]["endCursor"] if t["pageInfo"]["hasNextPage"] else None
|
|
216
|
+
|
|
217
|
+
if not (comments_cursor or reviews_cursor or threads_cursor):
|
|
218
|
+
break
|
|
219
|
+
|
|
220
|
+
assert pr_meta is not None
|
|
221
|
+
return {
|
|
222
|
+
"pull_request": pr_meta,
|
|
223
|
+
"conversation_comments": conversation_comments,
|
|
224
|
+
"reviews": reviews,
|
|
225
|
+
"review_threads": review_threads,
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def main() -> None:
|
|
230
|
+
_ensure_gh_authenticated()
|
|
231
|
+
owner, repo, number = get_current_pr_ref()
|
|
232
|
+
result = fetch_all(owner, repo, number)
|
|
233
|
+
print(json.dumps(result, indent=2))
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
if __name__ == "__main__":
|
|
237
|
+
main()
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gh-fix-ci
|
|
3
|
+
description: Use when a user asks to diagnose or fix failing GitHub PR checks in GitHub Actions using gh CLI and logs.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
tags: [debugging, devops, git]
|
|
6
|
+
dependencies: []
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# gh-fix-ci
|
|
10
|
+
|
|
11
|
+
Diagnose failing PR checks, extract actionable logs, and propose focused fixes.
|
|
12
|
+
|
|
13
|
+
## When to Use
|
|
14
|
+
|
|
15
|
+
- User asks to fix failing GitHub PR checks
|
|
16
|
+
- CI failures are in GitHub Actions
|
|
17
|
+
|
|
18
|
+
## When NOT to Use
|
|
19
|
+
|
|
20
|
+
- Checks are from external providers (Buildkite/Circle/etc.) without actionable logs in GitHub
|
|
21
|
+
- No `gh` auth and user does not want to authenticate
|
|
22
|
+
|
|
23
|
+
## Workflow
|
|
24
|
+
|
|
25
|
+
1. Verify auth: `gh auth status`
|
|
26
|
+
2. Resolve PR (`gh pr view --json number,url`) or use provided PR number/URL
|
|
27
|
+
3. Run check inspector script
|
|
28
|
+
4. Summarize failing checks and log snippets
|
|
29
|
+
5. Propose fix plan and implement
|
|
30
|
+
6. Re-run relevant checks
|
|
31
|
+
|
|
32
|
+
## Script
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
python3 .opencode/skill/gh-fix-ci/scripts/inspect_pr_checks.py --repo . --pr 123
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Add `--json` for machine-friendly output.
|