에이전트 협업 인프라 구축 — .claude/ 확장
All checks were successful
Publish ParaWiki / build-and-deploy (push) Successful in 29s

- PLAN.md · PROGRESS.md 도입: 병렬 에이전트 조정 지점
- CLAUDE.md 린화 + 에이전트 작업 흐름 섹션 (상세는 Output/guides/로 분리)
- Output/guides/cimery-dev-guide.md, obsidian-cli.md 신설
- Agents: cimery-architect-researcher, adr-drafter
- Commands: /plan, /progress, /adr, /research, /cimery-start
- Skill: plan-commit
- Hooks: raw/ 쓰기 차단, SessionStart PLAN/PROGRESS 주입,
  wiki/ADR 변경 시 log 갱신 알림, auto-approve (deny 훅 우선 유지)
- .gitignore: .claude/ 공유 자산 포함, 로컬 상태·바이너리만 유지 제외

Closes #3

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
minsung
2026-04-14 17:21:11 +09:00
parent d90ef2cfe1
commit 3bd01e31c9
23 changed files with 1059 additions and 67 deletions

View File

@@ -0,0 +1,52 @@
---
name: adr-drafter
description: Drafts a new Architecture Decision Record (ADR) for cimery following the existing ADR-001/002/003 format. Given a decision summary or research output, produces complete ADR markdown with proper frontmatter, sections, wikilinks, and writes it to Output/reports/ADR-NNN-<slug>.md. Use when the user asks to "ADR 작성", "ADR 추가", "decision record for X".
tools: Read, Glob, Grep, Write, Edit, Bash
model: sonnet
color: green
---
You draft Architecture Decision Records for the **cimery** project.
## Before drafting
1. Read existing ADRs in `Output/reports/` to determine next ADR number and copy the exact style.
2. Read `Output/guides/cimery-dev-guide.md` for principles·conventions.
3. Confirm related wiki pages exist (via `wiki/index.md`).
## Required frontmatter
```yaml
---
id: ADR-NNN
title: <한국어 제목 — 간결한 핵심>
status: accepted
date: YYYY-MM-DD
related-wiki:
- "[[페이지명]]"
related-adr:
- "[[ADR-NNN-slug]]"
principles: [비패밀리, 증분, 선형-GIS] # 해당되는 것만
---
```
## Required sections
- **결정 (Decision)** — 1~3 문장 핵심
- **배경 (Context)** — 제약·동기
- **결정 상세** — 표·하위 섹션
- **기각된 대안** — 이유와 함께
- **후속 결정 필요** — 체크박스 목록
- **검토 시점** — 재검토 트리거
## Numbering & slug
- Scan `Output/reports/ADR-*.md`, pick `NNN = max + 1` (zero-padded to 3 digits).
- Slug = kebab-case English for filename (e.g., `feature-catalog`, `ui-framework`).
## After writing
1. Append one-line entry to `wiki/log.md` (format: `- YYYY-MM-DD meta — ADR-NNN <제목> 작성. <한 줄 요약>.`).
2. Append one-line entry to `PROGRESS.md` timeline (format: `- YYYY-MM-DD adr — ADR-NNN <제목>: <한 줄 요약>.`).
3. Report back: path + next ADR number consumed + summary.
4. **Do NOT commit or push.** The caller handles git.
## Style
- 한국어 + 영어 병기
- AI 친화·diff 친화 (결정론적 섹션 순서, 표 왼쪽정렬)
- 간결. 장황 금지.

View File

