diff --git a/CLAUDE.md b/CLAUDE.md index 854daed..b87299f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -30,6 +30,89 @@ See `stories/_example/` for a complete reference. - **Storage**: Filebase (IPFS) - **Chain**: Base (L2) +## Local Writer API + +The local writer app runs on `http://localhost:7777` (configurable via `APP_PORT`). All endpoints except auth use `Authorization: Bearer {token}` headers. + +### Authentication + +The OWS passphrase is stored in plaintext in `~/.plotlink-ows/.env` as `OWS_PASSPHRASE`. It is used to decrypt and sign with the OWS wallet. For login verification, the passphrase is hashed with HMAC-SHA256 and compared against the stored hash in the database. + +| Endpoint | Method | Auth | Purpose | +|----------|--------|------|---------| +| `/api/auth/status` | GET | No | Check if passphrase is configured | +| `/api/auth/setup` | POST | No | First-run passphrase setup (≥4 chars) → returns `{ token }` | +| `/api/auth/login` | POST | No | Login with passphrase → returns `{ token }` (24h TTL) | +| `/api/auth/verify` | GET | Bearer | Check token validity | +| `/api/auth/reset-passphrase` | POST | Bearer | Update passphrase | + +### Publishing + +| Endpoint | Method | Purpose | +|----------|--------|---------| +| `/api/publish/preflight` | GET | Check wallet balance, Filebase config | +| `/api/publish/file` | POST | Publish story on-chain (SSE stream of progress events) | +| `/api/publish/retry-index` | POST | Retry indexing for a published file | +| `/api/publish/upload-cover` | POST | Upload cover image — FormData `file` field, **WebP or JPEG only**, max 500KB → returns `{ cid }` | +| `/api/publish/update-storyline` | POST | Update storyline metadata (coverCid, genre, language, isNsfw) | + +**Publish flow:** Upload to IPFS → estimate gas → sign with OWS wallet → broadcast → confirm → index on plotlink.xyz (8s delay + 10 retries × 30s). Genesis files call `createStoryline`, plot files (`plot-*.md`) call `chainPlot`. Content limit: 10K chars. + +**Cover update workflow:** +1. `POST /api/publish/upload-cover` with image file → get `cid` +2. `POST /api/publish/update-storyline` with `{ storylineId, coverCid: cid }` → updates on plotlink.xyz + +**Metadata update workflow:** +1. `POST /api/publish/update-storyline` with `{ storylineId, genre?, language?, isNsfw? }` + +Both upload-cover and update-storyline sign messages with the OWS wallet (message format: `PlotLink: Upload cover image\nTimestamp: {ts}` and `PlotLink: Update storyline #{id}\nTimestamp: {ts}`). + +### Stories + +| Endpoint | Method | Purpose | +|----------|--------|---------| +| `/api/stories` | GET | List all stories | +| `/api/stories/archived` | GET | List archived stories | +| `/api/stories/archive` | POST | Archive a story `{ name }` | +| `/api/stories/restore` | POST | Restore archived story `{ name }` | +| `/api/stories/:name` | GET | Story detail with file contents | +| `/api/stories/:name/:file` | GET | Single file content and publish status | +| `/api/stories/:name/:file` | PUT | Update file content `{ content }` | +| `/api/stories/:name/:file/publish-status` | POST | Record publish result (txHash, storylineId, etc.) | +| `/api/stories/:name/:file/mark-not-indexed` | POST | Mark file as not indexed `{ indexError? }` | + +### Terminal + +| Endpoint | Method | Purpose | +|----------|--------|---------| +| `/api/terminal/spawn` | POST | Spawn Claude CLI session for a story `{ storyName?, resume? }` | +| `/api/terminal/session/:storyName` | GET | Get stored session ID for a story | +| `/api/terminal/status` | GET | List all active terminal sessions | +| `/api/terminal/rename` | POST | Rename session `{ oldName, newName }` | +| `/api/terminal/stop` | POST | Kill default PTY (legacy) | +| `/api/terminal/:storyName` | DELETE | Kill a story's PTY | +| `/api/terminal/:storyName/discard` | DELETE | Kill PTY and clean metadata | +| `/ws/terminal` | WebSocket | Live PTY relay `?token={token}&story={name}&resume={bool}` | + +### Other Endpoints + +| Endpoint | Method | Purpose | +|----------|--------|---------| +| `/api/wallet` | GET | Wallet info and balances (ETH, USDC, PLOT) | +| `/api/wallet/create` | POST | Create OWS wallet if not exists | +| `/api/dashboard` | GET | Writer dashboard stats (stories, costs, royalties) | +| `/api/settings/register-agent` | POST | Register wallet on ERC-8004 | +| `/api/settings/generate-binding` | POST | Generate wallet binding proof | +| `/api/settings/link-status` | GET | Check ERC-8004 registration status | + +### Valid Genres and Languages + +Defined in `lib/genres.ts`: + +**Genres (21):** Romance, Fantasy, Science Fiction, Mystery, Thriller, Horror, Adventure, Historical Fiction, Contemporary Lit, Humor, Poetry, Non-Fiction, Fanfiction, Short Story, Paranormal, Werewolf, LGBTQ+, New Adult, Teen Fiction, Diverse Lit, Others + +**Languages (11):** English, Chinese, Korean, Japanese, Spanish, French, Hindi, Arabic, Portuguese, Russian, Others + ## Commands ```sh diff --git a/package.json b/package.json index ff437fa..2ef7239 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "plotlink-ows", - "version": "1.0.27", + "version": "1.0.28", "bin": { "plotlink-ows": "./bin/plotlink-ows.js" },