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
10 changes: 6 additions & 4 deletions .agents/rules/commits.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# Commit and History Rules

## Commit Units

- 하나의 commit은 하나의 목적만 담고, 독립적으로 리뷰·revert 가능해야 한다.
- 큰 작업도 작은 commit으로 나눈다. 단, 의미 있는 작업 단위가 깨질 정도로 쪼개지 않는다.
- 각 commit 시점에 빌드와 테스트가 통과해야 한다 (AGENTS.md의 Verify 게이트).
훅은 이것을 강제하지 않는다 — `pre-commit`은 형식만 보고, 전체 게이트는 `pre-push`
tip에 대해서만 돌린다. 따라서 이 항목은 도구가 아니라 작성자가 지키는 규칙이며,
깨지면 `git bisect`가 못 쓰게 된다. 범위 전체를 검증하려면
- 각 commit 시점에 빌드와 테스트가 통과해야 한다. 일반 게이트는 루트 `AGENTS.md`가 가리키는 `docs/getting-started.md`에 있고, 훅이 이 원칙을 대신 지키지는 않는다.
훅은 이것을 강제하지 않는다 — `pre-commit`은 형식만 보고, `pre-push`는 통합 기준점 대비
변경 범위의 tip만 검사한다(문서만 바꾼 push는 Rust 게이트를 건너뛴다). 따라서 이 항목은
도구가 아니라 작성자가 지키는 규칙이며, 깨지면 `git bisect`가 못 쓰게 된다. 범위 전체를 검증하려면
`NIGHTCROW_VERIFY_EACH_COMMIT=1 git push`.

## Feature-scoped Workflow
Expand Down
2 changes: 2 additions & 0 deletions .agents/rules/dependencies.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Dependency Rules

## Selecting

- 새 의존성 전에 stdlib 또는 이미 있는 의존성으로 되는지 먼저 확인한다.
Expand Down
13 changes: 4 additions & 9 deletions .agents/rules/docs.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
## What Exists
# Documentation Rules

- `README.md` — 무엇인지, 설치·실행, 사전 조건. 처음 보는 사람이 5분 안에 로컬 실행 가능한 수준.
- `docs/architecture.md` — 계층 구조, 모듈 책임, 핵심 설계 결정과 그 이유.
- `docs/` 나머지 — 기능별 사용 문서.
- 필요 없는 문서 유형을 새로 만들지 않는다. 유지보수할 수 없는 문서는 만들지 않는다.
- 형식적으로 빈 섹션(Contributing, License 등)을 채우지 않는다.

## What to Document
## Content

- 공개 인터페이스의 계약: 입력, 출력, 에러, 부작용.
- 비자명한 제약: 순서 의존성, 호출 전제 조건, 스레드/동시성 안전성.
- 코드가 표현하지 못하는 맥락과 "왜".
- 내부용 함수는 이름과 시그니처가 명확하면 문서화하지 않는다. 타입이 말하는 것을 주석으로 반복하지 않는다.
- 필요한 문서만 유지한다. 유지보수할 수 없는 문서나 형식적인 빈 섹션(Contributing, License 등)은 만들지 않는다.

## Quality

- 틀린 문서는 없는 문서보다 나쁘다. 코드 변경으로 내용이 달라지면 같은 작업 안에서 갱신한다.
- 문서는 현재 코드와 일치해야 한다. 코드 변경으로 내용이 달라지면 같은 작업 안에서 갱신한다.
- 예시 코드는 실제로 실행 가능한 상태를 유지한다.
- 추측이나 미래 계획을 사실처럼 쓰지 않는다.
25 changes: 10 additions & 15 deletions .agents/rules/guardrails.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,30 @@
# Guardrails

## File Size

- 모든 소스 파일(Rust, TypeScript, TSX, JavaScript)은 300줄 이하다. 테스트 파일도 예외 없다.
- 200줄 이상은 code smell이다. 분할을 검토한다.
- 모든 소스·테스트 파일(Rust, TypeScript, TSX, JavaScript)은 300줄 이하다. 테스트 파일도 예외 없다.
- 200줄 이상은 code smell이며 분할을 검토한다.
- 분할은 동작을 바꾸지 않는 순수 리팩토링이어야 한다. 모듈, 순수 함수, 컴포넌트/훅으로 쪼갠다.
- 생성물(`target/`, `viewer-ui/dist/`)과 벤더링한 서드파티는 제외한다.

