@deeplake/hivemind 0.7.75 → 0.7.77

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
@@ -372,16 +372,29 @@ function buildHooksJson() {
372
372
  UserPromptSubmit: [hookCmd("capture.js", 10)],
373
373
  PreToolUse: [hookCmd("pre-tool-use.js", 10, "Bash")],
374
374
  PostToolUse: [hookCmd("capture.js", 15)],
375
- Stop: [hookCmd("stop.js", 30)]
375
+ // One Stop matcher-block with TWO commands — stop.js (capture) +
376
+ // graph-on-stop.js (code-graph auto-build, G3). Single block (not two)
377
+ // mirrors the static codex/hooks/hooks.json and keeps one entry per
378
+ // event for the merge/dedupe logic.
379
+ Stop: [stopBlockWithGraph(30)]
376
380
  }
377
381
  };
378
382
  }
383
+ function stopBlockWithGraph(timeout) {
384
+ return {
385
+ hooks: [
386
+ { type: "command", command: `node "${join4(PLUGIN_DIR, "bundle", "stop.js")}"`, timeout },
387
+ { type: "command", command: `node "${join4(PLUGIN_DIR, "bundle", "graph-on-stop.js")}"`, timeout }
388
+ ]
389
+ };
390
+ }
379
391
  var HIVEMIND_BUNDLE_FILES = [
380
392
  "session-start.js",
381
393
  "session-start-setup.js",
382
394
  "capture.js",
383
395
  "pre-tool-use.js",
384
396
  "stop.js",
397
+ "graph-on-stop.js",
385
398
  "wiki-worker.js"
386
399
  ];
387
400
  function isHivemindHookEntry(entry, pluginDir = PLUGIN_DIR) {
@@ -716,8 +729,12 @@ function buildHookConfig() {
716
729
  preToolUse: [buildHookCmdShellMatcher("pre-tool-use.js", 30)],
717
730
  postToolUse: [buildHookCmd("capture.js", 15)],
718
731
  afterAgentResponse: [buildHookCmd("capture.js", 15)],
719
- stop: [buildHookCmd("capture.js", 15)],
720
- sessionEnd: [buildHookCmd("session-end.js", 30)]
732
+ // graph-on-stop: auto-build the code graph (A1 Cursor parity). Same hook
733
+ // Claude Code registers under Stop + SessionEnd. It's gated (rate limit +
734
+ // HEAD-changed + source-diff) so the common path is a ~5ms skip, and runs
735
+ // async so it never blocks Cursor.
736
+ stop: [buildHookCmd("capture.js", 15), buildHookCmd("graph-on-stop.js", 30)],
737
+ sessionEnd: [buildHookCmd("session-end.js", 30), buildHookCmd("graph-on-stop.js", 30)]
721
738
  };
722
739
  }
723
740
  function isHivemindEntry(entry) {
@@ -3479,7 +3496,10 @@ function buildHooksBlock() {
3479
3496
  pre_llm_call: [buildHookEntry("capture.js", 10)],
3480
3497
  post_tool_call: [buildHookEntry("capture.js", 15)],
3481
3498
  post_llm_call: [buildHookEntry("capture.js", 15)],
3482
- on_session_end: [buildHookEntry("session-end.js", 30)]
3499
+ // graph-on-stop: code-graph auto-build parity (G3), same gated hook as the
3500
+ // other agents. on_session_end is Hermes's session-close event (analogous
3501
+ // to Claude Code's SessionEnd).
3502
+ on_session_end: [buildHookEntry("session-end.js", 30), buildHookEntry("graph-on-stop.js", 30)]
3483
3503
  };
3484
3504
  }
