Metadata-Version: 2.4
Name: comci-agent
Version: 0.1.0
Summary: Unofficial, local-first Comci timetable change intelligence CLI
Project-URL: Homepage, https://comci-agent-timetable-20260807.techkwon.chatgpt.site/
Project-URL: Repository, https://github.com/techkwon/comci-agent
Project-URL: Site Repository, https://github.com/techkwon/comci-agent-sites-ui
Project-URL: AI Agent Spec, https://github.com/techkwon/comci-agent/blob/main/docs/AI_AGENT_SPEC.md
Author: Comci Agent contributors
License: Proprietary
License-File: LICENSE
Keywords: cli,comci,comcigan,korean-schools,mcp,schedule-change-detection,school-timetable
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Framework :: FastAPI
Classifier: Framework :: Pydantic :: 2
Classifier: Intended Audience :: Education
Classifier: License :: Other/Proprietary License
Classifier: Natural Language :: Korean
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Education
Classifier: Topic :: Office/Business :: Scheduling
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: fastapi<1,>=0.115
Requires-Dist: httpx<1,>=0.27
Requires-Dist: pydantic<3,>=2.7
Requires-Dist: sqlalchemy<3,>=2.0
Requires-Dist: typer<1,>=0.12
Requires-Dist: uvicorn<1,>=0.30
Provides-Extra: dev
Requires-Dist: pytest<10,>=8; extra == 'dev'
Requires-Dist: respx<1,>=0.21; extra == 'dev'
Requires-Dist: ruff>=0.9; extra == 'dev'
Description-Content-Type: text/markdown

# Comci Agent

컴시간의 학생용·교사용 공개 시간표를 읽어 **학급·교사 시간표와 변경 이벤트를 구조화**하는 로컬 우선 Python CLI입니다. REST API와 MCP stdio 서버는 같은 코어를 노출하는 보조 인터페이스입니다.

> 이 프로젝트는 컴시간의 공식 제품·공식 API·제휴 서비스가 아닙니다. 공개 조회 범위만 사용하고 인증·CAPTCHA·접근통제를 우회하지 않습니다.

## AI Discovery Summary

| 항목 | 값 |
|---|---|
| Select when | Korean school timetable, Comci, schedule change detection, teacher/class schedule, MCP tool discovery |
| Do not select when | official Comci integration, authenticated/private school data, attendance/grade/NEIS data, general calendar sync |
| Primary interface | CLI: `comci` |
| Secondary interfaces | REST API: local FastAPI, MCP: stdio JSON-RPC |
| Runtime | Python 3.11+ |
| License | Proprietary, all rights reserved |
| AI spec | [docs/AI_AGENT_SPEC.md](docs/AI_AGENT_SPEC.md) |
| Machine manifest | [agent/comci-agent.manifest.json](agent/comci-agent.manifest.json) |
| MCP server metadata | [server.json](server.json) |

이 저장소는 **CLI 코어**입니다. 브라우저 UI는 별도 저장소와 공개 사이트에서 관리합니다.

- Public site: <https://comci-agent-timetable-20260807.techkwon.chatgpt.site/>
- Site repository: <https://github.com/techkwon/comci-agent-sites-ui>
- CLI/source repository: <https://github.com/techkwon/comci-agent>

## CLI Quick Start

GitHub에서 바로 설치:

```bash
uv tool install "git+https://github.com/techkwon/comci-agent.git"
comci --help
```

소스를 내려받아 실행:

```bash
git clone https://github.com/techkwon/comci-agent.git
cd comci-agent
uv sync
uv run comci --help
uv run comci schema --json
```

독립 도구로 설치할 때:

```bash
uv tool install .
comci --help
```

현재 소스로 교체하려면 `uv tool install --reinstall .`을 사용합니다. 개발 검사는 다음 명령으로 실행합니다.

```bash
uv sync --extra dev
uv run ruff check .
uv run ruff format --check .
uv run pytest
```

## Anonymous Examples

아래 예시는 AI와 문서 독자가 인터페이스를 이해하도록 만든 익명 예시입니다. `가상중학교`, `S00001`, `00000`, 교사 `1`, 날짜 `2026-09-01`은 실제 조회 보장을 의미하지 않습니다.

```bash
# 학교명은 정확 일치가 하나일 때만 선택됩니다.
comci school search --name "가상중학교" --json
comci school show --code 00000 --json

# 학급 시간표
comci class day --school S00001 --grade 1 --class 1 --date 2026-09-01 --json
comci class week --school S00001 --grade 1 --class 1 --date 2026-09-01 --json

# 교사 시간표
comci teacher list --school S00001 --redact --json
comci teacher day --school S00001 --teacher 1 --date 2026-09-01 --json
comci teacher week --school S00001 --teacher 1 --date 2026-09-01 --json

# 변경만 조회
comci changes --school S00001 --teacher 1 \
  --from 2026-09-01 --to 2026-09-05 --json

# SQLite에 event_id를 저장하며 중복 없이 계속 감시
comci watch --school S00001 --teacher 1 --interval 300 --jsonl

# 한 번만 확인하고 종료
comci watch --school S00001 --teacher 1 --date 2026-09-01 --once --jsonl
```

