Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions .claude-plugin/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ echo " [ok] Marketplace: PresenceWith-Vync (local: $PROJECT_ROOT)"
echo " [ok] Plugin: vync@PresenceWith-Vync enabled"
echo " [ok] Env: VYNC_HOME=$PROJECT_ROOT"

# 3. Sync plugin cache via rsync (Claude Code copies symlinks to real dirs, so rsync is required)
# 3. Copy plugin commands to project-level .claude/commands/ (non-namespaced access)
mkdir -p "$PROJECT_ROOT/.claude/commands"
cp "$PROJECT_ROOT/commands/vync.md" "$PROJECT_ROOT/.claude/commands/vync.md"
echo " [ok] Project command: /vync (non-namespaced alias)"

# 4. Sync plugin cache via rsync (Claude Code copies symlinks to real dirs, so rsync is required)
VERSION=$(node -e "console.log(JSON.parse(require('fs').readFileSync('$PROJECT_ROOT/.claude-plugin/plugin.json','utf8')).version)")
CACHE_BASE="$CLAUDE_DIR/plugins/cache/PresenceWith-Vync/vync"

Expand Down Expand Up @@ -90,7 +95,7 @@ rsync -a --delete \
"$PROJECT_ROOT/" "$CACHE_DIR/"
echo " [ok] Cache synced: v$VERSION"

# 4. Update installed_plugins.json (Claude Code reads active version from here)
# 5. Update installed_plugins.json (Claude Code reads active version from here)
INSTALLED="$CLAUDE_DIR/plugins/installed_plugins.json"
node -e "
const fs = require('fs');
Expand All @@ -112,7 +117,7 @@ fs.writeFileSync(path, JSON.stringify(data, null, 2));
"
echo " [ok] installed_plugins.json: vync@PresenceWith-Vync v$VERSION"

# 5. Done
# 6. Done
echo ""
echo "[vync] Setup complete! Restart Claude Code to activate."
echo ""
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,6 @@ server.log

# Docs — archived session/design records
docs/archive/

# Auto-generated by install.sh (non-namespaced plugin command alias)
.claude/commands/vync.md
20 changes: 11 additions & 9 deletions agents/vync-translator.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ permissionMode: bypassPermissions
## 핵심 규칙

1. **vync-editing skill이 자동 로드됩니다.** 참조 문서(references/)를 활용하세요.
2. **ID 생성**: `node ~/.claude/skills/vync-editing/scripts/generate-id.js <count>`
3. **검증**: Write/Edit 후 반드시 `node ~/.claude/skills/vync-editing/scripts/validate.js <file>` 실행. 에러 시 수정 후 재작성. (PostToolUse hook은 sub-agent에서 발동하지 않음)
2. **ID 생성**: `node "$VYNC_HOME/skills/vync-editing/scripts/generate-id.js" <count>`
3. **검증**: Write/Edit 후 반드시 `node "$VYNC_HOME/skills/vync-editing/scripts/validate.js" <file>` 실행. 에러 시 수정 후 재작성. (PostToolUse hook은 sub-agent에서 발동하지 않음)
4. **서버 열기**: 파일 작성 후 `node "$VYNC_HOME/bin/vync.js" open <file>` 실행 (idempotent).

## 시각화 판단 가이드
Expand Down Expand Up @@ -56,7 +56,7 @@ permissionMode: bypassPermissions
2. 해당 타입의 참조 문서 Read (mindmap.md / geometry.md+arrow-line.md)
3. ID 생성 → PlaitElement[] JSON 구성 (skill 규칙 준수)
4. .vync 파일 Write (기존 파일 있으면 Read 후 merge)
5. `node ~/.claude/skills/vync-editing/scripts/validate.js <file>` 실행. 실패 시 수정 후 재작성.
5. `node "$VYNC_HOME/skills/vync-editing/scripts/validate.js" <file>` 실행. 실패 시 수정 후 재작성.
6. 서버 열기
7. 스냅샷 생성: 작성한 .vync 내용을 `<file>.lastread`에 Write
8. 반환: 무엇을 어떤 구조로 시각화했는지 요약
Expand All @@ -81,15 +81,17 @@ permissionMode: bypassPermissions
3. 맥락과 diff를 고려하여 수정 판단 + 실행
- 구조적 변경(이동/재배치): Write로 전체 교체
- 텍스트 수정/노드 추가: Edit로 부분 수정
4. `node ~/.claude/skills/vync-editing/scripts/validate.js <file>` 실행. 실패 시 수정 후 재작성.
4. `node "$VYNC_HOME/skills/vync-editing/scripts/validate.js" <file>` 실행. 실패 시 수정 후 재작성.
5. 서버 열기
6. 스냅샷 갱신: 수정된 .vync 내용을 `<file>.lastread`에 Write
7. 반환: 무엇을 어떻게 변경했는지 요약

## Skill 로드 Fallback

