Frame k-skill as an installable Korean skills package

The repo starts as a markdown-first multi-skill package with one shared security policy, one validation script, and lightweight install docs. This keeps v1 easy to publish and easy to review before any skill-specific automation grows deeper.

Constraint: Skills must stay compatible with the skills CLI package layout
Rejected: Add a repo-level manifest or build system | the package spec only requires per-skill SKILL.md
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep credential-bearing skills on 1Password CLI runtime injection, not plaintext env files
Tested: bash scripts/validate-skills.sh
Not-tested: Fresh-machine install via npx skills add
This commit is contained in:
Jeffrey (Dongkyu) Kim 2026-03-25 00:16:11 +09:00
commit dbc091d3d4
8 changed files with 271 additions and 0 deletions

8
.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
.DS_Store
node_modules/
.omx/
.env
.env.*
!examples/.env.op.example
.venv/
__pycache__/

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

74
README.md Normal file
View file

@ -0,0 +1,74 @@
# k-skill
한국인을 위한, 한국인에 의한, 한국인의 에이전트 스킬 모음집.
이 레포는 `skills` CLI로 설치 가능한 멀티-스킬 패키지다. 목표는 "한국인이라면 바로 쓸만한 자동화"를 가장 얇은 레이어로 묶는 것이다. v1은 이미 공개된 CLI, 패키지, 공식 Open API 위에 얹을 수 있는 것부터 빠르게 출발한다.
## Why
- `awesome list`처럼 소비되지만 실제로는 바로 실행 가능한 스킬 묶음으로 보이게 만들기
- 한국 로컬 서비스에 특화된 사용처로 차별화하기
- 큰 제품을 만들기 전에 virality가 나오는지 빠르게 검증하기
## v1 skills
- `srt-booking`: SRT 조회, 예매, 예약 확인, 취소
- `ktx-booking`: KTX/Korail 조회, 예매, 예약 확인, 취소
- `kbo-results`: 특정 날짜 KBO 경기 결과 조회
- `lotto-results`: 로또 최신 회차, 특정 회차, 번호 대조
- `seoul-subway-arrival`: 서울 지하철 실시간 도착 정보 조회
## Install
레포 전체에서 설치 가능한 스킬을 먼저 확인:
```bash
npx --yes skills add <owner/repo> --list
```
원하는 스킬만 선택 설치:
```bash
npx --yes skills add <owner/repo> --skill srt-booking --skill kbo-results
```
로컬 경로로 테스트 설치:
```bash
npx --yes skills add . --list
```
## Security policy
인증이 필요한 스킬은 평문 비밀번호, 직접 입력, `.env` 평문 파일을 금지한다.
- 필수: `1Password CLI (op)`
- 권장 실행 방식: `op run --env-file=.env.op -- <command>`
- 상세 정책: [`docs/security-and-secrets.md`](/Users/jeffrey/Projects/k-skill/docs/security-and-secrets.md)
- 예시 템플릿: [`examples/.env.op.example`](/Users/jeffrey/Projects/k-skill/examples/.env.op.example)
## Development
스킬 구조 검증:
```bash
bash scripts/validate-skills.sh
```
## Roadmap
다음 후보는 v1 뒤로 미뤘다.
- 네이버 스마트스토어 검색/주문
- 다나와 가격 비교
- 카카오톡 조회/전송
- HWP 문서 편집
- 당근 자동 거래
이유는 대체로 셋 중 하나다.
- 공개 CLI가 아직 약하다
- 공식 API auth/setup이 무겁다
- 자동화 안정성보다 계정 리스크가 크다
자세한 메모는 [`docs/roadmap.md`](/Users/jeffrey/Projects/k-skill/docs/roadmap.md)에 둔다.

38
docs/roadmap.md Normal file
View file

@ -0,0 +1,38 @@
# Roadmap
## v1 shipped first
빠르게 만들 수 있고, 공개 패키지나 공식 Open API 위에 얹을 수 있는 스킬부터 넣는다.
- SRT
- KTX
- KBO 경기 결과
- 로또 당첨번호
- 서울 지하철 도착 정보
## v1.5 candidates
### 네이버 스마트스토어
- 장점: 실제 수요가 크다
- 보류 이유: 공식 Commerce API auth/setup이 가볍지 않다
### 다나와 가격 비교
- 장점: 검색 수요가 명확하다
- 보류 이유: 안정적인 공개 CLI를 아직 못 찾았다
### 카카오톡 조회/전송
- 장점: 어그로가 매우 강하다
- 보류 이유: 계정/정책 리스크가 크다
### HWP 문서 편집
- 장점: 한국 로컬리티가 매우 강하다
- 보류 이유: 믿을 만한 자동화 표면이 아직 얇다
### 당근 자동 거래
- 장점: 바이럴 포텐셜이 높다
- 보류 이유: 계정 제재 리스크와 UI automation 의존도가 높다

