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
2 changes: 1 addition & 1 deletion .github/workflows/external-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:

- name: Run external smoke sequentially
env:
CLI_SMOKE_SERVICES: daiso gs25 seveneleven emart24 lottemart oliveyoung megabox lottecinema cgv opinet
CLI_SMOKE_SERVICES: daiso gs25 seveneleven emart24 lottemart oliveyoung megabox lottecinema cgv opinet dtryx
MCP_SMOKE_SERVICES: daiso gs25 seveneleven emart24 opinet
SMOKE_ATTEMPT_TIMEOUT_SECONDS: 90
run: |
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@

# Daiso MCP 및 Skill

다이소(제품/매장/재고), 상품 가격 비교, 주변 음식점/카페, 주유소/유가, 개발자 요청 제출, 롯데마트(매장/상품), GS25(매장/상품/재고), 세븐일레븐(상품/매장/재고/인기검색어/카탈로그), CU(매장/재고), 이마트24(매장/상품/재고), 올리브영(매장/재고), 메가박스(지점/영화/시간표/좌석), 롯데시네마(지점/영화/좌석), CGV(극장/영화/시간표) 조회 기능을 MCP, CLI, Codex Skill로 AI에 연결합니다.
다이소(제품/매장/재고), 상품 가격 비교, 주변 음식점/카페, 주유소/유가, 개발자 요청 제출, 롯데마트(매장/상품), GS25(매장/상품/재고), 세븐일레븐(상품/매장/재고/인기검색어/카탈로그), CU(매장/재고), 이마트24(매장/상품/재고), 올리브영(매장/재고), 메가박스(지점/영화/시간표/좌석), 롯데시네마(지점/영화/좌석), CGV(극장/영화/시간표), 디트릭스(독립·예술영화관/상영작/잔여 좌석) 조회 기능을 MCP, CLI, Codex Skill로 AI에 연결합니다.

디트릭스의 지원 범위와 CLI 예시는 [독립·예술영화관 조회 가이드](docs/dtryx.md)를 참고하세요.

<br>

Expand Down
37 changes: 37 additions & 0 deletions docs/dtryx.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# 디트릭스 독립·예술영화관 조회

디트릭스 예매 플랫폼을 사용하는 극장의 상영작, 상영 가능 날짜, 회차별 잔여 좌석을 조회합니다. 공개 원본 API를 직접 사용하며 Zyte나 별도 API 키가 필요하지 않습니다.

## 조회 방법

MCP 도구는 `dtryx_list_cinemas`, `dtryx_list_now_showing`, `dtryx_get_remaining_seats`입니다. 예를 들어 “서울 독립영화관에서 오늘 상영하는 영화와 잔여 좌석을 찾아줘”라고 요청할 수 있습니다.

```bash
npx daiso get /api/dtryx/cinemas --region 서울
npx daiso get /api/dtryx/movies --keyword 모모 --includePlayDates true
npx daiso get /api/dtryx/seats --region 서울 --movieName 경멸 --limit 20
```

- 상영작 조회에는 `cinemaCode` 또는 극장명 `keyword`가 필요합니다. 검색 결과가 여러 곳이면 첫 번째 극장을 선택하므로 정확한 조회에는 극장 코드를 쓰세요.
- 회차 조회에 극장 조건이 없으면 카탈로그 전체를 조회합니다. `region`, `keyword`, `brandCode`를 함께 쓰면 모든 조건에 맞는 극장만 조회합니다.
- `playDate`는 `YYYYMMDD` 또는 `YYYY-MM-DD`를 받으며 생략하면 한국 날짜 기준 오늘입니다. 원본에는 하이픈 날짜로 전달합니다.
- `limit`은 1~200, `timeoutMs`는 1~60000 정수이며 기본값은 각각 50, 15000입니다.
- 일부 극장 조회가 실패하면 성공한 회차와 `failedCinemas`를 함께 반환합니다. 모든 극장 조회가 실패하면 API는 503, MCP는 오류를 반환합니다. 성공적으로 조회한 날에 편성이 없으면 빈 목록일 수 있습니다.

## 카탈로그 범위

