diff --git a/apps/docs/astro.config.mjs b/apps/docs/astro.config.mjs
index 99942776..2885c78b 100644
--- a/apps/docs/astro.config.mjs
+++ b/apps/docs/astro.config.mjs
@@ -3,6 +3,7 @@ import { satteri } from "@astrojs/markdown-satteri";
import starlight from "@astrojs/starlight";
import tailwindcss from "@tailwindcss/vite";
import { defineConfig, envField, passthroughImageService } from "astro/config";
+import starlightBlog from "starlight-blog";
import starlightLlmsTxt from "starlight-llms-txt";
// Pages to include in llms-small.txt (unlisted pages are excluded automatically)
@@ -197,6 +198,9 @@ export default defineConfig({
ThemeProvider: "./src/components/starlight/ThemeProvider.astro",
},
plugins: [
+ starlightBlog({
+ title: "Blog",
+ }),
starlightLlmsTxt({
details: [
"Use these files progressively to control context size:",
@@ -227,7 +231,9 @@ export default defineConfig({
"errors*",
],
demote: ["ejecting*", "examples/*"],
- exclude: llmsSmallExclude,
+ // Blog posts are narrative, not reference material — keep them out of
+ // the generated llms-*.txt bundles.
+ exclude: [...llmsSmallExclude, "blog/**"],
rawContent: true,
customSets: [
{
diff --git a/apps/docs/package.json b/apps/docs/package.json
index 5a173820..b94c728b 100644
--- a/apps/docs/package.json
+++ b/apps/docs/package.json
@@ -23,6 +23,7 @@
"@astrojs/starlight": "^0.41.2",
"@astrojs/starlight-tailwind": "^5.0.0",
"astro": "^7.0.6",
+ "starlight-blog": "^0.27.0",
"starlight-llms-txt": "^0.11.0"
},
"devDependencies": {
diff --git a/apps/docs/src/content.config.ts b/apps/docs/src/content.config.ts
index 4be85d57..ecb54c25 100644
--- a/apps/docs/src/content.config.ts
+++ b/apps/docs/src/content.config.ts
@@ -1,8 +1,15 @@
import { docsLoader, i18nLoader } from "@astrojs/starlight/loaders";
import { docsSchema, i18nSchema } from "@astrojs/starlight/schema";
import { defineCollection } from "astro:content";
+import { blogSchema } from "starlight-blog/schema";
export const collections = {
- docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),
+ docs: defineCollection({
+ loader: docsLoader(),
+ // Extend the docs schema with starlight-blog's frontmatter fields (date,
+ // tags, excerpt, featured, draft, authors, cover). Only files under blog/
+ // use them.
+ schema: docsSchema({ extend: (context) => blogSchema(context) }),
+ }),
i18n: defineCollection({ loader: i18nLoader(), schema: i18nSchema() }),
};
diff --git a/apps/docs/src/content/docs/blog/_template.mdx b/apps/docs/src/content/docs/blog/_template.mdx
new file mode 100644
index 00000000..ccfc888e
--- /dev/null
+++ b/apps/docs/src/content/docs/blog/_template.mdx
@@ -0,0 +1,25 @@
+---
+# Copy this file to start a new post. Rename it to something URL-friendly
+# (the filename becomes the slug, e.g. blog/my-new-post) and delete this
+# comment block.
+title: Post title
+# A valid YAML date. Posts are listed newest-first by this field.
+date: 2026-07-06
+# Shown in the blog index and tag/author pages. Supports basic Markdown.
+excerpt: One or two sentences summarizing the post.
+tags:
+ - announcements
+# Set featured: true to pin the post to a "Featured posts" sidebar group.
+# featured: true
+# draft: true keeps the post visible in `pnpm dev` but out of production builds.
+draft: true
+---
+
+import NewsletterSignup from "../../../components/landing/NewsletterSignup.astro";
+
+Write the post body here as Markdown. Because this is an `.mdx` file you can
+also import and use Astro components.
+
+End every post with the newsletter call-to-action so readers can subscribe:
+
+
diff --git a/apps/docs/src/content/docs/blog/introducing-the-typegraph-blog.mdx b/apps/docs/src/content/docs/blog/introducing-the-typegraph-blog.mdx
new file mode 100644
index 00000000..c63ec3df
--- /dev/null
+++ b/apps/docs/src/content/docs/blog/introducing-the-typegraph-blog.mdx
@@ -0,0 +1,28 @@
+---
+title: Introducing the TypeGraph blog
+date: 2026-07-06
+excerpt: A home for release notes with narrative, deep-dives on new examples, and community highlights.
+tags:
+ - announcements
+---
+
+import NewsletterSignup from "../../../components/landing/NewsletterSignup.astro";
+
+Welcome to the TypeGraph blog. The [changelog](/changelog) will always be the
+authoritative, machine-generated list of what shipped — but it can't tell you
+_why_ a change matters or _how_ to use it. That's what this space is for.
+
+Here's what you can expect to find here:
+
+- **Release narratives** — the story behind a version: the problem that
+ prompted a feature, the design trade-offs, and how to adopt it.
+- **Example deep-dives** — walkthroughs of new entries in the
+ [examples](/examples/fhir-graph-merge) gallery, from FHIR graph merges to
+ agent-driven schemas.
+- **Community highlights** — projects, integrations, and patterns the community
+ is building on top of TypeGraph.
+
+New to the project? Start with [What is TypeGraph?](/overview) and the
+[Quick Start](/getting-started).
+
+
diff --git a/apps/docs/src/content/docs/blog/truth-maintenance-for-agent-memory.mdx b/apps/docs/src/content/docs/blog/truth-maintenance-for-agent-memory.mdx
new file mode 100644
index 00000000..cd34f8d6
--- /dev/null
+++ b/apps/docs/src/content/docs/blog/truth-maintenance-for-agent-memory.mdx
@@ -0,0 +1,178 @@
+---
+title: "Bitemporal Recorded Time and Provenance Retraction in TypeGraph"
+excerpt: "The last two releases complete TypeGraph's truth-maintenance story: 0.33 adds a second temporal axis, 0.34 adds provenance-backed retraction. Together they let a graph say why it believes a fact and recompute that belief when a source turns out to be wrong."
+date: 2026-07-07
+tags:
+ - announcements
+---
+
+import NewsletterSignup from "../../../components/landing/NewsletterSignup.astro";
+
+The last two TypeGraph releases finish a feature we'd been building toward for a while: a truth-maintenance layer for graph data, running on ordinary Postgres and SQLite tables.
+
+- **0.33** adds *recorded time* — a second temporal axis alongside TypeGraph's existing valid-time history — so you can reconstruct what the graph believed as of a given commit instant.
+- **0.34** adds the `@nicia-ai/typegraph/provenance` subpath: a way to record *why* a derived fact is believed, and to retract a bad source and have the graph recompute which facts still hold.
+
+This post walks through what each release shipped, then works a single example — a security pipeline whose overnight run turned out to be wrong — to show what the two together actually buy you.
+
+## Recorded time, the second temporal axis
+
+TypeGraph already had valid-time history. 0.33 adds the orthogonal axis, so the graph is now bitemporal:
+
+- **Valid time** is when a fact was true in the world — an invoice's effective date, a role grant's window — controlled by `validFrom` / `validTo` and read with `store.asOf(T)`.
+- **Recorded time** is when TypeGraph captured that fact — what the system knew, as of a commit instant. It's the SQL:2011 `FOR SYSTEM_TIME` axis, or Datomic's system-time axis, read with `store.asOfRecorded(T)`.
+
+Enable capture per store:
+
+```typescript
+const store = createStore(graph, backend, { history: true });
+```
+
+Managed collection writes through that store are then captured into recorded-time relations, each stamped with a per-graph monotonic commit instant (serialized on PostgreSQL via a per-graph advisory lock). Read at a recorded instant with `store.asOfRecorded(T)`, which returns a narrow, read-only reconstructing view; `store.recordedNow()` gives you the current high-water mark to use as an "as things stand now" anchor.
+
+The two axes are independent read lenses, and because they're lenses, they compose:
+
+```typescript
+store.asOf(validTime).asOfRecorded(recordedTime)
+```
+
+`store.asOf(T)` alone answers "what was true in the world at `T`." `store.asOfRecorded(T)` alone is diagonal bitemporal sugar — recorded and valid axes pinned to the same instant. Chain the two to pin them independently.
+
+One naming note, since it trips people coming from other systems: TypeGraph's `asOf` is valid time — the reverse of SQL:2011's `FOR SYSTEM_TIME AS OF` and Datomic's `d/as-of`, where a bare "as of" means system time. Valid-time reads are the common case here, so they got the short name; system time is the more explicit `asOfRecorded`.
+
+A few sharp edges worth knowing up front, because recorded time is deliberately an audit-and-replay lens, not a hot path:
+
+- **The recorded view reconstructs, so it only exposes reads that can be faithfully rebuilt** from the history relations: point reads (`getById` / `getByIds` and edge equivalents), a sealed `query()`, `subgraph()`, and the graph algorithms. Broad collection reads (`find` / `count`), `search`, and fulltext / vector predicates refuse with a typed error — those indexes reflect current state only.
+- **No backfill.** Capture is opt-in; enable it on a fresh graph. An entity that already existed is first recorded the next time it's written.
+- **Writes under `history: true` go through the typed collections.** Raw `tx.sql` is disabled (it would bypass capture), and external transactions adopt the callback form `store.withRecordedTransaction(externalTx, async (tx) => ...)` so capture has a flush point before the caller commits.
+
+## Provenance and retraction
+
+Recorded time answers "what did the graph believe, and when." 0.34 answers the harder question: *why* does it believe a derived fact, and what should happen to that fact when one of its premises turns out to be wrong.
+
+The new `@nicia-ai/typegraph/provenance` subpath maps your existing graph kinds onto four roles — sources, justifications, facts, and the edges between them — and gives you a `retract` operation that recomputes support instead of deleting blindly. It requires `{ history: true }`, so it builds directly on the 0.33 axis.
+
+```typescript
+import { createRetractionCapability } from "@nicia-ai/typegraph/provenance";
+
+const provenance = createRetractionCapability(store, {
+ source: { kinds: ["ScannerSource", "VendorSource"] },
+ justification: { kind: "Justification" },
+ fact: { kinds: ["Vulnerability", "DeployDecision"] },
+ premiseOf: { kind: "premiseOf" },
+ derives: { kind: "derives" },
+});
+```
+
+A fact stays believed while it has at least one justification whose premises are all still supported. Premises bottom out at sources. Retract a source and every justification that leaned on it stops counting — a fact loses currency only once it runs out of surviving justifications.
+
+Two properties make this safe to reach for:
+
+- **Retraction is scoped.** A transition only touches facts reachable from the sources that flipped.
+- **Retraction is reversible.** Closing a fact's currency is a belief-status change, not a domain delete — its edges are left untouched, so `unRetract` is an exact inverse of `retract`. And because it's a normal write under `history: true`, the whole before/after is replayable through `asOfRecorded`.
+
+This is deliberately the well-founded, monotonic slice of classic truth maintenance rather than a reimplementation of it wholesale. The storage follows the JTMS shape from Doyle's 1979 *A Truth Maintenance System* — AND-justifications over premises, sources as the base case, a fact believed only if some justification has all its premises supported. The question `retract` answers — which facts keep support after a source drops out — is the ATMS question from de Kleer's 1986 work: which combinations of sources hold each fact up. JTMS-shaped storage, ATMS-flavored query, ordinary SQL underneath. You configure it by mapping your own node kinds onto the roles, so an agent keeps writing ordinary graph data — it doesn't move to a dedicated reasoning engine to get retraction semantics.
+
+## What this enables: truth maintenance for agent memory
+
+The reason these two releases matter together is easiest to see on a concrete failure.
+
+Agent memory usually means retrieval: embed everything, fetch nearest neighbors, let the model sort it out. That works for recall. It doesn't work for belief. Retrieval remembers what was said. It doesn't remember *why* something was concluded, or what should happen to that conclusion when one of its sources turns out to be wrong. As agents move from a single chat transcript to a fleet that writes into shared memory — ingesting feeds, running scans, triaging into decisions — that gap stops being theoretical.
+
+Say a security pipeline runs overnight. A vuln-feed agent flags 60 services as shipping a vulnerable library, blocks their deploys, opens fix PRs, and pages the owning teams. By morning it turns out the feed had a bad package-name mapping and pinned a real CVE to the wrong package across a class of entries.
+
+What should happen to the 60 flags?
+
+You can't wipe them from the graph — some were independently confirmed by a SAST run or an SBOM check, and those services are genuinely vulnerable. You can't leave them either, because most were only ever the feed talking, and right now they're blocking shipments and paging people for nothing.
+
+What you actually want is the blast radius: of the 60, which flags die when the feed goes, and which stand on their own?
+
+Most memory stores can't answer that, because they store conclusions — messages, summaries, embeddings, rows — without recording which premises made each conclusion current. With the provenance layer, the support structure is right there in the graph:
+
+```plaintext
+VulnFeed ──▶ Vulnerable(svc-14) ──▶ BlockDeploy(svc-14)
+SASTRun ──▶ Vulnerable(svc-14) two sources, survives
+
+VulnFeed ──▶ Vulnerable(svc-22) ──▶ BlockDeploy(svc-22)
+ feed only, dies
+```
+
+Retract the feed, and `Vulnerable(svc-22)` loses its only source and goes non-current, which means `BlockDeploy(svc-22)` loses its premise and goes non-current too — the deploy unblocks. `Vulnerable(svc-14)` survives because the SAST run still backs it, so that block stands.
+
+```typescript
+const report = await provenance.retract({
+ kind: "VulnFeed",
+ id: badMappingSnapshotId,
+});
+
+// report.died:
+// flags and deploy blocks that had only the feed behind them
+//
+// report.survivedVia:
+// flags still confirmed by SAST or the SBOM check
+```
+
+Run that across all 60 services and `report` is the cleanup list: `died` is "unblock these and close the PRs," `survivedVia` is "these are still real." That's the query you can't run by hand at that scale.
+
+The source doesn't have to be a feed — it can be another agent's run. If a triage agent combined an overnight feed-ingest run, a SAST scan, and an SBOM rebuild into block-and-page decisions, and the feed-ingest run turns out to have trusted bad data, you retract that run as a source, not the whole fleet's memory:
+
+```typescript
+const report = await provenance.retract({
+ kind: "AgentRun",
+ id: overnightFeedRunId,
+});
+```
+
+Flags that only that run raised go non-current. Flags another run also supports survive. One agent can be wrong locally; shared memory recovers locally too, because it knows the blast radius.
+
+And because retraction lands on recorded time, the whole thing is replayable. It doesn't hard-delete — it flips unsupported facts to non-current and leaves the justification edges in place, so you can still see why something used to be believed:
+
+```typescript
+const before = await store.recordedNow();
+
+await provenance.retract({
+ kind: "VulnFeed",
+ id: badMappingSnapshotId,
+});
+
+const after = await store.recordedNow();
+
+await store.asOfRecorded(before)
+ .nodes.BlockDeploy
+ .getById("svc-22"); // current
+
+await store.asOfRecorded(after)
+ .nodes.BlockDeploy
+ .getById("svc-22"); // non-current
+```
+
+"Why did the agent block svc-22 at 2am, and why doesn't it anymore" becomes a query instead of an archaeology dig through logs.
+
+## Why plain SQL, and what it costs
+
+There's no portable, engine-native system-versioning story across Postgres and SQLite — Postgres needs an extension or an application-level pattern for it, and SQLite has no system-versioned table type at all. So TypeGraph stores history explicitly in its own relations and reconstructs point-in-time views in the query compiler, rather than delegating to a backend feature that only one engine has. One implementation runs on both backends: the same memory model works from a local SQLite file up to shared Postgres, with the provenance semantics unchanged. A solo agent can run this locally; a fleet writes into shared infrastructure with the same API.
+
+That reconstruction isn't free, and it's worth being upfront about the shape of the cost:
+
+- Only TypeGraph-managed writes are captured — raw SQL bypasses it. This is a provenance and audit layer for graph writes, not a database-level CDC/audit system.
+- There's no backfill. Enable history on a fresh graph; an entity that already existed before capture was enabled is first recorded the next time it's written.
+- Point-in-time reads reconstruct from history relations, so they're slower than current-state reads — most noticeably for full-graph reconstructions on PostgreSQL. Treat `asOfRecorded` as an audit and replay tool, not a hot path.
+- Per-write overhead runs roughly 2.5–6× uncaptured writes if each write is its own transaction, dropping to roughly 1–1.5× when writes are batched into one transaction.
+
+## Where this leaves agent memory
+
+A fact stored without provenance is organizational hearsay — memory that can't tell you why it believes what it believes, or what should happen when a source goes bad. That's fine for a single chat agent, where a lot of inconsistency can hide inside one transcript. It stops being fine the moment agents share memory: they'll read stale feeds, trust bad mappings, call flaky tools, and inherit each other's wrong assumptions, constantly.
+
+An agent memory that gates deploys, or maintains any long-lived model of a company, needs to answer three questions: what do we believe, why do we believe it, and what changes if this source turns out to be wrong. Truth maintenance stopped being a research curiosity the moment agents started keeping shared memory — TypeGraph 0.33 and 0.34 are that layer, built on graphs-on-SQL rather than a dedicated reasoning engine.
+
+## Try it
+
+- [Provenance and Retraction docs](/provenance)
+- [Provenance Retraction example](/examples/provenance-retraction/)
+- [Bitemporal Time Travel example](/examples/bitemporal-time-travel/)
+- [Full changelog](/changelog)
+- [GitHub](https://github.com/nicia-ai/typegraph)
+
+If you've mapped JTMS/ATMS-style truth maintenance onto relational storage elsewhere, or know of prior art doing the same, I'd like to hear about it — there's plenty written on truth maintenance systems and not much on doing it directly on ordinary SQL tables.
+
+
diff --git a/apps/docs/src/layouts/Landing.astro b/apps/docs/src/layouts/Landing.astro
index 2763b86c..7839c883 100644
--- a/apps/docs/src/layouts/Landing.astro
+++ b/apps/docs/src/layouts/Landing.astro
@@ -77,6 +77,11 @@ const ogImageAlt =
class="text-text-muted font-semibold hover:text-primary transition-colors"
>Get Started
+ Blog
=22.12.0'}
+ '@astrojs/rss@4.0.19':
+ resolution: {integrity: sha512-e+z5wYeYtffQdHQO8c2tkSd2JEBdAuRXJV4ZEU5IxkYeE6e39woDd7nw1PH1Kk2tEYNCYuKdylnnbhGmt61awA==}
+
'@astrojs/sitemap@3.7.3':
resolution: {integrity: sha512-f8euLVsyeAmAkSm/1M2Kb8sL8byQmfgbvBNaHFItCheTj/IpiJYSEWVcqDHZ/yEHxiS7+w87mQkzwZaPHmk5GA==}
@@ -1725,6 +1731,9 @@ packages:
resolution: {integrity: sha512-r3ZZhRjEcfEdKIZnoB1RusNgvHuaBRqfCzV4Gi+5A9yUX0S4HTws/ASWqt13wL4y4I+0rqsWGdA2w7EQXHi3+Q==}
engines: {node: '>=19.0.0'}
+ '@nodable/entities@2.2.0':
+ resolution: {integrity: sha512-9uGyhaQavEUMC8AIddIjau4NsnsXhou+j5sBAGojCM1oxmQpVKTWR/9JxABD6UAv12vpIms55fPZKFQEhG6uBg==}
+
'@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
@@ -2778,6 +2787,9 @@ packages:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
+ anynum@1.0.1:
+ resolution: {integrity: sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==}
+
arg@5.0.2:
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
@@ -3546,6 +3558,13 @@ packages:
fast-wrap-ansi@0.2.2:
resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==}
+ fast-xml-builder@1.2.1:
+ resolution: {integrity: sha512-tPb5TTWfgfVx5BNSi2xV0eLr89POeXXn0dXIsCJ9m1narrWxeIyx6je9d7Rce/3NyXLbvuQmLkxq+RuxMWejvw==}
+
+ fast-xml-parser@5.9.3:
+ resolution: {integrity: sha512-brCNCeScma/kqa54J4PIDriSSSLssRkuYaUCpvHJulGc3HGI/xxKUCTDcYkAdqJsyb//ydpbxecjC3hB9+tb/g==}
+ hasBin: true
+
fastq@1.20.1:
resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==}
@@ -3948,6 +3967,9 @@ packages:
resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==}
engines: {node: '>=18'}
+ is-unsafe@1.0.1:
+ resolution: {integrity: sha512-CLK2+VdgERgD96EYm5lUQssZYlRg2tkZnbsxZoacmSiRxiFJ4Nk4SzjCl+Ur+v3kXIY9dTIdb3IH22y1mZ56LA==}
+
is-windows@1.0.2:
resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==}
engines: {node: '>=0.10.0'}
@@ -4708,6 +4730,10 @@ packages:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
+ path-expression-matcher@1.6.1:
+ resolution: {integrity: sha512-h7bxdzhHk8Knyc4Tj+jMaa7fEEoUJy7p1qtbVgkYg1Uhpe5Np5VuGXCRZnkZvU+Q42M1vStt0ifa3ueykRJPmQ==}
+ engines: {node: '>=14.0.0'}
+
path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
@@ -5290,6 +5316,12 @@ packages:
stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+ starlight-blog@0.27.0:
+ resolution: {integrity: sha512-eCYT0VusgXXwmDfiTiQMUMjhfJAbtnEq5J0Wit37ut9t/LvBd8Oi9yQwe0kmY6wvH2yU905mNO6FJDZeryWtFw==}
+ engines: {node: '>=22.12.0'}
+ peerDependencies:
+ '@astrojs/starlight': '>=0.41.0'
+
starlight-llms-txt@0.11.0:
resolution: {integrity: sha512-83TU5zPgJhL9fXIWAOWjQjyQ6EKocshEjJyA4zOJjOqu/oxQsrTpYGYxjHLyfZe4LRD52N9eCuykSkaIYwUyDw==}
peerDependencies:
@@ -5348,6 +5380,9 @@ packages:
resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==}
engines: {node: '>=14.16'}
+ strnum@2.4.1:
+ resolution: {integrity: sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg==}
+
style-to-js@1.1.21:
resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==}
@@ -6004,6 +6039,10 @@ packages:
utf-8-validate:
optional: true
+ xml-naming@0.1.0:
+ resolution: {integrity: sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==}
+ engines: {node: '>=16.0.0'}
+
xtend@4.0.2:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
@@ -6267,6 +6306,12 @@ snapshots:
dependencies:
prismjs: 1.30.0
+ '@astrojs/rss@4.0.19':
+ dependencies:
+ fast-xml-parser: 5.9.3
+ piccolore: 0.1.3
+ zod: 4.4.3
+
'@astrojs/sitemap@3.7.3':
dependencies:
sitemap: 9.0.1
@@ -7590,6 +7635,8 @@ snapshots:
'@neondatabase/serverless@1.1.0': {}
+ '@nodable/entities@2.2.0': {}
+
'@nodelib/fs.scandir@2.1.5':
dependencies:
'@nodelib/fs.stat': 2.0.5
@@ -8489,6 +8536,8 @@ snapshots:
normalize-path: 3.0.0
picomatch: 2.3.2
+ anynum@1.0.1: {}
+
arg@5.0.2: {}
argparse@1.0.10:
@@ -9311,6 +9360,20 @@ snapshots:
dependencies:
fast-string-width: 3.0.2
+ fast-xml-builder@1.2.1:
+ dependencies:
+ path-expression-matcher: 1.6.1
+ xml-naming: 0.1.0
+
+ fast-xml-parser@5.9.3:
+ dependencies:
+ '@nodable/entities': 2.2.0
+ fast-xml-builder: 1.2.1
+ is-unsafe: 1.0.1
+ path-expression-matcher: 1.6.1
+ strnum: 2.4.1
+ xml-naming: 0.1.0
+
fastq@1.20.1:
dependencies:
reusify: 1.1.0
@@ -9811,6 +9874,8 @@ snapshots:
is-unicode-supported@2.1.0: {}
+ is-unsafe@1.0.1: {}
+
is-windows@1.0.2: {}
is-wsl@3.1.1:
@@ -10904,6 +10969,8 @@ snapshots:
path-exists@4.0.0: {}
+ path-expression-matcher@1.6.1: {}
+
path-key@3.1.1: {}
path-key@4.0.0: {}
@@ -11629,6 +11696,26 @@ snapshots:
stackback@0.0.2: {}
+ starlight-blog@0.27.0(@astrojs/markdown-satteri@0.3.3)(@astrojs/starlight@0.41.2(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@24.13.2)(jiti@2.7.0)(rollup@4.62.2)(tsx@4.23.0)(yaml@2.9.0))(typescript@5.9.3))(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@24.13.2)(jiti@2.7.0)(rollup@4.62.2)(tsx@4.23.0)(yaml@2.9.0)):
+ dependencies:
+ '@astrojs/markdown-remark': 7.2.1
+ '@astrojs/mdx': 7.0.2(@astrojs/markdown-satteri@0.3.3)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@24.13.2)(jiti@2.7.0)(rollup@4.62.2)(tsx@4.23.0)(yaml@2.9.0))
+ '@astrojs/rss': 4.0.19
+ '@astrojs/starlight': 0.41.2(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@24.13.2)(jiti@2.7.0)(rollup@4.62.2)(tsx@4.23.0)(yaml@2.9.0))(typescript@5.9.3)
+ github-slugger: 2.0.0
+ hast-util-from-html: 2.0.3
+ hast-util-to-html: 9.0.5
+ hast-util-to-string: 3.0.1
+ mdast-util-mdx-expression: 2.0.1
+ satteri: 0.9.4
+ unist-util-is: 6.0.1
+ unist-util-remove: 4.0.0
+ unist-util-visit: 5.1.0
+ transitivePeerDependencies:
+ - '@astrojs/markdown-satteri'
+ - astro
+ - supports-color
+
starlight-llms-txt@0.11.0(@astrojs/markdown-satteri@0.3.3)(@astrojs/starlight@0.41.2(@astrojs/markdown-remark@7.2.1)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@24.13.2)(jiti@2.7.0)(rollup@4.62.2)(tsx@4.23.0)(yaml@2.9.0))(typescript@5.9.3))(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@24.13.2)(jiti@2.7.0)(rollup@4.62.2)(tsx@4.23.0)(yaml@2.9.0)):
dependencies:
'@astrojs/mdx': 7.0.2(@astrojs/markdown-satteri@0.3.3)(astro@7.0.6(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@24.13.2)(jiti@2.7.0)(rollup@4.62.2)(tsx@4.23.0)(yaml@2.9.0))
@@ -11695,6 +11782,10 @@ snapshots:
strip-json-comments@5.0.3: {}
+ strnum@2.4.1:
+ dependencies:
+ anynum: 1.0.1
+
style-to-js@1.1.21:
dependencies:
style-to-object: 1.0.14
@@ -12336,6 +12427,8 @@ snapshots:
ws@8.21.0: {}
+ xml-naming@0.1.0: {}
+
xtend@4.0.2: {}
xxhash-wasm@1.1.0: {}