From 2503ac6c6bf735ef082427cbf0a18b68ae6181ff Mon Sep 17 00:00:00 2001 From: Ruben Ramirez Date: Fri, 13 Mar 2026 20:31:43 -0500 Subject: [PATCH] feat: add --skill-dir and --vault-dir arguments for custom directories - Add --skill-dir to override source skills directory - Add --vault-dir to override destination vault directory - Fix symlink handling to prevent source deletion - Fix shutil.move to use explicit destination path --- .megamemory/knowledge.db | Bin 0 -> 4096 bytes .megamemory/knowledge.db-shm | Bin 0 -> 32768 bytes .megamemory/knowledge.db-wal | Bin 0 -> 152472 bytes setup.py | 39 +++++++++++++++++++++++++++++------ 4 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 .megamemory/knowledge.db create mode 100644 .megamemory/knowledge.db-shm create mode 100644 .megamemory/knowledge.db-wal diff --git a/.megamemory/knowledge.db b/.megamemory/knowledge.db new file mode 100644 index 0000000000000000000000000000000000000000..0a06b00940a2e489182e153184a104fe6003c831 GIT binary patch literal 4096 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 Q@7t=Fw)XLpG>9+oUoIT;+yDRo literal 0 HcmV?d00001 diff --git a/setup.py b/setup.py index 7441f8e..12ba739 100644 --- a/setup.py +++ b/setup.py @@ -454,7 +454,9 @@ def get_category_for_skill(skill_name: str) -> str: exact_match = False if skill_name.startswith('"') and skill_name.endswith('"'): exact_match = True - name_lower = skill_name[1:-1].strip().lower().replace("_", "-").replace(" ", "-") + name_lower = ( + skill_name[1:-1].strip().lower().replace("_", "-").replace(" ", "-") + ) else: name_lower = skill_name.lower().replace("_", "-") @@ -523,9 +525,12 @@ def migrate_skills(): dest = cat_dir / folder.name if dest.exists(): - shutil.rmtree(dest) + if dest.is_symlink() or dest.is_file(): + dest.unlink() + else: + shutil.rmtree(dest) - shutil.move(str(folder), str(cat_dir)) + shutil.move(str(folder), str(dest)) category_counts[category] = category_counts.get(category, 0) + 1 moved_count += 1 @@ -625,9 +630,26 @@ def generate_pointers(category_counts): def main(): import argparse - parser = argparse.ArgumentParser(description="SkillPointer Setup - Infinite Context. Zero Token Tax.") - parser.add_argument("--agent", choices=["opencode", "claude"], default="opencode", - help="Target AI agent (opencode or claude)") + + parser = argparse.ArgumentParser( + description="SkillPointer Setup - Infinite Context. Zero Token Tax." + ) + parser.add_argument( + "--agent", + choices=["opencode", "claude"], + default="opencode", + help="Target AI agent (opencode or claude)", + ) + parser.add_argument( + "--skill-dir", + type=str, + help="Directory to search for skills (overrides --agent default)", + ) + parser.add_argument( + "--vault-dir", + type=str, + help="Directory to move skills to when creating pointers (overrides --agent default)", + ) args, unknown = parser.parse_known_args() if args.agent == "claude": @@ -635,6 +657,11 @@ def main(): CONFIG["active_skills_dir"] = Path.home() / ".claude" / "skills" CONFIG["hidden_library_dir"] = Path.home() / ".skillpointer-vault" + if args.skill_dir: + CONFIG["active_skills_dir"] = Path(args.skill_dir).expanduser().resolve() + if args.vault_dir: + CONFIG["hidden_library_dir"] = Path(args.vault_dir).expanduser().resolve() + # Handle 'install' argument for compatibility with Install.bat/vbs if unknown and unknown[0] == "install": pass