@deeplake/hivemind 0.7.79 → 0.7.81

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.
Files changed (46) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/bundle/cli.js +140 -94
  4. package/codex/bundle/capture.js +232 -72
  5. package/codex/bundle/commands/auth-login.js +14 -10
  6. package/codex/bundle/embeddings/embed-daemon.js +9 -5
  7. package/codex/bundle/graph-on-stop.js +32 -28
  8. package/codex/bundle/graph-pull-worker.js +27 -23
  9. package/codex/bundle/pre-tool-use.js +366 -123
  10. package/codex/bundle/session-start-setup.js +18 -14
  11. package/codex/bundle/session-start.js +26 -22
  12. package/codex/bundle/shell/deeplake-shell.js +30 -26
  13. package/codex/bundle/skillify-worker.js +14 -10
  14. package/codex/bundle/skillopt-worker.js +2061 -0
  15. package/codex/bundle/stop.js +50 -45
  16. package/codex/bundle/wiki-worker.js +18 -14
  17. package/cursor/bundle/capture.js +71 -44
  18. package/cursor/bundle/commands/auth-login.js +14 -10
  19. package/cursor/bundle/embeddings/embed-daemon.js +9 -5
  20. package/cursor/bundle/graph-on-stop.js +32 -28
  21. package/cursor/bundle/graph-pull-worker.js +27 -23
  22. package/cursor/bundle/pre-tool-use.js +28 -24
  23. package/cursor/bundle/session-end.js +40 -36
  24. package/cursor/bundle/session-start.js +39 -35
  25. package/cursor/bundle/shell/deeplake-shell.js +30 -26
  26. package/cursor/bundle/skillify-worker.js +14 -10
  27. package/cursor/bundle/wiki-worker.js +18 -14
  28. package/hermes/bundle/capture.js +235 -85
  29. package/hermes/bundle/commands/auth-login.js +14 -10
  30. package/hermes/bundle/embeddings/embed-daemon.js +9 -5
  31. package/hermes/bundle/graph-on-stop.js +32 -28
  32. package/hermes/bundle/graph-pull-worker.js +27 -23
  33. package/hermes/bundle/pre-tool-use.js +298 -74
  34. package/hermes/bundle/session-end.js +40 -36
  35. package/hermes/bundle/session-start.js +39 -35
  36. package/hermes/bundle/shell/deeplake-shell.js +30 -26
  37. package/hermes/bundle/skillify-worker.js +14 -10
  38. package/hermes/bundle/skillopt-worker.js +2061 -0
  39. package/hermes/bundle/wiki-worker.js +18 -14
  40. package/mcp/bundle/server.js +15 -11
  41. package/openclaw/dist/index.js +11 -7
  42. package/openclaw/dist/skillify-worker.js +14 -10
  43. package/openclaw/openclaw.plugin.json +1 -1
  44. package/openclaw/package.json +1 -1
  45. package/package.json +1 -1
  46. package/pi/extension-source/hivemind.ts +93 -0
@@ -17,7 +17,7 @@ __export(index_marker_store_exports, {
17
17
  hasFreshIndexMarker: () => hasFreshIndexMarker,
18
18
  writeIndexMarker: () => writeIndexMarker
19
19
  });
