@hutusi/amytis 1.10.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/AGENTS.md +13 -7
  2. package/CHANGELOG.md +17 -0
  3. package/CLAUDE.md +15 -1
  4. package/README.md +25 -2
  5. package/README.zh.md +25 -2
  6. package/TODO.md +6 -4
  7. package/bun.lock +30 -4
  8. package/content/posts/2026-01-21-kitchen-sink/index.mdx +26 -1
  9. package/docs/CONTRIBUTING.md +2 -0
  10. package/docs/DIGITAL_GARDEN.md +7 -1
  11. package/eslint.config.mjs +2 -0
  12. package/package.json +12 -4
  13. package/packages/create-amytis/package.json +13 -0
  14. package/packages/create-amytis/src/index.test.ts +187 -0
  15. package/packages/create-amytis/src/index.ts +230 -0
  16. package/packages/create-amytis/tsconfig.json +14 -0
  17. package/public/images/amytis-screenshot.jpg +0 -0
  18. package/public/next-image-export-optimizer-hashes.json +72 -2
  19. package/site.config.example.ts +12 -1
  20. package/site.config.ts +15 -1
  21. package/src/app/[slug]/[postSlug]/page.tsx +26 -13
  22. package/src/app/[slug]/page.tsx +2 -2
  23. package/src/app/archive/page.tsx +3 -7
  24. package/src/app/books/[slug]/[chapter]/page.tsx +36 -1
  25. package/src/app/books/[slug]/page.tsx +16 -2
  26. package/src/app/books/page.tsx +12 -8
  27. package/src/app/feed.atom/route.ts +62 -0
  28. package/src/app/feed.xml/route.ts +45 -21
  29. package/src/app/flows/[year]/[month]/[day]/page.tsx +8 -0
  30. package/src/app/flows/[year]/page.tsx +1 -1
  31. package/src/app/flows/page/[page]/page.tsx +2 -0
  32. package/src/app/flows/page.tsx +4 -0
  33. package/src/app/globals.css +3 -2
  34. package/src/app/layout.tsx +10 -0
  35. package/src/app/notes/[slug]/page.tsx +1 -2
  36. package/src/app/page.tsx +19 -7
  37. package/src/app/posts/[slug]/page.tsx +32 -8
  38. package/src/app/posts/page/[page]/page.tsx +4 -2
  39. package/src/app/posts/page.tsx +8 -5
  40. package/src/app/series/[slug]/page/[page]/page.tsx +8 -25
  41. package/src/app/series/[slug]/page.tsx +21 -19
  42. package/src/app/series/page.tsx +14 -28
  43. package/src/app/tags/[tag]/page.tsx +1 -1
  44. package/src/app/tags/page.tsx +1 -1
  45. package/src/components/Analytics.tsx +34 -36
  46. package/src/components/AuthorCard.tsx +14 -4
  47. package/src/components/BookMobileNav.tsx +8 -34
  48. package/src/components/BookSidebar.tsx +17 -107
  49. package/src/components/CodeBlock.test.tsx +19 -0
  50. package/src/components/CodeBlock.tsx +20 -16
  51. package/src/components/CuratedSeriesSection.tsx +10 -9
  52. package/src/components/ExternalLinks.tsx +1 -1
  53. package/src/components/FeaturedStoriesSection.tsx +10 -10
  54. package/src/components/FlowCalendarSidebar.tsx +10 -7
  55. package/src/components/FlowContent.tsx +33 -5
  56. package/src/components/Footer.tsx +28 -6
  57. package/src/components/InlineBookToc.tsx +56 -0
  58. package/src/components/KnowledgeGraph.tsx +26 -0
  59. package/src/components/MarkdownRenderer.test.tsx +41 -0
  60. package/src/components/MarkdownRenderer.tsx +33 -6
  61. package/src/components/NoteSidebar.tsx +6 -76
  62. package/src/components/Pagination.tsx +2 -2
  63. package/src/components/PostList.tsx +77 -61
  64. package/src/components/PostNavigation.tsx +5 -5
  65. package/src/components/PostSidebar.tsx +10 -106
  66. package/src/components/PrevNextNav.tsx +63 -0
  67. package/src/components/RecentNotesSection.tsx +1 -1
  68. package/src/components/RelatedPosts.tsx +1 -1
  69. package/src/components/RssFeedWidget.tsx +27 -8
  70. package/src/components/SectionLabel.tsx +16 -0
  71. package/src/components/SelectedBooksSection.tsx +2 -1
  72. package/src/components/SeriesCatalog.tsx +72 -68
  73. package/src/components/SeriesList.tsx +9 -35
  74. package/src/components/SeriesSidebar.tsx +2 -1
  75. package/src/components/TagContentTabs.tsx +17 -12
  76. package/src/components/TagPageHeader.tsx +12 -2
  77. package/src/components/TagSidebar.tsx +3 -2
  78. package/src/components/TagsIndexClient.tsx +1 -1
  79. package/src/components/TocPanel.tsx +67 -0
  80. package/src/hooks/useActiveHeading.ts +32 -0
  81. package/src/hooks/useSidebarAutoScroll.ts +19 -0
  82. package/src/i18n/translations.ts +26 -4
  83. package/src/layouts/BookLayout.tsx +10 -40
  84. package/src/layouts/PostLayout.tsx +9 -9
  85. package/src/layouts/SimpleLayout.tsx +2 -2
  86. package/src/lib/feed-utils.ts +68 -0
  87. package/src/lib/format-utils.test.ts +27 -0
  88. package/src/lib/format-utils.ts +3 -0
  89. package/src/lib/json-ld.ts +236 -0
  90. package/src/lib/markdown.ts +38 -4
  91. package/src/lib/rehype-image-metadata.test.ts +7 -1
  92. package/src/lib/rehype-image-metadata.ts +10 -0
  93. package/src/lib/scroll-utils.ts +11 -0
  94. package/src/lib/shuffle.ts +21 -0
  95. package/src/lib/urls.ts +15 -0
  96. package/tests/e2e/navigation.test.ts +15 -1
  97. package/tests/integration/books.test.ts +61 -0
  98. package/tests/integration/feed-utils.test.ts +145 -0
  99. package/tests/integration/series.test.ts +9 -0
  100. package/tests/unit/static-params.test.ts +35 -2
  101. /package/public/{screenshot.png → images/screenshot.png} +0 -0