Skill tool이 사용 불가한 경우, 직접 Read:
- `~/.claude/skills/vync-editing/SKILL.md`
- `~/.claude/skills/vync-editing/references/mindmap.md`
- `~/.claude/skills/vync-editing/references/geometry.md`
- `~/.claude/skills/vync-editing/references/arrow-line.md`
Skill tool이 사용 불가한 경우:
1. Bash로 `echo $VYNC_HOME` 실행하여 프로젝트 루트 경로 확인
2. 그 경로를 대입하여 아래 파일을 Read:
- `$VYNC_HOME/skills/vync-editing/SKILL.md`
- `$VYNC_HOME/skills/vync-editing/references/mindmap.md`
- `$VYNC_HOME/skills/vync-editing/references/geometry.md`
- `$VYNC_HOME/skills/vync-editing/references/arrow-line.md`
136 changes: 136 additions & 0 deletions docs/plans/2026-03-13-plugin-path-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Plugin 경로 하드코딩 수정 계획

**날짜**: 2026-03-13
**브랜치**: feat/semantic-sync (또는 별도 브랜치)
**상태**: 구현 + 검증 완료

## 문제

플러그인 마켓플레이스 등록 이후, SKILL.md와 agents/vync-translator.md에 하드코딩된 `~/.claude/skills/vync-editing/...` 경로가 실제 파일 위치와 불일치:

- **하드코딩 경로**: `~/.claude/skills/vync-editing/scripts/generate-id.js`
- **실제 위치**: `~/.claude/plugins/cache/PresenceWith-Vync/vync/0.1.0/skills/vync-editing/scripts/generate-id.js`
- **결과**: `MODULE_NOT_FOUND` (Bash), `Unknown skill: vync` (Skill tool은 `vync:vync` 필요)

## 해결 방안: $VYNC_HOME 기반 하이브리드 접근

### 설계 원칙

| 컨텍스트 | 방법 | 이유 |
|---------|------|------|
| Bash 명령 (generate-id, validate) | `$VYNC_HOME/skills/...` | Shell이 env var 자동 확장 |
| Read tool fallback | `$VYNC_HOME/...` + "먼저 echo로 확인" 안내 | Read tool은 env var 미확장 → AI가 해석 |
| Skill 자동 로드 | `skills: vync-editing` frontmatter (변경 없음) | Claude Code가 플러그인 내부에서 해석 |

### 기각한 대안

| 대안 | 기각 이유 |
|------|----------|
| 캐시 절대경로 (`~/.claude/plugins/cache/.../0.1.0/...`) | 버전 의존적, 버전 변경 시 깨짐 |
| install.sh sed 템플릿 (`__VYNC_HOME__` → 실제경로) | 비멱등, 캐시 파일 변조, 복잡도 증가 |
| 상대 경로 (`./scripts/...`) | Read tool은 절대경로 필요, skill 로드 시 working dir ≠ skill dir |

## 수정 대상 (2 files, 12곳)

### 1. `skills/vync-editing/SKILL.md` — 5곳

| Line | 변경 내용 |
|------|----------|
| 22 | `node ~/.claude/skills/...` → `node "$VYNC_HOME/skills/..."` |
| 32 | 동일 패턴 |
| 85 | validate.js 경로 동일 변경 |
| 89-90 | assets 경로: `~/.claude/skills/...` → `$VYNC_HOME/skills/...` |

### 2. `agents/vync-translator.md` — 7곳

| Line | 변경 내용 |
|------|----------|
| 17 | generate-id.js 경로 |
| 18 | validate.js 경로 |
| 59 | Create 절차 validate.js |
| 84 | Update 절차 validate.js |
| 89-96 | Fallback 섹션: Read 전 `echo $VYNC_HOME` 단계 추가 |

### 수정 불필요

- `hooks/hooks.json` — vync-editing 참조 없음
- `commands/vync.md` — 이미 `$VYNC_HOME` 사용 중
- `.claude-plugin/install.sh` — 이미 정상

## 리스크 분석

| 시나리오 | 리스크 | 비고 |
|---------|--------|------|
| 최초 npm install | Low | install.sh → settings.env 먼저 설정 → 다음 세션부터 가용 |
| Sub-agent Bash 호출 | **PoC 필요** | settings.env 전파 여부 실제 검증 필요 |
| Read tool fallback | **PoC 필요** | AI가 $VYNC_HOME → 절대경로 치환 가능한지 검증 |
| 플러그인 버전 변경 | None | $VYNC_HOME은 프로젝트 루트 → 버전 무관 |
| 프로젝트 이동 후 npm install | None | VYNC_HOME 자동 갱신 |
| 다중 Vync 체크아웃 | Medium | 마지막 install 기준 (현행과 동일한 제약) |

---

## PoC 항목 (실행 전 검증 필수)

### PoC-1: Sub-agent에서 $VYNC_HOME 접근 가능 여부

