@elyun/bylane 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,88 @@
1
+ #!/bin/bash
2
+ # byLane pre-commit 보안 검사
3
+
4
+ RED='\033[0;31m'
5
+ YELLOW='\033[1;33m'
6
+ GREEN='\033[0;32m'
7
+ NC='\033[0m'
8
+
9
+ ERRORS=0
10
+ WARNINGS=0
11
+
12
+ echo "보안 검사 실행 중..."
13
+
14
+ # 스테이징된 파일 목록
15
+ STAGED=$(git diff --cached --name-only --diff-filter=ACMR)
16
+
17
+ if [ -z "$STAGED" ]; then
18
+ echo -e "${GREEN}스테이징된 파일 없음. 건너뜀.${NC}"
19
+ exit 0
20
+ fi
21
+
22
+ # 1. 민감한 파일명 패턴
23
+ SENSITIVE_FILES=$(echo "$STAGED" | grep -iE \
24
+ '\.env$|\.env\.|credentials|secrets|\.pem$|\.key$|\.p12$|\.pfx$|id_rsa|id_dsa|\.secret' \
25
+ || true)
26
+
27
+ if [ -n "$SENSITIVE_FILES" ]; then
28
+ echo -e "${RED}[CRITICAL] 민감한 파일이 커밋에 포함되어 있습니다:${NC}"
29
+ echo "$SENSITIVE_FILES" | sed 's/^/ - /'
30
+ ERRORS=$((ERRORS + 1))
31
+ fi
32
+
33
+ # 2. 하드코딩된 시크릿 패턴
34
+ SECRET_PATTERNS=(
35
+ 'AKIA[0-9A-Z]{16}' # AWS Access Key
36
+ 'sk-[a-zA-Z0-9]{32,}' # OpenAI / Anthropic API Key
37
+ 'ghp_[a-zA-Z0-9]{36}' # GitHub Personal Access Token
38
+ 'ghs_[a-zA-Z0-9]{36}' # GitHub Actions Token
39
+ 'xox[baprs]-[0-9a-zA-Z]{10,}' # Slack Token
40
+ 'AIza[0-9A-Za-z_-]{35}' # Google API Key
41
+ 'ya29\.[0-9A-Za-z_-]+' # Google OAuth Token
42
+ 'Bearer [a-zA-Z0-9._-]{20,}' # Generic Bearer Token (긴 것만)
43
+ 'password[[:space:]]*=[[:space:]]*"[^"]{6,}' # Hardcoded password (double quote)
44
+ "password[[:space:]]*=[[:space:]]*'[^']{6,}" # Hardcoded password (single quote)
45
+ 'api_key[[:space:]]*[=:][[:space:]]*"[^"]{8,}' # Hardcoded API key
46
+ )
47
+
48
+ for pattern in "${SECRET_PATTERNS[@]}"; do
49
+ MATCHES=$(git diff --cached -U0 | grep '^+' | grep -v '^+++' | grep -iE "$pattern" || true)
50
+ if [ -n "$MATCHES" ]; then
51
+ echo -e "${RED}[CRITICAL] 하드코딩된 시크릿 의심 패턴 발견 (${pattern}):${NC}"
52
+ echo "$MATCHES" | head -3 | sed 's/^/ /'
53
+ ERRORS=$((ERRORS + 1))
54
+ fi
55
+ done
56
+
57
+ # 3. console.log (JS/TS 파일)
58
+ JS_FILES=$(echo "$STAGED" | grep -E '\.(js|ts|jsx|tsx)$' || true)
59
+ if [ -n "$JS_FILES" ]; then
60
+ CONSOLE_MATCHES=$(git diff --cached -U0 -- $JS_FILES | grep '^+' | grep -v '^+++' | grep 'console\.log' || true)
61
+ if [ -n "$CONSOLE_MATCHES" ]; then
62
+ echo -e "${YELLOW}[WARN] console.log 발견:${NC}"
63
+ echo "$CONSOLE_MATCHES" | head -3 | sed 's/^/ /'
64
+ WARNINGS=$((WARNINGS + 1))
65
+ fi
66
+ fi
67
+
68
+ # 4. node_modules 실수 커밋
69
+ NODE_MODULES=$(echo "$STAGED" | grep '^node_modules/' || true)
70
+ if [ -n "$NODE_MODULES" ]; then
71
+ echo -e "${RED}[CRITICAL] node_modules가 커밋에 포함되어 있습니다.${NC}"
72
+ ERRORS=$((ERRORS + 1))
73
+ fi
74
+
75
+ # 5. 결과 출력
76
+ echo ""
77
+ if [ $ERRORS -gt 0 ]; then
78
+ echo -e "${RED}보안 검사 실패: $ERRORS 개의 오류가 있습니다.${NC}"
79
+ echo "커밋이 차단되었습니다. 오류를 수정하세요."
80
+ echo "(검사를 건너뛰려면: git commit --no-verify)"
81
+ exit 1
82
+ elif [ $WARNINGS -gt 0 ]; then
83
+ echo -e "${YELLOW}경고: $WARNINGS 개의 주의 사항이 있습니다. 커밋은 계속됩니다.${NC}"
84
+ else
85
+ echo -e "${GREEN}보안 검사 통과.${NC}"
86
+ fi
87
+
88
+ exit 0
@@ -17,7 +17,9 @@ description: byLane 메인 커맨드. 자연어로 전체 개발 워크플로우
17
17
  /bylane commit
