···11+## [0.2.0] - 2026-02-01
22+33+### 🚀 Features
44+55+- Added bskyPostRef
66+- Added draft field to frontmatter config
77+88+### ⚙️ Miscellaneous Tasks
99+1010+- Update blog post
1111+- Fix blog build error
1212+- Adjust blog post
1313+- Updated docs
1414+- Version bump
1515+## [0.1.1] - 2026-01-31
1616+1717+### 🐛 Bug Fixes
1818+1919+- Fix tangled url to repo
2020+2121+### ⚙️ Miscellaneous Tasks
2222+2323+- Merge branch 'main' into feat/blog-post
2424+- Updated blog post
2525+- Updated date
2626+- Added publishing
2727+- Spelling and grammar
2828+- Updated package scripts
2929+- Refactored codebase to use node and fs instead of bun
3030+- Version bump
3131+## [0.1.0] - 2026-01-30
3232+3333+### 🚀 Features
3434+3535+- Init
3636+- Added blog post
3737+3838+### ⚙️ Miscellaneous Tasks
3939+4040+- Updated package.json
4141+- Cleaned up commands and libs
4242+- Updated init commands
4343+- Updated greeting
4444+- Updated readme
4545+- Link updates
4646+- Version bump
4747+- Added hugo support through frontmatter parsing
4848+- Version bump
4949+- Updated docs
5050+- Adapted inject.ts pattern
5151+- Updated docs
5252+- Version bump"
5353+- Updated package scripts
5454+- Updated scripts
5555+- Added ignore field to config
5656+- Udpate docs
5757+- Version bump
5858+- Added tags to flow
5959+- Added ability to exit during init flow
6060+- Version bump
6161+- Updated docs
6262+- Updated links
6363+- Updated docs
6464+- Initial refactor
6565+- Checkpoint
6666+- Refactored mapping
6767+- Docs updates
6868+- Docs updates
6969+- Version bump
+10-1
docs/docs/pages/blog/introducing-sequoia.mdx
···24242525It's designed to be run inside your existing repo, build a one-time config, and then be part of your regular workflow by publishing content or updating existing content, all following the Standard.site lexicons. The best part? It's designed to be fully interoperable. It doesn't matter if you're using Astro, 11ty, Hugo, Svelte, Next, Gatsby, Zola, you name it. If it's a static blog with markdown, Sequoia will work (and if for some reason it doesn't, [open an issue!](https://tangled.org/stevedylan.dev/sequoia/issues/new)). Here's a quick demo of Sequoia in action:
26262727-<iframe width="560" height="315" src="https://www.youtube.com/embed/sxursUHq5kw?si=aZSCmkMdYPiYns8u" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
2727+<iframe
2828+ class="w-full"
2929+ style={{aspectRatio: "16/9"}}
3030+ src="https://www.youtube.com/embed/sxursUHq5kw"
3131+ title="YouTube video player"
3232+ frameborder="0"
3333+ allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
3434+ referrerpolicy="strict-origin-when-cross-origin"
3535+ allowfullscreen
3636+></iframe>
28372938ATProto has proven to be one of the more exciting pieces of technology that has surfaced in the past few years, and it gives some of us hope for a web that is open once more. No more walled gardens, full control of our data, and connected through lexicons.
3039
+12-2
docs/docs/pages/config.mdx
···1515| `identity` | `string` | No | - | Which stored identity to use |
1616| `frontmatter` | `object` | No | - | Custom frontmatter field mappings |
1717| `ignore` | `string[]` | No | - | Glob patterns for files to ignore |
1818+| `bluesky` | `object` | No | - | Bluesky posting configuration |
1919+| `bluesky.enabled` | `boolean` | No | `false` | Post to Bluesky when publishing documents |
2020+| `bluesky.maxAgeDays` | `number` | No | `30` | Only post documents published within this many days |
18211922### Example
2023···3134 "frontmatter": {
3235 "publishDate": "date"
3336 },
3434- "ignore": ["_index.md"]
3737+ "ignore": ["_index.md"],
3838+ "bluesky": {
3939+ "enabled": true,
4040+ "maxAgeDays": 30
4141+ }
3542}
3643```
3744···4451| `publishDate` | `string` | Yes | `"publishDate"`, `"pubDate"`, `"date"`, `"createdAt"`, `"created_at"` | Publication date |
4552| `coverImage` | `string` | No | `"ogImage"` | Cover image filename |
4653| `tags` | `string[]` | No | `"tags"` | Post tags/categories |
5454+| `draft` | `boolean` | No | `"draft"` | If `true`, post is skipped during publish |
47554856### Example
4957···5462publishDate: 2024-01-15
5563ogImage: cover.jpg
5664tags: [welcome, intro]
6565+draft: false
5766---
5867```
5968···6574{
6675 "frontmatter": {
6776 "publishDate": "date",
6868- "coverImage": "thumbnail"
7777+ "coverImage": "thumbnail",
7878+ "draft": "private"
6979 }
7080}
7181```
+39-1
docs/docs/pages/publishing.mdx
···1010sequoia publish --dry-run
1111```
12121313-This will print out the posts that it has discovered, what will be published, and how many. Once everything looks good, send it!
1313+This will print out the posts that it has discovered, what will be published, and how many. If Bluesky posting is enabled, it will also show which posts will be shared to Bluesky. Once everything looks good, send it!
14141515```bash [Terminal]
1616sequoia publish
···2727```
28282929Sync will use your ATProto handle to look through all of the `standard.site.document` records on your PDS, and pull down the records that are for the publication in the config.
3030+3131+## Bluesky Posting
3232+3333+Sequoia can automatically post to Bluesky when new documents are published. Enable this in your config:
3434+3535+```json
3636+{
3737+ "bluesky": {
3838+ "enabled": true,
3939+ "maxAgeDays": 30
4040+ }
4141+}
4242+```
4343+4444+When enabled, each new document will create a Bluesky post with the title, description, and canonical URL. If a cover image exists, it will be embedded in the post. The combined content is limited to 300 characters.
4545+4646+The `maxAgeDays` setting prevents flooding your feed when first setting up Sequoia. For example, if you have 40 existing blog posts, only those published within the last 30 days will be posted to Bluesky.
4747+4848+## Draft Posts
4949+5050+Posts with `draft: true` in their frontmatter are automatically skipped during publishing. This lets you work on content without accidentally publishing it.
5151+5252+```yaml
5353+---
5454+title: Work in Progress
5555+draft: true
5656+---
5757+```
5858+5959+If your framework uses a different field name (like `private` or `hidden`), configure it in `sequoia.json`:
6060+6161+```json
6262+{
6363+ "frontmatter": {
6464+ "draft": "private"
6565+ }
6666+}
6767+```
30683169## Troubleshooting
3270
···44 publishDate?: string; // Field name for publish date (default: "publishDate", also checks "pubDate", "date", "createdAt", "created_at")
55 coverImage?: string; // Field name for cover image (default: "ogImage")
66 tags?: string; // Field name for tags (default: "tags")
77+ draft?: string; // Field name for draft status (default: "draft")
88+}
99+1010+// Strong reference for Bluesky post (com.atproto.repo.strongRef)
1111+export interface StrongRef {
1212+ uri: string; // at:// URI format
1313+ cid: string; // Content ID
1414+}
1515+1616+// Bluesky posting configuration
1717+export interface BlueskyConfig {
1818+ enabled: boolean;
1919+ maxAgeDays?: number; // Only post if published within N days (default: 7)
720}
821922export interface PublisherConfig {
···2235 slugField?: string; // Frontmatter field to use when slugSource is "frontmatter" (default: "slug")
2336 removeIndexFromSlug?: boolean; // Remove "/index" or "/_index" suffix from paths (default: false)
2437 textContentField?: string; // Frontmatter field to use for textContent instead of markdown body
3838+ bluesky?: BlueskyConfig; // Optional Bluesky posting configuration
2539}
26402741export interface Credentials {
···3751 tags?: string[];
3852 ogImage?: string;
3953 atUri?: string;
5454+ draft?: boolean;
4055}
41564257export interface BlogPost {
···6883 atUri?: string;
6984 lastPublished?: string;
7085 slug?: string; // The generated slug for this post (used by inject command)
8686+ bskyPostRef?: StrongRef; // Reference to corresponding Bluesky post
7187}
72887389export interface PublicationRecord {