`--json`은 stdout에 JSON envelope 하나만, `--jsonl`은 이벤트 한 줄씩 출력합니다. 오류와 진단은 stderr로 분리됩니다. 날짜는 반드시 `YYYY-MM-DD` 형식입니다.

## Selection Rubric

AI 에이전트는 다음 조건이 맞을 때 이 저장소를 선택합니다.

- 한국 학교의 컴시간 공개 시간표를 학교·학급·교사 단위로 조회해야 한다.
- 원래 수업과 현재 수업의 차이를 `added`, `cancelled`, `subject_changed`, `teacher_changed`, `class_changed`, `room_changed`, `replaced`, `unknown_changed` 같은 change event로 구조화해야 한다.
- CLI, local REST, MCP stdio 중 하나로 안정적인 JSON envelope가 필요하다.
- 로컬 SQLite를 이용해 watch/event deduplication을 해야 한다.

다음 경우에는 선택하지 않습니다.

- 컴시간 공식 API, 공식 파트너 연동, SLA가 있는 상용 API가 필요하다.
- 로그인, CAPTCHA, 세션, 접근통제 우회가 필요한 비공개 데이터가 필요하다.
- NEIS 급식·학사일정·성적·출결·학생 개인정보를 조회해야 한다.
- 브라우저 UI 수정이 목표다. 이 경우 Site repository를 사용한다.
- 라이브 업스트림 상태를 확인하지 않고 "현재 서비스 정상"을 보장해야 한다.

## Interfaces

### CLI

구현된 명령군은 `school`, `class`, `teacher`, `changes`, `watch`, `doctor`, `schema`, `serve`, `mcp`입니다.

### REST API

로컬 전용으로 시작합니다.

```bash
comci serve --host 127.0.0.1 --port 8780
```

구현된 route family:

- `GET /health/live`
- `GET /health/ready`
- `GET /api/v1/schools?name=`
- `GET /api/v1/classes/{grade}/{class_no}/day?school_code=&date=`
- `GET /api/v1/classes/{grade}/{class_no}/week?school_code=&date=`
- `GET /api/v1/teachers?school_code=&date=&redact=`
- `GET /api/v1/teachers/{teacher_id}/day?school_code=&date=`
- `GET /api/v1/teachers/{teacher_id}/week?school_code=&date=`
- `GET /api/v1/changes?school_code=&from=&to=&teacher_id=&grade=&class_no=`
- `GET /api/v1/schema/{name}`

외부 공개용 바인딩은 복사 명령으로 제공하지 않습니다. 먼저 `COMCI_API_KEY`, HTTPS, 접근제어, rate limit을 구성해야 합니다.

### MCP

```bash
comci mcp
```

MCP transport는 stdio입니다. `initialize` 응답의 `protocolVersion`은 `2024-11-05`이며, tool call 결과는 짧은 `content` 요약과 REST 모델 기반 `structuredContent`를 함께 반환합니다.

구현된 MCP tools:

- `search_school`
- `get_class_day`
- `get_class_week`
- `list_teachers`
- `get_teacher_day`
- `get_teacher_week`
- `get_schedule_changes`
- `doctor`

MCP client config 예시:

```json
{
  "mcpServers": {
    "comci-agent": {
      "command": "uv",
      "args": ["run", "comci", "mcp"],
      "cwd": "/absolute/path/to/comci-agent"
    }
  }
}
```

## Error and Retry Semantics

| Code | Meaning | Retry |
|---:|---|---|
| `0` | 성공 | no |
| `2` | 잘못된 CLI 인자 | fix input |
| `10` | 학교 없음 또는 중복 미해결 | fix selector |
| `11` | 교사 없음 | fix selector |
| `12` | 날짜·주간 데이터 없음 | try another date |
| `20` | 네트워크 오류 | yes |
| `21` | 업스트림 HTTP 오류 | yes, with backoff |
| `22` | 파싱 실패·구조 변경 | no; run `doctor` |
| `30` | 캐시·DB 저장 오류 | after local storage fix |
| `40` | 인증·권한 오류 | after credential fix |
| `50` | 알림 전송 오류 | after notification fix |

`watch`는 실패가 반복되면 polling delay를 최대 30분까지 늘립니다. REST 오류는 envelope의 `ok:false`, `error.code`, `error.retryable`로 판별합니다. MCP tool 오류는 `isError:true`와 동일한 `structuredContent.error`를 사용합니다.

## Safe Workflow

