"""graphlemon's own local runtime directory (U-003). architecture doc §13.2 "原始执行日志的存放位置" / 01-M 1.13 execution_log_file.file_path both give `~/.graphlemon/logs////.jsonl` as an *example* path, not a hard spec -- this module is what makes that example the actual convention (overridable via GRAPHLEMON_HOME, e.g. for tests). The default lives under the user's home directory, deliberately outside this repo's own checkout -- that's what makes "日志目录不纳入平台自身 Git 历史" (U-003's Done criterion) true by construction rather than by a .gitignore rule someone could forget to add. """ import os def platform_home(): """graphlemon's own local runtime directory root.""" override = os.environ.get("GRAPHLEMON_HOME") if override: return os.path.abspath(override) return os.path.join(os.path.expanduser("~"), ".graphlemon") def log_dir(): return os.path.join(platform_home(), "logs") def db_path(): """graphlemon's own sqlite database file (U-001 schema), same GRAPHLEMON_HOME-overridable root as everything else in this module.""" return os.path.join(platform_home(), "graphlemon.db") def log_file_path(project_id, task_id, run_id, node_exec_id): """01-M 1.13 execution_log_file.file_path convention.""" return os.path.join(log_dir(), project_id, task_id, run_id, node_exec_id + ".jsonl") def is_separate_from(target_folder_path): """True if graphlemon's platform home neither contains nor is contained by target_folder_path -- the physical-separation property U-003's Done criterion requires between the platform directory and any target project.""" home = os.path.realpath(platform_home()) target = os.path.realpath(target_folder_path) if home == target: return False home_prefix = home.rstrip(os.sep) + os.sep target_prefix = target.rstrip(os.sep) + os.sep return not target.startswith(home_prefix) and not home.startswith(target_prefix) def repo_root(): """graphlemon's own code checkout root (the directory containing `src/`, `.git`, `docs/`, ...) -- distinct from platform_home() (the ~/.graphlemon *runtime* directory for logs/db, deliberately outside the checkout). U-035 (05 §5.8 self-target rules) needs this to detect when a task's `target_folder_path` IS graphlemon's own repo.""" return os.path.dirname(os.path.dirname(os.path.abspath(__file__))) def is_self_target(target_folder_path, repo_root_path=None): """05 §5.8: `target_folder_path == graphlemon 平台自身安装路径`. Compares realpaths so a symlinked or relative target_folder_path still matches. `repo_root_path` defaults to this running instance's own checkout (`repo_root()`) but can be overridden -- e.g. by a test simulating a self-target scenario against a throwaway clone rather than this actual running checkout.""" root = repo_root_path if repo_root_path is not None else repo_root() return os.path.realpath(target_folder_path) == os.path.realpath(root)