18
18
  /bylane pr
19
19
  /bylane review [PR번호]
20
+ /bylane review-loop — 5분 주기 자동 리뷰 루프 시작
20
21
  /bylane respond [PR번호]
22
+ /bylane respond-loop — 5분 주기 자동 대응 루프 시작
21
23
  /bylane notify
22
24
  /bylane status — 현재 상태 한 줄 요약
23
25
  ```
@@ -37,7 +39,9 @@ description: byLane 메인 커맨드. 자연어로 전체 개발 워크플로우
37
39
  | `commit` | `bylane-commit-agent` |
38
40
  | `pr` | `bylane-pr-agent` |
39
41
  | `review` | `bylane-review-agent` |
42
+ | `review-loop` | `bylane-review-loop` |
40
43
  | `respond` | `bylane-respond-agent` |
44
+ | `respond-loop` | `bylane-respond-loop` |
41
45
  | `notify` | `bylane-notify-agent` |
42
46
  | `status` | `.bylane/state/` 파일 읽어 한 줄 요약 출력 |
43
47
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elyun/bylane",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "Frontend development harness for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,7 +10,9 @@
10
10
  "scripts": {
11
11
  "monitor": "node src/monitor/index.js",
12
12
  "test": "vitest run",
13
- "test:watch": "vitest"
13
+ "test:watch": "vitest",
14
+ "release": "bash scripts/release.sh",
15
+ "prepare": "git config core.hooksPath .githooks && chmod +x .githooks/pre-commit"
14
16
  },
15
17
  "dependencies": {
16
18
  "blessed": "^0.1.81",
@@ -0,0 +1,26 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ VERSION="v$(node -p "require('./package.json').version")"
5
+
6
+ echo "byLane npm 배포 시작: $VERSION"
7
+
8
+ # 작업 디렉토리 클린 확인 (untracked 파일 제외, 수정/스테이징된 파일만 체크)
9
+ DIRTY=$(git status --short | grep -v '^?' || true)
10
+ if [ -n "$DIRTY" ]; then
11
+ echo "오류: 커밋되지 않은 변경사항이 있습니다. 먼저 커밋하고 푸시하세요."
12
+ echo "$DIRTY"
13
+ exit 1
14
+ fi
15
+
16
+ # 테스트 실행
17
+ echo "테스트 실행 중..."
18
+ npm test
19
+
20
+ # npm 배포 (2FA 필요 시 프롬프트)
21
+ echo "npm 배포 중... (2FA 코드가 필요할 수 있습니다)"
22
+ npm publish --access public
23
+
24
+ echo ""
25
+ echo "배포 완료: $VERSION"
26
+ echo "https://www.npmjs.com/package/@elyun/bylane"
@@ -5,6 +5,17 @@ description: GitHub Issue 생성 및 분석. Figma 링크 감지 시 스펙 추
5
5
 
6
6
  # Issue Agent
7
7
 
8
+ ## GitHub 접근 방법
9
+
10
+ `.bylane/bylane.json`의 `github.method` 확인:
11
+
12
+ | 값 | 동작 |
13
+ |----|------|
14
+ | `"mcp"` | GitHub MCP 도구 사용 |
15
+ | `"cli"` | `gh` CLI 사용 |
16
+ | `"api"` | REST API + `$GITHUB_TOKEN` |
17
+ | `"auto"` (기본) | MCP → CLI → API 순서로 시도 |
18
+
8
19
  ## 입력
9
20
 
10
21
  - 자유 텍스트 (새 이슈 생성용) OR GitHub Issue 번호 (#N)
@@ -13,44 +24,65 @@ description: GitHub Issue 생성 및 분석. Figma 링크 감지 시 스펙 추
13
24
 
14
25
  ### 새 이슈 생성 모드 (텍스트 입력)
15
26
 
16
- 1. 입력 텍스트에서 다음을 추출:
17
- - 제목 (50자 이내)
18
- - 상세 설명
19
- - 구현 체크리스트 (예상 가능한 경우)
20
- - Figma URL (있는 경우)
27
+ 1. 입력 텍스트에서 추출:
28
+ - 제목 (50자 이내), 상세 설명, 구현 체크리스트, Figma URL
29
+
30
+ 2. 이슈 생성:
31
+
32
+ **MCP:**
33
+ → GitHub MCP `create_issue` 도구 사용
34
+
35
+ **CLI:**
36
+ ```bash
37
+ gh issue create \
38
+ --title "TITLE" \
39
+ --body "BODY" \
40
+ --label "bylane-auto"
41
+ ```
21
42
 
22
- 2. GitHub MCP로 이슈 생성:
23
- - `title`: 추출된 제목
24
- - `body`: Markdown 형식 설명 + 체크리스트
25
- - `labels`: `bylane-auto` 라벨 추가 (라벨이 없으면 생성)
43
+ **API:**
44
+ ```bash
45
+ curl -s -X POST \
46
+ -H "Authorization: Bearer $GITHUB_TOKEN" \
47
+ -H "Content-Type: application/json" \
48
+ https://api.github.com/repos/OWNER/REPO/issues \
49
+ -d '{"title":"TITLE","body":"BODY","labels":["bylane-auto"]}'
50
+ ```
26
51
 
27
- 3. Figma MCP 활성화 여부 확인 (`.bylane/bylane.json` → `extensions.figma.enabled`):
28
- - `true`이고 Figma URL 있으면 → **Figma 분석** 단계 실행
29
- - `false`이면 → 텍스트 기반 스펙만 생성
52
+ 3. Figma MCP 활성화 여부 확인 (`extensions.figma.enabled`):
53
+ - `true`이고 Figma URL 있으면 → Figma 분석 단계 실행
54
+ - `false` → 텍스트 기반 스펙만 생성
30
55
 
31
56
  ### 기존 이슈 분석 모드 (Issue 번호 입력)
32
57
 
33
- 1. GitHub MCP로 이슈 내용 로드
34
- 2. 본문에서 Figma URL 추출 시도
35
- 3. 스펙 생성 (아래 참조)
58
+ 1. 이슈 내용 로드:
36
59
 
37
- ### Figma 분석 (활성화된 경우)
60
+ **MCP:**
61
+ → GitHub MCP `get_issue` 도구 사용
62
+
63
+ **CLI:**
64
+ ```bash
65
+ gh issue view NUMBER --json title,body,labels
66
+ ```
67
+
68
+ **API:**
69
+ ```bash
70
+ curl -s \
71
+ -H "Authorization: Bearer $GITHUB_TOKEN" \
72
+ https://api.github.com/repos/OWNER/REPO/issues/NUMBER
73
+ ```
38
74
 
39
- Figma MCP `get_file` 또는 `get_node` 도구로 해당 프레임/컴포넌트 분석:
40
- - 컴포넌트 계층 구조
41
- - 색상 토큰
42
- - 타이포그래피
43
- - 스페이싱 값
75
+ 2. 본문에서 Figma URL 추출 시도 스펙 생성
76
+
77
+ ### Figma 분석 (활성화된 경우)
44
78
 
45
- 추출 결과를 스펙에 포함.
79
+ Figma MCP `get_file` 또는 `get_node` 도구로 프레임/컴포넌트 분석.
46
80
 
47
- **Figma 분석 실패 시 fallback:**
48
- - MCP 미설치 또는 URL 유효하지 않은 경우: 경고 로그 기록 후 텍스트 기반 스펙만 사용
49
- - `figmaSpec.enabled = false`로 출력
81
+ **실패 시 fallback:** 경고 로그 후 텍스트 기반 스펙 사용
50
82
 
51
- ## 출력: 구현 스펙
83
+ ## 출력
52
84
 
53
- `.bylane/state/issue-agent.json`에 저장:
85
+ `.bylane/state/issue-agent.json`:
54
86
 
55
87
  ```json
