@signetai/connector-hermes-agent 0.228.7 → 0.229.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,KAAK,eAAe,EAAuB,MAAM,wBAAwB,CAAC;AAqCtH,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,CAAC,EAAE,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC;IACxD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAClD,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAmqCD,qBAAa,oBAAqB,SAAQ,aAAa;IACtD,QAAQ,CAAC,IAAI,kBAAkB;IAC/B,QAAQ,CAAC,SAAS,kBAAkB;IAEpC,YAAY,IAAI,MAAM;IAItB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAwB;gBAEpC,MAAM,CAAC,EAAE,qBAAqB;IAK1C,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,aAAa;IAKrB,aAAa,IAAI,MAAM;IAKjB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,aAAa,CAAC;IAyLvF,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC;IA4D3C,WAAW,IAAI,OAAO;IAShB,QAAQ,IAAI,OAAO,CAAC,kBAAkB,CAAC;CAU7C;AAED,wBAAsB,yBAAyB,CAAC,IAAI,CAAC,EAAE;IACtD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAwG9B;AAED,wBAAgB,eAAe,IAAI,oBAAoB,CAEtD;AAED,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,KAAK,eAAe,EAAuB,MAAM,wBAAwB,CAAC;AAqCtH,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,CAAC,EAAE,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC;IACxD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAClD,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAs7CD,qBAAa,oBAAqB,SAAQ,aAAa;IACtD,QAAQ,CAAC,IAAI,kBAAkB;IAC/B,QAAQ,CAAC,SAAS,kBAAkB;IAEpC,YAAY,IAAI,MAAM;IAItB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAwB;gBAEpC,MAAM,CAAC,EAAE,qBAAqB;IAK1C,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,aAAa;IAKrB,aAAa,IAAI,MAAM;IAKjB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,aAAa,CAAC;IAyLvF,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC;IA4D3C,WAAW,IAAI,OAAO;IAShB,QAAQ,IAAI,OAAO,CAAC,kBAAkB,CAAC;CAU7C;AAED,wBAAsB,yBAAyB,CAAC,IAAI,CAAC,EAAE;IACtD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAwG9B;AAED,wBAAgB,eAAe,IAAI,oBAAoB,CAEtD;AAED,eAAe,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -35209,7 +35209,10 @@ ${content}`);
35209
35209
  async inspectHealth() {
35210
35210
  try {
35211
35211
  if (this.isInstalled()) {
35212
- return { status: "unknown", message: "Integration detected; runtime health has not been verified." };
35212
+ return {
35213
+ status: "unknown",
35214
+ message: "Signet integration files are installed. This connector does not check runtime health."
35215
+ };
35213
35216
  }
35214
35217
  if (this.isDetected()) {
35215
35218
  return { status: "degraded", message: "Harness detected; Signet integration is not configured." };
@@ -35217,7 +35220,7 @@ ${content}`);
35217
35220
  return { status: "unhealthy", message: "Signet integration is not installed." };
35218
35221
  } catch (error) {
35219
35222
  const message = error instanceof Error ? error.message : String(error);
35220
- return { status: "unhealthy", message: `Health inspection failed: ${message}` };
35223
+ return { status: "unknown", message: `Health inspection failed: ${message}` };
35221
35224
  }
35222
35225
  }
