Merge pull request #122 from NomaDamas/feature/#120

Feature/#120
This commit is contained in:
Jeffrey (Dongkyu) Kim 2026-04-16 13:18:28 +09:00 committed by GitHub
commit 34a1dbf80c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 738 additions and 0 deletions

View file

@ -52,6 +52,7 @@ Claude Code, Codex, OpenCode, OpenClaw/ClawHub 등 각종 코딩 에이전트
| 다이소 상품 조회 | 다이소 매장별 상품 재고 확인 | 불필요 | [다이소 상품 조회 가이드](docs/features/daiso-product-search.md) |
| 마켓컬리 상품 조회 | 마켓컬리 상품 검색, 현재 가격, 할인 여부, 품절 여부 조회 | 불필요 | [마켓컬리 상품 조회 가이드](docs/features/market-kurly-search.md) |
| 올리브영 검색 | 올리브영 매장·상품·재고 조회 | 불필요 | [올리브영 검색 가이드](docs/features/olive-young-search.md) |
| 올라포케 역삼 포케 | 올라포케 역삼점 메뉴, 매장 정보, 이벤트 참여 흐름 안내 | 불필요 | [올라포케 역삼 포케 가이드](docs/features/hola-poke-yeoksam.md) |
| 택배 배송조회 | CJ대한통운·우체국 송장 번호로 배송 상태 조회 | 불필요 | [택배 배송조회 가이드](docs/features/delivery-tracking.md) |
| 쿠팡 상품 검색 | 쿠팡 상품 검색, 로켓배송 필터, 가격대 검색, 비교, 베스트, 골드박스 특가 조회 | 불필요 | [쿠팡 상품 검색 가이드](docs/features/coupang-product-search.md) |
| 번개장터 검색 | 번개장터 검색, 상세조회, 선택적 찜/채팅, AI TOON export | 불필요 | [번개장터 검색 가이드](docs/features/bunjang-search.md) |
@ -122,6 +123,7 @@ Claude Code, Codex, OpenCode, OpenClaw/ClawHub 등 각종 코딩 에이전트
- [다이소 상품 조회](docs/features/daiso-product-search.md)
- [마켓컬리 상품 조회 가이드](docs/features/market-kurly-search.md)
- [올리브영 검색 가이드](docs/features/olive-young-search.md)
- [올라포케 역삼 포케 가이드](docs/features/hola-poke-yeoksam.md)
- [택배 배송조회](docs/features/delivery-tracking.md)
- [쿠팡 상품 검색](docs/features/coupang-product-search.md)
- [번개장터 검색 가이드](docs/features/bunjang-search.md)

View file