56
88
  {
@@ -63,27 +95,14 @@ Figma MCP `get_file` 또는 `get_node` 도구로 해당 프레임/컴포넌트
63
95
  "title": "다크모드 토글 버튼 추가",
64
96
  "description": "...",
65
97
  "checklist": ["ThemeToggle 컴포넌트 생성", "useTheme hook 구현"],
66
- "figmaSpec": {
67
- "enabled": false,
68
- "components": [],
69
- "colorTokens": {}
70
- }
98
+ "figmaSpec": { "enabled": false, "components": [], "colorTokens": {} }
71
99
  }
72
100
  }
73
101
  ```
74
102
 
75
103
  상태 기록:
76
104
  ```bash
77
- node -e "
78
- import('./src/state.js').then(({writeState, appendLog}) => {
79
- writeState('issue-agent', {
80
- status: 'in_progress',
81
- startedAt: new Date().toISOString(),
82
- progress: 0,
83
- retries: 0
84
- })
85
- })
86
- "
105
+ node -e "import('./src/state.js').then(({writeState})=>writeState('issue-agent',{status:'in_progress',startedAt:new Date().toISOString(),progress:0,retries:0}))"
87
106
  ```
88
107
 
89
108
  ## 수동 실행
@@ -5,6 +5,17 @@ description: 현재 브랜치의 커밋들로 GitHub Pull Request를 생성한
5
5
 
6
6
  # PR Agent
7
7
 
8
+ ## GitHub 접근 방법
9
+
10
+ `.bylane/bylane.json`의 `github.method` 확인:
11
+
12
+ | 값 | 동작 |
13
+ |----|------|
14
+ | `"mcp"` | GitHub MCP 도구 사용 |
15
+ | `"cli"` | `gh` CLI 사용 |
16
+ | `"api"` | REST API + `$GITHUB_TOKEN` |
17
+ | `"auto"` (기본) | MCP → CLI → API 순서로 시도 |
18
+
8
19
  ## 입력
9
20
 
10
21
  - `.bylane/state/commit-agent.json`의 `branchName`, `commitSha`
@@ -23,36 +34,44 @@ node -e "import('./src/state.js').then(({writeState})=>writeState('pr-agent',{st
23
34
  git push -u origin BRANCH_NAME
24
35
  ```