package/AGENTS.md CHANGED
@@ -1,21 +1,25 @@
1
1
  # Repository Guidelines
2
2
 
3
3
  ## Project Structure & Module Organization
4
- - `src/app/`: Next.js App Router pages and route handlers (`posts`, `series`, `tags`, `authors`, feeds, sitemap).
4
+ - `src/app/`: Next.js App Router pages and route handlers (`posts`, `series`, `books`, `flows`, `notes`, `tags`, `authors`, feeds, graph, sitemap, custom `[slug]` routes).
5
5
  - `src/components/`: Reusable UI building blocks (cards, navigation, search, i18n/theme controls).
6
- - `src/lib/`: Content parsing and shared logic (`markdown.ts`, i18n helpers, rehype utilities).
7
- - `content/posts/`, `content/series/`: Markdown/MDX source content. Use folder posts (`index.mdx` + `images/` or `assets/`) when media is co-located.
6
+ - `src/lib/`: Content parsing and shared logic (`markdown.ts`, feed helpers, URL helpers, rehype/remark utilities).
7
+ - `content/`: Markdown/MDX source content for posts, series, books, notes, flows, and static pages. Use folder posts (`index.mdx` + `images/` or `assets/`) when media is co-located.
8
8
  - `tests/`: Integration/e2e/tooling suites; keep focused utility tests near source (example: `src/lib/markdown.test.ts`).
9
9
  - `scripts/`: Bun-based authoring/import tooling.
10
+ - `packages/create-amytis/`: The `bun create amytis` scaffold CLI; keep its tests aligned with repo scaffolding behavior.
10
11
 
11
12
  ## Build, Test, and Development Commands
12
13
  - `bun install`: Install dependencies.
13
14
  - `bun dev`: Run local dev server at `http://localhost:3000`.
14
- - `bun run build`: Production export build (asset copy + Next build + image optimizer).
15
- - `bun run build:dev`: Build without export image optimization.
16
- - `bun run clean`: Remove generated outputs (`.next`, `out`, `public/posts`).
15
+ - `bun run build`: Production export build (copy assets, generate graph, Next build, optimize images, generate Pagefind index in `out/pagefind`).
16
+ - `bun run build:dev`: Build without export image optimization and generate the dev search index in `public/pagefind`.
17
+ - `bun run build:graph`: Regenerate the knowledge graph data.
18
+ - `bun run validate`: Run the recommended pre-PR validation sequence (`lint`, `test`, `build:dev`).
19
+ - `bun run clean`: Remove generated outputs (`.next`, `out`, `public/posts`, `public/books`, `public/flows`).
17
20
  - `bun run lint`: Run ESLint.
18
21
  - `bun test` / `bun run test:unit` / `bun run test:int` / `bun run test:e2e`: Run all or scoped tests.
22
+ - Content tooling: `bun run new`, `bun run new-weekly`, `bun run new-series`, `bun run new-note`, `bun run new-flow`, `bun run new-flow-from-chat`, `bun run new-from-pdf`, `bun run new-from-images`, `bun run import-book`, `bun run sync-book`, `bun run series-draft`.
19
23
 
20
24
  ## Coding Style & Naming Conventions
