memstack-skill-loader 4.1.1__tar.gz → 4.3.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 (38) hide show
  1. {memstack_skill_loader-4.1.1/src/memstack_skill_loader.egg-info → memstack_skill_loader-4.3.0}/PKG-INFO +2 -1
  2. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/pyproject.toml +2 -1
  3. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader/__init__.py +1 -1
  4. memstack_skill_loader-4.3.0/src/memstack_skill_loader/__main__.py +183 -0
  5. memstack_skill_loader-4.3.0/src/memstack_skill_loader/agent_runner.py +2153 -0
  6. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader/config.py +14 -3
  7. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader/dashboard.html +465 -122
  8. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader/dashboard.py +174 -116
  9. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader/license.py +46 -0
  10. memstack_skill_loader-4.3.0/src/memstack_skill_loader/proxy/__init__.py +2 -0
  11. memstack_skill_loader-4.3.0/src/memstack_skill_loader/proxy/body_parser.py +127 -0
  12. memstack_skill_loader-4.3.0/src/memstack_skill_loader/proxy/compressor.py +77 -0
  13. memstack_skill_loader-4.3.0/src/memstack_skill_loader/proxy/forwarder.py +47 -0
  14. memstack_skill_loader-4.3.0/src/memstack_skill_loader/proxy/pro_compressor.py +312 -0
  15. memstack_skill_loader-4.3.0/src/memstack_skill_loader/proxy/server.py +287 -0
  16. memstack_skill_loader-4.3.0/src/memstack_skill_loader/proxy/stats_tracker.py +125 -0
  17. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader/stats.py +161 -6
  18. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0/src/memstack_skill_loader.egg-info}/PKG-INFO +2 -1
  19. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader.egg-info/SOURCES.txt +9 -1
  20. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader.egg-info/requires.txt +1 -0
  21. memstack_skill_loader-4.3.0/tests/test_pro_compressor.py +382 -0
  22. memstack_skill_loader-4.1.1/src/memstack_skill_loader/__main__.py +0 -90
  23. memstack_skill_loader-4.1.1/src/memstack_skill_loader/agent_runner.py +0 -1243
  24. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/MANIFEST.in +0 -0
  25. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/README.md +0 -0
  26. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/setup.cfg +0 -0
  27. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader/categories.py +0 -0
  28. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader/compression.py +0 -0
  29. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader/indexer.py +0 -0
  30. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader/memory_db.py +0 -0
  31. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader/search.py +0 -0
  32. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader/server.py +0 -0
  33. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader/skill_config.py +0 -0
  34. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader/tfidf_search.py +0 -0
  35. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader/version_check.py +0 -0
  36. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader.egg-info/dependency_links.txt +0 -0
  37. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.0}/src/memstack_skill_loader.egg-info/entry_points.txt +0 -0
  38. {memstack_skill_loader-4.1.1 → memstack_skill_loader-4.3.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.1.1
3
+ Version: 4.3.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
@@ -8,3 +8,4 @@ Requires-Dist: lancedb>=0.6.0
8
8
  Requires-Dist: sentence-transformers>=2.2.0
9
9
  Requires-Dist: pyarrow>=14.0.0
10
10
  Requires-Dist: httpx>=0.24.0
11
+ Requires-Dist: aiohttp>=3.9
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "memstack-skill-loader"
7
- version = "4.1.1"
7
+ version = "4.3.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 = [
@@ -13,6 +13,7 @@ dependencies = [
13
13
  "sentence-transformers>=2.2.0",
14
14
  "pyarrow>=14.0.0",
15
15
  "httpx>=0.24.0",
16
+ "aiohttp>=3.9",
16
17
  ]
17
18
 
18
19
  [project.scripts]
@@ -1,3 +1,3 @@
1
1
  """MemStack Skill Loader — MCP server for semantic skill search."""
2
2
 
3
- __version__ = "4.1.1"
3
+ __version__ = "4.2.0"
@@ -0,0 +1,183 @@
1
+ """Entry point for python -m memstack_skill_loader."""
2
+
3
+ import asyncio
4
+ import os
5
+ import signal
6
+ import sys
7
+ import time
8
+ from pathlib import Path
9
+
10
+ from .server import run
11
+
12
+
13
+ def _run_agents(task: str) -> None:
14
+ """Start agent runner and print live message log until done."""
15
+ from . import agent_runner
16
+
17
+ print(f"\033[1;36m{'='*60}\033[0m")
18
+ print(f"\033[1;36m Agent Runner — Task Orchestration\033[0m")
19
+ print(f"\033[1;36m{'='*60}\033[0m")
20
+ print(f"\n Task: {task}")
21
+ print(f" Working dir: {sys.argv[3] if len(sys.argv) > 3 else '.'}")
22
+ print(f"\n Press Ctrl+C to stop all agents.\n")
23
+
24
+ working_dir = sys.argv[3] if len(sys.argv) > 3 else None
25
+ result = agent_runner.start_run(task=task, working_dir=working_dir)
26
+
27
+ if "error" in result:
28
+ print(f"\033[31mError: {result['error']}\033[0m", file=sys.stderr)
29
+ sys.exit(1)
30
+
31
+ print(f" Session: {result['session_id']}\n")
32
+ print(f"\033[90m{'─'*60}\033[0m")
33
+
34
+ seen_messages = 0
35
+ try:
36
+ while True:
37
+ time.sleep(2)
38
+ status = agent_runner.get_status()
39
+
40
+ # Print new messages
41
+ messages = status.get("messages", [])
42
+ for msg in messages[seen_messages:]:
43
+ from_name = msg.get("from", "?")
44
+ to_name = msg.get("to", "?")
45
+ content = msg.get("content", "")[:200]
46
+ ts = msg.get("timestamp", "")
47
+
48
+ color = "\033[35m" if from_name == "manager" else \
49
+ "\033[36m" if from_name == "builder" else \
50
+ "\033[32m" if from_name == "reviewer" else "\033[90m"
51
+
52
+ print(f" {color}{from_name}\033[0m → \033[37m{to_name}\033[0m")
53
+ for line in content.split("\n")[:5]:
54
+ print(f" {line}")
55
+ print()
56
+
57
+ seen_messages = len(messages)
58
+
59
+ # Check if done
60
+ session_status = status.get("status", "")
61
+ if session_status in ("completed", "error", "stopped"):
62
+ print(f"\033[90m{'─'*60}\033[0m")
63
+ color = "\033[32m" if session_status == "completed" else "\033[31m"
64
+ print(f"\n {color}Status: {session_status}\033[0m")
65
+ result_text = status.get("result", "")
66
+ if result_text:
67
+ print(f" {result_text[:300]}")
68
+ print()
69
+ break
70
+
71
+ except KeyboardInterrupt:
72
+ print("\n\n Stopping agents...")
73
+ agent_runner.stop_all()
74
+ print(" All agents stopped.")
75
+
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
+
149
+ def main():
150
+ if len(sys.argv) > 1 and sys.argv[1] == "stop":
151
+ _stop()
152
+ return
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:])
159
+ from .dashboard import start_dashboard
160
+ start_dashboard(with_proxy=args.with_proxy, proxy_port=args.proxy_port)
161
+ elif len(sys.argv) > 2 and sys.argv[1] == "run":
162
+ task = " ".join(sys.argv[2:])
163
+ _run_agents(task)
164
+ elif len(sys.argv) > 1 and sys.argv[1] == "proxy":
165
+ import argparse
166
+ parser = argparse.ArgumentParser(prog="memstack proxy")
167
+ parser.add_argument("--port", type=int, default=8787)
168
+ parser.add_argument("--host", default="127.0.0.1")
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)")
171
+ args = parser.parse_args(sys.argv[2:])
172
+ from .proxy.server import start_proxy
173
+ start_proxy(host=args.host, port=args.port, verbose=args.verbose, force_pro=args.pro)
174
+ elif len(sys.argv) > 1 and sys.argv[1] == "run":
175
+ print("Usage: python -m memstack_skill_loader run \"Your task description\"",
176
+ file=sys.stderr)
177
+ sys.exit(1)
178
+ else:
179
+ asyncio.run(run())
180
+
181
+
182
+ if __name__ == "__main__":
183
+ main()