@xiaotianxt/skills 0.1.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/EXCLUDED.md +42 -0
- package/LICENSE +21 -0
- package/README.md +165 -0
- package/SECURITY.md +23 -0
- package/SOURCES.md +45 -0
- package/bin/skills.mjs +241 -0
- package/package.json +38 -0
- package/skills/1password/SKILL.md +94 -0
- package/skills/1password/agents/openai.yaml +4 -0
- package/skills/1password/references/item-management.md +80 -0
- package/skills/1password/references/op-cli.md +107 -0
- package/skills/apple-calendar-event/SKILL.md +81 -0
- package/skills/apple-calendar-event/agents/openai.yaml +4 -0
- package/skills/apple-calendar-event/scripts/calendar_audit.py +201 -0
- package/skills/apple-calendar-event/scripts/calendar_event.py +164 -0
- package/skills/bro-browser/SKILL.md +118 -0
- package/skills/bro-browser/agents/openai.yaml +4 -0
- package/skills/bro-browser/references/tool-map.md +102 -0
- package/skills/bro-browser/references/workflows.md +146 -0
- package/skills/bro-browser/scripts/bro-call.mjs +189 -0
- package/skills/calendar/SKILL.md +182 -0
- package/skills/calendar/agents/openai.yaml +4 -0
- package/skills/calendar/references/operations.md +255 -0
- package/skills/calendar/scripts/calendar_list_review.py +157 -0
- package/skills/calendar/scripts/event_dedupe_preview.py +155 -0
- package/skills/canvas/SKILL.md +70 -0
- package/skills/canvas/agents/openai.yaml +4 -0
- package/skills/canvas/references/canvas-api.md +76 -0
- package/skills/course-exam-review-planner/SKILL.md +127 -0
- package/skills/cx/SKILL.md +25 -0
- package/skills/gh-fix-ci/LICENSE.txt +201 -0
- package/skills/gh-fix-ci/SKILL.md +81 -0
- package/skills/gh-fix-ci/agents/openai.yaml +6 -0
- package/skills/gh-fix-ci/assets/github-small.svg +3 -0
- package/skills/gh-fix-ci/assets/github.png +0 -0
- package/skills/gh-fix-ci/scripts/inspect_pr_checks.py +509 -0
- package/skills/gh-review-workflow/SKILL.md +61 -0
- package/skills/gh-review-workflow/agents/openai.yaml +4 -0
- package/skills/gh-review-workflow/references/workflow.md +48 -0
- package/skills/gh-review-workflow/scripts/fetch_review_state.py +222 -0
- package/skills/gh-review-workflow/scripts/resolve_review_threads.py +83 -0
- package/skills/github/SKILL.md +74 -0
- package/skills/github/agents/openai.yaml +6 -0
- package/skills/github/assets/github-small.svg +3 -0
- package/skills/github/assets/github.png +0 -0
- package/skills/gws-calendar/SKILL.md +126 -0
- package/skills/gws-calendar-agenda/SKILL.md +52 -0
- package/skills/gws-calendar-insert/SKILL.md +66 -0
- package/skills/gws-docs/SKILL.md +48 -0
- package/skills/gws-docs-write/SKILL.md +49 -0
- package/skills/gws-drive/SKILL.md +137 -0
- package/skills/gws-drive-upload/SKILL.md +52 -0
- package/skills/gws-gmail/SKILL.md +62 -0
- package/skills/gws-gmail-forward/SKILL.md +55 -0
- package/skills/gws-gmail-reply/SKILL.md +58 -0
- package/skills/gws-gmail-reply-all/SKILL.md +62 -0
- package/skills/gws-gmail-send/SKILL.md +57 -0
- package/skills/gws-gmail-triage/SKILL.md +50 -0
- package/skills/gws-gmail-watch/SKILL.md +58 -0
- package/skills/gws-shared/SKILL.md +27 -0
- package/skills/helium-browser-mcp/SKILL.md +137 -0
- package/skills/helium-browser-mcp/agents/openai.yaml +4 -0
- package/skills/helium-browser-mcp/scripts/obmcp.mjs +92 -0
- package/skills/helium-browser-mcp/scripts/openbrowsermcp-stdio-proxy.mjs +170 -0
- package/skills/learn/SKILL.md +122 -0
- package/skills/learn/agents/openai.yaml +7 -0
- package/skills/learn/assets/AGENTS.template.md +33 -0
- package/skills/learn/assets/errorlog.template.typ +61 -0
- package/skills/learn/assets/reading-sequence.template.md +23 -0
- package/skills/learn/assets/source-index.template.md +17 -0
- package/skills/learn/assets/tasklog.template.typ +57 -0
- package/skills/learn/assets/workbook.template.typ +60 -0
- package/skills/learn/references/learning-science.md +103 -0
- package/skills/learn/scripts/init_learning_workspace.py +70 -0
- package/skills/macos-messages/SKILL.md +258 -0
- package/skills/memory/SKILL.md +33 -0
- package/skills/memory/codex.md +186 -0
- package/skills/memory/opencode.md +164 -0
- package/skills/mimestreamctl/SKILL.md +170 -0
- package/skills/mimestreamctl/agents/openai.yaml +4 -0
- package/skills/mimestreamctl/scripts/mimestreamctl +33 -0
- package/skills/mon/SKILL.md +51 -0
- package/skills/mon/scripts/mon_spend_review.py +458 -0
- package/skills/ocr/SKILL.md +136 -0
- package/skills/ocr/agents/openai.yaml +4 -0
- package/skills/ocr/references/local-ocr-best-practices.md +297 -0
- package/skills/ocr/references/mineru-api.md +159 -0
- package/skills/ocr/scripts/ocr-router +22 -0
- package/skills/ocr/scripts/ocr_router.py +741 -0
- package/skills/panopto-mp4-bulk-download/SKILL.md +57 -0
- package/skills/panopto-mp4-bulk-download/agents/openai.yaml +4 -0
- package/skills/panopto-mp4-bulk-download/references/url-patterns.md +26 -0
- package/skills/panopto-mp4-bulk-download/scripts/panopto_bulk_mp4.sh +213 -0
- package/skills/rust-systems-style/SKILL.md +109 -0
- package/skills/rust-systems-style/agents/openai.yaml +4 -0
- package/skills/rust-systems-style/references/rust-review-checklist.md +77 -0
- package/skills/rust-systems-style/references/style-sources.md +68 -0
- package/skills/ship-ai-native-cli/SKILL.md +76 -0
- package/skills/ship-ai-native-cli/agents/openai.yaml +4 -0
- package/skills/ship-ai-native-cli/references/case-notes.md +83 -0
- package/skills/ship-ai-native-cli/references/product-method.md +82 -0
- package/skills/ship-ai-native-cli/references/release-checklist.md +147 -0
- package/skills/ship-ai-native-cli/references/rust-cli-shape.md +111 -0
- package/skills/telegram-mtproto-session/SKILL.md +125 -0
- package/skills/telegram-mtproto-session/agents/openai.yaml +4 -0
- package/skills/telegram-mtproto-session/scripts/telegram_session.py +687 -0
- package/skills/tg/SKILL.md +173 -0
- package/skills/things3-manager/SKILL.md +116 -0
- package/skills/things3-manager/scripts/things +42 -0
- package/skills/things3-manager/scripts/things_cli.py +514 -0
- package/skills/web-artifacts-builder/LICENSE.txt +202 -0
- package/skills/web-artifacts-builder/SKILL.md +74 -0
- package/skills/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/skills/web-artifacts-builder/scripts/init-artifact.sh +379 -0
- package/skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/skills/yeet/LICENSE.txt +201 -0
- package/skills/yeet/SKILL.md +71 -0
- package/skills/yeet/agents/openai.yaml +6 -0
- package/skills/yeet/assets/yeet-small.svg +3 -0
- package/skills/yeet/assets/yeet.png +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Review Workflow Reference
|
|
2
|
+
|
|
3
|
+
## Tool split
|
|
4
|
+
|
|
5
|
+
- Use GitHub metadata tools for:
|
|
6
|
+
- latest PR lookup
|
|
7
|
+
- PR title, state, branch mapping
|
|
8
|
+
- top-level PR comments
|
|
9
|
+
- Use `gh api graphql` for:
|
|
10
|
+
- inline review threads
|
|
11
|
+
- `isResolved`
|
|
12
|
+
- `isOutdated`
|
|
13
|
+
- thread file and line anchors
|
|
14
|
+
- resolving review threads
|
|
15
|
+
|
|
16
|
+
## Minimal workflow
|
|
17
|
+
|
|
18
|
+
1. Resolve the PR:
|
|
19
|
+
- explicit repo plus PR number if provided
|
|
20
|
+
- otherwise current branch PR through `gh pr view`
|
|
21
|
+
2. Fetch review state:
|
|
22
|
+
- `python3 ~/.codex/skills/gh-review-workflow/scripts/fetch_review_state.py`
|
|
23
|
+
3. Read these sections in order:
|
|
24
|
+
- `review_threads`
|
|
25
|
+
- `reviews`
|
|
26
|
+
- `conversation_comments`
|
|
27
|
+
4. Collapse duplicates:
|
|
28
|
+
- many inline comments may represent one shared design concern
|
|
29
|
+
5. After code changes:
|
|
30
|
+
- verify locally
|
|
31
|
+
- push
|
|
32
|
+
- resolve the addressed threads if the user asked
|
|
33
|
+
|
|
34
|
+
## Response shape
|
|
35
|
+
|
|
36
|
+
- Start with actionable findings.
|
|
37
|
+
- Mention file or behavior area.
|
|
38
|
+
- State which threads are already outdated.
|
|
39
|
+
- Distinguish:
|
|
40
|
+
- must fix
|
|
41
|
+
- reasonable suggestion
|
|
42
|
+
- explanation only
|
|
43
|
+
|
|
44
|
+
## Common pitfalls
|
|
45
|
+
|
|
46
|
+
- Looking only at top-level PR comments misses most real review feedback.
|
|
47
|
+
- `get_pull_request_reviews` style data may be incomplete for thread state; always verify with GraphQL thread reads.
|
|
48
|
+
- Resolving threads before pushing verified fixes makes the PR history confusing.
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Fetch PR comments, reviews, and inline review threads from GitHub."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import argparse
|
|
7
|
+
import json
|
|
8
|
+
import subprocess
|
|
9
|
+
import sys
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
QUERY = """\
|
|
13
|
+
query(
|
|
14
|
+
$owner: String!,
|
|
15
|
+
$repo: String!,
|
|
16
|
+
$number: Int!,
|
|
17
|
+
$commentsCursor: String,
|
|
18
|
+
$reviewsCursor: String,
|
|
19
|
+
$threadsCursor: String
|
|
20
|
+
) {
|
|
21
|
+
repository(owner: $owner, name: $repo) {
|
|
22
|
+
pullRequest(number: $number) {
|
|
23
|
+
number
|
|
24
|
+
url
|
|
25
|
+
title
|
|
26
|
+
state
|
|
27
|
+
comments(first: 100, after: $commentsCursor) {
|
|
28
|
+
pageInfo { hasNextPage endCursor }
|
|
29
|
+
nodes {
|
|
30
|
+
id
|
|
31
|
+
body
|
|
32
|
+
createdAt
|
|
33
|
+
updatedAt
|
|
34
|
+
author { login }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
reviews(first: 100, after: $reviewsCursor) {
|
|
38
|
+
pageInfo { hasNextPage endCursor }
|
|
39
|
+
nodes {
|
|
40
|
+
id
|
|
41
|
+
state
|
|
42
|
+
body
|
|
43
|
+
submittedAt
|
|
44
|
+
author { login }
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
reviewThreads(first: 100, after: $threadsCursor) {
|
|
48
|
+
pageInfo { hasNextPage endCursor }
|
|
49
|
+
nodes {
|
|
50
|
+
id
|
|
51
|
+
isResolved
|
|
52
|
+
isOutdated
|
|
53
|
+
path
|
|
54
|
+
line
|
|
55
|
+
diffSide
|
|
56
|
+
startLine
|
|
57
|
+
startDiffSide
|
|
58
|
+
originalLine
|
|
59
|
+
originalStartLine
|
|
60
|
+
resolvedBy { login }
|
|
61
|
+
comments(first: 100) {
|
|
62
|
+
nodes {
|
|
63
|
+
id
|
|
64
|
+
body
|
|
65
|
+
createdAt
|
|
66
|
+
updatedAt
|
|
67
|
+
author { login }
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _run(cmd: list[str], stdin: str | None = None) -> str:
|
|
79
|
+
proc = subprocess.run(cmd, input=stdin, capture_output=True, text=True)
|
|
80
|
+
if proc.returncode != 0:
|
|
81
|
+
raise RuntimeError(proc.stderr.strip() or "command failed")
|
|
82
|
+
return proc.stdout
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _run_json(cmd: list[str], stdin: str | None = None) -> dict[str, Any]:
|
|
86
|
+
return json.loads(_run(cmd, stdin=stdin))
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _ensure_auth() -> None:
|
|
90
|
+
try:
|
|
91
|
+
_run(["gh", "auth", "status"])
|
|
92
|
+
except RuntimeError as exc:
|
|
93
|
+
raise RuntimeError("gh auth is required; run `gh auth status` / `gh auth login`") from exc
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _current_branch_pr() -> tuple[str, str, int]:
|
|
97
|
+
pr = _run_json(
|
|
98
|
+
[
|
|
99
|
+
"gh",
|
|
100
|
+
"pr",
|
|
101
|
+
"view",
|
|
102
|
+
"--json",
|
|
103
|
+
"number,headRepositoryOwner,headRepository",
|
|
104
|
+
]
|
|
105
|
+
)
|
|
106
|
+
owner = pr["headRepositoryOwner"]["login"]
|
|
107
|
+
repo = pr["headRepository"]["name"]
|
|
108
|
+
number = int(pr["number"])
|
|
109
|
+
return owner, repo, number
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _fetch_page(
|
|
113
|
+
owner: str,
|
|
114
|
+
repo: str,
|
|
115
|
+
number: int,
|
|
116
|
+
comments_cursor: str | None,
|
|
117
|
+
reviews_cursor: str | None,
|
|
118
|
+
threads_cursor: str | None,
|
|
119
|
+
) -> dict[str, Any]:
|
|
120
|
+
cmd = [
|
|
121
|
+
"gh",
|
|
122
|
+
"api",
|
|
123
|
+
"graphql",
|
|
124
|
+
"-F",
|
|
125
|
+
"query=@-",
|
|
126
|
+
"-F",
|
|
127
|
+
f"owner={owner}",
|
|
128
|
+
"-F",
|
|
129
|
+
f"repo={repo}",
|
|
130
|
+
"-F",
|
|
131
|
+
f"number={number}",
|
|
132
|
+
]
|
|
133
|
+
if comments_cursor:
|
|
134
|
+
cmd += ["-F", f"commentsCursor={comments_cursor}"]
|
|
135
|
+
if reviews_cursor:
|
|
136
|
+
cmd += ["-F", f"reviewsCursor={reviews_cursor}"]
|
|
137
|
+
if threads_cursor:
|
|
138
|
+
cmd += ["-F", f"threadsCursor={threads_cursor}"]
|
|
139
|
+
return _run_json(cmd, stdin=QUERY)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _fetch_all(owner: str, repo: str, number: int) -> dict[str, Any]:
|
|
143
|
+
conversation_comments: list[dict[str, Any]] = []
|
|
144
|
+
reviews: list[dict[str, Any]] = []
|
|
145
|
+
review_threads: list[dict[str, Any]] = []
|
|
146
|
+
comments_cursor = None
|
|
147
|
+
reviews_cursor = None
|
|
148
|
+
threads_cursor = None
|
|
149
|
+
pull_request = None
|
|
150
|
+
|
|
151
|
+
while True:
|
|
152
|
+
payload = _fetch_page(
|
|
153
|
+
owner,
|
|
154
|
+
repo,
|
|
155
|
+
number,
|
|
156
|
+
comments_cursor,
|
|
157
|
+
reviews_cursor,
|
|
158
|
+
threads_cursor,
|
|
159
|
+
)
|
|
160
|
+
errors = payload.get("errors")
|
|
161
|
+
if errors:
|
|
162
|
+
raise RuntimeError(json.dumps(errors, indent=2))
|
|
163
|
+
|
|
164
|
+
pr = payload["data"]["repository"]["pullRequest"]
|
|
165
|
+
if pull_request is None:
|
|
166
|
+
pull_request = {
|
|
167
|
+
"number": pr["number"],
|
|
168
|
+
"url": pr["url"],
|
|
169
|
+
"title": pr["title"],
|
|
170
|
+
"state": pr["state"],
|
|
171
|
+
"owner": owner,
|
|
172
|
+
"repo": repo,
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
comments = pr["comments"]
|
|
176
|
+
review_list = pr["reviews"]
|
|
177
|
+
threads = pr["reviewThreads"]
|
|
178
|
+
conversation_comments.extend(comments.get("nodes") or [])
|
|
179
|
+
reviews.extend(review_list.get("nodes") or [])
|
|
180
|
+
review_threads.extend(threads.get("nodes") or [])
|
|
181
|
+
|
|
182
|
+
comments_cursor = comments["pageInfo"]["endCursor"] if comments["pageInfo"]["hasNextPage"] else None
|
|
183
|
+
reviews_cursor = review_list["pageInfo"]["endCursor"] if review_list["pageInfo"]["hasNextPage"] else None
|
|
184
|
+
threads_cursor = threads["pageInfo"]["endCursor"] if threads["pageInfo"]["hasNextPage"] else None
|
|
185
|
+
if not (comments_cursor or reviews_cursor or threads_cursor):
|
|
186
|
+
break
|
|
187
|
+
|
|
188
|
+
return {
|
|
189
|
+
"pull_request": pull_request,
|
|
190
|
+
"conversation_comments": conversation_comments,
|
|
191
|
+
"reviews": reviews,
|
|
192
|
+
"review_threads": review_threads,
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def main() -> int:
|
|
197
|
+
parser = argparse.ArgumentParser()
|
|
198
|
+
parser.add_argument("--owner")
|
|
199
|
+
parser.add_argument("--repo")
|
|
200
|
+
parser.add_argument("--number", type=int)
|
|
201
|
+
args = parser.parse_args()
|
|
202
|
+
|
|
203
|
+
_ensure_auth()
|
|
204
|
+
if args.owner or args.repo or args.number:
|
|
205
|
+
if not (args.owner and args.repo and args.number):
|
|
206
|
+
raise RuntimeError("pass --owner, --repo, and --number together")
|
|
207
|
+
owner, repo, number = args.owner, args.repo, args.number
|
|
208
|
+
else:
|
|
209
|
+
owner, repo, number = _current_branch_pr()
|
|
210
|
+
|
|
211
|
+
result = _fetch_all(owner, repo, number)
|
|
212
|
+
json.dump(result, sys.stdout, indent=2)
|
|
213
|
+
sys.stdout.write("\n")
|
|
214
|
+
return 0
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
if __name__ == "__main__":
|
|
218
|
+
try:
|
|
219
|
+
raise SystemExit(main())
|
|
220
|
+
except RuntimeError as exc:
|
|
221
|
+
print(str(exc), file=sys.stderr)
|
|
222
|
+
raise SystemExit(1)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Resolve GitHub PR review threads by id or from a saved review-state JSON dump."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import argparse
|
|
7
|
+
import json
|
|
8
|
+
import subprocess
|
|
9
|
+
import sys
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
MUTATION = """\
|
|
13
|
+
mutation($threadId: ID!) {
|
|
14
|
+
resolveReviewThread(input: {threadId: $threadId}) {
|
|
15
|
+
thread {
|
|
16
|
+
id
|
|
17
|
+
isResolved
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _run(cmd: list[str], stdin: str | None = None) -> str:
|
|
25
|
+
proc = subprocess.run(cmd, input=stdin, capture_output=True, text=True)
|
|
26
|
+
if proc.returncode != 0:
|
|
27
|
+
raise RuntimeError(proc.stderr.strip() or "command failed")
|
|
28
|
+
return proc.stdout
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _thread_ids_from_json(path: Path) -> list[str]:
|
|
32
|
+
data = json.loads(path.read_text())
|
|
33
|
+
ids = []
|
|
34
|
+
for thread in data.get("review_threads", []):
|
|
35
|
+
if not thread.get("isResolved"):
|
|
36
|
+
ids.append(thread["id"])
|
|
37
|
+
return ids
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _resolve(thread_id: str) -> dict[str, object]:
|
|
41
|
+
payload = _run(
|
|
42
|
+
[
|
|
43
|
+
"gh",
|
|
44
|
+
"api",
|
|
45
|
+
"graphql",
|
|
46
|
+
"-f",
|
|
47
|
+
f"query={MUTATION}",
|
|
48
|
+
"-F",
|
|
49
|
+
f"threadId={thread_id}",
|
|
50
|
+
]
|
|
51
|
+
)
|
|
52
|
+
return json.loads(payload)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def main() -> int:
|
|
56
|
+
parser = argparse.ArgumentParser()
|
|
57
|
+
parser.add_argument("thread_ids", nargs="*")
|
|
58
|
+
parser.add_argument("--from-json", type=Path)
|
|
59
|
+
args = parser.parse_args()
|
|
60
|
+
|
|
61
|
+
thread_ids = list(args.thread_ids)
|
|
62
|
+
if args.from_json is not None:
|
|
63
|
+
thread_ids.extend(_thread_ids_from_json(args.from_json))
|
|
64
|
+
if not thread_ids:
|
|
65
|
+
raise RuntimeError("provide thread ids or --from-json")
|
|
66
|
+
|
|
67
|
+
seen = set()
|
|
68
|
+
for thread_id in thread_ids:
|
|
69
|
+
if thread_id in seen:
|
|
70
|
+
continue
|
|
71
|
+
seen.add(thread_id)
|
|
72
|
+
result = _resolve(thread_id)
|
|
73
|
+
json.dump(result, sys.stdout)
|
|
74
|
+
sys.stdout.write("\n")
|
|
75
|
+
return 0
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
if __name__ == "__main__":
|
|
79
|
+
try:
|
|
80
|
+
raise SystemExit(main())
|
|
81
|
+
except RuntimeError as exc:
|
|
82
|
+
print(str(exc), file=sys.stderr)
|
|
83
|
+
raise SystemExit(1)
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: github
|
|
3
|
+
description: Triage and orient GitHub repository, pull request, and issue work through local GitHub MCP tools and the `gh` CLI. Use when the user asks for general GitHub help, wants PR or issue summaries, or needs repository context before choosing a more specific GitHub workflow.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# GitHub
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Use this skill as the umbrella entrypoint for general GitHub work. It should decide whether the task stays in repo and PR triage or should be handed off to a more specific review, CI, or publish workflow.
|
|
11
|
+
|
|
12
|
+
This workflow is intentionally hybrid:
|
|
13
|
+
|
|
14
|
+
- Prefer local GitHub MCP tools for repository, issue, pull request, comment, label, reaction, and PR creation workflows.
|
|
15
|
+
- Use local `git` and `gh` only when the connector does not cover the job well, especially for current-branch PR discovery, branch creation, commit and push, `gh auth status`, and GitHub Actions log inspection.
|
|
16
|
+
- Keep connector state and local checkout context aligned. If the request is about the current branch, resolve the local repo and branch before acting.
|
|
17
|
+
|
|
18
|
+
Once the intent is clear, route to the specialist skill immediately and do not keep broad GitHub triage in scope longer than needed.
|
|
19
|
+
|
|
20
|
+
## Connector-First Responsibilities
|
|
21
|
+
|
|
22
|
+
Handle these directly in this skill when the request does not need a narrower specialist workflow:
|
|
23
|
+
|
|
24
|
+
- repository orientation once the repo, PR, issue, or local checkout is identified
|
|
25
|
+
- recent PR or issue triage
|
|
26
|
+
- PR metadata summaries
|
|
27
|
+
- PR patch inspection
|
|
28
|
+
- PR comments, labels, and reactions
|
|
29
|
+
- issue lookup and summarization
|
|
30
|
+
- PR creation after a branch is already pushed
|
|
31
|
+
|
|
32
|
+
Prefer GitHub MCP tools for those flows because they provide structured PR, issue, and review-adjacent data without depending on a local checkout. If the repository is not already identifiable from the user request or local git context, ask for the repo instead of pretending there is a repo-search flow that may not exist.
|
|
33
|
+
|
|
34
|
+
## Routing Rules
|
|
35
|
+
|
|
36
|
+
1. Resolve the operating context first:
|
|
37
|
+
- If the user provides a repository, PR number, issue number, or URL, use that.
|
|
38
|
+
- If the request is about "this branch" or "the current PR", resolve local git context and use `gh` only as needed to discover the branch PR.
|
|
39
|
+
- If the repository is still ambiguous after local inspection, ask for the repo identifier.
|
|
40
|
+
2. Classify the request before taking action:
|
|
41
|
+
- `repo or PR triage`: summarize PRs, issues, patches, comments, labels, reactions, or repository state
|
|
42
|
+
- `review follow-up`: unresolved review threads, requested changes, or inline review feedback
|
|
43
|
+
- `CI debugging`: failing checks, Actions logs, or CI root-cause analysis
|
|
44
|
+
- `publish changes`: create or switch branches, stage changes, commit, push, and open a draft PR
|
|
45
|
+
3. Route to the specialist skill as soon as the category is clear:
|
|
46
|
+
- Review comments and requested changes: `../gh-review-workflow/SKILL.md`
|
|
47
|
+
- Failing GitHub Actions checks: `../gh-fix-ci/SKILL.md`
|
|
48
|
+
- Commit, push, and open PR: `../yeet/SKILL.md`
|
|
49
|
+
4. Keep the hybrid model consistent after routing:
|
|
50
|
+
- GitHub MCP first for PR and issue data
|
|
51
|
+
- local `git` and `gh` only for the specific gaps the connector does not cover
|
|
52
|
+
|
|
53
|
+
## Default Workflow
|
|
54
|
+
|
|
55
|
+
1. Resolve repository and item scope.
|
|
56
|
+
2. Gather structured PR or issue context through GitHub MCP tools.
|
|
57
|
+
3. Decide whether the task stays in connector-backed triage or needs a specialist skill.
|
|
58
|
+
4. Route immediately when the work becomes review follow-up, CI debugging, or publish workflow.
|
|
59
|
+
5. End with a clear summary of what was inspected, what changed, and what remains.
|
|
60
|
+
|
|
61
|
+
## Output Expectations
|
|
62
|
+
|
|
63
|
+
- For triage requests, return a concise summary of the repository, PR, or issue state and the next likely action.
|
|
64
|
+
- For mixed requests, tell the user which specialist path you are taking and why.
|
|
65
|
+
- For GitHub MCP write actions, restate the exact PR, issue, label, or reaction target before applying the change.
|
|
66
|
+
- Never imply that GitHub Actions logs are available through GitHub MCP alone. That remains a `gh` workflow.
|
|
67
|
+
|
|
68
|
+
## Examples
|
|
69
|
+
|
|
70
|
+
- "Use GitHub to summarize the open PRs in this repo and tell me what needs attention."
|
|
71
|
+
- "Help with this PR."
|
|
72
|
+
- "Review the latest comments on PR 482 and tell me what is actionable."
|
|
73
|
+
- "Debug the failing checks on this branch."
|
|
74
|
+
- "Commit these changes, push them, and open a draft PR."
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "GitHub"
|
|
3
|
+
short_description: "Inspect PRs, issues, CI, and publish flows"
|
|
4
|
+
icon_small: "./assets/github-small.svg"
|
|
5
|
+
icon_large: "./assets/github.png"
|
|
6
|
+
default_prompt: "Use $github to inspect pull requests and issues, orient the repository context, and choose the right GitHub workflow."
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
|
2
|
+
<path fill="currentColor" d="M8 1.3a6.665 6.665 0 0 1 5.413 10.56 6.677 6.677 0 0 1-3.288 2.432c-.333.067-.458-.142-.458-.316 0-.226.008-.942.008-1.834 0-.625-.208-1.025-.45-1.233 1.483-.167 3.042-.734 3.042-3.292a2.58 2.58 0 0 0-.684-1.792c.067-.166.3-.85-.066-1.766 0 0-.559-.184-1.834.683a6.186 6.186 0 0 0-1.666-.225c-.567 0-1.134.075-1.667.225-1.275-.858-1.833-.683-1.833-.683-.367.916-.134 1.6-.067 1.766a2.594 2.594 0 0 0-.683 1.792c0 2.55 1.55 3.125 3.033 3.292-.192.166-.367.458-.425.891-.383.175-1.342.459-1.942-.55-.125-.2-.5-.691-1.025-.683-.558.008-.225.317.009.442.283.158.608.75.683.941.133.376.567 1.092 2.242.784 0 .558.008 1.083.008 1.242 0 .174-.125.374-.458.316a6.662 6.662 0 0 1-4.559-6.325A6.665 6.665 0 0 1 8 1.3Z"/>
|
|
3
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gws-calendar
|
|
3
|
+
description: "Google Calendar: Manage calendars and events."
|
|
4
|
+
metadata:
|
|
5
|
+
openclaw:
|
|
6
|
+
category: "productivity"
|
|
7
|
+
requires:
|
|
8
|
+
bins: ["gws"]
|
|
9
|
+
cliHelp: "gws calendar --help"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# calendar (v3)
|
|
13
|
+
|
|
14
|
+
> **PREREQUISITE:** Read `../gws-shared/SKILL.md` for auth, global flags, and security rules. If missing, run `gws generate-skills` to create it.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
gws calendar <resource> <method> [flags]
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## User Calendar Policy
|
|
21
|
+
|
|
22
|
+
- Treat Google Calendar as the durable source of truth for user events.
|
|
23
|
+
- For this user's current setup, prefer `tianyupeiandy@gmail.com` as the default personal write calendar when the user does not specify another calendar.
|
|
24
|
+
- Verify the active account before writes:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
gws auth status
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
- List calendar IDs before cleanup, migration, or writes in multi-account contexts:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
gws calendar calendarList list --params '{"showHidden":true,"maxResults":250}'
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
- Use stable calendar IDs, not display names, when names may be duplicated. Apple Calendar can show multiple calendars with the same name from different stores.
|
|
37
|
+
- Treat school calendars such as `yupeit@andrew.cmu.edu` as transition sources unless the user explicitly asks to write there.
|
|
38
|
+
- Do not fall back to Apple Calendar for writes unless the user explicitly asks for Apple Calendar.
|
|
39
|
+
|
|
40
|
+
## Helper Commands
|
|
41
|
+
|
|
42
|
+
| Command | Description |
|
|
43
|
+
|---------|-------------|
|
|
44
|
+
| [`+insert`](../gws-calendar-insert/SKILL.md) | create a new event |
|
|
45
|
+
| [`+agenda`](../gws-calendar-agenda/SKILL.md) | Show upcoming events across all calendars |
|
|
46
|
+
|
|
47
|
+
## API Resources
|
|
48
|
+
|
|
49
|
+
### acl
|
|
50
|
+
|
|
51
|
+
- `delete` — Deletes an access control rule.
|
|
52
|
+
- `get` — Returns an access control rule.
|
|
53
|
+
- `insert` — Creates an access control rule.
|
|
54
|
+
- `list` — Returns the rules in the access control list for the calendar.
|
|
55
|
+
- `patch` — Updates an access control rule. This method supports patch semantics.
|
|
56
|
+
- `update` — Updates an access control rule.
|
|
57
|
+
- `watch` — Watch for changes to ACL resources.
|
|
58
|
+
|
|
59
|
+
### calendarList
|
|
60
|
+
|
|
61
|
+
- `delete` — Removes a calendar from the user's calendar list.
|
|
62
|
+
- `get` — Returns a calendar from the user's calendar list.
|
|
63
|
+
- `insert` — Inserts an existing calendar into the user's calendar list.
|
|
64
|
+
- `list` — Returns the calendars on the user's calendar list.
|
|
65
|
+
- `patch` — Updates an existing calendar on the user's calendar list. This method supports patch semantics.
|
|
66
|
+
- `update` — Updates an existing calendar on the user's calendar list.
|
|
67
|
+
- `watch` — Watch for changes to CalendarList resources.
|
|
68
|
+
|
|
69
|
+
### calendars
|
|
70
|
+
|
|
71
|
+
- `clear` — Clears a primary calendar. This operation deletes all events associated with the primary calendar of an account.
|
|
72
|
+
- `delete` — Deletes a secondary calendar. Use calendars.clear for clearing all events on primary calendars.
|
|
73
|
+
- `get` — Returns metadata for a calendar.
|
|
74
|
+
- `insert` — Creates a secondary calendar.
|
|
75
|
+
The authenticated user for the request is made the data owner of the new calendar.
|
|
76
|
+
|
|
77
|
+
Note: We recommend to authenticate as the intended data owner of the calendar. You can use domain-wide delegation of authority to allow applications to act on behalf of a specific user. Don't use a service account for authentication. If you use a service account for authentication, the service account is the data owner, which can lead to unexpected behavior.
|
|
78
|
+
- `patch` — Updates metadata for a calendar. This method supports patch semantics.
|
|
79
|
+
- `update` — Updates metadata for a calendar.
|
|
80
|
+
|
|
81
|
+
### channels
|
|
82
|
+
|
|
83
|
+
- `stop` — Stop watching resources through this channel
|
|
84
|
+
|
|
85
|
+
### colors
|
|
86
|
+
|
|
87
|
+
- `get` — Returns the color definitions for calendars and events.
|
|
88
|
+
|
|
89
|
+
### events
|
|
90
|
+
|
|
91
|
+
- `delete` — Deletes an event.
|
|
92
|
+
- `get` — Returns an event based on its Google Calendar ID. To retrieve an event using its iCalendar ID, call the events.list method using the iCalUID parameter.
|
|
93
|
+
- `import` — Imports an event. This operation is used to add a private copy of an existing event to a calendar. Only events with an eventType of default may be imported.
|
|
94
|
+
Deprecated behavior: If a non-default event is imported, its type will be changed to default and any event-type-specific properties it may have will be dropped.
|
|
95
|
+
- `insert` — Creates an event.
|
|
96
|
+
- `instances` — Returns instances of the specified recurring event.
|
|
97
|
+
- `list` — Returns events on the specified calendar.
|
|
98
|
+
- `move` — Moves an event to another calendar, i.e. changes an event's organizer. Note that only default events can be moved; birthday, focusTime, fromGmail, outOfOffice and workingLocation events cannot be moved.
|
|
99
|
+
- `patch` — Updates an event. This method supports patch semantics.
|
|
100
|
+
- `quickAdd` — Creates an event based on a simple text string.
|
|
101
|
+
- `update` — Updates an event.
|
|
102
|
+
- `watch` — Watch for changes to Events resources.
|
|
103
|
+
|
|
104
|
+
### freebusy
|
|
105
|
+
|
|
106
|
+
- `query` — Returns free/busy information for a set of calendars.
|
|
107
|
+
|
|
108
|
+
### settings
|
|
109
|
+
|
|
110
|
+
- `get` — Returns a single user setting.
|
|
111
|
+
- `list` — Returns all user settings for the authenticated user.
|
|
112
|
+
- `watch` — Watch for changes to Settings resources.
|
|
113
|
+
|
|
114
|
+
## Discovering Commands
|
|
115
|
+
|
|
116
|
+
Before calling any API method, inspect it:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# Browse resources and methods
|
|
120
|
+
gws calendar --help
|
|
121
|
+
|
|
122
|
+
# Inspect a method's required params, types, and defaults
|
|
123
|
+
gws schema calendar.<resource>.<method>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Use `gws schema` output to build your `--params` and `--json` flags.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gws-calendar-agenda
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
description: "Google Calendar: Show upcoming events across all calendars."
|
|
5
|
+
metadata:
|
|
6
|
+
openclaw:
|
|
7
|
+
category: "productivity"
|
|
8
|
+
requires:
|
|
9
|
+
bins: ["gws"]
|
|
10
|
+
cliHelp: "gws calendar +agenda --help"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# calendar +agenda
|
|
14
|
+
|
|
15
|
+
> **PREREQUISITE:** Read `../gws-shared/SKILL.md` for auth, global flags, and security rules. If missing, run `gws generate-skills` to create it.
|
|
16
|
+
|
|
17
|
+
Show upcoming events across all calendars
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
gws calendar +agenda
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Flags
|
|
26
|
+
|
|
27
|
+
| Flag | Required | Default | Description |
|
|
28
|
+
|------|----------|---------|-------------|
|
|
29
|
+
| `--today` | — | — | Show today's events |
|
|
30
|
+
| `--tomorrow` | — | — | Show tomorrow's events |
|
|
31
|
+
| `--week` | — | — | Show this week's events |
|
|
32
|
+
| `--days` | — | — | Number of days ahead to show |
|
|
33
|
+
| `--calendar` | — | — | Filter to specific calendar name or ID |
|
|
34
|
+
|
|
35
|
+
## Examples
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
gws calendar +agenda
|
|
39
|
+
gws calendar +agenda --today
|
|
40
|
+
gws calendar +agenda --week --format table
|
|
41
|
+
gws calendar +agenda --days 3 --calendar 'Work'
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Tips
|
|
45
|
+
|
|
46
|
+
- Read-only — never modifies events.
|
|
47
|
+
- Queries all calendars by default; use --calendar to filter.
|
|
48
|
+
|
|
49
|
+
## See Also
|
|
50
|
+
|
|
51
|
+
- [gws-shared](../gws-shared/SKILL.md) — Global flags and auth
|
|
52
|
+
- [gws-calendar](../gws-calendar/SKILL.md) — All manage calendars and events commands
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gws-calendar-insert
|
|
3
|
+
description: "Google Calendar: Create a new event."
|
|
4
|
+
metadata:
|
|
5
|
+
openclaw:
|
|
6
|
+
category: "productivity"
|
|
7
|
+
requires:
|
|
8
|
+
bins: ["gws"]
|
|
9
|
+
cliHelp: "gws calendar +insert --help"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# calendar +insert
|
|
13
|
+
|
|
14
|
+
> **PREREQUISITE:** Read `../gws-shared/SKILL.md` for auth, global flags, and security rules. If missing, run `gws generate-skills` to create it.
|
|
15
|
+
|
|
16
|
+
create a new event
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
gws calendar +insert --summary <TEXT> --start <TIME> --end <TIME>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Target Calendar Rules
|
|
25
|
+
|
|
26
|
+
- Always state the active Google account and target calendar before writing.
|
|
27
|
+
- In multi-account setups, prefer an explicit `--calendar <calendarId>` instead of relying on `primary`.
|
|
28
|
+
- For this user's current setup, when the user says "my calendar" or gives no target, use `--calendar tianyupeiandy@gmail.com` after `gws auth status` confirms the active user is `tianyupeiandy@gmail.com`.
|
|
29
|
+
- Do not write durable events to Apple Calendar, iCloud, or school calendars as a fallback.
|
|
30
|
+
- If multiple calendars share the same display name, list calendars and use the ID:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
gws calendar calendarList list --params '{"showHidden":true,"maxResults":250}'
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Flags
|
|
37
|
+
|
|
38
|
+
| Flag | Required | Default | Description |
|
|
39
|
+
|------|----------|---------|-------------|
|
|
40
|
+
| `--calendar` | — | primary | Calendar ID (default: primary) |
|
|
41
|
+
| `--summary` | ✓ | — | Event summary/title |
|
|
42
|
+
| `--start` | ✓ | — | Start time (ISO 8601, e.g., 2024-01-01T10:00:00Z) |
|
|
43
|
+
| `--end` | ✓ | — | End time (ISO 8601) |
|
|
44
|
+
| `--location` | — | — | Event location |
|
|
45
|
+
| `--description` | — | — | Event description/body |
|
|
46
|
+
| `--attendee` | — | — | Attendee email (can be used multiple times) |
|
|
47
|
+
|
|
48
|
+
## Examples
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
gws calendar +insert --summary 'Standup' --start '2026-06-17T09:00:00-07:00' --end '2026-06-17T09:30:00-07:00'
|
|
52
|
+
gws calendar +insert --summary 'Review' --start ... --end ... --attendee alice@example.com
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Tips
|
|
56
|
+
|
|
57
|
+
- Use RFC3339 format for times (e.g. 2026-06-17T09:00:00-07:00).
|
|
58
|
+
- For recurring events or conference links, use the raw API instead.
|
|
59
|
+
|
|
60
|
+
> [!CAUTION]
|
|
61
|
+
> This is a **write** command — confirm with the user before executing.
|
|
62
|
+
|
|
63
|
+
## See Also
|
|
64
|
+
|
|
65
|
+
- [gws-shared](../gws-shared/SKILL.md) — Global flags and auth
|
|
66
|
+
- [gws-calendar](../gws-calendar/SKILL.md) — All manage calendars and events commands
|