skills: one canonical skill dir, served over HTTP, fetched by the CLI - #12
Merged
Conversation
The shared-sites skill had drifted into separate copies: one embedded at
internal/web/init/SKILL.md and shipped by the CLI, and hand-maintained copies
elsewhere. The embedded copy was also stale against the server — it documented
neither streaming chat, nor ai.image, nor the per-site AI rate limit, all of
which the served shared.js and the AI handlers already support.
Make the repo the single source and the server the distribution point:
- Move the skill to skills/shared-sites/SKILL.md, beside install-shared-cli,
and embed both through a new top-level skills package (go:embed cannot
reach above its own package directory, so the embed lives there).
- Fold the missing API surface into the skill: streaming chat, ai.image, the
AI env vars and rate limit, and the silent-failure notes for db.subscribe,
ws.onMessage, and the positional args of ai.chat.
- Serve them: GET /skill.md on the base host, plus GET /api/skills and
GET /api/skills/{name}. /skill.md is base-host only, so a deployed site file
of the same name still wins, unlike /shared.js which is global.
- shared skill install now fetches from the server and falls back to the
built-in copy when it is unreachable, so an agent reads the skill for the
server it deploys to rather than the one the CLI was built from.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The
shared-sitesskill had drifted into separate copies. One was embedded atinternal/web/init/SKILL.mdand shipped by the CLI; others were maintained by hand outside the repo. The embedded copy was also stale against the server: it documented neither streaming chat, norai.image, nor the per-site AI rate limit, all of whichshared.jsand the AI handlers already support. An agent reading it would not know those features exist, and would read a 429 as a bug.This makes the repo the single source and the running server the distribution point.
What changed
One canonical location. The skill moves to
skills/shared-sites/SKILL.md, besideinstall-shared-cli. A new top-levelskillspackage embeds both. The embed lives there becausego:embedcannot reference a parent directory.The skill is current again. It now covers streaming chat,
ai.image, the AI environment variables and rate limit, and the three silent-failure traps:db.subscribetakes a handlers object,ws.onMessageis a method, andai.chattakes two positional arguments.The server serves them.
GET /skill.mdshared-sitesskill (base host only)GET /api/skillsGET /api/skills/{name}text/markdown/skill.mdis base-host only. On a site host that path belongs to the site, so a deployed file of the same name still wins./shared.jsis global by design; a skill file does not need to be.shared skill installfetches from the server and falls back to the built-in copy when the server is unreachable. An agent then reads the skill for the server it deploys to, not the one the CLI was built from. The fetch requires the---frontmatter, so an error page from a proxy or an older server falls back instead of writing garbage.The README install instructions for
install-shared-clidrop thegit clonein favour of acurlfrom the server.Testing
Against a local
sharedd:GET /skill.mdon the base host returns the skill astext/markdown; the same path onmysite.localhostdoes not.GET /api/skillslists both skills;GET /api/skills/nopereturns 404, and a name with a path separator is rejected before it reaches the embedded FS.shared skill installwrites the fetched copy, skips an existing file, and reports(from built-in copy)on stderr when the server is refused.shared initstill scaffolds the skill.go vet,go test, the three-OS cross-compile, andnix buildall pass.Not included
Rendering the skill per server (substituting the real base host into the URLs) is the natural follow-up. It would let a homelab drop its hand-maintained copy entirely. It is left out here to keep this change to one concern.