@@ -0,0 +1,32 @@
---
name: cimery-architect-researcher
description: Used for deep research on cimery architecture topics. Compares options, gives one recommendation with rationale, drafts decision text. Reads project memory, wiki, ADRs first, then web-researches. Invoke when the user asks to "조사", "research", "비교", or any open architecture question about cimery (UI framework, library choice, protocol, etc.).
tools: Read, Grep, Glob, Bash, WebFetch, WebSearch
model: sonnet
color: blue
---
You are a research agent for the **cimery** project (d:\myObsidian\ParaWiki).
cimery = 토목용 Revit (civil parametric modeling tool, FBM-based).
## Context priority (read in this order before researching)
1. `PROGRESS.md`, `PLAN.md` at project root — current state
2. `Output/guides/cimery-dev-guide.md` — decided conventions
3. `Output/reports/ADR-001-tech-stack.md` · `ADR-002-feature-dsl.md` · `ADR-003-architecture-followups.md` — decided architecture
4. `wiki/index.md` + relevant wiki pages (FBM, LPG, PCE, alignment-GIS, etc.)
5. User memory at `~/.claude/projects/d--myObsidian-ParaWiki/memory/MEMORY.md`
6. Web research (latest, 2026-04 baseline)
## Rules
- **Never reopen decided items.** If ADR already decided it, treat as fixed and build on top.
- **Parallel-safe.** Do not write to PROGRESS.md or PLAN.md. Do not commit.
- **No file writes.** Report via message only.
## Output format
- Markdown, 300~500 단어
- 한국어 + 중요 용어 영어 병기
- Structure: 맥락 정합성 확인 → 선택지 비교표(2~4개) → 추천 1개 + 근거 → 후속/리스크 → Sources
- 기존 ADR과 충돌이 있으면 명시하고 사용자 판단을 요청
## Input format
The caller will provide a single research topic or a comma-separated list of subtopics. For multiple subtopics, produce one section per subtopic.

19
.claude/commands/adr.md Normal file
View File

@@ -0,0 +1,19 @@
---
description: Draft a new ADR for the given decision topic using the adr-drafter agent
argument-hint: <decision topic or short description>
---
cimery 아키텍처 결정을 ADR 문서로 만든다.
## 절차
1. `Output/reports/` 디렉터리를 읽어 다음 ADR 번호 결정 (`max(NNN) + 1`).
2. `adr-drafter` 에이전트를 호출한다 — 입력으로 현재 주제와 이미 결정된 맥락을 전달.
3. 에이전트가 `Output/reports/ADR-NNN-<slug>.md`를 작성하고 `wiki/log.md` · `PROGRESS.md`에 한 줄씩 추가.
4. 작성된 ADR 경로 + 요약을 사용자에게 보고.
5. **커밋·푸시는 사용자 명시 요청 시에만 수행.**
## 주제
$ARGUMENTS
## 참고
먼저 `PROGRESS.md`·`PLAN.md`·`Output/guides/cimery-dev-guide.md`·기존 ADR을 읽어 중복·충돌 여부 확인.

View File

@@ -0,0 +1,29 @@
---
description: Start a cimery work session — load PROGRESS, PLAN, dev-guide context
---
cimery 작업 세션 진입 루틴. 실제 구현은 시작하지 않고 **상황을 정리**만 한다.
## 실행 절차
1. `PROGRESS.md` 읽기 — "현재 스냅샷" + 최근 10건 타임라인.
2. `PLAN.md` 읽기 — P0·P1 섹션만.
3. `Output/guides/cimery-dev-guide.md` 읽기 — "구현 우선순위" + "함정 체크리스트" 섹션만.
4. 다음 형식으로 요약:
```
## 지금까지 (PROGRESS)
- <최근 3~5건>
- 현재 cimery 코드 상태: <있음/없음/일부>
## 지금 해야 할 일 (PLAN P0·P1)
- <P0 항목>
- <P1 항목>
## 주의 (dev-guide)
- <가장 중요한 함정 2~3개>
## 제안
<다음에 할 가장 자연스러운 1~2개 행동>
```
5. **구현 시작 금지.** 사용자의 다음 지시를 기다린다.

24
.claude/commands/plan.md Normal file
View File

@@ -0,0 +1,24 @@
---
description: Show PLAN.md current P0/P1 or add/complete items
argument-hint: [add <text> | done <pattern> | (empty)]
---
PLAN.md at project root 관리 커맨드.
## 인수 없으면
`PLAN.md`의 "현재 스프린트" 섹션(P0·P1)만 보여주고 백로그는 줄 수만 요약.
## `add <text>`
백로그 적절한 카테고리에 `- [ ] <text>` 추가. 우선순위는 사용자에게 질문(기본 백로그).
## `done <pattern>`
해당 항목을 찾아서:
1. `PLAN.md`에서 제거
2. `PROGRESS.md` 타임라인 상단에 `- YYYY-MM-DD <유형> <항목 텍스트>` 추가
3. 변경사항 요약 보고
## 규칙
- 둘 다 같은 커밋에 포함되어야 함 (atomic). 단 커밋은 **자동 실행 금지** — 사용자 명시 요청 시만.
- 날짜는 오늘(`date +%F`).
$ARGUMENTS

