@legioncodeinc/honeycomb 0.1.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/.claude-plugin/marketplace.json +18 -0
- package/.claude-plugin/plugin.json +15 -0
- package/LICENSE +661 -0
- package/README.md +268 -0
- package/assets/logos/fonts/Inter-Italic-VariableFont_opsz_wght.ttf +0 -0
- package/assets/logos/fonts/Inter-VariableFont_opsz_wght.ttf +0 -0
- package/assets/logos/fonts/JetBrainsMono-Bold.woff2 +0 -0
- package/assets/logos/fonts/JetBrainsMono-Medium.woff2 +0 -0
- package/assets/logos/fonts/JetBrainsMono-Regular.woff2 +0 -0
- package/assets/logos/fonts/JetBrainsMono-SemiBold.woff2 +0 -0
- package/assets/logos/honeycomb-memory-cluster.svg +17 -0
- package/assets/readme.md +117 -0
- package/assets/styles.css +11 -0
- package/assets/tokens/base.css +76 -0
- package/assets/tokens/colors.css +111 -0
- package/assets/tokens/fonts.css +32 -0
- package/assets/tokens/spacing.css +48 -0
- package/assets/tokens/typography.css +38 -0
- package/bundle/cli.js +20049 -0
- package/daemon/dashboard-app.js +118 -0
- package/daemon/index.js +49533 -0
- package/daemon/package.json +1 -0
- package/embeddings/embed-daemon.js +218 -0
- package/harnesses/claude-code/.claude-plugin/plugin.json +14 -0
- package/harnesses/claude-code/bundle/capture.js +16459 -0
- package/harnesses/claude-code/bundle/index.js +16459 -0
- package/harnesses/claude-code/bundle/package.json +1 -0
- package/harnesses/claude-code/bundle/pre-tool-use.js +16459 -0
- package/harnesses/claude-code/bundle/session-end.js +16459 -0
- package/harnesses/claude-code/bundle/session-start.js +16459 -0
- package/harnesses/claude-code/hooks/hooks.json +86 -0
- package/harnesses/codex/bundle/capture.js +16451 -0
- package/harnesses/codex/bundle/index.js +16451 -0
- package/harnesses/codex/bundle/package.json +1 -0
- package/harnesses/codex/bundle/pre-tool-use.js +16451 -0
- package/harnesses/codex/bundle/session-start.js +16451 -0
- package/harnesses/codex/package.json +7 -0
- package/harnesses/cursor/bundle/capture.js +16459 -0
- package/harnesses/cursor/bundle/index.js +16459 -0
- package/harnesses/cursor/bundle/package.json +1 -0
- package/harnesses/cursor/bundle/pre-tool-use.js +16459 -0
- package/harnesses/cursor/bundle/session-end.js +16459 -0
- package/harnesses/cursor/bundle/session-start.js +16459 -0
- package/harnesses/hermes/bundle/index.js +30 -0
- package/harnesses/hermes/bundle/package.json +1 -0
- package/harnesses/openclaw/dist/index.js +55 -0
- package/harnesses/openclaw/dist/package.json +1 -0
- package/harnesses/openclaw/openclaw.plugin.json +47 -0
- package/harnesses/openclaw/package.json +22 -0
- package/harnesses/pi/bundle/index.js +30 -0
- package/harnesses/pi/bundle/package.json +1 -0
- package/mcp/bundle/package.json +1 -0
- package/mcp/bundle/server.js +24014 -0
- package/package.json +137 -0
- package/scripts/ensure-embed-deps.mjs +67 -0
- package/scripts/ensure-tree-sitter.mjs +89 -0
- package/sdk/index.js +312 -0
- package/sdk/openai.js +63 -0
- package/sdk/package.json +1 -0
- package/sdk/react.js +40 -0
- package/sdk/vercel.js +43 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
// dist/embeddings/src/index.js
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
|
|
4
|
+
// dist/src/shared/constants.js
|
|
5
|
+
var HONEYCOMB_VERSION = true ? "0.1.0" : "0.0.0-dev";
|
|
6
|
+
|
|
7
|
+
// dist/embeddings/src/index.js
|
|
8
|
+
var EMBED_DIMS = 768;
|
|
9
|
+
var MODEL_ID = "nomic-ai/nomic-embed-text-v1.5";
|
|
10
|
+
var MODEL_REVISION = "e9b6763023c676ca8431644204f50c2b100d9aab";
|
|
11
|
+
var MODEL_QUANTIZATION = "q8";
|
|
12
|
+
var DOCUMENT_PREFIX = "search_document: ";
|
|
13
|
+
var EMBED_HOST = "127.0.0.1";
|
|
14
|
+
var EMBED_PORT = 3851;
|
|
15
|
+
function resolveEmbedPort(override, rawEnvPort) {
|
|
16
|
+
if (override !== void 0)
|
|
17
|
+
return override;
|
|
18
|
+
if (rawEnvPort === void 0 || rawEnvPort.trim().length === 0)
|
|
19
|
+
return EMBED_PORT;
|
|
20
|
+
const envPort = Number(rawEnvPort);
|
|
21
|
+
return Number.isInteger(envPort) && envPort >= 0 && envPort < 65536 ? envPort : EMBED_PORT;
|
|
22
|
+
}
|
|
23
|
+
function embedDaemonInfo() {
|
|
24
|
+
return { version: HONEYCOMB_VERSION, model: MODEL_ID, revision: MODEL_REVISION, dims: EMBED_DIMS };
|
|
25
|
+
}
|
|
26
|
+
function modelCacheDir(env = process.env) {
|
|
27
|
+
const override = env.HONEYCOMB_EMBED_CACHE_DIR;
|
|
28
|
+
if (override !== void 0 && override.length > 0)
|
|
29
|
+
return override;
|
|
30
|
+
const home = env.HOME ?? env.USERPROFILE ?? process.cwd();
|
|
31
|
+
return `${home}/.honeycomb/embed-models`;
|
|
32
|
+
}
|
|
33
|
+
var loadTransformers = async () => {
|
|
34
|
+
const moduleSpecifier = "@huggingface/transformers";
|
|
35
|
+
const dynamicImport = new Function("m", "return import(m);");
|
|
36
|
+
return await dynamicImport(moduleSpecifier);
|
|
37
|
+
};
|
|
38
|
+
var extractor = null;
|
|
39
|
+
var warming = null;
|
|
40
|
+
async function warmup(env = process.env) {
|
|
41
|
+
if (extractor !== null)
|
|
42
|
+
return;
|
|
43
|
+
if (warming !== null)
|
|
44
|
+
return warming;
|
|
45
|
+
warming = (async () => {
|
|
46
|
+
const transformers = await loadTransformers();
|
|
47
|
+
transformers.env.cacheDir = modelCacheDir(env);
|
|
48
|
+
if ((env.HONEYCOMB_EMBED_OFFLINE ?? "").trim().length > 0) {
|
|
49
|
+
transformers.env.allowRemoteModels = false;
|
|
50
|
+
}
|
|
51
|
+
extractor = await transformers.pipeline("feature-extraction", MODEL_ID, {
|
|
52
|
+
revision: MODEL_REVISION,
|
|
53
|
+
dtype: MODEL_QUANTIZATION
|
|
54
|
+
});
|
|
55
|
+
await extractor(DOCUMENT_PREFIX + "warmup", { pooling: "mean", normalize: true });
|
|
56
|
+
})();
|
|
57
|
+
try {
|
|
58
|
+
await warming;
|
|
59
|
+
} finally {
|
|
60
|
+
warming = null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async function embed(text, env = process.env) {
|
|
64
|
+
if (extractor === null)
|
|
65
|
+
await warmup(env);
|
|
66
|
+
if (extractor === null)
|
|
67
|
+
throw new Error("embed model not available");
|
|
68
|
+
const out = await extractor(DOCUMENT_PREFIX + text, { pooling: "mean", normalize: true });
|
|
69
|
+
const vector = Array.from(out.data);
|
|
70
|
+
if (vector.length !== EMBED_DIMS) {
|
|
71
|
+
throw new Error(`embed dim mismatch: expected ${EMBED_DIMS}, got ${vector.length}`);
|
|
72
|
+
}
|
|
73
|
+
return vector;
|
|
74
|
+
}
|
|
75
|
+
var WARM_ERROR_MAX = 300;
|
|
76
|
+
function redactWarmError(err) {
|
|
77
|
+
const raw = err instanceof Error ? err.message : typeof err === "string" ? err : "warmup failed";
|
|
78
|
+
const redacted = raw.replace(/\bhf_[A-Za-z0-9]+/g, "[redacted]").replace(/(authorization|bearer|token|api[_-]?key|secret|password)\s*[:=]\s*\S+/gi, "$1=[redacted]").replace(/\s+/g, " ").trim();
|
|
79
|
+
return redacted.length > WARM_ERROR_MAX ? `${redacted.slice(0, WARM_ERROR_MAX - 1)}\u2026` : redacted;
|
|
80
|
+
}
|
|
81
|
+
async function readBody(req, maxBytes = 1e6) {
|
|
82
|
+
const chunks = [];
|
|
83
|
+
let total = 0;
|
|
84
|
+
for await (const chunk of req) {
|
|
85
|
+
const buf = chunk;
|
|
86
|
+
total += buf.length;
|
|
87
|
+
if (total > maxBytes)
|
|
88
|
+
throw new Error("request body too large");
|
|
89
|
+
chunks.push(buf);
|
|
90
|
+
}
|
|
91
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
92
|
+
}
|
|
93
|
+
function sendJson(res, status, body) {
|
|
94
|
+
const payload = JSON.stringify(body);
|
|
95
|
+
res.writeHead(status, { "content-type": "application/json" });
|
|
96
|
+
res.end(payload);
|
|
97
|
+
}
|
|
98
|
+
async function startEmbedDaemon(options = {}) {
|
|
99
|
+
const env = options.env ?? process.env;
|
|
100
|
+
const host = options.host ?? env.HONEYCOMB_EMBED_HOST ?? EMBED_HOST;
|
|
101
|
+
const port = resolveEmbedPort(options.port, env.HONEYCOMB_EMBED_PORT);
|
|
102
|
+
let warmFailed = false;
|
|
103
|
+
let warmError = null;
|
|
104
|
+
void warmup(env).catch((err) => {
|
|
105
|
+
warmFailed = true;
|
|
106
|
+
warmError = redactWarmError(err);
|
|
107
|
+
process.stderr.write(`[honeycomb-embed] warmup failed: ${warmError}
|
|
108
|
+
`);
|
|
109
|
+
});
|
|
110
|
+
const server = createServer((req, res) => {
|
|
111
|
+
void (async () => {
|
|
112
|
+
try {
|
|
113
|
+
if (req.method === "GET" && (req.url === "/health" || req.url === "/")) {
|
|
114
|
+
sendJson(res, 200, {
|
|
115
|
+
ok: true,
|
|
116
|
+
ready: extractor !== null,
|
|
117
|
+
warmFailed,
|
|
118
|
+
// The redacted warmup-failure reason (null until/unless warmup throws). No secret.
|
|
119
|
+
warmError,
|
|
120
|
+
...embedDaemonInfo()
|
|
121
|
+
});
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (req.method === "POST" && req.url === "/embed") {
|
|
125
|
+
const raw = await readBody(req);
|
|
126
|
+
let text;
|
|
127
|
+
try {
|
|
128
|
+
text = JSON.parse(raw).text;
|
|
129
|
+
} catch {
|
|
130
|
+
sendJson(res, 400, { error: "malformed request body" });
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (typeof text !== "string" || text.length === 0) {
|
|
134
|
+
sendJson(res, 400, { error: "missing or empty text" });
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (extractor === null) {
|
|
138
|
+
sendJson(res, 503, { error: "model not ready" });
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const vector = await embed(text, env);
|
|
142
|
+
sendJson(res, 200, { vector });
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
sendJson(res, 404, { error: "not found" });
|
|
146
|
+
} catch (err) {
|
|
147
|
+
const reason = err instanceof Error ? err.message : "embed failed";
|
|
148
|
+
sendJson(res, 500, { error: reason });
|
|
149
|
+
}
|
|
150
|
+
})();
|
|
151
|
+
});
|
|
152
|
+
await new Promise((resolve, reject) => {
|
|
153
|
+
server.once("error", reject);
|
|
154
|
+
server.listen(port, host, () => {
|
|
155
|
+
server.removeListener("error", reject);
|
|
156
|
+
resolve();
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
const bound = server.address();
|
|
160
|
+
const boundPort = typeof bound === "object" && bound !== null ? bound.port : port;
|
|
161
|
+
return {
|
|
162
|
+
address: { host, port: boundPort },
|
|
163
|
+
ready: () => extractor !== null,
|
|
164
|
+
close: () => new Promise((resolve) => {
|
|
165
|
+
server.close(() => resolve());
|
|
166
|
+
})
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function __resetForTest() {
|
|
170
|
+
extractor = null;
|
|
171
|
+
warming = null;
|
|
172
|
+
loadTransformers = defaultLoadTransformers;
|
|
173
|
+
}
|
|
174
|
+
var defaultLoadTransformers = loadTransformers;
|
|
175
|
+
function __setTransformersLoaderForTest(fake) {
|
|
176
|
+
loadTransformers = fake;
|
|
177
|
+
}
|
|
178
|
+
function __setExtractorForTest(fake) {
|
|
179
|
+
extractor = fake;
|
|
180
|
+
}
|
|
181
|
+
function isMainEntry() {
|
|
182
|
+
const entry = process.argv[1];
|
|
183
|
+
if (typeof entry !== "string" || entry.length === 0)
|
|
184
|
+
return false;
|
|
185
|
+
try {
|
|
186
|
+
return import.meta.url === new URL(`file://${entry}`).href || import.meta.url.endsWith("/embed-daemon.js");
|
|
187
|
+
} catch {
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (isMainEntry()) {
|
|
192
|
+
startEmbedDaemon().catch((err) => {
|
|
193
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
194
|
+
process.stderr.write(`[honeycomb-embed] failed to start: ${message}
|
|
195
|
+
`);
|
|
196
|
+
process.exitCode = 1;
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
export {
|
|
200
|
+
DOCUMENT_PREFIX,
|
|
201
|
+
EMBED_DIMS,
|
|
202
|
+
EMBED_HOST,
|
|
203
|
+
EMBED_PORT,
|
|
204
|
+
MODEL_ID,
|
|
205
|
+
MODEL_QUANTIZATION,
|
|
206
|
+
MODEL_REVISION,
|
|
207
|
+
WARM_ERROR_MAX,
|
|
208
|
+
__resetForTest,
|
|
209
|
+
__setExtractorForTest,
|
|
210
|
+
__setTransformersLoaderForTest,
|
|
211
|
+
embed,
|
|
212
|
+
embedDaemonInfo,
|
|
213
|
+
modelCacheDir,
|
|
214
|
+
redactWarmError,
|
|
215
|
+
resolveEmbedPort,
|
|
216
|
+
startEmbedDaemon,
|
|
217
|
+
warmup
|
|
218
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "honeycomb",
|
|
3
|
+
"description": "Honeycomb — persistent memory for Claude Code sessions via the local Honeycomb daemon",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Honeycomb"
|
|
7
|
+
},
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"keywords": [
|
|
10
|
+
"memory",
|
|
11
|
+
"claude-code",
|
|
12
|
+
"agent-memory"
|
|
13
|
+
]
|
|
14
|
+
}
|