## Platforms

- macOS, Linux, Windows 세 곳 모두에서 도는 것을 목표로 한다. 한 곳에서만 도는 코드는
기능이 아니라 미완성이다. CI도 세 OS를 모두 돈다 (`.github/workflows/ci.yml`).
- 플랫폼 분기는 호출부에 흩지 않고 seam 한 곳에 모은다 — 경로·시그널·스레드·로깅은
`src/platform/`, 소켓 타입은 `src/daemon/transport.rs`. 새 분기가 필요하면 seam을
늘리기 전에 기존 것에 들어갈 수 있는지 먼저 본다.
- 한쪽에만 있는 API(`PermissionsExt`, `setsid`, ConPTY 동작 차이)는 대응물을 찾거나
seam 뒤에 감춘다. 대응물이 없어 동작이 달라지면 무엇을 포기했는지 문서에 남긴다.
- 테스트를 `#[cfg(unix)]`로 막는 것은 최후 수단이다. 막는 순간 그 동작은 나머지
플랫폼에서 검증되지 않으므로, 왜 막았는지 주석으로 남긴다.
- Windows에서 작업 중이면 Unix 게이트는 `docker compose run --rm unix-gate`로 돌린다
(`docs/getting-started.md`).
- macOS, Linux, Windows 세 곳 모두에서 도는 것을 목표로 한다. 한 곳에서만 도는 코드는 기능이 아니라 미완성이다. CI도 세 OS를 모두 돈다 (`.github/workflows/ci.yml`).
- 플랫폼 분기는 호출부에 흩지 않고 seam 한 곳에 모은다 — 경로·시그널·스레드·로깅은 `src/platform/`, 소켓 타입은 `src/daemon/transport.rs`. 새 분기가 필요하면 seam을 늘리기 전에 기존 것에 들어갈 수 있는지 먼저 본다.
- 한쪽에만 있는 API(`PermissionsExt`, `setsid`, ConPTY 동작 차이)는 대응물을 찾거나 seam 뒤에 감춘다. 대응물이 없어 동작이 달라지면 무엇을 포기했는지 문서에 남긴다.
- 테스트를 `#[cfg(unix)]`로 막는 것은 최후 수단이다. 막는 순간 그 동작은 나머지 플랫폼에서 검증되지 않으므로, 왜 막았는지 주석으로 남긴다.
- Windows에서 작업 중이면 Unix 게이트는 `docker compose run --rm unix-gate`로 돌린다 (`docs/getting-started.md`).

## Architecture

- `docs/architecture.md`가 설계 결정의 기준이다. 구현이 문서와 어긋나면 문서를 먼저 고치거나 구현을 조정한다.
- top-level 구조는 새 모듈을 붙일 수 있도록 열어 두되, 초기 구현은 간소하게 시작한다.

## Code Quality

- 가장 단순한 해결책을 먼저 시도한다. 추상화는 반복이 실제로 발생한 후에 도입한다.
- 하나의 함수/모듈은 하나의 책임만 갖는다.
- 매직 넘버와 하드코딩 문자열은 이름 있는 상수로 뽑는다.
- 주석은 "왜"만 남긴다. 타입이 이미 말하는 것은 반복하지 않는다.
- 코드 내부 주석은 영어로만 작성하고 핵심적인 "why"만 설명한다. 코드·타입·이름만 보고 알 수 있는 동작은 주석으로 반복하지 않는다.

## Error Handling

Expand Down
2 changes: 2 additions & 0 deletions .agents/rules/security.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Security Rules

## Input Validation

- 시스템 경계(사용자 입력, 외부 API 응답, 파일 읽기, HTTP 요청)에서 오는 데이터는 항상 검증한다.
Expand Down
12 changes: 6 additions & 6 deletions .agents/rules/testing.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
# Testing

## Which Layer

