Anthropic renamed function hooks to "Claude Mods", committed to shipping them in
weeks and published the built-in mods' source plus the full TypeScript
declarations (anthropics/claude-code#91870, mods/ in the claude-code repo).
This aligns our component type with that.
Rename
- Component type `function-hooks` -> `mods` (dir, catalog key, route /mods,
CLI `--mod` with `--function-hook` kept as a hidden alias, tracking `mod`).
Old URLs redirect via dashboard/public/_redirects.
- Banners, blog, CLAUDE.md and .claude/rules updated from "proposal" to
"early access behind CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 (2.1.259+)".
Format: one directory = one complete plugin (Anthropic's mods/ layout)
- cli-tool/components/mods/{category}/{name}/ with .claude-plugin/plugin.json
(name, description, userConfig), hooks/hooks.json, hooks/** (any number of
files, relative imports), optional types/, tests/, README.md.
- Generator: README.md is the content; every text file ships in the
per-component content file (`files`), plus `modules` and `userConfig`.
- CLI: recursive download of the plugin directory (like skills), written
verbatim to .claude/skills/{name}/; validates manifest + hooks.json + modules.
- Site: SkillExplorer generalized (componentType, mainFile, files) so the
detail page shows README + the full file tree from the content file;
SendToRepoModal writes the whole plugin.
Modules rewritten against the real API
- types/claude-code.d.ts (as /plugin-types writes it, 2.1.271), tsconfig and
a CI job (mods-typecheck.yml) running tsc over every mod.
- All 10 existing mods fixed to the shipped shapes ($.fs.read(path),
$.http.fetch(url, init), $.ui.ask, { refuse } on plugin.register, Box/Text
elements, {result}/{deny}/context, static engine.create withholding) and
verified on Claude Code 2.1.272: claude plugin validate passes on all, and
deny / modifying / after / cache / audit / withhold+refuse were exercised
end to end with `claude -p --plugin-dir --debug-file`.
- Options need `userConfig` in plugin.json and are read from user/managed
settings (pluginConfigs[name].options), never project settings; documented.
Games
- games/cc-arcade vendored as-is (MIT, Seza Akgün) with two runtime fixes
($.clock.now() is a Promise in the 2.1.271 API).
- games/{snake,tetris,2048,minesweeper,flappy,pong,invaders,typing-test,
doom,pet}: each cc-arcade game as its own installable mod with its own
command (/tetris, /snake, ...), attributed to the original author.
- games/{pacman,tool-defense,diff-invaders}: new, written for aitmpl.
Pac-Man with the original ghost behaviours; Tool Defense, a tower defense
where every tool call Claude makes is an enemy; Diff Invaders, where every
Edit/Write's added lines become the alien formation. Pure logic with bun
tests, surface-module boards, typechecked and validated.
Catalog regenerated (24 mods).
* feat: add Function Hooks component type (experimental) with 10 hooks and blog
Introduce "function-hooks" as a new first-class component type based on
the Anthropic proposal in anthropics/claude-code#91870 (TypeScript hooks
as Koa-style middleware on a $ engine interface). The feature is not
shipped; every API name is provisional and the section is labelled
experimental everywhere.
- 10 function hooks under cli-tool/components/function-hooks/
(security, productivity, observability, ui, integrations, enterprise),
each as a .md doc page plus the installable .ts/.tsx hooks-module
- CLI: --function-hook installs the module as a local plugin under
.claude/plugins/<name>/ (plugin.json, hooks/hooks.json with modules)
and prints the experimental warning
- Catalog generator: scan function-hooks and emit dashboard artifacts
- Dashboard: type wiring, /function-hooks page with experimental banner
linking to the issue, Events/Module cards on the detail page,
sitemap, cart, webmcp; track-download now accepts loop/function-hook
- Blog: "Claude Code Function Hooks (Experimental)" article with cover
- Docs: CLAUDE.md and cli-tool rule
Claude-Session: https://claude.ai/code/session_01YBoJbmNMcRCexuKpH9mQtW
* fix: store function hooks as hooks.json + module, install as skills-dir plugin
Function hooks are not markdown docs. Per the proposal's architecture doc,
a function hook is a plugin's hooks/hooks.json with a "modules" key naming
a .ts/.tsx hooks-module beside it. Align the catalog and the CLI with that:
- Components are now {name}.json (hooks.json + catalog description) plus
the {name}.ts/.tsx module it names, mirroring how shell hooks store
.json + .py/.sh. The .md docs are removed.
- Generator reads the named module into the per-component content file
(module, moduleSource); the detail page renders the JSON and the module
with the experimental notice.
- CLI --function-hook downloads hooks.json and every module it names,
strips description, and writes the plugin to .claude/skills/{name}/,
which Claude Code auto-loads as {name}@skills-dir per the plugins
reference (no --plugin-dir needed).
- Docs and blog updated to the same install path.
Claude-Session: https://claude.ai/code/session_01YBoJbmNMcRCexuKpH9mQtW
* fix(function-hooks): address review findings
- CartSidebar: add --loop and --function-hook to TYPE_FLAGS so stack commands install them
- SendToRepoModal: export loops and function hooks (plugin layout with hooks.json + module)
- CLI: validate function hook identifier and hooks-module file names before building URLs/paths
- block-destructive-commands: rm rule now catches split flags, --recursive, quoted/trailing-slash targets, --no-preserve-root
- admin-capability-lockdown: shellPolicy deny|guardrail|allow; default withholds Bash, guardrail is labelled bypassable
- regenerate catalog
Claude-Session: https://claude.ai/code/session_01WsWgpvgeJgRMoLiYDcRXMU
The dashboard is on Cloudflare Pages with a 24h edge cache already in
place, but every island still downloaded the full ~1.9MB index (327KB
gz) — even the sidebars/plugins/collection pages that only need per-type
counts. This splits the index into purpose-built artifacts so the
browser fetches only what each surface needs.
Generator (scripts/generate_components_json.py):
- Decouple the docs and dashboard index writes (they were a byte copy).
docs/components.json keeps `security` (the legacy site renders it);
the dashboard index drops both `content` and `security` (unused there)
→ ~13% smaller.
- Emit dashboard/public/counts.json (per-type counts, ~150 bytes),
components/{type}.json (per-type slices), and search-index.json
(flat name/description/category/type/path for global search).
Dashboard islands:
- ComponentGrid loads only the active type via fetchComponentsByType,
re-fetching on type switch (per-type in-memory cache).
- SearchModal (Cmd+K) uses the lighter search-index.json.
- Sidebar + plugins index/detail + collection pages fetch counts.json
instead of the full index just to read array lengths.
- data.ts gains fetchComponentsByType/fetchSearchIndex (additive);
fetchComponents() stays for the SSR detail page and Discord bot.
Fix: SendToRepoModal read `match.content` off an index that no longer
carries content, so "Send to repo" produced empty PRs / threw "No
component content found". buildFileMap now pulls each item's content via
fetchComponentContent (the per-component files), which also removes its
full-index fetch.
_headers: cache/CORS blocks for counts.json, components/*, search-index.json.
Payload (gzip on-the-wire): sidebars/plugins/collection 327KB → ~124B;
grid default type (agents) 327KB → 145KB; Cmd+K 327KB → 260KB.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat: add Loops component type with referenced components
Introduce "loops" as a new first-class component type — autonomous
agentic workflows (goal + interval + stop condition) inspired by Loop
Engineering and the Forward Future Loop Library. A loop references other
components (agents, skills, hooks, commands) and the dashboard renders
those references as clickable cards on the loop detail page.
- Add 10 starter loops under cli-tool/components/loops/
(engineering, evaluation, operations)
- Catalog generator: scan loops + write per-component content files
- Dashboard: new type in icons/types/data, /loops page, and a
"Referenced Components" section on the loop detail page
- CLI: --loop flag installs the loop to .claude/loops/ and
auto-installs its referenced components
- Docs: CLAUDE.md and cli-tool rule updated
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T9ynMiCHt8JwdMd8KjCkES
* feat: add 8 more loops (goal/loop/schedule patterns)
Expand the loops catalog to 18, drawing ideas from community "Loop
Engineering" patterns. Adds loops across the three trigger verbs
(/goal, /loop, /schedule) and emphasizes the verifier-in-the-loop and
budget / anti-spin guardrails:
- engineering/five-minute-maintainer-loop
- engineering/build-test-fix-loop
- engineering/anti-spin-build-loop
- engineering/completion-contract-loop (goal)
- engineering/goal-refiner-loop (goal)
- engineering/adversarial-review-loop (cross-model)
- operations/overnight-pr-routine-loop (schedule)
- evaluation/human-approval-loop (human-in-the-loop)
All referenced components verified to exist; catalog regenerated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T9ynMiCHt8JwdMd8KjCkES
---------
Co-authored-by: Claude <noreply@anthropic.com>
El commit anterior creó docs/component-content/ como directorio intermedio
y luego lo copió a dashboard/public/component-content/, resultando en 1774
archivos duplicados en el repo. Ahora el generador escribe directo al destino
final (dashboard/public/component-content/) y se agrega docs/component-content/
a .gitignore para evitar que se vuelva a trackear.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Split components.json: índice sin content (1.9 MB / 249 KB br vs 15.6 MB / 4.15 MB br).
Generador produce component-content/{type}/{slug}.json por componente y auto-copia
a dashboard/public/. Página de detalle carga contenido on-demand via fetchComponentContent().
- Restaurar cabeceras de caché y seguridad perdidas en la migración Vercel→Cloudflare:
_headers con Cache-Control max-age=86400 para JSONs, immutable para _astro/*,
y HSTS, X-Frame-Options, Referrer-Policy, Permissions-Policy en todas las rutas.
- Eliminar dashboard/vercel.json (config muerta desde migración a Cloudflare Pages).
- Diferir hidratación: ClerkIsland y AuthButton client:load → client:idle;
SaveToCollectionButton → client:visible.
- Eliminar gpt-tokenizer del bundle del navegador: reemplazado por estimación chars/4.
- Actualizar .claude/rules/dashboard.md para reflejar hosting en Cloudflare Pages.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add MarkdownViewer, JsonViewer, SkillExplorer components with Code/Preview toggle, search (Cmd+F), TOC sidebar, and gradient fade expand/collapse
- Add FileTreeSidebar for skill file navigation (starts collapsed)
- Make file tree panel stretch to match content height
- Green download badge with icon on detail pages
- Remove Add to Stack button and sidebar collapse functionality
- Metadata displayed as clickable label pills with modal
- Add marked dependency for client-side markdown rendering
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>