@digitalvibes/ai-knowledge-db
v0.3.1
Published
AI knowledge vector storage (Postgres + pgvector) for Dibe website/project work. Stores client- and project-scoped knowledge and serves it back via semantic search.
Maintainers
Readme
@digitalvibes/ai-knowledge-db
AI knowledge vector storage for Dibe website/project work. A thin TypeScript package over Postgres + pgvector (hosted on Hetzner via EasyPanel) that stores client-, project-, and global-scoped knowledge and serves it back via semantic search. Ships with a Claude skill and a CLI.
- 🔐 No secrets in the package. Connection string, API key, and the default
client/project come from the consuming project's
.env. - 🧭 Scoped knowledge.
global→client→project. A project search automatically also pulls that client's shared + global knowledge. - 🤖 Agent-ready. A bundled skill (
skills/knowledge-db) and a paste-in Claude reference (CLAUDE.reference.md) teach agents to retrieve-before-build and store durable decisions.
Why pgvector + OpenAI
One Postgres instance holds both the relational metadata and the vectors —
simplest thing to run and back up on EasyPanel. Embeddings use
text-embedding-3-small (1536 dims), cheap and good for brand/website knowledge.
Install
npm install @digitalvibes/ai-knowledge-db1. Provision the DB (EasyPanel / Hetzner)
- In EasyPanel, create a Postgres service (it includes a database).
- Ensure the
vectorextension is available (the officialpgvector/pgvectorimage, orCREATE EXTENSION vector;on a Postgres with the extension installed). - Copy the connection string into your project's
.envasKNOWLEDGE_DB_URL.
2. Configure the consuming project
Copy .env.example → .env and fill in:
KNOWLEDGE_DB_URL=postgres://user:pass@host:5432/knowledge
OPENAI_API_KEY=sk-...
KNOWLEDGE_CLIENT_ID=acme-corp
KNOWLEDGE_PROJECT_ID=acme-website-2026Initialise the schema once:
npx knowledge-db init3. Use it
CLI
npx knowledge-db add "Client prefers sentence case headings." --scope client
npx knowledge-db add-file ./brand/voice.md --scope client --source brand/voice.md
npx knowledge-db search "what is the brand voice?"
npx knowledge-db delete --source brand/voice.mdLibrary
import { createKnowledgeDB } from "@digitalvibes/ai-knowledge-db";
const kb = createKnowledgeDB(); // reads .env
await kb.add({ content: "Hero CTA finalised as 'Start free'.", source: "decisions.md" });
const hits = await kb.search("homepage hero copy", { limit: 5 });
console.log(hits.map((h) => `${h.score.toFixed(2)} ${h.content}`));
await kb.close();API
| Method | Purpose |
|--------|---------|
| kb.init() | Create/upgrade extension, table, indexes (idempotent). |
| kb.add(input) | Append free-form knowledge (never overrides). |
| kb.put(input) | Versioned write by key — supersedes prior version, keeps history. |
| kb.upsertSource(input) | Re-ingest a source, superseding its prior version. |
| kb.search(query, opts) | Scoped semantic search → ranked SearchResult[]. Current versions only unless includeHistory/asOf. |
| kb.history(key, opts) | All versions of a key, newest first. |
| kb.delete(filter) | Hard-delete by id / key / source / project / client / scope. |
| kb.close() | Close the pool. |
Keeping facts current (pricing, hours, …)
Semantic search has no notion of "newest", so changeable facts use a stable
key. Writing the key again supersedes the old version (kept as history) and
makes the new value the only one returned in normal search:
await kb.put({ key: "pricing.basic-plan", content: "Basic plan is €50/mo.", scope: "client" });
await kb.put({ key: "pricing.basic-plan", content: "Basic plan is €80/mo.", scope: "client" });
await kb.search("how much is the basic plan?"); // → €80 only
await kb.search("…", { includeHistory: true }); // → both versions
await kb.search("…", { asOf: "2026-01-01" }); // → what was current then
await kb.history("pricing.basic-plan", { scope: "client" }); // → [€80 current, €50 superseded]Use add for accumulating notes, put --key for facts that change, and
add-file --source for documents.
Scoping a search
await kb.search("brand voice", {
clientId: "acme-corp",
projectId: "acme-website-2026",
includeClientKnowledge: true, // default — also pull the client's shared rows
includeGlobal: true, // default — also pull global rows
limit: 8,
minScore: 0.2,
});For agents
- Agent guide:
AGENTS.md— tool-agnostic, canonical usage (env, scopes, add/put/search/history, freshness rule). Source of truth for behavior. - Skill:
skills/knowledge-db/SKILL.md— full retrieve/add/update workflow for Claude Code. - Self-integration:
docs/integrating-into-your-project.md— instructions an installing/updating agent follows to document the DB in this project's own agent docs (CLAUDE.md/AGENTS.md/.cursorrules/docs/), matching the project's existing style, and refresh that section on update. - Quick paste (optional):
CLAUDE.reference.md— a ready-made block if you'd rather drop a fixed section intoCLAUDE.mdinstead of adapting.
After installing/updating this package, agents should wire its usage into the project's docs per
docs/integrating-into-your-project.md, then continue.
Switching embedding model
text-embedding-3-large → 3072 dims. Change vector(1536) → vector(3072) in
src/schema.sql, re-run init on a fresh table, and set
KNOWLEDGE_EMBED_MODEL=text-embedding-3-large.
Develop
npm install
npm run build # tsup → dist (esm + cjs + d.ts)
npm run typecheck