136 lines
4.0 KiB
Python
136 lines
4.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Build a fresh, independently recomputed classification of the live Hermes
|
|
fleet + the troupe repo working tree, for the 'sol' triage lane.
|
|
|
|
Classes (every item is tagged with a stable class string):
|
|
active-profile / deleted-profile
|
|
active-skill / archived-skill
|
|
plugin / memory / cron-fire
|
|
git-untracked / git-modified
|
|
"""
|
|
import json
|
|
import os
|
|
import glob
|
|
import subprocess
|
|
from datetime import datetime, timezone
|
|
|
|
HERMES = "/root/.hermes"
|
|
REPO = "/root/troupe-standup"
|
|
OUT = os.path.join(HERMES, "wizard-outputs", "sol", "fleet-classify-2026-11-01.json")
|
|
MD = os.path.join(HERMES, "wizard-outputs", "sol", "fleet-classify-2026-11-01.md")
|
|
|
|
def listdir(p):
|
|
try:
|
|
return sorted(os.listdir(p))
|
|
except OSError:
|
|
return []
|
|
|
|
def is_dir(p):
|
|
try:
|
|
return os.path.isdir(p)
|
|
except OSError:
|
|
return False
|
|
|
|
def git(*args):
|
|
return subprocess.run(
|
|
["git", "-C", REPO] + list(args), capture_output=True, text=True
|
|
).stdout
|
|
|
|
def classify():
|
|
classes = {}
|
|
def add(cls, name):
|
|
classes.setdefault(cls, []).append({"name": name})
|
|
|
|
profdir = os.path.join(HERMES, "profiles")
|
|
for n in listdir(profdir):
|
|
if n.startswith(".deleted"):
|
|
continue
|
|
add("active-profile", n)
|
|
deleted_dir = os.path.join(profdir, ".deleted")
|
|
for n in listdir(deleted_dir):
|
|
add("deleted-profile", n)
|
|
|
|
skills_dir = os.path.join(HERMES, "skills")
|
|
for n in listdir(skills_dir):
|
|
if n.startswith("."):
|
|
continue
|
|
if os.path.isdir(os.path.join(skills_dir, n, ".archive")):
|
|
add("archived-skill", n)
|
|
else:
|
|
add("active-skill", n)
|
|
if listdir(os.path.join(skills_dir, ".archive")):
|
|
for n in listdir(os.path.join(skills_dir, ".archive")):
|
|
add("archived-skill", n)
|
|
|
|
for n in listdir(os.path.join(HERMES, "plugins")):
|
|
add("plugin", n)
|
|
for n in listdir(os.path.join(HERMES, "memories")):
|
|
add("memory", n)
|
|
for n in sorted(glob.glob(os.path.join(HERMES, "cron", ".fire*"))):
|
|
add("cron-fire", os.path.basename(n))
|
|
|
|
profile_counts = {}
|
|
for cls, items in classes.items():
|
|
profile_counts[cls] = len(items)
|
|
return {"classes": classes, "summary": profile_counts}
|
|
|
|
|
|
def main():
|
|
data = classify()
|
|
data["meta"] = {
|
|
"agent": "sol",
|
|
"lane": "triage",
|
|
"generated_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
|
|
"source": "filesystem",
|
|
}
|
|
data["repo"] = {
|
|
"branch": git("branch", "--show-current").strip(),
|
|
"tracked_files": len(git("ls-files").splitlines()),
|
|
}
|
|
data["repo"]["last_commit"] = git("log", "-1", "--format=%h %s").strip()
|
|
|
|
os.makedirs(os.path.dirname(OUT), exist_ok=True)
|
|
with open(OUT, "w") as f:
|
|
json.dump(data, f, indent=2)
|
|
f.write("\n")
|
|
|
|
# markdown digest
|
|
lines = []
|
|
lines.append("# Fleet classification — sol triage lane")
|
|
lines.append("")
|
|
lines.append("Generated: " + data["meta"]["generated_at"])
|
|
lines.append("")
|
|
lines.append("## Summary")
|
|
lines.append("")
|
|
lines.append("| Class | Count |")
|
|
lines.append("|---|---|")
|
|
for cls in sorted(data["summary"]):
|
|
lines.append("| %s | %d |" % (cls, data["summary"][cls]))
|
|
lines.append("")
|
|
lines.append("## Repository")
|
|
lines.append("")
|
|
lines.append("| Field | Value |")
|
|
lines.append("|---|---|")
|
|
for k, v in data["repo"].items():
|
|
lines.append("| %s | %s |" % (k, v))
|
|
lines.append("")
|
|
lines.append("## Evidence (per-class item counts)")
|
|
lines.append("")
|
|
for cls in sorted(data["classes"]):
|
|
lines.append("### %s" % cls)
|
|
lines.append("")
|
|
lines.append("| name |")
|
|
lines.append("|---|")
|
|
for it in data["classes"][cls]:
|
|
lines.append("| %s |" % it["name"])
|
|
lines.append("")
|
|
with open(MD, "w") as f:
|
|
f.write("\n".join(lines))
|
|
|
|
print("Wrote", OUT)
|
|
print("Wrote", MD)
|
|
print(json.dumps(data["summary"], indent=2))
|
|
|
|
if __name__ == "__main__":
|
|
main()
|