124 lines
3.6 KiB
Python
Executable File
124 lines
3.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""odysseus-personal — shell wrapper for the personal-docs RAG index.
|
|
|
|
`data/personal_docs/` holds local files indexed into RAG so chat can
|
|
recall their content (`contacts.txt`, runbook fragments, etc.). This
|
|
CLI lists indexed directories + manages the index.
|
|
|
|
odysseus-personal list # files currently in the index
|
|
odysseus-personal dirs # tracked directory roots
|
|
odysseus-personal add-dir DIR
|
|
odysseus-personal remove-dir DIR
|
|
odysseus-personal reload # re-scan all dirs
|
|
odysseus-personal exclude PATH # mark a file as excluded
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
import sys
|
|
import os, sys
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "_lib"))
|
|
from cli import quiet_logs, emit, fail, common_parser, run, REPO_ROOT as _REPO_ROOT
|
|
quiet_logs()
|
|
|
|
import argparse, json, logging, os, sys
|
|
from pathlib import Path
|
|
|
|
try:
|
|
from src.personal_docs import PersonalDocsManager
|
|
quiet_logs()
|
|
except ModuleNotFoundError as e:
|
|
sys.stderr.write(f"error: {e}\nhint: run from repo root with venv active.\n")
|
|
sys.exit(2)
|
|
|
|
|
|
_DATA_DIR = str(_REPO_ROOT / "data")
|
|
_mgr: PersonalDocsManager | None = None
|
|
|
|
|
|
def _manager() -> PersonalDocsManager:
|
|
global _mgr
|
|
if _mgr is None:
|
|
_mgr = PersonalDocsManager(_DATA_DIR)
|
|
return _mgr
|
|
|
|
|
|
def cmd_list(args):
|
|
files = getattr(_manager(), "index", []) or []
|
|
out = [
|
|
{"name": f.get("name"), "size": f.get("size"), "path": f.get("path", "")}
|
|
for f in files
|
|
]
|
|
emit(out[: args.limit], args)
|
|
|
|
|
|
def cmd_dirs(args):
|
|
fn = getattr(_manager(), "get_indexed_directories", None)
|
|
if fn is None:
|
|
emit([], args)
|
|
return
|
|
emit(fn() or [], args)
|
|
|
|
|
|
def cmd_add_dir(args):
|
|
fn = getattr(_manager(), "add_directory", None)
|
|
if fn is None:
|
|
fail("PersonalDocsManager has no add_directory method on this version")
|
|
fn(args.directory)
|
|
emit({"ok": True, "directory": args.directory}, args)
|
|
|
|
|
|
def cmd_remove_dir(args):
|
|
fn = getattr(_manager(), "remove_directory", None)
|
|
if fn is None:
|
|
fail("PersonalDocsManager has no remove_directory method on this version")
|
|
fn(args.directory)
|
|
emit({"ok": True, "directory": args.directory}, args)
|
|
|
|
|
|
def cmd_reload(args):
|
|
_manager().refresh_index()
|
|
emit({"ok": True, "count": len(_manager().index)}, args)
|
|
|
|
|
|
def cmd_exclude(args):
|
|
fn = getattr(_manager(), "exclude_file", None)
|
|
if fn is None:
|
|
fail("PersonalDocsManager has no exclude_file method on this version")
|
|
fn(args.path)
|
|
emit({"ok": True, "excluded": args.path}, args)
|
|
|
|
|
|
def _build_parser():
|
|
common = argparse.ArgumentParser(add_help=False)
|
|
common.add_argument("--pretty", action="store_true")
|
|
p = argparse.ArgumentParser(prog="odysseus-personal", parents=[common])
|
|
sub = p.add_subparsers(dest="cmd", required=True)
|
|
|
|
pl = sub.add_parser("list", parents=[common])
|
|
pl.add_argument("--limit", type=int, default=500)
|
|
pl.set_defaults(func=cmd_list)
|
|
|
|
pd = sub.add_parser("dirs", parents=[common])
|
|
pd.set_defaults(func=cmd_dirs)
|
|
|
|
pa = sub.add_parser("add-dir", parents=[common])
|
|
pa.add_argument("directory")
|
|
pa.set_defaults(func=cmd_add_dir)
|
|
|
|
pr = sub.add_parser("remove-dir", parents=[common])
|
|
pr.add_argument("directory")
|
|
pr.set_defaults(func=cmd_remove_dir)
|
|
|
|
prl = sub.add_parser("reload", parents=[common])
|
|
prl.set_defaults(func=cmd_reload)
|
|
|
|
pex = sub.add_parser("exclude", parents=[common])
|
|
pex.add_argument("path")
|
|
pex.set_defaults(func=cmd_exclude)
|
|
|
|
return p
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(run(_build_parser()))
|