@deeplake/hivemind 0.7.26 → 0.7.28
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 +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/bundle/cli.js +1086 -93
- package/codex/bundle/capture.js +10 -5
- package/codex/bundle/commands/auth-login.js +10 -5
- package/codex/bundle/embeddings/embed-daemon.js +4 -2
- package/codex/bundle/pre-tool-use.js +10 -5
- package/codex/bundle/session-start-setup.js +10 -5
- package/codex/bundle/session-start.js +233 -136
- package/codex/bundle/shell/deeplake-shell.js +10 -5
- package/codex/bundle/skillify-worker.js +60 -21
- package/codex/bundle/stop.js +66 -25
- package/codex/bundle/wiki-worker.js +4 -2
- package/codex/skills/deeplake-memory/SKILL.md +33 -0
- package/cursor/bundle/capture.js +63 -22
- package/cursor/bundle/commands/auth-login.js +10 -5
- package/cursor/bundle/embeddings/embed-daemon.js +4 -2
- package/cursor/bundle/pre-tool-use.js +10 -5
- package/cursor/bundle/session-end.js +57 -19
- package/cursor/bundle/session-start.js +238 -87
- package/cursor/bundle/shell/deeplake-shell.js +10 -5
- package/cursor/bundle/skillify-worker.js +60 -21
- package/cursor/bundle/wiki-worker.js +4 -2
- package/hermes/bundle/capture.js +63 -22
- package/hermes/bundle/commands/auth-login.js +10 -5
- package/hermes/bundle/embeddings/embed-daemon.js +4 -2
- package/hermes/bundle/pre-tool-use.js +10 -5
- package/hermes/bundle/session-end.js +57 -19
- package/hermes/bundle/session-start.js +239 -87
- package/hermes/bundle/shell/deeplake-shell.js +10 -5
- package/hermes/bundle/skillify-worker.js +60 -21
- package/hermes/bundle/wiki-worker.js +4 -2
- package/mcp/bundle/server.js +10 -5
- package/openclaw/dist/chunks/{auth-creds-AEKS6D3P.js → auth-creds-KKTYIP27.js} +2 -1
- package/openclaw/dist/chunks/{chunk-SRCBBT4H.js → chunk-OSD5GJJ5.js} +2 -0
- package/openclaw/dist/chunks/{config-ZLH6JFJS.js → config-XEK4MJJS.js} +2 -0
- package/openclaw/dist/chunks/{index-marker-store-PGT5CW6T.js → index-marker-store-CPGF2BI7.js} +4 -2
- package/openclaw/dist/chunks/{setup-config-C35UK4LP.js → setup-config-VI54GEUM.js} +2 -0
- package/openclaw/dist/index.js +68 -19
- package/openclaw/dist/skillify-worker.js +67 -27
- package/openclaw/openclaw.plugin.json +1 -1
- package/openclaw/package.json +1 -1
- package/package.json +1 -1
- package/pi/extension-source/hivemind.ts +157 -19
|
@@ -17,21 +17,21 @@ __export(index_marker_store_exports, {
|
|
|
17
17
|
hasFreshIndexMarker: () => hasFreshIndexMarker,
|
|
18
18
|
writeIndexMarker: () => writeIndexMarker
|
|
19
19
|
});
|
|
20
|
-
import { existsSync as
|
|
21
|
-
import { join as
|
|
20
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "node:fs";
|
|
21
|
+
import { join as join7 } from "node:path";
|
|
22
22
|
import { tmpdir } from "node:os";
|
|
23
23
|
function getIndexMarkerDir() {
|
|
24
|
-
return process.env.HIVEMIND_INDEX_MARKER_DIR ??
|
|
24
|
+
return process.env.HIVEMIND_INDEX_MARKER_DIR ?? join7(tmpdir(), "hivemind-deeplake-indexes");
|
|
25
25
|
}
|
|
26
26
|
function buildIndexMarkerPath(workspaceId, orgId, table, suffix) {
|
|
27
27
|
const markerKey = [workspaceId, orgId, table, suffix].join("__").replace(/[^a-zA-Z0-9_.-]/g, "_");
|
|
28
|
-
return
|
|
28
|
+
return join7(getIndexMarkerDir(), `${markerKey}.json`);
|
|
29
29
|
}
|
|
30
30
|
function hasFreshIndexMarker(markerPath) {
|
|
31
|
-
if (!
|
|
31
|
+
if (!existsSync4(markerPath))
|
|
32
32
|
return false;
|
|
33
33
|
try {
|
|
34
|
-
const raw = JSON.parse(
|
|
34
|
+
const raw = JSON.parse(readFileSync5(markerPath, "utf-8"));
|
|
35
35
|
const updatedAt = raw.updatedAt ? new Date(raw.updatedAt).getTime() : NaN;
|
|
36
36
|
if (!Number.isFinite(updatedAt) || Date.now() - updatedAt > INDEX_MARKER_TTL_MS)
|
|
37
37
|
return false;
|
|
@@ -41,8 +41,8 @@ function hasFreshIndexMarker(markerPath) {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
function writeIndexMarker(markerPath) {
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
mkdirSync4(getIndexMarkerDir(), { recursive: true });
|
|
45
|
+
writeFileSync3(markerPath, JSON.stringify({ updatedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf-8");
|
|
46
46
|
}
|
|
47
47
|
var INDEX_MARKER_TTL_MS;
|
|
48
48
|
var init_index_marker_store = __esm({
|
|
@@ -53,9 +53,9 @@ var init_index_marker_store = __esm({
|
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
// dist/src/hooks/codex/session-start.js
|
|
56
|
-
import { spawn } from "node:child_process";
|
|
57
|
-
import { fileURLToPath } from "node:url";
|
|
58
|
-
import { dirname as
|
|
56
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
57
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
58
|
+
import { dirname as dirname6, join as join13 } from "node:path";
|
|
59
59
|
|
|
60
60
|
// dist/src/commands/auth.js
|
|
61
61
|
import { execSync } from "node:child_process";
|
|
@@ -104,32 +104,161 @@ function readStdin() {
|
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
// dist/src/skillify/local-manifest.js
|
|
108
|
+
import { existsSync, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
109
|
+
import { homedir as homedir2 } from "node:os";
|
|
110
|
+
import { dirname, join as join2 } from "node:path";
|
|
111
|
+
var LOCAL_MANIFEST_PATH = join2(homedir2(), ".claude", "hivemind", "local-mined.json");
|
|
112
|
+
var LOCAL_MINE_LOCK_PATH = join2(homedir2(), ".claude", "hivemind", "local-mined.lock");
|
|
113
|
+
function readLocalManifest(path = LOCAL_MANIFEST_PATH) {
|
|
114
|
+
if (!existsSync(path))
|
|
115
|
+
return null;
|
|
116
|
+
try {
|
|
117
|
+
return JSON.parse(readFileSync2(path, "utf-8"));
|
|
118
|
+
} catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function countLocalManifestEntries(path = LOCAL_MANIFEST_PATH) {
|
|
123
|
+
const m = readLocalManifest(path);
|
|
124
|
+
return Array.isArray(m?.entries) ? m.entries.length : 0;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// dist/src/skillify/spawn-mine-local-worker.js
|
|
128
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
129
|
+
import { closeSync, existsSync as existsSync2, mkdirSync as mkdirSync3, openSync, readdirSync, statSync, unlinkSync as unlinkSync2 } from "node:fs";
|
|
130
|
+
import { homedir as homedir3 } from "node:os";
|
|
131
|
+
import { dirname as dirname2, join as join3 } from "node:path";
|
|
132
|
+
import { fileURLToPath } from "node:url";
|
|
133
|
+
var HOME = homedir3();
|
|
134
|
+
var HIVEMIND_DIR = join3(HOME, ".claude", "hivemind");
|
|
135
|
+
var LOG_PATH = join3(HOME, ".claude", "hooks", "mine-local.log");
|
|
136
|
+
var CLAUDE_PROJECTS_DIR = join3(HOME, ".claude", "projects");
|
|
137
|
+
var LOCK_STALE_MS = 15 * 60 * 1e3;
|
|
138
|
+
function findBundledCliPath() {
|
|
139
|
+
try {
|
|
140
|
+
const thisDir = dirname2(fileURLToPath(import.meta.url));
|
|
141
|
+
const cliPath = join3(thisDir, "..", "..", "bundle", "cli.js");
|
|
142
|
+
return existsSync2(cliPath) ? cliPath : null;
|
|
143
|
+
} catch {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function findHivemindLauncher() {
|
|
148
|
+
const bundled = findBundledCliPath();
|
|
149
|
+
if (bundled)
|
|
150
|
+
return { kind: "node-script", path: bundled };
|
|
151
|
+
try {
|
|
152
|
+
const out = execFileSync("which", ["hivemind"], {
|
|
153
|
+
encoding: "utf-8",
|
|
154
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
155
|
+
});
|
|
156
|
+
const bin = out.trim();
|
|
157
|
+
return bin ? { kind: "bin", path: bin } : null;
|
|
158
|
+
} catch {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function hasLocalClaudeSessions() {
|
|
163
|
+
if (!existsSync2(CLAUDE_PROJECTS_DIR))
|
|
164
|
+
return false;
|
|
165
|
+
let subdirs;
|
|
166
|
+
try {
|
|
167
|
+
subdirs = readdirSync(CLAUDE_PROJECTS_DIR);
|
|
168
|
+
} catch {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
for (const sub of subdirs) {
|
|
172
|
+
let files;
|
|
173
|
+
try {
|
|
174
|
+
files = readdirSync(join3(CLAUDE_PROJECTS_DIR, sub));
|
|
175
|
+
} catch {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (files.some((f) => f.endsWith(".jsonl")))
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
function maybeAutoMineLocal() {
|
|
184
|
+
if (existsSync2(LOCAL_MANIFEST_PATH))
|
|
185
|
+
return { triggered: false, reason: "manifest-exists" };
|
|
186
|
+
if (existsSync2(LOCAL_MINE_LOCK_PATH)) {
|
|
187
|
+
let stale = false;
|
|
188
|
+
try {
|
|
189
|
+
const stats = statSync(LOCAL_MINE_LOCK_PATH);
|
|
190
|
+
stale = Date.now() - stats.mtimeMs > LOCK_STALE_MS;
|
|
191
|
+
} catch {
|
|
192
|
+
}
|
|
193
|
+
if (!stale)
|
|
194
|
+
return { triggered: false, reason: "lock-exists" };
|
|
195
|
+
try {
|
|
196
|
+
unlinkSync2(LOCAL_MINE_LOCK_PATH);
|
|
197
|
+
} catch {
|
|
198
|
+
return { triggered: false, reason: "lock-exists" };
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (!hasLocalClaudeSessions())
|
|
202
|
+
return { triggered: false, reason: "no-claude-sessions" };
|
|
203
|
+
const launcher = findHivemindLauncher();
|
|
204
|
+
if (!launcher)
|
|
205
|
+
return { triggered: false, reason: "no-hivemind-bin" };
|
|
206
|
+
try {
|
|
207
|
+
mkdirSync3(HIVEMIND_DIR, { recursive: true });
|
|
208
|
+
const fd = openSync(LOCAL_MINE_LOCK_PATH, "wx");
|
|
209
|
+
closeSync(fd);
|
|
210
|
+
} catch {
|
|
211
|
+
return { triggered: false, reason: "lock-acquire-failed" };
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
mkdirSync3(join3(HOME, ".claude", "hooks"), { recursive: true });
|
|
215
|
+
const out = openSync(LOG_PATH, "a");
|
|
216
|
+
const [cmd, args] = launcher.kind === "node-script" ? [process.execPath, [launcher.path, "skillify", "mine-local"]] : [launcher.path, ["skillify", "mine-local"]];
|
|
217
|
+
const child = spawn(cmd, args, {
|
|
218
|
+
detached: true,
|
|
219
|
+
stdio: ["ignore", out, out],
|
|
220
|
+
env: process.env
|
|
221
|
+
});
|
|
222
|
+
closeSync(out);
|
|
223
|
+
child.unref();
|
|
224
|
+
return { triggered: true };
|
|
225
|
+
} catch {
|
|
226
|
+
try {
|
|
227
|
+
unlinkSync2(LOCAL_MINE_LOCK_PATH);
|
|
228
|
+
} catch {
|
|
229
|
+
}
|
|
230
|
+
return { triggered: false, reason: "spawn-failed" };
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
107
234
|
// dist/src/utils/debug.js
|
|
108
235
|
import { appendFileSync } from "node:fs";
|
|
109
|
-
import { join as
|
|
110
|
-
import { homedir as
|
|
111
|
-
var
|
|
112
|
-
|
|
236
|
+
import { join as join4 } from "node:path";
|
|
237
|
+
import { homedir as homedir4 } from "node:os";
|
|
238
|
+
var LOG = join4(homedir4(), ".deeplake", "hook-debug.log");
|
|
239
|
+
function isDebug() {
|
|
240
|
+
return process.env.HIVEMIND_DEBUG === "1";
|
|
241
|
+
}
|
|
113
242
|
function log(tag, msg) {
|
|
114
|
-
if (!
|
|
243
|
+
if (!isDebug())
|
|
115
244
|
return;
|
|
116
245
|
appendFileSync(LOG, `${(/* @__PURE__ */ new Date()).toISOString()} [${tag}] ${msg}
|
|
117
246
|
`);
|
|
118
247
|
}
|
|
119
248
|
|
|
120
249
|
// dist/src/utils/version-check.js
|
|
121
|
-
import { readFileSync as
|
|
122
|
-
import { dirname, join as
|
|
250
|
+
import { readFileSync as readFileSync3 } from "node:fs";
|
|
251
|
+
import { dirname as dirname3, join as join5 } from "node:path";
|
|
123
252
|
function getInstalledVersion(bundleDir, pluginManifestDir) {
|
|
124
253
|
try {
|
|
125
|
-
const pluginJson =
|
|
126
|
-
const plugin = JSON.parse(
|
|
254
|
+
const pluginJson = join5(bundleDir, "..", pluginManifestDir, "plugin.json");
|
|
255
|
+
const plugin = JSON.parse(readFileSync3(pluginJson, "utf-8"));
|
|
127
256
|
if (plugin.version)
|
|
128
257
|
return plugin.version;
|
|
129
258
|
} catch {
|
|
130
259
|
}
|
|
131
260
|
try {
|
|
132
|
-
const stamp =
|
|
261
|
+
const stamp = readFileSync3(join5(bundleDir, "..", ".hivemind_version"), "utf-8").trim();
|
|
133
262
|
if (stamp)
|
|
134
263
|
return stamp;
|
|
135
264
|
} catch {
|
|
@@ -144,14 +273,14 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
|
|
|
144
273
|
]);
|
|
145
274
|
let dir = bundleDir;
|
|
146
275
|
for (let i = 0; i < 5; i++) {
|
|
147
|
-
const candidate =
|
|
276
|
+
const candidate = join5(dir, "package.json");
|
|
148
277
|
try {
|
|
149
|
-
const pkg = JSON.parse(
|
|
278
|
+
const pkg = JSON.parse(readFileSync3(candidate, "utf-8"));
|
|
150
279
|
if (HIVEMIND_PKG_NAMES.has(pkg.name) && pkg.version)
|
|
151
280
|
return pkg.version;
|
|
152
281
|
} catch {
|
|
153
282
|
}
|
|
154
|
-
const parent =
|
|
283
|
+
const parent = dirname3(dir);
|
|
155
284
|
if (parent === dir)
|
|
156
285
|
break;
|
|
157
286
|
dir = parent;
|
|
@@ -160,16 +289,16 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
|
|
|
160
289
|
}
|
|
161
290
|
|
|
162
291
|
// dist/src/config.js
|
|
163
|
-
import { readFileSync as
|
|
164
|
-
import { join as
|
|
165
|
-
import { homedir as
|
|
292
|
+
import { readFileSync as readFileSync4, existsSync as existsSync3 } from "node:fs";
|
|
293
|
+
import { join as join6 } from "node:path";
|
|
294
|
+
import { homedir as homedir5, userInfo } from "node:os";
|
|
166
295
|
function loadConfig() {
|
|
167
|
-
const home =
|
|
168
|
-
const credPath =
|
|
296
|
+
const home = homedir5();
|
|
297
|
+
const credPath = join6(home, ".deeplake", "credentials.json");
|
|
169
298
|
let creds = null;
|
|
170
|
-
if (
|
|
299
|
+
if (existsSync3(credPath)) {
|
|
171
300
|
try {
|
|
172
|
-
creds = JSON.parse(
|
|
301
|
+
creds = JSON.parse(readFileSync4(credPath, "utf-8"));
|
|
173
302
|
} catch {
|
|
174
303
|
return null;
|
|
175
304
|
}
|
|
@@ -188,7 +317,7 @@ function loadConfig() {
|
|
|
188
317
|
tableName: process.env.HIVEMIND_TABLE ?? "memory",
|
|
189
318
|
sessionsTableName: process.env.HIVEMIND_SESSIONS_TABLE ?? "sessions",
|
|
190
319
|
skillsTableName: process.env.HIVEMIND_SKILLS_TABLE ?? "skills",
|
|
191
|
-
memoryPath: process.env.HIVEMIND_MEMORY_PATH ??
|
|
320
|
+
memoryPath: process.env.HIVEMIND_MEMORY_PATH ?? join6(home, ".deeplake", "memory")
|
|
192
321
|
};
|
|
193
322
|
}
|
|
194
323
|
|
|
@@ -235,7 +364,9 @@ var RETRYABLE_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
|
235
364
|
var MAX_RETRIES = 3;
|
|
236
365
|
var BASE_DELAY_MS = 500;
|
|
237
366
|
var MAX_CONCURRENCY = 5;
|
|
238
|
-
|
|
367
|
+
function getQueryTimeoutMs() {
|
|
368
|
+
return Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
|
|
369
|
+
}
|
|
239
370
|
function sleep(ms) {
|
|
240
371
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
241
372
|
}
|
|
@@ -316,8 +447,9 @@ var DeeplakeApi = class {
|
|
|
316
447
|
let lastError;
|
|
317
448
|
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
318
449
|
let resp;
|
|
450
|
+
const timeoutMs = getQueryTimeoutMs();
|
|
319
451
|
try {
|
|
320
|
-
const signal = AbortSignal.timeout(
|
|
452
|
+
const signal = AbortSignal.timeout(timeoutMs);
|
|
321
453
|
resp = await fetch(`${this.apiUrl}/workspaces/${this.workspaceId}/tables/query`, {
|
|
322
454
|
method: "POST",
|
|
323
455
|
headers: {
|
|
@@ -331,7 +463,7 @@ var DeeplakeApi = class {
|
|
|
331
463
|
});
|
|
332
464
|
} catch (e) {
|
|
333
465
|
if (isTimeoutError(e)) {
|
|
334
|
-
lastError = new Error(`Query timeout after ${
|
|
466
|
+
lastError = new Error(`Query timeout after ${timeoutMs}ms`);
|
|
335
467
|
throw lastError;
|
|
336
468
|
}
|
|
337
469
|
lastError = e instanceof Error ? e : new Error(String(e));
|
|
@@ -622,14 +754,14 @@ var DeeplakeApi = class {
|
|
|
622
754
|
};
|
|
623
755
|
|
|
624
756
|
// dist/src/skillify/pull.js
|
|
625
|
-
import { existsSync as
|
|
626
|
-
import { homedir as
|
|
627
|
-
import { dirname as
|
|
757
|
+
import { existsSync as existsSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, renameSync as renameSync3, lstatSync as lstatSync2, readlinkSync, symlinkSync, unlinkSync as unlinkSync4 } from "node:fs";
|
|
758
|
+
import { homedir as homedir10 } from "node:os";
|
|
759
|
+
import { dirname as dirname5, join as join12 } from "node:path";
|
|
628
760
|
|
|
629
761
|
// dist/src/skillify/skill-writer.js
|
|
630
|
-
import { existsSync as
|
|
631
|
-
import { homedir as
|
|
632
|
-
import { join as
|
|
762
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync6, readdirSync as readdirSync2, statSync as statSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
763
|
+
import { homedir as homedir6 } from "node:os";
|
|
764
|
+
import { join as join8 } from "node:path";
|
|
633
765
|
function assertValidSkillName(name) {
|
|
634
766
|
if (typeof name !== "string" || name.length === 0) {
|
|
635
767
|
throw new Error(`invalid skill name: empty or non-string`);
|
|
@@ -695,26 +827,26 @@ function parseFrontmatter(text) {
|
|
|
695
827
|
}
|
|
696
828
|
|
|
697
829
|
// dist/src/skillify/manifest.js
|
|
698
|
-
import { existsSync as
|
|
699
|
-
import { homedir as
|
|
700
|
-
import { dirname as
|
|
830
|
+
import { existsSync as existsSync7, lstatSync, mkdirSync as mkdirSync6, readFileSync as readFileSync7, renameSync as renameSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync5 } from "node:fs";
|
|
831
|
+
import { homedir as homedir8 } from "node:os";
|
|
832
|
+
import { dirname as dirname4, join as join10 } from "node:path";
|
|
701
833
|
|
|
702
834
|
// dist/src/skillify/legacy-migration.js
|
|
703
|
-
import { existsSync as
|
|
704
|
-
import { homedir as
|
|
705
|
-
import { join as
|
|
835
|
+
import { existsSync as existsSync6, renameSync } from "node:fs";
|
|
836
|
+
import { homedir as homedir7 } from "node:os";
|
|
837
|
+
import { join as join9 } from "node:path";
|
|
706
838
|
var dlog = (msg) => log("skillify-migrate", msg);
|
|
707
839
|
var attempted = false;
|
|
708
840
|
function migrateLegacyStateDir() {
|
|
709
841
|
if (attempted)
|
|
710
842
|
return;
|
|
711
843
|
attempted = true;
|
|
712
|
-
const root =
|
|
713
|
-
const legacy =
|
|
714
|
-
const current =
|
|
715
|
-
if (!
|
|
844
|
+
const root = join9(homedir7(), ".deeplake", "state");
|
|
845
|
+
const legacy = join9(root, "skilify");
|
|
846
|
+
const current = join9(root, "skillify");
|
|
847
|
+
if (!existsSync6(legacy))
|
|
716
848
|
return;
|
|
717
|
-
if (
|
|
849
|
+
if (existsSync6(current))
|
|
718
850
|
return;
|
|
719
851
|
try {
|
|
720
852
|
renameSync(legacy, current);
|
|
@@ -734,15 +866,15 @@ function emptyManifest() {
|
|
|
734
866
|
return { version: 1, entries: [] };
|
|
735
867
|
}
|
|
736
868
|
function manifestPath() {
|
|
737
|
-
return
|
|
869
|
+
return join10(homedir8(), ".deeplake", "state", "skillify", "pulled.json");
|
|
738
870
|
}
|
|
739
871
|
function loadManifest(path = manifestPath()) {
|
|
740
872
|
migrateLegacyStateDir();
|
|
741
|
-
if (!
|
|
873
|
+
if (!existsSync7(path))
|
|
742
874
|
return emptyManifest();
|
|
743
875
|
let raw;
|
|
744
876
|
try {
|
|
745
|
-
raw =
|
|
877
|
+
raw = readFileSync7(path, "utf-8");
|
|
746
878
|
} catch {
|
|
747
879
|
return emptyManifest();
|
|
748
880
|
}
|
|
@@ -789,9 +921,9 @@ function loadManifest(path = manifestPath()) {
|
|
|
789
921
|
}
|
|
790
922
|
function saveManifest(m, path = manifestPath()) {
|
|
791
923
|
migrateLegacyStateDir();
|
|
792
|
-
|
|
924
|
+
mkdirSync6(dirname4(path), { recursive: true });
|
|
793
925
|
const tmp = `${path}.tmp`;
|
|
794
|
-
|
|
926
|
+
writeFileSync5(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
|
|
795
927
|
renameSync2(tmp, path);
|
|
796
928
|
}
|
|
797
929
|
function recordPull(entry, path = manifestPath()) {
|
|
@@ -817,7 +949,7 @@ function unlinkSymlinks(paths) {
|
|
|
817
949
|
if (!st.isSymbolicLink())
|
|
818
950
|
continue;
|
|
819
951
|
try {
|
|
820
|
-
|
|
952
|
+
unlinkSync3(path);
|
|
821
953
|
} catch {
|
|
822
954
|
}
|
|
823
955
|
}
|
|
@@ -827,7 +959,7 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
827
959
|
const live = [];
|
|
828
960
|
let pruned = 0;
|
|
829
961
|
for (const e of m.entries) {
|
|
830
|
-
if (
|
|
962
|
+
if (existsSync7(join10(e.installRoot, e.dirName))) {
|
|
831
963
|
live.push(e);
|
|
832
964
|
continue;
|
|
833
965
|
}
|
|
@@ -840,26 +972,26 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
840
972
|
}
|
|
841
973
|
|
|
842
974
|
// dist/src/skillify/agent-roots.js
|
|
843
|
-
import { existsSync as
|
|
844
|
-
import { homedir as
|
|
845
|
-
import { join as
|
|
975
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
976
|
+
import { homedir as homedir9 } from "node:os";
|
|
977
|
+
import { join as join11 } from "node:path";
|
|
846
978
|
function resolveDetected(home) {
|
|
847
979
|
const out = [];
|
|
848
|
-
const codexInstalled =
|
|
849
|
-
const piInstalled =
|
|
850
|
-
const hermesInstalled =
|
|
980
|
+
const codexInstalled = existsSync8(join11(home, ".codex"));
|
|
981
|
+
const piInstalled = existsSync8(join11(home, ".pi", "agent"));
|
|
982
|
+
const hermesInstalled = existsSync8(join11(home, ".hermes"));
|
|
851
983
|
if (codexInstalled || piInstalled) {
|
|
852
|
-
out.push(
|
|
984
|
+
out.push(join11(home, ".agents", "skills"));
|
|
853
985
|
}
|
|
854
986
|
if (hermesInstalled) {
|
|
855
|
-
out.push(
|
|
987
|
+
out.push(join11(home, ".hermes", "skills"));
|
|
856
988
|
}
|
|
857
989
|
if (piInstalled) {
|
|
858
|
-
out.push(
|
|
990
|
+
out.push(join11(home, ".pi", "agent", "skills"));
|
|
859
991
|
}
|
|
860
992
|
return out;
|
|
861
993
|
}
|
|
862
|
-
function detectAgentSkillsRoots(canonicalRoot, home =
|
|
994
|
+
function detectAgentSkillsRoots(canonicalRoot, home = homedir9()) {
|
|
863
995
|
return resolveDetected(home).filter((p) => p !== canonicalRoot);
|
|
864
996
|
}
|
|
865
997
|
|
|
@@ -903,15 +1035,15 @@ function isMissingTableError(message) {
|
|
|
903
1035
|
}
|
|
904
1036
|
function resolvePullDestination(install, cwd) {
|
|
905
1037
|
if (install === "global")
|
|
906
|
-
return
|
|
1038
|
+
return join12(homedir10(), ".claude", "skills");
|
|
907
1039
|
if (!cwd)
|
|
908
1040
|
throw new Error("install=project requires a cwd");
|
|
909
|
-
return
|
|
1041
|
+
return join12(cwd, ".claude", "skills");
|
|
910
1042
|
}
|
|
911
1043
|
function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
|
|
912
1044
|
const out = [];
|
|
913
1045
|
for (const root of agentRoots) {
|
|
914
|
-
const link =
|
|
1046
|
+
const link = join12(root, dirName);
|
|
915
1047
|
let existing;
|
|
916
1048
|
try {
|
|
917
1049
|
existing = lstatSync2(link);
|
|
@@ -933,13 +1065,13 @@ function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
|
|
|
933
1065
|
continue;
|
|
934
1066
|
}
|
|
935
1067
|
try {
|
|
936
|
-
|
|
1068
|
+
unlinkSync4(link);
|
|
937
1069
|
} catch {
|
|
938
1070
|
continue;
|
|
939
1071
|
}
|
|
940
1072
|
}
|
|
941
1073
|
try {
|
|
942
|
-
|
|
1074
|
+
mkdirSync7(dirname5(link), { recursive: true });
|
|
943
1075
|
symlinkSync(canonicalDir, link, "dir");
|
|
944
1076
|
out.push(link);
|
|
945
1077
|
} catch {
|
|
@@ -954,8 +1086,8 @@ function backfillSymlinks(installRoot) {
|
|
|
954
1086
|
return;
|
|
955
1087
|
const detected = detectAgentSkillsRoots(installRoot);
|
|
956
1088
|
for (const entry of entries) {
|
|
957
|
-
const canonical =
|
|
958
|
-
if (!
|
|
1089
|
+
const canonical = join12(entry.installRoot, entry.dirName);
|
|
1090
|
+
if (!existsSync9(canonical))
|
|
959
1091
|
continue;
|
|
960
1092
|
const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
|
|
961
1093
|
if (sameSorted(fresh, entry.symlinks))
|
|
@@ -1065,10 +1197,10 @@ function renderFrontmatter(fm) {
|
|
|
1065
1197
|
return lines.join("\n");
|
|
1066
1198
|
}
|
|
1067
1199
|
function readLocalVersion(path) {
|
|
1068
|
-
if (!
|
|
1200
|
+
if (!existsSync9(path))
|
|
1069
1201
|
return null;
|
|
1070
1202
|
try {
|
|
1071
|
-
const text =
|
|
1203
|
+
const text = readFileSync8(path, "utf-8");
|
|
1072
1204
|
const parsed = parseFrontmatter(text);
|
|
1073
1205
|
if (!parsed)
|
|
1074
1206
|
return null;
|
|
@@ -1163,8 +1295,8 @@ async function runPull(opts) {
|
|
|
1163
1295
|
summary.skipped++;
|
|
1164
1296
|
continue;
|
|
1165
1297
|
}
|
|
1166
|
-
const skillDir =
|
|
1167
|
-
const skillFile =
|
|
1298
|
+
const skillDir = join12(root, dirName);
|
|
1299
|
+
const skillFile = join12(skillDir, "SKILL.md");
|
|
1168
1300
|
const remoteVersion = Number(row.version ?? 1);
|
|
1169
1301
|
const localVersion = readLocalVersion(skillFile);
|
|
1170
1302
|
const action = decideAction({
|
|
@@ -1175,14 +1307,14 @@ async function runPull(opts) {
|
|
|
1175
1307
|
});
|
|
1176
1308
|
let manifestError;
|
|
1177
1309
|
if (action === "wrote") {
|
|
1178
|
-
|
|
1179
|
-
if (
|
|
1310
|
+
mkdirSync7(skillDir, { recursive: true });
|
|
1311
|
+
if (existsSync9(skillFile)) {
|
|
1180
1312
|
try {
|
|
1181
1313
|
renameSync3(skillFile, `${skillFile}.bak`);
|
|
1182
1314
|
} catch {
|
|
1183
1315
|
}
|
|
1184
1316
|
}
|
|
1185
|
-
|
|
1317
|
+
writeFileSync6(skillFile, renderSkillFile(row));
|
|
1186
1318
|
const symlinks = opts.install === "global" ? fanOutSymlinks(skillDir, dirName, detectAgentSkillsRoots(root)) : [];
|
|
1187
1319
|
try {
|
|
1188
1320
|
recordPull({
|
|
@@ -1278,53 +1410,7 @@ async function autoPullSkills(deps = {}) {
|
|
|
1278
1410
|
|
|
1279
1411
|
// dist/src/hooks/codex/session-start.js
|
|
1280
1412
|
var log4 = (msg) => log("codex-session-start", msg);
|
|
1281
|
-
var __bundleDir =
|
|
1282
|
-
var context = `DEEPLAKE MEMORY: Persistent memory at ~/.deeplake/memory/ shared across sessions, users, and agents.
|
|
1283
|
-
|
|
1284
|
-
Deeplake memory has THREE tiers \u2014 pick the right one for the question:
|
|
1285
|
-
1. ~/.deeplake/memory/index.md \u2014 auto-generated index, top 50 most-recently-updated entries with Created + Last Updated + Project + Description columns. ~5 KB. **For "what's recent / who did X this week / since <date>" queries, START HERE** and trust the Last Updated column over any "Started:" line in summary bodies.
|
|
1286
|
-
2. ~/.deeplake/memory/summaries/ \u2014 condensed wiki summaries per session (~3 KB each). For keyword/topic recall, search these.
|
|
1287
|
-
3. ~/.deeplake/memory/sessions/ \u2014 raw full-dialogue JSONL (~5 KB each). FALLBACK only \u2014 use when summaries don't contain the exact quote/turn you need.
|
|
1288
|
-
|
|
1289
|
-
Search workflow:
|
|
1290
|
-
- Time-based ("last week", "today", "since X"): cat ~/.deeplake/memory/index.md and read the most-recent rows.
|
|
1291
|
-
- Keyword/topic recall: grep -r "keyword" ~/.deeplake/memory/summaries/ (the shell hook routes this through hybrid lexical+semantic search \u2014 synonyms match too). Then cat the top-matching summary.
|
|
1292
|
-
- Raw transcript fallback only: grep -r "keyword" ~/.deeplake/memory/sessions/ (use sparingly \u2014 JSONL is verbose).
|
|
1293
|
-
|
|
1294
|
-
\u2705 grep -r "keyword" ~/.deeplake/memory/summaries/
|
|
1295
|
-
\u274C grep without a summaries/ or sessions/ suffix \u2014 too noisy
|
|
1296
|
-
|
|
1297
|
-
IMPORTANT: Only use bash builtins (cat, ls, grep, echo, jq, head, tail, sed, awk, etc.) on ~/.deeplake/memory/. Do NOT use python, python3, node, curl, or other interpreters \u2014 they are not available in the memory filesystem.
|
|
1298
|
-
Do NOT spawn subagents to read deeplake memory.
|
|
1299
|
-
|
|
1300
|
-
Organization management \u2014 each argument is SEPARATE (do NOT quote subcommands together):
|
|
1301
|
-
- hivemind login \u2014 SSO login
|
|
1302
|
-
- hivemind whoami \u2014 show current user/org
|
|
1303
|
-
- hivemind org list \u2014 list organizations
|
|
1304
|
-
- hivemind org switch <name-or-id> \u2014 switch organization
|
|
1305
|
-
- hivemind workspaces \u2014 list workspaces
|
|
1306
|
-
- hivemind workspace <id> \u2014 switch workspace
|
|
1307
|
-
- hivemind invite <email> <ADMIN|WRITE|READ> \u2014 invite member (ALWAYS ask user which role before inviting)
|
|
1308
|
-
- hivemind members \u2014 list members
|
|
1309
|
-
- hivemind remove <user-id> \u2014 remove member
|
|
1310
|
-
|
|
1311
|
-
SKILLS (skillify) \u2014 mine + share reusable skills across the org:
|
|
1312
|
-
- hivemind skillify \u2014 show scope/team/install + per-project state
|
|
1313
|
-
- hivemind skillify pull \u2014 sync project skills from the org table
|
|
1314
|
-
- hivemind skillify pull --user <email> \u2014 only that author's skills
|
|
1315
|
-
- hivemind skillify pull --users a,b,c \u2014 multiple authors (CSV)
|
|
1316
|
-
- hivemind skillify pull --all-users \u2014 explicit "no author filter"
|
|
1317
|
-
- hivemind skillify pull --to project|global \u2014 install location
|
|
1318
|
-
- hivemind skillify pull --dry-run \u2014 preview only
|
|
1319
|
-
- hivemind skillify pull --force \u2014 overwrite local (creates .bak)
|
|
1320
|
-
- hivemind skillify pull <skill-name> \u2014 pull only that skill (combines with --user)
|
|
1321
|
-
- hivemind skillify unpull \u2014 remove every skill previously installed by pull
|
|
1322
|
-
- hivemind skillify unpull --user <email> \u2014 remove only that author's pulls
|
|
1323
|
-
- hivemind skillify unpull --not-mine \u2014 remove all pulls except your own
|
|
1324
|
-
- hivemind skillify unpull --dry-run \u2014 preview without touching disk
|
|
1325
|
-
- hivemind skillify scope <me|team> \u2014 sharing scope for new skills
|
|
1326
|
-
- hivemind skillify install <project|global> \u2014 default install location
|
|
1327
|
-
- hivemind skillify team add|remove|list <name> \u2014 manage team list`;
|
|
1413
|
+
var __bundleDir = dirname6(fileURLToPath2(import.meta.url));
|
|
1328
1414
|
async function main() {
|
|
1329
1415
|
if (process.env.HIVEMIND_WIKI_WORKER === "1")
|
|
1330
1416
|
return;
|
|
@@ -1332,12 +1418,14 @@ async function main() {
|
|
|
1332
1418
|
const creds = loadCredentials();
|
|
1333
1419
|
if (!creds?.token) {
|
|
1334
1420
|
log4("no credentials found \u2014 run auth login to authenticate");
|
|
1421
|
+
const auto = maybeAutoMineLocal();
|
|
1422
|
+
log4(`auto-mine: ${auto.triggered ? "triggered (background)" : `skipped (${auto.reason})`}`);
|
|
1335
1423
|
} else {
|
|
1336
1424
|
log4(`credentials loaded: org=${creds.orgName ?? creds.orgId}`);
|
|
1337
1425
|
}
|
|
1338
1426
|
if (creds?.token) {
|
|
1339
|
-
const setupScript =
|
|
1340
|
-
const child =
|
|
1427
|
+
const setupScript = join13(__bundleDir, "session-start-setup.js");
|
|
1428
|
+
const child = spawn2("node", [setupScript], {
|
|
1341
1429
|
detached: true,
|
|
1342
1430
|
stdio: ["pipe", "ignore", "ignore"],
|
|
1343
1431
|
env: { ...process.env }
|
|
@@ -1355,10 +1443,19 @@ async function main() {
|
|
|
1355
1443
|
versionNotice = `
|
|
1356
1444
|
Hivemind v${current}`;
|
|
1357
1445
|
}
|
|
1358
|
-
const
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1446
|
+
const localMined = countLocalManifestEntries();
|
|
1447
|
+
const skillNoun = localMined === 1 ? "skill" : "skills";
|
|
1448
|
+
const additionalContext = creds?.token ? `Hivemind: logged in as org ${creds.orgName ?? creds.orgId} (workspace: ${creds.workspaceId ?? "default"}).${versionNotice}` : `Hivemind: not logged in. Run \`hivemind login\` to enable shared memory + skill sharing.${versionNotice}`;
|
|
1449
|
+
const systemMessage = !creds?.token && localMined > 0 ? `\u{1F4A1} ${localMined} ${skillNoun} mined from your local sessions live in ~/.claude/skills/. Run 'hivemind login' to share them with your team.` : void 0;
|
|
1450
|
+
const output = {
|
|
1451
|
+
hookSpecificOutput: {
|
|
1452
|
+
hookEventName: "SessionStart",
|
|
1453
|
+
additionalContext
|
|
1454
|
+
}
|
|
1455
|
+
};
|
|
1456
|
+
if (systemMessage)
|
|
1457
|
+
output.systemMessage = systemMessage;
|
|
1458
|
+
console.log(JSON.stringify(output));
|
|
1362
1459
|
}
|
|
1363
1460
|
main().catch((e) => {
|
|
1364
1461
|
log4(`fatal: ${e.message}`);
|
|
@@ -66803,10 +66803,12 @@ import { randomUUID } from "node:crypto";
|
|
|
66803
66803
|
import { appendFileSync } from "node:fs";
|
|
66804
66804
|
import { join as join5 } from "node:path";
|
|
66805
66805
|
import { homedir as homedir2 } from "node:os";
|
|
66806
|
-
var DEBUG = process.env.HIVEMIND_DEBUG === "1";
|
|
66807
66806
|
var LOG = join5(homedir2(), ".deeplake", "hook-debug.log");
|
|
66807
|
+
function isDebug() {
|
|
66808
|
+
return process.env.HIVEMIND_DEBUG === "1";
|
|
66809
|
+
}
|
|
66808
66810
|
function log(tag, msg) {
|
|
66809
|
-
if (!
|
|
66811
|
+
if (!isDebug())
|
|
66810
66812
|
return;
|
|
66811
66813
|
appendFileSync(LOG, `${(/* @__PURE__ */ new Date()).toISOString()} [${tag}] ${msg}
|
|
66812
66814
|
`);
|
|
@@ -66864,7 +66866,9 @@ var RETRYABLE_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
|
66864
66866
|
var MAX_RETRIES = 3;
|
|
66865
66867
|
var BASE_DELAY_MS = 500;
|
|
66866
66868
|
var MAX_CONCURRENCY = 5;
|
|
66867
|
-
|
|
66869
|
+
function getQueryTimeoutMs() {
|
|
66870
|
+
return Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
|
|
66871
|
+
}
|
|
66868
66872
|
function sleep(ms3) {
|
|
66869
66873
|
return new Promise((resolve5) => setTimeout(resolve5, ms3));
|
|
66870
66874
|
}
|
|
@@ -66945,8 +66949,9 @@ var DeeplakeApi = class {
|
|
|
66945
66949
|
let lastError;
|
|
66946
66950
|
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
66947
66951
|
let resp;
|
|
66952
|
+
const timeoutMs = getQueryTimeoutMs();
|
|
66948
66953
|
try {
|
|
66949
|
-
const signal = AbortSignal.timeout(
|
|
66954
|
+
const signal = AbortSignal.timeout(timeoutMs);
|
|
66950
66955
|
resp = await fetch(`${this.apiUrl}/workspaces/${this.workspaceId}/tables/query`, {
|
|
66951
66956
|
method: "POST",
|
|
66952
66957
|
headers: {
|
|
@@ -66960,7 +66965,7 @@ var DeeplakeApi = class {
|
|
|
66960
66965
|
});
|
|
66961
66966
|
} catch (e6) {
|
|
66962
66967
|
if (isTimeoutError(e6)) {
|
|
66963
|
-
lastError = new Error(`Query timeout after ${
|
|
66968
|
+
lastError = new Error(`Query timeout after ${timeoutMs}ms`);
|
|
66964
66969
|
throw lastError;
|
|
66965
66970
|
}
|
|
66966
66971
|
lastError = e6 instanceof Error ? e6 : new Error(String(e6));
|