#!/usr/bin/env python3 """instance_info.py — onboarding concierge đọc bối cảnh INSTANCE (tier + dashboard). Cho skill onboarding biết: gói (tier) nào để giới thiệu đúng tính năng mở khóa, và link dashboard (nếu deploy đã ghi). Tất định, stdlib only. KHÔNG đọc dữ liệu per-user (riêng tư). python3 lib/instance_info.py -> JSON {tier, dashboard, dashboard_url, dashboard_user} Nguồn: - tier + dashboard flag: /BUILD.txt (build_client ghi). None ở dev/source (chưa build). - dashboard_url: /instance/dashboard.txt (setup_dashboard.sh ghi khi deploy). None nếu chưa. """ import os import json def _bundle_root(): """Thư mục chứa BUILD.txt — đi lên từ cwd (skill chạy ở products/ceo) rồi từ __file__.""" for start in (os.getcwd(), os.path.dirname(os.path.abspath(__file__))): d = start for _ in range(5): if os.path.isfile(os.path.join(d, "BUILD.txt")): return d nd = os.path.dirname(d) if nd == d: break d = nd return None def main(): root = _bundle_root() tier = None dashboard = False if root: try: for line in open(os.path.join(root, "BUILD.txt"), encoding="utf-8"): s = line.strip() if s.startswith("tier:"): tier = s.split(":", 1)[1].strip() or None elif s.startswith("dashboard:"): dashboard = "true" in s.lower() except Exception: pass dash_url = None dash_user = None if root: try: for line in open(os.path.join(root, "instance", "dashboard.txt"), encoding="utf-8"): s = line.strip() if s.startswith("url:"): dash_url = s.split(":", 1)[1].strip() or None elif s.startswith("user:"): dash_user = s.split(":", 1)[1].strip() or None except Exception: pass print(json.dumps({ "tier": tier, "dashboard": dashboard, "dashboard_url": dash_url, "dashboard_user": dash_user, }, ensure_ascii=False)) if __name__ == "__main__": main()