현재 확인된 극장 22곳을 `src/services/dtryx/location.ts`에서 관리합니다. 전체 제휴 극장 목록을 보장하지 않습니다. 폐업·이전·신규 입점 여부를 정기적으로 확인해야 합니다. 좌표가 없어 거리순 조회는 제공하지 않습니다.

카탈로그에 없는 극장도 공식 `cinemaCode`와 `brandCode`를 함께 알고 있으면 조회할 수 있습니다. 좌석은 조회 시점의 원본 정보로, 예매 과정에서 달라질 수 있습니다.

## 메가박스 CLI

기존 메가박스 API에 전용 CLI 명령을 추가했습니다.

```bash
npx daiso megabox-theaters 강남 --limit 3
npx daiso megabox-movies --theaterId 1372
npx daiso megabox-seats --theaterId 1372 --limit 10
```

디트릭스는 위의 범용 `get` 명령을 사용합니다. API 명세와 Actions에도 디트릭스 경로가 포함돼 있습니다.
33 changes: 33 additions & 0 deletions docs/release-1.1.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# 1.1.0 릴리스 노트

## 추가

- 디트릭스 독립·예술영화관 22곳의 카탈로그, 상영작·상영 가능 날짜, 회차별 잔여 좌석을 MCP와 GET API로 제공합니다. 지역·극장명·브랜드 필터를 함께 적용하고, 부분 실패와 전체 장애를 구분합니다.
- 메가박스 CLI 명령 `megabox-theaters`, `megabox-movies`, `megabox-seats`를 추가했습니다.
- 디트릭스 API 명세, Actions 연결, CLI 사용 가이드와 운영 검사를 추가했습니다.

## 수정

- MCP smoke는 오류 응답을 JSON으로 해석하지 않고 원래 오류를 보존합니다.
- Zyte 계정 정지·키 누락과 GS25 인증 장애는 자동 재시도 대신 운영 설정 확인을 안내합니다.
- CU 웹 매장 검색은 공식 GET 경로를 사용합니다. 같은 검색 필드와 기존 Zyte POST 폴백은 유지합니다.
- 공용 JSON·텍스트 요청의 제한 시간을 응답 본문 읽기까지 적용합니다. 본문 오류에 새 재시도를 추가하지 않습니다.
- 현재 Node 타입과 호환되도록 인터랙티브 CLI의 표준 입출력 참조를 수정했습니다.

## 이전 npm 배포 이후 누적 반영

7월 14일의 1.0.10 이후 main에 반영된 Home Assistant 스키마 호환, MCP 오류 응답 계약, 한국 날짜 기준 영화 검색, GS25 공개 매장 API, 롯데시네마 잔여 좌석 계산, 운영 호출 제한 통계와 의존성 보안 수정을 포함합니다.

CLI는 원격 API를 호출하므로 서버 측 수정 중 일부는 기존 CLI에서도 적용됐습니다. 이번 릴리스는 패키지의 코드와 명령을 최신 main에 맞춥니다.

## 의존성

MCP SDK 1.30.0, Wrangler 4.131.2, Workers 타입 5.20260914.1, Biome 2.5.13, Node 타입 26.5.1, Playwright 1.63.0, proj4 2.22.0, globals 17.12.0으로 호환 가능한 갱신을 반영했습니다. Node 런타임 최소 버전은 22입니다.

## 운영 제약

릴리스 자체가 외부 계정이나 인증키를 복구하지는 않습니다. Zyte 정지 상태에서 이를 필요로 하는 서비스는 계속 조회 불가일 수 있으며, GS25 재고에는 유효한 GS25_API_KEY가 필요합니다. CU 재고의 운영 HTML 응답과 간헐적인 이마트24 지연은 배포 후 별도로 검증합니다. 비용 한도는 올리지 않았습니다.

## 기여

메가박스 CLI는 helenanova의 PR #183, 디트릭스는 bgmbgm94의 PR #178을 기반으로 통합하고 오류 처리·검증·문서를 보완했습니다.
40 changes: 40 additions & 0 deletions docs/superpowers/plans/2026-09-15-maintenance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# September Maintenance Implementation Plan

> Use superpowers:subagent-driven-development for independent implementation and review; operational investigation runs alongside code work.

