@acedatacloud/skills 2026.728.3 → 2026.728.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/package.json +1 -1
- package/skills/github/SKILL.md +206 -17
- package/skills/x/SKILL.md +7 -1
- package/skills/x/scripts/x.py +50 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acedatacloud/skills",
|
|
3
|
-
"version": "2026.728.
|
|
3
|
+
"version": "2026.728.5",
|
|
4
4
|
"description": "Agent Skills for AceDataCloud AI services — music, image, video generation, LLM chat, web search. Compatible with Claude Code, GitHub Copilot, Gemini CLI, OpenAI Codex, and 30+ AI coding agents.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-skills",
|
package/skills/github/SKILL.md
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: github
|
|
3
|
-
description: GitHub issues, pull requests, repos, code search, and Actions via the gh CLI. Use when the user mentions GitHub, an issue/PR number, a repo, a commit, or code review.
|
|
3
|
+
description: GitHub issues, pull requests, repos, code search, releases, gists, stars, watching, forks, and Actions via the gh CLI. Use when the user mentions GitHub, an issue/PR number, a repo, a commit, a release, a gist, or code review.
|
|
4
4
|
when_to_use: |
|
|
5
5
|
Trigger when the user wants to read or write something on GitHub —
|
|
6
|
-
list / view / create / comment on issues or PRs,
|
|
7
|
-
|
|
6
|
+
list / view / create / comment on issues or PRs, star / watch / fork a
|
|
7
|
+
repo, manage releases / gists / labels / milestones, search code, view
|
|
8
|
+
CI runs, etc.
|
|
8
9
|
connections: [github]
|
|
9
10
|
allowed_tools: [Bash]
|
|
10
11
|
license: Apache-2.0
|
|
11
12
|
metadata:
|
|
12
13
|
author: acedatacloud
|
|
13
|
-
version: "1.
|
|
14
|
+
version: "1.1"
|
|
14
15
|
---
|
|
15
16
|
|
|
16
17
|
Use the `gh` CLI for everything. The user's OAuth access token is exported
|
|
@@ -21,16 +22,40 @@ authenticated subcommand works regardless.
|
|
|
21
22
|
`gh --help` and `gh <subcommand> --help` are always current. When unsure,
|
|
22
23
|
read the help first instead of guessing flags.
|
|
23
24
|
|
|
25
|
+
## Granted scopes — what you can and cannot do
|
|
26
|
+
|
|
27
|
+
The connection requests exactly five scopes: `read:user`, `user:email`,
|
|
28
|
+
`repo`, `read:org`, `gist`. Everything in the Recipes below fits inside
|
|
29
|
+
them. These do NOT fit, and will fail no matter how you phrase the call:
|
|
30
|
+
|
|
31
|
+
| Want to… | Needs scope | Verdict |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| Follow / unfollow a user | `user:follow` (or full `user`) | ✗ we only have `read:user` |
|
|
34
|
+
| Block / unblock a user | `user` | ✗ |
|
|
35
|
+
| Read / write Projects V2 | `read:project` / `project` | ✗ `INSUFFICIENT_SCOPES` |
|
|
36
|
+
| Manage SSH / GPG keys | `admin:public_key` / `admin:gpg_key` | ✗ |
|
|
37
|
+
| Manage org membership, teams | `write:org` / `admin:org` | ✗ read-only via `read:org` |
|
|
38
|
+
| Manage repo webhooks | `admin:repo_hook` | ✗ |
|
|
39
|
+
|
|
40
|
+
Users pick scopes at install time and every box is optional, so even the
|
|
41
|
+
five above may be partially granted. A `404` on something you know exists,
|
|
42
|
+
or a `403`, usually means a missing scope — not a wrong URL. Say so plainly
|
|
43
|
+
and point the user at `auth.acedata.cloud/user/connections` to reconnect
|
|
44
|
+
with the box ticked.
|
|
45
|
+
|
|
24
46
|
## Two ways to call gh — prefer subcommands
|
|
25
47
|
|
|
26
48
|
### Style A: First-class subcommands — START HERE
|
|
27
49
|
|
|
28
50
|
`gh issue`, `gh pr`, `gh repo`, `gh search`, `gh release`, `gh workflow`,
|
|
29
|
-
`gh run`, `gh status`, `gh
|
|
30
|
-
`gh
|
|
51
|
+
`gh run`, `gh status`, `gh label`, `gh secret`, `gh variable`, `gh gist`,
|
|
52
|
+
`gh org`, `gh ruleset`. Use these whenever they cover the task; they
|
|
31
53
|
output formatted text by default and structured JSON via
|
|
32
54
|
`--json <fields> [--jq <expr>]`.
|
|
33
55
|
|
|
56
|
+
There is no `gh star` / `gh watch` subcommand — those go through
|
|
57
|
+
`gh api` (see below). `gh repo fork` does exist.
|
|
58
|
+
|
|
34
59
|
### Style B: Raw REST / GraphQL via `gh api`
|
|
35
60
|
|
|
36
61
|
`gh api <endpoint>` for REST, `gh api graphql -f query='…'` for GraphQL.
|
|
@@ -77,13 +102,28 @@ gh issue view 123 --repo OWNER/REPO --json title,body,comments \
|
|
|
77
102
|
gh issue create --repo OWNER/REPO --title "Bug: foo" --body "Repro steps…" --label bug
|
|
78
103
|
gh issue comment 123 --repo OWNER/REPO --body "LGTM"
|
|
79
104
|
gh issue close 123 --repo OWNER/REPO --comment "Fixed in #456"
|
|
105
|
+
gh issue reopen 123 --repo OWNER/REPO
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Edit an issue — labels, assignees, milestone, title, body
|
|
109
|
+
|
|
110
|
+
```sh
|
|
111
|
+
gh issue edit 123 --repo OWNER/REPO --add-label bug --add-assignee @me
|
|
112
|
+
gh issue edit 123 --repo OWNER/REPO --remove-label wontfix --milestone "v2.0"
|
|
113
|
+
gh issue edit 123 --repo OWNER/REPO --title "New title" --body "Rewritten body"
|
|
114
|
+
gh issue lock 123 --repo OWNER/REPO --reason spam
|
|
115
|
+
gh issue transfer 123 OWNER/OTHER_REPO --repo OWNER/REPO
|
|
80
116
|
```
|
|
81
117
|
|
|
118
|
+
`--add-project` / `--remove-project` need the `project` scope we do not
|
|
119
|
+
have; they will fail. Everything else on this list works.
|
|
120
|
+
|
|
82
121
|
### List PRs assigned to / authored by me
|
|
83
122
|
|
|
84
123
|
```sh
|
|
85
124
|
gh search prs --assignee=@me --state=open --json number,title,repository,updatedAt
|
|
86
125
|
gh search prs --author=@me --state=open
|
|
126
|
+
gh search prs --review-requested=@me --state=open
|
|
87
127
|
```
|
|
88
128
|
|
|
89
129
|
### View a PR with diff and CI checks
|
|
@@ -94,6 +134,16 @@ gh pr diff 456 --repo OWNER/REPO
|
|
|
94
134
|
gh pr checks 456 --repo OWNER/REPO
|
|
95
135
|
```
|
|
96
136
|
|
|
137
|
+
### Create / edit a PR
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
gh pr create --repo OWNER/REPO --base main --head feature-branch \
|
|
141
|
+
--title "Add foo" --body "Closes #123" --draft
|
|
142
|
+
gh pr edit 456 --repo OWNER/REPO --add-reviewer octocat --add-label review-needed
|
|
143
|
+
gh pr edit 456 --repo OWNER/REPO --base develop --title "Retitled"
|
|
144
|
+
gh pr ready 456 --repo OWNER/REPO # draft → ready for review
|
|
145
|
+
```
|
|
146
|
+
|
|
97
147
|
### Comment / review / merge a PR
|
|
98
148
|
|
|
99
149
|
```sh
|
|
@@ -101,27 +151,138 @@ gh pr comment 456 --repo OWNER/REPO --body "Please rebase on main."
|
|
|
101
151
|
gh pr review 456 --repo OWNER/REPO --approve --body "LGTM"
|
|
102
152
|
gh pr review 456 --repo OWNER/REPO --request-changes --body "See nits"
|
|
103
153
|
gh pr merge 456 --repo OWNER/REPO --squash --delete-branch
|
|
154
|
+
gh pr update-branch 456 --repo OWNER/REPO # merge base into the PR branch
|
|
155
|
+
gh pr close 456 --repo OWNER/REPO
|
|
104
156
|
```
|
|
105
157
|
|
|
106
|
-
|
|
158
|
+
`merge`, `close`, and `review --approve` are irreversible or publicly
|
|
159
|
+
visible. Confirm with the user before running them unless they clearly
|
|
160
|
+
asked for that exact action.
|
|
161
|
+
|
|
162
|
+
### Star / unstar a repo
|
|
163
|
+
|
|
164
|
+
No `gh` subcommand exists — use the REST route. A `204` means success,
|
|
165
|
+
and `GET` returns `204` when starred / `404` when not.
|
|
107
166
|
|
|
108
167
|
```sh
|
|
109
|
-
gh
|
|
110
|
-
|
|
168
|
+
gh api -X PUT user/starred/OWNER/REPO # star
|
|
169
|
+
gh api -X DELETE user/starred/OWNER/REPO # unstar
|
|
170
|
+
gh api user/starred/OWNER/REPO # 204 = starred, 404 = not
|
|
171
|
+
gh api user/starred --paginate --jq '.[].full_name' # list my stars
|
|
111
172
|
```
|
|
112
173
|
|
|
113
|
-
###
|
|
174
|
+
### Watch / unwatch a repo (notification subscription)
|
|
114
175
|
|
|
115
176
|
```sh
|
|
116
|
-
gh api
|
|
117
|
-
|
|
177
|
+
gh api -X PUT repos/OWNER/REPO/subscription -F subscribed=true # watch
|
|
178
|
+
gh api -X PUT repos/OWNER/REPO/subscription -F ignored=true # ignore
|
|
179
|
+
gh api -X DELETE repos/OWNER/REPO/subscription # unwatch
|
|
180
|
+
gh api user/subscriptions --paginate --jq '.[].full_name'
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Watching is distinct from starring: starring is a public bookmark,
|
|
184
|
+
watching only changes what lands in the user's notifications.
|
|
185
|
+
|
|
186
|
+
### Fork a repo
|
|
187
|
+
|
|
188
|
+
```sh
|
|
189
|
+
gh repo fork OWNER/REPO --clone=false
|
|
190
|
+
gh repo fork OWNER/REPO --org MY_ORG --default-branch-only
|
|
191
|
+
gh api repos/OWNER/REPO/forks --jq '.[].full_name'
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Starring and forking are visible on the user's public profile. Confirm
|
|
195
|
+
before doing either on someone else's repo unless explicitly asked.
|
|
196
|
+
|
|
197
|
+
### Notifications
|
|
198
|
+
|
|
199
|
+
```sh
|
|
200
|
+
gh api notifications --jq '.[] | "\(.repository.full_name) \(.subject.type) \(.subject.title)"'
|
|
201
|
+
gh api -X PATCH notifications # mark all read
|
|
202
|
+
gh api -X PATCH notifications/threads/<THREAD_ID> # mark one read
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Create / manage a repo
|
|
206
|
+
|
|
207
|
+
```sh
|
|
208
|
+
gh repo create OWNER/NEW_REPO --private --description "…"
|
|
209
|
+
gh repo view OWNER/REPO --json description,url,stargazerCount,defaultBranchRef
|
|
210
|
+
gh repo edit OWNER/REPO --description "New desc" --add-topic ai --visibility private
|
|
211
|
+
gh repo list OWNER --limit 30 --json name,visibility,updatedAt
|
|
212
|
+
gh repo archive OWNER/REPO --yes
|
|
118
213
|
```
|
|
119
214
|
|
|
120
|
-
|
|
215
|
+
`gh repo delete` needs `delete_repo`, which is NOT granted — it will fail.
|
|
216
|
+
Never reach for it.
|
|
217
|
+
|
|
218
|
+
### Releases
|
|
121
219
|
|
|
122
220
|
```sh
|
|
221
|
+
gh release list --repo OWNER/REPO --limit 10
|
|
222
|
+
gh release view v1.2.0 --repo OWNER/REPO
|
|
223
|
+
gh release create v1.2.0 --repo OWNER/REPO --title "v1.2.0" --notes "Changelog…"
|
|
224
|
+
gh release create v1.2.0 --repo OWNER/REPO --generate-notes ./dist/app.zip
|
|
225
|
+
gh release upload v1.2.0 ./extra-asset.tar.gz --repo OWNER/REPO
|
|
226
|
+
gh release download v1.2.0 --repo OWNER/REPO --pattern '*.zip'
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Gists
|
|
230
|
+
|
|
231
|
+
```sh
|
|
232
|
+
gh gist list --limit 20
|
|
233
|
+
gh gist create ./script.py --public --desc "Handy script"
|
|
234
|
+
gh gist view <GIST_ID>
|
|
235
|
+
gh gist edit <GIST_ID>
|
|
236
|
+
gh gist delete <GIST_ID>
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Labels and milestones
|
|
240
|
+
|
|
241
|
+
```sh
|
|
242
|
+
gh label list --repo OWNER/REPO
|
|
243
|
+
gh label create urgent --repo OWNER/REPO --color FF0000 --description "Drop everything"
|
|
244
|
+
gh label edit bug --repo OWNER/REPO --color 00FF00
|
|
245
|
+
gh label clone SOURCE_OWNER/SOURCE_REPO --repo OWNER/REPO
|
|
246
|
+
|
|
247
|
+
# Milestones have no gh subcommand — use the API
|
|
248
|
+
gh api repos/OWNER/REPO/milestones --jq '.[] | "\(.number) \(.title) \(.open_issues) open"'
|
|
249
|
+
gh api -X POST repos/OWNER/REPO/milestones -f title="v2.0" -f due_on="2026-12-31T23:59:59Z"
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Branches, commits, and comparing
|
|
253
|
+
|
|
254
|
+
```sh
|
|
255
|
+
gh api repos/OWNER/REPO/branches --jq '.[].name'
|
|
123
256
|
gh api "repos/OWNER/REPO/commits?per_page=20" \
|
|
124
257
|
--jq '.[] | "\(.sha[0:7]) \(.commit.author.date) \(.commit.message | split("\n")[0])"'
|
|
258
|
+
gh api repos/OWNER/REPO/compare/main...feature-branch \
|
|
259
|
+
--jq '{ahead: .ahead_by, behind: .behind_by, files: [.files[].filename]}'
|
|
260
|
+
gh api -X DELETE repos/OWNER/REPO/git/refs/heads/stale-branch
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Read / write a file in a repo
|
|
264
|
+
|
|
265
|
+
```sh
|
|
266
|
+
# Read raw bytes, no base64 dance
|
|
267
|
+
gh api "repos/OWNER/REPO/contents/path/to/file.ts" \
|
|
268
|
+
-H 'Accept: application/vnd.github.raw'
|
|
269
|
+
|
|
270
|
+
# Write requires base64 content + the current blob sha when replacing
|
|
271
|
+
SHA=$(gh api repos/OWNER/REPO/contents/README.md --jq .sha)
|
|
272
|
+
gh api -X PUT repos/OWNER/REPO/contents/README.md \
|
|
273
|
+
-f message="docs: update readme" \
|
|
274
|
+
-f content="$(base64 < ./README.md | tr -d '\n')" \
|
|
275
|
+
-f sha="$SHA"
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Search across GitHub
|
|
279
|
+
|
|
280
|
+
```sh
|
|
281
|
+
gh search code 'someFunction language:typescript' --limit 20 \
|
|
282
|
+
--json repository,path,url --jq '.[] | "\(.repository.nameWithOwner) \(.path)"'
|
|
283
|
+
gh search repos 'topic:mcp stars:>100' --limit 20 --json fullName,stargazersCount
|
|
284
|
+
gh search commits 'fix memory leak' --repo OWNER/REPO --limit 10
|
|
285
|
+
gh search issues 'is:open label:bug' --owner OWNER --limit 20
|
|
125
286
|
```
|
|
126
287
|
|
|
127
288
|
### Trigger / inspect Actions workflows
|
|
@@ -131,16 +292,34 @@ gh workflow list --repo OWNER/REPO
|
|
|
131
292
|
gh workflow run ci.yaml --repo OWNER/REPO --ref main -f key=value
|
|
132
293
|
gh run list --repo OWNER/REPO --workflow ci.yaml --limit 5
|
|
133
294
|
gh run view <RUN_ID> --repo OWNER/REPO --log-failed
|
|
295
|
+
gh run rerun <RUN_ID> --repo OWNER/REPO --failed
|
|
296
|
+
gh run cancel <RUN_ID> --repo OWNER/REPO
|
|
297
|
+
gh run watch <RUN_ID> --repo OWNER/REPO
|
|
134
298
|
```
|
|
135
299
|
|
|
136
|
-
###
|
|
300
|
+
### Actions secrets and variables
|
|
137
301
|
|
|
138
302
|
```sh
|
|
139
|
-
gh repo
|
|
140
|
-
gh repo
|
|
303
|
+
gh secret list --repo OWNER/REPO
|
|
304
|
+
gh secret set MY_TOKEN --repo OWNER/REPO --body "value"
|
|
305
|
+
gh variable list --repo OWNER/REPO
|
|
306
|
+
gh variable set MY_VAR --repo OWNER/REPO --body "value"
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Secret values are write-only — you can set and list names, never read a
|
|
310
|
+
value back. Never echo a secret the user gives you into a comment, issue,
|
|
311
|
+
or commit.
|
|
312
|
+
|
|
313
|
+
### Organizations (read-only under `read:org`)
|
|
314
|
+
|
|
315
|
+
```sh
|
|
316
|
+
gh org list
|
|
317
|
+
gh api user/orgs --jq '.[].login'
|
|
318
|
+
gh api orgs/ORG/members --jq '.[].login'
|
|
319
|
+
gh api orgs/ORG/repos --paginate --jq '.[].full_name'
|
|
141
320
|
```
|
|
142
321
|
|
|
143
|
-
### GraphQL for things REST can't do
|
|
322
|
+
### GraphQL for things REST can't do
|
|
144
323
|
|
|
145
324
|
```sh
|
|
146
325
|
gh api graphql -f query='
|
|
@@ -156,6 +335,9 @@ gh api graphql -f query='
|
|
|
156
335
|
}' -f owner=OWNER -f repo=REPO -F num=123
|
|
157
336
|
```
|
|
158
337
|
|
|
338
|
+
Projects V2 lives only in GraphQL and needs `read:project` — not granted,
|
|
339
|
+
so those queries return `INSUFFICIENT_SCOPES`. Don't build recipes on it.
|
|
340
|
+
|
|
159
341
|
## Notes
|
|
160
342
|
|
|
161
343
|
- For private repos the user MUST have granted `repo` scope when they
|
|
@@ -171,3 +353,10 @@ gh api graphql -f query='
|
|
|
171
353
|
- `gh api --paginate` only works on endpoints that emit a `Link` header;
|
|
172
354
|
for cursor-paginated endpoints you have to follow `pagination.next`
|
|
173
355
|
yourself.
|
|
356
|
+
- Write endpoints that take no body (star, follow, watch-delete) return
|
|
357
|
+
`204 No Content` on success — an empty response is the success case,
|
|
358
|
+
not a failure.
|
|
359
|
+
- This connection can run unattended in a scheduled task. Public actions
|
|
360
|
+
(star, fork, issue/PR comments, reviews, merges) leave a permanent,
|
|
361
|
+
publicly attributable trace on the user's account. In an unattended run,
|
|
362
|
+
stick to exactly what the task authorized.
|
package/skills/x/SKILL.md
CHANGED
|
@@ -81,7 +81,13 @@ the default.
|
|
|
81
81
|
On an actual auth error the cookie is expired — have the user reconnect at
|
|
82
82
|
<https://auth.acedata.cloud/user/connections>. A Cloudflare block is different:
|
|
83
83
|
reconnecting cookies does not fix it. Use `whoami` for identity checks; other
|
|
84
|
-
blocked endpoints need `X_PROXY` or the official X API. Do **not** loop-retry
|
|
84
|
+
blocked endpoints need `X_PROXY` or the official X API. Do **not** loop-retry a
|
|
85
|
+
Cloudflare block or an auth error.
|
|
86
|
+
|
|
87
|
+
A **404 is not an auth error.** X's identity endpoints 404 on roughly a quarter
|
|
88
|
+
of calls even with healthy cookies, on every account. `whoami` already retries
|
|
89
|
+
those internally, so if it still reports a 404, wait a moment and run it again —
|
|
90
|
+
do not tell the user to reconnect.
|
|
85
91
|
|
|
86
92
|
## Write commands — GATED (dry-run unless trailing `--confirm`)
|
|
87
93
|
|
package/skills/x/scripts/x.py
CHANGED
|
@@ -245,8 +245,52 @@ async def resolve_user(client, target: str):
|
|
|
245
245
|
|
|
246
246
|
# ── read commands ───────────────────────────────────────────────────
|
|
247
247
|
|
|
248
|
+
IDENTITY_ATTEMPTS = 4
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
class _UnraisableSentinel(Exception):
|
|
252
|
+
"""Stands in for twikit's NotFound when twikit is absent, so the unit tests
|
|
253
|
+
(which mock the client entirely) can exercise these paths."""
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def not_found_error():
|
|
257
|
+
try:
|
|
258
|
+
from twikit.errors import NotFound
|
|
259
|
+
except Exception:
|
|
260
|
+
return _UnraisableSentinel
|
|
261
|
+
return NotFound
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
async def retry_flaky_not_found(client, call, what: str):
|
|
265
|
+
"""Run `call(client)`, retrying X's intermittent 404s on a fresh session.
|
|
266
|
+
|
|
267
|
+
X's identity endpoints 404 on roughly a quarter of calls even with healthy
|
|
268
|
+
cookies (measured over 20-trial batches on three separate accounts), so a
|
|
269
|
+
404 here is NOT an expired cookie. Returns (result, client) — the client is
|
|
270
|
+
replaced on each retry because reusing the failing session keeps 404ing.
|
|
271
|
+
"""
|
|
272
|
+
not_found = not_found_error()
|
|
273
|
+
last_error = None
|
|
274
|
+
for attempt in range(IDENTITY_ATTEMPTS):
|
|
275
|
+
if attempt:
|
|
276
|
+
await asyncio.sleep(0.6 * attempt)
|
|
277
|
+
client = make_client()
|
|
278
|
+
try:
|
|
279
|
+
return await call(client), client
|
|
280
|
+
except not_found as e:
|
|
281
|
+
last_error = e
|
|
282
|
+
die(
|
|
283
|
+
f"X returned 404 for {what} on {IDENTITY_ATTEMPTS} consecutive attempts. "
|
|
284
|
+
"That endpoint is intermittently flaky — a 404 is not an expired cookie, "
|
|
285
|
+
"so reconnecting will not help. Retry the same command in a moment. "
|
|
286
|
+
f"({last_error})"
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
|
|
248
290
|
async def cmd_whoami(client, args):
|
|
249
|
-
settings, _ = await
|
|
291
|
+
(settings, _), client = await retry_flaky_not_found(
|
|
292
|
+
client, lambda c: c.v11.settings(), "the authenticated account's settings"
|
|
293
|
+
)
|
|
250
294
|
authenticated_screen_name = settings.get("screen_name") if isinstance(settings, dict) else None
|
|
251
295
|
if not isinstance(authenticated_screen_name, str) or not re.fullmatch(
|
|
252
296
|
r"[A-Za-z0-9_]{1,15}", authenticated_screen_name
|
|
@@ -260,7 +304,11 @@ async def cmd_whoami(client, args):
|
|
|
260
304
|
f"connected X account is @{authenticated_screen_name}, not @{expected_screen_name}; "
|
|
261
305
|
"stopped without performing any write"
|
|
262
306
|
)
|
|
263
|
-
u = await
|
|
307
|
+
u, client = await retry_flaky_not_found(
|
|
308
|
+
client,
|
|
309
|
+
lambda c: c.get_user_by_screen_name(authenticated_screen_name),
|
|
310
|
+
f"@{authenticated_screen_name}'s profile",
|
|
311
|
+
)
|
|
264
312
|
result = fmt_user(u)
|
|
265
313
|
result.update(
|
|
266
314
|
{
|