opencodekit 0.20.8 → 0.21.1

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.
Files changed (48) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/template/.opencode/AGENTS.md +25 -1
  3. package/dist/template/.opencode/memory.db +0 -0
  4. package/dist/template/.opencode/memory.db-shm +0 -0
  5. package/dist/template/.opencode/memory.db-wal +0 -0
  6. package/dist/template/.opencode/opencode.json +83 -609
  7. package/dist/template/.opencode/opencodex-fast.jsonc +1 -1
  8. package/dist/template/.opencode/package.json +2 -2
  9. package/dist/template/.opencode/plugin/copilot-auth.ts +86 -12
  10. package/dist/template/.opencode/plugin/prompt-leverage.ts +191 -0
  11. package/dist/template/.opencode/plugin/sdk/copilot/copilot-provider.ts +14 -2
  12. package/dist/template/.opencode/plugin/sdk/copilot/index.ts +2 -2
  13. package/dist/template/.opencode/plugin/sdk/copilot/responses/convert-to-openai-responses-input.ts +335 -0
  14. package/dist/template/.opencode/plugin/sdk/copilot/responses/map-openai-responses-finish-reason.ts +22 -0
  15. package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-config.ts +18 -0
  16. package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-error.ts +22 -0
  17. package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-responses-api-types.ts +214 -0
  18. package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-responses-language-model.ts +1770 -0
  19. package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-responses-prepare-tools.ts +173 -0
  20. package/dist/template/.opencode/plugin/sdk/copilot/responses/openai-responses-settings.ts +1 -0
  21. package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/code-interpreter.ts +87 -0
  22. package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/file-search.ts +127 -0
  23. package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/image-generation.ts +114 -0
  24. package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/local-shell.ts +64 -0
  25. package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/web-search-preview.ts +103 -0
  26. package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/web-search.ts +102 -0
  27. package/dist/template/.opencode/skill/gh-address-comments/SKILL.md +29 -0
  28. package/dist/template/.opencode/skill/gh-address-comments/scripts/fetch_comments.py +237 -0
  29. package/dist/template/.opencode/skill/gh-fix-ci/SKILL.md +38 -0
  30. package/dist/template/.opencode/skill/gh-fix-ci/scripts/inspect_pr_checks.py +509 -0
  31. package/dist/template/.opencode/skill/prompt-leverage/SKILL.md +90 -0
  32. package/dist/template/.opencode/skill/prompt-leverage/references/framework.md +91 -0
  33. package/dist/template/.opencode/skill/prompt-leverage/scripts/augment_prompt.py +157 -0
  34. package/dist/template/.opencode/skill/screenshot/SKILL.md +48 -0
  35. package/dist/template/.opencode/skill/screenshot/scripts/ensure_macos_permissions.sh +54 -0
  36. package/dist/template/.opencode/skill/screenshot/scripts/macos_display_info.swift +22 -0
  37. package/dist/template/.opencode/skill/screenshot/scripts/macos_permissions.swift +40 -0
  38. package/dist/template/.opencode/skill/screenshot/scripts/macos_window_info.swift +126 -0
  39. package/dist/template/.opencode/skill/screenshot/scripts/take_screenshot.ps1 +163 -0
  40. package/dist/template/.opencode/skill/screenshot/scripts/take_screenshot.py +585 -0
  41. package/dist/template/.opencode/skill/security-threat-model/SKILL.md +36 -0
  42. package/dist/template/.opencode/skill/security-threat-model/references/prompt-template.md +255 -0
  43. package/dist/template/.opencode/skill/security-threat-model/references/security-controls-and-assets.md +32 -0
  44. package/dist/template/.opencode/skill/skill-installer/SKILL.md +58 -0
  45. package/dist/template/.opencode/skill/skill-installer/scripts/github_utils.py +21 -0
  46. package/dist/template/.opencode/skill/skill-installer/scripts/install-skill-from-github.py +313 -0
  47. package/dist/template/.opencode/skill/skill-installer/scripts/list-skills.py +106 -0
  48. package/package.json +1 -1