21
25
  - Use TypeScript for app and utility code; MDX/Markdown for content.
@@ -27,12 +31,14 @@
27
31
  - Project uses `output: "export"` and `trailingSlash: true` in `next.config.ts`.
28
32
  - In `generateStaticParams()`, return raw segment values; do not pre-encode with `encodeURIComponent`.
29
33
  - Never link to route placeholders like `/posts/[slug]`; always link to concrete slugs (for example, `/posts/中文测试文章`).
34
+ - Posts may also resolve through custom top-level paths via `series.customPaths` and `[slug]/[postSlug]`; preserve those URL helpers instead of hardcoding paths.
30
35
  - When touching dynamic routes, verify both ASCII and Unicode paths.
31
36
 
32
37
  ## Testing Guidelines
33
38
  - Test framework: Bun (`bun:test`). File pattern: `*.test.ts`.
34
- - Add tests when changing slug resolution, content parsing, routing, or scaffolding scripts.
39
+ - Add tests when changing slug resolution, content parsing, routing, feed generation, or scaffolding scripts.
35
40
  - Before PR: run `bun run lint && bun test && bun run build:dev`.
41
+ - Search in local dev depends on the Pagefind output from `bun run build:dev`; regenerate it when changing content or search behavior.
36
42
 
37
43
  ## Commit & Pull Request Guidelines
38
44
  - Follow Conventional Commits used in history (`feat:`, `fix:`, `refactor:`, `docs:`, `release:`).
package/CHANGELOG.md CHANGED
@@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.11.0] - 2026-03-07
9
+
10
+ ### Changed
11
+ - **Feed Output Quality**: RSS and Atom feeds now render Markdown content as HTML, include richer item metadata, and send explicit cache headers for static deployments.
12
+ - **Metadata Consistency**: Consolidated image URL resolution so Open Graph and JSON-LD metadata use the same asset handling logic.
13
+ - **Documentation Sync**: Updated the English and Chinese READMEs plus contributor guidance to reflect current scaffolding behavior, dev-search setup, and workspace instructions.
14
+
15
+ ### Fixed
16
+ - **RSS Standards Compliance**: Corrected the RSS MIME type to `application/rss+xml` and improved RSS/Atom structure for better reader compatibility.
17
+ - **Feed Metadata Fidelity**: Improved handling of author fields, item content, and image metadata across feed generation and social preview output.
18
+ - **Post Page Polish**: Improved post page OG images, previous/next navigation consistency, and TOC indentation.
19
+ - **Book Link Consistency**: Standardized book links to use the shared URL helper.
20
+
21
+ ### Docs
22
+ - **Developer Notes**: Added inline documentation for `getFeedItems()` behavior and configuration handling.
23
+ - **Repository Instructions**: Refreshed repository-level agent instructions to match the current workspace layout and release workflow.
24
+
8
25
  ## [1.10.0] - 2026-03-02
9
26
 
10
27
  ### Added
package/CLAUDE.md CHANGED
@@ -96,6 +96,15 @@ bun run sync-book <slug> # Sync chapters list for one book
96
96
 
97
97
  Date-prefixed filenames (`2026-01-01-my-post.mdx`) extract dates automatically.
98
98
 
99
+ ## Config Files
100
+
101
+ There are two config files that must be kept in sync:
102
+
103
+ - **`site.config.ts`** — the live config for this repo (i18n enabled; locale-aware fields use `{ en: '...', zh: '...' }` objects)
104
+ - **`site.config.example.ts`** — single-language starter template shipped via `create-amytis`; locale-aware fields use plain strings; optional features (books, flow) default to disabled
105
+
106
+ **Rule:** Any schema change to `site.config.ts` (new field, renamed field, type change) must be mirrored in `site.config.example.ts`. Locale-aware values (`string | Record<string, string>`) should use plain strings in the example.
107
+
99
108
  ## Configuration (`site.config.ts`)
100
109
 
101
110
  Key configuration options:
@@ -109,8 +118,12 @@ Key configuration options:
109
118
  - `i18n` - Default locale and supported locales
110
119
  - `featured.series` - Scrollable series: `scrollThreshold` (default: 2), `maxItems` (default: 6)
111
120
  - `featured.stories` - Scrollable stories: `scrollThreshold` (default: 1), `maxItems` (default: 5)
112
- - `analytics.provider` - 'umami' | 'plausible' | 'google' | null
121
+ - `analytics.providers` - array of enabled providers: `['umami', 'google']`; `[]` disables analytics
113
122
  - `comments.provider` - 'giscus' | 'disqus' | null
