issue-sticker 0.12.0 → 0.13.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,52 @@
2
2
 
3
3
  npm 패키지 `issue-sticker`의 변경 이력입니다. 설치·업그레이드에 영향을 주는 변경만 기록합니다.
4
4
 
5
+ ## 0.13.0 - 2026-11-03
6
+
7
+ **백엔드 1.14.0 이상이 필요합니다.** 프로젝트 마스킹 정책(`GET /api/sdk/masking-policy`, `409 MASKING_POLICY_CHANGED`)과 설명 다시 불러오기(`POST /api/sdk/issues/:id/description/refresh`, 설명 숨김 저장 필드)를 사용합니다. 정책을 적용할 수 없는 상태에서는 이슈를 만들지 않습니다.
8
+
9
+ ### 호환성이 깨지는 변경 (headless)
10
+
11
+ - `HeadlessErrorCode` 에 `MASKING_POLICY_UNAVAILABLE`·`MASKING_POLICY_CHANGED`·`MASKING_SELECTOR_UNSUPPORTED`·`RATE_LIMITED` 를 추가합니다. 코드 값을 빠짐없이 나열해 분기하는 코드(`switch` 와 `never` 검사)나 `Record<HeadlessErrorCode, …>` 맵은 네 값을 처리해야 컴파일됩니다.
12
+ - 화면 마스킹 규칙의 선택자를 브라우저에서 적용할 수 없으면 `submitDraft()`·`createIssue()` 모두 `CAPTURE_FAILED` 대신 `MASKING_SELECTOR_UNSUPPORTED` 로 실패합니다. 다시 시도해도 결과가 같으므로 워크스페이스 관리자에게 문의하도록 안내합니다.
13
+ - 멤버로 로그인하지 않은 상태에서 서버가 401 을 돌려주면 `MEMBER_AUTH_REQUIRED` 대신 `AUTH_FAILED` 로 실패합니다. API key 문제를 멤버 로그인 문제로 안내하던 것을 바로잡습니다. 멤버 로그인 상태의 401 은 그대로 `MEMBER_AUTH_REQUIRED` 입니다.
14
+
15
+ ### 추가
16
+
17
+ - 위젯이 초기화할 때 API 키에 연결된 프로젝트의 마스킹 정책을 받아 메모리에 둡니다. 다른 키로 다시 초기화하면 앞 프로젝트의 정책은 버립니다. API 키에 `issues:create` 권한이 없으면 정책을 받을 수 없고, 정책을 적용할 수 없는 상태에서는 이슈를 만들지 않습니다.
18
+ - 이슈를 제출할 때 프로젝트 마스킹 정책을 콘솔·네트워크 로그, 웹소켓 기록, 페이지 URL 에 적용합니다. 키 이름 규칙으로 가리지 못한 키가 남은 네트워크 본문은 첨부에서 뺍니다.
19
+ - 마스킹 정책의 화면 요소 규칙을 세션 리플레이에도 적용합니다. 규칙에 해당하는 요소는 같은 크기의 가려짐 상자로 바뀌어 전송됩니다. 리플레이에 정책을 적용하지 못하면 위젯은 이슈를 생성하지 않고 안내하며, headless `submitDraft()` 는 `CAPTURE_FAILED` 로 실패합니다.
20
+ - 제출 직전에 정책을 다시 확인합니다. 서버가 `409 MASKING_POLICY_CHANGED` 로 정책이 바뀌었다고 알리면, 화면 마스킹 규칙이 같을 때는 새 정책으로 한 번 다시 제출하고 바뀌었을 때는 이슈를 생성하지 않고 안내합니다.
21
+ - 정책이 화면 녹화를 금지하면 영상 없이 이슈를 생성합니다. 위젯은 완료 안내에 이를 덧붙이고, headless `submitDraft()` 는 반환값에 `videoExcluded: true` 를 함께 돌려줍니다.
22
+ - 영상을 업로드하는 동안 프로젝트 마스킹 정책이 화면 녹화를 막으면 위젯이 "영상을 업로드하지 못했습니다" 대신 마스킹 정책 때문에 영상을 첨부하지 않았다고 안내합니다. 이슈는 영상 없이 남습니다. headless 는 이 경우 `snapshot.issues`·`snapshot.activeIssue` 의 이슈에 `video_status: 'failed'` 와 함께 `video_failure_reason: 'masking_video_excluded'` 를 싣습니다. 새 필드는 선택 필드라 기존 코드는 그대로 동작합니다.
23
+ - 마스킹 정책을 적용하지 못해 스크린샷을 첨부하지 않으면 이슈 설명 끝에 안내를 추가합니다. 요소 스크린샷처럼 남은 스크린샷을 첨부했으면 일부만 첨부하지 않았다고 안내합니다. AI 작성(`intent`)으로 제출하면 서버가 설명을 새로 생성하면서 이 안내가 사라지므로, headless `submitDraft()`·`createIssue()` 는 반환값에 `screenshotExcluded: true` 를 함께 돌려줍니다.
24
+ - headless `createIssue()` 입력에 `onError` 를 추가합니다. 이슈를 생성하지 않고 `null` 로 끝날 때 한 번 호출되며, `submitDraft()` 가 던지는 것과 같은 코드의 `IssueStickerHeadlessError` 를 전달합니다. 앱은 이 코드를 보고 다시 시도할지 판단합니다.
25
+ - 입력이 비었으면 `VALIDATION_ERROR`, 60초에 5건인 호출 한도를 넘었으면 `RATE_LIMITED` 로 전달합니다. 마스킹 정책 실패는 `MASKING_POLICY_CHANGED`·`MASKING_POLICY_UNAVAILABLE`·`CAPTURE_FAILED`·`MASKING_SELECTOR_UNSUPPORTED` 로 전달합니다.
26
+ - `onError` 에서 예외가 발생해도 `createIssue()` 는 예외를 던지지 않고 `null` 을 돌려줍니다.
27
+ - `createIssue()` 를 입력 없이 호출해도 예외를 던지지 않고 `VALIDATION_ERROR` 로 끝납니다. 이슈를 생성한 뒤 이후 처리에서 예외가 발생하면 `onError` 를 호출하지 않고 생성한 이슈를 돌려줍니다.
28
+ - 이슈 설명에 Jira에서만 고칠 수 있는 요소(패널, 접기 블록, 첨부 등)가 있으면 어떤 요소인지 안내합니다. 안내가 있어도 나머지 설명은 이슈스티커에서 계속 수정할 수 있고, 해당 요소를 바꾸거나 지우면 저장되지 않으며 되돌린 뒤 다시 저장하면 됩니다.
29
+ - 설명 저장이 실패하면 원인에 맞는 안내 문구를 보여줍니다. 연동된 서비스에서 설명이 먼저 바뀐 경우에는 최신 내용을 불러오고, 입력하던 내용은 그대로 둡니다.
30
+
31
+ ### 개선
32
+
33
+ - Notion과 연결된 이슈의 설명도 이슈스티커에서 수정할 수 있습니다. 이미지·파일·콜아웃·북마크처럼 Notion에서만 고칠 수 있는 요소가 있으면 어떤 요소인지 안내하고, 나머지 설명은 계속 수정할 수 있습니다. 설명 섹션의 제목이 Notion에서 지워진 경우에만 수정 버튼 대신 잠금 안내를 보여줍니다.
34
+ - 위젯에서 Jira·Notion과 연결된 이슈의 설명에 있는 패널, 콜아웃, 멘션처럼 외부 서비스에서만 수정할 수 있는 내용을 읽기 전용으로 표시합니다. 수정 화면에서는 이 내용을 숨기고, 저장해도 Jira·Notion 원본의 같은 자리에 그대로 남습니다. 첨부 이미지·파일처럼 보여줄 수 없는 내용은 한 줄 안내로 대신합니다. 설명 전체가 이런 내용이면 수정 버튼 없이 안내만 표시합니다.
35
+ - 이전에 연결된 이슈 중 외부 서비스에서만 수정할 수 있는 내용이 든 이슈는 설명을 다시 불러와야 수정할 수 있습니다. 이런 이슈에는 수정 버튼 대신 「다시 불러오기」가 표시되고, 이 버튼을 클릭하면 이슈 설명이 Jira·Notion의 현재 설명으로 바뀝니다. 연결이 끊겼거나 Jira 이슈·Notion 페이지가 삭제되어 다시 불러올 수 없는 이슈, 다시 불러와도 숨길 내용을 찾지 못한 이슈는 이전처럼 전체 설명을 수정합니다.
36
+
37
+ ### 개인정보 보호
38
+
39
+ - `rr-block` 등 차단 표식이 붙은 영역 안의 캔버스 이미지와 조작 기록을 세션 리플레이에 포함하지 않습니다. 이전에는 차단 영역이어도 캔버스를 조작하면 그 시점의 캔버스 이미지와 3D 오브젝트 이름이 리플레이에 첨부되었습니다. shadow root 안의 캔버스도 host 요소가 차단 영역 안에 있으면 포함하지 않습니다.
40
+ - `rr-mask` 등 마스킹 표식이 붙은 요소 안에 shadow root 가 있으면, 그 안의 텍스트도 세션 리플레이에서 가립니다. 이전에는 shadow root 안의 텍스트가 그대로 남았습니다. 마스킹 영역 안의 shadow root 에 있는 캔버스도 리플레이에 이미지와 조작 기록을 포함하지 않습니다.
41
+ - 화면 요소 마스킹 규칙으로 가린 영역의 입력창이나 캔버스가 페이지에서 제거된 뒤 페이지 스크립트가 값을 바꾸거나 그리면, 그 내용이 세션 리플레이에 남을 수 있던 문제를 수정합니다. 색·범위 입력값과 체크 상태, 캔버스 그리기 기록이 해당합니다. 이제 이슈를 생성할 때 리플레이 화면에 없는 요소의 입력·캔버스 기록을 지웁니다.
42
+ - 마스킹 정책으로 가린 영역 위의 클릭 좌표와 마우스 이동 위치는 세션 리플레이에 그대로 남깁니다. 이벤트 대상은 가려짐 상자로 바뀌어, 가린 요소 안의 어떤 요소를 클릭했는지는 전송하지 않습니다. 화면 키패드처럼 클릭 위치가 곧 입력값인 영역은 리플레이에서 입력값이 드러날 수 있습니다.
43
+
44
+ ### 수정
45
+
46
+ - 세션 리플레이에 열린 shadow root 안의 캔버스(`<model-viewer>` 등)를 조작한 기록과 캔버스 이미지가 포함됩니다. 이전에는 이런 캔버스의 조작을 기록하지 않았습니다.
47
+ - 캡처 제외로 지정한 canvas, video, 같은 출처 iframe이 스크린샷에 그대로 찍히던 문제를 수정했습니다. 이제 다른 제외 요소처럼 감춰지고, 주변 요소의 배치는 그대로 유지됩니다.
48
+ - 한 페이지를 오래 사용하는 웹앱에서 세션 리플레이를 녹화할수록 메모리 사용량이 계속 늘던 문제를 수정합니다. 화면 요소 마스킹 규칙에 해당하는 요소가 계속 생기고 사라지면 30분에 13MB 가까이 늘었습니다. 이제 리플레이 기록 구간(3분 안팎)에 나온 요소의 가림 정보만 유지하고, 리플레이 백업 크기 상한에 가림 정보도 포함합니다. 페이지를 이동한 뒤 이전 페이지의 리플레이를 복원할 때, 가림 정보가 이미 정리된 구간은 리플레이에서 뺍니다.
49
+ - 마스킹 정책을 받기 전에 찍은 스크린샷으로 이슈를 제출하면, 정책이 바뀌지 않았는데도 "마스킹 정책을 적용하기 위해 스크린샷을 다시 캡처했습니다" 안내가 뜨던 문제를 수정합니다. 이제 제출할 때 받은 정책으로 스크린샷을 한 번 다시 찍어 가린 뒤 안내 없이 이슈를 생성합니다. 세션 리플레이가 정책 없이 녹화된 경우는 기존처럼 안내하고 녹화를 새로 시작합니다.
50
+
5
51
  ## 0.12.0 - 2026-10-14
6
52
 
7
53
  **백엔드 1.13.0 이상이 필요합니다.** 비동기 업로드(`video_status`·`resumableUrl`·`replay_status`·`replayMeta` 계약)와 `Retry-After` 헤더 노출을 사용합니다.