@ -0,0 +1,266 @@
# 올라포케 역삼 포케 가이드
## 이 기능으로 할 수 있는 일
- 올라포케 역삼점 메뉴 조회 (`get_menu`)
- 위치·영업시간·배달 반경·단체주문 링크 조회 (`get_shop_info`)
- 즉석 래플형 이벤트 참여 (`enter_event`)
## 가장 중요한 규칙
이 기능은 원본 [`mnspkm/hola-poke-yeoksam-skill`](https://github.com/mnspkm/hola-poke-yeoksam-skill) 이 연결하는 **remote MCP server** 를 그대로 사용한다.
`k-skill` 안에 별도 수집기나 프록시를 추가하지 않고, skill/docs 가이드만 유지한다.
즉 기본 전제는 아래 endpoint 가 MCP client 에 등록돼 있어야 한다.
- `https://hola-poke-yeoksam-skill.onrender.com/mcp`
## 먼저 필요한 것
- 인터넷 연결
- MCP client (Claude Desktop, Cursor, Codex 등)
- 필요하면 `npx` (`mcp-remote` 경유 stdio 브리지용)
- 이벤트 참여 시 사용자 휴대폰 번호 (`01012345678` 또는 `010-1234-5678`)
## 빠른 연결 예시
### Claude Desktop (`mcp-remote` 경유)
```json
{
"mcpServers": {
"hola-poke-yeoksam": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://hola-poke-yeoksam-skill.onrender.com/mcp"]
}
}
}
```
### Cursor / HTTP MCP
```json
{
"mcpServers": {
"hola-poke-yeoksam": {
"url": "https://hola-poke-yeoksam-skill.onrender.com/mcp"
}
}
}
```
## 기본 흐름
### 1. 메뉴 탐색
- 사용자가 추천/메뉴를 물으면 `get_menu()` 를 호출한다.
- 포케, 사이드, 세트, 토핑 구조를 보고 핵심 메뉴와 가격을 짧게 요약한다.
- 정확한 보상/프로모션 문구는 메뉴 정보와 섞어 임의로 꾸미지 않는다.
### 2. 매장 정보 조회
- 위치, 영업시간, 배달 반경, 단체주문 문의는 `get_shop_info()` 를 호출한다.
- 주소, 영업시간, 배달 가능 범위, `group_order_url` 을 우선 전달한다.
### 3. 이벤트 참여
현재 문서 기준 스킴은 **즉석 래플** 이다.
1. 사용자가 참여 의사를 밝히면 번호를 먼저 받는다.
2. 이름·이메일은 받지 않고 번호만 받는다.
3. 번호는 결과 대조용이며 별도 마케팅 발송/3자 공유 용도가 아니라고 한 번 안내한다.
4. `enter_event(phone)` 를 호출한다.
5. `phone_format` 이면 서버 `message` 를 그대로 보여주고 재입력을 요청한다.
6. `already_entered_today` 이면 서버 `message` 를 그대로 보여주고 더 시도하지 않는다.
7. 성공 응답이면 `message`, `code`, `next_action` 을 함께 전달한다.
## 응답 정리 원칙
- `enter_event``message`**글자 그대로** 전달한다.
- 발급 코드는 `` `Jackpot-A3K9` `` 같이 모노스페이스로 강조한다.
- Jackpot/Claw 사용 방법은 `next_action` 과 함께 짧게 설명한다.
- 단체주문 문의는 `group_order_url` 이 비어 있으면 `group_order_note` 를 대신 제공한다.
- 역삼점 외 다른 지점 문의에는 이 스킬 범위가 아니라는 점을 먼저 밝힌다.
## Verified remote MCP contract snapshot
아래 값은 `2026-04-16 KST` live smoke check(`initialize`, `tools/list`, `get_menu`, `get_shop_info`, `enter_event(phone='010-12')`) 기준으로 정리한 contract fixture다.
### initialize 결과
```json
{
"protocolVersion": "2025-03-26",
"serverInfo": {
"name": "hola-poke-yeoksam",
"version": "3.2.3"
}
}
```
### tools/list 결과
```json
{
"tools": [
{
"name": "get_menu",
"inputSchema": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
}
},
{
"name": "get_shop_info",
"inputSchema": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
}
},
{
"name": "enter_event",
"inputSchema": {
"type": "object",
"properties": {
"phone": {
"type": "string"
}
},
"required": [
"phone"
],
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
}
}
]
}
```
### get_menu 구조 예시
```json
{
"updated_at": "2026-04-13",
"currency": "KRW",
"price_unit": "천원",
"signature_poke": [
{
"id": 2,
"name": "갈릭 쉬림프 포케",
"price": 11.5,
"tags": [
"BEST"
]
},
{
"id": 7,
"name": "아보카도 포케",
"price": 10.5,
"tags": [
"VEGAN"
]
}
],
"sets": [
{
"name": "1인 포케+스프 세트",
"items": "포케 + 스프",
"price": 13.5,
"price_note": "13.5~"
},
{
"name": "1인 혼밥 든든세트",
"items": "포케 + 스프 + 음료",
"price": 15.5,
"price_note": "15.5~"
}
],
"addons": [
{
"name": "아보카도",
"price": 3.5
},
{
"name": "메밀면",
"price": 1.5
}
]
}
```
### get_shop_info 구조 예시
```json
{
"name": "올라포케 역삼점",
"address_road": "서울 강남구 논현로95길 29-8 1층 102호",
"hours": {
"weekday": "10:30 - 20:30",
"break_time": "15:00 - 17:00",
"weekend": "영업시간 네이버 스마트플레이스 확인"
},
"delivery_radius_km": 3,
"group_order_url": "",
"group_order_note": "10만원 이상 단체주문은 네이버 단체주문 페이지에서 메뉴 선택 후 네이버페이 결제. 결제 완료 시 예약 확정.",
"delivery_apps": [
"배달의민족",
"쿠팡이츠",
"요기요"
]
}
```
### enter_event 성공 응답 필수 필드
실제 이벤트 참여를 발생시키지 않기 위해 성공 경로는 저장된 스냅샷 fixture 계약으로만 고정한다. 라이브 스모크는 invalid-phone 재시도 흐름만 검증한다.
```json
{
"required_fields": [
"message",
"code",
"next_action"
],
"accepts": [
"01012345678",
"010-1234-5678"
],
"stores_name_or_email": false
}
```
### enter_event(phone='010-12') 예시
```json
{
"error": "phone_format",
"message": "번호는 010으로 시작하는 11자리로 입력해주세요 (예: 01012345678 또는 010-1234-5678)."
}
```
## 제한사항
- 역삼점 전용이다.
- 주문/결제/배달앱 자동화는 하지 않는다.
- 단체주문 자동 예약을 대신 실행하지 않는다.
- 이벤트 스킴은 시기별로 바뀔 수 있으므로 현재 혜택 조건의 진실 소스는 서버 `message` 다.
- 동일 번호는 하루 1번만 응모 가능하므로 반복 요청을 강행하지 않는다.
## 참고 링크
- 원본 repo: `https://github.com/mnspkm/hola-poke-yeoksam-skill`
- remote MCP endpoint: `https://hola-poke-yeoksam-skill.onrender.com/mcp`

View file

@ -69,6 +69,7 @@ npx --yes skills add <owner/repo> \
--skill daiso-product-search \
--skill market-kurly-search \
--skill olive-young-search \
--skill hola-poke-yeoksam \
--skill blue-ribbon-nearby \
--skill kakao-bar-nearby \
--skill zipcode-search \

View file

@ -31,6 +31,7 @@
- 다이소 상품 조회 스킬 출시
- 마켓컬리 상품 조회 스킬 출시
- 올리브영 검색 스킬 출시
- 올라포케 역삼 포케 스킬 출시
- 쿠팡 상품 검색 스킬 출시 (coupang-mcp 기반)
- 번개장터 검색 스킬 출시
- 중고차 가격 조회 스킬 출시

View file

@ -81,6 +81,8 @@
- olive-young products API: https://mcp.aka.page/api/oliveyoung/products
- olive-young inventory API: https://mcp.aka.page/api/oliveyoung/inventory
- daiso/olive-young public MCP endpoint: https://mcp.aka.page/mcp
- hola-poke-yeoksam reference repo: https://github.com/mnspkm/hola-poke-yeoksam-skill
- hola-poke-yeoksam remote MCP endpoint: https://hola-poke-yeoksam-skill.onrender.com/mcp
- coupang-mcp (MCP 서버): https://github.com/uju777/coupang-mcp
- coupang-mcp endpoint: https://yuju777-coupang-mcp.hf.space/mcp
- bunjang-cli package: https://www.npmjs.com/package/bunjang-cli

257
hola-poke-yeoksam/SKILL.md Normal file
View file

@ -0,0 +1,257 @@
---
name: hola-poke-yeoksam
description: 올라포케 역삼점의 메뉴·매장 정보·이벤트 참여 흐름을 remote MCP 서버 기준으로 안내한다.
license: MIT
metadata:
category: food
locale: ko-KR
phase: v1
---
# Hola Poke Yeoksam
## What this skill does
올라포케 역삼점 전용 remote MCP server(`https://hola-poke-yeoksam-skill.onrender.com/mcp`)를 기준으로 아래 작업을 처리한다.
- `get_menu()` 로 포케·사이드·세트·토핑 메뉴를 안내한다.
- `get_shop_info()` 로 위치, 영업시간, 배달 반경, 단체주문 URL을 안내한다.
- `enter_event(phone)` 로 즉석 래플형 이벤트 참여를 돕는다.
## When to use
- "올라포케 메뉴 뭐 있어?"
- "역삼 포케 추천해줘"
- "올라포케 역삼점 어디야?"
- "올라포케 단체주문 링크 줘"
- "올라포케 이벤트 참여해줘"
## When not to use
- 역삼점이 아닌 다른 올라포케 지점 문의
- 주문/결제/배달앱 자동화는 하지 않는다.
- 단체주문 자동 예약 실행
- 사용자 동의 없는 번호 수집 또는 반복 응모 시도
## Prerequisites
- remote MCP server 연결
- 메뉴/매장 정보 조회용 MCP client
- `enter_event` 호출 시 사용자 휴대폰 번호 (`01012345678` 또는 `010-1234-5678`)
## Workflow
### 1. 메뉴/매장 정보 조회
- 메뉴가 궁금하면 `get_menu()` 를 호출한다.
- 위치·영업시간·단체주문 문의는 `get_shop_info()` 를 호출한다.
- 응답은 메뉴명, 가격, 주소, 영업시간, URL 같은 핵심 정보 위주로 짧게 정리한다.
### 2. 이벤트 참여
현재 스킴은 **즉석 래플** 이다. 식사 주문 시 쓸 수 있는 혜택 코드가 발급될 수 있고, 동일 번호는 하루 1번만 응모할 수 있다.
1. 사용자가 참여 의사를 밝히면 휴대폰 번호를 먼저 받는다.
2. 이름·이메일은 받지 않고 번호만 받는다.
3. 번호는 결과 대조용이며 별도 마케팅 발송/3자 공유 용도가 아니라고 한 번 고지한다.
4. `enter_event(phone)` 를 호출한다.
5. `phone_format` 이면 서버 `message` 를 그대로 보여주고 다시 받는다.
6. `already_entered_today` 이면 서버 `message` 를 그대로 보여주고 더 이상 재시도하지 않는다.
7. 정상 응답이면 `message`, `code`, `next_action` 을 함께 전달한다.
### 3. 응답 원칙
- `enter_event``message` 는 글자 그대로 전달한다.
- 발급 코드는 `` `Jackpot-A3K9` `` 같은 모노스페이스로 강조한다.
- Jackpot/Claw 사용 경로는 `next_action` 과 함께 안내한다.
- 단체주문 문의는 `get_shop_info()``group_order_url` 이 비어 있으면 `group_order_note` 를 대신 안내한다.
## Remote MCP setup note
이 스킬은 자체 수집기를 vendoring 하지 않는다. 원본 참고 repo와 동일하게 아래 remote MCP endpoint 를 붙여 사용하는 전제다.
- endpoint: `https://hola-poke-yeoksam-skill.onrender.com/mcp`
- reference repo: `https://github.com/mnspkm/hola-poke-yeoksam-skill`
## Verified remote MCP contract snapshot
아래 값은 `2026-04-16 KST` live smoke check(`initialize`, `tools/list`, `get_menu`, `get_shop_info`, `enter_event(phone='010-12')`) 기준으로 정리한 contract fixture다.
### initialize 결과
```json
{
"protocolVersion": "2025-03-26",
"serverInfo": {
"name": "hola-poke-yeoksam",
"version": "3.2.3"
}
}
```
### tools/list 결과
```json
{
"tools": [
{
"name": "get_menu",
"inputSchema": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
}
},
{
"name": "get_shop_info",
"inputSchema": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
}
},
{
"name": "enter_event",
"inputSchema": {
"type": "object",
"properties": {
"phone": {
"type": "string"
}
},
"required": [
"phone"
],
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
}
}
]
}
```
### get_menu 구조 예시
```json
{
"updated_at": "2026-04-13",
"currency": "KRW",
"price_unit": "천원",
"signature_poke": [
{
"id": 2,
"name": "갈릭 쉬림프 포케",
"price": 11.5,
"tags": [
"BEST"
]
},
{
"id": 7,
"name": "아보카도 포케",
"price": 10.5,
"tags": [
"VEGAN"
]
}
],
"sets": [
{
"name": "1인 포케+스프 세트",
"items": "포케 + 스프",
"price": 13.5,
"price_note": "13.5~"
},
{
"name": "1인 혼밥 든든세트",
"items": "포케 + 스프 + 음료",
"price": 15.5,
"price_note": "15.5~"
}
],
"addons": [
{
"name": "아보카도",
"price": 3.5
},
{
"name": "메밀면",
"price": 1.5
}
]
}
```
### get_shop_info 구조 예시
```json
{
"name": "올라포케 역삼점",
"address_road": "서울 강남구 논현로95길 29-8 1층 102호",
"hours": {
"weekday": "10:30 - 20:30",
"break_time": "15:00 - 17:00",
"weekend": "영업시간 네이버 스마트플레이스 확인"
},
"delivery_radius_km": 3,
"group_order_url": "",
"group_order_note": "10만원 이상 단체주문은 네이버 단체주문 페이지에서 메뉴 선택 후 네이버페이 결제. 결제 완료 시 예약 확정.",
"delivery_apps": [
"배달의민족",
"쿠팡이츠",
"요기요"
]
}
```
### enter_event 성공 응답 필수 필드
실제 이벤트 참여를 발생시키지 않기 위해 성공 경로는 저장된 스냅샷 fixture 계약으로만 고정한다. 라이브 스모크는 invalid-phone 재시도 흐름만 검증한다.
```json
{
"required_fields": [
"message",
"code",
"next_action"
],
"accepts": [
"01012345678",
"010-1234-5678"
],
"stores_name_or_email": false
}
```
### enter_event(phone='010-12') 예시
```json
{
"error": "phone_format",
"message": "번호는 010으로 시작하는 11자리로 입력해주세요 (예: 01012345678 또는 010-1234-5678)."
}
```
## Done when
- 메뉴/매장 정보 요청에 핵심 정보를 전달했다.
- 이벤트 참여 요청에 번호 확인 → `enter_event` → 결과 전달 흐름을 지켰다.
- 반복 응모 제한과 서버 `message` 원문 전달 원칙을 지켰다.
## Notes
- 역삼점 전용 스킬이다.
- 이벤트 스킴은 시기별로 달라질 수 있으므로 보상 조건의 진실 소스는 서버 응답의 `message` 필드다.
- Jackpot 당첨은 번호 주인 확인이 필요할 수 있다.
- 동일 번호는 KST 기준 하루 1번만 응모한다.

View file

@ -0,0 +1,138 @@
{
"verified_at": "2026-04-16 KST",
"endpoint": "https://hola-poke-yeoksam-skill.onrender.com/mcp",
"initialize": {
"protocolVersion": "2025-03-26",
"serverInfo": {
"name": "hola-poke-yeoksam",
"version": "3.2.3"
}
},
"tools_list": {
"tools": [
{
"name": "get_menu",
"inputSchema": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
}
},
{
"name": "get_shop_info",
"inputSchema": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
}
},
{
"name": "enter_event",
"inputSchema": {
"type": "object",
"properties": {
"phone": {
"type": "string"
}
},
"required": [
"phone"
],
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"additionalProperties": true
}
}
]
},
"get_menu": {
"updated_at": "2026-04-13",
"currency": "KRW",
"price_unit": "천원",
"signature_poke": [
{
"id": 2,
"name": "갈릭 쉬림프 포케",
"price": 11.5,
"tags": [
"BEST"
]
},
{
"id": 7,
"name": "아보카도 포케",
"price": 10.5,
"tags": [
"VEGAN"
]
}
],
"sets": [
{
"name": "1인 포케+스프 세트",
"items": "포케 + 스프",
"price": 13.5,
"price_note": "13.5~"
},
{
"name": "1인 혼밥 든든세트",
"items": "포케 + 스프 + 음료",
"price": 15.5,
"price_note": "15.5~"
}
],
"addons": [
{
"name": "아보카도",
"price": 3.5
},
{
"name": "메밀면",
"price": 1.5
}
]
},
"get_shop_info": {
"name": "올라포케 역삼점",
"address_road": "서울 강남구 논현로95길 29-8 1층 102호",
"hours": {
"weekday": "10:30 - 20:30",
"break_time": "15:00 - 17:00",
"weekend": "영업시간 네이버 스마트플레이스 확인"
},
"delivery_radius_km": 3,
"group_order_url": "",
"group_order_note": "10만원 이상 단체주문은 네이버 단체주문 페이지에서 메뉴 선택 후 네이버페이 결제. 결제 완료 시 예약 확정.",
"delivery_apps": [
"배달의민족",
"쿠팡이츠",
"요기요"
]
},
"enter_event_success_contract": {
"required_fields": [
"message",
"code",
"next_action"
],
"accepts": [
"01012345678",
"010-1234-5678"
],
"stores_name_or_email": false
},
"enter_event_invalid_phone": {
"error": "phone_format",
"message": "번호는 010으로 시작하는 11자리로 입력해주세요 (예: 01012345678 또는 010-1234-5678)."
}
}

