Skip to content

Commit b41aa2a

Browse files
committed
chore(pack): per-dir .npmignore for Python bytecode + tarball hygiene test
npm 11 ignores the root .npmignore inside files[]-allowlisted directories, so 24 __pycache__/*.pyc entries were shipping in the tarball. Per-dir .npmignore files in mcp-server/ and prd_taskmaster/ do the real filtering; the root file documents the trap defensively. New test asserts the npm pack --dry-run manifest stays free of bytecode and marketplace.json. Imported-From: prd-taskmaster-plugin@v5-final (f140490) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 82ac1b0)
1 parent f514657 commit b41aa2a

4 files changed

Lines changed: 48 additions & 0 deletions

File tree

.npmignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Root .npmignore — Python bytecode + dev-loopback marketplace patterns.
2+
#
3+
# IMPORTANT (npm 11 behavior): when package.json `files` lists a directory
4+
# like "mcp-server/" as an allowlist, the root .npmignore is NOT honored
5+
# for files INSIDE that directory. Filters must live in per-subdirectory
6+
# .npmignore files to actually take effect.
7+
#
8+
# The root entries below are kept defensively for:
9+
# - future npm versions that may honor root .npmignore with directory files
10+
# - fallback if a subdir .npmignore is ever accidentally deleted
11+
# - self-documentation of the filtering intent
12+
#
13+
# The ACTUAL working filters live at:
14+
# - mcp-server/.npmignore (excludes __pycache__, *.pyc)
15+
# - prd_taskmaster/.npmignore (excludes __pycache__, *.pyc)
16+
# - .claude-plugin/.npmignore (excludes marketplace.json dev config)
17+
**/__pycache__
18+
*.pyc
19+
.claude-plugin/marketplace.json

mcp-server/.npmignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
__pycache__
2+
*.pyc

prd_taskmaster/.npmignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
__pycache__
2+
*.pyc

tests/plugin/test_packaging_identity.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
import json
2+
import shutil
3+
import subprocess
4+
5+
import pytest
26
from pathlib import Path
37

48

@@ -55,3 +59,24 @@ def test_product_spec_marks_backend_abstraction_shipped_v41():
5559
assert "auto|taskmaster|native" in content
5660
assert "detect/init/parse_prd/expand/rate" in content
5761
assert "agent_action_required" in content
62+
63+
64+
@pytest.mark.skipif(shutil.which("npm") is None, reason="npm not available")
65+
def test_npm_pack_excludes_python_bytecode():
66+
# npm 11 does not honor the root .npmignore inside `files[]`-allowlisted
67+
# directories; per-subdir .npmignore files carry the real filtering. This
68+
# test guards the tarball against __pycache__/*.pyc regressions.
69+
result = subprocess.run(
70+
["npm", "pack", "--dry-run", "--json"],
71+
cwd=REPO_ROOT,
72+
capture_output=True,
73+
text=True,
74+
timeout=120,
75+
)
76+
assert result.returncode == 0, result.stderr
77+
78+
manifest = json.loads(result.stdout)
79+
paths = [entry["path"] for entry in manifest[0]["files"]]
80+
offenders = [p for p in paths if ".pyc" in p or "__pycache__" in p]
81+
assert offenders == []
82+
assert not any("marketplace.json" in p for p in paths)

0 commit comments

Comments
 (0)