@tencent-ai/agent-sdk 0.3.206-dev.0c715ff.202607102010 → 0.3.206
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/cli/dist/codebuddy-headless.js +178 -226
- package/cli/dist/web-ui/assets/{index-D0Z5-Zvd.js → index-BZjhFKbY.js} +2 -2
- package/cli/dist/web-ui/index.html +1 -1
- package/cli/dist/web-ui/sw.js +1 -1
- package/cli/package.json +2 -3
- package/cli/product.cloudhosted.json +2 -2
- package/cli/product.internal.json +2 -2
- package/cli/product.ioa.json +2 -2
- package/cli/product.json +2 -2
- package/cli/product.selfhosted.json +2 -2
- package/cli/vendor/shim/genie-safe-delete.cjs +781 -4
- package/cli/vendor/shim/safe-bin/safe-delete-bash-env.sh +1 -1
- package/cli/vendor/shim/safe-bin/safe-delete-common.sh +34 -95
- package/cli/vendor/shim/sitecustomize.py +22 -551
- package/package.json +2 -3
- package/cli/vendor/native-builds.json +0 -18
- package/cli/vendor/shim/broker-ipc-client.cjs +0 -158
- package/cli/vendor/shim/brokered-bin/codebuddy-toybox-dispatch +0 -381
- package/cli/vendor/shim/brokered-sandbox-bash-env.sh +0 -10
- package/cli/vendor/shim/native/binding.gyp +0 -13
- package/cli/vendor/shim/native/brokered_sandbox_native.c +0 -293
- package/cli/vendor/shim/native/darwin-arm64/brokered-sandbox-native.node +0 -0
- package/cli/vendor/shim/native/darwin-x64/brokered-sandbox-native.node +0 -0
- package/cli/vendor/shim/node-brokered-fs-shim.cjs +0 -932
- package/cli/vendor/shim/node-language-shim.cjs +0 -35
- package/cli/vendor/shim/node-safe-delete-shim.cjs +0 -810
- package/cli/vendor/shim/safe-delete-broker-delete.cjs +0 -166
- package/cli/vendor/shim/shell-runtime-bash-env.sh +0 -8
- package/cli/vendor/toybox-macos/LICENSE +0 -12
- package/cli/vendor/toybox-macos/toybox +0 -0
- package/cli/vendor/toybox-macos/toybox.sb +0 -19
- package/cli/vendor/zsh-macos/LICENSE +0 -37
- package/cli/vendor/zsh-macos/bin/zsh +0 -0
|
@@ -13,11 +13,8 @@ genie-safe-delete — Python 运行时安全删除 shim
|
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
15
|
import errno
|
|
16
|
-
import builtins
|
|
17
|
-
import io
|
|
18
16
|
import json
|
|
19
17
|
import os
|
|
20
|
-
import socket
|
|
21
18
|
import stat
|
|
22
19
|
import sys
|
|
23
20
|
import tempfile
|
|
@@ -32,11 +29,6 @@ _SESSION_ID = (
|
|
|
32
29
|
or os.environ.get("CLAUDE_SESSION_ID")
|
|
33
30
|
)
|
|
34
31
|
_IN_SANDBOX = os.environ.get("CODEBUDDY_SAFE_DELETE_SANDBOX") == "1"
|
|
35
|
-
_SAFE_DELETE_ENABLED = os.environ.get("CODEBUDDY_SAFE_DELETE_ENABLED") != "0"
|
|
36
|
-
_BROKERED_FS_HOOK_ENABLED = (
|
|
37
|
-
os.environ.get("CODEBUDDY_BROKERED_FS_HOOK_ENABLED") == "1"
|
|
38
|
-
or _IN_SANDBOX
|
|
39
|
-
)
|
|
40
32
|
|
|
41
33
|
if _SESSION_ID:
|
|
42
34
|
# __file__ 在 sitecustomize 加载时指向本文件路径,dirname 即 vendor/shim/
|
|
@@ -276,484 +268,14 @@ if _SESSION_ID:
|
|
|
276
268
|
import pathlib
|
|
277
269
|
import platform
|
|
278
270
|
|
|
279
|
-
_orig_builtin_open = builtins.open
|
|
280
|
-
_orig_io_open = io.open
|
|
281
|
-
_orig_os_open = os.open
|
|
282
271
|
_orig_remove = os.remove
|
|
283
272
|
_orig_unlink = os.unlink
|
|
284
273
|
_orig_rmdir = os.rmdir
|
|
285
|
-
_orig_mkdir = os.mkdir
|
|
286
|
-
_orig_makedirs = os.makedirs
|
|
287
|
-
_orig_rename = os.rename
|
|
288
|
-
_orig_replace = os.replace
|
|
289
|
-
_orig_chmod = os.chmod
|
|
290
|
-
_orig_link = os.link
|
|
291
|
-
_orig_symlink = os.symlink
|
|
292
274
|
_orig_shutil_rmtree = shutil.rmtree
|
|
293
|
-
_orig_shutil_copyfile = shutil.copyfile
|
|
294
|
-
_orig_shutil_copy2 = shutil.copy2
|
|
295
|
-
_orig_shutil_copytree = shutil.copytree
|
|
296
275
|
_orig_path_unlink = pathlib.Path.unlink
|
|
297
276
|
_orig_path_rmdir = pathlib.Path.rmdir
|
|
298
|
-
_orig_path_mkdir = pathlib.Path.mkdir
|
|
299
|
-
_orig_path_touch = pathlib.Path.touch
|
|
300
277
|
_report_path = os.environ.get("CODEBUDDY_SAFE_DELETE_REPORT_PATH")
|
|
301
278
|
|
|
302
|
-
# -----------------------------------------------------------------------
|
|
303
|
-
# Brokered sandbox file-token support.
|
|
304
|
-
#
|
|
305
|
-
# Mirrors the shell/toybox broker model, but the interception point is
|
|
306
|
-
# Python's runtime file APIs. The host still owns policy and token issuing.
|
|
307
|
-
# -----------------------------------------------------------------------
|
|
308
|
-
|
|
309
|
-
_broker_socket_path = os.environ.get("CODEBUDDY_SANDBOX_BROKER_IPC_ADDRESS")
|
|
310
|
-
_broker_session_id = os.environ.get("CODEBUDDY_SANDBOX_BROKER_SESSION_ID") or _SESSION_ID
|
|
311
|
-
_broker_tool_call_id = (
|
|
312
|
-
os.environ.get("CODEBUDDY_SANDBOX_BROKER_TOOL_CALL_ID")
|
|
313
|
-
or os.environ.get("CODEBUDDY_TOOL_CALL_ID")
|
|
314
|
-
)
|
|
315
|
-
_broker_trace_id = os.environ.get("CODEBUDDY_SANDBOX_BROKER_TRACE_ID")
|
|
316
|
-
_broker_file_token_command = (
|
|
317
|
-
os.environ.get("CODEBUDDY_SANDBOX_FILE_TOKEN_OPERATION_COMMAND")
|
|
318
|
-
or "FileTokenRequest"
|
|
319
|
-
)
|
|
320
|
-
_broker_host_operation_command = os.environ.get(
|
|
321
|
-
"CODEBUDDY_SANDBOX_HOST_FILE_OPERATION_COMMAND"
|
|
322
|
-
)
|
|
323
|
-
_broker_request_seq = 0
|
|
324
|
-
_broker_host_operation_depth = 0
|
|
325
|
-
_COPYTREE_DEFAULT = object()
|
|
326
|
-
|
|
327
|
-
def _broker_enabled():
|
|
328
|
-
return bool(sys.platform == "darwin" and _BROKERED_FS_HOOK_ENABLED and _broker_socket_path and _broker_session_id and _broker_file_token_command)
|
|
329
|
-
|
|
330
|
-
def _broker_write_completed_enabled():
|
|
331
|
-
return bool(sys.platform == "darwin" and _BROKERED_FS_HOOK_ENABLED and _broker_socket_path and _broker_session_id)
|
|
332
|
-
|
|
333
|
-
def _broker_host_ops_enabled():
|
|
334
|
-
return bool(
|
|
335
|
-
sys.platform == "darwin"
|
|
336
|
-
and _BROKERED_FS_HOOK_ENABLED
|
|
337
|
-
and _broker_socket_path
|
|
338
|
-
and _broker_session_id
|
|
339
|
-
and _broker_host_operation_command
|
|
340
|
-
and _broker_host_operation_depth == 0
|
|
341
|
-
)
|
|
342
|
-
|
|
343
|
-
def _broker_abs_path(file_path, dir_fd=None):
|
|
344
|
-
if isinstance(file_path, int):
|
|
345
|
-
return None
|
|
346
|
-
try:
|
|
347
|
-
raw_path = os.fspath(file_path)
|
|
348
|
-
except TypeError:
|
|
349
|
-
return None
|
|
350
|
-
if isinstance(raw_path, bytes):
|
|
351
|
-
try:
|
|
352
|
-
raw_path = os.fsdecode(raw_path)
|
|
353
|
-
except UnicodeError:
|
|
354
|
-
return None
|
|
355
|
-
if not raw_path:
|
|
356
|
-
return None
|
|
357
|
-
if dir_fd is not None and not os.path.isabs(raw_path):
|
|
358
|
-
return None
|
|
359
|
-
return os.path.abspath(raw_path)
|
|
360
|
-
|
|
361
|
-
def _broker_readline(sock):
|
|
362
|
-
chunks = []
|
|
363
|
-
while True:
|
|
364
|
-
chunk = sock.recv(1)
|
|
365
|
-
if not chunk:
|
|
366
|
-
break
|
|
367
|
-
if chunk == b"\n":
|
|
368
|
-
break
|
|
369
|
-
chunks.append(chunk)
|
|
370
|
-
return b"".join(chunks).decode("utf-8", errors="replace")
|
|
371
|
-
|
|
372
|
-
def _broker_consume_token(token):
|
|
373
|
-
if sys.platform != "darwin":
|
|
374
|
-
return
|
|
375
|
-
import ctypes
|
|
376
|
-
|
|
377
|
-
lib = ctypes.CDLL(None, use_errno=True)
|
|
378
|
-
fn = lib.sandbox_extension_consume
|
|
379
|
-
fn.argtypes = [ctypes.c_char_p]
|
|
380
|
-
fn.restype = ctypes.c_int64
|
|
381
|
-
handle = fn(token.encode("utf-8"))
|
|
382
|
-
if handle <= 0:
|
|
383
|
-
err = ctypes.get_errno() or errno.EINVAL
|
|
384
|
-
raise OSError(err, os.strerror(err))
|
|
385
|
-
|
|
386
|
-
def _broker_send_request(request):
|
|
387
|
-
try:
|
|
388
|
-
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as sock:
|
|
389
|
-
sock.settimeout(5)
|
|
390
|
-
sock.connect(_broker_socket_path)
|
|
391
|
-
sock.sendall((json.dumps(request, separators=(",", ":")) + "\n").encode("utf-8"))
|
|
392
|
-
line = _broker_readline(sock)
|
|
393
|
-
except Exception:
|
|
394
|
-
return None
|
|
395
|
-
|
|
396
|
-
try:
|
|
397
|
-
response = json.loads(line)
|
|
398
|
-
except Exception:
|
|
399
|
-
return None
|
|
400
|
-
return response if isinstance(response, dict) else None
|
|
401
|
-
|
|
402
|
-
def _broker_request_file_token(abs_path, operation):
|
|
403
|
-
global _broker_request_seq
|
|
404
|
-
if not _broker_enabled():
|
|
405
|
-
return
|
|
406
|
-
|
|
407
|
-
_broker_request_seq += 1
|
|
408
|
-
request = {
|
|
409
|
-
"id": "python-%d" % _broker_request_seq,
|
|
410
|
-
"command": _broker_file_token_command,
|
|
411
|
-
"runtime": "python",
|
|
412
|
-
"operation": operation,
|
|
413
|
-
"path": abs_path,
|
|
414
|
-
"sessionId": _broker_session_id,
|
|
415
|
-
}
|
|
416
|
-
if _broker_tool_call_id:
|
|
417
|
-
request["toolCallId"] = _broker_tool_call_id
|
|
418
|
-
if _broker_trace_id:
|
|
419
|
-
request["brokerTraceId"] = _broker_trace_id
|
|
420
|
-
|
|
421
|
-
response = _broker_send_request(request)
|
|
422
|
-
if response is None:
|
|
423
|
-
# Match toybox's fail-to-sandbox behavior: if IPC is unavailable,
|
|
424
|
-
# do not grant anything here; let the native sandbox decide.
|
|
425
|
-
return
|
|
426
|
-
|
|
427
|
-
token = response.get("token") if response.get("ok") is True else None
|
|
428
|
-
if isinstance(token, str) and token:
|
|
429
|
-
_broker_consume_token(token)
|
|
430
|
-
return
|
|
431
|
-
if response.get("decision") == "sandbox":
|
|
432
|
-
return
|
|
433
|
-
|
|
434
|
-
raise PermissionError(
|
|
435
|
-
response.get("error")
|
|
436
|
-
or "Brokered sandbox denied %s access to %s" % (operation, abs_path)
|
|
437
|
-
)
|
|
438
|
-
|
|
439
|
-
def _broker_notify_file_write_completed(abs_path, existed_before):
|
|
440
|
-
global _broker_request_seq
|
|
441
|
-
if existed_before:
|
|
442
|
-
return
|
|
443
|
-
if not _broker_write_completed_enabled():
|
|
444
|
-
return
|
|
445
|
-
|
|
446
|
-
_broker_request_seq += 1
|
|
447
|
-
request = {
|
|
448
|
-
"id": "python-%d" % _broker_request_seq,
|
|
449
|
-
"command": "FileWriteCompleted",
|
|
450
|
-
"runtime": "python",
|
|
451
|
-
"operation": "write",
|
|
452
|
-
"path": abs_path,
|
|
453
|
-
"sessionId": _broker_session_id,
|
|
454
|
-
}
|
|
455
|
-
if _broker_tool_call_id:
|
|
456
|
-
request["toolCallId"] = _broker_tool_call_id
|
|
457
|
-
if _broker_trace_id:
|
|
458
|
-
request["brokerTraceId"] = _broker_trace_id
|
|
459
|
-
_broker_send_request(request)
|
|
460
|
-
|
|
461
|
-
def _broker_request_host_operation(operation, primary_path, **fields):
|
|
462
|
-
global _broker_request_seq
|
|
463
|
-
if not _broker_host_ops_enabled():
|
|
464
|
-
return False
|
|
465
|
-
|
|
466
|
-
_broker_request_seq += 1
|
|
467
|
-
request = {
|
|
468
|
-
"id": "python-%d" % _broker_request_seq,
|
|
469
|
-
"command": _broker_host_operation_command,
|
|
470
|
-
"runtime": "python",
|
|
471
|
-
"operation": operation,
|
|
472
|
-
"sessionId": _broker_session_id,
|
|
473
|
-
}
|
|
474
|
-
request.update(fields)
|
|
475
|
-
if _broker_tool_call_id:
|
|
476
|
-
request["toolCallId"] = _broker_tool_call_id
|
|
477
|
-
if _broker_trace_id:
|
|
478
|
-
request["brokerTraceId"] = _broker_trace_id
|
|
479
|
-
|
|
480
|
-
response = _broker_send_request(request)
|
|
481
|
-
if response is None:
|
|
482
|
-
return False
|
|
483
|
-
if response.get("ok") is True:
|
|
484
|
-
return True
|
|
485
|
-
if response.get("decision") == "sandbox":
|
|
486
|
-
return False
|
|
487
|
-
raise PermissionError(
|
|
488
|
-
response.get("error")
|
|
489
|
-
or "Brokered sandbox denied host %s for %s" % (operation, primary_path)
|
|
490
|
-
)
|
|
491
|
-
|
|
492
|
-
def _broker_call_native_host_operation(fn, *args, **kwargs):
|
|
493
|
-
global _broker_host_operation_depth
|
|
494
|
-
_broker_host_operation_depth += 1
|
|
495
|
-
try:
|
|
496
|
-
return fn(*args, **kwargs)
|
|
497
|
-
finally:
|
|
498
|
-
_broker_host_operation_depth -= 1
|
|
499
|
-
|
|
500
|
-
def _broker_operation_for_mode(mode):
|
|
501
|
-
mode = mode or "r"
|
|
502
|
-
return "write" if any(ch in mode for ch in "wax+") else "read"
|
|
503
|
-
|
|
504
|
-
def _broker_operation_for_flags(flags):
|
|
505
|
-
write_flags = (
|
|
506
|
-
os.O_WRONLY
|
|
507
|
-
| os.O_RDWR
|
|
508
|
-
| os.O_CREAT
|
|
509
|
-
| os.O_TRUNC
|
|
510
|
-
| os.O_APPEND
|
|
511
|
-
| getattr(os, "O_TMPFILE", 0)
|
|
512
|
-
)
|
|
513
|
-
return "write" if flags & write_flags else "read"
|
|
514
|
-
|
|
515
|
-
def _broker_gate(file_path, operation, dir_fd=None):
|
|
516
|
-
abs_path = _broker_abs_path(file_path, dir_fd=dir_fd)
|
|
517
|
-
if abs_path:
|
|
518
|
-
_broker_request_file_token(abs_path, operation)
|
|
519
|
-
|
|
520
|
-
def _brokered_open(
|
|
521
|
-
open_fn,
|
|
522
|
-
file,
|
|
523
|
-
mode="r",
|
|
524
|
-
buffering=-1,
|
|
525
|
-
encoding=None,
|
|
526
|
-
errors=None,
|
|
527
|
-
newline=None,
|
|
528
|
-
closefd=True,
|
|
529
|
-
opener=None,
|
|
530
|
-
):
|
|
531
|
-
operation = _broker_operation_for_mode(mode)
|
|
532
|
-
abs_path = _broker_abs_path(file)
|
|
533
|
-
existed_before = bool(abs_path and os.path.exists(abs_path))
|
|
534
|
-
if abs_path:
|
|
535
|
-
_broker_request_file_token(abs_path, operation)
|
|
536
|
-
file_obj = open_fn(file, mode, buffering, encoding, errors, newline, closefd, opener)
|
|
537
|
-
if operation == "write" and abs_path and os.path.exists(abs_path):
|
|
538
|
-
_broker_notify_file_write_completed(abs_path, existed_before)
|
|
539
|
-
return file_obj
|
|
540
|
-
|
|
541
|
-
def _brokered_builtin_open(
|
|
542
|
-
file,
|
|
543
|
-
mode="r",
|
|
544
|
-
buffering=-1,
|
|
545
|
-
encoding=None,
|
|
546
|
-
errors=None,
|
|
547
|
-
newline=None,
|
|
548
|
-
closefd=True,
|
|
549
|
-
opener=None,
|
|
550
|
-
):
|
|
551
|
-
return _brokered_open(
|
|
552
|
-
_orig_builtin_open,
|
|
553
|
-
file, mode, buffering, encoding, errors, newline, closefd, opener,
|
|
554
|
-
)
|
|
555
|
-
|
|
556
|
-
def _brokered_io_open(
|
|
557
|
-
file,
|
|
558
|
-
mode="r",
|
|
559
|
-
buffering=-1,
|
|
560
|
-
encoding=None,
|
|
561
|
-
errors=None,
|
|
562
|
-
newline=None,
|
|
563
|
-
closefd=True,
|
|
564
|
-
opener=None,
|
|
565
|
-
):
|
|
566
|
-
return _brokered_open(
|
|
567
|
-
_orig_io_open,
|
|
568
|
-
file, mode, buffering, encoding, errors, newline, closefd, opener,
|
|
569
|
-
)
|
|
570
|
-
|
|
571
|
-
def _brokered_os_open(path, flags, mode=0o777, *, dir_fd=None):
|
|
572
|
-
_broker_gate(path, _broker_operation_for_flags(flags), dir_fd=dir_fd)
|
|
573
|
-
if dir_fd is not None:
|
|
574
|
-
return _orig_os_open(path, flags, mode, dir_fd=dir_fd)
|
|
575
|
-
return _orig_os_open(path, flags, mode)
|
|
576
|
-
|
|
577
|
-
def _brokered_os_mkdir(path, mode=0o777, *, dir_fd=None):
|
|
578
|
-
abs_path = _broker_abs_path(path, dir_fd=dir_fd)
|
|
579
|
-
if abs_path and isinstance(mode, int) and _broker_request_host_operation(
|
|
580
|
-
"mkdir", abs_path, path=abs_path, mode=mode
|
|
581
|
-
):
|
|
582
|
-
return None
|
|
583
|
-
if dir_fd is not None:
|
|
584
|
-
return _broker_call_native_host_operation(_orig_mkdir, path, mode, dir_fd=dir_fd)
|
|
585
|
-
return _broker_call_native_host_operation(_orig_mkdir, path, mode)
|
|
586
|
-
|
|
587
|
-
def _brokered_os_makedirs(name, mode=0o777, exist_ok=False):
|
|
588
|
-
abs_path = _broker_abs_path(name)
|
|
589
|
-
if abs_path and isinstance(mode, int):
|
|
590
|
-
if not exist_ok and os.path.exists(abs_path):
|
|
591
|
-
return _broker_call_native_host_operation(
|
|
592
|
-
_orig_makedirs, name, mode=mode, exist_ok=exist_ok
|
|
593
|
-
)
|
|
594
|
-
if _broker_request_host_operation(
|
|
595
|
-
"mkdir", abs_path, path=abs_path, recursive=True, mode=mode
|
|
596
|
-
):
|
|
597
|
-
return None
|
|
598
|
-
return _broker_call_native_host_operation(
|
|
599
|
-
_orig_makedirs, name, mode=mode, exist_ok=exist_ok
|
|
600
|
-
)
|
|
601
|
-
|
|
602
|
-
def _brokered_os_rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None):
|
|
603
|
-
from_path = _broker_abs_path(src, dir_fd=src_dir_fd)
|
|
604
|
-
to_path = _broker_abs_path(dst, dir_fd=dst_dir_fd)
|
|
605
|
-
if from_path and to_path and _broker_request_host_operation(
|
|
606
|
-
"rename", from_path, **{"from": from_path, "to": to_path}
|
|
607
|
-
):
|
|
608
|
-
return None
|
|
609
|
-
if src_dir_fd is not None or dst_dir_fd is not None:
|
|
610
|
-
return _broker_call_native_host_operation(
|
|
611
|
-
_orig_rename, src, dst, src_dir_fd=src_dir_fd, dst_dir_fd=dst_dir_fd
|
|
612
|
-
)
|
|
613
|
-
return _broker_call_native_host_operation(_orig_rename, src, dst)
|
|
614
|
-
|
|
615
|
-
def _brokered_os_replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None):
|
|
616
|
-
from_path = _broker_abs_path(src, dir_fd=src_dir_fd)
|
|
617
|
-
to_path = _broker_abs_path(dst, dir_fd=dst_dir_fd)
|
|
618
|
-
if from_path and to_path and _broker_request_host_operation(
|
|
619
|
-
"rename", from_path, **{"from": from_path, "to": to_path}
|
|
620
|
-
):
|
|
621
|
-
return None
|
|
622
|
-
if src_dir_fd is not None or dst_dir_fd is not None:
|
|
623
|
-
return _broker_call_native_host_operation(
|
|
624
|
-
_orig_replace, src, dst, src_dir_fd=src_dir_fd, dst_dir_fd=dst_dir_fd
|
|
625
|
-
)
|
|
626
|
-
return _broker_call_native_host_operation(_orig_replace, src, dst)
|
|
627
|
-
|
|
628
|
-
def _brokered_os_chmod(path, mode, *, dir_fd=None, follow_symlinks=True):
|
|
629
|
-
abs_path = _broker_abs_path(path, dir_fd=dir_fd)
|
|
630
|
-
if abs_path and isinstance(mode, int) and follow_symlinks and _broker_request_host_operation(
|
|
631
|
-
"chmod", abs_path, path=abs_path, mode=mode
|
|
632
|
-
):
|
|
633
|
-
return None
|
|
634
|
-
if dir_fd is not None:
|
|
635
|
-
return _broker_call_native_host_operation(
|
|
636
|
-
_orig_chmod, path, mode, dir_fd=dir_fd, follow_symlinks=follow_symlinks
|
|
637
|
-
)
|
|
638
|
-
return _broker_call_native_host_operation(
|
|
639
|
-
_orig_chmod, path, mode, follow_symlinks=follow_symlinks
|
|
640
|
-
)
|
|
641
|
-
|
|
642
|
-
def _brokered_os_link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True):
|
|
643
|
-
from_path = _broker_abs_path(src, dir_fd=src_dir_fd)
|
|
644
|
-
to_path = _broker_abs_path(dst, dir_fd=dst_dir_fd)
|
|
645
|
-
should_broker = follow_symlinks and from_path and to_path
|
|
646
|
-
try:
|
|
647
|
-
should_broker = should_broker and not os.path.islink(from_path)
|
|
648
|
-
except Exception:
|
|
649
|
-
should_broker = False
|
|
650
|
-
if should_broker and _broker_request_host_operation(
|
|
651
|
-
"link", from_path, **{"from": from_path, "to": to_path, "symbolic": False}
|
|
652
|
-
):
|
|
653
|
-
return None
|
|
654
|
-
if src_dir_fd is not None or dst_dir_fd is not None:
|
|
655
|
-
return _broker_call_native_host_operation(
|
|
656
|
-
_orig_link, src, dst, src_dir_fd=src_dir_fd, dst_dir_fd=dst_dir_fd,
|
|
657
|
-
follow_symlinks=follow_symlinks
|
|
658
|
-
)
|
|
659
|
-
return _broker_call_native_host_operation(
|
|
660
|
-
_orig_link, src, dst, follow_symlinks=follow_symlinks
|
|
661
|
-
)
|
|
662
|
-
|
|
663
|
-
def _brokered_os_symlink(src, dst, target_is_directory=False, *, dir_fd=None):
|
|
664
|
-
source = None
|
|
665
|
-
try:
|
|
666
|
-
source = os.fspath(src)
|
|
667
|
-
if isinstance(source, bytes):
|
|
668
|
-
source = os.fsdecode(source)
|
|
669
|
-
except (TypeError, UnicodeError):
|
|
670
|
-
source = None
|
|
671
|
-
to_path = _broker_abs_path(dst, dir_fd=dir_fd)
|
|
672
|
-
if source and to_path and _broker_request_host_operation(
|
|
673
|
-
"link", to_path, **{"from": source, "to": to_path, "symbolic": True}
|
|
674
|
-
):
|
|
675
|
-
return None
|
|
676
|
-
if dir_fd is not None:
|
|
677
|
-
return _broker_call_native_host_operation(
|
|
678
|
-
_orig_symlink, src, dst, target_is_directory, dir_fd=dir_fd
|
|
679
|
-
)
|
|
680
|
-
return _broker_call_native_host_operation(
|
|
681
|
-
_orig_symlink, src, dst, target_is_directory
|
|
682
|
-
)
|
|
683
|
-
|
|
684
|
-
def _brokered_shutil_copyfile(src, dst, *, follow_symlinks=True):
|
|
685
|
-
from_path = _broker_abs_path(src)
|
|
686
|
-
to_path = _broker_abs_path(dst)
|
|
687
|
-
if follow_symlinks and from_path and to_path and _broker_request_host_operation(
|
|
688
|
-
"copy", from_path, **{"from": from_path, "to": to_path, "recursive": False}
|
|
689
|
-
):
|
|
690
|
-
return dst
|
|
691
|
-
return _broker_call_native_host_operation(
|
|
692
|
-
_orig_shutil_copyfile, src, dst, follow_symlinks=follow_symlinks
|
|
693
|
-
)
|
|
694
|
-
|
|
695
|
-
def _brokered_shutil_copytree(
|
|
696
|
-
src,
|
|
697
|
-
dst,
|
|
698
|
-
symlinks=False,
|
|
699
|
-
ignore=None,
|
|
700
|
-
copy_function=_COPYTREE_DEFAULT,
|
|
701
|
-
ignore_dangling_symlinks=False,
|
|
702
|
-
dirs_exist_ok=False,
|
|
703
|
-
):
|
|
704
|
-
native_copy_function = (
|
|
705
|
-
_orig_shutil_copy2
|
|
706
|
-
if copy_function is _COPYTREE_DEFAULT
|
|
707
|
-
else copy_function
|
|
708
|
-
)
|
|
709
|
-
can_broker = (
|
|
710
|
-
symlinks is False
|
|
711
|
-
and ignore is None
|
|
712
|
-
and native_copy_function is _orig_shutil_copy2
|
|
713
|
-
and ignore_dangling_symlinks is False
|
|
714
|
-
and dirs_exist_ok is False
|
|
715
|
-
)
|
|
716
|
-
from_path = _broker_abs_path(src) if can_broker else None
|
|
717
|
-
to_path = _broker_abs_path(dst) if can_broker else None
|
|
718
|
-
if from_path and to_path and _broker_request_host_operation(
|
|
719
|
-
"copy", from_path, **{"from": from_path, "to": to_path, "recursive": True}
|
|
720
|
-
):
|
|
721
|
-
return dst
|
|
722
|
-
return _broker_call_native_host_operation(
|
|
723
|
-
_orig_shutil_copytree,
|
|
724
|
-
src,
|
|
725
|
-
dst,
|
|
726
|
-
symlinks=symlinks,
|
|
727
|
-
ignore=ignore,
|
|
728
|
-
copy_function=native_copy_function,
|
|
729
|
-
ignore_dangling_symlinks=ignore_dangling_symlinks,
|
|
730
|
-
dirs_exist_ok=dirs_exist_ok,
|
|
731
|
-
)
|
|
732
|
-
|
|
733
|
-
def _brokered_path_mkdir(self, mode=0o777, parents=False, exist_ok=False):
|
|
734
|
-
abs_path = _broker_abs_path(self)
|
|
735
|
-
if abs_path and isinstance(mode, int):
|
|
736
|
-
if not exist_ok and os.path.exists(abs_path):
|
|
737
|
-
return _broker_call_native_host_operation(
|
|
738
|
-
_orig_path_mkdir, self, mode=mode, parents=parents, exist_ok=exist_ok
|
|
739
|
-
)
|
|
740
|
-
if _broker_request_host_operation(
|
|
741
|
-
"mkdir", abs_path, path=abs_path, recursive=parents, mode=mode
|
|
742
|
-
):
|
|
743
|
-
return None
|
|
744
|
-
return _broker_call_native_host_operation(
|
|
745
|
-
_orig_path_mkdir, self, mode=mode, parents=parents, exist_ok=exist_ok
|
|
746
|
-
)
|
|
747
|
-
|
|
748
|
-
def _brokered_path_touch(self, mode=0o666, exist_ok=True):
|
|
749
|
-
abs_path = _broker_abs_path(self)
|
|
750
|
-
can_broker = abs_path and mode == 0o666 and (exist_ok or not os.path.exists(abs_path))
|
|
751
|
-
if can_broker and _broker_request_host_operation("touch", abs_path, path=abs_path):
|
|
752
|
-
return None
|
|
753
|
-
return _broker_call_native_host_operation(
|
|
754
|
-
_orig_path_touch, self, mode=mode, exist_ok=exist_ok
|
|
755
|
-
)
|
|
756
|
-
|
|
757
279
|
def _path_for_compare(path):
|
|
758
280
|
return os.path.normcase(os.path.realpath(os.path.abspath(path)))
|
|
759
281
|
|
|
@@ -792,7 +314,7 @@ if _SESSION_ID:
|
|
|
792
314
|
if not _report_path:
|
|
793
315
|
return
|
|
794
316
|
try:
|
|
795
|
-
with
|
|
317
|
+
with open(_report_path, "a", encoding="utf-8") as f:
|
|
796
318
|
f.write(json.dumps({
|
|
797
319
|
"operation": "trash",
|
|
798
320
|
"runtime": "python",
|
|
@@ -897,30 +419,11 @@ if _SESSION_ID:
|
|
|
897
419
|
return False
|
|
898
420
|
|
|
899
421
|
# -----------------------------------------------------------------------
|
|
900
|
-
#
|
|
422
|
+
# 核心:尝试移入回收站。优先 binary,降级到平台内联实现。
|
|
901
423
|
# 返回 True=已移入回收站;抛错=fail-closed,调用方不得真删。
|
|
902
424
|
# -----------------------------------------------------------------------
|
|
903
425
|
|
|
904
|
-
def
|
|
905
|
-
if not _broker_host_ops_enabled():
|
|
906
|
-
return "unavailable"
|
|
907
|
-
try:
|
|
908
|
-
if _broker_request_host_operation(
|
|
909
|
-
"delete",
|
|
910
|
-
abs_path,
|
|
911
|
-
path=abs_path,
|
|
912
|
-
deleteMode="trash",
|
|
913
|
-
recursive=bool(recursive),
|
|
914
|
-
force=bool(force),
|
|
915
|
-
):
|
|
916
|
-
return "ok"
|
|
917
|
-
return "unavailable"
|
|
918
|
-
except PermissionError:
|
|
919
|
-
return "denied"
|
|
920
|
-
except Exception:
|
|
921
|
-
return "unavailable"
|
|
922
|
-
|
|
923
|
-
def _try_trash(abs_path, recursive=False, force=False):
|
|
426
|
+
def _try_trash(abs_path):
|
|
924
427
|
if sys.platform == "win32" and _IN_SANDBOX:
|
|
925
428
|
message = (
|
|
926
429
|
"[safe-delete][SAFE_DELETE_FAIL_CLOSED] "
|
|
@@ -936,15 +439,6 @@ if _SESSION_ID:
|
|
|
936
439
|
pass
|
|
937
440
|
raise OSError(message)
|
|
938
441
|
_check_bulk_delete_guard(abs_path)
|
|
939
|
-
|
|
940
|
-
broker_result = _try_broker_delete(abs_path, recursive=recursive, force=force)
|
|
941
|
-
if broker_result == "ok":
|
|
942
|
-
return True
|
|
943
|
-
if broker_result == "denied":
|
|
944
|
-
raise PermissionError(
|
|
945
|
-
"[safe-delete] broker denied delete: path=%s" % abs_path
|
|
946
|
-
)
|
|
947
|
-
|
|
948
442
|
if _try_trash_via_binary(abs_path):
|
|
949
443
|
_record_trash(abs_path)
|
|
950
444
|
return True
|
|
@@ -967,18 +461,17 @@ if _SESSION_ID:
|
|
|
967
461
|
except OSError:
|
|
968
462
|
return False
|
|
969
463
|
|
|
970
|
-
def
|
|
464
|
+
def _is_under_os_tmp_dir(abs_path):
|
|
971
465
|
try:
|
|
972
466
|
target = _path_for_compare(os.fsdecode(abs_path))
|
|
973
|
-
|
|
974
|
-
rel = os.path.relpath(target, root_path)
|
|
975
|
-
except (TypeError, UnicodeError, ValueError):
|
|
467
|
+
except (TypeError, UnicodeError):
|
|
976
468
|
return False
|
|
977
|
-
return rel not in ("", ".") and rel != ".." and not rel.startswith(".." + os.sep) and not os.path.isabs(rel)
|
|
978
|
-
|
|
979
|
-
def _is_under_os_tmp_dir(abs_path):
|
|
980
469
|
for tmp_dir in _os_tmp_dirs:
|
|
981
|
-
|
|
470
|
+
try:
|
|
471
|
+
rel = os.path.relpath(target, tmp_dir)
|
|
472
|
+
except ValueError:
|
|
473
|
+
continue
|
|
474
|
+
if rel not in ("", ".") and rel != ".." and not rel.startswith(".." + os.sep) and not os.path.isabs(rel):
|
|
982
475
|
return True
|
|
983
476
|
return False
|
|
984
477
|
|
|
@@ -996,9 +489,6 @@ if _SESSION_ID:
|
|
|
996
489
|
return True
|
|
997
490
|
return False
|
|
998
491
|
|
|
999
|
-
def _should_bypass_safe_delete(abs_path):
|
|
1000
|
-
return _is_under_os_tmp_dir(abs_path) or _is_pip_site_packages_temp_dir(abs_path)
|
|
1001
|
-
|
|
1002
492
|
# -----------------------------------------------------------------------
|
|
1003
493
|
# 包装:os.remove / os.unlink (文件,不能是目录)
|
|
1004
494
|
# -----------------------------------------------------------------------
|
|
@@ -1008,7 +498,7 @@ if _SESSION_ID:
|
|
|
1008
498
|
if dir_fd is not None:
|
|
1009
499
|
return _orig_remove(path, dir_fd=dir_fd)
|
|
1010
500
|
abs_path = os.path.abspath(os.fspath(path))
|
|
1011
|
-
if
|
|
501
|
+
if _is_under_os_tmp_dir(abs_path) or _is_pip_site_packages_temp_dir(abs_path):
|
|
1012
502
|
return _orig_remove(path)
|
|
1013
503
|
st = _safe_lstat(abs_path)
|
|
1014
504
|
if not st:
|
|
@@ -1025,7 +515,7 @@ if _SESSION_ID:
|
|
|
1025
515
|
if dir_fd is not None:
|
|
1026
516
|
return _orig_rmdir(path, dir_fd=dir_fd)
|
|
1027
517
|
abs_path = os.path.abspath(os.fspath(path))
|
|
1028
|
-
if
|
|
518
|
+
if _is_under_os_tmp_dir(abs_path) or _is_pip_site_packages_temp_dir(abs_path):
|
|
1029
519
|
return _orig_rmdir(path)
|
|
1030
520
|
st = _safe_lstat(abs_path)
|
|
1031
521
|
if not st:
|
|
@@ -1049,7 +539,7 @@ if _SESSION_ID:
|
|
|
1049
539
|
path, ignore_errors=ignore_errors, onerror=onerror, **kwargs
|
|
1050
540
|
)
|
|
1051
541
|
|
|
1052
|
-
if
|
|
542
|
+
if _is_under_os_tmp_dir(abs_path) or _is_pip_site_packages_temp_dir(abs_path):
|
|
1053
543
|
return _orig_shutil_rmtree(
|
|
1054
544
|
path, ignore_errors=ignore_errors, onerror=onerror, **kwargs
|
|
1055
545
|
)
|
|
@@ -1066,7 +556,7 @@ if _SESSION_ID:
|
|
|
1066
556
|
)
|
|
1067
557
|
|
|
1068
558
|
try:
|
|
1069
|
-
_try_trash(abs_path
|
|
559
|
+
_try_trash(abs_path)
|
|
1070
560
|
except Exception as e:
|
|
1071
561
|
if ignore_errors:
|
|
1072
562
|
return
|
|
@@ -1081,7 +571,7 @@ if _SESSION_ID:
|
|
|
1081
571
|
|
|
1082
572
|
def _safe_path_unlink(self, missing_ok=False):
|
|
1083
573
|
abs_path = os.path.abspath(str(self))
|
|
1084
|
-
if
|
|
574
|
+
if _is_under_os_tmp_dir(abs_path) or _is_pip_site_packages_temp_dir(abs_path):
|
|
1085
575
|
return _orig_path_unlink(self, missing_ok=missing_ok)
|
|
1086
576
|
st = _safe_lstat(abs_path)
|
|
1087
577
|
if not st:
|
|
@@ -1094,7 +584,7 @@ if _SESSION_ID:
|
|
|
1094
584
|
|
|
1095
585
|
def _safe_path_rmdir(self):
|
|
1096
586
|
abs_path = os.path.abspath(str(self))
|
|
1097
|
-
if
|
|
587
|
+
if _is_under_os_tmp_dir(abs_path) or _is_pip_site_packages_temp_dir(abs_path):
|
|
1098
588
|
return _orig_path_rmdir(self)
|
|
1099
589
|
st = _safe_lstat(abs_path)
|
|
1100
590
|
if not st:
|
|
@@ -1109,28 +599,9 @@ if _SESSION_ID:
|
|
|
1109
599
|
# 安装 patch
|
|
1110
600
|
# -----------------------------------------------------------------------
|
|
1111
601
|
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
os.mkdir = _brokered_os_mkdir
|
|
1119
|
-
os.makedirs = _brokered_os_makedirs
|
|
1120
|
-
os.rename = _brokered_os_rename
|
|
1121
|
-
os.replace = _brokered_os_replace
|
|
1122
|
-
os.chmod = _brokered_os_chmod
|
|
1123
|
-
os.link = _brokered_os_link
|
|
1124
|
-
os.symlink = _brokered_os_symlink
|
|
1125
|
-
shutil.copyfile = _brokered_shutil_copyfile
|
|
1126
|
-
shutil.copytree = _brokered_shutil_copytree
|
|
1127
|
-
pathlib.Path.mkdir = _brokered_path_mkdir
|
|
1128
|
-
pathlib.Path.touch = _brokered_path_touch
|
|
1129
|
-
|
|
1130
|
-
if _SAFE_DELETE_ENABLED:
|
|
1131
|
-
os.remove = _safe_remove
|
|
1132
|
-
os.unlink = _safe_remove # CPython 里 os.unlink is os.remove,显式 patch 兼容其它实现
|
|
1133
|
-
os.rmdir = _safe_rmdir
|
|
1134
|
-
shutil.rmtree = _safe_shutil_rmtree
|
|
1135
|
-
pathlib.Path.unlink = _safe_path_unlink
|
|
1136
|
-
pathlib.Path.rmdir = _safe_path_rmdir
|
|
602
|
+
os.remove = _safe_remove
|
|
603
|
+
os.unlink = _safe_remove # CPython 里 os.unlink is os.remove,显式 patch 兼容其它实现
|
|
604
|
+
os.rmdir = _safe_rmdir
|
|
605
|
+
shutil.rmtree = _safe_shutil_rmtree
|
|
606
|
+
pathlib.Path.unlink = _safe_path_unlink
|
|
607
|
+
pathlib.Path.rmdir = _safe_path_rmdir
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tencent-ai/agent-sdk",
|
|
3
|
-
"version": "0.3.206
|
|
3
|
+
"version": "0.3.206",
|
|
4
4
|
"description": "CodeBuddy Code SDK for JavaScript/TypeScript",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
@@ -31,7 +31,6 @@
|
|
|
31
31
|
"zod": "^4.0.0"
|
|
32
32
|
},
|
|
33
33
|
"publishConfig": {
|
|
34
|
-
"access": "public"
|
|
35
|
-
"tag": "dev"
|
|
34
|
+
"access": "public"
|
|
36
35
|
}
|
|
37
36
|
}
|