[object Object]

← back to Cli Printing Press

feat(cli): add travel and food-and-dining categories (#187)

0ac6513428501cc4f2c9b6331ed2dc55cfe3fbf1 · 2026-04-12 15:28:01 -0700 · Trevin Chow

"other" is a weak catch-all for consumer-utility CLIs like flights,
hotels, restaurants, and recipes. Add two targeted categories and
alphabetize the full list for easier maintenance:

- travel (flights, hotels, maps, transit) — covers flightgoat,
  future kayak/google-flights CLIs
- food-and-dining (restaurants, recipes, delivery, reviews) —
  covers future Yelp/Allrecipes/DoorDash/Instacart/Pagliacci CLIs

Leaves weather-goat in "other" intentionally — weather is reference/
utility, not cleanly lifestyle or travel.

"other" and "example" remain at the end of the list as explicit
special cases (catch-all / test-only).

Companion README update in mvanhorn/printing-press-library to match.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 0ac6513428501cc4f2c9b6331ed2dc55cfe3fbf1
Author: Trevin Chow <trevin@trevinchow.com>
Date:   Sun Apr 12 15:28:01 2026 -0700

    feat(cli): add travel and food-and-dining categories (#187)
    
    "other" is a weak catch-all for consumer-utility CLIs like flights,
    hotels, restaurants, and recipes. Add two targeted categories and
    alphabetize the full list for easier maintenance:
    
    - travel (flights, hotels, maps, transit) — covers flightgoat,
      future kayak/google-flights CLIs
    - food-and-dining (restaurants, recipes, delivery, reviews) —
      covers future Yelp/Allrecipes/DoorDash/Instacart/Pagliacci CLIs
    
    Leaves weather-goat in "other" intentionally — weather is reference/
    utility, not cleanly lifestyle or travel.
    
    "other" and "example" remain at the end of the list as explicit
    special cases (catch-all / test-only).
    
    Companion README update in mvanhorn/printing-press-library to match.
    
    Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---
 AGENTS.md                        |  2 +-
 internal/catalog/catalog.go      | 24 ++++++++++++++----------
 internal/catalog/catalog_test.go |  8 ++++----
 3 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/AGENTS.md b/AGENTS.md
index 6b8cbe6b..c1a4e304 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -128,7 +128,7 @@ Releases are fully automated. No manual steps required.
 Catalog entries in `catalog/` must pass `internal/catalog` validation:
 - Required fields: name, display_name, description, category, spec_url, spec_format, tier
 - spec_url must use HTTPS
-- category must be: developer-tools, monitoring, cloud, project-management, productivity, social-and-messaging, sales-and-crm, marketing, payments, auth, commerce, ai, media-and-entertainment, devices, other
+- category must be: ai, auth, cloud, commerce, developer-tools, devices, food-and-dining, marketing, media-and-entertainment, monitoring, payments, productivity, project-management, sales-and-crm, social-and-messaging, travel, or other
 - tier must be: official or community
 
 ## Testing
diff --git a/internal/catalog/catalog.go b/internal/catalog/catalog.go
index debb9cf4..82a1b841 100644
--- a/internal/catalog/catalog.go
+++ b/internal/catalog/catalog.go
@@ -14,21 +14,25 @@ import (
 
 var namePattern = regexp.MustCompile(`^[a-z0-9]+(?:-[a-z0-9]+)*$`)
 
+// Public categories first, alphabetized. "other" and "example" are explicitly
+// special (catch-all / test-only) and kept at the end.
 var validCategories = map[string]struct{}{
+	"ai":                      {},
+	"auth":                    {},
+	"cloud":                   {},
+	"commerce":                {},
 	"developer-tools":         {},
+	"devices":                 {},
+	"food-and-dining":         {},
+	"marketing":               {},
+	"media-and-entertainment": {},
 	"monitoring":              {},
-	"cloud":                   {},
-	"project-management":      {},
+	"payments":                {},
 	"productivity":            {},
-	"social-and-messaging":    {},
+	"project-management":      {},
 	"sales-and-crm":           {},
-	"marketing":               {},
-	"payments":                {},
-	"auth":                    {},
-	"commerce":                {},
-	"ai":                      {},
-	"media-and-entertainment": {},
-	"devices":                 {},
+	"social-and-messaging":    {},
+	"travel":                  {},
 	"other":                   {},
 	"example":                 {},
 }
diff --git a/internal/catalog/catalog_test.go b/internal/catalog/catalog_test.go
index cfae7a9c..61995ca8 100644
--- a/internal/catalog/catalog_test.go
+++ b/internal/catalog/catalog_test.go
@@ -142,10 +142,10 @@ func TestValidateEntry(t *testing.T) {
 
 func TestAllPublicCategoriesAreValid(t *testing.T) {
 	publicCategories := []string{
-		"developer-tools", "monitoring", "cloud", "project-management",
-		"productivity", "social-and-messaging", "sales-and-crm", "marketing",
-		"payments", "auth", "commerce", "ai", "media-and-entertainment",
-		"devices", "other",
+		"ai", "auth", "cloud", "commerce", "developer-tools", "devices",
+		"food-and-dining", "marketing", "media-and-entertainment", "monitoring",
+		"payments", "productivity", "project-management", "sales-and-crm",
+		"social-and-messaging", "travel", "other",
 	}
 	base := Entry{
 		Name:        "test-api",

← 1011df38 fix(cli): enrich README and generate SKILL.md so printed CLI  ·  back to Cli Printing Press  ·  feat(scripts): add verify-skill — static SKILL.md validator 297c3c14 →