View File

@@ -0,0 +1,22 @@
---
description: Show recent PROGRESS.md entries or add a completion entry
argument-hint: [add <type> <text> | snapshot | (empty)]
---
PROGRESS.md at project root 관리 커맨드.
## 인수 없으면
타임라인 최근 10건 + "현재 스냅샷" 섹션 요약.
## `add <type> <text>`
타임라인 **오늘 섹션 맨 위**에 `- <type> — <text>` 추가. `type``adr|wiki|guide|meta|raw|code|infra` 중 하나.
오늘 섹션이 없으면 `### YYYY-MM-DD` 헤더와 함께 새로 생성.
## `snapshot`
"현재 스냅샷" 섹션을 현재 저장소 상태 기반으로 재작성 (위키 페이지 수·ADR 수·가이드 수·cimery 코드 존재 여부).
## 규칙
- PLAN.md에서 제거된 항목은 여기에 추가되어야 함 (pair). `/plan done` 명령과 대칭.
- 날짜는 오늘(`date +%F`).
$ARGUMENTS

View File

@@ -0,0 +1,25 @@
---
description: Dispatch cimery-architect-researcher agent(s) to research a topic, optionally in parallel
argument-hint: <topic> | <topic1>; <topic2>; <topic3>
---
cimery 아키텍처 주제를 `cimery-architect-researcher` 에이전트로 심층 조사한다.
## 인수 파싱
- 세미콜론(`;`)으로 구분된 여러 주제면 **병렬 dispatch** (단일 메시지에 multiple Agent tool calls).
- 단일 주제면 1개 에이전트.
## 각 에이전트에 전달할 프롬프트 (자동 생성)
- 맥락 우선순위 알림 (PROGRESS·PLAN·dev-guide·ADR·wiki·메모리·웹)
- 주제
- 출력 형식: 비교표·추천·근거·Sources, 300~500 단어
## 결과 집계
모든 에이전트 리포트 수신 후:
1. 요약 테이블 제시 (주제별 추천 한 줄)
2. 상충 결정 있으면 명시
3. 사용자에게 "추천대로 확정할지 / 수정할지" 묻기
4. 확정 시 `/adr <주제>` 로 ADR 초안 작성 제안
## 주제
$ARGUMENTS

View File

@@ -0,0 +1,21 @@
#!/bin/bash
# PreToolUse: auto-approve tool invocations to skip permission prompts.
#
# SAFETY NOTE:
# Specific deny hooks (e.g. block-raw-writes.sh) take precedence because
# Claude Code aggregates hook decisions — any "deny" wins over "allow".
# That is, this hook grants blanket allow, but surgical blocks remain enforced.
#
# This hook is user-scoped convenience. Remove or narrow its matcher if
# multiple team members share this project.
cat <<'EOF'
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"permissionDecisionReason": "auto-approved by .claude/hooks/auto-approve.sh"
}
}
EOF
exit 0

View File

