bikky 0.3.12 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +206 -0
- package/README.md +116 -154
- package/dist/config.d.ts +49 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +125 -4
- package/dist/config.js.map +1 -1
- package/dist/daemon/extraction.d.ts.map +1 -1
- package/dist/daemon/extraction.js +24 -19
- package/dist/daemon/extraction.js.map +1 -1
- package/dist/daemon/loop.d.ts.map +1 -1
- package/dist/daemon/loop.js +15 -1
- package/dist/daemon/loop.js.map +1 -1
- package/dist/daemon/qdrant.d.ts.map +1 -1
- package/dist/daemon/qdrant.js +0 -1
- package/dist/daemon/qdrant.js.map +1 -1
- package/dist/lib/qdrant-pool.d.ts +57 -0
- package/dist/lib/qdrant-pool.d.ts.map +1 -0
- package/dist/lib/qdrant-pool.js +104 -0
- package/dist/lib/qdrant-pool.js.map +1 -0
- package/dist/mcp/api.d.ts +56 -19
- package/dist/mcp/api.d.ts.map +1 -1
- package/dist/mcp/api.js +133 -72
- package/dist/mcp/api.js.map +1 -1
- package/dist/mcp/helpers.d.ts +0 -1
- package/dist/mcp/helpers.d.ts.map +1 -1
- package/dist/mcp/helpers.js +2 -15
- package/dist/mcp/helpers.js.map +1 -1
- package/dist/mcp/helpers.test.js +3 -21
- package/dist/mcp/helpers.test.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +29 -14
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/tools.d.ts +0 -7
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +337 -219
- package/dist/mcp/tools.js.map +1 -1
- package/dist/mcp/types.d.ts +0 -3
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/routing.d.ts +53 -0
- package/dist/routing.d.ts.map +1 -0
- package/dist/routing.js +129 -0
- package/dist/routing.js.map +1 -0
- package/dist/routing.test.d.ts +2 -0
- package/dist/routing.test.d.ts.map +1 -0
- package/dist/routing.test.js +79 -0
- package/dist/routing.test.js.map +1 -0
- package/docs/config/fully-hosted.md +57 -0
- package/docs/config/hosted-models.md +50 -0
- package/docs/config/hosted-qdrant-local-models.md +39 -0
- package/docs/config/local.md +34 -0
- package/docs/configuration.md +374 -0
- package/docs/screenshots/dashboard.png +0 -0
- package/docs/screenshots/graph.png +0 -0
- package/docs/screenshots/memory.png +0 -0
- package/package.json +7 -4
- package/dist/mcp/api.test.d.ts +0 -6
- package/dist/mcp/api.test.d.ts.map +0 -1
- package/dist/mcp/api.test.js +0 -130
- package/dist/mcp/api.test.js.map +0 -1
- package/dist/mcp/tools.integration.itest.d.ts +0 -23
- package/dist/mcp/tools.integration.itest.d.ts.map +0 -1
- package/dist/mcp/tools.integration.itest.js +0 -171
- package/dist/mcp/tools.integration.itest.js.map +0 -1
- package/dist/mcp/tools.test.d.ts +0 -16
- package/dist/mcp/tools.test.d.ts.map +0 -1
- package/dist/mcp/tools.test.js +0 -908
- package/dist/mcp/tools.test.js.map +0 -1
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Contributing to bikky
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in bikky! We welcome PRs of all sizes — from typo fixes to new daemon features. This document covers the practical bits: how the repo is laid out, how to run the tests, and what we look for in a contribution.
|
|
4
|
+
|
|
5
|
+
## Repository layout
|
|
6
|
+
|
|
7
|
+
bikky is a small monorepo:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
.
|
|
11
|
+
├── src/ # Core CLI + MCP server + daemon (published as `bikky`)
|
|
12
|
+
│ ├── cli/ # `bikky <subcommand>` entrypoints
|
|
13
|
+
│ ├── daemon/ # Background workers: extraction, consolidation, staleness, …
|
|
14
|
+
│ ├── mcp/ # MCP server (the surface AI agents call into)
|
|
15
|
+
│ ├── prompts/ # Versioned LLM prompt registry
|
|
16
|
+
│ └── llm/ # Provider adapters (OpenAI, Bedrock, Ollama, Portkey)
|
|
17
|
+
│ ├── embedding/ # embedding registry + providers
|
|
18
|
+
│ └── inference/ # chat-completion registry + providers
|
|
19
|
+
└── packages/
|
|
20
|
+
└── ui/ # Local web UI (`bikky-ui`) — Hono server + React frontend
|
|
21
|
+
├── src/lib/ # - config, qdrant client, embeddings
|
|
22
|
+
├── src/routes/ # - REST API routes
|
|
23
|
+
└── app/ # - React/Vite frontend
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Setup
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
git clone https://github.com/bikky-dev/bikky.git
|
|
30
|
+
cd bikky
|
|
31
|
+
npm install
|
|
32
|
+
cd packages/ui && npm install && cd ../..
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Running the tests
|
|
36
|
+
|
|
37
|
+
We use the Node.js built-in test runner ([`node:test`](https://nodejs.org/api/test.html)) — no Jest, no Vitest, no extra dependencies.
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Core (CLI, daemon, MCP server) — 300+ tests
|
|
41
|
+
npm test
|
|
42
|
+
|
|
43
|
+
# UI server + libraries — 50+ tests
|
|
44
|
+
cd packages/ui && npm test
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Both packages compile TypeScript into `dist/` first and then run the compiled `*.test.js` files. The UI test suite uses `--test-isolation=process --test-concurrency=1` because several tests share `~/.bikky/config.json` on the developer's machine; running them in isolation avoids flakiness.
|
|
48
|
+
|
|
49
|
+
> **Note on `~/.bikky/config.json`** — UI tests back up your real config in `before()` and restore it in `after()`. If a test crashes mid-run the file *should* survive, but if you ever see odd behaviour after a failed test run, just delete the file and re-run `bikky setup`.
|
|
50
|
+
|
|
51
|
+
### What we test
|
|
52
|
+
|
|
53
|
+
We aim for **focused, fast unit tests** that lock in behaviour without being a maintenance tax:
|
|
54
|
+
|
|
55
|
+
- Pure functions (filter builders, hashers, parsers) — exhaustive cases.
|
|
56
|
+
- Stateful modules (config loaders, lifecycle/PID, daemons) — happy path + a couple of failure modes.
|
|
57
|
+
- Network clients (Qdrant, embeddings, LLM providers) — mock `globalThis.fetch` and assert on the request, never call a real backend.
|
|
58
|
+
- HTTP routes (Hono) — exercise via `app.fetch(new Request(...))` against the real router with mocked underlying calls.
|
|
59
|
+
|
|
60
|
+
We deliberately **do not** test:
|
|
61
|
+
|
|
62
|
+
- LLM prompt quality or extraction accuracy. Those live in the separate [`bikky-evals`](https://github.com/bikky-dev/bikky-evals) repo, which uses DeepEval for prompt-level scoring.
|
|
63
|
+
- Implementation details (private function internals, exact log strings) — these change often and tests that pin them slow contributors down.
|
|
64
|
+
- The React frontend — the testable surface there is small; we rely on type-checking and manual smoke tests.
|
|
65
|
+
|
|
66
|
+
### Adding a new test
|
|
67
|
+
|
|
68
|
+
Tests live alongside the source as `*.test.ts`:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
src/foo.ts # source
|
|
72
|
+
src/foo.test.ts # tests
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Use the [`node:test`](https://nodejs.org/api/test.html) `describe/it/before/after` API and `node:assert/strict`. For mocking, prefer **dependency injection** (e.g. the `StaleDeps` pattern in `src/daemon/staleness.ts`) over module mocking — it keeps tests deterministic and the production code easier to reason about.
|
|
76
|
+
|
|
77
|
+
Good references for new tests:
|
|
78
|
+
|
|
79
|
+
| Pattern | Reference |
|
|
80
|
+
|----------------------------------|----------------------------------------|
|
|
81
|
+
| Filesystem with backup/restore | `src/lifecycle.test.ts` |
|
|
82
|
+
| Temp dir with `mkdtemp` | `src/logger.test.ts` |
|
|
83
|
+
| Env-based path override | `src/llm/telemetry.test.ts` |
|
|
84
|
+
| Dependency injection for daemons | `src/daemon/staleness.test.ts` |
|
|
85
|
+
| Mocking `globalThis.fetch` | `src/mcp/api.test.ts`, `packages/ui/src/lib/qdrant.test.ts` |
|
|
86
|
+
| Hono route via `app.fetch` | `packages/ui/src/routes/memory.test.ts` |
|
|
87
|
+
|
|
88
|
+
### Integration tests (opt-in, real Qdrant)
|
|
89
|
+
|
|
90
|
+
The default `npm test` mocks every external call. We also ship one **opt-in** end-to-end smoke test that talks to a real Qdrant instance (Cloud, local Docker, or self-hosted) and a real embedding provider — it's the only thing that catches filter-shape rejections, payload-index mismatches, vector-dimension drift, and whether the dedup similarity thresholds (`THRESHOLD_DUPLICATE`, `THRESHOLD_RELATED`) actually correspond to near-duplicates against your embedding model.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Uses your existing ~/.bikky/config.json + QDRANT_URL (and QDRANT_API_KEY if your Qdrant requires it).
|
|
94
|
+
BIKKY_INTEGRATION=1 npm run test:integration
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
What it does:
|
|
98
|
+
|
|
99
|
+
1. Creates a throwaway collection named `bikky-it-<short-uuid>` with the real payload indexes.
|
|
100
|
+
2. Exercises `memory_store` (insert, exact-dup, near-duplicate paraphrase), `memory_recall`, `memory_entity`, and `memory_forget` against live Qdrant + your real embeddings.
|
|
101
|
+
3. Drops the collection in `after()` regardless of pass/fail.
|
|
102
|
+
|
|
103
|
+
Cost is negligible — a handful of small embedding calls per run (≈ $0.0001 on OpenAI's `text-embedding-3-small`, free on Ollama). Files end in `.itest.ts` so the default `*.test.js` glob never picks them up.
|
|
104
|
+
|
|
105
|
+
If the near-duplicate paraphrase doesn't reinforce on your embedding model, the test logs the actual similarity score so you can re-tune `THRESHOLD_DUPLICATE` rather than failing outright.
|
|
106
|
+
|
|
107
|
+
## Adding an embedding or LLM provider
|
|
108
|
+
|
|
109
|
+
The most common contribution is **adding a new embedding or LLM provider**. Each provider is a single file. The registry dispatches by `provider.name`, so no central edits are required beyond adding one import line to the barrel.
|
|
110
|
+
|
|
111
|
+
### Embedding provider
|
|
112
|
+
|
|
113
|
+
1. Create `src/llm/embedding/providers/<name>.ts`:
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
import {
|
|
117
|
+
registerEmbeddingProvider,
|
|
118
|
+
type EmbeddingProvider,
|
|
119
|
+
type ResolvedEmbeddingConfig,
|
|
120
|
+
} from "../registry.js";
|
|
121
|
+
|
|
122
|
+
export const myProvider: EmbeddingProvider = {
|
|
123
|
+
name: "myprovider",
|
|
124
|
+
label: "My Provider",
|
|
125
|
+
browserCompatible: true, // false if it needs a server-only SDK
|
|
126
|
+
defaults: {
|
|
127
|
+
model: "default-model",
|
|
128
|
+
dimensions: 1024,
|
|
129
|
+
baseUrl: "https://api.example.com", // omit if SDK-only
|
|
130
|
+
},
|
|
131
|
+
async embed(text, cfg) {
|
|
132
|
+
// cfg.{model,baseUrl,apiKey,extra} are pre-resolved
|
|
133
|
+
const resp = await fetch(`${cfg.baseUrl}/v1/embeddings`, { /* … */ });
|
|
134
|
+
// throw on programmer error; return number[] on success
|
|
135
|
+
return [/* embedding vector */];
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
registerEmbeddingProvider(myProvider);
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
2. Add a side-effect import in `src/llm/embedding/providers/index.ts`:
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
import "./myprovider.js";
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
3. Add a small unit test next to your provider (`<name>.test.ts`). Mock
|
|
149
|
+
`globalThis.fetch` (see `ollama.test.ts` for the pattern). Cover at minimum:
|
|
150
|
+
- success path (verifies URL, headers, body shape)
|
|
151
|
+
- non-OK response handling
|
|
152
|
+
- any provider-specific behaviour (auth, extra headers, fallback fields)
|
|
153
|
+
|
|
154
|
+
4. If your provider is browser-friendly, mirror it under
|
|
155
|
+
`packages/ui/src/lib/embedding/providers/<name>.ts` so the UI can use it.
|
|
156
|
+
|
|
157
|
+
5. Configure it in `~/.bikky/config.json`:
|
|
158
|
+
|
|
159
|
+
```json
|
|
160
|
+
{
|
|
161
|
+
"embedding": {
|
|
162
|
+
"provider": "myprovider",
|
|
163
|
+
"model": "my-model",
|
|
164
|
+
"api_key": "…",
|
|
165
|
+
"extra": { "any-key": "any-value" }
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Or via env: `BIKKY_EMBEDDING_EXTRA_<KEY>=value` flows into `extra`.
|
|
171
|
+
|
|
172
|
+
### Inference (LLM) provider
|
|
173
|
+
|
|
174
|
+
Same pattern, under `src/llm/inference/providers/`. The interface is
|
|
175
|
+
`InferenceProvider` (see `src/llm/inference/types.ts`), the key method is
|
|
176
|
+
`chat(opts, cfg, log)`, and providers should **return `null`** on recoverable
|
|
177
|
+
errors (HTTP error, missing key, network failure) so the orchestrator can fall
|
|
178
|
+
back to `cfg.fallback` if configured. Throw only for programmer errors.
|
|
179
|
+
|
|
180
|
+
Configure a fallback chain via `llm.fallback_provider` in config (or
|
|
181
|
+
`LLM_FALLBACK_PROVIDER` env).
|
|
182
|
+
|
|
183
|
+
## Submitting changes
|
|
184
|
+
|
|
185
|
+
1. **Open an issue first** for non-trivial changes so we can align on the approach.
|
|
186
|
+
2. **Branch** from `main` (`git checkout -b your-feature-name`).
|
|
187
|
+
3. **Run the tests** in both packages before pushing.
|
|
188
|
+
4. **Open a PR** referencing the issue (`Closes #123`). CI will re-run tests on push.
|
|
189
|
+
5. We aim to review within a few business days — ping the issue if it goes quiet.
|
|
190
|
+
|
|
191
|
+
## Style
|
|
192
|
+
|
|
193
|
+
- TypeScript strict mode is on; no `any` unless interfacing with external SDK types (use a focused local interface to constrain the surface area).
|
|
194
|
+
- We prefer small, pure functions and clear module boundaries to elaborate abstractions.
|
|
195
|
+
- Tests live next to the source they cover (`foo.ts` + `foo.test.ts`).
|
|
196
|
+
- Providers must not call `process.exit`, log to stdout, or modify global state beyond their own module-scope cache.
|
|
197
|
+
- Heavy SDKs (e.g. `@aws-sdk/*`) **must be `await import(...)`-loaded inside the provider's `embed`/`chat`** so users on lighter providers don't pay the bundle cost.
|
|
198
|
+
- Comments explain *why*, not *what* — the code shows the *what*.
|
|
199
|
+
|
|
200
|
+
## License
|
|
201
|
+
|
|
202
|
+
By contributing, you agree that your contributions will be licensed under the project's [AGPL-3.0-or-later](LICENSE) license.
|
|
203
|
+
|
|
204
|
+
## Code of conduct
|
|
205
|
+
|
|
206
|
+
Be kind. We follow the [Contributor Covenant](https://www.contributor-covenant.org/version/2/1/code_of_conduct/).
|
package/README.md
CHANGED
|
@@ -1,196 +1,177 @@
|
|
|
1
1
|
<h1 align="center">bikky</h1>
|
|
2
2
|
|
|
3
|
-
<p align="center"><b>Persistent memory for AI coding agents — for teams
|
|
3
|
+
<p align="center"><b>Persistent memory for AI coding agents — built for teams and multi-agent engineering workflows.</b></p>
|
|
4
4
|
|
|
5
|
-
bikky gives AI coding agents (GitHub Copilot, Claude Code, Cursor, and other MCP clients) long-term memory that persists across sessions, across tools, and across your whole team.
|
|
5
|
+
bikky gives AI coding agents (GitHub Copilot, Claude Code, Cursor, and other MCP clients) long-term memory that persists across sessions, across tools, and across your whole team. When multiple engineers, agents, or repos need to build on the same knowledge base, bikky captures what's learned *during* sessions so future sessions start smarter.
|
|
6
6
|
|
|
7
7
|
### Who it's for
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
| 👥 **Teams & software factories** | What one engineer's agent learns today, every agent on the team can recall tomorrow. Shared memory turns institutional knowledge into something queryable instead of tribal — onboarding accelerates, conventions stop drifting, and the same lesson never gets re-learned twice. |
|
|
12
|
-
| 🧑💻 **Solo AI power devs** | You run multiple Cursor / Claude Code / Copilot sessions every day and you're tired of re-explaining the codebase, the conventions, and last week's decisions to each new agent. bikky remembers across every session and every tool. |
|
|
9
|
+
- 👥 **Teams & software factories** — What one engineer's agent learns today, every agent on the team can recall tomorrow. Shared memory turns institutional knowledge into something queryable instead of tribal — onboarding accelerates, conventions stop drifting, and the same lesson never gets re-learned twice.
|
|
10
|
+
- 🤖 **Multi-agent engineering workflows** — Multiple Cursor / Claude Code / Copilot sessions can share codebase context, conventions, and recent decisions instead of re-learning them from scratch.
|
|
13
11
|
|
|
14
12
|
<p align="center">
|
|
15
|
-
<img src="https://cdn.jsdelivr.net/npm/bikky@latest/docs/diagrams/team-memory.svg" alt="Memory — facts flow from individual sessions into a self-curating knowledge store
|
|
13
|
+
<img src="https://cdn.jsdelivr.net/npm/bikky@latest/docs/diagrams/team-memory.svg" alt="Memory — facts flow from individual sessions into a self-curating knowledge store shared across your team" width="720" />
|
|
16
14
|
</p>
|
|
17
15
|
|
|
18
|
-
<p align="center"><i>Knowledge flows from every session into a store that curates itself over time — deduplicating, distilling, and decaying stale facts — so every future session starts smarter
|
|
16
|
+
<p align="center"><i>Knowledge flows from every session into a store that curates itself over time — deduplicating, distilling, and decaying stale facts — so every future session starts smarter across the team.</i></p>
|
|
19
17
|
|
|
20
18
|
---
|
|
21
19
|
|
|
22
20
|
### The problem
|
|
23
21
|
|
|
24
|
-
The most valuable things you and your agents learn — why a config value exists, which deploy step matters, what broke last quarter, the convention you settled on yesterday — happen *during* sessions. And then they vanish when the session closes.
|
|
22
|
+
The most valuable things you and your agents learn — why a config value exists, which deploy step matters, what broke last quarter, the convention you settled on yesterday — happen *during* sessions. And then they vanish when the session closes. Across teams, repos, and tools, knowledge still lives in heads, chat threads, and closed PRs, and every new agent session has to learn it from scratch. Hand-written docs drift the moment they're published.
|
|
25
23
|
|
|
26
24
|
### How bikky solves it
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
bikky gives your agent memory tools and runs a small background service after `bikky setup`. You keep working normally; bikky captures useful facts, organizes them, recalls them in future sessions, and keeps the store tidy over time.
|
|
27
|
+
|
|
28
|
+
- **Capture** — Facts are extracted automatically from session transcripts; no manual docs to write.
|
|
29
|
+
- **Classify** — Memories are grouped as **engineering**, **product**, **human**, or **system** so they stay easy to browse and filter.
|
|
30
|
+
- **Recall** — Every new session, yours or a teammate's, recalls from the same store via semantic search.
|
|
31
|
+
- **Curate** — bikky merges duplicates, fades stale facts, resolves contradictions, distills recurring patterns, and builds an entity graph over time.
|
|
32
|
+
- **Compound** — Session 50 is dramatically better than session 1 because memory accumulates.
|
|
33
|
+
- **Route** — Optionally keep team, client, or environment-specific memory in separate Qdrant destinations from one install. See [separate memory stores](#optional-separate-memory-stores).
|
|
34
|
+
|
|
35
|
+
Subtypes keep recall precise without making setup harder:
|
|
36
|
+
|
|
37
|
+
- **Engineering** — codebase maps, architecture decisions, infra topology, access patterns, operational procedures, troubleshooting gotchas, and conventions.
|
|
38
|
+
- **Product** — domain rules, product decisions, requirements, user workflows, roadmap items, success metrics, and market insights.
|
|
39
|
+
- **Human** — preferences, person profiles, ownership notes, working agreements, and activity events.
|
|
40
|
+
- **System** — session indexes, episodes, workstreams, and feedback signals.
|
|
34
41
|
|
|
35
42
|
---
|
|
36
43
|
|
|
37
44
|
## Quick start
|
|
38
45
|
|
|
39
|
-
|
|
46
|
+
This is the fastest path to a working memory store: Qdrant runs locally, while hosted embeddings and LLM calls provide strong extraction and recall quality without running local models.
|
|
40
47
|
|
|
41
48
|
```bash
|
|
42
49
|
# 1. Pull and run Qdrant (vector store)
|
|
43
50
|
docker run -d --name qdrant -p 6333:6333 -v qdrant_storage:/qdrant/storage qdrant/qdrant
|
|
44
51
|
|
|
45
|
-
# 2. Install
|
|
46
|
-
ollama pull qwen3-embedding:0.6b
|
|
47
|
-
|
|
48
|
-
# 3. Install and start bikky
|
|
52
|
+
# 2. Install bikky
|
|
49
53
|
npm install -g bikky
|
|
50
|
-
|
|
54
|
+
mkdir -p ~/.bikky
|
|
55
|
+
# Replace sk-... below with your hosted model API key.
|
|
56
|
+
cat > ~/.bikky/config.json <<'JSON'
|
|
57
|
+
{
|
|
58
|
+
"qdrant_url": "http://localhost:6333",
|
|
59
|
+
"qdrant_api_key": "",
|
|
60
|
+
"embedding": {
|
|
61
|
+
"provider": "openai",
|
|
62
|
+
"model": "text-embedding-3-small",
|
|
63
|
+
"dimensions": 1536,
|
|
64
|
+
"api_key": "sk-..."
|
|
65
|
+
},
|
|
66
|
+
"llm": {
|
|
67
|
+
"provider": "openai",
|
|
68
|
+
"model": "gpt-4.1-mini",
|
|
69
|
+
"api_key": "sk-..."
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
JSON
|
|
73
|
+
# qdrant_api_key is optional; leave it empty or omit it for local Qdrant.
|
|
74
|
+
# Prefer env vars? Omit api_key above and set OPENAI_API_KEY instead.
|
|
75
|
+
|
|
76
|
+
# 3. Register bikky with your editor and start the background service
|
|
51
77
|
bikky setup # writes MCP config for Copilot + Claude Code, then starts the daemon
|
|
52
78
|
```
|
|
53
79
|
|
|
54
|
-
Restart your editor
|
|
80
|
+
Restart your editor. The memory tools appear automatically in supported MCP clients.
|
|
55
81
|
|
|
56
82
|
```bash
|
|
57
|
-
bikky status #
|
|
83
|
+
bikky status # confirms Qdrant, embeddings, daemon, and UI health
|
|
58
84
|
```
|
|
59
85
|
|
|
60
|
-
That's
|
|
86
|
+
That's it. You can keep Qdrant local forever, or move the vector store to Qdrant Cloud later for a shared team setup.
|
|
87
|
+
|
|
88
|
+
For other deployment shapes — fully hosted, 100% local, or hosted Qdrant with local models — see [Setup options](#setup-options).
|
|
61
89
|
|
|
62
90
|
---
|
|
63
91
|
|
|
64
|
-
## Setup
|
|
92
|
+
## Setup options
|
|
65
93
|
|
|
66
|
-
|
|
94
|
+
bikky supports four common setup shapes. Pick based on where you want Qdrant to run and where model calls should happen.
|
|
67
95
|
|
|
68
|
-
|
|
69
|
-
|---|---|---|
|
|
70
|
-
| **Node.js** | ≥ 20 | `nvm install 20` or your package manager |
|
|
71
|
-
| **Vector store** | Qdrant | **Local Docker** (free, recommended for dev) · **[Qdrant Cloud](https://cloud.qdrant.io)** (free tier, 1 GB) · **Self-hosted** anywhere reachable |
|
|
72
|
-
| **Embeddings** | One provider | **[Ollama](https://ollama.com)** local (free, default) · **OpenAI** · **AWS Bedrock** · **[Portkey](https://portkey.ai)** gateway |
|
|
73
|
-
| **LLM** *(optional)* | Used by the daemon for distillation & extraction | Same provider list as embeddings — leave on Ollama for a fully-local stack |
|
|
74
|
-
| **Docker** *(optional)* | Only if you run Qdrant locally | Docker Desktop, OrbStack, colima, etc. |
|
|
96
|
+
### What you need
|
|
75
97
|
|
|
76
|
-
|
|
98
|
+
| Component | Required | Options |
|
|
99
|
+
| ----------------------- | ------------------------------ | ---------------------------------------------------------------------------------------- |
|
|
100
|
+
| **Node.js** | ≥ 20 | `nvm install 20` or your package manager |
|
|
101
|
+
| **Vector store** | Qdrant | Local Docker · [Qdrant Cloud](https://cloud.qdrant.io) · Self-hosted |
|
|
102
|
+
| **Embeddings** | One provider | OpenAI · Ollama · Bedrock · Portkey |
|
|
103
|
+
| **LLM** | One provider | OpenAI · Ollama · Bedrock · Portkey |
|
|
104
|
+
| **Docker** *(optional)* | Only if you run Qdrant locally | Docker Desktop, OrbStack, colima, etc. |
|
|
77
105
|
|
|
78
|
-
|
|
79
|
-
npm install -g bikky # CLI + MCP server + daemon
|
|
80
|
-
npm install -g bikky-ui # optional web dashboard
|
|
81
|
-
```
|
|
106
|
+
Both `embedding.provider` and `llm.provider` accept the same values: `ollama`, `openai`, `bedrock`, or `portkey`.
|
|
82
107
|
|
|
83
|
-
|
|
108
|
+
> ⚠️ **Qdrant Cloud free tier does not include automatic backups.** Deleted collections cannot be recovered. If your memory data is valuable, use a paid Qdrant Cloud plan (which includes daily backups), run Qdrant locally with your own backup strategy, or periodically export snapshots via the [Qdrant snapshots API](https://qdrant.tech/documentation/concepts/snapshots/).
|
|
84
109
|
|
|
85
|
-
|
|
86
|
-
- **Hosted Qdrant + local Ollama** — Qdrant Cloud free tier for shared/team memory; embeddings still local.
|
|
87
|
-
- **Fully hosted** — Qdrant Cloud + OpenAI / Bedrock / Portkey for embeddings and LLM. Best for teams that want a single shared memory across many machines.
|
|
110
|
+
### Choose a setup
|
|
88
111
|
|
|
89
|
-
|
|
112
|
+
| Setup | Best for | Config |
|
|
113
|
+
| -------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------- |
|
|
114
|
+
| **Fully hosted** | Best performance and teams; managed vector storage and models | [Fully hosted config][fully-hosted-config] |
|
|
115
|
+
| **Local Qdrant + hosted models** | Local vector storage with hosted extraction and embedding | [Hosted models config][hosted-models-config] |
|
|
116
|
+
| **Local and free** | Local evaluation; quality depends on local models | [Local config guide][local-config] |
|
|
117
|
+
| **Hosted Qdrant + local Ollama** | Shared vector storage while keeping model calls local | [Hosted Qdrant + local models][hosted-qdrant-local-models-config] |
|
|
90
118
|
|
|
91
|
-
|
|
119
|
+
### Configuration basics
|
|
92
120
|
|
|
93
|
-
|
|
94
|
-
# A) Let your agent do it
|
|
95
|
-
> "Call configure_credentials with my Qdrant URL (and API key if needed)"
|
|
121
|
+
Pick the setup guide above for the copy-paste config. All setup shapes use the same three building blocks:
|
|
96
122
|
|
|
97
|
-
|
|
98
|
-
|
|
123
|
+
- **Qdrant** — where vectors and memory payloads are stored.
|
|
124
|
+
- **Embeddings** — how facts become searchable vectors.
|
|
125
|
+
- **LLM** — how session transcripts are extracted, curated, and distilled.
|
|
99
126
|
|
|
100
|
-
|
|
101
|
-
export QDRANT_URL="http://localhost:6333"
|
|
102
|
-
# export QDRANT_API_KEY="…" # only for Qdrant Cloud / authenticated self-hosted
|
|
103
|
-
```
|
|
127
|
+
Config lives at `~/.bikky/config.json`, or at `BIKKY_HOME/config.json` when `BIKKY_HOME` is set. You can keep credentials out of the file with environment variables such as `QDRANT_URL`, `QDRANT_API_KEY`, and provider API keys.
|
|
104
128
|
|
|
105
|
-
|
|
129
|
+
For hosted models, custom providers, multiple profiles, or advanced tuning, use the full configuration guide.
|
|
106
130
|
|
|
107
|
-
> 📖 **Full configuration
|
|
131
|
+
> 📖 **Full configuration guide:** [docs/configuration.md][configuration-guide]
|
|
108
132
|
>
|
|
109
|
-
> 🛠 Want to add a new embedding or LLM provider (Vertex, OpenRouter, etc.)? See **[CONTRIBUTING.md]
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
bikky
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
Domain
|
|
134
|
-
Project / repo / surface
|
|
135
|
-
Workstream
|
|
136
|
-
Episodes
|
|
137
|
-
Facts, decisions, preferences, activity events, operational notes
|
|
138
|
-
Current-state summaries
|
|
139
|
-
What matters now, open questions, blockers
|
|
140
|
-
Cross-cutting memory
|
|
141
|
-
Durable patterns, entity relationships, telemetry
|
|
133
|
+
> 🛠 Want to add a new embedding or LLM provider (Vertex, OpenRouter, etc.)? See **[CONTRIBUTING.md][contributing]** — it's a single-file change.
|
|
134
|
+
|
|
135
|
+
#### Optional: separate memory stores
|
|
136
|
+
|
|
137
|
+
Most installs use one Qdrant destination. If you need clean separation later, replace the single `qdrant_url` / `collection` fields with named `destinations[]`:
|
|
138
|
+
|
|
139
|
+
```jsonc
|
|
140
|
+
{
|
|
141
|
+
"destinations": [
|
|
142
|
+
{
|
|
143
|
+
"name": "platform",
|
|
144
|
+
"qdrant_url": "https://platform.cloud.qdrant.io:6333",
|
|
145
|
+
"qdrant_api_key": "...",
|
|
146
|
+
"collection": "bikky-platform",
|
|
147
|
+
"default": true
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"name": "client-a",
|
|
151
|
+
"qdrant_url": "https://client-a.cloud.qdrant.io:6333",
|
|
152
|
+
"qdrant_api_key": "...",
|
|
153
|
+
"collection": "bikky-client-a"
|
|
154
|
+
}
|
|
155
|
+
]
|
|
156
|
+
}
|
|
142
157
|
```
|
|
143
158
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
`category` is the broad subject area:
|
|
147
|
-
|
|
148
|
-
| Category | Captures |
|
|
149
|
-
|----------|----------|
|
|
150
|
-
| `engineering` | Codebase maps, architecture decisions, infrastructure topology, access patterns, operational procedures, troubleshooting gotchas, and engineering conventions |
|
|
151
|
-
| `product` | Domain rules, product decisions, requirements, user workflows, roadmap items, success metrics, and market insight |
|
|
152
|
-
| `human` | Preferences, person profiles, ownership notes, working agreements, and durable actor-action activity events |
|
|
153
|
-
| `system` | Bikky lifecycle memory: session indexes, episodes, workstreams, recall/feedback/outcome telemetry, and aggregate rollups |
|
|
154
|
-
|
|
155
|
-
`memory_subtype` is the precise capture shape inside a category:
|
|
156
|
-
|
|
157
|
-
| Category | Subtypes |
|
|
158
|
-
|----------|----------|
|
|
159
|
-
| `engineering` | `codebase_map`, `architecture_decision`, `infra_topology`, `access_pattern`, `operational_procedure`, `troubleshooting_gotcha`, `convention` |
|
|
160
|
-
| `product` | `domain_rule`, `product_decision`, `product_requirement`, `user_workflow`, `roadmap_item`, `success_metric`, `market_insight` |
|
|
161
|
-
| `human` | `preference`, `person_profile`, `ownership_note`, `working_agreement`, `activity_event` |
|
|
162
|
-
| `system` | `session_index`, `episode`, `workstream`, `recall_event`, `feedback_event`, `outcome_event`, `aggregate_rollup` |
|
|
163
|
-
|
|
164
|
-
`domain` is an activity/knowledge profile. The initial canonical domains are:
|
|
165
|
-
|
|
166
|
-
| Domain | Purpose |
|
|
167
|
-
|--------|---------|
|
|
168
|
-
| `software_engineering` | Default for coding-agent captures: repos, code, infrastructure, releases, incidents |
|
|
169
|
-
| `product_strategy` | Roadmap, positioning, experiments, customer insight, product decisions |
|
|
170
|
-
| `business_operations` | Company processes, vendors, compliance, obligations, recurring workflows |
|
|
171
|
-
| `research` | Source-backed investigation, hypotheses, contradictions, synthesis |
|
|
172
|
-
| `personal_productivity` | Individual goals, routines, preferences, projects, habits |
|
|
173
|
-
|
|
174
|
-
`kind` stays small (`fact`, `summary`, `distilled`, `relation`, `telemetry`). `source` is the creator class (`agent`, `system`, `user`, or `docs`). `actor_id` records the stable person or agent associated with a capture/action, and `workspace_id` scopes shared team memory. Legacy stored categories are read through compatibility aliases; this release does not migrate existing stored memories in place.
|
|
159
|
+
That is enough for explicit selection in the UI and tools. Add routing rules only when you want automatic placement by cwd, entity, content, or metadata. Existing single-Qdrant configs continue to work.
|
|
175
160
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
## Self-curation
|
|
179
|
-
|
|
180
|
-
Raw fact accumulation creates noise. bikky keeps the knowledge store clean automatically:
|
|
161
|
+
> 📖 **Details:** [multi-destination configuration](docs/configuration.md#multi-destination-routing)
|
|
181
162
|
|
|
182
|
-
-
|
|
183
|
-
-
|
|
184
|
-
-
|
|
185
|
-
-
|
|
186
|
-
-
|
|
187
|
-
|
|
163
|
+
[fully-hosted-config]: https://cdn.jsdelivr.net/npm/bikky@latest/docs/config/fully-hosted.md
|
|
164
|
+
[hosted-models-config]: https://cdn.jsdelivr.net/npm/bikky@latest/docs/config/hosted-models.md
|
|
165
|
+
[local-config]: https://cdn.jsdelivr.net/npm/bikky@latest/docs/config/local.md
|
|
166
|
+
[hosted-qdrant-local-models-config]: https://cdn.jsdelivr.net/npm/bikky@latest/docs/config/hosted-qdrant-local-models.md
|
|
167
|
+
[configuration-guide]: https://cdn.jsdelivr.net/npm/bikky@latest/docs/configuration.md
|
|
168
|
+
[contributing]: https://cdn.jsdelivr.net/npm/bikky@latest/CONTRIBUTING.md
|
|
188
169
|
|
|
189
170
|
---
|
|
190
171
|
|
|
191
172
|
## Web UI
|
|
192
173
|
|
|
193
|
-
[`bikky-ui`](
|
|
174
|
+
[`bikky-ui`](https://www.npmjs.com/package/bikky-ui) is a local dashboard for browsing and managing your team's memory — facts, entities, quality metrics, aggregate impact insights, and the relationship graph.
|
|
194
175
|
|
|
195
176
|
```bash
|
|
196
177
|
npx bikky-ui # one-shot — no install needed
|
|
@@ -200,17 +181,17 @@ bikky-ui # opens http://localhost:1422
|
|
|
200
181
|
```
|
|
201
182
|
|
|
202
183
|
<p align="center">
|
|
203
|
-
<img src="
|
|
184
|
+
<img src="docs/screenshots/dashboard.png" alt="Dashboard — overview stats, category breakdown, recent facts" width="720" />
|
|
204
185
|
</p>
|
|
205
186
|
<p align="center"><i>Dashboard — memory stats, category breakdown, and recent facts at a glance</i></p>
|
|
206
187
|
|
|
207
188
|
<p align="center">
|
|
208
|
-
<img src="
|
|
189
|
+
<img src="docs/screenshots/memory.png" alt="Memory browser — search, filter, and browse all stored facts" width="720" />
|
|
209
190
|
</p>
|
|
210
191
|
<p align="center"><i>Memory browser — search, filter by category/kind/source, and browse all stored facts</i></p>
|
|
211
192
|
|
|
212
193
|
<p align="center">
|
|
213
|
-
<img src="
|
|
194
|
+
<img src="docs/screenshots/graph.png" alt="Entity graph — interactive visualization of entity relationships" width="720" />
|
|
214
195
|
</p>
|
|
215
196
|
<p align="center"><i>Entity graph — interactive visualization of how concepts, people, and services relate</i></p>
|
|
216
197
|
|
|
@@ -229,26 +210,7 @@ bikky ui # launch the local web dashboard
|
|
|
229
210
|
bikky render # render a prompt to JSON (for eval harnesses & debugging)
|
|
230
211
|
```
|
|
231
212
|
|
|
232
|
-
`bikky status` is the first thing to run when setup feels wrong. It
|
|
233
|
-
config file, highlights env vars that override it, checks Qdrant reachability and
|
|
234
|
-
payload-index readiness without mutating the collection, runs a live embedding
|
|
235
|
-
smoke check, validates the configured LLM provider name without sending a chat
|
|
236
|
-
request, and reports daemon maintenance plus UI health. Use `bikky status --json` for automation,
|
|
237
|
-
`--no-live` to skip the embedding call, and `--no-ui` to skip the local UI probe.
|
|
238
|
-
|
|
239
|
-
### `bikky render` — inspect prompts
|
|
240
|
-
|
|
241
|
-
Render any of bikky'''s prompts to JSON without booting the MCP server. Useful for
|
|
242
|
-
external evaluation harnesses, prompt debugging, and reproducing model calls.
|
|
243
|
-
|
|
244
|
-
```bash
|
|
245
|
-
bikky render --list # list available prompts
|
|
246
|
-
echo '''{"transcript":"..."}''' | bikky render extraction # via stdin
|
|
247
|
-
bikky render extraction --input case.json # via file
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
Output: a JSON object with `promptName`, `messages`, `temperature`,
|
|
251
|
-
`max_tokens`, and `response_format` — exactly what bikky sends to the LLM.
|
|
213
|
+
`bikky status` is the first thing to run when setup feels wrong. It checks the config, Qdrant, embeddings, background daemon, and local UI health, then tells you what needs attention. Use `bikky status --json` for automation.
|
|
252
214
|
|
|
253
215
|
## License
|
|
254
216
|
|
package/dist/config.d.ts
CHANGED
|
@@ -76,11 +76,48 @@ export interface WatcherConfig {
|
|
|
76
76
|
path: string;
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* One Qdrant routing target. Each destination is fully self-contained: its own
|
|
81
|
+
* URL, API key, collection name, and match rules. All fields in `match` are
|
|
82
|
+
* arrays of regex strings; OR semantics within a destination's match block,
|
|
83
|
+
* first-match-wins across destinations.
|
|
84
|
+
*/
|
|
85
|
+
export interface DestinationMatch {
|
|
86
|
+
/** Match against `process.cwd()`. */
|
|
87
|
+
cwd?: string[];
|
|
88
|
+
/** Match against any of the input `entities`. */
|
|
89
|
+
entity?: string[];
|
|
90
|
+
/** Match against the input `content`. */
|
|
91
|
+
content?: string[];
|
|
92
|
+
/** Per-key match against the input `metadata`. */
|
|
93
|
+
metadata?: Record<string, string[]>;
|
|
94
|
+
}
|
|
95
|
+
export interface Destination {
|
|
96
|
+
/** Stable, unique name. Used as the `destination` override on tool calls. */
|
|
97
|
+
name: string;
|
|
98
|
+
qdrant_url: string;
|
|
99
|
+
qdrant_api_key: string | null;
|
|
100
|
+
collection: string;
|
|
101
|
+
/** Marks this destination as the fallback when no rule matches. */
|
|
102
|
+
default?: boolean;
|
|
103
|
+
/** Routing rules. Omit for a destination that is only reachable by override. */
|
|
104
|
+
match?: DestinationMatch;
|
|
105
|
+
}
|
|
79
106
|
export interface BikkyConfig {
|
|
107
|
+
/**
|
|
108
|
+
* Top-level Qdrant fields. When `destinations` is empty, a single default
|
|
109
|
+
* destination is synthesized from these — keeps single-Qdrant configs
|
|
110
|
+
* working without changes.
|
|
111
|
+
*/
|
|
80
112
|
qdrant_url: string | null;
|
|
81
113
|
qdrant_api_key: string | null;
|
|
82
114
|
collection: string;
|
|
83
|
-
|
|
115
|
+
/**
|
|
116
|
+
* One or more Qdrant routing targets. Memory operations resolve to a
|
|
117
|
+
* destination via override → cwd/entity/content/metadata regex match →
|
|
118
|
+
* default flag → first entry.
|
|
119
|
+
*/
|
|
120
|
+
destinations: Destination[];
|
|
84
121
|
aws_profile: string | null;
|
|
85
122
|
embedding: EmbeddingConfig;
|
|
86
123
|
llm: LLMConfig;
|
|
@@ -107,6 +144,17 @@ export declare function validateConfigObject(raw: unknown): ConfigIssue[];
|
|
|
107
144
|
export declare function inspectConfigFile(configPath?: string): ConfigFileDiagnostics;
|
|
108
145
|
export declare function getActiveConfigEnvOverrides(env?: NodeJS.ProcessEnv): string[];
|
|
109
146
|
export declare function loadConfig(): BikkyConfig;
|
|
147
|
+
/**
|
|
148
|
+
* Resolve the effective list of destinations from the loaded config.
|
|
149
|
+
*
|
|
150
|
+
* - If `destinations` is non-empty, return as-is.
|
|
151
|
+
* - Otherwise synthesize a single fallback destination from the top-level
|
|
152
|
+
* `qdrant_url` / `qdrant_api_key` / `collection` so existing single-Qdrant
|
|
153
|
+
* configs keep working without changes.
|
|
154
|
+
* - If neither is configured, returns an empty array — callers should treat
|
|
155
|
+
* that as "Qdrant not configured" the same way they did before.
|
|
156
|
+
*/
|
|
157
|
+
export declare function getEffectiveDestinations(config?: BikkyConfig): Destination[];
|
|
110
158
|
/** Save config to disk (used by setup command). */
|
|
111
159
|
export declare function saveConfig(config: BikkyConfig): void;
|
|
112
160
|
/** Reset cached config (for testing). */
|