wcgw 1.5.0__py3-none-any.whl → 1.5.2__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.

Potentially problematic release.


This version of wcgw might be problematic. Click here for more details.

@@ -223,9 +223,10 @@ def loop(
223
223
  input_schema=GetScreenInfo.model_json_schema(),
224
224
  name="GetScreenInfo",
225
225
  description="""
226
- - Get display information of an OS running on docker using image "ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest"
227
- - If user hasn't provided docker image id, check using `docker ps` and provide the id.
228
226
  - Important: call this first in the conversation before ScreenShot, Mouse, and Keyboard tools.
227
+ - Get display information of a linux os running on docker using image "ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest"
228
+ - If user hasn't provided docker image id, check using `docker ps` and provide the id.
229
+ - If the docker is not running, run using `docker run -d -p 6080:6080 ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest`
229
230
  - Connects shell to the docker environment.
230
231
  - Note: once this is called, the shell enters the docker environment. All bash commands will run over there.
231
232
  """,
@@ -234,26 +235,22 @@ def loop(
234
235
  input_schema=ScreenShot.model_json_schema(),
235
236
  name="ScreenShot",
236
237
  description="""
237
- - Capture screenshot of an OS running on docker using image "ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest"
238
- - If user hasn't provided docker image id, check using `docker ps` and provide the id.
239
- - Capture ScreenShot of the current screen for automation.
238
+ - Capture screenshot of the linux os on docker.
240
239
  """,
241
240
  ),
242
241
  ToolParam(
243
242
  input_schema=Mouse.model_json_schema(),
244
243
  name="Mouse",
245
244
  description="""
246
- - Interact with docker container running image "ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest"
247
- - If user hasn't provided docker image id, check using `docker ps` and provide the id.
248
- - Interact with the screen using mouse
245
+ - Interact with the linux os on docker using mouse.
246
+ - Uses xdotool
249
247
  """,
250
248
  ),
251
249
  ToolParam(
252
250
  input_schema=Keyboard.model_json_schema(),
253
251
  name="Keyboard",
254
252
  description="""
255
- - Interact with docker container running image "ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest"
256
- - If user hasn't provided docker image id, check using `docker ps` and provide the id.
253
+ - Interact with the linux os on docker using keyboard.
257
254
  - Emulate keyboard input to the screen
258
255
  - Uses xdootool to send keyboard input, keys like Return, BackSpace, Escape, Page_Up, etc. can be used.
259
256
  - Do not use it to interact with Bash tool.
@@ -26,7 +26,6 @@ from ..types_ import (
26
26
  OUTPUT_DIR = "/tmp/outputs"
27
27
  TYPING_DELAY_MS = 12
28
28
  TYPING_GROUP_SIZE = 50
29
- TRUNCATED_MESSAGE: str = "<response clipped><NOTE>To save on context only part of this file has been shown to you.</NOTE>"
30
29
 
31
30
  Action = Literal[
32
31
  "key",
@@ -187,6 +186,7 @@ class ComputerTool:
187
186
  docker_image_id: Optional[str] = None,
188
187
  text: str | None = None,
189
188
  coordinate: tuple[int, int] | None = None,
189
+ do_left_click_on_move: bool | None = None,
190
190
  **kwargs: Any,
191
191
  ) -> ToolResult:
192
192
  if action == "get_screen_info":
@@ -218,7 +218,12 @@ class ComputerTool:
218
218
  )
219
219
 
220
220
  if action == "mouse_move":
221
- return self.shell(f"{self.xdotool} mousemove {x} {y}")
221
+ if not do_left_click_on_move:
222
+ return self.shell(f"{self.xdotool} mousemove {x} {y}")
223
+ else:
224
+ return self.shell(
225
+ f"{self.xdotool} mousemove {x} {y} click 1",
226
+ )
222
227
  elif action == "left_click_drag":
223
228
  return self.shell(
224
229
  f"{self.xdotool} mousedown 1 mousemove {x} {y} mouseup 1",
@@ -402,6 +407,7 @@ def run_computer_tool(
402
407
  result = Computer(
403
408
  action="mouse_move",
404
409
  coordinate=(action.action.x, action.action.y),
410
+ do_left_click_on_move=action.action.do_left_click_on_move,
405
411
  )
406
412
  elif isinstance(action.action, LeftClickDrag):
407
413
  result = Computer(
@@ -1,15 +1,10 @@
1
1
  # Claude desktop support
2
2
 
3
- ## Setup
4
-
5
- Install xdtool
3
+ `wcgw` enables Claude desktop app on Mac to access shell and file system in order to automate tasks, run code, etc.
6
4
 
7
- ```sh
8
- brew install xdotool
5
+ It also has a computer use feature to connect to linux running on docker. Claude can fully control it including mouse and keyboard.
9
6
 
10
- # On macos:
11
- defaults write org.x.X11 enable_test_extensions -boolean true
12
- ```
7
+ ## Setup
13
8
 
14
9
  Update `claude_desktop_config.json` (~/Library/Application Support/Claude/claude_desktop_config.json)
15
10
 
@@ -17,8 +12,16 @@ Update `claude_desktop_config.json` (~/Library/Application Support/Claude/claude
17
12
  {
18
13
  "mcpServers": {
19
14
  "wcgw": {
20
- "command": "uvx",
21
- "args": ["--from", "wcgw@latest", "wcgw_mcp"]
15
+ "command": "uv",
16
+ "args": [
17
+ "tool",
18
+ "run",
19
+ "--from",
20
+ "wcgw@latest",
21
+ "--python",
22
+ "3.12",
23
+ "wcgw_mcp"
24
+ ]
22
25
  }
23
26
  }
24
27
  }
@@ -26,28 +29,17 @@ Update `claude_desktop_config.json` (~/Library/Application Support/Claude/claude
26
29
 
27
30
  Then restart claude app.
28
31
 
29
- ### Computer use support using desktop on docker
32
+ ### [Optional] Computer use support using desktop on docker
30
33
 
31
- Controlling the system isn't possible yet, but you can connect to a docker container which runs a linux os with desktop.
34
+ Computer use is enabled by default. Claude will be able to connect to any docker container with linux environment. Native system control isn't supported outside docker.
32
35
 
33
36
  First run a sample docker image with desktop and optionally VNC connection:
34
37
 
35
38
  ```sh
36
- docker run \
37
- --entrypoint "" \
38
- -p 6080:6080 \
39
- -e WIDTH=1024 \
40
- -e HEIGHT=768 \
41
- -d \
42
- ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest \
43
- bash -c "\
44
- ./start_all.sh && \
45
- ./novnc_startup.sh && \
46
- python http_server.py > /tmp/server_logs.txt 2>&1 & \
47
- tail -f /dev/null"
39
+ docker run -p 6080:6080 ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest
48
40
  ```
49
41
 
50
- Connect to `http://localhost:6080/vnc.html` for desktop view (VNC) of the system running in the docker.
42
+ Connect to `http://localhost:6080/vnc.html` for desktop view (VNC) of the system running in the docker. Then ask claude desktop app to control the docker os.
51
43
 
52
44
  ## Usage
53
45
 
@@ -10,8 +10,9 @@ from mcp.server.models import InitializationOptions
10
10
  import mcp.types as types
11
11
  from mcp.types import Tool as ToolParam
12
12
  from mcp.server import NotificationOptions, Server
13
- from pydantic import AnyUrl, ValidationError
13
+ from pydantic import AnyUrl, BaseModel, ValidationError
14
14
  import mcp.server.stdio
15
+ from .. import tools
15
16
  from ..tools import DoneFlag, get_tool_output, which_tool_name, default_enc
16
17
  from ...types_ import (
17
18
  BashCommand,
@@ -29,6 +30,7 @@ from ...types_ import (
29
30
  )
30
31
  from ..computer_use import Computer
31
32
 
33
+ tools.TIMEOUT = 3
32
34
 
33
35
  server = Server("wcgw")
34
36
 
@@ -149,9 +151,10 @@ async def handle_list_tools() -> list[types.Tool]:
149
151
  inputSchema=GetScreenInfo.model_json_schema(),
150
152
  name="GetScreenInfo",
151
153
  description="""
152
- - Get display information of an OS running on docker using image "ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest"
153
- - If user hasn't provided docker image id, check using `docker ps` and provide the id.
154
154
  - Important: call this first in the conversation before ScreenShot, Mouse, and Keyboard tools.
155
+ - Get display information of a linux os running on docker using image "ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest"
156
+ - If user hasn't provided docker image id, check using `docker ps` and provide the id.
157
+ - If the docker is not running, run using `docker run -d -p 6080:6080 ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest`
155
158
  - Connects shell to the docker environment.
156
159
  - Note: once this is called, the shell enters the docker environment. All bash commands will run over there.
157
160
  """,
@@ -160,29 +163,26 @@ async def handle_list_tools() -> list[types.Tool]:
160
163
  inputSchema=ScreenShot.model_json_schema(),
161
164
  name="ScreenShot",
162
165
  description="""
163
- - Capture screenshot of an OS running on docker using image "ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest"
164
- - If user hasn't provided docker image id, check using `docker ps` and provide the id.
165
- - Capture ScreenShot of the current screen for automation.
166
+ - Capture screenshot of the linux os on docker.
166
167
  """,
167
168
  ),
168
169
  ToolParam(
169
170
  inputSchema=Mouse.model_json_schema(),
170
171
  name="Mouse",
171
172
  description="""
172
- - Interact with docker container running image "ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest"
173
- - If user hasn't provided docker image id, check using `docker ps` and provide the id.
174
- - Interact with the screen using mouse
173
+ - Interact with the linux os on docker using mouse.
174
+ - Uses xdotool
175
175
  """,
176
176
  ),
177
177
  ToolParam(
178
178
  inputSchema=Keyboard.model_json_schema(),
179
179
  name="Keyboard",
180
180
  description="""
181
- - Interact with docker container running image "ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest"
182
- - If user hasn't provided docker image id, check using `docker ps` and provide the id.
181
+ - Interact with the linux os on docker using keyboard.
183
182
  - Emulate keyboard input to the screen
184
183
  - Uses xdootool to send keyboard input, keys like Return, BackSpace, Escape, Page_Up, etc. can be used.
185
184
  - Do not use it to interact with Bash tool.
185
+ - Make sure you've selected a text area or an editable element before sending text.
186
186
  """,
187
187
  ),
188
188
  ]
@@ -272,7 +272,7 @@ async def main() -> None:
272
272
  experimental_capabilities={},
273
273
  ),
274
274
  ),
275
- raise_exceptions=True,
275
+ raise_exceptions=False,
276
276
  )
277
277
  except BaseException as e:
278
278
  print(f"Server encountered an error: {e}", file=sys.stderr)
wcgw/client/sys_utils.py CHANGED
@@ -1,6 +1,7 @@
1
1
  import subprocess
2
2
 
3
3
  MAX_RESPONSE_LEN: int = 16000
4
+ TRUNCATED_MESSAGE: str = "<response clipped><NOTE>To save on context only part of this file has been shown to you.</NOTE>"
4
5
 
5
6
 
6
7
  def maybe_truncate(content: str, truncate_after: int | None = MAX_RESPONSE_LEN) -> str:
@@ -14,7 +15,7 @@ def maybe_truncate(content: str, truncate_after: int | None = MAX_RESPONSE_LEN)
14
15
 
15
16
  def command_run(
16
17
  cmd: str,
17
- timeout: float | None = 30.0, # seconds
18
+ timeout: float | None = 3.0, # seconds
18
19
  truncate_after: int | None = MAX_RESPONSE_LEN,
19
20
  text: bool = True,
20
21
  ) -> tuple[int, str, str]:
wcgw/client/tools.py CHANGED
@@ -71,7 +71,7 @@ from .openai_utils import get_input_cost, get_output_cost
71
71
 
72
72
  console = rich.console.Console(style="magenta", highlight=False, markup=False)
73
73
 
74
- TIMEOUT = 30
74
+ TIMEOUT = 5
75
75
 
76
76
 
77
77
  def render_terminal_output(text: str) -> str:
@@ -113,9 +113,9 @@ def start_shell() -> pexpect.spawn: # type: ignore
113
113
  encoding="utf-8",
114
114
  timeout=TIMEOUT,
115
115
  )
116
- SHELL.expect(PROMPT)
116
+ SHELL.expect(PROMPT, timeout=TIMEOUT)
117
117
  SHELL.sendline("stty -icanon -echo")
118
- SHELL.expect(PROMPT)
118
+ SHELL.expect(PROMPT, timeout=TIMEOUT)
119
119
  return SHELL
120
120
 
121
121
 
@@ -135,15 +135,15 @@ def _get_exit_code() -> int:
135
135
  return 0
136
136
  # First reset the prompt in case venv was sourced or other reasons.
137
137
  SHELL.sendline(f"export PS1={PROMPT}")
138
- SHELL.expect(PROMPT)
138
+ SHELL.expect(PROMPT, timeout=0.2)
139
139
  # Reset echo also if it was enabled
140
140
  SHELL.sendline("stty -icanon -echo")
141
- SHELL.expect(PROMPT)
141
+ SHELL.expect(PROMPT, timeout=0.2)
142
142
  SHELL.sendline("echo $?")
143
143
  before = ""
144
144
  while not _is_int(before): # Consume all previous output
145
145
  try:
146
- SHELL.expect(PROMPT)
146
+ SHELL.expect(PROMPT, timeout=0.2)
147
147
  except pexpect.TIMEOUT:
148
148
  print(f"Couldn't get exit code, before: {before}")
149
149
  raise
@@ -170,6 +170,7 @@ def initial_info() -> str:
170
170
  System: {uname_sysname}
171
171
  Machine: {uname_machine}
172
172
  Current working directory: {CWD}
173
+ wcgw version: {importlib.metadata.version("wcgw")}
173
174
  """
174
175
 
175
176
 
@@ -215,7 +216,7 @@ def update_repl_prompt(command: str) -> bool:
215
216
 
216
217
  def get_cwd() -> str:
217
218
  SHELL.sendline("pwd")
218
- SHELL.expect(PROMPT)
219
+ SHELL.expect(PROMPT, timeout=0.2)
219
220
  assert isinstance(SHELL.before, str)
220
221
  current_dir = render_terminal_output(SHELL.before).strip()
221
222
  return current_dir
@@ -342,13 +343,13 @@ def execute_bash(
342
343
  SHELL.expect(PROMPT)
343
344
  return "---\n\nFailure: user interrupted the execution", 0.0
344
345
 
345
- wait = timeout_s or 5
346
+ wait = timeout_s or TIMEOUT
346
347
  index = SHELL.expect([PROMPT, pexpect.TIMEOUT], timeout=wait)
347
348
  if index == 1:
348
349
  BASH_STATE = "pending"
349
350
  text = SHELL.before or ""
350
351
 
351
- text = render_terminal_output(text)
352
+ text = render_terminal_output(text[-100_000:])
352
353
  tokens = enc.encode(text)
353
354
 
354
355
  if max_tokens and len(tokens) >= max_tokens:
@@ -855,7 +856,7 @@ def get_tool_output(
855
856
  if imgBs64:
856
857
  console.print("Captured screenshot")
857
858
  outputs.append(ImageData(media_type="image/png", data=imgBs64))
858
- if not IS_IN_DOCKER:
859
+ if not IS_IN_DOCKER and isinstance(arg, GetScreenInfo):
859
860
  try:
860
861
  # At this point we should go into the docker env
861
862
  res, _ = execute_bash(
@@ -989,7 +990,7 @@ def read_file(readfile: ReadFile, max_tokens: Optional[int]) -> str:
989
990
 
990
991
  else:
991
992
  return_code, content, stderr = command_run(
992
- f"cat {readfile.file_path}",
993
+ f"cat {readfile.file_path}", timeout=TIMEOUT
993
994
  )
994
995
  if return_code != 0:
995
996
  raise Exception(
wcgw/types_.py CHANGED
@@ -60,12 +60,12 @@ class GetScreenInfo(BaseModel):
60
60
 
61
61
  class ScreenShot(BaseModel):
62
62
  type: Literal["ScreenShot"]
63
- docker_image_id: str
64
63
 
65
64
 
66
65
  class MouseMove(BaseModel):
67
66
  x: int
68
67
  y: int
68
+ do_left_click_on_move: bool
69
69
  type: Literal["MouseMove"]
70
70
 
71
71
 
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: wcgw
3
- Version: 1.5.0
3
+ Version: 1.5.2
4
4
  Summary: What could go wrong giving full shell access to chatgpt?
5
5
  Project-URL: Homepage, https://github.com/rusiaaman/wcgw
6
6
  Author-email: Aman Rusia <gapypi@arcfu.com>
7
7
  Requires-Python: <3.13,>=3.11
8
8
  Requires-Dist: anthropic>=0.39.0
9
9
  Requires-Dist: fastapi>=0.115.0
10
- Requires-Dist: mcp>=1.0.0
10
+ Requires-Dist: mcp
11
11
  Requires-Dist: mypy>=1.11.2
12
12
  Requires-Dist: nltk>=3.9.1
13
13
  Requires-Dist: openai>=1.46.0
@@ -29,7 +29,9 @@ Description-Content-Type: text/markdown
29
29
 
30
30
  # Shell and Coding agent on Chatgpt and Claude desktop apps
31
31
 
32
- A custom gpt on chatgpt web/desktop apps to interact with your local shell, edit files, run code, etc.
32
+ - An MCP server on claude desktop for autonomous shell, coding and desktop control agent.
33
+ - A custom gpt on chatgpt web/desktop apps to interact with your local shell, edit files, run code, etc.
34
+
33
35
 
34
36
  [![Tests](https://github.com/rusiaaman/wcgw/actions/workflows/python-tests.yml/badge.svg?branch=main)](https://github.com/rusiaaman/wcgw/actions/workflows/python-tests.yml)
35
37
  [![Build](https://github.com/rusiaaman/wcgw/actions/workflows/python-publish.yml/badge.svg)](https://github.com/rusiaaman/wcgw/actions/workflows/python-publish.yml)
@@ -40,6 +42,7 @@ A custom gpt on chatgpt web/desktop apps to interact with your local shell, edit
40
42
  ### 🚀 Highlights
41
43
 
42
44
  - ⚡ **Full Shell Access**: No restrictions, complete control.
45
+ - ⚡ **Desktop control on Claude**: Screen capture, mouse control, keyboard control on claude desktop (on mac with docker linux)
43
46
  - ⚡ **Create, Execute, Iterate**: Ask the gpt to keep running compiler checks till all errors are fixed, or ask it to keep checking for the status of a long running command till it's done.
44
47
  - ⚡ **Interactive Command Handling**: Supports interactive commands using arrow keys, interrupt, and ansi escape sequences.
45
48
  - ⚡ **REPL support**: [beta] Supports python/node and other REPL execution.
@@ -1,22 +1,22 @@
1
1
  wcgw/__init__.py,sha256=9K2QW7QuSLhMTVbKbBYd9UUp-ZyrfBrxcjuD_xk458k,118
2
- wcgw/types_.py,sha256=STKGeVdQNK_k8mcmAXpKZJY9YUpU7-mbJcFpXfzBuys,1732
2
+ wcgw/types_.py,sha256=EUhSD8eQAJgoLb3Q4H5n57eged6t0ayVW0CLgFvs9jQ,1739
3
3
  wcgw/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  wcgw/client/__main__.py,sha256=wcCrL4PjG51r5wVKqJhcoJPTLfHW0wNbD31DrUN0MWI,28
5
- wcgw/client/anthropic_client.py,sha256=owR-nIxQVGgw_ned8JOQ-QmmCBQvZSqgD08kYpU_Rbg,17730
5
+ wcgw/client/anthropic_client.py,sha256=_vFOraYHGjjMZKqdVOgH5CY6mUG0OQRYDH3img2LPEg,17325
6
6
  wcgw/client/cli.py,sha256=Oja42CHkVO8puqOXflko9NeephYCMa85aBmQTEjBZtI,932
7
7
  wcgw/client/common.py,sha256=grH-yV_4tnTQZ29xExn4YicGLxEq98z-HkEZwH0ReSg,1410
8
- wcgw/client/computer_use.py,sha256=jZCw4p7qfHEmhv9eqc1zyPyLTUyb54Ipw5UnRqzRWqc,14399
8
+ wcgw/client/computer_use.py,sha256=1Sev4HhHix-FWNb77l5nJd2EXe906AkAiaDUNRLK-Zo,14605
9
9
  wcgw/client/diff-instructions.txt,sha256=s5AJKG23JsjwRYhFZFQVvwDpF67vElawrmdXwvukR1A,1683
10
10
  wcgw/client/openai_client.py,sha256=L61ajFVQW2QPS3C0n1YsjgF4vQKfMIZHmp6iFBHutX8,17748
11
11
  wcgw/client/openai_utils.py,sha256=YNwCsA-Wqq7jWrxP0rfQmBTb1dI0s7dWXzQqyTzOZT4,2629
12
- wcgw/client/sys_utils.py,sha256=7_7o1Au33OkZUsW5nKW55xW_YRYZlvUpY6tHVLIILm8,1254
13
- wcgw/client/tools.py,sha256=PbS1YBELqibShPrpKCGq3KeXLS4t6AhTTkB5pQMgX-g,32476
14
- wcgw/client/mcp_server/Readme.md,sha256=dK9NqFQ0_tblLOgPI6DjWrSYs2UWKEJkvgnLW3T-EZk,1944
12
+ wcgw/client/sys_utils.py,sha256=GajPntKhaTUMn6EOmopENWZNR2G_BJyuVbuot0x6veI,1376
13
+ wcgw/client/tools.py,sha256=d7Fni7JU3aOh2vXBAw5k5rsxkdQVcxoxc5vipvEsA2g,32680
14
+ wcgw/client/mcp_server/Readme.md,sha256=1hNZtqltsORug7OzUjjoK5O8q5s9-Y3S0_rlzT-Wfg4,2033
15
15
  wcgw/client/mcp_server/__init__.py,sha256=cQ7PUrEmXUpio8x0SEoGWP5hCRPd7z2bAkNCbYbtTys,236
16
- wcgw/client/mcp_server/server.py,sha256=EzO4VNuSfcIMTue3sCsCqTTMku_AmsgJctBuPQfEQ8w,10160
16
+ wcgw/client/mcp_server/server.py,sha256=kKtPlPUIerC3eWB10IfNK_erLWGIi-jU0MP99j2d4bc,9890
17
17
  wcgw/relay/serve.py,sha256=RUcUeyL4Xt0EEo12Ul6VQjb4tRle4uIdsa85v7XXxEw,8771
18
18
  wcgw/relay/static/privacy.txt,sha256=s9qBdbx2SexCpC_z33sg16TptmAwDEehMCLz4L50JLc,529
19
- wcgw-1.5.0.dist-info/METADATA,sha256=_bTBKk1cMtbqt7dgM-wge3LuNCTe4s1CDzdSyR7P3WU,6292
20
- wcgw-1.5.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
21
- wcgw-1.5.0.dist-info/entry_points.txt,sha256=eKo1omwbAggWlQ0l7GKoR7uV1-j16nk9tK0BhC2Oz_E,120
22
- wcgw-1.5.0.dist-info/RECORD,,
19
+ wcgw-1.5.2.dist-info/METADATA,sha256=215jNmTFbkeETl2JrncCWwgEpUJU9H3MaE1pMHQEUyQ,6508
20
+ wcgw-1.5.2.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
21
+ wcgw-1.5.2.dist-info/entry_points.txt,sha256=eKo1omwbAggWlQ0l7GKoR7uV1-j16nk9tK0BhC2Oz_E,120
22
+ wcgw-1.5.2.dist-info/RECORD,,
File without changes