35223
35226
  getRecoveryCapabilities() {
@@ -35317,14 +35320,17 @@ function closeDirectory(fd) {
35317
35320
  }
35318
35321
  var SECURE_REMOVAL_CHANGED_STATUS = 75;
35319
35322
  var SECURE_REMOVAL_SCRIPT = [
35320
- "import os, sys",
35323
+ "import ctypes, os, secrets, stat, sys",
35321
35324
  "expected_dev = int(sys.argv[1])",
35322
35325
  "expected_ino = int(sys.argv[2])",
35323
35326
  "operation = sys.argv[3]",
35324
35327
  "name = sys.argv[4]",
35325
35328
  "expected_parent = sys.argv[5]",
35326
- "descriptor_root = sys.argv[6]",
35327
- "if os.path.realpath(os.path.join(descriptor_root, '3')) != expected_parent:",
35329
+ "expected_parent_stat = os.stat(expected_parent, follow_symlinks=False)",
35330
+ "if os.path.realpath(expected_parent) != expected_parent:",
35331
+ " raise SystemExit(75)",
35332
+ "opened_parent_stat = os.fstat(3)",
35333
+ "if (opened_parent_stat.st_dev, opened_parent_stat.st_ino) != (expected_parent_stat.st_dev, expected_parent_stat.st_ino):",
35328
35334
  " raise SystemExit(75)",
35329
35335
  "try:",
35330
35336
  " current = os.stat(name, dir_fd=3, follow_symlinks=False)",
@@ -35332,15 +35338,186 @@ var SECURE_REMOVAL_SCRIPT = [
35332
35338
  " raise SystemExit(75)",
35333
35339
  "if current.st_dev != expected_dev or current.st_ino != expected_ino:",
35334
35340
  " raise SystemExit(75)",
35341
+ "if operation == 'verify':",
35342
+ " raise SystemExit(0)",
35343
+ "if operation not in ('directory', 'file'):",
35344
+ " raise SystemExit(76)",
35345
+ "libc = ctypes.CDLL(None, use_errno=True)",
35346
+ "if sys.platform == 'darwin':",
35347
+ " rename_function = getattr(libc, 'renameatx_np', None)",
35348
+ " rename_flags = 4",
35349
+ "elif sys.platform.startswith('linux'):",
35350
+ " rename_function = getattr(libc, 'renameat2', None)",
35351
+ " rename_flags = 1",
35352
+ "else:",
35353
+ " rename_function = None",
35354
+ " rename_flags = 0",
35355
+ "if rename_function is None:",
35356
+ " raise OSError('exclusive descriptor-relative rename is unavailable')",
35357
+ "rename_function.argtypes = [ctypes.c_int, ctypes.c_char_p, ctypes.c_int, ctypes.c_char_p, ctypes.c_uint]",
35358
+ "rename_function.restype = ctypes.c_int",
35359
+ "def rename_exclusive(source_fd, source_name, destination_fd, destination_name):",
35360
+ " result = rename_function(source_fd, os.fsencode(source_name), destination_fd, os.fsencode(destination_name), rename_flags)",
35361
+ " if result != 0:",
35362
+ " error = ctypes.get_errno()",
35363
+ " raise OSError(error, os.strerror(error), source_name)",
35364
+ "quarantine = None",
35365
+ "for attempt in range(8):",
35366
+ " candidate = '.signet-remove-' + secrets.token_hex(16)",
35367
+ " try:",
35368
+ " os.mkdir(candidate, 0o700, dir_fd=3)",
35369
+ " quarantine = candidate",
35370
+ " break",
35371
+ " except FileExistsError:",
35372
+ " pass",
35373
+ "if quarantine is None:",
35374
+ " raise OSError('could not allocate a private removal directory')",
35375
+ "quarantine_fd = os.open(quarantine, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW, dir_fd=3)",
35376
+ "changed = False",
35377
+ "entry_moved = False",
35378
+ "try:",
35379
+ " os.fchmod(quarantine_fd, 0o700)",
35380
+ " try:",
35381
+ " rename_exclusive(3, name, quarantine_fd, 'entry')",
35382
+ " entry_moved = True",
35383
+ " except FileNotFoundError:",
35384
+ " changed = True",
35385
+ " if not changed:",
35386
+ " moved = os.stat('entry', dir_fd=quarantine_fd, follow_symlinks=False)",
35387
+ " if moved.st_dev != expected_dev or moved.st_ino != expected_ino:",
35388
+ " try:",
35389
+ " rename_exclusive(quarantine_fd, 'entry', 3, name)",
35390
+ " entry_moved = False",
35391
+ " except OSError as restore_error:",
35392
+ " print(f'recovery entry retained at {expected_parent}/{quarantine}/entry: {restore_error}', file=sys.stderr)",
35393
+ " changed = True",
35394
+ " elif operation == 'directory':",
35395
+ " if not stat.S_ISDIR(moved.st_mode):",
35396
+ " try:",
35397
+ " rename_exclusive(quarantine_fd, 'entry', 3, name)",
35398
+ " entry_moved = False",
35399
+ " except OSError as restore_error:",
35400
+ " print(f'recovery entry retained at {expected_parent}/{quarantine}/entry: {restore_error}', file=sys.stderr)",
35401
+ " changed = True",
35402
+ " else:",
35403
+ " os.rmdir('entry', dir_fd=quarantine_fd)",
35404
+ " entry_moved = False",
35405
+ " elif stat.S_ISDIR(moved.st_mode):",
35406
+ " try:",
35407
+ " rename_exclusive(quarantine_fd, 'entry', 3, name)",
35408
+ " entry_moved = False",
35409
+ " except OSError as restore_error:",
35410
+ " print(f'recovery entry retained at {expected_parent}/{quarantine}/entry: {restore_error}', file=sys.stderr)",
35411
+ " changed = True",
35412
+ " else:",
35413
+ " os.unlink('entry', dir_fd=quarantine_fd)",
35414
+ " entry_moved = False",
35415
+ "except Exception as error:",
35416
+ " if entry_moved:",
35417
+ " print(f'recovery entry retained at {expected_parent}/{quarantine}/entry: {error}', file=sys.stderr)",
35418
+ " else:",
35419
+ " try:",
35420
+ " os.rmdir(quarantine, dir_fd=3)",
35421
+ " except OSError:",
35422
+ " pass",
35423
+ " raise",
35424
+ "finally:",
35425
+ " os.close(quarantine_fd)",
35426
+ "if changed:",
35427
+ " try:",
35428
+ " os.rmdir(quarantine, dir_fd=3)",
35429
+ " except OSError:",
35430
+ " pass",
35431
+ " raise SystemExit(75)",
35432
+ "os.rmdir(quarantine, dir_fd=3)"
35433
+ ].join(`
35434
+ `);
35435
+ var SECURE_CREATE_DIRECTORIES_SCRIPT = [
35436
+ "import os, sys",
35437
+ "expected = os.stat(sys.argv[1], follow_symlinks=False)",
35438
+ "opened = os.fstat(3)",
35439
+ "if (opened.st_dev, opened.st_ino) != (expected.st_dev, expected.st_ino):",
35440
+ " raise SystemExit(75)",
35441
+ "fd = os.dup(3)",
35442
+ "try:",
35443
+ " for name in sys.argv[2:]:",
35444
+ " try:",
35445
+ " os.mkdir(name, dir_fd=fd)",
35446
+ " except FileExistsError:",
35447
+ " pass",
35448
+ " entry = os.stat(name, dir_fd=fd, follow_symlinks=False)",
35449
+ " child = os.open(name, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW, dir_fd=fd)",
35450
+ " opened = os.fstat(child)",
35451
+ " if (entry.st_dev, entry.st_ino) != (opened.st_dev, opened.st_ino):",
35452
+ " os.close(child)",
35453
+ " raise SystemExit(75)",
35454
+ " os.close(fd)",
35455
+ " fd = child",
35456
+ "finally:",
35457
+ " os.close(fd)"
35458
+ ].join(`
35459
+ `);
35460
+ var SECURE_WRITE_FILE_SCRIPT = [
35461
+ "import os, stat, sys",
35462
+ "expected = os.stat(sys.argv[1], follow_symlinks=False)",
35463
+ "opened = os.fstat(3)",
35464
+ "if (opened.st_dev, opened.st_ino) != (expected.st_dev, expected.st_ino):",
35465
+ " raise SystemExit(75)",
35466
+ "fd = os.dup(3)",
35467
+ "try:",
35468
+ " for name in sys.argv[2:-1]:",
35469
+ " entry = os.stat(name, dir_fd=fd, follow_symlinks=False)",
35470
+ " child = os.open(name, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW, dir_fd=fd)",
35471
+ " opened = os.fstat(child)",
35472
+ " if (entry.st_dev, entry.st_ino) != (opened.st_dev, opened.st_ino):",
35473
+ " os.close(child)",
35474
+ " raise SystemExit(75)",
35475
+ " os.close(fd)",
35476
+ " fd = child",
35477
+ " name = sys.argv[-1]",
35478
+ " try:",
35479
+ " entry = os.stat(name, dir_fd=fd, follow_symlinks=False)",
35480
+ " if not stat.S_ISREG(entry.st_mode):",
35481
+ " raise SystemExit(76)",
35482
+ " flags = os.O_WRONLY | os.O_NOFOLLOW",
35483
+ " except FileNotFoundError:",
35484
+ " entry = None",
35485
+ " flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW",
35486
+ " file_fd = os.open(name, flags, 0o666, dir_fd=fd)",
35487
+ " try:",
35488
+ " opened = os.fstat(file_fd)",
35489
+ " if entry is not None and (entry.st_dev, entry.st_ino) != (opened.st_dev, opened.st_ino):",
35490
+ " raise SystemExit(75)",
35491
+ " os.ftruncate(file_fd, 0)",
35492
+ " view = memoryview(sys.stdin.buffer.read())",
35493
+ " while view:",
35494
+ " written = os.write(file_fd, view)",
35495
+ " view = view[written:]",
35496
+ " finally:",
35497
+ " os.close(file_fd)",
35498
+ "finally:",
35499
+ " os.close(fd)"
35500
+ ].join(`
35501
+ `);
35502
+ var SECURE_READ_FILE_SCRIPT = [
35503
+ "import os, stat, sys",
35335
35504
  "try:",
35336
- " if operation == 'directory':",
35337
- " os.rmdir(name, dir_fd=3)",
35338
- " elif operation == 'file':",
35339
- " os.unlink(name, dir_fd=3)",
35340
- " elif operation != 'verify':",
35341
- " raise SystemExit(76)",
35505
+ " fd = os.open(sys.argv[-1], os.O_RDONLY | os.O_NOFOLLOW | os.O_NONBLOCK, dir_fd=3)",
35342
35506
  "except FileNotFoundError:",
35343
- " raise SystemExit(75)"
35507
+ " raise SystemExit(0)",
35508
+ "try:",
35509
+ " if not stat.S_ISREG(os.fstat(fd).st_mode):",
35510
+ " raise SystemExit(0)",
35511
+ " content = bytearray()",
35512
+ " while len(content) <= 65536:",
35513
+ " chunk = os.read(fd, min(4096, 65537 - len(content)))",
35514
+ " if not chunk:",
35515
+ " break",
35516
+ " content.extend(chunk)",
35517
+ " if len(content) <= 65536:",
35518
+ " sys.stdout.buffer.write(content)",
35519
+ "finally:",
35520
+ " os.close(fd)"
35344
35521
  ].join(`
35345
35522
  `);
35346
35523
  function getPythonCandidates() {
@@ -35355,6 +35532,30 @@ function getPythonCandidates() {
35355
35532
  { command: "python", args: [] }
35356
35533
  ];
35357
35534
  }
35535
+ function runSecureFilesystemOperation(fd, rootPath, script, args, input) {
35536
+ if (DESCRIPTOR_ROOT3 === null)
35537
+ throw new Error(DESCRIPTOR_WRITE_UNAVAILABLE_ERROR);
35538
+ const errors = [];
35539
+ for (const candidate of getPythonCandidates()) {
35540
+ const result = spawnSyncHidden(candidate.command, [...candidate.args, "-c", script, rootPath, ...args], {
35541
+ encoding: "utf-8",
35542
+ input: input === undefined ? undefined : Buffer.from(input),
35543
+ stdio: [input === undefined ? "ignore" : "pipe", "pipe", "pipe", fd],
35544
+ timeout: 5000
35545
+ });
35546
+ if (result.error) {
35547
+ errors.push(`${candidate.command}: ${result.error.message}`);
35548
+ continue;
35549
+ }
35550
+ if (result.status === 0)
35551
+ return result.stdout;
35552
+ if (result.status === 75)
35553
+ throw new Error("Hermes directory entry changed during secure write");
35554
+ const detail = result.stderr.trim();
35555
+ errors.push(`${candidate.command}: ${detail || `exited ${result.status ?? "without a status"}`}`);
35556
+ }
35557
+ throw new Error(`${DESCRIPTOR_WRITE_UNAVAILABLE_ERROR}: ${errors.join("; ") || "No Python interpreter found"}`);
35558
+ }
35358
35559
  function runSecureEntryOperation(parentFd, parentPath, name, expectedDev, expectedIno, operation) {
35359
35560
  if (DESCRIPTOR_ROOT3 === null)
35360
35561
  throw new Error(DESCRIPTOR_WRITE_UNAVAILABLE_ERROR);
@@ -35368,8 +35569,7 @@ function runSecureEntryOperation(parentFd, parentPath, name, expectedDev, expect
35368
35569
  String(expectedIno),
35369
35570
  operation,
35370
35571
  name,
35371
- parentPath,
35372
- DESCRIPTOR_ROOT3
35572
+ parentPath
35373
35573
  ], {
35374
35574
  encoding: "utf-8",
35375
35575
  stdio: ["ignore", "pipe", "pipe", parentFd],
@@ -35382,9 +35582,11 @@ function runSecureEntryOperation(parentFd, parentPath, name, expectedDev, expect
35382
35582
  if (result.status === 0)
35383
35583
  return;
35384
35584
  if (result.status === SECURE_REMOVAL_CHANGED_STATUS) {
35385
- throw new Error(`Hermes directory entry changed during secure removal: ${name}`);
35585
+ const detail = result.stderr.trim();
35586
+ throw new Error(`Hermes directory entry changed during secure removal: ${name}${detail ? ` (${detail})` : ""}`);
35386
35587
  }
35387
- errors.push(`${candidate.command}: exited ${result.status ?? "without a status"}`);
35588
+ const detail = result.stderr.trim();
35589
+ errors.push(`${candidate.command}: ${detail || `exited ${result.status ?? "without a status"}`}`);
35388
35590
  }
35389
35591
  throw new Error(`${DESCRIPTOR_WRITE_UNAVAILABLE_ERROR}: ${errors.join("; ") || "No Python interpreter found"}`);
35390
35592
  }
@@ -35397,6 +35599,12 @@ function removeEntryNoFollow(parentFd, parentPath, name, expectedDev, expectedIn
35397
35599
  function sameStatIdentity(left, right) {
35398
35600
  return left.dev === right.dev && left.ino === right.ino;
35399
35601
  }
35602
+ function assertDescriptorPathIdentity(fd, path, message) {
35603
+ const pathStat = lstatSync(path);
35604
+ if (realpathSync3(path) !== path || pathStat.isSymbolicLink() || !sameStatIdentity(fstatSync3(fd), pathStat)) {
35605
+ throw new Error(message);
35606
+ }
35607
+ }
35400
35608
  function ensureContainedDirectory(directory, targetRoot) {
35401
35609
  const safeDirectory = resolveContainedWritePath(directory, targetRoot);
35402
35610
  if (!DESCRIPTOR_WRITES_SUPPORTED) {
@@ -35420,6 +35628,15 @@ function ensureContainedDirectory(directory, targetRoot) {
35420
35628
  if (existingReal !== existing) {
35421
35629
  throw new Error(`Hermes target directory is symlinked and cannot be used for writes: ${directory}`);
35422
35630
  }
35631
+ if (process.platform === "darwin") {
35632
+ const fd = openDirectoryNoFollow(existing);
35633
+ try {
35634
+ runSecureFilesystemOperation(fd, existingReal, SECURE_CREATE_DIRECTORIES_SCRIPT, missing);
35635
+ } finally {
35636
+ closeDirectory(fd);
35637
+ }
35638
+ return;
35639
+ }
35423
35640
  let fd = openDirectoryNoFollow(existing);
35424
35641
  let expected = existingReal;
35425
35642
  try {
@@ -35456,6 +35673,24 @@ function writeContainedFile(targetPath, content, targetRoot) {
35456
35673
  }
35457
35674
  const rootPath = resolvePath(targetRoot);
35458
35675
  ensureContainedDirectory(dirname4(safePath), targetRoot);
35676
+ if (process.platform === "darwin") {
35677
+ const relativePath = relative2(rootPath, safePath);
35678
+ if (!relativePath || relativePath.startsWith("..") || isAbsolute2(relativePath)) {
35679
+ throw new Error(`Hermes target file escapes validated root: ${targetPath}`);
35680
+ }
35681
+ const components = relativePath.split(sep2);
35682
+ const fileName = components.pop();
35683
+ if (!fileName || components.some((component) => component === "" || component === "." || component === "..")) {
35684
+ throw new Error(`Hermes target file has an invalid relative path: ${targetPath}`);
35685
+ }
35686
+ const fd = openDirectoryNoFollow(rootPath);
35687
+ try {
35688
+ runSecureFilesystemOperation(fd, rootPath, SECURE_WRITE_FILE_SCRIPT, [...components, fileName], content);
35689
+ } finally {
35690
+ closeDirectory(fd);
35691
+ }
35692
+ return;
35693
+ }
35459
35694
  const relativePath = relative2(rootPath, safePath);
35460
35695
  if (!relativePath || relativePath.startsWith("..") || isAbsolute2(relativePath)) {
35461
35696
  throw new Error(`Hermes target file escapes validated root: ${targetPath}`);
@@ -35576,19 +35811,28 @@ function resolveContainedWritePath(targetPath, targetRoot) {
35576
35811
  return candidate;
35577
35812
  }
35578
35813
  function removeDirectoryContentsNoFollow(directoryFd, expectedDirectoryPath) {
35579
- if (realpathSync3(descriptorPath(directoryFd)) !== expectedDirectoryPath) {
35580
- throw new Error(`Hermes target directory changed during secure removal: ${expectedDirectoryPath}`);
35581
- }
35582
- for (const entry of readdirSync(descriptorPath(directoryFd), { withFileTypes: true })) {
35583
- const childPath = join5(descriptorPath(directoryFd), entry.name);
35814
+ assertDescriptorPathIdentity(directoryFd, expectedDirectoryPath, `Hermes target directory changed during secure removal: ${expectedDirectoryPath}`);
35815
+ const directoryEntriesPath = process.platform === "darwin" ? expectedDirectoryPath : descriptorPath(directoryFd);
35816
+ const entries = readdirSync(directoryEntriesPath, { withFileTypes: true });
35817
+ entries.sort((left, right) => {
35818
+ if (left.name === INSTALL_MARKER_FILE)
35819
+ return 1;
35820
+ if (right.name === INSTALL_MARKER_FILE)
35821
+ return -1;
35822
+ if (left.name < right.name)
35823
+ return -1;
35824
+ if (left.name > right.name)
35825
+ return 1;
35826
+ return 0;
35827
+ });
35828
+ for (const entry of entries) {
35829
+ const childPath = process.platform === "darwin" ? join5(expectedDirectoryPath, entry.name) : join5(descriptorPath(directoryFd), entry.name);
35584
35830
  const expectedChildPath = join5(expectedDirectoryPath, entry.name);
35585
35831
  if (entry.isDirectory() && !entry.isSymbolicLink()) {
35586
35832
  const childFd = openDirectoryNoFollow(childPath);
35587
35833
  try {
35588
35834
  const childIdentity = fstatSync3(childFd);
35589
- if (realpathSync3(descriptorPath(childFd)) !== expectedChildPath) {
35590
- throw new Error(`Hermes target directory changed during secure removal: ${expectedChildPath}`);
35591
- }
35835
+ assertDescriptorPathIdentity(childFd, expectedChildPath, `Hermes target directory changed during secure removal: ${expectedChildPath}`);
35592
35836
  assertEntryIdentityNoFollow(directoryFd, expectedDirectoryPath, entry.name, childIdentity.dev, childIdentity.ino);
35593
35837
  removeDirectoryContentsNoFollow(childFd, expectedChildPath);
35594
35838
  removeEntryNoFollow(directoryFd, expectedDirectoryPath, entry.name, childIdentity.dev, childIdentity.ino, true);
@@ -35601,7 +35845,7 @@ function removeDirectoryContentsNoFollow(directoryFd, expectedDirectoryPath) {
35601
35845
  removeEntryNoFollow(directoryFd, expectedDirectoryPath, entry.name, childIdentity.dev, childIdentity.ino, false);
35602
35846
  }
35603
35847
  }
35604
- function removeContainedDirectory(targetPath, targetRoot, targetKind) {
35848
+ function removeContainedDirectory(targetPath, targetRoot, targetKind, unownedTargetBehavior) {
35605
35849
  if (!DESCRIPTOR_WRITES_SUPPORTED)
35606
35850
  throw new Error(DESCRIPTOR_WRITE_UNAVAILABLE_ERROR);
35607
35851
  const safeTargetDir = resolveContainedWritePath(targetPath, targetRoot);
@@ -35619,12 +35863,11 @@ function removeContainedDirectory(targetPath, targetRoot, targetKind) {
35619
35863
  try {
35620
35864
  let expected = rootPath;
35621
35865
  for (const component of components) {
35622
- const childFd = openDirectoryNoFollow(join5(descriptorPath(parentFd), component));
35866
+ const childPath = process.platform === "darwin" ? join5(expected, component) : join5(descriptorPath(parentFd), component);
35867
+ const childFd = openDirectoryNoFollow(childPath);
35623
35868
  try {
35624
35869
  expected = join5(expected, component);
35625
- if (realpathSync3(descriptorPath(childFd)) !== expected) {
35626
- throw new Error(`Hermes target directory changed during secure removal: ${targetPath}`);
35627
- }
35870
+ assertDescriptorPathIdentity(childFd, expected, `Hermes target directory changed during secure removal: ${targetPath}`);
35628
35871
  } catch (error) {
35629
35872
  closeDirectory(childFd);
35630
35873
  throw error;
@@ -35632,21 +35875,22 @@ function removeContainedDirectory(targetPath, targetRoot, targetKind) {
35632
35875
  closeDirectory(parentFd);
35633
35876
  parentFd = childFd;
35634
35877
  }
35635
- const targetEntryPath = join5(descriptorPath(parentFd), targetName);
35878
+ const expectedTarget = join5(expected, targetName);
35879
+ const targetEntryPath = process.platform === "darwin" ? expectedTarget : join5(descriptorPath(parentFd), targetName);
35636
35880
  const targetFd = openDirectoryNoFollow(targetEntryPath);
35637
35881
  try {
35638
35882
  const targetIdentity = fstatSync3(targetFd);
35639
- const expectedTarget = join5(expected, targetName);
35640
- if (realpathSync3(descriptorPath(targetFd)) !== expectedTarget) {
35641
- throw new Error(`Hermes target directory changed during secure removal: ${targetPath}`);
35642
- }
35643
- const marker = readInstallMarkerFromDirectory(targetFd);
35883
+ assertDescriptorPathIdentity(targetFd, expectedTarget, `Hermes target directory changed during secure removal: ${targetPath}`);
35884
+ const marker = readInstallMarkerFromDirectory(targetFd, expectedTarget);
35644
35885
  if (marker === null || marker.targetKind !== targetKind) {
35886
+ if (unownedTargetBehavior === "skip")
35887
+ return false;
35645
35888
  throw new Error(`Refusing to uninstall unowned Hermes plugin path: ${targetPath} (missing or invalid ${INSTALL_MARKER_FILE})`);
35646
35889
  }
35647
35890
  assertEntryIdentityNoFollow(parentFd, expected, targetName, targetIdentity.dev, targetIdentity.ino);
35648
35891
  removeDirectoryContentsNoFollow(targetFd, expectedTarget);
35649
35892
  removeEntryNoFollow(parentFd, expected, targetName, targetIdentity.dev, targetIdentity.ino, true);
35893
+ return true;
35650
35894
  } finally {
35651
35895
  closeDirectory(targetFd);
35652
35896
  }
@@ -35672,12 +35916,11 @@ function removeContainedFile(targetPath, targetRoot) {
35672
35916
  try {
35673
35917
  let expected = rootPath;
35674
35918
  for (const component of components) {
35675
- const childFd = openDirectoryNoFollow(join5(descriptorPath(parentFd), component));
35919
+ const childPath = process.platform === "darwin" ? join5(expected, component) : join5(descriptorPath(parentFd), component);
35920
+ const childFd = openDirectoryNoFollow(childPath);
35676
35921
  try {
35677
35922
  expected = join5(expected, component);
35678
- if (realpathSync3(descriptorPath(childFd)) !== expected) {
35679
- throw new Error(`Hermes target file changed during secure removal: ${targetPath}`);
35680
- }
35923
+ assertDescriptorPathIdentity(childFd, expected, `Hermes target file changed during secure removal: ${targetPath}`);
35681
35924
  } catch (error) {
35682
35925
  closeDirectory(childFd);
35683
35926
  throw error;
@@ -35685,7 +35928,8 @@ function removeContainedFile(targetPath, targetRoot) {
35685
35928
  closeDirectory(parentFd);
35686
35929
  parentFd = childFd;
35687
35930
  }
35688
- const targetFile = lstatSync(join5(descriptorPath(parentFd), fileName));
35931
+ const filePath = process.platform === "darwin" ? join5(expected, fileName) : join5(descriptorPath(parentFd), fileName);
35932
+ const targetFile = lstatSync(filePath);
35689
35933
  removeEntryNoFollow(parentFd, expected, fileName, targetFile.dev, targetFile.ino, false);
35690
35934
  } finally {
35691
35935
  closeDirectory(parentFd);
@@ -35716,10 +35960,11 @@ function installPlugin(targetDir, targetKind, targetRoot) {
35716
35960
  written.push(writeInstallMarker(writeDir, targetKind, targetRoot));
35717
35961
  return written;
35718
35962
  }
35719
- function uninstallPlugin(targetDir, targetKind, targetRoot) {
35963
+ function uninstallPlugin(targetDir, targetKind, targetRoot, unownedTargetBehavior = "throw") {
35720
35964
  if (!pathEntryExists(targetDir))
35721
35965
  return [];
35722
- removeContainedDirectory(targetDir, targetRoot, targetKind);
35966
+ if (!removeContainedDirectory(targetDir, targetRoot, targetKind, unownedTargetBehavior))
35967
+ return [];
35723
35968
  return [targetDir];
35724
35969
  }
35725
35970
  function getConfigCandidates(hermesHome, targetRoot) {
@@ -36085,10 +36330,17 @@ function readInstallMarker(targetDir) {
36085
36330
  return null;
36086
36331
  }
36087
36332
  }
36088
- function readInstallMarkerFromDirectory(directoryFd) {
36333
+ function readInstallMarkerFromDirectory(directoryFd, directoryPath) {
36089
36334
  let markerFd;
36090
36335
  try {
36091
- markerFd = openSync(join5(descriptorPath(directoryFd), INSTALL_MARKER_FILE), constants.O_RDONLY | constants.O_NOFOLLOW);
36336
+ if (process.platform === "darwin") {
36337
+ const content = runSecureFilesystemOperation(directoryFd, directoryPath, SECURE_READ_FILE_SCRIPT, [
36338
+ INSTALL_MARKER_FILE
36339
+ ]);
36340
+ return parseInstallMarker(content);
36341
+ }
36342
+ const markerPath = join5(descriptorPath(directoryFd), INSTALL_MARKER_FILE);
36343
+ markerFd = openSync(markerPath, constants.O_RDONLY | constants.O_NOFOLLOW);
36092
36344
  return parseInstallMarker(readFileSync2(markerFd, "utf-8"));
36093
36345
  } catch {
36094
36346
  return null;
@@ -36472,11 +36724,12 @@ ${key}=${value}
36472
36724
  const userPluginTarget = getUserPluginTargetDir(hermesHome);
36473
36725
  const targetRoot = hermesHome;
36474
36726
  const safeUserPluginTarget = resolveContainedWritePath(userPluginTarget, targetRoot);
36475
- const marker = readInstallMarker(safeUserPluginTarget);
36476
- if (!pathEntryExists(safeUserPluginTarget) || marker === null || marker.targetKind !== "user") {
36727
+ if (!pathEntryExists(safeUserPluginTarget)) {
36477
36728
  return { filesRemoved, configsPatched };
36478
36729
  }
36479
- const userPluginRemoved = uninstallPlugin(userPluginTarget, "user", targetRoot);
36730
+ const userPluginRemoved = uninstallPlugin(userPluginTarget, "user", targetRoot, "skip");
36731
+ if (userPluginRemoved.length === 0)
36732
+ return { filesRemoved, configsPatched };
36480
36733
  filesRemoved.push(...userPluginRemoved);
36481
36734
  const providerConfig = restoreOrClearProvider(hermesHome, targetRoot);
36482
36735
  if (providerConfig.configPath) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signetai/connector-hermes-agent",
3
- "version": "0.228.7",
3
+ "version": "0.229.4",
4
4
  "description": "Signet connector for Hermes Agent — installs Signet as a pluggable memory provider",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -25,8 +25,8 @@
25
25
  "typecheck": "tsc --noEmit"
26
26
  },
27
27
  "dependencies": {
28
- "@signetai/connector-base": "0.228.7",
29
- "@signetai/core": "0.228.7"
28
+ "@signetai/connector-base": "0.229.4",
29
+ "@signetai/core": "0.229.4"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/node": "^22.0.0",