**Goal:** Restore recoverable service paths, improve diagnostics, integrate compatible maintenance PRs, and release verified code.

**Architecture:** Keep existing Worker, REST, MCP and CLI interfaces. Preserve explicit upstream failures and distinguish account configuration errors from transient failures. No spending-limit increase.

**Tech Stack:** TypeScript, Vitest, Cloudflare Workers, npm, GitHub Actions.

## Task 1: Error diagnostics

Files: scripts/ops/mcp-smoke.ts, src/core/errors.ts, tests/scripts/mcp-smoke.test.ts and existing error tests.

- [ ] Add a failing smoke test returning `{isError:true,content:[{type:'text',text:'Zyte API 호출 실패: 403 Your account has been suspended.'}]}`; assert error is preserved and no JSON parse error appears.
- [ ] Add diagnostics tests: known Zyte account suspension and missing credential are nonretryable with operator configuration guidance; ordinary upstream WAF 403 wrapped by 500 remains existing behavior; timeouts/429/5xx remain retryable.
- [ ] Run targeted Vitest tests and confirm intended failures.
- [ ] Implement minimal error-first parsing and narrowly recognized account/configuration classification. Preserve normal JSON validation.
- [ ] Run targeted tests, check, coverage, build; independent spec then quality review.

## Task 2: Operational recovery

- [ ] Check authenticated existing health data and Zyte billing/stats read-only, without changing spending limits.
- [ ] Compare CU and emart24 official requests with deployed failures; inspect GS25 authentication configuration and CGV direct endpoint.
- [ ] For each confirmed defect, record request evidence and add a failing regression test in the affected client tests before implementation. Do not invent fallback data or convert failures to success.
- [ ] Validate recovered path in deployment; document unresolved external credentials/account restrictions.

## Task 3: Dependencies and feature PRs

- [ ] Read current PR heads/diffs and lockfile versions; exclude superseded downgrades.
- [ ] Integrate compatible patch/minor updates, test installation without peer overrides, run audit and required checks.
- [ ] Review PR #183 and #178 actual code. Preserve contributor attribution when integrating; fill verified test/documentation gaps. Recheck complete coverage.
- [ ] Resolve superseded PRs and merge verified work within user authorization, preserving original branches.

## Task 4: Release and verification

- [ ] Independent final review, npm run check, npm run test:coverage, npm audit, npm run build, npm run release:dry-run.
- [ ] Version/tag commit, push matching Git state, publish npm using configured credentials or workflow. Verify registry version and gitHead.
- [ ] Verify deployment workflow and representative deployed API/MCP calls; record limitations with evidence.
- [ ] Update personal PROJECT.md and maintenance report, send completion notification.
18 changes: 18 additions & 0 deletions docs/superpowers/specs/2026-09-15-maintenance-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# 9월 유지보수 설계

사용자는 2026-09-15 점검 보고서의 모든 유지보수 진행을 승인했습니다.

## 범위와 완료 기준

1. MCP smoke는 오류 text를 JSON으로 해석하기 전에 isError를 확인하고 원인을 보존합니다. 계정 정지·설정 오류는 재시도 가능 장애와 구분합니다. 정상 응답 계약은 유지합니다.
2. Zyte 정지 사유와 GS25 인증 상태를 확인하고 CU·이마트24·CGV의 공식 요청 경로를 조사합니다. 확인된 무료 직접 경로가 있으면 복구하고, 없는 경우 명시적 조회 불가를 유지합니다. 비용 한도 상향이나 새 과금 계약은 포함하지 않습니다.
3. 의존성 PR 10건을 최신 main과 비교해 이미 반영된 항목을 정리하고 호환 가능한 갱신을 검증합니다. 메가박스 CLI와 디트릭스 PR은 코드·테스트·문서 검토 후 가능한 범위를 통합합니다.
4. 정적 검사, 모든 테스트, 네 지표 100% coverage, audit, 빌드, 패키지 dry-run, 독립 리뷰를 통과한 변경을 GitHub에 반영합니다. 릴리스 커밋과 태그를 일치시키고 npm 게시를 검증합니다. 배포 후 기존 운영 체크를 다시 확인합니다.

