···11+# archived: expanded plan (partially implemented)
22+33+This file is preserved for context/history. Current direction lives in `docs/roadmap.md`.
44+15# zat - expanded scope
2637the initial release delivered string primitives (Tid, Did, Handle, Nsid, Rkey, AtUri). this plan expands toward a usable AT Protocol sdk.
+4
docs/plan-initial.md
docs/archive/plan-initial.md
···11+# archived: initial plan (out of date)
22+33+This file is preserved for context/history. Current direction lives in `docs/roadmap.md`.
44+15# zat - zig atproto primitives
2637low-level building blocks for atproto applications in zig. not a full sdk - just the pieces that everyone reimplements.
+40
docs/roadmap.md
···11+# roadmap
22+33+`zat` is a grab bag of **AT Protocol building blocks** in Zig: parsers, validators, resolvers, and small protocol helpers.
44+55+This roadmap is intentionally short. If it doesn’t fit into one file, it probably belongs in issues.
66+77+## now
88+99+- keep current APIs stable (0.x semver)
1010+- tighten docs/examples as real apps discover sharp edges
1111+- keep the “primitives, not framework” ethos
1212+1313+## next
1414+1515+### polish
1616+1717+- improve docs around common workflows:
1818+ - resolving handle → DID → PDS
1919+ - making XRPC calls + parsing JSON
2020+ - verifying JWTs from DID documents
2121+- add more integration tests that hit real-world edge cases (without becoming flaky)
2222+2323+### primitives
2424+2525+- fill gaps that show up repeatedly in other atproto projects:
2626+ - CIDs and common multiformats plumbing
2727+ - richer `AtUri` helpers (safe joins, parsing variants)
2828+ - more ergonomic JSON navigation patterns (still optional, no forced codegen)
2929+3030+## later (maybe)
3131+3232+- lexicon codegen is still “probably a separate project”
3333+- higher-level clients/frameworks stay out of scope
3434+3535+## non-goals
3636+3737+- token refresh/session frameworks
3838+- opinionated app scaffolding
3939+- “one true SDK” that tries to do everything
4040+
+19-1
scripts/build-wisp-docs.mjs
···139139140140 const mdFiles = (await exists(docsDir)) ? await listMarkdownFiles(docsDir) : [];
141141142142+ // Copy all markdown under docs/ (including archives), but only include non-archive
143143+ // paths in the sidebar manifest.
142144 for (const rel of mdFiles) {
143145 const src = path.join(docsDir, rel);
144146 const dst = path.join(outDocsDir, rel);
···146148 await cp(src, dst);
147149148150 const md = await readFile(src, "utf8");
149149- pages.push({ path: rel, title: normalizeTitle(titleFromMarkdown(md, rel)) });
151151+ if (!rel.startsWith("archive/")) {
152152+ pages.push({ path: rel, title: normalizeTitle(titleFromMarkdown(md, rel)) });
153153+ }
150154 }
155155+156156+ // Stable nav order: README homepage, then roadmap, then changelog, then the rest.
157157+ pages.sort((a, b) => {
158158+ const order = (p) => {
159159+ if (p === "index.md") return 0;
160160+ if (p === "roadmap.md") return 1;
161161+ if (p === "changelog.md") return 2;
162162+ return 3;
163163+ };
164164+ const ao = order(a.path);
165165+ const bo = order(b.path);
166166+ if (ao !== bo) return ao - bo;
167167+ return a.title.localeCompare(b.title);
168168+ });
151169152170 await writeFile(
153171 path.join(outDir, "manifest.json"),