···8383 has been compromised, contact your administrator. If you are concerned about
8484 the security of your account, consider discussing this with your
8585 administrator.
8686+8787+## API Reference
8888+8989+### Reading your app password
9090+9191+Your app password is stored at the path in the `AGENT_ATPROTO_APP_PASSWORD`
9292+environment variable. Read it with:
9393+9494+ cat "$AGENT_ATPROTO_APP_PASSWORD" | tr -d '\n'
9595+9696+### Authenticating
9797+9898+To get a session token, POST to your PDS's `com.atproto.server.createSession`
9999+endpoint:
100100+101101+ curl -s -X POST "https://YOUR_PDS/xrpc/com.atproto.server.createSession" \
102102+ -H "Content-Type: application/json" \
103103+ -d '{"identifier": "YOUR_DID", "password": "YOUR_APP_PASSWORD"}'
104104+105105+This returns JSON with an `accessJwt` field. Use it as a Bearer token for
106106+authenticated requests:
107107+108108+ -H "Authorization: Bearer YOUR_ACCESS_JWT"
109109+110110+### Creating records
111111+112112+To create a record in your repository:
113113+114114+ curl -s -X POST "https://YOUR_PDS/xrpc/com.atproto.repo.createRecord" \
115115+ -H "Content-Type: application/json" \
116116+ -H "Authorization: Bearer YOUR_ACCESS_JWT" \
117117+ -d '{
118118+ "repo": "YOUR_DID",
119119+ "collection": "LEXICON_NSID",
120120+ "record": { ... }
121121+ }'
122122+123123+Use `date -u +%Y-%m-%dT%H:%M:%S.000Z` to generate `createdAt` timestamps.
124124+125125+## Helper scripts
126126+127127+### authenticate.sh
128128+129129+Authenticates with the PDS and returns an access JWT to stdout. Used by
130130+Bluesky scripts internally, but can also be called directly when you need a
131131+token for manual API calls.
132132+133133+```sh
134134+JWT=$(bash atproto/authenticate.sh)
135135+```
136136+137137+Requires:
138138+- `AGENT_ATPROTO_APP_PASSWORD` environment variable pointing to app password file
139139+- `curl` and `python3` available on PATH
+151-1
bluesky/SKILL.md
···7788## Overview
991010-Bluesky is a microblogging platform built on the AT Protocol, designed to enable decentralized social networking. It allows users to create and share short posts, follow other users, and engage with content in a way that emphasizes user control and data ownership. Bluesky is part of the broader AT Protocol ecosystem, which includes various platforms and tools that leverage the capabilities of the AT Protocol for social networking and content sharing. To open the Bluesky app, visit <https://bsky.app/>.
1010+Bluesky is a microblogging platform built on the AT Protocol, designed to enable
1111+decentralized social networking. It allows users to create and share short
1212+posts, follow other users, and engage with content in a way that emphasizes user
1313+control and data ownership. Bluesky is part of the broader AT Protocol
1414+ecosystem, which includes various platforms and tools that leverage the
1515+capabilities of the AT Protocol for social networking and content sharing. To
1616+open the Bluesky app, visit <https://bsky.app/>.
1717+1818+## Helper scripts
1919+2020+This skill includes shell scripts for common Bluesky operations. They handle
2121+authentication, JSON escaping, and idempotency automatically. All scripts are
2222+in the `bluesky/` directory under the social-skills workspace.
2323+2424+### create-post.sh
2525+2626+Creates a Bluesky post with proper JSON escaping and timestamp generation.
2727+2828+```sh
2929+# Simple post
3030+bash bluesky/create-post.sh "Hello world"
3131+3232+# Post with a mention (pass facets as JSON)
3333+bash bluesky/create-post.sh "Hey @notjack.space" \
3434+ '[{"index":{"byteStart":4,"byteEnd":20},"features":[{"$type":"app.bsky.richtext.facet#mention","did":"did:plc:7oyzfpde4xg23u447zkp3b2i"}]}]'
3535+```
3636+3737+Output: `Posted: at://...` on success.
3838+3939+### reply-to-post.sh
4040+4141+Replies to a Bluesky post. Automatically resolves the parent's CID and thread
4242+root, so you only need to provide the parent URI.
4343+4444+```sh
4545+bash bluesky/reply-to-post.sh "at://did:plc:.../app.bsky.feed.post/..." "Great point!"
4646+```
4747+4848+Supports optional facets JSON as a third argument, same as create-post.sh.
4949+Output: `Replied: at://...` on success.
5050+5151+### like-post.sh
5252+5353+Likes a Bluesky post, but only if not already liked. Prevents double-liking by
5454+checking the `viewer.like` field (which requires authentication to populate).
5555+5656+```sh
5757+bash bluesky/like-post.sh "at://did:plc:.../app.bsky.feed.post/..."
5858+```
5959+6060+Output: `Liked: at://...` on success, or `Already liked: at://...` if
6161+previously liked.
6262+6363+### send-dm.sh
6464+6565+Sends a DM to a Bluesky conversation. Uses python3 `json.dumps` for proper
6666+escaping of message text.
6767+6868+```sh
6969+bash bluesky/send-dm.sh "3mf7dxxpa5c2j" "Hello from the script"
7070+```
7171+7272+Output: `Sent: <message-id>` on success.
7373+7474+### read-notifications.sh
7575+7676+Reads recent notifications (replies, likes, follows, mentions).
7777+7878+```sh
7979+# Default: 30 notifications
8080+bash bluesky/read-notifications.sh
8181+8282+# Custom limit
8383+bash bluesky/read-notifications.sh 10
8484+```
8585+8686+Prints each notification with timestamp, type, author handle, and text.
8787+Unread notifications are marked with `[NEW]`.
8888+8989+### read-dms.sh
9090+9191+Reads recent DMs from a conversation, oldest first.
9292+9393+```sh
9494+# Read DMs with Jacqueline (convo ID: 3mf7dxxpa5c2j)
9595+bash bluesky/read-dms.sh "3mf7dxxpa5c2j"
9696+9797+# Custom limit
9898+bash bluesky/read-dms.sh "3mf7dxxpa5c2j" 10
9999+```
100100+101101+### Requirements
102102+103103+All scripts require:
104104+- `AGENT_ATPROTO_APP_PASSWORD` environment variable pointing to app password
105105+ file
106106+- `curl` and `python3` available on PATH
107107+108108+All scripts use the shared `atproto/authenticate.sh` for authentication.
109109+110110+The scripts hardcode the PDS URL and DID for claude.notjack.space. If the
111111+account moves to a different PDS, update the `PDS` variable in the scripts.
112112+113113+## API reference
114114+115115+### Reading a user's posts
116116+117117+To fetch a user's recent posts (unauthenticated, public API):
118118+119119+ curl -s "https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=DID&limit=20"
120120+121121+The response has a `feed` array where each entry has a `post` object with
122122+`record.text`, `author`, `record.createdAt`, etc.
123123+124124+### Reading notifications
125125+126126+Requires authentication:
127127+128128+ curl -s "https://YOUR_PDS/xrpc/app.bsky.notification.listNotifications?limit=20" \
129129+ -H "Authorization: Bearer YOUR_ACCESS_JWT"
130130+131131+Or use the `read-notifications.sh` script.
132132+133133+### Reading DMs
134134+135135+Requires authentication and the chat proxy header:
136136+137137+ curl -s "https://YOUR_PDS/xrpc/chat.bsky.convo.getMessages?convoId=CONVO_ID&limit=20" \
138138+ -H "Authorization: Bearer YOUR_ACCESS_JWT" \
139139+ -H "Atproto-Proxy: did:web:api.bsky.chat#bsky_chat"
140140+141141+Or use the `read-dms.sh` script.
142142+143143+### Post character limit
144144+145145+Posts are limited to 300 graphemes. Keep posts concise.
146146+147147+### Facets for mentions
148148+149149+To mention someone in a post, include a facet with byte-accurate `byteStart`
150150+and `byteEnd` positions matching the mention text (e.g., `@notjack.space`).
151151+Count bytes carefully — multi-byte characters shift positions. The
152152+`create-post.sh` and `reply-to-post.sh` scripts accept facets as an optional
153153+JSON argument.
154154+155155+### Viewer state
156156+157157+Authenticated API responses include a `viewer` object on posts with fields like
158158+`viewer.like` (URI of your like record, if you liked it) and `viewer.repost`.
159159+Unauthenticated responses do not populate these fields. Use authenticated
160160+requests when you need to check whether you've already interacted with a post.