25
36
 
26
- 2. PR 제목/본문 생성:
27
- - 제목: 스펙 제목 (70자 이내)
28
- - 본문:
29
- ```
30
- ## Summary
31
- - [변경 요약]
37
+ 2. PR 본문 생성:
38
+ ```
39
+ ## Summary
40
+ - [변경 요약]
41
+
42
+ ## Test Plan
43
+ - [ ] 변경된 기능 동작 확인
44
+ - [ ] 기존 테스트 통과 확인
45
+
46
+ Closes #ISSUE_NUMBER
47
+ ```
48
+
49
+ 3. PR 생성:
32
50
 
33
- ## Test Plan
34
- - [ ] 변경된 기능 동작 확인
35
- - [ ] 기존 테스트 통과 확인
51
+ **MCP:**
52
+ GitHub MCP `create_pull_request` 도구 사용
36
53
 
37
- Closes #ISSUE_NUMBER
38
- ```
54
+ **CLI:**
55
+ ```bash
56
+ gh pr create \
57
+ --title "TITLE" \
58
+ --body "BODY" \
59
+ --head BRANCH_NAME \
60
+ --base main
61
+ ```
39
62
 
40
- 3. GitHub MCP로 PR 생성:
41
- - `title`: 생성된 제목
42
- - `body`: 생성된 본문
43
- - `head`: 현재 브랜치명
44
- - `base`: main
63
+ **API:**
64
+ ```bash
65
+ curl -s -X POST \
66
+ -H "Authorization: Bearer $GITHUB_TOKEN" \
67
+ -H "Content-Type: application/json" \
68
+ https://api.github.com/repos/OWNER/REPO/pulls \
69
+ -d '{"title":"TITLE","body":"BODY","head":"BRANCH_NAME","base":"main"}'
70
+ ```
45
71
 
46
72
  4. 상태 업데이트:
