Skip to content

Commit 95bc2ea

Browse files
committed
feat: add blog posts on quantitative portfolio analysis and implement agent-based future-dated article publishing tool
1 parent 794cb27 commit 95bc2ea

7 files changed

Lines changed: 650 additions & 75 deletions
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
name: write-future-dated-article
3+
description: Writes a future-dated blog post describing a project or app from its website and GitHub repository URLs, incrementing the date from the most recent future-dated article in the repository.
4+
---
5+
6+
# Write Future-Dated Project Article Skill
7+
8+
This skill automates writing a high-quality, future-dated blog article describing a project or application based on a project website URL, a GitHub repository URL, and any specific process/hint inputs.
9+
10+
## Prerequisites
11+
12+
- The helper script [next_post_helper.py](file:///Volumes/Photos/Websites/hellotham-website/.agents/skills/write-future-dated-article/scripts/next_post_helper.py) must be executed to calculate the next target future date.
13+
14+
## Workflow
15+
16+
### 1. Calculate Target Date
17+
18+
Run the helper script to calculate the next release date (it finds the maximum publish date of all blog posts, and if it's in the future, increments it by 7 days; otherwise, it defaults to the next Monday):
19+
20+
```bash
21+
python3 /Volumes/Photos/Websites/hellotham-website/.agents/skills/write-future-dated-article/scripts/next_post_helper.py
22+
```
23+
24+
This returns:
25+
26+
- `DATE` (format: `YYYY-MM-DD`)
27+
- `ISO` (format: `YYYY-MM-DDT00:00:00.000Z`)
28+
29+
### 2. Gather Project Context
30+
31+
Use URL reading tools to collect information about the project:
32+
33+
- **Project/App Website:** Fetch the home page to understand the user-facing description, value proposition, and key features.
34+
- **GitHub Repository:** Fetch the `README.md` or home page to determine the technology stack (languages, frameworks, dependencies) and installation steps.
35+
- **User Hints:** Read any user-provided hints or design process details.
36+
37+
### 3. Write the Post
38+
39+
Create a new Markdown file inside `src/content/blog/` using the format `YYYY-MM-DD-[project-slug].md`.
40+
Ensure the frontmatter contains:
41+
42+
```yaml
43+
title: [Compelling title for the project]
44+
description: [Short, scannable overview of the project and its features]
45+
author: chris-tham
46+
publishDate: [ISO date from Step 1]
47+
featuredpost: false
48+
coverImage: ../../assets/site/screenshot.png
49+
tags:
50+
- [Tag 1]
51+
- [Tag 2]
52+
```
53+
54+
### 4. Structuring the Content
55+
56+
Structure the article sections as follows:
57+
58+
- **Overview:** What the project is and what problem it solves.
59+
- **Key Features:** Bullet points highlighting the main capabilities.
60+
- **Technology Stack:** List of frameworks, libraries, and tools used.
61+
- **Process of Building It:** Detail the development process, challenges overcome, and design decisions (incorporate any user-provided hints here).
62+
63+
### 5. Format & Verify
64+
65+
- Format the new post: `pnpm run lint`
66+
- Verify the site compiles correctly with the new post: `pnpm run check` and `pnpm run build`
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import os
2+
import re
3+
from datetime import datetime, timedelta
4+
5+
blog_dir = "/Volumes/Photos/Websites/hellotham-website/src/content/blog"
6+
7+
def get_next_date():
8+
today = datetime.now()
9+
10+
# Default fallback: next Monday
11+
days_ahead = 0 - today.weekday()
12+
if days_ahead <= 0:
13+
days_ahead += 7
14+
next_date = today + timedelta(days=days_ahead)
15+
16+
if not os.path.exists(blog_dir):
17+
return next_date.strftime("%Y-%m-%d"), next_date.strftime("%Y-%m-%dT00:00:00.000Z")
18+
19+
date_pattern = re.compile(r"^(\d{4})-(\d{2})-(\d{2})-")
20+
max_date = None
21+
22+
for filename in os.listdir(blog_dir):
23+
match = date_pattern.match(filename)
24+
if match:
25+
try:
26+
post_date = datetime.strptime(match.group(1) + "-" + match.group(2) + "-" + match.group(3), "%Y-%m-%d")
27+
if max_date is None or post_date > max_date:
28+
max_date = post_date
29+
except ValueError:
30+
continue
31+
32+
if max_date:
33+
# If the latest post is in the future relative to today, increment it by 7 days
34+
if max_date > today:
35+
next_date = max_date + timedelta(days=7)
36+
else:
37+
# If all posts are in the past, use the next Monday
38+
pass
39+
40+
return next_date.strftime("%Y-%m-%d"), next_date.strftime("%Y-%m-%dT00:00:00.000Z")
41+
42+
if __name__ == "__main__":
43+
date_str, iso_str = get_next_date()
44+
print(f"DATE={date_str}")
45+
print(f"ISO={iso_str}")

src/content/blog/2021-10-19-python-finance-1-intro.md

Lines changed: 0 additions & 75 deletions
This file was deleted.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
title: 'The Evolution of Hello Astro: My Personal Learning Journey with Astro'
3+
description: Reflecting on my first Astro project—migrating from Gatsby/Next.js, building a popular starter template, and partnering with Antigravity for a major v7 overhaul.
4+
author: chris-tham
5+
publishDate: 2026-07-20T00:00:00.000Z
6+
featuredpost: false
7+
coverImage: ../../assets/site/screenshot.png
8+
tags:
9+
- Hello Astro
10+
- Hello Tham
11+
- Astro
12+
- Gatsby
13+
- NextJS
14+
- template
15+
- Tailwind CSS
16+
- Antigravity
17+
---
18+
19+
Our base template, [hello-astro](https://github.com/hellotham/hello-astro) (deployed at [hellotham.github.io/hello-astro/](https://hellotham.github.io/hello-astro/)), remains the core base template for the **Hello Tham website**. Today, it has grown to be starred **194 times** and forked **58 times** on GitHub.
20+
21+
Looking back at the git log, this project represents my personal learning journey transitioning to Astro after years of building sites in Gatsby and Next.js. Here is the story of how it evolved from my first Astro experiment to a modern server-side rendered application.
22+
23+
---
24+
25+
### Part 1: The Hand-Coded Learning Journey (2022–2025)
26+
27+
Before July 2026, every single commit was coded by hand as I learned the ins and outs of the Astro ecosystem:
28+
29+
- **August 2022 (First Steps & Porting from Gatsby):** Having previously learnt Gatsby and Next.js, this was my first project coding in Astro. I began by porting the essential layout and pages from our legacy `hello-gatsby-starter`. I had to learn how Astro’s components, named slots, static generation, and scoped style models differed from React-based frameworks. I hand-coded our initial SEO tags, dark mode switch, and RSS feed.
30+
- **Late 2022 (Astro Collections & RPN calculator):** As Astro matured, I expanded the project by implementing Astro Content Collections (introduced in Astro 2.0). I integrated PhotoSwipe for galleries, Leaflet for maps, and minified Lunr search indexes.
31+
- **2023 (View Transitions & Astro 3.0):** Experimented with Astro's new `ViewTransitions` API (introduced in Astro 2.9/3.0) to enable smooth page transitions, integrated Markdoc, migrated from Yarn to `pnpm`, and refactored the project for Astro v3.0.
32+
- **2024–2025 (Maintenance & Astro 4.0):** Maintained the packages, resolved TS type errors, and migrated to `astro-icon` v1.x and Astro v4.x.
33+
34+
---
35+
36+
### Part 2: The Antigravity Partner Programming Era (July 2026)
37+
38+
In July 2026, after years of manual development, I partnered with **Antigravity** (a powerful agentic AI coding assistant designed by the Google Deepmind team) to perform a massive architectural overhaul:
39+
40+
- **Astro v7 & Tailwind CSS v4:** Upgraded our core compiler engines and migrated our style systems to Tailwind CSS v4, fixing search modal backdrop opacities.
41+
- **Modern Search Engine:** Fully migrated the search architecture from Lunr and Alpine.js to **Pagefind**, enabling highly performant local search indexing.
42+
- **Dynamic Future-Dating (SSR):** Reconfigured the site's dynamic routes to run on Server-Side Rendering (SSR) via `@astrojs/netlify`. Dynamic routes (`/`, `/blog`, `/rss.xml`, category/tag/author pages) now run on-demand to check the system date at request-time, ensuring future-dated posts are hidden until release.
43+
- **Modern tooling:** Rebuilt our linter configuration to leverage flat ESLint configs (`eslint.config.mjs`) and Prettier (`.prettierrc.mjs`).
44+
45+
---
46+
47+
### 📋 Full Change Log & Project Milestones
48+
49+
```mermaid
50+
timeline
51+
title Hello Astro Evolutionary Timeline
52+
2022 : First Astro Project (Gatsby Port) : Dark Mode & Lunr Search : Content Collections (Astro 2.0)
53+
2023 : Astro v3.0 Upgrade : View Transitions : Migrated from Yarn to pnpm
54+
2024 - 2025 : Astro v4.0 Upgrade : Icon 1.x Migration
55+
July 2026 (Antigravity) : Astro v7 & Tailwind v4 : Lunr -> Pagefind : Netlify SSR Future-Dating
56+
```
57+
58+
This learning journey began as a simple experiment to explore a new static site generator and has evolved into a popular open-source template. Powered by the clean foundations of manual development and the latest agentic capabilities of Antigravity, `hello-astro` continues to serve as the high-performance base of our web presence.

0 commit comments

Comments
 (0)