forge-cpp-mcp 0.5.0__tar.gz → 0.5.1__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.
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/PKG-INFO +16 -3
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/README.md +15 -2
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/process-details.js +3 -1
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/shared/app.js +3 -1
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/shared/result-view.js +1 -1
- forge_cpp_mcp-0.5.1/frontend/src/shared/tool-result.js +22 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/pyproject.toml +1 -1
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/__init__.py +1 -1
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/git/service.py +87 -37
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/.gitignore +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/LICENSE +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/admin.html +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/clangd-result.html +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/cmake-build.html +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/cmake-configure.html +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/cmake-profiles.html +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/cmake-run-test.html +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/cmake-test.html +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/debugger-result.html +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/git-result.html +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/package-lock.json +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/package.json +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/process-details.html +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/process-overview.html +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/sandbox.html +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/admin-form.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/admin-resource.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/admin-sandbox.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/admin-widget.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/admin.css +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/admin.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/clangd-navigation-view.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/clangd-result.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/clangd-view.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/cmake-build.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/cmake-configure.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/cmake-profiles.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/cmake-run-test.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/cmake-test.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/cmake-view.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/debugger-result.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/git-result.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/git-view.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/git.css +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/process-overview.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/process-status.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/process.css +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/shared/copy-icon.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/shared/presentation.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/shared/result-resources.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/shared/widget.css +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/source-view.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/toolsets.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/workspace-file.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/workspace-result.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/workspace-search.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/workspace-tree.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/src/workspace-view.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/tests/admin-widget.test.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/tests/result-resources.test.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/tests/result-view.test.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/tests/workspace.test.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/toolsets.html +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/vite.config.js +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/workspace-file.html +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/workspace-result.html +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/workspace-search.html +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/frontend/workspace-tree.html +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/hatch_build.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/admin/__init__.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/admin/errors.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/admin/history.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/admin/instance.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/admin/service.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/assets.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/clangd/__init__.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/clangd/errors.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/clangd/models.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/clangd/service.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/clangd/session.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/clangd/text.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/cmake/__init__.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/cmake/build_tree.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/cmake/errors.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/cmake/file_api.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/cmake/models.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/cmake/profiles.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/cmake/service.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/cmake/text.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/cmake/workspace.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/completion.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/debugger/__init__.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/debugger/errors.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/debugger/lldb_dap.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/debugger/models.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/debugger/service.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/debugger/session.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/debugger/text.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/diagnostics.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/git/__init__.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/git/errors.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/git/models.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/git/parsers.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/git/text.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/icons/clangd.LICENSE +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/icons/clangd.svg +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/icons/cmake.svg +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/icons/debugger.svg +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/icons/git.svg +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/icons/process.svg +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/icons/toolchain.svg +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/icons/workspace-edit.svg +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/icons/workspace-file.svg +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/icons/workspace-search.svg +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/icons/workspace.svg +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/local_ipc/__init__.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/local_ipc/errors.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/local_ipc/service.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/local_ipc/unix.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/local_ipc/windows.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/markdown.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/process/__init__.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/process/errors.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/process/host.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/process/models.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/process/service.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/process/text.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/process/transcript.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/progress.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/server.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/text.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/__init__.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/discovery.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/errors.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/loader.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/providers/__init__.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/providers/system.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/providers/user.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/providers/visual_studio.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/service.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/spec.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/__init__.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/clang.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/clang_cl.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/clangd.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/clangxx.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/cmake.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/cppvsdbg.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/ctest.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/gcc.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/gdb.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/git.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/gxx.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/link.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/lld.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/lld_link.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/lldb_dap.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/make.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/msbuild.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/msvc.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/tools/ninja.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/workspace/__init__.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/workspace/diff.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/workspace/errors.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/workspace/metadata.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/workspace/models.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/workspace/path.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/workspace/providers.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/workspace/service.py +0 -0
- {forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/workspace/text.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: forge-cpp-mcp
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: A safe MCP server for structured C++ project development workflows.
|
|
5
5
|
Project-URL: Homepage, https://github.com/hardened-steel/ForgeMCP
|
|
6
6
|
Project-URL: Repository, https://github.com/hardened-steel/ForgeMCP
|
|
@@ -87,6 +87,12 @@ without making additional tool calls. Process times are readable to seconds; JSO
|
|
|
87
87
|
copying preserve the original precision. A toolsets list shows summaries, while a
|
|
88
88
|
`toolset_get` result shows the details returned by that call.
|
|
89
89
|
|
|
90
|
+
When a host restores chat history without `structuredContent`, widgets can recover
|
|
91
|
+
the result from a single complete JSON object retained in a text content block,
|
|
92
|
+
including a fenced JSON block. This supports older JSON tool responses; current
|
|
93
|
+
plain-text responses alone cannot restore the structured result. Linked result
|
|
94
|
+
resources still disappear when the server restarts.
|
|
95
|
+
|
|
90
96
|
ForgeMCP can directly run an explicitly selected test executable inside the
|
|
91
97
|
project or storage root; it does not expose shell commands or external executable
|
|
92
98
|
paths over MCP. Feature services use
|
|
@@ -107,7 +113,7 @@ and install it in a virtual environment:
|
|
|
107
113
|
|
|
108
114
|
```powershell
|
|
109
115
|
python -m venv .venv
|
|
110
|
-
.\.venv\Scripts\python.exe -m pip install .\forge_cpp_mcp-0.5.
|
|
116
|
+
.\.venv\Scripts\python.exe -m pip install .\forge_cpp_mcp-0.5.1-py3-none-any.whl
|
|
111
117
|
.\.venv\Scripts\forgemcp.exe --help
|
|
112
118
|
```
|
|
113
119
|
|
|
@@ -120,7 +126,7 @@ The distribution name is `forge-cpp-mcp`; the Python module and server command a
|
|
|
120
126
|
After the package is published to PyPI, the install command can instead be:
|
|
121
127
|
|
|
122
128
|
```powershell
|
|
123
|
-
.\.venv\Scripts\python.exe -m pip install forge-cpp-mcp==0.5.
|
|
129
|
+
.\.venv\Scripts\python.exe -m pip install forge-cpp-mcp==0.5.1
|
|
124
130
|
```
|
|
125
131
|
|
|
126
132
|
## Setup from source
|
|
@@ -673,6 +679,13 @@ CMake alone determines compilation-context eligibility and notifies clangd throu
|
|
|
673
679
|
its existing subscription. Source notifications combine Git dirty paths and
|
|
674
680
|
committed tree changes; unknown changes use conservative invalidation. No external
|
|
675
681
|
file watcher or cross-instance execution queue is added.
|
|
682
|
+
Git snapshots the existence and types of tracked and nonignored untracked paths
|
|
683
|
+
before and after mutations, retaining previous paths and explicitly selected file
|
|
684
|
+
paths. Index/ref changes and commits, including `nothing to commit`, keep clangd
|
|
685
|
+
sessions when working-file structure and CMake inputs remain unchanged. Actual
|
|
686
|
+
path/type changes or an unknown outcome can invalidate contexts. Snapshots read no
|
|
687
|
+
source contents, include at most 100,000 distinct paths, and do not track ignored-only
|
|
688
|
+
changes or empty directories outside the catalog.
|
|
676
689
|
|
|
677
690
|
Git output is bounded to 4 MiB per command; narrow the request when the limit is
|
|
678
691
|
exceeded. Each command has a 300-second deadline and each request a 620-second
|
|
@@ -58,6 +58,12 @@ without making additional tool calls. Process times are readable to seconds; JSO
|
|
|
58
58
|
copying preserve the original precision. A toolsets list shows summaries, while a
|
|
59
59
|
`toolset_get` result shows the details returned by that call.
|
|
60
60
|
|
|
61
|
+
When a host restores chat history without `structuredContent`, widgets can recover
|
|
62
|
+
the result from a single complete JSON object retained in a text content block,
|
|
63
|
+
including a fenced JSON block. This supports older JSON tool responses; current
|
|
64
|
+
plain-text responses alone cannot restore the structured result. Linked result
|
|
65
|
+
resources still disappear when the server restarts.
|
|
66
|
+
|
|
61
67
|
ForgeMCP can directly run an explicitly selected test executable inside the
|
|
62
68
|
project or storage root; it does not expose shell commands or external executable
|
|
63
69
|
paths over MCP. Feature services use
|
|
@@ -78,7 +84,7 @@ and install it in a virtual environment:
|
|
|
78
84
|
|
|
79
85
|
```powershell
|
|
80
86
|
python -m venv .venv
|
|
81
|
-
.\.venv\Scripts\python.exe -m pip install .\forge_cpp_mcp-0.5.
|
|
87
|
+
.\.venv\Scripts\python.exe -m pip install .\forge_cpp_mcp-0.5.1-py3-none-any.whl
|
|
82
88
|
.\.venv\Scripts\forgemcp.exe --help
|
|
83
89
|
```
|
|
84
90
|
|
|
@@ -91,7 +97,7 @@ The distribution name is `forge-cpp-mcp`; the Python module and server command a
|
|
|
91
97
|
After the package is published to PyPI, the install command can instead be:
|
|
92
98
|
|
|
93
99
|
```powershell
|
|
94
|
-
.\.venv\Scripts\python.exe -m pip install forge-cpp-mcp==0.5.
|
|
100
|
+
.\.venv\Scripts\python.exe -m pip install forge-cpp-mcp==0.5.1
|
|
95
101
|
```
|
|
96
102
|
|
|
97
103
|
## Setup from source
|
|
@@ -644,6 +650,13 @@ CMake alone determines compilation-context eligibility and notifies clangd throu
|
|
|
644
650
|
its existing subscription. Source notifications combine Git dirty paths and
|
|
645
651
|
committed tree changes; unknown changes use conservative invalidation. No external
|
|
646
652
|
file watcher or cross-instance execution queue is added.
|
|
653
|
+
Git snapshots the existence and types of tracked and nonignored untracked paths
|
|
654
|
+
before and after mutations, retaining previous paths and explicitly selected file
|
|
655
|
+
paths. Index/ref changes and commits, including `nothing to commit`, keep clangd
|
|
656
|
+
sessions when working-file structure and CMake inputs remain unchanged. Actual
|
|
657
|
+
path/type changes or an unknown outcome can invalidate contexts. Snapshots read no
|
|
658
|
+
source contents, include at most 100,000 distinct paths, and do not track ignored-only
|
|
659
|
+
changes or empty directories outside the catalog.
|
|
647
660
|
|
|
648
661
|
Git output is bounded to 4 MiB per command; narrow the request when the limit is
|
|
649
662
|
exceeded. Each command has a 300-second deadline and each request a 620-second
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { App, PostMessageTransport, applyDocumentTheme, applyHostFonts, applyHostStyleVariables } from "@modelcontextprotocol/ext-apps";
|
|
2
2
|
import { timestamp } from "./shared/presentation.js";
|
|
3
|
+
import { restoreStructuredContent } from "./shared/tool-result.js";
|
|
3
4
|
import { processStatus } from "./process-status.js";
|
|
4
5
|
import "./shared/widget.css";
|
|
5
6
|
import "./process.css";
|
|
@@ -170,7 +171,8 @@ const contextChanged = (context) => {
|
|
|
170
171
|
}
|
|
171
172
|
};
|
|
172
173
|
app.addEventListener("toolinput", () => { details = undefined; render(); footer.textContent = "Reading process…"; });
|
|
173
|
-
app.addEventListener("toolresult", (
|
|
174
|
+
app.addEventListener("toolresult", (message) => {
|
|
175
|
+
const result = restoreStructuredContent(message);
|
|
174
176
|
if (result?.isError || !result?.structuredContent) {
|
|
175
177
|
footer.textContent = "Process result unavailable.";
|
|
176
178
|
return;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { App, PostMessageTransport, applyDocumentTheme, applyHostFonts, applyHostStyleVariables } from "@modelcontextprotocol/ext-apps";
|
|
2
2
|
import { createResultView } from "./result-view.js";
|
|
3
3
|
import { loadResultClangd, loadResultDiff, loadResultSkippedFiles } from "./result-resources.js";
|
|
4
|
+
import { restoreStructuredContent } from "./tool-result.js";
|
|
4
5
|
import "./widget.css";
|
|
5
6
|
|
|
6
7
|
/** Lifecycle bridge and immutable result-resource loading; never calls tools. */
|
|
@@ -27,7 +28,8 @@ export async function connectWidget({ toolName, describe, renderValue }) {
|
|
|
27
28
|
};
|
|
28
29
|
app.addEventListener("toolinput", invalidate(view.pending));
|
|
29
30
|
app.addEventListener("toolinputpartial", invalidate(view.pending));
|
|
30
|
-
app.addEventListener("toolresult", async (
|
|
31
|
+
app.addEventListener("toolresult", async (message) => {
|
|
32
|
+
const result = restoreStructuredContent(message);
|
|
31
33
|
const current = ++generation;
|
|
32
34
|
view.receive(result);
|
|
33
35
|
const data = result?.structuredContent;
|
|
@@ -346,7 +346,7 @@ export function createResultView(root, { toolName, describe, renderValue }) {
|
|
|
346
346
|
function receive(result) {
|
|
347
347
|
if (disposed) return;
|
|
348
348
|
clear("");
|
|
349
|
-
if (!result || result.structuredContent
|
|
349
|
+
if (!result || result.structuredContent == null || result.isError) {
|
|
350
350
|
const texts = (result?.content ?? []).filter((item) => item.type === "text").map((item) => item.text);
|
|
351
351
|
const message = result?.isError ? "Tool returned an error." : "No structured result was provided.";
|
|
352
352
|
content.append(element("p", "fm-empty", message));
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { isObject } from "./presentation.js";
|
|
2
|
+
|
|
3
|
+
/** Recover one complete JSON object when a host replays only text content. */
|
|
4
|
+
export function restoreStructuredContent(result) {
|
|
5
|
+
if (!result || result.isError || result.structuredContent != null) return result;
|
|
6
|
+
let recovered;
|
|
7
|
+
for (const item of result.content ?? []) {
|
|
8
|
+
if (item.type !== "text" || typeof item.text !== "string") continue;
|
|
9
|
+
const text = item.text.trim();
|
|
10
|
+
const fenced = /^```(?:json)?[ \t]*\r?\n([\s\S]*?)\r?\n```$/i.exec(text);
|
|
11
|
+
let value;
|
|
12
|
+
try {
|
|
13
|
+
value = JSON.parse(fenced ? fenced[1] : text);
|
|
14
|
+
} catch {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (!isObject(value)) continue;
|
|
18
|
+
if (recovered !== undefined) return result;
|
|
19
|
+
recovered = value;
|
|
20
|
+
}
|
|
21
|
+
return recovered === undefined ? result : { ...result, structuredContent: recovered };
|
|
22
|
+
}
|
|
@@ -7,7 +7,8 @@ from __future__ import annotations
|
|
|
7
7
|
|
|
8
8
|
import asyncio
|
|
9
9
|
import re
|
|
10
|
-
|
|
10
|
+
import stat
|
|
11
|
+
from collections.abc import AsyncGenerator, Awaitable, Callable, Collection, Sequence
|
|
11
12
|
from contextlib import asynccontextmanager
|
|
12
13
|
from contextvars import ContextVar
|
|
13
14
|
from dataclasses import dataclass, field
|
|
@@ -134,6 +135,7 @@ class GitService:
|
|
|
134
135
|
COMMIT_URI = "forgemcp://git/commits/{revision}"
|
|
135
136
|
COMMIT_FORMAT = "%H%x00%P%x00%an%x00%ae%x00%aI%x00%cn%x00%ce%x00%cI%x00%B"
|
|
136
137
|
MAX_BYTES = 4 * 1024 * 1024
|
|
138
|
+
MAX_SOURCE_PATHS = 100_000
|
|
137
139
|
|
|
138
140
|
def __init__(
|
|
139
141
|
self,
|
|
@@ -369,12 +371,13 @@ class GitService:
|
|
|
369
371
|
self,
|
|
370
372
|
arguments: Sequence[str],
|
|
371
373
|
*,
|
|
372
|
-
|
|
374
|
+
source_paths: Sequence[WorkspacePath] = (),
|
|
373
375
|
stdin: str | None = None,
|
|
374
376
|
) -> GitMutation:
|
|
375
377
|
"""Run a mutation once and reconcile source consumers even after partial failure."""
|
|
376
378
|
before = await self.status()
|
|
377
|
-
|
|
379
|
+
sources = await self.source_snapshot(source_paths)
|
|
380
|
+
structural = True
|
|
378
381
|
sync_error = None
|
|
379
382
|
result = None
|
|
380
383
|
after = GitStatus()
|
|
@@ -383,23 +386,29 @@ class GitService:
|
|
|
383
386
|
context = await self.cmake.begin_source_change()
|
|
384
387
|
try:
|
|
385
388
|
result = await self.command(arguments, check=False, read_only=False, stdin=stdin)
|
|
386
|
-
completed = True
|
|
387
389
|
try:
|
|
388
390
|
after = await self.status()
|
|
389
|
-
|
|
391
|
+
structural = sources != await self.source_snapshot(sources)
|
|
392
|
+
changes = await self.source_files(before, after)
|
|
390
393
|
except (GitError, ToolchainError):
|
|
391
394
|
sync_error = (
|
|
392
|
-
"Git command execution finished, but
|
|
393
|
-
"could not be
|
|
394
|
-
|
|
395
|
-
|
|
395
|
+
"Git command execution finished, but the resulting repository/source "
|
|
396
|
+
"state could not be fully verified. Treat unverified state as unknown. "
|
|
397
|
+
+ (
|
|
398
|
+
"The Git command succeeded. Do not repeat the completed mutation. "
|
|
399
|
+
if result.return_code == 0
|
|
400
|
+
else "The Git command failed and may have partially changed the "
|
|
401
|
+
"repository. Do not repeat it before checking git_status(). "
|
|
402
|
+
)
|
|
403
|
+
+ "Inspect git_status() and the returned process_ids with "
|
|
404
|
+
"process_get(process_id=...)."
|
|
396
405
|
)
|
|
397
406
|
finally:
|
|
398
407
|
try:
|
|
399
408
|
await self.cmake.finish_source_change(
|
|
400
409
|
context,
|
|
401
|
-
structural=
|
|
402
|
-
uncertain=
|
|
410
|
+
structural=structural,
|
|
411
|
+
uncertain=result is None or changes is None,
|
|
403
412
|
)
|
|
404
413
|
await self.analysis.refresh_source_changes(changes)
|
|
405
414
|
# A secondary synchronization error must not conceal a completed commit/push.
|
|
@@ -450,6 +459,62 @@ class GitService:
|
|
|
450
459
|
),
|
|
451
460
|
)
|
|
452
461
|
|
|
462
|
+
async def source_snapshot(
|
|
463
|
+
self,
|
|
464
|
+
paths: Collection[WorkspacePath] = (),
|
|
465
|
+
) -> dict[WorkspacePath, int | None]:
|
|
466
|
+
"""Record physical kinds of Git-visible paths, retaining previous and explicit names.
|
|
467
|
+
|
|
468
|
+
Newly visible paths have an unknown previous kind and conservatively change the
|
|
469
|
+
snapshot without reading source text.
|
|
470
|
+
"""
|
|
471
|
+
result = await self.command(
|
|
472
|
+
["ls-files", "--cached", "--others", "--exclude-standard", "-z"],
|
|
473
|
+
)
|
|
474
|
+
selected = set(paths)
|
|
475
|
+
for raw in result.stdout.split(b"\0"):
|
|
476
|
+
if raw:
|
|
477
|
+
selected.add(parsers.qualified(raw))
|
|
478
|
+
if len(selected) > self.MAX_SOURCE_PATHS:
|
|
479
|
+
raise GitError(
|
|
480
|
+
f"Git source snapshot exceeds the {self.MAX_SOURCE_PATHS}-path limit. "
|
|
481
|
+
"Inspect git_status() and exclude generated or unrelated untracked files "
|
|
482
|
+
"with .gitignore before another Git mutation. "
|
|
483
|
+
f"Inspect process_get(process_id={result.process_id}) for the source catalog."
|
|
484
|
+
)
|
|
485
|
+
snapshot = {}
|
|
486
|
+
try:
|
|
487
|
+
for index, path in enumerate(selected):
|
|
488
|
+
snapshot[path] = self.source_kind(path)
|
|
489
|
+
if index % 256 == 0:
|
|
490
|
+
await asyncio.sleep(0)
|
|
491
|
+
except GitError as error:
|
|
492
|
+
raise GitError(
|
|
493
|
+
f"{error} Inspect process_get(process_id={result.process_id}) "
|
|
494
|
+
"for the source catalog."
|
|
495
|
+
) from error
|
|
496
|
+
return snapshot
|
|
497
|
+
|
|
498
|
+
def source_kind(self, path: WorkspacePath) -> int | None:
|
|
499
|
+
"""Inspect a project entry itself without following it or escaping through its parents."""
|
|
500
|
+
native = self.workspace.root / path.relative
|
|
501
|
+
try:
|
|
502
|
+
if not native.parent.resolve().is_relative_to(self.workspace.root):
|
|
503
|
+
raise GitError(
|
|
504
|
+
f"Cannot inspect source path {display_value(str(path))}: its parent "
|
|
505
|
+
"traverses a link outside project/. Inspect git_status() and ask the "
|
|
506
|
+
"operator to keep source parents inside the configured project."
|
|
507
|
+
)
|
|
508
|
+
metadata = native.lstat()
|
|
509
|
+
return stat.S_IFLNK if native.is_junction() else stat.S_IFMT(metadata.st_mode)
|
|
510
|
+
except (FileNotFoundError, NotADirectoryError):
|
|
511
|
+
return None
|
|
512
|
+
except OSError as error:
|
|
513
|
+
raise GitError(
|
|
514
|
+
f"Cannot inspect source path {display_value(str(path))}: "
|
|
515
|
+
f"{os_error_reason(error)}. Check access permissions and inspect git_status()."
|
|
516
|
+
) from error
|
|
517
|
+
|
|
453
518
|
async def source_files(self, before: GitStatus, after: GitStatus) -> list[FileChange]:
|
|
454
519
|
"""Combine dirty paths and committed tree changes without scanning the project."""
|
|
455
520
|
affected = {entry.path for entry in [*before.entries, *after.entries]}
|
|
@@ -468,17 +533,7 @@ class GitService:
|
|
|
468
533
|
affected.add(change.original_path)
|
|
469
534
|
changes = []
|
|
470
535
|
for path in sorted(affected):
|
|
471
|
-
|
|
472
|
-
(self.workspace.root / path.relative).lstat()
|
|
473
|
-
except FileNotFoundError:
|
|
474
|
-
kind = 3
|
|
475
|
-
except OSError as error:
|
|
476
|
-
raise GitError(
|
|
477
|
-
f"Cannot inspect changed source path {display_value(str(path))}: "
|
|
478
|
-
f"{os_error_reason(error)}. Check access permissions and inspect git_status()."
|
|
479
|
-
) from error
|
|
480
|
-
else:
|
|
481
|
-
kind = 2
|
|
536
|
+
kind = 3 if self.source_kind(path) is None else 2
|
|
482
537
|
changes.append(FileChange(path, kind))
|
|
483
538
|
return changes
|
|
484
539
|
|
|
@@ -798,7 +853,7 @@ class GitService:
|
|
|
798
853
|
async with self.request(ctx):
|
|
799
854
|
result = await self.mutate(
|
|
800
855
|
["add", "--all", "--", *self.paths(paths)],
|
|
801
|
-
|
|
856
|
+
source_paths=paths,
|
|
802
857
|
)
|
|
803
858
|
return tool_result(result, render(result))
|
|
804
859
|
|
|
@@ -822,7 +877,7 @@ class GitService:
|
|
|
822
877
|
*selected,
|
|
823
878
|
]
|
|
824
879
|
)
|
|
825
|
-
result = await self.mutate(command,
|
|
880
|
+
result = await self.mutate(command, source_paths=paths)
|
|
826
881
|
return tool_result(result, render(result))
|
|
827
882
|
|
|
828
883
|
@apps.tool(resource_uri=self.WIDGET.uri, icons=[icon], annotations=writes)
|
|
@@ -841,7 +896,6 @@ class GitService:
|
|
|
841
896
|
)
|
|
842
897
|
result = await self.mutate(
|
|
843
898
|
["commit", *(["--amend"] if amend else []), "--file=-"],
|
|
844
|
-
source_changes=True,
|
|
845
899
|
stdin=message,
|
|
846
900
|
)
|
|
847
901
|
return tool_result(result, render(result))
|
|
@@ -861,7 +915,7 @@ class GitService:
|
|
|
861
915
|
)
|
|
862
916
|
result = await self.mutate(
|
|
863
917
|
["restore", "--worktree", *options, "--", *self.paths(paths)],
|
|
864
|
-
|
|
918
|
+
source_paths=paths,
|
|
865
919
|
)
|
|
866
920
|
return tool_result(result, render(result))
|
|
867
921
|
|
|
@@ -885,7 +939,7 @@ class GitService:
|
|
|
885
939
|
command = ["branch", name, await self.revision(start_point, "start_point")]
|
|
886
940
|
else:
|
|
887
941
|
command = ["branch", "-D" if force else "-d", name]
|
|
888
|
-
result = await self.mutate(command
|
|
942
|
+
result = await self.mutate(command)
|
|
889
943
|
return tool_result(result, render(result))
|
|
890
944
|
|
|
891
945
|
@apps.tool(resource_uri=self.WIDGET.uri, icons=[icon], annotations=writes)
|
|
@@ -906,7 +960,7 @@ class GitService:
|
|
|
906
960
|
command = ["switch", "--no-guess", *(["-c"] if create else []), branch]
|
|
907
961
|
if start_point is not None:
|
|
908
962
|
command.append(await self.revision(start_point, "start_point"))
|
|
909
|
-
result = await self.mutate(command
|
|
963
|
+
result = await self.mutate(command)
|
|
910
964
|
return tool_result(result, render(result))
|
|
911
965
|
|
|
912
966
|
@apps.tool(resource_uri=self.WIDGET.uri, icons=[icon], annotations=writes)
|
|
@@ -965,7 +1019,7 @@ class GitService:
|
|
|
965
1019
|
"Use git_stash(action='list') to list available references."
|
|
966
1020
|
)
|
|
967
1021
|
command = ["stash", action, reference]
|
|
968
|
-
changed = await self.mutate(command
|
|
1022
|
+
changed = await self.mutate(command)
|
|
969
1023
|
result = GitStashResult(**changed.model_dump())
|
|
970
1024
|
return tool_result(result, render(result))
|
|
971
1025
|
|
|
@@ -985,7 +1039,6 @@ class GitService:
|
|
|
985
1039
|
"--prune" if prune else "--no-prune",
|
|
986
1040
|
name,
|
|
987
1041
|
],
|
|
988
|
-
source_changes=True,
|
|
989
1042
|
)
|
|
990
1043
|
return tool_result(result, render(result))
|
|
991
1044
|
|
|
@@ -1019,7 +1072,7 @@ class GitService:
|
|
|
1019
1072
|
if branch is not None:
|
|
1020
1073
|
await self.branch_name(branch, "branch", full=True)
|
|
1021
1074
|
command.append("refs/heads/" + branch)
|
|
1022
|
-
result = await self.mutate(command
|
|
1075
|
+
result = await self.mutate(command)
|
|
1023
1076
|
return tool_result(result, render(result))
|
|
1024
1077
|
|
|
1025
1078
|
@apps.tool(resource_uri=self.WIDGET.uri, icons=[icon], annotations=network)
|
|
@@ -1055,7 +1108,7 @@ class GitService:
|
|
|
1055
1108
|
if set_upstream:
|
|
1056
1109
|
command.append("--set-upstream")
|
|
1057
1110
|
command.extend([name, f"HEAD:refs/heads/{target}"])
|
|
1058
|
-
result = await self.mutate(command
|
|
1111
|
+
result = await self.mutate(command)
|
|
1059
1112
|
return tool_result(result, render(result))
|
|
1060
1113
|
|
|
1061
1114
|
@apps.tool(resource_uri=self.WIDGET.uri, icons=[icon], annotations=writes)
|
|
@@ -1072,7 +1125,7 @@ class GitService:
|
|
|
1072
1125
|
if message is not None:
|
|
1073
1126
|
command.extend(["--message", message])
|
|
1074
1127
|
command.append(await self.revision(revision))
|
|
1075
|
-
result = await self.mutate(command
|
|
1128
|
+
result = await self.mutate(command)
|
|
1076
1129
|
return tool_result(result, render(result))
|
|
1077
1130
|
|
|
1078
1131
|
@apps.tool(resource_uri=self.WIDGET.uri, icons=[icon], annotations=writes)
|
|
@@ -1081,7 +1134,6 @@ class GitService:
|
|
|
1081
1134
|
async with self.request(ctx):
|
|
1082
1135
|
result = await self.mutate(
|
|
1083
1136
|
["rebase", "--no-autostash", await self.revision(revision)],
|
|
1084
|
-
source_changes=True,
|
|
1085
1137
|
)
|
|
1086
1138
|
return tool_result(result, render(result))
|
|
1087
1139
|
|
|
@@ -1108,7 +1160,6 @@ class GitService:
|
|
|
1108
1160
|
*(["--mainline", str(mainline)] if mainline else []),
|
|
1109
1161
|
*resolved,
|
|
1110
1162
|
],
|
|
1111
|
-
source_changes=True,
|
|
1112
1163
|
)
|
|
1113
1164
|
return tool_result(result, render(result))
|
|
1114
1165
|
|
|
@@ -1136,7 +1187,6 @@ class GitService:
|
|
|
1136
1187
|
*(["--mainline", str(mainline)] if mainline else []),
|
|
1137
1188
|
*resolved,
|
|
1138
1189
|
],
|
|
1139
|
-
source_changes=True,
|
|
1140
1190
|
)
|
|
1141
1191
|
return tool_result(result, render(result))
|
|
1142
1192
|
|
|
@@ -1223,7 +1273,7 @@ class GitService:
|
|
|
1223
1273
|
selected.replace("_", "-"),
|
|
1224
1274
|
f"--{action}",
|
|
1225
1275
|
]
|
|
1226
|
-
result = await self.mutate(command
|
|
1276
|
+
result = await self.mutate(command)
|
|
1227
1277
|
return tool_result(result, render(result))
|
|
1228
1278
|
|
|
1229
1279
|
@mcp.resource(self.STATUS_URI, mime_type="text/plain", icons=[icon])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{forge_cpp_mcp-0.5.0 → forge_cpp_mcp-0.5.1}/src/forgemcp/toolchain/providers/visual_studio.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|