@@ -0,0 +1,102 @@
1
+ import { createProviderToolFactory } from "@ai-sdk/provider-utils"
2
+ import { z } from "zod/v4"
3
+
4
+ export const webSearchArgsSchema = z.object({
5
+ filters: z
6
+ .object({
7
+ allowedDomains: z.array(z.string()).optional(),
8
+ })
9
+ .optional(),
10
+
11
+ searchContextSize: z.enum(["low", "medium", "high"]).optional(),
12
+
13
+ userLocation: z
14
+ .object({
15
+ type: z.literal("approximate"),
16
+ country: z.string().optional(),
17
+ city: z.string().optional(),
18
+ region: z.string().optional(),
19
+ timezone: z.string().optional(),
20
+ })
21
+ .optional(),
22
+ })
23
+
24
+ export const webSearchToolFactory = createProviderToolFactory<
25
+ {
26
+ // Web search doesn't take input parameters - it's controlled by the prompt
27
+ },
28
+ {
29
+ /**
30
+ * Filters for the search.
31
+ */
32
+ filters?: {
33
+ /**
34
+ * Allowed domains for the search.
35
+ * If not provided, all domains are allowed.
36
+ * Subdomains of the provided domains are allowed as well.
37
+ */
38
+ allowedDomains?: string[]
39
+ }
40
+
41
+ /**
42
+ * Search context size to use for the web search.
43
+ * - high: Most comprehensive context, highest cost, slower response
44
+ * - medium: Balanced context, cost, and latency (default)
45
+ * - low: Least context, lowest cost, fastest response
46
+ */
47
+ searchContextSize?: "low" | "medium" | "high"
48
+
49
+ /**
50
+ * User location information to provide geographically relevant search results.
51
+ */
52
+ userLocation?: {
53
+ /**
54
+ * Type of location (always 'approximate')
55
+ */
56
+ type: "approximate"
57
+ /**
58
+ * Two-letter ISO country code (e.g., 'US', 'GB')
59
+ */
60
+ country?: string
61
+ /**
62
+ * City name (free text, e.g., 'Minneapolis')
63
+ */
64
+ city?: string
65
+ /**
66
+ * Region name (free text, e.g., 'Minnesota')
67
+ */
68
+ region?: string
69
+ /**
70
+ * IANA timezone (e.g., 'America/Chicago')
71
+ */
72
+ timezone?: string
73
+ }
74
+ }
75
+ >({
76
+ id: "openai.web_search",
77
+ inputSchema: z.object({
78
+ action: z
79
+ .discriminatedUnion("type", [
80
+ z.object({
81
+ type: z.literal("search"),
82
+ query: z.string().nullish(),
83
+ }),
84
+ z.object({
85
+ type: z.literal("open_page"),
86
+ url: z.string(),
87
+ }),
88
+ z.object({
89
+ type: z.literal("find"),
90
+ url: z.string(),
91
+ pattern: z.string(),
92
+ }),
93
+ ])
94
+ .nullish(),
95
+ }),
96
+ })
97
+
98
+ export const webSearch = (
99
+ args: Parameters<typeof webSearchToolFactory>[0] = {}, // default
100
+ ) => {
101
+ return webSearchToolFactory(args)
102
+ }
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: gh-address-comments
3
+ description: Use when the user asks to review and address GitHub PR comments/threads for the current branch using gh CLI.
4
+ version: 1.0.0
5
+ tags: [workflow, git, agent-coordination]
6
+ dependencies: []
7
+ ---
8
+
9
+ # gh-address-comments
10
+
11
+ Fetch PR comments and review threads, then apply selected fixes.
12
+
13
+ ## When to Use
14
+
15
+ - User asks to resolve PR review comments
16
+ - User wants a numbered list of comment threads to triage
17
+
18
+ ## When NOT to Use
19
+
20
+ - No open PR associated with current branch
21
+ - `gh` is unavailable/auth is missing and user declines auth
22
+
23
+ ## Workflow
24
+
25
+ 1. Check auth: `gh auth status`
26
+ 2. Fetch comments: `python3 .opencode/skill/gh-address-comments/scripts/fetch_comments.py`
27
+ 3. Present numbered comment threads with short fix summaries
28
+ 4. Ask which comments to address
29
+ 5. Implement only selected fixes and report results
@@ -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.