20
- import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
20
+ import { existsSync as existsSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
21
21
  import { join as join5 } from "node:path";
22
22
  import { tmpdir } from "node:os";
23
23
  function getIndexMarkerDir() {
@@ -41,7 +41,7 @@ function hasFreshIndexMarker(markerPath) {
41
41
  }
42
42
  }
43
43
  function writeIndexMarker(markerPath) {
44
- mkdirSync3(getIndexMarkerDir(), { recursive: true });
44
+ mkdirSync4(getIndexMarkerDir(), { recursive: true });
45
45
  writeFileSync3(markerPath, JSON.stringify({ updatedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf-8");
46
46
  }
47
47
  var INDEX_MARKER_TTL_MS;
@@ -52,6 +52,11 @@ var init_index_marker_store = __esm({
52
52
  }
53
53
  });
54
54
 
55
+ // dist/src/hooks/codex/pre-tool-use.js
56
+ import { join as join19, dirname as dirname10 } from "node:path";
57
+ import { fileURLToPath as fileURLToPath4 } from "node:url";
58
+ import { spawnSync } from "node:child_process";
59
+
55
60
  // dist/src/utils/stdin.js
56
61
  function readStdin() {
57
62
  return new Promise((resolve4, reject) => {
@@ -120,8 +125,8 @@ function loadConfig() {
120
125
  import { randomUUID } from "node:crypto";
121
126
 
122
127
  // dist/src/utils/debug.js
123
- import { appendFileSync } from "node:fs";
124
- import { join as join2 } from "node:path";
128
+ import { appendFileSync, mkdirSync } from "node:fs";
129
+ import { dirname, join as join2 } from "node:path";
125
130
  import { homedir as homedir2 } from "node:os";
126
131
  var LOG = join2(homedir2(), ".deeplake", "hook-debug.log");
127
132
  function isDebug() {
@@ -130,8 +135,12 @@ function isDebug() {
130
135
  function log(tag, msg) {
131
136
  if (!isDebug())
132
137
  return;
133
- appendFileSync(LOG, `${(/* @__PURE__ */ new Date()).toISOString()} [${tag}] ${msg}
138
+ try {
139
+ mkdirSync(dirname(LOG), { recursive: true });
140
+ appendFileSync(LOG, `${(/* @__PURE__ */ new Date()).toISOString()} [${tag}] ${msg}
134
141
  `);
142
+ } catch {
143
+ }
135
144
  }
136
145
 
137
146
  // dist/src/utils/sql.js
@@ -340,7 +349,7 @@ async function healMissingColumns(args) {
340
349
  }
341
350
 
342
351
  // dist/src/notifications/queue.js
343
- import { readFileSync as readFileSync2, writeFileSync, renameSync, mkdirSync, openSync, closeSync, unlinkSync, statSync } from "node:fs";
352
+ import { readFileSync as readFileSync2, writeFileSync, renameSync, mkdirSync as mkdirSync2, openSync, closeSync, unlinkSync, statSync } from "node:fs";
344
353
  import { join as join3, resolve } from "node:path";
345
354
  import { homedir as homedir3 } from "node:os";
346
355
  import { setTimeout as sleep } from "node:timers/promises";
@@ -367,38 +376,38 @@ function readQueue() {
367
376
  return { queue: [] };
368
377
  }
369
378
  }
370
- function _isQueuePathInsideHome(path, home) {
371
- const r = resolve(path);
379
+ function _isQueuePathInsideHome(path2, home) {
380
+ const r = resolve(path2);
372
381
  const h = resolve(home);
373
382
  return r.startsWith(h + "/") || r === h;
374
383
  }
375
384
  function writeQueue(q) {
376
- const path = queuePath();
385
+ const path2 = queuePath();
377
386
  const home = resolve(homedir3());
378
- if (!_isQueuePathInsideHome(path, home)) {
379
- throw new Error(`notifications-queue write blocked: ${path} is outside ${home}`);
387
+ if (!_isQueuePathInsideHome(path2, home)) {
388
+ throw new Error(`notifications-queue write blocked: ${path2} is outside ${home}`);
380
389
  }
381
- mkdirSync(join3(home, ".deeplake"), { recursive: true, mode: 448 });
382
- const tmp = `${path}.${process.pid}.tmp`;
390
+ mkdirSync2(join3(home, ".deeplake"), { recursive: true, mode: 448 });
391
+ const tmp = `${path2}.${process.pid}.tmp`;
383
392
  writeFileSync(tmp, JSON.stringify(q, null, 2), { mode: 384 });
384
- renameSync(tmp, path);
393
+ renameSync(tmp, path2);
385
394
  }
386
395
  async function withQueueLock(fn) {
387
- const path = lockPath();
388
- mkdirSync(join3(homedir3(), ".deeplake"), { recursive: true, mode: 448 });
396
+ const path2 = lockPath();
397
+ mkdirSync2(join3(homedir3(), ".deeplake"), { recursive: true, mode: 448 });
389
398
  let fd = null;
390
399
  for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
391
400
  try {
392
- fd = openSync(path, "wx", 384);
401
+ fd = openSync(path2, "wx", 384);
393
402
  break;
394
403
  } catch (e) {
395
404
  const code = e.code;
396
405
  if (code !== "EEXIST")
397
406
  throw e;
398
407
  try {
399
- const age = Date.now() - statSync(path).mtimeMs;
408
+ const age = Date.now() - statSync(path2).mtimeMs;
400
409
  if (age > LOCK_STALE_MS) {
401
- unlinkSync(path);
410
+ unlinkSync(path2);
402
411
  continue;
403
412
  }
404
413
  } catch {
@@ -419,7 +428,7 @@ async function withQueueLock(fn) {
419
428
  } catch {
420
429
  }
421
430
  try {
422
- unlinkSync(path);
431
+ unlinkSync(path2);
423
432
  } catch {
424
433
  }
425
434
  }
@@ -441,7 +450,7 @@ async function enqueueNotification(n) {
441
450
  }
442
451
 
443
452
  // dist/src/commands/auth-creds.js
444
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2 } from "node:fs";
453
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3, unlinkSync as unlinkSync2 } from "node:fs";
445
454
  import { join as join4 } from "node:path";
446
455
  import { homedir as homedir4 } from "node:os";
447
456
  function configDir() {
@@ -695,9 +704,9 @@ var DeeplakeApi = class {
695
704
  }
696
705
  }
697
706
  /** Update specific columns on a row by path. */
698
- async updateColumns(path, columns) {
707
+ async updateColumns(path2, columns) {
699
708
  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)}'`);
709
+ await this.query(`UPDATE "${this.tableName}" SET ${setClauses} WHERE path = '${sqlStr(path2)}'`);
701
710
  }
702
711
  // ── Convenience ─────────────────────────────────────────────────────────────
703
712
  /** Create a BM25 search index on a column. */
@@ -1129,8 +1138,8 @@ function formatToolCall(obj) {
1129
1138
  input: ${formatToolInput(obj?.tool_input)}
1130
1139
  response: ${formatToolResponse(obj?.tool_response, obj?.tool_input, obj?.tool_name)}`;
1131
1140
  }
1132
- function normalizeContent(path, raw) {
1133
- if (!path.includes("/sessions/"))
1141
+ function normalizeContent(path2, raw) {
1142
+ if (!path2.includes("/sessions/"))
1134
1143
  return raw;
1135
1144
  if (!raw || raw[0] !== "{")
1136
1145
  return raw;
@@ -1848,22 +1857,22 @@ import { join as join8 } from "node:path";
1848
1857
  import { pathToFileURL } from "node:url";
1849
1858
 
1850
1859
  // dist/src/user-config.js
1851
- import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync6, renameSync as renameSync2, writeFileSync as writeFileSync4 } from "node:fs";
1860
+ import { existsSync as existsSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync6, renameSync as renameSync2, writeFileSync as writeFileSync4 } from "node:fs";
1852
1861
  import { homedir as homedir6 } from "node:os";
1853
- import { dirname, join as join7 } from "node:path";
1862
+ import { dirname as dirname2, join as join7 } from "node:path";
1854
1863
  var _configPath = () => process.env.HIVEMIND_CONFIG_PATH ?? join7(homedir6(), ".deeplake", "config.json");
1855
1864
  var _cache = null;
1856
1865
  var _migrated = false;
1857
1866
  function readUserConfig() {
1858
1867
  if (_cache !== null)
1859
1868
  return _cache;
1860
- const path = _configPath();
1861
- if (!existsSync4(path)) {
1869
+ const path2 = _configPath();
1870
+ if (!existsSync4(path2)) {
1862
1871
  _cache = {};
1863
1872
  return _cache;
1864
1873
  }
1865
1874
  try {
1866
- const raw = readFileSync6(path, "utf-8");
1875
+ const raw = readFileSync6(path2, "utf-8");
1867
1876
  const parsed = JSON.parse(raw);
1868
1877
  _cache = isPlainObject(parsed) ? parsed : {};
1869
1878
  } catch {
@@ -1874,13 +1883,13 @@ function readUserConfig() {
1874
1883
  function writeUserConfig(patch) {
1875
1884
  const current = readUserConfig();
1876
1885
  const merged = deepMerge(current, patch);
1877
- const path = _configPath();
1878
- const dir = dirname(path);
1886
+ const path2 = _configPath();
1887
+ const dir = dirname2(path2);
1879
1888
  if (!existsSync4(dir))
1880
- mkdirSync4(dir, { recursive: true });
1881
- const tmp = `${path}.tmp.${process.pid}`;
1889
+ mkdirSync5(dir, { recursive: true });
1890
+ const tmp = `${path2}.tmp.${process.pid}`;
1882
1891
  writeFileSync4(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
1883
- renameSync2(tmp, path);
1892
+ renameSync2(tmp, path2);
1884
1893
  _cache = merged;
1885
1894
  return merged;
1886
1895
  }
@@ -1961,11 +1970,11 @@ function embeddingsDisabled() {
1961
1970
 
1962
1971
  // dist/src/hooks/grep-direct.js
1963
1972
  import { fileURLToPath } from "node:url";
1964
- import { dirname as dirname2, join as join9 } from "node:path";
1973
+ import { dirname as dirname3, join as join9 } from "node:path";
1965
1974
  var SEMANTIC_ENABLED = process.env.HIVEMIND_SEMANTIC_SEARCH !== "false" && !embeddingsDisabled();
1966
1975
  var SEMANTIC_TIMEOUT_MS = Number(process.env.HIVEMIND_SEMANTIC_EMBED_TIMEOUT_MS ?? "500");
1967
1976
  function resolveDaemonPath() {
1968
- return join9(dirname2(fileURLToPath(import.meta.url)), "..", "embeddings", "embed-daemon.js");
1977
+ return join9(dirname3(fileURLToPath(import.meta.url)), "..", "embeddings", "embed-daemon.js");
1969
1978
  }
1970
1979
  var sharedEmbedClient = null;
1971
1980
  function getEmbedClient() {
@@ -2318,13 +2327,13 @@ async function handleGrepDirect(api, table, sessionsTable, params) {
2318
2327
  }
2319
2328
 
2320
2329
  // dist/src/graph/vfs-handler.js
2321
- import { existsSync as existsSync7, mkdirSync as mkdirSync8, readFileSync as readFileSync9, renameSync as renameSync5, writeFileSync as writeFileSync7 } from "node:fs";
2330
+ import { existsSync as existsSync7, mkdirSync as mkdirSync9, readFileSync as readFileSync9, renameSync as renameSync5, writeFileSync as writeFileSync7 } from "node:fs";
2322
2331
  import { createHash as createHash3 } from "node:crypto";
2323
- import { join as join13, dirname as dirname6 } from "node:path";
2332
+ import { join as join13, dirname as dirname7 } from "node:path";
2324
2333
 
2325
2334
  // dist/src/graph/last-build.js
2326
- import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync7, renameSync as renameSync3, writeFileSync as writeFileSync5 } from "node:fs";
2327
- import { dirname as dirname3, join as join10 } from "node:path";
2335
+ import { existsSync as existsSync5, mkdirSync as mkdirSync6, readFileSync as readFileSync7, renameSync as renameSync3, writeFileSync as writeFileSync5 } from "node:fs";
2336
+ import { dirname as dirname4, join as join10 } from "node:path";
2328
2337
  function lastBuildPath(baseDir, worktreeId) {
2329
2338
  if (worktreeId !== void 0) {
2330
2339
  return join10(baseDir, "worktrees", worktreeId, ".last-build.json");
@@ -2332,18 +2341,18 @@ function lastBuildPath(baseDir, worktreeId) {
2332
2341
  return join10(baseDir, ".last-build.json");
2333
2342
  }
2334
2343
  function readLastBuild(baseDir, worktreeId) {
2335
- let path = lastBuildPath(baseDir, worktreeId);
2336
- if (!existsSync5(path)) {
2344
+ let path2 = lastBuildPath(baseDir, worktreeId);
2345
+ if (!existsSync5(path2)) {
2337
2346
  if (worktreeId === void 0)
2338
2347
  return null;
2339
2348
  const legacy = lastBuildPath(baseDir, void 0);
2340
2349
  if (!existsSync5(legacy))
2341
2350
  return null;
2342
- path = legacy;
2351
+ path2 = legacy;
2343
2352
  }
2344
2353
  let raw;
2345
2354
  try {
2346
- raw = readFileSync7(path, "utf8");
2355
+ raw = readFileSync7(path2, "utf8");
2347
2356
  } catch {
2348
2357
  return null;
2349
2358
  }
@@ -2374,13 +2383,13 @@ function readLastBuild(baseDir, worktreeId) {
2374
2383
 
2375
2384
  // dist/src/graph/snapshot.js
2376
2385
  import { createHash } from "node:crypto";
2377
- import { mkdirSync as mkdirSync7, renameSync as renameSync4, writeFileSync as writeFileSync6 } from "node:fs";
2386
+ import { mkdirSync as mkdirSync8, renameSync as renameSync4, writeFileSync as writeFileSync6 } from "node:fs";
2378
2387
  import { homedir as homedir8 } from "node:os";
2379
- import { dirname as dirname5, join as join12 } from "node:path";
2388
+ import { dirname as dirname6, join as join12 } from "node:path";
2380
2389
 
2381
2390
  // dist/src/graph/history.js
2382
- import { appendFileSync as appendFileSync2, existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync8 } from "node:fs";
2383
- import { dirname as dirname4, join as join11 } from "node:path";
2391
+ import { appendFileSync as appendFileSync2, existsSync as existsSync6, mkdirSync as mkdirSync7, readFileSync as readFileSync8 } from "node:fs";
2392
+ import { dirname as dirname5, join as join11 } from "node:path";
2384
2393
 
2385
2394
  // dist/src/graph/resolve/cross-file.js
2386
2395
  import { posix } from "node:path";
@@ -2952,18 +2961,18 @@ function workTreeIdFor(cwd) {
2952
2961
  return createHash3("sha256").update(cwd).digest("hex").slice(0, 16);
2953
2962
  }
2954
2963
  function handleGraphVfs(subpath, cwd) {
2955
- const path = subpath.replace(/^\/+/, "");
2956
- if (path === "" || path === "/") {
2964
+ const path2 = subpath.replace(/^\/+/, "");
2965
+ if (path2 === "" || path2 === "/") {
2957
2966
  return { kind: "ok", body: dirListing() };
2958
2967
  }
2959
- if (path === "index.md" || path === "index") {
2968
+ if (path2 === "index.md" || path2 === "index") {
2960
2969
  return loadSnapshotOrError(cwd, (snap, baseDir) => ({
2961
2970
  kind: "ok",
2962
2971
  body: renderIndex(snap, baseDir, cwd)
2963
2972
  }));
2964
2973
  }
2965
- if (path.startsWith("find/")) {
2966
- const pattern = path.slice("find/".length);
2974
+ if (path2.startsWith("find/")) {
2975
+ const pattern = path2.slice("find/".length);
2967
2976
  if (pattern === "") {
2968
2977
  return { kind: "not-found", message: "find/ requires a pattern: cat memory/graph/find/<keyword>" };
2969
2978
  }
@@ -2972,8 +2981,8 @@ function handleGraphVfs(subpath, cwd) {
2972
2981
  body: renderFind(snap, pattern, baseDir, workTreeIdFor(cwd))
2973
2982
  }));
2974
2983
  }
2975
- if (path.startsWith("show/")) {
2976
- const key = path.slice("show/".length);
2984
+ if (path2.startsWith("show/")) {
2985
+ const key = path2.slice("show/".length);
2977
2986
  if (key === "") {
2978
2987
  return { kind: "not-found", message: "show/ requires a handle or pattern" };
2979
2988
  }
@@ -2982,8 +2991,8 @@ function handleGraphVfs(subpath, cwd) {
2982
2991
  body: renderShow(snap, key, baseDir, workTreeIdFor(cwd))
2983
2992
  }));
2984
2993
  }
2985
- if (path.startsWith("query/")) {
2986
- const pattern = path.slice("query/".length);
2994
+ if (path2.startsWith("query/")) {
2995
+ const pattern = path2.slice("query/".length);
2987
2996
  if (pattern === "") {
2988
2997
  return { kind: "not-found", message: "query/ requires a pattern: cat memory/graph/query/<keyword>" };
2989
2998
  }
@@ -2992,28 +3001,28 @@ function handleGraphVfs(subpath, cwd) {
2992
3001
  body: renderQuery(snap, pattern, baseDir, workTreeIdFor(cwd))
2993
3002
  }));
2994
3003
  }
2995
- if (path.startsWith("impact/")) {
2996
- const pattern = path.slice("impact/".length);
3004
+ if (path2.startsWith("impact/")) {
3005
+ const pattern = path2.slice("impact/".length);
2997
3006
  if (pattern === "") {
2998
3007
  return { kind: "not-found", message: "impact/ requires a pattern: cat memory/graph/impact/<symbol>" };
2999
3008
  }
3000
3009
  return loadSnapshotOrError(cwd, (snap) => ({ kind: "ok", body: renderImpact(snap, pattern) }));
3001
3010
  }
3002
- if (path.startsWith("neighborhood/")) {
3003
- const file = path.slice("neighborhood/".length);
3011
+ if (path2.startsWith("neighborhood/")) {
3012
+ const file = path2.slice("neighborhood/".length);
3004
3013
  if (file === "") {
3005
3014
  return { kind: "not-found", message: "neighborhood/ requires a file path: cat memory/graph/neighborhood/<file>" };
3006
3015
  }
3007
3016
  return loadSnapshotOrError(cwd, (snap) => ({ kind: "ok", body: renderNeighborhood(snap, file) }));
3008
3017
  }
3009
- if (path === "layers" || path === "layers/" || path === "layers/index.md") {
3018
+ if (path2 === "layers" || path2 === "layers/" || path2 === "layers/index.md") {
3010
3019
  return loadSnapshotOrError(cwd, (snap) => ({ kind: "ok", body: renderLayers(snap) }));
3011
3020
  }
3012
- if (path === "tour" || path === "tour/" || path === "tour/index.md") {
3021
+ if (path2 === "tour" || path2 === "tour/" || path2 === "tour/index.md") {
3013
3022
  return loadSnapshotOrError(cwd, (snap) => ({ kind: "ok", body: renderTour(snap) }));
3014
3023
  }
3015
- if (path.startsWith("path/")) {
3016
- const rest = path.slice("path/".length);
3024
+ if (path2.startsWith("path/")) {
3025
+ const rest = path2.slice("path/".length);
3017
3026
  const slash = rest.indexOf("/");
3018
3027
  if (slash <= 0 || slash === rest.length - 1) {
3019
3028
  return { kind: "not-found", message: "path/ needs two patterns: cat memory/graph/path/<from>/<to> (each a symbol-name substring, no slash)" };
@@ -3024,7 +3033,7 @@ function handleGraphVfs(subpath, cwd) {
3024
3033
  }
3025
3034
  return {
3026
3035
  kind: "not-found",
3027
- message: `Unknown endpoint: graph/${path}
3036
+ message: `Unknown endpoint: graph/${path2}
3028
3037
  Available: index.md, find/<pattern>, query/<pattern>, show/<handle-or-pattern>, impact/<pattern>, neighborhood/<file>, layers, tour, path/<from>/<to>`
3029
3038
  };
3030
3039
  }
@@ -3423,22 +3432,22 @@ function handlesPath(baseDir, worktreeId) {
3423
3432
  return join13(baseDir, "worktrees", worktreeId, ".find-handles.json");
3424
3433
  }
3425
3434
  function saveHandles(baseDir, worktreeId, ids, pattern) {
3426
- const path = handlesPath(baseDir, worktreeId);
3435
+ const path2 = handlesPath(baseDir, worktreeId);
3427
3436
  const payload = { pattern, ts: Date.now(), ids };
3428
3437
  try {
3429
- mkdirSync8(dirname6(path), { recursive: true });
3430
- const tmp = `${path}.tmp.${process.pid}.${Date.now()}`;
3438
+ mkdirSync9(dirname7(path2), { recursive: true });
3439
+ const tmp = `${path2}.tmp.${process.pid}.${Date.now()}`;
3431
3440
  writeFileSync7(tmp, JSON.stringify(payload));
3432
- renameSync5(tmp, path);
3441
+ renameSync5(tmp, path2);
3433
3442
  } catch {
3434
3443
  }
3435
3444
  }
3436
3445
  function loadHandles(baseDir, worktreeId) {
3437
- const path = handlesPath(baseDir, worktreeId);
3438
- if (!existsSync7(path))
3446
+ const path2 = handlesPath(baseDir, worktreeId);
3447
+ if (!existsSync7(path2))
3439
3448
  return null;
3440
3449
  try {
3441
- const parsed = JSON.parse(readFileSync9(path, "utf8"));
3450
+ const parsed = JSON.parse(readFileSync9(path2, "utf8"));
3442
3451
  if (parsed === null || typeof parsed !== "object")
3443
3452
  return null;
3444
3453
  const o = parsed;
@@ -3529,8 +3538,8 @@ function tryGraphRead(rewrittenCommand, cwd) {
3529
3538
  }
3530
3539
 
3531
3540
  // dist/src/hooks/virtual-table-query.js
3532
- function normalizeSessionPart(path, content) {
3533
- return normalizeContent(path, content);
3541
+ function normalizeSessionPart(path2, content) {
3542
+ return normalizeContent(path2, content);
3534
3543
  }
3535
3544
  var INDEX_LIMIT_PER_SECTION = 50;
3536
3545
  function buildVirtualIndexContent(summaryRows, sessionRows = [], opts = {}) {
@@ -3597,7 +3606,7 @@ function buildUnionQuery(memoryQuery, sessionsQuery) {
3597
3606
  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
3607
  }
3599
3608
  function buildInList(paths) {
3600
- return paths.map((path) => `'${sqlStr(path)}'`).join(", ");
3609
+ return paths.map((path2) => `'${sqlStr(path2)}'`).join(", ");
3601
3610
  }
3602
3611
  function buildDirFilter(dirs) {
3603
3612
  const cleaned = [...new Set(dirs.map((dir) => dir.replace(/\/+$/, "") || "/"))];
@@ -3620,7 +3629,7 @@ async function queryUnionRows(api, memoryQuery, sessionsQuery) {
3620
3629
  }
3621
3630
  async function readVirtualPathContents(api, memoryTable, sessionsTable, virtualPaths) {
3622
3631
  const uniquePaths = [...new Set(virtualPaths)];
3623
- const result = new Map(uniquePaths.map((path) => [path, null]));
3632
+ const result = new Map(uniquePaths.map((path2) => [path2, null]));
3624
3633
  if (uniquePaths.length === 0)
3625
3634
  return result;
3626
3635
  const inList = buildInList(uniquePaths);
@@ -3628,27 +3637,27 @@ async function readVirtualPathContents(api, memoryTable, sessionsTable, virtualP
3628
3637
  const memoryHits = /* @__PURE__ */ new Map();
3629
3638
  const sessionHits = /* @__PURE__ */ new Map();
3630
3639
  for (const row of rows) {
3631
- const path = row["path"];
3640
+ const path2 = row["path"];
3632
3641
  const content = row["content"];
3633
3642
  const sourceOrder = Number(row["source_order"] ?? 0);
3634
- if (typeof path !== "string" || typeof content !== "string")
3643
+ if (typeof path2 !== "string" || typeof content !== "string")
3635
3644
  continue;
3636
3645
  if (sourceOrder === 0) {
3637
- memoryHits.set(path, content);
3646
+ memoryHits.set(path2, content);
3638
3647
  } else {
3639
- const current = sessionHits.get(path) ?? [];
3640
- current.push(normalizeSessionPart(path, content));
3641
- sessionHits.set(path, current);
3648
+ const current = sessionHits.get(path2) ?? [];
3649
+ current.push(normalizeSessionPart(path2, content));
3650
+ sessionHits.set(path2, current);
3642
3651
  }
3643
3652
  }
3644
- for (const path of uniquePaths) {
3645
- if (memoryHits.has(path)) {
3646
- result.set(path, memoryHits.get(path) ?? null);
3653
+ for (const path2 of uniquePaths) {
3654
+ if (memoryHits.has(path2)) {
3655
+ result.set(path2, memoryHits.get(path2) ?? null);
3647
3656
  continue;
3648
3657
  }
3649
- const sessionParts = sessionHits.get(path) ?? [];
3658
+ const sessionParts = sessionHits.get(path2) ?? [];
3650
3659
  if (sessionParts.length > 0) {
3651
- result.set(path, sessionParts.join("\n"));
3660
+ result.set(path2, sessionParts.join("\n"));
3652
3661
  }
3653
3662
  }
3654
3663
  if (result.get("/index.md") === null && uniquePaths.includes("/index.md")) {
@@ -3675,12 +3684,12 @@ async function listVirtualPathRowsForDirs(api, memoryTable, sessionsTable, dirs)
3675
3684
  for (const dir of uniqueDirs)
3676
3685
  byDir.set(dir, []);
3677
3686
  for (const row of deduped) {
3678
- const path = row["path"];
3679
- if (typeof path !== "string")
3687
+ const path2 = row["path"];
3688
+ if (typeof path2 !== "string")
3680
3689
  continue;
3681
3690
  for (const dir of uniqueDirs) {
3682
3691
  const prefix = dir === "/" ? "/" : `${dir}/`;
3683
- if (dir === "/" || path.startsWith(prefix)) {
3692
+ if (dir === "/" || path2.startsWith(prefix)) {
3684
3693
  byDir.get(dir)?.push(row);
3685
3694
  }
3686
3695
  }
@@ -3703,10 +3712,10 @@ function dedupeRowsByPath(rows) {
3703
3712
  const seen = /* @__PURE__ */ new Set();
3704
3713
  const unique = [];
3705
3714
  for (const row of rows) {
3706
- const path = typeof row["path"] === "string" ? row["path"] : "";
3707
- if (!path || seen.has(path))
3715
+ const path2 = typeof row["path"] === "string" ? row["path"] : "";
3716
+ if (!path2 || seen.has(path2))
3708
3717
  continue;
3709
- seen.add(path);
3718
+ seen.add(path2);
3710
3719
  unique.push(row);
3711
3720
  }
3712
3721
  return unique;
@@ -3952,12 +3961,12 @@ function parseCompiledSegment(segment) {
3952
3961
  return null;
3953
3962
  if (headTokens[1] === "-n" && headTokens.length < 4 || /^-\d+$/.test(headTokens[1] ?? "") && headTokens.length < 3 || headTokens.length === 2 && /^-?\d+$/.test(headTokens[1] ?? ""))
3954
3963
  return null;
3955
- const path = headTokens[headTokens.length - 1];
3956
- if (path === "head" || path === "tail" || path === "-n")
3964
+ const path2 = headTokens[headTokens.length - 1];
3965
+ if (path2 === "head" || path2 === "tail" || path2 === "-n")
3957
3966
  return null;
3958
3967
  return {
3959
3968
  kind: "cat",
3960
- paths: expandBraceToken(path),
3969
+ paths: expandBraceToken(path2),
3961
3970
  lineLimit: parsed.lineLimit,
3962
3971
  fromEnd: parsed.fromEnd,
3963
3972
  countLines: false,
@@ -4068,10 +4077,10 @@ function renderDirectoryListing(dir, rows, longFormat) {
4068
4077
  const entries = /* @__PURE__ */ new Map();
4069
4078
  const prefix = dir === "/" ? "/" : `${dir}/`;
4070
4079
  for (const row of rows) {
4071
- const path = row["path"];
4072
- if (!path.startsWith(prefix) && dir !== "/")
4080
+ const path2 = row["path"];
4081
+ if (!path2.startsWith(prefix) && dir !== "/")
4073
4082
  continue;
4074
- const rest = dir === "/" ? path.slice(1) : path.slice(prefix.length);
4083
+ const rest = dir === "/" ? path2.slice(1) : path2.slice(prefix.length);
4075
4084
  const slash = rest.indexOf("/");
4076
4085
  const name = slash === -1 ? rest : rest.slice(0, slash);
4077
4086
  if (!name)
@@ -4115,8 +4124,8 @@ async function executeCompiledBashCommand(api, memoryTable, sessionsTable, cmd,
4115
4124
  }
4116
4125
  if (segment.kind === "cat") {
4117
4126
  const contents = [];
4118
- for (const path of segment.paths) {
4119
- const content = contentMap.get(path) ?? null;
4127
+ for (const path2 of segment.paths) {
4128
+ const content = contentMap.get(path2) ?? null;
4120
4129
  if (content === null) {
4121
4130
  if (segment.ignoreMissing)
4122
4131
  continue;
@@ -4153,11 +4162,11 @@ async function executeCompiledBashCommand(api, memoryTable, sessionsTable, cmd,
4153
4162
  continue;
4154
4163
  }
4155
4164
  const candidateContents = await readVirtualPathContentsFn(api, memoryTable, sessionsTable, candidatePaths);
4156
- const matched = refineGrepMatches(candidatePaths.flatMap((path) => {
4157
- const content = candidateContents.get(path);
4165
+ const matched = refineGrepMatches(candidatePaths.flatMap((path2) => {
4166
+ const content = candidateContents.get(path2);
4158
4167
  if (content === null || content === void 0)
4159
4168
  return [];
4160
- return [{ path, content: normalizeContent(path, content) }];
4169
+ return [{ path: path2, content: normalizeContent(path2, content) }];
4161
4170
  }), segment.params);
4162
4171
  const limited = segment.lineLimit > 0 ? matched.slice(0, segment.lineLimit) : matched;
4163
4172
  outputs.push(limited.join("\n") || "(no matches)");
@@ -4179,7 +4188,7 @@ async function executeCompiledBashCommand(api, memoryTable, sessionsTable, cmd,
4179
4188
  }
4180
4189
 
4181
4190
  // dist/src/hooks/query-cache.js
4182
- import { mkdirSync as mkdirSync9, readFileSync as readFileSync10, rmSync, writeFileSync as writeFileSync8 } from "node:fs";
4191
+ import { mkdirSync as mkdirSync10, readFileSync as readFileSync10, rmSync, writeFileSync as writeFileSync8 } from "node:fs";
4183
4192
  import { join as join14 } from "node:path";
4184
4193
  import { homedir as homedir9 } from "node:os";
4185
4194
  var log5 = (msg) => log("query-cache", msg);
@@ -4204,7 +4213,7 @@ function writeCachedIndexContent(sessionId, content, deps = {}) {
4204
4213
  const { logFn = log5 } = deps;
4205
4214
  try {
4206
4215
  const dir = getSessionQueryCacheDir(sessionId, deps);
4207
- mkdirSync9(dir, { recursive: true });
4216
+ mkdirSync10(dir, { recursive: true });
4208
4217
  writeFileSync8(join14(dir, INDEX_CACHE_FILE), content, "utf-8");
4209
4218
  } catch (e) {
4210
4219
  logFn(`write failed for session=${sessionId}: ${e.message}`);
@@ -4372,7 +4381,227 @@ function rewritePaths(cmd) {
4372
4381
  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
4382
  }
4374
4383
 
4384
+ // dist/src/skillify/skillopt-trigger.js
4385
+ import { spawn as spawn2 } from "node:child_process";
4386
+ import fs from "node:fs";
4387
+ import path from "node:path";
4388
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
4389
+
4390
+ // dist/src/skillify/state-dir.js
4391
+ import { homedir as homedir11 } from "node:os";
4392
+ import { join as join16 } from "node:path";
4393
+ function getStateDir() {
4394
+ const override = process.env.HIVEMIND_STATE_DIR?.trim();
4395
+ return override && override.length > 0 ? override : join16(homedir11(), ".deeplake", "state", "skillify");
4396
+ }
4397
+
4398
+ // dist/src/skillify/skill-invocations.js
4399
+ function pathToSkillRef(s) {
4400
+ if (typeof s !== "string")
4401
+ return null;
4402
+ const m = s.match(/\/skills\/(?:[^/\s"'`]+\/)*([^/\s"'`]+)\/SKILL\.md/);
4403
+ return m ? m[1] : null;
4404
+ }
4405
+ function splitOrgSkill(skill) {
4406
+ if (skill.includes(":"))
4407
+ return null;
4408
+ if (skill.includes("/") || skill.includes("\\") || skill.includes(".."))
4409
+ return null;
4410
+ const i = skill.lastIndexOf("--");
4411
+ if (i <= 0 || i + 2 >= skill.length)
4412
+ return null;
4413
+ return { name: skill.slice(0, i), author: skill.slice(i + 2) };
4414
+ }
4415
+
4416
+ // dist/src/skillify/manifest.js
4417
+ import { existsSync as existsSync9, lstatSync, mkdirSync as mkdirSync11, readFileSync as readFileSync11, renameSync as renameSync7, unlinkSync as unlinkSync4, writeFileSync as writeFileSync9 } from "node:fs";
4418
+ import { dirname as dirname9, join as join18 } from "node:path";
4419
+
4420
+ // dist/src/skillify/legacy-migration.js
4421
+ import { existsSync as existsSync8, renameSync as renameSync6 } from "node:fs";
4422
+ import { dirname as dirname8, join as join17 } from "node:path";
4423
+ var dlog = (msg) => log("skillify-migrate", msg);
4424
+ var attempted = false;
4425
+ function migrateLegacyStateDir() {
4426
+ if (process.env.HIVEMIND_STATE_DIR?.trim())
4427
+ return;
4428
+ if (attempted)
4429
+ return;
4430
+ attempted = true;
4431
+ const current = getStateDir();
4432
+ const legacy = join17(dirname8(current), "skilify");
4433
+ if (!existsSync8(legacy))
4434
+ return;
4435
+ if (existsSync8(current))
4436
+ return;
4437
+ try {
4438
+ renameSync6(legacy, current);
4439
+ dlog(`migrated ${legacy} -> ${current}`);
4440
+ } catch (err) {
4441
+ const code = err.code;
4442
+ if (code === "EXDEV" || code === "EPERM" || code === "ENOENT" || code === "EEXIST" || code === "ENOTEMPTY") {
4443
+ dlog(`migration skipped (${code}); legacy dir left as-is or another process handled it`);
4444
+ return;
4445
+ }
4446
+ throw err;
4447
+ }
4448
+ }
4449
+
4450
+ // dist/src/skillify/manifest.js
4451
+ function emptyManifest() {
4452
+ return { version: 1, entries: [] };
4453
+ }
4454
+ function manifestPath() {
4455
+ return join18(getStateDir(), "pulled.json");
4456
+ }
4457
+ function loadManifest(path2 = manifestPath()) {
4458
+ migrateLegacyStateDir();
4459
+ if (!existsSync9(path2))
4460
+ return emptyManifest();
4461
+ let raw;
4462
+ try {
4463
+ raw = readFileSync11(path2, "utf-8");
4464
+ } catch {
4465
+ return emptyManifest();
4466
+ }
4467
+ try {
4468
+ const parsed = JSON.parse(raw);
4469
+ if (!parsed || typeof parsed !== "object")
4470
+ return emptyManifest();
4471
+ if (parsed.version !== 1 || !Array.isArray(parsed.entries))
4472
+ return emptyManifest();
4473
+ const entries = [];
4474
+ for (const e of parsed.entries) {
4475
+ if (!e || typeof e !== "object")
4476
+ continue;
4477
+ if (typeof e.dirName !== "string" || !e.dirName)
4478
+ continue;
4479
+ if (e.dirName.includes("/") || e.dirName.includes("\\") || e.dirName.includes(".."))
4480
+ continue;
4481
+ if (typeof e.name !== "string" || !e.name)
4482
+ continue;
4483
+ if (typeof e.author !== "string")
4484
+ continue;
4485
+ if (typeof e.installRoot !== "string" || !e.installRoot)
4486
+ continue;
4487
+ if (e.install !== "global" && e.install !== "project")
4488
+ continue;
4489
+ 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)
4490
+ !p.includes("..")) : [];
4491
+ entries.push({
4492
+ dirName: e.dirName,
4493
+ name: e.name,
4494
+ author: e.author,
4495
+ projectKey: typeof e.projectKey === "string" ? e.projectKey : "",
4496
+ remoteVersion: typeof e.remoteVersion === "number" ? e.remoteVersion : 1,
4497
+ install: e.install,
4498
+ installRoot: e.installRoot,
4499
+ pulledAt: typeof e.pulledAt === "string" ? e.pulledAt : (/* @__PURE__ */ new Date()).toISOString(),
4500
+ symlinks
4501
+ });
4502
+ }
4503
+ return { version: 1, entries };
4504
+ } catch {
4505
+ return emptyManifest();
4506
+ }
4507
+ }
4508
+
4509
+ // dist/src/skillify/skillopt-env.js
4510
+ var SKILLOPT_ENV = {
4511
+ /** User-set kill switch: "1" disables the whole trigger. */
4512
+ DISABLED: "HIVEMIND_SKILLOPT_DISABLED",
4513
+ /** Recursion guard the trigger sets on the spawned worker so the worker can't re-arm. */
4514
+ WORKER: "HIVEMIND_SKILLOPT_WORKER",
4515
+ /** Worker inputs, handed trigger → worker via the child env. */
4516
+ SESSION: "HIVEMIND_SKILLOPT_SESSION",
4517
+ SKILL: "HIVEMIND_SKILLOPT_SKILL",
4518
+ REACTION: "HIVEMIND_SKILLOPT_REACTION",
4519
+ TOOL_USE_ID: "HIVEMIND_SKILLOPT_TOOL_USE_ID",
4520
+ /** Which agent's CLI runs the judge/proposer (claude_code/codex/hermes/cursor/pi). */
4521
+ AGENT: "HIVEMIND_SKILLOPT_AGENT",
4522
+ /** K-message judgment-window size override. */
4523
+ JUDGE_WINDOW: "HIVEMIND_SKILLOPT_JUDGE_WINDOW"
4524
+ };
4525
+
4526
+ // dist/src/skillify/skillopt-trigger.js
4527
+ var DEFAULT_JUDGE_WINDOW = 3;
4528
+ function judgeWindow(env = process.env) {
4529
+ const n = Number(env[SKILLOPT_ENV.JUDGE_WINDOW]);
4530
+ return Number.isFinite(n) && n > 0 ? Math.floor(n) : DEFAULT_JUDGE_WINDOW;
4531
+ }
4532
+ function defaultIsOrgSkill(skillRef) {
4533
+ try {
4534
+ return loadManifest().entries.some((e) => e.dirName === skillRef);
4535
+ } catch {
4536
+ return false;
4537
+ }
4538
+ }
4539
+ function pendingFile(sessionId) {
4540
+ const safe = sessionId.replace(/[^A-Za-z0-9_-]/g, "_").slice(0, 200);
4541
+ return path.join(getStateDir(), "skillopt", "pending", `${safe}.json`);
4542
+ }
4543
+ var fileStore = {
4544
+ load(sessionId) {
4545
+ try {
4546
+ return JSON.parse(fs.readFileSync(pendingFile(sessionId), "utf8"));
4547
+ } catch {
4548
+ return null;
4549
+ }
4550
+ },
4551
+ save(sessionId, p) {
4552
+ try {
4553
+ const f = pendingFile(sessionId);
4554
+ if (p === null) {
4555
+ try {
4556
+ fs.unlinkSync(f);
4557
+ } catch {
4558
+ }
4559
+ return;
4560
+ }
4561
+ fs.mkdirSync(path.dirname(f), { recursive: true });
4562
+ const tmp = `${f}.${process.pid}.tmp`;
4563
+ fs.writeFileSync(tmp, JSON.stringify(p));
4564
+ fs.renameSync(tmp, f);
4565
+ } catch {
4566
+ }
4567
+ }
4568
+ };
4569
+ function markSkillPending(sessionId, skillRef, toolUseId, deps = {}) {
4570
+ if (!sessionId || !skillRef)
4571
+ return false;
4572
+ if (!splitOrgSkill(skillRef))
4573
+ return false;
4574
+ if (!(deps.isOrgSkill ?? defaultIsOrgSkill)(skillRef))
4575
+ return false;
4576
+ (deps.store ?? fileStore).save(sessionId, { skill: skillRef, budget: judgeWindow(deps.env ?? process.env), toolUseId });
4577
+ return true;
4578
+ }
4579
+
4580
+ // dist/src/hooks/shared/skillopt-hook.js
4581
+ function skillRefFromSkillFileRead(toolName, toolInput) {
4582
+ if (/^read$/i.test(toolName))
4583
+ return pathToSkillRef(toolInput?.path);
4584
+ return pathToSkillRef(toolInput?.command);
4585
+ }
4586
+ function armSkillOptOnSkillUse(sessionId, toolName, toolInput, toolUseId) {
4587
+ try {
4588
+ if (process.env[SKILLOPT_ENV.DISABLED] === "1")
4589
+ return;
4590
+ let ref = null;
4591
+ if (toolName === "Skill") {
4592
+ const s = toolInput?.skill;
4593
+ ref = typeof s === "string" ? s : null;
4594
+ } else {
4595
+ ref = skillRefFromSkillFileRead(toolName, toolInput);
4596
+ }
4597
+ if (ref)
4598
+ markSkillPending(sessionId, ref, toolUseId);
4599
+ } catch {
4600
+ }
4601
+ }
4602
+
4375
4603
  // dist/src/hooks/codex/pre-tool-use.js
4604
+ var __bundleDir = dirname10(fileURLToPath4(import.meta.url));
4376
4605
  var log6 = (msg) => log("codex-pre", msg);
4377
4606
  function buildUnsupportedGuidance() {
4378
4607
  return "This command is not supported for ~/.deeplake/memory/ operations. Only bash builtins are available: cat, ls, grep, echo, jq, head, tail, wc, sort, find, etc. Do NOT use python, python3, node, curl, or other interpreters. Rewrite your command using only bash tools and retry.";
@@ -4380,11 +4609,11 @@ function buildUnsupportedGuidance() {
4380
4609
  function buildIndexContent(rows) {
4381
4610
  const lines = ["# Memory Index", "", `${rows.length} sessions:`, ""];
4382
4611
  for (const row of rows) {
4383
- const path = row["path"];
4612
+ const path2 = row["path"];
4384
4613
  const project = row["project"] || "";
4385
4614
  const description = (row["description"] || "").slice(0, 120);
4386
4615
  const date = (row["creation_date"] || "").slice(0, 10);
4387
- lines.push(`- [${path}](${path}) ${date} ${project ? `[${project}]` : ""} ${description}`);
4616
+ lines.push(`- [${path2}](${path2}) ${date} ${project ? `[${project}]` : ""} ${description}`);
4388
4617
  }
4389
4618
  return lines.join("\n");
4390
4619
  }
@@ -4414,16 +4643,16 @@ async function processCodexPreToolUse(input, deps = {}) {
4414
4643
  const api = createApi(table, config);
4415
4644
  const readVirtualPathContentsWithCache = async (cachePaths) => {
4416
4645
  const uniquePaths = [...new Set(cachePaths)];
4417
- const result = new Map(uniquePaths.map((path) => [path, null]));
4646
+ const result = new Map(uniquePaths.map((path2) => [path2, null]));
4418
4647
  const cachedIndex = uniquePaths.includes("/index.md") ? readCachedIndexContentFn(input.session_id) : null;
4419
- const remainingPaths = cachedIndex === null ? uniquePaths : uniquePaths.filter((path) => path !== "/index.md");
4648
+ const remainingPaths = cachedIndex === null ? uniquePaths : uniquePaths.filter((path2) => path2 !== "/index.md");
4420
4649
  if (cachedIndex !== null) {
4421
4650
  result.set("/index.md", cachedIndex);
4422
4651
  }
4423
4652
  if (remainingPaths.length > 0) {
4424
4653
  const fetched = await readVirtualPathContentsFn(api, table, sessionsTable, remainingPaths);
4425
- for (const [path, content] of fetched)
4426
- result.set(path, content);
4654
+ for (const [path2, content] of fetched)
4655
+ result.set(path2, content);
4427
4656
  }
4428
4657
  const fetchedIndex = result.get("/index.md");
4429
4658
  if (typeof fetchedIndex === "string") {
@@ -4519,10 +4748,10 @@ async function processCodexPreToolUse(input, deps = {}) {
4519
4748
  const entries = /* @__PURE__ */ new Map();
4520
4749
  const prefix = dir === "/" ? "/" : `${dir}/`;
4521
4750
  for (const row of rows) {
4522
- const path = row["path"];
4523
- if (!path.startsWith(prefix) && dir !== "/")
4751
+ const path2 = row["path"];
4752
+ if (!path2.startsWith(prefix) && dir !== "/")
4524
4753
  continue;
4525
- const rest = dir === "/" ? path.slice(1) : path.slice(prefix.length);
4754
+ const rest = dir === "/" ? path2.slice(1) : path2.slice(prefix.length);
4526
4755
  const slash = rest.indexOf("/");
4527
4756
  const name = slash === -1 ? rest : rest.slice(0, slash);
4528
4757
  if (!name)
@@ -4582,15 +4811,29 @@ async function processCodexPreToolUse(input, deps = {}) {
4582
4811
  logFn(`direct query failed: ${e.message}`);
4583
4812
  }
4584
4813
  }
4585
- logFn(`unroutable memory command, blocking with guidance: ${rewritten}`);
4586
- return {
4587
- action: "block",
4588
- output: buildUnsupportedGuidance(),
4589
- rewrittenCommand: rewritten
4590
- };
4814
+ const isWriteRedirect = /^\s*(echo|printf|tee)\b/.test(rewritten) && /\s>>?\s/.test(rewritten);
4815
+ const shellBundle = join19(__bundleDir, "shell", "deeplake-shell.js");
4816
+ logFn(`unroutable memory command, falling back to VFS shell: ${rewritten}`);
4817
+ try {
4818
+ const proc = spawnSync("node", [shellBundle, "-c", rewritten], {
4819
+ encoding: "utf-8",
4820
+ timeout: 1e4
4821
+ });
4822
+ if (proc.status === 0 || proc.stdout && proc.stdout.trim()) {
4823
+ const output = (proc.stdout?.trim() ?? "") || "(done)";
4824
+ return { action: isWriteRedirect ? "guide" : "block", output, rewrittenCommand: rewritten };
4825
+ }
4826
+ return { action: "block", output: buildUnsupportedGuidance(), rewrittenCommand: rewritten };
4827
+ } catch {
4828
+ return { action: "block", output: buildUnsupportedGuidance(), rewrittenCommand: rewritten };
4829
+ }
4591
4830
  }
4592
4831
  async function main() {
4593
4832
  const input = await readStdin();
4833
+ try {
4834
+ armSkillOptOnSkillUse(input.session_id, input.tool_name, input.tool_input, input.tool_use_id);
4835
+ } catch {
4836
+ }
4594
4837
  const decision = await processCodexPreToolUse(input);
4595
4838
  if (decision.action === "pass")
4596
4839
  return;