@deeplake/hivemind 0.7.78 → 0.7.80

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.
@@ -367,38 +367,38 @@ function readQueue() {
367
367
  return { queue: [] };
368
368
  }
369
369
  }
370
- function _isQueuePathInsideHome(path, home) {
371
- const r = resolve(path);
370
+ function _isQueuePathInsideHome(path2, home) {
371
+ const r = resolve(path2);
372
372
  const h = resolve(home);
373
373
  return r.startsWith(h + "/") || r === h;
374
374
  }
375
375
  function writeQueue(q) {
376
- const path = queuePath();
376
+ const path2 = queuePath();
377
377
  const home = resolve(homedir3());
378
- if (!_isQueuePathInsideHome(path, home)) {
379
- throw new Error(`notifications-queue write blocked: ${path} is outside ${home}`);
378
+ if (!_isQueuePathInsideHome(path2, home)) {
379
+ throw new Error(`notifications-queue write blocked: ${path2} is outside ${home}`);
380
380
  }
381
381
  mkdirSync(join3(home, ".deeplake"), { recursive: true, mode: 448 });
382
- const tmp = `${path}.${process.pid}.tmp`;
382
+ const tmp = `${path2}.${process.pid}.tmp`;
383
383
  writeFileSync(tmp, JSON.stringify(q, null, 2), { mode: 384 });
384
- renameSync(tmp, path);
384
+ renameSync(tmp, path2);
385
385
  }
386
386
  async function withQueueLock(fn) {
387
- const path = lockPath();
387
+ const path2 = lockPath();
388
388
  mkdirSync(join3(homedir3(), ".deeplake"), { recursive: true, mode: 448 });
389
389
  let fd = null;
390
390
  for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
391
391
  try {
392
- fd = openSync(path, "wx", 384);
392
+ fd = openSync(path2, "wx", 384);
393
393
  break;
394
394
  } catch (e) {
395
395
  const code = e.code;
396
396
  if (code !== "EEXIST")
397
397
  throw e;
398
398
  try {
399
- const age = Date.now() - statSync(path).mtimeMs;
399
+ const age = Date.now() - statSync(path2).mtimeMs;
400
400
  if (age > LOCK_STALE_MS) {
401
- unlinkSync(path);
401
+ unlinkSync(path2);
402
402
  continue;
403
403
  }
404
404
  } catch {
@@ -419,7 +419,7 @@ async function withQueueLock(fn) {
419
419
  } catch {
420
420
  }
421
421
  try {
422
- unlinkSync(path);
422
+ unlinkSync(path2);
423
423
  } catch {
424
424
  }
425
425
  }
@@ -695,9 +695,9 @@ var DeeplakeApi = class {
695
695
  }
696
696
  }
697
697
  /** Update specific columns on a row by path. */
698
- async updateColumns(path, columns) {
698
+ async updateColumns(path2, columns) {
699
699
  const setClauses = Object.entries(columns).map(([col, val]) => typeof val === "number" ? `${col} = ${val}` : `${col} = '${sqlStr(String(val))}'`).join(", ");
700
- await this.query(`UPDATE "${this.tableName}" SET ${setClauses} WHERE path = '${sqlStr(path)}'`);
700
+ await this.query(`UPDATE "${this.tableName}" SET ${setClauses} WHERE path = '${sqlStr(path2)}'`);
701
701
  }
702
702
  // ── Convenience ─────────────────────────────────────────────────────────────
703
703
  /** Create a BM25 search index on a column. */
@@ -1129,8 +1129,8 @@ function formatToolCall(obj) {
1129
1129
  input: ${formatToolInput(obj?.tool_input)}
1130
1130
  response: ${formatToolResponse(obj?.tool_response, obj?.tool_input, obj?.tool_name)}`;
1131
1131
  }
1132
- function normalizeContent(path, raw) {
1133
- if (!path.includes("/sessions/"))
1132
+ function normalizeContent(path2, raw) {
1133
+ if (!path2.includes("/sessions/"))
1134
1134
  return raw;
1135
1135
  if (!raw || raw[0] !== "{")
1136
1136
  return raw;
@@ -1857,13 +1857,13 @@ var _migrated = false;
1857
1857
  function readUserConfig() {
1858
1858
  if (_cache !== null)
1859
1859
  return _cache;
1860
- const path = _configPath();
1861
- if (!existsSync4(path)) {
1860
+ const path2 = _configPath();
1861
+ if (!existsSync4(path2)) {
1862
1862
  _cache = {};
1863
1863
  return _cache;
1864
1864
  }
1865
1865
  try {
1866
- const raw = readFileSync6(path, "utf-8");
1866
+ const raw = readFileSync6(path2, "utf-8");
1867
1867
  const parsed = JSON.parse(raw);
1868
1868
  _cache = isPlainObject(parsed) ? parsed : {};
1869
1869
  } catch {
@@ -1874,13 +1874,13 @@ function readUserConfig() {
1874
1874
  function writeUserConfig(patch) {
1875
1875
  const current = readUserConfig();
1876
1876
  const merged = deepMerge(current, patch);
1877
- const path = _configPath();
1878
- const dir = dirname(path);
1877
+ const path2 = _configPath();
1878
+ const dir = dirname(path2);
1879
1879
  if (!existsSync4(dir))
1880
1880
  mkdirSync4(dir, { recursive: true });
1881
- const tmp = `${path}.tmp.${process.pid}`;
1881
+ const tmp = `${path2}.tmp.${process.pid}`;
1882
1882
  writeFileSync4(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
1883
- renameSync2(tmp, path);
1883
+ renameSync2(tmp, path2);
1884
1884
  _cache = merged;
1885
1885
  return merged;
1886
1886
  }
@@ -2332,18 +2332,18 @@ function lastBuildPath(baseDir, worktreeId) {
2332
2332
  return join10(baseDir, ".last-build.json");
2333
2333
  }
2334
2334
  function readLastBuild(baseDir, worktreeId) {
2335
- let path = lastBuildPath(baseDir, worktreeId);
2336
- if (!existsSync5(path)) {
2335
+ let path2 = lastBuildPath(baseDir, worktreeId);
2336
+ if (!existsSync5(path2)) {
2337
2337
  if (worktreeId === void 0)
2338
2338
  return null;
2339
2339
  const legacy = lastBuildPath(baseDir, void 0);
2340
2340
  if (!existsSync5(legacy))
2341
2341
  return null;
2342
- path = legacy;
2342
+ path2 = legacy;
2343
2343
  }
2344
2344
  let raw;
2345
2345
  try {
2346
- raw = readFileSync7(path, "utf8");
2346
+ raw = readFileSync7(path2, "utf8");
2347
2347
  } catch {
2348
2348
  return null;
2349
2349
  }
@@ -2952,18 +2952,18 @@ function workTreeIdFor(cwd) {
2952
2952
  return createHash3("sha256").update(cwd).digest("hex").slice(0, 16);
2953
2953
  }
2954
2954
  function handleGraphVfs(subpath, cwd) {
2955
- const path = subpath.replace(/^\/+/, "");
2956
- if (path === "" || path === "/") {
2955
+ const path2 = subpath.replace(/^\/+/, "");
2956
+ if (path2 === "" || path2 === "/") {
2957
2957
  return { kind: "ok", body: dirListing() };
2958
2958
  }
2959
- if (path === "index.md" || path === "index") {
2959
+ if (path2 === "index.md" || path2 === "index") {
2960
2960
  return loadSnapshotOrError(cwd, (snap, baseDir) => ({
2961
2961
  kind: "ok",
2962
2962
  body: renderIndex(snap, baseDir, cwd)
2963
2963
  }));
2964
2964
  }
2965
- if (path.startsWith("find/")) {
2966
- const pattern = path.slice("find/".length);
2965
+ if (path2.startsWith("find/")) {
2966
+ const pattern = path2.slice("find/".length);
2967
2967
  if (pattern === "") {
2968
2968
  return { kind: "not-found", message: "find/ requires a pattern: cat memory/graph/find/<keyword>" };
2969
2969
  }
@@ -2972,8 +2972,8 @@ function handleGraphVfs(subpath, cwd) {
2972
2972
  body: renderFind(snap, pattern, baseDir, workTreeIdFor(cwd))
2973
2973
  }));
2974
2974
  }
2975
- if (path.startsWith("show/")) {
2976
- const key = path.slice("show/".length);
2975
+ if (path2.startsWith("show/")) {
2976
+ const key = path2.slice("show/".length);
2977
2977
  if (key === "") {
2978
2978
  return { kind: "not-found", message: "show/ requires a handle or pattern" };
2979
2979
  }
@@ -2982,8 +2982,8 @@ function handleGraphVfs(subpath, cwd) {
2982
2982
  body: renderShow(snap, key, baseDir, workTreeIdFor(cwd))
2983
2983
  }));
2984
2984
  }
2985
- if (path.startsWith("query/")) {
2986
- const pattern = path.slice("query/".length);
2985
+ if (path2.startsWith("query/")) {
2986
+ const pattern = path2.slice("query/".length);
2987
2987
  if (pattern === "") {
2988
2988
  return { kind: "not-found", message: "query/ requires a pattern: cat memory/graph/query/<keyword>" };
2989
2989
  }
@@ -2992,28 +2992,28 @@ function handleGraphVfs(subpath, cwd) {
2992
2992
  body: renderQuery(snap, pattern, baseDir, workTreeIdFor(cwd))
2993
2993
  }));
2994
2994
  }
2995
- if (path.startsWith("impact/")) {
2996
- const pattern = path.slice("impact/".length);
2995
+ if (path2.startsWith("impact/")) {
2996
+ const pattern = path2.slice("impact/".length);
2997
2997
  if (pattern === "") {
2998
2998
  return { kind: "not-found", message: "impact/ requires a pattern: cat memory/graph/impact/<symbol>" };
2999
2999
  }
3000
3000
  return loadSnapshotOrError(cwd, (snap) => ({ kind: "ok", body: renderImpact(snap, pattern) }));
3001
3001
  }
3002
- if (path.startsWith("neighborhood/")) {
3003
- const file = path.slice("neighborhood/".length);
3002
+ if (path2.startsWith("neighborhood/")) {
3003
+ const file = path2.slice("neighborhood/".length);
3004
3004
  if (file === "") {
3005
3005
  return { kind: "not-found", message: "neighborhood/ requires a file path: cat memory/graph/neighborhood/<file>" };
3006
3006
  }
3007
3007
  return loadSnapshotOrError(cwd, (snap) => ({ kind: "ok", body: renderNeighborhood(snap, file) }));
3008
3008
  }
3009
- if (path === "layers" || path === "layers/" || path === "layers/index.md") {
3009
+ if (path2 === "layers" || path2 === "layers/" || path2 === "layers/index.md") {
3010
3010
  return loadSnapshotOrError(cwd, (snap) => ({ kind: "ok", body: renderLayers(snap) }));
3011
3011
  }
3012
- if (path === "tour" || path === "tour/" || path === "tour/index.md") {
3012
+ if (path2 === "tour" || path2 === "tour/" || path2 === "tour/index.md") {
3013
3013
  return loadSnapshotOrError(cwd, (snap) => ({ kind: "ok", body: renderTour(snap) }));
3014
3014
  }
3015
- if (path.startsWith("path/")) {
3016
- const rest = path.slice("path/".length);
3015
+ if (path2.startsWith("path/")) {
3016
+ const rest = path2.slice("path/".length);
3017
3017
  const slash = rest.indexOf("/");
3018
3018
  if (slash <= 0 || slash === rest.length - 1) {
3019
3019
  return { kind: "not-found", message: "path/ needs two patterns: cat memory/graph/path/<from>/<to> (each a symbol-name substring, no slash)" };
@@ -3024,7 +3024,7 @@ function handleGraphVfs(subpath, cwd) {
3024
3024
  }
3025
3025
  return {
3026
3026
  kind: "not-found",
3027
- message: `Unknown endpoint: graph/${path}
3027
+ message: `Unknown endpoint: graph/${path2}
3028
3028
  Available: index.md, find/<pattern>, query/<pattern>, show/<handle-or-pattern>, impact/<pattern>, neighborhood/<file>, layers, tour, path/<from>/<to>`
3029
3029
  };
3030
3030
  }
@@ -3423,22 +3423,22 @@ function handlesPath(baseDir, worktreeId) {
3423
3423
  return join13(baseDir, "worktrees", worktreeId, ".find-handles.json");
3424
3424
  }
3425
3425
  function saveHandles(baseDir, worktreeId, ids, pattern) {
3426
- const path = handlesPath(baseDir, worktreeId);
3426
+ const path2 = handlesPath(baseDir, worktreeId);
3427
3427
  const payload = { pattern, ts: Date.now(), ids };
3428
3428
  try {
3429
- mkdirSync8(dirname6(path), { recursive: true });
3430
- const tmp = `${path}.tmp.${process.pid}.${Date.now()}`;
3429
+ mkdirSync8(dirname6(path2), { recursive: true });
3430
+ const tmp = `${path2}.tmp.${process.pid}.${Date.now()}`;
3431
3431
  writeFileSync7(tmp, JSON.stringify(payload));
3432
- renameSync5(tmp, path);
3432
+ renameSync5(tmp, path2);
3433
3433
  } catch {
3434
3434
  }
3435
3435
  }
3436
3436
  function loadHandles(baseDir, worktreeId) {
3437
- const path = handlesPath(baseDir, worktreeId);
3438
- if (!existsSync7(path))
3437
+ const path2 = handlesPath(baseDir, worktreeId);
3438
+ if (!existsSync7(path2))
3439
3439
  return null;
3440
3440
  try {
3441
- const parsed = JSON.parse(readFileSync9(path, "utf8"));
3441
+ const parsed = JSON.parse(readFileSync9(path2, "utf8"));
3442
3442
  if (parsed === null || typeof parsed !== "object")
3443
3443
  return null;
3444
3444
  const o = parsed;
@@ -3529,8 +3529,8 @@ function tryGraphRead(rewrittenCommand, cwd) {
3529
3529
  }
3530
3530
 
3531
3531
  // dist/src/hooks/virtual-table-query.js
3532
- function normalizeSessionPart(path, content) {
3533
- return normalizeContent(path, content);
3532
+ function normalizeSessionPart(path2, content) {
3533
+ return normalizeContent(path2, content);
3534
3534
  }
3535
3535
  var INDEX_LIMIT_PER_SECTION = 50;
3536
3536
  function buildVirtualIndexContent(summaryRows, sessionRows = [], opts = {}) {
@@ -3597,7 +3597,7 @@ function buildUnionQuery(memoryQuery, sessionsQuery) {
3597
3597
  return `SELECT path, content, size_bytes, creation_date, source_order FROM ((${memoryQuery}) UNION ALL (${sessionsQuery})) AS combined ORDER BY path, source_order, creation_date`;
3598
3598
  }
3599
3599
  function buildInList(paths) {
3600
- return paths.map((path) => `'${sqlStr(path)}'`).join(", ");
3600
+ return paths.map((path2) => `'${sqlStr(path2)}'`).join(", ");
3601
3601
  }
3602
3602
  function buildDirFilter(dirs) {
3603
3603
  const cleaned = [...new Set(dirs.map((dir) => dir.replace(/\/+$/, "") || "/"))];
@@ -3620,7 +3620,7 @@ async function queryUnionRows(api, memoryQuery, sessionsQuery) {
3620
3620
  }
3621
3621
  async function readVirtualPathContents(api, memoryTable, sessionsTable, virtualPaths) {
3622
3622
  const uniquePaths = [...new Set(virtualPaths)];
3623
- const result = new Map(uniquePaths.map((path) => [path, null]));
3623
+ const result = new Map(uniquePaths.map((path2) => [path2, null]));
3624
3624
  if (uniquePaths.length === 0)
3625
3625
  return result;
3626
3626
  const inList = buildInList(uniquePaths);
@@ -3628,27 +3628,27 @@ async function readVirtualPathContents(api, memoryTable, sessionsTable, virtualP
3628
3628
  const memoryHits = /* @__PURE__ */ new Map();
3629
3629
  const sessionHits = /* @__PURE__ */ new Map();
3630
3630
  for (const row of rows) {
3631
- const path = row["path"];
3631
+ const path2 = row["path"];
3632
3632
  const content = row["content"];
3633
3633
  const sourceOrder = Number(row["source_order"] ?? 0);
3634
- if (typeof path !== "string" || typeof content !== "string")
3634
+ if (typeof path2 !== "string" || typeof content !== "string")
3635
3635
  continue;
3636
3636
  if (sourceOrder === 0) {
3637
- memoryHits.set(path, content);
3637
+ memoryHits.set(path2, content);
3638
3638
  } else {
3639
- const current = sessionHits.get(path) ?? [];
3640
- current.push(normalizeSessionPart(path, content));
3641
- sessionHits.set(path, current);
3639
+ const current = sessionHits.get(path2) ?? [];
3640
+ current.push(normalizeSessionPart(path2, content));
3641
+ sessionHits.set(path2, current);
3642
3642
  }
3643
3643
  }
3644
- for (const path of uniquePaths) {
3645
- if (memoryHits.has(path)) {
3646
- result.set(path, memoryHits.get(path) ?? null);
3644
+ for (const path2 of uniquePaths) {
3645
+ if (memoryHits.has(path2)) {
3646
+ result.set(path2, memoryHits.get(path2) ?? null);
3647
3647
  continue;
3648
3648
  }
3649
- const sessionParts = sessionHits.get(path) ?? [];
3649
+ const sessionParts = sessionHits.get(path2) ?? [];
3650
3650
  if (sessionParts.length > 0) {
3651
- result.set(path, sessionParts.join("\n"));
3651
+ result.set(path2, sessionParts.join("\n"));
3652
3652
  }
3653
3653
  }
3654
3654
  if (result.get("/index.md") === null && uniquePaths.includes("/index.md")) {
@@ -3675,12 +3675,12 @@ async function listVirtualPathRowsForDirs(api, memoryTable, sessionsTable, dirs)
3675
3675
  for (const dir of uniqueDirs)
3676
3676
  byDir.set(dir, []);
3677
3677
  for (const row of deduped) {
3678
- const path = row["path"];
3679
- if (typeof path !== "string")
3678
+ const path2 = row["path"];
3679
+ if (typeof path2 !== "string")
3680
3680
  continue;
3681
3681
  for (const dir of uniqueDirs) {
3682
3682
  const prefix = dir === "/" ? "/" : `${dir}/`;
3683
- if (dir === "/" || path.startsWith(prefix)) {
3683
+ if (dir === "/" || path2.startsWith(prefix)) {
3684
3684
  byDir.get(dir)?.push(row);
3685
3685
  }
3686
3686
  }
@@ -3703,10 +3703,10 @@ function dedupeRowsByPath(rows) {
3703
3703
  const seen = /* @__PURE__ */ new Set();
3704
3704
  const unique = [];
3705
3705
  for (const row of rows) {
3706
- const path = typeof row["path"] === "string" ? row["path"] : "";
3707
- if (!path || seen.has(path))
3706
+ const path2 = typeof row["path"] === "string" ? row["path"] : "";
3707
+ if (!path2 || seen.has(path2))
3708
3708
  continue;
3709
- seen.add(path);
3709
+ seen.add(path2);
3710
3710
  unique.push(row);
3711
3711
  }
3712
3712
  return unique;
@@ -3952,12 +3952,12 @@ function parseCompiledSegment(segment) {
3952
3952
  return null;
3953
3953
  if (headTokens[1] === "-n" && headTokens.length < 4 || /^-\d+$/.test(headTokens[1] ?? "") && headTokens.length < 3 || headTokens.length === 2 && /^-?\d+$/.test(headTokens[1] ?? ""))
3954
3954
  return null;
3955
- const path = headTokens[headTokens.length - 1];
3956
- if (path === "head" || path === "tail" || path === "-n")
3955
+ const path2 = headTokens[headTokens.length - 1];
3956
+ if (path2 === "head" || path2 === "tail" || path2 === "-n")
3957
3957
  return null;
3958
3958
  return {
3959
3959
  kind: "cat",
3960
- paths: expandBraceToken(path),
3960
+ paths: expandBraceToken(path2),
3961
3961
  lineLimit: parsed.lineLimit,
3962
3962
  fromEnd: parsed.fromEnd,
3963
3963
  countLines: false,
@@ -4068,10 +4068,10 @@ function renderDirectoryListing(dir, rows, longFormat) {
4068
4068
  const entries = /* @__PURE__ */ new Map();
4069
4069
  const prefix = dir === "/" ? "/" : `${dir}/`;
4070
4070
  for (const row of rows) {
4071
- const path = row["path"];
4072
- if (!path.startsWith(prefix) && dir !== "/")
4071
+ const path2 = row["path"];
4072
+ if (!path2.startsWith(prefix) && dir !== "/")
4073
4073
  continue;
4074
- const rest = dir === "/" ? path.slice(1) : path.slice(prefix.length);
4074
+ const rest = dir === "/" ? path2.slice(1) : path2.slice(prefix.length);
4075
4075
  const slash = rest.indexOf("/");
4076
4076
  const name = slash === -1 ? rest : rest.slice(0, slash);
4077
4077
  if (!name)
@@ -4115,8 +4115,8 @@ async function executeCompiledBashCommand(api, memoryTable, sessionsTable, cmd,
4115
4115
  }
4116
4116
  if (segment.kind === "cat") {
4117
4117
  const contents = [];
4118
- for (const path of segment.paths) {
4119
- const content = contentMap.get(path) ?? null;
4118
+ for (const path2 of segment.paths) {
4119
+ const content = contentMap.get(path2) ?? null;
4120
4120
  if (content === null) {
4121
4121
  if (segment.ignoreMissing)
4122
4122
  continue;
@@ -4153,11 +4153,11 @@ async function executeCompiledBashCommand(api, memoryTable, sessionsTable, cmd,
4153
4153
  continue;
4154
4154
  }
4155
4155
  const candidateContents = await readVirtualPathContentsFn(api, memoryTable, sessionsTable, candidatePaths);
4156
- const matched = refineGrepMatches(candidatePaths.flatMap((path) => {
4157
- const content = candidateContents.get(path);
4156
+ const matched = refineGrepMatches(candidatePaths.flatMap((path2) => {
4157
+ const content = candidateContents.get(path2);
4158
4158
  if (content === null || content === void 0)
4159
4159
  return [];
4160
- return [{ path, content: normalizeContent(path, content) }];
4160
+ return [{ path: path2, content: normalizeContent(path2, content) }];
4161
4161
  }), segment.params);
4162
4162
  const limited = segment.lineLimit > 0 ? matched.slice(0, segment.lineLimit) : matched;
4163
4163
  outputs.push(limited.join("\n") || "(no matches)");
@@ -4372,6 +4372,225 @@ function rewritePaths(cmd) {
4372
4372
  return cmd.replace(new RegExp(escapeRe(MEMORY_PATH) + tail, "g"), "/").replace(new RegExp(escapeRe(TILDE_PATH) + tail, "g"), "/").replace(new RegExp('"' + escapeRe(HOME_VAR_PATH) + tail + '"', "g"), '"/"').replace(new RegExp(escapeRe(HOME_VAR_PATH) + tail, "g"), "/");
4373
4373
  }
4374
4374
 
4375
+ // dist/src/skillify/skillopt-trigger.js
4376
+ import { spawn as spawn2 } from "node:child_process";
4377
+ import fs from "node:fs";
4378
+ import path from "node:path";
4379
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
4380
+
4381
+ // dist/src/skillify/state-dir.js
4382
+ import { homedir as homedir11 } from "node:os";
4383
+ import { join as join16 } from "node:path";
4384
+ function getStateDir() {
4385
+ const override = process.env.HIVEMIND_STATE_DIR?.trim();
4386
+ return override && override.length > 0 ? override : join16(homedir11(), ".deeplake", "state", "skillify");
4387
+ }
4388
+
4389
+ // dist/src/skillify/skill-invocations.js
4390
+ function pathToSkillRef(s) {
4391
+ if (typeof s !== "string")
4392
+ return null;
4393
+ const m = s.match(/\/skills\/(?:[^/\s"'`]+\/)*([^/\s"'`]+)\/SKILL\.md/);
4394
+ return m ? m[1] : null;
4395
+ }
4396
+ function splitOrgSkill(skill) {
4397
+ if (skill.includes(":"))
4398
+ return null;
4399
+ if (skill.includes("/") || skill.includes("\\") || skill.includes(".."))
4400
+ return null;
4401
+ const i = skill.lastIndexOf("--");
4402
+ if (i <= 0 || i + 2 >= skill.length)
4403
+ return null;
4404
+ return { name: skill.slice(0, i), author: skill.slice(i + 2) };
4405
+ }
4406
+
4407
+ // dist/src/skillify/manifest.js
4408
+ import { existsSync as existsSync9, lstatSync, mkdirSync as mkdirSync10, readFileSync as readFileSync11, renameSync as renameSync7, unlinkSync as unlinkSync4, writeFileSync as writeFileSync9 } from "node:fs";
4409
+ import { dirname as dirname8, join as join18 } from "node:path";
4410
+
4411
+ // dist/src/skillify/legacy-migration.js
4412
+ import { existsSync as existsSync8, renameSync as renameSync6 } from "node:fs";
4413
+ import { dirname as dirname7, join as join17 } from "node:path";
4414
+ var dlog = (msg) => log("skillify-migrate", msg);
4415
+ var attempted = false;
4416
+ function migrateLegacyStateDir() {
4417
+ if (process.env.HIVEMIND_STATE_DIR?.trim())
4418
+ return;
4419
+ if (attempted)
4420
+ return;
4421
+ attempted = true;
4422
+ const current = getStateDir();
4423
+ const legacy = join17(dirname7(current), "skilify");
4424
+ if (!existsSync8(legacy))
4425
+ return;
4426
+ if (existsSync8(current))
4427
+ return;
4428
+ try {
4429
+ renameSync6(legacy, current);
4430
+ dlog(`migrated ${legacy} -> ${current}`);
4431
+ } catch (err) {
4432
+ const code = err.code;
4433
+ if (code === "EXDEV" || code === "EPERM" || code === "ENOENT" || code === "EEXIST" || code === "ENOTEMPTY") {
4434
+ dlog(`migration skipped (${code}); legacy dir left as-is or another process handled it`);
4435
+ return;
4436
+ }
4437
+ throw err;
4438
+ }
4439
+ }
4440
+
4441
+ // dist/src/skillify/manifest.js
4442
+ function emptyManifest() {
4443
+ return { version: 1, entries: [] };
4444
+ }
4445
+ function manifestPath() {
4446
+ return join18(getStateDir(), "pulled.json");
4447
+ }
4448
+ function loadManifest(path2 = manifestPath()) {
4449
+ migrateLegacyStateDir();
4450
+ if (!existsSync9(path2))
4451
+ return emptyManifest();
4452
+ let raw;
4453
+ try {
4454
+ raw = readFileSync11(path2, "utf-8");
4455
+ } catch {
4456
+ return emptyManifest();
4457
+ }
4458
+ try {
4459
+ const parsed = JSON.parse(raw);
4460
+ if (!parsed || typeof parsed !== "object")
4461
+ return emptyManifest();
4462
+ if (parsed.version !== 1 || !Array.isArray(parsed.entries))
4463
+ return emptyManifest();
4464
+ const entries = [];
4465
+ for (const e of parsed.entries) {
4466
+ if (!e || typeof e !== "object")
4467
+ continue;
4468
+ if (typeof e.dirName !== "string" || !e.dirName)
4469
+ continue;
4470
+ if (e.dirName.includes("/") || e.dirName.includes("\\") || e.dirName.includes(".."))
4471
+ continue;
4472
+ if (typeof e.name !== "string" || !e.name)
4473
+ continue;
4474
+ if (typeof e.author !== "string")
4475
+ continue;
4476
+ if (typeof e.installRoot !== "string" || !e.installRoot)
4477
+ continue;
4478
+ if (e.install !== "global" && e.install !== "project")
4479
+ continue;
4480
+ const symlinks = Array.isArray(e.symlinks) ? e.symlinks.filter((p) => typeof p === "string" && p.length > 0 && (p.startsWith("/") || /^[A-Za-z]:[\\/]/.test(p)) && // absolute (POSIX or Windows)
4481
+ !p.includes("..")) : [];
4482
+ entries.push({
4483
+ dirName: e.dirName,
4484
+ name: e.name,
4485
+ author: e.author,
4486
+ projectKey: typeof e.projectKey === "string" ? e.projectKey : "",
4487
+ remoteVersion: typeof e.remoteVersion === "number" ? e.remoteVersion : 1,
4488
+ install: e.install,
4489
+ installRoot: e.installRoot,
4490
+ pulledAt: typeof e.pulledAt === "string" ? e.pulledAt : (/* @__PURE__ */ new Date()).toISOString(),
4491
+ symlinks
4492
+ });
4493
+ }
4494
+ return { version: 1, entries };
4495
+ } catch {
4496
+ return emptyManifest();
4497
+ }
4498
+ }
4499
+
4500
+ // dist/src/skillify/skillopt-env.js
4501
+ var SKILLOPT_ENV = {
4502
+ /** User-set kill switch: "1" disables the whole trigger. */
4503
+ DISABLED: "HIVEMIND_SKILLOPT_DISABLED",
4504
+ /** Recursion guard the trigger sets on the spawned worker so the worker can't re-arm. */
4505
+ WORKER: "HIVEMIND_SKILLOPT_WORKER",
4506
+ /** Worker inputs, handed trigger → worker via the child env. */
4507
+ SESSION: "HIVEMIND_SKILLOPT_SESSION",
4508
+ SKILL: "HIVEMIND_SKILLOPT_SKILL",
4509
+ REACTION: "HIVEMIND_SKILLOPT_REACTION",
4510
+ TOOL_USE_ID: "HIVEMIND_SKILLOPT_TOOL_USE_ID",
4511
+ /** Which agent's CLI runs the judge/proposer (claude_code/codex/hermes/cursor/pi). */
4512
+ AGENT: "HIVEMIND_SKILLOPT_AGENT",
4513
+ /** K-message judgment-window size override. */
4514
+ JUDGE_WINDOW: "HIVEMIND_SKILLOPT_JUDGE_WINDOW"
4515
+ };
4516
+
4517
+ // dist/src/skillify/skillopt-trigger.js
4518
+ var DEFAULT_JUDGE_WINDOW = 3;
4519
+ function judgeWindow(env = process.env) {
4520
+ const n = Number(env[SKILLOPT_ENV.JUDGE_WINDOW]);
4521
+ return Number.isFinite(n) && n > 0 ? Math.floor(n) : DEFAULT_JUDGE_WINDOW;
4522
+ }
4523
+ function defaultIsOrgSkill(skillRef) {
4524
+ try {
4525
+ return loadManifest().entries.some((e) => e.dirName === skillRef);
4526
+ } catch {
4527
+ return false;
4528
+ }
4529
+ }
4530
+ function pendingFile(sessionId) {
4531
+ const safe = sessionId.replace(/[^A-Za-z0-9_-]/g, "_").slice(0, 200);
4532
+ return path.join(getStateDir(), "skillopt", "pending", `${safe}.json`);
4533
+ }
4534
+ var fileStore = {
4535
+ load(sessionId) {
4536
+ try {
4537
+ return JSON.parse(fs.readFileSync(pendingFile(sessionId), "utf8"));
4538
+ } catch {
4539
+ return null;
4540
+ }
4541
+ },
4542
+ save(sessionId, p) {
4543
+ try {
4544
+ const f = pendingFile(sessionId);
4545
+ if (p === null) {
4546
+ try {
4547
+ fs.unlinkSync(f);
4548
+ } catch {
4549
+ }
4550
+ return;
4551
+ }
4552
+ fs.mkdirSync(path.dirname(f), { recursive: true });
4553
+ const tmp = `${f}.${process.pid}.tmp`;
4554
+ fs.writeFileSync(tmp, JSON.stringify(p));
4555
+ fs.renameSync(tmp, f);
4556
+ } catch {
4557
+ }
4558
+ }
4559
+ };
4560
+ function markSkillPending(sessionId, skillRef, toolUseId, deps = {}) {
4561
+ if (!sessionId || !skillRef)
4562
+ return false;
4563
+ if (!splitOrgSkill(skillRef))
4564
+ return false;
4565
+ if (!(deps.isOrgSkill ?? defaultIsOrgSkill)(skillRef))
4566
+ return false;
4567
+ (deps.store ?? fileStore).save(sessionId, { skill: skillRef, budget: judgeWindow(deps.env ?? process.env), toolUseId });
4568
+ return true;
4569
+ }
4570
+
4571
+ // dist/src/hooks/shared/skillopt-hook.js
4572
+ function skillRefFromSkillFileRead(toolName, toolInput) {
4573
+ if (/^read$/i.test(toolName))
4574
+ return pathToSkillRef(toolInput?.path);
4575
+ return pathToSkillRef(toolInput?.command);
4576
+ }
4577
+ function armSkillOptOnSkillUse(sessionId, toolName, toolInput, toolUseId) {
4578
+ try {
4579
+ if (process.env[SKILLOPT_ENV.DISABLED] === "1")
4580
+ return;
4581
+ let ref = null;
4582
+ if (toolName === "Skill") {
4583
+ const s = toolInput?.skill;
4584
+ ref = typeof s === "string" ? s : null;
4585
+ } else {
4586
+ ref = skillRefFromSkillFileRead(toolName, toolInput);
4587
+ }
4588
+ if (ref)
4589
+ markSkillPending(sessionId, ref, toolUseId);
4590
+ } catch {
4591
+ }
4592
+ }
4593
+
4375
4594
  // dist/src/hooks/codex/pre-tool-use.js
4376
4595
  var log6 = (msg) => log("codex-pre", msg);
4377
4596
  function buildUnsupportedGuidance() {
@@ -4380,11 +4599,11 @@ function buildUnsupportedGuidance() {
4380
4599
  function buildIndexContent(rows) {
4381
4600
  const lines = ["# Memory Index", "", `${rows.length} sessions:`, ""];
4382
4601
  for (const row of rows) {
4383
- const path = row["path"];
4602
+ const path2 = row["path"];
4384
4603
  const project = row["project"] || "";
4385
4604
  const description = (row["description"] || "").slice(0, 120);
4386
4605
  const date = (row["creation_date"] || "").slice(0, 10);
4387
- lines.push(`- [${path}](${path}) ${date} ${project ? `[${project}]` : ""} ${description}`);
4606
+ lines.push(`- [${path2}](${path2}) ${date} ${project ? `[${project}]` : ""} ${description}`);
4388
4607
  }
4389
4608
  return lines.join("\n");
4390
4609
  }
@@ -4414,16 +4633,16 @@ async function processCodexPreToolUse(input, deps = {}) {
4414
4633
  const api = createApi(table, config);
4415
4634
  const readVirtualPathContentsWithCache = async (cachePaths) => {
4416
4635
  const uniquePaths = [...new Set(cachePaths)];
4417
- const result = new Map(uniquePaths.map((path) => [path, null]));
4636
+ const result = new Map(uniquePaths.map((path2) => [path2, null]));
4418
4637
  const cachedIndex = uniquePaths.includes("/index.md") ? readCachedIndexContentFn(input.session_id) : null;
4419
- const remainingPaths = cachedIndex === null ? uniquePaths : uniquePaths.filter((path) => path !== "/index.md");
4638
+ const remainingPaths = cachedIndex === null ? uniquePaths : uniquePaths.filter((path2) => path2 !== "/index.md");
4420
4639
  if (cachedIndex !== null) {
4421
4640
  result.set("/index.md", cachedIndex);
4422
4641
  }
4423
4642
  if (remainingPaths.length > 0) {
4424
4643
  const fetched = await readVirtualPathContentsFn(api, table, sessionsTable, remainingPaths);
4425
- for (const [path, content] of fetched)
4426
- result.set(path, content);
4644
+ for (const [path2, content] of fetched)
4645
+ result.set(path2, content);
4427
4646
  }
4428
4647
  const fetchedIndex = result.get("/index.md");
4429
4648
  if (typeof fetchedIndex === "string") {
@@ -4519,10 +4738,10 @@ async function processCodexPreToolUse(input, deps = {}) {
4519
4738
  const entries = /* @__PURE__ */ new Map();
4520
4739
  const prefix = dir === "/" ? "/" : `${dir}/`;
4521
4740
  for (const row of rows) {
4522
- const path = row["path"];
4523
- if (!path.startsWith(prefix) && dir !== "/")
4741
+ const path2 = row["path"];
4742
+ if (!path2.startsWith(prefix) && dir !== "/")
4524
4743
  continue;
4525
- const rest = dir === "/" ? path.slice(1) : path.slice(prefix.length);
4744
+ const rest = dir === "/" ? path2.slice(1) : path2.slice(prefix.length);
4526
4745
  const slash = rest.indexOf("/");
4527
4746
  const name = slash === -1 ? rest : rest.slice(0, slash);
4528
4747
  if (!name)
@@ -4591,6 +4810,10 @@ async function processCodexPreToolUse(input, deps = {}) {
4591
4810
  }
4592
4811
  async function main() {
4593
4812
  const input = await readStdin();
4813
+ try {
4814
+ armSkillOptOnSkillUse(input.session_id, input.tool_name, input.tool_input, input.tool_use_id);
4815
+ } catch {
4816
+ }
4594
4817
  const decision = await processCodexPreToolUse(input);
4595
4818
  if (decision.action === "pass")
4596
4819
  return;