@deeplake/hivemind 0.7.32 → 0.7.34
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 +332 -189
- package/codex/bundle/capture.js +365 -332
- package/codex/bundle/commands/auth-login.js +163 -30
- package/codex/bundle/pre-tool-use.js +334 -301
- package/codex/bundle/session-start-setup.js +193 -60
- package/codex/bundle/session-start.js +229 -87
- package/codex/bundle/shell/deeplake-shell.js +328 -295
- package/codex/bundle/skillify-worker.js +26 -18
- package/codex/bundle/stop.js +450 -394
- package/codex/bundle/wiki-worker.js +174 -292
- package/cursor/bundle/capture.js +448 -392
- package/cursor/bundle/commands/auth-login.js +163 -30
- package/cursor/bundle/pre-tool-use.js +324 -291
- package/cursor/bundle/session-end.js +43 -20
- package/cursor/bundle/session-start.js +272 -130
- package/cursor/bundle/shell/deeplake-shell.js +328 -295
- package/cursor/bundle/skillify-worker.js +26 -18
- package/cursor/bundle/wiki-worker.js +174 -292
- package/hermes/bundle/capture.js +448 -392
- package/hermes/bundle/commands/auth-login.js +163 -30
- package/hermes/bundle/pre-tool-use.js +324 -291
- package/hermes/bundle/session-end.js +43 -20
- package/hermes/bundle/session-start.js +269 -127
- package/hermes/bundle/shell/deeplake-shell.js +328 -295
- package/hermes/bundle/skillify-worker.js +26 -18
- package/hermes/bundle/wiki-worker.js +174 -292
- package/mcp/bundle/server.js +190 -57
- package/openclaw/dist/index.js +160 -32
- package/openclaw/dist/skillify-worker.js +26 -18
- 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 existsSync14, mkdirSync 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
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({
|
|
@@ -519,19 +519,19 @@ function isPluginsAllowMissingHivemind(allow) {
|
|
|
519
519
|
return Array.isArray(allow) && allow.length > 0 && !allow.includes("hivemind");
|
|
520
520
|
}
|
|
521
521
|
function ensureHivemindAllowlisted() {
|
|
522
|
-
const
|
|
523
|
-
if (!existsSync4(
|
|
524
|
-
return { status: "error", configPath, error: "openclaw config file not found" };
|
|
522
|
+
const configPath2 = getOpenclawConfigPath();
|
|
523
|
+
if (!existsSync4(configPath2)) {
|
|
524
|
+
return { status: "error", configPath: configPath2, error: "openclaw config file not found" };
|
|
525
525
|
}
|
|
526
526
|
let parsed;
|
|
527
527
|
try {
|
|
528
|
-
const raw = readFileSync5(
|
|
528
|
+
const raw = readFileSync5(configPath2, "utf-8");
|
|
529
529
|
parsed = JSON.parse(raw);
|
|
530
530
|
} catch (e) {
|
|
531
|
-
return { status: "error", configPath, error: `could not read/parse config: ${e instanceof Error ? e.message : String(e)}` };
|
|
531
|
+
return { status: "error", configPath: configPath2, error: `could not read/parse config: ${e instanceof Error ? e.message : String(e)}` };
|
|
532
532
|
}
|
|
533
533
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
534
|
-
return { status: "error", configPath, error: "openclaw config is not a JSON object" };
|
|
534
|
+
return { status: "error", configPath: configPath2, error: "openclaw config is not a JSON object" };
|
|
535
535
|
}
|
|
536
536
|
const plugins = parsed.plugins ?? {};
|
|
537
537
|
const pluginsAllowRaw = plugins.allow;
|
|
@@ -540,7 +540,7 @@ function ensureHivemindAllowlisted() {
|
|
|
540
540
|
const pluginsAllowNeedsPatch = isPluginsAllowMissingHivemind(pluginsAllowRaw);
|
|
541
541
|
const toolsAlsoAllowNeedsPatch = Array.isArray(alsoAllowRaw) && alsoAllowRaw.length > 0 && !isAllowlistCoveringHivemind(alsoAllowRaw);
|
|
542
542
|
if (!pluginsAllowNeedsPatch && !toolsAlsoAllowNeedsPatch) {
|
|
543
|
-
return { status: "already-set", configPath };
|
|
543
|
+
return { status: "already-set", configPath: configPath2 };
|
|
544
544
|
}
|
|
545
545
|
const updated = { ...parsed };
|
|
546
546
|
if (pluginsAllowNeedsPatch) {
|
|
@@ -557,18 +557,18 @@ function ensureHivemindAllowlisted() {
|
|
|
557
557
|
alsoAllow: [...alsoAllowRaw, "hivemind"]
|
|
558
558
|
};
|
|
559
559
|
}
|
|
560
|
-
const backupPath = `${
|
|
561
|
-
const tmpPath = `${
|
|
560
|
+
const backupPath = `${configPath2}.bak-hivemind-${Date.now()}`;
|
|
561
|
+
const tmpPath = `${configPath2}.tmp-hivemind-${process.pid}`;
|
|
562
562
|
try {
|
|
563
|
-
writeFileSync3(backupPath, readFileSync5(
|
|
563
|
+
writeFileSync3(backupPath, readFileSync5(configPath2, "utf-8"));
|
|
564
564
|
writeFileSync3(tmpPath, JSON.stringify(updated, null, 2) + "\n");
|
|
565
|
-
renameSync(tmpPath,
|
|
565
|
+
renameSync(tmpPath, configPath2);
|
|
566
566
|
} catch (e) {
|
|
567
|
-
return { status: "error", configPath, error: `could not write config: ${e instanceof Error ? e.message : String(e)}` };
|
|
567
|
+
return { status: "error", configPath: configPath2, error: `could not write config: ${e instanceof Error ? e.message : String(e)}` };
|
|
568
568
|
}
|
|
569
569
|
return {
|
|
570
570
|
status: "added",
|
|
571
|
-
configPath,
|
|
571
|
+
configPath: configPath2,
|
|
572
572
|
backupPath,
|
|
573
573
|
delta: {
|
|
574
574
|
pluginsAllow: pluginsAllowNeedsPatch,
|
|
@@ -4343,6 +4343,107 @@ function sqlIdent(name) {
|
|
|
4343
4343
|
var SUMMARY_EMBEDDING_COL = "summary_embedding";
|
|
4344
4344
|
var MESSAGE_EMBEDDING_COL = "message_embedding";
|
|
4345
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
|
+
|
|
4346
4447
|
// dist/src/deeplake-api.js
|
|
4347
4448
|
var indexMarkerStorePromise = null;
|
|
4348
4449
|
function getIndexMarkerStore() {
|
|
@@ -4350,7 +4451,7 @@ function getIndexMarkerStore() {
|
|
|
4350
4451
|
indexMarkerStorePromise = Promise.resolve().then(() => (init_index_marker_store(), index_marker_store_exports));
|
|
4351
4452
|
return indexMarkerStorePromise;
|
|
4352
4453
|
}
|
|
4353
|
-
var
|
|
4454
|
+
var log4 = (msg) => log2("sdk", msg);
|
|
4354
4455
|
function summarizeSql(sql, maxLen = 220) {
|
|
4355
4456
|
const compact = sql.replace(/\s+/g, " ").trim();
|
|
4356
4457
|
return compact.length > maxLen ? `${compact.slice(0, maxLen)}...` : compact;
|
|
@@ -4362,7 +4463,38 @@ function traceSql(msg) {
|
|
|
4362
4463
|
process.stderr.write(`[deeplake-sql] ${msg}
|
|
4363
4464
|
`);
|
|
4364
4465
|
if (process.env.HIVEMIND_DEBUG === "1")
|
|
4365
|
-
|
|
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";
|
|
4366
4498
|
}
|
|
4367
4499
|
var RETRYABLE_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
4368
4500
|
var MAX_RETRIES = 3;
|
|
@@ -4371,8 +4503,8 @@ var MAX_CONCURRENCY = 5;
|
|
|
4371
4503
|
function getQueryTimeoutMs() {
|
|
4372
4504
|
return Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
|
|
4373
4505
|
}
|
|
4374
|
-
function
|
|
4375
|
-
return new Promise((
|
|
4506
|
+
function sleep2(ms) {
|
|
4507
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
4376
4508
|
}
|
|
4377
4509
|
function isTimeoutError(error) {
|
|
4378
4510
|
const name = error instanceof Error ? error.name.toLowerCase() : "";
|
|
@@ -4402,7 +4534,7 @@ var Semaphore = class {
|
|
|
4402
4534
|
this.active++;
|
|
4403
4535
|
return;
|
|
4404
4536
|
}
|
|
4405
|
-
await new Promise((
|
|
4537
|
+
await new Promise((resolve2) => this.waiting.push(resolve2));
|
|
4406
4538
|
}
|
|
4407
4539
|
release() {
|
|
4408
4540
|
this.active--;
|
|
@@ -4473,8 +4605,8 @@ var DeeplakeApi = class {
|
|
|
4473
4605
|
lastError = e instanceof Error ? e : new Error(String(e));
|
|
4474
4606
|
if (attempt < MAX_RETRIES) {
|
|
4475
4607
|
const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
|
|
4476
|
-
|
|
4477
|
-
await
|
|
4608
|
+
log4(`query retry ${attempt + 1}/${MAX_RETRIES} (fetch error: ${lastError.message}) in ${delay.toFixed(0)}ms`);
|
|
4609
|
+
await sleep2(delay);
|
|
4478
4610
|
continue;
|
|
4479
4611
|
}
|
|
4480
4612
|
throw lastError;
|
|
@@ -4490,10 +4622,11 @@ var DeeplakeApi = class {
|
|
|
4490
4622
|
const alreadyExists = resp.status === 500 && isDuplicateIndexError(text);
|
|
4491
4623
|
if (!alreadyExists && attempt < MAX_RETRIES && (RETRYABLE_CODES.has(resp.status) || retryable403)) {
|
|
4492
4624
|
const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
|
|
4493
|
-
|
|
4494
|
-
await
|
|
4625
|
+
log4(`query retry ${attempt + 1}/${MAX_RETRIES} (${resp.status}) in ${delay.toFixed(0)}ms`);
|
|
4626
|
+
await sleep2(delay);
|
|
4495
4627
|
continue;
|
|
4496
4628
|
}
|
|
4629
|
+
maybeSignalBalanceExhausted(resp.status, text);
|
|
4497
4630
|
throw new Error(`Query failed: ${resp.status}: ${text.slice(0, 200)}`);
|
|
4498
4631
|
}
|
|
4499
4632
|
throw lastError ?? new Error("Query failed: max retries exceeded");
|
|
@@ -4514,7 +4647,7 @@ var DeeplakeApi = class {
|
|
|
4514
4647
|
const chunk = rows.slice(i, i + CONCURRENCY);
|
|
4515
4648
|
await Promise.allSettled(chunk.map((r) => this.upsertRowSql(r)));
|
|
4516
4649
|
}
|
|
4517
|
-
|
|
4650
|
+
log4(`commit: ${rows.length} rows`);
|
|
4518
4651
|
}
|
|
4519
4652
|
async upsertRowSql(row) {
|
|
4520
4653
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -4570,7 +4703,7 @@ var DeeplakeApi = class {
|
|
|
4570
4703
|
markers.writeIndexMarker(markerPath);
|
|
4571
4704
|
return;
|
|
4572
4705
|
}
|
|
4573
|
-
|
|
4706
|
+
log4(`index "${indexName}" skipped: ${e.message}`);
|
|
4574
4707
|
}
|
|
4575
4708
|
}
|
|
4576
4709
|
/**
|
|
@@ -4660,13 +4793,13 @@ var DeeplakeApi = class {
|
|
|
4660
4793
|
};
|
|
4661
4794
|
}
|
|
4662
4795
|
if (attempt < MAX_RETRIES && RETRYABLE_CODES.has(resp.status)) {
|
|
4663
|
-
await
|
|
4796
|
+
await sleep2(BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200);
|
|
4664
4797
|
continue;
|
|
4665
4798
|
}
|
|
4666
4799
|
return { tables: [], cacheable: false };
|
|
4667
4800
|
} catch {
|
|
4668
4801
|
if (attempt < MAX_RETRIES) {
|
|
4669
|
-
await
|
|
4802
|
+
await sleep2(BASE_DELAY_MS * Math.pow(2, attempt));
|
|
4670
4803
|
continue;
|
|
4671
4804
|
}
|
|
4672
4805
|
return { tables: [], cacheable: false };
|
|
@@ -4694,9 +4827,9 @@ var DeeplakeApi = class {
|
|
|
4694
4827
|
} catch (err) {
|
|
4695
4828
|
lastErr = err;
|
|
4696
4829
|
const msg = err instanceof Error ? err.message : String(err);
|
|
4697
|
-
|
|
4830
|
+
log4(`CREATE TABLE "${label}" attempt ${attempt + 1}/${OUTER_BACKOFFS_MS.length + 1} failed: ${msg}`);
|
|
4698
4831
|
if (attempt < OUTER_BACKOFFS_MS.length) {
|
|
4699
|
-
await
|
|
4832
|
+
await sleep2(OUTER_BACKOFFS_MS[attempt]);
|
|
4700
4833
|
}
|
|
4701
4834
|
}
|
|
4702
4835
|
}
|
|
@@ -4707,9 +4840,9 @@ var DeeplakeApi = class {
|
|
|
4707
4840
|
const tbl = sqlIdent(name ?? this.tableName);
|
|
4708
4841
|
const tables = await this.listTables();
|
|
4709
4842
|
if (!tables.includes(tbl)) {
|
|
4710
|
-
|
|
4843
|
+
log4(`table "${tbl}" not found, creating`);
|
|
4711
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);
|
|
4712
|
-
|
|
4845
|
+
log4(`table "${tbl}" created`);
|
|
4713
4846
|
if (!tables.includes(tbl))
|
|
4714
4847
|
this._tablesCache = [...tables, tbl];
|
|
4715
4848
|
}
|
|
@@ -4722,9 +4855,9 @@ var DeeplakeApi = class {
|
|
|
4722
4855
|
const safe = sqlIdent(name);
|
|
4723
4856
|
const tables = await this.listTables();
|
|
4724
4857
|
if (!tables.includes(safe)) {
|
|
4725
|
-
|
|
4858
|
+
log4(`table "${safe}" not found, creating`);
|
|
4726
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);
|
|
4727
|
-
|
|
4860
|
+
log4(`table "${safe}" created`);
|
|
4728
4861
|
if (!tables.includes(safe))
|
|
4729
4862
|
this._tablesCache = [...tables, safe];
|
|
4730
4863
|
}
|
|
@@ -4747,9 +4880,9 @@ var DeeplakeApi = class {
|
|
|
4747
4880
|
const safe = sqlIdent(name);
|
|
4748
4881
|
const tables = await this.listTables();
|
|
4749
4882
|
if (!tables.includes(safe)) {
|
|
4750
|
-
|
|
4883
|
+
log4(`table "${safe}" not found, creating`);
|
|
4751
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);
|
|
4752
|
-
|
|
4885
|
+
log4(`table "${safe}" created`);
|
|
4753
4886
|
if (!tables.includes(safe))
|
|
4754
4887
|
this._tablesCache = [...tables, safe];
|
|
4755
4888
|
}
|
|
@@ -4780,10 +4913,10 @@ function parseArgs(argv) {
|
|
|
4780
4913
|
}
|
|
4781
4914
|
function confirm(message) {
|
|
4782
4915
|
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
4783
|
-
return new Promise((
|
|
4916
|
+
return new Promise((resolve2) => {
|
|
4784
4917
|
rl.question(`${message} [y/N] `, (answer) => {
|
|
4785
4918
|
rl.close();
|
|
4786
|
-
|
|
4919
|
+
resolve2(answer.trim().toLowerCase() === "y");
|
|
4787
4920
|
});
|
|
4788
4921
|
});
|
|
4789
4922
|
}
|
|
@@ -5085,39 +5218,48 @@ if (process.argv[1] && process.argv[1].endsWith("auth-login.js")) {
|
|
|
5085
5218
|
}
|
|
5086
5219
|
|
|
5087
5220
|
// dist/src/commands/skillify.js
|
|
5088
|
-
import { readdirSync as readdirSync5, existsSync as existsSync26, readFileSync as
|
|
5089
|
-
import { homedir as
|
|
5090
|
-
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 homedir18 } from "node:os";
|
|
5223
|
+
import { dirname as dirname8, join as join31 } from "node:path";
|
|
5091
5224
|
|
|
5092
5225
|
// dist/src/skillify/scope-config.js
|
|
5093
|
-
import { existsSync as existsSync16, mkdirSync as
|
|
5226
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync6, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "node:fs";
|
|
5227
|
+
import { join as join21 } from "node:path";
|
|
5228
|
+
|
|
5229
|
+
// dist/src/skillify/legacy-migration.js
|
|
5230
|
+
import { existsSync as existsSync15, renameSync as renameSync4 } from "node:fs";
|
|
5231
|
+
import { dirname as dirname3, join as join20 } from "node:path";
|
|
5232
|
+
|
|
5233
|
+
// dist/src/skillify/state-dir.js
|
|
5094
5234
|
import { homedir as homedir9 } from "node:os";
|
|
5095
5235
|
import { join as join19 } from "node:path";
|
|
5236
|
+
function getStateDir() {
|
|
5237
|
+
const override = process.env.HIVEMIND_STATE_DIR?.trim();
|
|
5238
|
+
return override && override.length > 0 ? override : join19(homedir9(), ".deeplake", "state", "skillify");
|
|
5239
|
+
}
|
|
5096
5240
|
|
|
5097
5241
|
// dist/src/skillify/legacy-migration.js
|
|
5098
|
-
import { existsSync as existsSync15, renameSync as renameSync3 } from "node:fs";
|
|
5099
|
-
import { homedir as homedir8 } from "node:os";
|
|
5100
|
-
import { join as join18 } from "node:path";
|
|
5101
5242
|
var dlog = (msg) => log2("skillify-migrate", msg);
|
|
5102
5243
|
var attempted = false;
|
|
5103
5244
|
function migrateLegacyStateDir() {
|
|
5245
|
+
if (process.env.HIVEMIND_STATE_DIR?.trim())
|
|
5246
|
+
return;
|
|
5104
5247
|
if (attempted)
|
|
5105
5248
|
return;
|
|
5106
5249
|
attempted = true;
|
|
5107
|
-
const
|
|
5108
|
-
const legacy =
|
|
5109
|
-
const current = join18(root, "skillify");
|
|
5250
|
+
const current = getStateDir();
|
|
5251
|
+
const legacy = join20(dirname3(current), "skilify");
|
|
5110
5252
|
if (!existsSync15(legacy))
|
|
5111
5253
|
return;
|
|
5112
5254
|
if (existsSync15(current))
|
|
5113
5255
|
return;
|
|
5114
5256
|
try {
|
|
5115
|
-
|
|
5257
|
+
renameSync4(legacy, current);
|
|
5116
5258
|
dlog(`migrated ${legacy} -> ${current}`);
|
|
5117
5259
|
} catch (err) {
|
|
5118
5260
|
const code = err.code;
|
|
5119
|
-
if (code === "EXDEV" || code === "EPERM") {
|
|
5120
|
-
dlog(`migration
|
|
5261
|
+
if (code === "EXDEV" || code === "EPERM" || code === "ENOENT" || code === "EEXIST" || code === "ENOTEMPTY") {
|
|
5262
|
+
dlog(`migration skipped (${code}); legacy dir left as-is or another process handled it`);
|
|
5121
5263
|
return;
|
|
5122
5264
|
}
|
|
5123
5265
|
throw err;
|
|
@@ -5125,15 +5267,17 @@ function migrateLegacyStateDir() {
|
|
|
5125
5267
|
}
|
|
5126
5268
|
|
|
5127
5269
|
// dist/src/skillify/scope-config.js
|
|
5128
|
-
|
|
5129
|
-
|
|
5270
|
+
function configPath() {
|
|
5271
|
+
return join21(getStateDir(), "config.json");
|
|
5272
|
+
}
|
|
5130
5273
|
var DEFAULT = { scope: "me", team: [], install: "project" };
|
|
5131
5274
|
function loadScopeConfig() {
|
|
5132
5275
|
migrateLegacyStateDir();
|
|
5276
|
+
const CONFIG_PATH2 = configPath();
|
|
5133
5277
|
if (!existsSync16(CONFIG_PATH2))
|
|
5134
5278
|
return DEFAULT;
|
|
5135
5279
|
try {
|
|
5136
|
-
const raw = JSON.parse(
|
|
5280
|
+
const raw = JSON.parse(readFileSync14(CONFIG_PATH2, "utf-8"));
|
|
5137
5281
|
const scope = raw.scope === "team" ? "team" : raw.scope === "org" ? "team" : "me";
|
|
5138
5282
|
const team = Array.isArray(raw.team) ? raw.team.filter((s) => typeof s === "string") : [];
|
|
5139
5283
|
const install = raw.install === "global" ? "global" : "project";
|
|
@@ -5144,19 +5288,19 @@ function loadScopeConfig() {
|
|
|
5144
5288
|
}
|
|
5145
5289
|
function saveScopeConfig(cfg) {
|
|
5146
5290
|
migrateLegacyStateDir();
|
|
5147
|
-
|
|
5148
|
-
|
|
5291
|
+
mkdirSync6(getStateDir(), { recursive: true });
|
|
5292
|
+
writeFileSync10(configPath(), JSON.stringify(cfg, null, 2));
|
|
5149
5293
|
}
|
|
5150
5294
|
|
|
5151
5295
|
// dist/src/skillify/pull.js
|
|
5152
|
-
import { existsSync as existsSync20, readFileSync as
|
|
5153
|
-
import { homedir as
|
|
5154
|
-
import { dirname as
|
|
5296
|
+
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";
|
|
5297
|
+
import { homedir as homedir12 } from "node:os";
|
|
5298
|
+
import { dirname as dirname5, join as join25 } from "node:path";
|
|
5155
5299
|
|
|
5156
5300
|
// dist/src/skillify/skill-writer.js
|
|
5157
|
-
import { existsSync as existsSync17, mkdirSync as
|
|
5301
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync7, readFileSync as readFileSync15, readdirSync as readdirSync2, statSync as statSync3, writeFileSync as writeFileSync11 } from "node:fs";
|
|
5158
5302
|
import { homedir as homedir10 } from "node:os";
|
|
5159
|
-
import { join as
|
|
5303
|
+
import { join as join22 } from "node:path";
|
|
5160
5304
|
function assertValidSkillName(name) {
|
|
5161
5305
|
if (typeof name !== "string" || name.length === 0) {
|
|
5162
5306
|
throw new Error(`invalid skill name: empty or non-string`);
|
|
@@ -5172,10 +5316,10 @@ function assertValidSkillName(name) {
|
|
|
5172
5316
|
}
|
|
5173
5317
|
}
|
|
5174
5318
|
function skillDir(skillsRoot, name) {
|
|
5175
|
-
return
|
|
5319
|
+
return join22(skillsRoot, name);
|
|
5176
5320
|
}
|
|
5177
5321
|
function skillPath(skillsRoot, name) {
|
|
5178
|
-
return
|
|
5322
|
+
return join22(skillDir(skillsRoot, name), "SKILL.md");
|
|
5179
5323
|
}
|
|
5180
5324
|
function renderFrontmatter(fm) {
|
|
5181
5325
|
const lines = ["---"];
|
|
@@ -5256,7 +5400,7 @@ function writeNewSkill(args) {
|
|
|
5256
5400
|
if (existsSync17(path)) {
|
|
5257
5401
|
throw new Error(`skill already exists at ${path}; use mergeSkill`);
|
|
5258
5402
|
}
|
|
5259
|
-
|
|
5403
|
+
mkdirSync7(dir, { recursive: true });
|
|
5260
5404
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
5261
5405
|
const author = args.author && args.author.length > 0 ? args.author : void 0;
|
|
5262
5406
|
const contributors = author ? [author] : [];
|
|
@@ -5276,7 +5420,7 @@ function writeNewSkill(args) {
|
|
|
5276
5420
|
|
|
5277
5421
|
${args.body.trim()}
|
|
5278
5422
|
`;
|
|
5279
|
-
|
|
5423
|
+
writeFileSync11(path, text);
|
|
5280
5424
|
return {
|
|
5281
5425
|
path,
|
|
5282
5426
|
action: "created",
|
|
@@ -5292,29 +5436,28 @@ function listSkills(skillsRoot) {
|
|
|
5292
5436
|
return [];
|
|
5293
5437
|
const out = [];
|
|
5294
5438
|
for (const name of readdirSync2(skillsRoot)) {
|
|
5295
|
-
const skillFile =
|
|
5296
|
-
if (existsSync17(skillFile) &&
|
|
5297
|
-
out.push({ name, body:
|
|
5439
|
+
const skillFile = join22(skillsRoot, name, "SKILL.md");
|
|
5440
|
+
if (existsSync17(skillFile) && statSync3(skillFile).isFile()) {
|
|
5441
|
+
out.push({ name, body: readFileSync15(skillFile, "utf-8") });
|
|
5298
5442
|
}
|
|
5299
5443
|
}
|
|
5300
5444
|
return out;
|
|
5301
5445
|
}
|
|
5302
5446
|
function resolveSkillsRoot(install, cwd) {
|
|
5303
5447
|
if (install === "global") {
|
|
5304
|
-
return
|
|
5448
|
+
return join22(homedir10(), ".claude", "skills");
|
|
5305
5449
|
}
|
|
5306
|
-
return
|
|
5450
|
+
return join22(cwd, ".claude", "skills");
|
|
5307
5451
|
}
|
|
5308
5452
|
|
|
5309
5453
|
// dist/src/skillify/manifest.js
|
|
5310
|
-
import { existsSync as existsSync18, lstatSync as lstatSync3, mkdirSync as
|
|
5311
|
-
import {
|
|
5312
|
-
import { dirname as dirname3, join as join21 } from "node:path";
|
|
5454
|
+
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";
|
|
5455
|
+
import { dirname as dirname4, join as join23 } from "node:path";
|
|
5313
5456
|
function emptyManifest() {
|
|
5314
5457
|
return { version: 1, entries: [] };
|
|
5315
5458
|
}
|
|
5316
5459
|
function manifestPath() {
|
|
5317
|
-
return
|
|
5460
|
+
return join23(getStateDir(), "pulled.json");
|
|
5318
5461
|
}
|
|
5319
5462
|
function loadManifest(path = manifestPath()) {
|
|
5320
5463
|
migrateLegacyStateDir();
|
|
@@ -5322,7 +5465,7 @@ function loadManifest(path = manifestPath()) {
|
|
|
5322
5465
|
return emptyManifest();
|
|
5323
5466
|
let raw;
|
|
5324
5467
|
try {
|
|
5325
|
-
raw =
|
|
5468
|
+
raw = readFileSync16(path, "utf-8");
|
|
5326
5469
|
} catch {
|
|
5327
5470
|
return emptyManifest();
|
|
5328
5471
|
}
|
|
@@ -5369,10 +5512,10 @@ function loadManifest(path = manifestPath()) {
|
|
|
5369
5512
|
}
|
|
5370
5513
|
function saveManifest(m, path = manifestPath()) {
|
|
5371
5514
|
migrateLegacyStateDir();
|
|
5372
|
-
|
|
5515
|
+
mkdirSync8(dirname4(path), { recursive: true });
|
|
5373
5516
|
const tmp = `${path}.tmp`;
|
|
5374
|
-
|
|
5375
|
-
|
|
5517
|
+
writeFileSync12(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
|
|
5518
|
+
renameSync5(tmp, path);
|
|
5376
5519
|
}
|
|
5377
5520
|
function recordPull(entry, path = manifestPath()) {
|
|
5378
5521
|
const m = loadManifest(path);
|
|
@@ -5404,7 +5547,7 @@ function unlinkSymlinks(paths) {
|
|
|
5404
5547
|
if (!st.isSymbolicLink())
|
|
5405
5548
|
continue;
|
|
5406
5549
|
try {
|
|
5407
|
-
|
|
5550
|
+
unlinkSync8(path);
|
|
5408
5551
|
} catch {
|
|
5409
5552
|
}
|
|
5410
5553
|
}
|
|
@@ -5414,7 +5557,7 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
5414
5557
|
const live = [];
|
|
5415
5558
|
let pruned = 0;
|
|
5416
5559
|
for (const e of m.entries) {
|
|
5417
|
-
if (existsSync18(
|
|
5560
|
+
if (existsSync18(join23(e.installRoot, e.dirName))) {
|
|
5418
5561
|
live.push(e);
|
|
5419
5562
|
continue;
|
|
5420
5563
|
}
|
|
@@ -5428,25 +5571,25 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
5428
5571
|
|
|
5429
5572
|
// dist/src/skillify/agent-roots.js
|
|
5430
5573
|
import { existsSync as existsSync19 } from "node:fs";
|
|
5431
|
-
import { homedir as
|
|
5432
|
-
import { join as
|
|
5574
|
+
import { homedir as homedir11 } from "node:os";
|
|
5575
|
+
import { join as join24 } from "node:path";
|
|
5433
5576
|
function resolveDetected(home) {
|
|
5434
5577
|
const out = [];
|
|
5435
|
-
const codexInstalled = existsSync19(
|
|
5436
|
-
const piInstalled = existsSync19(
|
|
5437
|
-
const hermesInstalled = existsSync19(
|
|
5578
|
+
const codexInstalled = existsSync19(join24(home, ".codex"));
|
|
5579
|
+
const piInstalled = existsSync19(join24(home, ".pi", "agent"));
|
|
5580
|
+
const hermesInstalled = existsSync19(join24(home, ".hermes"));
|
|
5438
5581
|
if (codexInstalled || piInstalled) {
|
|
5439
|
-
out.push(
|
|
5582
|
+
out.push(join24(home, ".agents", "skills"));
|
|
5440
5583
|
}
|
|
5441
5584
|
if (hermesInstalled) {
|
|
5442
|
-
out.push(
|
|
5585
|
+
out.push(join24(home, ".hermes", "skills"));
|
|
5443
5586
|
}
|
|
5444
5587
|
if (piInstalled) {
|
|
5445
|
-
out.push(
|
|
5588
|
+
out.push(join24(home, ".pi", "agent", "skills"));
|
|
5446
5589
|
}
|
|
5447
5590
|
return out;
|
|
5448
5591
|
}
|
|
5449
|
-
function detectAgentSkillsRoots(canonicalRoot, home =
|
|
5592
|
+
function detectAgentSkillsRoots(canonicalRoot, home = homedir11()) {
|
|
5450
5593
|
return resolveDetected(home).filter((p) => p !== canonicalRoot);
|
|
5451
5594
|
}
|
|
5452
5595
|
|
|
@@ -5490,15 +5633,15 @@ function isMissingTableError(message) {
|
|
|
5490
5633
|
}
|
|
5491
5634
|
function resolvePullDestination(install, cwd) {
|
|
5492
5635
|
if (install === "global")
|
|
5493
|
-
return
|
|
5636
|
+
return join25(homedir12(), ".claude", "skills");
|
|
5494
5637
|
if (!cwd)
|
|
5495
5638
|
throw new Error("install=project requires a cwd");
|
|
5496
|
-
return
|
|
5639
|
+
return join25(cwd, ".claude", "skills");
|
|
5497
5640
|
}
|
|
5498
5641
|
function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
|
|
5499
5642
|
const out = [];
|
|
5500
5643
|
for (const root of agentRoots) {
|
|
5501
|
-
const link =
|
|
5644
|
+
const link = join25(root, dirName);
|
|
5502
5645
|
let existing;
|
|
5503
5646
|
try {
|
|
5504
5647
|
existing = lstatSync4(link);
|
|
@@ -5520,13 +5663,13 @@ function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
|
|
|
5520
5663
|
continue;
|
|
5521
5664
|
}
|
|
5522
5665
|
try {
|
|
5523
|
-
|
|
5666
|
+
unlinkSync9(link);
|
|
5524
5667
|
} catch {
|
|
5525
5668
|
continue;
|
|
5526
5669
|
}
|
|
5527
5670
|
}
|
|
5528
5671
|
try {
|
|
5529
|
-
|
|
5672
|
+
mkdirSync9(dirname5(link), { recursive: true });
|
|
5530
5673
|
symlinkSync2(canonicalDir, link, "dir");
|
|
5531
5674
|
out.push(link);
|
|
5532
5675
|
} catch {
|
|
@@ -5541,7 +5684,7 @@ function backfillSymlinks(installRoot) {
|
|
|
5541
5684
|
return;
|
|
5542
5685
|
const detected = detectAgentSkillsRoots(installRoot);
|
|
5543
5686
|
for (const entry of entries) {
|
|
5544
|
-
const canonical =
|
|
5687
|
+
const canonical = join25(entry.installRoot, entry.dirName);
|
|
5545
5688
|
if (!existsSync20(canonical))
|
|
5546
5689
|
continue;
|
|
5547
5690
|
const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
|
|
@@ -5655,7 +5798,7 @@ function readLocalVersion(path) {
|
|
|
5655
5798
|
if (!existsSync20(path))
|
|
5656
5799
|
return null;
|
|
5657
5800
|
try {
|
|
5658
|
-
const text =
|
|
5801
|
+
const text = readFileSync17(path, "utf-8");
|
|
5659
5802
|
const parsed = parseFrontmatter(text);
|
|
5660
5803
|
if (!parsed)
|
|
5661
5804
|
return null;
|
|
@@ -5750,8 +5893,8 @@ async function runPull(opts) {
|
|
|
5750
5893
|
summary.skipped++;
|
|
5751
5894
|
continue;
|
|
5752
5895
|
}
|
|
5753
|
-
const skillDir2 =
|
|
5754
|
-
const skillFile =
|
|
5896
|
+
const skillDir2 = join25(root, dirName);
|
|
5897
|
+
const skillFile = join25(skillDir2, "SKILL.md");
|
|
5755
5898
|
const remoteVersion = Number(row.version ?? 1);
|
|
5756
5899
|
const localVersion = readLocalVersion(skillFile);
|
|
5757
5900
|
const action = decideAction({
|
|
@@ -5762,14 +5905,14 @@ async function runPull(opts) {
|
|
|
5762
5905
|
});
|
|
5763
5906
|
let manifestError;
|
|
5764
5907
|
if (action === "wrote") {
|
|
5765
|
-
|
|
5908
|
+
mkdirSync9(skillDir2, { recursive: true });
|
|
5766
5909
|
if (existsSync20(skillFile)) {
|
|
5767
5910
|
try {
|
|
5768
|
-
|
|
5911
|
+
renameSync6(skillFile, `${skillFile}.bak`);
|
|
5769
5912
|
} catch {
|
|
5770
5913
|
}
|
|
5771
5914
|
}
|
|
5772
|
-
|
|
5915
|
+
writeFileSync13(skillFile, renderSkillFile(row));
|
|
5773
5916
|
const symlinks = opts.install === "global" ? fanOutSymlinks(skillDir2, dirName, detectAgentSkillsRoots(root)) : [];
|
|
5774
5917
|
try {
|
|
5775
5918
|
recordPull({
|
|
@@ -5811,15 +5954,15 @@ async function runPull(opts) {
|
|
|
5811
5954
|
}
|
|
5812
5955
|
|
|
5813
5956
|
// dist/src/skillify/unpull.js
|
|
5814
|
-
import { existsSync as existsSync21, readdirSync as readdirSync3, rmSync as rmSync5, statSync as
|
|
5815
|
-
import { homedir as
|
|
5816
|
-
import { join as
|
|
5957
|
+
import { existsSync as existsSync21, readdirSync as readdirSync3, rmSync as rmSync5, statSync as statSync4 } from "node:fs";
|
|
5958
|
+
import { homedir as homedir13 } from "node:os";
|
|
5959
|
+
import { join as join26 } from "node:path";
|
|
5817
5960
|
function resolveUnpullRoot(install, cwd) {
|
|
5818
5961
|
if (install === "global")
|
|
5819
|
-
return
|
|
5962
|
+
return join26(homedir13(), ".claude", "skills");
|
|
5820
5963
|
if (!cwd)
|
|
5821
5964
|
throw new Error("cwd required when install === 'project'");
|
|
5822
|
-
return
|
|
5965
|
+
return join26(cwd, ".claude", "skills");
|
|
5823
5966
|
}
|
|
5824
5967
|
function runUnpull(opts) {
|
|
5825
5968
|
const root = resolveUnpullRoot(opts.install, opts.cwd);
|
|
@@ -5842,7 +5985,7 @@ function runUnpull(opts) {
|
|
|
5842
5985
|
const entries = entriesForRoot(manifest, opts.install, root);
|
|
5843
5986
|
for (const entry of entries) {
|
|
5844
5987
|
summary.scanned++;
|
|
5845
|
-
const path =
|
|
5988
|
+
const path = join26(root, entry.dirName);
|
|
5846
5989
|
if (!existsSync21(path)) {
|
|
5847
5990
|
if (!opts.dryRun) {
|
|
5848
5991
|
unlinkSymlinks(entry.symlinks);
|
|
@@ -5901,10 +6044,10 @@ function runUnpull(opts) {
|
|
|
5901
6044
|
for (const dirName of readdirSync3(root)) {
|
|
5902
6045
|
if (manifestDirNames.has(dirName))
|
|
5903
6046
|
continue;
|
|
5904
|
-
const path =
|
|
6047
|
+
const path = join26(root, dirName);
|
|
5905
6048
|
let st;
|
|
5906
6049
|
try {
|
|
5907
|
-
st =
|
|
6050
|
+
st = statSync4(path);
|
|
5908
6051
|
} catch {
|
|
5909
6052
|
continue;
|
|
5910
6053
|
}
|
|
@@ -5980,21 +6123,21 @@ function decideTargetForManifestEntry(entry, opts, userFilter, haveUserFilter) {
|
|
|
5980
6123
|
|
|
5981
6124
|
// dist/src/commands/mine-local.js
|
|
5982
6125
|
import { spawn } from "node:child_process";
|
|
5983
|
-
import { existsSync as existsSync25, mkdirSync as
|
|
5984
|
-
import { homedir as
|
|
5985
|
-
import { basename, dirname as
|
|
6126
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync11, readFileSync as readFileSync20, writeFileSync as writeFileSync15 } from "node:fs";
|
|
6127
|
+
import { homedir as homedir17 } from "node:os";
|
|
6128
|
+
import { basename, dirname as dirname7, join as join30 } from "node:path";
|
|
5986
6129
|
|
|
5987
6130
|
// dist/src/skillify/local-source.js
|
|
5988
|
-
import { readdirSync as readdirSync4, readFileSync as
|
|
5989
|
-
import { homedir as
|
|
5990
|
-
import { join as
|
|
5991
|
-
var HOME2 =
|
|
6131
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync18, existsSync as existsSync22, statSync as statSync5 } from "node:fs";
|
|
6132
|
+
import { homedir as homedir14 } from "node:os";
|
|
6133
|
+
import { join as join27 } from "node:path";
|
|
6134
|
+
var HOME2 = homedir14();
|
|
5992
6135
|
function encodeCwdClaudeCode(cwd) {
|
|
5993
6136
|
return cwd.replace(/[/_]/g, "-");
|
|
5994
6137
|
}
|
|
5995
6138
|
function detectInstalledAgents() {
|
|
5996
6139
|
const installs = [];
|
|
5997
|
-
const claudeRoot =
|
|
6140
|
+
const claudeRoot = join27(HOME2, ".claude", "projects");
|
|
5998
6141
|
if (existsSync22(claudeRoot)) {
|
|
5999
6142
|
installs.push({
|
|
6000
6143
|
agent: "claude_code",
|
|
@@ -6002,7 +6145,7 @@ function detectInstalledAgents() {
|
|
|
6002
6145
|
encodeCwd: encodeCwdClaudeCode
|
|
6003
6146
|
});
|
|
6004
6147
|
}
|
|
6005
|
-
const codexRoot =
|
|
6148
|
+
const codexRoot = join27(HOME2, ".codex", "sessions");
|
|
6006
6149
|
if (existsSync22(codexRoot)) {
|
|
6007
6150
|
installs.push({
|
|
6008
6151
|
agent: "codex",
|
|
@@ -6030,9 +6173,9 @@ function listLocalSessions(installs, cwd) {
|
|
|
6030
6173
|
continue;
|
|
6031
6174
|
}
|
|
6032
6175
|
for (const sub of subdirs) {
|
|
6033
|
-
const subdirPath =
|
|
6176
|
+
const subdirPath = join27(install.sessionRoot, sub);
|
|
6034
6177
|
try {
|
|
6035
|
-
if (!
|
|
6178
|
+
if (!statSync5(subdirPath).isDirectory())
|
|
6036
6179
|
continue;
|
|
6037
6180
|
} catch {
|
|
6038
6181
|
continue;
|
|
@@ -6047,10 +6190,10 @@ function listLocalSessions(installs, cwd) {
|
|
|
6047
6190
|
for (const f of files) {
|
|
6048
6191
|
if (!f.endsWith(".jsonl"))
|
|
6049
6192
|
continue;
|
|
6050
|
-
const fullPath =
|
|
6193
|
+
const fullPath = join27(subdirPath, f);
|
|
6051
6194
|
let stats;
|
|
6052
6195
|
try {
|
|
6053
|
-
stats =
|
|
6196
|
+
stats = statSync5(fullPath);
|
|
6054
6197
|
} catch {
|
|
6055
6198
|
continue;
|
|
6056
6199
|
}
|
|
@@ -6108,7 +6251,7 @@ function pickSessions(candidates, opts) {
|
|
|
6108
6251
|
function nativeJsonlToRows(filePath, sessionId, agent) {
|
|
6109
6252
|
let raw;
|
|
6110
6253
|
try {
|
|
6111
|
-
raw =
|
|
6254
|
+
raw = readFileSync18(filePath, "utf-8");
|
|
6112
6255
|
} catch {
|
|
6113
6256
|
return [];
|
|
6114
6257
|
}
|
|
@@ -6200,8 +6343,8 @@ function extractPairs(rows) {
|
|
|
6200
6343
|
// dist/src/skillify/gate-runner.js
|
|
6201
6344
|
import { existsSync as existsSync23 } from "node:fs";
|
|
6202
6345
|
import { createRequire } from "node:module";
|
|
6203
|
-
import { homedir as
|
|
6204
|
-
import { join as
|
|
6346
|
+
import { homedir as homedir15 } from "node:os";
|
|
6347
|
+
import { join as join28 } from "node:path";
|
|
6205
6348
|
var requireForCp = createRequire(import.meta.url);
|
|
6206
6349
|
var { execFileSync: runChildProcess } = requireForCp("node:child_process");
|
|
6207
6350
|
var inheritedEnv = process;
|
|
@@ -6213,7 +6356,7 @@ function firstExistingPath(candidates) {
|
|
|
6213
6356
|
return null;
|
|
6214
6357
|
}
|
|
6215
6358
|
function findAgentBin(agent) {
|
|
6216
|
-
const home =
|
|
6359
|
+
const home = homedir15();
|
|
6217
6360
|
switch (agent) {
|
|
6218
6361
|
// /usr/bin/<name> is included in every candidate list — that's the
|
|
6219
6362
|
// common Linux package-manager install path (apt, dnf, pacman). Old
|
|
@@ -6222,45 +6365,45 @@ function findAgentBin(agent) {
|
|
|
6222
6365
|
// #170 caught the gap.
|
|
6223
6366
|
case "claude_code":
|
|
6224
6367
|
return firstExistingPath([
|
|
6225
|
-
|
|
6368
|
+
join28(home, ".claude", "local", "claude"),
|
|
6226
6369
|
"/usr/local/bin/claude",
|
|
6227
6370
|
"/usr/bin/claude",
|
|
6228
|
-
|
|
6229
|
-
|
|
6371
|
+
join28(home, ".npm-global", "bin", "claude"),
|
|
6372
|
+
join28(home, ".local", "bin", "claude"),
|
|
6230
6373
|
"/opt/homebrew/bin/claude"
|
|
6231
|
-
]) ??
|
|
6374
|
+
]) ?? join28(home, ".claude", "local", "claude");
|
|
6232
6375
|
case "codex":
|
|
6233
6376
|
return firstExistingPath([
|
|
6234
6377
|
"/usr/local/bin/codex",
|
|
6235
6378
|
"/usr/bin/codex",
|
|
6236
|
-
|
|
6237
|
-
|
|
6379
|
+
join28(home, ".npm-global", "bin", "codex"),
|
|
6380
|
+
join28(home, ".local", "bin", "codex"),
|
|
6238
6381
|
"/opt/homebrew/bin/codex"
|
|
6239
6382
|
]) ?? "/usr/local/bin/codex";
|
|
6240
6383
|
case "cursor":
|
|
6241
6384
|
return firstExistingPath([
|
|
6242
6385
|
"/usr/local/bin/cursor-agent",
|
|
6243
6386
|
"/usr/bin/cursor-agent",
|
|
6244
|
-
|
|
6245
|
-
|
|
6387
|
+
join28(home, ".npm-global", "bin", "cursor-agent"),
|
|
6388
|
+
join28(home, ".local", "bin", "cursor-agent"),
|
|
6246
6389
|
"/opt/homebrew/bin/cursor-agent"
|
|
6247
6390
|
]) ?? "/usr/local/bin/cursor-agent";
|
|
6248
6391
|
case "hermes":
|
|
6249
6392
|
return firstExistingPath([
|
|
6250
|
-
|
|
6393
|
+
join28(home, ".local", "bin", "hermes"),
|
|
6251
6394
|
"/usr/local/bin/hermes",
|
|
6252
6395
|
"/usr/bin/hermes",
|
|
6253
|
-
|
|
6396
|
+
join28(home, ".npm-global", "bin", "hermes"),
|
|
6254
6397
|
"/opt/homebrew/bin/hermes"
|
|
6255
|
-
]) ??
|
|
6398
|
+
]) ?? join28(home, ".local", "bin", "hermes");
|
|
6256
6399
|
case "pi":
|
|
6257
6400
|
return firstExistingPath([
|
|
6258
|
-
|
|
6401
|
+
join28(home, ".local", "bin", "pi"),
|
|
6259
6402
|
"/usr/local/bin/pi",
|
|
6260
6403
|
"/usr/bin/pi",
|
|
6261
|
-
|
|
6404
|
+
join28(home, ".npm-global", "bin", "pi"),
|
|
6262
6405
|
"/opt/homebrew/bin/pi"
|
|
6263
|
-
]) ??
|
|
6406
|
+
]) ?? join28(home, ".local", "bin", "pi");
|
|
6264
6407
|
}
|
|
6265
6408
|
}
|
|
6266
6409
|
|
|
@@ -6290,27 +6433,27 @@ function extractJsonBlock(s) {
|
|
|
6290
6433
|
}
|
|
6291
6434
|
|
|
6292
6435
|
// dist/src/skillify/local-manifest.js
|
|
6293
|
-
import { existsSync as existsSync24, mkdirSync as
|
|
6294
|
-
import { homedir as
|
|
6295
|
-
import { dirname as
|
|
6296
|
-
var LOCAL_MANIFEST_PATH =
|
|
6297
|
-
var LOCAL_MINE_LOCK_PATH =
|
|
6436
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync10, readFileSync as readFileSync19, writeFileSync as writeFileSync14 } from "node:fs";
|
|
6437
|
+
import { homedir as homedir16 } from "node:os";
|
|
6438
|
+
import { dirname as dirname6, join as join29 } from "node:path";
|
|
6439
|
+
var LOCAL_MANIFEST_PATH = join29(homedir16(), ".claude", "hivemind", "local-mined.json");
|
|
6440
|
+
var LOCAL_MINE_LOCK_PATH = join29(homedir16(), ".claude", "hivemind", "local-mined.lock");
|
|
6298
6441
|
function readLocalManifest(path = LOCAL_MANIFEST_PATH) {
|
|
6299
6442
|
if (!existsSync24(path))
|
|
6300
6443
|
return null;
|
|
6301
6444
|
try {
|
|
6302
|
-
return JSON.parse(
|
|
6445
|
+
return JSON.parse(readFileSync19(path, "utf-8"));
|
|
6303
6446
|
} catch {
|
|
6304
6447
|
return null;
|
|
6305
6448
|
}
|
|
6306
6449
|
}
|
|
6307
6450
|
function writeLocalManifest(m, path = LOCAL_MANIFEST_PATH) {
|
|
6308
|
-
|
|
6309
|
-
|
|
6451
|
+
mkdirSync10(dirname6(path), { recursive: true });
|
|
6452
|
+
writeFileSync14(path, JSON.stringify(m, null, 2));
|
|
6310
6453
|
}
|
|
6311
6454
|
|
|
6312
6455
|
// dist/src/commands/mine-local.js
|
|
6313
|
-
import { unlinkSync as
|
|
6456
|
+
import { unlinkSync as unlinkSync10 } from "node:fs";
|
|
6314
6457
|
var EPSILON = 0.3;
|
|
6315
6458
|
var DEFAULT_N = 8;
|
|
6316
6459
|
var PAIR_CHAR_CAP = 4e3;
|
|
@@ -6321,9 +6464,9 @@ var IN_FLIGHT_MAX_AGE_MS = 6e4;
|
|
|
6321
6464
|
var GATE_TIMEOUT_MS = 24e4;
|
|
6322
6465
|
var MANIFEST_PATH = LOCAL_MANIFEST_PATH;
|
|
6323
6466
|
function runGateViaStdin(opts) {
|
|
6324
|
-
return new Promise((
|
|
6467
|
+
return new Promise((resolve2) => {
|
|
6325
6468
|
if (opts.agent !== "claude_code") {
|
|
6326
|
-
|
|
6469
|
+
resolve2({
|
|
6327
6470
|
stdout: "",
|
|
6328
6471
|
stderr: "",
|
|
6329
6472
|
errored: true,
|
|
@@ -6332,7 +6475,7 @@ function runGateViaStdin(opts) {
|
|
|
6332
6475
|
return;
|
|
6333
6476
|
}
|
|
6334
6477
|
if (!existsSync25(opts.bin)) {
|
|
6335
|
-
|
|
6478
|
+
resolve2({
|
|
6336
6479
|
stdout: "",
|
|
6337
6480
|
stderr: "",
|
|
6338
6481
|
errored: true,
|
|
@@ -6359,7 +6502,7 @@ function runGateViaStdin(opts) {
|
|
|
6359
6502
|
if (settled)
|
|
6360
6503
|
return;
|
|
6361
6504
|
settled = true;
|
|
6362
|
-
|
|
6505
|
+
resolve2(r);
|
|
6363
6506
|
};
|
|
6364
6507
|
const timer = setTimeout(() => {
|
|
6365
6508
|
try {
|
|
@@ -6619,7 +6762,7 @@ async function runMineLocal(args) {
|
|
|
6619
6762
|
return;
|
|
6620
6763
|
lockReleased = true;
|
|
6621
6764
|
try {
|
|
6622
|
-
|
|
6765
|
+
unlinkSync10(LOCAL_MINE_LOCK_PATH);
|
|
6623
6766
|
} catch {
|
|
6624
6767
|
}
|
|
6625
6768
|
};
|
|
@@ -6676,8 +6819,8 @@ async function runMineLocalImpl(args) {
|
|
|
6676
6819
|
console.log(`Dry-run: would invoke ${gateAgent} gate on ${picked.length} session(s) in parallel (concurrency=${GATE_CONCURRENCY}).`);
|
|
6677
6820
|
return;
|
|
6678
6821
|
}
|
|
6679
|
-
const tmpDir =
|
|
6680
|
-
|
|
6822
|
+
const tmpDir = join30(homedir17(), ".claude", "hivemind", `mine-local-${Date.now()}`);
|
|
6823
|
+
mkdirSync11(tmpDir, { recursive: true });
|
|
6681
6824
|
console.log(`Running ${picked.length} gate call(s) in parallel (concurrency=${GATE_CONCURRENCY}, timeout=${GATE_TIMEOUT_MS / 1e3}s each)...`);
|
|
6682
6825
|
const results = await parallelMap(picked, GATE_CONCURRENCY, async (s) => {
|
|
6683
6826
|
const shortId = s.sessionId.slice(0, 8);
|
|
@@ -6688,23 +6831,23 @@ async function runMineLocalImpl(args) {
|
|
|
6688
6831
|
return { session: s, skills: [], reason: "no pairs", error: null };
|
|
6689
6832
|
}
|
|
6690
6833
|
const tail = pairs2.slice(-PER_SESSION_PAIR_CAP);
|
|
6691
|
-
const sessionTmp =
|
|
6692
|
-
|
|
6693
|
-
const verdictPath =
|
|
6834
|
+
const sessionTmp = join30(tmpDir, `s-${shortId}`);
|
|
6835
|
+
mkdirSync11(sessionTmp, { recursive: true });
|
|
6836
|
+
const verdictPath = join30(sessionTmp, "verdict.json");
|
|
6694
6837
|
const prompt = buildSessionPrompt(tail, s, verdictPath);
|
|
6695
|
-
|
|
6838
|
+
writeFileSync15(join30(sessionTmp, "prompt.txt"), prompt);
|
|
6696
6839
|
const gate = await runGateViaStdin({ agent: gateAgent, bin: gateBin, prompt, timeoutMs: GATE_TIMEOUT_MS });
|
|
6697
6840
|
try {
|
|
6698
|
-
|
|
6841
|
+
writeFileSync15(join30(sessionTmp, "gate-stdout.txt"), gate.stdout);
|
|
6699
6842
|
if (gate.stderr)
|
|
6700
|
-
|
|
6843
|
+
writeFileSync15(join30(sessionTmp, "gate-stderr.txt"), gate.stderr);
|
|
6701
6844
|
} catch {
|
|
6702
6845
|
}
|
|
6703
6846
|
if (gate.errored) {
|
|
6704
6847
|
console.log(` [${shortId}] gate failed: ${gate.errorMessage}`);
|
|
6705
6848
|
return { session: s, skills: [], reason: null, error: gate.errorMessage ?? "gate failed" };
|
|
6706
6849
|
}
|
|
6707
|
-
const verdictText = existsSync25(verdictPath) ?
|
|
6850
|
+
const verdictText = existsSync25(verdictPath) ? readFileSync20(verdictPath, "utf-8") : gate.stdout;
|
|
6708
6851
|
const mv = parseMultiVerdict(verdictText);
|
|
6709
6852
|
if (!mv) {
|
|
6710
6853
|
console.log(` [${shortId}] unparseable verdict (kept at ${sessionTmp})`);
|
|
@@ -6756,7 +6899,7 @@ async function runMineLocalImpl(args) {
|
|
|
6756
6899
|
sourceSessions: [session.sessionId],
|
|
6757
6900
|
agent: gateAgent
|
|
6758
6901
|
});
|
|
6759
|
-
const canonicalDir =
|
|
6902
|
+
const canonicalDir = dirname7(result.path);
|
|
6760
6903
|
const symlinks = fanOutRoots.length > 0 ? fanOutSymlinks(canonicalDir, basename(canonicalDir), fanOutRoots) : [];
|
|
6761
6904
|
const symlinkSuffix = symlinks.length > 0 ? `, fan-out \u2192 ${symlinks.length} root(s)` : "";
|
|
6762
6905
|
console.log(` wrote ${skill.name} \u2190 session ${session.sessionId.slice(0, 8)} (${session.agent}${symlinkSuffix})`);
|
|
@@ -6920,7 +7063,7 @@ function wrapAt(s, max) {
|
|
|
6920
7063
|
|
|
6921
7064
|
// dist/src/commands/skillify.js
|
|
6922
7065
|
function stateDir() {
|
|
6923
|
-
return
|
|
7066
|
+
return getStateDir();
|
|
6924
7067
|
}
|
|
6925
7068
|
function showStatus() {
|
|
6926
7069
|
const cfg = loadScopeConfig();
|
|
@@ -6940,7 +7083,7 @@ function showStatus() {
|
|
|
6940
7083
|
console.log(`state: ${files.length} project(s) tracked`);
|
|
6941
7084
|
for (const f of files) {
|
|
6942
7085
|
try {
|
|
6943
|
-
const s = JSON.parse(
|
|
7086
|
+
const s = JSON.parse(readFileSync21(join31(dir, f), "utf-8"));
|
|
6944
7087
|
const last = typeof s.updatedAt === "number" ? new Date(s.updatedAt).toISOString() : s.lastDate ?? "never";
|
|
6945
7088
|
const skills = Array.isArray(s.skillsGenerated) && s.skillsGenerated.length > 0 ? s.skillsGenerated.join(", ") : "none";
|
|
6946
7089
|
console.log(` - ${s.project} (counter=${s.counter}, last=${last}, skills=${skills})`);
|
|
@@ -6967,7 +7110,7 @@ function setInstall(loc) {
|
|
|
6967
7110
|
}
|
|
6968
7111
|
const cfg = loadScopeConfig();
|
|
6969
7112
|
saveScopeConfig({ ...cfg, install: loc });
|
|
6970
|
-
const path = loc === "global" ?
|
|
7113
|
+
const path = loc === "global" ? join31(homedir18(), ".claude", "skills") : "<cwd>/.claude/skills";
|
|
6971
7114
|
console.log(`Install location set to '${loc}'. New skills will be written to ${path}/<name>/SKILL.md.`);
|
|
6972
7115
|
}
|
|
6973
7116
|
function promoteSkill(name, cwd) {
|
|
@@ -6975,18 +7118,18 @@ function promoteSkill(name, cwd) {
|
|
|
6975
7118
|
console.error("Usage: hivemind skillify promote <skill-name>");
|
|
6976
7119
|
process.exit(1);
|
|
6977
7120
|
}
|
|
6978
|
-
const projectPath =
|
|
6979
|
-
const globalPath =
|
|
6980
|
-
if (!existsSync26(
|
|
7121
|
+
const projectPath = join31(cwd, ".claude", "skills", name);
|
|
7122
|
+
const globalPath = join31(homedir18(), ".claude", "skills", name);
|
|
7123
|
+
if (!existsSync26(join31(projectPath, "SKILL.md"))) {
|
|
6981
7124
|
console.error(`Skill '${name}' not found at ${projectPath}/SKILL.md`);
|
|
6982
7125
|
process.exit(1);
|
|
6983
7126
|
}
|
|
6984
|
-
if (existsSync26(
|
|
7127
|
+
if (existsSync26(join31(globalPath, "SKILL.md"))) {
|
|
6985
7128
|
console.error(`Skill '${name}' already exists at ${globalPath}/SKILL.md \u2014 refusing to overwrite. Remove it first or rename the project skill.`);
|
|
6986
7129
|
process.exit(1);
|
|
6987
7130
|
}
|
|
6988
|
-
|
|
6989
|
-
|
|
7131
|
+
mkdirSync12(dirname8(globalPath), { recursive: true });
|
|
7132
|
+
renameSync7(projectPath, globalPath);
|
|
6990
7133
|
console.log(`Promoted '${name}' from ${projectPath} \u2192 ${globalPath}.`);
|
|
6991
7134
|
}
|
|
6992
7135
|
function teamAdd(name) {
|
|
@@ -7092,7 +7235,7 @@ async function pullSkills(args) {
|
|
|
7092
7235
|
console.error(`pull failed: ${e?.message ?? e}`);
|
|
7093
7236
|
process.exit(1);
|
|
7094
7237
|
}
|
|
7095
|
-
const dest = toRaw === "global" ?
|
|
7238
|
+
const dest = toRaw === "global" ? join31(homedir18(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
|
|
7096
7239
|
const filterDesc = users.length === 0 ? "all users" : users.join(", ");
|
|
7097
7240
|
console.log(`Destination: ${dest}`);
|
|
7098
7241
|
console.log(`Filter: ${filterDesc}${skillName ? ` \xB7 skill='${skillName}'` : ""}${dryRun ? " \xB7 dry-run" : ""}${force ? " \xB7 force" : ""}`);
|
|
@@ -7142,7 +7285,7 @@ async function unpullSkills(args) {
|
|
|
7142
7285
|
all,
|
|
7143
7286
|
legacyCleanup
|
|
7144
7287
|
});
|
|
7145
|
-
const dest = toRaw === "global" ?
|
|
7288
|
+
const dest = toRaw === "global" ? join31(homedir18(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
|
|
7146
7289
|
const filterParts = [];
|
|
7147
7290
|
if (users.length > 0)
|
|
7148
7291
|
filterParts.push(`users=${users.join(",")}`);
|
|
@@ -7238,13 +7381,13 @@ if (process.argv[1] && process.argv[1].endsWith("skillify.js")) {
|
|
|
7238
7381
|
|
|
7239
7382
|
// dist/src/cli/update.js
|
|
7240
7383
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
7241
|
-
import { existsSync as existsSync27, readFileSync as
|
|
7242
|
-
import { dirname as
|
|
7384
|
+
import { existsSync as existsSync27, readFileSync as readFileSync23, realpathSync } from "node:fs";
|
|
7385
|
+
import { dirname as dirname10, sep } from "node:path";
|
|
7243
7386
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
7244
7387
|
|
|
7245
7388
|
// dist/src/utils/version-check.js
|
|
7246
|
-
import { readFileSync as
|
|
7247
|
-
import { dirname as
|
|
7389
|
+
import { readFileSync as readFileSync22 } from "node:fs";
|
|
7390
|
+
import { dirname as dirname9, join as join32 } from "node:path";
|
|
7248
7391
|
function isNewer(latest, current) {
|
|
7249
7392
|
const parse = (v) => v.split(".").map(Number);
|
|
7250
7393
|
const [la, lb, lc] = parse(latest);
|
|
@@ -7263,24 +7406,24 @@ function detectInstallKind(argv1) {
|
|
|
7263
7406
|
return argv1 ?? process.argv[1] ?? fileURLToPath2(import.meta.url);
|
|
7264
7407
|
}
|
|
7265
7408
|
})();
|
|
7266
|
-
let dir =
|
|
7409
|
+
let dir = dirname10(realArgv1);
|
|
7267
7410
|
let installDir = null;
|
|
7268
7411
|
for (let i = 0; i < 10; i++) {
|
|
7269
7412
|
const pkgPath = `${dir}${sep}package.json`;
|
|
7270
7413
|
try {
|
|
7271
|
-
const pkg = JSON.parse(
|
|
7414
|
+
const pkg = JSON.parse(readFileSync23(pkgPath, "utf-8"));
|
|
7272
7415
|
if (pkg.name === PKG_NAME || pkg.name === "hivemind") {
|
|
7273
7416
|
installDir = dir;
|
|
7274
7417
|
break;
|
|
7275
7418
|
}
|
|
7276
7419
|
} catch {
|
|
7277
7420
|
}
|
|
7278
|
-
const parent =
|
|
7421
|
+
const parent = dirname10(dir);
|
|
7279
7422
|
if (parent === dir)
|
|
7280
7423
|
break;
|
|
7281
7424
|
dir = parent;
|
|
7282
7425
|
}
|
|
7283
|
-
installDir ??=
|
|
7426
|
+
installDir ??= dirname10(realArgv1);
|
|
7284
7427
|
if (realArgv1.includes(`${sep}_npx${sep}`) || realArgv1.includes(`${sep}.npx${sep}`)) {
|
|
7285
7428
|
return { kind: "npx", installDir };
|
|
7286
7429
|
}
|
|
@@ -7292,7 +7435,7 @@ function detectInstallKind(argv1) {
|
|
|
7292
7435
|
if (existsSync27(`${gitDir}${sep}.git`)) {
|
|
7293
7436
|
return { kind: "local-dev", installDir };
|
|
7294
7437
|
}
|
|
7295
|
-
const parent =
|
|
7438
|
+
const parent = dirname10(gitDir);
|
|
7296
7439
|
if (parent === gitDir)
|
|
7297
7440
|
break;
|
|
7298
7441
|
gitDir = parent;
|