memstack-skill-loader 3.5.1__tar.gz → 3.5.2__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.
Files changed (24) hide show
  1. {memstack_skill_loader-3.5.1/src/memstack_skill_loader.egg-info → memstack_skill_loader-3.5.2}/PKG-INFO +1 -1
  2. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/README.md +10 -13
  3. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/pyproject.toml +1 -1
  4. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/config.py +51 -3
  5. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/server.py +9 -0
  6. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2/src/memstack_skill_loader.egg-info}/PKG-INFO +1 -1
  7. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/MANIFEST.in +0 -0
  8. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/setup.cfg +0 -0
  9. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/__init__.py +0 -0
  10. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/__main__.py +0 -0
  11. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/compression.py +0 -0
  12. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/dashboard.html +0 -0
  13. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/dashboard.py +0 -0
  14. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/indexer.py +0 -0
  15. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/license.py +0 -0
  16. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/search.py +0 -0
  17. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/stats.py +0 -0
  18. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/tfidf_search.py +0 -0
  19. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/version_check.py +0 -0
  20. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader.egg-info/SOURCES.txt +0 -0
  21. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader.egg-info/dependency_links.txt +0 -0
  22. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader.egg-info/entry_points.txt +0 -0
  23. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader.egg-info/requires.txt +0 -0
  24. {memstack_skill_loader-3.5.1 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memstack-skill-loader
3
- Version: 3.5.1
3
+ Version: 3.5.2
4
4
  Summary: MCP server that vector-indexes MemStack Pro skills for on-demand loading
5
5
  Requires-Python: >=3.12
6
6
  Requires-Dist: mcp>=1.0.0
@@ -4,27 +4,24 @@
4
4
 
5
5
  ## Quick Start (5 minutes)
6
6
 
7
- 1. **Clone both repos side-by-side:**
7
+ 1. **Install from PyPI:**
8
8
  ```bash
9
- git clone https://github.com/cwinvestments/memstack.git
10
- git clone https://github.com/cwinvestments/memstack-skill-loader.git
9
+ pip install memstack-skill-loader
11
10
  ```
12
11
 
13
- 2. **Install the skill loader:**
14
- ```bash
15
- cd memstack-skill-loader
16
- pip install -e . --break-system-packages
17
- ```
18
-
19
- 3. **Register with Claude Code:**
12
+ 2. **Register with Claude Code:**
20
13
  ```bash
21
14
  claude mcp add --scope user memstack-skills -- python -m memstack_skill_loader
22
15
  ```
23
16
 
24
- 4. **Restart Claude Code**, then type `list skills` to verify.
17
+ 3. **Restart Claude Code**, then type `list skills` to verify.
18
+
19
+ 4. **Activate Pro** (if purchased at [memstack.pro](https://memstack.pro)):
20
+ ```
21
+ activate_license(key="your-key-here", email="you@example.com")
22
+ ```
25
23
 
26
- > The skill loader auto-detects the `memstack` repo if cloned as a sibling directory.
27
- > To use a different location, set `MEMSTACK_SKILLS_DIR=/path/to/memstack/skills`.
24
+ > To override the skills path, set `MEMSTACK_SKILLS_DIR=/path/to/your/memstack/skills`.
28
25
 
29
26
  > See [QUICKSTART.md](QUICKSTART.md) for detailed setup, [QUICK-REFERENCE.md](QUICK-REFERENCE.md) for the full skill catalog, and [TROUBLESHOOTING.md](TROUBLESHOOTING.md) if you hit issues.
30
27
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "memstack-skill-loader"
7
- version = "3.5.1"
7
+ version = "3.5.2"
8
8
  description = "MCP server that vector-indexes MemStack Pro skills for on-demand loading"
9
9
  requires-python = ">=3.12"
10
10
  dependencies = [
@@ -60,14 +60,62 @@ class Config:
60
60
  )
61
61
 
62
62
 
63
+ def _auto_discover_skills() -> SkillSource | None:
64
+ """Scan common locations for MemStack skills when no config.json exists (PyPI installs)."""
65
+ env_dir = os.environ.get("MEMSTACK_SKILLS_DIR")
66
+ if env_dir:
67
+ p = Path(env_dir).expanduser()
68
+ if p.exists():
69
+ skill_files = list(p.glob("**/SKILL.md"))
70
+ if skill_files:
71
+ print(f"Using MEMSTACK_SKILLS_DIR: {p} ({len(skill_files)} skills found)", file=sys.stderr)
72
+ return SkillSource(type="local", path=str(p), pattern="**/SKILL.md", label="MemStack")
73
+
74
+ home = Path.home()
75
+ candidates = [
76
+ home / ".claude" / "plugins" / "cache" / "cwinvestments-memstack" / "memstack",
77
+ home / ".claude" / "plugins" / "marketplaces" / "cwinvestments-memstack" / "skills",
78
+ home / "memstack" / "skills",
79
+ Path.cwd().parent / "memstack" / "skills",
80
+ ]
81
+
82
+ for candidate in candidates:
83
+ if candidate.name == "memstack":
84
+ version_dirs = sorted(candidate.glob("*/skills"), reverse=True)
85
+ for vdir in version_dirs:
86
+ skill_files = list(vdir.glob("**/SKILL.md"))
87
+ if skill_files:
88
+ print(f"Auto-detected skills at: {vdir} ({len(skill_files)} skills found)", file=sys.stderr)
89
+ return SkillSource(type="local", path=str(vdir), pattern="**/SKILL.md", label="MemStack")
90
+ else:
91
+ if candidate.exists():
92
+ skill_files = list(candidate.glob("**/SKILL.md"))
93
+ if skill_files:
94
+ print(f"Auto-detected skills at: {candidate} ({len(skill_files)} skills found)", file=sys.stderr)
95
+ return SkillSource(type="local", path=str(candidate), pattern="**/SKILL.md", label="MemStack")
96
+
97
+ print(
98
+ "No skills found. Install the MemStack plugin first: "
99
+ "/plugin marketplace add cwinvestments/memstack",
100
+ file=sys.stderr,
101
+ )
102
+ return None
103
+
104
+
63
105
  def load_config(config_path: Path | None = None) -> Config:
64
- """Load config from JSON file. Falls back to defaults if not found."""
106
+ """Load config from JSON file. Falls back to auto-discovery if not found."""
65
107
  if config_path is None:
66
108
  config_path = Path(__file__).resolve().parent.parent.parent / "config.json"
67
109
 
68
110
  if not config_path.exists():
69
- print(f"Config not found at {config_path}, using defaults", file=sys.stderr)
70
- return Config()
111
+ source = _auto_discover_skills()
112
+ config = Config(
113
+ skill_sources=[source] if source else [],
114
+ auto_reindex_on_start=True,
115
+ )
116
+ if os.environ.get("MEMSTACK_PRO_LICENSE_KEY"):
117
+ config = config.with_pro_skills()
118
+ return config
71
119
 
72
120
  try:
73
121
  with open(config_path, encoding="utf-8") as f:
@@ -874,6 +874,15 @@ async def run():
874
874
  from .stats import backfill_categories
875
875
  backfill_categories(_CATEGORY_MAP)
876
876
 
877
+ # Auto-build index on first run (PyPI installs have no pre-built index).
878
+ if config.auto_reindex_on_start:
879
+ from .tfidf_search import _get_index as _peek_index
880
+ if _peek_index(config) is None:
881
+ from .indexer import build_index
882
+ print("[memstack] Building skill index for first time...", file=sys.stderr)
883
+ count = build_index(config)
884
+ print(f"[memstack] Indexed {count} skills.", file=sys.stderr)
885
+
877
886
  # Pre-load TF-IDF index before stdio_server starts its stdin reader thread.
878
887
  # On Windows, a blocking readline() in the stdin thread causes GIL contention
879
888
  # that slows down CPU-intensive operations (like sklearn import) by ~20x.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memstack-skill-loader
3
- Version: 3.5.1
3
+ Version: 3.5.2
4
4
  Summary: MCP server that vector-indexes MemStack Pro skills for on-demand loading
5
5
  Requires-Python: >=3.12
6
6
  Requires-Dist: mcp>=1.0.0