computer-use-ootb-internal 0.0.162__py3-none-any.whl → 0.0.164__py3-none-any.whl
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.
- computer_use_ootb_internal/guard_service.py +164 -76
- computer_use_ootb_internal/launch_ootb_elevated.ps1 +69 -0
- {computer_use_ootb_internal-0.0.162.dist-info → computer_use_ootb_internal-0.0.164.dist-info}/METADATA +1 -1
- {computer_use_ootb_internal-0.0.162.dist-info → computer_use_ootb_internal-0.0.164.dist-info}/RECORD +6 -5
- {computer_use_ootb_internal-0.0.162.dist-info → computer_use_ootb_internal-0.0.164.dist-info}/WHEEL +0 -0
- {computer_use_ootb_internal-0.0.162.dist-info → computer_use_ootb_internal-0.0.164.dist-info}/entry_points.txt +0 -0
@@ -23,6 +23,7 @@ import psutil # For process/user info
|
|
23
23
|
from flask import Flask, request, jsonify # For embedded server
|
24
24
|
from waitress import serve # For serving Flask app
|
25
25
|
import json # Needed for status reporting
|
26
|
+
import shutil # Added for shutil.which
|
26
27
|
|
27
28
|
# --- Configuration ---
|
28
29
|
_SERVICE_NAME = "OOTBGuardService"
|
@@ -226,7 +227,9 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
226
227
|
self.log_info(f"Using target executable: {self.target_executable_path}")
|
227
228
|
|
228
229
|
_service_instance = self
|
229
|
-
|
230
|
+
# Determine path to the signal script
|
231
|
+
self.signal_script_path = self._find_signal_script()
|
232
|
+
self.log_info(f"Service initialized. Target executable: {self.target_executable_path}. Signal script: {self.signal_script_path}")
|
230
233
|
|
231
234
|
def SvcStop(self):
|
232
235
|
self.log_info(f"Service stop requested.")
|
@@ -706,19 +709,9 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
706
709
|
|
707
710
|
|
708
711
|
try:
|
709
|
-
# 1. Ensure scheduled task exists (still useful fallback/persistence)
|
710
|
-
try:
|
711
|
-
task_created = self.create_or_update_logon_task(user, calculated_port)
|
712
|
-
task_created_status = "task_success" if task_created else "task_failed"
|
713
|
-
except Exception as task_err:
|
714
|
-
self.log_error(f"Internal trigger: Exception creating/updating task for {user}: {task_err}", exc_info=True)
|
715
|
-
task_created_status = "task_exception"
|
716
|
-
# Don't necessarily fail the whole operation yet
|
717
|
-
|
718
712
|
# 2. Check if user is active
|
719
713
|
active_sessions = {} # Re-check active sessions specifically for this user
|
720
714
|
session_id = None
|
721
|
-
token = None
|
722
715
|
is_active = False
|
723
716
|
try:
|
724
717
|
sessions = win32ts.WTSEnumerateSessions(win32ts.WTS_CURRENT_SERVER_HANDLE)
|
@@ -739,7 +732,7 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
739
732
|
if not is_active:
|
740
733
|
self.log_info(f"Internal trigger: User '{user}' is not active. Skipping immediate start.")
|
741
734
|
immediate_start_status = "start_skipped_inactive"
|
742
|
-
final_status =
|
735
|
+
final_status = "skipped_inactive" # Simplified status
|
743
736
|
return final_status # Exit early if inactive
|
744
737
|
|
745
738
|
# 3. Check if already running for this active user
|
@@ -756,61 +749,100 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
756
749
|
self.log_error(f"Internal trigger: Error checking existing processes for {user}: {e}")
|
757
750
|
# Continue and attempt start despite error?
|
758
751
|
|
759
|
-
# 4.
|
760
|
-
immediate_start_status = "
|
761
|
-
self.log_info(f"Internal trigger: User '{user}' is active and not running. Attempting start via
|
752
|
+
# 4. Attempt immediate start using CreateProcessAsUser to run helper script
|
753
|
+
immediate_start_status = "start_attempted_helper_script"
|
754
|
+
self.log_info(f"Internal trigger: User '{user}' is active and not running. Attempting start via helper script...")
|
755
|
+
|
756
|
+
if not self.target_executable_path:
|
757
|
+
self.log_error("Internal trigger: Cannot start process - target executable path not found.")
|
758
|
+
final_status = "failed_exe_not_found"
|
759
|
+
return final_status
|
762
760
|
|
763
|
-
# --- Start Task Scheduler logic ---
|
764
761
|
try:
|
765
|
-
#
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
final_status = "failed_task_creation"
|
762
|
+
# Find helper script path
|
763
|
+
helper_script_path = self._find_helper_script("launch_ootb_elevated.ps1")
|
764
|
+
if not helper_script_path:
|
765
|
+
self.log_error("Internal trigger: Cannot start process - helper script not found.")
|
766
|
+
final_status = "failed_helper_script_not_found"
|
771
767
|
return final_status
|
772
|
-
|
773
|
-
#
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
768
|
+
|
769
|
+
# Get PowerShell executable path
|
770
|
+
powershell_executable = self._find_powershell_executable()
|
771
|
+
if not powershell_executable:
|
772
|
+
self.log_error("Internal trigger: Cannot start process - powershell.exe not found.")
|
773
|
+
final_status = "failed_powershell_not_found"
|
774
|
+
return final_status
|
775
|
+
|
776
|
+
# Prepare arguments for the helper script (paths need quoting if they contain spaces)
|
777
|
+
target_exe_unquoted = self.target_executable_path.strip('"')
|
778
|
+
target_exe_dir = os.path.dirname(target_exe_unquoted) # Use directory of unquoted path
|
779
|
+
|
780
|
+
# Quote paths/args for command line - IMPORTANT: Use double quotes for PowerShell args
|
781
|
+
helper_script_arg = f'"{helper_script_path}"' if " " in helper_script_path else helper_script_path
|
782
|
+
target_exe_arg = f'"{target_exe_unquoted}"' if " " in target_exe_unquoted else target_exe_unquoted
|
783
|
+
working_dir_arg = f'"{target_exe_dir}"' if " " in target_exe_dir else target_exe_dir
|
784
|
+
# Username might need quoting if it contains special characters, double quote should be safe
|
785
|
+
target_user_arg = f'"{user}"'
|
786
|
+
|
787
|
+
# Construct the command line to execute powershell with the helper script and args
|
788
|
+
lpCommandLine = (
|
789
|
+
f'"{powershell_executable}" -NoProfile -ExecutionPolicy Bypass -NoExit '
|
790
|
+
f'-File {helper_script_arg} '
|
791
|
+
f'-TargetExePath {target_exe_arg} '
|
792
|
+
f'-Port {calculated_port} '
|
793
|
+
f'-TargetUser {target_user_arg} '
|
794
|
+
f'-WorkingDirectory {working_dir_arg}'
|
785
795
|
)
|
786
796
|
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
797
|
+
# Use CreateProcessAsUser to launch this command in the user's session
|
798
|
+
token = win32ts.WTSQueryUserToken(session_id)
|
799
|
+
env = win32profile.CreateEnvironmentBlock(token, False)
|
800
|
+
startup = win32process.STARTUPINFO()
|
801
|
+
# Ensure the window is visible on the user's desktop
|
802
|
+
startup.lpDesktop = "winsta0\\default"
|
803
|
+
creation_flags = win32con.CREATE_NEW_CONSOLE | win32con.NORMAL_PRIORITY_CLASS
|
804
|
+
lpApplicationName = None # Must be None when using lpCommandLine
|
805
|
+
# Working directory for powershell itself? Let it default or use script dir?
|
806
|
+
# Let's use the script's directory as CWD for powershell.exe
|
807
|
+
cwd = os.path.dirname(helper_script_path) # Use directory of unquoted path
|
808
|
+
|
809
|
+
self.log_info(f"Internal trigger: Launching helper script via CreateProcessAsUser:")
|
810
|
+
self.log_info(f" lpCommandLine: {lpCommandLine}")
|
811
|
+
self.log_info(f" lpCurrentDirectory: {cwd}")
|
812
|
+
|
813
|
+
# Execute the command in the user's session
|
814
|
+
hProcess, hThread, dwPid, dwTid = win32process.CreateProcessAsUser(
|
815
|
+
token, lpApplicationName, lpCommandLine, None, None, False,
|
816
|
+
creation_flags, env, cwd, startup
|
817
|
+
)
|
818
|
+
self.log_info(f"Internal trigger: CreateProcessAsUser call for helper script succeeded (Launcher PID: {dwPid}). Helper script should now run and trigger elevation.")
|
819
|
+
win32api.CloseHandle(hProcess)
|
820
|
+
win32api.CloseHandle(hThread)
|
821
|
+
|
822
|
+
# Assume success if CreateProcessAsUser succeeded.
|
823
|
+
# The actual success depends on the user interacting with UAC triggered by the helper.
|
824
|
+
immediate_start_status = "start_success_helper_launched"
|
825
|
+
final_status = "success_helper_launched"
|
826
|
+
|
827
|
+
except FileNotFoundError as fnf_err:
|
828
|
+
# This might now be powershell.exe OR the helper script
|
829
|
+
self.log_error(f"Internal trigger: File not found during helper script launch: {fnf_err}")
|
830
|
+
immediate_start_status = "start_failed_file_not_found"
|
831
|
+
final_status = "failed_file_not_found"
|
832
|
+
except Exception as launch_err:
|
833
|
+
self.log_error(f"Internal trigger: Exception during CreateProcessAsUser for helper script (user '{user}'): {launch_err}", exc_info=True)
|
834
|
+
immediate_start_status = "start_failed_launch_exception"
|
835
|
+
final_status = "failed_launch_exception"
|
836
|
+
finally:
|
837
|
+
# Ensure token exists and is not None before attempting to close
|
838
|
+
if 'token' in locals() and token is not None:
|
839
|
+
try:
|
840
|
+
win32api.CloseHandle(token)
|
841
|
+
except: # Ignore errors closing handle
|
842
|
+
pass
|
811
843
|
|
812
844
|
# Combine results (mostly determined by start attempt now)
|
813
|
-
#
|
845
|
+
# Status is now primarily determined by the helper script launch attempt
|
814
846
|
return final_status
|
815
847
|
|
816
848
|
except Exception as e:
|
@@ -818,35 +850,48 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
818
850
|
return "failed_trigger_exception"
|
819
851
|
|
820
852
|
|
821
|
-
def create_or_update_logon_task(self, username
|
853
|
+
def create_or_update_logon_task(self, username):
|
822
854
|
"""Creates/updates task to trigger the internal signal script on session connect."""
|
823
|
-
if not self.
|
824
|
-
self.log_error(f"Cannot create task for {username}:
|
855
|
+
if not self.signal_script_path:
|
856
|
+
self.log_error(f"Cannot create task for {username}: Signal script path is not set.")
|
825
857
|
return False
|
858
|
+
if not sys.executable:
|
859
|
+
self.log_error(f"Cannot create task for {username}: sys.executable is not found.")
|
860
|
+
return False
|
861
|
+
|
862
|
+
# Use the python executable that the service itself is running under
|
863
|
+
python_exe = sys.executable
|
864
|
+
if ' ' in python_exe and not python_exe.startswith('"'):
|
865
|
+
python_exe = f'"{python_exe}"'
|
826
866
|
|
827
867
|
task_name = f"OOTB_UserConnect_{username}"
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
#
|
868
|
+
# Action: Run python.exe with the signal script and username argument
|
869
|
+
action_executable = python_exe
|
870
|
+
# Ensure script path is quoted if needed
|
871
|
+
script_arg = self.signal_script_path # Should be quoted already by _find_signal_script
|
872
|
+
# Username might need quoting if it contains spaces, though unlikely
|
873
|
+
user_arg = username # Keep simple for now
|
874
|
+
action_arguments = f'{script_arg} "{user_arg}"' # Pass username as quoted arg
|
875
|
+
safe_action_executable = action_executable.replace("'", "''") # Escape for PS
|
876
|
+
safe_action_arguments = action_arguments.replace("'", "''") # Escape for PS
|
877
|
+
|
878
|
+
# Working directory for the script (likely its own directory)
|
833
879
|
try:
|
834
|
-
|
835
|
-
if not
|
836
|
-
safe_working_directory =
|
880
|
+
script_dir = os.path.dirname(self.signal_script_path.strip('"'))
|
881
|
+
if not script_dir: script_dir = "."
|
882
|
+
safe_working_directory = script_dir.replace("'", "''")
|
837
883
|
working_directory_setting = f"$action.WorkingDirectory = '{safe_working_directory}'"
|
838
884
|
except Exception as e:
|
839
|
-
self.log_error(f"Error determining working directory for
|
885
|
+
self.log_error(f"Error determining working directory for signal script task: {e}. WD will not be set.")
|
840
886
|
working_directory_setting = "# Could not set WorkingDirectory"
|
841
887
|
|
842
888
|
# PowerShell command construction
|
843
889
|
ps_command = f"""
|
844
890
|
$taskName = "{task_name}"
|
845
|
-
|
846
|
-
$principal = New-ScheduledTaskPrincipal -UserId "{username}" -LogonType Interactive -RunLevel Highest
|
891
|
+
$principal = New-ScheduledTaskPrincipal -UserId "{username}" -LogonType Interactive
|
847
892
|
|
848
|
-
# Action: Run
|
849
|
-
$action = New-ScheduledTaskAction -Execute '{
|
893
|
+
# Action: Run python signal script
|
894
|
+
$action = New-ScheduledTaskAction -Execute '{safe_action_executable}' -Argument '{safe_action_arguments}'
|
850
895
|
{working_directory_setting}
|
851
896
|
|
852
897
|
# Trigger: On session connect (Event ID 21)
|
@@ -916,6 +961,49 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
916
961
|
self.log_info(f"Attempted removal of scheduled task '{task_name}' for user '{username}'.")
|
917
962
|
return True
|
918
963
|
|
964
|
+
def _find_signal_script(self):
|
965
|
+
"""Finds the signal_connection.py script relative to this service file."""
|
966
|
+
return self._find_helper_script("signal_connection.py") # Reuse helper finding logic
|
967
|
+
|
968
|
+
def _find_helper_script(self, script_name):
|
969
|
+
"""Finds a helper script relative to this service file."""
|
970
|
+
try:
|
971
|
+
# Use __file__ which should be reliable when run as a service via pythonservice.exe
|
972
|
+
base_dir = os.path.dirname(os.path.abspath(__file__))
|
973
|
+
script_path = os.path.join(base_dir, script_name)
|
974
|
+
if os.path.exists(script_path):
|
975
|
+
self.log_info(f"Found helper script '{script_name}' at: {script_path}")
|
976
|
+
# Return unquoted path for potential quoting later
|
977
|
+
return script_path
|
978
|
+
else:
|
979
|
+
self.log_error(f"Helper script '{script_name}' not found near {base_dir}")
|
980
|
+
return None
|
981
|
+
except Exception as e:
|
982
|
+
self.log_error(f"Error finding helper script '{script_name}': {e}")
|
983
|
+
return None
|
984
|
+
|
985
|
+
def _find_powershell_executable(self):
|
986
|
+
"""Finds powershell.exe, preferring the system path."""
|
987
|
+
try:
|
988
|
+
# Check System32 first
|
989
|
+
system32_path = os.path.join(os.environ.get('SystemRoot', 'C:\\Windows'), 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe')
|
990
|
+
if os.path.exists(system32_path):
|
991
|
+
self.log_info(f"Found powershell.exe at: {system32_path}")
|
992
|
+
return system32_path
|
993
|
+
else:
|
994
|
+
# Fallback to checking PATH using shutil.which (requires Python 3.3+)
|
995
|
+
# Make sure to import shutil at the top of the file if not already present
|
996
|
+
powershell_path = shutil.which("powershell.exe")
|
997
|
+
if powershell_path:
|
998
|
+
self.log_info(f"Found powershell.exe via PATH: {powershell_path}")
|
999
|
+
return powershell_path
|
1000
|
+
else:
|
1001
|
+
self.log_error("powershell.exe not found in System32 or PATH.")
|
1002
|
+
return None
|
1003
|
+
except Exception as e:
|
1004
|
+
self.log_error(f"Error finding powershell.exe: {e}")
|
1005
|
+
return None
|
1006
|
+
|
919
1007
|
# --- Main Execution Block ---
|
920
1008
|
if __name__ == '__main__':
|
921
1009
|
if len(sys.argv) > 1 and sys.argv[1] == 'debug':
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# launch_ootb_elevated.ps1
|
2
|
+
param(
|
3
|
+
[Parameter(Mandatory=$true)]
|
4
|
+
[string]$TargetExePath,
|
5
|
+
|
6
|
+
[Parameter(Mandatory=$true)]
|
7
|
+
[string]$Port,
|
8
|
+
|
9
|
+
[Parameter(Mandatory=$true)]
|
10
|
+
[string]$TargetUser,
|
11
|
+
|
12
|
+
[Parameter(Mandatory=$true)]
|
13
|
+
[string]$WorkingDirectory
|
14
|
+
)
|
15
|
+
|
16
|
+
try {
|
17
|
+
Write-Host "--- OOTB Elevation Helper ---"
|
18
|
+
Write-Host "Timestamp: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
|
19
|
+
Write-Host "Received parameters:"
|
20
|
+
Write-Host " Target Exe Path : $TargetExePath"
|
21
|
+
Write-Host " Port : $Port"
|
22
|
+
Write-Host " Target User : $TargetUser"
|
23
|
+
Write-Host " Working Dir : $WorkingDirectory"
|
24
|
+
Write-Host ""
|
25
|
+
|
26
|
+
# Validate paths
|
27
|
+
if (-not (Test-Path -Path $TargetExePath -PathType Leaf)) {
|
28
|
+
throw "Target executable not found at '$TargetExePath'"
|
29
|
+
}
|
30
|
+
if (-not (Test-Path -Path $WorkingDirectory -PathType Container)) {
|
31
|
+
throw "Working directory not found at '$WorkingDirectory'"
|
32
|
+
}
|
33
|
+
|
34
|
+
# Construct the second argument for cmd.exe /K, precisely matching the working command
|
35
|
+
# Format: "<quoted_exe_path>" --port <port> --target_user ''<username>''
|
36
|
+
# Note: PowerShell handles escaping within double quotes differently.
|
37
|
+
# Using backticks ` before inner quotes is safer here.
|
38
|
+
$cmdKSecondArg = "`"`"$TargetExePath`"`" --port $Port --target_user ''$TargetUser''"
|
39
|
+
|
40
|
+
# Construct the argument list array for Start-Process launching cmd.exe
|
41
|
+
$startProcessArgs = @('/K', $cmdKSecondArg)
|
42
|
+
|
43
|
+
Write-Host "Constructed cmd.exe /K arguments: $cmdKSecondArg"
|
44
|
+
Write-Host "Constructed Start-Process arguments array: $($startProcessArgs -join ' ')" # For logging
|
45
|
+
Write-Host "Executing elevated process..."
|
46
|
+
Write-Host "Command: Start-Process -FilePath cmd.exe -ArgumentList @('/K', '$cmdKSecondArg') -WorkingDirectory '$WorkingDirectory' -Verb RunAs"
|
47
|
+
Write-Host "--- Waiting for UAC prompt if necessary ---"
|
48
|
+
|
49
|
+
# Execute the command to launch cmd elevated, which runs the target app
|
50
|
+
Start-Process -FilePath cmd.exe -ArgumentList $startProcessArgs -WorkingDirectory $WorkingDirectory -Verb RunAs
|
51
|
+
|
52
|
+
Write-Host "--- OOTB Elevation Helper: Start-Process command executed. ---"
|
53
|
+
# The calling powershell window (started by CreateProcessAsUser with -NoExit) will remain open.
|
54
|
+
|
55
|
+
} catch {
|
56
|
+
Write-Error "--- OOTB Elevation Helper Error ---"
|
57
|
+
Write-Error "Error launching elevated process: $($_.Exception.Message)"
|
58
|
+
Write-Error "Script Parameters:"
|
59
|
+
Write-Error " Target Exe Path : $TargetExePath"
|
60
|
+
Write-Error " Port : $Port"
|
61
|
+
Write-Error " Target User : $TargetUser"
|
62
|
+
Write-Error " Working Dir : $WorkingDirectory"
|
63
|
+
Write-Host "Press Enter to exit..."
|
64
|
+
Read-Host # Keep window open on error
|
65
|
+
Exit 1
|
66
|
+
}
|
67
|
+
|
68
|
+
# Exit gracefully if successful
|
69
|
+
Exit 0
|
{computer_use_ootb_internal-0.0.162.dist-info → computer_use_ootb_internal-0.0.164.dist-info}/RECORD
RENAMED
@@ -2,7 +2,8 @@ computer_use_ootb_internal/README.md,sha256=FxpW95lyub2iX73ZDfK6ML7SdEKg060H5I6G
|
|
2
2
|
computer_use_ootb_internal/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
|
3
3
|
computer_use_ootb_internal/app_teachmode.py,sha256=hiUTiX4jl1-5yqs3AwrOjNmToL5LbUb42o5XS4fiKAA,23805
|
4
4
|
computer_use_ootb_internal/dependency_check.py,sha256=y8RMEP6RXQzTgU1MS_1piBLtz4J-Hfn9RjUZg59dyvo,1333
|
5
|
-
computer_use_ootb_internal/guard_service.py,sha256=
|
5
|
+
computer_use_ootb_internal/guard_service.py,sha256=Ejfg3kXSirAN7XjVq4KlCblpwc5huJxqFN1iiDuP-68,54840
|
6
|
+
computer_use_ootb_internal/launch_ootb_elevated.ps1,sha256=h6CnpDd8pRwDqFu42E5GUuLdPrCHJWDuc_zOXaE9mtQ,2793
|
6
7
|
computer_use_ootb_internal/requirements-lite.txt,sha256=5DAHomz4A_P2BmTIXNkNqkHbnIF0AyZ4_1XAlb1LaYs,290
|
7
8
|
computer_use_ootb_internal/run_teachmode_ootb_args.py,sha256=eUPpfA7bB3bdBBiIBIxKJSS-Jpz2G6R46fpDO440Jyo,7687
|
8
9
|
computer_use_ootb_internal/service_manager.py,sha256=SD8jzfn0VVXBOr_nP6zmBWSC2TzrU_sp2e5JJkSlQFU,9734
|
@@ -34,7 +35,7 @@ computer_use_ootb_internal/computer_use_demo/tools/run.py,sha256=xhXdnBK1di9muaO
|
|
34
35
|
computer_use_ootb_internal/computer_use_demo/tools/screen_capture.py,sha256=L8qfvtUkPPQGt92N-2Zfw5ZTDBzLsDps39uMnX3_uSA,6857
|
35
36
|
computer_use_ootb_internal/preparation/__init__.py,sha256=AgtGHcBpiTkxJjF0xwcs3yyQ6SyUvhL3G0vD2XO-zJw,63
|
36
37
|
computer_use_ootb_internal/preparation/star_rail_prepare.py,sha256=r0b19M_c1sXkN3_MRFjql8w_ThC9nZUe8zbSLYUvKS8,4635
|
37
|
-
computer_use_ootb_internal-0.0.
|
38
|
-
computer_use_ootb_internal-0.0.
|
39
|
-
computer_use_ootb_internal-0.0.
|
40
|
-
computer_use_ootb_internal-0.0.
|
38
|
+
computer_use_ootb_internal-0.0.164.dist-info/METADATA,sha256=IYKzsXP34pDKBd92-DrsuLIQBmtqysJI1cihfZI3bzU,1048
|
39
|
+
computer_use_ootb_internal-0.0.164.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
40
|
+
computer_use_ootb_internal-0.0.164.dist-info/entry_points.txt,sha256=bXfyAU_qq-G1EiEgAQEioXvgEdRCFxaTooqdDD9Y4OA,258
|
41
|
+
computer_use_ootb_internal-0.0.164.dist-info/RECORD,,
|
{computer_use_ootb_internal-0.0.162.dist-info → computer_use_ootb_internal-0.0.164.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|