- 모듈 간 계약(인터페이스)을 추가/변경 → **contract test 필수**
- 순수 함수, 개별 모듈 로직 → unit test
- API endpoint, 요청 흐름 전체(web viewer, daemon protocol) → integration test
- 사용자 관점 시나리오 → end-to-end test
- 하나의 변경이 여러 유형에 걸치면 각각 작성한다.
- 변경 유형에 맞는 테스트를 추가한다: 모듈 간 계약(인터페이스)은 **contract test**, 순수 함수·개별 모듈 로직은 unit test, API endpoint·전체 요청 흐름(web viewer·daemon protocol)은 integration test, 사용자 관점 시나리오는 end-to-end test. 하나의 변경이 여러 유형에 걸치면 각각 작성한다.

## Rules

Expand All @@ -14,7 +12,9 @@
- mock은 외부 시스템 경계에만 쓴다.
- 각 테스트는 독립 실행 가능해야 한다. 테스트 간 상태 공유 금지.
- 테스트 이름은 `무엇을_하면_어떤_결과가_나온다` 패턴으로 의도를 드러낸다.
- 배치·네이밍은 기존 컨벤션을 따른다. 공유 fixture/helper는 공통 위치에 둔다 (`src/test_util.rs`).
- 단위 테스트는 구현 파일에 크게 inline하지 않고 sibling `*_tests.rs` 또는 인접 `tests/`로 분리한다. crate 공개 API 통합 테스트는 루트 `tests/`에 둔다.
- TS/TSX 테스트는 sibling `*.test.ts(x)` 파일에 둔다.
- 그 밖의 배치·네이밍은 기존 컨벤션을 따른다. 공유 fixture/helper는 공통 위치에 둔다 (`src/test_util.rs`).

## Flaky Tests

Expand Down
7 changes: 5 additions & 2 deletions .agents/skills/_shared/review-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@

## 3. 수정 적용

- 수정 후 AGENTS.md의 Verify 게이트(`cargo build`, `cargo test`, `cargo clippy --all-targets
--all-features -- -D warnings`)를 실행해 다른 것이 깨지지 않았는지 확인한다.
- 수정 후 루트 `AGENTS.md`가 가리키는 Verify 게이트(`docs/getting-started.md#building-and-testing`)를 실행해 다른 것이 깨지지 않았는지 확인한다.
- 테스트가 실패하면 원인을 먼저 분류한다.
- 수정이 원인: 수정을 되돌리고 **사용자 판단 필요**로 재분류한다.
- 기존 flaky 또는 환경 문제: 수정을 유지하고 실패 원인을 보고한다.
Expand All @@ -46,13 +45,17 @@
## 5. 보고 형식

### 즉시 반영한 항목

(각 항목: 파일, 변경 내용, 발견 근거. 없으면 `없음`)

### 사용자 판단이 필요한 항목

(각 항목: 파일, 지적 내용, 판단을 미룬 이유. 없으면 `없음`)

### 무시한 항목

(건수와 대표 사유. 없으면 `없음`)

### 리뷰 요약

(1-2문장 평가)
4 changes: 4 additions & 0 deletions .agents/skills/plan/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,19 @@ user-invocable: true
계획을 다음 형식으로 보고하고 구현 전 정렬한다.

### 목표 및 제약

(정리된 목표와 제약)

### 접근 방식

(선택한 방식과 이유. 대안이 있었으면 비교 요약)

### 구현 계획

(번호가 매겨진 단계별 목록)

### 불확실한 점

(추가 확인이 필요한 사항. 없으면 `없음`)

사용자가 계획을 승인하면 구현을 시작한다. 수정 요청이 있으면 계획을 조정한 후 재확인한다.
4 changes: 4 additions & 0 deletions .agents/skills/security-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,24 @@ user-invocable: true
먼저 `security.md`의 규칙 준수 여부를 변경된 코드에서 확인하고, 그 위에 다음을 본다.

### 입력과 주입

- 시스템 경계(사용자 입력, 외부 API 응답, 파일 경로, URL 파라미터, 헤더)의 검증 여부.
- Command Injection, XSS, Path Traversal 등 OWASP Top 10 노출 경로.
- 신뢰할 수 없는 입력의 역직렬화.

