memory-bank-skill 3.0.0__py3-none-any.whl
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.
- memory_bank_skill/__init__.py +3 -0
- memory_bank_skill/__main__.py +6 -0
- memory_bank_skill/_bundle.py +48 -0
- memory_bank_skill/cli.py +272 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/SKILL.md +231 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/VERSION +1 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/adapters/_lib_agents_md.sh +220 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/adapters/cline.sh +229 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/adapters/codex.sh +161 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/adapters/cursor.sh +209 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/adapters/git-hooks-fallback.sh +235 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/adapters/kilo.sh +121 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/adapters/opencode.sh +220 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/adapters/pi.sh +171 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/adapters/windsurf.sh +242 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/agents/mb-codebase-mapper.md +316 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/agents/mb-doctor.md +184 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/agents/mb-manager.md +367 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/agents/plan-verifier.md +127 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/adr.md +47 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/api-contract.md +64 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/catchup.md +12 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/changelog.md +12 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/commit.md +21 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/contract.md +43 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/db-migration.md +66 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/doc.md +19 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/done.md +6 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/mb.md +846 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/observability.md +75 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/plan.md +135 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/pr.md +14 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/refactor.md +17 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/review.md +131 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/security-review.md +91 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/start.md +7 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/commands/test.md +17 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/hooks/block-dangerous.sh +109 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/hooks/file-change-log.sh +108 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/hooks/mb-compact-reminder.sh +72 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/hooks/session-end-autosave.sh +95 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/install.sh +947 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/references/claude-md-template.md +112 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/references/metadata.md +102 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/references/planning-and-verification.md +89 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/references/structure.md +147 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/references/tags-vocabulary.md +50 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/references/templates.md +286 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/references/workflow.md +125 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/rules/CLAUDE-GLOBAL.md +132 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/rules/RULES.md +535 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/scripts/_lib.sh +224 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/scripts/mb-codegraph.py +634 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/scripts/mb-compact.sh +299 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/scripts/mb-context.sh +91 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/scripts/mb-deps-check.sh +204 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/scripts/mb-drift.sh +213 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/scripts/mb-import.py +327 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/scripts/mb-index-json.py +215 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/scripts/mb-index.sh +87 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/scripts/mb-metrics.sh +165 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/scripts/mb-note.sh +40 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/scripts/mb-plan-done.sh +161 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/scripts/mb-plan-sync.sh +191 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/scripts/mb-plan.sh +103 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/scripts/mb-search.sh +218 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/scripts/mb-tags-normalize.sh +247 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/scripts/mb-upgrade.sh +189 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/settings/hooks.json +96 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/settings/merge-hooks.py +120 -0
- memory_bank_skill-3.0.0.data/data/share/memory-bank-skill/uninstall.sh +267 -0
- memory_bank_skill-3.0.0.dist-info/METADATA +458 -0
- memory_bank_skill-3.0.0.dist-info/RECORD +76 -0
- memory_bank_skill-3.0.0.dist-info/WHEEL +4 -0
- memory_bank_skill-3.0.0.dist-info/entry_points.txt +2 -0
- memory_bank_skill-3.0.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Resolve paths to bundled skill files (install.sh, hooks/, adapters/, etc.).
|
|
2
|
+
|
|
3
|
+
Priority order:
|
|
4
|
+
1. $MB_SKILL_BUNDLE env override (for dev/testing)
|
|
5
|
+
2. Installed package data via sys.prefix/share/memory-bank-skill/
|
|
6
|
+
3. Development layout (running from repo checkout: ../install.sh relative to this file)
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import sys
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _candidate_paths() -> list[Path]:
|
|
17
|
+
paths: list[Path] = []
|
|
18
|
+
|
|
19
|
+
override = os.environ.get("MB_SKILL_BUNDLE")
|
|
20
|
+
if override:
|
|
21
|
+
paths.append(Path(override))
|
|
22
|
+
|
|
23
|
+
# Installed via pipx / pip — shared-data goes to <prefix>/share/memory-bank-skill/
|
|
24
|
+
prefix_share = Path(sys.prefix) / "share" / "memory-bank-skill"
|
|
25
|
+
paths.append(prefix_share)
|
|
26
|
+
|
|
27
|
+
# Dev layout: repo root is parent of memory_bank_skill/
|
|
28
|
+
dev_root = Path(__file__).resolve().parent.parent
|
|
29
|
+
paths.append(dev_root)
|
|
30
|
+
|
|
31
|
+
return paths
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def find_bundle_root() -> Path:
|
|
35
|
+
"""Return directory containing install.sh + skill resources, or raise."""
|
|
36
|
+
for p in _candidate_paths():
|
|
37
|
+
if (p / "install.sh").is_file():
|
|
38
|
+
return p
|
|
39
|
+
searched = "\n ".join(str(p) for p in _candidate_paths())
|
|
40
|
+
raise FileNotFoundError(
|
|
41
|
+
f"Cannot locate memory-bank-skill bundle. Searched:\n {searched}\n"
|
|
42
|
+
"Set MB_SKILL_BUNDLE env to point at the skill directory."
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def bundle_file(relative: str) -> Path:
|
|
47
|
+
"""Get absolute path to a bundled file like 'install.sh' or 'adapters/cursor.sh'."""
|
|
48
|
+
return find_bundle_root() / relative
|
memory_bank_skill/cli.py
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
"""memory-bank CLI — thin Python wrapper over install.sh / uninstall.sh.
|
|
2
|
+
|
|
3
|
+
Subcommands:
|
|
4
|
+
install Run global + optional cross-agent adapter install
|
|
5
|
+
uninstall Remove global install
|
|
6
|
+
init Bootstrap .memory-bank/ in current project (hint: use /mb init)
|
|
7
|
+
version Print version string
|
|
8
|
+
self-update Suggest pipx upgrade command
|
|
9
|
+
doctor Print resolved bundle path + platform info
|
|
10
|
+
|
|
11
|
+
Platform support:
|
|
12
|
+
- macOS / Linux: native bash
|
|
13
|
+
- Windows + Git for Windows: auto-detects bash.exe (C:\\Program Files\\Git\\bin\\)
|
|
14
|
+
- Windows + WSL: routes through `wsl bash` if `bash.exe` not found on PATH
|
|
15
|
+
- Windows without either: exits with install hint for Git/WSL
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import argparse
|
|
21
|
+
import os
|
|
22
|
+
import platform
|
|
23
|
+
import shutil
|
|
24
|
+
import subprocess
|
|
25
|
+
import sys
|
|
26
|
+
from pathlib import Path
|
|
27
|
+
|
|
28
|
+
from memory_bank_skill import __version__
|
|
29
|
+
from memory_bank_skill._bundle import find_bundle_root
|
|
30
|
+
|
|
31
|
+
PACKAGE_NAME = "memory-bank-skill"
|
|
32
|
+
VALID_CLIENTS = (
|
|
33
|
+
"claude-code",
|
|
34
|
+
"cursor",
|
|
35
|
+
"windsurf",
|
|
36
|
+
"cline",
|
|
37
|
+
"kilo",
|
|
38
|
+
"opencode",
|
|
39
|
+
"pi",
|
|
40
|
+
"codex",
|
|
41
|
+
)
|
|
42
|
+
VALID_LANGUAGES = ("en", "ru")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# ═══ Platform detection ═══
|
|
46
|
+
def is_windows() -> bool:
|
|
47
|
+
return platform.system().lower() == "windows"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# Common locations where Git for Windows installs bash.exe.
|
|
51
|
+
# Listed in priority order (user install first, system install second).
|
|
52
|
+
WINDOWS_BASH_CANDIDATES: tuple[str, ...] = (
|
|
53
|
+
r"C:\Program Files\Git\bin\bash.exe",
|
|
54
|
+
r"C:\Program Files (x86)\Git\bin\bash.exe",
|
|
55
|
+
r"C:\Users\Public\Git\bin\bash.exe",
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _env_bash_override() -> str | None:
|
|
60
|
+
"""Explicit user override: MB_BASH=/path/to/bash.exe."""
|
|
61
|
+
override = os.environ.get("MB_BASH")
|
|
62
|
+
if override and Path(override).exists():
|
|
63
|
+
return override
|
|
64
|
+
return None
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def find_bash() -> str | None:
|
|
68
|
+
"""Locate a usable bash executable. Returns absolute path or None."""
|
|
69
|
+
# Explicit override wins.
|
|
70
|
+
override = _env_bash_override()
|
|
71
|
+
if override:
|
|
72
|
+
return override
|
|
73
|
+
|
|
74
|
+
# POSIX: `bash` on PATH is the normal case.
|
|
75
|
+
if not is_windows():
|
|
76
|
+
found = shutil.which("bash")
|
|
77
|
+
return found
|
|
78
|
+
|
|
79
|
+
# Windows: prefer `bash.exe` on PATH (Git Bash adds its dir).
|
|
80
|
+
found = shutil.which("bash.exe") or shutil.which("bash")
|
|
81
|
+
if found and "system32" not in found.lower():
|
|
82
|
+
# Guard against WSL's C:\Windows\System32\bash.exe — that launches WSL
|
|
83
|
+
# interactively without forwarding the script path correctly in every
|
|
84
|
+
# environment. Skip it; fall through to explicit Git Bash paths first.
|
|
85
|
+
return found
|
|
86
|
+
|
|
87
|
+
# Check well-known Git for Windows install locations.
|
|
88
|
+
for candidate in WINDOWS_BASH_CANDIDATES:
|
|
89
|
+
if Path(candidate).exists():
|
|
90
|
+
return candidate
|
|
91
|
+
|
|
92
|
+
# Last resort: WSL via `wsl bash`. Only return if wsl.exe exists.
|
|
93
|
+
wsl = shutil.which("wsl.exe") or shutil.which("wsl")
|
|
94
|
+
if wsl:
|
|
95
|
+
return wsl # run_shell() handles the `wsl bash ...` invocation form.
|
|
96
|
+
|
|
97
|
+
return None
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def windows_install_hint() -> str:
|
|
101
|
+
return (
|
|
102
|
+
"memory-bank-skill needs bash on Windows. Install one of:\n"
|
|
103
|
+
" • Git for Windows: winget install Git.Git (provides bash.exe)\n"
|
|
104
|
+
" • WSL: wsl --install (full Linux env)\n"
|
|
105
|
+
"\n"
|
|
106
|
+
"Then re-run the command. Override detection with:\n"
|
|
107
|
+
' set MB_BASH="C:\\path\\to\\bash.exe"\n'
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def require_bash() -> str:
|
|
112
|
+
"""Return path to bash or exit with a helpful message."""
|
|
113
|
+
bash = find_bash()
|
|
114
|
+
if bash:
|
|
115
|
+
return bash
|
|
116
|
+
if is_windows():
|
|
117
|
+
sys.stderr.write(windows_install_hint())
|
|
118
|
+
else:
|
|
119
|
+
sys.stderr.write("[memory-bank] `bash` not found on PATH\n")
|
|
120
|
+
sys.exit(2)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
# ═══ Shell invocation ═══
|
|
124
|
+
def run_shell(script: str, *args: str) -> int:
|
|
125
|
+
"""Execute a bundled shell script, returning its exit code."""
|
|
126
|
+
bundle = find_bundle_root()
|
|
127
|
+
script_path = bundle / script
|
|
128
|
+
if not script_path.is_file():
|
|
129
|
+
sys.stderr.write(f"[memory-bank] missing bundled script: {script_path}\n")
|
|
130
|
+
return 3
|
|
131
|
+
|
|
132
|
+
bash = require_bash()
|
|
133
|
+
bash_lower = bash.lower()
|
|
134
|
+
is_wsl_wrapper = is_windows() and (bash_lower.endswith("wsl.exe") or bash_lower.endswith("wsl"))
|
|
135
|
+
|
|
136
|
+
if is_wsl_wrapper:
|
|
137
|
+
# WSL mode: `wsl bash <script> <args>`. WSL auto-translates C:\ paths
|
|
138
|
+
# under /mnt/c/ when the script resides on the Windows filesystem.
|
|
139
|
+
cmd = [bash, "bash", str(script_path), *args]
|
|
140
|
+
else:
|
|
141
|
+
cmd = [bash, str(script_path), *args]
|
|
142
|
+
|
|
143
|
+
try:
|
|
144
|
+
result = subprocess.run(cmd, check=False) # noqa: S603
|
|
145
|
+
except FileNotFoundError:
|
|
146
|
+
sys.stderr.write(f"[memory-bank] `{bash}` not found on PATH\n")
|
|
147
|
+
return 4
|
|
148
|
+
return result.returncode
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
# ═══ Subcommand handlers ═══
|
|
152
|
+
def cmd_install(args: argparse.Namespace) -> int:
|
|
153
|
+
sh_args: list[str] = []
|
|
154
|
+
if args.clients:
|
|
155
|
+
sh_args.extend(["--clients", args.clients])
|
|
156
|
+
if args.language:
|
|
157
|
+
sh_args.extend(["--language", args.language])
|
|
158
|
+
if args.project_root:
|
|
159
|
+
sh_args.extend(["--project-root", args.project_root])
|
|
160
|
+
if args.non_interactive:
|
|
161
|
+
sh_args.append("--non-interactive")
|
|
162
|
+
return run_shell("install.sh", *sh_args)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def cmd_uninstall(_args: argparse.Namespace) -> int:
|
|
166
|
+
return run_shell("uninstall.sh")
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def cmd_init(args: argparse.Namespace) -> int:
|
|
170
|
+
# `/mb init` is handled by Claude Code command; CLI just hints
|
|
171
|
+
target = args.project_root or os.getcwd()
|
|
172
|
+
sys.stdout.write(
|
|
173
|
+
f"[memory-bank] To initialize Memory Bank for a project, run inside Claude Code:\n"
|
|
174
|
+
f" /mb init\n\n"
|
|
175
|
+
f" Target project: {target}\n"
|
|
176
|
+
f" This creates .memory-bank/ with STATUS.md, checklist.md, plan.md, RESEARCH.md.\n"
|
|
177
|
+
)
|
|
178
|
+
return 0
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def cmd_version(_args: argparse.Namespace) -> int:
|
|
182
|
+
sys.stdout.write(f"memory-bank-skill {__version__}\n")
|
|
183
|
+
return 0
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def cmd_self_update(_args: argparse.Namespace) -> int:
|
|
187
|
+
sys.stdout.write(
|
|
188
|
+
f"To update memory-bank-skill:\n"
|
|
189
|
+
f" pipx upgrade {PACKAGE_NAME}\n\n"
|
|
190
|
+
f"Or (if installed via pip): pip install --upgrade {PACKAGE_NAME}\n"
|
|
191
|
+
)
|
|
192
|
+
return 0
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def cmd_doctor(_args: argparse.Namespace) -> int:
|
|
196
|
+
sys.stdout.write(f"memory-bank-skill {__version__}\n")
|
|
197
|
+
sys.stdout.write(f"Platform: {platform.system()} {platform.release()}\n")
|
|
198
|
+
sys.stdout.write(f"Python: {sys.version.split()[0]}\n")
|
|
199
|
+
try:
|
|
200
|
+
root = find_bundle_root()
|
|
201
|
+
sys.stdout.write(f"Bundle root: {root}\n")
|
|
202
|
+
sys.stdout.write(f"install.sh: {(root / 'install.sh').is_file()}\n")
|
|
203
|
+
sys.stdout.write(f"adapters/: {(root / 'adapters').is_dir()}\n")
|
|
204
|
+
except FileNotFoundError as e:
|
|
205
|
+
sys.stdout.write(f"Bundle: NOT FOUND ({e})\n")
|
|
206
|
+
return 1
|
|
207
|
+
|
|
208
|
+
# Bash discovery: now same report on every platform.
|
|
209
|
+
bash = find_bash()
|
|
210
|
+
if bash:
|
|
211
|
+
sys.stdout.write(f"bash: {bash}\n")
|
|
212
|
+
if is_windows():
|
|
213
|
+
sys.stdout.write(" (Windows: Git Bash / WSL detected — install / uninstall work.)\n")
|
|
214
|
+
else:
|
|
215
|
+
sys.stdout.write("bash: NOT FOUND\n")
|
|
216
|
+
if is_windows():
|
|
217
|
+
sys.stdout.write(windows_install_hint())
|
|
218
|
+
return 1
|
|
219
|
+
return 0
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
# ═══ Argparse ═══
|
|
223
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
224
|
+
parser = argparse.ArgumentParser(
|
|
225
|
+
prog="memory-bank",
|
|
226
|
+
description="Universal long-term project memory for AI coding clients.",
|
|
227
|
+
)
|
|
228
|
+
parser.add_argument("--version", action="version", version=f"memory-bank-skill {__version__}")
|
|
229
|
+
sub = parser.add_subparsers(dest="command", required=True, metavar="COMMAND")
|
|
230
|
+
|
|
231
|
+
p_install = sub.add_parser("install", help="Install skill globally + optional cross-agent adapters")
|
|
232
|
+
p_install.add_argument(
|
|
233
|
+
"--clients",
|
|
234
|
+
help=f"Comma-separated client list. Valid: {', '.join(VALID_CLIENTS)}. "
|
|
235
|
+
"Omit to use interactive menu when running in a TTY.",
|
|
236
|
+
)
|
|
237
|
+
p_install.add_argument(
|
|
238
|
+
"--language",
|
|
239
|
+
choices=VALID_LANGUAGES,
|
|
240
|
+
help=f"Preferred installed rules language. Valid: {', '.join(VALID_LANGUAGES)}.",
|
|
241
|
+
)
|
|
242
|
+
p_install.add_argument("--project-root", help="Target directory for cross-agent adapters (default: PWD)")
|
|
243
|
+
p_install.add_argument(
|
|
244
|
+
"--non-interactive",
|
|
245
|
+
action="store_true",
|
|
246
|
+
help="Skip interactive prompts; use defaults when --clients not specified.",
|
|
247
|
+
)
|
|
248
|
+
p_install.set_defaults(func=cmd_install)
|
|
249
|
+
|
|
250
|
+
p_uninstall = sub.add_parser("uninstall", help="Remove global skill install")
|
|
251
|
+
p_uninstall.set_defaults(func=cmd_uninstall)
|
|
252
|
+
|
|
253
|
+
p_init = sub.add_parser("init", help="Print initialization hint (use /mb init inside Claude Code)")
|
|
254
|
+
p_init.add_argument("--project-root", help="Target project directory (default: PWD)")
|
|
255
|
+
p_init.set_defaults(func=cmd_init)
|
|
256
|
+
|
|
257
|
+
p_version = sub.add_parser("version", help="Print version")
|
|
258
|
+
p_version.set_defaults(func=cmd_version)
|
|
259
|
+
|
|
260
|
+
p_update = sub.add_parser("self-update", help="Show upgrade command")
|
|
261
|
+
p_update.set_defaults(func=cmd_self_update)
|
|
262
|
+
|
|
263
|
+
p_doctor = sub.add_parser("doctor", help="Show bundle resolution + platform info")
|
|
264
|
+
p_doctor.set_defaults(func=cmd_doctor)
|
|
265
|
+
|
|
266
|
+
return parser
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def main(argv: list[str] | None = None) -> int:
|
|
270
|
+
parser = build_parser()
|
|
271
|
+
args = parser.parse_args(argv)
|
|
272
|
+
return args.func(args)
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: memory-bank
|
|
3
|
+
description: "Agent-agnostic long-term project memory through `.memory-bank/` + RULES (TDD/SOLID/Clean Architecture/FSD/Mobile) + dev-toolkit commands. Use when working in a project with a `.memory-bank/` directory or when the user explicitly asks for memory-bank workflow, code rules, or dev-toolkit commands."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Memory Bank Skill
|
|
7
|
+
|
|
8
|
+
Three-in-one skill for code agents:
|
|
9
|
+
|
|
10
|
+
1. **Memory Bank** — long-term project memory through `.memory-bank/` (`STATUS`, `plan`, `checklist`, `RESEARCH`, `BACKLOG`, `progress`, `lessons`, `notes/`, `plans/`, `experiments/`, `reports/`, `codebase/`).
|
|
11
|
+
2. **RULES** — global engineering rules: TDD, Clean Architecture (backend), FSD (frontend), Mobile (iOS/Android UDF), SOLID, Testing Trophy.
|
|
12
|
+
3. **Dev toolkit** — 18 commands: `/mb`, `/commit`, `/review`, `/test`, `/plan`, `/pr`, `/adr`, `/contract`, `/security-review`, `/db-migration`, `/api-contract`, `/observability`, `/refactor`, `/doc`, `/changelog`, `/catchup`, `/start`, `/done`.
|
|
13
|
+
|
|
14
|
+
Supported host model:
|
|
15
|
+
- **Claude Code / OpenCode** — native command surface + global install.
|
|
16
|
+
- **Cursor** — native full support: global skill alias (`~/.cursor/skills/memory-bank/`), global hooks (`~/.cursor/hooks.json`), global slash commands (`~/.cursor/commands/`), `~/.cursor/AGENTS.md` with managed section, plus a paste-ready file for Settings → Rules → User Rules. Project-level `.cursor/` adapter remains available as an add-on via `--clients cursor`.
|
|
17
|
+
- **Codex** — global skill discovery + `AGENTS.md` hints + project-level `.codex/` adapter; no separate native slash-command surface.
|
|
18
|
+
- **Other code agents** — via adapters, `AGENTS.md`, local hooks/configs, or direct CLI/script usage.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Quick start
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Initialization (stack auto-detect + CLAUDE.md generation)
|
|
26
|
+
/mb init # same as /mb init --full
|
|
27
|
+
/mb init --minimal # only the .memory-bank/ structure
|
|
28
|
+
|
|
29
|
+
# Session flow
|
|
30
|
+
/mb start # load context
|
|
31
|
+
# ... work, checklist.md updates as tasks complete ...
|
|
32
|
+
/mb verify # verify plan alignment (if there was a plan)
|
|
33
|
+
/mb done # actualize + note + progress
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
If the host does not support native slash commands, use:
|
|
37
|
+
- `commands/mb.md` as the workflow entrypoint;
|
|
38
|
+
- the `memory-bank ...` CLI for install/init/doctor flows;
|
|
39
|
+
- bundled scripts and agent prompts from this skill bundle.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Workspace resolution
|
|
44
|
+
|
|
45
|
+
Memory Bank supports external storage through `.claude-workspace`:
|
|
46
|
+
|
|
47
|
+
- If the project root contains `.claude-workspace` with `storage: external` and `project_id: <id>` → `mb_path = ~/.claude/workspaces/<id>/.memory-bank`
|
|
48
|
+
- Otherwise → `mb_path = ./.memory-bank` (default)
|
|
49
|
+
|
|
50
|
+
When invoking MB Manager or scripts, always pass the resolved `mb_path`.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Tools — shell scripts
|
|
55
|
+
|
|
56
|
+
All scripts live in `scripts/` next to this `SKILL.md`. In global installs, the bundle is typically available through host aliases:
|
|
57
|
+
- Claude Code: `~/.claude/skills/memory-bank/`
|
|
58
|
+
- Codex: `~/.codex/skills/memory-bank/`
|
|
59
|
+
- Cursor: `~/.cursor/skills/memory-bank/`
|
|
60
|
+
|
|
61
|
+
Scripts work with `.memory-bank/` in the current directory or through the `mb_path` argument.
|
|
62
|
+
|
|
63
|
+
| Script | Purpose |
|
|
64
|
+
|--------|---------|
|
|
65
|
+
| `mb-context.sh [--deep]` | Build context from core files (`STATUS` + `plan` + `checklist` + `RESEARCH` + codebase summary). `--deep` shows full codebase docs |
|
|
66
|
+
| `mb-search.sh <q> [--tag t]` | Search. `--tag` filters via `index.json` |
|
|
67
|
+
| `mb-note.sh <topic>` | Create `notes/YYYY-MM-DD_HH-MM_<topic>.md`. Collision-safe (`_2` / `_3`) |
|
|
68
|
+
| `mb-plan.sh <type> <topic>` | Create `plans/YYYY-MM-DD_<type>_<topic>.md` with `<!-- mb-stage:N -->` markers |
|
|
69
|
+
| `mb-plan-sync.sh <plan>` | Synchronize plan ↔ checklist + `plan.md` (idempotent) |
|
|
70
|
+
| `mb-plan-done.sh <plan>` | Close a plan: `⬜→✅` + move to `plans/done/` |
|
|
71
|
+
| `mb-metrics.sh [--run]` | Language-agnostic metrics (12 stacks). `--run` captures `test_status=pass|fail` |
|
|
72
|
+
| `mb-index.sh` | Registry of all entries (core + notes/plans/experiments/reports) |
|
|
73
|
+
| `mb-index-json.py` | Build `index.json` (frontmatter notes + lessons headings). Atomic |
|
|
74
|
+
| `mb-upgrade.sh [--check|--force]` | Self-update the skill from GitHub |
|
|
75
|
+
| `_lib.sh` | Shared helpers sourced by other scripts |
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Agents — subagents (sonnet)
|
|
80
|
+
|
|
81
|
+
| Agent | When to invoke | Prompt |
|
|
82
|
+
|-------|----------------|--------|
|
|
83
|
+
| `mb-manager` | `/mb context`, `search`, `note`, `tasks`, `done`, `update`, PreCompact hook | `agents/mb-manager.md` |
|
|
84
|
+
| `mb-doctor` | `/mb doctor` — memory-bank inconsistencies (use `mb-plan-sync.sh` first, only edit for semantic drift) | `agents/mb-doctor.md` |
|
|
85
|
+
| `mb-codebase-mapper` | `/mb map [focus]` — scan the codebase → `.memory-bank/codebase/{STACK,ARCHITECTURE,CONVENTIONS,CONCERNS}.md` | `agents/mb-codebase-mapper.md` |
|
|
86
|
+
| `plan-verifier` | `/mb verify` — required before `/mb done` when work followed a plan | `agents/plan-verifier.md` |
|
|
87
|
+
|
|
88
|
+
Do **NOT** delegate plan creation, architectural decisions, or ML-result evaluation to a subagent — that is main-agent work.
|
|
89
|
+
|
|
90
|
+
### Invocation format
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
Agent(
|
|
94
|
+
subagent_type="general-purpose",
|
|
95
|
+
model="sonnet",
|
|
96
|
+
description="<description>",
|
|
97
|
+
prompt="<contents of agents/<agent>.md>\n\naction: <action>\n\n<context>"
|
|
98
|
+
)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Host-specific notes
|
|
104
|
+
|
|
105
|
+
### Claude Code and native memory
|
|
106
|
+
|
|
107
|
+
Claude Code has built-in `auto memory` (user-level cross-project memory in `~/.claude/projects/.../memory/`). This skill does **not replace** it — the two complement each other:
|
|
108
|
+
|
|
109
|
+
| Aspect | `.memory-bank/` | Native `auto memory` |
|
|
110
|
+
|--------|------------------|----------------------|
|
|
111
|
+
| Scope | Project | User, cross-project |
|
|
112
|
+
| Stores | Status, plans, checklists, research, ADRs, lessons | Preferences, role, feedback |
|
|
113
|
+
| Owner | Team (via git) | Individual user |
|
|
114
|
+
|
|
115
|
+
Rule of thumb: if it helps a teammate pick up the project tomorrow, store it in `.memory-bank/`. If it helps you in another project, store it in native memory. They can coexist without conflict.
|
|
116
|
+
|
|
117
|
+
### Codex
|
|
118
|
+
|
|
119
|
+
For Codex, this skill is positioned as a global skill bundle plus a guidance layer:
|
|
120
|
+
- discovery goes through `~/.codex/skills/memory-bank/`
|
|
121
|
+
- global entrypoint/guidance goes through `~/.codex/AGENTS.md`
|
|
122
|
+
- hook/config integration remains primarily project-level through `.codex/`
|
|
123
|
+
|
|
124
|
+
Codex therefore uses the same Memory Bank workflow, but it does not need to expose the same native command surface as Claude Code/OpenCode.
|
|
125
|
+
|
|
126
|
+
### Cursor
|
|
127
|
+
|
|
128
|
+
Cursor is a first-class global target. `install.sh` writes five artifacts to `~/.cursor/`:
|
|
129
|
+
|
|
130
|
+
| Artifact | Purpose |
|
|
131
|
+
|----------|---------|
|
|
132
|
+
| `~/.cursor/skills/memory-bank/` | Personal skill alias — Cursor auto-discovers it by description |
|
|
133
|
+
| `~/.cursor/hooks.json` + `~/.cursor/hooks/*.sh` | Global hooks: `sessionEnd` (autosave), `preCompact` (reminder), `beforeShellExecution` (block-dangerous). Each entry tagged `_mb_owned: true` so user hooks are preserved |
|
|
134
|
+
| `~/.cursor/commands/*.md` | User-level slash commands mirrored from the skill `commands/` directory |
|
|
135
|
+
| `~/.cursor/AGENTS.md` | Marker section `memory-bank-cursor:start/end` — entrypoint for future Cursor versions that read global `AGENTS.md` |
|
|
136
|
+
| `~/.cursor/memory-bank-user-rules.md` | Paste-ready rules bundle for **Settings → Rules → User Rules** (Cursor exposes no file API for global User Rules, so this is a one-time manual step) |
|
|
137
|
+
|
|
138
|
+
Cursor User Rules paste flow:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
# macOS
|
|
142
|
+
pbcopy < ~/.cursor/memory-bank-user-rules.md
|
|
143
|
+
# Linux
|
|
144
|
+
xclip -selection clipboard < ~/.cursor/memory-bank-user-rules.md
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The project-level adapter (`.cursor/rules/memory-bank.mdc` + `.cursor/hooks.json`) remains available and is installed only when the user passes `--clients cursor`. Global and project-level installs coexist — Cursor merges hooks from both.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Private content — `<private>...</private>` (since v2.1)
|
|
152
|
+
|
|
153
|
+
Markdown syntax for excluding sensitive information (client data, API keys, partner names) from indexing and search:
|
|
154
|
+
|
|
155
|
+
```markdown
|
|
156
|
+
---
|
|
157
|
+
type: note
|
|
158
|
+
tags: [auth, partner-x]
|
|
159
|
+
importance: high
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
Discussed with client <private>Jane Doe, +1-555-***</private>.
|
|
163
|
+
Integration with <private>api_key=sk-abc123...</private> is scheduled for Tuesday.
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Protection model:**
|
|
167
|
+
- Content inside `<private>...</private>` does **not** go into `index.json` (neither `summary` nor `tags`)
|
|
168
|
+
- `mb-search` output redacts it as `[REDACTED]` (inline) or `[REDACTED match in private block]` (multi-line)
|
|
169
|
+
- The entry gets a `has_private: true` flag for downstream filtering
|
|
170
|
+
- An unclosed `<private>` without `</private>` makes the rest of the file private (fail-safe)
|
|
171
|
+
- `hooks/file-change-log.sh` warns when committing a file containing `<private>` blocks (reminder to review git exposure)
|
|
172
|
+
|
|
173
|
+
**Double confirmation for reveal:**
|
|
174
|
+
```bash
|
|
175
|
+
# Rejected without env:
|
|
176
|
+
mb-search --show-private <query>
|
|
177
|
+
# [error] --show-private requires MB_SHOW_PRIVATE=1
|
|
178
|
+
|
|
179
|
+
# Only with explicit opt-in:
|
|
180
|
+
MB_SHOW_PRIVATE=1 mb-search --show-private <query>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Important:** `<private>` protects against leakage through `index.json` / `mb-search`, but it does **not** filter `git diff`. For full protection, consider `.gitattributes` filters or git hooks.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Auto-capture (since v2.1)
|
|
188
|
+
|
|
189
|
+
The SessionEnd hook automatically appends a placeholder entry to `progress.md` when a session ends without an explicit `/mb done`. Work is not lost even if manual actualization was skipped.
|
|
190
|
+
|
|
191
|
+
**Modes (`MB_AUTO_CAPTURE` env):**
|
|
192
|
+
- `auto` (default) — hook writes an entry on session end
|
|
193
|
+
- `strict` — hook skips but prints a warning to stderr (for flows where manual actualization is required)
|
|
194
|
+
- `off` — full noop
|
|
195
|
+
|
|
196
|
+
**How it works:**
|
|
197
|
+
- After successful `/mb done`, the command writes `.memory-bank/.session-lock` → the hook sees the fresh lock (<1h) and skips auto-capture (manual actualization already happened)
|
|
198
|
+
- Without a lock, the hook adds a short note to `progress.md`. Full details can be reconstructed by `/mb start` in the next session (MB Manager can read the JSONL transcript)
|
|
199
|
+
- Concurrency-safe through a short `.auto-lock` (30 seconds) — prevents duplicates on parallel invocations
|
|
200
|
+
- Idempotent by `session_id` — same session + same day = one entry
|
|
201
|
+
|
|
202
|
+
**Opt-out:** `export MB_AUTO_CAPTURE=off` in `~/.zshrc` or disable the hook via `/mb upgrade` once that flag is available.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Weekly compact reminder (since v2.2.1)
|
|
207
|
+
|
|
208
|
+
The SessionEnd hook `hooks/mb-compact-reminder.sh` reminds the user to run `/mb compact` once a week — **only if the user has explicitly run `/mb compact --apply` at least once** (which creates `.memory-bank/.last-compact`). It is opt-in by design, so new installs stay silent.
|
|
209
|
+
|
|
210
|
+
**Logic:**
|
|
211
|
+
- `.last-compact` missing → silent (user not subscribed)
|
|
212
|
+
- `.last-compact` < 7 days → silent
|
|
213
|
+
- `.last-compact` ≥ 7 days + `mb-compact.sh --dry-run` shows `candidates > 0` → reminder to stderr with a `/mb compact` hint
|
|
214
|
+
- `.last-compact` ≥ 7 days + `candidates=0` → silent (nothing to compact)
|
|
215
|
+
|
|
216
|
+
**Opt-out:** `export MB_COMPACT_REMIND=off`. Read-only — it never changes files.
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## References
|
|
221
|
+
|
|
222
|
+
- Metadata protocol + `index.json` + 8 key rules: `references/metadata.md`
|
|
223
|
+
- Planning + Plan Verifier workflow: `references/planning-and-verification.md`
|
|
224
|
+
- Templates: `references/templates.md`
|
|
225
|
+
- Structure: `references/structure.md`
|
|
226
|
+
- Workflow: `references/workflow.md`
|
|
227
|
+
- CHANGELOG: `CHANGELOG.md`
|
|
228
|
+
- Migration v1→v2: `docs/MIGRATION-v1-v2.md`
|
|
229
|
+
- Primary entrypoint:
|
|
230
|
+
- `/mb` — if the host supports native commands
|
|
231
|
+
- `commands/mb.md` / `memory-bank` CLI — if native command surface is unavailable
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.0.0
|