47
73
  ```bash
48
- node -e "
49
- import('./src/state.js').then(({writeState})=>writeState('pr-agent',{
50
- status:'completed',
51
- progress:100,
52
- prNumber:'PR_NUMBER',
53
- prUrl:'PR_URL'
54
- }))
55
- "
74
+ node -e "import('./src/state.js').then(({writeState})=>writeState('pr-agent',{status:'completed',progress:100,prNumber:PR_NUMBER,prUrl:'PR_URL'}))"
56
75
  ```
57
76
 
58
77
  ## 출력
@@ -5,6 +5,17 @@ description: PR 리뷰 코멘트에 반박하거나 코드를 수정하여 반
5
5
 
6
6
  # Respond Agent
7
7
 
8
+ ## GitHub 접근 방법
9
+
10
+ `.bylane/bylane.json`의 `github.method` 확인:
11
+
12
+ | 값 | 동작 |
13
+ |----|------|
14
+ | `"mcp"` | GitHub MCP 도구 사용 |
15
+ | `"cli"` | `gh` CLI 사용 |
16
+ | `"api"` | REST API + `$GITHUB_TOKEN` |
17
+ | `"auto"` (기본) | MCP → CLI → API 순서로 시도 |
18
+
8
19
  ## 입력
9
20
 
10
21
  - PR 번호
@@ -18,23 +29,55 @@ node -e "import('./src/state.js').then(({writeState})=>writeState('respond-agent
18
29
 
19
30
  ## 실행 흐름
20
31
 
32
+ ### 리뷰 코멘트 로드
33
+
34
+ **MCP:**
35
+ → GitHub MCP `list_review_comments` 도구 사용
36
+
37
+ **CLI:**
38
+ ```bash
39
+ gh pr view PR_NUMBER --json reviews,comments
40
+ ```
41
+
42
+ **API:**
43
+ ```bash
44
+ curl -s \
45
+ -H "Authorization: Bearer $GITHUB_TOKEN" \
46
+ https://api.github.com/repos/OWNER/REPO/pulls/PR_NUMBER/comments
47
+ ```
48
+
21
49
  ### accept 모드
22
50
 
23
- 1. GitHub MCP로 미해결 리뷰 코멘트 로드
24
- 2. 코멘트별 수정 사항 결정
25
- 3. 코드 수정 (code-agent 서브 실행)
26
- 4. test-agent로 검증
27
- 5. commit-agent로 수정 커밋 (`fix: address review comments`)
28
- 6. GitHub MCP로 각 코멘트에 "반영 완료" 답글 작성
51
+ 1. 코멘트별 수정 사항 결정
52
+ 2. 코드 수정 (code-agent 서브 실행)
53
+ 3. test-agent 검증
54
+ 4. commit-agent로 수정 커밋 (`fix: address review comments`)
55
+ 5. 코멘트에 "반영 완료" 답글 게시:
56
+
57
+ **MCP:**
58
+ → GitHub MCP `create_review_comment_reply` 도구 사용
59
+
60
+ **CLI:**
61
+ ```bash
62
+ gh pr comment PR_NUMBER --body "REPLY_BODY"
63
+ ```
64
+
65
+ **API:**
66
+ ```bash
67
+ curl -s -X POST \
68
+ -H "Authorization: Bearer $GITHUB_TOKEN" \
69
+ -H "Content-Type: application/json" \
70
+ https://api.github.com/repos/OWNER/REPO/issues/PR_NUMBER/comments \
71
+ -d '{"body":"REPLY_BODY"}'
72
+ ```
29
73
 
30
74
  ### rebut 모드
31
75
 
32
- 1. GitHub MCP로 미해결 리뷰 코멘트 로드
33
- 2. 코멘트에 대해 근거를 기술한 반박 답글 작성:
34
- - 의도적 설계 결정인 경우: 배경 설명
35
- - 성능 트레이드오프: 구체적 수치 근거 제시
76
+ 1. 코멘트에 근거를 기술한 반박 답글 작성:
77
+ - 의도적 설계 결정: 배경 설명
78
+ - 성능 트레이드오프: 구체적 수치 근거
36
79
  - 스펙 요구사항과 일치하는 경우: 이슈 링크 첨부
37
- 3. GitHub MCP로 반박 답글 게시
80
+ 2. 위와 동일한 방법으로 답글 게시
38
81
 
39
82
  ## 출력
40
83
 
