wcgw 3.0.1rc3__tar.gz → 3.0.2__tar.gz
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.
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/PKG-INFO +24 -8
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/README.md +23 -7
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/gpt_action_json_schema.json +11 -93
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/gpt_instructions.txt +10 -13
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/pyproject.toml +1 -1
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/bash_state/bash_state.py +38 -117
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/modes.py +13 -12
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/tool_prompts.py +5 -11
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/tools.py +87 -47
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/relay/serve.py +0 -31
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/types_.py +24 -20
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw_cli/anthropic_client.py +26 -10
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw_cli/openai_client.py +1 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/tests/test_edit.py +1 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/tests/test_mcp_server.py +2 -5
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/tests/test_tools.py +79 -25
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/uv.lock +105 -103
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/.github/workflows/python-publish.yml +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/.github/workflows/python-tests.yml +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/.github/workflows/python-types.yml +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/.gitignore +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/.gitmodules +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/.python-version +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/.vscode/settings.json +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/Dockerfile +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/LICENSE +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/openai.md +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/.git +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/.github/workflows/main-checks.yml +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/.github/workflows/publish-pypi.yml +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/.github/workflows/pull-request-checks.yml +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/.github/workflows/shared.yml +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/.gitignore +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/.python-version +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/CODE_OF_CONDUCT.md +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/CONTRIBUTING.md +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/LICENSE +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/README.md +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/RELEASE.md +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/SECURITY.md +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/README.md +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-prompt/.python-version +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-prompt/README.md +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-prompt/mcp_simple_prompt/__init__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-prompt/mcp_simple_prompt/__main__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-prompt/mcp_simple_prompt/server.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-prompt/pyproject.toml +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-resource/.python-version +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-resource/README.md +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-resource/mcp_simple_resource/__init__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-resource/mcp_simple_resource/__main__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-resource/mcp_simple_resource/server.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-resource/pyproject.toml +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-tool/.python-version +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-tool/README.md +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-tool/mcp_simple_tool/__init__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-tool/mcp_simple_tool/__main__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-tool/mcp_simple_tool/server.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/examples/servers/simple-tool/pyproject.toml +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/pyproject.toml +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/__init__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/client/__init__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/client/__main__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/client/session.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/client/sse.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/client/stdio.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/py.typed +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/server/__init__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/server/__main__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/server/models.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/server/session.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/server/sse.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/server/stdio.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/server/websocket.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/shared/__init__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/shared/context.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/shared/exceptions.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/shared/memory.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/shared/progress.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/shared/session.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/shared/version.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/src/mcp_wcgw/types.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/tests/__init__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/tests/client/__init__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/tests/client/test_session.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/tests/client/test_stdio.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/tests/conftest.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/tests/server/__init__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/tests/server/test_session.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/tests/server/test_stdio.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/tests/shared/test_memory.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/tests/test_types.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/mcp_wcgw_fork/uv.lock +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/__init__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/__init__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/common.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/diff-instructions.txt +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/encoder/__init__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/file_ops/diff_edit.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/file_ops/search_replace.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/mcp_server/Readme.md +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/mcp_server/__init__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/mcp_server/server.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/memory.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/repo_ops/display_tree.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/repo_ops/path_prob.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/repo_ops/paths_model.vocab +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/repo_ops/paths_tokens.model +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/client/repo_ops/repo_context.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/py.typed +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/relay/client.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw/relay/static/privacy.txt +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw_cli/__init__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw_cli/__main__.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw_cli/cli.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/src/wcgw_cli/openai_utils.py +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/static/claude-ss.jpg +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/static/computer-use.jpg +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/static/example.jpg +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/static/rocket-icon.png +0 -0
- {wcgw-3.0.1rc3 → wcgw-3.0.2}/static/ss1.png +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wcgw
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.2
|
|
4
4
|
Summary: Shell and coding agent on claude and chatgpt
|
|
5
5
|
Project-URL: Homepage, https://github.com/rusiaaman/wcgw
|
|
6
6
|
Author-email: Aman Rusia <gapypi@arcfu.com>
|
|
@@ -43,6 +43,8 @@ Empowering chat applications to code, build and run on your local machine.
|
|
|
43
43
|
|
|
44
44
|
## Updates
|
|
45
45
|
|
|
46
|
+
- [16 Feb 2025] You can now attach to the working terminal that the AI uses. See the "attach-to-terminal" section below.
|
|
47
|
+
|
|
46
48
|
- [15 Jan 2025] Modes introduced: architect, code-writer, and all powerful wcgw mode.
|
|
47
49
|
|
|
48
50
|
- [8 Jan 2025] Context saving tool for saving relevant file paths along with a description in a single file. Can be used as a task checkpoint or for knowledge transfer.
|
|
@@ -51,9 +53,6 @@ Empowering chat applications to code, build and run on your local machine.
|
|
|
51
53
|
|
|
52
54
|
- [9 Dec 2024] [Vscode extension to paste context on Claude app](https://marketplace.visualstudio.com/items?itemName=AmanRusia.wcgw)
|
|
53
55
|
|
|
54
|
-
- [01 Dec 2024] Removed author hosted relay server for chatgpt.
|
|
55
|
-
|
|
56
|
-
- [26 Nov 2024] Introduced claude desktop support through mcp
|
|
57
56
|
|
|
58
57
|
## 🚀 Highlights
|
|
59
58
|
|
|
@@ -100,7 +99,7 @@ First install `uv` using homebrew `brew install uv`
|
|
|
100
99
|
|
|
101
100
|
(**Important:** use homebrew to install uv. Otherwise make sure `uv` is present in a global location like /usr/bin/)
|
|
102
101
|
|
|
103
|
-
Then update `claude_desktop_config.json` (~/Library/Application Support/Claude/claude_desktop_config.json)
|
|
102
|
+
Then create or update `claude_desktop_config.json` (~/Library/Application Support/Claude/claude_desktop_config.json) with following json.
|
|
104
103
|
|
|
105
104
|
```json
|
|
106
105
|
{
|
|
@@ -127,6 +126,8 @@ _If there's an error in setting up_
|
|
|
127
126
|
|
|
128
127
|
- If there's an error like "uv ENOENT", make sure `uv` is installed. Then run 'which uv' in the terminal, and use its output in place of "uv" in the configuration.
|
|
129
128
|
- If there's still an issue, check that `uv tool run --from wcgw@latest --python 3.12 wcgw_mcp` runs in your terminal. It should have no output and shouldn't exit.
|
|
129
|
+
- Try removing ~/.cache/uv folder
|
|
130
|
+
- Try using `uv` version `0.6.0` for which this tool was tested.
|
|
130
131
|
- Debug the mcp server using `npx @modelcontextprotocol/inspector@0.1.7 uv tool run --from wcgw@latest --python 3.12 wcgw_mcp`
|
|
131
132
|
|
|
132
133
|
### Alternative configuration using smithery (npx required)
|
|
@@ -139,6 +140,9 @@ Then to configure wcgw for Claude Desktop automatically via [Smithery](https://s
|
|
|
139
140
|
npx -y @smithery/cli install wcgw --client claude
|
|
140
141
|
```
|
|
141
142
|
|
|
143
|
+
_If there's an error in setting up_
|
|
144
|
+
- Try removing ~/.cache/uv folder
|
|
145
|
+
|
|
142
146
|
### Usage
|
|
143
147
|
|
|
144
148
|
Wait for a few seconds. You should be able to see this icon if everything goes right.
|
|
@@ -168,6 +172,21 @@ There are three built-in modes. You may ask Claude to run in one of the modes, l
|
|
|
168
172
|
|
|
169
173
|
Note: in code-writer mode either all commands are allowed or none are allowed for now. If you give a list of allowed commands, Claude is instructed to run only those commands, but no actual check happens. (WIP)
|
|
170
174
|
|
|
175
|
+
#### Attach to the working terminal to investigate
|
|
176
|
+
If you've `screen` command installed, wcgw runs on a screen instance automatically. If you've started wcgw mcp server, you can list the screen sessions:
|
|
177
|
+
|
|
178
|
+
`screen -ls`
|
|
179
|
+
|
|
180
|
+
And note down the wcgw screen name which will be something like `93358.wcgw.235521` where the last number is in the hour-minute-second format.
|
|
181
|
+
|
|
182
|
+
You can then attach to the session using `screen -x 93358.wcgw.235521`
|
|
183
|
+
|
|
184
|
+
You may interrupt any running command safely.
|
|
185
|
+
|
|
186
|
+
You can interact with the terminal but beware that the AI might be running in parallel and it may conflict with what you're doing. It's recommended to keep your interactions to minimum.
|
|
187
|
+
|
|
188
|
+
You shouldn't exit the session using `exit `or Ctrl-d, instead you should use `ctrl+a+d` to safely detach without destroying the screen session.
|
|
189
|
+
|
|
171
190
|
### [Optional] Vs code extension
|
|
172
191
|
|
|
173
192
|
https://marketplace.visualstudio.com/items?itemName=AmanRusia.wcgw
|
|
@@ -216,7 +235,6 @@ The server provides the following MCP tools:
|
|
|
216
235
|
- Parameters: `any_workspace_path` (string), `initial_files_to_read` (string[]), `mode_name` ("wcgw"|"architect"|"code_writer"), `task_id_to_resume` (string)
|
|
217
236
|
- `BashCommand`: Execute shell commands with timeout control
|
|
218
237
|
- Parameters: `command` (string), `wait_for_seconds` (int, optional)
|
|
219
|
-
- `BashInteraction`: Send keyboard input to running programs
|
|
220
238
|
- Parameters: `send_text` (string) or `send_specials` (["Enter"|"Key-up"|...]) or `send_ascii` (int[]), `wait_for_seconds` (int, optional)
|
|
221
239
|
|
|
222
240
|
**File Operations:**
|
|
@@ -234,7 +252,5 @@ The server provides the following MCP tools:
|
|
|
234
252
|
|
|
235
253
|
- `ContextSave`: Save project context and files for Knowledge Transfer or saving task checkpoints to be resumed later
|
|
236
254
|
- Parameters: `id` (string), `project_root_path` (string), `description` (string), `relevant_file_globs` (string[])
|
|
237
|
-
- `ResetShell`: Emergency reset for shell environment
|
|
238
|
-
- Parameters: `should_reset` (boolean)
|
|
239
255
|
|
|
240
256
|
All tools support absolute paths and include built-in protections against common errors. See the [MCP specification](https://modelcontextprotocol.io/) for detailed protocol information.
|
|
@@ -15,6 +15,8 @@ Empowering chat applications to code, build and run on your local machine.
|
|
|
15
15
|
|
|
16
16
|
## Updates
|
|
17
17
|
|
|
18
|
+
- [16 Feb 2025] You can now attach to the working terminal that the AI uses. See the "attach-to-terminal" section below.
|
|
19
|
+
|
|
18
20
|
- [15 Jan 2025] Modes introduced: architect, code-writer, and all powerful wcgw mode.
|
|
19
21
|
|
|
20
22
|
- [8 Jan 2025] Context saving tool for saving relevant file paths along with a description in a single file. Can be used as a task checkpoint or for knowledge transfer.
|
|
@@ -23,9 +25,6 @@ Empowering chat applications to code, build and run on your local machine.
|
|
|
23
25
|
|
|
24
26
|
- [9 Dec 2024] [Vscode extension to paste context on Claude app](https://marketplace.visualstudio.com/items?itemName=AmanRusia.wcgw)
|
|
25
27
|
|
|
26
|
-
- [01 Dec 2024] Removed author hosted relay server for chatgpt.
|
|
27
|
-
|
|
28
|
-
- [26 Nov 2024] Introduced claude desktop support through mcp
|
|
29
28
|
|
|
30
29
|
## 🚀 Highlights
|
|
31
30
|
|
|
@@ -72,7 +71,7 @@ First install `uv` using homebrew `brew install uv`
|
|
|
72
71
|
|
|
73
72
|
(**Important:** use homebrew to install uv. Otherwise make sure `uv` is present in a global location like /usr/bin/)
|
|
74
73
|
|
|
75
|
-
Then update `claude_desktop_config.json` (~/Library/Application Support/Claude/claude_desktop_config.json)
|
|
74
|
+
Then create or update `claude_desktop_config.json` (~/Library/Application Support/Claude/claude_desktop_config.json) with following json.
|
|
76
75
|
|
|
77
76
|
```json
|
|
78
77
|
{
|
|
@@ -99,6 +98,8 @@ _If there's an error in setting up_
|
|
|
99
98
|
|
|
100
99
|
- If there's an error like "uv ENOENT", make sure `uv` is installed. Then run 'which uv' in the terminal, and use its output in place of "uv" in the configuration.
|
|
101
100
|
- If there's still an issue, check that `uv tool run --from wcgw@latest --python 3.12 wcgw_mcp` runs in your terminal. It should have no output and shouldn't exit.
|
|
101
|
+
- Try removing ~/.cache/uv folder
|
|
102
|
+
- Try using `uv` version `0.6.0` for which this tool was tested.
|
|
102
103
|
- Debug the mcp server using `npx @modelcontextprotocol/inspector@0.1.7 uv tool run --from wcgw@latest --python 3.12 wcgw_mcp`
|
|
103
104
|
|
|
104
105
|
### Alternative configuration using smithery (npx required)
|
|
@@ -111,6 +112,9 @@ Then to configure wcgw for Claude Desktop automatically via [Smithery](https://s
|
|
|
111
112
|
npx -y @smithery/cli install wcgw --client claude
|
|
112
113
|
```
|
|
113
114
|
|
|
115
|
+
_If there's an error in setting up_
|
|
116
|
+
- Try removing ~/.cache/uv folder
|
|
117
|
+
|
|
114
118
|
### Usage
|
|
115
119
|
|
|
116
120
|
Wait for a few seconds. You should be able to see this icon if everything goes right.
|
|
@@ -140,6 +144,21 @@ There are three built-in modes. You may ask Claude to run in one of the modes, l
|
|
|
140
144
|
|
|
141
145
|
Note: in code-writer mode either all commands are allowed or none are allowed for now. If you give a list of allowed commands, Claude is instructed to run only those commands, but no actual check happens. (WIP)
|
|
142
146
|
|
|
147
|
+
#### Attach to the working terminal to investigate
|
|
148
|
+
If you've `screen` command installed, wcgw runs on a screen instance automatically. If you've started wcgw mcp server, you can list the screen sessions:
|
|
149
|
+
|
|
150
|
+
`screen -ls`
|
|
151
|
+
|
|
152
|
+
And note down the wcgw screen name which will be something like `93358.wcgw.235521` where the last number is in the hour-minute-second format.
|
|
153
|
+
|
|
154
|
+
You can then attach to the session using `screen -x 93358.wcgw.235521`
|
|
155
|
+
|
|
156
|
+
You may interrupt any running command safely.
|
|
157
|
+
|
|
158
|
+
You can interact with the terminal but beware that the AI might be running in parallel and it may conflict with what you're doing. It's recommended to keep your interactions to minimum.
|
|
159
|
+
|
|
160
|
+
You shouldn't exit the session using `exit `or Ctrl-d, instead you should use `ctrl+a+d` to safely detach without destroying the screen session.
|
|
161
|
+
|
|
143
162
|
### [Optional] Vs code extension
|
|
144
163
|
|
|
145
164
|
https://marketplace.visualstudio.com/items?itemName=AmanRusia.wcgw
|
|
@@ -188,7 +207,6 @@ The server provides the following MCP tools:
|
|
|
188
207
|
- Parameters: `any_workspace_path` (string), `initial_files_to_read` (string[]), `mode_name` ("wcgw"|"architect"|"code_writer"), `task_id_to_resume` (string)
|
|
189
208
|
- `BashCommand`: Execute shell commands with timeout control
|
|
190
209
|
- Parameters: `command` (string), `wait_for_seconds` (int, optional)
|
|
191
|
-
- `BashInteraction`: Send keyboard input to running programs
|
|
192
210
|
- Parameters: `send_text` (string) or `send_specials` (["Enter"|"Key-up"|...]) or `send_ascii` (int[]), `wait_for_seconds` (int, optional)
|
|
193
211
|
|
|
194
212
|
**File Operations:**
|
|
@@ -206,7 +224,5 @@ The server provides the following MCP tools:
|
|
|
206
224
|
|
|
207
225
|
- `ContextSave`: Save project context and files for Knowledge Transfer or saving task checkpoints to be resumed later
|
|
208
226
|
- Parameters: `id` (string), `project_root_path` (string), `description` (string), `relevant_file_globs` (string[])
|
|
209
|
-
- `ResetShell`: Emergency reset for shell environment
|
|
210
|
-
- Parameters: `should_reset` (boolean)
|
|
211
227
|
|
|
212
228
|
All tools support absolute paths and include built-in protections against common errors. See the [MCP specification](https://modelcontextprotocol.io/) for detailed protocol information.
|
|
@@ -90,46 +90,6 @@
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
},
|
|
93
|
-
"/v1/reset_wcgw": {
|
|
94
|
-
"post": {
|
|
95
|
-
"x-openai-isConsequential": false,
|
|
96
|
-
"summary": "Reset Wcgw",
|
|
97
|
-
"operationId": "reset_wcgw_v1_reset_wcgw_post",
|
|
98
|
-
"requestBody": {
|
|
99
|
-
"content": {
|
|
100
|
-
"application/json": {
|
|
101
|
-
"schema": {
|
|
102
|
-
"$ref": "#/components/schemas/ResetWcgwWithUUID"
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
"required": true
|
|
107
|
-
},
|
|
108
|
-
"responses": {
|
|
109
|
-
"200": {
|
|
110
|
-
"description": "Successful Response",
|
|
111
|
-
"content": {
|
|
112
|
-
"application/json": {
|
|
113
|
-
"schema": {
|
|
114
|
-
"type": "string",
|
|
115
|
-
"title": "Response Reset Wcgw V1 Reset Wcgw Post"
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
"422": {
|
|
121
|
-
"description": "Validation Error",
|
|
122
|
-
"content": {
|
|
123
|
-
"application/json": {
|
|
124
|
-
"schema": {
|
|
125
|
-
"$ref": "#/components/schemas/HTTPValidationError"
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
93
|
"/v1/bash_command": {
|
|
134
94
|
"post": {
|
|
135
95
|
"x-openai-isConsequential": false,
|
|
@@ -473,6 +433,16 @@
|
|
|
473
433
|
},
|
|
474
434
|
"InitializeWithUUID": {
|
|
475
435
|
"properties": {
|
|
436
|
+
"type": {
|
|
437
|
+
"type": "string",
|
|
438
|
+
"enum": [
|
|
439
|
+
"first_call",
|
|
440
|
+
"user_asked_mode_change",
|
|
441
|
+
"reset_shell",
|
|
442
|
+
"user_asked_change_workspace"
|
|
443
|
+
],
|
|
444
|
+
"title": "Type"
|
|
445
|
+
},
|
|
476
446
|
"any_workspace_path": {
|
|
477
447
|
"type": "string",
|
|
478
448
|
"title": "Any Workspace Path"
|
|
@@ -516,6 +486,7 @@
|
|
|
516
486
|
"additionalProperties": false,
|
|
517
487
|
"type": "object",
|
|
518
488
|
"required": [
|
|
489
|
+
"type",
|
|
519
490
|
"any_workspace_path",
|
|
520
491
|
"initial_files_to_read",
|
|
521
492
|
"task_id_to_resume",
|
|
@@ -547,59 +518,6 @@
|
|
|
547
518
|
],
|
|
548
519
|
"title": "ReadFileWithUUID"
|
|
549
520
|
},
|
|
550
|
-
"ResetWcgwWithUUID": {
|
|
551
|
-
"properties": {
|
|
552
|
-
"should_reset": {
|
|
553
|
-
"type": "boolean",
|
|
554
|
-
"const": true,
|
|
555
|
-
"title": "Should Reset"
|
|
556
|
-
},
|
|
557
|
-
"change_mode": {
|
|
558
|
-
"anyOf": [
|
|
559
|
-
{
|
|
560
|
-
"type": "string",
|
|
561
|
-
"enum": [
|
|
562
|
-
"wcgw",
|
|
563
|
-
"architect",
|
|
564
|
-
"code_writer"
|
|
565
|
-
]
|
|
566
|
-
},
|
|
567
|
-
{
|
|
568
|
-
"type": "null"
|
|
569
|
-
}
|
|
570
|
-
],
|
|
571
|
-
"title": "Change Mode"
|
|
572
|
-
},
|
|
573
|
-
"code_writer_config": {
|
|
574
|
-
"anyOf": [
|
|
575
|
-
{
|
|
576
|
-
"$ref": "#/components/schemas/CodeWriterMode"
|
|
577
|
-
},
|
|
578
|
-
{
|
|
579
|
-
"type": "null"
|
|
580
|
-
}
|
|
581
|
-
]
|
|
582
|
-
},
|
|
583
|
-
"starting_directory": {
|
|
584
|
-
"type": "string",
|
|
585
|
-
"title": "Starting Directory"
|
|
586
|
-
},
|
|
587
|
-
"user_id": {
|
|
588
|
-
"type": "string",
|
|
589
|
-
"format": "uuid",
|
|
590
|
-
"title": "User Id"
|
|
591
|
-
}
|
|
592
|
-
},
|
|
593
|
-
"additionalProperties": false,
|
|
594
|
-
"type": "object",
|
|
595
|
-
"required": [
|
|
596
|
-
"should_reset",
|
|
597
|
-
"change_mode",
|
|
598
|
-
"starting_directory",
|
|
599
|
-
"user_id"
|
|
600
|
-
],
|
|
601
|
-
"title": "ResetWcgwWithUUID"
|
|
602
|
-
},
|
|
603
521
|
"SendAscii": {
|
|
604
522
|
"properties": {
|
|
605
523
|
"send_ascii": {
|
|
@@ -9,16 +9,16 @@ Instructions:
|
|
|
9
9
|
- Do not install new tools/packages before ensuring no such tools/package or an alternative already exists.
|
|
10
10
|
|
|
11
11
|
Instructions for `Initialize`:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
- Always call this at the start of the conversation before using any of the shell tools from wcgw.
|
|
13
|
+
- Use `any_workspace_path` to initialize the shell in the appropriate project directory.
|
|
14
|
+
- If the user has mentioned a workspace or project root or any other file or folder use it to set `any_workspace_path`.
|
|
15
|
+
- If user has mentioned any files use `initial_files_to_read` to read, use absolute paths only.
|
|
16
|
+
- By default use mode "wcgw"
|
|
17
|
+
- In "code-writer" mode, set the commands and globs which user asked to set, otherwise use 'all'.
|
|
18
|
+
- Use type="first_call" if it's the first call to this tool.
|
|
19
|
+
- Use type="user_asked_mode_change" if in a conversation user has asked to change mode.
|
|
20
|
+
- Use type="reset_shell" if in a conversation shell is not working after multiple tries.
|
|
21
|
+
- Use type="user_asked_change_workspace" if in a conversation user asked to change workspace
|
|
22
22
|
|
|
23
23
|
Instructions for `BashCommand`:
|
|
24
24
|
- Execute a bash command. This is stateful (beware with subsequent calls).
|
|
@@ -40,9 +40,6 @@ Instructions for `Write if Empty`
|
|
|
40
40
|
- Provide absolute file path only.
|
|
41
41
|
- For editing existing files, use FileEdit.
|
|
42
42
|
|
|
43
|
-
Instructions for `ResetWcgw`
|
|
44
|
-
- Resets the shell. Use either when changing mode, or when all interrupts and prompt reset attempts have failed repeatedly.
|
|
45
|
-
|
|
46
43
|
Instructions for `ContextSave`
|
|
47
44
|
- Saves provided description and file contents of all the relevant file paths or globs in a single text file.
|
|
48
45
|
- Provide random unqiue id or whatever user provided.
|
|
@@ -8,8 +8,6 @@ import traceback
|
|
|
8
8
|
from dataclasses import dataclass
|
|
9
9
|
from typing import (
|
|
10
10
|
Any,
|
|
11
|
-
Callable,
|
|
12
|
-
Concatenate,
|
|
13
11
|
Literal,
|
|
14
12
|
Optional,
|
|
15
13
|
ParamSpec,
|
|
@@ -107,6 +105,9 @@ def cleanup_all_screens_with_name(name: str, console: Console) -> None:
|
|
|
107
105
|
output = (e.stdout or "") + (e.stderr or "")
|
|
108
106
|
except FileNotFoundError:
|
|
109
107
|
return
|
|
108
|
+
except Exception as e:
|
|
109
|
+
console.log(f"{e}: exception while clearing running screens.")
|
|
110
|
+
return
|
|
110
111
|
|
|
111
112
|
sessions_to_kill = []
|
|
112
113
|
|
|
@@ -130,8 +131,8 @@ def cleanup_all_screens_with_name(name: str, console: Console) -> None:
|
|
|
130
131
|
check=True,
|
|
131
132
|
timeout=CONFIG.timeout,
|
|
132
133
|
)
|
|
133
|
-
except
|
|
134
|
-
console.log(f"Failed to kill screen session: {session}")
|
|
134
|
+
except Exception as e:
|
|
135
|
+
console.log(f"Failed to kill screen session: {session}\n{e}")
|
|
135
136
|
|
|
136
137
|
|
|
137
138
|
def start_shell(
|
|
@@ -217,33 +218,7 @@ P = ParamSpec("P")
|
|
|
217
218
|
R = TypeVar("R")
|
|
218
219
|
|
|
219
220
|
|
|
220
|
-
def requires_shell(
|
|
221
|
-
func: Callable[Concatenate["BashState", "pexpect.spawn[str]", P], R],
|
|
222
|
-
) -> Callable[Concatenate["BashState", P], R]:
|
|
223
|
-
def wrapper(self: "BashState", /, *args: P.args, **kwargs: P.kwargs) -> R:
|
|
224
|
-
if not self._shell_loading.is_set():
|
|
225
|
-
if not self._shell_loading.wait(
|
|
226
|
-
timeout=CONFIG.timeout * 2
|
|
227
|
-
): # Twice in worst case if screen fails
|
|
228
|
-
raise RuntimeError("Shell initialization timeout")
|
|
229
|
-
|
|
230
|
-
if self._shell_error:
|
|
231
|
-
raise RuntimeError(f"Shell failed to initialize: {self._shell_error}.")
|
|
232
|
-
|
|
233
|
-
if not self._shell:
|
|
234
|
-
raise RuntimeError("Shell not initialized")
|
|
235
|
-
|
|
236
|
-
return func(self, self._shell, *args, **kwargs)
|
|
237
|
-
|
|
238
|
-
return wrapper
|
|
239
|
-
|
|
240
|
-
|
|
241
221
|
class BashState:
|
|
242
|
-
_shell: Optional["pexpect.spawn[str]"]
|
|
243
|
-
_shell_id: Optional[str]
|
|
244
|
-
_shell_lock: threading.Lock
|
|
245
|
-
_shell_loading: threading.Event
|
|
246
|
-
_shell_error: Optional[Exception]
|
|
247
222
|
_use_screen: bool
|
|
248
223
|
|
|
249
224
|
def __init__(
|
|
@@ -266,67 +241,39 @@ class BashState:
|
|
|
266
241
|
self._write_if_empty_mode: WriteIfEmptyMode = (
|
|
267
242
|
write_if_empty_mode or WriteIfEmptyMode("all")
|
|
268
243
|
)
|
|
269
|
-
self._mode = mode or
|
|
244
|
+
self._mode = mode or "wcgw"
|
|
270
245
|
self._whitelist_for_overwrite: set[str] = whitelist_for_overwrite or set()
|
|
271
246
|
self._bg_expect_thread: Optional[threading.Thread] = None
|
|
272
247
|
self._bg_expect_thread_stop_event = threading.Event()
|
|
273
|
-
self._shell = None
|
|
274
|
-
self._shell_id = None
|
|
275
|
-
self._shell_lock = threading.Lock()
|
|
276
|
-
self._shell_loading = threading.Event()
|
|
277
|
-
self._shell_error = None
|
|
278
248
|
self._use_screen = use_screen
|
|
279
|
-
self.
|
|
249
|
+
self._init_shell()
|
|
280
250
|
|
|
281
|
-
def
|
|
282
|
-
def load_shell() -> None:
|
|
283
|
-
try:
|
|
284
|
-
with self._shell_lock:
|
|
285
|
-
if self._shell is not None:
|
|
286
|
-
return
|
|
287
|
-
self._init_shell()
|
|
288
|
-
self.run_bg_expect_thread()
|
|
289
|
-
except Exception as e:
|
|
290
|
-
self._shell_error = e
|
|
291
|
-
finally:
|
|
292
|
-
self._shell_loading.set()
|
|
293
|
-
|
|
294
|
-
threading.Thread(target=load_shell).start()
|
|
295
|
-
|
|
296
|
-
@requires_shell
|
|
297
|
-
def expect(
|
|
298
|
-
self, shell: "pexpect.spawn[str]", pattern: Any, timeout: Optional[float] = -1
|
|
299
|
-
) -> int:
|
|
251
|
+
def expect(self, pattern: Any, timeout: Optional[float] = -1) -> int:
|
|
300
252
|
self.close_bg_expect_thread()
|
|
301
|
-
output =
|
|
253
|
+
output = self._shell.expect(pattern, timeout)
|
|
302
254
|
return output
|
|
303
255
|
|
|
304
|
-
|
|
305
|
-
def send(self, shell: "pexpect.spawn[str]", s: str | bytes) -> int:
|
|
256
|
+
def send(self, s: str | bytes) -> int:
|
|
306
257
|
self.close_bg_expect_thread()
|
|
307
|
-
output =
|
|
258
|
+
output = self._shell.send(s)
|
|
308
259
|
return output
|
|
309
260
|
|
|
310
|
-
|
|
311
|
-
def sendline(self, shell: "pexpect.spawn[str]", s: str | bytes) -> int:
|
|
261
|
+
def sendline(self, s: str | bytes) -> int:
|
|
312
262
|
self.close_bg_expect_thread()
|
|
313
|
-
output =
|
|
263
|
+
output = self._shell.sendline(s)
|
|
314
264
|
return output
|
|
315
265
|
|
|
316
266
|
@property
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
return shell.linesep
|
|
267
|
+
def linesep(self) -> Any:
|
|
268
|
+
return self._shell.linesep
|
|
320
269
|
|
|
321
|
-
|
|
322
|
-
def sendintr(self, shell: "pexpect.spawn[str]") -> None:
|
|
270
|
+
def sendintr(self) -> None:
|
|
323
271
|
self.close_bg_expect_thread()
|
|
324
|
-
|
|
272
|
+
self._shell.sendintr()
|
|
325
273
|
|
|
326
274
|
@property
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
return shell.before
|
|
275
|
+
def before(self) -> Optional[str]:
|
|
276
|
+
return self._shell.before
|
|
330
277
|
|
|
331
278
|
def run_bg_expect_thread(self) -> None:
|
|
332
279
|
"""
|
|
@@ -337,16 +284,11 @@ class BashState:
|
|
|
337
284
|
while True:
|
|
338
285
|
if self._bg_expect_thread_stop_event.is_set():
|
|
339
286
|
break
|
|
340
|
-
if self._shell is None:
|
|
341
|
-
time.sleep(0.1)
|
|
342
|
-
continue
|
|
343
287
|
output = self._shell.expect([pexpect.EOF, pexpect.TIMEOUT], timeout=0.1)
|
|
344
288
|
if output == 0:
|
|
345
289
|
break
|
|
346
290
|
|
|
347
|
-
if self._bg_expect_thread
|
|
348
|
-
if not self._bg_expect_thread_stop_event.is_set():
|
|
349
|
-
return
|
|
291
|
+
if self._bg_expect_thread:
|
|
350
292
|
self.close_bg_expect_thread()
|
|
351
293
|
|
|
352
294
|
self._bg_expect_thread = threading.Thread(
|
|
@@ -363,13 +305,8 @@ class BashState:
|
|
|
363
305
|
|
|
364
306
|
def cleanup(self) -> None:
|
|
365
307
|
self.close_bg_expect_thread()
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
self._shell.close(True)
|
|
369
|
-
if self._shell_id:
|
|
370
|
-
cleanup_all_screens_with_name(self._shell_id, self.console)
|
|
371
|
-
self._shell = None
|
|
372
|
-
self._shell_id = None
|
|
308
|
+
self._shell.close(True)
|
|
309
|
+
cleanup_all_screens_with_name(self._shell_id, self.console)
|
|
373
310
|
|
|
374
311
|
def __enter__(self) -> "BashState":
|
|
375
312
|
return self
|
|
@@ -393,31 +330,24 @@ class BashState:
|
|
|
393
330
|
def write_if_empty_mode(self) -> WriteIfEmptyMode:
|
|
394
331
|
return self._write_if_empty_mode
|
|
395
332
|
|
|
396
|
-
|
|
397
|
-
def ensure_env_and_bg_jobs(self, _: "pexpect.spawn[str]") -> Optional[int]:
|
|
398
|
-
return self._ensure_env_and_bg_jobs()
|
|
399
|
-
|
|
400
|
-
def _ensure_env_and_bg_jobs(self) -> Optional[int]:
|
|
401
|
-
# Do not add @requires_shell decorator here, as it will cause deadlock
|
|
402
|
-
self.close_bg_expect_thread()
|
|
403
|
-
assert self._shell is not None, "Bad state, shell is not initialized"
|
|
333
|
+
def ensure_env_and_bg_jobs(self) -> Optional[int]:
|
|
404
334
|
quick_timeout = 0.2 if not self.over_screen else 1
|
|
405
335
|
# First reset the prompt in case venv was sourced or other reasons.
|
|
406
|
-
self.
|
|
407
|
-
self.
|
|
336
|
+
self.sendline(PROMPT_STATEMENT)
|
|
337
|
+
self.expect(PROMPT_CONST, timeout=quick_timeout)
|
|
408
338
|
# Reset echo also if it was enabled
|
|
409
339
|
command = "jobs | wc -l"
|
|
410
|
-
self.
|
|
340
|
+
self.sendline(command)
|
|
411
341
|
before = ""
|
|
412
342
|
counts = 0
|
|
413
343
|
while not _is_int(before): # Consume all previous output
|
|
414
344
|
try:
|
|
415
|
-
self.
|
|
345
|
+
self.expect(PROMPT_CONST, timeout=quick_timeout)
|
|
416
346
|
except pexpect.TIMEOUT:
|
|
417
347
|
self.console.print(f"Couldn't get exit code, before: {before}")
|
|
418
348
|
raise
|
|
419
349
|
|
|
420
|
-
before_val = self.
|
|
350
|
+
before_val = self.before
|
|
421
351
|
if not isinstance(before_val, str):
|
|
422
352
|
before_val = str(before_val)
|
|
423
353
|
assert isinstance(before_val, str)
|
|
@@ -435,7 +365,6 @@ class BashState:
|
|
|
435
365
|
|
|
436
366
|
def _init_shell(self) -> None:
|
|
437
367
|
self._state: Literal["repl"] | datetime.datetime = "repl"
|
|
438
|
-
self._is_in_docker: Optional[str] = ""
|
|
439
368
|
# Ensure self._cwd exists
|
|
440
369
|
os.makedirs(self._cwd, exist_ok=True)
|
|
441
370
|
try:
|
|
@@ -461,10 +390,12 @@ class BashState:
|
|
|
461
390
|
|
|
462
391
|
self._pending_output = ""
|
|
463
392
|
try:
|
|
464
|
-
self.
|
|
393
|
+
self.ensure_env_and_bg_jobs()
|
|
465
394
|
except ValueError as e:
|
|
466
395
|
self.console.log("Error while running _ensure_env_and_bg_jobs" + str(e))
|
|
467
396
|
|
|
397
|
+
self.run_bg_expect_thread()
|
|
398
|
+
|
|
468
399
|
def set_pending(self, last_pending_output: str) -> None:
|
|
469
400
|
if not isinstance(self._state, datetime.datetime):
|
|
470
401
|
self._state = datetime.datetime.now()
|
|
@@ -480,13 +411,6 @@ class BashState:
|
|
|
480
411
|
return "repl"
|
|
481
412
|
return "pending"
|
|
482
413
|
|
|
483
|
-
@property
|
|
484
|
-
def is_in_docker(self) -> Optional[str]:
|
|
485
|
-
return self._is_in_docker
|
|
486
|
-
|
|
487
|
-
def set_in_docker(self, docker_image_id: str) -> None:
|
|
488
|
-
self._is_in_docker = docker_image_id
|
|
489
|
-
|
|
490
414
|
@property
|
|
491
415
|
def cwd(self) -> str:
|
|
492
416
|
return self._cwd
|
|
@@ -495,11 +419,10 @@ class BashState:
|
|
|
495
419
|
def prompt(self) -> str:
|
|
496
420
|
return PROMPT_CONST
|
|
497
421
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
before_val = shell.before
|
|
422
|
+
def update_cwd(self) -> str:
|
|
423
|
+
self.sendline("pwd")
|
|
424
|
+
self.expect(PROMPT_CONST, timeout=0.2)
|
|
425
|
+
before_val = self.before
|
|
503
426
|
if not isinstance(before_val, str):
|
|
504
427
|
before_val = str(before_val)
|
|
505
428
|
before_lines = render_terminal_output(before_val)
|
|
@@ -509,9 +432,7 @@ class BashState:
|
|
|
509
432
|
|
|
510
433
|
def reset_shell(self) -> None:
|
|
511
434
|
self.cleanup()
|
|
512
|
-
self.
|
|
513
|
-
self._shell_error = None
|
|
514
|
-
self._start_shell_loading()
|
|
435
|
+
self._init_shell()
|
|
515
436
|
|
|
516
437
|
def serialize(self) -> dict[str, Any]:
|
|
517
438
|
"""Serialize BashState to a dictionary for saving"""
|
|
@@ -531,7 +452,7 @@ class BashState:
|
|
|
531
452
|
BashCommandMode.deserialize(state["bash_command_mode"]),
|
|
532
453
|
FileEditMode.deserialize(state["file_edit_mode"]),
|
|
533
454
|
WriteIfEmptyMode.deserialize(state["write_if_empty_mode"]),
|
|
534
|
-
|
|
455
|
+
state["mode"],
|
|
535
456
|
state["whitelist_for_overwrite"],
|
|
536
457
|
)
|
|
537
458
|
|
|
@@ -595,7 +516,7 @@ WAITING_INPUT_MESSAGE = """A command is already running. NOTE: You can't run mul
|
|
|
595
516
|
1. Get its output using `send_ascii: [10] or send_specials: ["Enter"]`
|
|
596
517
|
2. Use `send_ascii` or `send_specials` to give inputs to the running program, don't use `BashCommand` OR
|
|
597
518
|
3. kill the previous program by sending ctrl+c first using `send_ascii` or `send_specials`
|
|
598
|
-
4.
|
|
519
|
+
4. Interrupt and run the process in background by re-running it using screen
|
|
599
520
|
"""
|
|
600
521
|
|
|
601
522
|
|