@deeplake/hivemind 0.7.31 → 0.7.33
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 +594 -267
- package/codex/bundle/capture.js +585 -124
- package/codex/bundle/commands/auth-login.js +163 -30
- package/codex/bundle/embeddings/embed-daemon.js +55 -4
- package/codex/bundle/pre-tool-use.js +475 -85
- package/codex/bundle/session-start-setup.js +193 -60
- package/codex/bundle/session-start.js +221 -88
- package/codex/bundle/shell/deeplake-shell.js +458 -68
- package/codex/bundle/stop.js +565 -175
- package/codex/bundle/wiki-worker.js +258 -19
- package/cursor/bundle/capture.js +660 -199
- package/cursor/bundle/commands/auth-login.js +163 -30
- package/cursor/bundle/embeddings/embed-daemon.js +55 -4
- package/cursor/bundle/pre-tool-use.js +460 -70
- package/cursor/bundle/session-start.js +271 -131
- package/cursor/bundle/shell/deeplake-shell.js +458 -68
- package/cursor/bundle/wiki-worker.js +258 -19
- package/hermes/bundle/capture.js +661 -200
- package/hermes/bundle/commands/auth-login.js +163 -30
- package/hermes/bundle/embeddings/embed-daemon.js +55 -4
- package/hermes/bundle/pre-tool-use.js +459 -69
- package/hermes/bundle/session-start.js +268 -128
- package/hermes/bundle/shell/deeplake-shell.js +458 -68
- package/hermes/bundle/wiki-worker.js +258 -19
- package/mcp/bundle/server.js +190 -57
- package/openclaw/dist/index.js +160 -32
- package/openclaw/openclaw.plugin.json +1 -1
- package/openclaw/package.json +1 -1
- package/package.json +1 -1
package/bundle/cli.js
CHANGED
|
@@ -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 existsSync14, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "node:fs";
|
|
21
|
+
import { join as join18 } 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 ?? join18(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 join18(getIndexMarkerDir(), `${markerKey}.json`);
|
|
29
29
|
}
|
|
30
30
|
function hasFreshIndexMarker(markerPath) {
|
|
31
|
-
if (!
|
|
31
|
+
if (!existsSync14(markerPath))
|
|
32
32
|
return false;
|
|
33
33
|
try {
|
|
34
|
-
const raw = JSON.parse(
|
|
34
|
+
const raw = JSON.parse(readFileSync13(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
|
+
mkdirSync5(getIndexMarkerDir(), { recursive: true });
|
|
45
|
+
writeFileSync9(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({
|
|
@@ -3681,42 +3681,137 @@ function uninstallPi() {
|
|
|
3681
3681
|
}
|
|
3682
3682
|
|
|
3683
3683
|
// dist/src/cli/embeddings.js
|
|
3684
|
-
import { copyFileSync as copyFileSync3, chmodSync, existsSync as
|
|
3685
|
-
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
3686
|
-
import {
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3684
|
+
import { copyFileSync as copyFileSync3, chmodSync, existsSync as existsSync11, lstatSync as lstatSync2, readdirSync, readFileSync as readFileSync9, readlinkSync, rmSync as rmSync4, statSync, unlinkSync as unlinkSync5 } from "node:fs";
|
|
3685
|
+
import { execFileSync as execFileSync3, spawnSync } from "node:child_process";
|
|
3686
|
+
import { userInfo } from "node:os";
|
|
3687
|
+
import { join as join12 } from "node:path";
|
|
3688
|
+
|
|
3689
|
+
// dist/src/embeddings/protocol.js
|
|
3690
|
+
var DEFAULT_SOCKET_DIR = "/tmp";
|
|
3691
|
+
var DEFAULT_IDLE_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
3692
|
+
function socketPathFor(uid, dir = DEFAULT_SOCKET_DIR) {
|
|
3693
|
+
return `${dir}/hivemind-embed-${uid}.sock`;
|
|
3694
|
+
}
|
|
3695
|
+
function pidPathFor(uid, dir = DEFAULT_SOCKET_DIR) {
|
|
3696
|
+
return `${dir}/hivemind-embed-${uid}.pid`;
|
|
3697
|
+
}
|
|
3698
|
+
|
|
3699
|
+
// dist/src/user-config.js
|
|
3700
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync2, readFileSync as readFileSync8, renameSync as renameSync2, writeFileSync as writeFileSync6 } from "node:fs";
|
|
3701
|
+
import { homedir as homedir4 } from "node:os";
|
|
3702
|
+
import { dirname as dirname2, join as join11 } from "node:path";
|
|
3703
|
+
var _configPath = () => process.env.HIVEMIND_CONFIG_PATH ?? join11(homedir4(), ".deeplake", "config.json");
|
|
3704
|
+
var _cache = null;
|
|
3705
|
+
var _migrated = false;
|
|
3706
|
+
function readUserConfig() {
|
|
3707
|
+
if (_cache !== null)
|
|
3708
|
+
return _cache;
|
|
3709
|
+
const path = _configPath();
|
|
3710
|
+
if (!existsSync10(path)) {
|
|
3711
|
+
_cache = {};
|
|
3712
|
+
return _cache;
|
|
3713
|
+
}
|
|
3714
|
+
try {
|
|
3715
|
+
const raw = readFileSync8(path, "utf-8");
|
|
3716
|
+
const parsed = JSON.parse(raw);
|
|
3717
|
+
_cache = isPlainObject(parsed) ? parsed : {};
|
|
3718
|
+
} catch {
|
|
3719
|
+
_cache = {};
|
|
3720
|
+
}
|
|
3721
|
+
return _cache;
|
|
3722
|
+
}
|
|
3723
|
+
function writeUserConfig(patch) {
|
|
3724
|
+
const current = readUserConfig();
|
|
3725
|
+
const merged = deepMerge(current, patch);
|
|
3726
|
+
const path = _configPath();
|
|
3727
|
+
const dir = dirname2(path);
|
|
3728
|
+
if (!existsSync10(dir))
|
|
3729
|
+
mkdirSync2(dir, { recursive: true });
|
|
3730
|
+
const tmp = `${path}.tmp.${process.pid}`;
|
|
3731
|
+
writeFileSync6(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
3732
|
+
renameSync2(tmp, path);
|
|
3733
|
+
_cache = merged;
|
|
3734
|
+
return merged;
|
|
3735
|
+
}
|
|
3736
|
+
function getEmbeddingsEnabled() {
|
|
3737
|
+
const cfg = readUserConfig();
|
|
3738
|
+
if (cfg.embeddings && typeof cfg.embeddings.enabled === "boolean") {
|
|
3739
|
+
return cfg.embeddings.enabled;
|
|
3740
|
+
}
|
|
3741
|
+
if (_migrated) {
|
|
3742
|
+
return migrationValueFromEnv();
|
|
3743
|
+
}
|
|
3744
|
+
_migrated = true;
|
|
3745
|
+
const enabled = migrationValueFromEnv();
|
|
3746
|
+
try {
|
|
3747
|
+
writeUserConfig({ embeddings: { enabled } });
|
|
3748
|
+
} catch {
|
|
3749
|
+
_cache = { ...cfg ?? {}, embeddings: { ...cfg?.embeddings ?? {}, enabled } };
|
|
3750
|
+
}
|
|
3751
|
+
return enabled;
|
|
3752
|
+
}
|
|
3753
|
+
function migrationValueFromEnv() {
|
|
3754
|
+
const raw = process.env.HIVEMIND_EMBEDDINGS;
|
|
3755
|
+
if (raw === void 0)
|
|
3756
|
+
return false;
|
|
3757
|
+
if (raw === "false")
|
|
3758
|
+
return false;
|
|
3759
|
+
return true;
|
|
3760
|
+
}
|
|
3761
|
+
function setEmbeddingsEnabled(enabled) {
|
|
3762
|
+
writeUserConfig({ embeddings: { enabled } });
|
|
3763
|
+
}
|
|
3764
|
+
function isPlainObject(value) {
|
|
3765
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3766
|
+
}
|
|
3767
|
+
function deepMerge(base, patch) {
|
|
3768
|
+
const out = { ...base };
|
|
3769
|
+
for (const key of Object.keys(patch)) {
|
|
3770
|
+
const patchVal = patch[key];
|
|
3771
|
+
const baseVal = base[key];
|
|
3772
|
+
if (isPlainObject(patchVal) && isPlainObject(baseVal)) {
|
|
3773
|
+
out[key] = { ...baseVal, ...patchVal };
|
|
3774
|
+
} else if (patchVal !== void 0) {
|
|
3775
|
+
out[key] = patchVal;
|
|
3776
|
+
}
|
|
3777
|
+
}
|
|
3778
|
+
return out;
|
|
3779
|
+
}
|
|
3780
|
+
|
|
3781
|
+
// dist/src/cli/embeddings.js
|
|
3782
|
+
var SHARED_DIR = join12(HOME, ".hivemind", "embed-deps");
|
|
3783
|
+
var SHARED_NODE_MODULES = join12(SHARED_DIR, "node_modules");
|
|
3784
|
+
var SHARED_DAEMON_PATH = join12(SHARED_DIR, "embed-daemon.js");
|
|
3690
3785
|
var TRANSFORMERS_PKG = "@huggingface/transformers";
|
|
3691
3786
|
var TRANSFORMERS_RANGE = "^3.0.0";
|
|
3692
3787
|
function findHivemindInstalls(home = HOME) {
|
|
3693
3788
|
const out = [];
|
|
3694
3789
|
const fixed = [
|
|
3695
|
-
{ id: "codex", pluginDir:
|
|
3696
|
-
{ id: "cursor", pluginDir:
|
|
3697
|
-
{ id: "hermes", pluginDir:
|
|
3790
|
+
{ id: "codex", pluginDir: join12(home, ".codex", "hivemind") },
|
|
3791
|
+
{ id: "cursor", pluginDir: join12(home, ".cursor", "hivemind") },
|
|
3792
|
+
{ id: "hermes", pluginDir: join12(home, ".hermes", "hivemind") }
|
|
3698
3793
|
];
|
|
3699
3794
|
for (const inst of fixed) {
|
|
3700
|
-
if (
|
|
3795
|
+
if (existsSync11(join12(inst.pluginDir, "bundle")))
|
|
3701
3796
|
out.push(inst);
|
|
3702
3797
|
}
|
|
3703
|
-
const ccCache =
|
|
3704
|
-
if (
|
|
3798
|
+
const ccCache = join12(home, ".claude", "plugins", "cache", "hivemind", "hivemind");
|
|
3799
|
+
if (existsSync11(ccCache)) {
|
|
3705
3800
|
let entries = [];
|
|
3706
3801
|
try {
|
|
3707
3802
|
entries = readdirSync(ccCache);
|
|
3708
3803
|
} catch {
|
|
3709
3804
|
}
|
|
3710
3805
|
for (const ver of entries) {
|
|
3711
|
-
const dir =
|
|
3806
|
+
const dir = join12(ccCache, ver);
|
|
3712
3807
|
try {
|
|
3713
3808
|
if (!statSync(dir).isDirectory())
|
|
3714
3809
|
continue;
|
|
3715
3810
|
} catch {
|
|
3716
3811
|
continue;
|
|
3717
3812
|
}
|
|
3718
|
-
const candidates = [
|
|
3719
|
-
if (candidates.some((p) =>
|
|
3813
|
+
const candidates = [join12(dir, "bundle"), join12(dir, "claude-code", "bundle")];
|
|
3814
|
+
if (candidates.some((p) => existsSync11(p))) {
|
|
3720
3815
|
out.push({ id: `claude (${ver})`, pluginDir: dir });
|
|
3721
3816
|
}
|
|
3722
3817
|
}
|
|
@@ -3724,10 +3819,10 @@ function findHivemindInstalls(home = HOME) {
|
|
|
3724
3819
|
return out;
|
|
3725
3820
|
}
|
|
3726
3821
|
function isSharedDepsInstalled(sharedNodeModules = SHARED_NODE_MODULES) {
|
|
3727
|
-
return
|
|
3822
|
+
return existsSync11(join12(sharedNodeModules, TRANSFORMERS_PKG));
|
|
3728
3823
|
}
|
|
3729
3824
|
function isSymlinkToSharedDeps(linkPath, sharedNodeModules) {
|
|
3730
|
-
if (!
|
|
3825
|
+
if (!existsSync11(linkPath))
|
|
3731
3826
|
return false;
|
|
3732
3827
|
try {
|
|
3733
3828
|
if (!lstatSync2(linkPath).isSymbolicLink())
|
|
@@ -3738,8 +3833,8 @@ function isSymlinkToSharedDeps(linkPath, sharedNodeModules) {
|
|
|
3738
3833
|
}
|
|
3739
3834
|
}
|
|
3740
3835
|
function linkStateFor(install, sharedNodeModules = SHARED_NODE_MODULES) {
|
|
3741
|
-
const link =
|
|
3742
|
-
if (!
|
|
3836
|
+
const link = join12(install.pluginDir, "node_modules");
|
|
3837
|
+
if (!existsSync11(link) && !isSymbolicLink(link))
|
|
3743
3838
|
return { kind: "no-node-modules" };
|
|
3744
3839
|
try {
|
|
3745
3840
|
if (lstatSync2(link).isSymbolicLink()) {
|
|
@@ -3763,7 +3858,7 @@ function ensureSharedDeps() {
|
|
|
3763
3858
|
log(` Embeddings installing ${TRANSFORMERS_PKG}@${TRANSFORMERS_RANGE} into ${SHARED_DIR}`);
|
|
3764
3859
|
log(` (~600 MB; first install only \u2014 every agent will share this)`);
|
|
3765
3860
|
ensureDir(SHARED_DIR);
|
|
3766
|
-
writeJson(
|
|
3861
|
+
writeJson(join12(SHARED_DIR, "package.json"), {
|
|
3767
3862
|
name: "hivemind-embed-deps",
|
|
3768
3863
|
version: "1.0.0",
|
|
3769
3864
|
private: true,
|
|
@@ -3777,8 +3872,8 @@ function ensureSharedDeps() {
|
|
|
3777
3872
|
log(` Embeddings shared deps already present at ${SHARED_DIR}`);
|
|
3778
3873
|
}
|
|
3779
3874
|
ensureDir(SHARED_DIR);
|
|
3780
|
-
const src =
|
|
3781
|
-
if (
|
|
3875
|
+
const src = join12(pkgRoot(), "embeddings", "embed-daemon.js");
|
|
3876
|
+
if (existsSync11(src)) {
|
|
3782
3877
|
copyFileSync3(src, SHARED_DAEMON_PATH);
|
|
3783
3878
|
chmodSync(SHARED_DAEMON_PATH, 493);
|
|
3784
3879
|
} else {
|
|
@@ -3786,40 +3881,115 @@ function ensureSharedDeps() {
|
|
|
3786
3881
|
}
|
|
3787
3882
|
}
|
|
3788
3883
|
function linkAgent(install) {
|
|
3789
|
-
const link =
|
|
3884
|
+
const link = join12(install.pluginDir, "node_modules");
|
|
3885
|
+
const state = linkStateFor(install);
|
|
3886
|
+
if (state.kind === "owns-own-node-modules") {
|
|
3887
|
+
warn(` Embeddings ${install.id.padEnd(20)} owns its own node_modules \u2014 skipping symlink (status: owns-own-node-modules)`);
|
|
3888
|
+
return;
|
|
3889
|
+
}
|
|
3790
3890
|
symlinkForce(SHARED_NODE_MODULES, link);
|
|
3791
3891
|
log(` Embeddings linked ${install.id.padEnd(20)} -> shared deps`);
|
|
3792
3892
|
}
|
|
3793
|
-
function
|
|
3893
|
+
function installEmbeddings() {
|
|
3794
3894
|
ensureSharedDeps();
|
|
3795
3895
|
const installs = findHivemindInstalls();
|
|
3796
3896
|
if (installs.length === 0) {
|
|
3797
3897
|
warn(" Embeddings no hivemind installs detected \u2014 run `hivemind install` first");
|
|
3798
3898
|
warn(" (the shared deps are in place; subsequent agent installs will pick them up if you re-run `hivemind embeddings install`)");
|
|
3799
|
-
|
|
3899
|
+
} else {
|
|
3900
|
+
for (const inst of installs)
|
|
3901
|
+
linkAgent(inst);
|
|
3902
|
+
}
|
|
3903
|
+
setEmbeddingsEnabled(true);
|
|
3904
|
+
log(` Embeddings enabled in ~/.deeplake/config.json`);
|
|
3905
|
+
log(` Embeddings ready. Restart your agents to pick up.`);
|
|
3906
|
+
}
|
|
3907
|
+
function enableEmbeddings() {
|
|
3908
|
+
setEmbeddingsEnabled(true);
|
|
3909
|
+
log(` Embeddings enabled in ~/.deeplake/config.json`);
|
|
3910
|
+
if (!isSharedDepsInstalled()) {
|
|
3911
|
+
warn(` Embeddings shared deps not installed yet \u2014 run \`hivemind embeddings install\` to download them`);
|
|
3912
|
+
} else {
|
|
3913
|
+
log(` Embeddings shared deps present \u2014 sessions will start producing embeddings on next restart`);
|
|
3800
3914
|
}
|
|
3801
|
-
for (const inst of installs)
|
|
3802
|
-
linkAgent(inst);
|
|
3803
|
-
log(` Embeddings enabled. Restart your agents to pick up.`);
|
|
3804
3915
|
}
|
|
3805
|
-
function
|
|
3916
|
+
function uninstallEmbeddings(opts) {
|
|
3806
3917
|
const installs = findHivemindInstalls();
|
|
3807
3918
|
for (const inst of installs) {
|
|
3808
|
-
const link =
|
|
3919
|
+
const link = join12(inst.pluginDir, "node_modules");
|
|
3809
3920
|
if (isSymlinkToSharedDeps(link, SHARED_NODE_MODULES)) {
|
|
3810
3921
|
unlinkSync5(link);
|
|
3811
3922
|
log(` Embeddings unlinked ${inst.id}`);
|
|
3812
3923
|
}
|
|
3813
3924
|
}
|
|
3814
|
-
if (opts?.prune &&
|
|
3925
|
+
if (opts?.prune && existsSync11(SHARED_DIR)) {
|
|
3815
3926
|
rmSync4(SHARED_DIR, { recursive: true, force: true });
|
|
3816
3927
|
log(` Embeddings pruned ${SHARED_DIR}`);
|
|
3817
3928
|
}
|
|
3929
|
+
setEmbeddingsEnabled(false);
|
|
3930
|
+
killEmbedDaemon();
|
|
3931
|
+
log(` Embeddings disabled in ~/.deeplake/config.json`);
|
|
3932
|
+
}
|
|
3933
|
+
function disableEmbeddings() {
|
|
3934
|
+
setEmbeddingsEnabled(false);
|
|
3935
|
+
killEmbedDaemon();
|
|
3936
|
+
log(` Embeddings disabled in ~/.deeplake/config.json`);
|
|
3937
|
+
log(` Embeddings daemon terminated; shared deps preserved (run \`hivemind embeddings uninstall\` to remove)`);
|
|
3938
|
+
}
|
|
3939
|
+
function killEmbedDaemon(socketDir) {
|
|
3940
|
+
const uid = typeof process.getuid === "function" ? process.getuid() : userInfo().uid;
|
|
3941
|
+
const pidPath = pidPathFor(String(uid), socketDir);
|
|
3942
|
+
const sockPath = socketPathFor(String(uid), socketDir);
|
|
3943
|
+
let pid = null;
|
|
3944
|
+
try {
|
|
3945
|
+
pid = Number.parseInt(readFileSync9(pidPath, "utf-8").trim(), 10);
|
|
3946
|
+
} catch {
|
|
3947
|
+
}
|
|
3948
|
+
if (pid !== null && Number.isFinite(pid) && _isDaemonAliveOnSocket(sockPath)) {
|
|
3949
|
+
try {
|
|
3950
|
+
process.kill(pid, "SIGTERM");
|
|
3951
|
+
} catch {
|
|
3952
|
+
}
|
|
3953
|
+
} else if (pid !== null) {
|
|
3954
|
+
log(` Embeddings pidfile present but socket dead \u2014 skipping SIGTERM on possibly-stale pid ${pid}`);
|
|
3955
|
+
}
|
|
3956
|
+
try {
|
|
3957
|
+
unlinkSync5(sockPath);
|
|
3958
|
+
} catch {
|
|
3959
|
+
}
|
|
3960
|
+
try {
|
|
3961
|
+
unlinkSync5(pidPath);
|
|
3962
|
+
} catch {
|
|
3963
|
+
}
|
|
3964
|
+
}
|
|
3965
|
+
function _isDaemonAliveOnSocket(sockPath, timeoutMs = 200) {
|
|
3966
|
+
if (!existsSync11(sockPath))
|
|
3967
|
+
return false;
|
|
3968
|
+
try {
|
|
3969
|
+
const child = spawnSync("node", [
|
|
3970
|
+
"-e",
|
|
3971
|
+
`const n=require("node:net");const s=n.connect(${JSON.stringify(sockPath)});s.once("connect",()=>{s.end();process.exit(0)});s.once("error",()=>process.exit(2));setTimeout(()=>process.exit(3),${timeoutMs});`
|
|
3972
|
+
], { timeout: timeoutMs + 1e3, stdio: "ignore" });
|
|
3973
|
+
return child.status === 0;
|
|
3974
|
+
} catch {
|
|
3975
|
+
return false;
|
|
3976
|
+
}
|
|
3818
3977
|
}
|
|
3819
3978
|
function statusEmbeddings() {
|
|
3979
|
+
const enabled = getEmbeddingsEnabled();
|
|
3980
|
+
log(`Config: ~/.deeplake/config.json embeddings.enabled = ${enabled}`);
|
|
3820
3981
|
log(`Shared deps: ${SHARED_DIR}`);
|
|
3821
3982
|
log(`Installed: ${isSharedDepsInstalled() ? "yes" : "no"}`);
|
|
3822
|
-
log(`Daemon: ${
|
|
3983
|
+
log(`Daemon: ${existsSync11(SHARED_DAEMON_PATH) ? SHARED_DAEMON_PATH : "(not present)"}`);
|
|
3984
|
+
if (!enabled) {
|
|
3985
|
+
log("");
|
|
3986
|
+
log(`Embeddings are DISABLED in user config. Run \`hivemind embeddings enable\` to opt in,`);
|
|
3987
|
+
log(`or \`hivemind embeddings install\` if the shared deps are not yet downloaded.`);
|
|
3988
|
+
} else if (!isSharedDepsInstalled()) {
|
|
3989
|
+
log("");
|
|
3990
|
+
warn(`Embeddings are enabled in config but shared deps are missing.`);
|
|
3991
|
+
warn(`Run \`hivemind embeddings install\` to download @huggingface/transformers.`);
|
|
3992
|
+
}
|
|
3823
3993
|
log("");
|
|
3824
3994
|
log(`Agent installs:`);
|
|
3825
3995
|
const installs = findHivemindInstalls();
|
|
@@ -3835,7 +4005,7 @@ function statusEmbeddings() {
|
|
|
3835
4005
|
label = "\u2713 linked \u2192 shared";
|
|
3836
4006
|
break;
|
|
3837
4007
|
case "no-node-modules":
|
|
3838
|
-
label = "\u2717 not linked
|
|
4008
|
+
label = "\u2717 not linked";
|
|
3839
4009
|
break;
|
|
3840
4010
|
case "owns-own-node-modules":
|
|
3841
4011
|
label = "\u25B3 has its own node_modules (not shared)";
|
|
@@ -3850,8 +4020,8 @@ function statusEmbeddings() {
|
|
|
3850
4020
|
}
|
|
3851
4021
|
|
|
3852
4022
|
// dist/src/cli/auth.js
|
|
3853
|
-
import { existsSync as
|
|
3854
|
-
import { join as
|
|
4023
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
4024
|
+
import { join as join14 } from "node:path";
|
|
3855
4025
|
|
|
3856
4026
|
// dist/src/commands/auth.js
|
|
3857
4027
|
import { execSync } from "node:child_process";
|
|
@@ -3866,25 +4036,25 @@ function deeplakeClientHeader() {
|
|
|
3866
4036
|
}
|
|
3867
4037
|
|
|
3868
4038
|
// dist/src/commands/auth-creds.js
|
|
3869
|
-
import { readFileSync as
|
|
3870
|
-
import { join as
|
|
3871
|
-
import { homedir as
|
|
4039
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync3, unlinkSync as unlinkSync6 } from "node:fs";
|
|
4040
|
+
import { join as join13 } from "node:path";
|
|
4041
|
+
import { homedir as homedir5 } from "node:os";
|
|
3872
4042
|
function configDir() {
|
|
3873
|
-
return
|
|
4043
|
+
return join13(homedir5(), ".deeplake");
|
|
3874
4044
|
}
|
|
3875
4045
|
function credsPath() {
|
|
3876
|
-
return
|
|
4046
|
+
return join13(configDir(), "credentials.json");
|
|
3877
4047
|
}
|
|
3878
4048
|
function loadCredentials() {
|
|
3879
4049
|
try {
|
|
3880
|
-
return JSON.parse(
|
|
4050
|
+
return JSON.parse(readFileSync10(credsPath(), "utf-8"));
|
|
3881
4051
|
} catch {
|
|
3882
4052
|
return null;
|
|
3883
4053
|
}
|
|
3884
4054
|
}
|
|
3885
4055
|
function saveCredentials(creds) {
|
|
3886
|
-
|
|
3887
|
-
|
|
4056
|
+
mkdirSync3(configDir(), { recursive: true, mode: 448 });
|
|
4057
|
+
writeFileSync7(credsPath(), JSON.stringify({ ...creds, savedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), { mode: 384 });
|
|
3888
4058
|
}
|
|
3889
4059
|
function deleteCredentials() {
|
|
3890
4060
|
try {
|
|
@@ -4073,9 +4243,9 @@ Using: ${orgName}
|
|
|
4073
4243
|
}
|
|
4074
4244
|
|
|
4075
4245
|
// dist/src/cli/auth.js
|
|
4076
|
-
var CREDS_PATH =
|
|
4246
|
+
var CREDS_PATH = join14(HOME, ".deeplake", "credentials.json");
|
|
4077
4247
|
function isLoggedIn() {
|
|
4078
|
-
return
|
|
4248
|
+
return existsSync12(CREDS_PATH) && loadCredentials() !== null;
|
|
4079
4249
|
}
|
|
4080
4250
|
async function ensureLoggedIn() {
|
|
4081
4251
|
if (isLoggedIn())
|
|
@@ -4108,16 +4278,16 @@ async function maybeShowOrgChoice() {
|
|
|
4108
4278
|
}
|
|
4109
4279
|
|
|
4110
4280
|
// dist/src/config.js
|
|
4111
|
-
import { readFileSync as
|
|
4112
|
-
import { join as
|
|
4113
|
-
import { homedir as
|
|
4281
|
+
import { readFileSync as readFileSync11, existsSync as existsSync13 } from "node:fs";
|
|
4282
|
+
import { join as join15 } from "node:path";
|
|
4283
|
+
import { homedir as homedir6, userInfo as userInfo2 } from "node:os";
|
|
4114
4284
|
function loadConfig() {
|
|
4115
|
-
const home =
|
|
4116
|
-
const credPath =
|
|
4285
|
+
const home = homedir6();
|
|
4286
|
+
const credPath = join15(home, ".deeplake", "credentials.json");
|
|
4117
4287
|
let creds = null;
|
|
4118
|
-
if (
|
|
4288
|
+
if (existsSync13(credPath)) {
|
|
4119
4289
|
try {
|
|
4120
|
-
creds = JSON.parse(
|
|
4290
|
+
creds = JSON.parse(readFileSync11(credPath, "utf-8"));
|
|
4121
4291
|
} catch {
|
|
4122
4292
|
return null;
|
|
4123
4293
|
}
|
|
@@ -4130,13 +4300,13 @@ function loadConfig() {
|
|
|
4130
4300
|
token,
|
|
4131
4301
|
orgId,
|
|
4132
4302
|
orgName: creds?.orgName ?? orgId,
|
|
4133
|
-
userName: creds?.userName ||
|
|
4303
|
+
userName: creds?.userName || userInfo2().username || "unknown",
|
|
4134
4304
|
workspaceId: process.env.HIVEMIND_WORKSPACE_ID ?? creds?.workspaceId ?? "default",
|
|
4135
4305
|
apiUrl: process.env.HIVEMIND_API_URL ?? creds?.apiUrl ?? "https://api.deeplake.ai",
|
|
4136
4306
|
tableName: process.env.HIVEMIND_TABLE ?? "memory",
|
|
4137
4307
|
sessionsTableName: process.env.HIVEMIND_SESSIONS_TABLE ?? "sessions",
|
|
4138
4308
|
skillsTableName: process.env.HIVEMIND_SKILLS_TABLE ?? "skills",
|
|
4139
|
-
memoryPath: process.env.HIVEMIND_MEMORY_PATH ??
|
|
4309
|
+
memoryPath: process.env.HIVEMIND_MEMORY_PATH ?? join15(home, ".deeplake", "memory")
|
|
4140
4310
|
};
|
|
4141
4311
|
}
|
|
4142
4312
|
|
|
@@ -4145,9 +4315,9 @@ import { randomUUID } from "node:crypto";
|
|
|
4145
4315
|
|
|
4146
4316
|
// dist/src/utils/debug.js
|
|
4147
4317
|
import { appendFileSync } from "node:fs";
|
|
4148
|
-
import { join as
|
|
4149
|
-
import { homedir as
|
|
4150
|
-
var LOG =
|
|
4318
|
+
import { join as join16 } from "node:path";
|
|
4319
|
+
import { homedir as homedir7 } from "node:os";
|
|
4320
|
+
var LOG = join16(homedir7(), ".deeplake", "hook-debug.log");
|
|
4151
4321
|
function isDebug() {
|
|
4152
4322
|
return process.env.HIVEMIND_DEBUG === "1";
|
|
4153
4323
|
}
|
|
@@ -4173,6 +4343,107 @@ function sqlIdent(name) {
|
|
|
4173
4343
|
var SUMMARY_EMBEDDING_COL = "summary_embedding";
|
|
4174
4344
|
var MESSAGE_EMBEDDING_COL = "message_embedding";
|
|
4175
4345
|
|
|
4346
|
+
// dist/src/notifications/queue.js
|
|
4347
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync8, renameSync as renameSync3, mkdirSync as mkdirSync4, openSync, closeSync, unlinkSync as unlinkSync7, statSync as statSync2 } from "node:fs";
|
|
4348
|
+
import { join as join17, resolve } from "node:path";
|
|
4349
|
+
import { homedir as homedir8 } from "node:os";
|
|
4350
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
4351
|
+
var log3 = (msg) => log2("notifications-queue", msg);
|
|
4352
|
+
var LOCK_RETRY_MAX = 50;
|
|
4353
|
+
var LOCK_RETRY_BASE_MS = 5;
|
|
4354
|
+
var LOCK_STALE_MS = 5e3;
|
|
4355
|
+
function queuePath() {
|
|
4356
|
+
return join17(homedir8(), ".deeplake", "notifications-queue.json");
|
|
4357
|
+
}
|
|
4358
|
+
function lockPath() {
|
|
4359
|
+
return `${queuePath()}.lock`;
|
|
4360
|
+
}
|
|
4361
|
+
function readQueue() {
|
|
4362
|
+
try {
|
|
4363
|
+
const raw = readFileSync12(queuePath(), "utf-8");
|
|
4364
|
+
const parsed = JSON.parse(raw);
|
|
4365
|
+
if (!parsed || !Array.isArray(parsed.queue)) {
|
|
4366
|
+
log3(`queue malformed \u2192 treating as empty`);
|
|
4367
|
+
return { queue: [] };
|
|
4368
|
+
}
|
|
4369
|
+
return { queue: parsed.queue };
|
|
4370
|
+
} catch {
|
|
4371
|
+
return { queue: [] };
|
|
4372
|
+
}
|
|
4373
|
+
}
|
|
4374
|
+
function _isQueuePathInsideHome(path, home) {
|
|
4375
|
+
const r = resolve(path);
|
|
4376
|
+
const h = resolve(home);
|
|
4377
|
+
return r.startsWith(h + "/") || r === h;
|
|
4378
|
+
}
|
|
4379
|
+
function writeQueue(q) {
|
|
4380
|
+
const path = queuePath();
|
|
4381
|
+
const home = resolve(homedir8());
|
|
4382
|
+
if (!_isQueuePathInsideHome(path, home)) {
|
|
4383
|
+
throw new Error(`notifications-queue write blocked: ${path} is outside ${home}`);
|
|
4384
|
+
}
|
|
4385
|
+
mkdirSync4(join17(home, ".deeplake"), { recursive: true, mode: 448 });
|
|
4386
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
4387
|
+
writeFileSync8(tmp, JSON.stringify(q, null, 2), { mode: 384 });
|
|
4388
|
+
renameSync3(tmp, path);
|
|
4389
|
+
}
|
|
4390
|
+
async function withQueueLock(fn) {
|
|
4391
|
+
const path = lockPath();
|
|
4392
|
+
mkdirSync4(join17(homedir8(), ".deeplake"), { recursive: true, mode: 448 });
|
|
4393
|
+
let fd = null;
|
|
4394
|
+
for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
|
|
4395
|
+
try {
|
|
4396
|
+
fd = openSync(path, "wx", 384);
|
|
4397
|
+
break;
|
|
4398
|
+
} catch (e) {
|
|
4399
|
+
const code = e.code;
|
|
4400
|
+
if (code !== "EEXIST")
|
|
4401
|
+
throw e;
|
|
4402
|
+
try {
|
|
4403
|
+
const age = Date.now() - statSync2(path).mtimeMs;
|
|
4404
|
+
if (age > LOCK_STALE_MS) {
|
|
4405
|
+
unlinkSync7(path);
|
|
4406
|
+
continue;
|
|
4407
|
+
}
|
|
4408
|
+
} catch {
|
|
4409
|
+
}
|
|
4410
|
+
const delay = LOCK_RETRY_BASE_MS * (attempt + 1);
|
|
4411
|
+
await sleep(delay);
|
|
4412
|
+
}
|
|
4413
|
+
}
|
|
4414
|
+
if (fd === null) {
|
|
4415
|
+
log3(`lock acquisition gave up after ${LOCK_RETRY_MAX} attempts \u2014 proceeding unlocked (last-writer-wins)`);
|
|
4416
|
+
return fn();
|
|
4417
|
+
}
|
|
4418
|
+
try {
|
|
4419
|
+
return fn();
|
|
4420
|
+
} finally {
|
|
4421
|
+
try {
|
|
4422
|
+
closeSync(fd);
|
|
4423
|
+
} catch {
|
|
4424
|
+
}
|
|
4425
|
+
try {
|
|
4426
|
+
unlinkSync7(path);
|
|
4427
|
+
} catch {
|
|
4428
|
+
}
|
|
4429
|
+
}
|
|
4430
|
+
}
|
|
4431
|
+
function sameDedupKey(a, b) {
|
|
4432
|
+
if (a.id !== b.id)
|
|
4433
|
+
return false;
|
|
4434
|
+
return JSON.stringify(a.dedupKey) === JSON.stringify(b.dedupKey);
|
|
4435
|
+
}
|
|
4436
|
+
async function enqueueNotification(n) {
|
|
4437
|
+
await withQueueLock(() => {
|
|
4438
|
+
const q = readQueue();
|
|
4439
|
+
if (q.queue.some((existing) => sameDedupKey(existing, n))) {
|
|
4440
|
+
return;
|
|
4441
|
+
}
|
|
4442
|
+
q.queue.push(n);
|
|
4443
|
+
writeQueue(q);
|
|
4444
|
+
});
|
|
4445
|
+
}
|
|
4446
|
+
|
|
4176
4447
|
// dist/src/deeplake-api.js
|
|
4177
4448
|
var indexMarkerStorePromise = null;
|
|
4178
4449
|
function getIndexMarkerStore() {
|
|
@@ -4180,7 +4451,7 @@ function getIndexMarkerStore() {
|
|
|
4180
4451
|
indexMarkerStorePromise = Promise.resolve().then(() => (init_index_marker_store(), index_marker_store_exports));
|
|
4181
4452
|
return indexMarkerStorePromise;
|
|
4182
4453
|
}
|
|
4183
|
-
var
|
|
4454
|
+
var log4 = (msg) => log2("sdk", msg);
|
|
4184
4455
|
function summarizeSql(sql, maxLen = 220) {
|
|
4185
4456
|
const compact = sql.replace(/\s+/g, " ").trim();
|
|
4186
4457
|
return compact.length > maxLen ? `${compact.slice(0, maxLen)}...` : compact;
|
|
@@ -4192,7 +4463,38 @@ function traceSql(msg) {
|
|
|
4192
4463
|
process.stderr.write(`[deeplake-sql] ${msg}
|
|
4193
4464
|
`);
|
|
4194
4465
|
if (process.env.HIVEMIND_DEBUG === "1")
|
|
4195
|
-
|
|
4466
|
+
log4(msg);
|
|
4467
|
+
}
|
|
4468
|
+
var _signalledBalanceExhausted = false;
|
|
4469
|
+
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
4470
|
+
if (status !== 402)
|
|
4471
|
+
return;
|
|
4472
|
+
if (!bodyText.includes("balance_cents"))
|
|
4473
|
+
return;
|
|
4474
|
+
if (_signalledBalanceExhausted)
|
|
4475
|
+
return;
|
|
4476
|
+
_signalledBalanceExhausted = true;
|
|
4477
|
+
log4(`balance exhausted \u2014 enqueuing session-start banner (body=${bodyText.slice(0, 120)})`);
|
|
4478
|
+
enqueueNotification({
|
|
4479
|
+
id: "balance-exhausted",
|
|
4480
|
+
severity: "warn",
|
|
4481
|
+
transient: true,
|
|
4482
|
+
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
4483
|
+
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
4484
|
+
dedupKey: { reason: "balance-zero" }
|
|
4485
|
+
}).catch((e) => {
|
|
4486
|
+
log4(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
4487
|
+
});
|
|
4488
|
+
}
|
|
4489
|
+
function billingUrl() {
|
|
4490
|
+
try {
|
|
4491
|
+
const c = loadCredentials();
|
|
4492
|
+
if (c?.orgName && c?.workspaceId) {
|
|
4493
|
+
return `https://deeplake.ai/${encodeURIComponent(c.orgName)}/workspace/${encodeURIComponent(c.workspaceId)}/billing`;
|
|
4494
|
+
}
|
|
4495
|
+
} catch {
|
|
4496
|
+
}
|
|
4497
|
+
return "https://deeplake.ai";
|
|
4196
4498
|
}
|
|
4197
4499
|
var RETRYABLE_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
4198
4500
|
var MAX_RETRIES = 3;
|
|
@@ -4201,8 +4503,8 @@ var MAX_CONCURRENCY = 5;
|
|
|
4201
4503
|
function getQueryTimeoutMs() {
|
|
4202
4504
|
return Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
|
|
4203
4505
|
}
|
|
4204
|
-
function
|
|
4205
|
-
return new Promise((
|
|
4506
|
+
function sleep2(ms) {
|
|
4507
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
4206
4508
|
}
|
|
4207
4509
|
function isTimeoutError(error) {
|
|
4208
4510
|
const name = error instanceof Error ? error.name.toLowerCase() : "";
|
|
@@ -4232,7 +4534,7 @@ var Semaphore = class {
|
|
|
4232
4534
|
this.active++;
|
|
4233
4535
|
return;
|
|
4234
4536
|
}
|
|
4235
|
-
await new Promise((
|
|
4537
|
+
await new Promise((resolve2) => this.waiting.push(resolve2));
|
|
4236
4538
|
}
|
|
4237
4539
|
release() {
|
|
4238
4540
|
this.active--;
|
|
@@ -4303,8 +4605,8 @@ var DeeplakeApi = class {
|
|
|
4303
4605
|
lastError = e instanceof Error ? e : new Error(String(e));
|
|
4304
4606
|
if (attempt < MAX_RETRIES) {
|
|
4305
4607
|
const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
|
|
4306
|
-
|
|
4307
|
-
await
|
|
4608
|
+
log4(`query retry ${attempt + 1}/${MAX_RETRIES} (fetch error: ${lastError.message}) in ${delay.toFixed(0)}ms`);
|
|
4609
|
+
await sleep2(delay);
|
|
4308
4610
|
continue;
|
|
4309
4611
|
}
|
|
4310
4612
|
throw lastError;
|
|
@@ -4320,10 +4622,11 @@ var DeeplakeApi = class {
|
|
|
4320
4622
|
const alreadyExists = resp.status === 500 && isDuplicateIndexError(text);
|
|
4321
4623
|
if (!alreadyExists && attempt < MAX_RETRIES && (RETRYABLE_CODES.has(resp.status) || retryable403)) {
|
|
4322
4624
|
const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
|
|
4323
|
-
|
|
4324
|
-
await
|
|
4625
|
+
log4(`query retry ${attempt + 1}/${MAX_RETRIES} (${resp.status}) in ${delay.toFixed(0)}ms`);
|
|
4626
|
+
await sleep2(delay);
|
|
4325
4627
|
continue;
|
|
4326
4628
|
}
|
|
4629
|
+
maybeSignalBalanceExhausted(resp.status, text);
|
|
4327
4630
|
throw new Error(`Query failed: ${resp.status}: ${text.slice(0, 200)}`);
|
|
4328
4631
|
}
|
|
4329
4632
|
throw lastError ?? new Error("Query failed: max retries exceeded");
|
|
@@ -4344,7 +4647,7 @@ var DeeplakeApi = class {
|
|
|
4344
4647
|
const chunk = rows.slice(i, i + CONCURRENCY);
|
|
4345
4648
|
await Promise.allSettled(chunk.map((r) => this.upsertRowSql(r)));
|
|
4346
4649
|
}
|
|
4347
|
-
|
|
4650
|
+
log4(`commit: ${rows.length} rows`);
|
|
4348
4651
|
}
|
|
4349
4652
|
async upsertRowSql(row) {
|
|
4350
4653
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -4400,7 +4703,7 @@ var DeeplakeApi = class {
|
|
|
4400
4703
|
markers.writeIndexMarker(markerPath);
|
|
4401
4704
|
return;
|
|
4402
4705
|
}
|
|
4403
|
-
|
|
4706
|
+
log4(`index "${indexName}" skipped: ${e.message}`);
|
|
4404
4707
|
}
|
|
4405
4708
|
}
|
|
4406
4709
|
/**
|
|
@@ -4490,13 +4793,13 @@ var DeeplakeApi = class {
|
|
|
4490
4793
|
};
|
|
4491
4794
|
}
|
|
4492
4795
|
if (attempt < MAX_RETRIES && RETRYABLE_CODES.has(resp.status)) {
|
|
4493
|
-
await
|
|
4796
|
+
await sleep2(BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200);
|
|
4494
4797
|
continue;
|
|
4495
4798
|
}
|
|
4496
4799
|
return { tables: [], cacheable: false };
|
|
4497
4800
|
} catch {
|
|
4498
4801
|
if (attempt < MAX_RETRIES) {
|
|
4499
|
-
await
|
|
4802
|
+
await sleep2(BASE_DELAY_MS * Math.pow(2, attempt));
|
|
4500
4803
|
continue;
|
|
4501
4804
|
}
|
|
4502
4805
|
return { tables: [], cacheable: false };
|
|
@@ -4524,9 +4827,9 @@ var DeeplakeApi = class {
|
|
|
4524
4827
|
} catch (err) {
|
|
4525
4828
|
lastErr = err;
|
|
4526
4829
|
const msg = err instanceof Error ? err.message : String(err);
|
|
4527
|
-
|
|
4830
|
+
log4(`CREATE TABLE "${label}" attempt ${attempt + 1}/${OUTER_BACKOFFS_MS.length + 1} failed: ${msg}`);
|
|
4528
4831
|
if (attempt < OUTER_BACKOFFS_MS.length) {
|
|
4529
|
-
await
|
|
4832
|
+
await sleep2(OUTER_BACKOFFS_MS[attempt]);
|
|
4530
4833
|
}
|
|
4531
4834
|
}
|
|
4532
4835
|
}
|
|
@@ -4537,9 +4840,9 @@ var DeeplakeApi = class {
|
|
|
4537
4840
|
const tbl = sqlIdent(name ?? this.tableName);
|
|
4538
4841
|
const tables = await this.listTables();
|
|
4539
4842
|
if (!tables.includes(tbl)) {
|
|
4540
|
-
|
|
4843
|
+
log4(`table "${tbl}" not found, creating`);
|
|
4541
4844
|
await this.createTableWithRetry(`CREATE TABLE IF NOT EXISTS "${tbl}" (id TEXT NOT NULL DEFAULT '', path TEXT NOT NULL DEFAULT '', filename TEXT NOT NULL DEFAULT '', summary TEXT NOT NULL DEFAULT '', summary_embedding FLOAT4[], author TEXT NOT NULL DEFAULT '', mime_type TEXT NOT NULL DEFAULT 'text/plain', size_bytes BIGINT NOT NULL DEFAULT 0, project TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', agent TEXT NOT NULL DEFAULT '', plugin_version TEXT NOT NULL DEFAULT '', creation_date TEXT NOT NULL DEFAULT '', last_update_date TEXT NOT NULL DEFAULT '') USING deeplake`, tbl);
|
|
4542
|
-
|
|
4845
|
+
log4(`table "${tbl}" created`);
|
|
4543
4846
|
if (!tables.includes(tbl))
|
|
4544
4847
|
this._tablesCache = [...tables, tbl];
|
|
4545
4848
|
}
|
|
@@ -4552,9 +4855,9 @@ var DeeplakeApi = class {
|
|
|
4552
4855
|
const safe = sqlIdent(name);
|
|
4553
4856
|
const tables = await this.listTables();
|
|
4554
4857
|
if (!tables.includes(safe)) {
|
|
4555
|
-
|
|
4858
|
+
log4(`table "${safe}" not found, creating`);
|
|
4556
4859
|
await this.createTableWithRetry(`CREATE TABLE IF NOT EXISTS "${safe}" (id TEXT NOT NULL DEFAULT '', path TEXT NOT NULL DEFAULT '', filename TEXT NOT NULL DEFAULT '', message JSONB, message_embedding FLOAT4[], author TEXT NOT NULL DEFAULT '', mime_type TEXT NOT NULL DEFAULT 'application/json', size_bytes BIGINT NOT NULL DEFAULT 0, project TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', agent TEXT NOT NULL DEFAULT '', plugin_version TEXT NOT NULL DEFAULT '', creation_date TEXT NOT NULL DEFAULT '', last_update_date TEXT NOT NULL DEFAULT '') USING deeplake`, safe);
|
|
4557
|
-
|
|
4860
|
+
log4(`table "${safe}" created`);
|
|
4558
4861
|
if (!tables.includes(safe))
|
|
4559
4862
|
this._tablesCache = [...tables, safe];
|
|
4560
4863
|
}
|
|
@@ -4577,9 +4880,9 @@ var DeeplakeApi = class {
|
|
|
4577
4880
|
const safe = sqlIdent(name);
|
|
4578
4881
|
const tables = await this.listTables();
|
|
4579
4882
|
if (!tables.includes(safe)) {
|
|
4580
|
-
|
|
4883
|
+
log4(`table "${safe}" not found, creating`);
|
|
4581
4884
|
await this.createTableWithRetry(`CREATE TABLE IF NOT EXISTS "${safe}" (id TEXT NOT NULL DEFAULT '', name TEXT NOT NULL DEFAULT '', project TEXT NOT NULL DEFAULT '', project_key TEXT NOT NULL DEFAULT '', local_path TEXT NOT NULL DEFAULT '', install TEXT NOT NULL DEFAULT 'project', source_sessions TEXT NOT NULL DEFAULT '[]', source_agent TEXT NOT NULL DEFAULT '', scope TEXT NOT NULL DEFAULT 'me', author TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', trigger_text TEXT NOT NULL DEFAULT '', body TEXT NOT NULL DEFAULT '', version BIGINT NOT NULL DEFAULT 1, created_at TEXT NOT NULL DEFAULT '', updated_at TEXT NOT NULL DEFAULT '') USING deeplake`, safe);
|
|
4582
|
-
|
|
4885
|
+
log4(`table "${safe}" created`);
|
|
4583
4886
|
if (!tables.includes(safe))
|
|
4584
4887
|
this._tablesCache = [...tables, safe];
|
|
4585
4888
|
}
|
|
@@ -4610,10 +4913,10 @@ function parseArgs(argv) {
|
|
|
4610
4913
|
}
|
|
4611
4914
|
function confirm(message) {
|
|
4612
4915
|
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
4613
|
-
return new Promise((
|
|
4916
|
+
return new Promise((resolve2) => {
|
|
4614
4917
|
rl.question(`${message} [y/N] `, (answer) => {
|
|
4615
4918
|
rl.close();
|
|
4616
|
-
|
|
4919
|
+
resolve2(answer.trim().toLowerCase() === "y");
|
|
4617
4920
|
});
|
|
4618
4921
|
});
|
|
4619
4922
|
}
|
|
@@ -4915,34 +5218,34 @@ if (process.argv[1] && process.argv[1].endsWith("auth-login.js")) {
|
|
|
4915
5218
|
}
|
|
4916
5219
|
|
|
4917
5220
|
// dist/src/commands/skillify.js
|
|
4918
|
-
import { readdirSync as readdirSync5, existsSync as
|
|
4919
|
-
import { homedir as
|
|
4920
|
-
import { dirname as
|
|
5221
|
+
import { readdirSync as readdirSync5, existsSync as existsSync26, readFileSync as readFileSync21, mkdirSync as mkdirSync12, renameSync as renameSync7 } from "node:fs";
|
|
5222
|
+
import { homedir as homedir20 } from "node:os";
|
|
5223
|
+
import { dirname as dirname7, join as join30 } from "node:path";
|
|
4921
5224
|
|
|
4922
5225
|
// dist/src/skillify/scope-config.js
|
|
4923
|
-
import { existsSync as
|
|
4924
|
-
import { homedir as
|
|
4925
|
-
import { join as
|
|
5226
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync6, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "node:fs";
|
|
5227
|
+
import { homedir as homedir10 } from "node:os";
|
|
5228
|
+
import { join as join20 } from "node:path";
|
|
4926
5229
|
|
|
4927
5230
|
// dist/src/skillify/legacy-migration.js
|
|
4928
|
-
import { existsSync as
|
|
4929
|
-
import { homedir as
|
|
4930
|
-
import { join as
|
|
5231
|
+
import { existsSync as existsSync15, renameSync as renameSync4 } from "node:fs";
|
|
5232
|
+
import { homedir as homedir9 } from "node:os";
|
|
5233
|
+
import { join as join19 } from "node:path";
|
|
4931
5234
|
var dlog = (msg) => log2("skillify-migrate", msg);
|
|
4932
5235
|
var attempted = false;
|
|
4933
5236
|
function migrateLegacyStateDir() {
|
|
4934
5237
|
if (attempted)
|
|
4935
5238
|
return;
|
|
4936
5239
|
attempted = true;
|
|
4937
|
-
const root =
|
|
4938
|
-
const legacy =
|
|
4939
|
-
const current =
|
|
4940
|
-
if (!
|
|
5240
|
+
const root = join19(homedir9(), ".deeplake", "state");
|
|
5241
|
+
const legacy = join19(root, "skilify");
|
|
5242
|
+
const current = join19(root, "skillify");
|
|
5243
|
+
if (!existsSync15(legacy))
|
|
4941
5244
|
return;
|
|
4942
|
-
if (
|
|
5245
|
+
if (existsSync15(current))
|
|
4943
5246
|
return;
|
|
4944
5247
|
try {
|
|
4945
|
-
|
|
5248
|
+
renameSync4(legacy, current);
|
|
4946
5249
|
dlog(`migrated ${legacy} -> ${current}`);
|
|
4947
5250
|
} catch (err) {
|
|
4948
5251
|
const code = err.code;
|
|
@@ -4955,15 +5258,15 @@ function migrateLegacyStateDir() {
|
|
|
4955
5258
|
}
|
|
4956
5259
|
|
|
4957
5260
|
// dist/src/skillify/scope-config.js
|
|
4958
|
-
var STATE_DIR =
|
|
4959
|
-
var CONFIG_PATH2 =
|
|
5261
|
+
var STATE_DIR = join20(homedir10(), ".deeplake", "state", "skillify");
|
|
5262
|
+
var CONFIG_PATH2 = join20(STATE_DIR, "config.json");
|
|
4960
5263
|
var DEFAULT = { scope: "me", team: [], install: "project" };
|
|
4961
5264
|
function loadScopeConfig() {
|
|
4962
5265
|
migrateLegacyStateDir();
|
|
4963
|
-
if (!
|
|
5266
|
+
if (!existsSync16(CONFIG_PATH2))
|
|
4964
5267
|
return DEFAULT;
|
|
4965
5268
|
try {
|
|
4966
|
-
const raw = JSON.parse(
|
|
5269
|
+
const raw = JSON.parse(readFileSync14(CONFIG_PATH2, "utf-8"));
|
|
4967
5270
|
const scope = raw.scope === "team" ? "team" : raw.scope === "org" ? "team" : "me";
|
|
4968
5271
|
const team = Array.isArray(raw.team) ? raw.team.filter((s) => typeof s === "string") : [];
|
|
4969
5272
|
const install = raw.install === "global" ? "global" : "project";
|
|
@@ -4974,19 +5277,19 @@ function loadScopeConfig() {
|
|
|
4974
5277
|
}
|
|
4975
5278
|
function saveScopeConfig(cfg) {
|
|
4976
5279
|
migrateLegacyStateDir();
|
|
4977
|
-
|
|
4978
|
-
|
|
5280
|
+
mkdirSync6(STATE_DIR, { recursive: true });
|
|
5281
|
+
writeFileSync10(CONFIG_PATH2, JSON.stringify(cfg, null, 2));
|
|
4979
5282
|
}
|
|
4980
5283
|
|
|
4981
5284
|
// dist/src/skillify/pull.js
|
|
4982
|
-
import { existsSync as
|
|
4983
|
-
import { homedir as
|
|
4984
|
-
import { dirname as
|
|
5285
|
+
import { existsSync as existsSync20, readFileSync as readFileSync17, writeFileSync as writeFileSync13, mkdirSync as mkdirSync9, renameSync as renameSync6, lstatSync as lstatSync4, readlinkSync as readlinkSync2, symlinkSync as symlinkSync2, unlinkSync as unlinkSync9 } from "node:fs";
|
|
5286
|
+
import { homedir as homedir14 } from "node:os";
|
|
5287
|
+
import { dirname as dirname4, join as join24 } from "node:path";
|
|
4985
5288
|
|
|
4986
5289
|
// dist/src/skillify/skill-writer.js
|
|
4987
|
-
import { existsSync as
|
|
4988
|
-
import { homedir as
|
|
4989
|
-
import { join as
|
|
5290
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync7, readFileSync as readFileSync15, readdirSync as readdirSync2, statSync as statSync3, writeFileSync as writeFileSync11 } from "node:fs";
|
|
5291
|
+
import { homedir as homedir11 } from "node:os";
|
|
5292
|
+
import { join as join21 } from "node:path";
|
|
4990
5293
|
function assertValidSkillName(name) {
|
|
4991
5294
|
if (typeof name !== "string" || name.length === 0) {
|
|
4992
5295
|
throw new Error(`invalid skill name: empty or non-string`);
|
|
@@ -5002,10 +5305,10 @@ function assertValidSkillName(name) {
|
|
|
5002
5305
|
}
|
|
5003
5306
|
}
|
|
5004
5307
|
function skillDir(skillsRoot, name) {
|
|
5005
|
-
return
|
|
5308
|
+
return join21(skillsRoot, name);
|
|
5006
5309
|
}
|
|
5007
5310
|
function skillPath(skillsRoot, name) {
|
|
5008
|
-
return
|
|
5311
|
+
return join21(skillDir(skillsRoot, name), "SKILL.md");
|
|
5009
5312
|
}
|
|
5010
5313
|
function renderFrontmatter(fm) {
|
|
5011
5314
|
const lines = ["---"];
|
|
@@ -5083,10 +5386,10 @@ function writeNewSkill(args) {
|
|
|
5083
5386
|
assertValidSkillName(args.name);
|
|
5084
5387
|
const dir = skillDir(args.skillsRoot, args.name);
|
|
5085
5388
|
const path = skillPath(args.skillsRoot, args.name);
|
|
5086
|
-
if (
|
|
5389
|
+
if (existsSync17(path)) {
|
|
5087
5390
|
throw new Error(`skill already exists at ${path}; use mergeSkill`);
|
|
5088
5391
|
}
|
|
5089
|
-
|
|
5392
|
+
mkdirSync7(dir, { recursive: true });
|
|
5090
5393
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
5091
5394
|
const author = args.author && args.author.length > 0 ? args.author : void 0;
|
|
5092
5395
|
const contributors = author ? [author] : [];
|
|
@@ -5106,7 +5409,7 @@ function writeNewSkill(args) {
|
|
|
5106
5409
|
|
|
5107
5410
|
${args.body.trim()}
|
|
5108
5411
|
`;
|
|
5109
|
-
|
|
5412
|
+
writeFileSync11(path, text);
|
|
5110
5413
|
return {
|
|
5111
5414
|
path,
|
|
5112
5415
|
action: "created",
|
|
@@ -5118,41 +5421,41 @@ ${args.body.trim()}
|
|
|
5118
5421
|
};
|
|
5119
5422
|
}
|
|
5120
5423
|
function listSkills(skillsRoot) {
|
|
5121
|
-
if (!
|
|
5424
|
+
if (!existsSync17(skillsRoot))
|
|
5122
5425
|
return [];
|
|
5123
5426
|
const out = [];
|
|
5124
5427
|
for (const name of readdirSync2(skillsRoot)) {
|
|
5125
|
-
const skillFile =
|
|
5126
|
-
if (
|
|
5127
|
-
out.push({ name, body:
|
|
5428
|
+
const skillFile = join21(skillsRoot, name, "SKILL.md");
|
|
5429
|
+
if (existsSync17(skillFile) && statSync3(skillFile).isFile()) {
|
|
5430
|
+
out.push({ name, body: readFileSync15(skillFile, "utf-8") });
|
|
5128
5431
|
}
|
|
5129
5432
|
}
|
|
5130
5433
|
return out;
|
|
5131
5434
|
}
|
|
5132
5435
|
function resolveSkillsRoot(install, cwd) {
|
|
5133
5436
|
if (install === "global") {
|
|
5134
|
-
return
|
|
5437
|
+
return join21(homedir11(), ".claude", "skills");
|
|
5135
5438
|
}
|
|
5136
|
-
return
|
|
5439
|
+
return join21(cwd, ".claude", "skills");
|
|
5137
5440
|
}
|
|
5138
5441
|
|
|
5139
5442
|
// dist/src/skillify/manifest.js
|
|
5140
|
-
import { existsSync as
|
|
5141
|
-
import { homedir as
|
|
5142
|
-
import { dirname as
|
|
5443
|
+
import { existsSync as existsSync18, lstatSync as lstatSync3, mkdirSync as mkdirSync8, readFileSync as readFileSync16, renameSync as renameSync5, unlinkSync as unlinkSync8, writeFileSync as writeFileSync12 } from "node:fs";
|
|
5444
|
+
import { homedir as homedir12 } from "node:os";
|
|
5445
|
+
import { dirname as dirname3, join as join22 } from "node:path";
|
|
5143
5446
|
function emptyManifest() {
|
|
5144
5447
|
return { version: 1, entries: [] };
|
|
5145
5448
|
}
|
|
5146
5449
|
function manifestPath() {
|
|
5147
|
-
return
|
|
5450
|
+
return join22(homedir12(), ".deeplake", "state", "skillify", "pulled.json");
|
|
5148
5451
|
}
|
|
5149
5452
|
function loadManifest(path = manifestPath()) {
|
|
5150
5453
|
migrateLegacyStateDir();
|
|
5151
|
-
if (!
|
|
5454
|
+
if (!existsSync18(path))
|
|
5152
5455
|
return emptyManifest();
|
|
5153
5456
|
let raw;
|
|
5154
5457
|
try {
|
|
5155
|
-
raw =
|
|
5458
|
+
raw = readFileSync16(path, "utf-8");
|
|
5156
5459
|
} catch {
|
|
5157
5460
|
return emptyManifest();
|
|
5158
5461
|
}
|
|
@@ -5199,10 +5502,10 @@ function loadManifest(path = manifestPath()) {
|
|
|
5199
5502
|
}
|
|
5200
5503
|
function saveManifest(m, path = manifestPath()) {
|
|
5201
5504
|
migrateLegacyStateDir();
|
|
5202
|
-
|
|
5505
|
+
mkdirSync8(dirname3(path), { recursive: true });
|
|
5203
5506
|
const tmp = `${path}.tmp`;
|
|
5204
|
-
|
|
5205
|
-
|
|
5507
|
+
writeFileSync12(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
|
|
5508
|
+
renameSync5(tmp, path);
|
|
5206
5509
|
}
|
|
5207
5510
|
function recordPull(entry, path = manifestPath()) {
|
|
5208
5511
|
const m = loadManifest(path);
|
|
@@ -5234,7 +5537,7 @@ function unlinkSymlinks(paths) {
|
|
|
5234
5537
|
if (!st.isSymbolicLink())
|
|
5235
5538
|
continue;
|
|
5236
5539
|
try {
|
|
5237
|
-
|
|
5540
|
+
unlinkSync8(path);
|
|
5238
5541
|
} catch {
|
|
5239
5542
|
}
|
|
5240
5543
|
}
|
|
@@ -5244,7 +5547,7 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
5244
5547
|
const live = [];
|
|
5245
5548
|
let pruned = 0;
|
|
5246
5549
|
for (const e of m.entries) {
|
|
5247
|
-
if (
|
|
5550
|
+
if (existsSync18(join22(e.installRoot, e.dirName))) {
|
|
5248
5551
|
live.push(e);
|
|
5249
5552
|
continue;
|
|
5250
5553
|
}
|
|
@@ -5257,26 +5560,26 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
5257
5560
|
}
|
|
5258
5561
|
|
|
5259
5562
|
// dist/src/skillify/agent-roots.js
|
|
5260
|
-
import { existsSync as
|
|
5261
|
-
import { homedir as
|
|
5262
|
-
import { join as
|
|
5563
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
5564
|
+
import { homedir as homedir13 } from "node:os";
|
|
5565
|
+
import { join as join23 } from "node:path";
|
|
5263
5566
|
function resolveDetected(home) {
|
|
5264
5567
|
const out = [];
|
|
5265
|
-
const codexInstalled =
|
|
5266
|
-
const piInstalled =
|
|
5267
|
-
const hermesInstalled =
|
|
5568
|
+
const codexInstalled = existsSync19(join23(home, ".codex"));
|
|
5569
|
+
const piInstalled = existsSync19(join23(home, ".pi", "agent"));
|
|
5570
|
+
const hermesInstalled = existsSync19(join23(home, ".hermes"));
|
|
5268
5571
|
if (codexInstalled || piInstalled) {
|
|
5269
|
-
out.push(
|
|
5572
|
+
out.push(join23(home, ".agents", "skills"));
|
|
5270
5573
|
}
|
|
5271
5574
|
if (hermesInstalled) {
|
|
5272
|
-
out.push(
|
|
5575
|
+
out.push(join23(home, ".hermes", "skills"));
|
|
5273
5576
|
}
|
|
5274
5577
|
if (piInstalled) {
|
|
5275
|
-
out.push(
|
|
5578
|
+
out.push(join23(home, ".pi", "agent", "skills"));
|
|
5276
5579
|
}
|
|
5277
5580
|
return out;
|
|
5278
5581
|
}
|
|
5279
|
-
function detectAgentSkillsRoots(canonicalRoot, home =
|
|
5582
|
+
function detectAgentSkillsRoots(canonicalRoot, home = homedir13()) {
|
|
5280
5583
|
return resolveDetected(home).filter((p) => p !== canonicalRoot);
|
|
5281
5584
|
}
|
|
5282
5585
|
|
|
@@ -5320,15 +5623,15 @@ function isMissingTableError(message) {
|
|
|
5320
5623
|
}
|
|
5321
5624
|
function resolvePullDestination(install, cwd) {
|
|
5322
5625
|
if (install === "global")
|
|
5323
|
-
return
|
|
5626
|
+
return join24(homedir14(), ".claude", "skills");
|
|
5324
5627
|
if (!cwd)
|
|
5325
5628
|
throw new Error("install=project requires a cwd");
|
|
5326
|
-
return
|
|
5629
|
+
return join24(cwd, ".claude", "skills");
|
|
5327
5630
|
}
|
|
5328
5631
|
function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
|
|
5329
5632
|
const out = [];
|
|
5330
5633
|
for (const root of agentRoots) {
|
|
5331
|
-
const link =
|
|
5634
|
+
const link = join24(root, dirName);
|
|
5332
5635
|
let existing;
|
|
5333
5636
|
try {
|
|
5334
5637
|
existing = lstatSync4(link);
|
|
@@ -5350,13 +5653,13 @@ function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
|
|
|
5350
5653
|
continue;
|
|
5351
5654
|
}
|
|
5352
5655
|
try {
|
|
5353
|
-
|
|
5656
|
+
unlinkSync9(link);
|
|
5354
5657
|
} catch {
|
|
5355
5658
|
continue;
|
|
5356
5659
|
}
|
|
5357
5660
|
}
|
|
5358
5661
|
try {
|
|
5359
|
-
|
|
5662
|
+
mkdirSync9(dirname4(link), { recursive: true });
|
|
5360
5663
|
symlinkSync2(canonicalDir, link, "dir");
|
|
5361
5664
|
out.push(link);
|
|
5362
5665
|
} catch {
|
|
@@ -5371,8 +5674,8 @@ function backfillSymlinks(installRoot) {
|
|
|
5371
5674
|
return;
|
|
5372
5675
|
const detected = detectAgentSkillsRoots(installRoot);
|
|
5373
5676
|
for (const entry of entries) {
|
|
5374
|
-
const canonical =
|
|
5375
|
-
if (!
|
|
5677
|
+
const canonical = join24(entry.installRoot, entry.dirName);
|
|
5678
|
+
if (!existsSync20(canonical))
|
|
5376
5679
|
continue;
|
|
5377
5680
|
const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
|
|
5378
5681
|
if (sameSorted(fresh, entry.symlinks))
|
|
@@ -5482,10 +5785,10 @@ function renderFrontmatter2(fm) {
|
|
|
5482
5785
|
return lines.join("\n");
|
|
5483
5786
|
}
|
|
5484
5787
|
function readLocalVersion(path) {
|
|
5485
|
-
if (!
|
|
5788
|
+
if (!existsSync20(path))
|
|
5486
5789
|
return null;
|
|
5487
5790
|
try {
|
|
5488
|
-
const text =
|
|
5791
|
+
const text = readFileSync17(path, "utf-8");
|
|
5489
5792
|
const parsed = parseFrontmatter(text);
|
|
5490
5793
|
if (!parsed)
|
|
5491
5794
|
return null;
|
|
@@ -5580,8 +5883,8 @@ async function runPull(opts) {
|
|
|
5580
5883
|
summary.skipped++;
|
|
5581
5884
|
continue;
|
|
5582
5885
|
}
|
|
5583
|
-
const skillDir2 =
|
|
5584
|
-
const skillFile =
|
|
5886
|
+
const skillDir2 = join24(root, dirName);
|
|
5887
|
+
const skillFile = join24(skillDir2, "SKILL.md");
|
|
5585
5888
|
const remoteVersion = Number(row.version ?? 1);
|
|
5586
5889
|
const localVersion = readLocalVersion(skillFile);
|
|
5587
5890
|
const action = decideAction({
|
|
@@ -5592,14 +5895,14 @@ async function runPull(opts) {
|
|
|
5592
5895
|
});
|
|
5593
5896
|
let manifestError;
|
|
5594
5897
|
if (action === "wrote") {
|
|
5595
|
-
|
|
5596
|
-
if (
|
|
5898
|
+
mkdirSync9(skillDir2, { recursive: true });
|
|
5899
|
+
if (existsSync20(skillFile)) {
|
|
5597
5900
|
try {
|
|
5598
|
-
|
|
5901
|
+
renameSync6(skillFile, `${skillFile}.bak`);
|
|
5599
5902
|
} catch {
|
|
5600
5903
|
}
|
|
5601
5904
|
}
|
|
5602
|
-
|
|
5905
|
+
writeFileSync13(skillFile, renderSkillFile(row));
|
|
5603
5906
|
const symlinks = opts.install === "global" ? fanOutSymlinks(skillDir2, dirName, detectAgentSkillsRoots(root)) : [];
|
|
5604
5907
|
try {
|
|
5605
5908
|
recordPull({
|
|
@@ -5641,15 +5944,15 @@ async function runPull(opts) {
|
|
|
5641
5944
|
}
|
|
5642
5945
|
|
|
5643
5946
|
// dist/src/skillify/unpull.js
|
|
5644
|
-
import { existsSync as
|
|
5645
|
-
import { homedir as
|
|
5646
|
-
import { join as
|
|
5947
|
+
import { existsSync as existsSync21, readdirSync as readdirSync3, rmSync as rmSync5, statSync as statSync4 } from "node:fs";
|
|
5948
|
+
import { homedir as homedir15 } from "node:os";
|
|
5949
|
+
import { join as join25 } from "node:path";
|
|
5647
5950
|
function resolveUnpullRoot(install, cwd) {
|
|
5648
5951
|
if (install === "global")
|
|
5649
|
-
return
|
|
5952
|
+
return join25(homedir15(), ".claude", "skills");
|
|
5650
5953
|
if (!cwd)
|
|
5651
5954
|
throw new Error("cwd required when install === 'project'");
|
|
5652
|
-
return
|
|
5955
|
+
return join25(cwd, ".claude", "skills");
|
|
5653
5956
|
}
|
|
5654
5957
|
function runUnpull(opts) {
|
|
5655
5958
|
const root = resolveUnpullRoot(opts.install, opts.cwd);
|
|
@@ -5672,8 +5975,8 @@ function runUnpull(opts) {
|
|
|
5672
5975
|
const entries = entriesForRoot(manifest, opts.install, root);
|
|
5673
5976
|
for (const entry of entries) {
|
|
5674
5977
|
summary.scanned++;
|
|
5675
|
-
const path =
|
|
5676
|
-
if (!
|
|
5978
|
+
const path = join25(root, entry.dirName);
|
|
5979
|
+
if (!existsSync21(path)) {
|
|
5677
5980
|
if (!opts.dryRun) {
|
|
5678
5981
|
unlinkSymlinks(entry.symlinks);
|
|
5679
5982
|
removePullEntry(opts.install, entry.installRoot, entry.dirName);
|
|
@@ -5726,15 +6029,15 @@ function runUnpull(opts) {
|
|
|
5726
6029
|
}
|
|
5727
6030
|
summary.entries.push(result);
|
|
5728
6031
|
}
|
|
5729
|
-
if (
|
|
6032
|
+
if (existsSync21(root) && (opts.all || opts.legacyCleanup)) {
|
|
5730
6033
|
const manifestDirNames = new Set(entries.map((e) => e.dirName));
|
|
5731
6034
|
for (const dirName of readdirSync3(root)) {
|
|
5732
6035
|
if (manifestDirNames.has(dirName))
|
|
5733
6036
|
continue;
|
|
5734
|
-
const path =
|
|
6037
|
+
const path = join25(root, dirName);
|
|
5735
6038
|
let st;
|
|
5736
6039
|
try {
|
|
5737
|
-
st =
|
|
6040
|
+
st = statSync4(path);
|
|
5738
6041
|
} catch {
|
|
5739
6042
|
continue;
|
|
5740
6043
|
}
|
|
@@ -5810,30 +6113,30 @@ function decideTargetForManifestEntry(entry, opts, userFilter, haveUserFilter) {
|
|
|
5810
6113
|
|
|
5811
6114
|
// dist/src/commands/mine-local.js
|
|
5812
6115
|
import { spawn } from "node:child_process";
|
|
5813
|
-
import { existsSync as
|
|
5814
|
-
import { homedir as
|
|
5815
|
-
import { basename, dirname as
|
|
6116
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync11, readFileSync as readFileSync20, writeFileSync as writeFileSync15 } from "node:fs";
|
|
6117
|
+
import { homedir as homedir19 } from "node:os";
|
|
6118
|
+
import { basename, dirname as dirname6, join as join29 } from "node:path";
|
|
5816
6119
|
|
|
5817
6120
|
// dist/src/skillify/local-source.js
|
|
5818
|
-
import { readdirSync as readdirSync4, readFileSync as
|
|
5819
|
-
import { homedir as
|
|
5820
|
-
import { join as
|
|
5821
|
-
var HOME2 =
|
|
6121
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync18, existsSync as existsSync22, statSync as statSync5 } from "node:fs";
|
|
6122
|
+
import { homedir as homedir16 } from "node:os";
|
|
6123
|
+
import { join as join26 } from "node:path";
|
|
6124
|
+
var HOME2 = homedir16();
|
|
5822
6125
|
function encodeCwdClaudeCode(cwd) {
|
|
5823
6126
|
return cwd.replace(/[/_]/g, "-");
|
|
5824
6127
|
}
|
|
5825
6128
|
function detectInstalledAgents() {
|
|
5826
6129
|
const installs = [];
|
|
5827
|
-
const claudeRoot =
|
|
5828
|
-
if (
|
|
6130
|
+
const claudeRoot = join26(HOME2, ".claude", "projects");
|
|
6131
|
+
if (existsSync22(claudeRoot)) {
|
|
5829
6132
|
installs.push({
|
|
5830
6133
|
agent: "claude_code",
|
|
5831
6134
|
sessionRoot: claudeRoot,
|
|
5832
6135
|
encodeCwd: encodeCwdClaudeCode
|
|
5833
6136
|
});
|
|
5834
6137
|
}
|
|
5835
|
-
const codexRoot =
|
|
5836
|
-
if (
|
|
6138
|
+
const codexRoot = join26(HOME2, ".codex", "sessions");
|
|
6139
|
+
if (existsSync22(codexRoot)) {
|
|
5837
6140
|
installs.push({
|
|
5838
6141
|
agent: "codex",
|
|
5839
6142
|
sessionRoot: codexRoot,
|
|
@@ -5860,9 +6163,9 @@ function listLocalSessions(installs, cwd) {
|
|
|
5860
6163
|
continue;
|
|
5861
6164
|
}
|
|
5862
6165
|
for (const sub of subdirs) {
|
|
5863
|
-
const subdirPath =
|
|
6166
|
+
const subdirPath = join26(install.sessionRoot, sub);
|
|
5864
6167
|
try {
|
|
5865
|
-
if (!
|
|
6168
|
+
if (!statSync5(subdirPath).isDirectory())
|
|
5866
6169
|
continue;
|
|
5867
6170
|
} catch {
|
|
5868
6171
|
continue;
|
|
@@ -5877,10 +6180,10 @@ function listLocalSessions(installs, cwd) {
|
|
|
5877
6180
|
for (const f of files) {
|
|
5878
6181
|
if (!f.endsWith(".jsonl"))
|
|
5879
6182
|
continue;
|
|
5880
|
-
const fullPath =
|
|
6183
|
+
const fullPath = join26(subdirPath, f);
|
|
5881
6184
|
let stats;
|
|
5882
6185
|
try {
|
|
5883
|
-
stats =
|
|
6186
|
+
stats = statSync5(fullPath);
|
|
5884
6187
|
} catch {
|
|
5885
6188
|
continue;
|
|
5886
6189
|
}
|
|
@@ -5938,7 +6241,7 @@ function pickSessions(candidates, opts) {
|
|
|
5938
6241
|
function nativeJsonlToRows(filePath, sessionId, agent) {
|
|
5939
6242
|
let raw;
|
|
5940
6243
|
try {
|
|
5941
|
-
raw =
|
|
6244
|
+
raw = readFileSync18(filePath, "utf-8");
|
|
5942
6245
|
} catch {
|
|
5943
6246
|
return [];
|
|
5944
6247
|
}
|
|
@@ -6028,22 +6331,22 @@ function extractPairs(rows) {
|
|
|
6028
6331
|
}
|
|
6029
6332
|
|
|
6030
6333
|
// dist/src/skillify/gate-runner.js
|
|
6031
|
-
import { existsSync as
|
|
6334
|
+
import { existsSync as existsSync23 } from "node:fs";
|
|
6032
6335
|
import { createRequire } from "node:module";
|
|
6033
|
-
import { homedir as
|
|
6034
|
-
import { join as
|
|
6336
|
+
import { homedir as homedir17 } from "node:os";
|
|
6337
|
+
import { join as join27 } from "node:path";
|
|
6035
6338
|
var requireForCp = createRequire(import.meta.url);
|
|
6036
6339
|
var { execFileSync: runChildProcess } = requireForCp("node:child_process");
|
|
6037
6340
|
var inheritedEnv = process;
|
|
6038
6341
|
function firstExistingPath(candidates) {
|
|
6039
6342
|
for (const c of candidates) {
|
|
6040
|
-
if (
|
|
6343
|
+
if (existsSync23(c))
|
|
6041
6344
|
return c;
|
|
6042
6345
|
}
|
|
6043
6346
|
return null;
|
|
6044
6347
|
}
|
|
6045
6348
|
function findAgentBin(agent) {
|
|
6046
|
-
const home =
|
|
6349
|
+
const home = homedir17();
|
|
6047
6350
|
switch (agent) {
|
|
6048
6351
|
// /usr/bin/<name> is included in every candidate list — that's the
|
|
6049
6352
|
// common Linux package-manager install path (apt, dnf, pacman). Old
|
|
@@ -6052,45 +6355,45 @@ function findAgentBin(agent) {
|
|
|
6052
6355
|
// #170 caught the gap.
|
|
6053
6356
|
case "claude_code":
|
|
6054
6357
|
return firstExistingPath([
|
|
6055
|
-
|
|
6358
|
+
join27(home, ".claude", "local", "claude"),
|
|
6056
6359
|
"/usr/local/bin/claude",
|
|
6057
6360
|
"/usr/bin/claude",
|
|
6058
|
-
|
|
6059
|
-
|
|
6361
|
+
join27(home, ".npm-global", "bin", "claude"),
|
|
6362
|
+
join27(home, ".local", "bin", "claude"),
|
|
6060
6363
|
"/opt/homebrew/bin/claude"
|
|
6061
|
-
]) ??
|
|
6364
|
+
]) ?? join27(home, ".claude", "local", "claude");
|
|
6062
6365
|
case "codex":
|
|
6063
6366
|
return firstExistingPath([
|
|
6064
6367
|
"/usr/local/bin/codex",
|
|
6065
6368
|
"/usr/bin/codex",
|
|
6066
|
-
|
|
6067
|
-
|
|
6369
|
+
join27(home, ".npm-global", "bin", "codex"),
|
|
6370
|
+
join27(home, ".local", "bin", "codex"),
|
|
6068
6371
|
"/opt/homebrew/bin/codex"
|
|
6069
6372
|
]) ?? "/usr/local/bin/codex";
|
|
6070
6373
|
case "cursor":
|
|
6071
6374
|
return firstExistingPath([
|
|
6072
6375
|
"/usr/local/bin/cursor-agent",
|
|
6073
6376
|
"/usr/bin/cursor-agent",
|
|
6074
|
-
|
|
6075
|
-
|
|
6377
|
+
join27(home, ".npm-global", "bin", "cursor-agent"),
|
|
6378
|
+
join27(home, ".local", "bin", "cursor-agent"),
|
|
6076
6379
|
"/opt/homebrew/bin/cursor-agent"
|
|
6077
6380
|
]) ?? "/usr/local/bin/cursor-agent";
|
|
6078
6381
|
case "hermes":
|
|
6079
6382
|
return firstExistingPath([
|
|
6080
|
-
|
|
6383
|
+
join27(home, ".local", "bin", "hermes"),
|
|
6081
6384
|
"/usr/local/bin/hermes",
|
|
6082
6385
|
"/usr/bin/hermes",
|
|
6083
|
-
|
|
6386
|
+
join27(home, ".npm-global", "bin", "hermes"),
|
|
6084
6387
|
"/opt/homebrew/bin/hermes"
|
|
6085
|
-
]) ??
|
|
6388
|
+
]) ?? join27(home, ".local", "bin", "hermes");
|
|
6086
6389
|
case "pi":
|
|
6087
6390
|
return firstExistingPath([
|
|
6088
|
-
|
|
6391
|
+
join27(home, ".local", "bin", "pi"),
|
|
6089
6392
|
"/usr/local/bin/pi",
|
|
6090
6393
|
"/usr/bin/pi",
|
|
6091
|
-
|
|
6394
|
+
join27(home, ".npm-global", "bin", "pi"),
|
|
6092
6395
|
"/opt/homebrew/bin/pi"
|
|
6093
|
-
]) ??
|
|
6396
|
+
]) ?? join27(home, ".local", "bin", "pi");
|
|
6094
6397
|
}
|
|
6095
6398
|
}
|
|
6096
6399
|
|
|
@@ -6120,27 +6423,27 @@ function extractJsonBlock(s) {
|
|
|
6120
6423
|
}
|
|
6121
6424
|
|
|
6122
6425
|
// dist/src/skillify/local-manifest.js
|
|
6123
|
-
import { existsSync as
|
|
6124
|
-
import { homedir as
|
|
6125
|
-
import { dirname as
|
|
6126
|
-
var LOCAL_MANIFEST_PATH =
|
|
6127
|
-
var LOCAL_MINE_LOCK_PATH =
|
|
6426
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync10, readFileSync as readFileSync19, writeFileSync as writeFileSync14 } from "node:fs";
|
|
6427
|
+
import { homedir as homedir18 } from "node:os";
|
|
6428
|
+
import { dirname as dirname5, join as join28 } from "node:path";
|
|
6429
|
+
var LOCAL_MANIFEST_PATH = join28(homedir18(), ".claude", "hivemind", "local-mined.json");
|
|
6430
|
+
var LOCAL_MINE_LOCK_PATH = join28(homedir18(), ".claude", "hivemind", "local-mined.lock");
|
|
6128
6431
|
function readLocalManifest(path = LOCAL_MANIFEST_PATH) {
|
|
6129
|
-
if (!
|
|
6432
|
+
if (!existsSync24(path))
|
|
6130
6433
|
return null;
|
|
6131
6434
|
try {
|
|
6132
|
-
return JSON.parse(
|
|
6435
|
+
return JSON.parse(readFileSync19(path, "utf-8"));
|
|
6133
6436
|
} catch {
|
|
6134
6437
|
return null;
|
|
6135
6438
|
}
|
|
6136
6439
|
}
|
|
6137
6440
|
function writeLocalManifest(m, path = LOCAL_MANIFEST_PATH) {
|
|
6138
|
-
|
|
6139
|
-
|
|
6441
|
+
mkdirSync10(dirname5(path), { recursive: true });
|
|
6442
|
+
writeFileSync14(path, JSON.stringify(m, null, 2));
|
|
6140
6443
|
}
|
|
6141
6444
|
|
|
6142
6445
|
// dist/src/commands/mine-local.js
|
|
6143
|
-
import { unlinkSync as
|
|
6446
|
+
import { unlinkSync as unlinkSync10 } from "node:fs";
|
|
6144
6447
|
var EPSILON = 0.3;
|
|
6145
6448
|
var DEFAULT_N = 8;
|
|
6146
6449
|
var PAIR_CHAR_CAP = 4e3;
|
|
@@ -6151,9 +6454,9 @@ var IN_FLIGHT_MAX_AGE_MS = 6e4;
|
|
|
6151
6454
|
var GATE_TIMEOUT_MS = 24e4;
|
|
6152
6455
|
var MANIFEST_PATH = LOCAL_MANIFEST_PATH;
|
|
6153
6456
|
function runGateViaStdin(opts) {
|
|
6154
|
-
return new Promise((
|
|
6457
|
+
return new Promise((resolve2) => {
|
|
6155
6458
|
if (opts.agent !== "claude_code") {
|
|
6156
|
-
|
|
6459
|
+
resolve2({
|
|
6157
6460
|
stdout: "",
|
|
6158
6461
|
stderr: "",
|
|
6159
6462
|
errored: true,
|
|
@@ -6161,8 +6464,8 @@ function runGateViaStdin(opts) {
|
|
|
6161
6464
|
});
|
|
6162
6465
|
return;
|
|
6163
6466
|
}
|
|
6164
|
-
if (!
|
|
6165
|
-
|
|
6467
|
+
if (!existsSync25(opts.bin)) {
|
|
6468
|
+
resolve2({
|
|
6166
6469
|
stdout: "",
|
|
6167
6470
|
stderr: "",
|
|
6168
6471
|
errored: true,
|
|
@@ -6189,7 +6492,7 @@ function runGateViaStdin(opts) {
|
|
|
6189
6492
|
if (settled)
|
|
6190
6493
|
return;
|
|
6191
6494
|
settled = true;
|
|
6192
|
-
|
|
6495
|
+
resolve2(r);
|
|
6193
6496
|
};
|
|
6194
6497
|
const timer = setTimeout(() => {
|
|
6195
6498
|
try {
|
|
@@ -6449,7 +6752,7 @@ async function runMineLocal(args) {
|
|
|
6449
6752
|
return;
|
|
6450
6753
|
lockReleased = true;
|
|
6451
6754
|
try {
|
|
6452
|
-
|
|
6755
|
+
unlinkSync10(LOCAL_MINE_LOCK_PATH);
|
|
6453
6756
|
} catch {
|
|
6454
6757
|
}
|
|
6455
6758
|
};
|
|
@@ -6506,8 +6809,8 @@ async function runMineLocalImpl(args) {
|
|
|
6506
6809
|
console.log(`Dry-run: would invoke ${gateAgent} gate on ${picked.length} session(s) in parallel (concurrency=${GATE_CONCURRENCY}).`);
|
|
6507
6810
|
return;
|
|
6508
6811
|
}
|
|
6509
|
-
const tmpDir =
|
|
6510
|
-
|
|
6812
|
+
const tmpDir = join29(homedir19(), ".claude", "hivemind", `mine-local-${Date.now()}`);
|
|
6813
|
+
mkdirSync11(tmpDir, { recursive: true });
|
|
6511
6814
|
console.log(`Running ${picked.length} gate call(s) in parallel (concurrency=${GATE_CONCURRENCY}, timeout=${GATE_TIMEOUT_MS / 1e3}s each)...`);
|
|
6512
6815
|
const results = await parallelMap(picked, GATE_CONCURRENCY, async (s) => {
|
|
6513
6816
|
const shortId = s.sessionId.slice(0, 8);
|
|
@@ -6518,23 +6821,23 @@ async function runMineLocalImpl(args) {
|
|
|
6518
6821
|
return { session: s, skills: [], reason: "no pairs", error: null };
|
|
6519
6822
|
}
|
|
6520
6823
|
const tail = pairs2.slice(-PER_SESSION_PAIR_CAP);
|
|
6521
|
-
const sessionTmp =
|
|
6522
|
-
|
|
6523
|
-
const verdictPath =
|
|
6824
|
+
const sessionTmp = join29(tmpDir, `s-${shortId}`);
|
|
6825
|
+
mkdirSync11(sessionTmp, { recursive: true });
|
|
6826
|
+
const verdictPath = join29(sessionTmp, "verdict.json");
|
|
6524
6827
|
const prompt = buildSessionPrompt(tail, s, verdictPath);
|
|
6525
|
-
|
|
6828
|
+
writeFileSync15(join29(sessionTmp, "prompt.txt"), prompt);
|
|
6526
6829
|
const gate = await runGateViaStdin({ agent: gateAgent, bin: gateBin, prompt, timeoutMs: GATE_TIMEOUT_MS });
|
|
6527
6830
|
try {
|
|
6528
|
-
|
|
6831
|
+
writeFileSync15(join29(sessionTmp, "gate-stdout.txt"), gate.stdout);
|
|
6529
6832
|
if (gate.stderr)
|
|
6530
|
-
|
|
6833
|
+
writeFileSync15(join29(sessionTmp, "gate-stderr.txt"), gate.stderr);
|
|
6531
6834
|
} catch {
|
|
6532
6835
|
}
|
|
6533
6836
|
if (gate.errored) {
|
|
6534
6837
|
console.log(` [${shortId}] gate failed: ${gate.errorMessage}`);
|
|
6535
6838
|
return { session: s, skills: [], reason: null, error: gate.errorMessage ?? "gate failed" };
|
|
6536
6839
|
}
|
|
6537
|
-
const verdictText =
|
|
6840
|
+
const verdictText = existsSync25(verdictPath) ? readFileSync20(verdictPath, "utf-8") : gate.stdout;
|
|
6538
6841
|
const mv = parseMultiVerdict(verdictText);
|
|
6539
6842
|
if (!mv) {
|
|
6540
6843
|
console.log(` [${shortId}] unparseable verdict (kept at ${sessionTmp})`);
|
|
@@ -6586,7 +6889,7 @@ async function runMineLocalImpl(args) {
|
|
|
6586
6889
|
sourceSessions: [session.sessionId],
|
|
6587
6890
|
agent: gateAgent
|
|
6588
6891
|
});
|
|
6589
|
-
const canonicalDir =
|
|
6892
|
+
const canonicalDir = dirname6(result.path);
|
|
6590
6893
|
const symlinks = fanOutRoots.length > 0 ? fanOutSymlinks(canonicalDir, basename(canonicalDir), fanOutRoots) : [];
|
|
6591
6894
|
const symlinkSuffix = symlinks.length > 0 ? `, fan-out \u2192 ${symlinks.length} root(s)` : "";
|
|
6592
6895
|
console.log(` wrote ${skill.name} \u2190 session ${session.sessionId.slice(0, 8)} (${session.agent}${symlinkSuffix})`);
|
|
@@ -6750,7 +7053,7 @@ function wrapAt(s, max) {
|
|
|
6750
7053
|
|
|
6751
7054
|
// dist/src/commands/skillify.js
|
|
6752
7055
|
function stateDir() {
|
|
6753
|
-
return
|
|
7056
|
+
return join30(homedir20(), ".deeplake", "state", "skillify");
|
|
6754
7057
|
}
|
|
6755
7058
|
function showStatus() {
|
|
6756
7059
|
const cfg = loadScopeConfig();
|
|
@@ -6758,7 +7061,7 @@ function showStatus() {
|
|
|
6758
7061
|
console.log(`team: ${cfg.team.length === 0 ? "(empty)" : cfg.team.join(", ")}`);
|
|
6759
7062
|
console.log(`install: ${cfg.install} (${cfg.install === "global" ? "~/.claude/skills/" : "<project>/.claude/skills/"})`);
|
|
6760
7063
|
const dir = stateDir();
|
|
6761
|
-
if (!
|
|
7064
|
+
if (!existsSync26(dir)) {
|
|
6762
7065
|
console.log(`state: (no projects tracked yet)`);
|
|
6763
7066
|
return;
|
|
6764
7067
|
}
|
|
@@ -6770,7 +7073,7 @@ function showStatus() {
|
|
|
6770
7073
|
console.log(`state: ${files.length} project(s) tracked`);
|
|
6771
7074
|
for (const f of files) {
|
|
6772
7075
|
try {
|
|
6773
|
-
const s = JSON.parse(
|
|
7076
|
+
const s = JSON.parse(readFileSync21(join30(dir, f), "utf-8"));
|
|
6774
7077
|
const last = typeof s.updatedAt === "number" ? new Date(s.updatedAt).toISOString() : s.lastDate ?? "never";
|
|
6775
7078
|
const skills = Array.isArray(s.skillsGenerated) && s.skillsGenerated.length > 0 ? s.skillsGenerated.join(", ") : "none";
|
|
6776
7079
|
console.log(` - ${s.project} (counter=${s.counter}, last=${last}, skills=${skills})`);
|
|
@@ -6797,7 +7100,7 @@ function setInstall(loc) {
|
|
|
6797
7100
|
}
|
|
6798
7101
|
const cfg = loadScopeConfig();
|
|
6799
7102
|
saveScopeConfig({ ...cfg, install: loc });
|
|
6800
|
-
const path = loc === "global" ?
|
|
7103
|
+
const path = loc === "global" ? join30(homedir20(), ".claude", "skills") : "<cwd>/.claude/skills";
|
|
6801
7104
|
console.log(`Install location set to '${loc}'. New skills will be written to ${path}/<name>/SKILL.md.`);
|
|
6802
7105
|
}
|
|
6803
7106
|
function promoteSkill(name, cwd) {
|
|
@@ -6805,18 +7108,18 @@ function promoteSkill(name, cwd) {
|
|
|
6805
7108
|
console.error("Usage: hivemind skillify promote <skill-name>");
|
|
6806
7109
|
process.exit(1);
|
|
6807
7110
|
}
|
|
6808
|
-
const projectPath =
|
|
6809
|
-
const globalPath =
|
|
6810
|
-
if (!
|
|
7111
|
+
const projectPath = join30(cwd, ".claude", "skills", name);
|
|
7112
|
+
const globalPath = join30(homedir20(), ".claude", "skills", name);
|
|
7113
|
+
if (!existsSync26(join30(projectPath, "SKILL.md"))) {
|
|
6811
7114
|
console.error(`Skill '${name}' not found at ${projectPath}/SKILL.md`);
|
|
6812
7115
|
process.exit(1);
|
|
6813
7116
|
}
|
|
6814
|
-
if (
|
|
7117
|
+
if (existsSync26(join30(globalPath, "SKILL.md"))) {
|
|
6815
7118
|
console.error(`Skill '${name}' already exists at ${globalPath}/SKILL.md \u2014 refusing to overwrite. Remove it first or rename the project skill.`);
|
|
6816
7119
|
process.exit(1);
|
|
6817
7120
|
}
|
|
6818
|
-
|
|
6819
|
-
|
|
7121
|
+
mkdirSync12(dirname7(globalPath), { recursive: true });
|
|
7122
|
+
renameSync7(projectPath, globalPath);
|
|
6820
7123
|
console.log(`Promoted '${name}' from ${projectPath} \u2192 ${globalPath}.`);
|
|
6821
7124
|
}
|
|
6822
7125
|
function teamAdd(name) {
|
|
@@ -6922,7 +7225,7 @@ async function pullSkills(args) {
|
|
|
6922
7225
|
console.error(`pull failed: ${e?.message ?? e}`);
|
|
6923
7226
|
process.exit(1);
|
|
6924
7227
|
}
|
|
6925
|
-
const dest = toRaw === "global" ?
|
|
7228
|
+
const dest = toRaw === "global" ? join30(homedir20(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
|
|
6926
7229
|
const filterDesc = users.length === 0 ? "all users" : users.join(", ");
|
|
6927
7230
|
console.log(`Destination: ${dest}`);
|
|
6928
7231
|
console.log(`Filter: ${filterDesc}${skillName ? ` \xB7 skill='${skillName}'` : ""}${dryRun ? " \xB7 dry-run" : ""}${force ? " \xB7 force" : ""}`);
|
|
@@ -6972,7 +7275,7 @@ async function unpullSkills(args) {
|
|
|
6972
7275
|
all,
|
|
6973
7276
|
legacyCleanup
|
|
6974
7277
|
});
|
|
6975
|
-
const dest = toRaw === "global" ?
|
|
7278
|
+
const dest = toRaw === "global" ? join30(homedir20(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
|
|
6976
7279
|
const filterParts = [];
|
|
6977
7280
|
if (users.length > 0)
|
|
6978
7281
|
filterParts.push(`users=${users.join(",")}`);
|
|
@@ -7068,13 +7371,13 @@ if (process.argv[1] && process.argv[1].endsWith("skillify.js")) {
|
|
|
7068
7371
|
|
|
7069
7372
|
// dist/src/cli/update.js
|
|
7070
7373
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
7071
|
-
import { existsSync as
|
|
7072
|
-
import { dirname as
|
|
7374
|
+
import { existsSync as existsSync27, readFileSync as readFileSync23, realpathSync } from "node:fs";
|
|
7375
|
+
import { dirname as dirname9, sep } from "node:path";
|
|
7073
7376
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
7074
7377
|
|
|
7075
7378
|
// dist/src/utils/version-check.js
|
|
7076
|
-
import { readFileSync as
|
|
7077
|
-
import { dirname as
|
|
7379
|
+
import { readFileSync as readFileSync22 } from "node:fs";
|
|
7380
|
+
import { dirname as dirname8, join as join31 } from "node:path";
|
|
7078
7381
|
function isNewer(latest, current) {
|
|
7079
7382
|
const parse = (v) => v.split(".").map(Number);
|
|
7080
7383
|
const [la, lb, lc] = parse(latest);
|
|
@@ -7093,24 +7396,24 @@ function detectInstallKind(argv1) {
|
|
|
7093
7396
|
return argv1 ?? process.argv[1] ?? fileURLToPath2(import.meta.url);
|
|
7094
7397
|
}
|
|
7095
7398
|
})();
|
|
7096
|
-
let dir =
|
|
7399
|
+
let dir = dirname9(realArgv1);
|
|
7097
7400
|
let installDir = null;
|
|
7098
7401
|
for (let i = 0; i < 10; i++) {
|
|
7099
7402
|
const pkgPath = `${dir}${sep}package.json`;
|
|
7100
7403
|
try {
|
|
7101
|
-
const pkg = JSON.parse(
|
|
7404
|
+
const pkg = JSON.parse(readFileSync23(pkgPath, "utf-8"));
|
|
7102
7405
|
if (pkg.name === PKG_NAME || pkg.name === "hivemind") {
|
|
7103
7406
|
installDir = dir;
|
|
7104
7407
|
break;
|
|
7105
7408
|
}
|
|
7106
7409
|
} catch {
|
|
7107
7410
|
}
|
|
7108
|
-
const parent =
|
|
7411
|
+
const parent = dirname9(dir);
|
|
7109
7412
|
if (parent === dir)
|
|
7110
7413
|
break;
|
|
7111
7414
|
dir = parent;
|
|
7112
7415
|
}
|
|
7113
|
-
installDir ??=
|
|
7416
|
+
installDir ??= dirname9(realArgv1);
|
|
7114
7417
|
if (realArgv1.includes(`${sep}_npx${sep}`) || realArgv1.includes(`${sep}.npx${sep}`)) {
|
|
7115
7418
|
return { kind: "npx", installDir };
|
|
7116
7419
|
}
|
|
@@ -7119,10 +7422,10 @@ function detectInstallKind(argv1) {
|
|
|
7119
7422
|
}
|
|
7120
7423
|
let gitDir = installDir;
|
|
7121
7424
|
for (let i = 0; i < 6; i++) {
|
|
7122
|
-
if (
|
|
7425
|
+
if (existsSync27(`${gitDir}${sep}.git`)) {
|
|
7123
7426
|
return { kind: "local-dev", installDir };
|
|
7124
7427
|
}
|
|
7125
|
-
const parent =
|
|
7428
|
+
const parent = dirname9(gitDir);
|
|
7126
7429
|
if (parent === gitDir)
|
|
7127
7430
|
break;
|
|
7128
7431
|
gitDir = parent;
|
|
@@ -7265,12 +7568,28 @@ Usage:
|
|
|
7265
7568
|
|
|
7266
7569
|
Semantic search (embeddings):
|
|
7267
7570
|
hivemind embeddings install Download @huggingface/transformers
|
|
7268
|
-
once (~600 MB) into a shared dir
|
|
7269
|
-
|
|
7270
|
-
plugin to it
|
|
7271
|
-
|
|
7272
|
-
|
|
7273
|
-
hivemind embeddings
|
|
7571
|
+
once (~600 MB) into a shared dir,
|
|
7572
|
+
symlink every detected agent
|
|
7573
|
+
plugin to it, and set
|
|
7574
|
+
embeddings.enabled = true in
|
|
7575
|
+
~/.deeplake/config.json. Idempotent.
|
|
7576
|
+
hivemind embeddings enable Light opt-in: flip
|
|
7577
|
+
embeddings.enabled = true in
|
|
7578
|
+
~/.deeplake/config.json. Use this
|
|
7579
|
+
after \`disable\` to turn back on
|
|
7580
|
+
without re-running install.
|
|
7581
|
+
hivemind embeddings disable Light opt-out: flip
|
|
7582
|
+
embeddings.enabled = false and
|
|
7583
|
+
SIGTERM the running daemon. Shared
|
|
7584
|
+
deps stay on disk.
|
|
7585
|
+
hivemind embeddings uninstall [--prune] Full opt-out: remove the per-agent
|
|
7586
|
+
symlinks, flip
|
|
7587
|
+
embeddings.enabled = false, and
|
|
7588
|
+
SIGTERM the daemon. --prune also
|
|
7589
|
+
deletes the shared dir to reclaim
|
|
7590
|
+
~600 MB.
|
|
7591
|
+
hivemind embeddings status Show config + shared-deps + per-
|
|
7592
|
+
agent state.
|
|
7274
7593
|
|
|
7275
7594
|
Add --with-embeddings to "hivemind install" (or "hivemind <agent> install")
|
|
7276
7595
|
to run "embeddings install" automatically after installing the agent(s).
|
|
@@ -7340,7 +7659,7 @@ async function runInstallAll(args) {
|
|
|
7340
7659
|
runSingleInstall(id);
|
|
7341
7660
|
if (withEmbeddings) {
|
|
7342
7661
|
log("");
|
|
7343
|
-
|
|
7662
|
+
installEmbeddings();
|
|
7344
7663
|
}
|
|
7345
7664
|
await maybeShowOrgChoice();
|
|
7346
7665
|
log("");
|
|
@@ -7433,19 +7752,27 @@ async function main() {
|
|
|
7433
7752
|
}
|
|
7434
7753
|
if (cmd === "embeddings") {
|
|
7435
7754
|
const sub = args[1];
|
|
7436
|
-
if (sub === "install"
|
|
7755
|
+
if (sub === "install") {
|
|
7756
|
+
installEmbeddings();
|
|
7757
|
+
return;
|
|
7758
|
+
}
|
|
7759
|
+
if (sub === "enable") {
|
|
7437
7760
|
enableEmbeddings();
|
|
7438
7761
|
return;
|
|
7439
7762
|
}
|
|
7440
|
-
if (sub === "
|
|
7441
|
-
disableEmbeddings(
|
|
7763
|
+
if (sub === "disable") {
|
|
7764
|
+
disableEmbeddings();
|
|
7765
|
+
return;
|
|
7766
|
+
}
|
|
7767
|
+
if (sub === "uninstall") {
|
|
7768
|
+
uninstallEmbeddings({ prune: hasFlag(args.slice(2), "--prune") });
|
|
7442
7769
|
return;
|
|
7443
7770
|
}
|
|
7444
7771
|
if (sub === "status") {
|
|
7445
7772
|
statusEmbeddings();
|
|
7446
7773
|
return;
|
|
7447
7774
|
}
|
|
7448
|
-
warn("Usage: hivemind embeddings install | uninstall [--prune] | status");
|
|
7775
|
+
warn("Usage: hivemind embeddings install | enable | disable | uninstall [--prune] | status");
|
|
7449
7776
|
process.exit(1);
|
|
7450
7777
|
}
|
|
7451
7778
|
if (AUTH_SUBCOMMANDS.has(cmd)) {
|
|
@@ -7459,7 +7786,7 @@ async function main() {
|
|
|
7459
7786
|
runSingleInstall(cmd);
|
|
7460
7787
|
if (hasFlag(args.slice(2), "--with-embeddings")) {
|
|
7461
7788
|
log("");
|
|
7462
|
-
|
|
7789
|
+
installEmbeddings();
|
|
7463
7790
|
}
|
|
7464
7791
|
} else if (sub === "uninstall")
|
|
7465
7792
|
runSingleUninstall(cmd);
|