3485
3505
  function mergeHooks3(existing) {
@@ -5653,8 +5673,8 @@ if (process.argv[1] && process.argv[1].endsWith("auth-login.js")) {
5653
5673
 
5654
5674
  // dist/src/commands/graph.js
5655
5675
  import { execSync as execSync3 } from "node:child_process";
5656
- import { readFileSync as readFileSync20, readdirSync as readdirSync2 } from "node:fs";
5657
- import { join as join27, relative, resolve as resolve4, sep } from "node:path";
5676
+ import { readFileSync as readFileSync21, readdirSync as readdirSync2 } from "node:fs";
5677
+ import { join as join28, relative, resolve as resolve4, sep } from "node:path";
5658
5678
  import { createHash as createHash6 } from "node:crypto";
5659
5679
 
5660
5680
  // dist/src/graph/cache.js
@@ -6094,6 +6114,282 @@ import { createHash as createHash4 } from "node:crypto";
6094
6114
  import { mkdirSync as mkdirSync10, renameSync as renameSync6, writeFileSync as writeFileSync14 } from "node:fs";
6095
6115
  import { homedir as homedir10 } from "node:os";
6096
6116
  import { dirname as dirname6, join as join23 } from "node:path";
6117
+
6118
+ // dist/src/graph/resolve/cross-file.js
6119
+ import { posix } from "node:path";
6120
+ var EXPORTABLE_KINDS = /* @__PURE__ */ new Set([
6121
+ "function",
6122
+ "class",
6123
+ "const",
6124
+ "interface",
6125
+ "type_alias",
6126
+ "enum"
6127
+ ]);
6128
+ var HERITAGE_KINDS = /* @__PURE__ */ new Set([
6129
+ "class",
6130
+ "interface",
6131
+ "type_alias",
6132
+ "enum"
6133
+ ]);
6134
+ function buildExportIndex(nodes) {
6135
+ const idx = /* @__PURE__ */ new Map();
6136
+ for (const n of nodes) {
6137
+ if (!n.exported || !EXPORTABLE_KINDS.has(n.kind))
6138
+ continue;
6139
+ let m = idx.get(n.source_file);
6140
+ if (!m) {
6141
+ m = /* @__PURE__ */ new Map();
6142
+ idx.set(n.source_file, m);
6143
+ }
6144
+ if (!m.has(n.label))
6145
+ m.set(n.label, n.id);
6146
+ }
6147
+ return idx;
6148
+ }
6149
+ function resolveCrossFileCalls(extractions, nodes) {
6150
+ const knownFiles = /* @__PURE__ */ new Set();
6151
+ for (const ex of extractions)
6152
+ knownFiles.add(ex.source_file);
6153
+ const exportIndex = buildExportIndex(nodes);
6154
+ const edges = [];
6155
+ const seen = /* @__PURE__ */ new Set();
6156
+ for (const ex of extractions) {
6157
+ const rawCalls = ex.raw_calls ?? [];
6158
+ const bindings = ex.import_bindings ?? [];
6159
+ if (rawCalls.length === 0 || bindings.length === 0)
6160
+ continue;
6161
+ const byLocal = /* @__PURE__ */ new Map();
6162
+ for (const b of bindings) {
6163
+ if (!byLocal.has(b.local_name))
6164
+ byLocal.set(b.local_name, b);
6165
+ }
6166
+ for (const rc of rawCalls) {
6167
+ const target = resolveOne(rc, byLocal, ex.source_file, knownFiles, exportIndex);
6168
+ if (target === null)
6169
+ continue;
6170
+ const key = `${rc.caller_id}\0${target}`;
6171
+ if (seen.has(key))
6172
+ continue;
6173
+ seen.add(key);
6174
+ edges.push({
6175
+ source: rc.caller_id,
6176
+ target,
6177
+ relation: "calls",
6178
+ confidence: "EXTRACTED"
6179
+ });
6180
+ }
6181
+ }
6182
+ return edges;
6183
+ }
6184
+ function resolveOne(rc, byLocal, fromFile, knownFiles, exportIndex) {
6185
+ let binding;
6186
+ let exportName;
6187
+ if (rc.receiver !== void 0) {
6188
+ binding = byLocal.get(rc.receiver);
6189
+ if (binding === void 0 || binding.kind !== "namespace")
6190
+ return null;
6191
+ if (binding.type_only)
6192
+ return null;
6193
+ exportName = rc.callee_name;
6194
+ } else {
6195
+ binding = byLocal.get(rc.callee_name);
6196
+ if (binding === void 0)
6197
+ return null;
6198
+ if (binding.type_only)
6199
+ return null;
6200
+ if (binding.kind !== "named")
6201
+ return null;
6202
+ exportName = binding.imported_name;
6203
+ }
6204
+ const targetFile = resolveModule(fromFile, binding.specifier, knownFiles);
6205
+ if (targetFile === null)
6206
+ return null;
6207
+ return exportIndex.get(targetFile)?.get(exportName) ?? null;
6208
+ }
6209
+ var MODULE_SUFFIX = "::module";
6210
+ var EXTERNAL_PREFIX = "external:";
6211
+ function repointImportEdges(links, knownFiles) {
6212
+ return links.map((e) => {
6213
+ if (e.relation !== "imports" || !e.target.startsWith(EXTERNAL_PREFIX))
6214
+ return e;
6215
+ if (!e.source.endsWith(MODULE_SUFFIX))
6216
+ return e;
6217
+ const fromFile = e.source.slice(0, -MODULE_SUFFIX.length);
6218
+ const specifier = e.target.slice(EXTERNAL_PREFIX.length);
6219
+ const resolved = resolveModule(fromFile, specifier, knownFiles);
6220
+ if (resolved === null)
6221
+ return e;
6222
+ return { ...e, target: `${resolved}${MODULE_SUFFIX}` };
6223
+ });
6224
+ }
6225
+ var UNRESOLVED_PREFIX = "unresolved:";
6226
+ function resolveHeritageEdges(links, extractions, nodes) {
6227
+ const knownFiles = /* @__PURE__ */ new Set();
6228
+ for (const ex of extractions)
6229
+ knownFiles.add(ex.source_file);
6230
+ const exportIndex = buildExportIndex(nodes);
6231
+ const localIndex = /* @__PURE__ */ new Map();
6232
+ for (const n of nodes) {
6233
+ if (!HERITAGE_KINDS.has(n.kind))
6234
+ continue;
6235
+ let m = localIndex.get(n.source_file);
6236
+ if (!m) {
6237
+ m = /* @__PURE__ */ new Map();
6238
+ localIndex.set(n.source_file, m);
6239
+ }
6240
+ if (!m.has(n.label))
6241
+ m.set(n.label, n.id);
6242
+ }
6243
+ const bindingsByFile = /* @__PURE__ */ new Map();
6244
+ for (const ex of extractions) {
6245
+ const m = /* @__PURE__ */ new Map();
6246
+ for (const b of ex.import_bindings ?? [])
6247
+ if (!m.has(b.local_name))
6248
+ m.set(b.local_name, b);
6249
+ bindingsByFile.set(ex.source_file, m);
6250
+ }
6251
+ return links.map((e) => {
6252
+ if (e.relation !== "extends" && e.relation !== "implements")
6253
+ return e;
6254
+ if (!e.target.startsWith(UNRESOLVED_PREFIX))
6255
+ return e;
6256
+ const parsed = parseUnresolved(e.target);
6257
+ if (parsed === null)
6258
+ return e;
6259
+ const { file, name } = parsed;
6260
+ const local = localIndex.get(file)?.get(name);
6261
+ if (local !== void 0)
6262
+ return { ...e, target: local };
6263
+ const binding = bindingsByFile.get(file)?.get(name);
6264
+ if (binding !== void 0 && binding.kind === "named") {
6265
+ const targetFile = resolveModule(file, binding.specifier, knownFiles);
6266
+ if (targetFile !== null) {
6267
+ const id = exportIndex.get(targetFile)?.get(binding.imported_name);
6268
+ if (id !== void 0)
6269
+ return { ...e, target: id };
6270
+ }
6271
+ }
6272
+ return e;
6273
+ });
6274
+ }
6275
+ function parseUnresolved(target) {
6276
+ const body = target.slice(UNRESOLVED_PREFIX.length);
6277
+ const lastColon = body.lastIndexOf(":");
6278
+ if (lastColon <= 0)
6279
+ return null;
6280
+ const rest = body.slice(0, lastColon);
6281
+ const nameColon = rest.lastIndexOf(":");
6282
+ if (nameColon <= 0)
6283
+ return null;
6284
+ const file = rest.slice(0, nameColon);
6285
+ const name = rest.slice(nameColon + 1);
6286
+ if (file.length === 0 || name.length === 0)
6287
+ return null;
6288
+ return { file, name };
6289
+ }
6290
+ function resolveModule(fromFile, specifier, knownFiles) {
6291
+ if (isPythonFile(fromFile))
6292
+ return resolvePythonModule(fromFile, specifier, knownFiles);
6293
+ if (!specifier.startsWith("./") && !specifier.startsWith("../"))
6294
+ return null;
6295
+ const baseDir = posix.dirname(fromFile);
6296
+ const explicit = specifier.match(/\.(tsx?|jsx?|mjs|cjs)$/)?.[0] ?? null;
6297
+ const stem = explicit ? specifier.slice(0, -explicit.length) : specifier;
6298
+ const joined = posix.normalize(posix.join(baseDir, stem));
6299
+ const TS_EXTS = [".ts", ".tsx"];
6300
+ const JS_EXTS = [".js", ".jsx", ".mjs", ".cjs"];
6301
+ const importerIsJs = /\.(jsx?|mjs|cjs)$/.test(fromFile);
6302
+ const primary = importerIsJs ? JS_EXTS : TS_EXTS;
6303
+ const secondary = importerIsJs ? TS_EXTS : JS_EXTS;
6304
+ const exts = [
6305
+ ...explicit ? [explicit] : [],
6306
+ ...primary,
6307
+ ...secondary
6308
+ ].filter((e, i, a) => a.indexOf(e) === i);
6309
+ for (const e of exts) {
6310
+ const c = `${joined}${e}`;
6311
+ if (knownFiles.has(c))
6312
+ return c;
6313
+ }
6314
+ for (const e of exts) {
6315
+ const c = `${joined}/index${e}`;
6316
+ if (knownFiles.has(c))
6317
+ return c;
6318
+ }
6319
+ return null;
6320
+ }
6321
+ var PY_EXTS = [".py", ".pyi"];
6322
+ function isPythonFile(p) {
6323
+ return p.endsWith(".py") || p.endsWith(".pyi");
6324
+ }
6325
+ function resolvePythonModule(fromFile, specifier, knownFiles) {
6326
+ let dots = 0;
6327
+ while (dots < specifier.length && specifier[dots] === ".")
6328
+ dots++;
6329
+ const tail = specifier.slice(dots);
6330
+ const segs = tail.length > 0 ? tail.split(".") : [];
6331
+ if (dots === 0) {
6332
+ if (segs.length === 0)
6333
+ return null;
6334
+ return matchPythonSuffix(segs.join("/"), knownFiles);
6335
+ }
6336
+ let dir = posix.dirname(fromFile);
6337
+ let climbed = 1;
6338
+ for (; climbed < dots && dir !== "" && dir !== "."; climbed++)
6339
+ dir = posix.dirname(dir);
6340
+ if (climbed < dots)
6341
+ return null;
6342
+ const base = segs.length > 0 ? posix.normalize(posix.join(dir, ...segs)) : dir;
6343
+ for (const e of PY_EXTS)
6344
+ if (knownFiles.has(`${base}${e}`))
6345
+ return `${base}${e}`;
6346
+ for (const e of PY_EXTS)
6347
+ if (knownFiles.has(`${base}/__init__${e}`))
6348
+ return `${base}/__init__${e}`;
6349
+ return null;
6350
+ }
6351
+ function matchPythonSuffix(suffix, knownFiles) {
6352
+ const targets = [
6353
+ ...PY_EXTS.map((e) => `${suffix}${e}`),
6354
+ ...PY_EXTS.map((e) => `${suffix}/__init__${e}`)
6355
+ ];
6356
+ for (const t of targets) {
6357
+ if (knownFiles.has(t))
6358
+ return t;
6359
+ let hit = null;
6360
+ let count = 0;
6361
+ for (const f of knownFiles) {
6362
+ if (f.endsWith(`/${t}`)) {
6363
+ hit = f;
6364
+ count++;
6365
+ }
6366
+ }
6367
+ if (count === 1)
6368
+ return hit;
6369
+ if (count > 1)
6370
+ return null;
6371
+ }
6372
+ return null;
6373
+ }
6374
+
6375
+ // dist/src/graph/node-metadata.js
6376
+ function annotateNodeDegrees(nodes, links) {
6377
+ const inDeg = /* @__PURE__ */ new Map();
6378
+ const outDeg = /* @__PURE__ */ new Map();
6379
+ for (const e of links) {
6380
+ outDeg.set(e.source, (outDeg.get(e.source) ?? 0) + 1);
6381
+ inDeg.set(e.target, (inDeg.get(e.target) ?? 0) + 1);
6382
+ }
6383
+ for (const n of nodes) {
6384
+ const fi = inDeg.get(n.id) ?? 0;
6385
+ const fo = outDeg.get(n.id) ?? 0;
6386
+ n.fan_in = fi;
6387
+ n.fan_out = fo;
6388
+ n.is_entrypoint = n.exported && fi === 0;
6389
+ }
6390
+ }
6391
+
6392
+ // dist/src/graph/snapshot.js
6097
6393
  function graphsRoot() {
6098
6394
  return process.env.HIVEMIND_GRAPHS_HOME ?? join23(homedir10(), ".hivemind", "graphs");
6099
6395
  }
@@ -6109,15 +6405,23 @@ function buildSnapshot(extractions, metadata, observation) {
6109
6405
  for (const e of ex.edges)
6110
6406
  links.push(e);
6111
6407
  }
6408
+ for (const e of resolveCrossFileCalls(extractions, nodes))
6409
+ links.push(e);
6410
+ const knownFiles = /* @__PURE__ */ new Set();
6411
+ for (const ex of extractions)
6412
+ knownFiles.add(ex.source_file);
6413
+ let resolvedLinks = repointImportEdges(links, knownFiles);
6414
+ resolvedLinks = resolveHeritageEdges(resolvedLinks, extractions, nodes);
6415
+ annotateNodeDegrees(nodes, resolvedLinks);
6112
6416
  nodes.sort(compareNodes);
6113
- links.sort(compareEdges);
6417
+ resolvedLinks.sort(compareEdges);
6114
6418
  return {
6115
6419
  directed: true,
6116
6420
  multigraph: true,
6117
6421
  graph: metadata,
6118
6422
  observation,
6119
6423
  nodes,
6120
- links
6424
+ links: resolvedLinks
6121
6425
  };
6122
6426
  }
6123
6427
  function compareNodes(a, b) {
@@ -6235,8 +6539,20 @@ async function pullSnapshot(cwd, deps = {}) {
6235
6539
  if (cloudPayload === null) {
6236
6540
  return errorOutcome2("SELECT cloud row", new Error("invalid snapshot_jsonb payload"));
6237
6541
  }
6542
+ let parsedSnapshot;
6543
+ try {
6544
+ parsedSnapshot = JSON.parse(cloudPayload);
6545
+ } catch (err) {
6546
+ return errorOutcome2("parse cloud snapshot", err);
6547
+ }
6548
+ if (parsedSnapshot === null || typeof parsedSnapshot !== "object") {
6549
+ return errorOutcome2("parse cloud snapshot", new Error("snapshot not an object"));
6550
+ }
6551
+ if (!Array.isArray(parsedSnapshot.nodes) || !Array.isArray(parsedSnapshot.links)) {
6552
+ return errorOutcome2("parse cloud snapshot", new Error("snapshot missing nodes/links arrays"));
6553
+ }
6238
6554
  if (cloudSha256 !== "") {
6239
- const computedSha = createHash5("sha256").update(cloudPayload).digest("hex");
6555
+ const computedSha = computeSnapshotSha2562(parsedSnapshot);
6240
6556
  if (cloudSha256 !== computedSha) {
6241
6557
  return errorOutcome2("SELECT cloud row", new Error(`snapshot_sha256 mismatch (expected ${cloudSha256}, got ${computedSha})`));
6242
6558
  }
@@ -6454,11 +6770,11 @@ function pickParserForPath(relativePath) {
6454
6770
  }
6455
6771
  function extractTypeScript(sourceCode, relativePath) {
6456
6772
  const parser = pickParserForPath(relativePath);
6457
- const CHUNK_BYTES = 16384;
6773
+ const CHUNK_BYTES2 = 16384;
6458
6774
  const tree = parser.parse((index) => {
6459
6775
  if (index >= sourceCode.length)
6460
6776
  return null;
6461
- return sourceCode.slice(index, index + CHUNK_BYTES);
6777
+ return sourceCode.slice(index, index + CHUNK_BYTES2);
6462
6778
  });
6463
6779
  const root = tree.rootNode;
6464
6780
  const result = {
@@ -6466,7 +6782,9 @@ function extractTypeScript(sourceCode, relativePath) {
6466
6782
  language: "typescript",
6467
6783
  nodes: [],
6468
6784
  edges: [],
6469
- parse_errors: []
6785
+ parse_errors: [],
6786
+ raw_calls: [],
6787
+ import_bindings: []
6470
6788
  };
6471
6789
  collectParseErrors(root, relativePath, result.parse_errors);
6472
6790
  const moduleNode = makeModuleNode(relativePath);
@@ -6475,8 +6793,16 @@ function extractTypeScript(sourceCode, relativePath) {
6475
6793
  extractDeclarations(root, relativePath, result, declByName, moduleNode);
6476
6794
  extractImports(root, relativePath, result, moduleNode);
6477
6795
  extractCalls(root, relativePath, result, declByName);
6796
+ if (isJavaScriptPath(relativePath)) {
6797
+ result.language = "javascript";
6798
+ for (const n of result.nodes)
6799
+ n.language = "javascript";
6800
+ }
6478
6801
  return result;
6479
6802
  }
6803
+ function isJavaScriptPath(relativePath) {
6804
+ return /\.(jsx?|mjs|cjs)$/.test(relativePath);
6805
+ }
6480
6806
  function collectParseErrors(node, relativePath, out) {
6481
6807
  if (node.isError || node.isMissing) {
6482
6808
  out.push({
@@ -6573,8 +6899,8 @@ function handleDeclaration(node, exported, relativePath, result, declByName, mod
6573
6899
  continue;
6574
6900
  const accessibility = firstNamedChildOfTypes(member, ["accessibility_modifier"]);
6575
6901
  const isHardPrivate = firstNamedChildOfTypes(member, ["private_property_identifier"]) !== null;
6576
- const isPublic = !isHardPrivate && (accessibility === null || accessibility.text === "public");
6577
- const methodExported = exported && isPublic;
6902
+ const isPublic2 = !isHardPrivate && (accessibility === null || accessibility.text === "public");
6903
+ const methodExported = exported && isPublic2;
6578
6904
  const methodKey = `${classNode.label}.${methodName}`;
6579
6905
  const methodNode = makeNodeWithExplicitLabel(relativePath, methodKey, methodName, "method", member, methodExported);
6580
6906
  pushNode(result, declByName, methodNode, methodKey);
@@ -6641,6 +6967,7 @@ function extractImports(node, relativePath, result, moduleNode) {
6641
6967
  relation: "imports",
6642
6968
  confidence: "EXTRACTED"
6643
6969
  });
6970
+ extractImportBindings(node, specifier, result);
6644
6971
  }
6645
6972
  }
6646
6973
  return;
@@ -6651,23 +6978,60 @@ function extractImports(node, relativePath, result, moduleNode) {
6651
6978
  extractImports(child, relativePath, result, moduleNode);
6652
6979
  }
6653
6980
  }
6981
+ function extractImportBindings(importStmt, specifier, result) {
6982
+ const stmtTypeOnly = /^import\s+type\b/.test(importStmt.text.trimStart());
6983
+ const clause = firstNamedChildOfTypes(importStmt, ["import_clause"]);
6984
+ if (clause === null)
6985
+ return;
6986
+ const push = (b) => {
6987
+ result.import_bindings.push({ ...b, specifier });
6988
+ };
6989
+ for (let i = 0; i < clause.namedChildCount; i++) {
6990
+ const child = clause.namedChild(i);
6991
+ if (child === null)
6992
+ continue;
6993
+ if (child.type === "identifier") {
6994
+ push({ local_name: child.text, imported_name: "default", kind: "default", type_only: stmtTypeOnly });
6995
+ } else if (child.type === "namespace_import") {
6996
+ const id = firstNamedChildOfTypes(child, ["identifier"]);
6997
+ if (id !== null)
6998
+ push({ local_name: id.text, imported_name: "*", kind: "namespace", type_only: stmtTypeOnly });
6999
+ } else if (child.type === "named_imports") {
7000
+ for (let j = 0; j < child.namedChildCount; j++) {
7001
+ const spec = child.namedChild(j);
7002
+ if (spec === null || spec.type !== "import_specifier")
7003
+ continue;
7004
+ const specTypeOnly = stmtTypeOnly || /^type\s+(?!as\b)/.test(spec.text);
7005
+ const nameNode = spec.childForFieldName("name");
7006
+ const aliasNode = spec.childForFieldName("alias");
7007
+ const imported = nameNode !== null ? nameNode.text : null;
7008
+ if (imported === null)
7009
+ continue;
7010
+ const local = aliasNode !== null ? aliasNode.text : imported;
7011
+ push({ local_name: local, imported_name: imported, kind: "named", type_only: specTypeOnly });
7012
+ }
7013
+ }
7014
+ }
7015
+ }
6654
7016
  function extractCalls(node, relativePath, result, declByName) {
6655
7017
  if (node.type === "call_expression") {
6656
7018
  const callee = node.childForFieldName("function");
6657
7019
  if (callee !== null) {
6658
- const calleeKey = resolveCalleeKey(callee, declByName);
6659
- if (calleeKey !== null) {
6660
- const targetNode = declByName.get(calleeKey);
7020
+ const callerNode = findEnclosingDeclaration(node, declByName);
7021
+ if (callerNode !== null) {
7022
+ const calleeKey = resolveCalleeKey(callee, declByName);
7023
+ const targetNode = calleeKey !== null ? declByName.get(calleeKey) : void 0;
6661
7024
  if (targetNode !== void 0) {
6662
- const callerNode = findEnclosingDeclaration(node, declByName);
6663
- if (callerNode !== null) {
6664
- result.edges.push({
6665
- source: callerNode.id,
6666
- target: targetNode.id,
6667
- relation: "calls",
6668
- confidence: "EXTRACTED"
6669
- });
6670
- }
7025
+ result.edges.push({
7026
+ source: callerNode.id,
7027
+ target: targetNode.id,
7028
+ relation: "calls",
7029
+ confidence: "EXTRACTED"
7030
+ });
7031
+ } else {
7032
+ const rc = rawCallFromCallee(callee, callerNode.id);
7033
+ if (rc !== null)
7034
+ result.raw_calls.push(rc);
6671
7035
  }
6672
7036
  }
6673
7037
  }
@@ -6678,6 +7042,19 @@ function extractCalls(node, relativePath, result, declByName) {
6678
7042
  extractCalls(child, relativePath, result, declByName);
6679
7043
  }
6680
7044
  }
7045
+ function rawCallFromCallee(callee, callerId) {
7046
+ if (callee.type === "identifier") {
7047
+ return { caller_id: callerId, callee_name: callee.text };
7048
+ }
7049
+ if (callee.type === "member_expression") {
7050
+ const object = callee.childForFieldName("object");
7051
+ const property = callee.childForFieldName("property");
7052
+ if (object !== null && object.type === "identifier" && property !== null && property.type === "property_identifier") {
7053
+ return { caller_id: callerId, callee_name: property.text, receiver: object.text };
7054
+ }
7055
+ }
7056
+ return null;
7057
+ }
6681
7058
  function resolveCalleeKey(callee, declByName) {
6682
7059
  if (callee.type === "identifier")
6683
7060
  return callee.text;
@@ -6754,9 +7131,31 @@ function makeNode(relativePath, name, kind, node, exported) {
6754
7131
  source_file: relativePath,
6755
7132
  source_location: locationStr(node),
6756
7133
  language: "typescript",
6757
- exported
7134
+ exported,
7135
+ signature: signatureOf(node, kind)
6758
7136
  };
6759
7137
  }
7138
+ function signatureOf(node, kind) {
7139
+ const text = node.text;
7140
+ let end = text.length;
7141
+ const nl = text.indexOf("\n");
7142
+ if (nl >= 0)
7143
+ end = Math.min(end, nl);
7144
+ const cutsAtBody = kind === "function" || kind === "class" || kind === "method" || kind === "interface" || kind === "enum";
7145
+ if (cutsAtBody) {
7146
+ const body = node.childForFieldName("body");
7147
+ if (body !== null) {
7148
+ end = Math.min(end, body.startIndex - node.startIndex);
7149
+ } else {
7150
+ const brace = text.indexOf("{");
7151
+ if (brace >= 0)
7152
+ end = Math.min(end, brace);
7153
+ }
7154
+ }
7155
+ const sig = text.slice(0, end).replace(/\s+/g, " ").trim();
7156
+ const cps = [...sig];
7157
+ return cps.length > 120 ? `${cps.slice(0, 117).join("")}...` : sig;
7158
+ }
6760
7159
  function makeNodeWithExplicitLabel(relativePath, idName, label, kind, node, exported) {
6761
7160
  return {
6762
7161
  id: nodeId(relativePath, idName, kind),
@@ -6765,7 +7164,8 @@ function makeNodeWithExplicitLabel(relativePath, idName, label, kind, node, expo
6765
7164
  source_file: relativePath,
6766
7165
  source_location: locationStr(node),
6767
7166
  language: "typescript",
6768
- exported
7167
+ exported,
7168
+ signature: signatureOf(node, kind)
6769
7169
  };
6770
7170
  }
6771
7171
  function pushNode(result, declByName, node, lookupKey) {
@@ -6805,9 +7205,433 @@ function firstNamedChildOfTypes(node, types) {
6805
7205
  return null;
6806
7206
  }
6807
7207
 
7208
+ // dist/src/graph/extract/python.js
7209
+ import Parser2 from "tree-sitter";
7210
+ import Python from "tree-sitter-python";
7211
+ var _pythonParser = null;
7212
+ function getPythonParser() {
7213
+ if (_pythonParser === null) {
7214
+ _pythonParser = new Parser2();
7215
+ _pythonParser.setLanguage(Python);
7216
+ }
7217
+ return _pythonParser;
7218
+ }
7219
+ var CHUNK_BYTES = 16384;
7220
+ function extractPython(sourceCode, relativePath) {
7221
+ const parser = getPythonParser();
7222
+ const tree = parser.parse((index) => index >= sourceCode.length ? null : sourceCode.slice(index, index + CHUNK_BYTES));
7223
+ const root = tree.rootNode;
7224
+ const result = {
7225
+ source_file: relativePath,
7226
+ language: "python",
7227
+ nodes: [],
7228
+ edges: [],
7229
+ parse_errors: [],
7230
+ raw_calls: [],
7231
+ import_bindings: []
7232
+ };
7233
+ collectParseErrors2(root, relativePath, result.parse_errors);
7234
+ const moduleNode = makeModuleNode2(relativePath);
7235
+ result.nodes.push(moduleNode);
7236
+ const declByName = /* @__PURE__ */ new Map();
7237
+ extractDeclarations2(
7238
+ root,
7239
+ relativePath,
7240
+ result,
7241
+ declByName,
7242
+ /*topLevel*/
7243
+ true
7244
+ );
7245
+ extractImports2(root, relativePath, result, moduleNode);
7246
+ extractCalls2(root, result, declByName);
7247
+ return result;
7248
+ }
7249
+ function collectParseErrors2(node, relativePath, out) {
7250
+ if (node.isError || node.isMissing) {
7251
+ out.push({ source_file: relativePath, message: node.isMissing ? `missing node: ${node.type}` : `parse error at ${loc(node)}`, location: loc(node) });
7252
+ return;
7253
+ }
7254
+ for (let i = 0; i < node.namedChildCount; i++) {
7255
+ const c = node.namedChild(i);
7256
+ if (c !== null)
7257
+ collectParseErrors2(c, relativePath, out);
7258
+ }
7259
+ }
7260
+ function extractDeclarations2(node, relativePath, result, declByName, topLevel) {
7261
+ for (let i = 0; i < node.namedChildCount; i++) {
7262
+ const child = node.namedChild(i);
7263
+ if (child === null)
7264
+ continue;
7265
+ if (child.type === "function_definition") {
7266
+ const name = textOfField2(child, "name");
7267
+ if (name !== null)
7268
+ pushNode2(result, declByName, makeNode2(relativePath, name, "function", child, isPublic(name)));
7269
+ } else if (child.type === "class_definition") {
7270
+ handleClass(child, relativePath, result, declByName);
7271
+ } else if (topLevel && child.type === "expression_statement") {
7272
+ const assign = firstOfType(child, "assignment");
7273
+ if (assign !== null) {
7274
+ const lhs = assign.childForFieldName("left");
7275
+ if (lhs !== null && lhs.type === "identifier") {
7276
+ pushNode2(result, declByName, makeNode2(relativePath, lhs.text, "const", assign, isPublic(lhs.text)));
7277
+ }
7278
+ }
7279
+ } else if (child.type === "decorated_definition") {
7280
+ extractDeclarations2(child, relativePath, result, declByName, topLevel);
7281
+ }
7282
+ }
7283
+ }
7284
+ function handleClass(node, relativePath, result, declByName) {
7285
+ const name = textOfField2(node, "name");
7286
+ if (name === null)
7287
+ return;
7288
+ const classNode = makeNode2(relativePath, name, "class", node, isPublic(name));
7289
+ pushNode2(result, declByName, classNode);
7290
+ const supers = node.childForFieldName("superclasses");
7291
+ if (supers !== null) {
7292
+ for (let i = 0; i < supers.namedChildCount; i++) {
7293
+ const base = supers.namedChild(i);
7294
+ if (base === null)
7295
+ continue;
7296
+ let baseName = null;
7297
+ if (base.type === "identifier")
7298
+ baseName = base.text;
7299
+ else if (base.type === "attribute") {
7300
+ const attr = base.childForFieldName("attribute");
7301
+ baseName = attr !== null ? attr.text : null;
7302
+ }
7303
+ if (baseName === null || baseName.length === 0)
7304
+ continue;
7305
+ result.edges.push({
7306
+ source: classNode.id,
7307
+ target: nodeIdUnresolved2(relativePath, baseName, "class"),
7308
+ relation: "extends",
7309
+ confidence: "EXTRACTED"
7310
+ });
7311
+ }
7312
+ }
7313
+ const body = node.childForFieldName("body");
7314
+ if (body !== null) {
7315
+ for (let i = 0; i < body.namedChildCount; i++) {
7316
+ let member = body.namedChild(i);
7317
+ if (member === null)
7318
+ continue;
7319
+ if (member.type === "decorated_definition")
7320
+ member = firstOfType(member, "function_definition");
7321
+ if (member === null || member.type !== "function_definition")
7322
+ continue;
7323
+ const mName = textOfField2(member, "name");
7324
+ if (mName === null)
7325
+ continue;
7326
+ const methodNode = makeNodeWithExplicitLabel2(relativePath, `${name}.${mName}`, mName, "method", member, isPublic(name) && isPublic(mName));
7327
+ pushNode2(result, declByName, methodNode);
7328
+ result.edges.push({ source: classNode.id, target: methodNode.id, relation: "method_of", confidence: "EXTRACTED" });
7329
+ }
7330
+ }
7331
+ }
7332
+ function extractImports2(node, relativePath, result, moduleNode) {
7333
+ if (node.type === "import_statement") {
7334
+ for (let i = 0; i < node.namedChildCount; i++) {
7335
+ const child = node.namedChild(i);
7336
+ if (child === null)
7337
+ continue;
7338
+ let modText = null;
7339
+ let local = null;
7340
+ if (child.type === "dotted_name") {
7341
+ modText = child.text;
7342
+ local = lastDottedSegment(child.text);
7343
+ } else if (child.type === "aliased_import") {
7344
+ const name = child.childForFieldName("name");
7345
+ const alias = child.childForFieldName("alias");
7346
+ if (name !== null) {
7347
+ modText = name.text;
7348
+ local = alias !== null ? alias.text : lastDottedSegment(name.text);
7349
+ }
7350
+ }
7351
+ if (modText !== null) {
7352
+ pushImportEdge(result, moduleNode, modText);
7353
+ if (local !== null)
7354
+ result.import_bindings.push({ local_name: local, imported_name: "*", kind: "namespace", specifier: modText });
7355
+ }
7356
+ }
7357
+ return;
7358
+ }
7359
+ if (node.type === "import_from_statement") {
7360
+ const modNode = node.childForFieldName("module_name");
7361
+ const modText = modNode !== null ? modNode.text : ".";
7362
+ pushImportEdge(result, moduleNode, modText);
7363
+ for (let i = 0; i < node.namedChildCount; i++) {
7364
+ const child = node.namedChild(i);
7365
+ if (child === null || child === modNode)
7366
+ continue;
7367
+ if (child.type === "dotted_name" || child.type === "identifier") {
7368
+ const imported = child.text;
7369
+ result.import_bindings.push({ local_name: lastDottedSegment(imported), imported_name: imported, kind: "named", specifier: modText });
7370
+ } else if (child.type === "aliased_import") {
7371
+ const name = child.childForFieldName("name");
7372
+ const alias = child.childForFieldName("alias");
7373
+ if (name !== null)
7374
+ result.import_bindings.push({ local_name: alias !== null ? alias.text : lastDottedSegment(name.text), imported_name: name.text, kind: "named", specifier: modText });
7375
+ }
7376
+ }
7377
+ return;
7378
+ }
7379
+ for (let i = 0; i < node.namedChildCount; i++) {
7380
+ const c = node.namedChild(i);
7381
+ if (c !== null)
7382
+ extractImports2(c, relativePath, result, moduleNode);
7383
+ }
7384
+ }
7385
+ function pushImportEdge(result, moduleNode, specifier) {
7386
+ if (specifier.length === 0)
7387
+ return;
7388
+ result.edges.push({ source: moduleNode.id, target: `external:${specifier}`, relation: "imports", confidence: "EXTRACTED" });
7389
+ }
7390
+ function extractCalls2(node, result, declByName) {
7391
+ if (node.type === "call") {
7392
+ const callee = node.childForFieldName("function");
7393
+ if (callee !== null) {
7394
+ const caller = findEnclosingDeclaration2(node, declByName);
7395
+ if (caller !== null) {
7396
+ const key = resolveCalleeKey2(callee);
7397
+ const target = key !== null ? declByName.get(key) : void 0;
7398
+ if (target !== void 0) {
7399
+ result.edges.push({ source: caller.id, target: target.id, relation: "calls", confidence: "EXTRACTED" });
7400
+ } else {
7401
+ const rc = rawCallFromCallee2(callee, caller.id);
7402
+ if (rc !== null)
7403
+ result.raw_calls.push(rc);
7404
+ }
7405
+ }
7406
+ }
7407
+ }
7408
+ for (let i = 0; i < node.namedChildCount; i++) {
7409
+ const c = node.namedChild(i);
7410
+ if (c !== null)
7411
+ extractCalls2(c, result, declByName);
7412
+ }
7413
+ }
7414
+ function resolveCalleeKey2(callee) {
7415
+ if (callee.type === "identifier")
7416
+ return callee.text;
7417
+ if (callee.type === "attribute") {
7418
+ const obj = callee.childForFieldName("object");
7419
+ const attr = callee.childForFieldName("attribute");
7420
+ if (obj !== null && obj.type === "identifier" && obj.text === "self" && attr !== null) {
7421
+ const cls = findEnclosingClassName2(callee);
7422
+ if (cls !== null)
7423
+ return `${cls}.${attr.text}`;
7424
+ }
7425
+ }
7426
+ return null;
7427
+ }
7428
+ function rawCallFromCallee2(callee, callerId) {
7429
+ if (callee.type === "identifier")
7430
+ return { caller_id: callerId, callee_name: callee.text };
7431
+ if (callee.type === "attribute") {
7432
+ const obj = callee.childForFieldName("object");
7433
+ const attr = callee.childForFieldName("attribute");
7434
+ if (obj !== null && obj.type === "identifier" && obj.text !== "self" && attr !== null) {
7435
+ return { caller_id: callerId, callee_name: attr.text, receiver: obj.text };
7436
+ }
7437
+ }
7438
+ return null;
7439
+ }
7440
+ function findEnclosingDeclaration2(node, declByName) {
7441
+ let cur = node.parent;
7442
+ while (cur !== null) {
7443
+ if (cur.type === "function_definition") {
7444
+ const name = textOfField2(cur, "name");
7445
+ const cls = findEnclosingClassName2(cur);
7446
+ if (name !== null) {
7447
+ const n = cls !== null ? declByName.get(`${cls}.${name}`) : declByName.get(name);
7448
+ if (n !== void 0)
7449
+ return n;
7450
+ }
7451
+ }
7452
+ cur = cur.parent;
7453
+ }
7454
+ return null;
7455
+ }
7456
+ function findEnclosingClassName2(node) {
7457
+ let cur = node.parent;
7458
+ while (cur !== null) {
7459
+ if (cur.type === "class_definition")
7460
+ return textOfField2(cur, "name");
7461
+ cur = cur.parent;
7462
+ }
7463
+ return null;
7464
+ }
7465
+ function makeNode2(relativePath, name, kind, node, exported) {
7466
+ return { id: nodeId2(relativePath, name, kind), label: name, kind, source_file: relativePath, source_location: loc(node), language: "python", exported, signature: signatureOf2(node, kind) };
7467
+ }
7468
+ function makeNodeWithExplicitLabel2(relativePath, idName, label, kind, node, exported) {
7469
+ return { id: nodeId2(relativePath, idName, kind), label, kind, source_file: relativePath, source_location: loc(node), language: "python", exported, signature: signatureOf2(node, kind) };
7470
+ }
7471
+ function makeModuleNode2(relativePath) {
7472
+ return { id: `${relativePath}::module`, label: relativePath, kind: "module", source_file: relativePath, source_location: "L1", language: "python", exported: false };
7473
+ }
7474
+ function pushNode2(result, declByName, node) {
7475
+ result.nodes.push(node);
7476
+ const key = node.kind === "method" ? node.id.split(":")[1] : node.label;
7477
+ if (!declByName.has(key))
7478
+ declByName.set(key, node);
7479
+ }
7480
+ function signatureOf2(node, kind) {
7481
+ const text = node.text;
7482
+ let end = text.length;
7483
+ const nl = text.indexOf("\n");
7484
+ if (nl >= 0)
7485
+ end = Math.min(end, nl);
7486
+ if (kind === "function" || kind === "method" || kind === "class") {
7487
+ const body = node.childForFieldName("body");
7488
+ if (body !== null)
7489
+ end = Math.min(end, body.startIndex - node.startIndex);
7490
+ }
7491
+ const sig = text.slice(0, end).replace(/\s+/g, " ").replace(/:\s*$/, "").trim();
7492
+ const cps = [...sig];
7493
+ return cps.length > 120 ? `${cps.slice(0, 117).join("")}...` : sig;
7494
+ }
7495
+ function nodeId2(relativePath, name, kind) {
7496
+ return `${relativePath}:${name}:${kind}`;
7497
+ }
7498
+ function nodeIdUnresolved2(relativePath, name, kind) {
7499
+ return `unresolved:${relativePath}:${name}:${kind}`;
7500
+ }
7501
+ function loc(node) {
7502
+ const start = node.startPosition.row + 1;
7503
+ const end = node.endPosition.row + 1;
7504
+ return end > start ? `L${start}-${end}` : `L${start}`;
7505
+ }
7506
+ function textOfField2(node, field) {
7507
+ const f = node.childForFieldName(field);
7508
+ return f !== null ? f.text : null;
7509
+ }
7510
+ function firstOfType(node, type2) {
7511
+ for (let i = 0; i < node.namedChildCount; i++) {
7512
+ const c = node.namedChild(i);
7513
+ if (c !== null && c.type === type2)
7514
+ return c;
7515
+ }
7516
+ return null;
7517
+ }
7518
+ function lastDottedSegment(dotted) {
7519
+ const parts = dotted.split(".");
7520
+ return parts[parts.length - 1] ?? dotted;
7521
+ }
7522
+ function isPublic(name) {
7523
+ return !name.startsWith("_");
7524
+ }
7525
+
7526
+ // dist/src/graph/extract/index.js
7527
+ function isPythonPath(relativePath) {
7528
+ return /\.pyi?$/.test(relativePath);
7529
+ }
7530
+ function extractFile(sourceCode, relativePath) {
7531
+ if (isPythonPath(relativePath))
7532
+ return extractPython(sourceCode, relativePath);
7533
+ return extractTypeScript(sourceCode, relativePath);
7534
+ }
7535
+
7536
+ // dist/src/graph/ignore-config.js
7537
+ import { mkdirSync as mkdirSync12, readFileSync as readFileSync19, writeFileSync as writeFileSync16 } from "node:fs";
7538
+ import { homedir as homedir11 } from "node:os";
7539
+ import { join as join26 } from "node:path";
7540
+ var DEFAULT_IGNORE_DIRS = [
7541
+ // JS / TS toolchains
7542
+ "node_modules",
7543
+ "bower_components",
7544
+ "jspm_packages",
7545
+ ".pnpm-store",
7546
+ "dist",
7547
+ "build",
7548
+ "out",
7549
+ "coverage",
7550
+ "bundle",
7551
+ ".next",
7552
+ ".nuxt",
7553
+ ".svelte-kit",
7554
+ ".turbo",
7555
+ ".parcel-cache",
7556
+ ".cache",
7557
+ ".vite",
7558
+ ".nyc_output",
7559
+ // Python
7560
+ "venv",
7561
+ ".venv",
7562
+ "env",
7563
+ ".env",
7564
+ "virtualenv",
7565
+ "__pycache__",
7566
+ "site-packages",
7567
+ "__pypackages__",
7568
+ ".pytest_cache",
7569
+ ".mypy_cache",
7570
+ ".ruff_cache",
7571
+ ".tox",
7572
+ ".eggs",
7573
+ ".ipynb_checkpoints",
7574
+ ".hypothesis",
7575
+ // Rust / Java / .NET / Go vendoring
7576
+ "target",
7577
+ "obj",
7578
+ "vendor",
7579
+ ".gradle",
7580
+ ".mvn",
7581
+ // Native / mobile
7582
+ "Pods",
7583
+ "DerivedData",
7584
+ ".build",
7585
+ // VCS / IDE
7586
+ ".git",
7587
+ ".svn",
7588
+ ".hg",
7589
+ ".idea",
7590
+ ".vscode",
7591
+ ".vs",
7592
+ // Infra / misc
7593
+ ".terraform",
7594
+ "tmp",
7595
+ "temp",
7596
+ "logs",
7597
+ "third_party",
7598
+ "third-party"
7599
+ ];
7600
+ var FILE_NAME = "graph-ignore.json";
7601
+ function defaultConfigObject() {
7602
+ return {
7603
+ _comment: "Directory names skipped when building the hivemind code graph. Edit freely. When respectGitignore is true, the repo's .gitignore is also honored (anchoring-correct).",
7604
+ ignoreDirs: [...DEFAULT_IGNORE_DIRS],
7605
+ respectGitignore: true
7606
+ };
7607
+ }
7608
+ function loadGraphIgnore(deeplakeDir = join26(homedir11(), ".deeplake")) {
7609
+ const path = join26(deeplakeDir, FILE_NAME);
7610
+ try {
7611
+ const parsed = JSON.parse(readFileSync19(path, "utf8"));
7612
+ const ignoreDirs = Array.isArray(parsed.ignoreDirs) ? parsed.ignoreDirs.filter((s) => typeof s === "string") : [...DEFAULT_IGNORE_DIRS];
7613
+ const respectGitignore = typeof parsed.respectGitignore === "boolean" ? parsed.respectGitignore : true;
7614
+ return { ignoreDirs, respectGitignore };
7615
+ } catch {
7616
+ }
7617
+ try {
7618
+ mkdirSync12(deeplakeDir, { recursive: true });
7619
+ writeFileSync16(path, JSON.stringify(defaultConfigObject(), null, 2) + "\n", { flag: "wx" });
7620
+ } catch {
7621
+ }
7622
+ return { ignoreDirs: [...DEFAULT_IGNORE_DIRS], respectGitignore: true };
7623
+ }
7624
+ function ignoreDirSet(config) {
7625
+ return new Set(config.ignoreDirs);
7626
+ }
7627
+ function pathHasIgnoredSegment(relPath, ignore) {
7628
+ const segs = relPath.split("/");
7629
+ return segs.some((seg, i) => ignore.has(seg) || i < segs.length - 1 && seg.startsWith("."));
7630
+ }
7631
+
6808
7632
  // dist/src/graph/git-hook-install.js
6809
- import { chmodSync as chmodSync2, existsSync as existsSync20, mkdirSync as mkdirSync12, readFileSync as readFileSync19, unlinkSync as unlinkSync8, writeFileSync as writeFileSync16 } from "node:fs";
6810
- import { dirname as dirname8, join as join26, resolve as resolve3 } from "node:path";
7633
+ import { chmodSync as chmodSync2, existsSync as existsSync20, mkdirSync as mkdirSync13, readFileSync as readFileSync20, unlinkSync as unlinkSync8, writeFileSync as writeFileSync17 } from "node:fs";
7634
+ import { dirname as dirname8, join as join27, resolve as resolve3 } from "node:path";
6811
7635
  import { execFileSync as execFileSync5 } from "node:child_process";
6812
7636
  var HOOK_BEGIN_MARKER = "# HIVEMIND_GRAPH_HOOK_BEGIN \u2014 managed by `hivemind graph init`";
6813
7637
  var HOOK_END_MARKER = "# HIVEMIND_GRAPH_HOOK_END";
@@ -6870,7 +7694,7 @@ function tryGitTopLevel(cwd) {
6870
7694
  }
6871
7695
  function postCommitHookPath(cwd) {
6872
7696
  const hooksDir = gitHooksDir(cwd);
6873
- return hooksDir === null ? null : join26(hooksDir, "post-commit");
7697
+ return hooksDir === null ? null : join27(hooksDir, "post-commit");
6874
7698
  }
6875
7699
  function installPostCommitHook(cwd, opts = {}) {
6876
7700
  const path = postCommitHookPath(cwd);
@@ -6879,7 +7703,7 @@ function installPostCommitHook(cwd, opts = {}) {
6879
7703
  }
6880
7704
  const existed = existsSync20(path);
6881
7705
  if (existed) {
6882
- const content = readFileSync19(path, "utf8");
7706
+ const content = readFileSync20(path, "utf8");
6883
7707
  if (containsOurMarkers(content)) {
6884
7708
  return { kind: "already-ours", path };
6885
7709
  }
@@ -6899,8 +7723,8 @@ function installPostCommitHook(cwd, opts = {}) {
6899
7723
  hint: "hivemind binary not found on PATH. Install hivemind globally (`npm install -g @deeplake/hivemind`) before running `hivemind graph init`, so the hook can find a stable absolute path to call."
6900
7724
  };
6901
7725
  }
6902
- mkdirSync12(dirname8(path), { recursive: true });
6903
- writeFileSync16(path, buildHookFile(hivemindPath), { mode: 493 });
7726
+ mkdirSync13(dirname8(path), { recursive: true });
7727
+ writeFileSync17(path, buildHookFile(hivemindPath), { mode: 493 });
6904
7728
  try {
6905
7729
  chmodSync2(path, 493);
6906
7730
  } catch {
@@ -6927,7 +7751,7 @@ function uninstallPostCommitHook(cwd) {
6927
7751
  if (!existsSync20(path)) {
6928
7752
  return { kind: "no-hook", path };
6929
7753
  }
6930
- const content = readFileSync19(path, "utf8");
7754
+ const content = readFileSync20(path, "utf8");
6931
7755
  if (!containsOurMarkers(content)) {
6932
7756
  return {
6933
7757
  kind: "not-ours",
@@ -6941,7 +7765,7 @@ function uninstallPostCommitHook(cwd) {
6941
7765
  unlinkSync8(path);
6942
7766
  return { kind: "removed", path, wholeFileDeleted: true };
6943
7767
  }
6944
- writeFileSync16(path, stripped);
7768
+ writeFileSync17(path, stripped);
6945
7769
  return { kind: "removed", path, wholeFileDeleted: false };
6946
7770
  }
6947
7771
  function containsOurMarkers(content) {
@@ -6967,11 +7791,11 @@ function buildHookFile(hivemindPath) {
6967
7791
  }
6968
7792
 
6969
7793
  // dist/src/commands/graph.js
6970
- var USAGE = `hivemind graph \u2014 codebase-graph commands (Phase 1 \u2014 TypeScript only)
7794
+ var USAGE = `hivemind graph \u2014 codebase-graph commands (TypeScript / JavaScript / Python)
6971
7795
 
6972
7796
  Usage:
6973
7797
  hivemind graph build [--cwd <path>]
6974
- Walk the project for TypeScript source files, extract symbols + edges,
7798
+ Walk the project for supported source files (TS/JS/Python), extract symbols + edges,
6975
7799
  and write a snapshot to ~/.hivemind/graphs/<repo-key>/snapshots/<commit-sha>.json.
6976
7800
  Also updates ~/.hivemind/graphs/<repo-key>/latest-commit.txt and the
6977
7801
  per-repo .last-build.json (consumed by the SessionEnd auto-build hook).
@@ -7015,15 +7839,6 @@ Usage:
7015
7839
 
7016
7840
  Future subcommands (Phase 1.5+): daemon, search, latest, push, pull, prune.
7017
7841
  `;
7018
- var DEFAULT_IGNORES = /* @__PURE__ */ new Set([
7019
- "node_modules",
7020
- ".git",
7021
- "bundle",
7022
- "dist",
7023
- "coverage",
7024
- ".cache",
7025
- ".nyc_output"
7026
- ]);
7027
7842
  function runGraphCommand(args) {
7028
7843
  const sub = args[0];
7029
7844
  if (sub === void 0 || sub === "--help" || sub === "-h" || sub === "help") {
@@ -7299,8 +8114,9 @@ async function runBuildCommand(args) {
7299
8114
  console.log(` branch: ${branch ?? "(none / detached)"}`);
7300
8115
  console.log(` output: ${baseDir}`);
7301
8116
  console.log("");
7302
- const sourceFiles = discoverSourceFiles(cwd);
7303
- console.log(`Discovered ${sourceFiles.length} TypeScript source files. Extracting...`);
8117
+ const ignoreConfig = loadGraphIgnore();
8118
+ const sourceFiles = discoverSourceFiles(cwd, ignoreConfig);
8119
+ console.log(`Discovered ${sourceFiles.length} source files. Extracting...`);
7304
8120
  const extractions = [];
7305
8121
  let skipped = 0;
7306
8122
  let totalParseErrors = 0;
@@ -7308,11 +8124,11 @@ async function runBuildCommand(args) {
7308
8124
  for (const abs of sourceFiles) {
7309
8125
  const rel = toForwardSlash(relative(cwd, abs));
7310
8126
  try {
7311
- const content = readFileSync20(abs, "utf8");
8127
+ const content = readFileSync21(abs, "utf8");
7312
8128
  const contentSha = fileContentHash(content);
7313
8129
  let extraction = readCache(baseDir, contentSha, rel);
7314
8130
  if (extraction === null) {
7315
- extraction = extractTypeScript(content, rel);
8131
+ extraction = extractFile(content, rel);
7316
8132
  writeCache(baseDir, contentSha, extraction);
7317
8133
  } else {
7318
8134
  cacheHits += 1;
@@ -7447,13 +8263,44 @@ async function runPullCommand(args) {
7447
8263
  function workTreeIdFor2(cwd) {
7448
8264
  return createHash6("sha256").update(cwd).digest("hex").slice(0, 16);
7449
8265
  }
7450
- function discoverSourceFiles(rootDir) {
8266
+ function discoverSourceFiles(rootDir, config) {
8267
+ const ignore = ignoreDirSet(config);
8268
+ if (config.respectGitignore) {
8269
+ const fromGit = gitListSourceFiles(rootDir, ignore);
8270
+ if (fromGit !== null)
8271
+ return fromGit;
8272
+ }
8273
+ const out = [];
8274
+ walk(rootDir, out, ignore);
8275
+ out.sort();
8276
+ return out;
8277
+ }
8278
+ function gitListSourceFiles(rootDir, ignore) {
8279
+ let stdout;
8280
+ try {
8281
+ stdout = execSync3("git ls-files --cached --others --exclude-standard -z", {
8282
+ cwd: rootDir,
8283
+ encoding: "utf8",
8284
+ stdio: ["ignore", "pipe", "ignore"],
8285
+ maxBuffer: 64 * 1024 * 1024
8286
+ });
8287
+ } catch {
8288
+ return null;
8289
+ }
7451
8290
  const out = [];
7452
- walk(rootDir, out);
8291
+ for (const rel of stdout.split("\0")) {
8292
+ if (rel.length === 0)
8293
+ continue;
8294
+ if (!isSourceFile(rel))
8295
+ continue;
8296
+ if (pathHasIgnoredSegment(rel, ignore))
8297
+ continue;
8298
+ out.push(join28(rootDir, rel));
8299
+ }
7453
8300
  out.sort();
7454
8301
  return out;
7455
8302
  }
7456
- function walk(dir, out) {
8303
+ function walk(dir, out, ignore) {
7457
8304
  let entries;
7458
8305
  try {
7459
8306
  entries = readdirSync2(dir, { withFileTypes: true });
@@ -7461,13 +8308,13 @@ function walk(dir, out) {
7461
8308
  return;
7462
8309
  }
7463
8310
  for (const entry of entries) {
7464
- if (DEFAULT_IGNORES.has(entry.name))
8311
+ if (ignore.has(entry.name))
7465
8312
  continue;
7466
8313
  if (entry.name.startsWith("."))
7467
8314
  continue;
7468
- const abs = join27(dir, entry.name);
8315
+ const abs = join28(dir, entry.name);
7469
8316
  if (entry.isDirectory()) {
7470
- walk(abs, out);
8317
+ walk(abs, out, ignore);
7471
8318
  } else if (entry.isFile() && isSourceFile(entry.name)) {
7472
8319
  out.push(abs);
7473
8320
  }
@@ -7476,7 +8323,7 @@ function walk(dir, out) {
7476
8323
  function isSourceFile(name) {
7477
8324
  if (name.endsWith(".d.ts"))
7478
8325
  return false;
7479
- return name.endsWith(".ts") || name.endsWith(".tsx");
8326
+ return /\.(tsx?|jsx?|mjs|cjs|pyi?)$/.test(name);
7480
8327
  }
7481
8328
  function toForwardSlash(p) {
7482
8329
  return sep === "\\" ? p.replace(/\\/g, "/") : p;
@@ -7506,25 +8353,25 @@ function readGitBranch(cwd) {
7506
8353
  }
7507
8354
 
7508
8355
  // dist/src/commands/dashboard.js
7509
- import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync19 } from "node:fs";
7510
- import { homedir as homedir15 } from "node:os";
7511
- import { dirname as dirname12, join as join35, resolve as resolve5 } from "node:path";
8356
+ import { mkdirSync as mkdirSync17, writeFileSync as writeFileSync20 } from "node:fs";
8357
+ import { homedir as homedir16 } from "node:os";
8358
+ import { dirname as dirname12, join as join36, resolve as resolve5 } from "node:path";
7512
8359
 
7513
8360
  // dist/src/dashboard/data.js
7514
- import { existsSync as existsSync25, readFileSync as readFileSync24, readdirSync as readdirSync4, statSync as statSync3 } from "node:fs";
7515
- import { homedir as homedir14 } from "node:os";
7516
- import { join as join33 } from "node:path";
8361
+ import { existsSync as existsSync25, readFileSync as readFileSync25, readdirSync as readdirSync4, statSync as statSync3 } from "node:fs";
8362
+ import { homedir as homedir15 } from "node:os";
8363
+ import { join as join34 } from "node:path";
7517
8364
 
7518
8365
  // dist/src/notifications/sources/org-stats.js
7519
- import { existsSync as existsSync21, mkdirSync as mkdirSync13, readFileSync as readFileSync21, writeFileSync as writeFileSync17 } from "node:fs";
7520
- import { homedir as homedir11 } from "node:os";
7521
- import { dirname as dirname9, join as join28 } from "node:path";
8366
+ import { existsSync as existsSync21, mkdirSync as mkdirSync14, readFileSync as readFileSync22, writeFileSync as writeFileSync18 } from "node:fs";
8367
+ import { homedir as homedir12 } from "node:os";
8368
+ import { dirname as dirname9, join as join29 } from "node:path";
7522
8369
  var log5 = (msg) => log2("notifications-org-stats", msg);
7523
8370
  var FETCH_TIMEOUT_MS = 1500;
7524
8371
  var DEFAULT_API_URL3 = "https://api.deeplake.ai";
7525
8372
  var CACHE_TTL_MS = 60 * 60 * 1e3;
7526
8373
  function cacheFilePath() {
7527
- return join28(homedir11(), ".deeplake", "hivemind-stats-cache.json");
8374
+ return join29(homedir12(), ".deeplake", "hivemind-stats-cache.json");
7528
8375
  }
7529
8376
  var BALANCE_HEADER = "X-Activeloop-Balance-Cents";
7530
8377
  function parseBalanceHeader(resp) {
@@ -7553,7 +8400,7 @@ function readCache2(scopeKey) {
7553
8400
  if (!existsSync21(cacheFilePath()))
7554
8401
  return {};
7555
8402
  try {
7556
- const parsed = JSON.parse(readFileSync21(cacheFilePath(), "utf-8"));
8403
+ const parsed = JSON.parse(readFileSync22(cacheFilePath(), "utf-8"));
7557
8404
  if (!parsed || typeof parsed !== "object")
7558
8405
  return {};
7559
8406
  if (parsed.scopeKey !== scopeKey)
@@ -7574,9 +8421,9 @@ function readCache2(scopeKey) {
7574
8421
  }
7575
8422
  function writeCache2(scopeKey, data) {
7576
8423
  try {
7577
- mkdirSync13(dirname9(cacheFilePath()), { recursive: true });
8424
+ mkdirSync14(dirname9(cacheFilePath()), { recursive: true });
7578
8425
  const body = { fetchedAt: Date.now(), scopeKey, data };
7579
- writeFileSync17(cacheFilePath(), JSON.stringify(body), "utf-8");
8426
+ writeFileSync18(cacheFilePath(), JSON.stringify(body), "utf-8");
7580
8427
  } catch (e) {
7581
8428
  log5(`cache write failed: ${e?.message ?? String(e)}`);
7582
8429
  }
@@ -7628,18 +8475,18 @@ async function fetchOrgStats(creds) {
7628
8475
  }
7629
8476
 
7630
8477
  // dist/src/notifications/usage-tracker.js
7631
- import { appendFileSync as appendFileSync3, existsSync as existsSync22, mkdirSync as mkdirSync14, readFileSync as readFileSync22, readdirSync as readdirSync3 } from "node:fs";
7632
- import { dirname as dirname10, join as join29 } from "node:path";
7633
- import { homedir as homedir12 } from "node:os";
8478
+ import { appendFileSync as appendFileSync3, existsSync as existsSync22, mkdirSync as mkdirSync15, readFileSync as readFileSync23, readdirSync as readdirSync3 } from "node:fs";
8479
+ import { dirname as dirname10, join as join30 } from "node:path";
8480
+ import { homedir as homedir13 } from "node:os";
7634
8481
  var log6 = (msg) => log2("usage-tracker", msg);
7635
8482
  function statsFilePath() {
7636
- return join29(homedir12(), ".deeplake", "usage-stats.jsonl");
8483
+ return join30(homedir13(), ".deeplake", "usage-stats.jsonl");
7637
8484
  }
7638
8485
  function readUsageRecords() {
7639
8486
  try {
7640
8487
  if (!existsSync22(statsFilePath()))
7641
8488
  return [];
7642
- const raw = readFileSync22(statsFilePath(), "utf-8");
8489
+ const raw = readFileSync23(statsFilePath(), "utf-8");
7643
8490
  const out = [];
7644
8491
  for (const line of raw.split("\n")) {
7645
8492
  const trimmed = line.trim();
@@ -7676,7 +8523,7 @@ function sumMetric(records, key) {
7676
8523
  function countUserGeneratedSkills(userName) {
7677
8524
  if (!userName)
7678
8525
  return 0;
7679
- const dir = join29(homedir12(), ".claude", "skills");
8526
+ const dir = join30(homedir13(), ".claude", "skills");
7680
8527
  if (!existsSync22(dir))
7681
8528
  return 0;
7682
8529
  const suffix = `--${userName}`;
@@ -7695,19 +8542,19 @@ function countUserGeneratedSkills(userName) {
7695
8542
  }
7696
8543
 
7697
8544
  // dist/src/skillify/state.js
7698
- import { readFileSync as readFileSync23, writeFileSync as writeFileSync18, writeSync, mkdirSync as mkdirSync15, renameSync as renameSync9, rmdirSync, existsSync as existsSync24, lstatSync as lstatSync3, unlinkSync as unlinkSync9, openSync as openSync2, closeSync as closeSync2 } from "node:fs";
7699
- import { join as join32 } from "node:path";
8545
+ import { readFileSync as readFileSync24, writeFileSync as writeFileSync19, writeSync, mkdirSync as mkdirSync16, renameSync as renameSync9, rmdirSync, existsSync as existsSync24, lstatSync as lstatSync3, unlinkSync as unlinkSync9, openSync as openSync2, closeSync as closeSync2 } from "node:fs";
8546
+ import { join as join33 } from "node:path";
7700
8547
 
7701
8548
  // dist/src/skillify/legacy-migration.js
7702
8549
  import { existsSync as existsSync23, renameSync as renameSync8 } from "node:fs";
7703
- import { dirname as dirname11, join as join31 } from "node:path";
8550
+ import { dirname as dirname11, join as join32 } from "node:path";
7704
8551
 
7705
8552
  // dist/src/skillify/state-dir.js
7706
- import { homedir as homedir13 } from "node:os";
7707
- import { join as join30 } from "node:path";
8553
+ import { homedir as homedir14 } from "node:os";
8554
+ import { join as join31 } from "node:path";
7708
8555
  function getStateDir() {
7709
8556
  const override = process.env.HIVEMIND_STATE_DIR?.trim();
7710
- return override && override.length > 0 ? override : join30(homedir13(), ".deeplake", "state", "skillify");
8557
+ return override && override.length > 0 ? override : join31(homedir14(), ".deeplake", "state", "skillify");
7711
8558
  }
7712
8559
 
7713
8560
  // dist/src/skillify/legacy-migration.js
@@ -7720,7 +8567,7 @@ function migrateLegacyStateDir() {
7720
8567
  return;
7721
8568
  attempted = true;
7722
8569
  const current = getStateDir();
7723
- const legacy = join31(dirname11(current), "skilify");
8570
+ const legacy = join32(dirname11(current), "skilify");
7724
8571
  if (!existsSync23(legacy))
7725
8572
  return;
7726
8573
  if (existsSync23(current))
@@ -7750,7 +8597,7 @@ var log7 = (msg) => log2("dashboard-data", msg);
7750
8597
  var BYTES_PER_TOKEN = 4;
7751
8598
  var SAVINGS_MULTIPLIER = 1.7;
7752
8599
  function graphsRoot2() {
7753
- return process.env.HIVEMIND_GRAPHS_HOME ?? join33(homedir14(), ".hivemind", "graphs");
8600
+ return process.env.HIVEMIND_GRAPHS_HOME ?? join34(homedir15(), ".hivemind", "graphs");
7754
8601
  }
7755
8602
  function bytesToSavedTokens(bytes) {
7756
8603
  if (!Number.isFinite(bytes) || bytes <= 0)
@@ -7759,16 +8606,16 @@ function bytesToSavedTokens(bytes) {
7759
8606
  return (SAVINGS_MULTIPLIER - 1) * delivered;
7760
8607
  }
7761
8608
  function resolveSnapshot(repoDir2) {
7762
- const snapshotsDir = join33(repoDir2, "snapshots");
8609
+ const snapshotsDir = join34(repoDir2, "snapshots");
7763
8610
  if (!existsSync25(snapshotsDir))
7764
8611
  return null;
7765
8612
  let snapshotPath = null;
7766
- const pointer = join33(repoDir2, "latest-commit.txt");
8613
+ const pointer = join34(repoDir2, "latest-commit.txt");
7767
8614
  if (existsSync25(pointer)) {
7768
8615
  try {
7769
- const sha = readFileSync24(pointer, "utf-8").trim();
8616
+ const sha = readFileSync25(pointer, "utf-8").trim();
7770
8617
  if (sha) {
7771
- const candidate = join33(snapshotsDir, `${sha}.json`);
8618
+ const candidate = join34(snapshotsDir, `${sha}.json`);
7772
8619
  if (existsSync25(candidate))
7773
8620
  snapshotPath = candidate;
7774
8621
  else
@@ -7781,7 +8628,7 @@ function resolveSnapshot(repoDir2) {
7781
8628
  if (!snapshotPath) {
7782
8629
  try {
7783
8630
  const candidates = readdirSync4(snapshotsDir).filter((name) => name.endsWith(".json")).map((name) => {
7784
- const full = join33(snapshotsDir, name);
8631
+ const full = join34(snapshotsDir, name);
7785
8632
  return { full, mtime: statSync3(full).mtimeMs };
7786
8633
  }).sort((a, b) => b.mtime - a.mtime);
7787
8634
  if (candidates.length > 0)
@@ -7794,7 +8641,7 @@ function resolveSnapshot(repoDir2) {
7794
8641
  return null;
7795
8642
  let raw;
7796
8643
  try {
7797
- raw = readFileSync24(snapshotPath, "utf-8");
8644
+ raw = readFileSync25(snapshotPath, "utf-8");
7798
8645
  } catch (e) {
7799
8646
  log7(`snapshot read failed: ${e?.message ?? String(e)}`);
7800
8647
  return null;
@@ -7864,7 +8711,7 @@ async function loadKpis(creds) {
7864
8711
  async function loadDashboardData(opts = {}) {
7865
8712
  const cwd = opts.cwd ?? process.cwd();
7866
8713
  const { key: repoKey, project: repoProject } = deriveProjectKey(cwd);
7867
- const repoDir2 = join33(opts.graphsHome ?? graphsRoot2(), repoKey);
8714
+ const repoDir2 = join34(opts.graphsHome ?? graphsRoot2(), repoKey);
7868
8715
  const graph = resolveSnapshot(repoDir2);
7869
8716
  const creds = opts.creds === void 0 ? loadCredentials() : opts.creds;
7870
8717
  const kpis = await loadKpis(creds);
@@ -7881,7 +8728,7 @@ async function loadDashboardData(opts = {}) {
7881
8728
  import { spawn } from "node:child_process";
7882
8729
  import { accessSync, constants as fsConstants, statSync as statSync4 } from "node:fs";
7883
8730
  import { platform as nodePlatform } from "node:os";
7884
- import { delimiter, join as join34 } from "node:path";
8731
+ import { delimiter, join as join35 } from "node:path";
7885
8732
  function resolveOpenPlatform() {
7886
8733
  const p = nodePlatform();
7887
8734
  if (p === "linux" || p === "darwin" || p === "win32")
@@ -7908,7 +8755,7 @@ function findBinaryOnPath(name) {
7908
8755
  if (!dir)
7909
8756
  continue;
7910
8757
  for (const ext of exts) {
7911
- const candidate = join34(dir, name + ext);
8758
+ const candidate = join35(dir, name + ext);
7912
8759
  try {
7913
8760
  const st = statSync4(candidate);
7914
8761
  if (!st.isFile())
@@ -8000,8 +8847,8 @@ function transformSnapshotToVis(snapshot) {
8000
8847
  if (kind)
8001
8848
  titleParts.push(kind);
8002
8849
  if (sourceFile) {
8003
- const loc = sourceLoc ? `${sourceFile}:${sourceLoc}` : sourceFile;
8004
- titleParts.push(loc);
8850
+ const loc2 = sourceLoc ? `${sourceFile}:${sourceLoc}` : sourceFile;
8851
+ titleParts.push(loc2);
8005
8852
  }
8006
8853
  const color = kind && KIND_COLORS[kind] ? KIND_COLORS[kind] : DEFAULT_NODE_COLOR;
8007
8854
  visNodes.push({
@@ -8418,7 +9265,7 @@ function parseDashboardArgs(args) {
8418
9265
  };
8419
9266
  }
8420
9267
  function defaultDashboardOutPath(repoKey) {
8421
- return join35(homedir15(), ".hivemind", "dashboards", repoKey, "index.html");
9268
+ return join36(homedir16(), ".hivemind", "dashboards", repoKey, "index.html");
8422
9269
  }
8423
9270
  async function runDashboardCommand(rawArgs, runOpts = {}) {
8424
9271
  const out = runOpts.out ?? ((s) => {
@@ -8452,8 +9299,8 @@ async function runDashboardCommand(rawArgs, runOpts = {}) {
8452
9299
  const finalOut = outPath || defaultDashboardOutPath(data.repoKey);
8453
9300
  const absOut = resolve5(finalOut);
8454
9301
  try {
8455
- mkdirSync16(dirname12(absOut), { recursive: true });
8456
- writeFileSync19(absOut, html, "utf-8");
9302
+ mkdirSync17(dirname12(absOut), { recursive: true });
9303
+ writeFileSync20(absOut, html, "utf-8");
8457
9304
  } catch (e) {
8458
9305
  err(`hivemind dashboard: failed to write ${absOut}: ${e?.message ?? String(e)}
8459
9306
  `);
@@ -8532,15 +9379,15 @@ function defaultOnSignal(signal, handler) {
8532
9379
  }
8533
9380
 
8534
9381
  // dist/src/commands/skillify.js
8535
- import { readdirSync as readdirSync8, existsSync as existsSync36, readFileSync as readFileSync32, mkdirSync as mkdirSync23, renameSync as renameSync12 } from "node:fs";
8536
- import { homedir as homedir24 } from "node:os";
8537
- import { dirname as dirname17, join as join46 } from "node:path";
9382
+ import { readdirSync as readdirSync8, existsSync as existsSync36, readFileSync as readFileSync33, mkdirSync as mkdirSync24, renameSync as renameSync12 } from "node:fs";
9383
+ import { homedir as homedir25 } from "node:os";
9384
+ import { dirname as dirname17, join as join47 } from "node:path";
8538
9385
 
8539
9386
  // dist/src/skillify/scope-config.js
8540
- import { existsSync as existsSync26, mkdirSync as mkdirSync17, readFileSync as readFileSync25, writeFileSync as writeFileSync20 } from "node:fs";
8541
- import { join as join36 } from "node:path";
9387
+ import { existsSync as existsSync26, mkdirSync as mkdirSync18, readFileSync as readFileSync26, writeFileSync as writeFileSync21 } from "node:fs";
9388
+ import { join as join37 } from "node:path";
8542
9389
  function configPath() {
8543
- return join36(getStateDir(), "config.json");
9390
+ return join37(getStateDir(), "config.json");
8544
9391
  }
8545
9392
  var DEFAULT = { scope: "me", team: [], install: "project" };
8546
9393
  function loadScopeConfig() {
@@ -8549,7 +9396,7 @@ function loadScopeConfig() {
8549
9396
  if (!existsSync26(CONFIG_PATH2))
8550
9397
  return DEFAULT;
8551
9398
  try {
8552
- const raw = JSON.parse(readFileSync25(CONFIG_PATH2, "utf-8"));
9399
+ const raw = JSON.parse(readFileSync26(CONFIG_PATH2, "utf-8"));
8553
9400
  const scope = raw.scope === "team" ? "team" : raw.scope === "org" ? "team" : "me";
8554
9401
  const team = Array.isArray(raw.team) ? raw.team.filter((s) => typeof s === "string") : [];
8555
9402
  const install = raw.install === "global" ? "global" : "project";
@@ -8560,19 +9407,19 @@ function loadScopeConfig() {
8560
9407
  }
8561
9408
  function saveScopeConfig(cfg) {
8562
9409
  migrateLegacyStateDir();
8563
- mkdirSync17(getStateDir(), { recursive: true });
8564
- writeFileSync20(configPath(), JSON.stringify(cfg, null, 2));
9410
+ mkdirSync18(getStateDir(), { recursive: true });
9411
+ writeFileSync21(configPath(), JSON.stringify(cfg, null, 2));
8565
9412
  }
8566
9413
 
8567
9414
  // dist/src/skillify/pull.js
8568
- import { existsSync as existsSync30, readFileSync as readFileSync28, writeFileSync as writeFileSync23, mkdirSync as mkdirSync20, renameSync as renameSync11, lstatSync as lstatSync5, readlinkSync as readlinkSync2, symlinkSync as symlinkSync2, unlinkSync as unlinkSync11 } from "node:fs";
8569
- import { homedir as homedir18 } from "node:os";
8570
- import { dirname as dirname14, join as join40 } from "node:path";
9415
+ import { existsSync as existsSync30, readFileSync as readFileSync29, writeFileSync as writeFileSync24, mkdirSync as mkdirSync21, renameSync as renameSync11, lstatSync as lstatSync5, readlinkSync as readlinkSync2, symlinkSync as symlinkSync2, unlinkSync as unlinkSync11 } from "node:fs";
9416
+ import { homedir as homedir19 } from "node:os";
9417
+ import { dirname as dirname14, join as join41 } from "node:path";
8571
9418
 
8572
9419
  // dist/src/skillify/skill-writer.js
8573
- import { existsSync as existsSync27, mkdirSync as mkdirSync18, readFileSync as readFileSync26, readdirSync as readdirSync5, statSync as statSync5, writeFileSync as writeFileSync21 } from "node:fs";
8574
- import { homedir as homedir16 } from "node:os";
8575
- import { join as join37 } from "node:path";
9420
+ import { existsSync as existsSync27, mkdirSync as mkdirSync19, readFileSync as readFileSync27, readdirSync as readdirSync5, statSync as statSync5, writeFileSync as writeFileSync22 } from "node:fs";
9421
+ import { homedir as homedir17 } from "node:os";
9422
+ import { join as join38 } from "node:path";
8576
9423
  function assertValidSkillName(name) {
8577
9424
  if (typeof name !== "string" || name.length === 0) {
8578
9425
  throw new Error(`invalid skill name: empty or non-string`);
@@ -8588,10 +9435,10 @@ function assertValidSkillName(name) {
8588
9435
  }
8589
9436
  }
8590
9437
  function skillDir(skillsRoot, name) {
8591
- return join37(skillsRoot, name);
9438
+ return join38(skillsRoot, name);
8592
9439
  }
8593
9440
  function skillPath(skillsRoot, name) {
8594
- return join37(skillDir(skillsRoot, name), "SKILL.md");
9441
+ return join38(skillDir(skillsRoot, name), "SKILL.md");
8595
9442
  }
8596
9443
  function renderFrontmatter(fm) {
8597
9444
  const lines = ["---"];
@@ -8672,7 +9519,7 @@ function writeNewSkill(args) {
8672
9519
  if (existsSync27(path)) {
8673
9520
  throw new Error(`skill already exists at ${path}; use mergeSkill`);
8674
9521
  }
8675
- mkdirSync18(dir, { recursive: true });
9522
+ mkdirSync19(dir, { recursive: true });
8676
9523
  const now = (/* @__PURE__ */ new Date()).toISOString();
8677
9524
  const author = args.author && args.author.length > 0 ? args.author : void 0;
8678
9525
  const contributors = author ? [author] : [];
@@ -8692,7 +9539,7 @@ function writeNewSkill(args) {
8692
9539
 
8693
9540
  ${args.body.trim()}
8694
9541
  `;
8695
- writeFileSync21(path, text);
9542
+ writeFileSync22(path, text);
8696
9543
  return {
8697
9544
  path,
8698
9545
  action: "created",
@@ -8708,28 +9555,28 @@ function listSkills(skillsRoot) {
8708
9555
  return [];
8709
9556
  const out = [];
8710
9557
  for (const name of readdirSync5(skillsRoot)) {
8711
- const skillFile = join37(skillsRoot, name, "SKILL.md");
9558
+ const skillFile = join38(skillsRoot, name, "SKILL.md");
8712
9559
  if (existsSync27(skillFile) && statSync5(skillFile).isFile()) {
8713
- out.push({ name, body: readFileSync26(skillFile, "utf-8") });
9560
+ out.push({ name, body: readFileSync27(skillFile, "utf-8") });
8714
9561
  }
8715
9562
  }
8716
9563
  return out;
8717
9564
  }
8718
9565
  function resolveSkillsRoot(install, cwd) {
8719
9566
  if (install === "global") {
8720
- return join37(homedir16(), ".claude", "skills");
9567
+ return join38(homedir17(), ".claude", "skills");
8721
9568
  }
8722
- return join37(cwd, ".claude", "skills");
9569
+ return join38(cwd, ".claude", "skills");
8723
9570
  }
8724
9571
 
8725
9572
  // dist/src/skillify/manifest.js
8726
- import { existsSync as existsSync28, lstatSync as lstatSync4, mkdirSync as mkdirSync19, readFileSync as readFileSync27, renameSync as renameSync10, unlinkSync as unlinkSync10, writeFileSync as writeFileSync22 } from "node:fs";
8727
- import { dirname as dirname13, join as join38 } from "node:path";
9573
+ import { existsSync as existsSync28, lstatSync as lstatSync4, mkdirSync as mkdirSync20, readFileSync as readFileSync28, renameSync as renameSync10, unlinkSync as unlinkSync10, writeFileSync as writeFileSync23 } from "node:fs";
9574
+ import { dirname as dirname13, join as join39 } from "node:path";
8728
9575
  function emptyManifest() {
8729
9576
  return { version: 1, entries: [] };
8730
9577
  }
8731
9578
  function manifestPath() {
8732
- return join38(getStateDir(), "pulled.json");
9579
+ return join39(getStateDir(), "pulled.json");
8733
9580
  }
8734
9581
  function loadManifest(path = manifestPath()) {
8735
9582
  migrateLegacyStateDir();
@@ -8737,7 +9584,7 @@ function loadManifest(path = manifestPath()) {
8737
9584
  return emptyManifest();
8738
9585
  let raw;
8739
9586
  try {
8740
- raw = readFileSync27(path, "utf-8");
9587
+ raw = readFileSync28(path, "utf-8");
8741
9588
  } catch {
8742
9589
  return emptyManifest();
8743
9590
  }
@@ -8784,9 +9631,9 @@ function loadManifest(path = manifestPath()) {
8784
9631
  }
8785
9632
  function saveManifest(m, path = manifestPath()) {
8786
9633
  migrateLegacyStateDir();
8787
- mkdirSync19(dirname13(path), { recursive: true });
9634
+ mkdirSync20(dirname13(path), { recursive: true });
8788
9635
  const tmp = `${path}.tmp`;
8789
- writeFileSync22(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
9636
+ writeFileSync23(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
8790
9637
  renameSync10(tmp, path);
8791
9638
  }
8792
9639
  function recordPull(entry, path = manifestPath()) {
@@ -8829,7 +9676,7 @@ function pruneOrphanedEntries(path = manifestPath()) {
8829
9676
  const live = [];
8830
9677
  let pruned = 0;
8831
9678
  for (const e of m.entries) {
8832
- if (existsSync28(join38(e.installRoot, e.dirName))) {
9679
+ if (existsSync28(join39(e.installRoot, e.dirName))) {
8833
9680
  live.push(e);
8834
9681
  continue;
8835
9682
  }
@@ -8843,25 +9690,25 @@ function pruneOrphanedEntries(path = manifestPath()) {
8843
9690
 
8844
9691
  // dist/src/skillify/agent-roots.js
8845
9692
  import { existsSync as existsSync29 } from "node:fs";
8846
- import { homedir as homedir17 } from "node:os";
8847
- import { join as join39 } from "node:path";
9693
+ import { homedir as homedir18 } from "node:os";
9694
+ import { join as join40 } from "node:path";
8848
9695
  function resolveDetected(home) {
8849
9696
  const out = [];
8850
- const codexInstalled = existsSync29(join39(home, ".codex"));
8851
- const piInstalled = existsSync29(join39(home, ".pi", "agent"));
8852
- const hermesInstalled = existsSync29(join39(home, ".hermes"));
9697
+ const codexInstalled = existsSync29(join40(home, ".codex"));
9698
+ const piInstalled = existsSync29(join40(home, ".pi", "agent"));
9699
+ const hermesInstalled = existsSync29(join40(home, ".hermes"));
8853
9700
  if (codexInstalled || piInstalled) {
8854
- out.push(join39(home, ".agents", "skills"));
9701
+ out.push(join40(home, ".agents", "skills"));
8855
9702
  }
8856
9703
  if (hermesInstalled) {
8857
- out.push(join39(home, ".hermes", "skills"));
9704
+ out.push(join40(home, ".hermes", "skills"));
8858
9705
  }
8859
9706
  if (piInstalled) {
8860
- out.push(join39(home, ".pi", "agent", "skills"));
9707
+ out.push(join40(home, ".pi", "agent", "skills"));
8861
9708
  }
8862
9709
  return out;
8863
9710
  }
8864
- function detectAgentSkillsRoots(canonicalRoot, home = homedir17()) {
9711
+ function detectAgentSkillsRoots(canonicalRoot, home = homedir18()) {
8865
9712
  return resolveDetected(home).filter((p) => p !== canonicalRoot);
8866
9713
  }
8867
9714
 
@@ -8905,15 +9752,15 @@ function isMissingTableError2(message) {
8905
9752
  }
8906
9753
  function resolvePullDestination(install, cwd) {
8907
9754
  if (install === "global")
8908
- return join40(homedir18(), ".claude", "skills");
9755
+ return join41(homedir19(), ".claude", "skills");
8909
9756
  if (!cwd)
8910
9757
  throw new Error("install=project requires a cwd");
8911
- return join40(cwd, ".claude", "skills");
9758
+ return join41(cwd, ".claude", "skills");
8912
9759
  }
8913
9760
  function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
8914
9761
  const out = [];
8915
9762
  for (const root of agentRoots) {
8916
- const link = join40(root, dirName);
9763
+ const link = join41(root, dirName);
8917
9764
  let existing;
8918
9765
  try {
8919
9766
  existing = lstatSync5(link);
@@ -8941,7 +9788,7 @@ function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
8941
9788
  }
8942
9789
  }
8943
9790
  try {
8944
- mkdirSync20(dirname14(link), { recursive: true });
9791
+ mkdirSync21(dirname14(link), { recursive: true });
8945
9792
  symlinkSync2(canonicalDir, link, "dir");
8946
9793
  out.push(link);
8947
9794
  } catch {
@@ -8956,7 +9803,7 @@ function backfillSymlinks(installRoot) {
8956
9803
  return;
8957
9804
  const detected = detectAgentSkillsRoots(installRoot);
8958
9805
  for (const entry of entries) {
8959
- const canonical = join40(entry.installRoot, entry.dirName);
9806
+ const canonical = join41(entry.installRoot, entry.dirName);
8960
9807
  if (!existsSync30(canonical))
8961
9808
  continue;
8962
9809
  const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
@@ -9070,7 +9917,7 @@ function readLocalVersion(path) {
9070
9917
  if (!existsSync30(path))
9071
9918
  return null;
9072
9919
  try {
9073
- const text = readFileSync28(path, "utf-8");
9920
+ const text = readFileSync29(path, "utf-8");
9074
9921
  const parsed = parseFrontmatter(text);
9075
9922
  if (!parsed)
9076
9923
  return null;
@@ -9169,8 +10016,8 @@ async function runPull(opts) {
9169
10016
  summary.skipped++;
9170
10017
  continue;
9171
10018
  }
9172
- const skillDir2 = join40(root, dirName);
9173
- const skillFile = join40(skillDir2, "SKILL.md");
10019
+ const skillDir2 = join41(root, dirName);
10020
+ const skillFile = join41(skillDir2, "SKILL.md");
9174
10021
  const remoteVersion = Number(row.version ?? 1);
9175
10022
  const localVersion = readLocalVersion(skillFile);
9176
10023
  const action = decideAction({
@@ -9181,14 +10028,14 @@ async function runPull(opts) {
9181
10028
  });
9182
10029
  let manifestError;
9183
10030
  if (action === "wrote") {
9184
- mkdirSync20(skillDir2, { recursive: true });
10031
+ mkdirSync21(skillDir2, { recursive: true });
9185
10032
  if (existsSync30(skillFile)) {
9186
10033
  try {
9187
10034
  renameSync11(skillFile, `${skillFile}.bak`);
9188
10035
  } catch {
9189
10036
  }
9190
10037
  }
9191
- writeFileSync23(skillFile, renderSkillFile(row));
10038
+ writeFileSync24(skillFile, renderSkillFile(row));
9192
10039
  const symlinks = opts.install === "global" ? fanOutSymlinks(skillDir2, dirName, detectAgentSkillsRoots(root)) : [];
9193
10040
  try {
9194
10041
  recordPull({
@@ -9231,14 +10078,14 @@ async function runPull(opts) {
9231
10078
 
9232
10079
  // dist/src/skillify/unpull.js
9233
10080
  import { existsSync as existsSync31, readdirSync as readdirSync6, rmSync as rmSync5, statSync as statSync6 } from "node:fs";
9234
- import { homedir as homedir19 } from "node:os";
9235
- import { join as join41 } from "node:path";
10081
+ import { homedir as homedir20 } from "node:os";
10082
+ import { join as join42 } from "node:path";
9236
10083
  function resolveUnpullRoot(install, cwd) {
9237
10084
  if (install === "global")
9238
- return join41(homedir19(), ".claude", "skills");
10085
+ return join42(homedir20(), ".claude", "skills");
9239
10086
  if (!cwd)
9240
10087
  throw new Error("cwd required when install === 'project'");
9241
- return join41(cwd, ".claude", "skills");
10088
+ return join42(cwd, ".claude", "skills");
9242
10089
  }
9243
10090
  function runUnpull(opts) {
9244
10091
  const root = resolveUnpullRoot(opts.install, opts.cwd);
@@ -9261,7 +10108,7 @@ function runUnpull(opts) {
9261
10108
  const entries = entriesForRoot(manifest, opts.install, root);
9262
10109
  for (const entry of entries) {
9263
10110
  summary.scanned++;
9264
- const path = join41(root, entry.dirName);
10111
+ const path = join42(root, entry.dirName);
9265
10112
  if (!existsSync31(path)) {
9266
10113
  if (!opts.dryRun) {
9267
10114
  unlinkSymlinks(entry.symlinks);
@@ -9320,7 +10167,7 @@ function runUnpull(opts) {
9320
10167
  for (const dirName of readdirSync6(root)) {
9321
10168
  if (manifestDirNames.has(dirName))
9322
10169
  continue;
9323
- const path = join41(root, dirName);
10170
+ const path = join42(root, dirName);
9324
10171
  let st;
9325
10172
  try {
9326
10173
  st = statSync6(path);
@@ -9399,21 +10246,21 @@ function decideTargetForManifestEntry(entry, opts, userFilter, haveUserFilter) {
9399
10246
 
9400
10247
  // dist/src/commands/mine-local.js
9401
10248
  import { spawn as spawn2 } from "node:child_process";
9402
- import { existsSync as existsSync35, mkdirSync as mkdirSync22, readFileSync as readFileSync31, writeFileSync as writeFileSync25 } from "node:fs";
9403
- import { homedir as homedir23 } from "node:os";
9404
- import { basename as basename2, dirname as dirname16, join as join45 } from "node:path";
10249
+ import { existsSync as existsSync35, mkdirSync as mkdirSync23, readFileSync as readFileSync32, writeFileSync as writeFileSync26 } from "node:fs";
10250
+ import { homedir as homedir24 } from "node:os";
10251
+ import { basename as basename2, dirname as dirname16, join as join46 } from "node:path";
9405
10252
 
9406
10253
  // dist/src/skillify/local-source.js
9407
- import { readdirSync as readdirSync7, readFileSync as readFileSync29, existsSync as existsSync32, statSync as statSync7 } from "node:fs";
9408
- import { homedir as homedir20 } from "node:os";
9409
- import { join as join42 } from "node:path";
9410
- var HOME2 = homedir20();
10254
+ import { readdirSync as readdirSync7, readFileSync as readFileSync30, existsSync as existsSync32, statSync as statSync7 } from "node:fs";
10255
+ import { homedir as homedir21 } from "node:os";
10256
+ import { join as join43 } from "node:path";
10257
+ var HOME2 = homedir21();
9411
10258
  function encodeCwdClaudeCode(cwd) {
9412
10259
  return cwd.replace(/[/_]/g, "-");
9413
10260
  }
9414
10261
  function detectInstalledAgents() {
9415
10262
  const installs = [];
9416
- const claudeRoot = join42(HOME2, ".claude", "projects");
10263
+ const claudeRoot = join43(HOME2, ".claude", "projects");
9417
10264
  if (existsSync32(claudeRoot)) {
9418
10265
  installs.push({
9419
10266
  agent: "claude_code",
@@ -9421,7 +10268,7 @@ function detectInstalledAgents() {
9421
10268
  encodeCwd: encodeCwdClaudeCode
9422
10269
  });
9423
10270
  }
9424
- const codexRoot = join42(HOME2, ".codex", "sessions");
10271
+ const codexRoot = join43(HOME2, ".codex", "sessions");
9425
10272
  if (existsSync32(codexRoot)) {
9426
10273
  installs.push({
9427
10274
  agent: "codex",
@@ -9449,7 +10296,7 @@ function listLocalSessions(installs, cwd) {
9449
10296
  continue;
9450
10297
  }
9451
10298
  for (const sub of subdirs) {
9452
- const subdirPath = join42(install.sessionRoot, sub);
10299
+ const subdirPath = join43(install.sessionRoot, sub);
9453
10300
  try {
9454
10301
  if (!statSync7(subdirPath).isDirectory())
9455
10302
  continue;
@@ -9466,7 +10313,7 @@ function listLocalSessions(installs, cwd) {
9466
10313
  for (const f of files) {
9467
10314
  if (!f.endsWith(".jsonl"))
9468
10315
  continue;
9469
- const fullPath = join42(subdirPath, f);
10316
+ const fullPath = join43(subdirPath, f);
9470
10317
  let stats;
9471
10318
  try {
9472
10319
  stats = statSync7(fullPath);
@@ -9527,7 +10374,7 @@ function pickSessions(candidates, opts) {
9527
10374
  function nativeJsonlToRows(filePath, sessionId, agent) {
9528
10375
  let raw;
9529
10376
  try {
9530
- raw = readFileSync29(filePath, "utf-8");
10377
+ raw = readFileSync30(filePath, "utf-8");
9531
10378
  } catch {
9532
10379
  return [];
9533
10380
  }
@@ -9619,8 +10466,8 @@ function extractPairs(rows) {
9619
10466
  // dist/src/skillify/gate-runner.js
9620
10467
  import { existsSync as existsSync33 } from "node:fs";
9621
10468
  import { createRequire } from "node:module";
9622
- import { homedir as homedir21 } from "node:os";
9623
- import { join as join43 } from "node:path";
10469
+ import { homedir as homedir22 } from "node:os";
10470
+ import { join as join44 } from "node:path";
9624
10471
  var requireForCp = createRequire(import.meta.url);
9625
10472
  var { execFileSync: runChildProcess } = requireForCp("node:child_process");
9626
10473
  var inheritedEnv = process;
@@ -9632,7 +10479,7 @@ function firstExistingPath(candidates) {
9632
10479
  return null;
9633
10480
  }
9634
10481
  function findAgentBin(agent) {
9635
- const home = homedir21();
10482
+ const home = homedir22();
9636
10483
  switch (agent) {
9637
10484
  // /usr/bin/<name> is included in every candidate list — that's the
9638
10485
  // common Linux package-manager install path (apt, dnf, pacman). Old
@@ -9641,45 +10488,45 @@ function findAgentBin(agent) {
9641
10488
  // #170 caught the gap.
9642
10489
  case "claude_code":
9643
10490
  return firstExistingPath([
9644
- join43(home, ".claude", "local", "claude"),
10491
+ join44(home, ".claude", "local", "claude"),
9645
10492
  "/usr/local/bin/claude",
9646
10493
  "/usr/bin/claude",
9647
- join43(home, ".npm-global", "bin", "claude"),
9648
- join43(home, ".local", "bin", "claude"),
10494
+ join44(home, ".npm-global", "bin", "claude"),
10495
+ join44(home, ".local", "bin", "claude"),
9649
10496
  "/opt/homebrew/bin/claude"
9650
- ]) ?? join43(home, ".claude", "local", "claude");
10497
+ ]) ?? join44(home, ".claude", "local", "claude");
9651
10498
  case "codex":
9652
10499
  return firstExistingPath([
9653
10500
  "/usr/local/bin/codex",
9654
10501
  "/usr/bin/codex",
9655
- join43(home, ".npm-global", "bin", "codex"),
9656
- join43(home, ".local", "bin", "codex"),
10502
+ join44(home, ".npm-global", "bin", "codex"),
10503
+ join44(home, ".local", "bin", "codex"),
9657
10504
  "/opt/homebrew/bin/codex"
9658
10505
  ]) ?? "/usr/local/bin/codex";
9659
10506
  case "cursor":
9660
10507
  return firstExistingPath([
9661
10508
  "/usr/local/bin/cursor-agent",
9662
10509
  "/usr/bin/cursor-agent",
9663
- join43(home, ".npm-global", "bin", "cursor-agent"),
9664
- join43(home, ".local", "bin", "cursor-agent"),
10510
+ join44(home, ".npm-global", "bin", "cursor-agent"),
10511
+ join44(home, ".local", "bin", "cursor-agent"),
9665
10512
  "/opt/homebrew/bin/cursor-agent"
9666
10513
  ]) ?? "/usr/local/bin/cursor-agent";
9667
10514
  case "hermes":
9668
10515
  return firstExistingPath([
9669
- join43(home, ".local", "bin", "hermes"),
10516
+ join44(home, ".local", "bin", "hermes"),
9670
10517
  "/usr/local/bin/hermes",
9671
10518
  "/usr/bin/hermes",
9672
- join43(home, ".npm-global", "bin", "hermes"),
10519
+ join44(home, ".npm-global", "bin", "hermes"),
9673
10520
  "/opt/homebrew/bin/hermes"
9674
- ]) ?? join43(home, ".local", "bin", "hermes");
10521
+ ]) ?? join44(home, ".local", "bin", "hermes");
9675
10522
  case "pi":
9676
10523
  return firstExistingPath([
9677
- join43(home, ".local", "bin", "pi"),
10524
+ join44(home, ".local", "bin", "pi"),
9678
10525
  "/usr/local/bin/pi",
9679
10526
  "/usr/bin/pi",
9680
- join43(home, ".npm-global", "bin", "pi"),
10527
+ join44(home, ".npm-global", "bin", "pi"),
9681
10528
  "/opt/homebrew/bin/pi"
9682
- ]) ?? join43(home, ".local", "bin", "pi");
10529
+ ]) ?? join44(home, ".local", "bin", "pi");
9683
10530
  }
9684
10531
  }
9685
10532
 
@@ -9709,23 +10556,23 @@ function extractJsonBlock(s) {
9709
10556
  }
9710
10557
 
9711
10558
  // dist/src/skillify/local-manifest.js
9712
- import { existsSync as existsSync34, mkdirSync as mkdirSync21, readFileSync as readFileSync30, writeFileSync as writeFileSync24 } from "node:fs";
9713
- import { homedir as homedir22 } from "node:os";
9714
- import { dirname as dirname15, join as join44 } from "node:path";
9715
- var LOCAL_MANIFEST_PATH = join44(homedir22(), ".claude", "hivemind", "local-mined.json");
9716
- var LOCAL_MINE_LOCK_PATH = join44(homedir22(), ".claude", "hivemind", "local-mined.lock");
10559
+ import { existsSync as existsSync34, mkdirSync as mkdirSync22, readFileSync as readFileSync31, writeFileSync as writeFileSync25 } from "node:fs";
10560
+ import { homedir as homedir23 } from "node:os";
10561
+ import { dirname as dirname15, join as join45 } from "node:path";
10562
+ var LOCAL_MANIFEST_PATH = join45(homedir23(), ".claude", "hivemind", "local-mined.json");
10563
+ var LOCAL_MINE_LOCK_PATH = join45(homedir23(), ".claude", "hivemind", "local-mined.lock");
9717
10564
  function readLocalManifest(path = LOCAL_MANIFEST_PATH) {
9718
10565
  if (!existsSync34(path))
9719
10566
  return null;
9720
10567
  try {
9721
- return JSON.parse(readFileSync30(path, "utf-8"));
10568
+ return JSON.parse(readFileSync31(path, "utf-8"));
9722
10569
  } catch {
9723
10570
  return null;
9724
10571
  }
9725
10572
  }
9726
10573
  function writeLocalManifest(m, path = LOCAL_MANIFEST_PATH) {
9727
- mkdirSync21(dirname15(path), { recursive: true });
9728
- writeFileSync24(path, JSON.stringify(m, null, 2));
10574
+ mkdirSync22(dirname15(path), { recursive: true });
10575
+ writeFileSync25(path, JSON.stringify(m, null, 2));
9729
10576
  }
9730
10577
  function countLocalManifestEntries(path = LOCAL_MANIFEST_PATH) {
9731
10578
  const m = readLocalManifest(path);
@@ -10159,8 +11006,8 @@ async function runMineLocalImpl(args) {
10159
11006
  console.log(`Dry-run: would invoke ${gateAgent} gate on ${picked.length} session(s) in parallel (concurrency=${GATE_CONCURRENCY}).`);
10160
11007
  return;
10161
11008
  }
10162
- const tmpDir = join45(homedir23(), ".claude", "hivemind", `mine-local-${Date.now()}`);
10163
- mkdirSync22(tmpDir, { recursive: true });
11009
+ const tmpDir = join46(homedir24(), ".claude", "hivemind", `mine-local-${Date.now()}`);
11010
+ mkdirSync23(tmpDir, { recursive: true });
10164
11011
  console.log(`Running ${picked.length} gate call(s) in parallel (concurrency=${GATE_CONCURRENCY}, timeout=${GATE_TIMEOUT_MS / 1e3}s each)...`);
10165
11012
  const results = await parallelMap(picked, GATE_CONCURRENCY, async (s) => {
10166
11013
  const shortId = s.sessionId.slice(0, 8);
@@ -10171,23 +11018,23 @@ async function runMineLocalImpl(args) {
10171
11018
  return { session: s, skills: [], reason: "no pairs", error: null };
10172
11019
  }
10173
11020
  const tail = pairs2.slice(-PER_SESSION_PAIR_CAP);
10174
- const sessionTmp = join45(tmpDir, `s-${shortId}`);
10175
- mkdirSync22(sessionTmp, { recursive: true });
10176
- const verdictPath = join45(sessionTmp, "verdict.json");
11021
+ const sessionTmp = join46(tmpDir, `s-${shortId}`);
11022
+ mkdirSync23(sessionTmp, { recursive: true });
11023
+ const verdictPath = join46(sessionTmp, "verdict.json");
10177
11024
  const prompt = buildSessionPrompt(tail, s, verdictPath);
10178
- writeFileSync25(join45(sessionTmp, "prompt.txt"), prompt);
11025
+ writeFileSync26(join46(sessionTmp, "prompt.txt"), prompt);
10179
11026
  const gate = await runGateViaStdin({ agent: gateAgent, bin: gateBin, prompt, timeoutMs: GATE_TIMEOUT_MS });
10180
11027
  try {
10181
- writeFileSync25(join45(sessionTmp, "gate-stdout.txt"), gate.stdout);
11028
+ writeFileSync26(join46(sessionTmp, "gate-stdout.txt"), gate.stdout);
10182
11029
  if (gate.stderr)
10183
- writeFileSync25(join45(sessionTmp, "gate-stderr.txt"), gate.stderr);
11030
+ writeFileSync26(join46(sessionTmp, "gate-stderr.txt"), gate.stderr);
10184
11031
  } catch {
10185
11032
  }
10186
11033
  if (gate.errored) {
10187
11034
  console.log(` [${shortId}] gate failed: ${gate.errorMessage}`);
10188
11035
  return { session: s, skills: [], reason: null, error: gate.errorMessage ?? "gate failed" };
10189
11036
  }
10190
- const verdictText = existsSync35(verdictPath) ? readFileSync31(verdictPath, "utf-8") : gate.stdout;
11037
+ const verdictText = existsSync35(verdictPath) ? readFileSync32(verdictPath, "utf-8") : gate.stdout;
10191
11038
  const mv = parseMultiVerdict(verdictText);
10192
11039
  if (!mv) {
10193
11040
  console.log(` [${shortId}] unparseable verdict (kept at ${sessionTmp})`);
@@ -10428,7 +11275,7 @@ function showStatus() {
10428
11275
  console.log(`state: ${files.length} project(s) tracked`);
10429
11276
  for (const f of files) {
10430
11277
  try {
10431
- const s = JSON.parse(readFileSync32(join46(dir, f), "utf-8"));
11278
+ const s = JSON.parse(readFileSync33(join47(dir, f), "utf-8"));
10432
11279
  const last = typeof s.updatedAt === "number" ? new Date(s.updatedAt).toISOString() : s.lastDate ?? "never";
10433
11280
  const skills = Array.isArray(s.skillsGenerated) && s.skillsGenerated.length > 0 ? s.skillsGenerated.join(", ") : "none";
10434
11281
  console.log(` - ${s.project} (counter=${s.counter}, last=${last}, skills=${skills})`);
@@ -10448,32 +11295,32 @@ function setScope(scope) {
10448
11295
  console.log(`Note: team list is empty. Use 'hivemind skillify team add <username>' to populate it.`);
10449
11296
  }
10450
11297
  }
10451
- function setInstall(loc) {
10452
- if (loc !== "project" && loc !== "global") {
10453
- console.error(`Invalid install location '${loc}'. Use one of: project, global`);
11298
+ function setInstall(loc2) {
11299
+ if (loc2 !== "project" && loc2 !== "global") {
11300
+ console.error(`Invalid install location '${loc2}'. Use one of: project, global`);
10454
11301
  process.exit(1);
10455
11302
  }
10456
11303
  const cfg = loadScopeConfig();
10457
- saveScopeConfig({ ...cfg, install: loc });
10458
- const path = loc === "global" ? join46(homedir24(), ".claude", "skills") : "<cwd>/.claude/skills";
10459
- console.log(`Install location set to '${loc}'. New skills will be written to ${path}/<name>/SKILL.md.`);
11304
+ saveScopeConfig({ ...cfg, install: loc2 });
11305
+ const path = loc2 === "global" ? join47(homedir25(), ".claude", "skills") : "<cwd>/.claude/skills";
11306
+ console.log(`Install location set to '${loc2}'. New skills will be written to ${path}/<name>/SKILL.md.`);
10460
11307
  }
10461
11308
  function promoteSkill(name, cwd) {
10462
11309
  if (!name) {
10463
11310
  console.error("Usage: hivemind skillify promote <skill-name>");
10464
11311
  process.exit(1);
10465
11312
  }
10466
- const projectPath = join46(cwd, ".claude", "skills", name);
10467
- const globalPath = join46(homedir24(), ".claude", "skills", name);
10468
- if (!existsSync36(join46(projectPath, "SKILL.md"))) {
11313
+ const projectPath = join47(cwd, ".claude", "skills", name);
11314
+ const globalPath = join47(homedir25(), ".claude", "skills", name);
11315
+ if (!existsSync36(join47(projectPath, "SKILL.md"))) {
10469
11316
  console.error(`Skill '${name}' not found at ${projectPath}/SKILL.md`);
10470
11317
  process.exit(1);
10471
11318
  }
10472
- if (existsSync36(join46(globalPath, "SKILL.md"))) {
11319
+ if (existsSync36(join47(globalPath, "SKILL.md"))) {
10473
11320
  console.error(`Skill '${name}' already exists at ${globalPath}/SKILL.md \u2014 refusing to overwrite. Remove it first or rename the project skill.`);
10474
11321
  process.exit(1);
10475
11322
  }
10476
- mkdirSync23(dirname17(globalPath), { recursive: true });
11323
+ mkdirSync24(dirname17(globalPath), { recursive: true });
10477
11324
  renameSync12(projectPath, globalPath);
10478
11325
  console.log(`Promoted '${name}' from ${projectPath} \u2192 ${globalPath}.`);
10479
11326
  }
@@ -10580,7 +11427,7 @@ async function pullSkills(args) {
10580
11427
  console.error(`pull failed: ${e?.message ?? e}`);
10581
11428
  process.exit(1);
10582
11429
  }
10583
- const dest = toRaw === "global" ? join46(homedir24(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
11430
+ const dest = toRaw === "global" ? join47(homedir25(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
10584
11431
  const filterDesc = users.length === 0 ? "all users" : users.join(", ");
10585
11432
  console.log(`Destination: ${dest}`);
10586
11433
  console.log(`Filter: ${filterDesc}${skillName ? ` \xB7 skill='${skillName}'` : ""}${dryRun ? " \xB7 dry-run" : ""}${force ? " \xB7 force" : ""}`);
@@ -10630,7 +11477,7 @@ async function unpullSkills(args) {
10630
11477
  all,
10631
11478
  legacyCleanup
10632
11479
  });
10633
- const dest = toRaw === "global" ? join46(homedir24(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
11480
+ const dest = toRaw === "global" ? join47(homedir25(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
10634
11481
  const filterParts = [];
10635
11482
  if (users.length > 0)
10636
11483
  filterParts.push(`users=${users.join(",")}`);
@@ -11498,14 +12345,14 @@ async function runContextCommand(args) {
11498
12345
 
11499
12346
  // dist/src/cli/update.js
11500
12347
  import { execFileSync as execFileSync6 } from "node:child_process";
11501
- import { closeSync as closeSync3, existsSync as existsSync37, mkdirSync as mkdirSync24, openSync as openSync3, readFileSync as readFileSync34, realpathSync, unlinkSync as unlinkSync13, writeSync as writeSync2 } from "node:fs";
11502
- import { homedir as homedir25 } from "node:os";
11503
- import { dirname as dirname19, join as join48, sep as sep2 } from "node:path";
12348
+ import { closeSync as closeSync3, existsSync as existsSync37, mkdirSync as mkdirSync25, openSync as openSync3, readFileSync as readFileSync35, realpathSync, unlinkSync as unlinkSync13, writeSync as writeSync2 } from "node:fs";
12349
+ import { homedir as homedir26 } from "node:os";
12350
+ import { dirname as dirname19, join as join49, sep as sep2 } from "node:path";
11504
12351
  import { fileURLToPath as fileURLToPath2 } from "node:url";
11505
12352
 
11506
12353
  // dist/src/utils/version-check.js
11507
- import { readFileSync as readFileSync33 } from "node:fs";
11508
- import { dirname as dirname18, join as join47 } from "node:path";
12354
+ import { readFileSync as readFileSync34 } from "node:fs";
12355
+ import { dirname as dirname18, join as join48 } from "node:path";
11509
12356
  function isNewer(latest, current) {
11510
12357
  const parse = (v) => v.split(".").map(Number);
11511
12358
  const [la, lb, lc] = parse(latest);
@@ -11517,7 +12364,7 @@ function isNewer(latest, current) {
11517
12364
  var NPM_REGISTRY_URL = "https://registry.npmjs.org/@deeplake/hivemind/latest";
11518
12365
  var PKG_NAME = "@deeplake/hivemind";
11519
12366
  function defaultLockPath() {
11520
- return join48(homedir25(), ".deeplake", "hivemind-update.lock");
12367
+ return join49(homedir26(), ".deeplake", "hivemind-update.lock");
11521
12368
  }
11522
12369
  function detectInstallKind(argv1) {
11523
12370
  const realArgv1 = (() => {
@@ -11532,7 +12379,7 @@ function detectInstallKind(argv1) {
11532
12379
  for (let i = 0; i < 10; i++) {
11533
12380
  const pkgPath = `${dir}${sep2}package.json`;
11534
12381
  try {
11535
- const pkg = JSON.parse(readFileSync34(pkgPath, "utf-8"));
12382
+ const pkg = JSON.parse(readFileSync35(pkgPath, "utf-8"));
11536
12383
  if (pkg.name === PKG_NAME || pkg.name === "hivemind") {
11537
12384
  installDir = dir;
11538
12385
  break;
@@ -11578,7 +12425,7 @@ var defaultSpawn = (cmd, args) => {
11578
12425
  execFileSync6(cmd, args, { stdio: "inherit" });
11579
12426
  };
11580
12427
  function tryAcquireLock(path) {
11581
- mkdirSync24(dirname19(path), { recursive: true, mode: 448 });
12428
+ mkdirSync25(dirname19(path), { recursive: true, mode: 448 });
11582
12429
  const claim = () => {
11583
12430
  const fd = openSync3(path, "wx", 384);
11584
12431
  writeSync2(fd, String(process.pid));
@@ -11592,7 +12439,7 @@ function tryAcquireLock(path) {
11592
12439
  }
11593
12440
  let holderPid = 0;
11594
12441
  try {
11595
- holderPid = Number(readFileSync34(path, "utf-8").trim()) || 0;
12442
+ holderPid = Number(readFileSync35(path, "utf-8").trim()) || 0;
11596
12443
  } catch {
11597
12444
  try {
11598
12445
  return claim();
@@ -11720,9 +12567,9 @@ async function runUpdate(opts = {}) {
11720
12567
 
11721
12568
  // dist/src/cli/install-scan.js
11722
12569
  import { spawn as spawn4 } from "node:child_process";
11723
- import { existsSync as existsSync39, readFileSync as readFileSync35, readdirSync as readdirSync9, unlinkSync as unlinkSync14 } from "node:fs";
11724
- import { homedir as homedir26 } from "node:os";
11725
- import { join as join49 } from "node:path";
12570
+ import { existsSync as existsSync39, readFileSync as readFileSync36, readdirSync as readdirSync9, unlinkSync as unlinkSync14 } from "node:fs";
12571
+ import { homedir as homedir27 } from "node:os";
12572
+ import { join as join50 } from "node:path";
11726
12573
 
11727
12574
  // dist/src/skillify/advisor.js
11728
12575
  import { spawn as spawn3 } from "node:child_process";
@@ -11885,10 +12732,10 @@ async function runAdvisor(manifestPath3 = LOCAL_MANIFEST_PATH) {
11885
12732
 
11886
12733
  // dist/src/cli/install-scan.js
11887
12734
  function claudeProjectsDir() {
11888
- return join49(homedir26(), ".claude", "projects");
12735
+ return join50(homedir27(), ".claude", "projects");
11889
12736
  }
11890
12737
  function manifestPath2() {
11891
- return join49(homedir26(), ".claude", "hivemind", "local-mined.json");
12738
+ return join50(homedir27(), ".claude", "hivemind", "local-mined.json");
11892
12739
  }
11893
12740
  var SCAN_TIMEOUT_MS = 3e5;
11894
12741
  var INSTALL_SCAN_SESSION_COUNT = 10;
@@ -11897,7 +12744,7 @@ function manifestIsTrulyEmpty() {
11897
12744
  if (!existsSync39(p))
11898
12745
  return false;
11899
12746
  try {
11900
- const m = JSON.parse(readFileSync35(p, "utf-8"));
12747
+ const m = JSON.parse(readFileSync36(p, "utf-8"));
11901
12748
  return Array.isArray(m.entries) && m.entries.length === 0;
11902
12749
  } catch {
11903
12750
  return false;
@@ -11916,7 +12763,7 @@ function hasLocalClaudeSessions() {
11916
12763
  for (const sub of subdirs) {
11917
12764
  let files;
11918
12765
  try {
11919
- files = readdirSync9(join49(projectsDir, sub));
12766
+ files = readdirSync9(join50(projectsDir, sub));
11920
12767
  } catch {
11921
12768
  continue;
11922
12769
  }