@deeplake/hivemind 0.7.40 → 0.7.44

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/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 mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "node:fs";
21
- import { join as join18 } from "node:path";
20
+ import { existsSync as existsSync14, mkdirSync as mkdirSync6, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "node:fs";
21
+ import { join as join19 } from "node:path";
22
22
  import { tmpdir } from "node:os";
23
23
  function getIndexMarkerDir() {
24
- return process.env.HIVEMIND_INDEX_MARKER_DIR ?? join18(tmpdir(), "hivemind-deeplake-indexes");
24
+ return process.env.HIVEMIND_INDEX_MARKER_DIR ?? join19(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 join18(getIndexMarkerDir(), `${markerKey}.json`);
28
+ return join19(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(readFileSync13(markerPath, "utf-8"));
34
+ const raw = JSON.parse(readFileSync14(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
- mkdirSync5(getIndexMarkerDir(), { recursive: true });
45
- writeFileSync9(markerPath, JSON.stringify({ updatedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf-8");
44
+ mkdirSync6(getIndexMarkerDir(), { recursive: true });
45
+ writeFileSync10(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({
@@ -4045,7 +4045,7 @@ function statusEmbeddings() {
4045
4045
 
4046
4046
  // dist/src/cli/auth.js
4047
4047
  import { existsSync as existsSync12 } from "node:fs";
4048
- import { join as join14 } from "node:path";
4048
+ import { join as join15 } from "node:path";
4049
4049
 
4050
4050
  // dist/src/commands/auth.js
4051
4051
  import { execSync } from "node:child_process";
@@ -4059,26 +4059,61 @@ function deeplakeClientHeader() {
4059
4059
  return { [DEEPLAKE_CLIENT_HEADER]: deeplakeClientValue() };
4060
4060
  }
4061
4061
 
4062
- // dist/src/commands/auth-creds.js
4063
- import { readFileSync as readFileSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync3, unlinkSync as unlinkSync6 } from "node:fs";
4062
+ // dist/src/commands/install-id.js
4063
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync3 } from "node:fs";
4064
4064
  import { join as join13 } from "node:path";
4065
4065
  import { homedir as homedir5 } from "node:os";
4066
+ import { randomUUID } from "node:crypto";
4066
4067
  function configDir() {
4067
4068
  return join13(homedir5(), ".deeplake");
4068
4069
  }
4070
+ function installIDPath() {
4071
+ return join13(configDir(), "install-id");
4072
+ }
4073
+ var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
4074
+ function getOrCreateInstallID() {
4075
+ try {
4076
+ const value = readFileSync10(installIDPath(), "utf-8").trim();
4077
+ if (UUID_RE.test(value))
4078
+ return value;
4079
+ } catch {
4080
+ }
4081
+ const id = randomUUID();
4082
+ try {
4083
+ mkdirSync3(configDir(), { recursive: true, mode: 448 });
4084
+ writeFileSync7(installIDPath(), id, { mode: 384 });
4085
+ return id;
4086
+ } catch {
4087
+ return "";
4088
+ }
4089
+ }
4090
+ function hivemindInstallIDHeader() {
4091
+ const id = getOrCreateInstallID();
4092
+ if (!id)
4093
+ return {};
4094
+ return { "X-Hivemind-Install-Id": id };
4095
+ }
4096
+
4097
+ // dist/src/commands/auth-creds.js
4098
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync8, mkdirSync as mkdirSync4, unlinkSync as unlinkSync6 } from "node:fs";
4099
+ import { join as join14 } from "node:path";
4100
+ import { homedir as homedir6 } from "node:os";
4101
+ function configDir2() {
4102
+ return join14(homedir6(), ".deeplake");
4103
+ }
4069
4104
  function credsPath() {
4070
- return join13(configDir(), "credentials.json");
4105
+ return join14(configDir2(), "credentials.json");
4071
4106
  }
4072
4107
  function loadCredentials() {
4073
4108
  try {
4074
- return JSON.parse(readFileSync10(credsPath(), "utf-8"));
4109
+ return JSON.parse(readFileSync11(credsPath(), "utf-8"));
4075
4110
  } catch {
4076
4111
  return null;
4077
4112
  }
4078
4113
  }
4079
4114
  function saveCredentials(creds) {
4080
- mkdirSync3(configDir(), { recursive: true, mode: 448 });
4081
- writeFileSync7(credsPath(), JSON.stringify({ ...creds, savedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), { mode: 384 });
4115
+ mkdirSync4(configDir2(), { recursive: true, mode: 448 });
4116
+ writeFileSync8(credsPath(), JSON.stringify({ ...creds, savedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), { mode: 384 });
4082
4117
  }
4083
4118
  function deleteCredentials() {
4084
4119
  try {
@@ -4145,7 +4180,11 @@ async function apiDelete(path, token, apiUrl, orgId) {
4145
4180
  async function requestDeviceCode(apiUrl = DEFAULT_API_URL) {
4146
4181
  const resp = await fetch(`${apiUrl}/auth/device/code`, {
4147
4182
  method: "POST",
4148
- headers: { "Content-Type": "application/json", ...deeplakeClientHeader() }
4183
+ headers: {
4184
+ "Content-Type": "application/json",
4185
+ ...deeplakeClientHeader(),
4186
+ ...hivemindInstallIDHeader()
4187
+ }
4149
4188
  });
4150
4189
  if (!resp.ok)
4151
4190
  throw new Error(`Device flow unavailable: HTTP ${resp.status}`);
@@ -4154,7 +4193,11 @@ async function requestDeviceCode(apiUrl = DEFAULT_API_URL) {
4154
4193
  async function pollForToken(deviceCode, apiUrl = DEFAULT_API_URL) {
4155
4194
  const resp = await fetch(`${apiUrl}/auth/device/token`, {
4156
4195
  method: "POST",
4157
- headers: { "Content-Type": "application/json", ...deeplakeClientHeader() },
4196
+ headers: {
4197
+ "Content-Type": "application/json",
4198
+ ...deeplakeClientHeader(),
4199
+ ...hivemindInstallIDHeader()
4200
+ },
4158
4201
  body: JSON.stringify({ device_code: deviceCode })
4159
4202
  });
4160
4203
  if (resp.ok)
@@ -4312,7 +4355,7 @@ var DEFAULT_API_URL2 = "https://api.deeplake.ai";
4312
4355
  function resolveApiUrl() {
4313
4356
  return process.env.HIVEMIND_API_URL ?? DEFAULT_API_URL2;
4314
4357
  }
4315
- var CREDS_PATH = join14(HOME, ".deeplake", "credentials.json");
4358
+ var CREDS_PATH = join15(HOME, ".deeplake", "credentials.json");
4316
4359
  function isLoggedIn() {
4317
4360
  return existsSync12(CREDS_PATH) && loadCredentials() !== null;
4318
4361
  }
@@ -4360,16 +4403,16 @@ async function maybeShowOrgChoice() {
4360
4403
  }
4361
4404
 
4362
4405
  // dist/src/config.js
4363
- import { readFileSync as readFileSync11, existsSync as existsSync13 } from "node:fs";
4364
- import { join as join15 } from "node:path";
4365
- import { homedir as homedir6, userInfo as userInfo2 } from "node:os";
4406
+ import { readFileSync as readFileSync12, existsSync as existsSync13 } from "node:fs";
4407
+ import { join as join16 } from "node:path";
4408
+ import { homedir as homedir7, userInfo as userInfo2 } from "node:os";
4366
4409
  function loadConfig() {
4367
- const home = homedir6();
4368
- const credPath = join15(home, ".deeplake", "credentials.json");
4410
+ const home = homedir7();
4411
+ const credPath = join16(home, ".deeplake", "credentials.json");
4369
4412
  let creds = null;
4370
4413
  if (existsSync13(credPath)) {
4371
4414
  try {
4372
- creds = JSON.parse(readFileSync11(credPath, "utf-8"));
4415
+ creds = JSON.parse(readFileSync12(credPath, "utf-8"));
4373
4416
  } catch {
4374
4417
  return null;
4375
4418
  }
@@ -4388,18 +4431,18 @@ function loadConfig() {
4388
4431
  tableName: process.env.HIVEMIND_TABLE ?? "memory",
4389
4432
  sessionsTableName: process.env.HIVEMIND_SESSIONS_TABLE ?? "sessions",
4390
4433
  skillsTableName: process.env.HIVEMIND_SKILLS_TABLE ?? "skills",
4391
- memoryPath: process.env.HIVEMIND_MEMORY_PATH ?? join15(home, ".deeplake", "memory")
4434
+ memoryPath: process.env.HIVEMIND_MEMORY_PATH ?? join16(home, ".deeplake", "memory")
4392
4435
  };
4393
4436
  }
4394
4437
 
4395
4438
  // dist/src/deeplake-api.js
4396
- import { randomUUID } from "node:crypto";
4439
+ import { randomUUID as randomUUID2 } from "node:crypto";
4397
4440
 
4398
4441
  // dist/src/utils/debug.js
4399
4442
  import { appendFileSync } from "node:fs";
4400
- import { join as join16 } from "node:path";
4401
- import { homedir as homedir7 } from "node:os";
4402
- var LOG = join16(homedir7(), ".deeplake", "hook-debug.log");
4443
+ import { join as join17 } from "node:path";
4444
+ import { homedir as homedir8 } from "node:os";
4445
+ var LOG = join17(homedir8(), ".deeplake", "hook-debug.log");
4403
4446
  function isDebug() {
4404
4447
  return process.env.HIVEMIND_DEBUG === "1";
4405
4448
  }
@@ -4542,23 +4585,23 @@ async function healMissingColumns(args) {
4542
4585
  }
4543
4586
 
4544
4587
  // dist/src/notifications/queue.js
4545
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync8, renameSync as renameSync3, mkdirSync as mkdirSync4, openSync, closeSync, unlinkSync as unlinkSync7, statSync as statSync2 } from "node:fs";
4546
- import { join as join17, resolve } from "node:path";
4547
- import { homedir as homedir8 } from "node:os";
4588
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, renameSync as renameSync3, mkdirSync as mkdirSync5, openSync, closeSync, unlinkSync as unlinkSync7, statSync as statSync2 } from "node:fs";
4589
+ import { join as join18, resolve } from "node:path";
4590
+ import { homedir as homedir9 } from "node:os";
4548
4591
  import { setTimeout as sleep } from "node:timers/promises";
4549
4592
  var log3 = (msg) => log2("notifications-queue", msg);
4550
4593
  var LOCK_RETRY_MAX = 50;
4551
4594
  var LOCK_RETRY_BASE_MS = 5;
4552
4595
  var LOCK_STALE_MS = 5e3;
4553
4596
  function queuePath() {
4554
- return join17(homedir8(), ".deeplake", "notifications-queue.json");
4597
+ return join18(homedir9(), ".deeplake", "notifications-queue.json");
4555
4598
  }
4556
4599
  function lockPath() {
4557
4600
  return `${queuePath()}.lock`;
4558
4601
  }
4559
4602
  function readQueue() {
4560
4603
  try {
4561
- const raw = readFileSync12(queuePath(), "utf-8");
4604
+ const raw = readFileSync13(queuePath(), "utf-8");
4562
4605
  const parsed = JSON.parse(raw);
4563
4606
  if (!parsed || !Array.isArray(parsed.queue)) {
4564
4607
  log3(`queue malformed \u2192 treating as empty`);
@@ -4576,18 +4619,18 @@ function _isQueuePathInsideHome(path, home) {
4576
4619
  }
4577
4620
  function writeQueue(q) {
4578
4621
  const path = queuePath();
4579
- const home = resolve(homedir8());
4622
+ const home = resolve(homedir9());
4580
4623
  if (!_isQueuePathInsideHome(path, home)) {
4581
4624
  throw new Error(`notifications-queue write blocked: ${path} is outside ${home}`);
4582
4625
  }
4583
- mkdirSync4(join17(home, ".deeplake"), { recursive: true, mode: 448 });
4626
+ mkdirSync5(join18(home, ".deeplake"), { recursive: true, mode: 448 });
4584
4627
  const tmp = `${path}.${process.pid}.tmp`;
4585
- writeFileSync8(tmp, JSON.stringify(q, null, 2), { mode: 384 });
4628
+ writeFileSync9(tmp, JSON.stringify(q, null, 2), { mode: 384 });
4586
4629
  renameSync3(tmp, path);
4587
4630
  }
4588
4631
  async function withQueueLock(fn) {
4589
4632
  const path = lockPath();
4590
- mkdirSync4(join17(homedir8(), ".deeplake"), { recursive: true, mode: 448 });
4633
+ mkdirSync5(join18(homedir9(), ".deeplake"), { recursive: true, mode: 448 });
4591
4634
  let fd = null;
4592
4635
  for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
4593
4636
  try {
@@ -4860,7 +4903,7 @@ var DeeplakeApi = class {
4860
4903
  setClauses += `, description = '${sqlStr(row.description)}'`;
4861
4904
  await this.query(`UPDATE "${this.tableName}" SET ${setClauses} WHERE path = '${sqlStr(row.path)}'`);
4862
4905
  } else {
4863
- const id = randomUUID();
4906
+ const id = randomUUID2();
4864
4907
  let cols = `id, path, filename, summary, ${SUMMARY_EMBEDDING_COL}, mime_type, size_bytes, creation_date, last_update_date`;
4865
4908
  let vals = `'${id}', '${sqlStr(row.path)}', '${sqlStr(row.filename)}', E'${sqlStr(row.contentText)}', NULL, '${sqlStr(row.mimeType)}', ${row.sizeBytes}, '${cd}', '${lud}'`;
4866
4909
  if (row.project !== void 0) {
@@ -5375,24 +5418,24 @@ if (process.argv[1] && process.argv[1].endsWith("auth-login.js")) {
5375
5418
  }
5376
5419
 
5377
5420
  // dist/src/commands/skillify.js
5378
- import { readdirSync as readdirSync5, existsSync as existsSync26, readFileSync as readFileSync21, mkdirSync as mkdirSync12, renameSync as renameSync7 } from "node:fs";
5379
- import { homedir as homedir18 } from "node:os";
5380
- import { dirname as dirname8, join as join31 } from "node:path";
5421
+ import { readdirSync as readdirSync5, existsSync as existsSync26, readFileSync as readFileSync22, mkdirSync as mkdirSync13, renameSync as renameSync7 } from "node:fs";
5422
+ import { homedir as homedir19 } from "node:os";
5423
+ import { dirname as dirname8, join as join32 } from "node:path";
5381
5424
 
5382
5425
  // dist/src/skillify/scope-config.js
5383
- import { existsSync as existsSync16, mkdirSync as mkdirSync6, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "node:fs";
5384
- import { join as join21 } from "node:path";
5426
+ import { existsSync as existsSync16, mkdirSync as mkdirSync7, readFileSync as readFileSync15, writeFileSync as writeFileSync11 } from "node:fs";
5427
+ import { join as join22 } from "node:path";
5385
5428
 
5386
5429
  // dist/src/skillify/legacy-migration.js
5387
5430
  import { existsSync as existsSync15, renameSync as renameSync4 } from "node:fs";
5388
- import { dirname as dirname3, join as join20 } from "node:path";
5431
+ import { dirname as dirname3, join as join21 } from "node:path";
5389
5432
 
5390
5433
  // dist/src/skillify/state-dir.js
5391
- import { homedir as homedir9 } from "node:os";
5392
- import { join as join19 } from "node:path";
5434
+ import { homedir as homedir10 } from "node:os";
5435
+ import { join as join20 } from "node:path";
5393
5436
  function getStateDir() {
5394
5437
  const override = process.env.HIVEMIND_STATE_DIR?.trim();
5395
- return override && override.length > 0 ? override : join19(homedir9(), ".deeplake", "state", "skillify");
5438
+ return override && override.length > 0 ? override : join20(homedir10(), ".deeplake", "state", "skillify");
5396
5439
  }
5397
5440
 
5398
5441
  // dist/src/skillify/legacy-migration.js
@@ -5405,7 +5448,7 @@ function migrateLegacyStateDir() {
5405
5448
  return;
5406
5449
  attempted = true;
5407
5450
  const current = getStateDir();
5408
- const legacy = join20(dirname3(current), "skilify");
5451
+ const legacy = join21(dirname3(current), "skilify");
5409
5452
  if (!existsSync15(legacy))
5410
5453
  return;
5411
5454
  if (existsSync15(current))
@@ -5425,7 +5468,7 @@ function migrateLegacyStateDir() {
5425
5468
 
5426
5469
  // dist/src/skillify/scope-config.js
5427
5470
  function configPath() {
5428
- return join21(getStateDir(), "config.json");
5471
+ return join22(getStateDir(), "config.json");
5429
5472
  }
5430
5473
  var DEFAULT = { scope: "me", team: [], install: "project" };
5431
5474
  function loadScopeConfig() {
@@ -5434,7 +5477,7 @@ function loadScopeConfig() {
5434
5477
  if (!existsSync16(CONFIG_PATH2))
5435
5478
  return DEFAULT;
5436
5479
  try {
5437
- const raw = JSON.parse(readFileSync14(CONFIG_PATH2, "utf-8"));
5480
+ const raw = JSON.parse(readFileSync15(CONFIG_PATH2, "utf-8"));
5438
5481
  const scope = raw.scope === "team" ? "team" : raw.scope === "org" ? "team" : "me";
5439
5482
  const team = Array.isArray(raw.team) ? raw.team.filter((s) => typeof s === "string") : [];
5440
5483
  const install = raw.install === "global" ? "global" : "project";
@@ -5445,19 +5488,19 @@ function loadScopeConfig() {
5445
5488
  }
5446
5489
  function saveScopeConfig(cfg) {
5447
5490
  migrateLegacyStateDir();
5448
- mkdirSync6(getStateDir(), { recursive: true });
5449
- writeFileSync10(configPath(), JSON.stringify(cfg, null, 2));
5491
+ mkdirSync7(getStateDir(), { recursive: true });
5492
+ writeFileSync11(configPath(), JSON.stringify(cfg, null, 2));
5450
5493
  }
5451
5494
 
5452
5495
  // dist/src/skillify/pull.js
5453
- 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";
5454
- import { homedir as homedir12 } from "node:os";
5455
- import { dirname as dirname5, join as join25 } from "node:path";
5496
+ import { existsSync as existsSync20, readFileSync as readFileSync18, writeFileSync as writeFileSync14, mkdirSync as mkdirSync10, renameSync as renameSync6, lstatSync as lstatSync4, readlinkSync as readlinkSync2, symlinkSync as symlinkSync2, unlinkSync as unlinkSync9 } from "node:fs";
5497
+ import { homedir as homedir13 } from "node:os";
5498
+ import { dirname as dirname5, join as join26 } from "node:path";
5456
5499
 
5457
5500
  // dist/src/skillify/skill-writer.js
5458
- import { existsSync as existsSync17, mkdirSync as mkdirSync7, readFileSync as readFileSync15, readdirSync as readdirSync2, statSync as statSync3, writeFileSync as writeFileSync11 } from "node:fs";
5459
- import { homedir as homedir10 } from "node:os";
5460
- import { join as join22 } from "node:path";
5501
+ import { existsSync as existsSync17, mkdirSync as mkdirSync8, readFileSync as readFileSync16, readdirSync as readdirSync2, statSync as statSync3, writeFileSync as writeFileSync12 } from "node:fs";
5502
+ import { homedir as homedir11 } from "node:os";
5503
+ import { join as join23 } from "node:path";
5461
5504
  function assertValidSkillName(name) {
5462
5505
  if (typeof name !== "string" || name.length === 0) {
5463
5506
  throw new Error(`invalid skill name: empty or non-string`);
@@ -5473,10 +5516,10 @@ function assertValidSkillName(name) {
5473
5516
  }
5474
5517
  }
5475
5518
  function skillDir(skillsRoot, name) {
5476
- return join22(skillsRoot, name);
5519
+ return join23(skillsRoot, name);
5477
5520
  }
5478
5521
  function skillPath(skillsRoot, name) {
5479
- return join22(skillDir(skillsRoot, name), "SKILL.md");
5522
+ return join23(skillDir(skillsRoot, name), "SKILL.md");
5480
5523
  }
5481
5524
  function renderFrontmatter(fm) {
5482
5525
  const lines = ["---"];
@@ -5557,7 +5600,7 @@ function writeNewSkill(args) {
5557
5600
  if (existsSync17(path)) {
5558
5601
  throw new Error(`skill already exists at ${path}; use mergeSkill`);
5559
5602
  }
5560
- mkdirSync7(dir, { recursive: true });
5603
+ mkdirSync8(dir, { recursive: true });
5561
5604
  const now = (/* @__PURE__ */ new Date()).toISOString();
5562
5605
  const author = args.author && args.author.length > 0 ? args.author : void 0;
5563
5606
  const contributors = author ? [author] : [];
@@ -5577,7 +5620,7 @@ function writeNewSkill(args) {
5577
5620
 
5578
5621
  ${args.body.trim()}
5579
5622
  `;
5580
- writeFileSync11(path, text);
5623
+ writeFileSync12(path, text);
5581
5624
  return {
5582
5625
  path,
5583
5626
  action: "created",
@@ -5593,28 +5636,28 @@ function listSkills(skillsRoot) {
5593
5636
  return [];
5594
5637
  const out = [];
5595
5638
  for (const name of readdirSync2(skillsRoot)) {
5596
- const skillFile = join22(skillsRoot, name, "SKILL.md");
5639
+ const skillFile = join23(skillsRoot, name, "SKILL.md");
5597
5640
  if (existsSync17(skillFile) && statSync3(skillFile).isFile()) {
5598
- out.push({ name, body: readFileSync15(skillFile, "utf-8") });
5641
+ out.push({ name, body: readFileSync16(skillFile, "utf-8") });
5599
5642
  }
5600
5643
  }
5601
5644
  return out;
5602
5645
  }
5603
5646
  function resolveSkillsRoot(install, cwd) {
5604
5647
  if (install === "global") {
5605
- return join22(homedir10(), ".claude", "skills");
5648
+ return join23(homedir11(), ".claude", "skills");
5606
5649
  }
5607
- return join22(cwd, ".claude", "skills");
5650
+ return join23(cwd, ".claude", "skills");
5608
5651
  }
5609
5652
 
5610
5653
  // dist/src/skillify/manifest.js
5611
- 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";
5612
- import { dirname as dirname4, join as join23 } from "node:path";
5654
+ import { existsSync as existsSync18, lstatSync as lstatSync3, mkdirSync as mkdirSync9, readFileSync as readFileSync17, renameSync as renameSync5, unlinkSync as unlinkSync8, writeFileSync as writeFileSync13 } from "node:fs";
5655
+ import { dirname as dirname4, join as join24 } from "node:path";
5613
5656
  function emptyManifest() {
5614
5657
  return { version: 1, entries: [] };
5615
5658
  }
5616
5659
  function manifestPath() {
5617
- return join23(getStateDir(), "pulled.json");
5660
+ return join24(getStateDir(), "pulled.json");
5618
5661
  }
5619
5662
  function loadManifest(path = manifestPath()) {
5620
5663
  migrateLegacyStateDir();
@@ -5622,7 +5665,7 @@ function loadManifest(path = manifestPath()) {
5622
5665
  return emptyManifest();
5623
5666
  let raw;
5624
5667
  try {
5625
- raw = readFileSync16(path, "utf-8");
5668
+ raw = readFileSync17(path, "utf-8");
5626
5669
  } catch {
5627
5670
  return emptyManifest();
5628
5671
  }
@@ -5669,9 +5712,9 @@ function loadManifest(path = manifestPath()) {
5669
5712
  }
5670
5713
  function saveManifest(m, path = manifestPath()) {
5671
5714
  migrateLegacyStateDir();
5672
- mkdirSync8(dirname4(path), { recursive: true });
5715
+ mkdirSync9(dirname4(path), { recursive: true });
5673
5716
  const tmp = `${path}.tmp`;
5674
- writeFileSync12(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
5717
+ writeFileSync13(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
5675
5718
  renameSync5(tmp, path);
5676
5719
  }
5677
5720
  function recordPull(entry, path = manifestPath()) {
@@ -5714,7 +5757,7 @@ function pruneOrphanedEntries(path = manifestPath()) {
5714
5757
  const live = [];
5715
5758
  let pruned = 0;
5716
5759
  for (const e of m.entries) {
5717
- if (existsSync18(join23(e.installRoot, e.dirName))) {
5760
+ if (existsSync18(join24(e.installRoot, e.dirName))) {
5718
5761
  live.push(e);
5719
5762
  continue;
5720
5763
  }
@@ -5728,25 +5771,25 @@ function pruneOrphanedEntries(path = manifestPath()) {
5728
5771
 
5729
5772
  // dist/src/skillify/agent-roots.js
5730
5773
  import { existsSync as existsSync19 } from "node:fs";
5731
- import { homedir as homedir11 } from "node:os";
5732
- import { join as join24 } from "node:path";
5774
+ import { homedir as homedir12 } from "node:os";
5775
+ import { join as join25 } from "node:path";
5733
5776
  function resolveDetected(home) {
5734
5777
  const out = [];
5735
- const codexInstalled = existsSync19(join24(home, ".codex"));
5736
- const piInstalled = existsSync19(join24(home, ".pi", "agent"));
5737
- const hermesInstalled = existsSync19(join24(home, ".hermes"));
5778
+ const codexInstalled = existsSync19(join25(home, ".codex"));
5779
+ const piInstalled = existsSync19(join25(home, ".pi", "agent"));
5780
+ const hermesInstalled = existsSync19(join25(home, ".hermes"));
5738
5781
  if (codexInstalled || piInstalled) {
5739
- out.push(join24(home, ".agents", "skills"));
5782
+ out.push(join25(home, ".agents", "skills"));
5740
5783
  }
5741
5784
  if (hermesInstalled) {
5742
- out.push(join24(home, ".hermes", "skills"));
5785
+ out.push(join25(home, ".hermes", "skills"));
5743
5786
  }
5744
5787
  if (piInstalled) {
5745
- out.push(join24(home, ".pi", "agent", "skills"));
5788
+ out.push(join25(home, ".pi", "agent", "skills"));
5746
5789
  }
5747
5790
  return out;
5748
5791
  }
5749
- function detectAgentSkillsRoots(canonicalRoot, home = homedir11()) {
5792
+ function detectAgentSkillsRoots(canonicalRoot, home = homedir12()) {
5750
5793
  return resolveDetected(home).filter((p) => p !== canonicalRoot);
5751
5794
  }
5752
5795
 
@@ -5790,15 +5833,15 @@ function isMissingTableError(message) {
5790
5833
  }
5791
5834
  function resolvePullDestination(install, cwd) {
5792
5835
  if (install === "global")
5793
- return join25(homedir12(), ".claude", "skills");
5836
+ return join26(homedir13(), ".claude", "skills");
5794
5837
  if (!cwd)
5795
5838
  throw new Error("install=project requires a cwd");
5796
- return join25(cwd, ".claude", "skills");
5839
+ return join26(cwd, ".claude", "skills");
5797
5840
  }
5798
5841
  function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
5799
5842
  const out = [];
5800
5843
  for (const root of agentRoots) {
5801
- const link = join25(root, dirName);
5844
+ const link = join26(root, dirName);
5802
5845
  let existing;
5803
5846
  try {
5804
5847
  existing = lstatSync4(link);
@@ -5826,7 +5869,7 @@ function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
5826
5869
  }
5827
5870
  }
5828
5871
  try {
5829
- mkdirSync9(dirname5(link), { recursive: true });
5872
+ mkdirSync10(dirname5(link), { recursive: true });
5830
5873
  symlinkSync2(canonicalDir, link, "dir");
5831
5874
  out.push(link);
5832
5875
  } catch {
@@ -5841,7 +5884,7 @@ function backfillSymlinks(installRoot) {
5841
5884
  return;
5842
5885
  const detected = detectAgentSkillsRoots(installRoot);
5843
5886
  for (const entry of entries) {
5844
- const canonical = join25(entry.installRoot, entry.dirName);
5887
+ const canonical = join26(entry.installRoot, entry.dirName);
5845
5888
  if (!existsSync20(canonical))
5846
5889
  continue;
5847
5890
  const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
@@ -5955,7 +5998,7 @@ function readLocalVersion(path) {
5955
5998
  if (!existsSync20(path))
5956
5999
  return null;
5957
6000
  try {
5958
- const text = readFileSync17(path, "utf-8");
6001
+ const text = readFileSync18(path, "utf-8");
5959
6002
  const parsed = parseFrontmatter(text);
5960
6003
  if (!parsed)
5961
6004
  return null;
@@ -6050,8 +6093,8 @@ async function runPull(opts) {
6050
6093
  summary.skipped++;
6051
6094
  continue;
6052
6095
  }
6053
- const skillDir2 = join25(root, dirName);
6054
- const skillFile = join25(skillDir2, "SKILL.md");
6096
+ const skillDir2 = join26(root, dirName);
6097
+ const skillFile = join26(skillDir2, "SKILL.md");
6055
6098
  const remoteVersion = Number(row.version ?? 1);
6056
6099
  const localVersion = readLocalVersion(skillFile);
6057
6100
  const action = decideAction({
@@ -6062,14 +6105,14 @@ async function runPull(opts) {
6062
6105
  });
6063
6106
  let manifestError;
6064
6107
  if (action === "wrote") {
6065
- mkdirSync9(skillDir2, { recursive: true });
6108
+ mkdirSync10(skillDir2, { recursive: true });
6066
6109
  if (existsSync20(skillFile)) {
6067
6110
  try {
6068
6111
  renameSync6(skillFile, `${skillFile}.bak`);
6069
6112
  } catch {
6070
6113
  }
6071
6114
  }
6072
- writeFileSync13(skillFile, renderSkillFile(row));
6115
+ writeFileSync14(skillFile, renderSkillFile(row));
6073
6116
  const symlinks = opts.install === "global" ? fanOutSymlinks(skillDir2, dirName, detectAgentSkillsRoots(root)) : [];
6074
6117
  try {
6075
6118
  recordPull({
@@ -6112,14 +6155,14 @@ async function runPull(opts) {
6112
6155
 
6113
6156
  // dist/src/skillify/unpull.js
6114
6157
  import { existsSync as existsSync21, readdirSync as readdirSync3, rmSync as rmSync5, statSync as statSync4 } from "node:fs";
6115
- import { homedir as homedir13 } from "node:os";
6116
- import { join as join26 } from "node:path";
6158
+ import { homedir as homedir14 } from "node:os";
6159
+ import { join as join27 } from "node:path";
6117
6160
  function resolveUnpullRoot(install, cwd) {
6118
6161
  if (install === "global")
6119
- return join26(homedir13(), ".claude", "skills");
6162
+ return join27(homedir14(), ".claude", "skills");
6120
6163
  if (!cwd)
6121
6164
  throw new Error("cwd required when install === 'project'");
6122
- return join26(cwd, ".claude", "skills");
6165
+ return join27(cwd, ".claude", "skills");
6123
6166
  }
6124
6167
  function runUnpull(opts) {
6125
6168
  const root = resolveUnpullRoot(opts.install, opts.cwd);
@@ -6142,7 +6185,7 @@ function runUnpull(opts) {
6142
6185
  const entries = entriesForRoot(manifest, opts.install, root);
6143
6186
  for (const entry of entries) {
6144
6187
  summary.scanned++;
6145
- const path = join26(root, entry.dirName);
6188
+ const path = join27(root, entry.dirName);
6146
6189
  if (!existsSync21(path)) {
6147
6190
  if (!opts.dryRun) {
6148
6191
  unlinkSymlinks(entry.symlinks);
@@ -6201,7 +6244,7 @@ function runUnpull(opts) {
6201
6244
  for (const dirName of readdirSync3(root)) {
6202
6245
  if (manifestDirNames.has(dirName))
6203
6246
  continue;
6204
- const path = join26(root, dirName);
6247
+ const path = join27(root, dirName);
6205
6248
  let st;
6206
6249
  try {
6207
6250
  st = statSync4(path);
@@ -6280,21 +6323,21 @@ function decideTargetForManifestEntry(entry, opts, userFilter, haveUserFilter) {
6280
6323
 
6281
6324
  // dist/src/commands/mine-local.js
6282
6325
  import { spawn } from "node:child_process";
6283
- import { existsSync as existsSync25, mkdirSync as mkdirSync11, readFileSync as readFileSync20, writeFileSync as writeFileSync15 } from "node:fs";
6284
- import { homedir as homedir17 } from "node:os";
6285
- import { basename, dirname as dirname7, join as join30 } from "node:path";
6326
+ import { existsSync as existsSync25, mkdirSync as mkdirSync12, readFileSync as readFileSync21, writeFileSync as writeFileSync16 } from "node:fs";
6327
+ import { homedir as homedir18 } from "node:os";
6328
+ import { basename, dirname as dirname7, join as join31 } from "node:path";
6286
6329
 
6287
6330
  // dist/src/skillify/local-source.js
6288
- import { readdirSync as readdirSync4, readFileSync as readFileSync18, existsSync as existsSync22, statSync as statSync5 } from "node:fs";
6289
- import { homedir as homedir14 } from "node:os";
6290
- import { join as join27 } from "node:path";
6291
- var HOME2 = homedir14();
6331
+ import { readdirSync as readdirSync4, readFileSync as readFileSync19, existsSync as existsSync22, statSync as statSync5 } from "node:fs";
6332
+ import { homedir as homedir15 } from "node:os";
6333
+ import { join as join28 } from "node:path";
6334
+ var HOME2 = homedir15();
6292
6335
  function encodeCwdClaudeCode(cwd) {
6293
6336
  return cwd.replace(/[/_]/g, "-");
6294
6337
  }
6295
6338
  function detectInstalledAgents() {
6296
6339
  const installs = [];
6297
- const claudeRoot = join27(HOME2, ".claude", "projects");
6340
+ const claudeRoot = join28(HOME2, ".claude", "projects");
6298
6341
  if (existsSync22(claudeRoot)) {
6299
6342
  installs.push({
6300
6343
  agent: "claude_code",
@@ -6302,7 +6345,7 @@ function detectInstalledAgents() {
6302
6345
  encodeCwd: encodeCwdClaudeCode
6303
6346
  });
6304
6347
  }
6305
- const codexRoot = join27(HOME2, ".codex", "sessions");
6348
+ const codexRoot = join28(HOME2, ".codex", "sessions");
6306
6349
  if (existsSync22(codexRoot)) {
6307
6350
  installs.push({
6308
6351
  agent: "codex",
@@ -6330,7 +6373,7 @@ function listLocalSessions(installs, cwd) {
6330
6373
  continue;
6331
6374
  }
6332
6375
  for (const sub of subdirs) {
6333
- const subdirPath = join27(install.sessionRoot, sub);
6376
+ const subdirPath = join28(install.sessionRoot, sub);
6334
6377
  try {
6335
6378
  if (!statSync5(subdirPath).isDirectory())
6336
6379
  continue;
@@ -6347,7 +6390,7 @@ function listLocalSessions(installs, cwd) {
6347
6390
  for (const f of files) {
6348
6391
  if (!f.endsWith(".jsonl"))
6349
6392
  continue;
6350
- const fullPath = join27(subdirPath, f);
6393
+ const fullPath = join28(subdirPath, f);
6351
6394
  let stats;
6352
6395
  try {
6353
6396
  stats = statSync5(fullPath);
@@ -6408,7 +6451,7 @@ function pickSessions(candidates, opts) {
6408
6451
  function nativeJsonlToRows(filePath, sessionId, agent) {
6409
6452
  let raw;
6410
6453
  try {
6411
- raw = readFileSync18(filePath, "utf-8");
6454
+ raw = readFileSync19(filePath, "utf-8");
6412
6455
  } catch {
6413
6456
  return [];
6414
6457
  }
@@ -6500,8 +6543,8 @@ function extractPairs(rows) {
6500
6543
  // dist/src/skillify/gate-runner.js
6501
6544
  import { existsSync as existsSync23 } from "node:fs";
6502
6545
  import { createRequire } from "node:module";
6503
- import { homedir as homedir15 } from "node:os";
6504
- import { join as join28 } from "node:path";
6546
+ import { homedir as homedir16 } from "node:os";
6547
+ import { join as join29 } from "node:path";
6505
6548
  var requireForCp = createRequire(import.meta.url);
6506
6549
  var { execFileSync: runChildProcess } = requireForCp("node:child_process");
6507
6550
  var inheritedEnv = process;
@@ -6513,7 +6556,7 @@ function firstExistingPath(candidates) {
6513
6556
  return null;
6514
6557
  }
6515
6558
  function findAgentBin(agent) {
6516
- const home = homedir15();
6559
+ const home = homedir16();
6517
6560
  switch (agent) {
6518
6561
  // /usr/bin/<name> is included in every candidate list — that's the
6519
6562
  // common Linux package-manager install path (apt, dnf, pacman). Old
@@ -6522,45 +6565,45 @@ function findAgentBin(agent) {
6522
6565
  // #170 caught the gap.
6523
6566
  case "claude_code":
6524
6567
  return firstExistingPath([
6525
- join28(home, ".claude", "local", "claude"),
6568
+ join29(home, ".claude", "local", "claude"),
6526
6569
  "/usr/local/bin/claude",
6527
6570
  "/usr/bin/claude",
6528
- join28(home, ".npm-global", "bin", "claude"),
6529
- join28(home, ".local", "bin", "claude"),
6571
+ join29(home, ".npm-global", "bin", "claude"),
6572
+ join29(home, ".local", "bin", "claude"),
6530
6573
  "/opt/homebrew/bin/claude"
6531
- ]) ?? join28(home, ".claude", "local", "claude");
6574
+ ]) ?? join29(home, ".claude", "local", "claude");
6532
6575
  case "codex":
6533
6576
  return firstExistingPath([
6534
6577
  "/usr/local/bin/codex",
6535
6578
  "/usr/bin/codex",
6536
- join28(home, ".npm-global", "bin", "codex"),
6537
- join28(home, ".local", "bin", "codex"),
6579
+ join29(home, ".npm-global", "bin", "codex"),
6580
+ join29(home, ".local", "bin", "codex"),
6538
6581
  "/opt/homebrew/bin/codex"
6539
6582
  ]) ?? "/usr/local/bin/codex";
6540
6583
  case "cursor":
6541
6584
  return firstExistingPath([
6542
6585
  "/usr/local/bin/cursor-agent",
6543
6586
  "/usr/bin/cursor-agent",
6544
- join28(home, ".npm-global", "bin", "cursor-agent"),
6545
- join28(home, ".local", "bin", "cursor-agent"),
6587
+ join29(home, ".npm-global", "bin", "cursor-agent"),
6588
+ join29(home, ".local", "bin", "cursor-agent"),
6546
6589
  "/opt/homebrew/bin/cursor-agent"
6547
6590
  ]) ?? "/usr/local/bin/cursor-agent";
6548
6591
  case "hermes":
6549
6592
  return firstExistingPath([
6550
- join28(home, ".local", "bin", "hermes"),
6593
+ join29(home, ".local", "bin", "hermes"),
6551
6594
  "/usr/local/bin/hermes",
6552
6595
  "/usr/bin/hermes",
6553
- join28(home, ".npm-global", "bin", "hermes"),
6596
+ join29(home, ".npm-global", "bin", "hermes"),
6554
6597
  "/opt/homebrew/bin/hermes"
6555
- ]) ?? join28(home, ".local", "bin", "hermes");
6598
+ ]) ?? join29(home, ".local", "bin", "hermes");
6556
6599
  case "pi":
6557
6600
  return firstExistingPath([
6558
- join28(home, ".local", "bin", "pi"),
6601
+ join29(home, ".local", "bin", "pi"),
6559
6602
  "/usr/local/bin/pi",
6560
6603
  "/usr/bin/pi",
6561
- join28(home, ".npm-global", "bin", "pi"),
6604
+ join29(home, ".npm-global", "bin", "pi"),
6562
6605
  "/opt/homebrew/bin/pi"
6563
- ]) ?? join28(home, ".local", "bin", "pi");
6606
+ ]) ?? join29(home, ".local", "bin", "pi");
6564
6607
  }
6565
6608
  }
6566
6609
 
@@ -6590,24 +6633,25 @@ function extractJsonBlock(s) {
6590
6633
  }
6591
6634
 
6592
6635
  // dist/src/skillify/local-manifest.js
6593
- import { existsSync as existsSync24, mkdirSync as mkdirSync10, readFileSync as readFileSync19, writeFileSync as writeFileSync14 } from "node:fs";
6594
- import { homedir as homedir16 } from "node:os";
6595
- import { dirname as dirname6, join as join29 } from "node:path";
6596
- var LOCAL_MANIFEST_PATH = join29(homedir16(), ".claude", "hivemind", "local-mined.json");
6597
- var LOCAL_MINE_LOCK_PATH = join29(homedir16(), ".claude", "hivemind", "local-mined.lock");
6636
+ import { existsSync as existsSync24, mkdirSync as mkdirSync11, readFileSync as readFileSync20, writeFileSync as writeFileSync15 } from "node:fs";
6637
+ import { homedir as homedir17 } from "node:os";
6638
+ import { dirname as dirname6, join as join30 } from "node:path";
6639
+ var LOCAL_MANIFEST_PATH = join30(homedir17(), ".claude", "hivemind", "local-mined.json");
6640
+ var LOCAL_MINE_LOCK_PATH = join30(homedir17(), ".claude", "hivemind", "local-mined.lock");
6598
6641
  function readLocalManifest(path = LOCAL_MANIFEST_PATH) {
6599
6642
  if (!existsSync24(path))
6600
6643
  return null;
6601
6644
  try {
6602
- return JSON.parse(readFileSync19(path, "utf-8"));
6645
+ return JSON.parse(readFileSync20(path, "utf-8"));
6603
6646
  } catch {
6604
6647
  return null;
6605
6648
  }
6606
6649
  }
6607
6650
  function writeLocalManifest(m, path = LOCAL_MANIFEST_PATH) {
6608
- mkdirSync10(dirname6(path), { recursive: true });
6609
- writeFileSync14(path, JSON.stringify(m, null, 2));
6651
+ mkdirSync11(dirname6(path), { recursive: true });
6652
+ writeFileSync15(path, JSON.stringify(m, null, 2));
6610
6653
  }
6654
+ var LATEST_RUN_WINDOW_MS = 5 * 60 * 1e3;
6611
6655
 
6612
6656
  // dist/src/commands/mine-local.js
6613
6657
  import { unlinkSync as unlinkSync10 } from "node:fs";
@@ -6739,11 +6783,26 @@ function buildSessionPrompt(pairs2, session, verdictPath) {
6739
6783
  `- A skill qualifies if it captures a concrete, repeatable workflow OR a non-obvious`,
6740
6784
  ` constraint/gotcha a future engineer would benefit from knowing. Intra-session is fine \u2014`,
6741
6785
  ` one deep dive yielding a generalizable takeaway counts.`,
6786
+ `- Especially valuable: REPEATABLE-MISTAKE patterns. Cases where the assistant declared`,
6787
+ ` work "done"/"fixed"/"verified" and the user came back to the same problem later; where`,
6788
+ ` the same class of mistake recurs (forgot to run tests, mishandled async state,`,
6789
+ ` hallucinated function/file existence, re-asked for confirmation on already-authorized`,
6790
+ ` work, jumped to plans without checking with the user, etc.); where the user manually`,
6791
+ ` corrected the same kind of error >1 time. These are the highest-value catches.`,
6742
6792
  `- Skip patterns that are obvious from reading the codebase or already in CLAUDE.md.`,
6743
6793
  `- Each body uses short sections (When to use, Workflow, Anti-patterns), concrete commands`,
6744
6794
  ` / paths / snippets drawn from the exchanges below, no marketing, no emojis.`,
6745
6795
  `- Each body under ~3000 characters.`,
6746
6796
  `- Skill names are kebab-case slugs (lowercase letters/digits/hyphens only).`,
6797
+ `- For each skill, also emit a one-line "insight": a concrete, quantified, second-person`,
6798
+ ` sentence describing what hivemind found that prompted the skill. Examples:`,
6799
+ ` "You revisited 4 merged PRs in the last month because the assistant declared 'done'`,
6800
+ ` before checking test output."`,
6801
+ ` "You corrected the same env-mismatch (beta vs prod) twice in the same week before`,
6802
+ ` deciding to switch deployment targets."`,
6803
+ ` The insight is what users will see at next SessionStart, so it must be honest \u2014 only`,
6804
+ ` assert counts and patterns you can ground in THIS session's exchanges. Omit the field`,
6805
+ ` if you cannot write a concrete, quantified line.`,
6747
6806
  ``,
6748
6807
  `=== EXCHANGES (user prompts + assistant final answers, tool calls stripped) ===`,
6749
6808
  renderPairsBlock(pairs2),
@@ -6762,7 +6821,8 @@ function buildSessionPrompt(pairs2, session, verdictPath) {
6762
6821
  ` "name": "<kebab-case>",`,
6763
6822
  ` "description": "<one-line>",`,
6764
6823
  ` "trigger": "<short trigger>",`,
6765
- ` "body": "<full SKILL.md body without frontmatter>"`,
6824
+ ` "body": "<full SKILL.md body without frontmatter>",`,
6825
+ ` "insight": "<one-line, concrete + quantified + second person; OPTIONAL>"`,
6766
6826
  ` },`,
6767
6827
  ` ... up to 3 entries, or [] if nothing qualifies`,
6768
6828
  ` ]`,
@@ -6794,9 +6854,12 @@ function parseMultiVerdict(raw) {
6794
6854
  const description = typeof s.description === "string" ? s.description.trim() : "";
6795
6855
  const body = typeof s.body === "string" ? s.body.trim() : "";
6796
6856
  const trigger = typeof s.trigger === "string" ? s.trigger.trim() : void 0;
6857
+ const rawInsight = typeof s.insight === "string" ? s.insight : "";
6858
+ const normalizedInsight = rawInsight.replace(/\s+/g, " ").trim();
6859
+ const insight = normalizedInsight.length > 0 ? normalizedInsight.slice(0, 280) : void 0;
6797
6860
  if (!name || !body)
6798
6861
  continue;
6799
- out.push({ name, description, body, trigger });
6862
+ out.push({ name, description, body, trigger, insight });
6800
6863
  }
6801
6864
  return { reason: typeof parsed.reason === "string" ? parsed.reason : void 0, skills: out };
6802
6865
  }
@@ -6976,8 +7039,8 @@ async function runMineLocalImpl(args) {
6976
7039
  console.log(`Dry-run: would invoke ${gateAgent} gate on ${picked.length} session(s) in parallel (concurrency=${GATE_CONCURRENCY}).`);
6977
7040
  return;
6978
7041
  }
6979
- const tmpDir = join30(homedir17(), ".claude", "hivemind", `mine-local-${Date.now()}`);
6980
- mkdirSync11(tmpDir, { recursive: true });
7042
+ const tmpDir = join31(homedir18(), ".claude", "hivemind", `mine-local-${Date.now()}`);
7043
+ mkdirSync12(tmpDir, { recursive: true });
6981
7044
  console.log(`Running ${picked.length} gate call(s) in parallel (concurrency=${GATE_CONCURRENCY}, timeout=${GATE_TIMEOUT_MS / 1e3}s each)...`);
6982
7045
  const results = await parallelMap(picked, GATE_CONCURRENCY, async (s) => {
6983
7046
  const shortId = s.sessionId.slice(0, 8);
@@ -6988,23 +7051,23 @@ async function runMineLocalImpl(args) {
6988
7051
  return { session: s, skills: [], reason: "no pairs", error: null };
6989
7052
  }
6990
7053
  const tail = pairs2.slice(-PER_SESSION_PAIR_CAP);
6991
- const sessionTmp = join30(tmpDir, `s-${shortId}`);
6992
- mkdirSync11(sessionTmp, { recursive: true });
6993
- const verdictPath = join30(sessionTmp, "verdict.json");
7054
+ const sessionTmp = join31(tmpDir, `s-${shortId}`);
7055
+ mkdirSync12(sessionTmp, { recursive: true });
7056
+ const verdictPath = join31(sessionTmp, "verdict.json");
6994
7057
  const prompt = buildSessionPrompt(tail, s, verdictPath);
6995
- writeFileSync15(join30(sessionTmp, "prompt.txt"), prompt);
7058
+ writeFileSync16(join31(sessionTmp, "prompt.txt"), prompt);
6996
7059
  const gate = await runGateViaStdin({ agent: gateAgent, bin: gateBin, prompt, timeoutMs: GATE_TIMEOUT_MS });
6997
7060
  try {
6998
- writeFileSync15(join30(sessionTmp, "gate-stdout.txt"), gate.stdout);
7061
+ writeFileSync16(join31(sessionTmp, "gate-stdout.txt"), gate.stdout);
6999
7062
  if (gate.stderr)
7000
- writeFileSync15(join30(sessionTmp, "gate-stderr.txt"), gate.stderr);
7063
+ writeFileSync16(join31(sessionTmp, "gate-stderr.txt"), gate.stderr);
7001
7064
  } catch {
7002
7065
  }
7003
7066
  if (gate.errored) {
7004
7067
  console.log(` [${shortId}] gate failed: ${gate.errorMessage}`);
7005
7068
  return { session: s, skills: [], reason: null, error: gate.errorMessage ?? "gate failed" };
7006
7069
  }
7007
- const verdictText = existsSync25(verdictPath) ? readFileSync20(verdictPath, "utf-8") : gate.stdout;
7070
+ const verdictText = existsSync25(verdictPath) ? readFileSync21(verdictPath, "utf-8") : gate.stdout;
7008
7071
  const mv = parseMultiVerdict(verdictText);
7009
7072
  if (!mv) {
7010
7073
  console.log(` [${shortId}] unparseable verdict (kept at ${sessionTmp})`);
@@ -7081,7 +7144,12 @@ async function runMineLocalImpl(args) {
7081
7144
  source_agent: session.agent,
7082
7145
  gate_agent: gateAgent,
7083
7146
  created_at: result.createdAt,
7084
- uploaded: false
7147
+ uploaded: false,
7148
+ // Persist the one-line insight when the gate produced one. Omitted
7149
+ // (undefined → absent in JSON) when the gate couldn't ground a
7150
+ // concrete line, so the SessionStart banner falls back to the
7151
+ // count-only surface for entries written before this field landed.
7152
+ ...skill.insight ? { insight: skill.insight } : {}
7085
7153
  }));
7086
7154
  saveManifest2({
7087
7155
  created_at: existing?.created_at ?? (/* @__PURE__ */ new Date()).toISOString(),
@@ -7240,7 +7308,7 @@ function showStatus() {
7240
7308
  console.log(`state: ${files.length} project(s) tracked`);
7241
7309
  for (const f of files) {
7242
7310
  try {
7243
- const s = JSON.parse(readFileSync21(join31(dir, f), "utf-8"));
7311
+ const s = JSON.parse(readFileSync22(join32(dir, f), "utf-8"));
7244
7312
  const last = typeof s.updatedAt === "number" ? new Date(s.updatedAt).toISOString() : s.lastDate ?? "never";
7245
7313
  const skills = Array.isArray(s.skillsGenerated) && s.skillsGenerated.length > 0 ? s.skillsGenerated.join(", ") : "none";
7246
7314
  console.log(` - ${s.project} (counter=${s.counter}, last=${last}, skills=${skills})`);
@@ -7267,7 +7335,7 @@ function setInstall(loc) {
7267
7335
  }
7268
7336
  const cfg = loadScopeConfig();
7269
7337
  saveScopeConfig({ ...cfg, install: loc });
7270
- const path = loc === "global" ? join31(homedir18(), ".claude", "skills") : "<cwd>/.claude/skills";
7338
+ const path = loc === "global" ? join32(homedir19(), ".claude", "skills") : "<cwd>/.claude/skills";
7271
7339
  console.log(`Install location set to '${loc}'. New skills will be written to ${path}/<name>/SKILL.md.`);
7272
7340
  }
7273
7341
  function promoteSkill(name, cwd) {
@@ -7275,17 +7343,17 @@ function promoteSkill(name, cwd) {
7275
7343
  console.error("Usage: hivemind skillify promote <skill-name>");
7276
7344
  process.exit(1);
7277
7345
  }
7278
- const projectPath = join31(cwd, ".claude", "skills", name);
7279
- const globalPath = join31(homedir18(), ".claude", "skills", name);
7280
- if (!existsSync26(join31(projectPath, "SKILL.md"))) {
7346
+ const projectPath = join32(cwd, ".claude", "skills", name);
7347
+ const globalPath = join32(homedir19(), ".claude", "skills", name);
7348
+ if (!existsSync26(join32(projectPath, "SKILL.md"))) {
7281
7349
  console.error(`Skill '${name}' not found at ${projectPath}/SKILL.md`);
7282
7350
  process.exit(1);
7283
7351
  }
7284
- if (existsSync26(join31(globalPath, "SKILL.md"))) {
7352
+ if (existsSync26(join32(globalPath, "SKILL.md"))) {
7285
7353
  console.error(`Skill '${name}' already exists at ${globalPath}/SKILL.md \u2014 refusing to overwrite. Remove it first or rename the project skill.`);
7286
7354
  process.exit(1);
7287
7355
  }
7288
- mkdirSync12(dirname8(globalPath), { recursive: true });
7356
+ mkdirSync13(dirname8(globalPath), { recursive: true });
7289
7357
  renameSync7(projectPath, globalPath);
7290
7358
  console.log(`Promoted '${name}' from ${projectPath} \u2192 ${globalPath}.`);
7291
7359
  }
@@ -7392,7 +7460,7 @@ async function pullSkills(args) {
7392
7460
  console.error(`pull failed: ${e?.message ?? e}`);
7393
7461
  process.exit(1);
7394
7462
  }
7395
- const dest = toRaw === "global" ? join31(homedir18(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
7463
+ const dest = toRaw === "global" ? join32(homedir19(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
7396
7464
  const filterDesc = users.length === 0 ? "all users" : users.join(", ");
7397
7465
  console.log(`Destination: ${dest}`);
7398
7466
  console.log(`Filter: ${filterDesc}${skillName ? ` \xB7 skill='${skillName}'` : ""}${dryRun ? " \xB7 dry-run" : ""}${force ? " \xB7 force" : ""}`);
@@ -7442,7 +7510,7 @@ async function unpullSkills(args) {
7442
7510
  all,
7443
7511
  legacyCleanup
7444
7512
  });
7445
- const dest = toRaw === "global" ? join31(homedir18(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
7513
+ const dest = toRaw === "global" ? join32(homedir19(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
7446
7514
  const filterParts = [];
7447
7515
  if (users.length > 0)
7448
7516
  filterParts.push(`users=${users.join(",")}`);
@@ -7538,14 +7606,14 @@ if (process.argv[1] && process.argv[1].endsWith("skillify.js")) {
7538
7606
 
7539
7607
  // dist/src/cli/update.js
7540
7608
  import { execFileSync as execFileSync4 } from "node:child_process";
7541
- import { closeSync as closeSync2, existsSync as existsSync27, mkdirSync as mkdirSync13, openSync as openSync2, readFileSync as readFileSync23, realpathSync, unlinkSync as unlinkSync11, writeSync } from "node:fs";
7542
- import { homedir as homedir19 } from "node:os";
7543
- import { dirname as dirname10, join as join33, sep } from "node:path";
7609
+ import { closeSync as closeSync2, existsSync as existsSync27, mkdirSync as mkdirSync14, openSync as openSync2, readFileSync as readFileSync24, realpathSync, unlinkSync as unlinkSync11, writeSync } from "node:fs";
7610
+ import { homedir as homedir20 } from "node:os";
7611
+ import { dirname as dirname10, join as join34, sep } from "node:path";
7544
7612
  import { fileURLToPath as fileURLToPath2 } from "node:url";
7545
7613
 
7546
7614
  // dist/src/utils/version-check.js
7547
- import { readFileSync as readFileSync22 } from "node:fs";
7548
- import { dirname as dirname9, join as join32 } from "node:path";
7615
+ import { readFileSync as readFileSync23 } from "node:fs";
7616
+ import { dirname as dirname9, join as join33 } from "node:path";
7549
7617
  function isNewer(latest, current) {
7550
7618
  const parse = (v) => v.split(".").map(Number);
7551
7619
  const [la, lb, lc] = parse(latest);
@@ -7557,7 +7625,7 @@ function isNewer(latest, current) {
7557
7625
  var NPM_REGISTRY_URL = "https://registry.npmjs.org/@deeplake/hivemind/latest";
7558
7626
  var PKG_NAME = "@deeplake/hivemind";
7559
7627
  function defaultLockPath() {
7560
- return join33(homedir19(), ".deeplake", "hivemind-update.lock");
7628
+ return join34(homedir20(), ".deeplake", "hivemind-update.lock");
7561
7629
  }
7562
7630
  function detectInstallKind(argv1) {
7563
7631
  const realArgv1 = (() => {
@@ -7572,7 +7640,7 @@ function detectInstallKind(argv1) {
7572
7640
  for (let i = 0; i < 10; i++) {
7573
7641
  const pkgPath = `${dir}${sep}package.json`;
7574
7642
  try {
7575
- const pkg = JSON.parse(readFileSync23(pkgPath, "utf-8"));
7643
+ const pkg = JSON.parse(readFileSync24(pkgPath, "utf-8"));
7576
7644
  if (pkg.name === PKG_NAME || pkg.name === "hivemind") {
7577
7645
  installDir = dir;
7578
7646
  break;
@@ -7618,7 +7686,7 @@ var defaultSpawn = (cmd, args) => {
7618
7686
  execFileSync4(cmd, args, { stdio: "inherit" });
7619
7687
  };
7620
7688
  function tryAcquireLock(path) {
7621
- mkdirSync13(dirname10(path), { recursive: true, mode: 448 });
7689
+ mkdirSync14(dirname10(path), { recursive: true, mode: 448 });
7622
7690
  const claim = () => {
7623
7691
  const fd = openSync2(path, "wx", 384);
7624
7692
  writeSync(fd, String(process.pid));
@@ -7632,7 +7700,7 @@ function tryAcquireLock(path) {
7632
7700
  }
7633
7701
  let holderPid = 0;
7634
7702
  try {
7635
- holderPid = Number(readFileSync23(path, "utf-8").trim()) || 0;
7703
+ holderPid = Number(readFileSync24(path, "utf-8").trim()) || 0;
7636
7704
  } catch {
7637
7705
  try {
7638
7706
  return claim();