123
+ - `feed.format` - 'rss' | 'atom' | 'both'
124
+ - `feed.content` - 'full' | 'excerpt'
125
+ - `feed.maxItems` - max feed items (0 = unlimited)
126
+ - `footer.bottomLinks` - custom links in the footer bottom bar (ICP, cookie policy, etc.); `text` accepts plain string or `{ en, zh }` locale map
114
127
  - `posts.basePath` - Custom URL prefix for all posts (default: `'posts'`); e.g. `'articles'` → posts at `/articles/[slug]`
115
128
  - `posts.authors.default` - Fallback authors when a post has none set in frontmatter
116
129
  - `posts.authors.showInHeader` - Show author byline below post title (default: true)
@@ -125,6 +138,7 @@ Key configuration options:
125
138
  ```yaml
126
139
  ---
127
140
  title: "Post Title"
141
+ subtitle: "Optional subtitle line" # Rendered below the title in italic
128
142
  date: "2026-01-01"
129
143
  excerpt: "Optional summary (auto-generated if omitted)"
130
144
  category: "Category Name"
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  [**Live Demo**](https://amytis.vercel.app/)
8
8
 
9
- ![Amytis Screenshot](public/screenshot.png)
9
+ ![Amytis Screenshot](public/images/amytis-screenshot.jpg)
10
10
 
11
11
  ## The Knowledge Ladder
12
12
 
@@ -50,9 +50,13 @@ Each stage builds on the previous one, so your garden can evolve naturally.
50
50
  - Co-located assets: keep images inside post folders (`./images/`).
51
51
  - Date-prefixed filenames: `2026-01-01-my-post.mdx`.
52
52
  - Draft support for posts, series, books, and flows.
53
+ - **Author Ecosystem:** Per-author profile pages with bio, avatar, and social links. Posts are filterable by author; an optional author card appears at the end of each post.
53
54
  - **Performance & SEO:**
54
55
  - Fully static export with optimized WebP images.
55
- - Native sitemap and RSS feed generation.
56
+ - Open Graph and Twitter card metadata for every content type.
57
+ - JSON-LD structured data (`BlogPosting`, `Book`, `Article`) for Google rich results.
58
+ - RSS/Atom feed with configurable format (`rss` | `atom` | `both`) and content depth (`full` | `excerpt`).
59
+ - Feed auto-discovery links in `<head>`, native sitemap generation.
56
60
  - Multilingual reading time estimate (supports Latin and CJK).
57
61
  - **Integrations:**
58
62
  - Analytics: Umami, Plausible, or Google Analytics.
@@ -71,6 +75,20 @@ Each stage builds on the previous one, so your garden can evolve naturally.
71
75
 
72
76
  ## Quick Start
73
77
 
78
+ ### New Project (Recommended)
79
+
80
+ Scaffold a new Amytis site with one command:
81
+
82
+ ```bash
83
+ bun create amytis my-garden
84
+ cd my-garden
85
+ bun dev
86
+ ```
87
+
88
+ The scaffold command downloads the latest tagged Amytis release, installs dependencies, and patches `site.config.ts` and `package.json` with your project metadata.
89
+
90
+ ### Clone & Run
91
+
74
92
  1. **Install Dependencies:**
75
93
  ```bash
76
94
  bun install
@@ -82,6 +100,8 @@ Each stage builds on the previous one, so your garden can evolve naturally.
82
100
  ```
83
101
  Visit [http://localhost:3000](http://localhost:3000).
84
102
 
103
+ > **Search in dev:** the Pagefind index is generated during `bun run build:dev`. Run it once before testing Cmd/Ctrl+K locally, and re-run it after content changes.
104
+
85
105
  3. **Build for Production (Static Export):**
86
106
  ```bash
87
107
  bun run build
@@ -115,6 +135,7 @@ bun run test:e2e
115
135
 
116
136
  ## Create Content
117
137
  bun run new "Post Title"
138
+ bun run new-weekly "Weekly Topic"
118
139
  bun run new-series "Series Name"
119
140
  bun run new-note "Concept"
120
141
  bun run new-flow
@@ -204,6 +225,8 @@ amytis/
204
225
  components/ # React components
205
226
  lib/
206
227
  markdown.ts # Data access layer
228
+ packages/
229
+ create-amytis/ # `bun create amytis` scaffold CLI
207
230
  site.config.ts # Site configuration
