iriai-cli 0.2.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.
- iriai_cli-0.2.0/LICENSE +21 -0
- iriai_cli-0.2.0/PKG-INFO +134 -0
- iriai_cli-0.2.0/README.md +105 -0
- iriai_cli-0.2.0/pyproject.toml +56 -0
- iriai_cli-0.2.0/setup.cfg +4 -0
- iriai_cli-0.2.0/src/iriai_cli/__init__.py +3 -0
- iriai_cli-0.2.0/src/iriai_cli/__main__.py +6 -0
- iriai_cli-0.2.0/src/iriai_cli/api_client.py +169 -0
- iriai_cli-0.2.0/src/iriai_cli/auth.py +252 -0
- iriai_cli-0.2.0/src/iriai_cli/cli.py +417 -0
- iriai_cli-0.2.0/src/iriai_cli/config.py +38 -0
- iriai_cli-0.2.0/src/iriai_cli/deploy_client.py +181 -0
- iriai_cli-0.2.0/src/iriai_cli/diff_viewer.py +1 -0
- iriai_cli-0.2.0/src/iriai_cli/file_writer.py +180 -0
- iriai_cli-0.2.0/src/iriai_cli/fix_deploy.py +350 -0
- iriai_cli-0.2.0/src/iriai_cli/fix_deploy_llm.py +211 -0
- iriai_cli-0.2.0/src/iriai_cli/local_analyzer.py +346 -0
- iriai_cli-0.2.0/src/iriai_cli/local_llm.py +310 -0
- iriai_cli-0.2.0/src/iriai_cli/module_loader.py +122 -0
- iriai_cli-0.2.0/src/iriai_cli/repo_manager.py +68 -0
- iriai_cli-0.2.0/src/iriai_cli/tarball_builder.py +88 -0
- iriai_cli-0.2.0/src/iriai_cli.egg-info/PKG-INFO +134 -0
- iriai_cli-0.2.0/src/iriai_cli.egg-info/SOURCES.txt +26 -0
- iriai_cli-0.2.0/src/iriai_cli.egg-info/dependency_links.txt +1 -0
- iriai_cli-0.2.0/src/iriai_cli.egg-info/entry_points.txt +2 -0
- iriai_cli-0.2.0/src/iriai_cli.egg-info/requires.txt +10 -0
- iriai_cli-0.2.0/src/iriai_cli.egg-info/top_level.txt +1 -0
- iriai_cli-0.2.0/tests/test_tarball_builder.py +309 -0
iriai_cli-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Iriai Platform Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
iriai_cli-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: iriai-cli
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: CLI tool for integrating Iriai platform modules into local projects
|
|
5
|
+
Author: Iriai Platform Team
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/thedanielzhang/iriai-cli
|
|
8
|
+
Project-URL: Repository, https://github.com/thedanielzhang/iriai-cli.git
|
|
9
|
+
Project-URL: Issues, https://github.com/thedanielzhang/iriai-cli/issues
|
|
10
|
+
Keywords: iriai,cli,integration,modules
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Requires-Python: >=3.11
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Requires-Dist: click>=8.1.0
|
|
20
|
+
Requires-Dist: httpx>=0.27.0
|
|
21
|
+
Requires-Dist: pyyaml>=6.0
|
|
22
|
+
Requires-Dist: rich>=13.7.0
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
25
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
|
|
26
|
+
Requires-Dist: black>=24.0.0; extra == "dev"
|
|
27
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# iriai-cli
|
|
31
|
+
|
|
32
|
+
Command-line tool for integrating Iriai platform modules into your local projects.
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install iriai-cli
|
|
38
|
+
# or
|
|
39
|
+
pipx install iriai-cli
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# List available modules
|
|
46
|
+
iriai modules list
|
|
47
|
+
|
|
48
|
+
# Analyze your project
|
|
49
|
+
iriai analyze
|
|
50
|
+
|
|
51
|
+
# Install a module
|
|
52
|
+
iriai integrate auth-react --action install
|
|
53
|
+
|
|
54
|
+
# Repair a misconfigured module
|
|
55
|
+
iriai integrate auth-react --action repair
|
|
56
|
+
|
|
57
|
+
# Install multiple modules
|
|
58
|
+
iriai integrate auth-react auth-python pwa --action install
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Features
|
|
62
|
+
|
|
63
|
+
- Local file integration (no Git commits required)
|
|
64
|
+
- Pre-flight analysis and misconfiguration detection
|
|
65
|
+
- LLM-powered code generation via engine API or locally via Claude Code (`--local`)
|
|
66
|
+
- Interactive file write prompts (Apply/Skip/Overwrite-all)
|
|
67
|
+
- Syntax-highlighted diffs
|
|
68
|
+
- Secret file filtering (`.env`, `*.pem`, `*.key`, `credentials.*`, etc.)
|
|
69
|
+
- Dry-run mode for previewing changes
|
|
70
|
+
|
|
71
|
+
## Configuration
|
|
72
|
+
|
|
73
|
+
### Environment Variables
|
|
74
|
+
|
|
75
|
+
| Variable | Default | Description |
|
|
76
|
+
|----------|---------|-------------|
|
|
77
|
+
| `IRIAI_ENGINE_URL` | `https://integration.iriai.app` | Integration engine base URL |
|
|
78
|
+
| `IRIAI_API_TOKEN` | *(none)* | Bearer token for authenticated modules (get from deploy console) |
|
|
79
|
+
| `IRIAI_MODULES_DIR` | *(fetched from API)* | Override: load module definitions from local YAML files instead of API |
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Point to local engine during development
|
|
83
|
+
export IRIAI_ENGINE_URL=http://localhost:8005
|
|
84
|
+
|
|
85
|
+
# Set API token for authenticated modules
|
|
86
|
+
export IRIAI_API_TOKEN=your_token_here
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Commands
|
|
90
|
+
|
|
91
|
+
### `iriai modules list`
|
|
92
|
+
|
|
93
|
+
List all available modules with their versions and descriptions.
|
|
94
|
+
|
|
95
|
+
### `iriai analyze`
|
|
96
|
+
|
|
97
|
+
Analyze the current directory for module compatibility and misconfigurations. Creates a tarball of the project directory (excluding secrets and ignored files) and uploads it to the engine's `POST /api/analyze-local` endpoint.
|
|
98
|
+
|
|
99
|
+
### `iriai integrate <modules...>`
|
|
100
|
+
|
|
101
|
+
Integrate one or more modules into your project.
|
|
102
|
+
|
|
103
|
+
Options:
|
|
104
|
+
- `--action`: `install`, `repair`, or `overwrite` (default: `install`)
|
|
105
|
+
- `--depth`: `core` or `full` (default: `full`)
|
|
106
|
+
- `--yes`: Skip interactive prompts, apply all changes
|
|
107
|
+
- `--dry-run`: Show what would be changed without writing files
|
|
108
|
+
- `--local`: Run entirely locally via Claude Code (`claude -p`) instead of the engine API
|
|
109
|
+
|
|
110
|
+
### Local Mode (`--local`)
|
|
111
|
+
|
|
112
|
+
The `--local` flag runs LLM integration on your machine via Claude Code instead of the engine API:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
iriai integrate auth-react --local
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
This mode:
|
|
119
|
+
1. Fetches module definitions from the integration engine API
|
|
120
|
+
2. Analyzes the project locally (same logic as the engine)
|
|
121
|
+
3. Builds a prompt identical to `LLMIntegrator._build_prompt()`
|
|
122
|
+
4. Invokes `claude -p` subprocess with a 5-minute timeout
|
|
123
|
+
5. Parses the structured JSON response
|
|
124
|
+
6. Applies file operations through interactive prompts
|
|
125
|
+
|
|
126
|
+
**Requirements:** Claude Code CLI (`claude`) must be installed and on your PATH.
|
|
127
|
+
|
|
128
|
+
**Note:** Profile matching is skipped in local mode (requires database). Most integrations work without profile-specific config.
|
|
129
|
+
|
|
130
|
+
For development, set `IRIAI_MODULES_DIR` to load module definitions from local YAML files instead of the API.
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
MIT
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# iriai-cli
|
|
2
|
+
|
|
3
|
+
Command-line tool for integrating Iriai platform modules into your local projects.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install iriai-cli
|
|
9
|
+
# or
|
|
10
|
+
pipx install iriai-cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# List available modules
|
|
17
|
+
iriai modules list
|
|
18
|
+
|
|
19
|
+
# Analyze your project
|
|
20
|
+
iriai analyze
|
|
21
|
+
|
|
22
|
+
# Install a module
|
|
23
|
+
iriai integrate auth-react --action install
|
|
24
|
+
|
|
25
|
+
# Repair a misconfigured module
|
|
26
|
+
iriai integrate auth-react --action repair
|
|
27
|
+
|
|
28
|
+
# Install multiple modules
|
|
29
|
+
iriai integrate auth-react auth-python pwa --action install
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Features
|
|
33
|
+
|
|
34
|
+
- Local file integration (no Git commits required)
|
|
35
|
+
- Pre-flight analysis and misconfiguration detection
|
|
36
|
+
- LLM-powered code generation via engine API or locally via Claude Code (`--local`)
|
|
37
|
+
- Interactive file write prompts (Apply/Skip/Overwrite-all)
|
|
38
|
+
- Syntax-highlighted diffs
|
|
39
|
+
- Secret file filtering (`.env`, `*.pem`, `*.key`, `credentials.*`, etc.)
|
|
40
|
+
- Dry-run mode for previewing changes
|
|
41
|
+
|
|
42
|
+
## Configuration
|
|
43
|
+
|
|
44
|
+
### Environment Variables
|
|
45
|
+
|
|
46
|
+
| Variable | Default | Description |
|
|
47
|
+
|----------|---------|-------------|
|
|
48
|
+
| `IRIAI_ENGINE_URL` | `https://integration.iriai.app` | Integration engine base URL |
|
|
49
|
+
| `IRIAI_API_TOKEN` | *(none)* | Bearer token for authenticated modules (get from deploy console) |
|
|
50
|
+
| `IRIAI_MODULES_DIR` | *(fetched from API)* | Override: load module definitions from local YAML files instead of API |
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Point to local engine during development
|
|
54
|
+
export IRIAI_ENGINE_URL=http://localhost:8005
|
|
55
|
+
|
|
56
|
+
# Set API token for authenticated modules
|
|
57
|
+
export IRIAI_API_TOKEN=your_token_here
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Commands
|
|
61
|
+
|
|
62
|
+
### `iriai modules list`
|
|
63
|
+
|
|
64
|
+
List all available modules with their versions and descriptions.
|
|
65
|
+
|
|
66
|
+
### `iriai analyze`
|
|
67
|
+
|
|
68
|
+
Analyze the current directory for module compatibility and misconfigurations. Creates a tarball of the project directory (excluding secrets and ignored files) and uploads it to the engine's `POST /api/analyze-local` endpoint.
|
|
69
|
+
|
|
70
|
+
### `iriai integrate <modules...>`
|
|
71
|
+
|
|
72
|
+
Integrate one or more modules into your project.
|
|
73
|
+
|
|
74
|
+
Options:
|
|
75
|
+
- `--action`: `install`, `repair`, or `overwrite` (default: `install`)
|
|
76
|
+
- `--depth`: `core` or `full` (default: `full`)
|
|
77
|
+
- `--yes`: Skip interactive prompts, apply all changes
|
|
78
|
+
- `--dry-run`: Show what would be changed without writing files
|
|
79
|
+
- `--local`: Run entirely locally via Claude Code (`claude -p`) instead of the engine API
|
|
80
|
+
|
|
81
|
+
### Local Mode (`--local`)
|
|
82
|
+
|
|
83
|
+
The `--local` flag runs LLM integration on your machine via Claude Code instead of the engine API:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
iriai integrate auth-react --local
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
This mode:
|
|
90
|
+
1. Fetches module definitions from the integration engine API
|
|
91
|
+
2. Analyzes the project locally (same logic as the engine)
|
|
92
|
+
3. Builds a prompt identical to `LLMIntegrator._build_prompt()`
|
|
93
|
+
4. Invokes `claude -p` subprocess with a 5-minute timeout
|
|
94
|
+
5. Parses the structured JSON response
|
|
95
|
+
6. Applies file operations through interactive prompts
|
|
96
|
+
|
|
97
|
+
**Requirements:** Claude Code CLI (`claude`) must be installed and on your PATH.
|
|
98
|
+
|
|
99
|
+
**Note:** Profile matching is skipped in local mode (requires database). Most integrations work without profile-specific config.
|
|
100
|
+
|
|
101
|
+
For development, set `IRIAI_MODULES_DIR` to load module definitions from local YAML files instead of the API.
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
MIT
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "iriai-cli"
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "CLI tool for integrating Iriai platform modules into local projects"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "Iriai Platform Team"}
|
|
14
|
+
]
|
|
15
|
+
keywords = ["iriai", "cli", "integration", "modules"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
dependencies = [
|
|
25
|
+
"click>=8.1.0",
|
|
26
|
+
"httpx>=0.27.0",
|
|
27
|
+
"pyyaml>=6.0",
|
|
28
|
+
"rich>=13.7.0",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://github.com/thedanielzhang/iriai-cli"
|
|
33
|
+
Repository = "https://github.com/thedanielzhang/iriai-cli.git"
|
|
34
|
+
Issues = "https://github.com/thedanielzhang/iriai-cli/issues"
|
|
35
|
+
|
|
36
|
+
[project.optional-dependencies]
|
|
37
|
+
dev = [
|
|
38
|
+
"pytest>=8.0.0",
|
|
39
|
+
"pytest-asyncio>=0.23.0",
|
|
40
|
+
"black>=24.0.0",
|
|
41
|
+
"ruff>=0.1.0",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[project.scripts]
|
|
45
|
+
iriai = "iriai_cli.cli:main"
|
|
46
|
+
|
|
47
|
+
[tool.setuptools.packages.find]
|
|
48
|
+
where = ["src"]
|
|
49
|
+
|
|
50
|
+
[tool.black]
|
|
51
|
+
line-length = 100
|
|
52
|
+
target-version = ["py311"]
|
|
53
|
+
|
|
54
|
+
[tool.ruff]
|
|
55
|
+
line-length = 100
|
|
56
|
+
target-version = "py311"
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"""HTTP client for integration engine API."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
import httpx
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
|
|
9
|
+
from .config import config
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
console = Console()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class APIError(Exception):
|
|
16
|
+
"""Base error for API communication."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, message: str, status_code: int | None = None):
|
|
19
|
+
self.status_code = status_code
|
|
20
|
+
super().__init__(message)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class APIClient:
|
|
24
|
+
"""Async HTTP client for the integration engine."""
|
|
25
|
+
|
|
26
|
+
def __init__(self, base_url: str | None = None, timeout: int = 30):
|
|
27
|
+
self.base_url = base_url or config.engine_url
|
|
28
|
+
self.timeout = timeout
|
|
29
|
+
|
|
30
|
+
async def get_modules(self) -> list[dict[str, Any]]:
|
|
31
|
+
"""Fetch available modules.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
List of module metadata dicts.
|
|
35
|
+
"""
|
|
36
|
+
async with httpx.AsyncClient(timeout=self.timeout) as client:
|
|
37
|
+
try:
|
|
38
|
+
response = await client.get(
|
|
39
|
+
f"{self.base_url}/api/modules",
|
|
40
|
+
headers=config.headers,
|
|
41
|
+
)
|
|
42
|
+
response.raise_for_status()
|
|
43
|
+
data = response.json()
|
|
44
|
+
return data.get("modules", [])
|
|
45
|
+
except httpx.HTTPStatusError as e:
|
|
46
|
+
raise APIError(
|
|
47
|
+
f"Failed to fetch modules: {e.response.status_code}",
|
|
48
|
+
status_code=e.response.status_code,
|
|
49
|
+
)
|
|
50
|
+
except httpx.RequestError as e:
|
|
51
|
+
raise APIError(f"Network error: {e}")
|
|
52
|
+
|
|
53
|
+
async def get_module_definition(self, name: str) -> dict[str, Any]:
|
|
54
|
+
"""Fetch a full module definition by name.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
name: Module name (e.g., "auth-react").
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
Full module definition dict including prompt_template, analyze config, etc.
|
|
61
|
+
"""
|
|
62
|
+
async with httpx.AsyncClient(timeout=self.timeout) as client:
|
|
63
|
+
try:
|
|
64
|
+
response = await client.get(
|
|
65
|
+
f"{self.base_url}/api/modules/{name}",
|
|
66
|
+
headers=config.headers,
|
|
67
|
+
)
|
|
68
|
+
response.raise_for_status()
|
|
69
|
+
return response.json()
|
|
70
|
+
except httpx.HTTPStatusError as e:
|
|
71
|
+
if e.response.status_code == 404:
|
|
72
|
+
raise APIError(f"Module '{name}' not found", status_code=404)
|
|
73
|
+
raise APIError(
|
|
74
|
+
f"Failed to fetch module '{name}': {e.response.status_code}",
|
|
75
|
+
status_code=e.response.status_code,
|
|
76
|
+
)
|
|
77
|
+
except httpx.RequestError as e:
|
|
78
|
+
raise APIError(f"Network error: {e}")
|
|
79
|
+
|
|
80
|
+
async def analyze(self, tarball_path: str, modules: list[str] | None = None) -> dict[str, Any]:
|
|
81
|
+
"""Analyze a project tarball via POST /api/analyze-local.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
tarball_path: Path to .tar.gz file.
|
|
85
|
+
modules: Optional list of module names to check.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
Analysis result dict.
|
|
89
|
+
"""
|
|
90
|
+
import json as _json
|
|
91
|
+
|
|
92
|
+
async with httpx.AsyncClient(timeout=60) as client:
|
|
93
|
+
try:
|
|
94
|
+
with open(tarball_path, "rb") as f:
|
|
95
|
+
files = {"tarball": ("project.tar.gz", f, "application/gzip")}
|
|
96
|
+
data = {}
|
|
97
|
+
if modules:
|
|
98
|
+
data["modules"] = _json.dumps(modules)
|
|
99
|
+
headers = {}
|
|
100
|
+
if config.api_token:
|
|
101
|
+
headers["Authorization"] = f"Bearer {config.api_token}"
|
|
102
|
+
response = await client.post(
|
|
103
|
+
f"{self.base_url}/api/analyze-local",
|
|
104
|
+
headers=headers,
|
|
105
|
+
files=files,
|
|
106
|
+
data=data,
|
|
107
|
+
)
|
|
108
|
+
response.raise_for_status()
|
|
109
|
+
return response.json()
|
|
110
|
+
except httpx.HTTPStatusError as e:
|
|
111
|
+
raise APIError(
|
|
112
|
+
f"Analysis failed: {e.response.status_code}",
|
|
113
|
+
status_code=e.response.status_code,
|
|
114
|
+
)
|
|
115
|
+
except httpx.RequestError as e:
|
|
116
|
+
raise APIError(f"Network error: {e}")
|
|
117
|
+
|
|
118
|
+
async def integrate_local(
|
|
119
|
+
self,
|
|
120
|
+
tarball_path: str,
|
|
121
|
+
modules: dict[str, str],
|
|
122
|
+
integration_depth: str = "full",
|
|
123
|
+
competing_solution_choices: dict[str, str] | None = None,
|
|
124
|
+
) -> dict[str, Any]:
|
|
125
|
+
"""Trigger local integration.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
tarball_path: Path to project tarball.
|
|
129
|
+
modules: Module name -> action mapping.
|
|
130
|
+
integration_depth: "core" or "full".
|
|
131
|
+
competing_solution_choices: Optional competing solution choices.
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
Integration result dict with file operations.
|
|
135
|
+
"""
|
|
136
|
+
import json
|
|
137
|
+
|
|
138
|
+
async with httpx.AsyncClient(timeout=120) as client:
|
|
139
|
+
try:
|
|
140
|
+
with open(tarball_path, "rb") as f:
|
|
141
|
+
files = {"tarball": ("project.tar.gz", f, "application/gzip")}
|
|
142
|
+
data = {
|
|
143
|
+
"modules": json.dumps(modules),
|
|
144
|
+
"integration_depth": integration_depth,
|
|
145
|
+
}
|
|
146
|
+
if competing_solution_choices:
|
|
147
|
+
data["competing_solution_choices"] = json.dumps(
|
|
148
|
+
competing_solution_choices
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
headers = {}
|
|
152
|
+
if config.api_token:
|
|
153
|
+
headers["Authorization"] = f"Bearer {config.api_token}"
|
|
154
|
+
|
|
155
|
+
response = await client.post(
|
|
156
|
+
f"{self.base_url}/api/integrate-local",
|
|
157
|
+
headers=headers,
|
|
158
|
+
files=files,
|
|
159
|
+
data=data,
|
|
160
|
+
)
|
|
161
|
+
response.raise_for_status()
|
|
162
|
+
return response.json()
|
|
163
|
+
except httpx.HTTPStatusError as e:
|
|
164
|
+
raise APIError(
|
|
165
|
+
f"Integration failed: {e.response.status_code}",
|
|
166
|
+
status_code=e.response.status_code,
|
|
167
|
+
)
|
|
168
|
+
except httpx.RequestError as e:
|
|
169
|
+
raise APIError(f"Network error: {e}")
|