Skip to content

Commit 5783110

Browse files
fix(build): Include amplifier-bundle/ in wheel package
The build_hooks.py was missing logic to copy amplifier-bundle/ into the package during wheel build. This caused 'amplihack amplifier' to fail with 'Warning: amplihack bundle not found' when installed via uvx/pip. Added: - bundle_src/bundle_dest paths to _CustomBuildBackend - _copy_bundle_directory() method - _cleanup_bundle_directory() method - Call to copy/cleanup in build_wheel() Verified: wheel now includes amplifier-bundle/ and bundle is found at runtime. 🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
1 parent d519972 commit 5783110

File tree

1 file changed

+45
-9
lines changed

1 file changed

+45
-9
lines changed

build_hooks.py

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
"""Build hooks for setuptools to include .claude/ directory in wheels.
1+
"""Build hooks for setuptools to include .claude/, .github/, and amplifier-bundle/ in wheels.
22
3-
This module provides custom build hooks that copy the .claude/ directory
4-
from the repository root into src/amplihack/.claude/ before building the wheel.
5-
This ensures the framework files are included in the wheel distribution for
6-
UVX deployment.
3+
This module provides custom build hooks that copy directories from the repository
4+
root into src/amplihack/ before building the wheel. This ensures the framework
5+
files are included in the wheel distribution for UVX deployment.
76
87
Why this is needed:
98
- MANIFEST.in only controls sdist, not wheels
109
- Wheels only include files inside Python packages
11-
- .claude/ is at repo root (outside src/amplihack/)
12-
- Solution: Copy .claude/ into package before build
10+
- .claude/, .github/, and amplifier-bundle/ are at repo root (outside src/amplihack/)
11+
- Solution: Copy them into package before build, cleanup after
1312
1413
Why symlinks=True is required:
1514
- Enables support for symlinks within .claude/ directory structure
@@ -29,14 +28,16 @@
2928

3029

3130
class _CustomBuildBackend:
32-
"""Custom build backend that copies .claude/ and .github/ before building."""
31+
"""Custom build backend that copies .claude/, .github/, and amplifier-bundle/ before building."""
3332

3433
def __init__(self):
3534
self.repo_root = Path(__file__).parent
3635
self.claude_src = self.repo_root / ".claude"
3736
self.claude_dest = self.repo_root / "src" / "amplihack" / ".claude"
3837
self.github_src = self.repo_root / ".github"
3938
self.github_dest = self.repo_root / "src" / "amplihack" / ".github"
39+
self.bundle_src = self.repo_root / "amplifier-bundle"
40+
self.bundle_dest = self.repo_root / "src" / "amplihack" / "amplifier-bundle"
4041

4142
def _copy_claude_directory(self):
4243
"""Copy .claude/ from repo root to src/amplihack/ if needed."""
@@ -114,11 +115,45 @@ def _cleanup_github_directory(self):
114115
print(f"Cleaning up {self.github_dest}")
115116
shutil.rmtree(self.github_dest)
116117

118+
def _copy_bundle_directory(self):
119+
"""Copy amplifier-bundle/ from repo root to src/amplihack/ if needed."""
120+
if not self.bundle_src.exists():
121+
print(f"Warning: amplifier-bundle/ not found at {self.bundle_src}")
122+
return
123+
124+
# Remove existing amplifier-bundle/ in package to ensure clean copy
125+
if self.bundle_dest.exists():
126+
print(f"Removing existing {self.bundle_dest}")
127+
shutil.rmtree(self.bundle_dest)
128+
129+
# Copy amplifier-bundle/ into package
130+
print(f"Copying {self.bundle_src} -> {self.bundle_dest}")
131+
shutil.copytree(
132+
self.bundle_src,
133+
self.bundle_dest,
134+
symlinks=True,
135+
ignore=shutil.ignore_patterns(
136+
"__pycache__",
137+
"*.pyc",
138+
"*.pyo",
139+
"*~",
140+
".DS_Store",
141+
),
142+
)
143+
print("Successfully copied amplifier-bundle/ to package")
144+
145+
def _cleanup_bundle_directory(self):
146+
"""Remove amplifier-bundle/ from package after build."""
147+
if self.bundle_dest.exists():
148+
print(f"Cleaning up {self.bundle_dest}")
149+
shutil.rmtree(self.bundle_dest)
150+
117151
def build_wheel(self, wheel_directory, config_settings=None, metadata_directory=None):
118-
"""Build wheel with .claude/ and .github/ directories included."""
152+
"""Build wheel with .claude/, .github/, and amplifier-bundle/ directories included."""
119153
try:
120154
self._copy_claude_directory()
121155
self._copy_github_directory()
156+
self._copy_bundle_directory()
122157
result = _orig.build_wheel(
123158
wheel_directory,
124159
config_settings=config_settings,
@@ -129,6 +164,7 @@ def build_wheel(self, wheel_directory, config_settings=None, metadata_directory=
129164
# Always cleanup, even if build fails
130165
self._cleanup_claude_directory()
131166
self._cleanup_github_directory()
167+
self._cleanup_bundle_directory()
132168

133169
def build_sdist(self, sdist_directory, config_settings=None):
134170
"""Build sdist (MANIFEST.in handles .claude/ for sdist)."""

0 commit comments

Comments
 (0)