memstack-skill-loader 4.2.0__tar.gz → 4.4.0__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 (43) hide show
  1. {memstack_skill_loader-4.2.0/src/memstack_skill_loader.egg-info → memstack_skill_loader-4.4.0}/PKG-INFO +1 -1
  2. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/README.md +21 -17
  3. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/pyproject.toml +1 -1
  4. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/__init__.py +1 -1
  5. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/__main__.py +86 -2
  6. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/agent_runner.py +864 -41
  7. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/config.py +14 -3
  8. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/dashboard.html +708 -118
  9. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/dashboard.py +297 -31
  10. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/license.py +48 -2
  11. memstack_skill_loader-4.4.0/src/memstack_skill_loader/proxy/__init__.py +2 -0
  12. memstack_skill_loader-4.4.0/src/memstack_skill_loader/proxy/_diag.py +83 -0
  13. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/proxy/body_parser.py +66 -4
  14. memstack_skill_loader-4.4.0/src/memstack_skill_loader/proxy/compressor.py +26 -0
  15. memstack_skill_loader-4.4.0/src/memstack_skill_loader/proxy/pro_compressor.py +767 -0
  16. memstack_skill_loader-4.4.0/src/memstack_skill_loader/proxy/server.py +294 -0
  17. memstack_skill_loader-4.4.0/src/memstack_skill_loader/proxy/stats_tracker.py +214 -0
  18. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/server.py +328 -10
  19. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/stats.py +35 -10
  20. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0/src/memstack_skill_loader.egg-info}/PKG-INFO +1 -1
  21. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader.egg-info/SOURCES.txt +6 -1
  22. memstack_skill_loader-4.4.0/tests/test_pro_compressor.py +384 -0
  23. memstack_skill_loader-4.4.0/tests/test_pro_skills_update.py +281 -0
  24. memstack_skill_loader-4.4.0/tests/test_skill_drift.py +36 -0
  25. memstack_skill_loader-4.2.0/src/memstack_skill_loader/proxy/__init__.py +0 -0
  26. memstack_skill_loader-4.2.0/src/memstack_skill_loader/proxy/compressor.py +0 -70
  27. memstack_skill_loader-4.2.0/src/memstack_skill_loader/proxy/server.py +0 -227
  28. memstack_skill_loader-4.2.0/src/memstack_skill_loader/proxy/stats_tracker.py +0 -103
  29. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/MANIFEST.in +0 -0
  30. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/setup.cfg +0 -0
  31. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/categories.py +0 -0
  32. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/compression.py +0 -0
  33. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/indexer.py +0 -0
  34. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/memory_db.py +0 -0
  35. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/proxy/forwarder.py +0 -0
  36. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/search.py +0 -0
  37. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/skill_config.py +0 -0
  38. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/tfidf_search.py +0 -0
  39. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader/version_check.py +0 -0
  40. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader.egg-info/dependency_links.txt +0 -0
  41. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader.egg-info/entry_points.txt +0 -0
  42. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/src/memstack_skill_loader.egg-info/requires.txt +0 -0
  43. {memstack_skill_loader-4.2.0 → memstack_skill_loader-4.4.0}/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: 4.2.0
3
+ Version: 4.4.0
4
4
  Summary: MCP server that vector-indexes MemStack Pro skills for on-demand loading
5
5
  Requires-Python: >=3.10
6
6
  Requires-Dist: mcp>=1.0.0
@@ -1,22 +1,26 @@
1
1
  # MemStack™ Skill Loader
2
2
 
3
- **127 skills for Claude Code** 85 free + 42 Pro exclusive. Vector-indexed so CC loads only the skill it needs, saving your context window.
3
+ **127 skills for Claude Code:** 84 free + 43 Pro exclusive. Vector-indexed so CC loads only the skill it needs, saving your context window.
4
4
 
5
5
  ## Quick Start (5 minutes)
6
6
 
7
- 1. **Install from PyPI:**
7
+ 1. **Get the free skills (in Claude Code):** Installs the plugin that provides the 84 free skills.
8
+ ```
9
+ /plugin marketplace add cwinvestments/memstack
10
+ /plugin install memstack@cwinvestments-memstack
11
+ ```
12
+
13
+ 2. **Install the engine (in your terminal):** Vector-indexes the skills so Claude Code loads only what it needs.
8
14
  ```bash
9
15
  pip install memstack-skill-loader
10
16
  ```
11
17
 
12
- 2. **Register with Claude Code:**
18
+ 3. **Register the engine with Claude Code (in your terminal):**
13
19
  ```bash
14
20
  claude mcp add --scope user memstack-skills -- python -m memstack_skill_loader
15
21
  ```
16
22
 
