From 820f01659752a6ac4542482c875b5213d6e5bfdf Mon Sep 17 00:00:00 2001 From: kascit Date: Mon, 4 May 2026 01:38:33 +0530 Subject: [PATCH 01/11] chore: sort versions.env keys --- versions.env | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/versions.env b/versions.env index 4b44f55..b55e810 100644 --- a/versions.env +++ b/versions.env @@ -1,12 +1,12 @@ # Single source of truth for third-party tool versions -ZOLA_VERSION=0.22.1 -TAILWIND_VERSION=4.2.2 DAISYUI_VERSION=5.5.19 +ESBUILD_VERSION=0.28.0 +ESLINT_VERSION=9.38.0 FA_VERSION=7.2.0 -KATEX_VERSION=0.16.45 JUST_VERSION=1.48.1 -TERSER_VERSION=5.46.1 -ESBUILD_VERSION=0.28.0 +KATEX_VERSION=0.16.45 PNPM_VERSION=10.8.0 -ESLINT_VERSION=9.38.0 STYLELINT_VERSION=16.10.0 +TAILWIND_VERSION=4.2.2 +TERSER_VERSION=5.46.1 +ZOLA_VERSION=0.22.1 From 0f3b10ec808e1b139fd7a9c03ba65e8ef215ba53 Mon Sep 17 00:00:00 2001 From: kascit Date: Mon, 4 May 2026 03:25:19 +0530 Subject: [PATCH 02/11] fix: resolve mobile animation, card layout, taxonomy tags, and CSP issues - Hide heavy starfield animation on mobile using existing device check logic - Fix project card details button layout wrapping and stretching - Synchronize project techs with tags taxonomy to prevent 404s on about page - Add sentry cdn to CSP connect-src to fix blocked map file requests --- content/about.md | 2 +- scripts/sync-project-pages.js | 2 +- templates/landing.html | 18 ++++++++++++++++++ templates/macros/head.html | 2 +- templates/macros/projects.html | 3 +-- templates/project.html | 4 +++- 6 files changed, 25 insertions(+), 6 deletions(-) diff --git a/content/about.md b/content/about.md index 987e732..f14d78b 100644 --- a/content/about.md +++ b/content/about.md @@ -17,7 +17,7 @@ next_subtitle = "Next" enabled = false [taxonomies] -tags = ["systems", "backend", "devops", "data", "tooling", "security", "frontend", "cloud"] +tags = ["systems", "backend", "devops", "data", "tooling", "security", "frontend", "cloud", "Java", "Python", "Go", "C / C++", "JavaScript", "Lua", "SQL", "Bash", "Spring Boot", "Node.js", "PostgreSQL", "MongoDB", "Redis", "DynamoDB", "AWS", "GCP", "Docker", "Kubernetes", "CI/CD", "Terraform", "Neovim", "Linux", "Git", "Postman", "AI Systems", "Applied Cryptography", "Computer Graphics"] +++
diff --git a/scripts/sync-project-pages.js b/scripts/sync-project-pages.js index fb3c845..0623a49 100644 --- a/scripts/sync-project-pages.js +++ b/scripts/sync-project-pages.js @@ -71,7 +71,7 @@ function renderPage(project) { const repoTopics = compactUnique(project.repo_topics || []); const thumbnailImage = String(project.thumbnail_image || "").trim(); const thumbnailAlt = String(project.thumbnail_alt || title).trim(); - const tags = compactUnique(project.tags || []); + const tags = compactUnique([...(project.tags || []), ...(project.techs || [])]); const statusBadgeMap = { live: "Live", diff --git a/templates/landing.html b/templates/landing.html index 2b691b4..82efe2c 100644 --- a/templates/landing.html +++ b/templates/landing.html @@ -99,4 +99,22 @@
+ + {% endblock main_content %} diff --git a/templates/macros/head.html b/templates/macros/head.html index b060801..559c050 100644 --- a/templates/macros/head.html +++ b/templates/macros/head.html @@ -41,7 +41,7 @@ - + diff --git a/templates/macros/projects.html b/templates/macros/projects.html index e5723a9..6fbffc9 100644 --- a/templates/macros/projects.html +++ b/templates/macros/projects.html @@ -7,7 +7,6 @@ {% endmacro status_badge %} {% macro project_links(live_url="", github_url="", url="", url_label="Visit", external=false) %} -
{% if live_url %} Live {% endif %} @@ -19,5 +18,5 @@ {% if url and url != live_url and url != github_url %} {{ url_label }} {% endif %} -
{% endmacro project_links %} + diff --git a/templates/project.html b/templates/project.html index 7ee30f4..842a31c 100644 --- a/templates/project.html +++ b/templates/project.html @@ -45,7 +45,9 @@

Project Links

- {{ macros_projects::project_links(live_url=project_live, github_url=project_github, url=project_url, url_label=project_url_label, external=project_external) }} +
+ {{ macros_projects::project_links(live_url=project_live, github_url=project_github, url=project_url, url_label=project_url_label, external=project_external) }} +
{% endif %} {% endblock content %} From f2f8ba103c88dc01f1cffddc7c6d6b498bd30b97 Mon Sep 17 00:00:00 2001 From: kascit Date: Mon, 4 May 2026 03:30:17 +0530 Subject: [PATCH 03/11] feat: add 'up' project, fix 'stuff' link, dynamically generate taxonomy tags - Read about.md dynamically to generate skill tags seed page to ensure Zola taxonomy generation without manual frontmatter syncing - Add 'up' service health dashboard project to projects.json - Add live URL to 'stuff' project - Standardize casing for technology labels in projects.json --- data/projects.json | 56 ++++++++++++++++++++++++++++++---- scripts/sync-project-pages.js | 35 ++++++++++++++++++++- templates/archive.html | 56 ++++++++++++++++++---------------- templates/taxonomy_list.html | 2 +- templates/taxonomy_single.html | 2 +- 5 files changed, 116 insertions(+), 35 deletions(-) diff --git a/data/projects.json b/data/projects.json index 8811f59..5871300 100644 --- a/data/projects.json +++ b/data/projects.json @@ -1,5 +1,48 @@ { "projects": [ + { + "slug": "up", + "title": "UP", + "group": "featured", + "icon": "fa-solid fa-signal", + "description": "Real-time service health dashboard for all dhanur.me services. Written in Go, zero external dependencies, deployed on Render.", + "extended_description": "A lightweight status monitor with concurrent goroutine probes and in-memory rolling history. Designed for absolute minimal resource footprint.", + "role": "Status Dashboard", + "highlights": [ + "Concurrent goroutines probe every service every 30 seconds", + "Pure Go standard library with zero external dependencies", + "Single embedded HTML file served at root", + "In-memory 45-minute rolling window for history" + ], + "lang": "Go", + "status": "live", + "techs": [ + "Go", + "Monitoring", + "Status Page", + "Render", + "Concurrency" + ], + "tags": [ + "infra", + "systems", + "backend", + "devops", + "tooling" + ], + "github_url": "https://github.com/kascit/up", + "live_url": "https://up.dhanur.me", + "repo_language": "Go", + "repo_topics": [ + "go", + "status-page", + "monitoring", + "dashboard" + ], + "repo_updated_at": "2026-05-01T10:00:00Z", + "repo_archived": false, + "repo_stars": 1 + }, { "slug": "face-rekognition", "title": "Face Rekognition", @@ -126,7 +169,7 @@ "Data Structures", "DSA", "Linked List", - "Oop", + "OOP", "Playlist Manager" ], "tags": [ @@ -301,7 +344,7 @@ "extended_description": "This is my practical junk drawer: tiny CLIs, helper scripts, and quality-of-life automations I keep building whenever something feels repetitive.", "role": "Personal Utility Suite", "lang": "HTML", - "status": "wip", + "status": "live", "highlights": [ "Personal tools focused on daily workflow friction", "Small utilities designed for fast iteration", @@ -326,7 +369,8 @@ "repo_topics": [], "repo_updated_at": "2026-04-04T16:51:26Z", "repo_archived": false, - "repo_stars": 0 + "repo_stars": 0, + "live_url": "https://dhanur.me/stuff/" }, { "slug": "leetcode-solutions", @@ -482,9 +526,9 @@ "status": "archived", "techs": [ "HTML", - "Css", + "CSS", "Game", - "Javascript", + "JavaScript", "Tic Tac Toe", "Web Game" ], @@ -586,4 +630,4 @@ "repo_stars": 1 } ] -} +} \ No newline at end of file diff --git a/scripts/sync-project-pages.js b/scripts/sync-project-pages.js index 0623a49..0d3eaa6 100644 --- a/scripts/sync-project-pages.js +++ b/scripts/sync-project-pages.js @@ -194,7 +194,40 @@ function main() { ensureDir(PROJECTS_DIR); removeLegacyGeneratedDir(); removePreviouslyGeneratedPages(PROJECTS_DIR); - fs.rmSync(path.join(PROJECTS_DIR, "_skill-tags-seed.md"), { force: true }); + const seedFile = path.join(PROJECTS_DIR, "_skill-tags-seed.md"); + fs.rmSync(seedFile, { force: true }); + + const aboutPath = path.join(ROOT, "content", "about.md"); + if (fs.existsSync(aboutPath)) { + let aboutContent = fs.readFileSync(aboutPath, "utf8"); + const regex = /\{\{\s*tag_chip\(name="([^"]+)"/g; + let match; + let dynamicTags = []; + while ((match = regex.exec(aboutContent)) !== null) { + dynamicTags.push(match[1]); + } + + if (dynamicTags.length > 0) { + let existingTags = []; + const tagsMatch = aboutContent.match(/^tags\s*=\s*\[(.*?)\]/m); + if (tagsMatch && tagsMatch[1]) { + existingTags = tagsMatch[1].split(',') + .map(t => t.trim().replace(/^"|"$/g, '')) + .filter(t => t.length > 0); + } + + const allAboutTags = compactUnique([...existingTags, ...dynamicTags]); + + const updatedContent = aboutContent.replace( + /^tags\s*=\s*\[.*?\]/m, + `tags = ${tomlArray(allAboutTags)}` + ); + + if (updatedContent !== aboutContent) { + fs.writeFileSync(aboutPath, updatedContent, "utf8"); + } + } + } let written = 0; for (const project of projects) { diff --git a/templates/archive.html b/templates/archive.html index ca2b8f8..efacdf9 100644 --- a/templates/archive.html +++ b/templates/archive.html @@ -11,7 +11,7 @@

- + @@ -84,29 +84,33 @@

- - {% endblock content %} @@ -167,10 +171,10 @@