@deeplake/hivemind 0.7.25 → 0.7.27
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 +1102 -151
- package/codex/bundle/session-start.js +223 -131
- package/codex/skills/deeplake-memory/SKILL.md +33 -0
- package/cursor/bundle/session-start.js +228 -82
- package/hermes/bundle/session-start.js +229 -82
- package/openclaw/dist/index.js +1 -1
- 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
|
@@ -53,8 +53,8 @@ var init_index_marker_store = __esm({
|
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
// dist/src/hooks/cursor/session-start.js
|
|
56
|
-
import { fileURLToPath } from "node:url";
|
|
57
|
-
import { dirname as
|
|
56
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
57
|
+
import { dirname as dirname6 } from "node:path";
|
|
58
58
|
|
|
59
59
|
// dist/src/commands/auth.js
|
|
60
60
|
import { execSync } from "node:child_process";
|
|
@@ -561,6 +561,162 @@ var DeeplakeApi = class {
|
|
|
561
561
|
}
|
|
562
562
|
};
|
|
563
563
|
|
|
564
|
+
// dist/src/cli/skillify-spec.js
|
|
565
|
+
var SKILLIFY_COMMANDS = [
|
|
566
|
+
{ cmd: "hivemind skillify", desc: "show scope, team, install, per-project state" },
|
|
567
|
+
{ cmd: "hivemind skillify pull", desc: "sync project skills from the org table to local FS" },
|
|
568
|
+
{ cmd: "hivemind skillify pull --user <email>", desc: "only skills authored by that user" },
|
|
569
|
+
{ cmd: "hivemind skillify pull --users <a,b,c>", desc: "only skills from those authors" },
|
|
570
|
+
{ cmd: "hivemind skillify pull --all-users", desc: 'explicit "no author filter" (default)' },
|
|
571
|
+
{ cmd: "hivemind skillify pull --to <project|global>", desc: "install location (project=cwd/.claude/skills, global=~/.claude/skills)" },
|
|
572
|
+
{ cmd: "hivemind skillify pull --dry-run", desc: "preview without touching disk" },
|
|
573
|
+
{ cmd: "hivemind skillify pull --force", desc: "overwrite local files even if up-to-date (creates .bak)" },
|
|
574
|
+
{ cmd: "hivemind skillify pull <skill-name>", desc: "pull only that one skill (combines with --user)" },
|
|
575
|
+
{ cmd: "hivemind skillify unpull", desc: "remove every skill previously installed by pull" },
|
|
576
|
+
{ cmd: "hivemind skillify unpull --user <email>", desc: "remove only that author's pulls" },
|
|
577
|
+
{ cmd: "hivemind skillify unpull --not-mine", desc: "remove all pulls except your own" },
|
|
578
|
+
{ cmd: "hivemind skillify unpull --dry-run", desc: "preview without touching disk" },
|
|
579
|
+
{ cmd: "hivemind skillify scope <me|team|org>", desc: "sharing scope for newly mined skills" },
|
|
580
|
+
{ cmd: "hivemind skillify install <project|global>", desc: "default install location for new skills" },
|
|
581
|
+
{ cmd: "hivemind skillify promote <skill-name>", desc: "move a project skill to the global location" },
|
|
582
|
+
{ cmd: "hivemind skillify team add|remove|list <name>", desc: "manage team member list" },
|
|
583
|
+
{ cmd: "hivemind skillify mine-local", desc: "one-shot: mine skills from local sessions (no auth needed)" },
|
|
584
|
+
{ cmd: "hivemind skillify mine-local --n <num|all>", desc: "how many sessions to mine (default: 8)" },
|
|
585
|
+
{ cmd: "hivemind skillify mine-local --force", desc: "re-run even if the manifest sentinel exists" },
|
|
586
|
+
{ cmd: "hivemind skillify mine-local --dry-run", desc: "stop before calling the LLM gate" }
|
|
587
|
+
];
|
|
588
|
+
function renderSkillifyCommands() {
|
|
589
|
+
const maxLen = Math.max(...SKILLIFY_COMMANDS.map((c) => c.cmd.length));
|
|
590
|
+
return SKILLIFY_COMMANDS.map((c) => `- ${c.cmd.padEnd(maxLen + 2)} \u2014 ${c.desc}`).join("\n");
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// dist/src/skillify/local-manifest.js
|
|
594
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
595
|
+
import { homedir as homedir4 } from "node:os";
|
|
596
|
+
import { dirname, join as join5 } from "node:path";
|
|
597
|
+
var LOCAL_MANIFEST_PATH = join5(homedir4(), ".claude", "hivemind", "local-mined.json");
|
|
598
|
+
var LOCAL_MINE_LOCK_PATH = join5(homedir4(), ".claude", "hivemind", "local-mined.lock");
|
|
599
|
+
function readLocalManifest(path = LOCAL_MANIFEST_PATH) {
|
|
600
|
+
if (!existsSync3(path))
|
|
601
|
+
return null;
|
|
602
|
+
try {
|
|
603
|
+
return JSON.parse(readFileSync4(path, "utf-8"));
|
|
604
|
+
} catch {
|
|
605
|
+
return null;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
function countLocalManifestEntries(path = LOCAL_MANIFEST_PATH) {
|
|
609
|
+
const m = readLocalManifest(path);
|
|
610
|
+
return Array.isArray(m?.entries) ? m.entries.length : 0;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// dist/src/skillify/spawn-mine-local-worker.js
|
|
614
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
615
|
+
import { closeSync, existsSync as existsSync4, mkdirSync as mkdirSync4, openSync, readdirSync, statSync, unlinkSync as unlinkSync2 } from "node:fs";
|
|
616
|
+
import { homedir as homedir5 } from "node:os";
|
|
617
|
+
import { dirname as dirname2, join as join6 } from "node:path";
|
|
618
|
+
import { fileURLToPath } from "node:url";
|
|
619
|
+
var HOME = homedir5();
|
|
620
|
+
var HIVEMIND_DIR = join6(HOME, ".claude", "hivemind");
|
|
621
|
+
var LOG_PATH = join6(HOME, ".claude", "hooks", "mine-local.log");
|
|
622
|
+
var CLAUDE_PROJECTS_DIR = join6(HOME, ".claude", "projects");
|
|
623
|
+
var LOCK_STALE_MS = 15 * 60 * 1e3;
|
|
624
|
+
function findBundledCliPath() {
|
|
625
|
+
try {
|
|
626
|
+
const thisDir = dirname2(fileURLToPath(import.meta.url));
|
|
627
|
+
const cliPath = join6(thisDir, "..", "..", "bundle", "cli.js");
|
|
628
|
+
return existsSync4(cliPath) ? cliPath : null;
|
|
629
|
+
} catch {
|
|
630
|
+
return null;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
function findHivemindLauncher() {
|
|
634
|
+
const bundled = findBundledCliPath();
|
|
635
|
+
if (bundled)
|
|
636
|
+
return { kind: "node-script", path: bundled };
|
|
637
|
+
try {
|
|
638
|
+
const out = execFileSync("which", ["hivemind"], {
|
|
639
|
+
encoding: "utf-8",
|
|
640
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
641
|
+
});
|
|
642
|
+
const bin = out.trim();
|
|
643
|
+
return bin ? { kind: "bin", path: bin } : null;
|
|
644
|
+
} catch {
|
|
645
|
+
return null;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
function hasLocalClaudeSessions() {
|
|
649
|
+
if (!existsSync4(CLAUDE_PROJECTS_DIR))
|
|
650
|
+
return false;
|
|
651
|
+
let subdirs;
|
|
652
|
+
try {
|
|
653
|
+
subdirs = readdirSync(CLAUDE_PROJECTS_DIR);
|
|
654
|
+
} catch {
|
|
655
|
+
return false;
|
|
656
|
+
}
|
|
657
|
+
for (const sub of subdirs) {
|
|
658
|
+
let files;
|
|
659
|
+
try {
|
|
660
|
+
files = readdirSync(join6(CLAUDE_PROJECTS_DIR, sub));
|
|
661
|
+
} catch {
|
|
662
|
+
continue;
|
|
663
|
+
}
|
|
664
|
+
if (files.some((f) => f.endsWith(".jsonl")))
|
|
665
|
+
return true;
|
|
666
|
+
}
|
|
667
|
+
return false;
|
|
668
|
+
}
|
|
669
|
+
function maybeAutoMineLocal() {
|
|
670
|
+
if (existsSync4(LOCAL_MANIFEST_PATH))
|
|
671
|
+
return { triggered: false, reason: "manifest-exists" };
|
|
672
|
+
if (existsSync4(LOCAL_MINE_LOCK_PATH)) {
|
|
673
|
+
let stale = false;
|
|
674
|
+
try {
|
|
675
|
+
const stats = statSync(LOCAL_MINE_LOCK_PATH);
|
|
676
|
+
stale = Date.now() - stats.mtimeMs > LOCK_STALE_MS;
|
|
677
|
+
} catch {
|
|
678
|
+
}
|
|
679
|
+
if (!stale)
|
|
680
|
+
return { triggered: false, reason: "lock-exists" };
|
|
681
|
+
try {
|
|
682
|
+
unlinkSync2(LOCAL_MINE_LOCK_PATH);
|
|
683
|
+
} catch {
|
|
684
|
+
return { triggered: false, reason: "lock-exists" };
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
if (!hasLocalClaudeSessions())
|
|
688
|
+
return { triggered: false, reason: "no-claude-sessions" };
|
|
689
|
+
const launcher = findHivemindLauncher();
|
|
690
|
+
if (!launcher)
|
|
691
|
+
return { triggered: false, reason: "no-hivemind-bin" };
|
|
692
|
+
try {
|
|
693
|
+
mkdirSync4(HIVEMIND_DIR, { recursive: true });
|
|
694
|
+
const fd = openSync(LOCAL_MINE_LOCK_PATH, "wx");
|
|
695
|
+
closeSync(fd);
|
|
696
|
+
} catch {
|
|
697
|
+
return { triggered: false, reason: "lock-acquire-failed" };
|
|
698
|
+
}
|
|
699
|
+
try {
|
|
700
|
+
mkdirSync4(join6(HOME, ".claude", "hooks"), { recursive: true });
|
|
701
|
+
const out = openSync(LOG_PATH, "a");
|
|
702
|
+
const [cmd, args] = launcher.kind === "node-script" ? [process.execPath, [launcher.path, "skillify", "mine-local"]] : [launcher.path, ["skillify", "mine-local"]];
|
|
703
|
+
const child = spawn(cmd, args, {
|
|
704
|
+
detached: true,
|
|
705
|
+
stdio: ["ignore", out, out],
|
|
706
|
+
env: process.env
|
|
707
|
+
});
|
|
708
|
+
closeSync(out);
|
|
709
|
+
child.unref();
|
|
710
|
+
return { triggered: true };
|
|
711
|
+
} catch {
|
|
712
|
+
try {
|
|
713
|
+
unlinkSync2(LOCAL_MINE_LOCK_PATH);
|
|
714
|
+
} catch {
|
|
715
|
+
}
|
|
716
|
+
return { triggered: false, reason: "spawn-failed" };
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
|
|
564
720
|
// dist/src/utils/stdin.js
|
|
565
721
|
function readStdin() {
|
|
566
722
|
return new Promise((resolve, reject) => {
|
|
@@ -579,18 +735,18 @@ function readStdin() {
|
|
|
579
735
|
}
|
|
580
736
|
|
|
581
737
|
// dist/src/utils/version-check.js
|
|
582
|
-
import { readFileSync as
|
|
583
|
-
import { dirname, join as
|
|
738
|
+
import { readFileSync as readFileSync5 } from "node:fs";
|
|
739
|
+
import { dirname as dirname3, join as join7 } from "node:path";
|
|
584
740
|
function getInstalledVersion(bundleDir, pluginManifestDir) {
|
|
585
741
|
try {
|
|
586
|
-
const pluginJson =
|
|
587
|
-
const plugin = JSON.parse(
|
|
742
|
+
const pluginJson = join7(bundleDir, "..", pluginManifestDir, "plugin.json");
|
|
743
|
+
const plugin = JSON.parse(readFileSync5(pluginJson, "utf-8"));
|
|
588
744
|
if (plugin.version)
|
|
589
745
|
return plugin.version;
|
|
590
746
|
} catch {
|
|
591
747
|
}
|
|
592
748
|
try {
|
|
593
|
-
const stamp =
|
|
749
|
+
const stamp = readFileSync5(join7(bundleDir, "..", ".hivemind_version"), "utf-8").trim();
|
|
594
750
|
if (stamp)
|
|
595
751
|
return stamp;
|
|
596
752
|
} catch {
|
|
@@ -605,14 +761,14 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
|
|
|
605
761
|
]);
|
|
606
762
|
let dir = bundleDir;
|
|
607
763
|
for (let i = 0; i < 5; i++) {
|
|
608
|
-
const candidate =
|
|
764
|
+
const candidate = join7(dir, "package.json");
|
|
609
765
|
try {
|
|
610
|
-
const pkg = JSON.parse(
|
|
766
|
+
const pkg = JSON.parse(readFileSync5(candidate, "utf-8"));
|
|
611
767
|
if (HIVEMIND_PKG_NAMES.has(pkg.name) && pkg.version)
|
|
612
768
|
return pkg.version;
|
|
613
769
|
} catch {
|
|
614
770
|
}
|
|
615
|
-
const parent =
|
|
771
|
+
const parent = dirname3(dir);
|
|
616
772
|
if (parent === dir)
|
|
617
773
|
break;
|
|
618
774
|
dir = parent;
|
|
@@ -621,12 +777,12 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
|
|
|
621
777
|
}
|
|
622
778
|
|
|
623
779
|
// dist/src/hooks/shared/autoupdate.js
|
|
624
|
-
import { spawn } from "node:child_process";
|
|
625
|
-
import { existsSync as
|
|
626
|
-
import { join as
|
|
780
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
781
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
782
|
+
import { join as join8 } from "node:path";
|
|
627
783
|
var log3 = (msg) => log("autoupdate", msg);
|
|
628
784
|
var defaultSpawn = (cmd, args) => {
|
|
629
|
-
const child =
|
|
785
|
+
const child = spawn2(cmd, args, {
|
|
630
786
|
detached: true,
|
|
631
787
|
stdio: "ignore"
|
|
632
788
|
});
|
|
@@ -639,8 +795,8 @@ function findHivemindOnPath() {
|
|
|
639
795
|
const PATH = process.env.PATH ?? "";
|
|
640
796
|
const dirs = PATH.split(":").filter(Boolean);
|
|
641
797
|
for (const dir of dirs) {
|
|
642
|
-
const candidate =
|
|
643
|
-
if (
|
|
798
|
+
const candidate = join8(dir, "hivemind");
|
|
799
|
+
if (existsSync5(candidate))
|
|
644
800
|
return candidate;
|
|
645
801
|
}
|
|
646
802
|
return null;
|
|
@@ -674,14 +830,14 @@ async function autoUpdate(creds, opts) {
|
|
|
674
830
|
}
|
|
675
831
|
|
|
676
832
|
// dist/src/skillify/pull.js
|
|
677
|
-
import { existsSync as
|
|
678
|
-
import { homedir as
|
|
679
|
-
import { dirname as
|
|
833
|
+
import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, renameSync as renameSync3, lstatSync as lstatSync2, readlinkSync, symlinkSync, unlinkSync as unlinkSync4 } from "node:fs";
|
|
834
|
+
import { homedir as homedir10 } from "node:os";
|
|
835
|
+
import { dirname as dirname5, join as join13 } from "node:path";
|
|
680
836
|
|
|
681
837
|
// dist/src/skillify/skill-writer.js
|
|
682
|
-
import { existsSync as
|
|
683
|
-
import { homedir as
|
|
684
|
-
import { join as
|
|
838
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync6, readdirSync as readdirSync2, statSync as statSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
839
|
+
import { homedir as homedir6 } from "node:os";
|
|
840
|
+
import { join as join9 } from "node:path";
|
|
685
841
|
function assertValidSkillName(name) {
|
|
686
842
|
if (typeof name !== "string" || name.length === 0) {
|
|
687
843
|
throw new Error(`invalid skill name: empty or non-string`);
|
|
@@ -747,26 +903,26 @@ function parseFrontmatter(text) {
|
|
|
747
903
|
}
|
|
748
904
|
|
|
749
905
|
// dist/src/skillify/manifest.js
|
|
750
|
-
import { existsSync as
|
|
751
|
-
import { homedir as
|
|
752
|
-
import { dirname as
|
|
906
|
+
import { existsSync as existsSync8, lstatSync, mkdirSync as mkdirSync6, readFileSync as readFileSync7, renameSync as renameSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync5 } from "node:fs";
|
|
907
|
+
import { homedir as homedir8 } from "node:os";
|
|
908
|
+
import { dirname as dirname4, join as join11 } from "node:path";
|
|
753
909
|
|
|
754
910
|
// dist/src/skillify/legacy-migration.js
|
|
755
|
-
import { existsSync as
|
|
756
|
-
import { homedir as
|
|
757
|
-
import { join as
|
|
911
|
+
import { existsSync as existsSync7, renameSync } from "node:fs";
|
|
912
|
+
import { homedir as homedir7 } from "node:os";
|
|
913
|
+
import { join as join10 } from "node:path";
|
|
758
914
|
var dlog = (msg) => log("skillify-migrate", msg);
|
|
759
915
|
var attempted = false;
|
|
760
916
|
function migrateLegacyStateDir() {
|
|
761
917
|
if (attempted)
|
|
762
918
|
return;
|
|
763
919
|
attempted = true;
|
|
764
|
-
const root =
|
|
765
|
-
const legacy =
|
|
766
|
-
const current =
|
|
767
|
-
if (!
|
|
920
|
+
const root = join10(homedir7(), ".deeplake", "state");
|
|
921
|
+
const legacy = join10(root, "skilify");
|
|
922
|
+
const current = join10(root, "skillify");
|
|
923
|
+
if (!existsSync7(legacy))
|
|
768
924
|
return;
|
|
769
|
-
if (
|
|
925
|
+
if (existsSync7(current))
|
|
770
926
|
return;
|
|
771
927
|
try {
|
|
772
928
|
renameSync(legacy, current);
|
|
@@ -786,15 +942,15 @@ function emptyManifest() {
|
|
|
786
942
|
return { version: 1, entries: [] };
|
|
787
943
|
}
|
|
788
944
|
function manifestPath() {
|
|
789
|
-
return
|
|
945
|
+
return join11(homedir8(), ".deeplake", "state", "skillify", "pulled.json");
|
|
790
946
|
}
|
|
791
947
|
function loadManifest(path = manifestPath()) {
|
|
792
948
|
migrateLegacyStateDir();
|
|
793
|
-
if (!
|
|
949
|
+
if (!existsSync8(path))
|
|
794
950
|
return emptyManifest();
|
|
795
951
|
let raw;
|
|
796
952
|
try {
|
|
797
|
-
raw =
|
|
953
|
+
raw = readFileSync7(path, "utf-8");
|
|
798
954
|
} catch {
|
|
799
955
|
return emptyManifest();
|
|
800
956
|
}
|
|
@@ -841,9 +997,9 @@ function loadManifest(path = manifestPath()) {
|
|
|
841
997
|
}
|
|
842
998
|
function saveManifest(m, path = manifestPath()) {
|
|
843
999
|
migrateLegacyStateDir();
|
|
844
|
-
|
|
1000
|
+
mkdirSync6(dirname4(path), { recursive: true });
|
|
845
1001
|
const tmp = `${path}.tmp`;
|
|
846
|
-
|
|
1002
|
+
writeFileSync5(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
|
|
847
1003
|
renameSync2(tmp, path);
|
|
848
1004
|
}
|
|
849
1005
|
function recordPull(entry, path = manifestPath()) {
|
|
@@ -869,7 +1025,7 @@ function unlinkSymlinks(paths) {
|
|
|
869
1025
|
if (!st.isSymbolicLink())
|
|
870
1026
|
continue;
|
|
871
1027
|
try {
|
|
872
|
-
|
|
1028
|
+
unlinkSync3(path);
|
|
873
1029
|
} catch {
|
|
874
1030
|
}
|
|
875
1031
|
}
|
|
@@ -879,7 +1035,7 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
879
1035
|
const live = [];
|
|
880
1036
|
let pruned = 0;
|
|
881
1037
|
for (const e of m.entries) {
|
|
882
|
-
if (
|
|
1038
|
+
if (existsSync8(join11(e.installRoot, e.dirName))) {
|
|
883
1039
|
live.push(e);
|
|
884
1040
|
continue;
|
|
885
1041
|
}
|
|
@@ -892,26 +1048,26 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
892
1048
|
}
|
|
893
1049
|
|
|
894
1050
|
// dist/src/skillify/agent-roots.js
|
|
895
|
-
import { existsSync as
|
|
896
|
-
import { homedir as
|
|
897
|
-
import { join as
|
|
1051
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
1052
|
+
import { homedir as homedir9 } from "node:os";
|
|
1053
|
+
import { join as join12 } from "node:path";
|
|
898
1054
|
function resolveDetected(home) {
|
|
899
1055
|
const out = [];
|
|
900
|
-
const codexInstalled =
|
|
901
|
-
const piInstalled =
|
|
902
|
-
const hermesInstalled =
|
|
1056
|
+
const codexInstalled = existsSync9(join12(home, ".codex"));
|
|
1057
|
+
const piInstalled = existsSync9(join12(home, ".pi", "agent"));
|
|
1058
|
+
const hermesInstalled = existsSync9(join12(home, ".hermes"));
|
|
903
1059
|
if (codexInstalled || piInstalled) {
|
|
904
|
-
out.push(
|
|
1060
|
+
out.push(join12(home, ".agents", "skills"));
|
|
905
1061
|
}
|
|
906
1062
|
if (hermesInstalled) {
|
|
907
|
-
out.push(
|
|
1063
|
+
out.push(join12(home, ".hermes", "skills"));
|
|
908
1064
|
}
|
|
909
1065
|
if (piInstalled) {
|
|
910
|
-
out.push(
|
|
1066
|
+
out.push(join12(home, ".pi", "agent", "skills"));
|
|
911
1067
|
}
|
|
912
1068
|
return out;
|
|
913
1069
|
}
|
|
914
|
-
function detectAgentSkillsRoots(canonicalRoot, home =
|
|
1070
|
+
function detectAgentSkillsRoots(canonicalRoot, home = homedir9()) {
|
|
915
1071
|
return resolveDetected(home).filter((p) => p !== canonicalRoot);
|
|
916
1072
|
}
|
|
917
1073
|
|
|
@@ -955,15 +1111,15 @@ function isMissingTableError(message) {
|
|
|
955
1111
|
}
|
|
956
1112
|
function resolvePullDestination(install, cwd) {
|
|
957
1113
|
if (install === "global")
|
|
958
|
-
return
|
|
1114
|
+
return join13(homedir10(), ".claude", "skills");
|
|
959
1115
|
if (!cwd)
|
|
960
1116
|
throw new Error("install=project requires a cwd");
|
|
961
|
-
return
|
|
1117
|
+
return join13(cwd, ".claude", "skills");
|
|
962
1118
|
}
|
|
963
1119
|
function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
|
|
964
1120
|
const out = [];
|
|
965
1121
|
for (const root of agentRoots) {
|
|
966
|
-
const link =
|
|
1122
|
+
const link = join13(root, dirName);
|
|
967
1123
|
let existing;
|
|
968
1124
|
try {
|
|
969
1125
|
existing = lstatSync2(link);
|
|
@@ -985,13 +1141,13 @@ function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
|
|
|
985
1141
|
continue;
|
|
986
1142
|
}
|
|
987
1143
|
try {
|
|
988
|
-
|
|
1144
|
+
unlinkSync4(link);
|
|
989
1145
|
} catch {
|
|
990
1146
|
continue;
|
|
991
1147
|
}
|
|
992
1148
|
}
|
|
993
1149
|
try {
|
|
994
|
-
|
|
1150
|
+
mkdirSync7(dirname5(link), { recursive: true });
|
|
995
1151
|
symlinkSync(canonicalDir, link, "dir");
|
|
996
1152
|
out.push(link);
|
|
997
1153
|
} catch {
|
|
@@ -1006,8 +1162,8 @@ function backfillSymlinks(installRoot) {
|
|
|
1006
1162
|
return;
|
|
1007
1163
|
const detected = detectAgentSkillsRoots(installRoot);
|
|
1008
1164
|
for (const entry of entries) {
|
|
1009
|
-
const canonical =
|
|
1010
|
-
if (!
|
|
1165
|
+
const canonical = join13(entry.installRoot, entry.dirName);
|
|
1166
|
+
if (!existsSync10(canonical))
|
|
1011
1167
|
continue;
|
|
1012
1168
|
const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
|
|
1013
1169
|
if (sameSorted(fresh, entry.symlinks))
|
|
@@ -1117,10 +1273,10 @@ function renderFrontmatter(fm) {
|
|
|
1117
1273
|
return lines.join("\n");
|
|
1118
1274
|
}
|
|
1119
1275
|
function readLocalVersion(path) {
|
|
1120
|
-
if (!
|
|
1276
|
+
if (!existsSync10(path))
|
|
1121
1277
|
return null;
|
|
1122
1278
|
try {
|
|
1123
|
-
const text =
|
|
1279
|
+
const text = readFileSync8(path, "utf-8");
|
|
1124
1280
|
const parsed = parseFrontmatter(text);
|
|
1125
1281
|
if (!parsed)
|
|
1126
1282
|
return null;
|
|
@@ -1215,8 +1371,8 @@ async function runPull(opts) {
|
|
|
1215
1371
|
summary.skipped++;
|
|
1216
1372
|
continue;
|
|
1217
1373
|
}
|
|
1218
|
-
const skillDir =
|
|
1219
|
-
const skillFile =
|
|
1374
|
+
const skillDir = join13(root, dirName);
|
|
1375
|
+
const skillFile = join13(skillDir, "SKILL.md");
|
|
1220
1376
|
const remoteVersion = Number(row.version ?? 1);
|
|
1221
1377
|
const localVersion = readLocalVersion(skillFile);
|
|
1222
1378
|
const action = decideAction({
|
|
@@ -1227,14 +1383,14 @@ async function runPull(opts) {
|
|
|
1227
1383
|
});
|
|
1228
1384
|
let manifestError;
|
|
1229
1385
|
if (action === "wrote") {
|
|
1230
|
-
|
|
1231
|
-
if (
|
|
1386
|
+
mkdirSync7(skillDir, { recursive: true });
|
|
1387
|
+
if (existsSync10(skillFile)) {
|
|
1232
1388
|
try {
|
|
1233
1389
|
renameSync3(skillFile, `${skillFile}.bak`);
|
|
1234
1390
|
} catch {
|
|
1235
1391
|
}
|
|
1236
1392
|
}
|
|
1237
|
-
|
|
1393
|
+
writeFileSync6(skillFile, renderSkillFile(row));
|
|
1238
1394
|
const symlinks = opts.install === "global" ? fanOutSymlinks(skillDir, dirName, detectAgentSkillsRoots(root)) : [];
|
|
1239
1395
|
try {
|
|
1240
1396
|
recordPull({
|
|
@@ -1330,7 +1486,7 @@ async function autoPullSkills(deps = {}) {
|
|
|
1330
1486
|
|
|
1331
1487
|
// dist/src/hooks/cursor/session-start.js
|
|
1332
1488
|
var log5 = (msg) => log("cursor-session-start", msg);
|
|
1333
|
-
var __bundleDir =
|
|
1489
|
+
var __bundleDir = dirname6(fileURLToPath2(import.meta.url));
|
|
1334
1490
|
var context = `DEEPLAKE MEMORY: Persistent memory at ~/.deeplake/memory/ shared across sessions, users, and agents.
|
|
1335
1491
|
|
|
1336
1492
|
Structure: index.md (start here) \u2192 summaries/*.md \u2192 sessions/*.jsonl (last resort). Do NOT jump straight to JSONL.
|
|
@@ -1350,22 +1506,7 @@ Organization management \u2014 each argument is SEPARATE (do NOT quote subcomman
|
|
|
1350
1506
|
- hivemind remove <user-id> \u2014 remove member
|
|
1351
1507
|
|
|
1352
1508
|
SKILLS (skillify) \u2014 mine + share reusable skills across the org:
|
|
1353
|
-
|
|
1354
|
-
- hivemind skillify pull \u2014 sync project skills from the org table
|
|
1355
|
-
- hivemind skillify pull --user <email> \u2014 only that author's skills
|
|
1356
|
-
- hivemind skillify pull --users a,b,c \u2014 multiple authors (CSV)
|
|
1357
|
-
- hivemind skillify pull --all-users \u2014 explicit "no author filter"
|
|
1358
|
-
- hivemind skillify pull --to project|global \u2014 install location
|
|
1359
|
-
- hivemind skillify pull --dry-run \u2014 preview only
|
|
1360
|
-
- hivemind skillify pull --force \u2014 overwrite local (creates .bak)
|
|
1361
|
-
- hivemind skillify pull <skill-name> \u2014 pull only that skill (combines with --user)
|
|
1362
|
-
- hivemind skillify unpull \u2014 remove every skill previously installed by pull
|
|
1363
|
-
- hivemind skillify unpull --user <email> \u2014 remove only that author's pulls
|
|
1364
|
-
- hivemind skillify unpull --not-mine \u2014 remove all pulls except your own
|
|
1365
|
-
- hivemind skillify unpull --dry-run \u2014 preview without touching disk
|
|
1366
|
-
- hivemind skillify scope <me|team> \u2014 sharing scope for new skills
|
|
1367
|
-
- hivemind skillify install <project|global> \u2014 default install location
|
|
1368
|
-
- hivemind skillify team add|remove|list <name> \u2014 manage team list`;
|
|
1509
|
+
${renderSkillifyCommands()}`;
|
|
1369
1510
|
function resolveSessionId(input) {
|
|
1370
1511
|
return input.session_id ?? input.conversation_id ?? `cursor-${Date.now()}`;
|
|
1371
1512
|
}
|
|
@@ -1404,6 +1545,8 @@ async function main() {
|
|
|
1404
1545
|
const creds = loadCredentials();
|
|
1405
1546
|
if (!creds?.token) {
|
|
1406
1547
|
log5("no credentials found");
|
|
1548
|
+
const auto = maybeAutoMineLocal();
|
|
1549
|
+
log5(`auto-mine: ${auto.triggered ? "triggered (background)" : `skipped (${auto.reason})`}`);
|
|
1407
1550
|
} else {
|
|
1408
1551
|
log5(`credentials loaded: org=${creds.orgName ?? creds.orgId}`);
|
|
1409
1552
|
}
|
|
@@ -1433,9 +1576,12 @@ async function main() {
|
|
|
1433
1576
|
if (current)
|
|
1434
1577
|
versionNotice = `
|
|
1435
1578
|
Hivemind v${current}`;
|
|
1579
|
+
const localMined = countLocalManifestEntries();
|
|
1580
|
+
const localMinedNote = localMined > 0 ? `
|
|
1581
|
+
${localMined} local skill${localMined === 1 ? "" : "s"} from past 'hivemind skillify mine-local' run(s) live in ~/.claude/skills/. Run 'hivemind login' to start sharing new mining results with your team.` : "";
|
|
1436
1582
|
const additionalContext = creds?.token ? `${context}
|
|
1437
1583
|
Logged in to Deeplake as org: ${creds.orgName ?? creds.orgId} (workspace: ${creds.workspaceId ?? "default"})${versionNotice}` : `${context}
|
|
1438
|
-
Not logged in to Deeplake. Run: hivemind login${versionNotice}`;
|
|
1584
|
+
Not logged in to Deeplake. Run: hivemind login${localMinedNote}${versionNotice}`;
|
|
1439
1585
|
console.log(JSON.stringify({ additional_context: additionalContext }));
|
|
1440
1586
|
}
|
|
1441
1587
|
main().catch((e) => {
|