17
- 3. **Restart Claude Code**, then type `list skills` to verify.
18
-
19
- 4. **Activate Pro** (if purchased at [memstack.pro](https://memstack.pro)):
23
+ 4. **Restart Claude Code, then activate (in Claude Code):** Use `key="free"` for the free tier, or your Pro key from [memstack.pro](https://memstack.pro). Then type `list skills` to verify.
20
24
  ```
21
25
  activate_license(key="your-key-here", email="you@example.com")
22
26
  ```
@@ -27,11 +31,11 @@
27
31
 
28
32
  ## How It Works
29
33
 
30
- MCP server that vector-indexes all 127 MemStack™ skills so Claude Code can call `find_skill("deploy to Railway")` and load **only** the relevant skill on demand instead of all skills consuming context window.
34
+ MCP server that vector-indexes all 127 MemStack™ skills so Claude Code can call `find_skill("deploy to Railway")` and load **only** the relevant skill on demand, instead of all skills consuming context window.
31
35
 
32
- - **No API keys required** everything runs locally
33
- - **Pro skills auto-detected** set your license key and they appear automatically
34
- - **Auto-reindex on start** skills stay current without manual rebuilds
36
+ - **No API keys required:** everything runs locally
37
+ - **Pro skills auto-detected:** set your license key and they appear automatically
38
+ - **Auto-reindex on start:** skills stay current without manual rebuilds
35
39
 
36
40
  ### Environment Variable Override
37
41
 
@@ -99,7 +103,7 @@ The `config.json` file controls where skills are loaded from:
99
103
  }
100
104
  ```
101
105
 
102
- Pro skills are **auto-detected** when `MEMSTACK_PRO_LICENSE_KEY` is set no need to add them to `config.json`.
106
+ Pro skills are **auto-detected** when `MEMSTACK_PRO_LICENSE_KEY` is set, no need to add them to `config.json`.
103
107
 
104
108
  Add entries to `skill_sources` to index skills from multiple directories:
105
109
 
@@ -123,8 +127,8 @@ Add entries to `skill_sources` to index skills from multiple directories:
123
127
  ```
124
128
 
125
129
  The `pattern` field controls how skills are discovered:
126
- - `**/SKILL.md` Subdirectory structure (e.g., `category/skill-name/SKILL.md`)
127
- - `*.md` Flat directory (each `.md` file is a skill)
130
+ - `**/SKILL.md`: Subdirectory structure (e.g., `category/skill-name/SKILL.md`)
131
+ - `*.md`: Flat directory (each `.md` file is a skill)
128
132
 
129
133
  ## Release Notes
130
134
 
@@ -133,16 +137,16 @@ The `pattern` field controls how skills are discovered:
133
137
  - Dashboard: 6-page localhost dashboard (Overview, Skills Manager, Burn Report, Memory Browser, Agent Monitor, Settings)
134
138
  - Agent Runner: 3-agent orchestration (Manager/Builder/Reviewer) with per-agent model selection
135
139
  - 17 MCP tools
136
- - 127 skills (85 free + 42 Pro)
140
+ - 127 skills (84 free + 43 Pro)
137
141
  - Real-time context window monitoring per agent
138
142
  - Session diary with AI-authored markdown narratives
139
143
  - Safe git staging (prevents accidental commits of secrets/runtime data)
140
144
  - Task completion notifications (browser, tab flash, audio)
141
145
  - Token usage tracking with estimated costs
142
- - Headroom proxy integration (~35-40% token savings)
146
+ - TokenStack™ proxy integration (~35-40% token savings)
143
147
 
144
- **[v3.4.0](https://github.com/cwinvestments/memstack-skill-loader/releases/tag/v3.4.0)** 100 Skills Milestone (18 new Pro skills, auto-detection, display name fixes)
148
+ **[v3.4.0](https://github.com/cwinvestments/memstack-skill-loader/releases/tag/v3.4.0)**: 100 Skills Milestone (18 new Pro skills, auto-detection, display name fixes)
145
149
 
146
150
  ## License
147
151
 
148
- Proprietary Part of MemStack™ Pro by CW Affiliate Investments LLC.
152
+ Proprietary. Part of MemStack™ Pro by CW Affiliate Investments LLC.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "memstack-skill-loader"
7
- version = "4.2.0"
7
+ version = "4.4.0"
8
8
  description = "MCP server that vector-indexes MemStack Pro skills for on-demand loading"
9
9
  requires-python = ">=3.10"
10
10
  dependencies = [
@@ -1,3 +1,3 @@
1
1
  """MemStack Skill Loader — MCP server for semantic skill search."""
2
2
 
3
- __version__ = "4.2.0"
3
+ __version__ = "4.4.0"
@@ -1,8 +1,11 @@
1
1
  """Entry point for python -m memstack_skill_loader."""
2
2
 
3
3
  import asyncio
4
+ import os
5
+ import signal
4
6
  import sys
5
7
  import time
8
+ from pathlib import Path
6
9
 
7
10
  from .server import run
8
11
 
@@ -71,10 +74,90 @@ def _run_agents(task: str) -> None:
71
74
  print(" All agents stopped.")
72
75
 
73
76
 
77
+ def _stop() -> None:
78
+ """Stop the MemStack dashboard and any agent runner claude.exe processes."""
79
+ pid_file = Path.home() / ".memstack" / "dashboard.pid"
80
+ if not pid_file.exists():
81
+ print("No MemStack dashboard running.")
82
+ return
83
+
84
+ try:
85
+ pid = int(pid_file.read_text().strip())
86
+ except (ValueError, OSError):
87
+ print("No MemStack dashboard running (corrupt PID file).")
88
+ pid_file.unlink(missing_ok=True)
89
+ return
90
+
91
+ # Check if the process is alive
92
+ try:
93
+ os.kill(pid, 0)
94
+ except OSError:
95
+ print("No MemStack dashboard running (process not found).")
96
+ pid_file.unlink(missing_ok=True)
97
+ return
98
+
99
+ # Kill any claude.exe processes spawned by agent runner
100
+ killed_agents = 0
101
+ try:
102
+ import subprocess
103
+ if sys.platform == "win32":
104
+ result = subprocess.run(
105
+ ["wmic", "process", "where",
106
+ f"ParentProcessId={pid} and Name='claude.exe'",
107
+ "get", "ProcessId"],
108
+ capture_output=True, text=True, timeout=10,
109
+ )
110
+ for line in result.stdout.splitlines():
111
+ line = line.strip()
112
+ if line.isdigit():
113
+ try:
114
+ os.kill(int(line), signal.SIGTERM)
115
+ killed_agents += 1
116
+ except OSError:
117
+ pass
118
+ else:
119
+ result = subprocess.run(
120
+ ["pgrep", "-P", str(pid), "-x", "claude"],
121
+ capture_output=True, text=True, timeout=10,
122
+ )
123
+ for line in result.stdout.splitlines():
124
+ line = line.strip()
125
+ if line.isdigit():
126
+ try:
127
+ os.kill(int(line), signal.SIGTERM)
128
+ killed_agents += 1
129
+ except OSError:
130
+ pass
131
+ except Exception:
132
+ pass
133
+
134
+ # Kill the dashboard process
135
+ try:
136
+ if sys.platform == "win32":
137
+ os.kill(pid, signal.SIGTERM)
138
+ else:
139
+ os.kill(pid, signal.SIGTERM)
140
+ print(f"MemStack dashboard stopped (PID {pid}).")
141
+ if killed_agents:
142
+ print(f"Stopped {killed_agents} agent process(es).")
143
+ except OSError as exc:
144
+ print(f"Failed to stop dashboard (PID {pid}): {exc}")
145
+
146
+ pid_file.unlink(missing_ok=True)
147
+
148
+
74
149
  def main():
150
+ if len(sys.argv) > 1 and sys.argv[1] == "stop":
151
+ _stop()
152
+ return
75
153
  if len(sys.argv) > 1 and sys.argv[1] == "dashboard":
154
+ import argparse
155
+ parser = argparse.ArgumentParser(prog="memstack dashboard")
156
+ parser.add_argument("--with-proxy", action="store_true", help="Start TokenStack proxy on background thread")
157
+ parser.add_argument("--proxy-port", type=int, default=8787, help="Proxy port (default 8787)")
158
+ args = parser.parse_args(sys.argv[2:])
76
159
  from .dashboard import start_dashboard
77
- start_dashboard()
160
+ start_dashboard(with_proxy=args.with_proxy, proxy_port=args.proxy_port)
78
161
  elif len(sys.argv) > 2 and sys.argv[1] == "run":
79
162
  task = " ".join(sys.argv[2:])
80
163
  _run_agents(task)
@@ -84,9 +167,10 @@ def main():
84
167
  parser.add_argument("--port", type=int, default=8787)
85
168
  parser.add_argument("--host", default="127.0.0.1")
86
169
  parser.add_argument("--verbose", action="store_true", help="Show parser diagnostics")
170
+ parser.add_argument("--pro", action="store_true", help="Force pro tier transforms (testing without license file)")
87
171
  args = parser.parse_args(sys.argv[2:])
88
172
  from .proxy.server import start_proxy
89
- start_proxy(host=args.host, port=args.port, verbose=args.verbose)
173
+ start_proxy(host=args.host, port=args.port, verbose=args.verbose, force_pro=args.pro)
90
174
  elif len(sys.argv) > 1 and sys.argv[1] == "run":
91
175
  print("Usage: python -m memstack_skill_loader run \"Your task description\"",
92
176
  file=sys.stderr)