Skip to content

Commit b781d10

Browse files
committed
fix: update example Mastodon access token in README
1 parent 7c1057f commit b781d10

2 files changed

Lines changed: 315 additions & 2 deletions

File tree

CLAUDE.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

CLAUDE.md

Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
# AGENTS.md - HyperPost
2+
3+
> Guidelines for AI agents working in this codebase.
4+
>
5+
> Also read: `~/dev/hyperdrift/AGENTS.md` — workspace-level context (deploy tooling, fleet management, HD infra).
6+
7+
## Project Overview
8+
9+
**HyperPost** is a unified social media posting CLI tool that publishes content to multiple social networks simultaneously. Built with TypeScript, it uses Prisma for database operations and supports Mastodon, Bluesky, Discord, Reddit, Dev.to, and Medium.
10+
11+
Part of the **HyperDrift** ecosystem - open-source tools for independent developers.
12+
13+
## Essential Commands
14+
15+
```bash
16+
# Package manager - ALWAYS use pnpm
17+
pnpm install # Install dependencies
18+
pnpm build # Build with tsup (outputs to dist/)
19+
pnpm dev # Watch mode development
20+
pnpm test # Run Jest tests
21+
pnpm lint # ESLint on src/**/*.ts
22+
pnpm typecheck # TypeScript type checking (tsc --noEmit)
23+
24+
# Database (Prisma with SQLite)
25+
pnpm db:generate # Generate Prisma client after schema changes
26+
pnpm db:push # Push schema to database
27+
pnpm db:studio # Open Prisma Studio GUI
28+
pnpm db:migrate # Create migrations for production
29+
30+
# CLI testing
31+
pnpm cli # Run CLI directly (node dist/cli.js)
32+
hyper-post setup # Interactive setup wizard
33+
hyper-post post -c "..." # Post to all platforms
34+
hyper-post platforms # List configured platforms
35+
```
36+
37+
## Project Structure
38+
39+
```
40+
src/
41+
├── HyperPost.ts # Main class - orchestrates multi-platform posting
42+
├── cli.ts # Commander-based CLI implementation
43+
├── database.ts # Prisma client singleton
44+
├── index.ts # Public API exports
45+
├── setup.ts # Interactive setup wizard
46+
├── signup-manager.ts # Manages credentials in ~/.config/hyper-post/
47+
├── signup-templates.ts # Platform signup requirements and templates
48+
├── platforms/
49+
│ ├── BasePlatform.ts # Abstract base class for all platforms
50+
│ ├── BlueskyPlatform.ts
51+
│ ├── MastodonPlatform.ts
52+
│ ├── DiscordPlatform.ts
53+
│ ├── RedditPlatform.ts
54+
│ ├── DevtoPlatform.ts
55+
│ ├── MediumPlatform.ts
56+
│ └── index.ts # Platform exports
57+
├── types/
58+
│ └── index.ts # TypeScript interfaces (SocialPost, PostingResult, etc.)
59+
└── utils/
60+
└── contentFormat.ts # MDX/Markdown detection and conversion for Medium
61+
62+
schema.prisma # Database schema (SQLite default)
63+
tsup.config.ts # Build configuration (CJS + ESM)
64+
```
65+
66+
## Architecture Patterns
67+
68+
### Platform Pattern
69+
70+
All platforms extend `BasePlatform` and implement:
71+
72+
```typescript
73+
abstract class BasePlatform {
74+
abstract get name(): string; // lowercase identifier
75+
abstract get displayName(): string; // human-readable name
76+
abstract post(content: SocialPost): Promise<PostingResult>;
77+
abstract gatherAnalytics(postUrl: string): Promise<PostAnalytics>;
78+
abstract discoverPosts(limit?: number): Promise<...>;
79+
protected abstract getRequiredCredentials(): string[];
80+
}
81+
```
82+
83+
### Adding a New Platform
84+
85+
1. Create `src/platforms/NewPlatform.ts` extending `BasePlatform`
86+
2. Export from `src/platforms/index.ts`
87+
3. Add to `SupportedPlatforms` type in `src/types/index.ts`
88+
4. Add initialization in `HyperPost.initializePlatforms()`
89+
5. Add platform data in `HyperPost.initializeDatabase()`
90+
6. Add signup requirements in `src/signup-templates.ts`
91+
92+
### Credential Storage
93+
94+
- User credentials stored in `~/.config/hyper-post/signup-data.json`
95+
- Config defaults in `~/.config/hyper-post/config.json`
96+
- `SignupManager` class handles all credential operations
97+
- Environment variables override stored credentials
98+
99+
### Database Schema
100+
101+
```prisma
102+
Post # Content with SHA-256 hash for deduplication
103+
Platform # Platform metadata (mastodon, bluesky, etc.)
104+
PostPlatform # Many-to-many: which posts went to which platforms
105+
PostAnalytics # Engagement metrics per post-platform
106+
ScheduledPost # Future posts with status tracking
107+
```
108+
109+
## Key Types
110+
111+
```typescript
112+
interface SocialPost {
113+
content: string;
114+
title?: string;
115+
url?: string;
116+
imageUrl?: string;
117+
tags?: string[];
118+
}
119+
120+
interface PostingResult {
121+
platform: string;
122+
success: boolean;
123+
postId?: string;
124+
url?: string;
125+
error?: string;
126+
}
127+
128+
type SupportedPlatforms = 'mastodon' | 'bluesky' | 'discord' | 'reddit' | 'devto' | 'medium' | ...;
129+
```
130+
131+
## Build System
132+
133+
- **tsup** bundles the project into `dist/`
134+
- Three entry points: `index.ts` (library), `cli.ts` (CLI), `setup.ts` (wizard)
135+
- CLI and setup get `#!/usr/bin/env node` banner
136+
- Library outputs both CJS and ESM
137+
- TypeScript target: ES2022
138+
139+
## Coding Conventions
140+
141+
### TypeScript
142+
- Strict mode enabled
143+
- Use `async/await` for all async operations
144+
- Return `PostingResult` objects from platform `post()` methods
145+
- Use `createResult()` helper in platforms for consistent returns
146+
147+
### Error Handling
148+
- Platforms catch errors and return failure results (don't throw)
149+
- Use `console.warn()` for non-fatal issues (analytics failures, etc.)
150+
- CLI uses `process.exit(1)` for fatal errors
151+
152+
### Naming
153+
- Platform classes: `{Name}Platform` (e.g., `BlueskyPlatform`)
154+
- Platform identifiers: lowercase (e.g., `bluesky`)
155+
- Credential keys: camelCase (e.g., `accessToken`, `integrationToken`)
156+
157+
### Imports
158+
- Use named imports
159+
- Platform implementations use `require()` for some packages (e.g., `mastodon-api`)
160+
- Group imports: external packages, then internal modules
161+
162+
## Testing
163+
164+
- Jest is configured but no test files exist yet
165+
- Test commands exist in `package.json`
166+
- Recommended: add tests in `__tests__/` or `*.test.ts` files
167+
168+
## CLI Commands
169+
170+
| Command | Description |
171+
|---------|-------------|
172+
| `post` | Post content to platforms (`-c`, `-t`, `-u`, `--tags`, `-p`, `--dry-run`) |
173+
| `platforms` | List/test configured platforms |
174+
| `setup` | Interactive setup wizard |
175+
| `history` | View posting history |
176+
| `analytics` | View engagement data |
177+
| `gather-analytics` | Fetch fresh metrics from platforms |
178+
| `discover-posts` | Find existing posts on platforms |
179+
| `import-post` | Import external post for tracking |
180+
| `repost` | Repost content to additional platforms |
181+
| `schedule` | Schedule future posts |
182+
| `schedule-list` | List scheduled posts |
183+
| `schedule-cancel` | Cancel scheduled post |
184+
| `schedule-run` | Process due posts (for cron) |
185+
| `promote` | **Blog promotion** - parse MDX posts and share to platforms |
186+
187+
### Blog Promotion (`promote`)
188+
189+
The `promote` command reads MDX blog posts from a content directory and posts them to social platforms:
190+
191+
```bash
192+
# List available blog posts
193+
hyper-post promote --list
194+
195+
# Promote a specific article
196+
hyper-post promote --slug revela-part-1-architecture --dry-run
197+
198+
# Promote with full content to Dev.to/Medium
199+
hyper-post promote --slug my-article --full-content
200+
201+
# Schedule promotion for later
202+
hyper-post promote --slug my-article --schedule "2025-02-01 10:00"
203+
204+
# Promote recent posts (last 7 days)
205+
hyper-post promote --recent 7
206+
207+
# Custom blog directory
208+
hyper-post promote --blog-dir /path/to/content/blog --base-url https://mysite.com
209+
```
210+
211+
Default blog directory: `/Users/yann/dev/hyperdrift-io/hyper-drift/content/blog`
212+
213+
## Platform-Specific Notes
214+
215+
### Medium
216+
- Requires Markdown content format
217+
- Uses `contentFormat.ts` utilities for MDX → Markdown conversion
218+
- Tags limited to 5, max 25 chars each
219+
- Hashtags extracted from content automatically
220+
221+
### Bluesky
222+
- Uses `@atproto/api` SDK
223+
- Creates rich text with facets for link detection
224+
- URL embeds created as `app.bsky.embed.external`
225+
226+
### Mastodon
227+
- Uses `mastodon-api` npm package
228+
- Instance URL required in credentials
229+
- Tags appended as hashtags to status text
230+
231+
### Discord
232+
- Uses `discord.js`
233+
- Requires bot token and channel ID
234+
- Posts as bot messages
235+
236+
## Gotchas
237+
238+
1. **Build before CLI testing**: Always run `pnpm build` before testing CLI changes
239+
2. **Prisma generation**: Run `pnpm db:generate` after any `schema.prisma` changes
240+
3. **Duplicate detection**: Content is hashed (title + content + url) with 24-hour window
241+
4. **Platform initialization**: Database platforms are upserted on `HyperPost` construction
242+
5. **Medium content**: Must be Markdown - MDX auto-converted, plain text rejected
243+
6. **Credential precedence**: Environment variables override stored credentials
244+
7. **pnpm only**: Project uses pnpm workspace - don't use npm or yarn
245+
246+
## Dependencies
247+
248+
Key production dependencies:
249+
- `@atproto/api` - Bluesky API
250+
- `@prisma/client` - Database ORM
251+
- `axios` - HTTP client (Medium, Dev.to, Reddit)
252+
- `commander` - CLI framework
253+
- `discord.js` - Discord API
254+
- `mastodon-api` - Mastodon API
255+
- `@mdx-js/mdx` / `remark` - Content format conversion
256+
- `zod` - Schema validation
257+
258+
## File Locations
259+
260+
- Config: `~/.config/hyper-post/`
261+
- Database: `./hyperpost.db` (SQLite, in project root)
262+
- Built output: `./dist/`
263+
- Source: `./src/`
264+
265+
## Integration with HyperDrift Blog
266+
267+
HyperPost is designed to promote articles from the HyperDrift blog (`/Users/yann/dev/hyperdrift-io/hyper-drift/content/blog`).
268+
269+
### Workflow for New Blog Posts
270+
271+
1. **Write the article** in MDX format with frontmatter:
272+
```yaml
273+
---
274+
title: "Article Title"
275+
date: "2025-02-01T10:00:00Z"
276+
excerpt: "Brief summary for social posts"
277+
tags: ["tag1", "tag2"]
278+
---
279+
```
280+
281+
2. **Preview the promotion**:
282+
```bash
283+
hyper-post promote --slug article-slug --dry-run
284+
```
285+
286+
3. **Post to all platforms**:
287+
```bash
288+
hyper-post promote --slug article-slug
289+
```
290+
291+
4. **Or schedule for optimal timing**:
292+
```bash
293+
hyper-post promote --slug article-slug --schedule "2025-02-01 10:00"
294+
```
295+
296+
### Platform Strategy
297+
298+
- **Short-form** (Mastodon, Bluesky): Uses excerpt
299+
- **Long-form** (Dev.to, Medium): Use `--full-content` for cross-posting the full article
300+
301+
### Currently Configured Platforms
302+
303+
Run `hyper-post platforms` to see active platforms. As of now:
304+
- Mastodon (mastodon.social/@hyperdrift)
305+
- Bluesky (hyper-drift.bsky.social)
306+
- Dev.to (dev.to/hyperdrift)
307+
308+
### Missing Platforms to Consider
309+
310+
- **Reddit** - Requires OAuth setup (client_id, client_secret, username, password)
311+
- **Medium** - Requires integration token
312+
- **Discord** - Requires bot token and channel ID
313+
- **Hashnode** - Developer blogging platform (not yet implemented)
314+
- **Daily.dev** - Content aggregation via Squads (not yet implemented)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ For CI/CD, Docker, or custom setups, you can override stored credentials with en
204204
```bash
205205
# Mastodon
206206
export MASTODON_INSTANCE=your-instance.social
207-
export MASTODON_ACCESS_TOKEN=<paste-mastodon-access-token>
207+
export MASTODON_ACCESS_TOKEN=your_access_token
208208

209209
# Bluesky
210210
export BLUESKY_IDENTIFIER=your-handle.bsky.social

0 commit comments

Comments
 (0)