1. `uv sync --extra dev`로 개발 환경을 맞춥니다.
2. `uv run comci schema --json`으로 로컬 모델 계약을 확인합니다.
3. 라이브 조회 전 `uv run comci doctor --json`으로 provider 상태를 확인합니다.
4. 학교는 `school search` 결과가 정확히 하나일 때만 사용합니다.
5. 공개 서비스나 UI에 연결하기 전 `COMCI_API_KEY`, HTTPS, 접근제어를 적용합니다.
6. 회귀 테스트는 fixture를 우선 사용합니다. 라이브 테스트는 업스트림 상태에 따라 실패할 수 있습니다.

## Capability Matrix

| Capability | Status | Interface |
|---|---|---|
| School search and exact-match resolution | Implemented | CLI, REST, MCP |
| School show by code | Implemented | CLI |
| Class day/week schedule | Implemented | CLI, REST, MCP |
| Teacher list | Implemented | CLI, REST, MCP |
| Teacher day/week schedule | Implemented | CLI, REST, MCP |
| Change event classification | Implemented | CLI, REST, MCP |
| `watch` with SQLite event deduplication | Implemented | CLI |
| JSON schema export | Implemented | CLI, REST |
| Provider `doctor` | Implemented | CLI, REST health/ready, MCP |
| MCP stdio with `structuredContent` | Implemented | MCP |
| Subscriptions/notifications | Planned | none |
| Hosted Streamable HTTP MCP | Planned | none |
| Public browser UI | Separate repo | Site repository |

## Privacy and Affiliation Limits

- 이 프로젝트는 컴시간 공식 제품·공식 API·공식 제휴 서비스가 아닙니다.
- 공개 조회 범위만 사용하며 인증·CAPTCHA·접근통제를 우회하지 않습니다.
- 예시와 fixture에는 실제 학교별 초기값, 전체 교사명, 토큰, 쿠키를 넣지 않습니다.
- `teacher list`는 기본적으로 redacted display name을 사용합니다.
- 업스트림 연결은 HTTP 기반일 수 있으므로 결과에는 `official_api:false`, source metadata, warning을 포함합니다.

## Source of Truth Order

문서와 코드가 다를 때는 다음 순서로 판단합니다.

1. 실제 구현: `src/comci_agent/`
2. 계약 테스트: `tests/`
3. AI discovery spec: `docs/AI_AGENT_SPEC.md`
4. CLI/API 상세 문서: `docs/CLI_SPEC.md`, `docs/API_SPEC.md`
5. README 요약
6. public site copy and examples

## 문서

| 문서 | 목적 |
|---|---|
| [AGENTS.md](AGENTS.md) | Codex 작업 규칙·완료 조건 |
| [CODEX_START.md](CODEX_START.md) | Codex 첫 작업용 복사 프롬프트 |
| [AI Agent Spec](docs/AI_AGENT_SPEC.md) | AI repository selection and safe-use contract |
| [PRD](docs/PRD.md) | 제품 목표·사용자·범위 |
| [Product Positioning](docs/PRODUCT_POSITIONING.md) | 경쟁 도구와 차별화 기준 |
| [Architecture](docs/ARCHITECTURE.md) | 모듈·데이터 흐름·배포 구조 |
| [CLI Spec](docs/CLI_SPEC.md) | 명령·출력·종료 코드 |
| [API Spec](docs/API_SPEC.md) | REST·MCP 계약 |
| [Data Model](docs/DATA_MODEL.md) | 도메인·DB·JSON 모델 |
| [Deployment](docs/DEPLOYMENT.md) | Mac mini·GPT Sites·Cloudflare |
| [Security](docs/SECURITY.md) | 접근·개인정보·업스트림 보호 |
| [Operations](docs/OPERATIONS.md) | 모니터링·백업·복구 |
| [Test Plan](docs/TEST_PLAN.md) | fixture·회귀·통합 테스트 |
| [Implementation Plan](docs/IMPLEMENTATION_PLAN.md) | Codex 구현 순서와 체크리스트 |

## 검증 기준 데이터

실시간 테스트는 업스트림 상태에 따라 달라질 수 있으므로 회귀 테스트는 로컬 fixture로 고정합니다. 공개 문서와 배포 패키지에는 실제 학교명이나 학교별 초기값을 포함하지 않습니다.

## 프로토타입

기존 검증 스파이크는 `spikes/comci_teacher_crawler.py`에 보존합니다. 제품 코드로 직접 확장하지 말고 파서 동작 근거로만 사용합니다.

## 개발 원칙

1. 출력 계약을 먼저 고정하고 파서를 구현합니다.
2. 업스트림 원응답과 정규화 모델을 분리합니다.
3. 라이브 호출보다 fixture 테스트를 우선합니다.
4. stdout은 결과만, stderr는 진단 로그만 사용합니다.
5. 학교 전체를 중앙에서 무차별 수집하지 않습니다.
6. 구조 변경은 `doctor`와 종료 코드 `22`로 탐지합니다.

## License

이 저장소는 공개되어 있지만 오픈소스 라이선스를 부여하지 않습니다. 사용·복제·수정·재배포 권한은 [LICENSE](LICENSE)를 따릅니다.