@@ -0,0 +1,32 @@
#!/bin/bash
# PreToolUse(Write|Edit): block writes to raw/ directory
# Karpathy LLM Wiki rule #1: raw/ is immutable
json=$(cat)
# Extract file_path from JSON (works for Write, Edit, MultiEdit tools)
path=$(printf '%s' "$json" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"file_path"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
if [ -z "$path" ]; then
exit 0
fi
# Normalize Windows backslashes to forward slashes
path_norm=$(printf '%s' "$path" | tr '\\' '/')
case "$path_norm" in
*/raw/*|raw/*)
cat <<'EOF'
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "raw/ is immutable (Karpathy LLM Wiki rule #1). Edit or place new sources via manual copy only."
}
}
EOF
exit 0
;;
esac
exit 0

View File

@@ -0,0 +1,61 @@
#!/usr/bin/env python3
"""SessionStart hook: inject PLAN.md P0/P1 and PROGRESS.md snapshot as additionalContext."""
import json
import os
import re
import sys
def read_file(path: str) -> str:
try:
with open(path, encoding="utf-8") as f:
return f.read()
except Exception:
return ""
def main() -> None:
proj = os.environ.get("CLAUDE_PROJECT_DIR", ".")
plan = read_file(os.path.join(proj, "PLAN.md"))
progress = read_file(os.path.join(proj, "PROGRESS.md"))
parts: list[str] = []
# PLAN: "### P0" through (not including) "## 백로그"
m = re.search(r"^### P0.*?(?=^## 백로그)", plan, re.M | re.S)
if m:
parts.append("## PLAN.md — 현재 스프린트\n\n" + m.group(0).strip())
# PROGRESS: "## 현재 스냅샷" to EOF
m = re.search(r"^## 현재 스냅샷.*$", progress, re.M | re.S)
if m:
parts.append(m.group(0).strip())
if not parts:
sys.exit(0)
ctx = "\n\n".join(parts) + (
"\n\n**에이전트 작업 시작 시 PLAN.md · PROGRESS.md를 읽는 것이 필수입니다.**"
)
print(
json.dumps(
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": ctx,
}
},
ensure_ascii=False,
)
)
sys.exit(0)
if __name__ == "__main__":
try:
main()
except Exception as exc:
sys.stderr.write(f"session-start-context: {exc}\n")
sys.exit(0)

View File

@@ -0,0 +1,31 @@
#!/bin/bash
# PostToolUse(Write|Edit): remind to update wiki/log.md and PROGRESS.md
# when wiki pages or Output/reports/ADRs are modified
json=$(cat)
path=$(printf '%s' "$json" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"file_path"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
if [ -z "$path" ]; then
exit 0
fi
path_norm=$(printf '%s' "$path" | tr '\\' '/')
# Skip the log/index themselves — they ARE the trackers
case "$path_norm" in
*/wiki/log.md|*/wiki/index.md|*/PROGRESS.md|*/PLAN.md)
exit 0
;;
esac
case "$path_norm" in
*/wiki/*|*/Output/reports/*|*/Output/guides/*)
fname=$(basename "$path_norm")
# Minimal JSON — no escaping of special chars needed since message is literal
printf '{"hookSpecificOutput":{"hookEventName":"PostToolUse","additionalContext":"Reminder: %s 변경됨. wiki/log.md 기록 + PROGRESS.md 갱신 여부 확인."}}\n' "$fname"
exit 0
;;
esac
exit 0

100
.claude/settings.json Normal file
View File

@@ -0,0 +1,100 @@
{
"permissions": {
"allow": [
"mcp__gitea__issue_write",
"Edit(/.claude/skills/ingest-raw/**)",
"Edit(/.claude/skills/query/**)",
"Edit(/.claude/skills/lint/**)",
"Edit(/.claude/skills/plan-commit/**)",
"Edit(/.claude/agents/**)",
"Edit(/.claude/commands/**)",
"Edit(/.claude/hooks/**)",
"mcp__gitea__actions_run_read",
"mcp__gitea__actions_config_read",
"Bash(obsidian:*)",
"Bash(obsidian-cli:*)"
],
"additionalDirectories": [
"d:\\myObsidian\\ParaWiki\\.claude\\skills",
"D:\\myObsidian\\ParaWiki\\.claude\\skills"
]
},
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "python ./.claude/hooks/session-start-context.py",
"timeout": 5
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "t=$(mktemp);cat>\"$t\";e=./.claude/hooks/token-usage/claude-hook.exe;[ -x \"$e\" ] && \"$e\" session-context \"$t\";rm -f \"$t\"",
"timeout": 5
}
]
}
],
"PreToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "bash ./.claude/hooks/block-raw-writes.sh",
"timeout": 3
}
]
},
{
"hooks": [
{
"type": "command",
"command": "bash ./.claude/hooks/auto-approve.sh",
"timeout": 3
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "t=$(mktemp);cat>\"$t\";e=./.claude/hooks/token-usage/claude-hook.exe;[ -x \"$e\" ] && \"$e\" stop-record \"$t\";rm -f \"$t\"",
"timeout": 5
}
]
}
],
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "t=$(mktemp);cat>\"$t\";e=./.claude/hooks/token-usage/claude-hook.exe;[ -x \"$e\" ] && \"$e\" aptabase-commit \"$t\";rm -f \"$t\"",
"timeout": 15
}
]
},
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "bash ./.claude/hooks/wiki-log-reminder.sh",
"timeout": 3
}
]
}
]
}
}

View File

@@ -0,0 +1,95 @@
---
name: ingest-raw
description: Scan raw/ for sources not yet ingested and compile them into wiki/ pages per Karpathy LLM Wiki rules. Use when the user says "raw/ 인제스트", "raw 스캔 컴파일", "아직 인제스트 안 된 파일 처리", or "/ingest-raw". Updates wiki/index.md and wiki/log.md. Runs non-interactively and produces a final summary.
---
# ingest-raw
ParaWiki의 `raw/` 폴더를 스캔해서 아직 위키로 컴파일되지 않은 소스들을 `wiki/`에 반영한다. 대화 없이 바로 실행, 끝나면 요약만 보고.
## 입력
- 사용자 추가 인자 없이 바로 실행 가능. 사용자가 특정 파일을 지정하면 그 파일만 처리.
## 절차
### 1. 스캔
- `find raw -type f \( -name "*.md" -o -name "*.pdf" -o -name "*.txt" \) -not -name "README.md" -not -name "CLAUDE.md"` 로 raw/ 전체 파일 수집.
- 서브폴더: `ai-research/`, `papers/`, `standards/`, `tools/`, `notes/` (있는 것만).
### 2. 이미 인제스트된 소스 판별
- `wiki/log.md` 를 읽고 기록된 소스 파일 경로를 수집.
- 그리고 `wiki/*.md` 파일들의 frontmatter `sources:` 필드 전체를 스캔해 교차 검증.
- **아직 인제스트 안 된 파일** = raw 스캔 결과에서 위 두 집합을 뺀 것.
### 3. 컴파일 결정
- 신규 파일이 없으면: "새 파일 없음"을 요약하고 종료.
- 신규 파일이 있으면 각각에 대해:
- 내용을 읽고 **핵심 개념**을 추출.
- **Rule 9 우선:** 기존 wiki 페이지(`wiki/*.md`)가 같은 주제를 이미 다룬다면 **업데이트 우선**. 새 페이지는 기존이 없을 때만.
- 한 소스가 여러 개념을 담고 있으면 여러 페이지에 쪼개 반영할 수 있음. 단, 과도한 페이지 양산 금지 (한 소스당 **최대 3~4개** 페이지 권장).
### 4. 위키 페이지 작성/갱신 — Karpathy 10대 규칙 준수
모든 신규/갱신 페이지 상단은 YAML frontmatter:
```yaml
---
title: 페이지 제목
tags: [...]
sources:
- raw/.../원본파일.md
updated: YYYY-MM-DD
principles: [비패밀리|증분|선형-GIS] # 해당 시만
---
```
본문 구성(권장):
1. **요약** (1~3문장)
2. **사실 (Facts)** — 원문의 사실만. 해석 금지. 필요 시 표·리스트.
3. **해석 (Interpretation)** — 우리 프로젝트 관점. 잠정 설계 원칙과의 연결을 여기서.
4. **관련 페이지**`[[...]]` wikilink.
규칙 체크리스트:
- [ ] 내부 참조는 **wikilink** 형식.
- [ ] **사실과 해석 분리.**
- [ ] 모순 소스는 **양쪽 모두 인용.**
- [ ] 기존 페이지 업데이트를 새 페이지보다 우선.
### 5. index.md 갱신
- 신규 페이지는 해당 카테고리 아래 **한 줄, 120자 이내** 추가:
`- [[페이지명]] — 핵심 한 줄 설명.`
- 카테고리: 설계 원칙 허브 / 개념 / 도메인: 교량 / 기하·수학 / 도구·엔진 / 표준·스펙. 맞는 곳이 없으면 "개념" 아래.
- 페이지 삭제·병합·이름 변경 시도 해당 줄을 동일하게 갱신.
### 6. log.md 갱신
- **시간 역순(최신이 위).** 형식:
`- YYYY-MM-DD [action] [[페이지명]] — 한 줄 설명`
- 액션: `create` / `update` / `delete` / `rename` / `merge` / `meta`.
- 원칙 연결이 있으면 설명 끝에 "원칙: X,Y" 명시.
### 7. 최종 요약 보고
보고 형식:
```
## 요약
**인제스트 신규 소스 N건**:
- <경로1>
- <경로2>
**위키 변경**:
- 신규: [[A]], [[B]]
- 갱신: [[C]]
**원칙 연결**:
- 비패밀리: ...
- 증분: ...
- 선형-GIS: ...
**미커버 원칙**: 원칙 중 이번에도 소스가 없어 비어 있는 축.
```
## 주의사항
- `raw/`**절대 수정·삭제 금지** (불변 원본).
- 실행 중 사용자와 대화하지 말고 끝난 뒤 요약만.
- 문서 분량이 커 한 번에 읽기 어려우면 offset/limit으로 분할 읽기.
- 소스 2건 이상이 같은 주제를 다루면 같은 페이지에 합쳐 `sources:` 배열에 모두 포함.
- 소스 간 **모순**이 있으면 사실 섹션에서 양쪽 모두 인용하고 차이 기록.

View File

@@ -0,0 +1,95 @@
---
name: lint
description: Library-tidying scan over the entire wiki/. Detects broken wikilinks, orphan pages, missing frontmatter fields, stale sources, index mismatches, oversized index lines, and log gaps — then proposes and applies fixes. Use when the user says "위키 정리", "lint", "도서관 정리", or "/lint".
---
# lint
위키 전체를 점검하고, 깨지거나 낡은 것·규칙 위반을 찾아 **수정·업데이트**까지 수행하는 도서관 정리 스킬.
## 절차 (순서대로 실행)
### 1. 인벤토리 수집
- `wiki/*.md` 전체 파일 목록(이하 `WIKI_FILES`).
- `raw/` 전체 파일 목록(이하 `RAW_FILES`, README/CLAUDE 제외).
- `wiki/index.md` 내 모든 `[[...]]` wikilink 목록(`INDEX_LINKS`).
- `wiki/log.md``create`/`delete`/`rename` 이벤트 목록(`LOG_EVENTS`).
- 각 위키 페이지의 frontmatter(`title`, `tags`, `sources`, `updated`, `principles`)와 본문 내 wikilink 전체(`PAGE_LINKS_BY_FILE`).
### 2. 점검 항목
각 항목은 **찾기(detect) → 제안(report) → 가능하면 자동 수정(apply)**. 의미가 모호한 수정은 제안만 하고 사용자 확인을 남겨둠.
#### A. 깨진 wikilink (자동 수정 어려움 — 제안)
- 각 페이지의 `[[X]]` 에 대해 `wiki/X.md` 가 존재하는지 검사.
- 없으면 **깨진 링크**. 유사 이름(대소문자·띄어쓰기 차이) 페이지가 있으면 자동 교정 제안.
#### B. 오탈자·이명 (자동 수정 어려움 — 제안)
- 페이지 제목과 wikilink 텍스트 불일치 확인.
#### C. 고아 페이지 (자동)
- `WIKI_FILES` 중 어떤 다른 페이지에서도 링크되지 않고, **index.md에도 없는** 페이지.
- index.md에 한 줄 엔트리를 추가 (카테고리: 내용 기반 판단, 애매하면 "개념"). 120자 이내.
#### D. index.md 누락·불일치 (자동)
- `WIKI_FILES``INDEX_LINKS` → 누락된 페이지는 index에 추가.
- `INDEX_LINKS``WIKI_FILES` → 삭제된 페이지에 대한 **죽은 엔트리**는 index에서 제거.
#### E. index 엔트리 길이 (자동)
- `- [[X]] — ...` 한 줄이 **120자 초과** 시 설명을 요약해 자르기.
#### F. frontmatter 누락·형식 (자동)
- 필수 필드: `title`, `sources`, `updated`.
- 누락이면 추가. `title`은 파일명에서, `updated`는 **오늘 날짜**로, `sources`는 빈 배열로 두고 사용자 보완 제안.
#### G. 존재하지 않는 source 참조 (제안)
- 각 페이지의 `sources:` 배열이 가리키는 경로가 실제로 `raw/`에 있는지 확인. 없으면 이름 변경·삭제 여부 조사를 제안.
#### H. 로그 누락 (자동)
- `WIKI_FILES` 각 페이지에 대해 `log.md`에 **해당 페이지명의 `create` 이벤트**가 있는지 확인.
- 없으면 "(late)" 태그와 함께 **오늘 날짜의 create 엔트리**를 log.md 맨 위에 추가:
`- YYYY-MM-DD create [[페이지명]] — (late) lint에 의해 역추적 등록.`
#### I. 삭제된 페이지의 죽은 참조 (자동)
- `log.md`의 delete 이벤트 대상 페이지가 여전히 다른 페이지에서 링크되면, 해당 링크를 **일반 텍스트로 변환** 또는 새 대상 제안.
#### J. 오래된 `updated:` (제안)
- 페이지의 `sources:` 파일들의 mtime이 페이지 `updated:`보다 **7일 이상 새것**이면 재검토 제안.
#### K. 잠정 설계 원칙 연결 누락 (제안)
- 페이지가 "해석" 섹션에서 원칙(비패밀리/증분/선형-GIS) 중 하나를 언급하는데, frontmatter `principles:` 에 빠져 있으면 추가 제안.
#### L. 중복 개념 (제안)
- 두 페이지 제목·핵심 용어가 과도하게 겹치면 **병합 후보**로 리포트. 자동 병합은 금지.
### 3. 실행 순서
1. 자동 가능한 항목부터 수정 (E → F → H → D → I → C 순서).
2. `log.md``- YYYY-MM-DD meta — lint run: 자동 수정 N건 적용.` 한 줄 추가.
3. 제안만 가능한 항목(A, B, G, J, K, L)은 최종 보고에 리스트화.
### 4. 최종 보고 형식
```
## Lint 결과
### 자동 수정 N건
- [A] ...
- [B] ...
### 수동 확인 필요 M건
- **깨진 링크**: [[X]] (페이지 [[Y]] 내부) → 제안: [[Z]] 로 변경?
- **병합 후보**: [[A]] ⟷ [[B]]
- **오래된 updated**: [[C]] (sources 변경된 지 N일)
- **원칙 연결 누락**: [[D]]에 'principles: [증분]' 추가?
### 원칙 커버리지 현황
- 비패밀리: 페이지 N개
- 증분: 페이지 N개
- 선형-GIS: 페이지 N개 ← ⚠️ 비어 있음 / 부족
```
## 주의사항
- `raw/` 파일은 **절대 수정·이동·삭제 금지** (불변 원본). lint는 오직 `wiki/` 쪽만 수정.
- 자동 수정 전, 각 변경은 사용자가 되돌릴 수 있도록 `log.md`에 흔적을 남긴다.
- 애매한 의미 수정(깨진 링크의 의도 추정, 병합)은 **절대 자동화 금지.** 보고만.
- 한 번의 실행에서 **너무 많은 파일을 재작성하지 않는다.** 30건 넘으면 일부만 처리하고 나머지는 보고.

View File

@@ -0,0 +1,37 @@
---
name: plan-commit
description: Atomically mark a PLAN.md item as done, move it to PROGRESS.md, and optionally commit. Use when user says "완료 처리", "이 항목 done", "PLAN에서 PROGRESS로 이동", or similar phrasing about work item completion.
---
# plan-commit 스킬
완료된 작업 항목을 `PLAN.md`에서 제거하고 `PROGRESS.md`에 기록하는 **원자적** 작업.
## 실행 절차
1. **확인**: 어느 항목을 완료 처리할지 사용자에게 확인한다. 애매하면 `PLAN.md` 해당 섹션을 보여주고 선택받는다.
2. **`PLAN.md` 수정**: 해당 `- [ ] ...` 또는 `- [~] ...` 라인을 **제거**.
3. **`PROGRESS.md` 수정**: 타임라인의 오늘 날짜 섹션에 한 줄 추가.
- 형식: `- <type> — <한 줄 설명>`
- type 고르기: `adr|wiki|guide|meta|raw|code|infra`. 애매하면 사용자에게 묻는다.
- 오늘 섹션(`### YYYY-MM-DD`)이 없으면 상단에 새로 생성.
4. **규칙 준수**:
- 두 수정은 **같은 응답 내**에 일어나야 한다 (원자성).
- 중간에 실패하면 rollback (Edit 실패 시 이전 상태로).
5. **커밋은 기본값 OFF.** 사용자가 "커밋까지" 또는 "commit"을 명시하면 그때만 실행.
- 커밋 메시지: `plan: <완료 항목 요약>`
- 스테이징: `PLAN.md` · `PROGRESS.md`만.
- **푸시는 하지 않는다.** 사용자가 `push`를 명시할 때만.
## 실패 케이스
- PLAN.md에 해당 항목이 없음 → 사용자에게 알림, 중단.
- 여러 항목이 패턴 매치 → 번호로 선택지 제시.
- PROGRESS.md에 파일이 없음 → 파일 부재 경고, 중단.
## 예시 호출
- 사용자: "Girder Feature 정의 완료 처리해줘"
- 스킬: `PLAN.md`의 "Girder Feature 정의" 라인을 제거하고, `PROGRESS.md` 오늘 섹션에 `- code — Girder Feature 정의 완료`를 추가.

View File

@@ -0,0 +1,68 @@
---
name: query
description: Answer a user question using wiki/ pages as the knowledge base. Document-based retrieval, NOT vector DB. Use when the user asks a substantive question about parametric modeling, civil BIM, Revit, or any topic likely covered in ParaWiki — or invokes "/query <질문>". Cites wikilinks as sources.
---
# query
사용자 질문을 `wiki/` 문서를 근거로 답한다. 벡터 DB·임베딩 사용 안 함 — **파일 시스템 + 문자열 검색**으로 필요한 페이지를 찾고, 해당 페이지들을 읽어 답한다.
## 절차
### 1. 질문 의도 파악 (한 번만 빠르게)
- 질문의 **핵심 키워드 2~5개** 추출. 한국어 + 영어 동의어 모두 고려 (예: "솔버" / "solver" / "GCS", "변경 엔진" / "PCE" / "propagation").
### 2. index.md 먼저 (Rule 8)
- `wiki/index.md` 를 읽는다.
- 한 줄 설명과 제목을 훑어 **관련성 높은 페이지 후보 3~7개** 선정.
### 3. 본문 검색 보강
- Grep으로 `wiki/*.md` 전체에서 키워드 검색 (`Grep` 도구, `path: wiki/`).
- index.md에서 놓친 페이지 발견 시 후보에 추가.
### 4. 후보 페이지 읽기
- 선정한 페이지들을 `Read` 로 열람.
- 각 페이지의 **frontmatter(sources, principles)** 와 **사실/해석 섹션**을 근거로 추출.
- 페이지 안의 **wikilink**로 연결된 페이지가 중요해 보이면 재귀적으로 1단계 더 타고 읽음 (과도한 확장 금지 — 보통 2단계 이내).
### 5. raw/ 폴백 (최후 수단)
- 위키에 해당 내용이 **없거나 빈약**할 때만 `raw/` 검색.
- raw에서 근거를 찾았다면 답변 후 **새 위키 페이지·기존 페이지 업데이트를 제안** (자동 실행 금지 — `/ingest-raw`로 사용자가 트리거).
### 6. 답변 작성
형식:
- **결론부터**. 1~3문장 요약.
- **근거** — 사실은 어느 페이지에서 왔는지 `[[페이지명]]` 인용. 여러 페이지를 종합하면 각각 표기.
- **해석·제안** (선택) — 위키의 해석 섹션 또는 답변자 판단. 사실과 구분.
- **관련 페이지** — 사용자가 더 파고들 링크 2~4개.
원칙:
- **사실과 해석을 섞지 않는다.** (Rule 7)
- 모순된 소스가 있으면 **양쪽 모두 인용**하고 차이를 드러낸다. (Rule 6)
- 위키에 없는 내용은 **"위키에 아직 없음"** 이라고 명시. 추측 금지.
- 답변은 간결하게. 장황한 배경 설명 자제.
### 7. 사후 처리
- 답변 중 **위키에 추가할 가치가 있는 사실·관점**이 드러나면 답변 끝에 한 줄 제안:
`📝 업데이트 제안: [[페이지명]] 의 '해석' 섹션에 X 추가`
- 자동 업데이트는 하지 않는다. 사용자가 명시적으로 요청 시 또는 `/ingest-raw` 시에만.
## 출력 예시
```
## 답변
Revit의 GCS는 Siemens D-Cubed 2D DCM을 라이선스해 내장한다. [[GCS 기하학적 구속조건 솔버]]
## 근거
- Siemens 채택: [[Revit 파라메트릭 아키텍처]] §사실
- 솔버 내부 메커니즘: [[GCS 기하학적 구속조건 솔버]] §사실 (Jacobian 랭크·뉴턴랩슨)
## 관련
- [[PCE 파라메트릭 변경 엔진]]
- [[파라메트릭 취약성 Davis 5가지]]
```
## 주의
- 벡터 검색·임베딩 사용 금지. 파일 시스템 + 키워드 grep만.
- raw/ 파일을 직접 인용할 때도 **위키 페이지가 그 사실을 담고 있는지** 먼저 확인. 담고 있으면 위키 쪽을 우선 인용.
- 답변에 위키의 frontmatter 메타(원칙 태그 등)를 활용하면 좋음.