### 인증 및 권한

- 인증 우회 가능성, 권한 검사가 빠진 엔드포인트·명령.
- 세션/토큰의 만료, 무효화, 저장 방식. 권한 상승 경로.

### 정보 노출

- 키/토큰 하드코딩. 민감 정보가 로그, 에러 메시지, 응답 본문, 커밋 히스토리에 새는지.
- 에러 응답의 내부 세부사항(스택 트레이스, 내부 경로) 노출.
- 에러 처리가 보안 검사를 우회하는 경로를 만드는지.

### 노출면

- 로컬 daemon 소켓과 web viewer의 바인드 주소·권한이 필요한 최소인지.
- CORS, CSP 등 브라우저 보안 정책 설정.
- root/admin 권한을 요구하는 구현, 불필요하게 넓은 권한을 요구하는 의존성.
Expand Down
4 changes: 4 additions & 0 deletions .agents/skills/self-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,28 @@ user-invocable: true
## 분석 렌즈 (extended thinking)

### 정합성

- 호출하는 함수, 의존하는 타입, 참조하는 상수가 실제로 존재하고 올바른지.
- 새 인터페이스/타입과 기존 구현체 간 계약이 맞는지.
- import 경로, export 누락, 순환 참조.

### 로직

- 분기의 완전성 (switch/if-else).
- 에러 경로에서의 리소스 정리와 상태 롤백.
- 경계 조건 (null, empty, 0, max).
- 비동기 코드의 await 누락, 에러 전파 누락.

### 설계 정합성

- `docs/architecture.md`의 계층 책임과 일치하는지.
- `.agents/rules/`의 규칙을 위반하지 않는지.
- scope 문서가 있으면 그 범위 내인지.
- 모듈 간 의존 방향이 설계 의도와 맞는지.
- 문서 간 충돌은 Architecture > Rules > Scope 우선순위로 해소한다.

### 테스트 충분성

- 변경된 로직의 주요 경로와 에러 경로에 대응하는 테스트가 있는지.
- 테스트가 구현 세부사항이 아니라 계약/동작을 검증하는지.

Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
/viewer-ui/tsconfig.tsbuildinfo
# Agent tool scratch state
/.atl/
/.worktress/
/.worktrees/

# Checkout-local agent instructions
/AGENTS.local.md
Expand Down
5 changes: 5 additions & 0 deletions .markdownlint-cli2.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"config": {
"MD013": false
}
}
50 changes: 19 additions & 31 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,29 @@
# nightcrow

체크아웃 루트에 `AGENTS.local.md`가 있으면 이 문서와 함께 읽고 적용한다.

Agent-adjacent Rust TUI: 상단은 git diff/commit log 뷰어, 하단은 split-view 멀티 터미널 패널.
설계는 `docs/architecture.md`, 사용법은 `README.md`.
설계 기준은 `docs/architecture.md`, 설치·실행과 사용법은 `README.md`와 `docs/`다.

## 에이전트 설정

원본은 `.agents/`에 두고 도구별 디렉터리는 symlink만 둔다 (`.claude/rules`,
`.claude/skills` → `../.agents/...`). 새 도구를 붙일 때도 복사하지 말고 링크한다.
Windows에서 링크를 체크아웃하려면 개발자 모드 + `git config core.symlinks true`가
필요하고, 없으면 링크가 경로 문자열이 담긴 일반 파일로 풀린다.
원본은 `.agents/`에 두고 도구별 디렉터리는 symlink만 둔다 (`.claude/rules`, `.claude/skills` → `../.agents/...`). 새 도구를 붙일 때도 복사하지 말고 링크한다. Windows에서 링크를 체크아웃하려면 개발자 모드와 `git config core.symlinks true`가 필요하다. 그렇지 않으면 링크가 경로 문자열을 담은 일반 파일로 풀린다.

`.agents/rules/`는 항상 적용되는 규칙, `.agents/skills/`는 `/plan`, `/self-review`, `/security-review` 절차다. 스킬 공통 절차는 `.agents/skills/_shared/`에서 관리하며 이 문서에 복제하지 않는다.

