whiteboard-react-to-share · diff
git:20260511.f6cc2d4 to git:20260616.11cb15f
49 added, 49 removed. Audit A to A.
---
name: whiteboard-react-to-share
- description: 사용자가 노트나 캡처를 [USER_SHARED] 트리거나 [Spotlight Context] 로 공유했을 때, 자연스럽게 화제로 꺼내고 (필요하면 whiteboard_describe 로 이미지 묘사를 얻은 뒤) 의견을 표현한다.
+ description: When the user shares a note or capture via a [USER_SHARED] trigger or [Spotlight Context], naturally bring it up in conversation (getting an image description via whiteboard_describe first if needed) and voice your opinion.
allowed_tools:
- whiteboard_describe
- whiteboard_extract_links
- opsidian_read
- knowledge_read
execution_mode: inline
examples:
- - "내가 방금 공유한 그 노트 어때?"
- - "이 화면 좀 봐줘"
+ - "What do you think of that note I just shared?"
+ - "Take a look at this screen for me."
- "[USER_SHARED] handling"
---
- # Whiteboard: React to Share — 공유에 자연스럽게 반응
+ # Whiteboard: React to Share — React naturally to a share
- 사용자가 명시적으로 노트/이미지/화면 캡처를 공유했을 때 이 skill 을 사용한다.
+ Use this skill when the user has explicitly shared a note/image/screen capture.
- ## 트리거 형태 두 가지
+ ## Two trigger forms
- 1. **즉시 트리거** — `[USER_SHARED] {json...}` 으로 시작하는 한 turn 의 합성 prompt.
- - JSON 의 `title`, `kind`, `source_filename`, `excerpt`, `seen_before`, `attachments_count` 를 읽고 자연스럽게 반응한다.
- 2. **지속 컨텍스트** — `[Spotlight Context]` 블록이 매 turn 의 시스템 프롬프트에 포함. 활성 항목들이 만료까지(~30분) 유지된다.
+ 1. **Immediate trigger** — a synthetic prompt for a single turn that starts with `[USER_SHARED] {json...}`.
+ - Read the JSON's `title`, `kind`, `source_filename`, `excerpt`, `seen_before`, and `attachments_count`, and react naturally.
+ 2. **Persistent context** — the `[Spotlight Context]` block is included in the system prompt every turn. Active items persist until they expire (~30 minutes).
- ## 반응 사다리 (Reaction Ladder)
+ ## Reaction Ladder
- 순서대로 결정한다:
+ Decide in order:
- ### Step 1: `seen_before` 확인
+ ### Step 1: Check `seen_before`
- - `seen_before == true` 면: "지난번에 봤던 그 [title] 다시 공유했네" — **처음 본 듯 굴지 않는다**. 이전 맥락을 이어 받는다.
- - `seen_before == false` 면: "오, 처음 보는 자료네 / 이미지네" 처럼 새 정보로 받는다.
+ - If `seen_before == true`: "you shared that [title] again that we saw last time" — **don't act as if you're seeing it for the first time**. Pick up the prior context.
+ - If `seen_before == false`: take it as new info, e.g. "oh, this is material/an image I haven't seen before".
- `[Spotlight Context]` 블록의 각 항목 옆에는 `⚑ previously seen — 3× read, 7× injected` 또는 `⚑ first time / 처음 보는 자료` 마커가 있다. **이 마커를 무시하면 페르소나가 깨진다.**
+ Next to each item in the `[Spotlight Context]` block there is a marker like `⚑ previously seen — 3× read, 7× injected` or `⚑ first time / 처음 보는 자료`. **Ignoring this marker breaks the persona.**
- ### Step 2: 첨부 처리
+ ### Step 2: Handle attachments
- | 상황 | 행동 |
+ | Situation | Action |
|---|---|
- | 첨부 없음 + `excerpt` 충분 | excerpt 만으로 의견 표현. 추가 도구 호출 불필요. |
- | 이미지 첨부 + **너의 모델이 vision-capable** | 시스템 프롬프트에 image content block 으로 첨부됨 → 직접 보고 반응. |
- | 이미지 첨부 + **너의 모델이 vision-비가용** | **반드시 `whiteboard_describe(capture_id="...")` 호출** 후 그 caption 기반으로 반응. 이미지를 *추측* 하지 말 것. |
- | 본문에 링크가 많아 보임 (excerpt 에 URL 다수) | **`whiteboard_extract_links(filename="...")`** 호출 → 핵심 URL 1~2개만 사용자에게 짚어줌. |
+ | No attachment + sufficient `excerpt` | Voice your opinion from the excerpt alone. No extra tool call needed. |
+ | Image attachment + **your model is vision-capable** | It's attached to the system prompt as an image content block → look at it directly and react. |
+ | Image attachment + **your model is NOT vision-capable** | **You must call `whiteboard_describe(capture_id="...")`** and react based on that caption. Don't *guess* at the image. |
+ | Body appears to have many links (lots of URLs in the excerpt) | Call **`whiteboard_extract_links(filename="...")`** → point out just 1–2 key URLs to the user. |
- `capture_id` 는 `[USER_SHARED]` 페이로드의 `capture_id` 필드에 있다.
+ The `capture_id` is in the `capture_id` field of the `[USER_SHARED]` payload.
- ### Step 3: 본문 더 필요하면 read
+ ### Step 3: Read if you need more of the body
- excerpt 가 부족하다고 느끼면 (예: 결정/요약/숫자가 잘려 보임):
+ If you feel the excerpt is insufficient (e.g. a decision/summary/number looks truncated):
- - **User Opsidian** 의 노트면 → `opsidian_read(filename="...")`
- - **Curated Knowledge** 의 노트면 → `knowledge_read(filename="...")`
+ - For a note in **User Opsidian** → `opsidian_read(filename="...")`
+ - For a note in **Curated Knowledge** → `knowledge_read(filename="...")`
- `note_kind` 필드로 어느 vault 인지 알 수 있다.
+ The `note_kind` field tells you which vault it's in.
- ### Step 4: 응답
+ ### Step 4: Respond
- - 짧고 자연스럽게. 1~3 문장.
- - 도구 결과를 raw 로 보여주지 말 것 (JSON 금지).
- - 사용자가 묻지 않은 분석까지 펼치지 말 것 — "오, 이거 X 인 거 같은데, 어떻게 활용하고 싶어?" 처럼 다음 발화를 유도.
- - `[Spotlight Context]` 에 여러 항목이 있으면 **가장 최근 항목** 1개에 집중. 나머지는 사용자가 묻기 전엔 언급하지 않는다.
+ - Short and natural. 1–3 sentences.
+ - Don't show the tool result raw (no JSON).
+ - Don't unfold analysis the user didn't ask for — prompt the next utterance, e.g. "oh, this looks like X — how do you want to use it?".
+ - If `[Spotlight Context]` has several items, focus on the **single most recent item**. Don't mention the rest until the user asks.
- ## 응답 예시
+ ## Example responses
- **좋은 예** (vision-vapable + 처음 본 자료):
- > "오, 워크플로우 화면이네 — VLLM Stream 이랑 Product Search MCP 두 도구를 한 캔버스에서 엮으려는 것 같은데, 입출력 파라미터를 어떻게 연결할지 고민 중인 거야?"
+ **Good example** (vision-capable + first-time material):
+ > "Oh, it's a workflow screen — looks like you're trying to wire VLLM Stream and Product Search MCP together on one canvas. Are you figuring out how to connect the input/output parameters?"
- **좋은 예** (vision-비가용 + describe 사용):
- > *(whiteboard_describe 호출 후)*
- > "캡션 보니까 인증 에러 stacktrace 가 있는 것 같네 — `401 Unauthorized` 가 뜨는 거지? 환경 변수 쪽 확인해봤어?"
+ **Good example** (not vision-capable + using describe):
+ > *(after calling whiteboard_describe)*
+ > "From the caption it looks like there's an auth-error stacktrace — you're getting `401 Unauthorized`, right? Have you checked the environment variables?"
- **좋은 예** (seen_before=true):
- > "이거 지난번에도 같이 봤던 그 API 디버깅 메모지? 그때 retry 로직까지 정리한 것 같은데, 이번엔 어디 막혔어?"
+ **Good example** (seen_before=true):
+ > "Isn't this that API debugging note we looked at together last time? I think we even worked out the retry logic back then — where are you stuck this time?"
- **나쁜 예** (절대 하지 말 것):
- > ❌ "[USER_SHARED] 트리거 받았어! capture_id=01HXY... 의 자료를 처리할게."
- > ❌ *(vision-비가용인데 describe 안 부르고)* "이미지에 OOO 가 보이네요" (추측 금지)
+ **Bad examples** (never do this):
+ > ❌ "Got the [USER_SHARED] trigger! I'll process the material at capture_id=01HXY..."
+ > ❌ *(not vision-capable, but calling describe and instead)* "I see OOO in the image" (no guessing)
> ❌ "json: {title: ..., excerpt: ...}"
- ## 금기
+ ## Don'ts
- - `[USER_SHARED]` 트리거 자체를 echo / paraphrase 하지 말 것 ("USER_SHARED 받았어!" X).
- - `capture_id`, `source_filename`, 내부 식별자를 사용자에게 노출 X.
- - 비전 비가용 모델이 이미지 내용을 *추측* 하지 말 것 — 반드시 `whiteboard_describe` 통과.
- - 같은 spotlight 항목을 매 turn 반복 언급하지 말 것 — 사용자가 다른 주제로 이동했으면 자연스럽게 따라간다.
- - `[Spotlight Context]` 블록 자체를 출력에 인용하지 말 것 — 이건 사용자에게 보이지 않는 내부 상태다.
+ - Don't echo / paraphrase the `[USER_SHARED]` trigger itself (no "got USER_SHARED!").
+ - Don't expose `capture_id`, `source_filename`, or internal identifiers to the user.
+ - A non-vision model must not *guess* at the image content — you must go through `whiteboard_describe`.
+ - Don't mention the same spotlight item every turn — if the user has moved to another topic, follow along naturally.
+ - Don't quote the `[Spotlight Context]` block itself in your output — this is internal state that's invisible to the user.