@deeplake/hivemind 0.7.16 → 0.7.17
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 +196 -44
- package/codex/bundle/session-start.js +1103 -8
- package/cursor/bundle/session-start.js +582 -8
- package/hermes/bundle/session-start.js +580 -6
- 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 +52 -3
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Cloud-backed persistent shared memory for AI agents powered by Deeplake",
|
|
9
|
-
"version": "0.7.
|
|
9
|
+
"version": "0.7.17"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "hivemind",
|
|
14
14
|
"description": "Persistent shared memory powered by Deeplake — captures all session activity and provides cross-session, cross-agent memory search",
|
|
15
|
-
"version": "0.7.
|
|
15
|
+
"version": "0.7.17",
|
|
16
16
|
"source": "./claude-code",
|
|
17
17
|
"homepage": "https://github.com/activeloopai/hivemind"
|
|
18
18
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hivemind",
|
|
3
3
|
"description": "Cloud-backed persistent memory powered by Deeplake — read, write, and share memory across Claude Code sessions and agents",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.17",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Activeloop",
|
|
7
7
|
"url": "https://deeplake.ai"
|
package/bundle/cli.js
CHANGED
|
@@ -3353,6 +3353,7 @@ var VERSION_DIR = join8(PI_AGENT_DIR, ".hivemind");
|
|
|
3353
3353
|
var WIKI_WORKER_DIR = join8(PI_AGENT_DIR, "hivemind");
|
|
3354
3354
|
var WIKI_WORKER_PATH = join8(WIKI_WORKER_DIR, "wiki-worker.js");
|
|
3355
3355
|
var SKILIFY_WORKER_PATH = join8(WIKI_WORKER_DIR, "skilify-worker.js");
|
|
3356
|
+
var AUTOPULL_WORKER_PATH = join8(WIKI_WORKER_DIR, "autopull-worker.js");
|
|
3356
3357
|
var HIVEMIND_BLOCK_START = "<!-- BEGIN hivemind-memory -->";
|
|
3357
3358
|
var HIVEMIND_BLOCK_END = "<!-- END hivemind-memory -->";
|
|
3358
3359
|
var HIVEMIND_BLOCK_BODY = `${HIVEMIND_BLOCK_START}
|
|
@@ -3442,6 +3443,11 @@ function installPi() {
|
|
|
3442
3443
|
ensureDir(WIKI_WORKER_DIR);
|
|
3443
3444
|
copyFileSync2(srcSkilifyWorker, SKILIFY_WORKER_PATH);
|
|
3444
3445
|
}
|
|
3446
|
+
const srcAutopullWorker = join8(pkgRoot(), "pi", "bundle", "autopull-worker.js");
|
|
3447
|
+
if (existsSync7(srcAutopullWorker)) {
|
|
3448
|
+
ensureDir(WIKI_WORKER_DIR);
|
|
3449
|
+
copyFileSync2(srcAutopullWorker, AUTOPULL_WORKER_PATH);
|
|
3450
|
+
}
|
|
3445
3451
|
ensureDir(VERSION_DIR);
|
|
3446
3452
|
writeVersionStamp(VERSION_DIR, getVersion());
|
|
3447
3453
|
log(` pi AGENTS.md updated -> ${AGENTS_MD}`);
|
|
@@ -3452,6 +3458,9 @@ function installPi() {
|
|
|
3452
3458
|
if (existsSync7(SKILIFY_WORKER_PATH)) {
|
|
3453
3459
|
log(` pi skilify-worker installed -> ${SKILIFY_WORKER_PATH}`);
|
|
3454
3460
|
}
|
|
3461
|
+
if (existsSync7(AUTOPULL_WORKER_PATH)) {
|
|
3462
|
+
log(` pi autopull-worker installed -> ${AUTOPULL_WORKER_PATH}`);
|
|
3463
|
+
}
|
|
3455
3464
|
}
|
|
3456
3465
|
function uninstallPi() {
|
|
3457
3466
|
if (existsSync7(LEGACY_SKILL_DIR)) {
|
|
@@ -4710,9 +4719,9 @@ if (process.argv[1] && process.argv[1].endsWith("auth-login.js")) {
|
|
|
4710
4719
|
}
|
|
4711
4720
|
|
|
4712
4721
|
// dist/src/commands/skilify.js
|
|
4713
|
-
import { readdirSync as readdirSync4, existsSync as
|
|
4714
|
-
import { homedir as
|
|
4715
|
-
import { dirname as
|
|
4722
|
+
import { readdirSync as readdirSync4, existsSync as existsSync18, readFileSync as readFileSync13, mkdirSync as mkdirSync8, renameSync as renameSync3 } from "node:fs";
|
|
4723
|
+
import { homedir as homedir11 } from "node:os";
|
|
4724
|
+
import { dirname as dirname4, join as join21 } from "node:path";
|
|
4716
4725
|
|
|
4717
4726
|
// dist/src/skilify/scope-config.js
|
|
4718
4727
|
import { existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "node:fs";
|
|
@@ -4740,9 +4749,9 @@ function saveScopeConfig(cfg) {
|
|
|
4740
4749
|
}
|
|
4741
4750
|
|
|
4742
4751
|
// dist/src/skilify/pull.js
|
|
4743
|
-
import { existsSync as
|
|
4744
|
-
import { homedir as
|
|
4745
|
-
import { join as
|
|
4752
|
+
import { existsSync as existsSync16, readFileSync as readFileSync12, writeFileSync as writeFileSync9, mkdirSync as mkdirSync7, renameSync as renameSync2, lstatSync as lstatSync4, readlinkSync as readlinkSync2, symlinkSync as symlinkSync2, unlinkSync as unlinkSync8 } from "node:fs";
|
|
4753
|
+
import { homedir as homedir9 } from "node:os";
|
|
4754
|
+
import { dirname as dirname3, join as join19 } from "node:path";
|
|
4746
4755
|
|
|
4747
4756
|
// dist/src/skilify/skill-writer.js
|
|
4748
4757
|
import { existsSync as existsSync13, mkdirSync as mkdirSync5, readFileSync as readFileSync10, readdirSync as readdirSync2, statSync as statSync2, writeFileSync as writeFileSync7 } from "node:fs";
|
|
@@ -4806,7 +4815,7 @@ function parseFrontmatter(text) {
|
|
|
4806
4815
|
}
|
|
4807
4816
|
|
|
4808
4817
|
// dist/src/skilify/manifest.js
|
|
4809
|
-
import { existsSync as existsSync14, mkdirSync as mkdirSync6, readFileSync as readFileSync11, renameSync, writeFileSync as writeFileSync8 } from "node:fs";
|
|
4818
|
+
import { existsSync as existsSync14, lstatSync as lstatSync3, mkdirSync as mkdirSync6, readFileSync as readFileSync11, renameSync, unlinkSync as unlinkSync7, writeFileSync as writeFileSync8 } from "node:fs";
|
|
4810
4819
|
import { homedir as homedir7 } from "node:os";
|
|
4811
4820
|
import { dirname as dirname2, join as join17 } from "node:path";
|
|
4812
4821
|
function emptyManifest() {
|
|
@@ -4846,6 +4855,8 @@ function loadManifest(path = manifestPath()) {
|
|
|
4846
4855
|
continue;
|
|
4847
4856
|
if (e.install !== "global" && e.install !== "project")
|
|
4848
4857
|
continue;
|
|
4858
|
+
const symlinks = Array.isArray(e.symlinks) ? e.symlinks.filter((p) => typeof p === "string" && p.length > 0 && (p.startsWith("/") || /^[A-Za-z]:[\\/]/.test(p)) && // absolute (POSIX or Windows)
|
|
4859
|
+
!p.includes("..")) : [];
|
|
4849
4860
|
entries.push({
|
|
4850
4861
|
dirName: e.dirName,
|
|
4851
4862
|
name: e.name,
|
|
@@ -4854,7 +4865,8 @@ function loadManifest(path = manifestPath()) {
|
|
|
4854
4865
|
remoteVersion: typeof e.remoteVersion === "number" ? e.remoteVersion : 1,
|
|
4855
4866
|
install: e.install,
|
|
4856
4867
|
installRoot: e.installRoot,
|
|
4857
|
-
pulledAt: typeof e.pulledAt === "string" ? e.pulledAt : (/* @__PURE__ */ new Date()).toISOString()
|
|
4868
|
+
pulledAt: typeof e.pulledAt === "string" ? e.pulledAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
4869
|
+
symlinks
|
|
4858
4870
|
});
|
|
4859
4871
|
}
|
|
4860
4872
|
return { version: 1, entries };
|
|
@@ -4887,6 +4899,62 @@ function removePullEntry(install, installRoot, dirName, path = manifestPath()) {
|
|
|
4887
4899
|
function entriesForRoot(m, install, installRoot) {
|
|
4888
4900
|
return m.entries.filter((e) => e.install === install && e.installRoot === installRoot);
|
|
4889
4901
|
}
|
|
4902
|
+
function unlinkSymlinks(paths) {
|
|
4903
|
+
for (const path of paths) {
|
|
4904
|
+
let st;
|
|
4905
|
+
try {
|
|
4906
|
+
st = lstatSync3(path);
|
|
4907
|
+
} catch {
|
|
4908
|
+
continue;
|
|
4909
|
+
}
|
|
4910
|
+
if (!st.isSymbolicLink())
|
|
4911
|
+
continue;
|
|
4912
|
+
try {
|
|
4913
|
+
unlinkSync7(path);
|
|
4914
|
+
} catch {
|
|
4915
|
+
}
|
|
4916
|
+
}
|
|
4917
|
+
}
|
|
4918
|
+
function pruneOrphanedEntries(path = manifestPath()) {
|
|
4919
|
+
const m = loadManifest(path);
|
|
4920
|
+
const live = [];
|
|
4921
|
+
let pruned = 0;
|
|
4922
|
+
for (const e of m.entries) {
|
|
4923
|
+
if (existsSync14(join17(e.installRoot, e.dirName))) {
|
|
4924
|
+
live.push(e);
|
|
4925
|
+
continue;
|
|
4926
|
+
}
|
|
4927
|
+
unlinkSymlinks(e.symlinks);
|
|
4928
|
+
pruned++;
|
|
4929
|
+
}
|
|
4930
|
+
if (pruned > 0)
|
|
4931
|
+
saveManifest({ version: 1, entries: live }, path);
|
|
4932
|
+
return pruned;
|
|
4933
|
+
}
|
|
4934
|
+
|
|
4935
|
+
// dist/src/skilify/agent-roots.js
|
|
4936
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
4937
|
+
import { homedir as homedir8 } from "node:os";
|
|
4938
|
+
import { join as join18 } from "node:path";
|
|
4939
|
+
function resolveDetected(home) {
|
|
4940
|
+
const out = [];
|
|
4941
|
+
const codexInstalled = existsSync15(join18(home, ".codex"));
|
|
4942
|
+
const piInstalled = existsSync15(join18(home, ".pi", "agent"));
|
|
4943
|
+
const hermesInstalled = existsSync15(join18(home, ".hermes"));
|
|
4944
|
+
if (codexInstalled || piInstalled) {
|
|
4945
|
+
out.push(join18(home, ".agents", "skills"));
|
|
4946
|
+
}
|
|
4947
|
+
if (hermesInstalled) {
|
|
4948
|
+
out.push(join18(home, ".hermes", "skills"));
|
|
4949
|
+
}
|
|
4950
|
+
if (piInstalled) {
|
|
4951
|
+
out.push(join18(home, ".pi", "agent", "skills"));
|
|
4952
|
+
}
|
|
4953
|
+
return out;
|
|
4954
|
+
}
|
|
4955
|
+
function detectAgentSkillsRoots(canonicalRoot, home = homedir8()) {
|
|
4956
|
+
return resolveDetected(home).filter((p) => p !== canonicalRoot);
|
|
4957
|
+
}
|
|
4890
4958
|
|
|
4891
4959
|
// dist/src/skilify/pull.js
|
|
4892
4960
|
function assertValidAuthor(author) {
|
|
@@ -4920,10 +4988,78 @@ function isMissingTableError(message) {
|
|
|
4920
4988
|
}
|
|
4921
4989
|
function resolvePullDestination(install, cwd) {
|
|
4922
4990
|
if (install === "global")
|
|
4923
|
-
return
|
|
4991
|
+
return join19(homedir9(), ".claude", "skills");
|
|
4924
4992
|
if (!cwd)
|
|
4925
4993
|
throw new Error("install=project requires a cwd");
|
|
4926
|
-
return
|
|
4994
|
+
return join19(cwd, ".claude", "skills");
|
|
4995
|
+
}
|
|
4996
|
+
function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
|
|
4997
|
+
const out = [];
|
|
4998
|
+
for (const root of agentRoots) {
|
|
4999
|
+
const link = join19(root, dirName);
|
|
5000
|
+
let existing;
|
|
5001
|
+
try {
|
|
5002
|
+
existing = lstatSync4(link);
|
|
5003
|
+
} catch {
|
|
5004
|
+
existing = null;
|
|
5005
|
+
}
|
|
5006
|
+
if (existing) {
|
|
5007
|
+
if (!existing.isSymbolicLink()) {
|
|
5008
|
+
continue;
|
|
5009
|
+
}
|
|
5010
|
+
let current;
|
|
5011
|
+
try {
|
|
5012
|
+
current = readlinkSync2(link);
|
|
5013
|
+
} catch {
|
|
5014
|
+
current = null;
|
|
5015
|
+
}
|
|
5016
|
+
if (current === canonicalDir) {
|
|
5017
|
+
out.push(link);
|
|
5018
|
+
continue;
|
|
5019
|
+
}
|
|
5020
|
+
try {
|
|
5021
|
+
unlinkSync8(link);
|
|
5022
|
+
} catch {
|
|
5023
|
+
continue;
|
|
5024
|
+
}
|
|
5025
|
+
}
|
|
5026
|
+
try {
|
|
5027
|
+
mkdirSync7(dirname3(link), { recursive: true });
|
|
5028
|
+
symlinkSync2(canonicalDir, link, "dir");
|
|
5029
|
+
out.push(link);
|
|
5030
|
+
} catch {
|
|
5031
|
+
}
|
|
5032
|
+
}
|
|
5033
|
+
return out;
|
|
5034
|
+
}
|
|
5035
|
+
function backfillSymlinks(installRoot) {
|
|
5036
|
+
const manifest = loadManifest();
|
|
5037
|
+
const entries = entriesForRoot(manifest, "global", installRoot);
|
|
5038
|
+
if (entries.length === 0)
|
|
5039
|
+
return;
|
|
5040
|
+
const detected = detectAgentSkillsRoots(installRoot);
|
|
5041
|
+
for (const entry of entries) {
|
|
5042
|
+
const canonical = join19(entry.installRoot, entry.dirName);
|
|
5043
|
+
if (!existsSync16(canonical))
|
|
5044
|
+
continue;
|
|
5045
|
+
const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
|
|
5046
|
+
if (sameSorted(fresh, entry.symlinks))
|
|
5047
|
+
continue;
|
|
5048
|
+
try {
|
|
5049
|
+
recordPull({ ...entry, symlinks: fresh });
|
|
5050
|
+
} catch {
|
|
5051
|
+
}
|
|
5052
|
+
}
|
|
5053
|
+
}
|
|
5054
|
+
function sameSorted(a, b) {
|
|
5055
|
+
if (a.length !== b.length)
|
|
5056
|
+
return false;
|
|
5057
|
+
const sa = [...a].sort();
|
|
5058
|
+
const sb = [...b].sort();
|
|
5059
|
+
for (let i = 0; i < sa.length; i++)
|
|
5060
|
+
if (sa[i] !== sb[i])
|
|
5061
|
+
return false;
|
|
5062
|
+
return true;
|
|
4927
5063
|
}
|
|
4928
5064
|
function selectLatestPerName(rows) {
|
|
4929
5065
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -4989,7 +5125,7 @@ function renderFrontmatter(fm) {
|
|
|
4989
5125
|
return lines.join("\n");
|
|
4990
5126
|
}
|
|
4991
5127
|
function readLocalVersion(path) {
|
|
4992
|
-
if (!
|
|
5128
|
+
if (!existsSync16(path))
|
|
4993
5129
|
return null;
|
|
4994
5130
|
try {
|
|
4995
5131
|
const text = readFileSync12(path, "utf-8");
|
|
@@ -5009,6 +5145,8 @@ function decideAction(args) {
|
|
|
5009
5145
|
return args.dryRun ? "dryrun" : "wrote";
|
|
5010
5146
|
}
|
|
5011
5147
|
async function runPull(opts) {
|
|
5148
|
+
if (!opts.dryRun)
|
|
5149
|
+
pruneOrphanedEntries();
|
|
5012
5150
|
const sql = buildPullSql({
|
|
5013
5151
|
tableName: opts.tableName,
|
|
5014
5152
|
users: opts.users,
|
|
@@ -5076,8 +5214,8 @@ async function runPull(opts) {
|
|
|
5076
5214
|
summary.skipped++;
|
|
5077
5215
|
continue;
|
|
5078
5216
|
}
|
|
5079
|
-
const skillDir =
|
|
5080
|
-
const skillFile =
|
|
5217
|
+
const skillDir = join19(root, dirName);
|
|
5218
|
+
const skillFile = join19(skillDir, "SKILL.md");
|
|
5081
5219
|
const remoteVersion = Number(row.version ?? 1);
|
|
5082
5220
|
const localVersion = readLocalVersion(skillFile);
|
|
5083
5221
|
const action = decideAction({
|
|
@@ -5089,13 +5227,14 @@ async function runPull(opts) {
|
|
|
5089
5227
|
let manifestError;
|
|
5090
5228
|
if (action === "wrote") {
|
|
5091
5229
|
mkdirSync7(skillDir, { recursive: true });
|
|
5092
|
-
if (
|
|
5230
|
+
if (existsSync16(skillFile)) {
|
|
5093
5231
|
try {
|
|
5094
5232
|
renameSync2(skillFile, `${skillFile}.bak`);
|
|
5095
5233
|
} catch {
|
|
5096
5234
|
}
|
|
5097
5235
|
}
|
|
5098
5236
|
writeFileSync9(skillFile, renderSkillFile(row));
|
|
5237
|
+
const symlinks = opts.install === "global" ? fanOutSymlinks(skillDir, dirName, detectAgentSkillsRoots(root)) : [];
|
|
5099
5238
|
try {
|
|
5100
5239
|
recordPull({
|
|
5101
5240
|
dirName,
|
|
@@ -5105,7 +5244,8 @@ async function runPull(opts) {
|
|
|
5105
5244
|
remoteVersion,
|
|
5106
5245
|
install: opts.install,
|
|
5107
5246
|
installRoot: root,
|
|
5108
|
-
pulledAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5247
|
+
pulledAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5248
|
+
symlinks
|
|
5109
5249
|
});
|
|
5110
5250
|
} catch (e) {
|
|
5111
5251
|
manifestError = e?.message ?? String(e);
|
|
@@ -5128,19 +5268,22 @@ async function runPull(opts) {
|
|
|
5128
5268
|
else
|
|
5129
5269
|
summary.skipped++;
|
|
5130
5270
|
}
|
|
5271
|
+
if (!opts.dryRun && opts.install === "global") {
|
|
5272
|
+
backfillSymlinks(root);
|
|
5273
|
+
}
|
|
5131
5274
|
return summary;
|
|
5132
5275
|
}
|
|
5133
5276
|
|
|
5134
5277
|
// dist/src/skilify/unpull.js
|
|
5135
|
-
import { existsSync as
|
|
5136
|
-
import { homedir as
|
|
5137
|
-
import { join as
|
|
5278
|
+
import { existsSync as existsSync17, readdirSync as readdirSync3, rmSync as rmSync5, statSync as statSync3 } from "node:fs";
|
|
5279
|
+
import { homedir as homedir10 } from "node:os";
|
|
5280
|
+
import { join as join20 } from "node:path";
|
|
5138
5281
|
function resolveUnpullRoot(install, cwd) {
|
|
5139
5282
|
if (install === "global")
|
|
5140
|
-
return
|
|
5283
|
+
return join20(homedir10(), ".claude", "skills");
|
|
5141
5284
|
if (!cwd)
|
|
5142
5285
|
throw new Error("cwd required when install === 'project'");
|
|
5143
|
-
return
|
|
5286
|
+
return join20(cwd, ".claude", "skills");
|
|
5144
5287
|
}
|
|
5145
5288
|
function runUnpull(opts) {
|
|
5146
5289
|
const root = resolveUnpullRoot(opts.install, opts.cwd);
|
|
@@ -5163,10 +5306,12 @@ function runUnpull(opts) {
|
|
|
5163
5306
|
const entries = entriesForRoot(manifest, opts.install, root);
|
|
5164
5307
|
for (const entry of entries) {
|
|
5165
5308
|
summary.scanned++;
|
|
5166
|
-
const path =
|
|
5167
|
-
if (!
|
|
5168
|
-
if (!opts.dryRun)
|
|
5309
|
+
const path = join20(root, entry.dirName);
|
|
5310
|
+
if (!existsSync17(path)) {
|
|
5311
|
+
if (!opts.dryRun) {
|
|
5312
|
+
unlinkSymlinks(entry.symlinks);
|
|
5169
5313
|
removePullEntry(opts.install, entry.installRoot, entry.dirName);
|
|
5314
|
+
}
|
|
5170
5315
|
summary.entries.push({
|
|
5171
5316
|
dirName: entry.dirName,
|
|
5172
5317
|
kind: "manifest-orphan",
|
|
@@ -5203,6 +5348,7 @@ function runUnpull(opts) {
|
|
|
5203
5348
|
} else {
|
|
5204
5349
|
try {
|
|
5205
5350
|
rmSync5(path, { recursive: true, force: true });
|
|
5351
|
+
unlinkSymlinks(entry.symlinks);
|
|
5206
5352
|
removePullEntry(opts.install, entry.installRoot, entry.dirName);
|
|
5207
5353
|
result.action = "removed";
|
|
5208
5354
|
summary.removed++;
|
|
@@ -5214,12 +5360,12 @@ function runUnpull(opts) {
|
|
|
5214
5360
|
}
|
|
5215
5361
|
summary.entries.push(result);
|
|
5216
5362
|
}
|
|
5217
|
-
if (
|
|
5363
|
+
if (existsSync17(root) && (opts.all || opts.legacyCleanup)) {
|
|
5218
5364
|
const manifestDirNames = new Set(entries.map((e) => e.dirName));
|
|
5219
5365
|
for (const dirName of readdirSync3(root)) {
|
|
5220
5366
|
if (manifestDirNames.has(dirName))
|
|
5221
5367
|
continue;
|
|
5222
|
-
const path =
|
|
5368
|
+
const path = join20(root, dirName);
|
|
5223
5369
|
let st;
|
|
5224
5370
|
try {
|
|
5225
5371
|
st = statSync3(path);
|
|
@@ -5298,7 +5444,7 @@ function decideTargetForManifestEntry(entry, opts, userFilter, haveUserFilter) {
|
|
|
5298
5444
|
|
|
5299
5445
|
// dist/src/commands/skilify.js
|
|
5300
5446
|
function stateDir() {
|
|
5301
|
-
return
|
|
5447
|
+
return join21(homedir11(), ".deeplake", "state", "skilify");
|
|
5302
5448
|
}
|
|
5303
5449
|
function showStatus() {
|
|
5304
5450
|
const cfg = loadScopeConfig();
|
|
@@ -5306,7 +5452,7 @@ function showStatus() {
|
|
|
5306
5452
|
console.log(`team: ${cfg.team.length === 0 ? "(empty)" : cfg.team.join(", ")}`);
|
|
5307
5453
|
console.log(`install: ${cfg.install} (${cfg.install === "global" ? "~/.claude/skills/" : "<project>/.claude/skills/"})`);
|
|
5308
5454
|
const dir = stateDir();
|
|
5309
|
-
if (!
|
|
5455
|
+
if (!existsSync18(dir)) {
|
|
5310
5456
|
console.log(`state: (no projects tracked yet)`);
|
|
5311
5457
|
return;
|
|
5312
5458
|
}
|
|
@@ -5318,7 +5464,7 @@ function showStatus() {
|
|
|
5318
5464
|
console.log(`state: ${files.length} project(s) tracked`);
|
|
5319
5465
|
for (const f of files) {
|
|
5320
5466
|
try {
|
|
5321
|
-
const s = JSON.parse(readFileSync13(
|
|
5467
|
+
const s = JSON.parse(readFileSync13(join21(dir, f), "utf-8"));
|
|
5322
5468
|
const skills = s.skillsGenerated.length === 0 ? "none" : s.skillsGenerated.join(", ");
|
|
5323
5469
|
console.log(` - ${s.project} (counter=${s.counter}, last=${s.lastDate ?? "never"}, skills=${skills})`);
|
|
5324
5470
|
} catch {
|
|
@@ -5344,7 +5490,7 @@ function setInstall(loc) {
|
|
|
5344
5490
|
}
|
|
5345
5491
|
const cfg = loadScopeConfig();
|
|
5346
5492
|
saveScopeConfig({ ...cfg, install: loc });
|
|
5347
|
-
const path = loc === "global" ?
|
|
5493
|
+
const path = loc === "global" ? join21(homedir11(), ".claude", "skills") : "<cwd>/.claude/skills";
|
|
5348
5494
|
console.log(`Install location set to '${loc}'. New skills will be written to ${path}/<name>/SKILL.md.`);
|
|
5349
5495
|
}
|
|
5350
5496
|
function promoteSkill(name, cwd) {
|
|
@@ -5352,17 +5498,17 @@ function promoteSkill(name, cwd) {
|
|
|
5352
5498
|
console.error("Usage: hivemind skilify promote <skill-name>");
|
|
5353
5499
|
process.exit(1);
|
|
5354
5500
|
}
|
|
5355
|
-
const projectPath =
|
|
5356
|
-
const globalPath =
|
|
5357
|
-
if (!
|
|
5501
|
+
const projectPath = join21(cwd, ".claude", "skills", name);
|
|
5502
|
+
const globalPath = join21(homedir11(), ".claude", "skills", name);
|
|
5503
|
+
if (!existsSync18(join21(projectPath, "SKILL.md"))) {
|
|
5358
5504
|
console.error(`Skill '${name}' not found at ${projectPath}/SKILL.md`);
|
|
5359
5505
|
process.exit(1);
|
|
5360
5506
|
}
|
|
5361
|
-
if (
|
|
5507
|
+
if (existsSync18(join21(globalPath, "SKILL.md"))) {
|
|
5362
5508
|
console.error(`Skill '${name}' already exists at ${globalPath}/SKILL.md \u2014 refusing to overwrite. Remove it first or rename the project skill.`);
|
|
5363
5509
|
process.exit(1);
|
|
5364
5510
|
}
|
|
5365
|
-
mkdirSync8(
|
|
5511
|
+
mkdirSync8(dirname4(globalPath), { recursive: true });
|
|
5366
5512
|
renameSync3(projectPath, globalPath);
|
|
5367
5513
|
console.log(`Promoted '${name}' from ${projectPath} \u2192 ${globalPath}.`);
|
|
5368
5514
|
}
|
|
@@ -5493,7 +5639,7 @@ async function pullSkills(args) {
|
|
|
5493
5639
|
console.error(`pull failed: ${e?.message ?? e}`);
|
|
5494
5640
|
process.exit(1);
|
|
5495
5641
|
}
|
|
5496
|
-
const dest = toRaw === "global" ?
|
|
5642
|
+
const dest = toRaw === "global" ? join21(homedir11(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
|
|
5497
5643
|
const filterDesc = users.length === 0 ? "all users" : users.join(", ");
|
|
5498
5644
|
console.log(`Destination: ${dest}`);
|
|
5499
5645
|
console.log(`Filter: ${filterDesc}${skillName ? ` \xB7 skill='${skillName}'` : ""}${dryRun ? " \xB7 dry-run" : ""}${force ? " \xB7 force" : ""}`);
|
|
@@ -5543,7 +5689,7 @@ async function unpullSkills(args) {
|
|
|
5543
5689
|
all,
|
|
5544
5690
|
legacyCleanup
|
|
5545
5691
|
});
|
|
5546
|
-
const dest = toRaw === "global" ?
|
|
5692
|
+
const dest = toRaw === "global" ? join21(homedir11(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
|
|
5547
5693
|
const filterParts = [];
|
|
5548
5694
|
if (users.length > 0)
|
|
5549
5695
|
filterParts.push(`users=${users.join(",")}`);
|
|
@@ -5632,13 +5778,13 @@ if (process.argv[1] && process.argv[1].endsWith("skilify.js")) {
|
|
|
5632
5778
|
|
|
5633
5779
|
// dist/src/cli/update.js
|
|
5634
5780
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
5635
|
-
import { existsSync as
|
|
5636
|
-
import { dirname as
|
|
5781
|
+
import { existsSync as existsSync19, readFileSync as readFileSync15, realpathSync } from "node:fs";
|
|
5782
|
+
import { dirname as dirname6, sep } from "node:path";
|
|
5637
5783
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
5638
5784
|
|
|
5639
5785
|
// dist/src/utils/version-check.js
|
|
5640
5786
|
import { readFileSync as readFileSync14 } from "node:fs";
|
|
5641
|
-
import { dirname as
|
|
5787
|
+
import { dirname as dirname5, join as join22 } from "node:path";
|
|
5642
5788
|
function isNewer(latest, current) {
|
|
5643
5789
|
const parse = (v) => v.split(".").map(Number);
|
|
5644
5790
|
const [la, lb, lc] = parse(latest);
|
|
@@ -5657,7 +5803,7 @@ function detectInstallKind(argv1) {
|
|
|
5657
5803
|
return argv1 ?? process.argv[1] ?? fileURLToPath2(import.meta.url);
|
|
5658
5804
|
}
|
|
5659
5805
|
})();
|
|
5660
|
-
let dir =
|
|
5806
|
+
let dir = dirname6(realArgv1);
|
|
5661
5807
|
let installDir = null;
|
|
5662
5808
|
for (let i = 0; i < 10; i++) {
|
|
5663
5809
|
const pkgPath = `${dir}${sep}package.json`;
|
|
@@ -5669,12 +5815,12 @@ function detectInstallKind(argv1) {
|
|
|
5669
5815
|
}
|
|
5670
5816
|
} catch {
|
|
5671
5817
|
}
|
|
5672
|
-
const parent =
|
|
5818
|
+
const parent = dirname6(dir);
|
|
5673
5819
|
if (parent === dir)
|
|
5674
5820
|
break;
|
|
5675
5821
|
dir = parent;
|
|
5676
5822
|
}
|
|
5677
|
-
installDir ??=
|
|
5823
|
+
installDir ??= dirname6(realArgv1);
|
|
5678
5824
|
if (realArgv1.includes(`${sep}_npx${sep}`) || realArgv1.includes(`${sep}.npx${sep}`)) {
|
|
5679
5825
|
return { kind: "npx", installDir };
|
|
5680
5826
|
}
|
|
@@ -5683,10 +5829,10 @@ function detectInstallKind(argv1) {
|
|
|
5683
5829
|
}
|
|
5684
5830
|
let gitDir = installDir;
|
|
5685
5831
|
for (let i = 0; i < 6; i++) {
|
|
5686
|
-
if (
|
|
5832
|
+
if (existsSync19(`${gitDir}${sep}.git`)) {
|
|
5687
5833
|
return { kind: "local-dev", installDir };
|
|
5688
5834
|
}
|
|
5689
|
-
const parent =
|
|
5835
|
+
const parent = dirname6(gitDir);
|
|
5690
5836
|
if (parent === gitDir)
|
|
5691
5837
|
break;
|
|
5692
5838
|
gitDir = parent;
|
|
@@ -5845,6 +5991,12 @@ Skill management (mine + share reusable Claude skills across the org):
|
|
|
5845
5991
|
Options: --user <email>, --users a,b,c,
|
|
5846
5992
|
--all-users, --to <project|global>,
|
|
5847
5993
|
--dry-run, --force.
|
|
5994
|
+
Note: every agent's SessionStart hook
|
|
5995
|
+
auto-runs 'pull --all-users --to global'
|
|
5996
|
+
on every session. File writes are
|
|
5997
|
+
idempotent (skipped when local is
|
|
5998
|
+
at-or-newer than remote). Disable via
|
|
5999
|
+
HIVEMIND_AUTOPULL_DISABLED=1.
|
|
5848
6000
|
hivemind skilify unpull Remove skills previously installed by pull.
|
|
5849
6001
|
Options: --user, --users, --not-mine,
|
|
5850
6002
|
--to <project|global>, --dry-run,
|