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

@@ -59,14 +59,14 @@ def call_hello_renamed():
59
59
  ```
60
60
 
61
61
  # *SEARCH/REPLACE block* Rules:
62
- Every "<<<<<<< SEARCH" section must *EXACTLY MATCH* the existing file content, character for character, including all comments, docstrings, whitespaces, etc.
63
62
 
64
- Including multiple unique *SEARCH/REPLACE* blocks if needed.
65
- Include enough and only enough lines in each SEARCH section to uniquely match each set of lines that need to change.
66
-
67
- Keep *SEARCH/REPLACE* blocks concise.
68
- Break large *SEARCH/REPLACE* blocks into a series of smaller blocks that each change a small portion of the file.
69
- Include just the changing lines, and a few surrounding lines (0-3 lines) if needed for uniqueness.
70
- Other than for uniqueness, avoid including those lines which do not change in search (and replace) blocks. Target 0-3 non trivial extra lines per block.
71
-
72
- Preserve leading spaces and indentations in both SEARCH and REPLACE blocks.
63
+ - Every "SEARCH" section must *EXACTLY MATCH* the existing file content, character for character, including all comments, docstrings, whitespaces, etc.
64
+ - In a single call the edit blocks should be constructed from top to bottom of the file in a sequence.
65
+ - An edit block can't edit over a previous edit in the same tool call.
66
+ - Including multiple unique *SEARCH/REPLACE* blocks if needed.
67
+ - Include enough and only enough lines in each SEARCH section to uniquely match each set of lines that need to change.
68
+ - Keep *SEARCH/REPLACE* blocks concise.
69
+ - Break large *SEARCH/REPLACE* blocks into a series of smaller blocks that each change a small portion of the file.
70
+ - Include just the changing lines, and a few surrounding lines (0-3 lines) if needed for uniqueness.
71
+ - Other than for uniqueness, avoid including those lines which do not change in search (and replace) blocks. Target 0-3 non trivial extra lines per block.
72
+ - Preserve leading spaces and indentations in both SEARCH and REPLACE blocks.
@@ -57,7 +57,6 @@ TOOL_PROMPTS = [
57
57
  - Read full file content of one or more files.
58
58
  - Provide absolute paths only (~ allowed)
59
59
  - Only if the task requires line numbers understanding:
60
- - You may populate "show_line_numbers_reason" with your reason, by default null/empty means no line numbers are shown.
61
60
  - You may extract a range of lines. E.g., `/path/to/file:1-10` for lines 1-10. You can drop start or end like `/path/to/file:1-` or `/path/to/file:-10`
62
61
  """,
63
62
  annotations=ToolAnnotations(readOnlyHint=True, openWorldHint=False),
wcgw/client/tools.py CHANGED
@@ -263,8 +263,21 @@ def initialize(
263
263
  )
264
264
  initial_files_context = f"---\n# Requested files\n{initial_files}\n---\n"
265
265
 
266
- # Check for CLAUDE.md in the workspace folder on first call
266
+ # Check for global CLAUDE.md and workspace CLAUDE.md
267
267
  alignment_context = ""
268
+
269
+ # First check for global CLAUDE.md in ~/.wcgw/CLAUDE.md
270
+ global_alignment_file_path = os.path.join(expanduser("~"), ".wcgw", "CLAUDE.md")
271
+ if os.path.exists(global_alignment_file_path):
272
+ try:
273
+ with open(global_alignment_file_path, "r") as f:
274
+ global_alignment_content = f.read()
275
+ alignment_context += f"---\n# Important guidelines from the user\n```\n{global_alignment_content}\n```\n---\n\n"
276
+ except Exception:
277
+ # Handle any errors when reading the global file
278
+ pass
279
+
280
+ # Then check for workspace-specific CLAUDE.md
268
281
  if folder_to_start:
269
282
  alignment_file_path = os.path.join(folder_to_start, "CLAUDE.md")
270
283
  if os.path.exists(alignment_file_path):
@@ -272,10 +285,10 @@ def initialize(
272
285
  # Read the CLAUDE.md file content
273
286
  with open(alignment_file_path, "r") as f:
274
287
  alignment_content = f.read()
275
- alignment_context = f"---\n# CLAUDE.md - Project alignment guidelines\n```\n{alignment_content}\n```\n---\n\n"
288
+ alignment_context += f"---\n# CLAUDE.md - user shared project guidelines to follow\n```\n{alignment_content}\n```\n---\n\n"
276
289
  except Exception:
277
290
  # Handle any errors when reading the file
278
- alignment_context = ""
291
+ pass
279
292
 
280
293
  uname_sysname = os.uname().sysname
281
294
  uname_machine = os.uname().machine
@@ -604,15 +617,12 @@ def write_file(
604
617
  paths_: list[str] = []
605
618
  for start, end in unread_ranges:
606
619
  paths_.append(path_ + ":" + f"{start}-{end}")
607
- paths_readfiles = ReadFiles(
608
- file_paths=paths_, show_line_numbers_reason=""
609
- )
620
+ paths_readfiles = ReadFiles(file_paths=paths_)
610
621
  readfiles, file_ranges_dict, truncated = read_files(
611
622
  paths_readfiles.file_paths,
612
623
  coding_max_tokens,
613
624
  noncoding_max_tokens,
614
625
  context,
615
- show_line_numbers=False,
616
626
  start_line_nums=paths_readfiles.start_line_nums,
617
627
  end_line_nums=paths_readfiles.end_line_nums,
618
628
  )
@@ -1001,7 +1011,6 @@ def get_tool_output(
1001
1011
  coding_max_tokens,
1002
1012
  noncoding_max_tokens,
1003
1013
  context,
1004
- bool(arg.show_line_numbers_reason),
1005
1014
  arg.start_line_nums,
1006
1015
  arg.end_line_nums,
1007
1016
  )
@@ -1123,7 +1132,6 @@ def read_files(
1123
1132
  coding_max_tokens: Optional[int],
1124
1133
  noncoding_max_tokens: Optional[int],
1125
1134
  context: Context,
1126
- show_line_numbers: bool = False,
1127
1135
  start_line_nums: Optional[list[Optional[int]]] = None,
1128
1136
  end_line_nums: Optional[list[Optional[int]]] = None,
1129
1137
  ) -> tuple[
@@ -1160,7 +1168,6 @@ def read_files(
1160
1168
  coding_max_tokens,
1161
1169
  noncoding_max_tokens,
1162
1170
  context,
1163
- show_line_numbers,
1164
1171
  start_line_num,
1165
1172
  end_line_num,
1166
1173
  )
@@ -1204,12 +1211,11 @@ def read_file(
1204
1211
  coding_max_tokens: Optional[int],
1205
1212
  noncoding_max_tokens: Optional[int],
1206
1213
  context: Context,
1207
- show_line_numbers: bool = False,
1208
1214
  start_line_num: Optional[int] = None,
1209
1215
  end_line_num: Optional[int] = None,
1210
1216
  ) -> tuple[str, bool, int, str, tuple[int, int]]:
1211
1217
  context.console.print(f"Reading file: {file_path}")
1212
-
1218
+ show_line_numbers = True
1213
1219
  # Line numbers are now passed as parameters, no need to parse from path
1214
1220
 
1215
1221
  # Expand the path before checking if it's absolute
@@ -1230,7 +1236,6 @@ def read_file(
1230
1236
 
1231
1237
  if all_lines and all_lines[-1].endswith("\n"):
1232
1238
  # Special handling of line counts because readlines doesn't consider last empty line as a separate line
1233
- all_lines[-1] = all_lines[-1][:-1]
1234
1239
  all_lines.append("")
1235
1240
 
1236
1241
  total_lines = len(all_lines)
@@ -1355,7 +1360,6 @@ if __name__ == "__main__":
1355
1360
  Context(BASH_STATE, BASH_STATE.console),
1356
1361
  ReadFiles(
1357
1362
  file_paths=["/Users/arusia/repos/wcgw/src/wcgw/client/tools.py"],
1358
- show_line_numbers_reason="true",
1359
1363
  ),
1360
1364
  default_enc,
1361
1365
  0,
wcgw/types_.py CHANGED
@@ -123,10 +123,13 @@ class WriteIfEmpty(BaseModel):
123
123
 
124
124
  class ReadFiles(BaseModel):
125
125
  file_paths: list[str]
126
- show_line_numbers_reason: Optional[str] = None
127
126
  _start_line_nums: List[Optional[int]] = PrivateAttr(default_factory=lambda: [])
128
127
  _end_line_nums: List[Optional[int]] = PrivateAttr(default_factory=lambda: [])
129
128
 
129
+ @property
130
+ def show_line_numbers_reason(self) -> str:
131
+ return "True"
132
+
130
133
  @property
131
134
  def start_line_nums(self) -> List[Optional[int]]:
132
135
  """Get the start line numbers."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wcgw
3
- Version: 5.2.0
3
+ Version: 5.3.1
4
4
  Summary: Shell and coding agent for Claude and other mcp clients
5
5
  Project-URL: Homepage, https://github.com/rusiaaman/wcgw
6
6
  Author-email: Aman Rusia <gapypi@arcfu.com>
@@ -19,7 +19,7 @@ Requires-Dist: pyte>=0.8.2
19
19
  Requires-Dist: python-dotenv>=1.0.1
20
20
  Requires-Dist: rich>=13.8.1
21
21
  Requires-Dist: semantic-version>=2.10.0
22
- Requires-Dist: syntax-checker==0.4.0b4
22
+ Requires-Dist: syntax-checker==0.4.0
23
23
  Requires-Dist: tokenizers>=0.21.0
24
24
  Requires-Dist: toml>=0.10.2
25
25
  Requires-Dist: tree-sitter-bash>=0.23.3
@@ -41,7 +41,6 @@ wcgw is an MCP server with tightly integrated shell and code editing tools.
41
41
  [![Mypy strict](https://github.com/rusiaaman/wcgw/actions/workflows/python-types.yml/badge.svg?branch=main)](https://github.com/rusiaaman/wcgw/actions/workflows/python-types.yml)
42
42
  [![Build](https://github.com/rusiaaman/wcgw/actions/workflows/python-publish.yml/badge.svg)](https://github.com/rusiaaman/wcgw/actions/workflows/python-publish.yml)
43
43
  [![codecov](https://codecov.io/gh/rusiaaman/wcgw/graph/badge.svg)](https://codecov.io/gh/rusiaaman/wcgw)
44
- [![Reddit](https://img.shields.io/badge/Reddit-r%2Fwcgw_mcp-red)](https://www.reddit.com/r/wcgw_mcp/)
45
44
 
46
45
  ## Demo
47
46
 
@@ -87,6 +86,7 @@ wcgw is an MCP server with tightly integrated shell and code editing tools.
87
86
  - By default it runs in 'wcgw' mode that has no restrictions and full authorisation.
88
87
  - More details in [Modes section](#modes)
89
88
  - ⚡ **Runs in multiplex terminal** Run `screen -x` to attach to the terminal that the AI runs commands on. See history or interrupt process or interact with the same terminal that AI uses.
89
+ - ⚡ **Automatically load CLAUDE.md** Loads "CLAUDE.md" file in project root and sends as instructions during initialisation. Instructions in a global "~/.wcgw/CLAUDE.md" file are loaded and added along with project specific CLAUDE.md. The file name is case sensitive.
90
90
 
91
91
  ## Top use cases examples
92
92
 
@@ -1,13 +1,13 @@
1
1
  wcgw/__init__.py,sha256=JgAY25VsA208v8E7QTIU0E50nsk-TCJ4FWTEHmnssYU,127
2
2
  wcgw/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- wcgw/types_.py,sha256=nTj0Lr_ytBDHoeQ94ebO0mzuhsluBG6GmtT9eszIjuI,8141
3
+ wcgw/types_.py,sha256=9cK7ooTbGK3QaBNJCFZLnrezfpFUSNkA8S02JCHCl6c,8174
4
4
  wcgw/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  wcgw/client/common.py,sha256=OCH7Tx64jojz3M3iONUrGMadE07W21DiZs5sOxWX1Qc,1456
6
- wcgw/client/diff-instructions.txt,sha256=eKRFA86yXWIGwNxIDaegTgTzIrFIBDWWiN1yP8Hf3i4,1685
6
+ wcgw/client/diff-instructions.txt,sha256=a-UeK9VEHJlwffAzZ-I1OiUkeMOuGU8zj3By-_STy28,1866
7
7
  wcgw/client/memory.py,sha256=U2Nw2si3Zg7n_RhNAuaYcmrrDtZ_Mooi-kfAOKflT-I,3079
8
8
  wcgw/client/modes.py,sha256=roH6SPBokJMr5IzAlccdI-vJyvyS5vqSMMyth7TE86A,10315
9
- wcgw/client/tool_prompts.py,sha256=0hfYmCzCo6kh_IC8RGJRfQ6hkB333GZvs_g3o_cvc2w,4662
10
- wcgw/client/tools.py,sha256=Xo1lOLfzuDNZljESpkSOXlPUKG_4WJGAFaZ7K7ilV8s,48788
9
+ wcgw/client/tool_prompts.py,sha256=7tq9ijSo4CznVlMFcWpauELfCT_QAqwi8Chsl3SRfBY,4539
10
+ wcgw/client/tools.py,sha256=YNxXmNj2-rhCPZ12wmfMBsAXn0_nQnCPs1OTudEh5wM,49026
11
11
  wcgw/client/bash_state/bash_state.py,sha256=b-Zo6pO3psfxu9TA0uw1ZZAa6bLmDPxbl7277fZfmrM,41862
12
12
  wcgw/client/bash_state/parser/__init__.py,sha256=AnlNSmoQTSoqqlLOLX4P1uXfzc5VGeCGJsGgtisq2zE,207
13
13
  wcgw/client/bash_state/parser/bash_statement_parser.py,sha256=9a8vPO1r3_tXmaAcubTQ5UY-NseWlalgm8LZA17LXuY,6058
@@ -30,8 +30,8 @@ wcgw_cli/anthropic_client.py,sha256=8bjDY59-aioyTJgpB-NBHZNhZaq6rqcTJcOf81kzCyA,
30
30
  wcgw_cli/cli.py,sha256=-7FBe_lahKyUOhf65iurTA1M1gXXXAiT0OVKQVcZKKo,948
31
31
  wcgw_cli/openai_client.py,sha256=GOqoSFazTV-cFjpdZGPM0DIwec8Up2TEcKUbsN40AGY,15990
32
32
  wcgw_cli/openai_utils.py,sha256=xGOb3W5ALrIozV7oszfGYztpj0FnXdD7jAxm5lEIVKY,2439
33
- wcgw-5.2.0.dist-info/METADATA,sha256=EW_fVplOiHFH1b8033vhslBodxghzY4Qw-03iugwuDg,15512
34
- wcgw-5.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
35
- wcgw-5.2.0.dist-info/entry_points.txt,sha256=UnjK-MAH4Qssh0tGJDMeij1oi-oRKokItkknP_BwShE,94
36
- wcgw-5.2.0.dist-info/licenses/LICENSE,sha256=BvY8xqjOfc3X2qZpGpX3MZEmF-4Dp0LqgKBbT6L_8oI,11142
37
- wcgw-5.2.0.dist-info/RECORD,,
33
+ wcgw-5.3.1.dist-info/METADATA,sha256=PPBEAE1xpGfRsX8I5nZuTKnQLIZnWBXzPc96CQtyhFs,15679
34
+ wcgw-5.3.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
35
+ wcgw-5.3.1.dist-info/entry_points.txt,sha256=UnjK-MAH4Qssh0tGJDMeij1oi-oRKokItkknP_BwShE,94
36
+ wcgw-5.3.1.dist-info/licenses/LICENSE,sha256=BvY8xqjOfc3X2qZpGpX3MZEmF-4Dp0LqgKBbT6L_8oI,11142
37
+ wcgw-5.3.1.dist-info/RECORD,,
File without changes