proofflow-mcp 0.1.0__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.
- proofflow_mcp-0.1.0/.gitignore +24 -0
- proofflow_mcp-0.1.0/PKG-INFO +169 -0
- proofflow_mcp-0.1.0/README.md +144 -0
- proofflow_mcp-0.1.0/pyproject.toml +48 -0
- proofflow_mcp-0.1.0/src/proofflow_mcp/__init__.py +3 -0
- proofflow_mcp-0.1.0/src/proofflow_mcp/__main__.py +5 -0
- proofflow_mcp-0.1.0/src/proofflow_mcp/client.py +175 -0
- proofflow_mcp-0.1.0/src/proofflow_mcp/server.py +534 -0
- proofflow_mcp-0.1.0/src/proofflow_mcp/tools/__init__.py +0 -0
- proofflow_mcp-0.1.0/tests/__init__.py +0 -0
- proofflow_mcp-0.1.0/tests/conftest.py +8 -0
- proofflow_mcp-0.1.0/tests/test_client.py +178 -0
- proofflow_mcp-0.1.0/tests/test_server.py +41 -0
- proofflow_mcp-0.1.0/tests/test_tools.py +225 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
.venv/
|
|
5
|
+
.pytest_cache/
|
|
6
|
+
|
|
7
|
+
# Local data
|
|
8
|
+
*.sqlite3
|
|
9
|
+
*.db
|
|
10
|
+
backend/data/demo/
|
|
11
|
+
sample_data/work/
|
|
12
|
+
sample_data/repos/
|
|
13
|
+
|
|
14
|
+
# Frontend
|
|
15
|
+
node_modules/
|
|
16
|
+
dist/
|
|
17
|
+
.vite/
|
|
18
|
+
*.tsbuildinfo
|
|
19
|
+
|
|
20
|
+
# OS and editor files
|
|
21
|
+
.DS_Store
|
|
22
|
+
Thumbs.db
|
|
23
|
+
.idea/
|
|
24
|
+
.vscode/
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: proofflow-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server for ProofFlow – audit infrastructure for AI coding agents
|
|
5
|
+
Project-URL: Homepage, https://github.com/Hyperion-GPU/ProofFlow-v0.1
|
|
6
|
+
Project-URL: Repository, https://github.com/Hyperion-GPU/ProofFlow-v0.1
|
|
7
|
+
Project-URL: Issues, https://github.com/Hyperion-GPU/ProofFlow-v0.1/issues
|
|
8
|
+
Author: Hyperion-GPU
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
Keywords: ai-agent,audit,claude-code,codex,mcp,proofflow
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
17
|
+
Requires-Python: >=3.11
|
|
18
|
+
Requires-Dist: httpx>=0.27.0
|
|
19
|
+
Requires-Dist: mcp>=1.0.0
|
|
20
|
+
Provides-Extra: dev
|
|
21
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
22
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
23
|
+
Requires-Dist: respx>=0.21; extra == 'dev'
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# ProofFlow MCP Server
|
|
27
|
+
|
|
28
|
+
MCP (Model Context Protocol) server that exposes ProofFlow's audit capabilities as tools for Claude Code and Codex.
|
|
29
|
+
|
|
30
|
+
## What it does
|
|
31
|
+
|
|
32
|
+
Lets AI coding assistants trigger ProofFlow workflows directly:
|
|
33
|
+
|
|
34
|
+
- **Scan folders** — index files with SHA-256 hashes, create audit Cases
|
|
35
|
+
- **Code review** — analyze git diffs, generate evidence-backed risk claims
|
|
36
|
+
- **Suggest actions** — generate file organization suggestions
|
|
37
|
+
- **Approve & execute** — run pending actions (with policy gate awareness)
|
|
38
|
+
- **Export Proof Packets** — generate shareable markdown audit reports
|
|
39
|
+
- **Search** — full-text search across indexed artifacts
|
|
40
|
+
- **Undo** — reverse executed actions
|
|
41
|
+
|
|
42
|
+
## Prerequisites
|
|
43
|
+
|
|
44
|
+
- Python 3.11+
|
|
45
|
+
- ProofFlow backend running on `http://127.0.0.1:8787`
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
cd mcp-server
|
|
51
|
+
pip install -e .
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
For development (includes test dependencies):
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install -e ".[dev]"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
> Note: Install in a separate virtualenv from the backend to avoid starlette version conflicts between FastAPI and the MCP SDK.
|
|
61
|
+
|
|
62
|
+
## Configuration
|
|
63
|
+
|
|
64
|
+
### Claude Code
|
|
65
|
+
|
|
66
|
+
Add to your project's `.mcp.json` or `~/.claude/settings.json`:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"mcpServers": {
|
|
71
|
+
"proofflow": {
|
|
72
|
+
"command": "python",
|
|
73
|
+
"args": ["-m", "proofflow_mcp"],
|
|
74
|
+
"env": {
|
|
75
|
+
"PROOFFLOW_BASE_URL": "http://127.0.0.1:8787"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Claude Desktop
|
|
83
|
+
|
|
84
|
+
Add to `claude_desktop_config.json`:
|
|
85
|
+
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
86
|
+
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"mcpServers": {
|
|
91
|
+
"proofflow": {
|
|
92
|
+
"command": "proofflow-mcp",
|
|
93
|
+
"env": {
|
|
94
|
+
"PROOFFLOW_BASE_URL": "http://127.0.0.1:8787"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Codex
|
|
102
|
+
|
|
103
|
+
Add to your Codex MCP configuration with the same command/args pattern.
|
|
104
|
+
|
|
105
|
+
### Environment Variables
|
|
106
|
+
|
|
107
|
+
| Variable | Default | Description |
|
|
108
|
+
|----------|---------|-------------|
|
|
109
|
+
| `PROOFFLOW_BASE_URL` | `http://127.0.0.1:8787` | ProofFlow backend URL |
|
|
110
|
+
| `PROOFFLOW_TIMEOUT` | `30` | HTTP request timeout in seconds |
|
|
111
|
+
| `PROOFFLOW_API_KEY` | *(unset)* | API key for backend auth (optional) |
|
|
112
|
+
| `PROOFFLOW_MCP_MAX_CONCURRENT` | `5` | Max concurrent MCP tool calls |
|
|
113
|
+
|
|
114
|
+
## Available Tools
|
|
115
|
+
|
|
116
|
+
| Tool | Description |
|
|
117
|
+
|------|-------------|
|
|
118
|
+
| `proofflow_health` | Check backend connectivity |
|
|
119
|
+
| `proofflow_scan` | Scan a folder, create Case + Artifacts |
|
|
120
|
+
| `proofflow_suggest` | Generate cleanup suggestions for a scanned Case |
|
|
121
|
+
| `proofflow_review` | AgentGuard code review on a git repo |
|
|
122
|
+
| `proofflow_status` | Get full Case status (artifacts, claims, actions) |
|
|
123
|
+
| `proofflow_approve_execute` | Approve and execute a pending action |
|
|
124
|
+
| `proofflow_export_packet` | Export Case as Proof Packet (markdown) |
|
|
125
|
+
| `proofflow_search` | Full-text search across artifacts |
|
|
126
|
+
| `proofflow_list_cases` | List all Cases |
|
|
127
|
+
| `proofflow_list_actions` | List actions for a Case |
|
|
128
|
+
| `proofflow_undo` | Undo an executed action |
|
|
129
|
+
| `proofflow_decide` | Create a decision to approve/reject a policy gate |
|
|
130
|
+
|
|
131
|
+
## Usage Example
|
|
132
|
+
|
|
133
|
+
In Claude Code, once configured:
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
> Review the code changes in this repo for safety
|
|
137
|
+
|
|
138
|
+
Claude will call proofflow_review with the current repo path,
|
|
139
|
+
creating an AgentGuard Case with evidence-backed claims.
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Running Tests
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
cd mcp-server
|
|
146
|
+
python -m pytest tests/ -v
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Running the Server Directly
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
python -m proofflow_mcp
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The server communicates via stdio (stdin/stdout) per the MCP protocol.
|
|
156
|
+
|
|
157
|
+
## Architecture
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
Claude Code / Codex
|
|
161
|
+
↓ (MCP stdio)
|
|
162
|
+
ProofFlow MCP Server
|
|
163
|
+
↓ (HTTP)
|
|
164
|
+
ProofFlow Backend (localhost:8787)
|
|
165
|
+
↓
|
|
166
|
+
SQLite DB + Local Files
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
The MCP server is a thin adapter — all business logic lives in the ProofFlow backend.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# ProofFlow MCP Server
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) server that exposes ProofFlow's audit capabilities as tools for Claude Code and Codex.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
Lets AI coding assistants trigger ProofFlow workflows directly:
|
|
8
|
+
|
|
9
|
+
- **Scan folders** — index files with SHA-256 hashes, create audit Cases
|
|
10
|
+
- **Code review** — analyze git diffs, generate evidence-backed risk claims
|
|
11
|
+
- **Suggest actions** — generate file organization suggestions
|
|
12
|
+
- **Approve & execute** — run pending actions (with policy gate awareness)
|
|
13
|
+
- **Export Proof Packets** — generate shareable markdown audit reports
|
|
14
|
+
- **Search** — full-text search across indexed artifacts
|
|
15
|
+
- **Undo** — reverse executed actions
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
- Python 3.11+
|
|
20
|
+
- ProofFlow backend running on `http://127.0.0.1:8787`
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
cd mcp-server
|
|
26
|
+
pip install -e .
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
For development (includes test dependencies):
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install -e ".[dev]"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
> Note: Install in a separate virtualenv from the backend to avoid starlette version conflicts between FastAPI and the MCP SDK.
|
|
36
|
+
|
|
37
|
+
## Configuration
|
|
38
|
+
|
|
39
|
+
### Claude Code
|
|
40
|
+
|
|
41
|
+
Add to your project's `.mcp.json` or `~/.claude/settings.json`:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"mcpServers": {
|
|
46
|
+
"proofflow": {
|
|
47
|
+
"command": "python",
|
|
48
|
+
"args": ["-m", "proofflow_mcp"],
|
|
49
|
+
"env": {
|
|
50
|
+
"PROOFFLOW_BASE_URL": "http://127.0.0.1:8787"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Claude Desktop
|
|
58
|
+
|
|
59
|
+
Add to `claude_desktop_config.json`:
|
|
60
|
+
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
61
|
+
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"mcpServers": {
|
|
66
|
+
"proofflow": {
|
|
67
|
+
"command": "proofflow-mcp",
|
|
68
|
+
"env": {
|
|
69
|
+
"PROOFFLOW_BASE_URL": "http://127.0.0.1:8787"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Codex
|
|
77
|
+
|
|
78
|
+
Add to your Codex MCP configuration with the same command/args pattern.
|
|
79
|
+
|
|
80
|
+
### Environment Variables
|
|
81
|
+
|
|
82
|
+
| Variable | Default | Description |
|
|
83
|
+
|----------|---------|-------------|
|
|
84
|
+
| `PROOFFLOW_BASE_URL` | `http://127.0.0.1:8787` | ProofFlow backend URL |
|
|
85
|
+
| `PROOFFLOW_TIMEOUT` | `30` | HTTP request timeout in seconds |
|
|
86
|
+
| `PROOFFLOW_API_KEY` | *(unset)* | API key for backend auth (optional) |
|
|
87
|
+
| `PROOFFLOW_MCP_MAX_CONCURRENT` | `5` | Max concurrent MCP tool calls |
|
|
88
|
+
|
|
89
|
+
## Available Tools
|
|
90
|
+
|
|
91
|
+
| Tool | Description |
|
|
92
|
+
|------|-------------|
|
|
93
|
+
| `proofflow_health` | Check backend connectivity |
|
|
94
|
+
| `proofflow_scan` | Scan a folder, create Case + Artifacts |
|
|
95
|
+
| `proofflow_suggest` | Generate cleanup suggestions for a scanned Case |
|
|
96
|
+
| `proofflow_review` | AgentGuard code review on a git repo |
|
|
97
|
+
| `proofflow_status` | Get full Case status (artifacts, claims, actions) |
|
|
98
|
+
| `proofflow_approve_execute` | Approve and execute a pending action |
|
|
99
|
+
| `proofflow_export_packet` | Export Case as Proof Packet (markdown) |
|
|
100
|
+
| `proofflow_search` | Full-text search across artifacts |
|
|
101
|
+
| `proofflow_list_cases` | List all Cases |
|
|
102
|
+
| `proofflow_list_actions` | List actions for a Case |
|
|
103
|
+
| `proofflow_undo` | Undo an executed action |
|
|
104
|
+
| `proofflow_decide` | Create a decision to approve/reject a policy gate |
|
|
105
|
+
|
|
106
|
+
## Usage Example
|
|
107
|
+
|
|
108
|
+
In Claude Code, once configured:
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
> Review the code changes in this repo for safety
|
|
112
|
+
|
|
113
|
+
Claude will call proofflow_review with the current repo path,
|
|
114
|
+
creating an AgentGuard Case with evidence-backed claims.
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Running Tests
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
cd mcp-server
|
|
121
|
+
python -m pytest tests/ -v
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Running the Server Directly
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
python -m proofflow_mcp
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The server communicates via stdio (stdin/stdout) per the MCP protocol.
|
|
131
|
+
|
|
132
|
+
## Architecture
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
Claude Code / Codex
|
|
136
|
+
↓ (MCP stdio)
|
|
137
|
+
ProofFlow MCP Server
|
|
138
|
+
↓ (HTTP)
|
|
139
|
+
ProofFlow Backend (localhost:8787)
|
|
140
|
+
↓
|
|
141
|
+
SQLite DB + Local Files
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The MCP server is a thin adapter — all business logic lives in the ProofFlow backend.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "proofflow-mcp"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "MCP server for ProofFlow – audit infrastructure for AI coding agents"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Hyperion-GPU" },
|
|
14
|
+
]
|
|
15
|
+
keywords = ["mcp", "proofflow", "audit", "ai-agent", "claude-code", "codex"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Topic :: Software Development :: Quality Assurance",
|
|
23
|
+
]
|
|
24
|
+
dependencies = [
|
|
25
|
+
"mcp>=1.0.0",
|
|
26
|
+
"httpx>=0.27.0",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Homepage = "https://github.com/Hyperion-GPU/ProofFlow-v0.1"
|
|
31
|
+
Repository = "https://github.com/Hyperion-GPU/ProofFlow-v0.1"
|
|
32
|
+
Issues = "https://github.com/Hyperion-GPU/ProofFlow-v0.1/issues"
|
|
33
|
+
|
|
34
|
+
[project.scripts]
|
|
35
|
+
proofflow-mcp = "proofflow_mcp.server:main"
|
|
36
|
+
|
|
37
|
+
[tool.hatch.build.targets.wheel]
|
|
38
|
+
packages = ["src/proofflow_mcp"]
|
|
39
|
+
|
|
40
|
+
[tool.pytest.ini_options]
|
|
41
|
+
testpaths = ["tests"]
|
|
42
|
+
|
|
43
|
+
[project.optional-dependencies]
|
|
44
|
+
dev = [
|
|
45
|
+
"pytest>=8.0",
|
|
46
|
+
"pytest-asyncio>=0.23",
|
|
47
|
+
"respx>=0.21",
|
|
48
|
+
]
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"""HTTP client wrapper for the ProofFlow backend REST API."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
import httpx
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ProofFlowError(Exception):
|
|
12
|
+
"""Raised when a ProofFlow API call fails."""
|
|
13
|
+
|
|
14
|
+
def __init__(self, message: str, status_code: int | None = None):
|
|
15
|
+
super().__init__(message)
|
|
16
|
+
self.status_code = status_code
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ProofFlowClient:
|
|
20
|
+
"""Async HTTP client for the ProofFlow backend."""
|
|
21
|
+
|
|
22
|
+
def __init__(self) -> None:
|
|
23
|
+
self._base_url = os.getenv("PROOFFLOW_BASE_URL", "http://127.0.0.1:8787")
|
|
24
|
+
self._timeout = float(os.getenv("PROOFFLOW_TIMEOUT", "30"))
|
|
25
|
+
self._http: httpx.AsyncClient | None = None
|
|
26
|
+
|
|
27
|
+
async def _get_http(self) -> httpx.AsyncClient:
|
|
28
|
+
if self._http is None or self._http.is_closed:
|
|
29
|
+
headers: dict[str, str] = {}
|
|
30
|
+
api_key = os.getenv("PROOFFLOW_API_KEY")
|
|
31
|
+
if api_key:
|
|
32
|
+
headers["X-ProofFlow-Token"] = api_key
|
|
33
|
+
self._http = httpx.AsyncClient(
|
|
34
|
+
base_url=self._base_url, timeout=self._timeout, headers=headers
|
|
35
|
+
)
|
|
36
|
+
return self._http
|
|
37
|
+
|
|
38
|
+
async def close(self) -> None:
|
|
39
|
+
if self._http and not self._http.is_closed:
|
|
40
|
+
await self._http.aclose()
|
|
41
|
+
|
|
42
|
+
async def _request(
|
|
43
|
+
self, method: str, path: str, **kwargs: Any
|
|
44
|
+
) -> dict[str, Any] | list[dict[str, Any]]:
|
|
45
|
+
http = await self._get_http()
|
|
46
|
+
try:
|
|
47
|
+
response = await http.request(method, path, **kwargs)
|
|
48
|
+
except httpx.ConnectError:
|
|
49
|
+
raise ProofFlowError(
|
|
50
|
+
"ProofFlow backend is not running. "
|
|
51
|
+
"Start it with: cd backend && python -m uvicorn proofflow.main:app --port 8787"
|
|
52
|
+
)
|
|
53
|
+
except httpx.TimeoutException:
|
|
54
|
+
raise ProofFlowError(
|
|
55
|
+
f"ProofFlow backend timed out after {self._timeout}s"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
if response.status_code >= 400:
|
|
59
|
+
try:
|
|
60
|
+
detail = response.json().get("detail", response.text)
|
|
61
|
+
except Exception:
|
|
62
|
+
detail = response.text
|
|
63
|
+
raise ProofFlowError(
|
|
64
|
+
f"ProofFlow API error ({response.status_code}): {detail}",
|
|
65
|
+
status_code=response.status_code,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
return response.json()
|
|
69
|
+
|
|
70
|
+
# --- Health ---
|
|
71
|
+
|
|
72
|
+
async def health(self) -> dict[str, Any]:
|
|
73
|
+
return await self._request("GET", "/health")
|
|
74
|
+
|
|
75
|
+
# --- Cases ---
|
|
76
|
+
|
|
77
|
+
async def list_cases(self) -> list[dict[str, Any]]:
|
|
78
|
+
return await self._request("GET", "/cases")
|
|
79
|
+
|
|
80
|
+
async def get_case_packet(self, case_id: str) -> dict[str, Any]:
|
|
81
|
+
return await self._request("GET", f"/cases/{case_id}/packet")
|
|
82
|
+
|
|
83
|
+
# --- LocalProof ---
|
|
84
|
+
|
|
85
|
+
async def scan(
|
|
86
|
+
self,
|
|
87
|
+
folder_path: str,
|
|
88
|
+
recursive: bool = True,
|
|
89
|
+
max_files: int = 500,
|
|
90
|
+
) -> dict[str, Any]:
|
|
91
|
+
return await self._request(
|
|
92
|
+
"POST",
|
|
93
|
+
"/localproof/scan",
|
|
94
|
+
json={"folder_path": folder_path, "recursive": recursive, "max_files": max_files},
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
async def suggest_actions(
|
|
98
|
+
self, case_id: str, target_root: str
|
|
99
|
+
) -> dict[str, Any]:
|
|
100
|
+
return await self._request(
|
|
101
|
+
"POST",
|
|
102
|
+
"/localproof/suggest-actions",
|
|
103
|
+
json={"case_id": case_id, "target_root": target_root},
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# --- AgentGuard ---
|
|
107
|
+
|
|
108
|
+
async def review(
|
|
109
|
+
self,
|
|
110
|
+
repo_path: str,
|
|
111
|
+
base_ref: str = "HEAD",
|
|
112
|
+
include_untracked: bool = True,
|
|
113
|
+
test_command: str | None = None,
|
|
114
|
+
) -> dict[str, Any]:
|
|
115
|
+
body: dict[str, Any] = {
|
|
116
|
+
"repo_path": repo_path,
|
|
117
|
+
"base_ref": base_ref,
|
|
118
|
+
"include_untracked": include_untracked,
|
|
119
|
+
}
|
|
120
|
+
if test_command is not None:
|
|
121
|
+
body["test_command"] = test_command
|
|
122
|
+
return await self._request("POST", "/agentguard/review", json=body)
|
|
123
|
+
|
|
124
|
+
# --- Actions ---
|
|
125
|
+
|
|
126
|
+
async def list_actions(self, case_id: str) -> list[dict[str, Any]]:
|
|
127
|
+
return await self._request("GET", f"/cases/{case_id}/actions")
|
|
128
|
+
|
|
129
|
+
async def approve_action(self, action_id: str) -> dict[str, Any]:
|
|
130
|
+
return await self._request("POST", f"/actions/{action_id}/approve")
|
|
131
|
+
|
|
132
|
+
async def execute_action(self, action_id: str) -> dict[str, Any]:
|
|
133
|
+
return await self._request("POST", f"/actions/{action_id}/execute")
|
|
134
|
+
|
|
135
|
+
async def undo_action(self, action_id: str) -> dict[str, Any]:
|
|
136
|
+
return await self._request("POST", f"/actions/{action_id}/undo")
|
|
137
|
+
|
|
138
|
+
# --- Reports ---
|
|
139
|
+
|
|
140
|
+
async def export_report(self, case_id: str) -> dict[str, Any]:
|
|
141
|
+
return await self._request(
|
|
142
|
+
"POST",
|
|
143
|
+
f"/reports/cases/{case_id}/export",
|
|
144
|
+
json={"format": "markdown"},
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
# --- Search ---
|
|
148
|
+
|
|
149
|
+
async def search(self, query: str, limit: int = 25) -> dict[str, Any]:
|
|
150
|
+
return await self._request(
|
|
151
|
+
"GET", "/search", params={"q": query, "limit": limit}
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
# --- Decisions ---
|
|
155
|
+
|
|
156
|
+
async def create_decision(
|
|
157
|
+
self,
|
|
158
|
+
case_id: str,
|
|
159
|
+
title: str,
|
|
160
|
+
status: str,
|
|
161
|
+
rationale: str,
|
|
162
|
+
result: str,
|
|
163
|
+
metadata: dict[str, Any] | None = None,
|
|
164
|
+
) -> dict[str, Any]:
|
|
165
|
+
body: dict[str, Any] = {
|
|
166
|
+
"title": title,
|
|
167
|
+
"status": status,
|
|
168
|
+
"rationale": rationale,
|
|
169
|
+
"result": result,
|
|
170
|
+
}
|
|
171
|
+
if metadata:
|
|
172
|
+
body["metadata"] = metadata
|
|
173
|
+
return await self._request(
|
|
174
|
+
"POST", f"/cases/{case_id}/decisions", json=body
|
|
175
|
+
)
|