From 0232f18d8f19cad969a7c464c9beee5a1347c781 Mon Sep 17 00:00:00 2001 From: Sutu Sebastian Date: Fri, 23 Oct 2026 10:50:45 +0300 Subject: [PATCH 01/17] OpenCode v2: add the plugin, docs for both harnesses, and the new homepage Add the OpenCode v2 plugin on the shared engine: a per-session mirror, the DAG projection, a blocking compaction checkpoint, a child-session reader, and nine lifecycle commands. Add the host seams that let the engine run in a second harness. Rebuild the docs around both harnesses: per-harness guides and reference pages from shared Blume includes, audited comparison pages under each harness, and OpenCode options, commands, tools, and files checked against the adapter source. Refresh the toolchain and dependencies, and add changesets for the engine seams, the plugin, the owner-only store files, and the dependency refresh. Bring the updated homepage from Pencil: a Pi, OpenCode v2, and DeepSeek host switch that drives both install commands, the engine and shell package cards, and the refreshed footer. Gates: vp check, bun run test, typecheck, pack, docs build, validate, audit, opencode:check, opencode:smoke. --- .agents/skills/docs-governance/SKILL.md | 65 +- .agents/skills/docs-voice/SKILL.md | 21 +- .../typescript-best-practices/PATTERNS.md | 4 +- .changeset/README.md | 11 +- .changeset/core-host-seams.md | 5 + .changeset/dependency-refresh.md | 7 + .changeset/opencode-lossless.md | 5 + .changeset/owner-only-store-files.md | 5 + .github/actions/setup/action.yml | 4 +- .github/workflows/ci.yml | 43 +- .github/workflows/deploy-docs.yml | 3 - AGENTS.md | 4 +- README.md | 80 +- apps/docs/.gitignore | 3 - apps/docs/blume.config.ts | 39 +- apps/docs/components.ts | 12 +- apps/docs/components/blume/EmptyFooter.astro | 4 + apps/docs/components/blume/Footer.astro | 53 +- apps/docs/components/blume/Header.astro | 156 ++- apps/docs/components/blume/Pagination.astro | 37 +- apps/docs/components/blume/Sidebar.astro | 171 +++ apps/docs/components/curated-popular.ts | 8 +- apps/docs/components/mdx/HarnessCards.astro | 57 + apps/docs/components/seo/FaqSection.astro | 13 +- apps/docs/components/seo/lcm-faqs.ts | 58 +- apps/docs/components/seo/opencode-faqs.ts | 49 + apps/docs/components/seo/pi-faqs.ts | 44 + apps/docs/components/visuals/DagFigure.astro | 117 +- apps/docs/components/visuals/RecallFlow.astro | 6 +- .../_snippets/guides/configuration/intro.mdx | 1 + .../guides/configuration/opencode.mdx | 24 + .../_snippets/guides/configuration/pi.mdx | 77 ++ .../guides/cross-session-recall/intro.mdx | 1 + .../guides/cross-session-recall/opencode.mdx | 5 + .../guides/cross-session-recall/pi.mdx | 57 + .../guides/getting-started/after.mdx | 40 + .../guides/getting-started/intro.mdx | 5 + .../guides/getting-started/opencode.mdx | 86 ++ .../_snippets/guides/getting-started/pi.mdx | 62 + .../guides/troubleshooting/intro.mdx | 1 + .../guides/troubleshooting/opencode.mdx | 11 + .../guides/troubleshooting/pi.mdx} | 57 +- .../_snippets/reference/command/after.mdx | 1 + .../_snippets/reference/command/intro.mdx | 1 + .../_snippets/reference/command/opencode.mdx | 93 ++ .../reference/command/pi.mdx} | 40 +- .../_snippets/reference/config/after.mdx | 5 + .../_snippets/reference/config/intro.mdx | 1 + .../_snippets/reference/config/opencode.mdx | 39 + .../content/_snippets/reference/config/pi.mdx | 52 + .../_snippets/reference/files/after.mdx | 9 + .../_snippets/reference/files/intro.mdx | 1 + .../_snippets/reference/files/opencode.mdx | 64 + .../content/_snippets/reference/files/pi.mdx | 72 ++ .../_snippets/reference/tools/after.mdx | 5 + .../_snippets/reference/tools/intro.mdx | 1 + .../_snippets/reference/tools/opencode.mdx | 95 ++ .../content/_snippets/reference/tools/pi.mdx | 92 ++ .../content/concepts/compaction-zones.mdx | 2 +- .../content/concepts/engine-and-harness.mdx | 50 +- apps/docs/content/concepts/how-it-works.mdx | 6 +- apps/docs/content/concepts/index.mdx | 39 +- apps/docs/content/concepts/limits.mdx | 16 +- .../concepts/recall-and-provenance.mdx | 4 +- apps/docs/content/concepts/security.mdx | 4 +- .../content/concepts/token-estimation.mdx | 6 +- apps/docs/content/guides/configuration.mdx | 96 -- .../content/guides/cross-session-recall.mdx | 70 -- apps/docs/content/guides/faq.mdx | 4 +- apps/docs/content/guides/getting-started.mdx | 109 -- apps/docs/content/guides/index.mdx | 18 - apps/docs/content/guides/meta.ts | 8 +- .../content/guides/opencode/configuration.mdx | 18 + .../guides/opencode/cross-session-recall.mdx | 16 + apps/docs/content/guides/opencode/faq.mdx | 16 + .../guides/opencode/getting-started.mdx | 16 + apps/docs/content/guides/opencode/meta.ts | 9 + .../guides/opencode/troubleshooting.mdx | 16 + apps/docs/content/guides/pi/configuration.mdx | 18 + .../guides/pi/cross-session-recall.mdx | 16 + apps/docs/content/guides/pi/faq.mdx | 16 + .../content/guides/pi/getting-started.mdx | 16 + apps/docs/content/guides/pi/meta.ts | 9 + .../content/guides/pi/troubleshooting.mdx | 16 + apps/docs/content/reference/comparison.mdx | 32 + apps/docs/content/reference/config.mdx | 65 - apps/docs/content/reference/files.mdx | 83 -- apps/docs/content/reference/index.mdx | 19 - apps/docs/content/reference/meta.ts | 2 +- .../content/reference/opencode/command.mdx | 15 + .../content/reference/opencode/comparison.mdx | 141 +++ .../content/reference/opencode/config.mdx | 15 + .../docs/content/reference/opencode/files.mdx | 15 + apps/docs/content/reference/opencode/meta.ts | 9 + .../docs/content/reference/opencode/tools.mdx | 16 + apps/docs/content/reference/pi/command.mdx | 15 + .../reference/pi/comparison.mdx} | 37 +- apps/docs/content/reference/pi/config.mdx | 15 + apps/docs/content/reference/pi/files.mdx | 15 + apps/docs/content/reference/pi/meta.ts | 9 + apps/docs/content/reference/pi/tools.mdx | 16 + apps/docs/content/reference/roadmap.mdx | 29 - apps/docs/content/reference/tools.mdx | 107 -- apps/docs/content/roadmap.mdx | 35 + apps/docs/harness-icons.ts | 8 + apps/docs/harness-nav.ts | 38 + apps/docs/package.json | 8 +- apps/docs/pages/404.astro | 2 +- apps/docs/pages/_home/CopyCommand.astro | 35 +- apps/docs/pages/_home/FinalCta.astro | 9 +- apps/docs/pages/_home/Hero.astro | 115 +- apps/docs/pages/_home/Packages.astro | 123 +- apps/docs/pages/_home/Zones.astro | 2 +- apps/docs/public/logos/deepseek.svg | 1 + apps/docs/public/logos/opencode-dark.svg | 1 + apps/docs/public/logos/opencode-light.svg | 1 + apps/docs/public/logos/pi-color.svg | 5 + apps/docs/public/logos/pi-dark.svg | 5 + apps/docs/public/logos/pi-light.svg | 5 + apps/docs/scripts/build-comparison.ts | 121 -- apps/docs/theme.css | 26 + bun.lock | 1077 ++++++++++++----- docs/roadmap.md | 50 +- package.json | 21 +- packages/core/README.md | 11 +- packages/core/package.json | 2 +- packages/core/src/commit-policy.ts | 9 + packages/core/src/context-policy.ts | 55 +- packages/core/src/recall-view.ts | 10 +- packages/core/src/retrieval.ts | 6 +- packages/core/src/store.ts | 31 +- packages/core/test/core.test.ts | 63 +- packages/core/test/package-boundary.test.ts | 10 +- packages/core/test/scope-docs.test.ts | 5 +- packages/opencode/CHANGELOG.md | 1 + packages/opencode/LICENSE | 13 + packages/opencode/README.md | 267 ++++ packages/opencode/package.json | 48 + packages/opencode/src/checkpoint.ts | 51 + packages/opencode/src/command.ts | 261 ++++ packages/opencode/src/compaction.ts | 257 ++++ packages/opencode/src/context.ts | 563 +++++++++ packages/opencode/src/cross-session.ts | 205 ++++ packages/opencode/src/host.ts | 286 +++++ packages/opencode/src/index.ts | 4 + packages/opencode/src/ingest.ts | 316 +++++ packages/opencode/src/lifecycle.ts | 533 ++++++++ packages/opencode/src/map.ts | 276 +++++ packages/opencode/src/metrics.ts | 116 ++ packages/opencode/src/model-host.ts | 105 ++ packages/opencode/src/pass.ts | 158 +++ packages/opencode/src/plugin.ts | 502 ++++++++ packages/opencode/src/reader.ts | 468 +++++++ packages/opencode/src/sidecars.ts | 104 ++ packages/opencode/src/tools.ts | 536 ++++++++ packages/opencode/src/window.ts | 54 + packages/opencode/test/async-pass.test.ts | 219 ++++ .../opencode/test/compaction-hook.test.ts | 308 +++++ .../opencode/test/context-checkpoint.test.ts | 374 ++++++ .../opencode/test/context-projection.test.ts | 485 ++++++++ packages/opencode/test/context-reader.test.ts | 185 +++ packages/opencode/test/cross-session.test.ts | 250 ++++ packages/opencode/test/host-compat.test.ts | 153 +++ packages/opencode/test/ingest.test.ts | 268 ++++ packages/opencode/test/lifecycle.test.ts | 195 +++ packages/opencode/test/map.test.ts | 194 +++ packages/opencode/test/metrics.test.ts | 91 ++ packages/opencode/test/model-host.test.ts | 98 ++ packages/opencode/test/pass.test.ts | 132 ++ packages/opencode/test/plugin.test.ts | 277 +++++ .../opencode/test/publish-surface.test.ts | 127 ++ packages/opencode/test/reader.test.ts | 334 +++++ packages/opencode/test/report.test.ts | 124 ++ packages/opencode/test/sidecars.test.ts | 33 + .../opencode/test/support/opencode-fake.ts | 231 ++++ packages/opencode/test/tools.test.ts | 438 +++++++ packages/opencode/tsconfig.build.json | 7 + packages/opencode/tsconfig.json | 4 + packages/opencode/vite.config.ts | 26 + packages/pi/README.md | 8 +- packages/pi/package.json | 18 +- packages/pi/src/tools/recall.ts | 12 +- packages/pi/test/egress-redact.test.ts | 2 +- packages/pi/test/hook-adapter.test.ts | 4 +- packages/pi/test/publish-surface.test.ts | 9 +- packages/pi/test/recall-tools.test.ts | 2 +- packages/pi/tsconfig.build.json | 7 + packages/pi/vite.config.ts | 5 +- scripts/opencode-compact.ts | 385 ++++++ scripts/opencode-config.ts | 110 ++ scripts/opencode-live.ts | 228 ++++ scripts/opencode-smoke.ts | 219 ++++ 192 files changed, 14376 insertions(+), 1551 deletions(-) create mode 100644 .changeset/core-host-seams.md create mode 100644 .changeset/dependency-refresh.md create mode 100644 .changeset/opencode-lossless.md create mode 100644 .changeset/owner-only-store-files.md create mode 100644 apps/docs/components/blume/EmptyFooter.astro create mode 100644 apps/docs/components/blume/Sidebar.astro create mode 100644 apps/docs/components/mdx/HarnessCards.astro create mode 100644 apps/docs/components/seo/opencode-faqs.ts create mode 100644 apps/docs/components/seo/pi-faqs.ts create mode 100644 apps/docs/content/_snippets/guides/configuration/intro.mdx create mode 100644 apps/docs/content/_snippets/guides/configuration/opencode.mdx create mode 100644 apps/docs/content/_snippets/guides/configuration/pi.mdx create mode 100644 apps/docs/content/_snippets/guides/cross-session-recall/intro.mdx create mode 100644 apps/docs/content/_snippets/guides/cross-session-recall/opencode.mdx create mode 100644 apps/docs/content/_snippets/guides/cross-session-recall/pi.mdx create mode 100644 apps/docs/content/_snippets/guides/getting-started/after.mdx create mode 100644 apps/docs/content/_snippets/guides/getting-started/intro.mdx create mode 100644 apps/docs/content/_snippets/guides/getting-started/opencode.mdx create mode 100644 apps/docs/content/_snippets/guides/getting-started/pi.mdx create mode 100644 apps/docs/content/_snippets/guides/troubleshooting/intro.mdx create mode 100644 apps/docs/content/_snippets/guides/troubleshooting/opencode.mdx rename apps/docs/content/{guides/troubleshooting.mdx => _snippets/guides/troubleshooting/pi.mdx} (57%) create mode 100644 apps/docs/content/_snippets/reference/command/after.mdx create mode 100644 apps/docs/content/_snippets/reference/command/intro.mdx create mode 100644 apps/docs/content/_snippets/reference/command/opencode.mdx rename apps/docs/content/{reference/command.mdx => _snippets/reference/command/pi.mdx} (80%) create mode 100644 apps/docs/content/_snippets/reference/config/after.mdx create mode 100644 apps/docs/content/_snippets/reference/config/intro.mdx create mode 100644 apps/docs/content/_snippets/reference/config/opencode.mdx create mode 100644 apps/docs/content/_snippets/reference/config/pi.mdx create mode 100644 apps/docs/content/_snippets/reference/files/after.mdx create mode 100644 apps/docs/content/_snippets/reference/files/intro.mdx create mode 100644 apps/docs/content/_snippets/reference/files/opencode.mdx create mode 100644 apps/docs/content/_snippets/reference/files/pi.mdx create mode 100644 apps/docs/content/_snippets/reference/tools/after.mdx create mode 100644 apps/docs/content/_snippets/reference/tools/intro.mdx create mode 100644 apps/docs/content/_snippets/reference/tools/opencode.mdx create mode 100644 apps/docs/content/_snippets/reference/tools/pi.mdx delete mode 100644 apps/docs/content/guides/configuration.mdx delete mode 100644 apps/docs/content/guides/cross-session-recall.mdx delete mode 100644 apps/docs/content/guides/getting-started.mdx delete mode 100644 apps/docs/content/guides/index.mdx create mode 100644 apps/docs/content/guides/opencode/configuration.mdx create mode 100644 apps/docs/content/guides/opencode/cross-session-recall.mdx create mode 100644 apps/docs/content/guides/opencode/faq.mdx create mode 100644 apps/docs/content/guides/opencode/getting-started.mdx create mode 100644 apps/docs/content/guides/opencode/meta.ts create mode 100644 apps/docs/content/guides/opencode/troubleshooting.mdx create mode 100644 apps/docs/content/guides/pi/configuration.mdx create mode 100644 apps/docs/content/guides/pi/cross-session-recall.mdx create mode 100644 apps/docs/content/guides/pi/faq.mdx create mode 100644 apps/docs/content/guides/pi/getting-started.mdx create mode 100644 apps/docs/content/guides/pi/meta.ts create mode 100644 apps/docs/content/guides/pi/troubleshooting.mdx create mode 100644 apps/docs/content/reference/comparison.mdx delete mode 100644 apps/docs/content/reference/config.mdx delete mode 100644 apps/docs/content/reference/files.mdx delete mode 100644 apps/docs/content/reference/index.mdx create mode 100644 apps/docs/content/reference/opencode/command.mdx create mode 100644 apps/docs/content/reference/opencode/comparison.mdx create mode 100644 apps/docs/content/reference/opencode/config.mdx create mode 100644 apps/docs/content/reference/opencode/files.mdx create mode 100644 apps/docs/content/reference/opencode/meta.ts create mode 100644 apps/docs/content/reference/opencode/tools.mdx create mode 100644 apps/docs/content/reference/pi/command.mdx rename apps/docs/{COMPARISON.md => content/reference/pi/comparison.mdx} (94%) create mode 100644 apps/docs/content/reference/pi/config.mdx create mode 100644 apps/docs/content/reference/pi/files.mdx create mode 100644 apps/docs/content/reference/pi/meta.ts create mode 100644 apps/docs/content/reference/pi/tools.mdx delete mode 100644 apps/docs/content/reference/roadmap.mdx delete mode 100644 apps/docs/content/reference/tools.mdx create mode 100644 apps/docs/content/roadmap.mdx create mode 100644 apps/docs/harness-icons.ts create mode 100644 apps/docs/harness-nav.ts create mode 100644 apps/docs/public/logos/deepseek.svg create mode 100644 apps/docs/public/logos/opencode-dark.svg create mode 100644 apps/docs/public/logos/opencode-light.svg create mode 100644 apps/docs/public/logos/pi-color.svg create mode 100644 apps/docs/public/logos/pi-dark.svg create mode 100644 apps/docs/public/logos/pi-light.svg delete mode 100644 apps/docs/scripts/build-comparison.ts create mode 100644 packages/opencode/CHANGELOG.md create mode 100644 packages/opencode/LICENSE create mode 100644 packages/opencode/README.md create mode 100644 packages/opencode/package.json create mode 100644 packages/opencode/src/checkpoint.ts create mode 100644 packages/opencode/src/command.ts create mode 100644 packages/opencode/src/compaction.ts create mode 100644 packages/opencode/src/context.ts create mode 100644 packages/opencode/src/cross-session.ts create mode 100644 packages/opencode/src/host.ts create mode 100644 packages/opencode/src/index.ts create mode 100644 packages/opencode/src/ingest.ts create mode 100644 packages/opencode/src/lifecycle.ts create mode 100644 packages/opencode/src/map.ts create mode 100644 packages/opencode/src/metrics.ts create mode 100644 packages/opencode/src/model-host.ts create mode 100644 packages/opencode/src/pass.ts create mode 100644 packages/opencode/src/plugin.ts create mode 100644 packages/opencode/src/reader.ts create mode 100644 packages/opencode/src/sidecars.ts create mode 100644 packages/opencode/src/tools.ts create mode 100644 packages/opencode/src/window.ts create mode 100644 packages/opencode/test/async-pass.test.ts create mode 100644 packages/opencode/test/compaction-hook.test.ts create mode 100644 packages/opencode/test/context-checkpoint.test.ts create mode 100644 packages/opencode/test/context-projection.test.ts create mode 100644 packages/opencode/test/context-reader.test.ts create mode 100644 packages/opencode/test/cross-session.test.ts create mode 100644 packages/opencode/test/host-compat.test.ts create mode 100644 packages/opencode/test/ingest.test.ts create mode 100644 packages/opencode/test/lifecycle.test.ts create mode 100644 packages/opencode/test/map.test.ts create mode 100644 packages/opencode/test/metrics.test.ts create mode 100644 packages/opencode/test/model-host.test.ts create mode 100644 packages/opencode/test/pass.test.ts create mode 100644 packages/opencode/test/plugin.test.ts create mode 100644 packages/opencode/test/publish-surface.test.ts create mode 100644 packages/opencode/test/reader.test.ts create mode 100644 packages/opencode/test/report.test.ts create mode 100644 packages/opencode/test/sidecars.test.ts create mode 100644 packages/opencode/test/support/opencode-fake.ts create mode 100644 packages/opencode/test/tools.test.ts create mode 100644 packages/opencode/tsconfig.build.json create mode 100644 packages/opencode/tsconfig.json create mode 100644 packages/opencode/vite.config.ts create mode 100644 packages/pi/tsconfig.build.json create mode 100644 scripts/opencode-compact.ts create mode 100644 scripts/opencode-config.ts create mode 100644 scripts/opencode-live.ts create mode 100644 scripts/opencode-smoke.ts diff --git a/.agents/skills/docs-governance/SKILL.md b/.agents/skills/docs-governance/SKILL.md index 58cabd8..1727fa5 100644 --- a/.agents/skills/docs-governance/SKILL.md +++ b/.agents/skills/docs-governance/SKILL.md @@ -1,30 +1,38 @@ --- name: docs-governance -description: Doc lanes for this repo. Use when creating or editing README.md, docs/roadmap.md, CHANGELOG.md, COMPARISON.md, a package README, a changeset, or any file under .agents/; each doc has one job and content never gets copied between them. +description: Doc lanes for this repo. Use when creating or editing README.md, docs/roadmap.md, CHANGELOG.md, the comparison sources, a package README, a changeset, or any file under .agents/; each doc has one job and content never gets copied between them. --- # Docs governance Each doc has exactly one job, keep content in its lane: -| File | Is for | Never contains | -| ------------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | -| `README.md` | Repo map: the two packages, where to work, the gates, doc links | Install, config or usage sections; version history; roadmap; internal rationale | -| `packages/pi/README.md` | The adapter's npm landing: what it does, install, commands, config pointers | Version history, roadmap, repo map, engine internals | -| `packages/*/CHANGELOG.md` | Each package's version history, written by changesets | Marketing prose, roadmap | -| `apps/docs/COMPARISON.md` | Peer comparison with verified cells, the source the site's comparison page generates from | Feature marketing | -| `packages/core/README.md` | The engine's API: the entry, the two ports, the boundary rule | Pi-specific behaviour, the split's rationale | -| `docs/roadmap.md` | Forward-looking work, evidence gates, rejected items | Shipped-feature history | -| `.agents/**` | Agent rules, skills, lessons | Product docs | +| File | Is for | Never contains | +| ----------------------------------------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | +| `README.md` | Repo map: the three packages, where to work, the gates, doc links | Install, config or usage sections; version history; roadmap; internal rationale | +| `packages/pi/README.md` | The adapter's npm landing: what it does, install, commands, config pointers | Version history, roadmap, repo map, engine internals | +| `packages/opencode/README.md` | The OpenCode adapter's npm landing: what it does, install, commands, tools, live loop | Version history, roadmap, repo map, engine internals | +| `packages/*/CHANGELOG.md` | Each package's version history, written by changesets | Marketing prose, roadmap | +| `apps/docs/content/reference/pi/comparison.mdx` | Audited Pi peer comparison; the page and the source are one file | Feature marketing, unverified cells | +| `apps/docs/content/reference/opencode/comparison.mdx` | Audited OpenCode v2 peer comparison; the page and the source are one file | Feature marketing, unverified cells | +| `apps/docs/content/_snippets/**` | Shared Markdown or MDX fragments, spliced into the per-harness wrapper pages with `` | Frontmatter, a second full copy of a page, or the other harness's content | +| `packages/core/README.md` | The engine's API: the entry, the two ports, the boundary rule | Pi-specific behaviour, the split's rationale | +| `docs/roadmap.md` | Forward-looking work, evidence gates, rejected items | Shipped-feature history | +| `.agents/**` | Agent rules, skills, lessons | Product docs | ## Rules 1. **Never duplicate content across these docs**, package READMEs included, link - instead. + instead. The per-harness guide and reference pages are the one exception in + form, not in content: `apps/docs/content/_snippets/**` holds the shared + fragments, plus one partial per harness where the page differs. The wrappers + under `apps/docs/content/{guides,reference}/{pi,opencode}/*.mdx` hold + frontmatter and `` statements only. Edit the snippet, never the + wrapper body. 2. **Version bumps flow through changesets**, run `bun run changeset` with your change; `bun run version` generates the CHANGELOG entry. Every changeset - names the package it bumps in the frontmatter, the engine included: both - packages publish, so both take changesets. Never hand-bump `package.json` + names the package it bumps in the frontmatter, the engine included: all + three packages publish, so all three take changesets. Never hand-bump `package.json` version for shipped work. The generator in `.changeset/config.json` must stay `@changesets/cli/changelog`: the `changelog-github` generator aborts `bun run version` without a @@ -39,31 +47,32 @@ Each doc has exactly one job, keep content in its lane: never cut. `apps/docs` is private and ships nothing to npm, so a site-only change takes no changeset. 3. **Comparison claims are verified against tarballs, dated, and peer-named - only in `COMPARISON.md`.** Check a peer package against its published + only in the comparison sources.** Check a peer package against its published tarball and npm metadata (`npm view peerDependencies dependencies -time.modified`), never against its README, and stamp `COMPARISON.md` with + time.modified`), never against its README, and stamp each source with "Last verified: …" before treating a cell as settled. Credit a peer's win in the cell: a comparison that shows only our wins is marketing. - Peer package names appear in `COMPARISON.md` and in the page generated - from it (`apps/docs/content/reference/comparison.mdx`, written by - `apps/docs/scripts/build-comparison.ts`), and nowhere else in this repo or - on the site (owner policy). The generated page restates no cell - and is never hand-edited: `COMPARISON.md` is the only writer's source. There - are no inspiration credits: the design cites the LCM paper (algorithmic + Peer package names appear in + `apps/docs/content/reference/{pi,opencode}/comparison.mdx`, and nowhere else + in this repo or on the site (owner policy). Those two pages are both the + audited source and the rendered page: edit a cell there, with its + verification note and date, never in a second copy. There are no inspiration + credits: the design cites the LCM paper (algorithmic spec) and the smart-zone framing (Matt Pocock) only, because the code is an original implementation. The docs site carries no credit line; a concept page cites the paper where a mechanism comes from, as [how it works](../../../apps/docs/content/concepts/how-it-works.mdx) does. - Attribution lives in `packages/*/README.md`, `apps/docs/COMPARISON.md`, and + Attribution lives in `packages/*/README.md`, the comparison sources, and the licence preamble (owner decision). - `COMPARISON.md` is not a spec: a design decision cites a paper section or a + The comparison sources are not a spec: a design decision cites a paper section or a measured result, never a comparison cell, and a cell that scores a mechanism as a peer's cost is not a reason to lack it. -4. **Each published package owns its landing docs.** `packages/pi/README.md` is - the landing npm shows, `packages/pi/CHANGELOG.md` is the version history - changesets writes in place, and `packages/pi/LICENSE` is a copy of the root - licence. The comparison lives beside the docs site (`apps/docs/COMPARISON.md`) - and generates the site's comparison page, so the tarball no longer ships it. The +4. **Each published package owns its landing docs.** `packages//README.md` is + the landing npm shows, `packages//CHANGELOG.md` is the version history + changesets writes in place, and `packages//LICENSE` is a copy of the root + licence. The comparisons live in + `apps/docs/content/reference/{pi,opencode}/comparison.mdx`, so the tarball + no longer ships them. The holder named there is the org brand, `stainless-code`, as in every other stainless-code package, never a personal name. npm always includes `README` and `LICENSE` from the package directory, so the diff --git a/.agents/skills/docs-voice/SKILL.md b/.agents/skills/docs-voice/SKILL.md index a9a1264..ce488de 100644 --- a/.agents/skills/docs-voice/SKILL.md +++ b/.agents/skills/docs-voice/SKILL.md @@ -11,14 +11,15 @@ description: Voice and pipeline for the published docs site (apps/docs): heading ## Surfaces and their modes -| Surface | Mode | Boundary | -| ------------------------------------ | ----------- | ------------------------------------------------------------------------- | -| `pages/_home/*`, `pages/index.astro` | copy | Opinion and pitch are allowed. No claim the page cannot show. | -| `content/concepts/**` | explanation | Opinion allowed. A heading tolerates "About ..." in front. | -| `content/guides/**` | how-to | Commands, conditions, expected output. No teaching. | -| `content/reference/**` | reference | Dry. No "you", no persuasion, spec tables only. | -| `content/reference/comparison.mdx` | generated | Never hand-edited; `apps/docs/COMPARISON.md` is the only writer's source. | -| `content/**/index.mdx` | routing | Help the reader choose, do not summarize. | +| Surface | Mode | Boundary | +| ------------------------------------------------ | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `pages/_home/*`, `pages/index.astro` | copy | Opinion and pitch are allowed. No claim the page cannot show. | +| `content/concepts/**` | explanation | Opinion allowed. A heading tolerates "About ..." in front. | +| `content/guides/**` | how-to | Commands, conditions, expected output. No teaching. | +| `content/reference/**` | reference | Dry. No "you", no persuasion, spec tables only. | +| `content/reference/{pi,opencode}/comparison.mdx` | reference | Audited peer comparison; the page is the source, so the verification note and date live with the cells. | +| `apps/docs/content/_snippets/**` | source | Shared fragments, plus one partial per harness where the page differs. The wrapper pages under `content/{guides,reference}/` hold frontmatter and includes only. | +| `content/**/index.mdx` | routing | Help the reader choose, do not summarize. | ## Headings carry the point @@ -65,8 +66,8 @@ If anything links to it, take the new text and pin the slug. `blume audit` reads the built `apps/docs/dist`, and an isolated build omits `robots.txt` and `llms.txt`, so an isolated build cannot be audited. A non-isolated build refuses to run while `blume dev` is up. 1. Stop the dev server. -2. From `apps/docs`: `rm -rf dist && bunx blume build`. -3. `bunx blume validate --strict`. +2. From `apps/docs`: `rm -rf dist && bun run build`. +3. `bun run validate --strict`. 4. `bunx blume audit --fail-on error`. 5. Restart `bunx blume dev`. diff --git a/.agents/skills/typescript-best-practices/PATTERNS.md b/.agents/skills/typescript-best-practices/PATTERNS.md index 220ef50..569bb26 100644 --- a/.agents/skills/typescript-best-practices/PATTERNS.md +++ b/.agents/skills/typescript-best-practices/PATTERNS.md @@ -31,7 +31,9 @@ type DiffState = { loading: boolean; diff?: GitDiff; error?: string }; // Do. Only valid states exist. type DiffState = - { kind: "loading" } | { kind: "ready"; diff: GitDiff } | { kind: "error"; error: string }; + | { kind: "loading" } + | { kind: "ready"; diff: GitDiff } + | { kind: "error"; error: string }; ``` Pick one discriminant name (`kind`, `type`, `tag`) and stick to it. diff --git a/.changeset/README.md b/.changeset/README.md index fb84d04..8415d15 100644 --- a/.changeset/README.md +++ b/.changeset/README.md @@ -5,9 +5,8 @@ generated `.changeset/*.md` file on `main` in the same commit as the change. At release time: `bun run version` (bumps the version and writes the changelog from the pending changesets), then `bun run pack`. -Two packages, each published from its own directory, so a changeset names the -package it bumps in the frontmatter (`"pi-lossless": patch`). The engine, -`lossless-core`, takes no changeset until it publishes. The changelog text comes -from `@changesets/cli/changelog`, which writes it locally from the changeset -bodies. This repo has no remote and no pull requests, so the GitHub changelog -generator is never used. +Each package publishes from its own directory, so a changeset names the package +it bumps in the frontmatter (`"pi-lossless": patch`). The engine, +`lossless-core`, takes a changeset like any other published package. The +changelog text comes from `@changesets/cli/changelog`, which writes it locally +from the changeset bodies; the GitHub changelog generator is never used. diff --git a/.changeset/core-host-seams.md b/.changeset/core-host-seams.md new file mode 100644 index 0000000..ac9d49d --- /dev/null +++ b/.changeset/core-host-seams.md @@ -0,0 +1,5 @@ +--- +"lossless-core": patch +--- + +Add the three host seams the OpenCode adapter uses: `renderableFrontier` renders a store's DAG frontier for a host checkpoint, `grepView` accepts an `expandTool` name so each adapter can name its own expansion tool, and `LcmStore.entryCountWithPrefix` counts a family of rows without a table scan. diff --git a/.changeset/dependency-refresh.md b/.changeset/dependency-refresh.md new file mode 100644 index 0000000..f84ce64 --- /dev/null +++ b/.changeset/dependency-refresh.md @@ -0,0 +1,7 @@ +--- +"lossless-core": patch +"pi-lossless": patch +"opencode-lossless": patch +--- + +Refresh every external dependency to its newest published version: Vite+ 1.3.0 and Vitest 5.0.5, TypeScript 7.0.2, `@types/node` 26.6.5, `@changesets/cli` 3.0.3, Pi 1.4.0, OpenCode 2.1.3, Typebox 1.4.3, Blume 2.2.4, and Bun 1.4.4. Pi host packages now use the `*` peer range its package guide documents for packages the host supplies. diff --git a/.changeset/opencode-lossless.md b/.changeset/opencode-lossless.md new file mode 100644 index 0000000..4ef55c5 --- /dev/null +++ b/.changeset/opencode-lossless.md @@ -0,0 +1,5 @@ +--- +"opencode-lossless": patch +--- + +Add the OpenCode v2 adapter. It mirrors prompts, assistant text, and tool traffic verbatim into a per-session SQLite sidecar; registers `lcm_grep`, `lcm_describe`, `lcm_expand`, and the `/lossless-status`, `/lossless-report`, `/lossless-pass`, `/lossless-backup`, `/lossless-export`, `/lossless-import`, `/lossless-diagnose`, `/lossless-migrate`, and `/lossless-gc` commands; and records the host's compaction boundaries and summaries beside the rows they replace. `assembly` defaults to true: it builds the leaf and condensed DAG, projects the aged frontier into `session.context`, and hands the same frontier to the host as its compaction checkpoint, marked so the next request re-applies it. `assembly: false` leaves compaction to the host and omits `/lossless-pass` and `lcm_expand_query`. `lcm_expand_query` runs a child session narrowed to the three recall tools, reads the parent's sidecar, returns findings only, and removes the child with its transcript sidecar. Every seam writes a diagnostic row to `metrics.jsonl` (projection, checkpoint, pass, recall, reader), and `/lossless-report` summarizes this session's rows. `lcm_grep` gains `scope` and `lcm_expand` gains `session`, which read other sessions' sidecars read-only; OpenCode keeps one global sidecar directory, so `sessions` and `all_sessions` are equivalent and the reader remains session-scoped. `/lossless-diagnose` builds a redacted bundle and can repair the full-text index. `/lossless-gc` is age-based because the plugin API cannot list host sessions; it exports each transcript before deleting and never touches the current or open sidecar. There is no cockpit: the promise plugin API has no interactive TUI surface, so one needs a separate TUI plugin. The adapter has no runtime dependencies, and sidecar files and their WAL are owner-only (0600) with a 0700 directory. diff --git a/.changeset/owner-only-store-files.md b/.changeset/owner-only-store-files.md new file mode 100644 index 0000000..a8e8768 --- /dev/null +++ b/.changeset/owner-only-store-files.md @@ -0,0 +1,5 @@ +--- +"lossless-core": patch +--- + +Create store files owner-only before SQLite opens them, so the database, WAL, and shared-memory files are 0600 from the first write, and repair an existing world-readable database on open. diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 93018be..552fc1d 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -7,7 +7,7 @@ runs: - name: Setup Bun (the install, the audit, and the node-based scripts) uses: oven-sh/setup-bun@v2 with: - bun-version: 1.4.2 + bun-version: 1.4.4 - name: Setup Node (the npm publish dry runs and the node-based scripts) uses: actions/setup-node@v4 @@ -17,7 +17,7 @@ runs: # Vite+'s installer is what puts `vp` on PATH for a bare `vp run` step; the # two manager flags keep setup-bun and setup-node the tools the jobs use. - name: Setup Vite+ (vp on PATH, cached dependencies) - uses: voidzero-dev/setup-vp@v1.21.1 + uses: voidzero-dev/setup-vp@v1.21.2 with: node-manager: false package-manager: false diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f1ef685..4245f6a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -95,6 +95,19 @@ jobs: working-directory: packages/core run: npm publish --dry-run + - name: Verify the OpenCode adapter's publish tarball (dry run) + working-directory: packages/opencode + run: npm publish --dry-run + + - name: Verify the OpenCode bundle and declarations name no host SDK + run: | + if grep -qE '@opencode/|lossless-core/src/' \ + packages/opencode/dist/index.mjs \ + packages/opencode/dist/index.d.mts; then + echo "the published artifact names a host SDK or the engine source" >&2 + exit 1 + fi + docs: name: 📖 Docs site runs-on: ubuntu-latest @@ -109,9 +122,6 @@ jobs: - name: Setup uses: ./.github/actions/setup - - name: Generate the comparison page from COMPARISON.md - run: bun apps/docs/scripts/build-comparison.ts - - name: Validate docs links run: vp run --filter ./apps/docs validate --strict @@ -144,34 +154,23 @@ jobs: # act on it. Capture the exit code directly; a pipe into tee would # report tee's status, not bun's. # - # Ignored: fifteen highs in the private docs workspace via the Blume - # 2.1.3 subtree and two @earendil-works peer packages kept external. - # Pinned versions come from that subtree and peer ranges, so - # `bun audit fix` clears 0 without upstream bumps. Reassess on every - # Blume bump; any other path still blocks. + # Ignored: two highs that live only outside a published tarball. + # lodash-es comes from Blume 2.2.4's mermaid subtree (dagre-d3-es pins + # 4.17.23), and path-to-regexp 6.1.0 from @astrojs/vercel's + # routing-utils; the other path-to-regexp instance sits inside the + # @earendil-works/pi-ai peer subtree the host supplies. Both bundles + # keep their peers external. Reassess on every Blume or Pi bump; any + # other path still blocks. set +e out=$(NO_COLOR=1 bun audit --audit-level=high \ --ignore=GHSA-r5fr-rjxr-66jc \ --ignore=GHSA-9wv6-86v2-598j \ - --ignore=GHSA-4cwx-7wf7-3272 \ - --ignore=GHSA-vmh5-mc38-953g \ - --ignore=GHSA-vxpw-j846-p89q \ - --ignore=GHSA-hm92-r4w5-c3mj \ - --ignore=GHSA-qhr7-859c-m2p7 \ - --ignore=GHSA-6j4f-fj2g-mc7p \ - --ignore=GHSA-j22f-vq7h-c4qm \ - --ignore=GHSA-mcm9-63f2-9j32 \ - --ignore=GHSA-x5rw-q4pp-hg5g \ - --ignore=GHSA-ch52-4w7c-c8xp \ - --ignore=GHSA-68fv-2mgg-jv7q \ - --ignore=GHSA-rfgv-xxqx-mfg5 \ - --ignore=GHSA-w293-vg96-wgc3 \ 2>&1) code=$? set -e printf '%s\n' "$out" if [ "$code" -eq 0 ]; then exit 0; fi - # bun 1.4.2 wording: "error: POST - ConnectionRefused", + # bun 1.4.4 wording: "error: POST - ConnectionRefused", # " did not answer the audit request; skipped", # " returned a non-JSON audit response". if ! grep -qE '[0-9]+ vulnerabilit' <<<"$out" && diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 9beb2fb..e2ba12d 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -38,9 +38,6 @@ jobs: - name: Setup Bun uses: ./.github/actions/setup - - name: Generate the comparison page from COMPARISON.md - run: bun apps/docs/scripts/build-comparison.ts - - name: Validate docs links run: vp run --filter ./apps/docs validate --strict diff --git a/AGENTS.md b/AGENTS.md index 675ad34..654db28 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,12 +2,12 @@ This file loads every turn. What belongs in it, and which channels load at all, are defined in [`.agents/README.md`](.agents/README.md). Skills under `.agents/skills/` load by description; everything else is reached by link. -This repo is two packages: `packages/core` is the engine (`lossless-core`) and `packages/pi` is the Pi adapter (`pi-lossless`). [docs/roadmap.md](docs/roadmap.md) holds forward-looking decisions, and [`packages/pi/CHANGELOG.md`](packages/pi/CHANGELOG.md) holds the extension's shipped ones. +This repo holds the engine in `packages/core` (`lossless-core`) and the harness adapters under `packages/` (`pi` and `opencode`). [docs/roadmap.md](docs/roadmap.md) holds forward-looking decisions, and [`packages/pi/CHANGELOG.md`](packages/pi/CHANGELOG.md) holds the shipped ones. ## Non-negotiables - After each step (slice, plan item, fix, doc edit), run `vp check`; on `packages/*/src/**` or `packages/*/test/**` changes also `bun run test` and `bun run typecheck`. Never carry a red gate forward. `bun run test` (`vp test`, Vitest through Vite+) is the only test runner here, and the repo keeps no Bun test config: a bare `bun test` is not a supported way to check a change. Details: [`verify-after-each-step`](.agents/skills/verify-after-each-step/SKILL.md). -- After any turn that changed code under `packages/*/src/`, run `bun run pack`; live Pi sessions keep the old `dist/` until restarted. +- After any turn that changed code under `packages/*/src/`, run `bun run pack`; live Pi sessions keep the old `dist/` until restarted, and a running OpenCode server reloads the plugin when its configured directory changes. - No em dashes in any prose this repo ships or replies with. Apply [`unslop`](.agents/skills/unslop/SKILL.md) to every prose surface. - Prose names the agent **Pi**. Lowercase forms are identifiers: the `pi` command, `pi-lossless`, `pi-*` package names, `~/.pi/` paths, and version labels that sit beside `node`. Verbatim message text, fixture payloads and quoted host output keep the casing they came with. - New skills go under `.agents/skills/`. Policy that must fire is a skill or a line in this file, never a file reached only by link ([`.agents/README.md`](.agents/README.md)). diff --git a/README.md b/README.md index 34c3a2e..6af82a4 100644 --- a/README.md +++ b/README.md @@ -4,34 +4,39 @@ Lossless Context Management for coding agents: every message is stored verbatim, aged context is replaced by summaries a model can navigate, and the original text stays searchable. Nothing is lost, and the model sees less. -This repository holds the engine and the Pi extension that consumes it: +This repository holds the engine and the adapters that consume it: -| Package | Directory | What it is | -| ------------------------------------------ | --------------- | ------------------------------------------------------------------------------------------------------------- | -| [`pi-lossless`](packages/pi/README.md) | `packages/pi` | The extension a Pi user installs (`pi install npm:pi-lossless`): the recall tools, the cockpit, the commands. | -| [`lossless-core`](packages/core/README.md) | `packages/core` | The engine: ingest, compaction and retrieval behind a two-port host contract, naming no agent SDK. | +| Package | Directory | What it is | +| -------------------------------------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------ | +| [`pi-lossless`](packages/pi/README.md) | `packages/pi` | The Pi extension (`pi install npm:pi-lossless`): recall tools, cockpit, commands. | +| [`opencode-lossless`](packages/opencode/README.md) | `packages/opencode` | The OpenCode v2 plugin: recall tools, lifecycle commands, DAG projection, per-session sidecar. | +| [`lossless-core`](packages/core/README.md) | `packages/core` | The engine: ingest, compaction, and retrieval behind a two-port host contract, with no agent SDK dependency. | -`lossless-core` is a workspace `devDependency` of the adapter, and the pack -inlines it into `dist/index.mjs`, so the installed package stays one -self-contained artifact with no runtime dependencies. A harness other than Pi -implements `ModelHost` and `Reader` and drives the engine from -[`lossless-core`](https://npmx.dev/package/lossless-core). +`lossless-core` is a workspace `devDependency` of the Pi and OpenCode +adapters, and the pack inlines it into `dist/index.mjs`, so each published +package is one self-contained artifact with no runtime dependencies. The Pi +adapter implements both host ports. The OpenCode adapter implements `ModelHost` +and runs retrieval in a host child session, because its plugin API has no +in-process tool-calling completion. ## Where to work -| Path | Holds | -| ----------------------- | ---------------------------------------------------------------------------- | -| `packages/core/src/**` | the engine; the port in `src/host.ts` is its only host-facing surface | -| `packages/core/test/**` | engine tests, over port doubles rather than the Pi adapter | -| `packages/pi/src/**` | the Pi adapter, the only Pi-aware code in the tree | -| `packages/pi/test/**` | adapter tests, the Pi-shaped doubles, and the end-to-end spawn | -| `apps/docs/**` | the documentation site (Blume) | -| `scripts/**` | repo tools: the long-context evaluation, the metrics report, the peer census | -| `.agents/**` | agent rules, skills and lessons | +| Path | Holds | +| -------------------------------- | -------------------------------------------------------------------------------------------------------- | +| `packages/core/src/**` | the engine; the port in `src/host.ts` is its only host-facing surface | +| `packages/core/test/**` | engine tests, over port doubles rather than the Pi adapter | +| `packages/pi/src/**` | the Pi adapter, the only Pi-aware code in the tree | +| `packages/pi/test/**` | adapter tests, the Pi-shaped doubles, and the end-to-end spawn | +| `packages/opencode/src/**` | the OpenCode v2 adapter, the only OpenCode-aware code in the tree | +| `packages/opencode/test/**` | adapter tests, the host-shaped doubles, and the host-compat guard | +| `apps/docs/**` | the documentation site (Blume), its generated pages, and the per-harness page source | +| `apps/docs/content/_snippets/**` | shared guide and reference fragments; the per-harness wrappers include them | +| `scripts/**` | repo tools: the long-context evaluation, the metrics report, the peer census, and the OpenCode live loop | +| `.agents/**` | agent rules, skills and lessons | Test support files under `packages/core/test/` are shared on purpose: one HOME -guard, one pass-outcome reader, one temp-home helper, referenced by both -packages' test configs. +guard, one pass-outcome reader, one temp-home helper, referenced by every +package's test config. Every package declares its own needs. A library the package calls at runtime is a `dependencies` entry; a host package the bundle imports rather than inlines is @@ -42,20 +47,23 @@ own scripts run. ## Gates -Run these from the root. Every step is green by itself, and no gate is carried -red into the next one. +Run these from the root. A red gate stops the next step. ```bash bun install -bun run test # both suites, the only runner (vp test under the hood) +bun run test # all suites (vp test) bun run typecheck # one program over the tree vp check # format and lint -bun run pack # both publish bundles, dist included +bun run pack # all publish bundles, dist included bun run eval # the procedural long-context ladder, on demand ``` `bun run pack` writes the `dist/` a live Pi session loads, so after a change -under `packages/*/src` run it and restart Pi. The docs site has its own gates: +under `packages/*/src` run it and restart Pi. A running OpenCode server reloads +the plugin when its configured directory changes; its loop is +`bun run opencode:check`, `bun run opencode:smoke`, and `bun run opencode:compact` +(see [packages/opencode/README.md](packages/opencode/README.md#live-loop)). +The docs site has its own gates: ```bash cd apps/docs && bun run build && bun run validate --strict && bun run audit @@ -63,15 +71,17 @@ cd apps/docs && bun run build && bun run validate --strict && bun run audit ## Docs -| | | -| ----------------------------------------------------- | ------------------------------------------------------------------------------- | -| [The docs site](https://stainless-code.com/lossless/) | How LCM behaves in a session, the config keys, the limits | -| [pi-lossless](packages/pi/README.md) | Install, the commands, and the three recall tools | -| [lossless-core](packages/core/README.md) | The engine's API and the two ports a host implements | -| [COMPARISON.md](apps/docs/COMPARISON.md) | Peer comparison with verified cells, the source behind the site comparison page | -| [docs/roadmap.md](docs/roadmap.md) | Forward-looking work, evidence gates, and rejected items | -| [CHANGELOG.md](packages/pi/CHANGELOG.md) | Version history, generated from changesets | -| [AGENTS.md](AGENTS.md) | Agent rules, with the skills and lessons under `.agents/` | +| | | +| ------------------------------------------------------------------------------ | ---------------------------------------------------------------- | +| [The docs site](https://stainless-code.com/lossless/) | How LCM behaves in a session, the config keys, the limits | +| [pi-lossless](packages/pi/README.md) | Install, the commands, and the three recall tools | +| [opencode-lossless](packages/opencode/README.md) | Install, the commands, the four recall tools, and the live loop | +| [lossless-core](packages/core/README.md) | The engine's API and the ports a host supplies | +| [pi/comparison.mdx](apps/docs/content/reference/pi/comparison.mdx) | Audited Pi peer comparison, page and source in one file | +| [opencode/comparison.mdx](apps/docs/content/reference/opencode/comparison.mdx) | Audited OpenCode v2 peer comparison, page and source in one file | +| [docs/roadmap.md](docs/roadmap.md) | Forward-looking work, evidence gates, and rejected items | +| [CHANGELOG.md](packages/pi/CHANGELOG.md) | Per-package version history, generated from changesets | +| [AGENTS.md](AGENTS.md) | Agent rules, with the skills and lessons under `.agents/` | ## License diff --git a/apps/docs/.gitignore b/apps/docs/.gitignore index 502bae8..60905e0 100644 --- a/apps/docs/.gitignore +++ b/apps/docs/.gitignore @@ -1,6 +1,3 @@ .blume/ .blume-verify/ dist/ - -# Generated from COMPARISON.md by scripts/build-comparison.ts; that file is the source -content/reference/comparison.mdx diff --git a/apps/docs/blume.config.ts b/apps/docs/blume.config.ts index 30c5d33..e6c0c3e 100644 --- a/apps/docs/blume.config.ts +++ b/apps/docs/blume.config.ts @@ -4,7 +4,7 @@ import { fileURLToPath } from "node:url"; import { defineConfig } from "blume"; import { orama } from "blume/search"; -import { filesystem } from "blume/sources"; +import { filesystem, githubReleases } from "blume/sources"; import { CURATED_POPULAR } from "./components/curated-popular.js"; @@ -71,36 +71,39 @@ export default defineConfig({ lastModified: "git", content: { - sources: [filesystem({ root: "content" })], + sources: [ + filesystem({ root: "content" }), + githubReleases({ + owner: "stainless-code", + repo: "lossless", + prefix: "changelog", + }), + ], + }, + + changelog: { + title: "Changelog", + description: "Every Lossless package release, newest first.", }, integrations: [webAppHeadIntegration], navigation: { tabs: [ - { label: "Guides", path: "/guides" }, + { label: "Guides", path: "/guides", href: "/guides/pi/getting-started" }, { label: "Concepts", path: "/concepts" }, - { label: "Reference", path: "/reference" }, - ], - featured: [ - { - label: "Comparison", - href: "/reference/comparison", - icon: "scale", - }, - { - label: "GitHub", - href: "https://github.com/stainless-code/lossless", - icon: "github", - }, + { label: "Reference", path: "/reference", href: "/reference/pi/tools" }, + { label: "Roadmap", path: "/roadmap" }, + { label: "Changelog", path: "/changelog" }, ], sidebar: { display: "flat" }, }, footer: { links: [ - { label: "Comparison", href: "/reference/comparison" }, - { label: "Roadmap", href: "/reference/roadmap" }, + { label: "Comparison", href: "/reference/pi/comparison" }, + { label: "Roadmap", href: "/roadmap" }, + { label: "Changelog", href: "/changelog" }, { label: "npm", href: "https://npmx.dev/package/pi-lossless" }, { label: "MIT license", diff --git a/apps/docs/components.ts b/apps/docs/components.ts index 2849626..6be7530 100644 --- a/apps/docs/components.ts +++ b/apps/docs/components.ts @@ -2,15 +2,19 @@ import { defineComponents } from "blume"; export default defineComponents({ layout: { - // No layout.Footer: the homepage slots one, docs pages stay empty. - // String paths, so the `.astro` files stay out of this TypeScript project: - // Vite+'s type program has no `*.astro` module declaration and Blume - // resolves a path against the project root the same way. + // Docs pages have no site footer; the landing page slots its own through + // PageLayout, and the 404 page keeps the default footer. String paths, so + // the `.astro` files stay out of this TypeScript project: Vite+'s type + // program has no `*.astro` module declaration and Blume resolves a path + // against the project root the same way. Header: "./components/blume/Header.astro", + Footer: "./components/blume/EmptyFooter.astro", Pagination: "./components/blume/Pagination.astro", + Sidebar: "./components/blume/Sidebar.astro", }, mdx: { FaqSection: "./components/seo/FaqSection.astro", + HarnessCards: "./components/mdx/HarnessCards.astro", DagFigure: "./components/visuals/DagFigure.astro", EscalationLadder: "./components/visuals/EscalationLadder.astro", RecallFlow: "./components/visuals/RecallFlow.astro", diff --git a/apps/docs/components/blume/EmptyFooter.astro b/apps/docs/components/blume/EmptyFooter.astro new file mode 100644 index 0000000..0c8936f --- /dev/null +++ b/apps/docs/components/blume/EmptyFooter.astro @@ -0,0 +1,4 @@ +--- +// Docs pages intentionally render no site footer. The landing page slots its +// own footer through PageLayout, and the 404 page keeps the default one. +--- diff --git a/apps/docs/components/blume/Footer.astro b/apps/docs/components/blume/Footer.astro index f503fbf..90f3249 100644 --- a/apps/docs/components/blume/Footer.astro +++ b/apps/docs/components/blume/Footer.astro @@ -30,61 +30,58 @@ const groups: { { label: "Docs", links: [ - { href: contentHref("/guides"), label: "Guides" }, + { href: contentHref("/guides/pi/getting-started"), label: "Guides" }, { href: contentHref("/concepts"), label: "Concepts" }, - { href: contentHref("/reference"), label: "Reference" }, - { href: contentHref("/reference/comparison"), label: "Comparison" }, + { href: contentHref("/reference/pi/tools"), label: "Reference" }, + { href: contentHref("/reference/pi/comparison"), label: "Comparison" }, + { href: contentHref("/roadmap"), label: "Roadmap" }, + { href: contentHref("/changelog"), label: "Changelog" }, ], }, { label: "Packages", links: [ - { href: "https://npmx.dev/package/pi-lossless", label: "pi-lossless", external: true }, { href: "https://npmx.dev/package/lossless-core", label: "lossless-core", external: true }, - { href: `${repoUrl}/blob/main/docs/roadmap.md`, label: "Roadmap", external: true }, + { href: "https://npmx.dev/package/pi-lossless", label: "pi-lossless", external: true }, + { href: "https://npmx.dev/package/opencode-lossless", label: "opencode-lossless", external: true }, ], }, { label: "Project", links: [ { href: repoUrl, label: "GitHub", external: true }, - { href: "https://npmx.dev/package/pi-lossless", label: "npm", external: true }, { href: `${repoUrl}/blob/main/LICENSE`, label: "MIT license", external: true }, - { href: "https://github.com/stainless-code", label: "stainless-code", external: true }, ], }, ]; ---