Commits
Rewrites the auth section from a "two ways" menu into a directive (run the
command, it opens the browser; don't pre-login or offer app-passwords unless
headless). Adds a serving-model section (SPA mode, _redirects, custom 404,
root-relative rewriter) and its hard limit — static files only, no per-request
OG/meta injection, so per-page link previews need an external renderer while
display pages don't. Documents the async custom-domain claim→DNS→verify→add-site
flow.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
the publish-skills workflow used a ship-then-prune step (vit ship isn't
idempotent, so it deleted old same-name records after shipping). that prune is
unsafe under concurrent CI runs: overlapping runs snapshot each other's
freshly-shipped records as "stale" and delete them — which wiped the published
skills. not worth the risk for 7 skills. publish manually instead:
CLAUDECODE=1 vit ship --skill ./skills/<name>/ --tags "..."
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tangled CI exposes only the current commit (TANGLED_SHA), no push range — so a
HEAD~1 diff misses skills edited in earlier commits of a multi-commit push
(exactly what happened to microcosm-patterns: its edit landed in a commit whose
pipeline never ran, and the tip commit's diff didn't see it).
drop change detection entirely: read skills/ and ship all 7 each run. the
ship-then-prune step already guarantees one record per skill, so re-shipping
unchanged skills is harmless. cheap and can never miss one.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
two changes that together remove all local runtime requirements:
- remove the atproto-mcp server: it loads a heavy sentence-transformers index
into the local process on startup, not worth imposing on users. instead,
microcosm-patterns now points the agent at atproto.com guides+specs,
docs.bsky.app, and the bluesky-social/atproto lexicons dir, and to inspect
unfamiliar lexicons via ufos+slingshot.
- point pdsx at its hosted endpoint (pdsx-by-zzstoatzz.fastmcp.app) instead of
`uvx --from pdsx[mcp]`. both bundled servers are now hosted HTTP, so uv is no
longer a requirement — dropped that whole section from the README.
updated README (requirements removed, server table, credits) and the codex
longDescription. verified in an isolated checkout: plugin loads pdsx +
pub-search, both ✓ Connected over HTTP.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
atproto-mcp loads a heavy sentence-transformers index into the local process
on startup — not worth imposing on every user. dropped it from .mcp.json.
microcosm-patterns now tells the agent to read protocol docs / lexicon schemas
directly (atproto.com guides+specs, docs.bsky.app, the bluesky-social/atproto
lexicons dir) and to inspect unfamiliar lexicons via ufos+slingshot, instead of
relying on a bundled docs index. updated README (server tables, requirements)
and the codex longDescription.
verified: `claude --plugin-dir .` now loads only pdsx + pub-search.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- "a claude code plugin" -> Claude Code AND Codex (codex install added in 38cf526)
- pub-search URL: pub-search.waow.tech -> the actual .mcp.json endpoint
(pub-search-by-zzstoatzz.fastmcp.app/mcp)
- local dev: `claude --plugin-dir .` (was ./protopack, a nonexistent subdir)
- note the vit auto-publish workflow
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
vit ship writes a new org.v-it.skill record each run and leaves the old
same-name one behind (not idempotent). publish-skills.mjs now opens a PDS
session (resolve handle -> did -> PDS, createSession with the app password),
snapshots existing skill-<name> records, ships, then deletes the prior ones —
leaving exactly one record per skill. ship failure keeps the old record. a
skill deleted from the repo gets all its records removed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
per the Agent Skills spec (agentskills.io): names should be domain-clear and
name must match the dir. two fixes:
- `app-patterns` was vague -> `microcosm-patterns` (it's specifically about
composing Constellation/Slingshot/Spacedust/UFOs)
- dropped the standalone `atproto` skill: a skill named "atproto" overclaims
when the whole pack is atproto. its orientation (mental model, tool
inventory, which-tool-for-what) is now the top of microcosm-patterns.
updated README table, the publish-skills tag map, and shipped the rename to
vit (deleted the orphaned skill-atproto / skill-app-patterns records). vit
now matches the repo: 7 skills.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
second CI run got past the PATH fix and headless login succeeded, then died
on `sed: command not found` — the nixery image (nodejs/git/bash) has no
sed/sort/awk. rather than fight shell portability, do it in node (already
present): scripts/publish-skills.mjs diffs skills/<name>/ vs the previous
commit and ships only changed skills. workflow just runs the script.
verified locally: HEAD (only .tangled changed) → "no skill changes"; the
wisp-fix commit → detects ['wisp'].
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
first run failed with `bash: line 7: vit: command not found` — `npm install
-g vit` succeeds but the nixery image doesn't have npm's global bin dir on
PATH. export it after install (and `vit --version` as a fast smoke check).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
.tangled/workflows/publish-skills.yml: on push to main, ship only the skills
whose skills/<name>/ tree changed in that push (first push ships all). headless
auth via `vit login --app-password "$VIT_APP_PASSWORD"`; sets CLAUDECODE=1 to
satisfy vit's coding-agent gate on `ship --skill`. per-skill discovery tags.
wisp skill corrected against wisp.place-monorepo source + the live hosting
service (both claims were stale):
- there IS a `login`/`logout` subcommand, plus headless `--password` for CI;
removed the "no separate login subcommand / run interactively" guidance
- the path rewriter does NOT mangle inline JS: it's a tag scanner that copies
<script>/<style> through unchanged and only rewrites root-relative URLs in
specific attributes (verified: zero subpath injection in a live served page)
- clarified `serve` previews a DEPLOYED site (firehose), not the local build
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
packages protopack as a codex cli plugin alongside the existing claude code
plugin (skills + .mcp.json reused verbatim), and corrects skill drift found
by checking each tool's live API and source.
codex plugin:
- .codex-plugin/plugin.json (mirrors .claude-plugin + codex `interface` block)
- .agents/plugins/marketplace.json (root plugin via `url` source — codex only
discovers plugins in marketplace subdirs, so a self-referential `url` entry
is required; verified end-to-end with codex-cli 0.133)
- README documents `codex plugin marketplace add` / `plugin add`
- .gitignore for vit's local .vit/ ship log
skill audit (verified against live endpoints + at-microcosm/microcosm-rs source):
- ufos: rewrote — there is no `/collection/{nsid}` route; param is `order`
(kebab-case enum dids-estimate|records-created), not `sort`; stats/timeseries/
records/prefix/search are separate endpoints; collection is repeatable; limit
1..=200
- pub-search: `search_semantic`/`search_hybrid` aren't tools — it's one `search`
with a `mode` enum; added real tools (get_popular, discover_focal_post,
describe_cluster, recommended_by_top_authors) + `author` filter
- spacedust: current version emits only operation:"create" (no history → no
deletes/replay); messages include source_rev; limits/prefixes/filter-logic
confirmed against source
- app-patterns + microcosm-api.md: synced ufos section; /links/distinct-dids
takes collection+path (not source); resolveMiniDoc returns handle/pds (not
avatars)
slingshot, constellation, atproto verified correct (unchanged); wisp left as-is
(recently audited from source).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
the html-rewriter.ts regex-matches attribute names (src, href, action,
data, poster, srcset) with \b word boundaries across the entire HTML
string — it doesn't exclude <script> tags. any JS variable named
`data`, `src`, etc. followed by `=` gets rewritten as a path.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
previous description said wisp only rewrites HTML href/src attributes.
wrong — it also rewrites inside <script> tags. anything matching
`= /...` gets path-prefixed, turning `= await res.json()` into
`=/did:plc:.../site/await res.json()`. the safe fix is always using
external .js files instead of inline scripts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
the previous replace_all merged closing ``` onto curl lines.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
plugin users may not have jq (or python3) installed. the curl examples
work fine without pretty-printing and the response shape comments
already document the structure.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
consolidated endpoint tables, param details, response shapes, and
source format values for all four Microcosm services in one reference
file. loaded on demand when Claude is actually building with the APIs,
not on every skill activation.
follows agentskills.io progressive disclosure pattern: SKILL.md is the
overview, references/ has the dense material Claude pulls when needed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
brief paragraph covering repos, DIDs, handles, collections, lexicons,
PDS, relays, AppViews, and portable identity. links to atproto.com's
understanding-atproto page for deeper grounding via WebFetch.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
the web explorer is for humans — claude needs API params. reframe the
web explorer as something to suggest to users, keep the actionable
guidance on sort and prefix filtering.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- app-patterns: document which Bluesky public API endpoints work without
auth (getProfile, getFeed, etc.) vs which don't (searchPosts, getTimeline)
- ufos: emphasize web explorer over raw API for browsing
- wisp: clarify auth is inline during deploy, no separate login subcommand
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
curl examples document endpoint URLs, parameter names, and response
shapes — not teaching Claude how to use curl. UFOs gets actual query
params (sort, prefix, collection detail) since the worker was guessing
blindly. CORS note in app-patterns. Spacedust gets a concrete websocat
example showing filter construction.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
new atproto skill triggers on any atproto work and shows
what tools are available. wisp skill now warns about subpath
serving and framework path requirements.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
remove code examples that teach Claude things it already knows
(fetch, Promise.all, WebSocket). keep only what it genuinely
doesn't have: endpoint URLs, param formats, filter logic,
decision guidance.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- point to live docs at each service's URL instead of mirroring API ref
- include only tested, working examples (verified with curl)
- note getBacklinkDids/getManyToMany are in source but not yet deployed
- dramatically shorter — 592 lines removed
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
constellation:
- restore getBacklinkDids XRPC endpoint (it exists in source)
- add getManyToMany endpoint (list items, not just counts)
- fix limits back to 100/1000 (source constants, web docs were stale)
- confirm cursor support on all paginated endpoints
- document /links/all endpoint for exploring all link types
slingshot:
- add blue.microcosm.identity.resolveMiniDoc (new stable path)
- add blue.microcosm.repo.getRecordByUri (ergonomic AT-URI endpoint)
- note com.atproto.sync.getRecord is work in progress
- note listRecords is not supported
- migrate examples from com.bad-example to blue.microcosm namespace
spacedust:
- add filter limits (subjects 50k, DIDs 10k, prefixes 100, sources 1k)
- document AND/OR semantics: subject filters OR each other, AND with sources
app-patterns:
- migrate to blue.microcosm namespace in examples
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- getManyToManyCounts is for many-to-many relationships, not batch queries
- getBacklinkDids XRPC endpoint doesn't exist (legacy /links/distinct-dids only)
- default limit is 16, max is 100 (not 100/1000)
- update app-patterns to use parallel getBacklinksCount instead of wrong batch endpoint
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
indexes Leaflet, Whitewind, Pckt, Offprint, Greengale via keyword,
semantic, and hybrid search. bundled as hosted MCP server.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
skills for Microcosm services (Constellation, Spacedust, Slingshot, UFOs),
bundled MCP servers (pdsx for record CRUD, atproto-mcp for docs search),
and common app-building patterns.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrites the auth section from a "two ways" menu into a directive (run the
command, it opens the browser; don't pre-login or offer app-passwords unless
headless). Adds a serving-model section (SPA mode, _redirects, custom 404,
root-relative rewriter) and its hard limit — static files only, no per-request
OG/meta injection, so per-page link previews need an external renderer while
display pages don't. Documents the async custom-domain claim→DNS→verify→add-site
flow.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
the publish-skills workflow used a ship-then-prune step (vit ship isn't
idempotent, so it deleted old same-name records after shipping). that prune is
unsafe under concurrent CI runs: overlapping runs snapshot each other's
freshly-shipped records as "stale" and delete them — which wiped the published
skills. not worth the risk for 7 skills. publish manually instead:
CLAUDECODE=1 vit ship --skill ./skills/<name>/ --tags "..."
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tangled CI exposes only the current commit (TANGLED_SHA), no push range — so a
HEAD~1 diff misses skills edited in earlier commits of a multi-commit push
(exactly what happened to microcosm-patterns: its edit landed in a commit whose
pipeline never ran, and the tip commit's diff didn't see it).
drop change detection entirely: read skills/ and ship all 7 each run. the
ship-then-prune step already guarantees one record per skill, so re-shipping
unchanged skills is harmless. cheap and can never miss one.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
two changes that together remove all local runtime requirements:
- remove the atproto-mcp server: it loads a heavy sentence-transformers index
into the local process on startup, not worth imposing on users. instead,
microcosm-patterns now points the agent at atproto.com guides+specs,
docs.bsky.app, and the bluesky-social/atproto lexicons dir, and to inspect
unfamiliar lexicons via ufos+slingshot.
- point pdsx at its hosted endpoint (pdsx-by-zzstoatzz.fastmcp.app) instead of
`uvx --from pdsx[mcp]`. both bundled servers are now hosted HTTP, so uv is no
longer a requirement — dropped that whole section from the README.
updated README (requirements removed, server table, credits) and the codex
longDescription. verified in an isolated checkout: plugin loads pdsx +
pub-search, both ✓ Connected over HTTP.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
atproto-mcp loads a heavy sentence-transformers index into the local process
on startup — not worth imposing on every user. dropped it from .mcp.json.
microcosm-patterns now tells the agent to read protocol docs / lexicon schemas
directly (atproto.com guides+specs, docs.bsky.app, the bluesky-social/atproto
lexicons dir) and to inspect unfamiliar lexicons via ufos+slingshot, instead of
relying on a bundled docs index. updated README (server tables, requirements)
and the codex longDescription.
verified: `claude --plugin-dir .` now loads only pdsx + pub-search.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- "a claude code plugin" -> Claude Code AND Codex (codex install added in 38cf526)
- pub-search URL: pub-search.waow.tech -> the actual .mcp.json endpoint
(pub-search-by-zzstoatzz.fastmcp.app/mcp)
- local dev: `claude --plugin-dir .` (was ./protopack, a nonexistent subdir)
- note the vit auto-publish workflow
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
vit ship writes a new org.v-it.skill record each run and leaves the old
same-name one behind (not idempotent). publish-skills.mjs now opens a PDS
session (resolve handle -> did -> PDS, createSession with the app password),
snapshots existing skill-<name> records, ships, then deletes the prior ones —
leaving exactly one record per skill. ship failure keeps the old record. a
skill deleted from the repo gets all its records removed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
per the Agent Skills spec (agentskills.io): names should be domain-clear and
name must match the dir. two fixes:
- `app-patterns` was vague -> `microcosm-patterns` (it's specifically about
composing Constellation/Slingshot/Spacedust/UFOs)
- dropped the standalone `atproto` skill: a skill named "atproto" overclaims
when the whole pack is atproto. its orientation (mental model, tool
inventory, which-tool-for-what) is now the top of microcosm-patterns.
updated README table, the publish-skills tag map, and shipped the rename to
vit (deleted the orphaned skill-atproto / skill-app-patterns records). vit
now matches the repo: 7 skills.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
second CI run got past the PATH fix and headless login succeeded, then died
on `sed: command not found` — the nixery image (nodejs/git/bash) has no
sed/sort/awk. rather than fight shell portability, do it in node (already
present): scripts/publish-skills.mjs diffs skills/<name>/ vs the previous
commit and ships only changed skills. workflow just runs the script.
verified locally: HEAD (only .tangled changed) → "no skill changes"; the
wisp-fix commit → detects ['wisp'].
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
.tangled/workflows/publish-skills.yml: on push to main, ship only the skills
whose skills/<name>/ tree changed in that push (first push ships all). headless
auth via `vit login --app-password "$VIT_APP_PASSWORD"`; sets CLAUDECODE=1 to
satisfy vit's coding-agent gate on `ship --skill`. per-skill discovery tags.
wisp skill corrected against wisp.place-monorepo source + the live hosting
service (both claims were stale):
- there IS a `login`/`logout` subcommand, plus headless `--password` for CI;
removed the "no separate login subcommand / run interactively" guidance
- the path rewriter does NOT mangle inline JS: it's a tag scanner that copies
<script>/<style> through unchanged and only rewrites root-relative URLs in
specific attributes (verified: zero subpath injection in a live served page)
- clarified `serve` previews a DEPLOYED site (firehose), not the local build
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
packages protopack as a codex cli plugin alongside the existing claude code
plugin (skills + .mcp.json reused verbatim), and corrects skill drift found
by checking each tool's live API and source.
codex plugin:
- .codex-plugin/plugin.json (mirrors .claude-plugin + codex `interface` block)
- .agents/plugins/marketplace.json (root plugin via `url` source — codex only
discovers plugins in marketplace subdirs, so a self-referential `url` entry
is required; verified end-to-end with codex-cli 0.133)
- README documents `codex plugin marketplace add` / `plugin add`
- .gitignore for vit's local .vit/ ship log
skill audit (verified against live endpoints + at-microcosm/microcosm-rs source):
- ufos: rewrote — there is no `/collection/{nsid}` route; param is `order`
(kebab-case enum dids-estimate|records-created), not `sort`; stats/timeseries/
records/prefix/search are separate endpoints; collection is repeatable; limit
1..=200
- pub-search: `search_semantic`/`search_hybrid` aren't tools — it's one `search`
with a `mode` enum; added real tools (get_popular, discover_focal_post,
describe_cluster, recommended_by_top_authors) + `author` filter
- spacedust: current version emits only operation:"create" (no history → no
deletes/replay); messages include source_rev; limits/prefixes/filter-logic
confirmed against source
- app-patterns + microcosm-api.md: synced ufos section; /links/distinct-dids
takes collection+path (not source); resolveMiniDoc returns handle/pds (not
avatars)
slingshot, constellation, atproto verified correct (unchanged); wisp left as-is
(recently audited from source).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
the html-rewriter.ts regex-matches attribute names (src, href, action,
data, poster, srcset) with \b word boundaries across the entire HTML
string — it doesn't exclude <script> tags. any JS variable named
`data`, `src`, etc. followed by `=` gets rewritten as a path.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
previous description said wisp only rewrites HTML href/src attributes.
wrong — it also rewrites inside <script> tags. anything matching
`= /...` gets path-prefixed, turning `= await res.json()` into
`=/did:plc:.../site/await res.json()`. the safe fix is always using
external .js files instead of inline scripts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
consolidated endpoint tables, param details, response shapes, and
source format values for all four Microcosm services in one reference
file. loaded on demand when Claude is actually building with the APIs,
not on every skill activation.
follows agentskills.io progressive disclosure pattern: SKILL.md is the
overview, references/ has the dense material Claude pulls when needed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- app-patterns: document which Bluesky public API endpoints work without
auth (getProfile, getFeed, etc.) vs which don't (searchPosts, getTimeline)
- ufos: emphasize web explorer over raw API for browsing
- wisp: clarify auth is inline during deploy, no separate login subcommand
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
curl examples document endpoint URLs, parameter names, and response
shapes — not teaching Claude how to use curl. UFOs gets actual query
params (sort, prefix, collection detail) since the worker was guessing
blindly. CORS note in app-patterns. Spacedust gets a concrete websocat
example showing filter construction.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
constellation:
- restore getBacklinkDids XRPC endpoint (it exists in source)
- add getManyToMany endpoint (list items, not just counts)
- fix limits back to 100/1000 (source constants, web docs were stale)
- confirm cursor support on all paginated endpoints
- document /links/all endpoint for exploring all link types
slingshot:
- add blue.microcosm.identity.resolveMiniDoc (new stable path)
- add blue.microcosm.repo.getRecordByUri (ergonomic AT-URI endpoint)
- note com.atproto.sync.getRecord is work in progress
- note listRecords is not supported
- migrate examples from com.bad-example to blue.microcosm namespace
spacedust:
- add filter limits (subjects 50k, DIDs 10k, prefixes 100, sources 1k)
- document AND/OR semantics: subject filters OR each other, AND with sources
app-patterns:
- migrate to blue.microcosm namespace in examples
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- getManyToManyCounts is for many-to-many relationships, not batch queries
- getBacklinkDids XRPC endpoint doesn't exist (legacy /links/distinct-dids only)
- default limit is 16, max is 100 (not 100/1000)
- update app-patterns to use parallel getBacklinksCount instead of wrong batch endpoint
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>