## 접근

단순 의존성 갱신만으로는 운영 장애가 해결되지 않습니다. 반대로 유료 우회 확대는 기존 비용 결정을 위반합니다. 오류 원인을 보존하는 작은 수정, 검증된 공식 직접 경로 복구, 호환 의존성 통합을 순차 반영합니다. 장애를 빈 성공으로 숨기거나 확인되지 않은 인증키를 생성하지 않습니다.

## 구조와 검증

기존 scripts/ops/mcp-smoke.ts, src/core/errors.ts와 대응 테스트를 우선 수정합니다. 서비스 수정은 해당 client/api 모듈에 제한하고 450줄을 유지합니다. 오류 회귀는 실패 테스트를 먼저 작성하고 통과시킵니다. 외부 계정 사유와 코드 결함을 분리해 기록합니다. 외부 제약 때문에 실제 조회를 복구하지 못한 경우에는 검증 결과와 남은 조건을 명시합니다.
50 changes: 49 additions & 1 deletion openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,51 @@
"summary": "공통 GET 액션 실행",
"description": "action 값에 따라 기존 GET API 엔드포인트로 프록시합니다. OpenAI Actions 등록 시 이 단일 엔드포인트를 사용하세요.",
"parameters": [
{
"name": "cinemaCode",
"in": "query",
"required": false,
"description": "디트릭스 극장 코드",
"schema": {
"type": "string"
}
},
{
"name": "brandCode",
"in": "query",
"required": false,
"description": "디트릭스 브랜드 코드",
"schema": {
"type": "string"
}
},
{
"name": "region",
"in": "query",
"required": false,
"description": "디트릭스 광역 지역명",
"schema": {
"type": "string"
}
},
{
"name": "movieName",
"in": "query",
"required": false,
"description": "디트릭스 영화명 부분 일치",
"schema": {
"type": "string"
}
},
{
"name": "includePlayDates",
"in": "query",
"required": false,
"description": "디트릭스 상영 가능 날짜 포함",
"schema": {
"type": "boolean"
}
},
{
"name": "action",
"in": "query",
Expand All @@ -30,6 +75,9 @@
"schema": {
"type": "string",
"enum": [
"dtryxListCinemas",
"dtryxListNowShowing",
"dtryxGetRemainingSeats",
"daisoSearchProducts",
"daisoGetProduct",
"daisoFindStores",
Expand Down Expand Up @@ -551,7 +599,7 @@
"name": "timeoutMs",
"in": "query",
"required": false,
"description": "세븐일레븐 inventory 타임아웃",
"description": "원본 요청 타임아웃(ms), 디트릭스는 1~60000",
"schema": {
"type": "integer"
}
Expand Down
35 changes: 34 additions & 1 deletion openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,46 @@ paths:
summary: 공통 GET 액션 실행
description: action 값에 따라 기존 GET API 엔드포인트로 프록시합니다. OpenAI Actions 등록 시 이 단일 엔드포인트를 사용하세요.
parameters:
- name: cinemaCode
in: query
required: false
description: 디트릭스 극장 코드
schema:
type: string
- name: brandCode
in: query
required: false
description: 디트릭스 브랜드 코드
schema:
type: string
- name: region
in: query
required: false
description: 디트릭스 광역 지역명
schema:
type: string
- name: movieName
in: query
required: false
description: 디트릭스 영화명 부분 일치
schema:
type: string
- name: includePlayDates
in: query
required: false
description: 디트릭스 상영 가능 날짜 포함
schema:
type: boolean
- name: action
in: query
required: true
description: 실행할 액션 이름입니다. 사용 가능한 값은 enum 목록을 참고하세요.
schema:
type: string
enum:
- dtryxListCinemas
- dtryxListNowShowing
- dtryxGetRemainingSeats
- daisoSearchProducts
- daisoGetProduct
- daisoFindStores
Expand Down Expand Up @@ -389,7 +422,7 @@ paths:
- name: timeoutMs
in: query
required: false
description: 세븐일레븐 inventory 타임아웃
description: 원본 요청 타임아웃(ms), 디트릭스는 1~60000
schema:
type: integer
responses:
Expand Down
Loading