← Files Memova.aiARCHIVED FILE
scripts/kb_setup_reminder.py
5.34 KB · Nov 10, 2026 · 06:32 UTC
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import json
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
STATE_PATH = Path.home() / ".cache" / "memova-codex-plugin" / "kb-setup-reminder-v1.json"
def main() -> int:
parser = argparse.ArgumentParser(description="Check one-time Memova knowledge-base setup reminder state.")
parser.add_argument("--mark-complete", action="store_true")
parser.add_argument("--vault-path")
parser.add_argument(
"--backend-completed",
action="store_true",
help=(
"Required with --mark-complete. Set only after complete_knowledge_base_setup "
"succeeds for the same setup session."
),
)
parser.add_argument(
"--setup-session-id",
help="Backend setup session id that was completed before marking the local reminder complete.",
)
args = parser.parse_args()
state = read_state()
discovered = discover_vaults(args.vault_path)
if args.mark_complete:
if not args.backend_completed or not args.setup_session_id:
print_json(
{
"schema_version": "memova_kb_setup_reminder_v1",
"status": "blocked",
"error_code": "backend_setup_completion_required",
"error": (
"--mark-complete is allowed only after the backend "
"complete_knowledge_base_setup call succeeds. Re-run with "
"--backend-completed and --setup-session-id after that MCP call."
),
"should_remind": True,
"state_path": str(STATE_PATH),
"discovered_vaults": discovered,
},
)
return 2
state["completed_at"] = utc_now()
state["setup_session_id"] = args.setup_session_id
state["backend_completed"] = True
if args.vault_path:
state["vault_path"] = str(Path(args.vault_path).expanduser().resolve(strict=False))
write_state(state)
print_json(
{
"schema_version": "memova_kb_setup_reminder_v1",
"status": "complete_marked",
"should_remind": False,
"state_path": str(STATE_PATH),
"discovered_vaults": discovered,
},
)
return 0
if discovered and not state.get("completed_at"):
state["completed_at"] = utc_now()
state["vault_path"] = discovered[0]["vault_path"]
write_state(state)
should_remind = not discovered and not state.get("reminded_at") and not state.get("completed_at")
if should_remind:
state["reminded_at"] = utc_now()
write_state(state)
print_json(
{
"schema_version": "memova_kb_setup_reminder_v1",
"should_remind": should_remind,
"already_reminded": bool(state.get("reminded_at")) and not should_remind,
"completed": bool(state.get("completed_at") or discovered),
"state_path": str(STATE_PATH),
"discovered_vaults": discovered,
"message": (
"Memova knowledge base is not set up on this Mac yet. You can run "
"'@memova Set up knowledge base.' when you want Codex to create or connect it."
if should_remind
else None
),
},
)
return 0
def utc_now() -> str:
return datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
def read_state() -> dict[str, Any]:
if not STATE_PATH.exists():
return {}
try:
return json.loads(STATE_PATH.read_text(encoding="utf-8"))
except json.JSONDecodeError:
return {}
def write_state(state: dict[str, Any]) -> None:
STATE_PATH.parent.mkdir(parents=True, exist_ok=True)
STATE_PATH.write_text(json.dumps(state, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
def discover_vaults(extra_path: str | None = None) -> list[dict[str, str]]:
candidates: list[Path] = []
home = Path.home()
if extra_path:
candidates.append(Path(extra_path).expanduser())
candidates.extend(
[
home / "Library" / "Mobile Documents" / "com~apple~CloudDocs" / "Memova Vault",
home / "Library" / "Mobile Documents" / "com~apple~CloudDocs" / "Memova",
home / "Documents" / "Memova Vault",
],
)
discovered: list[dict[str, str]] = []
seen: set[str] = set()
for candidate in candidates:
root = candidate.resolve(strict=False)
manifest = root / "_memova" / "manifest.json"
key = str(root)
if key in seen or not manifest.is_file():
continue
seen.add(key)
manifest_id = ""
try:
manifest_id = str(json.loads(manifest.read_text(encoding="utf-8")).get("manifest_id") or "")
except json.JSONDecodeError:
manifest_id = ""
discovered.append(
{
"vault_path": key,
"manifest_path": str(manifest),
"manifest_id": manifest_id,
},
)
return discovered
def print_json(data: dict[str, Any]) -> None:
print(json.dumps(data, indent=2, ensure_ascii=False))
if __name__ == "__main__":
raise SystemExit(main())
SHA-256: cdb69e55bcf1faa65fa6664a4bd6a91abf7f9ab11db0ff7be5245c4c2a713fe5