@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.
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +300 -47
- package/package.json +3 -3
package/dist/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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 {
|
|
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: "
|
|
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
|
-
"
|
|
35327
|
-
"if os.path.realpath(
|
|
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
|
-
"
|
|
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(
|
|
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
|
-
|
|
35585
|
+
const detail = result.stderr.trim();
|
|
35586
|
+
throw new Error(`Hermes directory entry changed during secure removal: ${name}${detail ? ` (${detail})` : ""}`);
|
|
35386
35587
|
}
|
|
35387
|
-
|
|
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
|
-
|
|
35580
|
-
|
|
35581
|
-
}
|
|
35582
|
-
|
|
35583
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
35640
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
29
|
-
"@signetai/core": "0.
|
|
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",
|