multi-lang-build 0.2.5__py3-none-any.whl → 0.3.0__py3-none-any.whl
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.
- multi_lang_build/__init__.py +4 -4
- multi_lang_build/cli.py +5 -2
- multi_lang_build/compiler/__init__.py +1 -1
- multi_lang_build/compiler/go_compiler.py +403 -0
- multi_lang_build/compiler/go_support/__init__.py +19 -0
- multi_lang_build/compiler/go_support/binary.py +119 -0
- multi_lang_build/compiler/go_support/builder.py +228 -0
- multi_lang_build/compiler/go_support/cleaner.py +40 -0
- multi_lang_build/compiler/go_support/env.py +41 -0
- multi_lang_build/compiler/go_support/mirror.py +111 -0
- multi_lang_build/compiler/go_support/module.py +80 -0
- multi_lang_build/compiler/go_support/tester.py +200 -0
- multi_lang_build/compiler/pnpm.py +61 -209
- multi_lang_build/compiler/pnpm_support/__init__.py +6 -0
- multi_lang_build/compiler/pnpm_support/executor.py +148 -0
- multi_lang_build/compiler/pnpm_support/project.py +53 -0
- multi_lang_build/compiler/python.py +65 -222
- multi_lang_build/compiler/python_support/__init__.py +13 -0
- multi_lang_build/compiler/python_support/cleaner.py +56 -0
- multi_lang_build/compiler/python_support/cli.py +46 -0
- multi_lang_build/compiler/python_support/detector.py +64 -0
- multi_lang_build/compiler/python_support/installer.py +162 -0
- multi_lang_build/compiler/python_support/venv.py +63 -0
- multi_lang_build/ide_register.py +97 -0
- multi_lang_build/mirror/config.py +19 -0
- multi_lang_build/register/support/__init__.py +13 -0
- multi_lang_build/register/support/claude.py +94 -0
- multi_lang_build/register/support/codebuddy.py +100 -0
- multi_lang_build/register/support/opencode.py +62 -0
- multi_lang_build/register/support/trae.py +72 -0
- {multi_lang_build-0.2.5.dist-info → multi_lang_build-0.3.0.dist-info}/METADATA +41 -5
- multi_lang_build-0.3.0.dist-info/RECORD +40 -0
- multi_lang_build/compiler/go.py +0 -468
- multi_lang_build/register.py +0 -412
- multi_lang_build-0.2.5.dist-info/RECORD +0 -18
- {multi_lang_build-0.2.5.dist-info → multi_lang_build-0.3.0.dist-info}/WHEEL +0 -0
- {multi_lang_build-0.2.5.dist-info → multi_lang_build-0.3.0.dist-info}/entry_points.txt +0 -0
- {multi_lang_build-0.2.5.dist-info → multi_lang_build-0.3.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""Python dependency installation."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import subprocess
|
|
5
|
+
import sys
|
|
6
|
+
import time
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from multi_lang_build.compiler.base import BuildResult
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class DependencyInstaller:
|
|
13
|
+
"""Install Python dependencies for various build systems."""
|
|
14
|
+
|
|
15
|
+
@staticmethod
|
|
16
|
+
def install_poetry(
|
|
17
|
+
python_executable: str,
|
|
18
|
+
source_dir: Path,
|
|
19
|
+
environment: dict[str, str],
|
|
20
|
+
dev: bool = False,
|
|
21
|
+
stream_output: bool = True,
|
|
22
|
+
) -> BuildResult:
|
|
23
|
+
"""Install dependencies using Poetry."""
|
|
24
|
+
cmd = [python_executable, "-m", "poetry", "install"]
|
|
25
|
+
if dev:
|
|
26
|
+
cmd.append("--with=dev")
|
|
27
|
+
|
|
28
|
+
return DependencyInstaller._run_pip(
|
|
29
|
+
cmd, source_dir, source_dir, environment, stream_output
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
@staticmethod
|
|
33
|
+
def install_pip(
|
|
34
|
+
python_executable: str,
|
|
35
|
+
source_dir: Path,
|
|
36
|
+
environment: dict[str, str],
|
|
37
|
+
dev: bool = False,
|
|
38
|
+
stream_output: bool = True,
|
|
39
|
+
) -> BuildResult:
|
|
40
|
+
"""Install dependencies using pip."""
|
|
41
|
+
cmd = [python_executable, "-m", "pip", "install", "-r", str(source_dir / "requirements.txt")]
|
|
42
|
+
|
|
43
|
+
if dev:
|
|
44
|
+
cmd.append("-r")
|
|
45
|
+
cmd.append(str(source_dir / "requirements-dev.txt"))
|
|
46
|
+
|
|
47
|
+
return DependencyInstaller._run_pip(
|
|
48
|
+
cmd, source_dir, source_dir, environment, stream_output
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def _run_pip(
|
|
53
|
+
command: list[str],
|
|
54
|
+
source_dir: Path,
|
|
55
|
+
output_dir: Path,
|
|
56
|
+
environment: dict[str, str],
|
|
57
|
+
stream_output: bool,
|
|
58
|
+
) -> BuildResult:
|
|
59
|
+
"""Execute pip command."""
|
|
60
|
+
import time
|
|
61
|
+
|
|
62
|
+
start_time = time.perf_counter()
|
|
63
|
+
|
|
64
|
+
try:
|
|
65
|
+
if stream_output:
|
|
66
|
+
return DependencyInstaller._stream_pip(
|
|
67
|
+
command, source_dir, environment, start_time
|
|
68
|
+
)
|
|
69
|
+
else:
|
|
70
|
+
return DependencyInstaller._capture_pip(
|
|
71
|
+
command, source_dir, environment, start_time
|
|
72
|
+
)
|
|
73
|
+
except Exception as e:
|
|
74
|
+
duration = time.perf_counter() - start_time
|
|
75
|
+
return BuildResult(
|
|
76
|
+
success=False,
|
|
77
|
+
return_code=-2,
|
|
78
|
+
stdout="",
|
|
79
|
+
stderr=f"Install error: {str(e)}",
|
|
80
|
+
output_path=None,
|
|
81
|
+
duration_seconds=duration,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
@staticmethod
|
|
85
|
+
def _stream_pip(
|
|
86
|
+
command: list[str],
|
|
87
|
+
source_dir: Path,
|
|
88
|
+
environment: dict[str, str],
|
|
89
|
+
start_time: float,
|
|
90
|
+
) -> BuildResult:
|
|
91
|
+
"""Execute pip with streaming output."""
|
|
92
|
+
import os
|
|
93
|
+
import subprocess as sp
|
|
94
|
+
import sys
|
|
95
|
+
|
|
96
|
+
stdout_buffer = []
|
|
97
|
+
stderr_buffer = []
|
|
98
|
+
|
|
99
|
+
process = sp.Popen(
|
|
100
|
+
command,
|
|
101
|
+
cwd=source_dir,
|
|
102
|
+
stdout=sp.PIPE,
|
|
103
|
+
stderr=sp.PIPE,
|
|
104
|
+
text=True,
|
|
105
|
+
env={**os.environ, **environment},
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# Read stdout
|
|
109
|
+
if process.stdout:
|
|
110
|
+
for line in process.stdout:
|
|
111
|
+
line = line.rstrip('\n\r')
|
|
112
|
+
stdout_buffer.append(line)
|
|
113
|
+
print(line)
|
|
114
|
+
sys.stdout.flush()
|
|
115
|
+
|
|
116
|
+
# Read stderr
|
|
117
|
+
if process.stderr:
|
|
118
|
+
for line in process.stderr:
|
|
119
|
+
line = line.rstrip('\n\r')
|
|
120
|
+
stderr_buffer.append(line)
|
|
121
|
+
print(line, file=sys.stderr)
|
|
122
|
+
sys.stderr.flush()
|
|
123
|
+
|
|
124
|
+
return_code = process.wait()
|
|
125
|
+
duration = time.perf_counter() - start_time
|
|
126
|
+
|
|
127
|
+
return BuildResult(
|
|
128
|
+
success=return_code == 0,
|
|
129
|
+
return_code=return_code,
|
|
130
|
+
stdout='\n'.join(stdout_buffer),
|
|
131
|
+
stderr='\n'.join(stderr_buffer),
|
|
132
|
+
output_path=source_dir,
|
|
133
|
+
duration_seconds=duration,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
@staticmethod
|
|
137
|
+
def _capture_pip(
|
|
138
|
+
command: list[str],
|
|
139
|
+
source_dir: Path,
|
|
140
|
+
environment: dict[str, str],
|
|
141
|
+
start_time: float,
|
|
142
|
+
) -> BuildResult:
|
|
143
|
+
"""Execute pip with captured output."""
|
|
144
|
+
result = subprocess.run(
|
|
145
|
+
command,
|
|
146
|
+
cwd=source_dir,
|
|
147
|
+
capture_output=True,
|
|
148
|
+
text=True,
|
|
149
|
+
timeout=3600,
|
|
150
|
+
env={**os.environ, **environment},
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
duration = time.perf_counter() - start_time
|
|
154
|
+
|
|
155
|
+
return BuildResult(
|
|
156
|
+
success=result.returncode == 0,
|
|
157
|
+
return_code=result.returncode,
|
|
158
|
+
stdout=result.stdout,
|
|
159
|
+
stderr=result.stderr,
|
|
160
|
+
output_path=source_dir,
|
|
161
|
+
duration_seconds=duration,
|
|
162
|
+
)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""Python virtual environment management."""
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
import venv
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from multi_lang_build.compiler.base import BuildResult
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class VenvManager:
|
|
11
|
+
"""Manage Python virtual environments."""
|
|
12
|
+
|
|
13
|
+
@staticmethod
|
|
14
|
+
def create(
|
|
15
|
+
directory: Path,
|
|
16
|
+
python_path: str | None = None,
|
|
17
|
+
mirror_enabled: bool = True,
|
|
18
|
+
) -> BuildResult:
|
|
19
|
+
"""Create a virtual environment.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
directory: Directory to create the venv in
|
|
23
|
+
python_path: Python interpreter to use
|
|
24
|
+
mirror_enabled: Whether to configure pip mirror
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
BuildResult containing success status and output information.
|
|
28
|
+
"""
|
|
29
|
+
start_time = time.perf_counter()
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
env_builder = venv.EnvBuilder(with_pip=True, clear=True)
|
|
33
|
+
env_builder.create(directory)
|
|
34
|
+
|
|
35
|
+
# Configure pip mirror if enabled
|
|
36
|
+
if mirror_enabled:
|
|
37
|
+
pip_config_dir = directory / "pip.conf"
|
|
38
|
+
pip_config_dir.write_text(
|
|
39
|
+
"[global]\n"
|
|
40
|
+
"index-url = https://pypi.tuna.tsinghua.edu.cn/simple\n"
|
|
41
|
+
"trusted-host = pypi.tuna.tsinghua.edu.cn\n"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
duration = time.perf_counter() - start_time
|
|
45
|
+
|
|
46
|
+
return BuildResult(
|
|
47
|
+
success=True,
|
|
48
|
+
return_code=0,
|
|
49
|
+
stdout=f"Virtual environment created at {directory}",
|
|
50
|
+
stderr="",
|
|
51
|
+
output_path=directory,
|
|
52
|
+
duration_seconds=duration,
|
|
53
|
+
)
|
|
54
|
+
except Exception as e:
|
|
55
|
+
duration = time.perf_counter() - start_time
|
|
56
|
+
return BuildResult(
|
|
57
|
+
success=False,
|
|
58
|
+
return_code=-1,
|
|
59
|
+
stdout="",
|
|
60
|
+
stderr=f"Failed to create virtual environment: {str(e)}",
|
|
61
|
+
output_path=None,
|
|
62
|
+
duration_seconds=duration,
|
|
63
|
+
)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Register multi-lang-build as a skill for various IDEs."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
from typing import Literal
|
|
8
|
+
|
|
9
|
+
from multi_lang_build.register.support import (
|
|
10
|
+
register_claude_code,
|
|
11
|
+
register_opencode,
|
|
12
|
+
register_trae,
|
|
13
|
+
register_codebuddy,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def get_cli_path() -> str:
|
|
18
|
+
"""Get the path to the multi-lang-build CLI."""
|
|
19
|
+
result = subprocess.run(
|
|
20
|
+
["which", "multi-lang-build"],
|
|
21
|
+
capture_output=True,
|
|
22
|
+
text=True,
|
|
23
|
+
)
|
|
24
|
+
if result.returncode == 0:
|
|
25
|
+
return result.stdout.strip()
|
|
26
|
+
return f"{sys.executable} -m multi_lang_build"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def register_skill(
|
|
30
|
+
ide: Literal["claude", "opencode", "trae", "codebuddy", "all"] = "claude",
|
|
31
|
+
global_level: bool = False
|
|
32
|
+
) -> bool:
|
|
33
|
+
"""Register multi-lang-build as a skill for the specified IDE.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
ide: The IDE to register with. Options: "claude", "opencode", "trae", "codebuddy", "all"
|
|
37
|
+
Default is "claude".
|
|
38
|
+
global_level: If True, register to global config. If False (default), register to project-level.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
True if registration succeeded, False otherwise.
|
|
42
|
+
"""
|
|
43
|
+
print(f"📝 Registering multi-lang-build for {ide}...\n")
|
|
44
|
+
|
|
45
|
+
if ide == "all":
|
|
46
|
+
results = [
|
|
47
|
+
("Claude Code", register_claude_code(project_level=not global_level)),
|
|
48
|
+
("OpenCode", register_opencode(project_level=not global_level)),
|
|
49
|
+
("Trae", register_trae(project_level=not global_level)),
|
|
50
|
+
("CodeBuddy", register_codebuddy(project_level=not global_level)),
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
print("\n" + "=" * 50)
|
|
54
|
+
print("Registration Summary:")
|
|
55
|
+
for name, success in results:
|
|
56
|
+
status = "✅" if success else "❌"
|
|
57
|
+
print(f" {status} {name}")
|
|
58
|
+
|
|
59
|
+
return all(success for _, success in results)
|
|
60
|
+
|
|
61
|
+
elif ide == "claude":
|
|
62
|
+
return register_claude_code(project_level=not global_level)
|
|
63
|
+
elif ide == "opencode":
|
|
64
|
+
return register_opencode(project_level=not global_level)
|
|
65
|
+
elif ide == "trae":
|
|
66
|
+
return register_trae(project_level=not global_level)
|
|
67
|
+
elif ide == "codebuddy":
|
|
68
|
+
return register_codebuddy(project_level=not global_level)
|
|
69
|
+
else:
|
|
70
|
+
print(f"❌ Unknown IDE: {ide}")
|
|
71
|
+
print("Supported IDEs: claude, opencode, trae, codebuddy, all")
|
|
72
|
+
return False
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
if __name__ == "__main__":
|
|
76
|
+
import argparse
|
|
77
|
+
|
|
78
|
+
parser = argparse.ArgumentParser(
|
|
79
|
+
description="Register multi-lang-build as an IDE skill"
|
|
80
|
+
)
|
|
81
|
+
parser.add_argument(
|
|
82
|
+
"ide",
|
|
83
|
+
nargs="?",
|
|
84
|
+
default="claude",
|
|
85
|
+
choices=["claude", "opencode", "trae", "codebuddy", "all"],
|
|
86
|
+
help="IDE to register with (default: claude)",
|
|
87
|
+
)
|
|
88
|
+
parser.add_argument(
|
|
89
|
+
"--global",
|
|
90
|
+
dest="global_level",
|
|
91
|
+
action="store_true",
|
|
92
|
+
help="Register to global config instead of project-level",
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
args = parser.parse_args()
|
|
96
|
+
success = register_skill(args.ide, global_level=args.global_level)
|
|
97
|
+
sys.exit(0 if success else 1)
|
|
@@ -249,3 +249,22 @@ def validate_mirror_config(mirror_config: MirrorConfig) -> bool:
|
|
|
249
249
|
return False
|
|
250
250
|
|
|
251
251
|
return True
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
# Go mirrors in failover order (goproxy.io → goproxy.cn → goproxy.vip.cn)
|
|
255
|
+
GO_MIRROR_FALLBACK_ORDER = ["go_qiniu", "go", "go_vip"]
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def get_go_mirror_with_fallback(failover: bool = True) -> list[str]:
|
|
259
|
+
"""Get Go mirror list for failover.
|
|
260
|
+
|
|
261
|
+
Args:
|
|
262
|
+
failover: If True, return all mirrors in fallback order.
|
|
263
|
+
If False, return only the default mirror.
|
|
264
|
+
|
|
265
|
+
Returns:
|
|
266
|
+
List of mirror keys to try.
|
|
267
|
+
"""
|
|
268
|
+
if failover:
|
|
269
|
+
return GO_MIRROR_FALLBACK_ORDER
|
|
270
|
+
return ["go"]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""IDE registration support modules."""
|
|
2
|
+
|
|
3
|
+
from multi_lang_build.register.support.claude import register_claude_code
|
|
4
|
+
from multi_lang_build.register.support.opencode import register_opencode
|
|
5
|
+
from multi_lang_build.register.support.trae import register_trae
|
|
6
|
+
from multi_lang_build.register.support.codebuddy import register_codebuddy
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"register_claude_code",
|
|
10
|
+
"register_opencode",
|
|
11
|
+
"register_trae",
|
|
12
|
+
"register_codebuddy",
|
|
13
|
+
]
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"""Register with Claude Code."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import subprocess
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def register_claude_code(project_level: bool = True) -> bool:
|
|
8
|
+
"""Register as Claude Code skill.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
project_level: If True (default), register to project-level .claude/multi-lang-build.md.
|
|
12
|
+
If False, register to global ~/.claude/CLAUDE.md.
|
|
13
|
+
"""
|
|
14
|
+
try:
|
|
15
|
+
# Determine registration path
|
|
16
|
+
if project_level:
|
|
17
|
+
# Project-level: .claude/multi-lang-build.md in current directory
|
|
18
|
+
config_dir = Path.cwd() / ".claude"
|
|
19
|
+
config_dir.mkdir(exist_ok=True)
|
|
20
|
+
skill_file = config_dir / "multi-lang-build.md"
|
|
21
|
+
level_name = "project-level"
|
|
22
|
+
else:
|
|
23
|
+
# Global-level: ~/.claude/CLAUDE.md (only check CLI for global)
|
|
24
|
+
result = subprocess.run(
|
|
25
|
+
["which", "claude"],
|
|
26
|
+
capture_output=True,
|
|
27
|
+
text=True,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
if result.returncode != 0:
|
|
31
|
+
print("❌ Claude Code CLI not found. Please install it first:")
|
|
32
|
+
print(" npm install -g @anthropic-ai/claude-code")
|
|
33
|
+
return False
|
|
34
|
+
|
|
35
|
+
claude_dir = Path.home() / ".claude"
|
|
36
|
+
claude_dir.mkdir(exist_ok=True)
|
|
37
|
+
skill_file = claude_dir / "CLAUDE.md"
|
|
38
|
+
level_name = "global"
|
|
39
|
+
|
|
40
|
+
skill_content = """## Multi-Lang Build Tool
|
|
41
|
+
|
|
42
|
+
You can use the `multi-lang-build` tool to compile projects:
|
|
43
|
+
|
|
44
|
+
### Available Commands:
|
|
45
|
+
- `multi-lang-build pnpm <source> --output <dir>` - Build pnpm projects
|
|
46
|
+
- `multi-lang-build go <source> --output <bin>` - Build Go projects
|
|
47
|
+
- `multi-lang-build python <source> --output <dir>` - Build Python projects
|
|
48
|
+
- `multi-lang-build mirror list|set|show` - Configure domestic mirrors
|
|
49
|
+
|
|
50
|
+
### Examples:
|
|
51
|
+
```bash
|
|
52
|
+
# Build Go project
|
|
53
|
+
multi-lang-build go ./src --output ./bin/app --mirror
|
|
54
|
+
|
|
55
|
+
# Build with specific target (multi-entry support)
|
|
56
|
+
multi-lang-build go ./src --output ./bin/server --target cmd/server/main.go
|
|
57
|
+
|
|
58
|
+
# Build Python project
|
|
59
|
+
multi-lang-build python ./src --output ./dist --mirror
|
|
60
|
+
|
|
61
|
+
# Build pnpm project
|
|
62
|
+
multi-lang-build pnpm ./src --output ./dist --mirror
|
|
63
|
+
|
|
64
|
+
# Configure mirror
|
|
65
|
+
multi-lang-build mirror set pip pip_aliyun
|
|
66
|
+
multi-lang-build mirror set go
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
When working with Go projects, check if there are multiple main packages and use the `--target` flag to specify which one to build.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
if project_level:
|
|
73
|
+
# Project-level: create dedicated file
|
|
74
|
+
with open(skill_file, "w") as f:
|
|
75
|
+
f.write(skill_content)
|
|
76
|
+
print(f"✅ Registered with Claude Code ({level_name}, created {skill_file})")
|
|
77
|
+
else:
|
|
78
|
+
# Global-level: append to existing CLAUDE.md if not already present
|
|
79
|
+
existing_content = ""
|
|
80
|
+
if skill_file.exists():
|
|
81
|
+
existing_content = skill_file.read_text()
|
|
82
|
+
|
|
83
|
+
if "## Multi-Lang Build Tool" not in existing_content:
|
|
84
|
+
with open(skill_file, "a") as f:
|
|
85
|
+
f.write(skill_content)
|
|
86
|
+
print(f"✅ Registered with Claude Code ({level_name}, added to {skill_file})")
|
|
87
|
+
else:
|
|
88
|
+
print(f"ℹ️ Already registered with Claude Code ({level_name}, {skill_file})")
|
|
89
|
+
|
|
90
|
+
return True
|
|
91
|
+
|
|
92
|
+
except Exception as e:
|
|
93
|
+
print(f"❌ Failed to register with Claude Code: {e}")
|
|
94
|
+
return False
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"""Register with CodeBuddy."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def register_codebuddy(project_level: bool = True) -> bool:
|
|
7
|
+
"""Register as CodeBuddy skill.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
project_level: If True (default), register to project-level .codebuddy/skills.yaml.
|
|
11
|
+
If False, register to global ~/.codebuddy/skills.yaml.
|
|
12
|
+
"""
|
|
13
|
+
try:
|
|
14
|
+
# Determine registration path
|
|
15
|
+
if project_level:
|
|
16
|
+
# Project-level: .codebuddy/skills.yaml in current directory
|
|
17
|
+
base_dir = Path.cwd()
|
|
18
|
+
config_dir = base_dir / ".codebuddy"
|
|
19
|
+
config_dir.mkdir(exist_ok=True)
|
|
20
|
+
skills_file = config_dir / "skills.yaml"
|
|
21
|
+
level_name = "project-level"
|
|
22
|
+
else:
|
|
23
|
+
# Global-level: ~/.codebuddy/skills.yaml
|
|
24
|
+
config_dir = Path.home() / ".codebuddy"
|
|
25
|
+
config_dir.mkdir(exist_ok=True)
|
|
26
|
+
skills_file = config_dir / "skills.yaml"
|
|
27
|
+
level_name = "global"
|
|
28
|
+
|
|
29
|
+
skill_config = """# Multi-Lang Build Skill
|
|
30
|
+
skills:
|
|
31
|
+
multi-lang-build:
|
|
32
|
+
name: "Multi-Lang Build"
|
|
33
|
+
description: "Multi-language automated build tool with mirror acceleration"
|
|
34
|
+
version: "0.2.0"
|
|
35
|
+
|
|
36
|
+
commands:
|
|
37
|
+
build-go:
|
|
38
|
+
description: "Build Go project"
|
|
39
|
+
command: "multi-lang-build go {source} --output {output}"
|
|
40
|
+
args:
|
|
41
|
+
- name: source
|
|
42
|
+
description: "Source directory"
|
|
43
|
+
required: true
|
|
44
|
+
- name: output
|
|
45
|
+
description: "Output path"
|
|
46
|
+
required: true
|
|
47
|
+
- name: target
|
|
48
|
+
description: "Build target (file or directory)"
|
|
49
|
+
required: false
|
|
50
|
+
- name: mirror
|
|
51
|
+
description: "Enable mirror acceleration"
|
|
52
|
+
type: flag
|
|
53
|
+
|
|
54
|
+
build-python:
|
|
55
|
+
description: "Build Python project"
|
|
56
|
+
command: "multi-lang-build python {source} --output {output}"
|
|
57
|
+
args:
|
|
58
|
+
- name: source
|
|
59
|
+
description: "Source directory"
|
|
60
|
+
required: true
|
|
61
|
+
- name: output
|
|
62
|
+
description: "Output directory"
|
|
63
|
+
required: true
|
|
64
|
+
- name: mirror
|
|
65
|
+
description: "Enable mirror acceleration"
|
|
66
|
+
type: flag
|
|
67
|
+
|
|
68
|
+
build-pnpm:
|
|
69
|
+
description: "Build pnpm project"
|
|
70
|
+
command: "multi-lang-build pnpm {source} --output {output}"
|
|
71
|
+
args:
|
|
72
|
+
- name: source
|
|
73
|
+
description: "Source directory"
|
|
74
|
+
required: true
|
|
75
|
+
- name: output
|
|
76
|
+
description: "Output directory"
|
|
77
|
+
required: true
|
|
78
|
+
- name: mirror
|
|
79
|
+
description: "Enable mirror acceleration"
|
|
80
|
+
type: flag
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
# Append or create
|
|
84
|
+
if skills_file.exists():
|
|
85
|
+
content = skills_file.read_text()
|
|
86
|
+
if "multi-lang-build" not in content:
|
|
87
|
+
with open(skills_file, "a") as f:
|
|
88
|
+
f.write("\n" + skill_config)
|
|
89
|
+
print(f"✅ Registered with CodeBuddy ({level_name}, updated {skills_file})")
|
|
90
|
+
else:
|
|
91
|
+
print(f"ℹ️ Already registered with CodeBuddy ({level_name}, {skills_file})")
|
|
92
|
+
else:
|
|
93
|
+
skills_file.write_text(skill_config)
|
|
94
|
+
print(f"✅ Registered with CodeBuddy ({level_name}, created {skills_file})")
|
|
95
|
+
|
|
96
|
+
return True
|
|
97
|
+
|
|
98
|
+
except Exception as e:
|
|
99
|
+
print(f"❌ Failed to register with CodeBuddy: {e}")
|
|
100
|
+
return False
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Register with OpenCode."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def register_opencode(project_level: bool = True) -> bool:
|
|
8
|
+
"""Register as OpenCode skill.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
project_level: If True (default), register to project-level .opencode/skills.json.
|
|
12
|
+
If False, register to global ~/.config/opencode/skills.json.
|
|
13
|
+
"""
|
|
14
|
+
try:
|
|
15
|
+
# Determine registration path
|
|
16
|
+
if project_level:
|
|
17
|
+
# Project-level: .opencode/skills.json in current directory
|
|
18
|
+
base_dir = Path.cwd()
|
|
19
|
+
config_dir = base_dir / ".opencode"
|
|
20
|
+
config_dir.mkdir(exist_ok=True)
|
|
21
|
+
skills_file = config_dir / "skills.json"
|
|
22
|
+
level_name = "project-level"
|
|
23
|
+
else:
|
|
24
|
+
# Global-level: ~/.config/opencode/skills.json
|
|
25
|
+
config_dir = Path.home() / ".config" / "opencode"
|
|
26
|
+
config_dir.mkdir(parents=True, exist_ok=True)
|
|
27
|
+
skills_file = config_dir / "skills.json"
|
|
28
|
+
level_name = "global"
|
|
29
|
+
|
|
30
|
+
# Create or update skills.json
|
|
31
|
+
skills: dict = {}
|
|
32
|
+
|
|
33
|
+
if skills_file.exists():
|
|
34
|
+
with open(skills_file) as f:
|
|
35
|
+
skills = json.load(f)
|
|
36
|
+
|
|
37
|
+
# Add multi-lang-build skill
|
|
38
|
+
skills["multi-lang-build"] = {
|
|
39
|
+
"name": "multi-lang-build",
|
|
40
|
+
"description": "Multi-language automated build tool with mirror acceleration",
|
|
41
|
+
"commands": {
|
|
42
|
+
"build-go": "multi-lang-build go <source> --output <output> [--mirror] [--target <target>]",
|
|
43
|
+
"build-python": "multi-lang-build python <source> --output <output> [--mirror]",
|
|
44
|
+
"build-pnpm": "multi-lang-build pnpm <source> --output <output> [--mirror]",
|
|
45
|
+
},
|
|
46
|
+
"examples": [
|
|
47
|
+
"multi-lang-build go ./src --output ./bin/app --mirror",
|
|
48
|
+
"multi-lang-build go ./src --output ./bin/server --target cmd/server/main.go",
|
|
49
|
+
"multi-lang-build python ./src --output ./dist --mirror",
|
|
50
|
+
"multi-lang-build pnpm ./src --output ./dist --mirror",
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
with open(skills_file, "w") as f:
|
|
55
|
+
json.dump(skills, f, indent=2)
|
|
56
|
+
|
|
57
|
+
print(f"✅ Registered with OpenCode ({level_name}, config: {skills_file})")
|
|
58
|
+
return True
|
|
59
|
+
|
|
60
|
+
except Exception as e:
|
|
61
|
+
print(f"❌ Failed to register with OpenCode: {e}")
|
|
62
|
+
return False
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""Register with Trae."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def register_trae(project_level: bool = True) -> bool:
|
|
8
|
+
"""Register as Trae skill.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
project_level: If True (default), register to project-level .trae/skills.json.
|
|
12
|
+
If False, register to global ~/.trae/skills.json.
|
|
13
|
+
"""
|
|
14
|
+
try:
|
|
15
|
+
# Determine registration path
|
|
16
|
+
if project_level:
|
|
17
|
+
# Project-level: .trae/skills.json in current directory
|
|
18
|
+
base_dir = Path.cwd()
|
|
19
|
+
config_dir = base_dir / ".trae"
|
|
20
|
+
config_dir.mkdir(exist_ok=True)
|
|
21
|
+
skills_file = config_dir / "skills.json"
|
|
22
|
+
level_name = "project-level"
|
|
23
|
+
else:
|
|
24
|
+
# Global-level: ~/.trae/skills.json
|
|
25
|
+
config_dir = Path.home() / ".trae"
|
|
26
|
+
config_dir.mkdir(exist_ok=True)
|
|
27
|
+
skills_file = config_dir / "skills.json"
|
|
28
|
+
level_name = "global"
|
|
29
|
+
|
|
30
|
+
# Create or update skills.json
|
|
31
|
+
skills: dict = {}
|
|
32
|
+
|
|
33
|
+
if skills_file.exists():
|
|
34
|
+
with open(skills_file) as f:
|
|
35
|
+
skills = json.load(f)
|
|
36
|
+
|
|
37
|
+
# Add multi-lang-build skill
|
|
38
|
+
skills["multi-lang-build"] = {
|
|
39
|
+
"name": "Multi-Lang Build",
|
|
40
|
+
"description": "Automated build tool for Go, Python, and pnpm projects",
|
|
41
|
+
"category": "build",
|
|
42
|
+
"commands": [
|
|
43
|
+
{
|
|
44
|
+
"name": "build-go",
|
|
45
|
+
"command": "multi-lang-build go {source} --output {output}",
|
|
46
|
+
"description": "Build Go project",
|
|
47
|
+
"args": ["source", "output", "target", "mirror"]
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"name": "build-python",
|
|
51
|
+
"command": "multi-lang-build python {source} --output {output}",
|
|
52
|
+
"description": "Build Python project",
|
|
53
|
+
"args": ["source", "output", "mirror"]
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "build-pnpm",
|
|
57
|
+
"command": "multi-lang-build pnpm {source} --output {output}",
|
|
58
|
+
"description": "Build pnpm project",
|
|
59
|
+
"args": ["source", "output", "mirror"]
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
with open(skills_file, "w") as f:
|
|
65
|
+
json.dump(skills, f, indent=2)
|
|
66
|
+
|
|
67
|
+
print(f"✅ Registered with Trae ({level_name}, config: {skills_file})")
|
|
68
|
+
return True
|
|
69
|
+
|
|
70
|
+
except Exception as e:
|
|
71
|
+
print(f"❌ Failed to register with Trae: {e}")
|
|
72
|
+
return False
|