208
231
  ```
209
232
 
package/README.zh.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  [**在线演示**](https://amytis.vercel.app/)
8
8
 
9
- ![Amytis 截图](public/screenshot.png)
9
+ ![Amytis 截图](public/images/amytis-screenshot.jpg)
10
10
 
11
11
  ## 知识阶梯
12
12
 
@@ -43,9 +43,13 @@ Amytis 围绕一条从粗糙到精炼的知识路径构建:
43
43
  - 自动系统主题检测(明/暗)
44
44
  - 四套配色主题:default、blue、rose、amber
45
45
  - 吸顶目录与阅读进度跟踪
46
+ - **作者生态**:每位作者有独立主页,包含简介、头像与社交链接。文章支持按作者筛选,并可在文末显示作者卡片。
46
47
  - **性能与 SEO**:
47
48
  - 全静态导出与 WebP 优化
48
- - 自动 sitemapRSS
49
+ - 每种内容类型均有完整的 Open Graph Twitter Card 元数据
50
+ - JSON-LD 结构化数据(`BlogPosting`、`Book`、`Article`),支持 Google 富媒体搜索结果
51
+ - RSS/Atom 订阅源,格式(`rss` | `atom` | `both`)与内容深度(`full` | `excerpt`)可配置
52
+ - `<head>` 自动注入 Feed 发现链接,原生 sitemap 生成
49
53
  - 支持 Latin/CJK 的多语言阅读时长估算
50
54
  - **集成能力**:
51
55
  - 统计:Umami / Plausible / Google Analytics
@@ -62,6 +66,20 @@ Amytis 围绕一条从粗糙到精炼的知识路径构建:
62
66
 
63
67
  ## 快速开始
64
68
 
69
+ ### 新建项目(推荐)
70
+
71
+ 一条命令创建新的 Amytis 站点:
72
+
73
+ ```bash
74
+ bun create amytis my-garden
75
+ cd my-garden
76
+ bun dev
77
+ ```
78
+
79
+ 该脚手架会下载最新发布版 Amytis,自动安装依赖,并根据你的项目信息更新 `site.config.ts` 和 `package.json`。
80
+
81
+ ### 克隆运行
82
+
65
83
  1. **安装依赖**
66
84
  ```bash
67
85
  bun install
@@ -73,6 +91,8 @@ Amytis 围绕一条从粗糙到精炼的知识路径构建:
73
91
  ```
74
92
  打开 [http://localhost:3000](http://localhost:3000)。
75
93
 
94
+ > **本地搜索说明:** Pagefind 索引是在执行 `bun run build:dev` 时生成的。本地测试 Cmd/Ctrl+K 前先运行一次;内容更新后也需要重新生成。
95
+
76
96
  3. **生产构建(静态导出)**
77
97
  ```bash
78
98
  bun run build
@@ -106,6 +126,7 @@ bun run test:e2e
106
126
 
107
127
  ## Create Content
108
128
  bun run new "Post Title"
129
+ bun run new-weekly "Weekly Topic"
109
130
  bun run new-series "Series Name"
110
131
  bun run new-note "Concept"
111
132
  bun run new-flow
@@ -157,6 +178,8 @@ amytis/
157
178
  app/
158
179
  components/
159
180
  lib/
181
+ packages/
182
+ create-amytis/
160
183
  site.config.ts