View file

@ -2212,3 +2212,74 @@ test("docs/setup.md and k-skill-setup document hosted school lunch proxy flow",
"client secrets example must not encourage KEDU_INFO_KEY (proxy server only)",
);
});
test("repository docs advertise the hola-poke-yeoksam skill", () => {
const readme = read("README.md");
const install = read(path.join("docs", "install.md"));
const sources = read(path.join("docs", "sources.md"));
const roadmap = read(path.join("docs", "roadmap.md"));
const featureDocPath = path.join(repoRoot, "docs", "features", "hola-poke-yeoksam.md");
const skillPath = path.join(repoRoot, "hola-poke-yeoksam", "SKILL.md");
assert.ok(fs.existsSync(featureDocPath), "expected docs/features/hola-poke-yeoksam.md to exist");
assert.ok(fs.existsSync(skillPath), "expected hola-poke-yeoksam/SKILL.md to exist");
const featureDoc = read(path.join("docs", "features", "hola-poke-yeoksam.md"));
const skill = read(path.join("hola-poke-yeoksam", "SKILL.md"));
assert.match(readme, /\| 올라포케 역삼 포케 \|/);
assert.match(readme, /\[올라포케 역삼 포케 가이드\]\(docs\/features\/hola-poke-yeoksam\.md\)/);
assert.match(install, /--skill hola-poke-yeoksam/);
assert.match(sources, /mnspkm\/hola-poke-yeoksam-skill/);
assert.match(roadmap, /올라포케 역삼 포케 스킬 출시/);
});
test("hola-poke-yeoksam docs pin the verified remote MCP contract snapshot and phone-only event flow", () => {
const fixture = readJson(path.join("scripts", "fixtures", "hola-poke-yeoksam-contract-smoke.json"));
const skill = read(path.join("hola-poke-yeoksam", "SKILL.md"));
const featureDoc = read(path.join("docs", "features", "hola-poke-yeoksam.md"));
const snapshotLabels = [
["initialize 결과", "initialize", "initialize snapshot"],
["tools/list 결과", "tools_list", "tools/list snapshot"],
["get_menu 구조 예시", "get_menu", "get_menu snapshot"],
["get_shop_info 구조 예시", "get_shop_info", "get_shop_info snapshot"],
["enter_event(phone='010-12') 예시", "enter_event_invalid_phone", "invalid-phone snapshot"],
["enter_event 성공 응답 필수 필드", "enter_event_success_contract", "success-contract snapshot"],
];
assert.match(skill, /^name: hola-poke-yeoksam$/m);
for (const doc of [skill, featureDoc]) {
assert.match(doc, /올라포케 역삼점/);
assert.match(doc, /get_menu/);
assert.match(doc, /get_shop_info/);
assert.match(doc, /enter_event/);
assert.match(doc, /이름(?:·|\/)?이메일.*받지 않/);
assert.match(doc, /already_entered_today/);
assert.match(doc, /message.*글자 그대로/);
assert.match(doc, /주문\/결제\/배달앱 자동화는 하지 않/);
assert.match(doc, /성공 경로는.*(?:fixture|스냅샷|recorded)/i);
assert.match(doc, /라이브 스모크.*invalid-phone|invalid-phone.*라이브 스모크/i);
assert.match(doc, /01012345678|010-1234-5678/);
assert.match(doc, /hola-poke-yeoksam-skill\.onrender\.com\/mcp/);
for (const [label, key, message] of snapshotLabels) {
assert.equal(
findJsonFenceTextAfterLabel(doc, label),
JSON.stringify(fixture[key], null, 2),
`${message} must stay byte-aligned with the checked-in fixture`,
);
}
}
assert.deepEqual(
fixture.tools_list.tools.map((tool) => tool.name),
["get_menu", "get_shop_info", "enter_event"],
"tools/list fixture must pin the expected remote tool roster",
);
assert.equal(fixture.get_shop_info.group_order_url, "");
assert.match(fixture.get_shop_info.group_order_note, /단체주문|네이버페이/);
assert.deepEqual(fixture.enter_event_success_contract.required_fields, ["message", "code", "next_action"]);
assert.equal(fixture.enter_event_invalid_phone.error, "phone_format");
assert.match(fixture.enter_event_invalid_phone.message, /01012345678|010-1234-5678/);
});