feat: 문서 구조 변경 및 tech-visual 스킬 추가

This commit is contained in:
DongHyeonka
2026-09-04 18:20:00 +09:00
parent 43901f0abf
commit 2efb7ee1f2
683 changed files with 61180 additions and 10479 deletions
+91
View File
@@ -0,0 +1,91 @@
#!/usr/bin/env python3
"""tech-log-tree.json 을 다시 만든다.
SSOT(final/document.md)에서 뽑은 글감과 이미 쓴 기록을 한 파일에 모은다. 기록 파일이
정본이므로 이 스크립트는 그것을 읽어 채우고, 아직 글이 없는 글감은 사람이 적은 항목을
그대로 둔다.
python3 scripts/build-tech-log-tree.py [프로젝트 ...]
"""
from __future__ import annotations
import json, re, sys, glob, os, datetime
KINDS = ["case", "concept", "reference", "question", "decision"]
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
def front_matter(path: str) -> dict:
text = open(path, encoding="utf-8").read()
if not text.startswith("---"):
return {}
end = text.find("\n---", 3)
out = {}
for line in text[3:end].splitlines():
m = re.match(r"^([a-zA-Z_]+):\s*(.*)$", line)
if m:
out[m.group(1)] = m.group(2).strip().strip('"')
return out
def build(project: str) -> dict:
base = os.path.join(ROOT, "docs", project)
studio = os.path.join(base, "tech-log-studio")
tree_path = os.path.join(studio, "tech-log-tree.json")
previous = {}
if os.path.exists(tree_path):
previous = json.load(open(tree_path, encoding="utf-8"))
ssot = "final/document.md" if os.path.exists(os.path.join(base, "final/document.md")) else None
topics = {}
for topic_dir in sorted(d for d in glob.glob(os.path.join(studio, "*")) if os.path.isdir(d)):
topic = os.path.basename(topic_dir)
entry = {"topic": topic, "kinds": {}}
for kind in KINDS:
items = []
for f in sorted(glob.glob(os.path.join(topic_dir, kind, "*.md"))):
fm = front_matter(f)
text = open(f, encoding="utf-8").read()
items.append({
"title": fm.get("title", os.path.basename(f)),
"slug": fm.get("slug", ""),
"file": os.path.relpath(f, studio),
"status": fm.get("status", "미작성"),
"studioId": fm.get("id", ""),
"assets": len(re.findall(r"^ - key: ", text, re.M)),
"evidence": len(re.findall(r"^ - \.\./", text, re.M)),
})
# 아직 글이 없는 글감은 지난 tree 에서 가져와 유지한다
written = {i["slug"] for i in items if i["slug"]}
for old in previous.get("topics", {}).get(topic, {}).get("kinds", {}).get(kind, []):
if not old.get("file") and old.get("slug") not in written:
items.append(old)
entry["kinds"][kind] = items
topics[topic] = entry
return {
"project": project,
"ssot": ssot,
"generatedAt": datetime.date.today().isoformat(),
"note": "글감 목록이다. file 이 있으면 이미 쓴 기록이고, 없으면 아직 쓰지 않은 글감이다.",
"topics": topics,
}
def main(argv: list[str]) -> int:
projects = argv[1:] or [
os.path.basename(os.path.dirname(p))
for p in glob.glob(os.path.join(ROOT, "docs/*/tech-log-studio"))
]
for project in sorted(projects):
tree = build(project)
out = os.path.join(ROOT, "docs", project, "tech-log-studio", "tech-log-tree.json")
with open(out, "w", encoding="utf-8") as fh:
json.dump(tree, fh, ensure_ascii=False, indent=2)
fh.write("\n")
n = sum(len(v) for t in tree["topics"].values() for v in t["kinds"].values())
print(f"{os.path.relpath(out, ROOT)} — 주제 {len(tree['topics'])} · 글감 {n}")
return 0
if __name__ == "__main__":
raise SystemExit(main(sys.argv))
+12
View File
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
# techviz CLI 래퍼. 도구는 별도 저장소에 있고 이 저장소에는 스킬만 들어와 있다.
# 경로가 다르면 TECHVIZ_HOME 으로 알려 준다.
set -euo pipefail
TECHVIZ_HOME="${TECHVIZ_HOME:-/home/donghyeon/workspace/ai-tool/technical-visualization-haness}"
if [ ! -d "$TECHVIZ_HOME/src/techviz" ]; then
echo "techviz 도구를 찾지 못했다: $TECHVIZ_HOME" >&2
echo "TECHVIZ_HOME 으로 technical-visualization-haness 경로를 알려 준다." >&2
exit 1
fi
export TECHVIZ_HOME
PYTHONPATH="$TECHVIZ_HOME/src${PYTHONPATH:+:$PYTHONPATH}" exec python3 -m techviz "$@"