stigmergy 1.0.68 ā 1.0.70
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.
- package/README.en.md +306 -300
- package/README.md +469 -301
- package/package.json +97 -81
- package/scripts/publish.js +268 -0
- package/scripts/simple-publish.js +59 -0
- package/src/index.js +12 -0
- package/test/enhanced-main-alignment.test.js +298 -0
- package/test/hook-system-integration-test.js +307 -0
- package/test/natural-language-skills-test.js +320 -0
- package/test/nl-integration-test.js +179 -0
- package/test/parameter-parsing-test.js +143 -0
- package/test/real-test.js +435 -0
- package/test/system-compatibility-test.js +447 -0
- package/test/tdd-fixes-test.js +211 -0
- package/test/third-party-skills-test.js +321 -0
- package/test/tool-selection-integration-test.js +157 -0
- package/test/unit/cli-scanner.test.js +291 -0
- package/test/unit/cross-cli-executor.test.js +399 -0
- package/src/adapters/claude/__init__.py +0 -13
- package/src/adapters/claude/claude_skills_integration.py +0 -609
- package/src/adapters/claude/hook_adapter.py +0 -663
- package/src/adapters/claude/install_claude_integration.py +0 -265
- package/src/adapters/claude/skills_hook_adapter.py +0 -841
- package/src/adapters/claude/standalone_claude_adapter.py +0 -384
- package/src/adapters/cline/__init__.py +0 -20
- package/src/adapters/cline/config.py +0 -108
- package/src/adapters/cline/install_cline_integration.py +0 -617
- package/src/adapters/cline/mcp_server.py +0 -713
- package/src/adapters/cline/standalone_cline_adapter.py +0 -459
- package/src/adapters/codebuddy/__init__.py +0 -13
- package/src/adapters/codebuddy/buddy_adapter.py +0 -1125
- package/src/adapters/codebuddy/install_codebuddy_integration.py +0 -279
- package/src/adapters/codebuddy/skills_hook_adapter.py +0 -672
- package/src/adapters/codebuddy/skills_integration.py +0 -395
- package/src/adapters/codebuddy/standalone_codebuddy_adapter.py +0 -403
- package/src/adapters/codex/__init__.py +0 -11
- package/src/adapters/codex/base.py +0 -46
- package/src/adapters/codex/install_codex_integration.py +0 -311
- package/src/adapters/codex/mcp_server.py +0 -493
- package/src/adapters/codex/natural_language_parser.py +0 -82
- package/src/adapters/codex/slash_command_adapter.py +0 -326
- package/src/adapters/codex/standalone_codex_adapter.py +0 -362
- package/src/adapters/copilot/__init__.py +0 -13
- package/src/adapters/copilot/install_copilot_integration.py +0 -564
- package/src/adapters/copilot/mcp_adapter.py +0 -772
- package/src/adapters/copilot/mcp_server.py +0 -168
- package/src/adapters/copilot/standalone_copilot_adapter.py +0 -114
- package/src/adapters/gemini/__init__.py +0 -13
- package/src/adapters/gemini/extension_adapter.py +0 -690
- package/src/adapters/gemini/install_gemini_integration.py +0 -257
- package/src/adapters/gemini/standalone_gemini_adapter.py +0 -366
- package/src/adapters/iflow/__init__.py +0 -7
- package/src/adapters/iflow/hook_adapter.py +0 -1038
- package/src/adapters/iflow/hook_installer.py +0 -536
- package/src/adapters/iflow/install_iflow_integration.py +0 -271
- package/src/adapters/iflow/official_hook_adapter.py +0 -1272
- package/src/adapters/iflow/standalone_iflow_adapter.py +0 -48
- package/src/adapters/iflow/workflow_adapter.py +0 -793
- package/src/adapters/qoder/hook_installer.py +0 -732
- package/src/adapters/qoder/install_qoder_integration.py +0 -265
- package/src/adapters/qoder/notification_hook_adapter.py +0 -863
- package/src/adapters/qoder/standalone_qoder_adapter.py +0 -48
- package/src/adapters/qwen/__init__.py +0 -17
- package/src/adapters/qwencode/__init__.py +0 -13
- package/src/adapters/qwencode/inheritance_adapter.py +0 -818
- package/src/adapters/qwencode/install_qwencode_integration.py +0 -276
- package/src/adapters/qwencode/standalone_qwencode_adapter.py +0 -399
- package/src/atomic_collaboration_handler.py +0 -461
- package/src/cli_collaboration_agent.py +0 -697
- package/src/collaboration/hooks.py +0 -315
- package/src/core/__init__.py +0 -21
- package/src/core/ai_environment_scanner.py +0 -331
- package/src/core/base_adapter.py +0 -220
- package/src/core/cli_hook_integration.py +0 -406
- package/src/core/cross_cli_executor.py +0 -713
- package/src/core/cross_cli_mapping.py +0 -1165
- package/src/core/cross_platform_encoding.py +0 -365
- package/src/core/cross_platform_safe_cli.py +0 -894
- package/src/core/direct_cli_executor.py +0 -805
- package/src/core/direct_cli_hook_system.py +0 -958
- package/src/core/enhanced_init_processor.py +0 -467
- package/src/core/graceful_cli_executor.py +0 -912
- package/src/core/md_enhancer.py +0 -342
- package/src/core/md_generator.py +0 -619
- package/src/core/models.py +0 -218
- package/src/core/parser.py +0 -108
- package/src/core/real_cli_hook_system.py +0 -852
- package/src/core/real_cross_cli_system.py +0 -925
- package/src/core/verified_cross_cli_system.py +0 -961
- package/src/deploy.js +0 -737
- package/src/enhanced-main.js +0 -626
- package/src/enhanced_deploy.js +0 -303
- package/src/enhanced_universal_cli_setup.py +0 -930
- package/src/kimi_wrapper.py +0 -104
- package/src/main.js +0 -1309
- package/src/shell_integration.py +0 -398
- package/src/simple-main.js +0 -315
- package/src/smart_router_creator.py +0 -323
- package/src/universal_cli_setup.py +0 -1289
- package/src/utils/__init__.py +0 -12
- package/src/utils/cli_detector.py +0 -445
- package/src/utils/file_utils.py +0 -246
|
@@ -1,617 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Cline CLI Integration Installation Script
|
|
3
|
-
|
|
4
|
-
This script handles the installation and configuration of Cline CLI
|
|
5
|
-
integration with the Stigmergy system, including MCP server setup
|
|
6
|
-
and cross-platform compatibility.
|
|
7
|
-
|
|
8
|
-
Features:
|
|
9
|
-
- Cross-platform installation (Windows, Linux, macOS)
|
|
10
|
-
- MCP server configuration
|
|
11
|
-
- Environment variable setup
|
|
12
|
-
- Dependency verification
|
|
13
|
-
- Safe encoding handling
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
import os
|
|
17
|
-
import sys
|
|
18
|
-
import json
|
|
19
|
-
import subprocess
|
|
20
|
-
import shutil
|
|
21
|
-
import logging
|
|
22
|
-
import datetime
|
|
23
|
-
from pathlib import Path
|
|
24
|
-
from typing import Dict, Any, Optional, List
|
|
25
|
-
|
|
26
|
-
# Configure logging
|
|
27
|
-
logging.basicConfig(
|
|
28
|
-
level=logging.INFO,
|
|
29
|
-
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
30
|
-
)
|
|
31
|
-
logger = logging.getLogger(__name__)
|
|
32
|
-
|
|
33
|
-
# Add project root to path
|
|
34
|
-
project_root = Path(__file__).parent.parent.parent.parent
|
|
35
|
-
sys.path.insert(0, str(project_root))
|
|
36
|
-
|
|
37
|
-
from src.utils.platform_utils import get_platform_info, is_windows, is_linux, is_macos
|
|
38
|
-
from src.utils.encoding_utils import safe_encode_command, safe_decode_output
|
|
39
|
-
from src.utils.file_utils import ensure_directory_exists, safe_write_json_file, safe_read_json_file
|
|
40
|
-
from src.adapters.cline.config import (
|
|
41
|
-
CLINE_CONFIG,
|
|
42
|
-
get_cline_config_path,
|
|
43
|
-
get_mcp_settings_path,
|
|
44
|
-
get_mcp_server_directory,
|
|
45
|
-
create_default_mcp_settings
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
class ClineInstaller:
|
|
50
|
-
"""Cline CLI installation and configuration manager"""
|
|
51
|
-
|
|
52
|
-
def __init__(self):
|
|
53
|
-
self.platform = get_platform_info()
|
|
54
|
-
self.node_version = None
|
|
55
|
-
self.npm_version = None
|
|
56
|
-
self.cline_installed = False
|
|
57
|
-
self.mcp_configured = False
|
|
58
|
-
|
|
59
|
-
def check_prerequisites(self) -> Dict[str, Any]:
|
|
60
|
-
"""Check system prerequisites for Cline installation"""
|
|
61
|
-
logger.info("Checking system prerequisites...")
|
|
62
|
-
|
|
63
|
-
results = {
|
|
64
|
-
"node_available": False,
|
|
65
|
-
"npm_available": False,
|
|
66
|
-
"node_version": None,
|
|
67
|
-
"npm_version": None,
|
|
68
|
-
"node_compatible": False,
|
|
69
|
-
"npm_compatible": False,
|
|
70
|
-
"all_met": False
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
# Check Node.js
|
|
74
|
-
try:
|
|
75
|
-
result = subprocess.run(
|
|
76
|
-
["node", "--version"],
|
|
77
|
-
capture_output=True,
|
|
78
|
-
text=True,
|
|
79
|
-
timeout=10
|
|
80
|
-
)
|
|
81
|
-
if result.returncode == 0:
|
|
82
|
-
node_version = result.stdout.strip()
|
|
83
|
-
results["node_available"] = True
|
|
84
|
-
results["node_version"] = node_version
|
|
85
|
-
|
|
86
|
-
# Check version compatibility (Node.js 18+)
|
|
87
|
-
version_parts = node_version.lstrip('v').split('.')
|
|
88
|
-
if len(version_parts) >= 1:
|
|
89
|
-
major_version = int(version_parts[0])
|
|
90
|
-
results["node_compatible"] = major_version >= 18
|
|
91
|
-
|
|
92
|
-
except (subprocess.TimeoutExpired, FileNotFoundError, Exception) as e:
|
|
93
|
-
logger.warning(f"Node.js check failed: {e}")
|
|
94
|
-
|
|
95
|
-
# Check npm
|
|
96
|
-
try:
|
|
97
|
-
result = subprocess.run(
|
|
98
|
-
["npm", "--version"],
|
|
99
|
-
capture_output=True,
|
|
100
|
-
text=True,
|
|
101
|
-
timeout=10
|
|
102
|
-
)
|
|
103
|
-
if result.returncode == 0:
|
|
104
|
-
npm_version = result.stdout.strip()
|
|
105
|
-
results["npm_available"] = True
|
|
106
|
-
results["npm_version"] = npm_version
|
|
107
|
-
|
|
108
|
-
# Check version compatibility (npm 7+)
|
|
109
|
-
version_parts = npm_version.split('.')
|
|
110
|
-
if len(version_parts) >= 1:
|
|
111
|
-
major_version = int(version_parts[0])
|
|
112
|
-
results["npm_compatible"] = major_version >= 7
|
|
113
|
-
|
|
114
|
-
except (subprocess.TimeoutExpired, FileNotFoundError, Exception) as e:
|
|
115
|
-
logger.warning(f"npm check failed: {e}")
|
|
116
|
-
|
|
117
|
-
# Overall compatibility
|
|
118
|
-
results["all_met"] = (
|
|
119
|
-
results["node_available"] and
|
|
120
|
-
results["npm_available"] and
|
|
121
|
-
results["node_compatible"] and
|
|
122
|
-
results["npm_compatible"]
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
return results
|
|
126
|
-
|
|
127
|
-
def install_cline(self, use_global: bool = True) -> bool:
|
|
128
|
-
"""Install Cline CLI package"""
|
|
129
|
-
logger.info("Installing Cline CLI...")
|
|
130
|
-
|
|
131
|
-
try:
|
|
132
|
-
if use_global:
|
|
133
|
-
# Global installation
|
|
134
|
-
cmd = ["npm", "install", "-g", CLINE_CONFIG["npm_package"]]
|
|
135
|
-
logger.info(f"Running: {' '.join(cmd)}")
|
|
136
|
-
|
|
137
|
-
result = subprocess.run(
|
|
138
|
-
cmd,
|
|
139
|
-
capture_output=True,
|
|
140
|
-
text=True,
|
|
141
|
-
timeout=300, # 5 minutes timeout
|
|
142
|
-
env=self._get_safe_environment()
|
|
143
|
-
)
|
|
144
|
-
else:
|
|
145
|
-
# Local installation (for development)
|
|
146
|
-
cmd = ["npm", "install", CLINE_CONFIG["npm_package"]]
|
|
147
|
-
logger.info(f"Running: {' '.join(cmd)}")
|
|
148
|
-
|
|
149
|
-
result = subprocess.run(
|
|
150
|
-
cmd,
|
|
151
|
-
capture_output=True,
|
|
152
|
-
text=True,
|
|
153
|
-
timeout=300,
|
|
154
|
-
env=self._get_safe_environment()
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
if result.returncode == 0:
|
|
158
|
-
logger.info("Cline CLI installed successfully")
|
|
159
|
-
self.cline_installed = True
|
|
160
|
-
return True
|
|
161
|
-
else:
|
|
162
|
-
logger.error(f"Cline installation failed: {result.stderr}")
|
|
163
|
-
return False
|
|
164
|
-
|
|
165
|
-
except subprocess.TimeoutExpired:
|
|
166
|
-
logger.error("Cline installation timed out")
|
|
167
|
-
return False
|
|
168
|
-
except Exception as e:
|
|
169
|
-
logger.error(f"Cline installation error: {e}")
|
|
170
|
-
return False
|
|
171
|
-
|
|
172
|
-
def verify_cline_installation(self) -> bool:
|
|
173
|
-
"""Verify that Cline CLI is properly installed"""
|
|
174
|
-
logger.info("Verifying Cline CLI installation...")
|
|
175
|
-
|
|
176
|
-
try:
|
|
177
|
-
result = subprocess.run(
|
|
178
|
-
["cline", "--version"],
|
|
179
|
-
capture_output=True,
|
|
180
|
-
text=True,
|
|
181
|
-
timeout=10
|
|
182
|
-
)
|
|
183
|
-
|
|
184
|
-
if result.returncode == 0:
|
|
185
|
-
version = result.stdout.strip()
|
|
186
|
-
logger.info(f"Cline CLI version: {version}")
|
|
187
|
-
return True
|
|
188
|
-
else:
|
|
189
|
-
# Try npx alternative
|
|
190
|
-
result = subprocess.run(
|
|
191
|
-
["npx", "-y", "cline", "--version"],
|
|
192
|
-
capture_output=True,
|
|
193
|
-
text=True,
|
|
194
|
-
timeout=30
|
|
195
|
-
)
|
|
196
|
-
|
|
197
|
-
if result.returncode == 0:
|
|
198
|
-
version = result.stdout.strip()
|
|
199
|
-
logger.info(f"Cline CLI version (via npx): {version}")
|
|
200
|
-
return True
|
|
201
|
-
else:
|
|
202
|
-
logger.error(f"Cline verification failed: {result.stderr}")
|
|
203
|
-
return False
|
|
204
|
-
|
|
205
|
-
except (subprocess.TimeoutExpired, FileNotFoundError, Exception) as e:
|
|
206
|
-
logger.error(f"Cline verification error: {e}")
|
|
207
|
-
return False
|
|
208
|
-
|
|
209
|
-
def setup_mcp_configuration(self) -> bool:
|
|
210
|
-
"""Setup MCP configuration for Cline integration"""
|
|
211
|
-
logger.info("Setting up MCP configuration...")
|
|
212
|
-
|
|
213
|
-
try:
|
|
214
|
-
# Create Cline configuration directory
|
|
215
|
-
config_path = get_cline_config_path()
|
|
216
|
-
ensure_directory_exists(config_path)
|
|
217
|
-
|
|
218
|
-
# Create MCP settings
|
|
219
|
-
mcp_settings = create_default_mcp_settings()
|
|
220
|
-
|
|
221
|
-
# Add Stigmergy-specific MCP server configuration
|
|
222
|
-
stigmergy_server_config = {
|
|
223
|
-
"command": "python",
|
|
224
|
-
"args": ["-m", "src.adapters.cline.mcp_server"],
|
|
225
|
-
"env": {
|
|
226
|
-
"STIGMERGY_PROJECT_ROOT": self.project_root,
|
|
227
|
-
"STIGMERGY_COLLABORATION_MODE": "enabled",
|
|
228
|
-
"PYTHONPATH": str(project_root)
|
|
229
|
-
},
|
|
230
|
-
"disabled": False,
|
|
231
|
-
"autoStart": True,
|
|
232
|
-
"timeout": CLINE_CONFIG["mcp_default_timeout"]
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
mcp_settings["mcpServers"]["stigmergy"] = stigmergy_server_config
|
|
236
|
-
|
|
237
|
-
# Write MCP settings
|
|
238
|
-
settings_path = get_mcp_settings_path()
|
|
239
|
-
safe_write_json_file(settings_path, mcp_settings)
|
|
240
|
-
|
|
241
|
-
# Create MCP server directory
|
|
242
|
-
mcp_server_dir = get_mcp_server_directory()
|
|
243
|
-
ensure_directory_exists(mcp_server_dir)
|
|
244
|
-
|
|
245
|
-
# Create server manifest
|
|
246
|
-
manifest = {
|
|
247
|
-
"name": "stigmergy-mcp-server",
|
|
248
|
-
"version": "1.0.0",
|
|
249
|
-
"description": "Stigmergy CLI Multi-Agents MCP Server",
|
|
250
|
-
"tools": [
|
|
251
|
-
{
|
|
252
|
-
"name": "search_files",
|
|
253
|
-
"description": "Search for files in the project"
|
|
254
|
-
},
|
|
255
|
-
{
|
|
256
|
-
"name": "read_project_file",
|
|
257
|
-
"description": "Read project file content"
|
|
258
|
-
},
|
|
259
|
-
{
|
|
260
|
-
"name": "get_project_structure",
|
|
261
|
-
"description": "Get project directory structure"
|
|
262
|
-
},
|
|
263
|
-
{
|
|
264
|
-
"name": "analyze_codebase",
|
|
265
|
-
"description": "Analyze codebase patterns"
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
"name": "collaborate_with_cli",
|
|
269
|
-
"description": "Collaborate with other CLI tools"
|
|
270
|
-
}
|
|
271
|
-
]
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
manifest_path = mcp_server_dir / "stigmergy-mcp-manifest.json"
|
|
275
|
-
safe_write_json_file(manifest_path, manifest)
|
|
276
|
-
|
|
277
|
-
self.mcp_configured = True
|
|
278
|
-
logger.info("MCP configuration completed successfully")
|
|
279
|
-
return True
|
|
280
|
-
|
|
281
|
-
except Exception as e:
|
|
282
|
-
logger.error(f"MCP configuration error: {e}")
|
|
283
|
-
return False
|
|
284
|
-
|
|
285
|
-
def create_cross_platform_scripts(self) -> bool:
|
|
286
|
-
"""Create cross-platform execution scripts"""
|
|
287
|
-
logger.info("Creating cross-platform execution scripts...")
|
|
288
|
-
|
|
289
|
-
try:
|
|
290
|
-
# Create scripts directory
|
|
291
|
-
scripts_dir = project_root / "scripts" / "cline"
|
|
292
|
-
ensure_directory_exists(scripts_dir)
|
|
293
|
-
|
|
294
|
-
# Windows batch script
|
|
295
|
-
if is_windows():
|
|
296
|
-
self._create_windows_scripts(scripts_dir)
|
|
297
|
-
|
|
298
|
-
# Unix shell scripts
|
|
299
|
-
if is_linux() or is_macos():
|
|
300
|
-
self._create_unix_scripts(scripts_dir)
|
|
301
|
-
|
|
302
|
-
# Cross-platform Python script
|
|
303
|
-
self._create_python_script(scripts_dir)
|
|
304
|
-
|
|
305
|
-
logger.info("Cross-platform scripts created successfully")
|
|
306
|
-
return True
|
|
307
|
-
|
|
308
|
-
except Exception as e:
|
|
309
|
-
logger.error(f"Script creation error: {e}")
|
|
310
|
-
return False
|
|
311
|
-
|
|
312
|
-
def _create_windows_scripts(self, scripts_dir: Path):
|
|
313
|
-
"""Create Windows batch scripts"""
|
|
314
|
-
# Main execution script
|
|
315
|
-
batch_content = f"""@echo off
|
|
316
|
-
REM Cline CLI Execution Script for Windows
|
|
317
|
-
REM Generated by Stigmergy Cline Integration
|
|
318
|
-
|
|
319
|
-
setlocal enabledelayedexpansion
|
|
320
|
-
|
|
321
|
-
REM Set up environment
|
|
322
|
-
set "STIGMERGY_PROJECT_ROOT={project_root}"
|
|
323
|
-
set "STIGMERGY_COLLABORATION_MODE=enabled"
|
|
324
|
-
set "PYTHONPATH={project_root}"
|
|
325
|
-
|
|
326
|
-
REM Check if cline is available
|
|
327
|
-
where cline >nul 2>nul
|
|
328
|
-
if %errorlevel% equ 0 (
|
|
329
|
-
REM Use direct cline command
|
|
330
|
-
cline %*
|
|
331
|
-
) else (
|
|
332
|
-
REM Fallback to npx
|
|
333
|
-
npx -y cline %*
|
|
334
|
-
)
|
|
335
|
-
|
|
336
|
-
endlocal
|
|
337
|
-
"""
|
|
338
|
-
|
|
339
|
-
batch_path = scripts_dir / "cline.bat"
|
|
340
|
-
with open(batch_path, 'w', encoding='utf-8') as f:
|
|
341
|
-
f.write(batch_content)
|
|
342
|
-
|
|
343
|
-
# MCP server startup script
|
|
344
|
-
mcp_batch_content = f"""@echo off
|
|
345
|
-
REM Stigmergy MCP Server Startup Script for Windows
|
|
346
|
-
|
|
347
|
-
setlocal enabledelayedexpansion
|
|
348
|
-
|
|
349
|
-
REM Set up environment
|
|
350
|
-
set "STIGMERGY_PROJECT_ROOT={project_root}"
|
|
351
|
-
set "STIGMERGY_COLLABORATION_MODE=enabled"
|
|
352
|
-
set "PYTHONPATH={project_root}"
|
|
353
|
-
|
|
354
|
-
REM Start MCP server
|
|
355
|
-
python -m src.adapters.cline.mcp_server
|
|
356
|
-
|
|
357
|
-
endlocal
|
|
358
|
-
"""
|
|
359
|
-
|
|
360
|
-
mcp_batch_path = scripts_dir / "cline-mcp-server.bat"
|
|
361
|
-
with open(mcp_batch_path, 'w', encoding='utf-8') as f:
|
|
362
|
-
f.write(mcp_batch_content)
|
|
363
|
-
|
|
364
|
-
def _create_unix_scripts(self, scripts_dir: Path):
|
|
365
|
-
"""Create Unix shell scripts"""
|
|
366
|
-
# Main execution script
|
|
367
|
-
shell_content = f"""#!/bin/bash
|
|
368
|
-
# Cline CLI Execution Script for Unix
|
|
369
|
-
# Generated by Stigmergy Cline Integration
|
|
370
|
-
|
|
371
|
-
# Set up environment
|
|
372
|
-
export STIGMERGY_PROJECT_ROOT="{project_root}"
|
|
373
|
-
export STIGMERGY_COLLABORATION_MODE="enabled"
|
|
374
|
-
export PYTHONPATH="{project_root}"
|
|
375
|
-
|
|
376
|
-
# Check if cline is available
|
|
377
|
-
if command -v cline >/dev/null 2>&1; then
|
|
378
|
-
# Use direct cline command
|
|
379
|
-
cline "$@"
|
|
380
|
-
else
|
|
381
|
-
# Fallback to npx
|
|
382
|
-
npx -y cline "$@"
|
|
383
|
-
fi
|
|
384
|
-
"""
|
|
385
|
-
|
|
386
|
-
shell_path = scripts_dir / "cline.sh"
|
|
387
|
-
with open(shell_path, 'w', encoding='utf-8') as f:
|
|
388
|
-
f.write(shell_content)
|
|
389
|
-
|
|
390
|
-
# Make executable
|
|
391
|
-
os.chmod(shell_path, 0o755)
|
|
392
|
-
|
|
393
|
-
# MCP server startup script
|
|
394
|
-
mcp_shell_content = f"""#!/bin/bash
|
|
395
|
-
# Stigmergy MCP Server Startup Script for Unix
|
|
396
|
-
|
|
397
|
-
# Set up environment
|
|
398
|
-
export STIGMERGY_PROJECT_ROOT="{project_root}"
|
|
399
|
-
export STIGMERGY_COLLABORATION_MODE="enabled"
|
|
400
|
-
export PYTHONPATH="{project_root}"
|
|
401
|
-
|
|
402
|
-
# Start MCP server
|
|
403
|
-
python -m src.adapters.cline.mcp_server
|
|
404
|
-
"""
|
|
405
|
-
|
|
406
|
-
mcp_shell_path = scripts_dir / "cline-mcp-server.sh"
|
|
407
|
-
with open(mcp_shell_path, 'w', encoding='utf-8') as f:
|
|
408
|
-
f.write(mcp_shell_content)
|
|
409
|
-
|
|
410
|
-
# Make executable
|
|
411
|
-
os.chmod(mcp_shell_path, 0o755)
|
|
412
|
-
|
|
413
|
-
def _create_python_script(self, scripts_dir: Path):
|
|
414
|
-
"""Create cross-platform Python script"""
|
|
415
|
-
python_content = f"""#!/usr/bin/env python3
|
|
416
|
-
\"\"\"
|
|
417
|
-
Cross-platform Cline CLI Execution Script
|
|
418
|
-
Generated by Stigmergy Cline Integration
|
|
419
|
-
\"\"\"
|
|
420
|
-
|
|
421
|
-
import os
|
|
422
|
-
import sys
|
|
423
|
-
import subprocess
|
|
424
|
-
import platform
|
|
425
|
-
from pathlib import Path
|
|
426
|
-
|
|
427
|
-
def main():
|
|
428
|
-
# Set up environment
|
|
429
|
-
project_root = Path(r"{project_root}")
|
|
430
|
-
os.environ["STIGMERGY_PROJECT_ROOT"] = str(project_root)
|
|
431
|
-
os.environ["STIGMERGY_COLLABORATION_MODE"] = "enabled"
|
|
432
|
-
os.environ["PYTHONPATH"] = str(project_root)
|
|
433
|
-
|
|
434
|
-
# Check if cline is available
|
|
435
|
-
try:
|
|
436
|
-
result = subprocess.run(
|
|
437
|
-
["cline", "--version"],
|
|
438
|
-
capture_output=True,
|
|
439
|
-
timeout=10
|
|
440
|
-
)
|
|
441
|
-
if result.returncode == 0:
|
|
442
|
-
# Use direct cline command
|
|
443
|
-
cmd = ["cline"] + sys.argv[1:]
|
|
444
|
-
else:
|
|
445
|
-
# Fallback to npx
|
|
446
|
-
cmd = ["npx", "-y", "cline"] + sys.argv[1:]
|
|
447
|
-
except (FileNotFoundError, subprocess.TimeoutExpired):
|
|
448
|
-
# Fallback to npx
|
|
449
|
-
cmd = ["npx", "-y", "cline"] + sys.argv[1:]
|
|
450
|
-
|
|
451
|
-
# Execute command
|
|
452
|
-
try:
|
|
453
|
-
result = subprocess.run(cmd, check=True)
|
|
454
|
-
return result.returncode
|
|
455
|
-
except subprocess.CalledProcessError as e:
|
|
456
|
-
print(f"Cline execution failed: {{e}}")
|
|
457
|
-
return e.returncode
|
|
458
|
-
except Exception as e:
|
|
459
|
-
print(f"Error executing Cline: {{e}}")
|
|
460
|
-
return 1
|
|
461
|
-
|
|
462
|
-
if __name__ == "__main__":
|
|
463
|
-
sys.exit(main())
|
|
464
|
-
"""
|
|
465
|
-
|
|
466
|
-
python_path = scripts_dir / "cline.py"
|
|
467
|
-
with open(python_path, 'w', encoding='utf-8') as f:
|
|
468
|
-
f.write(python_content)
|
|
469
|
-
|
|
470
|
-
# Make executable on Unix
|
|
471
|
-
if not is_windows():
|
|
472
|
-
os.chmod(python_path, 0o755)
|
|
473
|
-
|
|
474
|
-
def _get_safe_environment(self) -> Dict[str, str]:
|
|
475
|
-
"""Get safe environment variables for subprocess execution"""
|
|
476
|
-
env = os.environ.copy()
|
|
477
|
-
|
|
478
|
-
# Ensure Node.js and npm are in PATH
|
|
479
|
-
if is_windows():
|
|
480
|
-
# Common Node.js installation paths on Windows
|
|
481
|
-
node_paths = [
|
|
482
|
-
r"C:\Program Files\nodejs",
|
|
483
|
-
r"C:\Program Files (x86)\nodejs",
|
|
484
|
-
os.path.expanduser(r"~\AppData\Roaming\npm")
|
|
485
|
-
]
|
|
486
|
-
else:
|
|
487
|
-
# Common Node.js installation paths on Unix
|
|
488
|
-
node_paths = [
|
|
489
|
-
"/usr/local/bin",
|
|
490
|
-
"/usr/bin",
|
|
491
|
-
os.path.expanduser("~/.npm-global/bin"),
|
|
492
|
-
os.path.expanduser("~/.local/bin")
|
|
493
|
-
]
|
|
494
|
-
|
|
495
|
-
# Add to PATH if not already present
|
|
496
|
-
current_path = env.get("PATH", "")
|
|
497
|
-
for node_path in node_paths:
|
|
498
|
-
if os.path.exists(node_path) and node_path not in current_path:
|
|
499
|
-
env["PATH"] = f"{node_path}{os.pathsep}{current_path}"
|
|
500
|
-
|
|
501
|
-
# Set project-specific environment variables
|
|
502
|
-
env["STIGMERGY_PROJECT_ROOT"] = str(project_root)
|
|
503
|
-
env["STIGMERGY_COLLABORATION_MODE"] = "enabled"
|
|
504
|
-
env["PYTHONPATH"] = str(project_root)
|
|
505
|
-
|
|
506
|
-
return env
|
|
507
|
-
|
|
508
|
-
def create_integration_report(self) -> Dict[str, Any]:
|
|
509
|
-
"""Create installation integration report"""
|
|
510
|
-
return {
|
|
511
|
-
"installation_date": str(datetime.datetime.now()),
|
|
512
|
-
"platform": self.platform,
|
|
513
|
-
"cline_installed": self.cline_installed,
|
|
514
|
-
"mcp_configured": self.mcp_configured,
|
|
515
|
-
"node_version": self.node_version,
|
|
516
|
-
"npm_version": self.npm_version,
|
|
517
|
-
"config_paths": {
|
|
518
|
-
"cline_config": str(get_cline_config_path()),
|
|
519
|
-
"mcp_settings": str(get_mcp_settings_path()),
|
|
520
|
-
"mcp_server_dir": str(get_mcp_server_directory())
|
|
521
|
-
},
|
|
522
|
-
"status": "success" if (self.cline_installed and self.mcp_configured) else "partial"
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
def run_full_installation(self) -> bool:
|
|
526
|
-
"""Run the complete installation process"""
|
|
527
|
-
logger.info("Starting Cline CLI integration installation...")
|
|
528
|
-
|
|
529
|
-
# Check prerequisites
|
|
530
|
-
prereqs = self.check_prerequisites()
|
|
531
|
-
if not prereqs["all_met"]:
|
|
532
|
-
logger.error("Prerequisites not met:")
|
|
533
|
-
if not prereqs["node_available"]:
|
|
534
|
-
logger.error("- Node.js not found")
|
|
535
|
-
if not prereqs["npm_available"]:
|
|
536
|
-
logger.error("- npm not found")
|
|
537
|
-
if not prereqs["node_compatible"]:
|
|
538
|
-
logger.error(f"- Node.js version incompatible (need 18+, got {prereqs['node_version']})")
|
|
539
|
-
if not prereqs["npm_compatible"]:
|
|
540
|
-
logger.error(f"- npm version incompatible (need 7+, got {prereqs['npm_version']})")
|
|
541
|
-
return False
|
|
542
|
-
|
|
543
|
-
self.node_version = prereqs["node_version"]
|
|
544
|
-
self.npm_version = prereqs["npm_version"]
|
|
545
|
-
|
|
546
|
-
# Install Cline CLI
|
|
547
|
-
if not self.install_cline():
|
|
548
|
-
logger.error("Cline CLI installation failed")
|
|
549
|
-
return False
|
|
550
|
-
|
|
551
|
-
# Verify installation
|
|
552
|
-
if not self.verify_cline_installation():
|
|
553
|
-
logger.error("Cline CLI verification failed")
|
|
554
|
-
return False
|
|
555
|
-
|
|
556
|
-
# Setup MCP configuration
|
|
557
|
-
if not self.setup_mcp_configuration():
|
|
558
|
-
logger.error("MCP configuration failed")
|
|
559
|
-
return False
|
|
560
|
-
|
|
561
|
-
# Create cross-platform scripts
|
|
562
|
-
if not self.create_cross_platform_scripts():
|
|
563
|
-
logger.error("Cross-platform script creation failed")
|
|
564
|
-
return False
|
|
565
|
-
|
|
566
|
-
logger.info("Cline CLI integration installation completed successfully!")
|
|
567
|
-
return True
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
def main():
|
|
571
|
-
"""Main installation function"""
|
|
572
|
-
installer = ClineInstaller()
|
|
573
|
-
|
|
574
|
-
try:
|
|
575
|
-
success = installer.run_full_installation()
|
|
576
|
-
|
|
577
|
-
if success:
|
|
578
|
-
# Create integration report
|
|
579
|
-
report = installer.create_integration_report()
|
|
580
|
-
report_path = project_root / "cline_integration_report.json"
|
|
581
|
-
|
|
582
|
-
with open(report_path, 'w', encoding='utf-8') as f:
|
|
583
|
-
json.dump(report, f, indent=2, ensure_ascii=False)
|
|
584
|
-
|
|
585
|
-
logger.info(f"Integration report saved to: {report_path}")
|
|
586
|
-
logger.info("ā
Cline CLI integration installation completed successfully!")
|
|
587
|
-
|
|
588
|
-
# Print usage instructions
|
|
589
|
-
print("\n" + "="*60)
|
|
590
|
-
print("Cline CLI Integration - Usage Instructions")
|
|
591
|
-
print("="*60)
|
|
592
|
-
print(f"š Configuration directory: {get_cline_config_path()}")
|
|
593
|
-
print(f"āļø MCP settings: {get_mcp_settings_path()}")
|
|
594
|
-
print(f"š„ļø MCP server directory: {get_mcp_server_directory()}")
|
|
595
|
-
print("\nš Quick start:")
|
|
596
|
-
print(" cline task 'Analyze this codebase'")
|
|
597
|
-
print(" cline task 'Create a tool that searches for TODO comments'")
|
|
598
|
-
print("\nš Cross-CLI collaboration:")
|
|
599
|
-
print(" use cline to analyze the project structure")
|
|
600
|
-
print(" call cline to create a new tool")
|
|
601
|
-
print("\nš For more information, see: cline.md")
|
|
602
|
-
|
|
603
|
-
return 0
|
|
604
|
-
else:
|
|
605
|
-
logger.error("ā Installation failed. Check the logs above for details.")
|
|
606
|
-
return 1
|
|
607
|
-
|
|
608
|
-
except KeyboardInterrupt:
|
|
609
|
-
logger.info("Installation interrupted by user")
|
|
610
|
-
return 1
|
|
611
|
-
except Exception as e:
|
|
612
|
-
logger.error(f"Unexpected error during installation: {e}")
|
|
613
|
-
return 1
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
if __name__ == "__main__":
|
|
617
|
-
sys.exit(main())
|