feat(website): Add last updated dates for resources#649
Conversation
…ns, and skills - Add git-dates.mjs utility to extract file modification dates from git history - Include lastUpdated field in JSON data for all resource types - Display relative time (e.g., '3 days ago') with full date on hover - Add 'Recently Updated' sort option to agents, prompts, instructions, and skills pages - Update deploy-website.yml to use fetch-depth: 0 for full git history CI overhead: ~20-30s additional for full git checkout
There was a problem hiding this comment.
Pull request overview
This PR adds git-based “last updated” timestamps to the website’s resources and surfaces them in the UI with sorting and display enhancements.
Changes:
- Introduces a
git-datesutility and wires it intogenerate-website-data.mjsto computelastUpdatedfor agents, prompts, instructions, skills, and collections, and propagates it into the search index. - Updates agents, prompts, instructions, and skills pages to display “Updated X ago” with a full-date tooltip and to support a “Recently Updated” sort option, backed by new helpers in
website/src/scripts/utils.tsand corresponding CSS. - Adjusts the deploy workflow to fetch full git history so that last-updated data is accurate during CI builds.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| website/src/scripts/utils.ts | Adds date formatting helpers and getLastUpdatedHtml used to render relative “Updated …” labels with a full-date tooltip. |
| website/src/scripts/pages/skills.ts | Extends skills data with lastUpdated, adds sort state/logic, integrates the new sort dropdown, and renders the last-updated label in the resource meta. |
| website/src/scripts/pages/prompts.ts | Extends prompt items with lastUpdated, adds sort option handling and UI wiring, and renders last-updated info per prompt. |
| website/src/scripts/pages/instructions.ts | Adds lastUpdated to instruction items, sort options and handlers, and last-updated display in the list UI. |
| website/src/scripts/pages/agents.ts | Adds lastUpdated to agents, sorting by title or last updated, and last-updated display in agent metadata, including wiring up the new sort control. |
| website/src/pages/skills.astro | Adds a “Sort” select control (Name A–Z / Recently Updated) to the Skills page filters. |
| website/src/pages/prompts.astro | Adds a “Sort” select control for prompts to switch between name and recently updated ordering. |
| website/src/pages/instructions.astro | Adds a “Sort” select control for instructions, consistent with other resource pages. |
| website/src/pages/agents.astro | Adds a “Sort” select control for agents to support recently updated ordering. |
| website/public/styles/global.css | Introduces .last-updated styling to align the timestamp visually with existing resource metadata tags. |
| eng/utils/git-dates.mjs | New utility to query git history once and build a map of file paths to last-modified ISO dates, plus a helper to get a single file’s date. |
| eng/generate-website-data.mjs | Integrates git dates into data generation for each resource type, includes lastUpdated in JSON and search index entries, and logs loaded git-date stats. |
| .github/workflows/deploy-website.yml | Sets fetch-depth: 0 on checkout so CI has full git history for accurate last-updated computation. |
Comments suppressed due to low confidence (1)
eng/utils/git-dates.mjs:9
- The imported
pathmodule is never used in this file, which adds unnecessary noise and may get flagged by linters. Consider removing the unused import to keep the utility lean and aligned with common style and linting rules.
import path from "path";
| const now = new Date(); | ||
| const diffMs = now.getTime() - date.getTime(); | ||
| const diffSeconds = Math.floor(diffMs / 1000); | ||
| const diffMinutes = Math.floor(diffSeconds / 60); | ||
| const diffHours = Math.floor(diffMinutes / 60); | ||
| const diffDays = Math.floor(diffHours / 24); | ||
| const diffWeeks = Math.floor(diffDays / 7); | ||
| const diffMonths = Math.floor(diffDays / 30); | ||
| const diffYears = Math.floor(diffDays / 365); | ||
|
|
||
| if (diffDays === 0) { | ||
| if (diffHours === 0) { | ||
| if (diffMinutes === 0) return "just now"; | ||
| return diffMinutes === 1 ? "1 minute ago" : `${diffMinutes} minutes ago`; | ||
| } | ||
| return diffHours === 1 ? "1 hour ago" : `${diffHours} hours ago`; | ||
| } | ||
| if (diffDays === 1) return "yesterday"; | ||
| if (diffDays < 7) return `${diffDays} days ago`; | ||
| if (diffWeeks === 1) return "1 week ago"; | ||
| if (diffWeeks < 4) return `${diffWeeks} weeks ago`; | ||
| if (diffMonths === 1) return "1 month ago"; | ||
| if (diffMonths < 12) return `${diffMonths} months ago`; | ||
| if (diffYears === 1) return "1 year ago"; | ||
| return `${diffYears} years ago`; |
There was a problem hiding this comment.
formatRelativeTime assumes the input date is always in the past; if isoDate is in the future (e.g., due to clock skew on a commit), diffMs becomes negative and diffYears will also be negative, producing strings like "-1 years ago" instead of something sensible. It would be more robust to explicitly handle diffMs <= 0 (for example by clamping to "just now" or treating such cases as unknown) before computing the various time units.
These are valid variable names used in sorting comparison functions for the last updated date feature.
Summary
Display "last updated" dates derived from git commit history on the website for agents, prompts, instructions, and skills.
Changes
Backend (Data Generation)
eng/utils/git-dates.mjsutility to extract file modification dates from git history efficiently (single git command)lastUpdatedfield in JSON data for all resource types (agents, prompts, instructions, skills, collections)lastUpdatedFrontend (Website)
.last-updatedCSS stylingCI
deploy-website.ymlto usefetch-depth: 0for full git historyCI Overhead
Screenshots
The "Updated X days ago" appears in the resource meta section, with a tooltip showing the full date on hover. Users can sort by "Recently Updated" using the new sort dropdown.
Testing
npm run website:data- generates JSON with lastUpdated fieldsnpm run website:build- full build succeeds