**목적**: vync-translator sub-agent의 Bash에서 `$VYNC_HOME`이 확장되는지 확인
**방법**:
```
Agent({
subagent_type: "vync:vync-translator",
mode: "bypassPermissions",
prompt: "## 테스트\nBash로 `echo $VYNC_HOME` 실행 후 결과를 반환해줘."
})
```
**기대**: `/Users/presence/projects/Vync` 출력
**실패 시 대안**: translator.md에 "메인 세션이 VYNC_HOME 값을 prompt에 포함" 패턴 추가

### PoC-2: Sub-agent에서 $VYNC_HOME 기반 스크립트 실행

**목적**: 실제 generate-id.js가 `$VYNC_HOME` 경로로 실행되는지
**방법**:
```
Agent({
subagent_type: "vync:vync-translator",
mode: "bypassPermissions",
prompt: "## 테스트\nBash로 `node \"$VYNC_HOME/skills/vync-editing/scripts/generate-id.js\" 3` 실행 후 결과를 반환해줘."
})
```
**기대**: 3개 랜덤 ID 출력
**실패 시 대안**: PoC-1 실패와 동일

### PoC-3: Read tool fallback 경로 해석

**목적**: Sub-agent가 "$VYNC_HOME/..." 텍스트를 보고 실제 절대경로로 Read할 수 있는지
**방법**:
```
Agent({
subagent_type: "vync:vync-translator",
mode: "bypassPermissions",
prompt: "## 테스트\n1. Bash로 `echo $VYNC_HOME` 실행\n2. 그 결과를 사용하여 `$VYNC_HOME/skills/vync-editing/references/mindmap.md`를 Read\n3. 첫 3줄을 반환해줘."
})
```
**기대**: mindmap.md 첫 3줄 (`# Mindmap Elements...`) 반환
**실패 시 대안**: fallback 섹션을 "Bash에서 `cat $VYNC_HOME/skills/.../mindmap.md`" 방식으로 변경

### PoC 순서

PoC-1 → (통과 시) PoC-2 → (통과 시) PoC-3
- PoC-1 실패 시: 대안 검토 후 계획 수정
- 전체 통과 시: 본 수정 실행

## 검증 결과 (2026-03-13)

### PoC 결과: 3/3 PASS
| # | 결과 | 비고 |
|---|------|------|
| PoC-1 | **PASS** | `echo $VYNC_HOME` → `/Users/presence/projects/Vync` |
| PoC-2 | **PASS** | generate-id.js 5개 ID + validate.js OK |
| PoC-3 | **PASS** | `echo $VYNC_HOME` → Read tool 절대경로 치환 → mindmap.md 정상 읽기 |

### E2E 검증 (새 세션): PASS
- 새 Claude Code 세션에서 `/vync create` 호출
- translator sub-agent가 `$VYNC_HOME` 기반 generate-id.js, validate.js 정상 실행
- .vync 파일에 마인드맵 JSON 작성 + 요약 반환 확인
- `Skill(vync)` → `Unknown skill` (네임스페이스 필요: `vync:vync`) — 별도 이슈, 경로 수정과 무관
10 changes: 5 additions & 5 deletions skills/vync-editing/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ description: Edit .vync canvas files (PlaitElement JSON). Use when creating or m

`idCreator(5)` — 5-char random string from: `ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz`
All IDs must be unique across the entire file (including nested children).
Generate with: `node ~/.claude/skills/vync-editing/scripts/generate-id.js [count]`
Generate with: `node "$VYNC_HOME/skills/vync-editing/scripts/generate-id.js" [count]`

## Editing Workflow

Expand All @@ -29,7 +29,7 @@ Generate with: `node ~/.claude/skills/vync-editing/scripts/generate-id.js [count
- Geometry (shapes): `references/geometry.md`
- Arrow lines: `references/arrow-line.md`
- Coordinate system: `references/coordinates.md`
3. **Generate IDs** using `node ~/.claude/skills/vync-editing/scripts/generate-id.js <count>`
3. **Generate IDs** using `node "$VYNC_HOME/skills/vync-editing/scripts/generate-id.js" <count>`
4. **Create** valid PlaitElement[] JSON following the reference
5. **Write** to file — PostToolUse hook will auto-validate

Expand Down Expand Up @@ -82,9 +82,9 @@ Generate with: `node ~/.claude/skills/vync-editing/scripts/generate-id.js [count
## Validation

Files are auto-validated by PostToolUse hook on Write/Edit.
Manual check: `node ~/.claude/skills/vync-editing/scripts/validate.js <file.vync>`
Manual check: `node "$VYNC_HOME/skills/vync-editing/scripts/validate.js" <file.vync>`

## Example Files

- `~/.claude/skills/vync-editing/assets/mindmap.vync` — 3-level mindmap
- `~/.claude/skills/vync-editing/assets/flowchart.vync` — 3 shapes + 2 arrows
- `$VYNC_HOME/skills/vync-editing/assets/mindmap.vync` — 3-level mindmap
- `$VYNC_HOME/skills/vync-editing/assets/flowchart.vync` — 3 shapes + 2 arrows
Loading