View file

@ -0,0 +1,64 @@
# Security And Secrets
`k-skill`은 인증이 필요한 스킬에서 비밀번호나 토큰을 채팅창에 직접 붙여 넣는 방식을 허용하지 않는다. 기본 원칙은 "비밀값은 런타임 주입만 허용"이다.
## Required
- `op` installed
- signed in to 1Password
- shared vault or personal vault with the needed credentials
## Allowed patterns
### 1. `op run` with secret references
`.env.op` 같은 파일에는 실제 비밀번호를 넣지 말고 `op://...` 참조만 둔다.
```dotenv
KSKILL_SRT_ID=op://Private/k-skill-srt/username
KSKILL_SRT_PASSWORD=op://Private/k-skill-srt/password
KSKILL_KTX_ID=op://Private/k-skill-ktx/username
KSKILL_KTX_PASSWORD=op://Private/k-skill-ktx/password
SEOUL_OPEN_API_KEY=op://Private/k-skill-seoul-openapi/credential
```
실행은 항상 다음 패턴으로 한다.
```bash
op run --env-file=.env.op -- <command>
```
### 2. `op read` for one-off reads
단발성 확인이 필요할 때만 사용한다.
```bash
op read "op://Private/k-skill-srt/username"
```
## Forbidden patterns
- 채팅 메시지에 비밀번호/토큰을 직접 붙여 넣기
- 실제 비밀값이 들어있는 `.env` 파일을 git에 두기
- 셸 히스토리에 남는 `export PASSWORD=...`
- 스킬 문서 안에 예시용 실비밀번호를 쓰기
## Suggested vault items
- `k-skill-srt`
- `k-skill-ktx`
- `k-skill-seoul-openapi`
필드는 최소한 다음으로 맞춘다.
- `username`
- `password`
- `credential`
## Why 1Password CLI
- `op run`, `op read`, `op inject`로 런타임 주입 경로가 명확하다
- 에이전트가 평문 비밀값 대신 secret reference를 다루기 쉽다
- 팀 공유 vault와 개인 vault를 둘 다 지원한다
이 레포의 credential-bearing skill은 전부 이 정책을 전제로 작성한다.

10
docs/sources.md Normal file
View file

@ -0,0 +1,10 @@
# Sources
현재 v1 설계 시 확인한 외부 표면:
- Vercel skills package 구조: https://vercel.com/kb/guide/agent-skills-creating-installing-and-sharing-reusable-agent-context
- `koreantrain`: https://pypi.org/project/koreantrain/
- `kbo-game`: https://github.com/vkehfdl1/kbo-game
- `korean-lotto`: https://github.com/hs85jeong/korean-lotto
- 서울특별시 지하철 실시간 도착정보: https://www.data.go.kr/data/15058052/openapi.do
- 1Password CLI: https://developer.1password.com/docs/cli/reference/

5
examples/.env.op.example Normal file
View file

@ -0,0 +1,5 @@
KSKILL_SRT_ID=op://Private/k-skill-srt/username
KSKILL_SRT_PASSWORD=op://Private/k-skill-srt/password
KSKILL_KTX_ID=op://Private/k-skill-ktx/username
KSKILL_KTX_PASSWORD=op://Private/k-skill-ktx/password
SEOUL_OPEN_API_KEY=op://Private/k-skill-seoul-openapi/credential

51
scripts/validate-skills.sh Executable file
View file

@ -0,0 +1,51 @@
#!/usr/bin/env bash
set -euo pipefail
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
status=0
while IFS= read -r -d '' skill_dir; do
skill_name="$(basename "$skill_dir")"
skill_file="$skill_dir/SKILL.md"
if [[ ! -f "$skill_file" ]]; then
echo "missing SKILL.md: $skill_name"
status=1
continue
fi
if ! head -n 1 "$skill_file" | grep -qx -- "---"; then
echo "missing frontmatter start: $skill_file"
status=1
fi
if ! grep -q '^name: ' "$skill_file"; then
echo "missing name field: $skill_file"
status=1
fi
if ! grep -q '^description: ' "$skill_file"; then
echo "missing description field: $skill_file"
status=1
fi
declared_name="$(sed -n 's/^name: //p' "$skill_file" | head -n 1 | tr -d '"')"
if [[ "$declared_name" != "$skill_name" ]]; then
echo "name mismatch: $skill_file declares '$declared_name' but directory is '$skill_name'"
status=1
fi
done < <(
find "$root" -mindepth 1 -maxdepth 1 -type d \
! -name .git \
! -name .omx \
! -name docs \
! -name scripts \
! -name examples \
-print0
)
if [[ "$status" -ne 0 ]]; then
exit "$status"
fi
echo "skill layout looks valid"