Guidance for AI agents (and human collaborators) working on the LaCogito personal site — a Jekyll blog forked from Huxpro’s theme, hosted via GitHub Pages.
Read this before editing posts, pages, layouts, or theme assets.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
.
├── _config.yml # Jekyll config (collections, plugins, markdown, sidebar, PWA)
├── _layouts/ # default, page, post, intro, poem, keynote
├── _includes/ # nav, head, footer, intro-header, short-about, featured-tags, ...
├── _plugins/ # ruby3_compat.rb
├── content/
│ ├── _posts/ # blog posts (YYYY-MM-DD-title.md)
│ ├── _drafts/ # unpublished drafts (incl. post-template.md)
│ ├── _poems/ # poem collection (title.md, no date prefix)
│ ├── about.html # /about/ page (multilingual zh + en)
│ ├── archive.html # /archive/ tag-filtered post index
│ └── poems.html # /poems/ poem listing
├── img/ # header backgrounds, avatar, favicon, inpost/
├── less/ # LESS sources (compiled to css/ via Grunt)
├── css/ # compiled CSS (do not edit by hand)
├── js/ # site JS (minified by Grunt)
├── pwa/ # service worker / manifest assets
├── sw.js # service worker entry
├── index.html # home (paginated post list, layout: page)
├── _config.yml
├── Gemfile # jekyll ~> 4.4, jekyll-paginate, jekyll-redirect-from
├── package.json # Grunt toolchain (less, uglify, watch)
├── Gruntfile.js # LESS→CSS + JS uglify + banner
├── Rakefile # `rake post title="..."` scaffolder
└── .agents/
├── rules/ # post-writing-style.md (pre-2025 voice/tone/structure rules)
└── skills/
Key conventions:
collections_dir: content — all collections (_posts, _poems) live under content/.permalink: pretty, paginate: 10, markdown: kramdown with GFM input.future: true — posts dated in the future will publish.content/ with a title and navigation_weight in its front matter appears in the navbar (sorted ascending by weight), unless hide-in-nav: true.Prefer the Rake scaffolder so the front matter matches the theme exactly:
1
$ rake post title="A Title" subtitle="A subtitle" [date="YYYY-MM-DD"]
This creates content/_posts/YYYY-MM-DD-a-title.md with the canonical front matter. Edit the generated file — do not hand-roll the filename or front matter, since the Rake task enforces the slug rules and date format the theme expects.
If you scaffold manually, the required front matter is:
1
2
3
4
5
6
7
8
9
---
layout: post
title: "Title Here"
subtitle: "Optional English subtitle"
date: YYYY-MM-DD
author: "Xiaming Chen"
header-img: "img/post-bg-universe.jpg"
tags: ["Tag One", "Tag Two"]
---
content/_posts/YYYY-MM-DD-slug.md. Slug is lowercased, spaces→-, non-word chars stripped.layout: always post for blog entries. Use poem for the poems collection.header-img: path under img/. Default img/post-bg-universe.jpg. Available backgrounds live in img/ (e.g. post-bg-digital-native.jpg, post-bg-halting.jpg, home-bg.jpg). Add new background images to img/ and reference them by relative path.tags: a YAML array. Tags with ≥ featured-condition-size posts (currently 1) appear in the sidebar “Featured Tags” block.subtitle, redirect_from (array of old paths, requires jekyll-redirect-from), multilingual: true, mathjax: true, no-catalog: true, lang: 'en' (controls preview truncation length on the home list)..agents/rules/post-writing-style.mdNew posts in content/_posts/ must follow the pre-2025 writing style documented in .agents/rules/post-writing-style.md. Summary of the rules distilled from the 2014–2024 corpus:
header-img default unless a topic-specific background exists.<!-- more --> (excerpt break) → ## sections → curated bullet lists with personal annotations → blockquotes for cited definitions → references footer.When drafting, open 2–3 existing pre-2025 posts in content/_posts/ (e.g. 2017-01-06-all-takenism.md, 2018-08-06-meta-computability.md, 2023-12-10-what-lisp-surprises-me.md) as voice references.
Unpublished posts live in content/_drafts/. A post-template.md scaffold exists there. Jekyll does not build drafts by default; to preview drafts locally:
1
$ bundle exec jekyll serve --drafts
Move a draft to content/_posts/ with a date prefix when ready to publish.
Poems are a Jekyll collection (collections: poems, output: true) rooted at content/_poems/. Each poem is title.md (no date prefix required; the date goes in front matter). Front matter:
1
2
3
4
5
---
layout: poem
title: 标题
date: YYYY-MM-DD HH:MM:SS +0800
---
Poems use the poem layout (prev/next pager iterates site.poems sorted by date descending). They are listed on content/poems.html at /poems/.
Static HTML pages live in content/ and use layout: page (or intro, default). Current pages:
| File | URL | Layout | Nav weight |
|---|---|---|---|
content/about.html |
/about/ |
page | 90 |
content/archive.html |
/archive/ |
default | 80 |
content/poems.html |
/poems/ |
intro | 10 |
index.html (root) |
/ |
page | — |
The navbar (_includes/nav.html) auto-includes every HTML page that has:
title in front matter, andhide-in-nav != true.Pages are sorted by navigation_weight (ascending). Lower weight = further left. To add a new nav entry, create an HTML file in content/ with:
1
2
3
4
5
6
---
layout: page
title: "New Page"
permalink: /new-page/
navigation_weight: 50
---
To hide a page from the nav, set hide-in-nav: true.
content/about.html pulls content from _includes/about/zh.md and _includes/about/en.md and renders both with a multilingual selector. Edit those two includes to update the about text — do not inline the content into about.html.
content/archive.html is a tag-filtered, year-grouped index of all posts. It is data-driven — no manual editing is needed when posts are added. Only edit it to change the archive’s layout or filtering logic.
Theme styles are written in less/jaminc-blog.less and compiled to css/jaminc-blog.css / css/jaminc-blog.min.css by Grunt. Never edit files in css/ directly — they are build artifacts.
To work on styles:
1
2
$ npm install # first time only
$ npm run dev # grunt watch (LESS) + jekyll serve
Or a one-shot build:
1
$ npx grunt # uglify + less + usebanner
Site JS lives in js/jaminc-blog.js and is minified to js/jaminc-blog.min.js by Grunt. Same rule: edit the source, not the .min.js.
img/post-bg-*.jpgimg/about-bg*.jpg, img/contact-bg.jpg, img/tag-bg.jpg, img/home-bg*.jpgimg/avatar.jpg (referenced in _config.yml as sidebar-avatar)img/inpost/Reference any image in front matter or body as img/... (relative to project root; the theme prepends site.baseurl).
default.html — base HTML shell: <head>, nav, search, ``, footer.page.html — static page with optional sidebar (site.sidebar / page.sidebar).post.html — single post: intro header, content, prev/next pager, optional Disqus/Netease comments, side catalog, featured tags.intro.html — minimal page (used by poems.html): header + full-width content, no sidebar.poem.html — single poem: like post.html but pager iterates site.poems.keynote.html — presentation-style layout.Common includes under _includes/:
nav.html — navbar (data-driven, see §3.2).head.html — <head> (meta, CSS, fonts).footer.html — footer.intro-header.html — the big header band; takes type (post/page) and short (bool).short-about.html — sidebar bio block.featured-tags.html — sidebar tag cloud.friends.html — friends list (currently site.friends: [] in _config.yml).multilingual-sel.html — zh/en toggle, shown when page.multilingual: true.mathjax_support.html / mathjax_support2.html — MathJax; enabled per-post via mathjax: true or site-wide via page-mathjax in _config.yml.1
2
3
4
5
6
7
8
9
10
11
12
# Ruby deps (first time)
$ bundle install
# Serve with live reload
$ npm start
# → http://localhost:4000
# With drafts visible
$ bundle exec jekyll serve --drafts
# Theme work (LESS + JS) with auto-rebuild
$ npm run dev
Ruby version: 3.4.8 (pinned in Gemfile). Use rbenv (see README.md) if your system Ruby differs.
_config.yml)| Key | Value | Notes |
|---|---|---|
title |
LaCogito | Site title / navbar brand |
url |
https://lambdacogito.github.io |
Canonical URL |
collections_dir |
content |
All collections under content/ |
future |
true |
Future-dated posts publish |
permalink |
pretty |
/YYYY/MM/DD/title/ |
paginate |
10 |
Posts per page on index.html |
markdown |
kramdown (GFM) |
Header IDs enabled for side catalog |
plugins |
jekyll-paginate, jekyll-redirect-from |
|
sidebar |
true |
Global sidebar on page layout |
sidebar-about-description |
Researcher on Knowledge Computing… | Sidebar bio |
featured-tags |
true |
Sidebar tag cloud |
featured-condition-size |
1 |
Min posts for a tag to be “featured” |
service-worker |
true |
PWA enabled |
friends |
[] |
Friends list — add { title, href } entries here |
When asked to write a new post:
rake post title="..." [subtitle="..."] [date="..."] or copy content/_drafts/post-template.md..agents/rules/post-writing-style.md and 2–3 pre-2025 posts for voice.<!-- more --> → ## sections → lists/quotes → references.header-img, tags, author: "Xiaming Chen".bundle exec jekyll serve --drafts if it’s a draft.When asked to add/edit a page or nav entry:
content/ with layout: page (or intro).permalink, title, and navigation_weight in front matter._includes/nav.html.When asked to change theme styles:
less/jaminc-blog.less (source), not css/.npx grunt or npm run dev to recompile.When asked to add a header image:
img/ (follow the post-bg-*.jpg naming for post backgrounds).img/your-image.jpg in the post’s header-img.Do
rake post to scaffold posts..agents/rules/post-writing-style.md for voice and structure.<!-- more --> to set the excerpt break on long posts.Don’t
css/ or *.min.js — they are build artifacts._includes/nav.html — use navigation_weight in page front matter instead.content/about.html — edit _includes/about/{zh,en}.md.future: true).