@deeplake/hivemind 0.7.51 → 0.7.52
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.
|
@@ -6,18 +6,18 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Cloud-backed persistent shared memory for AI agents powered by Deeplake",
|
|
9
|
-
"version": "0.7.
|
|
9
|
+
"version": "0.7.52"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "hivemind",
|
|
14
14
|
"description": "Persistent shared memory powered by Deeplake — captures all session activity and provides cross-session, cross-agent memory search",
|
|
15
|
-
"version": "0.7.
|
|
15
|
+
"version": "0.7.52",
|
|
16
16
|
"source": {
|
|
17
17
|
"source": "git-subdir",
|
|
18
18
|
"url": "https://github.com/activeloopai/hivemind.git",
|
|
19
19
|
"path": "claude-code",
|
|
20
|
-
"sha": "
|
|
20
|
+
"sha": "f8a757482c192ad29790eb63a1be9d07c5633f18"
|
|
21
21
|
},
|
|
22
22
|
"homepage": "https://github.com/activeloopai/hivemind"
|
|
23
23
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hivemind",
|
|
3
3
|
"description": "Cloud-backed persistent memory powered by Deeplake — read, write, and share memory across Claude Code sessions and agents",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.52",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Activeloop",
|
|
7
7
|
"url": "https://deeplake.ai"
|
package/bundle/cli.js
CHANGED
|
@@ -9665,7 +9665,45 @@ function writeLocalManifest(m, path = LOCAL_MANIFEST_PATH) {
|
|
|
9665
9665
|
mkdirSync21(dirname15(path), { recursive: true });
|
|
9666
9666
|
writeFileSync24(path, JSON.stringify(m, null, 2));
|
|
9667
9667
|
}
|
|
9668
|
+
function countLocalManifestEntries(path = LOCAL_MANIFEST_PATH) {
|
|
9669
|
+
const m = readLocalManifest(path);
|
|
9670
|
+
return Array.isArray(m?.entries) ? m.entries.length : 0;
|
|
9671
|
+
}
|
|
9668
9672
|
var LATEST_RUN_WINDOW_MS = 5 * 60 * 1e3;
|
|
9673
|
+
function getLatestInsightEntry(path = LOCAL_MANIFEST_PATH) {
|
|
9674
|
+
const m = readLocalManifest(path);
|
|
9675
|
+
if (!m || !Array.isArray(m.entries))
|
|
9676
|
+
return null;
|
|
9677
|
+
let newestTs = Number.NEGATIVE_INFINITY;
|
|
9678
|
+
for (const e of m.entries) {
|
|
9679
|
+
if (!e)
|
|
9680
|
+
continue;
|
|
9681
|
+
const ts = Date.parse(e.created_at ?? "");
|
|
9682
|
+
if (Number.isFinite(ts) && ts > newestTs)
|
|
9683
|
+
newestTs = ts;
|
|
9684
|
+
}
|
|
9685
|
+
if (!Number.isFinite(newestTs))
|
|
9686
|
+
return null;
|
|
9687
|
+
let best = null;
|
|
9688
|
+
let bestTs = Number.NEGATIVE_INFINITY;
|
|
9689
|
+
let bestIsPrimary = false;
|
|
9690
|
+
for (const e of m.entries) {
|
|
9691
|
+
if (!e || typeof e.insight !== "string" || e.insight.trim().length === 0)
|
|
9692
|
+
continue;
|
|
9693
|
+
const ts = Date.parse(e.created_at ?? "");
|
|
9694
|
+
if (!Number.isFinite(ts))
|
|
9695
|
+
continue;
|
|
9696
|
+
if (newestTs - ts > LATEST_RUN_WINDOW_MS)
|
|
9697
|
+
continue;
|
|
9698
|
+
const isPrimary = e.primary === true;
|
|
9699
|
+
if (!best || isPrimary && !bestIsPrimary || isPrimary === bestIsPrimary && ts > bestTs) {
|
|
9700
|
+
best = e;
|
|
9701
|
+
bestTs = ts;
|
|
9702
|
+
bestIsPrimary = isPrimary;
|
|
9703
|
+
}
|
|
9704
|
+
}
|
|
9705
|
+
return best;
|
|
9706
|
+
}
|
|
9669
9707
|
|
|
9670
9708
|
// dist/src/commands/mine-local.js
|
|
9671
9709
|
import { unlinkSync as unlinkSync12 } from "node:fs";
|
|
@@ -10012,18 +10050,24 @@ async function runMineLocalImpl(args) {
|
|
|
10012
10050
|
const force = takeBoolFlag(work, "--force");
|
|
10013
10051
|
const dryRun = takeBoolFlag(work, "--dry-run");
|
|
10014
10052
|
const nRaw = takeFlagValue(work, "--n");
|
|
10053
|
+
const onlyAgent = takeFlagValue(work, "--only");
|
|
10015
10054
|
if (loadManifest2() && !force) {
|
|
10016
10055
|
console.error(`Local skills have already been mined on this machine.`);
|
|
10017
10056
|
console.error(`Manifest: ${MANIFEST_PATH}`);
|
|
10018
10057
|
console.error(`Pass --force to re-mine.`);
|
|
10019
10058
|
process.exit(1);
|
|
10020
10059
|
}
|
|
10021
|
-
const
|
|
10022
|
-
if (
|
|
10060
|
+
const installsAll = detectInstalledAgents();
|
|
10061
|
+
if (installsAll.length === 0) {
|
|
10023
10062
|
console.error(`No agent session directories detected. Run a session first.`);
|
|
10024
10063
|
process.exit(1);
|
|
10025
10064
|
}
|
|
10026
|
-
|
|
10065
|
+
const installs = onlyAgent ? installsAll.filter((i) => i.agent === onlyAgent) : installsAll;
|
|
10066
|
+
if (installs.length === 0) {
|
|
10067
|
+
console.error(`No '${onlyAgent}' session directory detected. Skipping mine-local.`);
|
|
10068
|
+
process.exit(1);
|
|
10069
|
+
}
|
|
10070
|
+
console.log(`Detected installed agents: ${installs.map((i) => i.agent).join(", ")}${onlyAgent ? ` (filtered to ${onlyAgent})` : ""}`);
|
|
10027
10071
|
const host = detectHostAgent();
|
|
10028
10072
|
const fallback = installs[0].agent;
|
|
10029
10073
|
const gateAgent = gateAgentFor(host, fallback, installs);
|
|
@@ -11461,7 +11505,7 @@ async function runUpdate(opts = {}) {
|
|
|
11461
11505
|
}
|
|
11462
11506
|
log(`Update available: ${current} \u2192 ${latest}`);
|
|
11463
11507
|
const detected = opts.installKindOverride ?? detectInstallKind();
|
|
11464
|
-
const
|
|
11508
|
+
const spawn5 = opts.spawn ?? defaultSpawn;
|
|
11465
11509
|
switch (detected.kind) {
|
|
11466
11510
|
case "npm-global": {
|
|
11467
11511
|
if (opts.dryRun) {
|
|
@@ -11476,7 +11520,7 @@ async function runUpdate(opts = {}) {
|
|
|
11476
11520
|
try {
|
|
11477
11521
|
log(`Upgrading via npm\u2026`);
|
|
11478
11522
|
try {
|
|
11479
|
-
|
|
11523
|
+
spawn5("npm", ["install", "-g", `${PKG_NAME}@latest`]);
|
|
11480
11524
|
} catch (e) {
|
|
11481
11525
|
warn(`npm install failed: ${e.message}`);
|
|
11482
11526
|
warn(`Try running it manually: npm install -g ${PKG_NAME}@latest`);
|
|
@@ -11485,7 +11529,7 @@ async function runUpdate(opts = {}) {
|
|
|
11485
11529
|
log(``);
|
|
11486
11530
|
log(`Refreshing agent bundles\u2026`);
|
|
11487
11531
|
try {
|
|
11488
|
-
|
|
11532
|
+
spawn5("hivemind", ["install", "--skip-auth"]);
|
|
11489
11533
|
} catch (e) {
|
|
11490
11534
|
warn(`Agent refresh failed: ${e.message}`);
|
|
11491
11535
|
warn(`Run manually: hivemind install`);
|
|
@@ -11536,6 +11580,325 @@ async function runUpdate(opts = {}) {
|
|
|
11536
11580
|
}
|
|
11537
11581
|
}
|
|
11538
11582
|
|
|
11583
|
+
// dist/src/cli/install-scan.js
|
|
11584
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
11585
|
+
import { existsSync as existsSync39, readFileSync as readFileSync35, readdirSync as readdirSync9, unlinkSync as unlinkSync14 } from "node:fs";
|
|
11586
|
+
import { homedir as homedir26 } from "node:os";
|
|
11587
|
+
import { join as join49 } from "node:path";
|
|
11588
|
+
|
|
11589
|
+
// dist/src/skillify/advisor.js
|
|
11590
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
11591
|
+
import { existsSync as existsSync38 } from "node:fs";
|
|
11592
|
+
var ADVISOR_TIMEOUT_MS = 6e4;
|
|
11593
|
+
var MAX_CANDIDATES = 20;
|
|
11594
|
+
function buildAdvisorPrompt(candidates) {
|
|
11595
|
+
const lines = [
|
|
11596
|
+
"You are reviewing skill candidates extracted from a user's coding sessions.",
|
|
11597
|
+
"Pick the ONE candidate whose `insight` field is most useful to show the user as a",
|
|
11598
|
+
"concrete finding from their past work. Reply on EXACTLY ONE LINE.",
|
|
11599
|
+
"",
|
|
11600
|
+
"GOOD insights are:",
|
|
11601
|
+
" - Concrete and counted (cite specific numbers, file names, durations)",
|
|
11602
|
+
' - About a real coding mistake or pattern the USER made (in 2nd person \u2014 "You did X")',
|
|
11603
|
+
" - Actionable: the user can change behavior based on knowing this",
|
|
11604
|
+
"",
|
|
11605
|
+
"BAD insights (REJECT these) are:",
|
|
11606
|
+
' - Meta-commentary about why the skill was saved ("User explicitly requested...")',
|
|
11607
|
+
" - Vague / generic engineering platitudes the user already knows",
|
|
11608
|
+
" - About someone other than the user (a teammate, a third party)",
|
|
11609
|
+
' - Hypothetical ("could lead to...", "might cause...") rather than observed',
|
|
11610
|
+
"",
|
|
11611
|
+
"Output format \u2014 STRICT, one line only:",
|
|
11612
|
+
" PICK: <number 1-N>",
|
|
11613
|
+
"OR",
|
|
11614
|
+
" REJECT_ALL: <short reason why every candidate failed>",
|
|
11615
|
+
"",
|
|
11616
|
+
"Candidates:"
|
|
11617
|
+
];
|
|
11618
|
+
for (const [i, c] of candidates.entries()) {
|
|
11619
|
+
lines.push(`${i + 1}. name=${c.skill_name} insight=${JSON.stringify((c.insight ?? "").slice(0, 400))}`);
|
|
11620
|
+
}
|
|
11621
|
+
return lines.join("\n");
|
|
11622
|
+
}
|
|
11623
|
+
function parseAdvisorOutput(raw, candidates) {
|
|
11624
|
+
const cleaned = raw.trim();
|
|
11625
|
+
const pickMatch = cleaned.match(/PICK:\s*(\d+)/i);
|
|
11626
|
+
if (pickMatch) {
|
|
11627
|
+
const idx = parseInt(pickMatch[1], 10) - 1;
|
|
11628
|
+
if (idx >= 0 && idx < candidates.length) {
|
|
11629
|
+
return {
|
|
11630
|
+
pickedSkillName: candidates[idx].skill_name,
|
|
11631
|
+
reason: cleaned,
|
|
11632
|
+
rawOutput: raw
|
|
11633
|
+
};
|
|
11634
|
+
}
|
|
11635
|
+
}
|
|
11636
|
+
const rejectMatch = cleaned.match(/REJECT_ALL:\s*(.+)/i);
|
|
11637
|
+
if (rejectMatch) {
|
|
11638
|
+
return { pickedSkillName: null, reason: rejectMatch[1].trim(), rawOutput: raw };
|
|
11639
|
+
}
|
|
11640
|
+
return { pickedSkillName: null, reason: `unparseable advisor output: ${cleaned.slice(0, 120)}`, rawOutput: raw };
|
|
11641
|
+
}
|
|
11642
|
+
function runAdvisorGate(prompt, claudeBin) {
|
|
11643
|
+
return new Promise((resolve6, reject) => {
|
|
11644
|
+
const child = spawn3(claudeBin, [
|
|
11645
|
+
"-p",
|
|
11646
|
+
"--no-session-persistence",
|
|
11647
|
+
"--model",
|
|
11648
|
+
"sonnet",
|
|
11649
|
+
"--permission-mode",
|
|
11650
|
+
"bypassPermissions"
|
|
11651
|
+
], {
|
|
11652
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
11653
|
+
env: { ...process.env, HIVEMIND_WIKI_WORKER: "1", HIVEMIND_CAPTURE: "false" }
|
|
11654
|
+
});
|
|
11655
|
+
let stdout = "";
|
|
11656
|
+
let stderr = "";
|
|
11657
|
+
let settled = false;
|
|
11658
|
+
const finish = (err, out) => {
|
|
11659
|
+
if (settled)
|
|
11660
|
+
return;
|
|
11661
|
+
settled = true;
|
|
11662
|
+
if (err)
|
|
11663
|
+
reject(err);
|
|
11664
|
+
else
|
|
11665
|
+
resolve6(out);
|
|
11666
|
+
};
|
|
11667
|
+
const timer = setTimeout(() => {
|
|
11668
|
+
try {
|
|
11669
|
+
child.kill("SIGKILL");
|
|
11670
|
+
} catch {
|
|
11671
|
+
}
|
|
11672
|
+
finish(new Error(`advisor timed out after ${ADVISOR_TIMEOUT_MS}ms`), "");
|
|
11673
|
+
}, ADVISOR_TIMEOUT_MS);
|
|
11674
|
+
child.stdout.on("data", (b) => {
|
|
11675
|
+
stdout += b.toString("utf-8");
|
|
11676
|
+
});
|
|
11677
|
+
child.stderr.on("data", (b) => {
|
|
11678
|
+
stderr += b.toString("utf-8");
|
|
11679
|
+
});
|
|
11680
|
+
child.on("error", (e) => {
|
|
11681
|
+
clearTimeout(timer);
|
|
11682
|
+
finish(e, "");
|
|
11683
|
+
});
|
|
11684
|
+
child.on("close", (code) => {
|
|
11685
|
+
clearTimeout(timer);
|
|
11686
|
+
if (code !== 0) {
|
|
11687
|
+
finish(new Error(`advisor CLI exit ${code}; stderr=${stderr.slice(0, 200)}`), "");
|
|
11688
|
+
} else {
|
|
11689
|
+
finish(null, stdout);
|
|
11690
|
+
}
|
|
11691
|
+
});
|
|
11692
|
+
child.stdin.on("error", (e) => {
|
|
11693
|
+
clearTimeout(timer);
|
|
11694
|
+
finish(e, "");
|
|
11695
|
+
});
|
|
11696
|
+
child.stdin.end(prompt);
|
|
11697
|
+
});
|
|
11698
|
+
}
|
|
11699
|
+
async function runAdvisor(manifestPath3 = LOCAL_MANIFEST_PATH) {
|
|
11700
|
+
const m = readLocalManifest(manifestPath3);
|
|
11701
|
+
if (!m || !Array.isArray(m.entries))
|
|
11702
|
+
return null;
|
|
11703
|
+
const insightBearing = m.entries.filter((e) => e && typeof e.insight === "string" && e.insight.trim().length > 0);
|
|
11704
|
+
if (insightBearing.length === 0)
|
|
11705
|
+
return null;
|
|
11706
|
+
if (insightBearing.length === 1) {
|
|
11707
|
+
insightBearing[0].primary = true;
|
|
11708
|
+
writeLocalManifest(m, manifestPath3);
|
|
11709
|
+
return {
|
|
11710
|
+
pickedSkillName: insightBearing[0].skill_name,
|
|
11711
|
+
reason: "trivial pick (single candidate)",
|
|
11712
|
+
rawOutput: ""
|
|
11713
|
+
};
|
|
11714
|
+
}
|
|
11715
|
+
const claudeBin = findAgentBin("claude_code");
|
|
11716
|
+
if (!claudeBin || !existsSync38(claudeBin)) {
|
|
11717
|
+
return null;
|
|
11718
|
+
}
|
|
11719
|
+
const ranked = [...insightBearing].sort((a, b) => (b.created_at ?? "").localeCompare(a.created_at ?? "")).slice(0, MAX_CANDIDATES);
|
|
11720
|
+
const prompt = buildAdvisorPrompt(ranked);
|
|
11721
|
+
let raw;
|
|
11722
|
+
try {
|
|
11723
|
+
raw = await runAdvisorGate(prompt, claudeBin);
|
|
11724
|
+
} catch (err) {
|
|
11725
|
+
return {
|
|
11726
|
+
pickedSkillName: null,
|
|
11727
|
+
reason: `advisor invocation failed: ${err.message}`,
|
|
11728
|
+
rawOutput: ""
|
|
11729
|
+
};
|
|
11730
|
+
}
|
|
11731
|
+
const result = parseAdvisorOutput(raw, ranked);
|
|
11732
|
+
if (result.pickedSkillName) {
|
|
11733
|
+
for (const e of m.entries) {
|
|
11734
|
+
if (e && e.primary === true)
|
|
11735
|
+
delete e.primary;
|
|
11736
|
+
}
|
|
11737
|
+
for (const e of m.entries) {
|
|
11738
|
+
if (e && e.skill_name === result.pickedSkillName) {
|
|
11739
|
+
e.primary = true;
|
|
11740
|
+
break;
|
|
11741
|
+
}
|
|
11742
|
+
}
|
|
11743
|
+
writeLocalManifest(m, manifestPath3);
|
|
11744
|
+
}
|
|
11745
|
+
return result;
|
|
11746
|
+
}
|
|
11747
|
+
|
|
11748
|
+
// dist/src/cli/install-scan.js
|
|
11749
|
+
function claudeProjectsDir() {
|
|
11750
|
+
return join49(homedir26(), ".claude", "projects");
|
|
11751
|
+
}
|
|
11752
|
+
function manifestPath2() {
|
|
11753
|
+
return join49(homedir26(), ".claude", "hivemind", "local-mined.json");
|
|
11754
|
+
}
|
|
11755
|
+
var SCAN_TIMEOUT_MS = 3e5;
|
|
11756
|
+
var INSTALL_SCAN_SESSION_COUNT = 10;
|
|
11757
|
+
function manifestIsTrulyEmpty() {
|
|
11758
|
+
const p = manifestPath2();
|
|
11759
|
+
if (!existsSync39(p))
|
|
11760
|
+
return false;
|
|
11761
|
+
try {
|
|
11762
|
+
const m = JSON.parse(readFileSync35(p, "utf-8"));
|
|
11763
|
+
return Array.isArray(m.entries) && m.entries.length === 0;
|
|
11764
|
+
} catch {
|
|
11765
|
+
return false;
|
|
11766
|
+
}
|
|
11767
|
+
}
|
|
11768
|
+
function hasLocalClaudeSessions() {
|
|
11769
|
+
const projectsDir = claudeProjectsDir();
|
|
11770
|
+
if (!existsSync39(projectsDir))
|
|
11771
|
+
return false;
|
|
11772
|
+
let subdirs;
|
|
11773
|
+
try {
|
|
11774
|
+
subdirs = readdirSync9(projectsDir);
|
|
11775
|
+
} catch {
|
|
11776
|
+
return false;
|
|
11777
|
+
}
|
|
11778
|
+
for (const sub of subdirs) {
|
|
11779
|
+
let files;
|
|
11780
|
+
try {
|
|
11781
|
+
files = readdirSync9(join49(projectsDir, sub));
|
|
11782
|
+
} catch {
|
|
11783
|
+
continue;
|
|
11784
|
+
}
|
|
11785
|
+
if (files.some((f) => f.endsWith(".jsonl")))
|
|
11786
|
+
return true;
|
|
11787
|
+
}
|
|
11788
|
+
return false;
|
|
11789
|
+
}
|
|
11790
|
+
function canOfferInstallScan() {
|
|
11791
|
+
const bin = findAgentBin("claude_code");
|
|
11792
|
+
if (!bin || !existsSync39(bin))
|
|
11793
|
+
return false;
|
|
11794
|
+
if (!hasLocalClaudeSessions())
|
|
11795
|
+
return false;
|
|
11796
|
+
if (existsSync39(manifestPath2()))
|
|
11797
|
+
return false;
|
|
11798
|
+
return true;
|
|
11799
|
+
}
|
|
11800
|
+
function unlinkManifestIfCorrupt() {
|
|
11801
|
+
const p = manifestPath2();
|
|
11802
|
+
if (!existsSync39(p))
|
|
11803
|
+
return;
|
|
11804
|
+
if (readLocalManifest(p) === null) {
|
|
11805
|
+
try {
|
|
11806
|
+
unlinkSync14(p);
|
|
11807
|
+
} catch {
|
|
11808
|
+
}
|
|
11809
|
+
}
|
|
11810
|
+
}
|
|
11811
|
+
function runInstallScan() {
|
|
11812
|
+
return new Promise((resolve6) => {
|
|
11813
|
+
const cliPath = process.argv[1];
|
|
11814
|
+
if (!cliPath || !existsSync39(cliPath)) {
|
|
11815
|
+
resolve6({ insight: null, skillsCount: 0 });
|
|
11816
|
+
return;
|
|
11817
|
+
}
|
|
11818
|
+
const child = spawn4(process.execPath, [
|
|
11819
|
+
cliPath,
|
|
11820
|
+
"skillify",
|
|
11821
|
+
"mine-local",
|
|
11822
|
+
"--n",
|
|
11823
|
+
String(INSTALL_SCAN_SESSION_COUNT),
|
|
11824
|
+
// The install copy advertises a "Claude Code" scan, so filter
|
|
11825
|
+
// the mine-local picker to claude_code sessions. Without this,
|
|
11826
|
+
// mine-local walks every installed agent (Codex, Cursor,
|
|
11827
|
+
// Hermes, pi) and could surface an insight from a Codex
|
|
11828
|
+
// session despite what we promised — codex PR #198 P2.
|
|
11829
|
+
"--only",
|
|
11830
|
+
"claude_code"
|
|
11831
|
+
], {
|
|
11832
|
+
stdio: ["ignore", "ignore", "ignore"],
|
|
11833
|
+
// HIVEMIND_CAPTURE=false: the spawned mine-local would otherwise
|
|
11834
|
+
// try to capture its own activity, which is a no-op without
|
|
11835
|
+
// credentials but spams the log. Keep it quiet.
|
|
11836
|
+
env: { ...process.env, HIVEMIND_CAPTURE: "false" }
|
|
11837
|
+
});
|
|
11838
|
+
let settled = false;
|
|
11839
|
+
const finish = (result) => {
|
|
11840
|
+
if (settled)
|
|
11841
|
+
return;
|
|
11842
|
+
settled = true;
|
|
11843
|
+
resolve6(result);
|
|
11844
|
+
};
|
|
11845
|
+
const timer = setTimeout(() => {
|
|
11846
|
+
try {
|
|
11847
|
+
child.kill("SIGKILL");
|
|
11848
|
+
} catch {
|
|
11849
|
+
}
|
|
11850
|
+
unlinkManifestIfCorrupt();
|
|
11851
|
+
finish({ insight: null, skillsCount: 0 });
|
|
11852
|
+
}, SCAN_TIMEOUT_MS);
|
|
11853
|
+
child.on("close", async (code) => {
|
|
11854
|
+
clearTimeout(timer);
|
|
11855
|
+
if (code !== 0) {
|
|
11856
|
+
unlinkManifestIfCorrupt();
|
|
11857
|
+
finish({ insight: null, skillsCount: 0 });
|
|
11858
|
+
return;
|
|
11859
|
+
}
|
|
11860
|
+
let advisorResult = null;
|
|
11861
|
+
try {
|
|
11862
|
+
advisorResult = await runAdvisor();
|
|
11863
|
+
} catch {
|
|
11864
|
+
}
|
|
11865
|
+
const advisorRejected = advisorResult !== null && advisorResult.pickedSkillName === null;
|
|
11866
|
+
let entry = null;
|
|
11867
|
+
if (!advisorRejected) {
|
|
11868
|
+
try {
|
|
11869
|
+
entry = getLatestInsightEntry();
|
|
11870
|
+
} catch {
|
|
11871
|
+
}
|
|
11872
|
+
}
|
|
11873
|
+
let skillsCount = 0;
|
|
11874
|
+
try {
|
|
11875
|
+
skillsCount = countLocalManifestEntries();
|
|
11876
|
+
} catch {
|
|
11877
|
+
}
|
|
11878
|
+
if (!entry && manifestIsTrulyEmpty()) {
|
|
11879
|
+
try {
|
|
11880
|
+
unlinkSync14(manifestPath2());
|
|
11881
|
+
} catch {
|
|
11882
|
+
}
|
|
11883
|
+
skillsCount = 0;
|
|
11884
|
+
}
|
|
11885
|
+
finish({ insight: entry, skillsCount });
|
|
11886
|
+
});
|
|
11887
|
+
child.on("error", () => {
|
|
11888
|
+
clearTimeout(timer);
|
|
11889
|
+
unlinkManifestIfCorrupt();
|
|
11890
|
+
finish({ insight: null, skillsCount: 0 });
|
|
11891
|
+
});
|
|
11892
|
+
});
|
|
11893
|
+
}
|
|
11894
|
+
function formatScanResult(entry) {
|
|
11895
|
+
const rawInsight = (entry.insight ?? "").replace(/\s+/g, " ").trim();
|
|
11896
|
+
const insight = rawInsight.length > 280 ? rawInsight.slice(0, 277).replace(/\s\S*$/, "") + "\u2026" : rawInsight;
|
|
11897
|
+
return `\u2713 Found a pattern in your past sessions:
|
|
11898
|
+
\u{1F4CC} ${insight}
|
|
11899
|
+
\u2728 Skill \`${entry.skill_name}\` ready to catch it next time`;
|
|
11900
|
+
}
|
|
11901
|
+
|
|
11539
11902
|
// dist/src/cli/index.js
|
|
11540
11903
|
var AUTH_SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
11541
11904
|
"whoami",
|
|
@@ -11717,14 +12080,44 @@ async function runAuthGate(args) {
|
|
|
11717
12080
|
log("Or run `hivemind login` after install.");
|
|
11718
12081
|
return;
|
|
11719
12082
|
}
|
|
12083
|
+
let foundInsight = null;
|
|
12084
|
+
if (canOfferInstallScan()) {
|
|
12085
|
+
log("");
|
|
12086
|
+
log("\u{1F41D} Want me to scan your recent Claude Code sessions for repeatable mistakes?");
|
|
12087
|
+
log("Takes 2-4 minutes. Scans 10 sessions in parallel using your Claude Code subscription.");
|
|
12088
|
+
log("");
|
|
12089
|
+
const scanOk = await confirm("Scan now?", true);
|
|
12090
|
+
if (scanOk) {
|
|
12091
|
+
log("");
|
|
12092
|
+
log("Scanning your 10 most-recent sessions (up to 5 min). Be patient \u2014 haiku is running in the background.");
|
|
12093
|
+
const { insight, skillsCount } = await runInstallScan();
|
|
12094
|
+
log("");
|
|
12095
|
+
if (insight && insight.insight && insight.insight.trim().length > 0) {
|
|
12096
|
+
log(formatScanResult(insight));
|
|
12097
|
+
foundInsight = { skill_name: insight.skill_name };
|
|
12098
|
+
} else if (skillsCount > 0) {
|
|
12099
|
+
log(`Mined ${skillsCount} skill${skillsCount === 1 ? "" : "s"} locally \u2014 they'll be available in your next claude session.`);
|
|
12100
|
+
log("(No banner-quality insight to surface here \u2014 the gate is conservative on what gets the top-line.)");
|
|
12101
|
+
} else {
|
|
12102
|
+
log("No repeatable patterns found in this scan. (That's OK \u2014 the gate is conservative.)");
|
|
12103
|
+
}
|
|
12104
|
+
}
|
|
12105
|
+
}
|
|
11720
12106
|
log("");
|
|
11721
|
-
|
|
11722
|
-
|
|
11723
|
-
|
|
11724
|
-
|
|
11725
|
-
|
|
11726
|
-
|
|
11727
|
-
|
|
12107
|
+
if (foundInsight) {
|
|
12108
|
+
log("\u{1F41D} Sign in to keep this skill across machines and share it with your team.");
|
|
12109
|
+
log("");
|
|
12110
|
+
log(`Without sign-in, \`${foundInsight.skill_name}\` lives only on this machine and`);
|
|
12111
|
+
log("won't follow you to a new laptop or be shared with teammates who'd benefit.");
|
|
12112
|
+
} else {
|
|
12113
|
+
log("\u{1F41D} One more step to unlock Hivemind");
|
|
12114
|
+
log("");
|
|
12115
|
+
log("To enable shared memory and auto-learning across your agents,");
|
|
12116
|
+
log("we need to sign you in. Your traces will be securely stored in");
|
|
12117
|
+
log("your private Hivemind, so all your agents can recall them.");
|
|
12118
|
+
log("");
|
|
12119
|
+
log("You can later connect your own cloud storage like S3/GCS/Azure Blob.");
|
|
12120
|
+
}
|
|
11728
12121
|
log("");
|
|
11729
12122
|
const yes = await confirm("Sign in now?", true);
|
|
11730
12123
|
let signedIn = false;
|
package/openclaw/dist/index.js
CHANGED
|
@@ -1727,7 +1727,7 @@ function extractLatestVersion(body) {
|
|
|
1727
1727
|
return typeof v === "string" && v.length > 0 ? v : null;
|
|
1728
1728
|
}
|
|
1729
1729
|
function getInstalledVersion() {
|
|
1730
|
-
return "0.7.
|
|
1730
|
+
return "0.7.52".length > 0 ? "0.7.52" : null;
|
|
1731
1731
|
}
|
|
1732
1732
|
function isNewer(latest, current) {
|
|
1733
1733
|
const parse = (v) => v.replace(/-.*$/, "").split(".").map(Number);
|
package/openclaw/package.json
CHANGED