fleet-memory/hindsight-docs/docusaurus.config.ts
Nicolò Boschi 576016f5dc
feat: add @vectorize-io/hindsight-all daemon lifecycle package (#949)
* feat: add @vectorize-io/hindsight-embed daemon lifecycle package

Create a new top-level `hindsight-embed-npm/` package that owns the daemon
lifecycle for the Python `hindsight-embed` CLI: spawning via `uvx`, writing
the profile, waiting for `/health`, and shutting down. Nothing more.

Deliberately does not ship an HTTP client — `@vectorize-io/hindsight-client`
already covers retain / recall / reflect / createBank against the Hindsight
API, and the two packages compose: once `manager.start()` returns, consumers
talk to the daemon via `new HindsightClient({ baseUrl: manager.getBaseUrl() })`.

`HindsightEmbedManagerOptions.env` forwards an arbitrary `Record<string,
string>` to both the daemon process and the profile config via `--env K=V`,
and `extraProfileCreateArgs` / `extraDaemonStartArgs` escape hatches cover
any new CLI flag without waiting for a wrapper release.

Refactor `hindsight-integrations/openclaw` to consume both packages:
`HindsightEmbedManager` for daemon lifecycle in local mode, `HindsightClient`
for all HTTP memory operations. Drop the bespoke subprocess/HTTP client that
used to live in openclaw. The retain queue stays local to openclaw (it's a
client-side reliability workaround with a single consumer today — will move
to the client package or server-side when a second consumer needs it).

Wire the new package into the main release pipeline (versioned alongside
the other core packages, published from `v*` tags) and add a CI build job.

* docs: add Embedded Node.js SDK page for @vectorize-io/hindsight-embed

* refactor: rename hindsight-embed-npm to hindsight-all, restructure docs sidebar

The Node package previously named @vectorize-io/hindsight-embed was
semantically misnamed: hindsight-embed (Python) is a CLI tool, while what
this Node package actually provides is the Node equivalent of hindsight-all
— a programmatic lifecycle manager for a local Hindsight daemon. Rename to
match.

Package rename
  - hindsight-embed-npm/ → hindsight-all-npm/ (git mv, history preserved)
  - @vectorize-io/hindsight-embed → @vectorize-io/hindsight-all
  - class HindsightEmbedManager → HindsightServer (matches Python hindsight-all)
  - HindsightEmbedManagerOptions → HindsightServerOptions
  - src/manager.ts → src/server.ts, src/manager.test.ts → src/server.test.ts
  - openclaw (index.ts, backfill.ts, tests) and the claude-code Python port
    updated to reference the new names

Docs restructure
  - Split sdks/python.md: now client-only content. New sdks/hindsight-all.md
    covers the programmatic hindsight-all Python package (HindsightServer and
    HindsightEmbedded).
  - Rename sdks/embed-npm.md → sdks/hindsight-all-npm.md with HindsightServer
    examples.
  - New "Installation" sidebar section, placed after Hosting, containing
    Docker / Kubernetes / Bare Metal (anchor links into developer/installation)
    plus Programmatic API (Python), Programmatic API (Node.js), and Daemon CLI.
  - Add si-docker, si-kubernetes, si-nodedotjs, lu-hard-drive to the sidebar
    ICON_MAP.

Docs dev-server fix
  - docusaurus.config.ts: drop the flaky NODE_ENV sniff for including the
    "Next" version. Use INCLUDE_CURRENT_VERSION exclusively. NODE_ENV was
    unreliable across hot-reload paths and caused the Next version to
    disappear intermittently when editing files.
  - scripts/dev/start-docs.sh: export INCLUDE_CURRENT_VERSION=true so local
    dev always shows Next; production builds leave it unset.

Lockfile cleanup
  - package-lock.json and hindsight-integrations/openclaw/package-lock.json
    had extraneous hindsight-embed-npm blocks left over from the rename.
    Removed manually and verified with npm install.

* ci: fix openclaw jobs by pre-building workspace deps; regenerate docs-skill

The build-openclaw-integration and test-openclaw-integration jobs failed
with "Failed to resolve entry for package @vectorize-io/hindsight-all"
because openclaw depends on two monorepo workspaces via `file:` deps
(@vectorize-io/hindsight-client and @vectorize-io/hindsight-all) whose
`dist/` directories are gitignored and never built before openclaw's npm ci.
Both jobs now install the root workspace and build the two deps first,
mirroring the release-control-plane pattern.

Also regenerate skills/hindsight-docs/references/* via
./scripts/generate-docs-skill.sh:
  - new skill pages for sdks/hindsight-all{.md,-npm.md}
  - updated skill pages for sdks/embed.md and sdks/python.md to match
    the new H1s and split content
  - incidental refreshes to changelog/index.md, developer/models.md,
    openapi.json, and uv.lock that verify-generated-files picked up

* ci: build openclaw before running tests so symlink test can realpath dist
2026-04-10 15:51:44 +02:00

423 lines
12 KiB
TypeScript

import {themes as prismThemes} from 'prism-react-renderer';
import type {Config} from '@docusaurus/types';
import type * as Preset from '@docusaurus/preset-classic';
const umamiUrl = process.env.UMAMI_URL;
const umamiWebsiteId = process.env.UMAMI_WEBSITE_ID;
// Announcement bar - supports HTML for links
// Set to empty string '' to hide the bar
const ANNOUNCEMENT_BAR = 'Hindsight is State-of-the-Art on Memory for AI Agents | <a href="https://arxiv.org/abs/2512.12818" target="_blank">Read the paper →</a>';
const config: Config = {
title: 'Hindsight',
tagline: 'Hindsight: Agent Memory That Works Like Human Memory',
favicon: 'img/favicon.png',
future: {
v4: true,
},
markdown: {
mermaid: true,
},
url: 'https://hindsight.vectorize.io',
baseUrl: '/',
organizationName: 'vectorize-io',
projectName: 'hindsight',
trailingSlash: false,
onBrokenLinks: 'throw',
i18n: {
defaultLocale: 'en',
locales: ['en'],
},
headTags: [
{
tagName: 'link',
attributes: {
rel: 'preconnect',
href: 'https://fonts.googleapis.com',
},
},
{
tagName: 'link',
attributes: {
rel: 'preconnect',
href: 'https://fonts.gstatic.com',
crossorigin: 'anonymous',
},
},
{
tagName: 'link',
attributes: {
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500;600&family=Space+Grotesk:wght@500;600;700&display=swap',
media: 'print',
onload: "this.media='all'",
},
},
],
scripts: [
...(umamiUrl && umamiWebsiteId
? [
{
src: `${umamiUrl}/script.js`,
async: true,
defer: true,
'data-website-id': umamiWebsiteId,
},
]
: []),
],
presets: [
[
'classic',
{
docs: {
sidebarPath: './sidebars.ts',
routeBasePath: '/',
// Whether to include the "current" (Next / unreleased) docs version.
//
// Controlled by the single explicit env var INCLUDE_CURRENT_VERSION.
// `start-docs.sh` sets it to "true" so local dev always sees Next;
// production builds leave it unset so only released versions ship.
//
// We deliberately do NOT sniff NODE_ENV here — it's unreliable
// across Docusaurus hot-reload paths and used to cause the Next
// version to disappear intermittently when editing files.
onlyIncludeVersions: (() => {
const includeCurrent = process.env.INCLUDE_CURRENT_VERSION === 'true';
let released: string[] = [];
try {
released = require('./versions.json') as string[];
} catch {
// No versions.json yet — nothing has been released.
return undefined;
}
return includeCurrent ? ['current', ...released] : released;
})(),
// Disable version badges on all versions
versions: (() => {
const config: Record<string, {badge: boolean}> = {
current: {badge: false},
};
try {
const versions = require('./versions.json') as string[];
versions.forEach((v: string) => {
config[v] = {badge: false};
});
} catch {
// No versions yet
}
return config;
})(),
},
blog: {
showReadingTime: true,
blogTitle: 'Hindsight Blog',
blogDescription: 'Updates, insights, and deep dives into agent memory',
postsPerPage: 'ALL',
blogSidebarCount: 0,
},
theme: {
customCss: './src/css/custom.css',
},
} satisfies Preset.Options,
],
[
'redocusaurus',
{
specs: [
{
id: 'hindsight-api',
spec: 'static/openapi.json',
route: '/api-reference',
url: '/openapi.json',
},
],
theme: {
primaryColor: '#0074d9',
sidebar: {
backgroundColor: '#09090b',
},
rightPanel: {
backgroundColor: '#18181b',
},
typography: {
fontSize: '15px',
fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
headings: {
fontFamily: "'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
},
code: {
fontFamily: "'JetBrains Mono', 'Fira Code', 'SF Mono', Monaco, Consolas, monospace",
fontSize: '13px',
},
},
},
config: {
scrollYOffset: 60,
nativeScrollbars: true,
expandSingleSchemaField: true,
expandResponses: '200,201',
},
},
],
],
plugins: [
[
'@docusaurus/plugin-content-docs',
{
id: 'integrations',
path: './docs-integrations',
routeBasePath: 'sdks/integrations',
sidebarPath: false,
},
],
],
themes: [
'@docusaurus/theme-mermaid',
[
'@easyops-cn/docusaurus-search-local',
{
hashed: true,
docsRouteBasePath: '/',
indexBlog: true,
blogRouteBasePath: '/blog',
highlightSearchTermsOnTargetPage: false,
},
],
],
themeConfig: {
...(ANNOUNCEMENT_BAR && {
announcementBar: {
id: 'announcement',
content: ANNOUNCEMENT_BAR,
backgroundColor: '#0074d9',
textColor: '#ffffff',
isCloseable: false,
},
}),
image: 'img/logo.png',
colorMode: {
defaultMode: 'dark',
respectPrefersColorScheme: true,
},
navbar: {
logo: {
alt: 'Hindsight Logo',
src: 'img/logo.png',
style: { height: '32px' },
},
items: [
{
type: 'doc',
docId: 'developer/index',
position: 'left',
label: 'Developer',
className: 'navbar-item-developer',
},
{
to: '/integrations',
position: 'left',
label: 'Integrations',
className: 'navbar-item-integrations',
},
{
to: '/changelog',
position: 'left',
label: 'Changelog',
className: 'navbar-item-changelog',
},
{
type: 'dropdown',
label: 'Resources',
position: 'left',
className: 'navbar-item-resources',
items: [
{
to: '/templates',
label: 'Bank Templates Hub',
customProps: { icon: 'lu-layout-template' },
},
{
to: '/best-practices',
label: 'Best Practices',
customProps: { icon: 'lu-star' },
},
{
to: '/faq',
label: 'FAQ',
customProps: { icon: 'lu-circle-help' },
},
{
to: '/cookbook',
label: 'Cookbook',
customProps: { icon: 'lu-book' },
},
{
to: '/blog',
label: 'Blog',
customProps: { icon: 'lu-rss' },
},
{
to: '/api-reference',
label: 'API Reference',
customProps: { icon: 'lu-book-open' },
},
{
href: 'https://join.slack.com/t/hindsight-space/shared_invite/zt-3nhbm4w29-LeSJ5Ixi6j8PdiYOCPlOgg',
label: 'Community',
customProps: { icon: 'si-slack' },
},
{
href: 'https://benchmarks.hindsight.vectorize.io/',
label: 'Benchmarks',
customProps: { icon: 'lu-chart-bar' },
},
{
href: 'https://benchmarks.hindsight.vectorize.io/',
label: 'Which Model Should I Use?',
customProps: { icon: 'lu-cpu' },
},
{
href: 'https://arxiv.org/abs/2512.12818',
label: 'Paper',
customProps: { icon: 'lu-file-text' },
},
],
},
{
type: 'docsVersionDropdown',
position: 'right',
className: 'navbar-item-version',
},
{
href: 'https://ui.hindsight.vectorize.io/signup',
position: 'right',
label: 'Cloud',
className: 'navbar-item-cloud',
},
{
href: 'https://github.com/vectorize-io/hindsight',
position: 'right',
label: 'GitHub',
className: 'header-github-link',
},
],
},
footer: {
style: 'dark',
links: [
{
title: 'Documentation',
items: [
{
label: 'Introduction',
to: '/',
},
{
label: 'Developer Guide',
to: '/developer/installation',
},
{
label: 'Clients & Integrations',
to: '/sdks/python',
},
{
label: 'API Reference',
to: '/api-reference/',
},
],
},
{
title: 'Resources',
items: [
{
label: 'Cookbook',
to: '/cookbook',
},
{
label: 'Changelog',
to: '/changelog',
},
{
label: 'Hindsight Cloud',
href: 'https://ui.hindsight.vectorize.io/signup',
},
],
},
{
title: 'Community',
items: [
{
label: 'GitHub',
href: 'https://github.com/vectorize-io/hindsight',
},
{
label: 'Slack',
href: 'https://join.slack.com/t/hindsight-space/shared_invite/zt-3nhbm4w29-LeSJ5Ixi6j8PdiYOCPlOgg',
},
],
},
],
copyright: `Copyright © ${new Date().getFullYear()} Vectorize, Inc.`,
},
prism: {
theme: prismThemes.github,
darkTheme: prismThemes.dracula,
additionalLanguages: ['bash', 'json', 'python', 'rust'],
},
mermaid: {
theme: {
light: 'base',
dark: 'base',
},
options: {
themeVariables: {
// Gradient start (#0074d9 blue) for nodes
primaryColor: '#0074d9',
primaryTextColor: '#ffffff',
primaryBorderColor: '#005db0',
// Gradient end (#009296 teal) for edges/clusters
secondaryColor: '#009296',
secondaryTextColor: '#ffffff',
secondaryBorderColor: '#007a7d',
// Tertiary
tertiaryColor: '#e6f7f8',
tertiaryTextColor: '#1e293b',
// Lines and edges - gradient end color
lineColor: '#009296',
// Text
textColor: '#1e293b',
// Node specific - gradient start
nodeBkg: '#0074d9',
nodeTextColor: '#ffffff',
nodeBorder: '#005db0',
// Main background
mainBkg: '#0074d9',
// Clusters/subgraphs - gradient end
clusterBkg: 'rgba(0, 146, 150, 0.08)',
clusterBorder: '#009296',
// Labels
edgeLabelBackground: 'transparent',
labelBackground: 'transparent',
// Font - Inter to match body text
fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
},
},
},
} satisfies Preset.ThemeConfig,
};
export default config;