From b3448031088447d76d80ac6b2bfa08320973a2d9 Mon Sep 17 00:00:00 2001 From: Igor Soarez Date: Thu, 29 Oct 2026 21:40:43 +0000 Subject: pi: generate mcp.json from ~/.config/pi/mcp.d fragments pi reads user-level MCP servers from one file, and a private layer linked that file to the same copy on every host -- so every host got a server only one machine could run. Build it the way models.json is built, from fragments another layer or one machine drops in mcp.d; this repo ships none, and with none the file is left absent. pi-models.py becomes pi-merge.py, which takes the key to merge and an optional base file, and serves both. --- link/pi-models.py | 66 ------------------------------------------------------- 1 file changed, 66 deletions(-) delete mode 100644 link/pi-models.py (limited to 'link/pi-models.py') diff --git a/link/pi-models.py b/link/pi-models.py deleted file mode 100644 index 6188c94..0000000 --- a/link/pi-models.py +++ /dev/null @@ -1,66 +0,0 @@ -"""Generate ~/.pi/agent/models.json from the repo and its fragments. - -Run by link/pi.sh. It lives in a file rather than a heredoc inside $( ): -macOS ships bash 3.2, which does not skip heredoc content when it scans -for the end of a command substitution, so an odd number of apostrophes in -here would stop the whole script parsing -- which it did, on 2026-09-25. -""" - -import glob, json, os, sys - -base_path, frag_dir, target = sys.argv[1:4] - - -def load(path): - with open(path) as f: - return json.load(f) - - -# The repo's providers, then each fragment's. A fragment may add a provider or -# replace one of the same name; any other top-level key takes the last file's -# value. Which provider came from where is reported: a fragment quietly -# shadowing a provider the repo ships would otherwise be invisible. -desired = {} -notes = [] -for path in [base_path] + sorted(glob.glob(os.path.join(frag_dir, "*.json"))): - try: - layer = load(path) - except (OSError, ValueError) as e: - print("error:cannot read %s: %s" % (path, e)) - sys.exit(0) - for key, value in layer.items(): - if key == "providers": - providers = desired.setdefault("providers", {}) - if path != base_path: - for name in value: - notes.append("%s %s by %s" % ( - name, - "replaced" if name in providers else "added", - os.path.basename(path), - )) - providers.update(value) - else: - desired[key] = value - -# A symlink is the pre-generation state: replace it, even with no fragments, so -# the live file is never the tracked one. -was_link = os.path.islink(target) -try: - current = None if was_link else load(target) -except (OSError, ValueError): - current = None - -for note in notes: - print("note:" + note) - -if current == desired: - print("unchanged:") -elif os.environ.get("DRY_RUN"): - print("would-write:" + ("replacing the link" if was_link else "merged changes")) -else: - tmp = target + ".dotfiles-tmp" - with open(tmp, "w") as f: - json.dump(desired, f, indent=2) - f.write("\n") - os.replace(tmp, target) - print("wrote:" + ("replaced the link" if was_link else "merged changes")) -- cgit v1.2.3