## Scope guides

변경 범위에 해당하는 scope guide도 함께 읽는다. 공통 규칙을 scope guide에 다시 적지 않는다.

- `.agents/rules/` — 항상 적용되는 개발 규칙. 무엇을 지킬지는 각 파일이 정한다.
- `.agents/skills/` — `/plan`, `/self-review`, `/security-review`. 각 스킬의 절차는
해당 `SKILL.md`가 정하므로 이 문서에 옮겨 적지 않는다.
- `.agents/skills/_shared/` — 스킬이 공유하는 절차 문서.
- `docs/AGENTS.md` — `docs/`
- `src/AGENTS.md` — `src/`
- `viewer-ui/AGENTS.md` — `viewer-ui/`
- `plugins/AGENTS.md` — `plugins/`

## 개발 흐름

1. **Plan** — 변경이 단순하지 않으면 `/plan`으로 사용자와 정렬한 뒤 구현한다.
단순한 버그 수정·설정 변경은 바로 구현한다.
2. **Implement** — `docs/architecture.md`의 설계 제약을 따른다. 구현이 문서와 어긋나면
문서를 먼저 갱신하거나 구현을 조정한다. 코드는 macOS·Linux·Windows 세 곳에서
도는 것을 목표로 한다 — 플랫폼 seam과 게이팅 규칙은 `.agents/rules/guardrails.md`.
3. **Verify** — `cargo build`, `cargo test`,
`cargo clippy --all-targets --all-features -- -D warnings`가 통과해야 한다.
`viewer-ui/src`를 건드렸으면 `npm --prefix viewer-ui test`와
`npm --prefix viewer-ui run build`(dist가 안 바뀌어야 한다)도 통과해야 한다.
훅은 두 단계로 나뉜다 (`git config core.hooksPath .githooks`).
`pre-commit`은 `cargo fmt --all --check`만 돌려 커밋을 가볍게 유지하고,
`pre-push`가 CI와 동일한 게이트를 실행한다. 막으려는 실패(붉은 CI)는 push 시점에
발생하므로 게이트도 그 시점에 둔다. `pre-push`는 통합 브랜치(`upstream/dev`) 대비
변경만 검사하므로 문서만 바꾼 push는 cargo를 아예 실행하지 않는다.
훅은 push되는 tip만 검증한다. **각 commit이 개별적으로 green이어야 한다는 요구는
여전히 작성자의 몫이다** (`commits.md`). bisect할 history라면
`NIGHTCROW_VERIFY_EACH_COMMIT=1 git push`로 범위 내 모든 commit을 검증한다.
빌드·테스트 절차와 다른 플랫폼 게이트 돌리는 법은 `docs/getting-started.md`의
"Building and testing" 섹션에 있다.
4. **Review** — `/self-review`로 자체 점검하고, 인증/보안/공개 API 등 민감한 변경이면
`/security-review`도 실행한다.
5. **Commit** — `.agents/rules/commits.md`를 따른다. push는 사용자가 결정한다.
1. **Plan** — 변경이 단순하지 않으면 `/plan`으로 사용자와 정렬한 뒤 구현한다. 단순한 버그 수정·설정 변경은 바로 구현한다.
2. **Implement** — `docs/architecture.md`와 해당 scope guide의 경계를 따른다. 공통 플랫폼·코드 품질 제약은 `.agents/rules/guardrails.md`에 있다.
3. **Verify** — 빌드·테스트·포맷·다른 플랫폼·viewer bundle 게이트는 [`docs/getting-started.md`](docs/getting-started.md)의 [Building and testing](docs/getting-started.md#building-and-testing)을 따른다. 커밋별 green과 history 규칙은 [`commits.md`](.agents/rules/commits.md)에 있다.
4. **Review** — `/self-review`로 자체 점검하고, 인증·보안·공개 API 등 민감한 변경이면 `/security-review`도 실행한다. 각 스킬의 절차는 해당 `SKILL.md`를 따른다.
5. **Commit** — [`.agents/rules/commits.md`](.agents/rules/commits.md)를 따른다. push는 사용자가 결정한다.
3 changes: 0 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading