agentleFS
ryanbaumannryanbaumann/fieldwork/.agents/skills/portfolio-content/SKILL.md

portfolio-content

Skill2 starsChanged 28 days agoMITView on GitHub

How to add or update content on this site — work entries, blog posts, talks, pages, static assets, or a whole new content type. The CMS is the filesystem.

The file

We split this skill into the rules it gives an agent

7 rules. About 0 are common, 2 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    When renaming a published detail page, set its new slug, add every previous path to aliases, and update canonical.

    line 60
  2. Distinctive:

    Every hosted essay needs three purposeful visual assets before publication:

    line 62
  3. Distinctive:

    Write asset-specific alt text for each.

    line 68
  4. Very specific:

    Add { name, label, listPage, detailPages } to COLLECTIONS in build.mjs.

    line 72
  5. Very specific:

    Create content/<name>/ with a _TEMPLATE.md.

    line 73
  6. Very specific:

    Add the nav item in layout() and a section intro in site.json if wanted.

    line 74
  7. Very specific:

    Run the portfolio-review skill before publication.

    line 79

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Updating content

The CMS is content/ + build.mjs. Add a markdown file and rebuild. Every collection folder has a _TEMPLATE.md (underscore-prefixed files are skipped by the build).

Front matter

A ----delimited block of key: value lines. Values that parse as JSON (arrays, objects, numbers, booleans) are used as such; everything else is a string. Common keys:

KeyUsed byMeaning
title, summaryallShown in lists, cards, and meta tags. Use the writing skill's packaging framework before publishing.
orderallSort key (ascending); ties break by date descending
featuredworktrue puts the entry on the home page
org, role, period, tags, linksworkCard + case-study header
date, externalwritingexternal: <url> = outbound link, no page
slug, aliasesdetail pagesPin the canonical slug and list old root-relative paths that must permanently redirect to it
image, imageAltnarrative pagesPurposeful visible image plus literal alt text
socialImage, shareTitle, shareSummary, shareImageAltshareable pagesDedicated 1200×627 social preview and its copy/alt contract
draft, noindex, publishAtwritingDrafts stay private to /writer/; publishAt is an explicit UTC timestamp gate
venue, type, linkstalksRow metadata; type is free-form
eyebrowpagesLabel above the page title

Keep tags reader-facing and reusable. Prefer the existing vocabulary: developer experience, ai, growth, distribution, evals, open source, product, developer tools, architecture, research, maps, and a small number of domain-specific terms. Use at most three tags unless a fourth materially improves discovery. Do not create a synonym such as applied ai or agent experience when an existing tag already carries the meaning.

Where things go

  • Work case study → content/work/<slug>.md. Body renders at /work/<slug>/; no body = card links out to the first links URL.
  • Blog post → content/writing/<slug>.md (or npm run new:post -- "Title" from the repo root). New posts are drafts. Use --publish or --schedule 2099-07-14T16:00:00Z deliberately. Use the writing skill for voice, titles, summaries, social preview copy, and social-draft packaging.
  • Talk / presentation → content/talks/<slug>.md, decks in static/decks/ (see the presenting skill).
  • Agent script → canonical package in ../agent-scripts/<slug>/, with an optional reader-facing field note in content/writing/<slug>.md. The field note summarizes and links to the package; it does not duplicate the full prompt.
  • Standalone page → content/pages/<slug>.md → /<slug>/. Add it to the nav in build.mjs layout() if it should be globally reachable.
  • Any static asset (images, PDFs, files) → static/, copied verbatim into the site root.
  • Site-wide copy (name, thesis, section intros, links) → content/site.json.

Internal links in content are written root-relative (/work/, /decks/x.pdf); the build rebases them if the site is mounted under a subpath.

Drafts and schedules

  • draft: true + noindex: true never enters public HTML, RSS, or sitemap.
  • draft: false with no publishAt publishes on the next deploy.
  • draft: false + publishAt: <UTC ISO timestamp> publishes on the first scheduled deploy at or after that time.
  • Any automation that decides public state must reuse isPublished() from build.mjs or pin an explicit parity test to that implementation. Never paraphrase publication as draft === false: test a future schedule first, then before, at, and after its UTC boundary.
  • /writer/ is a separate password-protected build with preview and publishing controls. It needs server-only writer and GitHub credentials; see docs/WRITER_WORKFLOW.md.
  • The repository is public. Committed Markdown and static/ assets are not confidential even when the rendered route is protected.

Markdown headings receive stable fragment IDs. Authors may pin one with ## Heading {#stable-id}. Tables, fenced code language labels, blockquotes, images, lists, emphasis, and links are supported.

When renaming a published detail page, set its new slug, add every previous path to aliases, and update canonical. The build writes redirects.json; the gateway turns each alias into an HTTP 308 and preserves the query string. Never leave the old page rendered as duplicate content.

Every hosted essay needs three purposeful visual assets before publication:

  1. A dedicated 1200×675 header that explains the thesis without repeating the title.
  2. A distinct 1200×627 raster social card composed for thumbnail legibility.
  3. At least one dedicated 1200×675 inline image that shows a mechanism, artifact, or evidence from the argument.

Write asset-specific alt text for each. Do not reuse a generic portfolio preview, title card, or the header as the inline evidence image.

Adding a new content type

  1. Add { name, label, listPage, detailPages } to COLLECTIONS in build.mjs.
  2. Create content/<name>/ with a _TEMPLATE.md.
  3. Add the nav item in layout() and a section intro in site.json if wanted.
  4. node build.mjs — the index, rows, and detail pages come for free.

Verify

Run the portfolio-review skill before publication. Its claim, link, canonical, redirect, image, metadata, browser, and independent-review gates are required in addition to the build commands below.

node build.mjs   # prints the page count
BASE_PATH=/writer/ PORTFOLIO_WRITER_MODE=true PORTFOLIO_DIST_DIR=writer-dist node build.mjs
node serve.mjs   # preview at http://localhost:4000

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.