agentsmesh 0.36.0 → 0.37.0

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.
@@ -383,13 +383,8 @@ declare function importLegacyLessons(projectRoot: string, options: ImportLegacyO
383
383
  /**
384
384
  * Cross-platform process lock backed by an atomic mkdir.
385
385
  *
386
- * Acquire semantics: mkdir with no `recursive` option is atomic per POSIX and
387
- * returns EEXIST if the directory already exists. That makes it a reliable
388
- * cross-process mutex without any third-party dependency.
389
- *
390
386
  * Stale recovery: the holder writes its PID and start timestamp into the lock
391
- * dir. On contention we peek at the PID: a dead same-host holder is evicted at
392
- * once. A live holder (or one on another host, whose PID we cannot probe) is
387
+ * dir. A dead same-host holder is evicted at once. A live or remote holder is
393
388
  * evicted only past `staleMs` — an hours-long bound that catches a hung
394
389
  * process or a recycled PID, never a slow but healthy run.
395
390
  */
package/dist/lessons.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { o as RankedLesson, j as LessonsQuery, A as AddLessonInput, a as AddLessonOptions, b as AddLessonResult } from './init-Dtp4V1_v.js';
2
- export { c as AddLessonTriggers, D as DEFAULT_RECALL_LIMIT, X as DEFAULT_RECALL_MAX_TOKENS, I as ImportLegacyOptions, d as ImportLegacyReport, Y as LESSONS_LOCK_FILENAME, L as LESSONS_PROCEDURAL_RULE, e as Lesson, f as LessonStatus, g as LessonsGraph, Z as LessonsGraphExistsError, h as LessonsGraphSchema, i as LessonsPaths, M as MatchedLesson, k as MergeLessonsOptions, l as MergeLessonsResult, m as MutateOptions, R as RankOptions, n as RankReason, S as ScaffoldLessonsResult, p as StripMarkersOptions, q as StripMarkersReport, T as Topic, r as Trigger, s as TriggerKind, U as UnknownTopicError, V as ValidationFinding, t as ValidationLevel, u as ValidationReport, v as acquireLessonsLock, w as addLesson, x as graphFilePath, y as importLegacyLessons, _ as lessonsLockPath, z as lessonsPaths, B as loadLessonsGraph, C as mergeLessons, E as mutateLessonsGraph, F as parseGraph, G as queryLessons, H as rankLessons, J as scaffoldLessons, K as serializeGraph, N as stripLegacyMarkers, O as stripMarkersInGraph, P as toRelPath, Q as tryLoadLessonsGraph, W as validateLessonsGraph } from './init-Dtp4V1_v.js';
1
+ import { o as RankedLesson, j as LessonsQuery, A as AddLessonInput, a as AddLessonOptions, b as AddLessonResult } from './init-BtgoRmIs.js';
2
+ export { c as AddLessonTriggers, D as DEFAULT_RECALL_LIMIT, X as DEFAULT_RECALL_MAX_TOKENS, I as ImportLegacyOptions, d as ImportLegacyReport, Y as LESSONS_LOCK_FILENAME, L as LESSONS_PROCEDURAL_RULE, e as Lesson, f as LessonStatus, g as LessonsGraph, Z as LessonsGraphExistsError, h as LessonsGraphSchema, i as LessonsPaths, M as MatchedLesson, k as MergeLessonsOptions, l as MergeLessonsResult, m as MutateOptions, R as RankOptions, n as RankReason, S as ScaffoldLessonsResult, p as StripMarkersOptions, q as StripMarkersReport, T as Topic, r as Trigger, s as TriggerKind, U as UnknownTopicError, V as ValidationFinding, t as ValidationLevel, u as ValidationReport, v as acquireLessonsLock, w as addLesson, x as graphFilePath, y as importLegacyLessons, _ as lessonsLockPath, z as lessonsPaths, B as loadLessonsGraph, C as mergeLessons, E as mutateLessonsGraph, F as parseGraph, G as queryLessons, H as rankLessons, J as scaffoldLessons, K as serializeGraph, N as stripLegacyMarkers, O as stripMarkersInGraph, P as toRelPath, Q as tryLoadLessonsGraph, W as validateLessonsGraph } from './init-BtgoRmIs.js';
3
3
  import 'zod';
4
4
 
5
5
  /**
package/dist/lessons.js CHANGED
@@ -2,11 +2,11 @@ import { z } from 'zod';
2
2
  import { readFileSync, existsSync, mkdirSync, writeFileSync, rmSync, statSync, renameSync, readdirSync, realpathSync, appendFileSync } from 'fs';
3
3
  import { resolve, dirname, join, relative, sep, basename, extname } from 'path';
4
4
  import { stringify, parse, parseDocument, YAMLSeq, YAMLMap } from 'yaml';
5
- import { createHash } from 'crypto';
5
+ import { createHash, randomUUID } from 'crypto';
6
6
  import picomatch from 'picomatch';
7
- import { mkdir, rm, writeFile, readFile, stat, lstat, unlink, rename, chmod } from 'fs/promises';
7
+ import { mkdir, rm, writeFile, readFile, stat, lstat, open, rename } from 'fs/promises';
8
8
  import { tmpdir, hostname } from 'os';
9
- import 'timers/promises';
9
+ import { setTimeout as setTimeout$1 } from 'timers/promises';
10
10
 
11
11
  // src/lessons/graph-schema.ts
12
12
  var CURRENT_GRAPH_VERSION = 2;
@@ -1190,8 +1190,7 @@ async function acquireProcessLock(lockPath, opts = {}) {
1190
1190
  if (acquired) return acquired;
1191
1191
  const existing = await inspectLock(lockPath);
1192
1192
  if (existing !== "young" && isStale(existing, stale)) {
1193
- await rm(lockPath, { recursive: true, force: true }).catch(() => {
1194
- });
1193
+ await rm(lockPath, { recursive: true, force: true });
1195
1194
  continue;
1196
1195
  }
1197
1196
  if (attempt >= retries) {
@@ -1215,7 +1214,13 @@ async function tryAcquire(lockPath) {
1215
1214
  started: Date.now(),
1216
1215
  hostname: getHostname()
1217
1216
  };
1218
- await writeFile(metadataPath, JSON.stringify(metadata), "utf-8");
1217
+ try {
1218
+ await writeFile(metadataPath, JSON.stringify(metadata), "utf-8");
1219
+ } catch (error) {
1220
+ await rm(lockPath, { recursive: true, force: true }).catch(() => {
1221
+ });
1222
+ throw error;
1223
+ }
1219
1224
  let released = false;
1220
1225
  const cleanup = () => {
1221
1226
  if (released) return;
@@ -3038,6 +3043,91 @@ function shouldNormalizeLineEndings(path) {
3038
3043
  const base = basename(path).toLowerCase();
3039
3044
  return TEXT_DOTFILES.has(base);
3040
3045
  }
3046
+ var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
3047
+ ".png",
3048
+ ".jpg",
3049
+ ".jpeg",
3050
+ ".gif",
3051
+ ".bmp",
3052
+ ".ico",
3053
+ ".webp",
3054
+ ".avif",
3055
+ ".tiff",
3056
+ ".pdf",
3057
+ ".zip",
3058
+ ".gz",
3059
+ ".tgz",
3060
+ ".bz2",
3061
+ ".xz",
3062
+ ".7z",
3063
+ ".rar",
3064
+ ".jar",
3065
+ ".woff",
3066
+ ".woff2",
3067
+ ".ttf",
3068
+ ".otf",
3069
+ ".eot",
3070
+ ".mp3",
3071
+ ".mp4",
3072
+ ".wav",
3073
+ ".ogg",
3074
+ ".webm",
3075
+ ".mov",
3076
+ ".wasm",
3077
+ ".bin",
3078
+ ".dat",
3079
+ ".db",
3080
+ ".sqlite",
3081
+ ".so",
3082
+ ".dylib",
3083
+ ".dll",
3084
+ ".exe",
3085
+ ".class",
3086
+ ".pyc",
3087
+ // Office and design documents are zip or proprietary containers.
3088
+ ".xlsx",
3089
+ ".xls",
3090
+ ".docx",
3091
+ ".doc",
3092
+ ".pptx",
3093
+ ".ppt",
3094
+ ".odt",
3095
+ ".ods",
3096
+ ".psd",
3097
+ ".ai",
3098
+ ".sketch",
3099
+ ".fig",
3100
+ ".heic",
3101
+ ".heif",
3102
+ // Archives, columnar data, models and compressed payloads.
3103
+ ".tar",
3104
+ ".zst",
3105
+ ".br",
3106
+ ".lz4",
3107
+ ".parquet",
3108
+ ".avro",
3109
+ ".orc",
3110
+ ".pkl",
3111
+ ".npy",
3112
+ ".npz",
3113
+ ".onnx",
3114
+ ".pt",
3115
+ ".safetensors",
3116
+ ".gguf",
3117
+ ".sqlite3",
3118
+ ".avi",
3119
+ ".mkv",
3120
+ ".flac",
3121
+ ".aac",
3122
+ ".m4a",
3123
+ ".ttc"
3124
+ ]);
3125
+ function isBinaryPayloadPath(path) {
3126
+ return BINARY_EXTENSIONS.has(extname(path).toLowerCase());
3127
+ }
3128
+ function payloadEncodingFor(path) {
3129
+ return isBinaryPayloadPath(path) ? "latin1" : "utf-8";
3130
+ }
3041
3131
  function normalizeLineEndings(content) {
3042
3132
  return content.replace(/\r\n?/g, "\n");
3043
3133
  }
@@ -3045,11 +3135,28 @@ var EXECUTABLE_SCRIPT_EXTENSIONS = /* @__PURE__ */ new Set([".sh", ".bash", ".zs
3045
3135
  function executableModeFor(path) {
3046
3136
  return EXECUTABLE_SCRIPT_EXTENSIONS.has(extname(path).toLowerCase()) ? 493 : void 0;
3047
3137
  }
3138
+ var TRANSIENT_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EACCES", "EBUSY", "ENOTEMPTY", "EEXIST"]);
3139
+ async function renameWithRetry(from, to, options = {}) {
3140
+ const attempts = options.attempts ?? 5;
3141
+ const delayMs = options.delayMs ?? 50;
3142
+ for (let attempt = 0; ; attempt++) {
3143
+ try {
3144
+ await rename(from, to);
3145
+ return;
3146
+ } catch (err) {
3147
+ const code = err.code;
3148
+ const transient = code !== void 0 && TRANSIENT_RENAME_CODES.has(code);
3149
+ if (!transient || attempt >= attempts - 1) throw err;
3150
+ await setTimeout$1(delayMs * 2 ** attempt);
3151
+ }
3152
+ }
3153
+ }
3048
3154
 
3049
3155
  // src/utils/filesystem/fs.ts
3050
3156
  async function readFileSafe(path) {
3051
3157
  try {
3052
- const data = await readFile(path, "utf-8");
3158
+ const data = await readFile(path, payloadEncodingFor(path));
3159
+ if (isBinaryPayloadPath(path)) return data;
3053
3160
  return data.startsWith(UTF8_BOM) ? data.slice(UTF8_BOM.length) : data;
3054
3161
  } catch (err) {
3055
3162
  const e = err;
@@ -3073,40 +3180,28 @@ async function writeFileAtomic(path, content, options) {
3073
3180
  { errnoCode: "EISDIR" }
3074
3181
  );
3075
3182
  }
3076
- if (info.isSymbolicLink()) {
3077
- await unlink(path).catch((e) => {
3078
- if (e.code !== "ENOENT") throw e;
3079
- });
3080
- }
3081
3183
  } catch (err) {
3082
3184
  if (err instanceof FileSystemError) throw err;
3083
3185
  const e = err;
3084
3186
  if (e.code !== "ENOENT") throw err;
3085
3187
  }
3086
- const tmpPath = `${path}.tmp`;
3188
+ const tmpPath = `${path}.tmp-${randomUUID()}`;
3087
3189
  const payload = shouldNormalizeLineEndings(path) ? normalizeLineEndings(content) : content;
3088
3190
  const mode = executableModeFor(path);
3191
+ let handle;
3192
+ let ownsTemporaryFile = false;
3089
3193
  try {
3090
- try {
3091
- const tmpInfo = await lstat(tmpPath);
3092
- if (tmpInfo.isSymbolicLink()) {
3093
- await unlink(tmpPath);
3094
- }
3095
- } catch (tmpErr) {
3096
- if (tmpErr.code !== "ENOENT") throw tmpErr;
3097
- }
3098
- const writeOpts = {
3099
- encoding: "utf-8",
3100
- flag: "w"
3101
- };
3102
- if (mode !== void 0) writeOpts.mode = mode;
3103
- await writeFile(tmpPath, payload, writeOpts);
3104
- await rename(tmpPath, path);
3105
- if (mode !== void 0) {
3106
- await chmod(path, mode);
3107
- }
3194
+ handle = await open(tmpPath, "wx", mode);
3195
+ ownsTemporaryFile = true;
3196
+ await handle.writeFile(payload, payloadEncodingFor(path));
3197
+ if (mode !== void 0) await handle.chmod(mode);
3198
+ await handle.close();
3199
+ handle = void 0;
3200
+ await renameWithRetry(tmpPath, path);
3108
3201
  } catch (err) {
3109
- await rm(tmpPath, { force: true }).catch(() => {
3202
+ await handle?.close().catch(() => {
3203
+ });
3204
+ if (ownsTemporaryFile) await rm(tmpPath, { force: true }).catch(() => {
3110
3205
  });
3111
3206
  const e = err;
3112
3207
  throw new FileSystemError(