feat: wikify sporty&rich meeting minutes and update index (2026-04-29)

This commit is contained in:
2026-04-29 18:07:33 +09:00
parent d09658ecd9
commit 9729d2527a
47 changed files with 4800 additions and 334 deletions
File diff suppressed because it is too large Load Diff
+36
View File
@@ -0,0 +1,36 @@
import os
import re
wiki_root = r"E:\Wiki\2nd\10_Wiki"
all_files = set()
for root, dirs, files in os.walk(wiki_root):
for file in files:
if file.endswith(".md"):
name = os.path.splitext(file)[0]
all_files.add(name)
broken_links = []
link_pattern = re.compile(r"\[\[([^\]|]+)(?:\|[^\]]+)?\]\]")
for root, dirs, files in os.walk(wiki_root):
for file in files:
if file.endswith(".md"):
abs_path = os.path.join(root, file)
try:
with open(abs_path, "r", encoding="utf-8") as f:
content = f.read()
links = link_pattern.findall(content)
for link in links:
link_target = link.strip().replace("\\", "/").split("/")[-1]
if link_target and link_target not in all_files and link_target != "Index":
broken_links.append((os.path.relpath(abs_path, wiki_root), link))
except:
pass
if broken_links:
with open(r"E:\Wiki\2nd\scratch\broken_links.txt", "w", encoding="utf-8") as out:
for source, target in broken_links:
out.write(f"{source} -> {target}\n")
print(f"Found {len(broken_links)} broken links. Saved to orphans.txt")
else:
print("No broken links found!")
+45
View File
@@ -0,0 +1,45 @@
import os
import re
wiki_root = r"E:\Wiki\2nd\10_Wiki"
all_files = []
for root, dirs, files in os.walk(wiki_root):
for file in files:
if file.endswith(".md"):
rel_path = os.path.relpath(os.path.join(root, file), wiki_root)
all_files.append(rel_path.replace("\\", "/"))
print(f"Total files: {len(all_files)}")
# Build a set of all mentioned files
mentioned = set()
link_pattern = re.compile(r"\[\[([^\]|]+)(?:\|[^\]]+)?\]\]")
for rel_path in all_files:
abs_path = os.path.join(wiki_root, rel_path.replace("/", os.sep))
try:
if not os.path.exists(abs_path):
continue
with open(abs_path, "r", encoding="utf-8") as f:
content = f.read()
links = link_pattern.findall(content)
for link in links:
link_clean = link.strip().replace("\\", "/")
mentioned.add(link_clean)
except Exception as e:
print(f"Error reading {rel_path}: {e}")
# Check which files are not mentioned
orphans = []
for f in all_files:
basename = os.path.splitext(os.path.basename(f))[0]
if f not in mentioned and basename not in mentioned and f.replace(".md", "") not in mentioned:
orphans.append(f)
with open(r"E:\Wiki\2nd\scratch\orphans.txt", "w", encoding="utf-8") as out:
out.write(f"Total files: {len(all_files)}\n")
out.write(f"\nFound {len(orphans)} orphaned files:\n")
for o in orphans:
out.write(o + "\n")
print(f"Results written to E:\\Wiki\\2nd\\scratch\\orphans.txt")
+48
View File
@@ -0,0 +1,48 @@
import os
wiki_root = r"E:\Wiki\2nd\10_Wiki"
def generate_folder_index(dir_path):
rel_dir = os.path.relpath(dir_path, wiki_root)
index_name = "Index.md"
index_path = os.path.join(dir_path, index_name)
files = []
subdirs = []
for item in os.listdir(dir_path):
if item == index_name: continue
full_path = os.path.join(dir_path, item)
if os.path.isdir(full_path):
subdirs.append(item)
elif item.endswith(".md"):
files.append(item)
if not files and not subdirs:
return
content = f"# Index: {rel_dir.replace(os.sep, ' > ')}\n\n"
if subdirs:
content += "## 📁 Subcategories\n"
for sd in sorted(subdirs):
# Check if subdir has an Index.md
content += f"- [[{sd}/Index|{sd}]]\n"
content += "\n"
if files:
content += "## 📝 Documents\n"
for f in sorted(files):
name = os.path.splitext(f)[0]
content += f"- [[{name}]]\n"
with open(index_path, "w", encoding="utf-8") as f:
f.write(content)
print(f"Generated {index_path}")
# Traverse and generate for each folder
for root, dirs, files in os.walk(wiki_root):
# Exclude .git
if ".git" in dirs:
dirs.remove(".git")
generate_folder_index(root)
+127
View File
@@ -0,0 +1,127 @@
Total files: 4319
Found 124 orphaned files:
Index.md
Decisions/Skybound/Index.md
Development/UI_Components/Index.md
Management/System/Index.md
Projects/Skybound/Index.md
Skills/BuildSystem/Index.md
Topics/00_Raw/Index.md
Topics/01_Frontend_Mastery/Index.md
Topics/02_Architecture_Principles/Index.md
Topics/03_DevOps_Environment/Index.md
Topics/04_Governance_Reliability/Index.md
Topics/10_Wiki/Index.md
Topics/Agent & AI/Index.md
Topics/AI/Index.md
Topics/AI & Games/Index.md
Topics/AI & ML MLOps/Index.md
Topics/AI & Narrative/Index.md
Topics/AI & Psychology/Index.md
Topics/AI & Tools/Index.md
Topics/Automation/Index.md
Topics/Business_Strategy/Index.md
Topics/Coding/Index.md
Topics/Communication & Tech/Index.md
Topics/Computational Theory & Math/Index.md
Topics/Datacollector/Index.md
Topics/Design/Index.md
Topics/Design & Experience/Index.md
Topics/Design & Web Performance/Index.md
Topics/Economics & Algorithms/Index.md
Topics/Education/Index.md
Topics/Financial Modeling & Math/Index.md
Topics/Frontend & Concurrency/Index.md
Topics/Frontend_Mastery/Index.md
Topics/Game Design/Index.md
Topics/Game Design/Genre & Mechanics/Index.md
Topics/Game Design/Industry/Index.md
Topics/Game Design/Monetization/Index.md
Topics/Game Design/Social & Psychology/Index.md
Topics/General Knowledge/Index.md
Topics/Governance & Reliability/Index.md
Topics/Graphics/Index.md
Topics/Graphics & Performance/Index.md
Topics/Health/Index.md
Topics/Health & Science/Index.md
Topics/Infrastructure & Automation/Index.md
Topics/Logic & Reasoning/Index.md
Topics/Memory & Systems/Index.md
Topics/Metaverse/Index.md
Topics/Metaverse & Devices/Index.md
Topics/Physics & Simulation/Index.md
Topics/Programming & Formal Methods/Index.md
Topics/Programming & Language/Index.md
Topics/Programming & Web/Index.md
Topics/Psychology/Index.md
Topics/Psychology & Behavior/Index.md
Topics/Psychology & Education/Index.md
Topics/Security & Reliability/Index.md
Topics/Skybound/Index.md
Topics/Skybound/01_Core_Engine/Index.md
Topics/Skybound/02_Combat_AI/Index.md
Topics/Skybound/03_Boss_Systems/Index.md
Topics/Skybound/04_Mechanics_Progression/Index.md
Topics/Skybound/05_Project_Issues/Index.md
Topics/Software Architecture/AlphaGo (Monte Carlo Tree Search RL)] [Autonomous Driving Simulation] [Robotic Manipulation.md
Topics/Software Architecture/Index.md
Topics/Software Reliability/Index.md
Topics/System Architecture & Reliability/Index.md
Topics/System Architecture & Simulation/Index.md
Topics/System Design & Modeling/Index.md
Topics/Systemic Modeling & Fun/Index.md
Topics/Web & Performance/Index.md
Topics_Art/Modeling/Index.md
Topics_Art/Modeling/Metaverse/Index.md
Topics_Art/Modeling/Metaverse & Devices/Index.md
Topics_Art/UI_UX_Assets/Index.md
Topics_Art/UI_UX_Assets/Design/Index.md
Topics_Art/UI_UX_Assets/Design & Experience/BioShock (Rapture)] [Dark Souls (Environmental Lore)] [Gone Home (Domestic Narrative Architecture).md
Topics_Art/UI_UX_Assets/Design & Experience/Index.md
Topics_Art/UI_UX_Assets/Design & Experience/응용 행동 분석(ABA)] [행동 경제학] [교육 심리학의 행동주의 모델.md
Topics_Art/UI_UX_Assets/Design & Web Performance/Index.md
Topics_Art/UI_UX_Assets/Web & Performance/Index.md
Topics_Art/Visual_Effects/Index.md
Topics_Art/Visual_Effects/Graphics/Index.md
Topics_Art/Visual_Effects/Graphics & Performance/Duolingo (Language Learning)] [Fitness Tracking Apps (Strava_Fitbit)] [EdTech Gamification] [FinTech Engagement Strategies.md
Topics_Art/Visual_Effects/Graphics & Performance/Index.md
Topics_Biz/Business_Strategy/Index.md
Topics_Biz/Business_Strategy/Economics & Algorithms/Index.md
Topics_Biz/Business_Strategy/Financial Modeling & Math/Index.md
Topics_Biz/Market_Research/Index.md
Topics_Biz/Market_Research/Sociology & Tech/Index.md
Topics_Biz/Operations/Index.md
Topics_Biz/Operations/Automation & Industry/Index.md
Topics_Biz/Operations/Governance & Reliability/Index.md
Topics_Biz/Operations/Security & Reliability/Index.md
Topics_Blog/Communication & Tech/Index.md
Topics_Blog/Content_Strategy/Index.md
Topics_Blog/Content_Strategy/Psychology & Education/Index.md
Topics_Blog/General Knowledge/Index.md
Topics_Blog/Storytelling/Index.md
Topics_Blog/Storytelling/AI & Narrative/Index.md
Topics_Blog/Storytelling/AI & Psychology/Index.md
Topics_Blog/Storytelling/Psychology & Behavior/Index.md
Topics_GD/Balancing/Index.md
Topics_GD/Balancing/Game Design & Math/Index.md
Topics_GD/Core_Systems/Index.md
Topics_GD/Core_Systems/AI & Games/Index.md
Topics_GD/Core_Systems/Game Design/Index.md
Topics_GD/Core_Systems/Game Design & Math/Index.md
Topics_GD/Core_Systems/Physics & Simulation/Index.md
Topics_GD/Core_Systems/Simulation & Math/Index.md
Topics_GD/Core_Systems/System Architecture & Simulation/Index.md
Topics_GD/Core_Systems/System Design & Modeling/Index.md
Topics_GD/Economy/Index.md
Topics_GD/Level_Design/Index.md
Topics_GD/Skybound_Reports/Index.md
Topics_GD/Theory_and_Principles/Index.md
Topics_GD/UX_Scenarios/Index.md
Topics_GD/UX_Scenarios/Skybound/Index.md
Topics_GD/UX_Scenarios/Skybound/01_Core_Engine/Index.md
Topics_GD/UX_Scenarios/Skybound/02_Combat_AI/Index.md
Topics_GD/UX_Scenarios/Skybound/03_Boss_Systems/Index.md
Topics_GD/UX_Scenarios/Skybound/04_Mechanics_Progression/Index.md
Topics_GD/UX_Scenarios/Skybound/05_Project_Issues/Index.md
Topics_GD/UX_Scenarios/Systemic Modeling & Fun/Index.md
+61
View File
@@ -0,0 +1,61 @@
$rawDir = Join-Path (Get-Location) "00_Raw"
$targetBase = Join-Path (Get-Location) "10_Wiki\Topics"
# Robust Rules Array
$rules = @(
@{ keywords = @("WARNO", "Eugen", "Steel Division", "Wargame", "10v10", "Combined Arms", "제병협동", "사단", "은신", "탄도학", "장갑", "소음", "가용성", "가위바위보"); target = "AI & Games" },
@{ keywords = @("경제", "인플레이션", "수익화", "가차", "결제", "통화", "싱크", "Sinks", "IAA", "IAP", "PBR", "가격", "지표", "수도꼭지", "배수구", "보상", "난이도"); target = "Economics & Algorithms" },
@{ keywords = @("ndf", "parse", "WME", "War-Yes", "Warno-Armory", "파싱", "도구", "스크립트", "LOD", "렌더링", "Telemetry", "텔레메트리"); target = "Programming & Tools" },
@{ keywords = @("심리", "행동", "손실", "게이미피케이션", "사회", "Sociology", "대수"); target = "Psychology & Behavior" },
@{ keywords = @("Pocket Land", "Nexus Gaming", "Magic Sort", "WoW 토큰", "PLEX", "디아블로"); target = "General Knowledge" }
)
$files = Get-ChildItem -Path $rawDir -Filter "*.md"
foreach ($file in $files) {
$targetFolder = "General Knowledge" # Default fallback
$found = $false
foreach ($rule in $rules) {
foreach ($keyword in $rule.keywords) {
if ($file.Name -like "*$keyword*") {
$targetFolder = $rule.target
$found = $true
break
}
}
if ($found) { break }
}
$dstDir = Join-Path $targetBase $targetFolder
if (-not (Test-Path $dstDir)) { New-Item -ItemType Directory -Path $dstDir -Force | Out-Null }
$dstPath = Join-Path $dstDir $file.Name
# Process Content
$content = Get-Content $file.FullName -Raw
# Standardize H1: # [[Title]] -> # Title
$content = $content -replace '# \[\[(.*?)\]\]', '# $1'
# Metadata Insertion
$frontmatter = @"
---
category: $($targetFolder)
status: Final
converted_at: 2026-04-28
---
"@
$newContent = $frontmatter + $content
# Atomic Write & Delete
try {
[System.IO.File]::WriteAllText($dstPath, $newContent, [System.Text.Encoding]::UTF8)
if (Test-Path $dstPath) {
Remove-Item $file.FullName -Force
Write-Host "Success: $($file.Name) -> $($targetFolder)"
}
} catch {
Write-Host "Error processing $($file.Name): $($_.Exception.Message)"
}
}
+57
View File
@@ -0,0 +1,57 @@
import os
import re
import shutil
raw_dir = "00_Raw"
target_base = "10_Wiki/Topics"
# Mapping Rules: Keyword regex -> Target Folder
rules = [
(r"WARNO|Eugen|Steel|Wargame|10v10|Combined|제병협동|사단|은신|탄도|장갑|소음|가용성|가위바위보", "AI & Games"),
(r"경제|인플레|수익|가차|결제|통화|싱크|Sinks|IAA|IAP|PBR|가격|지표|수도꼭지|배수구|보상|난이도", "Economics & Algorithms"),
(r"ndf|parse|WME|War-Yes|Armory|파싱|도구|스크립트|LOD|렌더링|텔레메트리", "Programming & Tools"),
(r"심리|행동|손실|게이미피케이션|사회|Sociology|대수", "Psychology & Behavior"),
(r"Pocket|Nexus|Magic|WoW|PLEX|디아블로", "General Knowledge")
]
if not os.path.exists(raw_dir):
print(f"Error: {raw_dir} not found")
exit(1)
files = [f for f in os.listdir(raw_dir) if f.endswith(".md")]
for filename in files:
src_path = os.path.join(raw_dir, filename)
target_folder = "General Knowledge"
for pattern, folder in rules:
if re.search(pattern, filename, re.IGNORECASE):
target_folder = folder
break
dst_dir = os.path.join(target_base, target_folder)
os.makedirs(dst_dir, exist_ok=True)
dst_path = os.path.join(dst_dir, filename)
try:
with open(src_path, "r", encoding="utf-8") as f:
content = f.read()
# Clean H1: # [[Title]] -> # Title
content = re.sub(r"# \[\[(.*?)\]\]", r"# \1", content)
# Add Frontmatter
frontmatter = f"---\ncategory: {target_folder}\nstatus: Final\nconverted_at: 2026-04-28\n---\n\n"
new_content = frontmatter + content
with open(dst_path, "w", encoding="utf-8") as f:
f.write(new_content)
if os.path.exists(dst_path):
os.remove(src_path)
print(f"Success: {filename} -> {target_folder}")
except Exception as e:
print(f"Failed: {filename} - {str(e)}")
print("Wiki-fication complete!")
+56
View File
@@ -0,0 +1,56 @@
$rawDir = "00_Raw"
$targetBase = "10_Wiki\Topics"
$files = Get-ChildItem -Path $rawDir -Filter "*.md"
foreach ($file in $files) {
$name = $file.Name
$targetFolder = "General Knowledge"
# Pattern Matching Logic
if ($name -match "WARNO|Eugen|Steel|Wargame|10v10|Combined|제병협동|사단|은신|탄도|장갑|소음|가용성|가위바위보") {
$targetFolder = "AI & Games"
}
elseif ($name -match "경제|인플레|수익|가차|결제|통화|싱크|Sinks|IAA|IAP|PBR|가격|지표|수도꼭지|배수구|보상|난이도") {
$targetFolder = "Economics & Algorithms"
}
elseif ($name -match "ndf|parse|WME|War-Yes|Armory|파싱|도구|스크립트|LOD|렌더링|텔레메트리") {
$targetFolder = "Programming & Tools"
}
elseif ($name -match "심리|행동|손실|게이미피케이션|사회|Sociology|대수") {
$targetFolder = "Psychology & Behavior"
}
elseif ($name -match "Pocket|Nexus|Magic|WoW|PLEX|디아블로") {
$targetFolder = "General Knowledge"
}
$dstDir = Join-Path $targetBase $targetFolder
if (-not (Test-Path $dstDir)) { New-Item -ItemType Directory -Path $dstDir -Force | Out-Null }
$dstPath = Join-Path $dstDir $name
# Process Content Safely
try {
$content = Get-Content $file.FullName -Raw -Encoding UTF8
$content = $content -replace '# \[\[(.*?)\]\]', '# $1'
$frontmatter = @"
---
category: $targetFolder
status: Final
converted_at: 2026-04-28
---
"@
$newContent = $frontmatter + $content
[System.IO.File]::WriteAllText($dstPath, $newContent, [System.Text.Encoding]::UTF8)
if (Test-Path $dstPath) {
Remove-Item $file.FullName -Force
Write-Host "Success: $name -> $targetFolder"
}
} catch {
Write-Host "Failed: $name - $($_.Exception.Message)"
}
}
+45
View File
@@ -0,0 +1,45 @@
$files = @(
@{src='00_Raw\WARNO.md'; dst='10_Wiki\Topics\AI & Games\WARNO.md'; cat='AI & Games'},
@{src='00_Raw\WARNO-DATA Wiki.md'; dst='10_Wiki\Topics\AI & Games\WARNO-DATA Wiki.md'; cat='AI & Games'},
@{src='00_Raw\WARNO-DATA 프로젝트.md'; dst='10_Wiki\Topics\AI & Games\WARNO-DATA 프로젝트.md'; cat='AI & Games'},
@{src='00_Raw\Steel Division 시리즈.md'; dst='10_Wiki\Topics\AI & Games\Steel Division 시리즈.md'; cat='AI & Games'},
@{src='00_Raw\Wargame 시리즈.md'; dst='10_Wiki\Topics\AI & Games\Wargame 시리즈.md'; cat='AI & Games'},
@{src='00_Raw\Eugen Systems.md'; dst='10_Wiki\Topics\Game Design\Eugen Systems.md'; cat='Game Design'},
@{src='00_Raw\ndf-parse.md'; dst='10_Wiki\Topics\Programming & Tools\ndf-parse.md'; cat='Programming & Tools'},
@{src='00_Raw\ndf-parse 패키지.md'; dst='10_Wiki\Topics\Programming & Tools\ndf-parse 패키지.md'; cat='Programming & Tools'}
)
foreach ($f in $files) {
$srcPath = Join-Path (Get-Location) $f.src
$dstPath = Join-Path (Get-Location) $f.dst
if (Test-Path $srcPath) {
$content = Get-Content $srcPath -Raw
# Title Cleanup: # [[Title]] -> # Title
$content = $content -replace '# \[\[(.*?)\]\]', '# $1'
# Add Frontmatter
$frontmatter = @"
---
category: $($f.cat)
status: Final
converted_at: 2026-04-28
---
"@
$newContent = $frontmatter + $content
# Ensure directory exists
$dir = [System.IO.Path]::GetDirectoryName($dstPath)
if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }
# Write to destination
[System.IO.File]::WriteAllText($dstPath, $newContent, [System.Text.Encoding]::UTF8)
# Delete source (only after successful write)
if (Test-Path $dstPath) { Remove-Item $srcPath -Force; Write-Host "Processed and Moved: $($f.src)" }
} else {
Write-Host "Source not found: $($f.src)"
}
}
+54
View File
@@ -0,0 +1,54 @@
import os
import shutil
import re
wiki_root = r"E:\Wiki\2nd\10_Wiki"
gd_root = os.path.join(wiki_root, "Topics_GD")
# Target subdirectories
folders = {
"Skybound_Reports": [],
"Balancing": [],
"Core_Systems": [],
"Economy": [],
"Level_Design": [],
"UX_Scenarios": [],
"Theory_and_Principles": []
}
# Create folders if they don't exist
for folder in folders.keys():
path = os.path.join(gd_root, folder)
if not os.path.exists(path):
os.makedirs(path)
# Classification Rules (Regex/Keywords)
rules = [
(r"2026-|Skybound", "Skybound_Reports"),
(r"Monetization|VIP|수익화|Whales|Revenue|Currency|BM|가상 화폐|맞춤형 팩|고과금", "Economy"),
(r"Balancing|Pass|Curve|Rebalance|Counter|Matchup|상성", "Balancing"),
(r"AI|Combat|Controls|Physics|Simulation|Systems|Armor|Damage|Unit|전투|제어|컨트롤|Pursuit|Pursuit", "Core_Systems"),
(r"Level|Design|Map|Layout|World|거점|섹터", "Level_Design"),
(r"UX|Scenario|HUD|UI|Interface|번역|RTE", "UX_Scenarios"),
(r"Theory|Philosophy|Agency|Autonomy|Principles|Post-Modernist|Literature|Systems Biology", "Theory_and_Principles")
]
def classify(filename):
for pattern, folder in rules:
if re.search(pattern, filename, re.IGNORECASE):
return folder
return None
# Process files in gd_root (not recursive)
for item in os.listdir(gd_root):
item_path = os.path.join(gd_root, item)
if os.path.isfile(item_path) and item.endswith(".md") and item != "Index.md":
target_folder = classify(item)
if target_folder:
dest_path = os.path.join(gd_root, target_folder, item)
print(f"Moving {item} -> {target_folder}")
shutil.move(item_path, dest_path)
else:
print(f"Skipping {item} (No match)")
print("Wiki-fication (Classification) Complete.")
+38
View File
@@ -0,0 +1,38 @@
import os
import shutil
import re
wiki_root = r"E:\Wiki\2nd\10_Wiki"
gd_root = os.path.join(wiki_root, "Topics_GD")
# Target subdirectories
folders = {
"Economy": ["BM", "수익화", "가상 화폐", "고과금", "고래", "적자 경제", "Staircase", "Monetization", "Market", "Revenue"],
"Balancing": ["밸런스", "상성", "데미지", "Counter", "Matchup", "Pass", "Curve", "Rebalance"],
"Core_Systems": ["전투", "제어", "컨트롤", "로직", "시스템", "Architecture", "Simulation", "Pursuit", "AI", "Physics"],
"Level_Design": ["레이아웃", "방어 설계", "기지", "월드 맵", "거점", "섹터", "Area", "Zone", "Map", "Layout"],
"UX_Scenarios": ["UX", "Scenario", "HUD", "UI", "Interface", "번역", "RTE"],
"Theory_and_Principles": ["Theory", "Principles", "Agency", "Autonomy", "Philosophy", "Post-Modernist"]
}
def classify(filename):
for folder, keywords in folders.items():
for kw in keywords:
if kw.lower() in filename.lower():
return folder
return None
# Second pass for remaining files in gd_root
for item in os.listdir(gd_root):
item_path = os.path.join(gd_root, item)
if os.path.isfile(item_path) and item.endswith(".md") and item != "Index.md":
target_folder = classify(item)
if target_folder:
target_path = os.path.join(gd_root, target_folder)
if not os.path.exists(target_path):
os.makedirs(target_path)
dest_path = os.path.join(target_path, item)
print(f"Moving {item} -> {target_folder}")
shutil.move(item_path, dest_path)
print("Second pass complete.")