161
184
  ```
162
185
 
package/TODO.md CHANGED
@@ -1,18 +1,19 @@
1
1
  # Amytis Roadmap
2
2
 
3
3
  ## 🚀 Priority UX & Engineering
4
- - [ ] **Image Zoom**: Implement medium-zoom or a lightbox for MDX images.
5
4
  - [ ] **Breadcrumbs**: Extend Flow breadcrumbs to standard Posts and Books.
6
5
  - [ ] **Dynamic OG**: Generate automated social cards with Satori for every post.
7
6
  - [ ] **PWA Support**: Add manifest and service worker for offline reading.
8
- - [ ] **SEO Boost**: Implement JSON-LD structured data for Articles, Books, and Breadcrumbs.
7
+ - [ ] **Image Zoom**: Implement medium-zoom or a lightbox for MDX images.
9
8
 
10
9
  ## 🌿 Digital Garden Evolution
11
- - [ ] **Knowledge Graph**:
10
+ - [ ] **Knowledge Graph**:
12
11
  - [ ] Interactive fullscreen mode for the graph.
13
12
  - [ ] Filter graph by tags or content types.
14
13
  - [ ] "Local Graph" view in the sidebar of individual notes.
15
- - [ ] **Discovery**:
14
+ - [ ] **Hover Preview**: Show a floating excerpt card when hovering over wiki-links, without navigating away.
15
+ - [ ] **Transclusion**: Embed another note or post's content inline using `![[slug]]` syntax.
16
+ - [ ] **Discovery**:
16
17
  - [ ] "On this day" section for Flows (history from previous years).
17
18
  - [ ] RSS/Atom feeds for specific categories or tags.
18
19
  - [ ] **Notes**: Support for un-linked mentions (searching for note titles in plain text).
@@ -23,6 +24,7 @@
23
24
  - [ ] **Optimization**: Automatically compress and resize co-located images during build.
24
25
 
25
26
  ## ✅ Completed Highlights
27
+ - [x] **JSON-LD Structured Data**: `BlogPosting`, `Book`, and `Article` schemas for Google rich results.
26
28
  - [x] **Digital Garden**: Notes, Wiki-links, Backlinks, and interactive Knowledge Graph.
27
29
  - [x] **Pagefind Search**: High-performance static full-text indexing with rich UI.
28
30
  - [x] **Smart Navigation**: Persistent "Previous" and "Next" article links on all posts.
package/bun.lock CHANGED
@@ -11,6 +11,7 @@
11
11
  "github-slugger": "^2.0.0",
12
12
  "gray-matter": "^4.0.3",
13
13
  "image-size": "^2.0.2",
14
+ "katex": "^0.16.33",
14
15
  "mermaid": "^11.12.3",
15
16
  "next": "16.1.6",
16
17
  "next-image-export-optimizer": "^1.20.1",
@@ -23,8 +24,12 @@
23
24
  "rehype-katex": "^7.0.1",
24
25
  "rehype-raw": "^7.0.0",
25
26
  "rehype-slug": "^6.0.0",
27
+ "rehype-stringify": "^10.0.1",
26
28
  "remark-gfm": "^4.0.1",
27
29
  "remark-math": "^6.0.0",
30
+ "remark-parse": "^11.0.0",
31
+ "remark-rehype": "^11.1.2",
32
+ "unified": "^11.0.5",
28
33
  "unist-util-visit": "^5.1.0",
29
34
  "zod": "^4.3.6",
30
35
  },
@@ -32,7 +37,9 @@
32
37
  "@tailwindcss/postcss": "^4.1.18",
33
38
  "@types/bun": "^1.3.9",
34
39
  "@types/d3": "^7.4.3",
40
+ "@types/hast": "^3.0.4",
35
41
  "@types/image-size": "^0.8.0",
42
+ "@types/mdast": "^4.0.4",
36
43
  "@types/node": "^24.10.13",
37
44
  "@types/react": "^19.2.14",
38
45
  "@types/react-dom": "^19.2.3",
@@ -46,6 +53,13 @@
46
53
  "typescript": "^5.9.3",
47
54
  },
48
55
  },
56
+ "packages/create-amytis": {
57
+ "name": "create-amytis",
58
+ "version": "0.1.0",
59
+ "bin": {
60
+ "create-amytis": "./dist/index.js",
61
+ },
62
+ },
49
63
  },
50
64
  "trustedDependencies": [
51
65
  "sharp",
@@ -558,7 +572,7 @@
558
572
 
559
573
  "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="],
560
574
 
561
- "commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
575
+ "commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="],
562
576
 
563
577
  "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
564
578
 
@@ -568,6 +582,8 @@
568
582
 
569
583
  "cose-base": ["cose-base@1.0.3", "", { "dependencies": { "layout-base": "^1.0.0" } }, "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg=="],
570
584
 
585
+ "create-amytis": ["create-amytis@workspace:packages/create-amytis"],
586
+
571
587
  "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
572
588
 
573
589
  "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
@@ -842,6 +858,8 @@
842
858
 
843
859
  "hast-util-raw": ["hast-util-raw@9.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "hast-util-from-parse5": "^8.0.0", "hast-util-to-parse5": "^8.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "parse5": "^7.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw=="],
844
860
 
861
+ "hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="],
862
+
845
863
  "hast-util-to-jsx-runtime": ["hast-util-to-jsx-runtime@2.3.6", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "vfile-message": "^4.0.0" } }, "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg=="],
846
864
 
847
865
  "hast-util-to-parse5": ["hast-util-to-parse5@8.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA=="],
@@ -970,7 +988,7 @@
970
988
 
971
989
  "jsx-ast-utils": ["jsx-ast-utils@3.3.5", "", { "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", "object.assign": "^4.1.4", "object.values": "^1.1.6" } }, "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ=="],
972
990
 
973
- "katex": ["katex@0.16.28", "", { "dependencies": { "commander": "^8.3.0" }, "bin": { "katex": "cli.js" } }, "sha512-YHzO7721WbmAL6Ov1uzN/l5mY5WWWhJBSW+jq4tkfZfsxmo1hu6frS0EOswvjBUnWE6NtjEs48SFn5CQESRLZg=="],
991
+ "katex": ["katex@0.16.33", "", { "dependencies": { "commander": "^8.3.0" }, "bin": { "katex": "cli.js" } }, "sha512-q3N5u+1sY9Bu7T4nlXoiRBXWfwSefNGoKeOwekV+gw0cAXQlz2Ww6BLcmBxVDeXBMUDQv6fK5bcNaJLxob3ZQA=="],
974
992
 
975
993
  "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
976
994
 
@@ -1260,6 +1278,8 @@
1260
1278
 
1261
1279
  "rehype-slug": ["rehype-slug@6.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "github-slugger": "^2.0.0", "hast-util-heading-rank": "^3.0.0", "hast-util-to-string": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A=="],
1262
1280
 
1281
+ "rehype-stringify": ["rehype-stringify@10.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-to-html": "^9.0.0", "unified": "^11.0.0" } }, "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA=="],
1282
+
1263
1283
  "remark-gfm": ["remark-gfm@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-gfm": "^3.0.0", "micromark-extension-gfm": "^3.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg=="],
1264
1284
 
1265
1285
  "remark-math": ["remark-math@6.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-math": "^3.0.0", "micromark-extension-math": "^3.0.0", "unified": "^11.0.0" } }, "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA=="],
@@ -1504,6 +1524,8 @@
1504
1524
 
1505
1525
  "cytoscape-fcose/cose-base": ["cose-base@2.2.0", "", { "dependencies": { "layout-base": "^2.0.0" } }, "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g=="],
1506
1526
 
1527
+ "d3-dsv/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
1528
+
1507
1529
  "d3-sankey/d3-array": ["d3-array@2.12.1", "", { "dependencies": { "internmap": "^1.0.0" } }, "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ=="],
1508
1530
 
1509
1531
  "d3-sankey/d3-shape": ["d3-shape@1.3.7", "", { "dependencies": { "d3-path": "1" } }, "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw=="],
@@ -1520,16 +1542,20 @@
1520
1542
 
1521
1543
  "is-bun-module/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
1522
1544
 
1523
- "katex/commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="],
1524
-
1525
1545
  "mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
1526
1546
 
1547
+ "mermaid/katex": ["katex@0.16.28", "", { "dependencies": { "commander": "^8.3.0" }, "bin": { "katex": "cli.js" } }, "sha512-YHzO7721WbmAL6Ov1uzN/l5mY5WWWhJBSW+jq4tkfZfsxmo1hu6frS0EOswvjBUnWE6NtjEs48SFn5CQESRLZg=="],
1548
+
1549
+ "micromark-extension-math/katex": ["katex@0.16.28", "", { "dependencies": { "commander": "^8.3.0" }, "bin": { "katex": "cli.js" } }, "sha512-YHzO7721WbmAL6Ov1uzN/l5mY5WWWhJBSW+jq4tkfZfsxmo1hu6frS0EOswvjBUnWE6NtjEs48SFn5CQESRLZg=="],
1550
+
1527
1551
  "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
1528
1552
 
1529
1553
  "next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
1530
1554
 
1531
1555
  "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
1532
1556
 
1557
+ "rehype-katex/katex": ["katex@0.16.28", "", { "dependencies": { "commander": "^8.3.0" }, "bin": { "katex": "cli.js" } }, "sha512-YHzO7721WbmAL6Ov1uzN/l5mY5WWWhJBSW+jq4tkfZfsxmo1hu6frS0EOswvjBUnWE6NtjEs48SFn5CQESRLZg=="],
1558
+
1533
1559
  "sharp/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
1534
1560
 
1535
1561
  "@eslint/eslintrc/js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
@@ -7,7 +7,7 @@ tags: ["features", "test", "demo"]
7
7
  authors: ["Amytis Team", "Tester"]
8
8
  layout: "post"
9
9
  latex: true
10
- toc: false
10
+ toc: true
11
11
  ---
12
12
 
13
13
  # Heading Level 1
@@ -128,6 +128,31 @@ sequenceDiagram
128
128
  ### Raw HTML (Quoted)
129
129
  <img src="./assets/test.svg" width="100" alt="Small HTML Image" style="border: 2px solid #ccc; border-radius: 8px;" />
130
130
 
131
+ ### Photos from Public Directory
132
+
133
+ ![Antelope Canyon](/images/antelope-canyon.jpg)
134
+
135
+ ![Mountain Landscape](/images/mountains.jpg)
136
+
137
+ ![Lake View](/images/lake.jpg)
138
+
139
+ ![Flowers](/images/flowers.jpg)
140
+
141
+ ![Cappadocia](/images/cappadocia.jpg)
142
+
143
+ ![Galaxy](/images/galaxy.jpg)
144
+
145
+ ### Vibrant Waves (AVIF format)
146
+
147
+ ![Vibrant Waves](/images/vibrant-waves.avif)
148
+
149
+ ### Side by Side (Raw HTML)
150
+
151
+ <div style="display: flex; gap: 1rem; flex-wrap: wrap;">
152
+ <img src="/images/antelope-canyon.jpg" alt="Antelope Canyon" style="width: 48%; border-radius: 8px;" />
153
+ <img src="/images/cappadocia.jpg" alt="Cappadocia" style="width: 48%; border-radius: 8px;" />
154
+ </div>
155
+
131
156
  ---
132
157
 
133
158
  ## Tables
@@ -93,7 +93,9 @@ bun run series-draft "my-series" --undraft
93
93
  ```bash
