choavis-agent 1.5.26 → 1.5.27
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.
- package/.claude/lib/credentials.cjs +2 -2
- package/.claude/skills/confluence/SKILL.md +4 -7
- package/.claude/skills/jira/SKILL.md +72 -7
- package/CLAUDE.md +42 -0
- package/dist/index.js +59 -6
- package/package.json +1 -1
|
@@ -35,8 +35,8 @@ function loadJiraCredentials() {
|
|
|
35
35
|
|
|
36
36
|
throw new Error(
|
|
37
37
|
'Jira 인증 정보를 찾을 수 없습니다.\n' +
|
|
38
|
-
' Slack에서
|
|
39
|
-
'
|
|
38
|
+
' Slack에서 "지라 연동해줘"라고 말하거나\n' +
|
|
39
|
+
' choavis-agent init 명령으로 설정하세요.'
|
|
40
40
|
);
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -7,14 +7,11 @@ description: Confluence 위키 페이지 검색, 조회, 생성, 수정. 사용
|
|
|
7
7
|
|
|
8
8
|
`.claude/lib/confluence-api.cjs` Node.js 클라이언트를 사용하여 Confluence REST API를 호출합니다.
|
|
9
9
|
|
|
10
|
-
## 기본 정보
|
|
11
|
-
|
|
12
|
-
- 위키 URL: https://musinsa-oneteam.atlassian.net/wiki
|
|
13
|
-
|
|
14
10
|
## 인증
|
|
15
11
|
|
|
16
|
-
Jira와 동일한 Atlassian 크리덴셜을
|
|
17
|
-
|
|
12
|
+
Jira와 동일한 Atlassian 크리덴셜을 사용합니다.
|
|
13
|
+
- 크리덴셜 파일: `~/.config/choavis-agent/atlassian-credentials.json`
|
|
14
|
+
- 인증 오류 발생 시: "Atlassian 연동이 필요합니다. 설정할까요?"라고 안내하고, Jira Skill의 연동 설정 절차를 진행하세요.
|
|
18
15
|
|
|
19
16
|
## API 호출 방법
|
|
20
17
|
|
|
@@ -100,7 +97,7 @@ URL: https://...
|
|
|
100
97
|
|
|
101
98
|
| 에러 | 대응 |
|
|
102
99
|
|------|------|
|
|
103
|
-
| 인증 실패 |
|
|
100
|
+
| 인증 실패 | Atlassian 연동 설정 안내 (Jira Skill 참조) |
|
|
104
101
|
| 스페이스 없음 | `spaces` 명령으로 목록 제공 |
|
|
105
102
|
| 페이지 없음 | 페이지 ID/제목 확인 안내 |
|
|
106
103
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: jira
|
|
3
|
-
description: Jira 이슈 검색, 조회, 생성, 상태 변경, 댓글
|
|
3
|
+
description: Jira 이슈 검색, 조회, 생성, 상태 변경, 댓글 추가, Atlassian 연동 설정. 사용자가 Jira 관련 작업이나 Atlassian 연동을 요청할 때 자동 활성화.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Jira Skill
|
|
@@ -9,10 +9,75 @@ description: Jira 이슈 검색, 조회, 생성, 상태 변경, 댓글 추가.
|
|
|
9
9
|
|
|
10
10
|
## 인증
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
크리덴셜 확인 순서:
|
|
13
|
+
1. 환경변수: `JIRA_URL`, `JIRA_USERNAME`, `JIRA_API_TOKEN` (에이전트 시작 시 자동 주입)
|
|
14
|
+
2. 파일: `~/.config/choavis-agent/atlassian-credentials.json`
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
## Atlassian 연동 설정 (Slack 대화로 설정)
|
|
17
|
+
|
|
18
|
+
사용자가 "지라 연동해줘", "Atlassian 설정", "jira setup" 등을 요청하면 아래 절차를 따릅니다:
|
|
19
|
+
|
|
20
|
+
### 1단계: 필요 정보 안내 및 수집
|
|
21
|
+
|
|
22
|
+
사용자에게 3가지 정보를 순서대로 요청합니다:
|
|
23
|
+
|
|
24
|
+
1. **Atlassian Cloud URL** — 예: `https://your-domain.atlassian.net`
|
|
25
|
+
2. **이메일** — Atlassian 로그인 계정
|
|
26
|
+
3. **API 토큰** — https://id.atlassian.com/manage-profile/security/api-tokens 에서 발급
|
|
27
|
+
|
|
28
|
+
한 번에 다 물어보지 말고 하나씩 대화로 진행하세요. API 토큰 발급 방법을 모르는 경우 링크와 함께 간단히 안내하세요.
|
|
29
|
+
|
|
30
|
+
### 2단계: 크리덴셜 저장
|
|
31
|
+
|
|
32
|
+
정보를 모두 받으면 아래 명령으로 저장합니다:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
mkdir -p ~/.config/choavis-agent && cat > ~/.config/choavis-agent/atlassian-credentials.json << 'CRED_EOF'
|
|
36
|
+
{
|
|
37
|
+
"jiraUrl": "USER_INPUT_URL",
|
|
38
|
+
"username": "USER_INPUT_EMAIL",
|
|
39
|
+
"apiToken": "USER_INPUT_TOKEN",
|
|
40
|
+
"createdAt": "ISO_TIMESTAMP"
|
|
41
|
+
}
|
|
42
|
+
CRED_EOF
|
|
43
|
+
chmod 600 ~/.config/choavis-agent/atlassian-credentials.json
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 3단계: 연결 확인
|
|
47
|
+
|
|
48
|
+
저장 후 바로 테스트합니다:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
node .claude/lib/jira-api.cjs projects
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
성공하면 "Atlassian 연동 완료! Jira와 Confluence 모두 사용 가능합니다." 안내.
|
|
55
|
+
실패하면 에러 메시지를 보고 URL/이메일/토큰 확인을 요청하세요.
|
|
56
|
+
|
|
57
|
+
### 연동 상태 확인
|
|
58
|
+
|
|
59
|
+
사용자가 "지라 연동 상태", "Atlassian 설정 확인" 등을 요청하면:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
cat ~/.config/choavis-agent/atlassian-credentials.json 2>/dev/null
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
- 파일이 있으면: URL과 이메일만 표시 (토큰은 `****`로 마스킹)
|
|
66
|
+
- 파일이 없으면: "Atlassian 연동이 설정되지 않았습니다. 설정하시겠습니까?" 안내
|
|
67
|
+
|
|
68
|
+
### 연동 해제
|
|
69
|
+
|
|
70
|
+
사용자가 "지라 연동 해제", "Atlassian 설정 삭제" 등을 요청하면:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
rm ~/.config/choavis-agent/atlassian-credentials.json
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
삭제 전 반드시 확인을 받으세요. 에이전트 재시작 후 완전 적용됩니다.
|
|
77
|
+
|
|
78
|
+
## 트리거 키워드 (설정)
|
|
79
|
+
|
|
80
|
+
지라 연동, jira setup, jira 설정, Atlassian 연동, Atlassian 설정, 지라 설정해줘, 지라 연결, 연동 상태, 연동 해제
|
|
16
81
|
|
|
17
82
|
## API 호출 방법
|
|
18
83
|
|
|
@@ -69,7 +134,7 @@ node .claude/lib/jira-api.cjs comment KEY-123 "댓글 내용"
|
|
|
69
134
|
node .claude/lib/jira-api.cjs projects
|
|
70
135
|
```
|
|
71
136
|
|
|
72
|
-
## 트리거 키워드
|
|
137
|
+
## 트리거 키워드 (API)
|
|
73
138
|
|
|
74
139
|
지라, jira, 이슈 검색, 이슈 조회, 이슈 생성, 이슈 상태, JQL, 내 이슈, 할당된 이슈, 스프린트, 이슈 만들어, 상태 변경, 댓글 추가
|
|
75
140
|
|
|
@@ -85,8 +150,8 @@ node .claude/lib/jira-api.cjs projects
|
|
|
85
150
|
|
|
86
151
|
| 에러 | 대응 |
|
|
87
152
|
|------|------|
|
|
88
|
-
| "인증 정보를 찾을 수 없습니다" |
|
|
89
|
-
| HTTP 401/403 | 토큰 만료 가능성,
|
|
153
|
+
| "인증 정보를 찾을 수 없습니다" | Atlassian 연동 설정 절차 시작 |
|
|
154
|
+
| HTTP 401/403 | 토큰 만료 가능성, 재설정 안내 |
|
|
90
155
|
| HTTP 404 | 이슈/프로젝트 키 확인 안내 |
|
|
91
156
|
|
|
92
157
|
## 주의사항
|
package/CLAUDE.md
CHANGED
|
@@ -73,3 +73,45 @@ Slack은 단순한 UI일 뿐이다. 너는 이 프로젝트 루트에서 동작
|
|
|
73
73
|
- 코드 변경 시 무엇을 왜 변경했는지 설명
|
|
74
74
|
- 긴 코드 블록보다 핵심 변경사항 위주로 설명
|
|
75
75
|
- 불확실한 것은 추측하지 않고 확인 후 답변
|
|
76
|
+
- 작업이 끝나지 않았으면 끝까지 완료해라. 중간에 임의로 요약하거나 생략하지 마라
|
|
77
|
+
|
|
78
|
+
## Slack 출력 포맷 (필수)
|
|
79
|
+
|
|
80
|
+
너의 응답은 Slack에 표시된다. 반드시 Slack mrkdwn 형식으로 출력해라. 일반 마크다운(GitHub 스타일)은 사용하지 마라.
|
|
81
|
+
|
|
82
|
+
### Slack mrkdwn 규칙
|
|
83
|
+
|
|
84
|
+
- 볼드: `*텍스트*` (별 1개, `**`은 쓰지 마라)
|
|
85
|
+
- 이탤릭: `_텍스트_`
|
|
86
|
+
- 취소선: `~텍스트~`
|
|
87
|
+
- 인라인 코드: `` `코드` ``
|
|
88
|
+
- 코드 블록: ` ```코드``` ` (언어 지정 불필요)
|
|
89
|
+
- 링크: `<URL|텍스트>`
|
|
90
|
+
- 인용: `>` (줄 시작)
|
|
91
|
+
- 리스트: `•` 또는 숫자 사용 (마크다운 `-` 대신 `•` 권장)
|
|
92
|
+
|
|
93
|
+
### 절대 하지 말 것
|
|
94
|
+
|
|
95
|
+
- `#`, `##`, `###` 헤더 사용 금지 → 대신 `*제목*`으로 볼드 처리
|
|
96
|
+
- `**텍스트**` 사용 금지 → `*텍스트*`
|
|
97
|
+
- `[텍스트](URL)` 사용 금지 → `<URL|텍스트>`
|
|
98
|
+
- `` 사용 금지 → `<URL|이미지>`
|
|
99
|
+
- `~~텍스트~~` 사용 금지 → `~텍스트~`
|
|
100
|
+
- 마크다운 테이블(`| col | col |`) 사용 금지 → 리스트 형태로 표현
|
|
101
|
+
|
|
102
|
+
### 테이블 대체 표현
|
|
103
|
+
|
|
104
|
+
마크다운 테이블 대신 이렇게 표현해라:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
*항목1:* 값1 · *항목2:* 값2
|
|
108
|
+
*항목1:* 값3 · *항목2:* 값4
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
또는 리스트로:
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
• *이름:* 홍길동
|
|
115
|
+
*상태:* 진행 중
|
|
116
|
+
*우선순위:* High
|
|
117
|
+
```
|
package/dist/index.js
CHANGED
|
@@ -66431,12 +66431,65 @@ function extractCodeBlocks(text) {
|
|
|
66431
66431
|
return blocks;
|
|
66432
66432
|
}
|
|
66433
66433
|
function convertToSlackMarkdown(text) {
|
|
66434
|
-
|
|
66435
|
-
|
|
66436
|
-
|
|
66437
|
-
|
|
66438
|
-
|
|
66439
|
-
|
|
66434
|
+
return processNonCodeSegments(text, (segment) => {
|
|
66435
|
+
let result = segment;
|
|
66436
|
+
result = convertTableSegment(result);
|
|
66437
|
+
result = result.replace(/^(\s*[-*_]{3,}\s*)$/gm, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
66438
|
+
result = result.replace(/^#{1,2}\s+(.+)$/gm, "\n*$1*\n");
|
|
66439
|
+
result = result.replace(/^#{3,6}\s+(.+)$/gm, "*$1*");
|
|
66440
|
+
result = result.replace(/\*\*\*(.+?)\*\*\*/gs, "*_$1_*");
|
|
66441
|
+
result = result.replace(/\*\*(.+?)\*\*/gs, "*$1*");
|
|
66442
|
+
result = result.replace(/~~(.+?)~~/g, "~$1~");
|
|
66443
|
+
result = result.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, "<$2|$1>");
|
|
66444
|
+
result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, "<$2|$1>");
|
|
66445
|
+
result = result.replace(/^(\s*)[-*]\s*\[x\]\s*/gm, "$1:white_check_mark: ");
|
|
66446
|
+
result = result.replace(/^(\s*)[-*]\s*\[ \]\s*/gm, "$1:white_large_square: ");
|
|
66447
|
+
return result;
|
|
66448
|
+
}).replace(/\n{3,}/g, "\n\n").trim();
|
|
66449
|
+
}
|
|
66450
|
+
function processNonCodeSegments(text, transform) {
|
|
66451
|
+
const parts = [];
|
|
66452
|
+
const codeBlockPattern = /```[\s\S]*?```/g;
|
|
66453
|
+
let lastIndex = 0;
|
|
66454
|
+
let match;
|
|
66455
|
+
while ((match = codeBlockPattern.exec(text)) !== null) {
|
|
66456
|
+
if (match.index > lastIndex) {
|
|
66457
|
+
parts.push(transform(text.slice(lastIndex, match.index)));
|
|
66458
|
+
}
|
|
66459
|
+
parts.push(match[0]);
|
|
66460
|
+
lastIndex = match.index + match[0].length;
|
|
66461
|
+
}
|
|
66462
|
+
if (lastIndex < text.length) {
|
|
66463
|
+
parts.push(transform(text.slice(lastIndex)));
|
|
66464
|
+
}
|
|
66465
|
+
return parts.join("");
|
|
66466
|
+
}
|
|
66467
|
+
function convertTableSegment(text) {
|
|
66468
|
+
const tablePattern = /(?:^[ \t]*\|.+\|[ \t]*$\n?)+/gm;
|
|
66469
|
+
return text.replace(tablePattern, (tableBlock) => {
|
|
66470
|
+
const rows = tableBlock.trim().split("\n").map((row) => row.trim());
|
|
66471
|
+
if (rows.length < 2) return tableBlock;
|
|
66472
|
+
const dataRows = rows.filter((row) => !/^\|[\s\-:]+\|$/.test(row));
|
|
66473
|
+
if (dataRows.length === 0) return tableBlock;
|
|
66474
|
+
const parsed = dataRows.map(
|
|
66475
|
+
(row) => row.split("|").slice(1, -1).map((cell) => cell.trim())
|
|
66476
|
+
);
|
|
66477
|
+
if (parsed.length === 0 || parsed[0].length === 0) return tableBlock;
|
|
66478
|
+
const headers = parsed[0];
|
|
66479
|
+
const bodyRows = parsed.slice(1);
|
|
66480
|
+
if (bodyRows.length === 0) {
|
|
66481
|
+
return headers.map((h2) => `*${h2}*`).join(" | ") + "\n";
|
|
66482
|
+
}
|
|
66483
|
+
const lines = [];
|
|
66484
|
+
for (const row of bodyRows) {
|
|
66485
|
+
const entries = headers.map((h2, i2) => {
|
|
66486
|
+
const val = row[i2] ?? "";
|
|
66487
|
+
return `*${h2}:* ${val}`;
|
|
66488
|
+
});
|
|
66489
|
+
lines.push(entries.join(" \xB7 "));
|
|
66490
|
+
}
|
|
66491
|
+
return lines.join("\n") + "\n";
|
|
66492
|
+
});
|
|
66440
66493
|
}
|
|
66441
66494
|
function formatResponse(text) {
|
|
66442
66495
|
const codeBlocks = extractCodeBlocks(text);
|