Skip to content

AGENTS.md

106 lines · 3.9 KB · Markdown
Raw

@kody/bluesky — agent notes

Human setup and intent live in README.md. This file is for agents: imports, smoke/dryRun execute snippets, and edge cases. Auth is the user secret blueskyAppPassword plus a handle in packageStorage (or per-call). Never paste the app password. Do not disable live webhooks or jobs.

Secrets / storage

KindName / keyNotes
Credential slot (raw)blueskyAppPasswordUser secret, hosts bsky.social, *.bsky.network. Read with packageSecrets.get because createSession needs it in the JSON body; the session accessJwt goes in Authorization. Raw reads work only in Kody-run code (cloud execute, jobs, webhooks), not --local.
Package storageblueskyHandleDefault actor after fork; override with identifier / actor / handle

Public AppView GETs use https://public.api.bsky.app and do not need the secret. Authenticated calls create a session against https://bsky.social (override with service).

Import paths

ExportImport
overview / safety metadatakody:@kody/bluesky
smoke-testkody:@kody/bluesky/smoke-test
requestkody:@kody/bluesky/request
resolve-handlekody:@kody/bluesky/resolve-handle
get-profilekody:@kody/bluesky/get-profile
search-postskody:@kody/bluesky/search-posts
get-author-feedkody:@kody/bluesky/get-author-feed
get-post-threadkody:@kody/bluesky/get-post-thread
list-notificationskody:@kody/bluesky/list-notifications
create-postkody:@kody/bluesky/create-post
delete-postkody:@kody/bluesky/delete-post
like-postkody:@kody/bluesky/like-post
repostkody:@kody/bluesky/repost
followkody:@kody/bluesky/follow
unfollowkody:@kody/bluesky/unfollow
default-handlekody:@kody/bluesky/default-handle

Prefer static kody:@kody/bluesky/... imports from execute. Do not lead with packages.invoke.

Smoke test (read-only)

Safe before credentials exist: returns { ok: true, live: false } plus setup URLs. With secret + handle, reads the session profile and does not post.

import smokeTest from 'kody:@kody/bluesky/smoke-test'

export default async function main() {
	return await smokeTest()
	// => { ok: true, live: false, setup: { ... } } or live profile metadata
}

Public profile read (no secret):

import getProfile from 'kody:@kody/bluesky/get-profile'

export default async function main() {
	return await getProfile({ actor: 'bsky.app' })
}

dryRun / confirm (writes)

Mutating helpers never create a session when dryRun: true (or when confirm is omitted). Live writes require confirm: true after the user approves the exact text or target.

import createPost from 'kody:@kody/bluesky/create-post'

export default async function main() {
	return await createPost({
		text: 'Watch this: https://example.com',
		externalCard: {
			uri: 'https://example.com',
			title: 'Example video',
			description: 'A useful video.',
			thumbnailUrl: 'https://example.com/thumbnail.jpg',
		},
		dryRun: true,
	})
}

create-post adds clickable facets for HTTP(S) URLs unless callers provide facets or set autoLinkFacets: false. Pass externalCard with uri, title, description, and optional thumbnailUrl. Thumbnails over Bluesky's 1 MB blob limit are fitted before upload. Dry-runs report originalBytes, uploadBytes, mimeType, and fitted instead of uploading.

Edge cases / fork notes

  • Fork first. Platform @kody/bluesky storage is shared by the official listing, not a personal account.
  • Persist the caller's handle with packageStorage().set('blueskyHandle', …) on the forked package, or pass identifiers per call.
  • Mutating XRPC via ./request still needs dryRun / confirm like dedicated helpers.
  • Never treat smoke success as permission to post.
  • Keep LICENSE (MIT), ## Intent, and community-icon.svg for community listing.