94
94
  bun test # Run all tests
95
95
  bun run test:unit # Run unit tests
96
+ bun run test:int # Run integration tests
96
97
  bun run test:e2e # Run end-to-end tests
98
+ bun run validate # Lint + test + build:dev
97
99
  ```
98
100
 
99
101
  ## Building
@@ -53,7 +53,7 @@ Flows are a stream-style collection of daily notes, micro-blogging, or imported
53
53
 
54
54
  ## Configuration
55
55
 
56
- In `site.config.ts`, ensure flow features are enabled (the graph and notes surfaces are flow-related in current routing):
56
+ Flows are controlled by `site.config.ts`, while notes and the graph are always routed when corresponding content exists:
57
57
 
58
58
  ```typescript
59
59
  export const siteConfig = {
@@ -66,3 +66,9 @@ export const siteConfig = {
66
66
  }
67
67
  };
68
68
  ```
69
+
70
+ Related settings that shape the digital-garden experience live alongside that flag:
71
+
72
+ - `flows.recentCount`: controls how many flow entries appear on the homepage.
73
+ - `pagination.flows` and `pagination.notes`: control listing page sizes.
74
+ - `homepage.sections`: lets you enable, disable, or reorder homepage sections such as recent flows.
package/eslint.config.mjs CHANGED
@@ -14,6 +14,8 @@ const eslintConfig = defineConfig([
14
14
  "next-env.d.ts",
15
15
  // Generated at build time — not authored code
16
16
  "public/pagefind/**",
17
+ // Package compiled output — not authored code
18
+ "packages/*/dist/**",
17
19
  ]),
18
20
  ]);
19
21
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hutusi/amytis",
3
- "version": "1.10.0",
3
+ "version": "1.11.0",
4
4
  "description": "A high-performance digital garden and blog engine with Next.js 16 and Tailwind CSS v4",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,8 +33,8 @@
33
33
  "deploy": "bun scripts/deploy.ts",
34
34
  "start": "next start",
35
35
  "lint": "eslint",
36
- "test": "bun test src tests/unit tests/tooling && bun run test:int",
37
- "test:unit": "bun test src tests/unit",
36
+ "test": "bun test src tests/unit tests/tooling packages/create-amytis/src && bun run test:int",
37
+ "test:unit": "bun test src tests/unit packages/create-amytis/src",
38
38
  "test:int": "bun test tests/integration",
39
39
  "test:e2e": "bun test tests/e2e"
40
40
  },
@@ -45,6 +45,7 @@
45
45
  "github-slugger": "^2.0.0",
46
46
  "gray-matter": "^4.0.3",
47
47
  "image-size": "^2.0.2",
48
+ "katex": "^0.16.33",
48
49
  "mermaid": "^11.12.3",
49
50
  "next": "16.1.6",
50
51
  "next-image-export-optimizer": "^1.20.1",
@@ -57,8 +58,12 @@
57
58
  "rehype-katex": "^7.0.1",
58
59
  "rehype-raw": "^7.0.0",
59
60
  "rehype-slug": "^6.0.0",
61
+ "rehype-stringify": "^10.0.1",
60
62
  "remark-gfm": "^4.0.1",
61
63
  "remark-math": "^6.0.0",
64
+ "remark-parse": "^11.0.0",
65
+ "remark-rehype": "^11.1.2",
66
+ "unified": "^11.0.5",
62
67
  "unist-util-visit": "^5.1.0",
63
68
  "zod": "^4.3.6"
64
69
  },
@@ -66,7 +71,9 @@
66
71
  "@tailwindcss/postcss": "^4.1.18",
67
72
  "@types/bun": "^1.3.9",
68
73
  "@types/d3": "^7.4.3",
74
+ "@types/hast": "^3.0.4",
69
75
  "@types/image-size": "^0.8.0",
76
+ "@types/mdast": "^4.0.4",
70
77
  "@types/node": "^24.10.13",
71
78
  "@types/react": "^19.2.14",
72
79
  "@types/react-dom": "^19.2.3",
@@ -86,5 +93,6 @@
86
93
  "trustedDependencies": [
87
94
  "sharp",
88
95
  "unrs-resolver"
89
- ]
96
+ ],
97
+ "workspaces": ["packages/*"]
90
98
  }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "create-amytis",
3
+ "version": "0.1.0",
4
+ "description": "Create a new Amytis digital garden",
5
+ "license": "MIT",
6
+ "bin": { "create-amytis": "./dist/index.js" },
7
+ "scripts": {
8
+ "build": "bun build src/index.ts --outfile dist/index.js --target node --sourcemap=none",
9
+ "dev": "bun src/index.ts",
10
+ "test": "bun test src"
11
+ },
12
+ "files": ["dist"]
13
+ }