···83 has been compromised, contact your administrator. If you are concerned about
84 the security of your account, consider discussing this with your
85 administrator.
000000000000000000000000000000000000000000000000000000
···83 has been compromised, contact your administrator. If you are concerned about
84 the security of your account, consider discussing this with your
85 administrator.
86+87+## API Reference
88+89+### Reading your app password
90+91+Your app password is stored at the path in the `AGENT_ATPROTO_APP_PASSWORD`
92+environment variable. Read it with:
93+94+ cat "$AGENT_ATPROTO_APP_PASSWORD" | tr -d '\n'
95+96+### Authenticating
97+98+To get a session token, POST to your PDS's `com.atproto.server.createSession`
99+endpoint:
100+101+ curl -s -X POST "https://YOUR_PDS/xrpc/com.atproto.server.createSession" \
102+ -H "Content-Type: application/json" \
103+ -d '{"identifier": "YOUR_DID", "password": "YOUR_APP_PASSWORD"}'
104+105+This returns JSON with an `accessJwt` field. Use it as a Bearer token for
106+authenticated requests:
107+108+ -H "Authorization: Bearer YOUR_ACCESS_JWT"
109+110+### Creating records
111+112+To create a record in your repository:
113+114+ curl -s -X POST "https://YOUR_PDS/xrpc/com.atproto.repo.createRecord" \
115+ -H "Content-Type: application/json" \
116+ -H "Authorization: Bearer YOUR_ACCESS_JWT" \
117+ -d '{
118+ "repo": "YOUR_DID",
119+ "collection": "LEXICON_NSID",
120+ "record": { ... }
121+ }'
122+123+Use `date -u +%Y-%m-%dT%H:%M:%S.000Z` to generate `createdAt` timestamps.
124+125+## Helper scripts
126+127+### authenticate.sh
128+129+Authenticates with the PDS and returns an access JWT to stdout. Used by
130+Bluesky scripts internally, but can also be called directly when you need a
131+token for manual API calls.
132+133+```sh
134+JWT=$(bash atproto/authenticate.sh)
135+```
136+137+Requires:
138+- `AGENT_ATPROTO_APP_PASSWORD` environment variable pointing to app password file
139+- `curl` and `python3` available on PATH
+151-1
bluesky/SKILL.md
···78## Overview
910-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/>.
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
···78## Overview
910+Bluesky is a microblogging platform built on the AT Protocol, designed to enable
11+decentralized social networking. It allows users to create and share short
12+posts, follow other users, and engage with content in a way that emphasizes user
13+control and data ownership. Bluesky is part of the broader AT Protocol
14+ecosystem, which includes various platforms and tools that leverage the
15+capabilities of the AT Protocol for social networking and content sharing. To
16+open the Bluesky app, visit <https://bsky.app/>.
17+18+## Helper scripts
19+20+This skill includes shell scripts for common Bluesky operations. They handle
21+authentication, JSON escaping, and idempotency automatically. All scripts are
22+in the `bluesky/` directory under the social-skills workspace.
23+24+### create-post.sh
25+26+Creates a Bluesky post with proper JSON escaping and timestamp generation.
27+28+```sh
29+# Simple post
30+bash bluesky/create-post.sh "Hello world"
31+32+# Post with a mention (pass facets as JSON)
33+bash bluesky/create-post.sh "Hey @notjack.space" \
34+ '[{"index":{"byteStart":4,"byteEnd":20},"features":[{"$type":"app.bsky.richtext.facet#mention","did":"did:plc:7oyzfpde4xg23u447zkp3b2i"}]}]'
35+```
36+37+Output: `Posted: at://...` on success.
38+39+### reply-to-post.sh
40+41+Replies to a Bluesky post. Automatically resolves the parent's CID and thread
42+root, so you only need to provide the parent URI.
43+44+```sh
45+bash bluesky/reply-to-post.sh "at://did:plc:.../app.bsky.feed.post/..." "Great point!"
46+```
47+48+Supports optional facets JSON as a third argument, same as create-post.sh.
49+Output: `Replied: at://...` on success.
50+51+### like-post.sh
52+53+Likes a Bluesky post, but only if not already liked. Prevents double-liking by
54+checking the `viewer.like` field (which requires authentication to populate).
55+56+```sh
57+bash bluesky/like-post.sh "at://did:plc:.../app.bsky.feed.post/..."
58+```
59+60+Output: `Liked: at://...` on success, or `Already liked: at://...` if
61+previously liked.
62+63+### send-dm.sh
64+65+Sends a DM to a Bluesky conversation. Uses python3 `json.dumps` for proper
66+escaping of message text.
67+68+```sh
69+bash bluesky/send-dm.sh "3mf7dxxpa5c2j" "Hello from the script"
70+```
71+72+Output: `Sent: <message-id>` on success.
73+74+### read-notifications.sh
75+76+Reads recent notifications (replies, likes, follows, mentions).
77+78+```sh
79+# Default: 30 notifications
80+bash bluesky/read-notifications.sh
81+82+# Custom limit
83+bash bluesky/read-notifications.sh 10
84+```
85+86+Prints each notification with timestamp, type, author handle, and text.
87+Unread notifications are marked with `[NEW]`.
88+89+### read-dms.sh
90+91+Reads recent DMs from a conversation, oldest first.
92+93+```sh
94+# Read DMs with Jacqueline (convo ID: 3mf7dxxpa5c2j)
95+bash bluesky/read-dms.sh "3mf7dxxpa5c2j"
96+97+# Custom limit
98+bash bluesky/read-dms.sh "3mf7dxxpa5c2j" 10
99+```
100+101+### Requirements
102+103+All scripts require:
104+- `AGENT_ATPROTO_APP_PASSWORD` environment variable pointing to app password
105+ file
106+- `curl` and `python3` available on PATH
107+108+All scripts use the shared `atproto/authenticate.sh` for authentication.
109+110+The scripts hardcode the PDS URL and DID for claude.notjack.space. If the
111+account moves to a different PDS, update the `PDS` variable in the scripts.
112+113+## API reference
114+115+### Reading a user's posts
116+117+To fetch a user's recent posts (unauthenticated, public API):
118+119+ curl -s "https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=DID&limit=20"
120+121+The response has a `feed` array where each entry has a `post` object with
122+`record.text`, `author`, `record.createdAt`, etc.
123+124+### Reading notifications
125+126+Requires authentication:
127+128+ curl -s "https://YOUR_PDS/xrpc/app.bsky.notification.listNotifications?limit=20" \
129+ -H "Authorization: Bearer YOUR_ACCESS_JWT"
130+131+Or use the `read-notifications.sh` script.
132+133+### Reading DMs
134+135+Requires authentication and the chat proxy header:
136+137+ curl -s "https://YOUR_PDS/xrpc/chat.bsky.convo.getMessages?convoId=CONVO_ID&limit=20" \
138+ -H "Authorization: Bearer YOUR_ACCESS_JWT" \
139+ -H "Atproto-Proxy: did:web:api.bsky.chat#bsky_chat"
140+141+Or use the `read-dms.sh` script.
142+143+### Post character limit
144+145+Posts are limited to 300 graphemes. Keep posts concise.
146+147+### Facets for mentions
148+149+To mention someone in a post, include a facet with byte-accurate `byteStart`
150+and `byteEnd` positions matching the mention text (e.g., `@notjack.space`).
151+Count bytes carefully — multi-byte characters shift positions. The
152+`create-post.sh` and `reply-to-post.sh` scripts accept facets as an optional
153+JSON argument.
154+155+### Viewer state
156+157+Authenticated API responses include a `viewer` object on posts with fields like
158+`viewer.like` (URI of your like record, if you liked it) and `viewer.repost`.
159+Unauthenticated responses do not populate these fields. Use authenticated
160+requests when you need to check whether you've already interacted with a post.