@@ -0,0 +1,109 @@
1
+ ---
2
+ name: bylane-respond-loop
3
+ description: 5분 주기로 내 PR에 달린 리뷰/코멘트를 감지하여 자동으로 반박하거나 반영한다.
4
+ ---
5
+
6
+ # Respond Loop Agent
7
+
8
+ ## 개요
9
+
10
+ 백그라운드 폴러(`src/respond-loop.js`)가 5분마다 내 PR에 달린 리뷰/코멘트를 감지하여
11
+ `.bylane/state/respond-queue.json`에 기록한다. 이 skill은 해당 큐를 감시하다가
12
+ `status: "pending"` 항목이 생기면 `bylane-respond-agent`를 실행한다.
13
+
14
+ 감지 대상:
15
+ - `CHANGES_REQUESTED` 리뷰
16
+ - 일반 코멘트 (COMMENTED)
17
+ - 대응 후 추가된 새 코멘트 (updatedAt 변경 감지)
18
+
19
+ ## 시작
20
+
21
+ ### 1. 폴러 시작 (백그라운드)
22
+
23
+ ```bash
24
+ node src/respond-loop.js &
25
+ echo "폴러 PID: $!"
26
+ ```
27
+
28
+ ### 2. 큐 감시 루프
29
+
30
+ pending PR이 생길 때마다 respond-agent를 실행한다:
31
+
32
+ ```bash
33
+ node -e "
34
+ import('./src/state.js').then(({readState}) => {
35
+ const q = readState('respond-queue', '.bylane/state')
36
+ const pending = (q?.queue ?? []).filter(p => p.status === 'pending')
37
+ console.log(JSON.stringify(pending))
38
+ })
39
+ "
40
+ ```
41
+
42
+ pending 항목이 있으면 각 PR에 대해:
43
+
44
+ 1. `hasChangesRequested` 여부 확인:
45
+ - `true` → 사용자에게 `accept` / `rebut` 모드 선택 요청 후 `bylane-respond-agent` 실행
46
+ - `false` (코멘트만) → 코멘트 내용 확인 후 `accept` / `rebut` 모드 자동 판단 또는 사용자에게 선택 요청
47
+
48
+ 2. `bylane-respond-agent` skill 실행 (PR 번호 + 모드 전달)
49
+
50
+ 3. 완료 후 큐 항목을 `status: "responded"`로 업데이트:
51
+
52
+ ```bash
53
+ node -e "
54
+ import('./src/state.js').then(({readState, writeState}) => {
55
+ const q = readState('respond-queue', '.bylane/state')
56
+ const queue = (q?.queue ?? []).map(p =>
57
+ p.number === PR_NUMBER
58
+ ? { ...p, status: 'responded', respondedAt: new Date().toISOString() }
59
+ : p
60
+ )
61
+ writeState('respond-queue', { status: 'running', queue }, '.bylane/state')
62
+ })
63
+ "
64
+ ```
65
+
66
+ 4. 다음 pending 항목으로 반복. pending 없으면 30초 대기 후 재확인.
67
+
68
+ ## 큐 항목 스키마
69
+
70
+ `.bylane/state/respond-queue.json`:
71
+
72
+ ```json
73
+ {
74
+ "agent": "respond-queue",
75
+ "status": "running",
76
+ "queue": [
77
+ {
78
+ "number": 45,
79
+ "title": "Add dark mode toggle",
80
+ "url": "https://github.com/owner/repo/pull/45",
81
+ "branch": "feature/45-dark-mode",
82
+ "updatedAt": "2026-04-05T10:00:00Z",
83
+ "hasChangesRequested": true,
84
+ "status": "pending",
85
+ "detectedAt": "2026-04-05T10:01:00Z"
86
+ }
87
+ ]
88
+ }
89
+ ```
90
+
91
+ `status` 값:
92
+ - `pending` — 대응 대기 중
93
+ - `responding` — 현재 respond-agent 실행 중
94
+ - `responded` — 대응 완료 (새 코멘트 오면 pending으로 재전환)
95
+
96
+ ## 재감지
97
+
98
+ 폴러가 이미 `responded` 상태인 PR의 `updatedAt`이 변경된 것을 감지하면
99
+ 자동으로 `status: "pending"`으로 되돌린다.
100
+
101
+ ## 종료
102
+
103
+ ```bash
104
+ kill $(pgrep -f respond-loop.js)
105
+ ```
106
+
107
+ ## 수동 실행
108
+
109
+ `/bylane respond-loop`