memstack-skill-loader 3.5.0__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.
- {memstack_skill_loader-3.5.0/src/memstack_skill_loader.egg-info → memstack_skill_loader-3.5.2}/PKG-INFO +1 -1
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/README.md +10 -13
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/pyproject.toml +1 -1
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/config.py +51 -3
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/server.py +9 -0
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/version_check.py +16 -25
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2/src/memstack_skill_loader.egg-info}/PKG-INFO +1 -1
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/MANIFEST.in +0 -0
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/setup.cfg +0 -0
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/__init__.py +0 -0
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/__main__.py +0 -0
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/compression.py +0 -0
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/dashboard.html +0 -0
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/dashboard.py +0 -0
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/indexer.py +0 -0
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/license.py +0 -0
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/search.py +0 -0
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/stats.py +0 -0
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/tfidf_search.py +0 -0
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader.egg-info/SOURCES.txt +0 -0
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader.egg-info/dependency_links.txt +0 -0
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader.egg-info/entry_points.txt +0 -0
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader.egg-info/requires.txt +0 -0
- {memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader.egg-info/top_level.txt +0 -0
|
@@ -4,27 +4,24 @@
|
|
|
4
4
|
|
|
5
5
|
## Quick Start (5 minutes)
|
|
6
6
|
|
|
7
|
-
1. **
|
|
7
|
+
1. **Install from PyPI:**
|
|
8
8
|
```bash
|
|
9
|
-
|
|
10
|
-
git clone https://github.com/cwinvestments/memstack-skill-loader.git
|
|
9
|
+
pip install memstack-skill-loader
|
|
11
10
|
```
|
|
12
11
|
|
|
13
|
-
2. **
|
|
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
|
-
|
|
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
|
-
>
|
|
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
|
|
{memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/config.py
RENAMED
|
@@ -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
|
|
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
|
-
|
|
70
|
-
|
|
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:
|
{memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/server.py
RENAMED
|
@@ -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,28 +1,22 @@
|
|
|
1
|
-
"""Check for MemStack updates via
|
|
1
|
+
"""Check for MemStack updates via the PyPI JSON API."""
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
-
import os
|
|
5
4
|
import sys
|
|
6
5
|
import time
|
|
7
6
|
from pathlib import Path
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
PYPI_URL = "https://pypi.org/pypi/memstack-skill-loader/json"
|
|
10
9
|
CACHE_FILE = Path.home() / ".memstack" / "version-check.json"
|
|
11
|
-
CACHE_TTL = 86400 # 24 hours
|
|
10
|
+
CACHE_TTL = 86400 # 24 hours
|
|
12
11
|
|
|
13
12
|
|
|
14
|
-
def
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
try:
|
|
22
|
-
return version_file.read_text(encoding="utf-8").strip()
|
|
23
|
-
except OSError:
|
|
24
|
-
return None
|
|
25
|
-
return None
|
|
13
|
+
def _get_local_version() -> str | None:
|
|
14
|
+
"""Get the installed package version via importlib.metadata."""
|
|
15
|
+
try:
|
|
16
|
+
from importlib.metadata import version
|
|
17
|
+
return version("memstack-skill-loader")
|
|
18
|
+
except Exception:
|
|
19
|
+
return None
|
|
26
20
|
|
|
27
21
|
|
|
28
22
|
def _read_cache() -> dict | None:
|
|
@@ -51,32 +45,30 @@ def _write_cache(remote_version: str) -> None:
|
|
|
51
45
|
|
|
52
46
|
|
|
53
47
|
def check_for_updates() -> None:
|
|
54
|
-
"""Check
|
|
48
|
+
"""Check PyPI for a newer MemStack version. Prints to stderr if update available."""
|
|
55
49
|
try:
|
|
56
|
-
local_version =
|
|
50
|
+
local_version = _get_local_version()
|
|
57
51
|
if not local_version:
|
|
58
52
|
return
|
|
59
53
|
|
|
60
|
-
# Check cache first
|
|
61
54
|
cached = _read_cache()
|
|
62
55
|
if cached:
|
|
63
56
|
remote_version = cached.get("remote_version", "")
|
|
64
57
|
if remote_version and remote_version != local_version:
|
|
65
58
|
print(
|
|
66
59
|
f"[memstack] Update available: {remote_version} (you have {local_version}). "
|
|
67
|
-
f"Run
|
|
60
|
+
f"Run: pip install memstack-skill-loader --upgrade",
|
|
68
61
|
file=sys.stderr,
|
|
69
62
|
)
|
|
70
63
|
return
|
|
71
64
|
|
|
72
|
-
# Fetch from GitHub API
|
|
73
65
|
import httpx
|
|
74
|
-
response = httpx.get(
|
|
66
|
+
response = httpx.get(PYPI_URL, timeout=5.0, follow_redirects=True)
|
|
75
67
|
if response.status_code != 200:
|
|
76
68
|
return
|
|
77
69
|
|
|
78
70
|
data = response.json()
|
|
79
|
-
remote_version = data.get("
|
|
71
|
+
remote_version = data.get("info", {}).get("version", "")
|
|
80
72
|
if not remote_version:
|
|
81
73
|
return
|
|
82
74
|
|
|
@@ -85,9 +77,8 @@ def check_for_updates() -> None:
|
|
|
85
77
|
if remote_version != local_version:
|
|
86
78
|
print(
|
|
87
79
|
f"[memstack] Update available: {remote_version} (you have {local_version}). "
|
|
88
|
-
f"Run
|
|
80
|
+
f"Run: pip install memstack-skill-loader --upgrade",
|
|
89
81
|
file=sys.stderr,
|
|
90
82
|
)
|
|
91
83
|
except Exception:
|
|
92
|
-
# Silently skip on any error — never block skill loading
|
|
93
84
|
pass
|
|
File without changes
|
|
File without changes
|
{memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/__init__.py
RENAMED
|
File without changes
|
{memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/__main__.py
RENAMED
|
File without changes
|
{memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/compression.py
RENAMED
|
File without changes
|
{memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/dashboard.html
RENAMED
|
File without changes
|
{memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/dashboard.py
RENAMED
|
File without changes
|
{memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/indexer.py
RENAMED
|
File without changes
|
{memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/license.py
RENAMED
|
File without changes
|
{memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/search.py
RENAMED
|
File without changes
|
{memstack_skill_loader-3.5.0 → memstack_skill_loader-3.5.2}/src/memstack_skill_loader/stats.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|