dsh-composer-plus 1.14.0 → 1.16.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/README.ko.md CHANGED
@@ -29,7 +29,7 @@ dsh plugin --profile web add dsh-composer-plus
29
29
 
30
30
  그런 다음 dsh를 다시 시작하세요. (CLI는 데스크톱 프로필에 설치할 수 없습니다. 데스크톱 프로필은 앱이 관리합니다.)
31
31
 
32
- > dsh의 pnpm은 게시된 지 24시간이 지나지 않은 버전을 건너뜁니다. 릴리스 직후에는 버전을 붙여서 설치하세요: `dsh-composer-plus@1.14.0`.
32
+ > dsh의 pnpm은 게시된 지 24시간이 지나지 않은 버전을 건너뜁니다. 릴리스 직후에는 버전을 붙여서 설치하세요: `dsh-composer-plus@1.16.0`.
33
33
 
34
34
  ## 기능
35
35
 
@@ -37,7 +37,7 @@ dsh plugin --profile web add dsh-composer-plus
37
37
 
38
38
  | 기능 | 사용 방법 | 스크린샷 |
39
39
  |---|---|---|
40
- | **변경 사항 패널** | <a id="feature-changespanel"></a>오른쪽 사이드바 → `+` → **변경 사항**. **커밋 안 됨**, **스테이징 안 됨**, **스테이징됨**, **브랜치** 중 하나를 고르면 변경된 파일이 `+/-` 개수와 함께 표시됩니다. 파일을 클릭하면 diff를 볼 수 있습니다. **마지막 턴**은 최근 턴에 대한 dsh 자체 검토 화면을 엽니다. 브랜치 이름을 클릭하면(또는 **트리** 선택) 브랜치 트리를 볼 수 있습니다. 위쪽의 브랜치를 클릭하면 그 브랜치로 이동하고, 커밋을 클릭하면 그 파일과 diff를 볼 수 있습니다. **이 채팅**은 열린 채팅의 파일 도구(write, edit)가 모든 턴에서 쓴 파일만 보여 주고, 첫 메시지 이후의 전체 diff도 보여 줍니다. **␣** 버튼은 공백 변경을 숨깁니다(`git diff -w`). 들여쓰기나 줄 끝만 바뀐 줄은 표시되지 않습니다. 파일의 **…** 메뉴 → **이 파일을 변경한 채팅**은 같은 저장소에서 쓰기 또는 편집 도구로 그 파일을 변경한 채팅을 변경한 요청과 함께 최신순으로 보여 줍니다. 클릭하면 그 요청 위치에서 채팅이 열립니다. | <a href="assets/features/changesPanel.webp"><img src="assets/features/changesPanel.webp" width="160" alt="스크린샷: 변경 사항 패널"></a> |
40
+ | **변경 사항 패널** | <a id="feature-changespanel"></a>오른쪽 사이드바 → `+` → **변경 사항**. 페이지는 **트리**로 열립니다. 채팅 저장소의 브랜치 맵입니다. 카드 세 개가 브랜치 수를 보여 줍니다. 전체 브랜치, 병합된 브랜치, 병합을 기다리는 브랜치의 수입니다. 카드를 클릭하면 그 브랜치만 보이고, 다시 클릭하면 모든 브랜치가 보입니다. 각 브랜치는 마지막 커밋이 표시된 상자입니다. 메인 브랜치에 그 브랜치의 작업이 있으면 초록색, 없으면 주황색이고, 메인 브랜치는 파란색입니다. 각 브랜치에서 화살표가 그 브랜치를 받아들인 브랜치(✅ **병합됨**)나 그 브랜치가 시작된 브랜치(⏳ **대기 중**, 점선)로 이어집니다. 상자를 클릭하면 브랜치의 커밋을 볼 수 있고, 이어서 커밋을 클릭하면 그 파일과 diff를 볼 수 있습니다. **병합됨**을 클릭하면 병합 커밋의 파일을, **대기 중**을 클릭하면 브랜치가 대상 브랜치에 가져오는 파일을 볼 수 있습니다. 원격 브랜치는 이름이 같은 로컬 브랜치가 없을 때만 표시됩니다. 모드 메뉴에서 **커밋 안 됨**, **스테이징 안 됨**, **스테이징됨**, **브랜치** 중 하나를 고르면 변경된 파일이 `+/-` 개수와 함께 표시됩니다. 파일을 클릭하면 diff를 볼 수 있습니다. **마지막 턴**은 최근 턴에 대한 dsh 자체 검토 화면을 엽니다. **이 채팅**은 열린 채팅의 파일 도구(write, edit)가 모든 턴에서 쓴 파일만 보여 주고, 첫 메시지 이후의 전체 diff도 보여 줍니다. **␣** 버튼은 공백 변경을 숨깁니다(`git diff -w`). 들여쓰기나 줄 끝만 바뀐 줄은 표시되지 않습니다. 파일의 **…** 메뉴 → **이 파일을 변경한 채팅**은 같은 저장소에서 쓰기 또는 편집 도구로 그 파일을 변경한 채팅을 변경한 요청과 함께 최신순으로 보여 줍니다. 클릭하면 그 요청 위치에서 채팅이 열립니다. | <a href="assets/features/changesPanel.webp"><img src="assets/features/changesPanel.webp" width="160" alt="스크린샷: 변경 사항 패널"></a> |
41
41
  | **기능 아이디어** | <a id="feature-featureideas"></a>오른쪽 사이드바 → `+` → **기능 아이디어** → **기능 제안**. 채팅 자체의 모델이 채팅 프로젝트의 짧은 요약(최상위 파일, README와 매니페스트의 앞부분, README 나머지 부분의 개요, 최근 커밋 제목)을 읽고 기능을 최대 8개 제안합니다. 제안은 dsh UI 언어로 된 카드 묶음으로 표시됩니다. 카드를 오른쪽으로 스와이프하면(또는 **✓** 클릭, `→` 누르기. 어느 방법이든 카드가 그쪽으로 날아갑니다) 같은 프로젝트에서 새 채팅이 시작됩니다. 새 채팅은 그 아이디어를 요청으로 삼아 계획 모드로 시작하므로, 계획을 승인하기 전에는 아무것도 바뀌지 않습니다. 계획을 건너뛰려면 **▶ 바로 구현**을 클릭하세요(또는 `↑` 누르기. 카드가 위로 날아갑니다). 새 채팅이 그 아이디어를 일반 요청으로 삼아 바로 시작하고, 모델이 변경을 적용한 뒤 검사를 실행합니다(승인은 평소대로 적용됩니다). 건너뛰려면 왼쪽으로 스와이프하세요(또는 **✕**, `←`). **실행 취소**(또는 `Z`)는 건너뛴 카드를 되돌립니다. 좋은 아이디어를 나중을 위해 저장하려면 **↓**를 클릭하세요(또는 `↓` 누르기). 아이디어는 프로젝트의 **나중에** 목록에 들어갑니다. 같은 프로젝트 폴더의 모든 채팅에서 이 목록이 보입니다(재시작 후에도). **나중에(N)** 버튼은 목록을 엽니다. **계획하기**는 그 아이디어로 같은 계획 모드 채팅을 시작하고, **바로 구현**은 계획 없는 채팅을 시작합니다. 둘 다 아이디어를 목록에서 뺍니다. **모두 함께 계획 (N)** 버튼은 목록의 모든 아이디어로 계획 모드 채팅 하나를 시작하므로, 공통 부분은 한 번만 계획됩니다. **목록에서 제거**는 아이디어를 삭제합니다. **체크리스트로 복사**는 목록 전체를 Markdown 체크리스트(`- [ ] Title — Summary`, 아이디어마다 한 줄)로 클립보드에 복사합니다. 이슈 트래커나 TODO 파일에 쓸 수 있으며, 네트워크 요청은 하지 않습니다. 아이디어의 **GitHub 이슈 열기**는 사용자의 GitHub CLI(`gh`) 로그인으로 프로젝트의 GitHub 저장소에 아이디어의 제목과 요약(그리고 중요한 이유)으로 이슈를 엽니다. 그러면 아이디어 옆에 **이슈 #N** 링크가 표시되고, 이 링크로 이슈를 열 수 있습니다. **아이디어 더 받기**는 카드를 추가합니다. 한 분야에 대한 아이디어만 받으려면 **기능 제안** 옆 입력란에 짧은 **집중 주제**를 입력하거나(최대 80자, `Enter`로도 제안합니다), 그 아래의 고정 주제 **성능**, **접근성**, **테스트**, **보안**, **사용성**, **문서** 중 하나를 클릭하세요(다시 클릭하면 지워집니다). 그러면 모델은 그 주제에 관한 기능만 제안합니다. 입력란이 비어 있으면 어떤 기능이든 제안합니다. 한 프로젝트에서 같은 아이디어는 두 번 제안되지 않습니다. 제안된 모든 아이디어(건너뛴 것, 저장한 것, 시작한 것)는 프로젝트의 **기록**에 들어갑니다. 모델에는 그 아이디어를 다시 제안하지 말라는 지시가 전달되고, 제목이 반복된 아이디어는 버려집니다. **기록**은 아이디어를 **시작됨** 또는 **제안됨**으로 표시해 보여 줍니다. **잊기**(또는 **모두 잊기**)를 누르면 그 아이디어가 다시 나올 수 있지만, 아직 **나중에** 목록에 있는 아이디어는 그 목록에서 제거할 때까지 제안에 나오지 않습니다. 모델은 클릭할 때만 실행됩니다. | <a href="assets/features/featureIdeas.webp"><img src="assets/features/featureIdeas.webp" width="160" alt="스크린샷: 기능 아이디어"></a> |
42
42
  | **내용 검색** | <a id="feature-contentsearch"></a>dsh 자체 사이드바 검색(**작업 공간** 옆의 돋보기. 데스크톱 앱에서는 `Cmd+K`, 브라우저에서는 `Cmd+Alt+K`)이 제목뿐 아니라 내 메시지와 답변 속 단어로도 채팅을 찾고, 일치하는 텍스트를 채팅 아래에 보여 줍니다. 이 검색은 dsh에 이미 있지만 꺼진 상태로 제공됩니다. 이 기능은 컴퓨터에 검색 색인 파일을 두고 그 검색을 켭니다. 색인은 dsh 시작 후 첫 검색 때 만들어지며(채팅 250개에 약 15초, 제한 사항 참고) 다음 시작 때도 그대로 쓰입니다. 기본적으로 켜져 있습니다. 변경 사항은 dsh를 다시 시작한 뒤 적용됩니다. | <a href="assets/features/contentSearch.webp"><img src="assets/features/contentSearch.webp" width="160" alt="스크린샷: 내용 검색"></a> |
43
43
  | **턴 되돌리기** | <a id="feature-turnrollback"></a>내 메시지 위에 포인터를 올리고 **↶** 버튼(복사 옆)을 클릭하세요. **채팅만**은 그 메시지와 이후의 모든 내용(답변, 도구 호출)을 채팅과 모델 컨텍스트에서 빼고, 메시지를 입력란에 다시 넣습니다. 메시지를 고친 뒤 다시 보내세요. **채팅과 파일**은 먼저 그 메시지 이후 바뀐 프로젝트 파일 목록을 보여 주고, 그 파일도 이전 상태로 되돌립니다. dsh 편집 도구가 바꾼 내용뿐 아니라 명령(`bash`)이 바꾼 내용도 되돌립니다. 실행 중인 턴은 먼저 멈춥니다. 채팅 로그는 다시 쓰지 않습니다. 숨겨진 표시 하나가 철회된 부분을 가립니다. dsh 자체의 `/compact`가 오래된 메시지를 가리는 방식과 같습니다. [dsh-rewind-plugin](https://www.npmjs.com/package/dsh-rewind-plugin)이 설치되어 있으면 이 일은 그 플러그인이 맡고, Composer Plus는 두 번째 버튼을 보여 주지 않습니다. 되돌린 뒤에는 입력란 위에 **다시 실행** 표시줄이 나타납니다. 이 표시줄은 되돌리기 직전 시점부터 새 채팅을 시작하고(같은 메시지와 컨텍스트), **채팅과 파일**을 고르면 파일도 다시 가져옵니다. 되돌린 뒤에 내가 바꾼 파일은 목록에 표시되고 그대로 유지됩니다. 단, 덮어쓰기 확인란을 선택하면 그 파일도 덮어씁니다. | <a href="assets/features/turnRollback.webp"><img src="assets/features/turnRollback.webp" width="160" alt="스크린샷: 턴 되돌리기"></a> |
@@ -46,10 +46,12 @@ dsh plugin --profile web add dsh-composer-plus
46
46
  | **입력 기록** | <a id="feature-inputhistory"></a>빈 입력란에서 `↑` / `↓`를 누르면 터미널처럼 보낸 메시지를 차례로 불러옵니다. | <a href="assets/features/inputHistory.webp"><img src="assets/features/inputHistory.webp" width="160" alt="스크린샷: 입력 기록"></a> |
47
47
  | **Shift+Tab 계획 모드** | <a id="feature-plantoggle"></a>`Shift+Tab`은 초안 맨 앞에 `/plan `을 붙입니다(다시 누르면 제거). 채팅이 이미 계획 모드이면 `Shift+Tab`으로 계획 모드를 종료합니다. | <a href="assets/features/planToggle.webp"><img src="assets/features/planToggle.webp" width="160" alt="스크린샷: Shift+Tab 계획 모드"></a> |
48
48
  | **입력란 포커스 유지** | <a id="feature-keepfocus"></a>`/` 명령이나 스킬을 보낸 뒤에도 커서가 입력란에 남아 바로 다시 입력할 수 있습니다. 명령을 입력하고 `Enter`를 누르는 키보드 매크로에서도 작동합니다. dsh는 명령을 처리하는 동안 입력란을 읽기 전용으로 만들고, 그때 브라우저가 포커스를 해제합니다. 이 기능은 포커스를 입력란으로 돌려놓습니다. 단, 메뉴, 대화 상자, 다른 입력 필드에 포커스가 있으면 돌려놓지 않습니다. | <a href="assets/features/keepFocus.webp"><img src="assets/features/keepFocus.webp" width="160" alt="스크린샷: 입력란 포커스 유지"></a> |
49
+ | **질문 카드를 창에 맞추기** | <a id="feature-questionfit"></a>에이전트가 질문하면 질문과 답변이 카드 안에서 함께 스크롤되고, **건너뛰기**와 **제출**은 아래쪽에 계속 보입니다. 카드는 창 높이(채팅 헤더와 채팅 일부를 위해 200 px를 뺀 높이)를 사용하므로 창에 따라 커지고 작아집니다. 이 기능이 없으면 dsh는 카드를 창의 60%(최대 520 px)로 제한하고 답변만 스크롤합니다. 질문이 길면 질문의 끝, 답변, 버튼이 카드 밖으로 밀려날 수 있습니다. | <a href="assets/features/questionFit.webp"><img src="assets/features/questionFit.webp" width="160" alt="스크린샷: 질문 카드를 창에 맞추기"></a> |
49
50
  | **원클릭 계속** | <a id="feature-continuebutton"></a>턴이 중지되거나, 실패하거나, 중간에 끊긴 뒤에는 빈 입력란에 **▶**가 표시됩니다. 한 번 클릭하면 입력란에 아무것도 쓰지 않고, 보이는 채팅 메시지도 추가하지 않은 채 기존 대화를 이어 갑니다(모델은 “멈춘 곳에서 계속하라”는 짧은 숨은 메모를 받습니다. Claude 같은 일부 제공자는 어시스턴트 답변으로 끝나는 요청을 거부하기 때문입니다). 대기열의 메시지는 그대로 남습니다. ▶는 중지된 작업만 이어 가고, 그다음에 대기열이 실행됩니다. 완료된 턴 뒤에는 일반 보내기 버튼이 그대로 있습니다. | <a href="assets/features/continueButton.webp"><img src="assets/features/continueButton.webp" width="160" alt="스크린샷: 원클릭 계속"></a> |
50
51
  | **재시작 후 이어서 실행** | <a id="feature-resumeafterrestart"></a>기본적으로 꺼져 있습니다. **설정 → Composer Plus**에서 켜세요. 채팅이 작업하는 중에 dsh를 종료하면(또는 dsh가 닫히면), dsh를 다시 열 때 그 채팅이 자동으로 이어집니다. 이때 원클릭 계속과 같은 숨은 메모를 씁니다. 목표 라운드(`/goal`)가 실행 중이었다면 목표는 다음 라운드로 계속됩니다(dsh는 시작할 때마다 목표를 일시 중지하고, 사용자가 재개할 때까지 기다립니다). 직접 중지한 채팅, 완료된 채팅, 실패한 채팅은 이어지지 않습니다. dsh 자체에는 이 설정이 없습니다. dsh는 이런 턴을 중단됨으로 표시할 뿐입니다. | <a href="assets/features/resumeAfterRestart.webp"><img src="assets/features/resumeAfterRestart.webp" width="160" alt="스크린샷: 재시작 후 이어서 실행"></a> |
51
52
  | **대기열 끌어서 놓기** | <a id="feature-queuereorder"></a>대기 중인 메시지에 핸들(⠿)이 생깁니다. 끌어서 순서를 바꾸거나, 핸들에 포커스를 두고 `↑` / `↓`를 누르세요. `Esc`는 이동을 취소합니다. | <a href="assets/features/queueReorder.webp"><img src="assets/features/queueReorder.webp" width="160" alt="스크린샷: 대기열 끌어서 놓기"></a> |
52
- | **대기 중인 메시지 제자리 편집** | <a id="feature-queueedit"></a>대기 중인 메시지를 더블클릭하세요. 메시지가 dsh 자체 편집 상자로 바뀝니다. 텍스트를 고친 뒤 `Enter`를 눌러 저장하거나 `Esc`를 눌러 취소하세요. 메시지는 대기열에서 자기 자리를 유지합니다. 이미지나 파일이 있는 메시지는 이 방법으로 편집할 수 없습니다(dsh 대기열은 텍스트만 편집합니다). | <a href="assets/features/queueEdit.webp"><img src="assets/features/queueEdit.webp" width="160" alt="스크린샷: 대기 중인 메시지 제자리 편집"></a> |
53
+ | **대기 중인 메시지 제자리 편집** | <a id="feature-queueedit"></a>대기 중인 메시지를 더블클릭하거나 편집 버튼(**대기 중인 메시지 편집**)을 클릭하세요. 그 행 안에 편집기가 열립니다. 텍스트를 고치고, 이미지나 파일을 ✕로 제거하거나, 클립(**이미지 또는 파일 추가**)이나 이미지 붙여넣기로 새로 추가하세요. `Enter`는 저장, `Esc`는 취소, `Shift+Enter`는 줄 추가입니다. 메시지는 대기열에서 자기 자리를 유지하고, 남겨 둔 이미지와 파일은 그대로입니다. 편집기가 열려 있는 동안에는 대기열 순서를 바꿀 수 없습니다. Tether에서는 대기 중인 메시지 메뉴 → Edit입니다. | <a href="assets/features/queueEdit.webp"><img src="assets/features/queueEdit.webp" width="160" alt="스크린샷: 대기 중인 메시지 제자리 편집"></a> |
54
+ | **중지 후 보낸 메시지 먼저 실행** | <a id="feature-stopsendfirst"></a>기본적으로 켜져 있습니다. 대기열에 메시지가 있는 상태에서 채팅을 중지한 뒤 새 메시지를 보내면, 새 메시지가 바로 단독으로 실행됩니다. 대기 중인 메시지는 순서를 유지하고 그 뒤에 턴마다 하나씩 실행됩니다. 이 기능이 없으면 dsh는 새 메시지를 대기열 끝에 넣고 대신 대기열의 첫 메시지를 실행하므로, 새 메시지가 마지막에 실행됩니다. 채팅이 작업하는 중에 보낸 메시지는 여전히 대기열 끝에서 기다립니다. | <a href="assets/features/stopSendFirst.webp"><img src="assets/features/stopSendFirst.webp" width="160" alt="스크린샷: 중지 후 보낸 메시지 먼저 실행"></a> |
53
55
  | **세션 링크 복사** | <a id="feature-copydeeplink"></a>사이드바에서 채팅을 마우스 오른쪽 버튼으로 클릭 → **세션 링크 복사**. `dsh-session:…` 링크를 다른 채팅에 붙여 넣으면 그 채팅이 읽기 전용 컨텍스트로 첨부됩니다. dsh 0.2.1에는 자체 **세션 ID 복사**가 있지만, 이 메뉴는 ID만 복사합니다. 이 항목은 그 바로 다음에 표시됩니다. | <a href="assets/features/copyDeeplink.webp"><img src="assets/features/copyDeeplink.webp" width="160" alt="스크린샷: 세션 링크 복사"></a> |
54
56
  | **메시지 링크 복사** | <a id="feature-copymessagelink"></a>메시지 위에 포인터를 올리고 **🔗**를 클릭하세요(메시지의 작업 줄에 있고, 답변에서는 시간 옆에 있습니다). 링크는 세션 링크 뒤에 메시지 번호를 붙인 것입니다: `dsh-session:…#42`. 이 링크를 메시지에 붙여 넣고 보내세요. dsh 0.2.1 이상에서는 링크가 칩으로 표시됩니다. 칩을 클릭하면 그 채팅이 열리고, 메시지로 스크롤한 뒤 2초 동안 강조 표시합니다. 세션 링크처럼 그 채팅을 읽기 전용 컨텍스트로도 첨부합니다. | <a href="assets/features/copyMessageLink.webp"><img src="assets/features/copyMessageLink.webp" width="160" alt="스크린샷: 메시지 링크 복사"></a> |
55
57
  | **채팅을 Markdown으로 내보내기** | <a id="feature-exportmarkdown"></a>사이드바에서 채팅을 마우스 오른쪽 버튼으로 클릭(또는 채팅의 **…** 메뉴 열기) → **Markdown으로 내보내기…**. 대화 상자에 채팅의 메시지 수가 표시됩니다. **클립보드에 복사**는 채팅을 Markdown으로 복사하고, **.md 파일 저장**은 브라우저 다운로드로 `<chat title>.md` 파일을 저장합니다(dsh 데스크톱: 시스템 설정에 따라 다운로드 폴더에 저장되거나 저장 대화 상자가 열립니다). 파일에는 채팅 제목, 프로젝트 이름, 날짜가 들어가고, 그 뒤에 메시지마다 `## 나` 또는 `## 어시스턴트` 섹션이 하나씩 이어집니다. 코드 블록은 그대로 유지됩니다. 메시지가 닫지 않은 코드 블록은 닫힙니다. | <a href="assets/features/exportMarkdown.webp"><img src="assets/features/exportMarkdown.webp" width="160" alt="스크린샷: 채팅을 Markdown으로 내보내기"></a> |
@@ -57,23 +59,30 @@ dsh plugin --profile web add dsh-composer-plus
57
59
  | **새 채팅의 프로젝트 검색** | <a id="feature-projectpicker"></a>새 채팅 → 입력란 위의 프로젝트 버튼. 프로젝트가 A–Z 순서로 표시되고, 맨 위에 **프로젝트 검색** 상자가 있습니다. 이름의 일부를 입력하고(대소문자와 악센트 구분 없음) `Enter`를 누르면 첫 번째로 일치하는 프로젝트가 선택됩니다. 일치하는 것이 없으면 **일치하는 프로젝트 없음**이 표시됩니다. 사이드바에 저장된 dsh의 프로젝트 순서는 바뀌지 않습니다. | <a href="assets/features/projectPicker.webp"><img src="assets/features/projectPicker.webp" width="160" alt="스크린샷: 새 채팅의 프로젝트 검색"></a> |
58
60
  | **새 세션의 기본 작업 공간** | <a id="feature-defaultworkspace"></a>설정 → Composer Plus → **새 세션의 기본 작업 공간** → **새 세션을 열 위치**: 프로젝트나 **일반 폴더(default-workspace)** 중 하나를 고르세요(기본값: dsh 자체 폴더 `Documents/deepseek-harness/default-workspace`, 처음 사용할 때 만들어집니다). 그러면 사이드바 맨 위의 **새 세션**(과 그 단축키)은 다른 프로젝트의 채팅이 열려 있을 때도 항상 그곳에서 새 채팅을 엽니다. 프로젝트 옆의 `+`는 여전히 그 프로젝트를 열고, 새 채팅의 입력란 위에 있는 프로젝트 버튼으로도 여전히 프로젝트를 바꿀 수 있습니다. | <a href="assets/features/defaultWorkspace.webp"><img src="assets/features/defaultWorkspace.webp" width="160" alt="스크린샷: 새 세션의 기본 작업 공간"></a> |
59
61
  | **채팅에서 찾기** | <a id="feature-findinchat"></a>채팅에서 Mac에서는 `Cmd+F`(Windows와 Linux에서는 `Ctrl+F`)를 누르면 채팅 위에 찾기 상자가 열립니다. 단어를 입력하면 화면에 있는 메시지와 답변의 일치 항목이 모두 강조 표시되고, 현재 항목은 더 진한 색으로 표시되며, 상자에 n / 전체가 표시됩니다. `Enter` 또는 `↓`는 다음 일치 항목으로, `Shift+Enter` 또는 `↑`는 이전 일치 항목으로 이동합니다(화살표 버튼도 같습니다). 채팅은 일치 항목을 가운데로 스크롤합니다. 대소문자, 악센트, 튀르키예어의 점 없는 ı는 구분하지 않습니다. `Esc`는 상자를 닫고 커서를 원래 자리로 되돌립니다. 답변이 스트리밍되는 동안에도 찾기가 채팅을 따라갑니다. | <a href="assets/features/findInChat.webp"><img src="assets/features/findInChat.webp" width="160" alt="스크린샷: 채팅에서 찾기"></a> |
60
- | **채팅별 브랜치** | <a id="feature-worktreechats"></a>새 채팅 → 프로젝트 버튼 옆의 ⑂ main 버튼 → **새 브랜치**를 고른 뒤 첫 메시지를 입력해 보내세요. AI가 그 메시지를 보고 브랜치 이름(`feat/…`, `fix/…`)을 짓고, Composer Plus가 `<project>/.worktrees/`에 그 브랜치의 git worktree를 만들고, `.worktreeinclude`에 나열된 무시된 파일(예: `.env`, `node_modules/`)을 복사한 뒤, 거기서 메시지와 함께 새 채팅을 엽니다. 열린 채팅의 헤더에는 ⑂ 브랜치 · 변경 N개 · ↑ ↓(또는 **푸시 안 됨**)가 표시됩니다. 클릭하면 **변경 사항**이 열립니다. 같은 메뉴에 열린 worktree도 나열됩니다. 하나를 고르면 거기서 채팅을 시작합니다. 사이드바에서 브랜치 폴더를 프로젝트 안에 표시하려면 dsh의 **보기 옵션** → **작업 공간 트리**를 고르세요. | <a href="assets/features/worktreeChats.webp"><img src="assets/features/worktreeChats.webp" width="160" alt="스크린샷: 채팅별 브랜치"></a> |
62
+ | **채팅별 브랜치** | <a id="feature-worktreechats"></a>새 채팅 화면에서 프로젝트 버튼과 모드 버튼 사이의 브랜치 버튼(브랜치 아이콘)에는 기본으로 **새 브랜치**가 표시됩니다. 첫 메시지를 입력해 보내세요. 현재 브랜치에 남으려면 같은 버튼에서 “현재 브랜치(main)”를 고르세요. 첫 메시지에 이미지와 파일을 첨부할 수 있습니다. 계획 모드에서는 새 채팅도 계획 모드로 시작합니다. 메시지를 `/plan <메시지>`로 보내거나(Shift+Tab), 먼저 새 채팅을 계획 모드로 바꾸세요. AI가 그 메시지를 보고 브랜치 이름(`feat/…`, `fix/…`)을 짓고, Composer Plus가 `<project>/.worktrees/`에 그 브랜치의 git worktree를 만들고, `.worktreeinclude`에 나열된 무시된 파일(예: `.env`, `node_modules/`)을 복사한 뒤, 거기서 메시지와 함께 새 채팅을 엽니다. 열린 채팅의 헤더에는 ⑂ 브랜치 · 변경 N개 · ↑ ↓(또는 **푸시 안 됨**)가 표시됩니다. 클릭하면 **변경 사항**이 열립니다. 같은 메뉴에 열린 worktree도 나열됩니다. 하나를 고르면 거기서 채팅을 시작합니다. 사이드바에서 브랜치 폴더를 프로젝트 안에 표시하려면 dsh의 **보기 옵션** → **작업 공간 트리**를 고르세요. | <a href="assets/features/worktreeChats.webp"><img src="assets/features/worktreeChats.webp" width="160" alt="스크린샷: 채팅별 브랜치"></a> |
63
+ | **작업 공간 트리의 브랜치** | <a id="feature-branchtree"></a>설정 → Composer Plus → **작업 공간 트리의 브랜치**(기본값은 꺼짐). 켜면 `<project>/.worktrees/`에 worktree 폴더가 있는 각 브랜치가 해당 프로젝트 안의 프로젝트로 표시됩니다. 중첩해서 보려면 dsh의 **보기 옵션** → **작업 공간 트리**를 선택하세요. 폴더가 삭제된 브랜치는 목록에서 사라지고, dsh는 그 채팅을 **그룹 없음** 아래에 표시합니다. 프로젝트 폴더에 있는 채팅의 에이전트가 브랜치를 만들고 그 브랜치로 전환하면(`git switch -c`, `git checkout -b`), 폴더에 커밋되지 않은 변경이 없을 때 프로젝트 폴더는 이전 브랜치로 돌아가고, 브랜치는 자체 폴더를 받으며, 채팅은 그곳으로 이동합니다. 복사본이 브랜치 프로젝트에서 열려 작업을 계속하고, 이전 채팅은 보관됩니다. 목록은 시작할 때, 30초마다, 각 턴이 끝난 뒤, 창으로 돌아올 때 확인됩니다. | <a href="assets/features/branchTree.webp"><img src="assets/features/branchTree.webp" width="160" alt="스크린샷: 작업 공간 트리의 브랜치"></a> |
61
64
  | **다음 메시지 예측** | <a id="feature-nextprediction"></a>기본적으로 켜져 있습니다. **설정 → Composer Plus**에서 끌 수 있습니다. 에이전트가 턴을 마치면(중지되거나 실패한 턴 제외) 빈 입력란에 다음 메시지의 예측이 회색으로 표시되고, **Tab으로 수락** 힌트가 함께 나옵니다. `Tab`을 누르면 텍스트가 입력란에 들어가지만 보내지는 않습니다. `Esc`를 누르면 그 턴 동안 예측이 숨겨집니다. 입력을 시작해도 숨겨지고, 새 턴이 오면 새 예측으로 바뀝니다. 스위치 아래의 **모델** 메뉴에는 dsh 자체의 모델 목록이 나옵니다(dsh 모델 메뉴와 같은 목록). 기본으로 **dsh 기본값**이 선택되어 있으며, dsh의 기본 모델을 따릅니다. 턴이 끝날 때마다 짧은 모델 호출이 한 번 일어납니다. Tether에서는 예측이 빈 입력란 위에 표시됩니다. 탭하면 입력란에 들어갑니다. | <a href="assets/features/nextPrediction.webp"><img src="assets/features/nextPrediction.webp" width="160" alt="스크린샷: 다음 메시지 예측"></a> |
62
65
  | **입력 중 자동 완성** | <a id="feature-typingcompletion"></a>기본적으로 꺼져 있습니다. **설정 → Composer Plus**에서 켤 수 있습니다. 입력하는 동안 커서 바로 뒤의 회색 텍스트가 메시지가 이어질 수 있는 내용을 보여 줍니다. `Tab`을 누르면 메시지에 추가되지만 보내지는 않습니다. `Esc`를 누르면 숨겨집니다. 사용자가 직접 이어서 쓸 말만 제안합니다. 사용자에게 하는 답변이나 지어낸 오류 문구, 이름은 제안하지 않습니다. 메시지가 끝난 것처럼 보이거나 모델이 확신하지 못하면 아무것도 표시되지 않습니다. 회색 텍스트의 다음 글자를 그대로 입력하면 텍스트가 유지되고, 새 모델 호출은 없습니다. 스위치 아래에 이 기능 전용 **모델** 메뉴가 있습니다. 첫 항목인 **다음 메시지 예측과 같음**은 **다음 메시지 예측**의 모델을 사용합니다(기본값). 기능마다 다른 모델을 쓰려면 다른 모델을 고르세요. 예를 들어 자동 완성에는 더 빠른 모델을 고를 수 있습니다. 입력을 멈출 때마다 모델을 한 번 호출하므로 예측보다 토큰을 훨씬 많이 사용합니다. 빠르고 비용이 낮은 모델을 고르세요. 슬래시 명령, 파일 칩이 있는 메시지, 커서가 끝에 있지 않을 때는 실행되지 않습니다. Tether에서는 입력하는 동안 나머지 텍스트가 입력란 위에 표시됩니다. 탭하면 추가됩니다. | <a href="assets/features/typingCompletion.webp"><img src="assets/features/typingCompletion.webp" width="160" alt="스크린샷: 입력 중 자동 완성"></a> |
63
66
  | **프롬프트 개선** | <a id="feature-promptimprove"></a>대략적인 요청을 입력한 뒤 모델 메뉴 옆의 요술봉(**프롬프트 개선**)을 클릭하세요. 모델 호출 한 번으로 요청을 더 명확한 프롬프트로 다시 씁니다. 목표를 먼저 쓰고, 여러 부분이 있으면 짧은 번호 단계로 나누고, 실행할 검사를 적습니다. 이 채팅(되돌린 메시지 제외), 프로젝트의 README, AGENTS.md, 매니페스트, 변경된 파일, 이름이 입력한 단어와 일치하는 파일을 읽고, 사용 언어를 유지합니다. 파일 이름을 지어내지 않습니다. 새 텍스트가 초안을 대신하지만 보내지는 않습니다. 읽고 고친 뒤 `Enter`를 누르세요. `Cmd/Ctrl+Z`를 누르면 한 번에 원래 텍스트로 돌아오며, 버튼(**개선 실행 취소**)도 같습니다. 작업 중에 입력하면 새로 입력한 텍스트가 유지됩니다. `Esc`를 누르거나 한 번 더 클릭하면 취소됩니다. 설정에 전용 **모델** 메뉴가 있습니다(기본값: **채팅의 모델과 같음**). 슬래시 명령이나 파일 칩이 있는 메시지에는 쓸 수 없습니다. Tether에서는 요술봉이 입력란 옆에 있습니다. | <a href="assets/features/promptImprove.webp"><img src="assets/features/promptImprove.webp" width="160" alt="스크린샷: 프롬프트 개선"></a> |
64
67
  | **목표 확인** | <a id="feature-goalcheck"></a>`/goal`로 목표를 시작하세요. 에이전트가 자동 라운드에서 목표를 완료로 표시하면, 목표는 두 가지 확인을 통과해야만 닫힙니다. 먼저 프로젝트의 테스트 명령이 채팅 폴더에서 채팅의 샌드박스 모드로 실행됩니다. 명령은 직접 정한 명령이거나 `package.json`, `Makefile`, `Cargo.toml`, `go.mod` 또는 pytest에서 찾은 명령입니다. 에이전트 자신의 최신 단계가 그 테스트의 성공한 실행이었다면 다시 실행하지 않습니다. 그다음 도구가 없는 독립적인 모델 호출 한 번이 목표, 이 채팅, `git status`, 테스트 결과를 읽습니다. 확인에 실패하면 목표는 진행 중으로 남고, 에이전트가 이유를 읽은 뒤 다음 라운드가 이어집니다. 목표 바 아래의 행(**목표 확인**)에 테스트와 마지막 결과가 표시됩니다. **편집**에서 직접 테스트 명령과 시간 또는 토큰 제한을 정합니다. 제한을 넘으면 목표가 차단됩니다. **지금 실행**은 목표를 닫지 않고 확인을 실행합니다. 설정에 전용 **모델** 메뉴가 있습니다(기본값: **채팅의 모델과 같음**). 목표를 직접 완료하면 아무것도 확인하지 않습니다. | <a href="assets/features/goalCheck.webp"><img src="assets/features/goalCheck.webp" width="160" alt="스크린샷: 목표 확인"></a> |
68
+ | **프로젝트 메모리** | <a id="feature-projectmemory"></a>기본적으로 꺼져 있습니다. **설정 → Composer Plus**에서 켜세요. 프로젝트 폴더마다 자체 메모리가 있으며, 그 프로젝트의 이후 채팅이 읽습니다. DS Bot이 Bot마다 메모리를 두는 것과 같습니다. 턴이 끝날 때마다 채팅의 모델을 한 번 호출해 새 메시지(되돌린 메시지 제외)를 읽고, 오래 유지되는 선호, 결정, 사실을 짧은 메모로 저장하며, 오래된 메모를 바꾸거나 지웁니다. 에이전트도 직접 메모를 저장, 삭제, 검색할 수 있습니다(`memory_remember`, `memory_forget`, `memory_recall`). 메모는 전역일 수도 있으며, 이때는 모든 프로젝트가 읽습니다. 새 채팅은 시스템 프롬프트에서 메모를 받습니다. 나중에 저장한 메모는 다음 채팅부터 보입니다. 파일은 dsh 홈 폴더의 Markdown(`storages/dsh-composer-plus/memory/`)이며 프로젝트 폴더에는 절대 저장되지 않습니다. | <a href="assets/features/projectMemory.webp"><img src="assets/features/projectMemory.webp" width="160" alt="스크린샷: 프로젝트 메모리"></a> |
65
69
  | **이 채팅에서 허용** | <a id="feature-allowforchat"></a>자동 검토가 확인을 요청하면 승인 카드에 **이 채팅에서 허용**이 추가됩니다. 이후 같은 채팅의 같은 도구는 인수와 관계없이 시간 제한이 끝날 때까지 허용됩니다(기본값 1시간. **설정 → Composer Plus → 이 채팅에서 허용**에서 고릅니다). 그 후에는 에이전트가 다시 묻습니다. 헤더 칩에서 허용 목록과 종료 시각을 보고 취소할 수 있습니다. 허용은 재시작 후에도 유지됩니다. | <a href="assets/features/allowForChat.webp"><img src="assets/features/allowForChat.webp" width="160" alt="스크린샷: 이 채팅에서 허용"></a> |
66
- | **프로젝트 상태** | <a id="feature-projectstatus"></a>사이드바의 프로젝트 행에 그 채팅과 같은 실행 중 / 대기 중 / 완료 표시가 나타납니다. 그래서 접힌 프로젝트도 안의 채팅이 작업 중인지, 사용자의 조치가 필요한지 알려 줍니다. 사용자의 조치를 기다리는 채팅이 먼저 표시되고, 그다음 아직 열지 않은 완료된 채팅(초록색 점, 다른 채팅이 아직 실행 중일 때도 표시), 마지막으로 실행 중 표시가 나타납니다. 포인터를 올리면 자세한 내용이 보입니다. | <a href="assets/features/projectStatus.webp"><img src="assets/features/projectStatus.webp" width="160" alt="스크린샷: 프로젝트 상태"></a> |
67
- | **채팅 행의 Git 브랜치** | <a id="feature-sessionbranch"></a>사이드바의 각 채팅 행에 작은 회색 배지로, 채팅의 마지막 턴 때 채팅 프로젝트 폴더가 있던 git 브랜치가 표시됩니다(예: `main` 또는 `feature/login`. 분리된 HEAD는 짧은 커밋 ID를 괄호 안에 표시합니다). 한 프로젝트에서 서로 다른 브랜치에 있는 두 채팅이 더 이상 똑같아 보이지 않으며, 잘못된 브랜치에서 채팅을 이어 가려 할 때 바로 알 수 있습니다. 배지에 포인터를 올리면 전체 이름이 보입니다. Host 쪽은 턴이 시작될 때와 끝날 때 브랜치를 읽습니다(`git branch --show-current`, 읽기 전용). 이 기능을 설치한 뒤 턴이 없는 채팅이나 git 저장소가 아닌 폴더에는 배지가 표시되지 않습니다. | <a href="assets/features/sessionBranch.webp"><img src="assets/features/sessionBranch.webp" width="160" alt="스크린샷: 채팅 행의 Git 브랜치"></a> |
70
+ | **프로젝트 상태** | <a id="feature-projectstatus"></a>사이드바의 프로젝트 행에 그 채팅과 같은 실행 중 / 대기 중 / 완료 표시가 나타납니다. 그래서 접힌 프로젝트도 안의 채팅이 작업 중인지, 사용자의 조치가 필요한지 알려 줍니다. 사용자의 조치를 기다리는 채팅이 먼저 표시되고, 그다음 아직 열지 않은 완료된 채팅(초록색 점, 다른 채팅이 아직 실행 중일 때도 표시), 마지막으로 실행 중 표시가 나타납니다. 포인터를 올리면 자세한 내용이 보입니다. **작업 공간 트리**에서는 상위 폴더의 행에도 그 안에 있는 각 프로젝트(예: `.worktrees/` 안의 각 브랜치 폴더)의 채팅 상태가 표시되며, 폴더가 접혀 있을 때도 마찬가지입니다. | <a href="assets/features/projectStatus.webp"><img src="assets/features/projectStatus.webp" width="160" alt="스크린샷: 프로젝트 상태"></a> |
71
+ | **채팅 행의 Git 브랜치** | <a id="feature-sessionbranch"></a>사이드바의 각 채팅 행에 작은 회색 배지로, 채팅의 마지막 턴 때 채팅 프로젝트 폴더가 있던 git 브랜치가 표시됩니다(예: `main` 또는 `feature/login`. 분리된 HEAD는 짧은 커밋 ID를 괄호 안에 표시합니다). 한 프로젝트에서 서로 다른 브랜치에 있는 두 채팅이 더 이상 똑같아 보이지 않으며, 잘못된 브랜치에서 채팅을 이어 가려 할 때 바로 알 수 있습니다. 배지에 포인터를 올리면 전체 이름이 보입니다. Host 쪽은 턴이 시작될 때와 끝날 때 브랜치를 읽습니다(`git branch --show-current`, 읽기 전용). 이 기능을 설치한 뒤 턴이 없는 채팅이나 git 저장소가 아닌 폴더에는 배지가 표시되지 않습니다. 채팅 위의 프로젝트 행 이름이 브랜치와 같으면(예: “채팅별 브랜치” 폴더) 채팅 행에 배지가 표시되지 않지만, “하나의 목록”에서는 계속 표시됩니다. | <a href="assets/features/sessionBranch.webp"><img src="assets/features/sessionBranch.webp" width="160" alt="스크린샷: 채팅 행의 Git 브랜치"></a> |
68
72
  | **모두 읽음으로 표시** | <a id="feature-markprojectread"></a>사이드바에서 프로젝트의 **…** 버튼 → **모두 읽음으로 표시**를 클릭하세요. 그 프로젝트의 모든 채팅에서 초록색 읽지 않음 점이 한 번에 사라집니다. 다른 프로젝트의 점은 그대로 남습니다. 프로젝트에 읽지 않은 채팅이 없으면 이 항목은 회색으로 표시됩니다(**읽지 않은 채팅 없음**). | <a href="assets/features/markProjectRead.webp"><img src="assets/features/markProjectRead.webp" width="160" alt="스크린샷: 모두 읽음으로 표시"></a> |
69
73
  | **활성 프로젝트 우선** | <a id="feature-activeprojectsfirst"></a>채팅이 실행을 시작하거나 사용자의 조치가 필요해지면, 그 프로젝트가 dsh 자체 행 애니메이션으로 사이드바 맨 위로 이동합니다(직접 끌어 올릴 때와 같은 움직임). 완료된 프로젝트는 제자리에 남으며, 평소처럼 원하는 곳으로 끌어 옮길 수 있습니다. 이동은 dsh의 프로젝트 순서에 저장되므로, 이 기능을 꺼도 현재 순서가 유지됩니다. | <a href="assets/features/projectStatus.webp"><img src="assets/features/projectStatus.webp" width="160" alt="스크린샷: 활성 프로젝트 우선"></a> |
70
- | **최근 프로젝트 필터** | <a id="feature-recentprojects"></a>사이드바 → 보기 옵션(슬라이더 아이콘) → **최근 2시간 내 활성**. 이 옵션을 선택하면 사이드바에는 최근 2시간 안에 활성 채팅이 있었던 프로젝트만 표시됩니다. 활성 채팅은 그 시간 안에 업데이트된 채팅, 실행 중이거나 대기 중인 채팅, 열려 있는 채팅, 아직 열지 않은 완료된 채팅(dsh의 초록색 “완료” 점)입니다. 마지막 경우는 2시간이 지나도 해당됩니다. 이런 채팅이 없는 프로젝트는 숨겨지며, 새 프로젝트와 빈 프로젝트도 숨겨집니다. 모든 프로젝트를 다시 보려면 옵션을 다시 선택하세요. 선택은 이 기기에 저장됩니다. | <a href="assets/features/recentProjects.webp"><img src="assets/features/recentProjects.webp" width="160" alt="스크린샷: 최근 프로젝트 필터"></a> |
74
+ | **최근 프로젝트 필터** | <a id="feature-recentprojects"></a>사이드바 → 보기 옵션(슬라이더 아이콘) → **최근 2시간 내 활성**. 이 옵션을 선택하면 사이드바에는 최근 2시간 안에 활성 채팅이 있었던 프로젝트만 표시됩니다. 활성 채팅은 그 시간 안에 업데이트된 채팅, 실행 중이거나 대기 중인 채팅, 열려 있는 채팅, 아직 열지 않은 완료된 채팅(dsh의 초록색 “완료” 점)입니다. 마지막 경우는 2시간이 지나도 해당됩니다. 이런 채팅이 없는 프로젝트는 숨겨지며, 새 프로젝트와 빈 프로젝트도 숨겨집니다. **작업 공간 트리**에서는 안에 있는 프로젝트가 활성인 동안 상위 폴더가 계속 표시되고, 최근 2시간 안에 활성 상태가 아니었던 채팅도 숨겨지므로 최근 채팅만 표시됩니다. 모든 프로젝트를 다시 보려면 옵션을 다시 선택하세요. 선택은 이 기기에 저장됩니다. | <a href="assets/features/recentProjects.webp"><img src="assets/features/recentProjects.webp" width="160" alt="스크린샷: 최근 프로젝트 필터"></a> |
71
75
  | **모든 프로젝트 접기** | <a id="feature-collapseprojects"></a>사이드바에 열린 프로젝트가 있으면 보기 옵션(슬라이더 아이콘) 옆에 버튼이 나타납니다. 클릭하면 열린 프로젝트를 한 번에 모두 닫습니다. 예를 들어 프로젝트 5개 중 열린 3개를 한 번에 닫습니다. 열린 프로젝트가 없으면 버튼이 다시 숨겨집니다. | <a href="assets/features/collapseProjects.webp"><img src="assets/features/collapseProjects.webp" width="160" alt="스크린샷: 모든 프로젝트 접기"></a> |
72
76
  | **상태별 정렬** | <a id="feature-statusorder"></a>사이드바 → 보기 옵션 → **정렬 기준** → **상태별**(**하나의 목록**과 함께 사용). 완료된 채팅이 먼저 옵니다(dsh의 “완료” 점. 오류로 끝난 턴에도 이 점이 붙습니다). 그다음 실행 중이거나 대기 중인 채팅, 활성 자동화(예약)가 있는 채팅, 나머지 채팅이 dsh 순서대로 옵니다. 완료된 채팅을 열면 아래로 이동합니다. 보기만 바뀝니다. 원래대로 돌아가려면 **수동** 또는 **마지막 업데이트**를 선택하세요. | <a href="assets/features/statusOrder.webp"><img src="assets/features/statusOrder.webp" width="160" alt="스크린샷: 상태별 정렬"></a> |
73
77
  | **백그라운드 알림** | <a id="feature-notifications"></a>dsh가 백그라운드에 있을 때 턴이 끝나면(답변의 첫 줄과 함께) 알림을 받습니다. 채팅이 정말로 사용자를 기다릴 때도 알림을 받습니다. 기다리는 이유는 승인(도구 이름), 답변(질문), 계획 검토입니다. 요청이 1.5초 뒤에도 열려 있어야 알림이 갑니다. 그래서 자동으로 처리된 승인(자동 검토 허용, 다른 플러그인)은 알림을 보내지 않습니다. 요청에 답하면 알림도 바로 사라집니다. Dock/작업 표시줄 배지는 기다리는 채팅 수를 보여 줍니다. 알림을 클릭하면 그 채팅이 열립니다. | <a href="assets/features/notifications.webp"><img src="assets/features/notifications.webp" width="160" alt="스크린샷: 백그라운드 알림"></a> |
78
+ | **유휴 상태일 때 대기 중인 채팅 열기** | <a id="feature-idleswitch"></a>채팅이 질문을 하거나 승인 또는 계획 검토를 기다리고 있을 때(주황색 점) 30초 동안 dsh를 사용하지 않으면 dsh가 그 채팅을 엽니다. 여러 채팅이 기다리면 가장 오래 기다린 채팅이 먼저 열리고, 다음 채팅은 다시 30초 동안 사용하지 않으면 열립니다. 키 입력, 클릭, 마우스 이동, 스크롤 휠, 터치가 있으면 30초를 다시 셉니다. 포커스가 있는 입력란에 텍스트가 있거나, 텍스트를 선택했거나, 메뉴나 대화 상자가 열려 있어도 전환하지 않습니다. 기다리는 채팅이 화면에 있는 동안에는 아무것도 바뀌지 않습니다. 답하지 않고 기다리는 채팅을 떠나면, 다음에 30초 동안 사용하지 않을 때 그 채팅이 다시 열릴 수 있습니다. dsh가 백그라운드에 있을 때도 작동하지만, dsh가 앞으로 나오지는 않습니다. | <a href="assets/features/idleSwitch.webp"><img src="assets/features/idleSwitch.webp" width="160" alt="스크린샷: 유휴 상태일 때 대기 중인 채팅 열기"></a> |
74
79
  | **애플리케이션 언어** | <a id="feature-language"></a>설정 → Composer Plus → **애플리케이션 언어**에서 dsh 인터페이스 전체를 Türkçe, Español, Português (Brasil), Français, Deutsch, Русский, 日本語, 한국어, Bahasa Indonesia, Tiếng Việt, हिन्दी 중 하나로 바꿉니다(아래 참고). | <a href="assets/features/language.webp"><img src="assets/features/language.webp" width="160" alt="스크린샷: 애플리케이션 언어"></a> |
75
80
  | **모바일 연결(iPhone)** | <a id="feature-mobileconnect"></a>[Tether](tether/) 앱으로 iPhone에서 dsh를 사용하세요. 같은 Wi-Fi나 [Tailscale](https://tailscale.com)을 통해 연결합니다. **설정 → Composer Plus**에서 켜세요(이 Mac에서 네트워크 포트를 열기 때문에 기본적으로 꺼져 있습니다). 그다음 사이드바 왼쪽 아래의 **모바일 연결**을 클릭하세요. iPhone 카메라(**Open in Tether**를 탭)나 Tether의 **Scan code**로 QR 코드를 스캔하고, **Connect**를 탭한 뒤 **Approve**를 클릭하세요. 먼저 Tether를 설치하세요. Tether가 없으면 카메라가 이 코드를 열 수 없습니다. 휴대폰에서 채팅을 보고, 메시지를 보내고(사진 포함: 입력란의 **+** → Camera, Photos 또는 Paste image), 승인과 질문에 답하고, 모델과 에이전트를 바꿀 수 있습니다. Mac은 원하는 만큼 페어링할 수 있으며, 앱 왼쪽 위의 Mac 이름으로 Mac을 전환합니다. **모바일 연결** 패널에는 페어링된 iPhone이 마지막 연결 시각과 함께 표시되며, **Remove**를 누르면 그 iPhone의 연결이 즉시 끊깁니다. “Tailscale only”는 로컬 네트워크의 연결을 거부하고(공유 Wi-Fi용), 액세스 로그는 누가 연결을 시도했는지 보여 줍니다. Tether에서는 “Settings → Privacy”에서 Face ID로 앱을 잠급니다. | <a href="assets/features/mobileConnect.webp"><img src="assets/features/mobileConnect.webp" width="160" alt="스크린샷: 모바일 연결(iPhone)"></a> |
76
81
  | **자동 업데이트** | <a id="feature-autoupdate"></a>dsh가 시작되면 플러그인이 [최신 GitHub 릴리스](https://github.com/furkancak1r/dsh-composer-plus/releases/latest)를 확인합니다. 더 새로운 버전이고 npm에도 올라와 있으면, dsh 자체 플러그인 관리자(설정 → 플러그인과 같은 경로)로 정확히 그 버전을 설치하고 알려 줍니다. 새 버전을 로드하려면 dsh를 다시 시작하세요. **설정 → Composer Plus → Composer Plus 업데이트**에서 버전을 볼 수 있고, **업데이트 확인** / **지금 업데이트** 버튼도 있습니다. 새 버전으로 dsh를 처음 시작하면 **Composer Plus N의 새로운 기능** 창이 그 버전의 릴리스 노트를 한 번 보여 줍니다(같은 업데이트 확인에서 받은 내용이며 추가 네트워크 호출은 없습니다). **닫기** 또는 `Esc`로 닫습니다. | <a href="assets/features/autoUpdate.webp"><img src="assets/features/autoUpdate.webp" width="160" alt="스크린샷: 자동 업데이트"></a> |
82
+ | **백업** | <a id="feature-backup"></a>설정 → Composer Plus → **백업** → **지금 백업**은 dsh 홈 전체(채팅, 설정, 플러그인, MCP, 스킬)를 체크섬과 함께 `~/Desktop/dsh-backups`의 아카이브 하나에 씁니다. 아카이브에서 비밀 값은 마스킹됩니다. 자격 증명 파일, 키 파일(`.pem`, `.key`), yml 설정의 token, secret, password 값은 이 컴퓨터에만, 폴더의 `vault`에 남습니다. `cache/`, `dsh-runtimes/`, `node_modules`는 아카이브에 들어가지 않습니다(dsh가 다시 만듭니다). 목록의 각 백업에는 **검사**(끝까지 읽음), **다른 컴퓨터용**(새 컴퓨터로 복사할 폴더, 복구 콘솔 포함), **삭제**가 있습니다. 같은 폴더에 있는 dsh-backup의 아카이브도 표시되고 사용할 수 있습니다. 복원하려면 dsh를 종료하고 복구 콘솔을 사용하세요. | <a href="assets/features/backup.webp"><img src="assets/features/backup.webp" width="160" alt="스크린샷: 백업"></a> |
83
+ | **자동 백업** | <a id="feature-autobackup"></a>**자동 백업**을 켜세요(기본적으로 꺼져 있습니다. 각 사본은 캐시를 뺀 dsh 홈과 크기가 거의 같습니다). 얼마나 자주 백업할지(**간격**: 6시간에서 7일, 기본값 24시간)와 백업을 몇 개 남길지(**보관**: 3에서 14, 기본값 7)를 고르세요. 다음 백업 시각은 스위치 아래에 표시됩니다. 실패한 백업도 그곳에 표시되고, 30분 뒤에 다시 시도합니다. dsh나 Composer Plus가 새 버전으로 시작하면, 시작 직후 새 버전이 데이터를 오래 쓰기 전에 스냅샷을 만듭니다(가장 최신 두 개가 남고, **업그레이드 전**으로 표시됩니다). | <a href="assets/features/autoBackup.webp"><img src="assets/features/autoBackup.webp" width="160" alt="스크린샷: 자동 백업"></a> |
84
+ | **세션 로그 점검** | <a id="feature-sessiondoctor"></a>**세션 로그 검사**는 모든 채팅의 로그를 읽고, dsh가 열 수 없는 로그를 나열합니다(깨진 프레임, 잘린 레코드, 잘못된 시퀀스 번호). 마지막 부분만 덜 쓰인 로그는 나열되지 않습니다. dsh가 직접 고칩니다. **백업에서 복구**는 정상 사본이 있는 가장 최신 백업에서 사본을 되돌려 놓고, 손상된 파일은 그 옆에 보관합니다(`.corrupt-<시각>`). 그 백업 이후에 작성된 메시지는 사본에 없습니다. 이 dsh에서 열려 있는 채팅은 여기서 복구되지 않습니다. dsh를 종료하고 복구 콘솔에서 복구하세요. | <a href="assets/features/sessionDoctor.webp"><img src="assets/features/sessionDoctor.webp" width="160" alt="스크린샷: 세션 로그 점검"></a> |
85
+ | **복구 콘솔** | <a id="feature-rescueconsole"></a>백업할 때마다 백업 폴더에 복구 콘솔도 넣습니다. dsh가 닫혀 있거나 시작되지 않으면 그 폴더에서 `Composer Plus Rescue`를 여세요(macOS: `Composer Plus Rescue.command`). 터미널 창의 메뉴에서 백업을 나열, 검사, 복원하고 세션 로그를 검사, 복구할 수 있습니다. 네트워크 포트를 열지 않습니다. 복원할 때는 `RESTORE`를 입력해야 하며, 현재 dsh 홈을 `.dsh.pre-restore-<시각>`으로 남기고, 마스킹된 비밀 값을 vault에서 되돌려 놓고, `cache/`, `dsh-runtimes/`, `node_modules`를 이전 폴더에서 옮겨 옵니다. dsh 없이도 작동합니다. Node.js나 DeepSeek Harness 앱 자체를 사용합니다. 새 컴퓨터에서는 **다른 컴퓨터용** 폴더를 복사하고 그곳에서 `Composer Plus Rescue`를 여세요. | <a href="assets/features/rescueConsole.webp"><img src="assets/features/rescueConsole.webp" width="160" alt="스크린샷: 복구 콘솔"></a> |
77
86
 
78
87
  <!-- END GENERATED FEATURES -->
79
88
 
@@ -117,7 +126,7 @@ English · 中文 · Türkçe · Español · Português (Brasil) · Français ·
117
126
  | `Esc` | 예측이 표시된 빈 입력란 | 예측 숨기기 |
118
127
  | `Cmd/Ctrl+Z` | **프롬프트 개선**을 사용한 뒤의 입력란 | 입력한 텍스트 되돌리기 |
119
128
  | `Esc` | **프롬프트 개선**이 실행 중인 입력란 | 개선 취소 |
120
- | `Enter` / `Esc` | 더블클릭한 대기 중인 메시지 | 편집 저장 / 취소 |
129
+ | `Enter` / `Esc` | 대기 중인 메시지 편집기 | 편집 저장 / 취소 |
121
130
  | Mac에서는 `Cmd+F`, Windows와 Linux에서는 `Ctrl+F` | 열린 채팅 | **채팅에서 찾기** 열기 |
122
131
  | `Enter` / `Shift+Enter`, `↓` / `↑` | **채팅에서 찾기** 상자 | 다음 / 이전 일치 항목 |
123
132
  | `Esc` | **채팅에서 찾기** 상자 | 상자 닫기 |
@@ -151,6 +160,9 @@ dsh `0.2.0-rc.2`(데스크톱과 웹)와 `0.2.1-rc.2`(웹)에서 테스트했습
151
160
  - **입력 중 자동 완성:** 켜기 전까지 꺼져 있습니다. 켜져 있는 동안 입력을 멈출 때마다 Host 쪽은 지금까지 입력한 텍스트와, 그 채팅에서 사용자가 직접 보낸 메시지와 에이전트의 텍스트 답변(도구 출력, 숨은 컨텍스트, 추론 제외)을 채팅 기준 최대 약 3,000자까지 **입력 중 자동 완성**에서 고른 모델(기본값: **다음 메시지 예측**의 모델)에 보냅니다. 입력을 다시 멈추면 이전 요청은 중지됩니다. 채팅에는 아무것도 저장되지 않습니다. 스위치는 `$DSH_HOME/storages/dsh-composer-plus/complete.json`(소유자 전용 파일)에 보관됩니다.
152
161
  - **프롬프트 개선:** 요술봉을 클릭하기 전에는 아무것도 실행되지 않습니다. 클릭하면 Host 쪽은 초안, 그 채팅에서 사용자가 직접 보낸 메시지와 에이전트의 텍스트 답변(도구 출력, 숨은 컨텍스트, 추론, 되돌린 메시지 제외. 최대 약 6,000자, 가장 최근 부분), **기능 아이디어**와 같은 프로젝트 요약(파일 규칙도 같음: `.env*`나 키 파일 없음, 폴더 밖을 가리키는 심볼릭 링크 없음, FIFO 없음), `git status`가 변경됨으로 표시하는 경로, 이름에 초안과 같은 단어가 들어 있는 추적되거나 추적되지 않는(무시되지 않은) 경로 최대 30개를 **프롬프트 개선**에서 고른 모델(기본값: 채팅 자체의 모델)에 요청 한 번으로 보냅니다. 이 요약 외의 파일 내용은 보내지 않습니다. 채팅과 프로젝트에는 아무것도 쓰지 않습니다. 답변은 입력란의 초안을 바꿀 뿐이며, 보낼지는 사용자가 정합니다. 고른 모델은 `$DSH_HOME/storages/dsh-composer-plus/improve.json`(소유자 전용 파일)에 보관됩니다.
153
162
  - **목표 확인:** 에이전트가 자동 라운드에서 `/goal`을 완료로 표시할 때(또는 **지금 실행**을 클릭할 때)만 실행됩니다. Host 쪽은 테스트 명령을 채팅 폴더에서 채팅의 샌드박스 모드로 실행합니다(dsh 자체의 `bash` 도구와 같음: 같은 파일 접근 정책. 그 샌드박스를 시작할 수 없으면 테스트를 실행하지 않고 확인은 실패합니다). 명령을 찾으려고 `package.json`, `Makefile`, `Cargo.toml`, `go.mod`, `pyproject.toml`, `pytest.ini`만 폴더 안의 일반 파일로 읽습니다(폴더 밖을 가리키는 심볼릭 링크 없음, FIFO 없음). 그다음 목표, 목표가 시작된 뒤의 채팅(사용자의 메시지, 에이전트의 답변, 1,000자로 자른 도구 호출, 각 도구 결과의 마지막 2,000자. 추론과 되돌린 단계 제외. 최대 약 60,000자, 가장 최근 부분), `git status --short`, 테스트 출력의 끝부분을 **목표 확인**에서 고른 모델(기본값: 채팅 자체의 모델)에 도구 없는 요청 한 번으로 보냅니다. 도구 출력에는 에이전트가 읽은 내용이 들어 있을 수 있으므로, 채팅 자체와 마찬가지로 이 요청에 파일의 일부가 들어갈 수 있습니다. 채팅과 프로젝트에는 아무것도 쓰지 않습니다. 직접 정한 테스트 명령, 제한, 마지막 결과(출력의 끝부분 포함), 고른 모델은 `$DSH_HOME/storages/dsh-composer-plus/goal-check.json`(소유자 전용 파일, 최신 채팅 500개)에 보관됩니다.
163
+ - **프로젝트 메모리:** 직접 켜기 전까지는 꺼져 있습니다. 켜져 있는 동안 최상위 채팅의 턴이 끝날 때마다 Host 쪽이 지난 검토 이후 그 채팅의 새 메시지(사용자 메시지와 에이전트의 텍스트 답변. 도구 출력, 추론, 숨은 컨텍스트, 되돌린 메시지는 제외. 분기한 채팅에서는 부모 채팅의 복사본 제외. 최대 약 16,000자)와 저장된 메모를, 도구 없는 요청 한 번으로 채팅 자체의 모델에 보냅니다. 메모는 `$DSH_HOME/storages/dsh-composer-plus/memory/` 아래의 Markdown 파일(소유자만 읽고 쓸 수 있음)입니다. 프로젝트 폴더마다 `projects/<id>/`(`<id>`는 폴더 실제 경로의 해시이며, `project.json`에 폴더가 적힙니다), `global/`, `journal.jsonl`(각 변경과 변경 전후의 줄), `reviewed.json`(각 채팅을 어디까지 읽었는지)이 있습니다. 프로젝트 폴더에는 아무것도 쓰지 않습니다. 키, 토큰, 비밀번호, 신분증 번호처럼 보이는 메모는 거부합니다. 프로젝트의 메모는 그 폴더의 새 채팅마다 시스템 프롬프트에 들어가므로, 그 채팅의 모든 요청과 함께 모델에 전달됩니다. 스위치는 같은 위치의 `memory.json`에 있습니다.
164
+ - **백업:** 아무것도 컴퓨터 밖으로 나가지 않습니다. 아카이브는 `~/Desktop/dsh-backups`에 저장됩니다(소유자 전용 파일). 비밀 값은 아카이브에 들어가지 않습니다. 자격 증명 파일(`.credentials.yaml`, `.env`), 키 파일(`.pem`, `.key`, `.p12`, `.pfx`), yml 파일의 token, secret, password, API 키 설정 값은 마스킹되고, 실제 사본은 같은 폴더의 `composer-plus-vault/<archive>/`(소유자 전용)에, 이 컴퓨터에만 남습니다. **다른 컴퓨터용**은 vault를 복사하지 않습니다. 그 비밀 값은 새 컴퓨터에서 다시 입력하세요. 채팅 로그, 설정, dsh 홈의 나머지 내용은 그대로 아카이브에 들어갑니다. `$DSH_HOME` 자체처럼 이 폴더를 비공개로 두세요. 백업은 `O_NOFOLLOW | O_NONBLOCK`으로 파일을 읽습니다. 심볼릭 링크는 링크로 저장하고(따라가지 않음), FIFO나 장치는 건너뜁니다. 자동 백업 스위치와 설정은 `$DSH_HOME/storages/dsh-composer-plus/auto-backup.json`에, 복구 콘솔 스위치는 `rescue-console.json`에 있습니다. dsh가 실행되는 동안에는 `running/host-<pid>.json`이 각 dsh 프로세스를 나타냅니다(복구 콘솔은 이 파일들을 읽고 복원을 거부합니다).
165
+ - **복구 콘솔:** 터미널 메뉴이며, 네트워크 포트를 열지 않습니다. 복원은 dsh 홈 옆의 새 폴더에만 씁니다(파일은 `O_EXCL | O_NOFOLLOW`로 쓰고, 심볼릭 링크는 마지막에 만들며 따라가지 않음). 안전하지 않은 이름(`..`, 절대 경로), 장치나 FIFO, 둘 이상의 최상위 폴더, 링크 아래의 항목이 있는 아카이브는 거부합니다.
154
166
 
155
167
  ## 문제 해결
156
168
 
@@ -165,11 +177,15 @@ dsh `0.2.0-rc.2`(데스크톱과 웹)와 `0.2.1-rc.2`(웹)에서 테스트했습
165
177
  - **삭제할 때 다른 dsh가 이 채팅을 열고 있다고 표시됨:** 같은 dsh 홈을 쓰는 두 번째 dsh가 채팅 잠금을 잡고 있습니다. 그 창이나 dsh를 닫은 뒤 다시 삭제하세요. 그동안 채팅은 보관된 상태로 남습니다.
166
178
  - **"Tailscale only"를 켠 뒤 iPhone이 연결되지 않음:** Mac과 iPhone 모두에서 Tailscale이 켜져 있어야 합니다. Mac에서 꺼져 있으면 모바일 연결 패널에 경고가 표시됩니다. 액세스 로그에서 거부된 각 시도와 그 이유를 볼 수 있습니다.
167
179
  - **재시작 후 채팅이 이어지지 않음:** dsh를 종료할 때 재시작 후 이어서 실행이 꺼져 있었거나, 그 턴을 직접 중지했거나, 턴이 이미 끝났거나(완료 또는 실패), 채팅이 보관되었거나, 실행 중인 채팅이 20개보다 많았습니다(가장 최근 채팅 20개만 이어짐).
180
+ - **재시작 후 대기열이 비어 있음:** 대기열을 비우는 것은 dsh 자체의 종료입니다. 재시작 후 이어서 실행은 이어서 실행하는 채팅에서만 대기열을 되돌립니다. 다른 채팅에서는 메시지를 다시 보내세요. 종료 직전에 삭제한 메시지가 돌아올 수 있습니다. 그때는 다시 삭제하세요.
168
181
  - **GitHub 이슈 열기에 "gh could not open the issue"가 표시됨:** 이 메시지는 `gh` 자체 출력의 첫 줄입니다. 터미널에서 `gh auth status`를 실행하고 `gh auth login`으로 로그인하세요. 채팅 폴더에 GitHub 원격 저장소가 있어야 합니다(`git remote -v`). "not installed or not on the PATH of dsh"는 dsh가 `gh`를 찾지 못했다는 뜻입니다. 설치하거나, `gh`가 작동하는 터미널에서 dsh를 시작하세요.
169
182
  - **채팅 행에 브랜치 배지가 없음:** 이 버전을 설치한 뒤 그 채팅에 턴이 없었거나, 폴더가 git 저장소가 아니거나, **채팅 행의 Git 브랜치**가 꺼져 있습니다. 업데이트한 뒤에는 dsh를 다시 시작하세요(브랜치는 Host 쪽이 기록합니다).
170
183
  - **목표 확인에 테스트가 종료 코드 127 또는 "not found"로 끝났다고 표시됨:** Finder나 Dock에서 시작한 dsh는 터미널보다 PATH가 짧을 수 있어서 `npm`, `pnpm`, `cargo`를 찾지 못합니다. 터미널에서 dsh를 시작하거나, **목표 확인** → **편집**에서 전체 경로를 쓴 테스트 명령을 직접 정하세요. **지금 실행**을 누르면 결과가 바로 표시됩니다.
171
184
  - **목표가 닫히지 않고 에이전트가 계속 작업함:** **목표 확인**이 실패한 테스트나 남은 작업을 찾았습니다. 목표 아래의 행에 이유가 표시됩니다(자세한 내용은 결과에 포인터를 올려 보세요). 원인이나 테스트 명령을 고치거나, `/goal` 또는 목표 바로 목표를 직접 완료하세요(이 완료는 확인하지 않습니다).
172
- - **릴리스 직후 설치 실패:** 버전을 붙여서 설치하세요(`dsh-composer-plus@1.14.0`). 위의 설치 안내를 참고하세요.
185
+ - **릴리스 직후 설치 실패:** 버전을 붙여서 설치하세요(`dsh-composer-plus@1.16.0`). 위의 설치 안내를 참고하세요.
186
+ - **지금 백업에서 "다른 백업 작업이 실행 중입니다"라고 표시됨:** 다른 dsh 창이나 복구 콘솔에서 작업이 실행 중입니다(둘은 백업 폴더의 잠금 파일 `.composer-plus.lock`을 함께 씁니다). 작업이 끝날 때까지 기다리세요. 실행 중인 작업이 없으면, 다음에 클릭할 때 종료된 프로세스의 잠금을 넘겨받습니다.
187
+ - **복구 콘솔에 "dsh is running"이라고 표시됨:** 먼저 dsh를 종료하세요. dsh가 정말 닫혀 있다면, 메시지에 나온 파일은 비정상 종료로 남은 것입니다. 그 파일을 삭제하고 다시 시도하세요.
188
+ - **복원 후 dsh가 시작되지 않거나 플러그인이 없음:** 프로필의 플러그인 패키지를 다시 설치해야 합니다. 복구 콘솔이 복원 후에 이를 제안합니다. 또는 콘솔이 나열하는 `$DSH_HOME/profiles/` 아래의 각 폴더에서 `pnpm install`을 실행하세요. vault에 없던 비밀 값(다른 컴퓨터)은 다시 입력해야 합니다. 콘솔이 그 목록을 보여 줍니다.
173
189
 
174
190
  ## 제한 사항
175
191
 
@@ -177,6 +193,7 @@ dsh `0.2.0-rc.2`(데스크톱과 웹)와 `0.2.1-rc.2`(웹)에서 테스트했습
177
193
  - **기능 아이디어**는 dsh나 페이지를 다시 로드할 때까지 채팅마다 카드를 메모리에 둡니다. 그 뒤 **기능 제안**은 모델에 다시 묻습니다. 카드는 클릭한 시점의 dsh UI 언어로 나옵니다. 언어를 바꿔도 이미 쌓인 카드는 원래 언어를 유지하고, **아이디어 더 받기**는 새 언어를 씁니다. 모델은 코드가 아니라 짧은 프로젝트 요약만 봅니다. 그래서 프로젝트에 이미 있는 기능을 제안할 수도 있습니다. 그럴 때는 건너뛰세요. 새 채팅은 프로필에 dsh의 `/plan` 명령이 있을 때만 계획 모드로 실행됩니다. 없으면 아이디어가 일반 첫 메시지로 전달됩니다. **나중에** 목록은 채팅의 폴더 경로에 속합니다. 같은 폴더를 심볼릭 링크로 열면 별도 목록이 생깁니다. 프로젝트당 최대 50개 아이디어를 보관하며(더 추가하려면 하나를 제거하세요), 같은 제목은 한 번만 보관합니다. 카드를 끌면 왼쪽 또는 오른쪽만 결정됩니다. 저장하려면 **↓**를, 바로 구현하려면 **▶**를 쓰세요. 반복은 제목으로만 찾습니다. 그래서 모델이 이전 아이디어를 새 이름으로 다시 제안할 수 있습니다. 그럴 때는 건너뛰세요. 모델이 이전 아이디어만 답하면 새로 보이는 것이 없습니다. 다시 클릭하세요. 집중 주제가 좁으면 이런 일이 더 자주 생깁니다. 더 넓은 주제를 쓰거나 주제를 지우세요. 집중 주제는 dsh나 페이지를 다시 로드할 때까지 채팅마다 입력란에 남아 있습니다.
178
194
  - **채팅을 Markdown으로 내보내기**에는 사용자 자신의 메시지와 어시스턴트의 텍스트 답변만 들어갑니다. 도구 호출과 그 출력, 생각, 이미지(`[image]` 줄로 표시됩니다), 숨겨진 컨텍스트, 턴 되돌리기나 dsh-rewind-plugin로 뺀 메시지는 빠집니다. 한 턴의 답변은 섹션 하나로 합쳐집니다. 내보내기 한 번에는 최대 약 400만 자가 들어갑니다. 더 긴 채팅은 앞부분과 안내 문구만 내보냅니다.
179
195
  - **재시작 후 이어서 실행**은 턴을 이어 갈 뿐, 처음부터 다시 실행하지 않습니다. 종료 시점에 실행 중이던 도구 호출은 dsh의 “결과 알 수 없음” 결과로 끝납니다. 모델에게는 끝난 작업을 반복하지 말라고 알리지만, 두 번 실행하면 안전하지 않은 명령이 다시 실행될 수 있습니다. 열려 있던 하위 에이전트, 승인, 질문은 복원되지 않습니다. 대신 부모 채팅이 이어지면서 다시 묻습니다. 한 번 시작할 때 최대 20개 채팅만 이어집니다.
196
+ - **재시작 후 이어서 실행**과 대기열: dsh는 종료할 때 채팅의 대기열을 비웁니다. 플러그인은 대기 중이던 메시지를 채팅 로그에서 되돌리며, 순서, 편집 내용, 이미지와 파일도 그대로입니다. 되돌린 메시지는 이어서 실행한 턴 다음에 실행됩니다. 대기열이 돌아오는 채팅은 이어서 실행되는 채팅뿐입니다(스위치가 켜져 있고 턴 실행 중에 종료된 경우). dsh는 대기열의 마지막 메시지를 직접 삭제한 것도 같은 방식으로 기록합니다. 삭제한 뒤 다음 단계가 시작되기 전에 dsh가 종료되면 그 메시지가 돌아옵니다.
180
197
 
181
198
  - **내용 검색**은 dsh 자체 검색이므로 dsh의 제한을 그대로 가집니다. 사용자와 어시스턴트 메시지만 검색합니다. 도구 출력(명령, 파일 내용, 결과)과 추론은 검색하지 않으며, 사용자, 어시스턴트, 도구 메시지를 고르는 필터도 없습니다. 단어 일부가 아니라 단어 전체가 일치해야 합니다(`deploy`로는 `deployment`를 찾을 수 없음). 악센트가 있는 글자는 악센트 없이도 일치합니다(`seker`로 `şeker`를 찾음). 채팅마다 한 행에 dsh의 240자 발췌가 표시되며, 최대 20행입니다.
182
199
  - **내용 검색**의 비용은 실제 채팅 로그 247개의 사본으로 측정했습니다(159 MB, dsh 0.2.1-rc.2, Apple Silicon, 32 GB). 시작 후 첫 검색에서 약 15초 동안 색인을 만듭니다. 그중 약 7초 동안 dsh의 Host가 아무 응답도 하지 않으므로, 다른 채팅의 스트리밍이 그 순간 멈춥니다(페이지 자체는 멈추지 않습니다). Host의 메모리는 최고 약 1.1 GB 늘어납니다. 1분 뒤에도 시작 때보다 약 0.5–0.6 GB 많은 상태가 dsh를 종료할 때까지 유지됩니다. 색인 파일은 약 165 MB입니다. 이후 검색은 약 0.5초 걸립니다. 재시작 후 첫 검색은 약 1초 걸리고(새 채팅이나 바뀐 채팅만 추가) 메모리가 약 70 MB 늘어납니다. 컴퓨터 메모리가 적다면 이 기능을 끄세요.
@@ -187,19 +204,25 @@ dsh `0.2.0-rc.2`(데스크톱과 웹)와 `0.2.1-rc.2`(웹)에서 테스트했습
187
204
  - 새 버전이 dsh 설정을 하나도 바꾸지 않으면 dsh 0.2.1은 업데이트를 바로 로드합니다. 그 밖의 경우와 dsh 0.2.0에서는 업데이트를 로드하려면 dsh를 다시 시작하세요. 플러그인은 dsh를 대신 재시작하지 않습니다. dsh 플러그인 관리자가 없는 웹/CLI 프로필은 새 버전을 알리기만 합니다.
188
205
  - **이 채팅에서 허용**은 허용한 순간부터 시간 제한을 셉니다. 새 시간 제한은 유효한 허용에 즉시 적용되므로, 더 짧은 시간 제한은 허용을 즉시 끝낼 수 있습니다. 버전 1.12 이하의 허용에는 시간 정보가 없습니다. 업데이트 후 에이전트가 그 도구들에 대해 한 번 더 묻습니다.
189
206
  - **입력란 포커스 유지**는 `/` 명령이나 스킬을 보낸 뒤에만 포커스를 돌려줍니다. dsh가 명령을 처리하는 몇 밀리초 동안 입력란이 읽기 전용이므로, 그동안 누른 키는 사라집니다. dsh의 `/` 메뉴가 아직 열려 있으면 `Enter`는 강조된 행을 선택하고 메시지를 보내지 않습니다.
190
- - **모바일 연결**은 macOS에서만 작동합니다(`en0`, `openssl`, `swift`, `dns-sd` 사용). 고정 포트 19390과 19391을 쓰므로, Mac마다 한 번에 dsh 하나에서만 실행할 수 있습니다(각 Mac은 휴대폰의 Mac 목록에서 항목 하나입니다). 휴대폰은 Tether가 열려 있거나 막 백그라운드로 간 동안에만 알림을 받습니다(푸시 서비스 없음). iOS 앱은 아직 App Store에 없습니다. Xcode로 `tether/ios`에서 빌드하세요. "Tailscale only"를 켜도 Mac에 Wi-Fi 또는 이더넷 주소가 있어야 합니다(게이트웨이는 그런 주소가 있을 때만 시작됩니다). 액세스 로그는 Mac마다 따로 있으며, 가장 최근의 시도 200개만 보관합니다. 1분 안에 반복된 시도는 새 행을 만들지 않고 같은 행의 횟수를 하나 늘립니다. Tether의 앱 잠금은 iPhone 잠금 화면의 알림 미리보기를 숨기지 않습니다. iOS 설정에서 끄세요. Tether의 초록 점은 Mac을 따릅니다. dsh에서 연 채팅은 휴대폰에서도 점이 사라집니다. Tether에서 연 채팅은 휴대폰에서만 점이 사라집니다. Mac에 있는 dsh 자체의 점은 Mac에서 그 채팅을 열 때까지 남습니다.
207
+ - **질문 카드를 창에 맞추기**는 dsh의 질문 카드만 바꾸고 계획 검토 카드는 바꾸지 않습니다. 카드는 dsh의 마크업(`data-question-key`, `data-question-scroll`)으로 찾습니다. dsh 업데이트로 이 마크업이 바뀌면 카드는 dsh가 그리는 대로 보입니다. 카드 높이는 채팅이 아니라 창을 따릅니다. 좁은 사이드 패널 안의 채팅에서는 높은 카드가 채팅 위로 넘칠 수 있습니다.
208
+ - **모바일 연결**은 macOS에서만 작동합니다(`en0`, `openssl`, `swift`, `dns-sd` 사용). 고정 포트 19390과 19391을 쓰므로, Mac마다 한 번에 dsh 하나에서만 실행할 수 있습니다(각 Mac은 휴대폰의 Mac 목록에서 항목 하나입니다). 휴대폰은 Tether가 열려 있거나 막 백그라운드로 간 동안에만 알림을 받습니다(푸시 서비스 없음). Tether에서 "Settings → Notifications → Send notifications"를 켜기 전에는 Tether가 알림을 보내지 않습니다. 이 설정은 기본적으로 꺼져 있으며, 켤 때 iOS가 권한을 요청합니다. iOS 앱은 아직 App Store에 없습니다. Xcode로 `tether/ios`에서 빌드하세요. "Tailscale only"를 켜도 Mac에 Wi-Fi 또는 이더넷 주소가 있어야 합니다(게이트웨이는 그런 주소가 있을 때만 시작됩니다). 액세스 로그는 Mac마다 따로 있으며, 가장 최근의 시도 200개만 보관합니다. 1분 안에 반복된 시도는 새 행을 만들지 않고 같은 행의 횟수를 하나 늘립니다. Tether의 앱 잠금은 iPhone 잠금 화면의 알림 미리보기를 숨기지 않습니다. iOS 설정에서 끄세요. Tether의 초록 점은 Mac을 따릅니다. dsh에서 연 채팅은 휴대폰에서도 점이 사라집니다. Tether에서 연 채팅은 휴대폰에서만 점이 사라집니다. Mac에 있는 dsh 자체의 점은 Mac에서 그 채팅을 열 때까지 남습니다.
191
209
  - 세션 링크는 채팅 안에서 작동하지만, 클릭해도 채팅이 열리지는 않습니다. **메시지 링크 복사**로 만든 링크는 dsh 0.2.1 이상에서만, 그리고 채팅 안의 메시지에서만 그 메시지를 엽니다(dsh 0.2.0에는 사용자 텍스트 규칙이 없으므로, 링크는 복사되지만 일반 텍스트로 보입니다). 되돌리기로 빠진 메시지나, 압축으로 dsh가 불러오는 기록에서 빠진 메시지는 보여 줄 수 없습니다. 이때 링크가 그렇다고 알려 줍니다. 🔗 버튼은 dsh의 메시지 행에 붙습니다. dsh 업데이트로 그 마크업이 바뀌면 버튼이 표시되지 않습니다.
192
210
  - **모두 읽음으로 표시**는 공개 API가 아닌 dsh의 일부(dsh 세션 상태의 `completionUnread` 목록)를 통해 dsh 자체의 읽지 않음 점을 바꿉니다. dsh 업데이트로 이 이름이 바뀌면 항목이 표시되지 않습니다. 이 항목은 dsh의 프로젝트 "…" 메뉴에 들어가는데, 이 메뉴에는 플러그인용 슬롯이 없습니다. dsh가 이 메뉴를 바꾸면 이 항목도 표시되지 않습니다.
193
- - **대기 중인 메시지 제자리 편집**은 dsh 자체의 대기열 편집기를 열므로 그 제한도 따릅니다. 이미지나 파일이 있는 메시지는 편집할 수 없고, 그사이 전송이 시작된 메시지는 바뀌지 않습니다(dsh가 자체 오류를 표시합니다).
211
+ - **대기 중인 메시지 제자리 편집**은 그사이 전송이 시작된 메시지를 바꾸지 않고, 그사이 바뀐 메시지(예: iPhone의 Tether에서 바꾼 메시지)를 덮어쓰지 않으며, 알림으로 이를 알려 줍니다. 새 이미지에는 이미지를 받는 모델이 필요하고(dsh 자체의 이미지 제한이 적용됩니다), 새 파일은 업로드가 끝나야 저장할 수 있습니다. 내 대기 중인 메시지만 편집할 수 있고, 대기열의 목표 라운드나 질문에 대한 답변은 편집할 수 없습니다. 플러그인을 업데이트한 뒤에는 텍스트만 바꾸는 편집만 바로 되며, 이미지나 파일이 있는 메시지를 저장하려면 먼저 dsh를 다시 시작해야 합니다(Host 쪽은 시작할 때 로드됩니다).
194
212
  - **다시 실행**은 되돌린 채팅을 절대 바꾸지 않습니다. 되돌리기 직전 시점부터 새 채팅을 시작하므로(dsh 자체 포크, 같은 모델 컨텍스트), 새 채팅은 새 ID와 제목을 가집니다. 채팅의 가장 최근 되돌리기만, 한 번만, 그리고 그 뒤에 아무것도 없을 때만 다시 실행할 수 있습니다(새 메시지를 보내면 이 선택지가 사라집니다). 되돌린 뒤 내가 바꾼 파일은 덮어쓰기 상자를 체크하지 않는 한 유지됩니다. 다시 실행에는 되돌리기가 보관한 스냅샷이 필요합니다(같은 50개 범위). 이 버전 이전에 한 되돌리기나 **채팅만**으로 한 되돌리기는 메시지만 다시 가져옵니다.
213
+ - **트리** 브랜치 맵은 각 화살표가 어디로 가는지 추측합니다. git은 브랜치가 어느 브랜치로 병합되었는지 저장하지 않기 때문입니다. 병합된 브랜치는 병합 커밋으로 그 브랜치를 처음 받아들인 브랜치를 가리킵니다. 대기 중인 브랜치는 그 브랜치가 시작된 가장 가까운 브랜치(메인 브랜치 우선)를 가리킵니다. 두 브랜치가 같은 커밋에서 시작되었으면 맵이 잘못된 브랜치를 고를 수 있습니다. fast-forward로 앞으로 이동한 브랜치에는 병합 커밋이 없으므로, 그 브랜치의 **병합됨** 라벨을 클릭해도 아무것도 열리지 않습니다. 메인 브랜치는 `origin`의 기본 브랜치이고, 없으면 `main` 또는 `master`, 그것도 없으면 열려 있는 브랜치입니다. 맵은 최신 커밋 20,000개를 읽고 브랜치를 최대 60개까지 보여 줍니다. 기록이 더 길면 일부 화살표가 틀릴 수 있다고 알려 줍니다. squash나 rebase로 병합한 브랜치(예: GitHub에서)는 **대기 중**으로 표시됩니다. git이 그 커밋과의 연결을 저장하지 않기 때문입니다.
195
214
  - **이 채팅**은 dsh의 파일 도구(`write`, `edit`, `str_replace_editor`)가 쓴 파일만 셉니다. 명령(`bash`)이 바꾼 파일은 이 보기에 없고, **커밋 안 됨**에 표시됩니다. 채팅의 턴 되돌리기 스냅샷이 없으면(턴 되돌리기 꺼짐, dsh-rewind-plugin 설치됨, 또는 플러그인보다 오래된 채팅) 보기는 마지막 커밋과 비교하고 그렇다고 알려 줍니다. 턴 되돌리기는 채팅마다 최신 스냅샷 50개를 보관합니다. 더 긴 채팅에서는 보기가 보관된 가장 오래된 스냅샷과 비교하고, 어느 메시지부터인지 알려 주며, 그 이전의 변경은 세지 않습니다. **공백 변경 숨기기**는 `git diff -w`입니다. 줄 안의 공백만 바뀐 줄도 숨겨집니다.
196
215
  - **GitHub 이슈 열기**에는 dsh의 PATH에 있는 GitHub CLI(`gh`)와 채팅 폴더의 GitHub 원격 저장소가 필요합니다. 최대 60초 동안 실행됩니다. `gh`가 더 오래 걸리면, 이슈가 GitHub에는 만들어졌지만 목록에는 링크가 없을 수 있습니다(다시 클릭하기 전에 GitHub를 확인하세요. 목록은 끝난 실행에서만 링크를 읽으므로, 다시 클릭하면 두 번째 이슈가 열릴 수 있습니다). GitHub 원격 저장소가 둘 이상인 폴더는 `gh` 자체의 기본값(`gh repo set-default`)을 씁니다.
197
216
  - **이 파일을 변경한 채팅**은 **이 채팅**처럼 dsh의 파일 도구(`write`, `edit`, `str_replace_editor`)만 압니다. 명령(`bash`)으로 만든 변경은 목록에 나오지 않습니다. 저장소의 최신 채팅 300개(만든 시점 기준)를 읽고, 더 있으면 그렇다고 알려 줍니다. 최대 100행을 보여 줍니다. 이름이 바뀐 파일은 도구가 쓴 이름으로 표시됩니다. 폴더가 저장소 밖에 있는 채팅(같은 파일로 가는 다른 경로를 통한 경우도 포함)은 세지 않습니다. dsh를 시작한 뒤 처음 열 때는 저장소의 모든 채팅 로그를 읽습니다(채팅 275개에 약 4초). 그 뒤로 열 때는 그 이후에 바뀐 채팅만 읽습니다.
198
- - **채팅 행의 Git 브랜치**는 현재 브랜치가 아니라, 마지막 턴이 시작되거나 끝날 때 채팅 폴더가 있던 브랜치를 보여 줍니다. 턴 밖에서 브랜치를 바꾸면 다음 턴 뒤에 표시됩니다. 이 버전 이전의 채팅에는 다음 턴까지 배지가 표시되지 않습니다. 배지는 dsh의 채팅 행 마크업 안에 들어갑니다(dsh에는 그곳에 슬롯이 없습니다). dsh 업데이트로 그 마크업이 바뀌면 배지가 표시되지 않습니다.
217
+ - **채팅 행의 Git 브랜치**는 현재 브랜치가 아니라, 마지막 턴이 시작되거나 끝날 때 채팅 폴더가 있던 브랜치를 보여 줍니다. 턴 밖에서 브랜치를 바꾸면 다음 턴 뒤에 표시됩니다. 이 버전 이전의 채팅에는 다음 턴까지 배지가 표시되지 않습니다. 배지는 dsh의 채팅 행 마크업 안에 들어갑니다(dsh에는 그곳에 슬롯이 없습니다). dsh 업데이트로 그 마크업이 바뀌면 배지가 표시되지 않습니다. 채팅 위의 프로젝트 행 이름이 브랜치와 같으면(예: “채팅별 브랜치” 폴더) 채팅 행에 배지가 표시되지 않지만, “하나의 목록”에서는 계속 표시됩니다.
218
+ - **채팅별 브랜치**를 계획 모드에서 쓸 때: dsh는 `/plan <메시지>`를 메시지가 아니라 명령으로 보냅니다. 그래서 Composer Plus가 dsh 입력란에서 명령 전송을 가로챕니다(공개 API가 아님). dsh 업데이트로 이것이 바뀌면, **새 브랜치**를 고른 상태의 `/plan <메시지>`는 열린 새 채팅에서 dsh 자체 명령으로 실행됩니다. Host가 새 채팅에서 계획 모드를 켜지 못하면 브랜치 폴더는 남고 메시지는 보내지지 않습니다. 따라서 새 채팅이 기본 모드에서 파일을 바꾸지 않습니다.
219
+ - **채팅별 브랜치**: 채팅의 브랜치 폴더(`<project>/.worktrees/<name>`)가 삭제되면(예: 채팅 자신의 에이전트가 worktree를 제거하고 브랜치를 삭제할 때) 채팅의 다음 단계에서 채팅이 그 폴더 밖으로 옮겨집니다. 브랜치 폴더의 프로젝트는 사이드바에서 사라지고, 채팅은 그룹 없음 아래에 표시되며 열린 상태로 유지됩니다. dsh 0.2.1 이상에서는 채팅이 프로젝트의 기본 폴더에서 계속되고, 모델은 새 폴더에 대한 안내를 받습니다. dsh 0.2.0에서는 채팅이 삭제된 폴더를 그대로 사용합니다. 그곳에서 실행하는 명령은 새 채팅을 시작할 때까지 실패합니다. 이동은 채팅의 다음 단계에서만 일어나므로, 어떤 채팅도 사용하지 않는 삭제된 브랜치의 프로젝트는 사이드바에 남습니다. dsh의 프로젝트 메뉴로 제거하세요. 채팅이 옮겨지는 동안 같은 저장소의 **새 브랜치**는 "다시 시도하세요"라고 답합니다. 스위치를 끄면 dsh 자체 오류("working-directory: directory does not exist")가 다시 표시됩니다.
220
+ - **작업 공간 트리의 브랜치**은(는) 클릭 없이 git에 씁니다. 채팅을 옮길 때 프로젝트 폴더를 이전 브랜치로 되돌리고(`git switch`) worktree를 추가합니다(`git worktree add`). 브랜치, worktree, 파일은 절대 삭제하지 않습니다. dsh는 채팅의 폴더를 바꿀 수 없으므로, 옮겨진 채팅은 복사본(새 id를 가진 dsh 자체 포크)이고 이전 채팅은 보관됩니다. 복사본은 멈춘 작업을 이어서 합니다. 브랜치가 생겼을 때 실행 중이던 도구 호출은 거부로 끝나고, 에이전트는 새 폴더에서 그것을 다시 실행합니다. 이전 채팅의 목표는 함께 옮겨지지 않습니다. 폴더가 저장소의 메인 폴더인 채팅만 옮겨지며, 그 턴에서 만들고 전환한 브랜치(`git switch -c`, `git checkout -b`)일 때만 옮겨집니다. `git branch`만으로 만든 브랜치, 커밋되지 않은 변경이 있는 폴더, 연결된 worktree, 하위 폴더는 아무것도 옮기지 않습니다. 트리에는 `<project>/.worktrees/` 바로 아래에 있고 브랜치가 있는 worktree만 표시됩니다. 분리된(detached) worktree나 다른 위치의 worktree는 표시되지 않습니다. 복사본은 원래 채팅이 열려 있던 채팅일 때만 저절로 열립니다(플러그인은 dsh의 사이드바 행에서 이를 읽습니다). 그 외에는 브랜치 프로젝트에 있습니다.
199
221
  - **채팅에서 찾기**는 페이지가 보여 주는 것만 검색합니다. 불러온 메시지와 답변이 대상이며(이전 것은 위로 스크롤하거나 **이전 기록 로드**를 클릭하세요), 닫힌 도구 단계와 도구 출력 안의 접힌 텍스트는 검색하지 않습니다. 일치 항목은 최대 2,000개까지 셉니다(그 뒤에는 "2000+"). 브라우저의 하이라이트 API를 씁니다(Chromium 105 이상, 데스크톱 앱에는 있습니다). 더 오래된 브라우저에서는 개수와 이동은 작동하지만 색은 표시되지 않습니다. Mac에서는 `Cmd+F`(Windows와 Linux에서는 `Ctrl+F`)가 화면에 채팅이 있을 때만 이것을 엽니다. 다른 곳에서는 브라우저 자체의 찾기가 전처럼 작동합니다. Mac에서 `Ctrl+F`는 텍스트 필드에서 macOS 기능(커서를 한 글자 앞으로 이동)을 그대로 유지합니다.
222
+ - **유휴 상태일 때 대기 중인 채팅 열기**는 dsh 창이 보는 동작만 압니다. 다른 앱에서 하는 작업은 세지 않으므로, dsh가 백그라운드에 있으면 30초 뒤에 대기 중인 채팅을 열 수 있습니다. dsh를 앞으로 가져오지는 않습니다. 키 입력, 클릭, 마우스 이동 없이 읽기만 하면 유휴 상태로 봅니다. dsh의 주황색 점이 있는 채팅(질문, 승인, 계획 검토)만 봅니다. 서브에이전트의 요청은 부모 채팅에 표시됩니다. 기다리는 채팅이 화면에 있는 동안에는 다른 채팅을 열지 않습니다. 답하지 않고 떠난 채팅은 다음에 30초 동안 사용하지 않으면 다시 열릴 수 있습니다. 30초는 바꿀 수 없습니다.
200
223
  - 재시작 전에 보낸 알림을 클릭하면 dsh를 앞으로 가져오기만 합니다.
201
224
  - 활성 프로젝트는 dsh에 저장되는 프로젝트 순서로 이동하므로, 새 순서는 재시작 후에도 유지됩니다. 어느 프로젝트에도 속하지 않은 채팅("그룹 없음")은 이동할 수 없습니다. dsh는 이 채팅을 항상 맨 마지막에 나열합니다.
202
- - dsh의 사이드바 보기 옵션 메뉴에는 확장 지점이 없습니다. 그래서 최근 프로젝트 옵션은 dsh 자체 메뉴에 추가됩니다. dsh 업데이트로 이 메뉴가 바뀌면 옵션이 표시되지 않고 모든 프로젝트가 계속 보입니다. 필터는 프로젝트 행에 적용되므로 **하나의 목록**은 걸러지지 않습니다. **작업 공간**과 함께 쓰세요. **작업 공간 트리**에서는 숨겨진 상위 폴더가 그 안의 활성 프로젝트도 숨깁니다. **상태별**에도 같은 종류의 제한이 있습니다. dsh에는 정렬 슬롯이 없으므로, 항목과 행 순서가 dsh의 메뉴와 목록 마크업에 붙습니다.
225
+ - dsh의 사이드바 보기 옵션 메뉴에는 확장 지점이 없습니다. 그래서 최근 프로젝트 옵션은 dsh 자체 메뉴에 추가됩니다. dsh 업데이트로 이 메뉴가 바뀌면 옵션이 표시되지 않고 모든 프로젝트가 계속 보입니다. 필터는 프로젝트 행에 적용되므로 **하나의 목록**은 걸러지지 않습니다. **작업 공간 트리**에서는 안에 있는 프로젝트가 활성인 동안 상위 폴더도 계속 보이고, 최근 2시간 동안 활성이 아니었던 채팅 행도 숨겨집니다. **작업 공간**에서는 프로젝트 행만 걸러집니다. 필터는 dsh가 저장한 보기 설정(공개 API가 아님)에서 지금 어떤 보기인지 읽습니다. dsh 업데이트로 그 이름이 바뀌면 **작업 공간 트리**는 **작업 공간**처럼 걸러집니다. 프로젝트 상태도 같은 설정을 읽습니다. **작업 공간 트리**에서는 상위 폴더 행이 그 안에 있는 프로젝트의 채팅도 셉니다. dsh가 이 설정의 이름을 바꾸면 각 행은 자기 채팅만 표시합니다. **상태별**에도 같은 종류의 제한이 있습니다. dsh에는 정렬 슬롯이 없으므로, 항목과 행 순서가 dsh의 메뉴와 목록 마크업에 붙습니다.
203
226
  - dsh에는 프로젝트 행 메뉴나 작업 공간 헤더 슬롯도 없습니다. **경로 복사**는 dsh의 행 마크업으로 프로젝트 행을 찾습니다. **모든 프로젝트 접기**는 dsh 헤더에 들어가서, 프로젝트 행을 클릭하는 것과 같은 방식으로 열린 프로젝트를 하나씩 닫습니다. dsh 업데이트로 이 마크업이 바뀌면 오른쪽 클릭 시 브라우저 메뉴가 나오고 버튼은 표시되지 않습니다.
204
227
  - dsh에는 새 채팅의 프로젝트 메뉴에도 확장 지점이 없습니다. 그래서 **프로젝트 검색** 상자와 A–Z 순서는 dsh의 메뉴 마크업에 붙습니다. dsh 업데이트로 이 마크업이 바뀌면 메뉴는 dsh가 그리는 그대로 표시됩니다. 즉, 저장된 순서로 표시되고 검색 상자는 없습니다. A–Z 순서는 보기일 뿐이며, dsh에 저장된 프로젝트 순서를 바꾸지 않습니다.
205
228
  - dsh에는 **새 세션**를 열 위치를 고르는 확장 지점도 없습니다. **새 세션의 기본 작업 공간**은 공개 API가 아닌 dsh 메서드(dsh 작업 공간 서비스의 `startSession`)를 감쌉니다. dsh 업데이트로 이 이름이 바뀌면 **새 세션**는 dsh가 고른 위치(열린 프로젝트 또는 최근 프로젝트)에서 열립니다. 프로젝트를 지정하지 않는 모든 호출이 기본값을 사용합니다: 사이드바 버튼, 그 단축키, 로고, 그리고 **자동화 작업** 페이지의 **새로 만들기**도 마찬가지입니다. dsh는 시작할 때 여전히 마지막 채팅을 엽니다. 일반 폴더는 처음 사용할 때 만들어지고 프로젝트에 추가됩니다. Windows나 Linux에서 Documents 폴더를 옮겼다면 dsh 자체 폴더와 다른 폴더일 수 있습니다.
@@ -207,6 +230,12 @@ dsh `0.2.0-rc.2`(데스크톱과 웹)와 `0.2.1-rc.2`(웹)에서 테스트했습
207
230
  - **입력 중 자동 완성**은 dsh 자체의 입력란 힌트(dsh가 슬래시 명령의 인수 힌트에 쓰는 `--dsh-composer-hint` 스타일)로 텍스트를 표시합니다. 슬래시 명령, 파일 칩이나 기호 칩이 있는 메시지, 커서가 메시지 끝에 있지 않을 때는 실행되지 않습니다. dsh 업데이트로 이 스타일이 바뀌면 완성 텍스트가 표시되지 않습니다. 입력을 멈출 때마다 모델 호출이 한 번 일어납니다.
208
231
  - **프롬프트 개선**은 짧은 프로젝트 요약, 변경된 경로, 이름이 입력한 단어와 일치하는 경로만 보며, 코드 자체는 보지 않습니다. 그래서 맞는 파일을 놓칠 수 있고, 전달받은 경로만 언급합니다. 보내기 전에 새 텍스트를 읽어 보세요. 슬래시 명령이나 파일 칩이나 기호 칩이 있는 메시지에서는 실행되지 않습니다(새 텍스트는 일반 텍스트라서 칩이 사라지기 때문입니다). 메시지는 최대 8,000자까지 가능합니다. 이미지는 그대로 첨부되어 있고, 텍스트만 바뀝니다. 클릭할 때마다 모델 호출이 한 번 일어나며, 성능이 높은 모델은 1분쯤 걸릴 수 있습니다(`Esc`로 취소).
209
232
  - **목표 확인**은 에이전트가 자동 목표 라운드에서 한 완료만 확인합니다. 채팅에서 사용자가 요청한 완료, `/goal`, 목표 바는 확인하지 않습니다. 에이전트는 테스트나 테스트 명령의 파일을 스스로 바꿀 수 있습니다. 검증 모델은 채팅을 읽으므로 이를 알아챌 수 있지만, 양쪽 방향으로 틀릴 수 있습니다(잘못된 "완료되지 않음"은 라운드를 한 번 더 쓰고, 잘못된 "완료"는 목표를 닫습니다). 검증 모델은 채팅과 `git status`를 보며, 코드 자체는 보지 않습니다. 테스트 실행은 파일을 바꿀 수 있는 에이전트의 최신 단계가 같은 폴더에서 정확히 같은 명령을 성공적으로 실행한 에이전트 자신의 `bash` 실행일 때만 재사용합니다. 파이프(`| tail`)나 `&&`가 있는 명령은 재사용하지 않습니다. 예산은 턴이 끝날 때 측정하므로, 한 턴이 예산을 넘을 수 있습니다. 채팅 자체의 모델 호출만 셉니다(하위 에이전트의 호출은 세지 않음). 확인이 실행되는 동안 `update_goal`은 기다립니다(테스트는 최대 15분, 검증은 최대 3분). 포크한 채팅은 새 채팅 ID를 받으므로, 부모 채팅 자체의 테스트 명령과 제한 없이 시작합니다. 검증까지 간 완료마다 모델 호출이 한 번 일어납니다.
233
+ - **중지 후 보낸 메시지 먼저 실행**은 채팅을 중지한 뒤에만 동작합니다(또는 실패한 턴 뒤, 아직 대기열이 있는 채팅을 열 때). 턴이 실행되는 중에 보낸 메시지는 여전히 대기열 끝에서 기다립니다. 내가 대기열에 넣은 메시지만 앞지릅니다. 대기열에 목표 라운드나 질문 답변이 기다리고 있으면 dsh 자체 순서가 유지됩니다. 공개 API가 아닌 dsh의 일부(중지된 턴이 아직 끝나는 중인지)를 읽습니다. dsh 업데이트로 그 이름이 바뀌면, 메시지는 그 턴이 끝난 뒤에만 앞으로 옮겨집니다. 서브에이전트 채팅은 dsh 자체 순서를 유지합니다.
234
+ - **프로젝트 메모리**는 채팅의 첫 폴더(dsh의 프로젝트 폴더)에 속합니다. `cd`로 폴더를 바꾼 채팅은 첫 프로젝트의 메모리를 계속 씁니다. 같은 파일로 가는 다른 경로로 연 같은 폴더는 메모리를 공유합니다. 채팅은 시작할 때 메모리 섹션을 고정하므로, 나중에 저장한 메모는 다음 채팅부터 보입니다(`memory_recall`은 바로 찾습니다). 검토는 모델이 남기기로 정한 것만 남깁니다. 사실을 놓치거나 틀린 것을 남길 수 있으니, 파일을 열어 확인하고 dsh가 닫혀 있을 때 직접 고치거나 지우세요. 사용자 메시지가 있는 턴이 끝날 때마다 모델 호출이 한 번 듭니다. 호출이 실패하면 다음 턴 뒤에 같은 메시지를 다시 읽습니다. 서브에이전트 채팅은 검토하지 않습니다. 아이디어와 파일 형식은 [DS Bot](https://github.com/Fei2411/DS-Bot)(Apache-2.0)에서 왔습니다. Composer Plus는 그 코드를 쓰지 않으며, DS Bot 자체의 메모리를 읽거나 쓰지 않습니다.
235
+ - **백업**은 고정된 폴더 하나, `~/Desktop/dsh-backups`만 씁니다(dsh-backup의 기본 폴더이므로 그 아카이브도 계속 쓸 수 있습니다). 다른 폴더를 고르는 설정은 없습니다. 아카이브 크기는 `cache/`와 `dsh-runtimes/`를 뺀 dsh 홈과 거의 같습니다(측정: Apple Silicon에서 1.6 GB의 파일이 약 30초 만에 830 MB 아카이브가 되었고, 그동안 dsh는 계속 응답했습니다). 읽는 동안 바뀐 파일은 백업이 그 파일을 열었을 때의 상태로 저장됩니다. 그래서 열려 있는 채팅의 로그가 잘린 레코드로 끝날 수 있으며, dsh가 다음에 쓸 때 이를 복구합니다. 마스킹은 yml 파일의 비밀 값을 한 줄에 있는 키 이름(`token:`, `apiKey:`, …)으로 찾습니다. 플로 맵(`{token: x}`) 안, 그런 키 아래의 목록 안, JSON 파일 안(예: `.json` 파일에 있는 MCP 서버의 `apiKey`), 또는 다른 이름 아래에 있는 비밀 값은 아카이브에 남습니다. dsh-backup의 유형별 아카이브(`dsh-t-…`)는 목록에 나오지 않습니다. **다른 컴퓨터용**은 아카이브를 복사합니다(APFS에서는 클론이므로 추가 공간이 들지 않음). vault는 함께 복사되지 않습니다. **지금 백업**은 어떤 백업도 삭제하지 않습니다. 자동 백업은 Composer Plus가 만든 최신 백업을 보관하고(**자동 백업**의 **보관** 설정), 자신이 만든 더 오래된 백업을 삭제합니다. 업그레이드 전 스냅샷은 따로 셉니다(최신 2개가 남음). dsh-backup의 아카이브는 삭제되지 않습니다. **삭제**로 지우세요. dsh-backup이 아직 설치되어 있으면, dsh-backup은 Composer Plus 아카이브를 자기 보관 개수에 포함하며 그 아카이브를 삭제할 수 있습니다.
236
+ - **복원**은 dsh가 닫혀 있을 때 복구 콘솔에서만 실행되며, dsh 홈 전체를 바꿉니다. 기존 홈은 직접 삭제할 때까지 옆에 `.dsh.pre-restore-<time>`으로 남으므로, 디스크에 둘 다 들어갈 공간이 필요합니다. 채팅은 프로젝트 경로를 그대로 유지합니다. 다른 컴퓨터에서 다른 경로에 있는 프로젝트는 다시 추가할 때까지 없는 것으로 표시됩니다. dsh 홈 밖을 가리키는 심볼릭 링크(예: 다른 폴더에서 링크한 스킬)는 링크로 돌아오며, 그 대상은 그 컴퓨터에 있어야 합니다.
237
+ - **세션 로그 점검**은 무엇이 열리는지에 대한 dsh 자체 규칙으로 각 채팅의 최신 로그를 읽습니다. JSON이 아니거나 순서가 어긋난 행은 그 뒤에 턴 종료가 있을 때만 손상으로 칩니다(그렇지 않으면 dsh는 그 행부터의 내용을 빼고 채팅을 열기 때문에 목록에 나오지 않습니다). 로그의 이벤트를 dsh 자체의 이벤트 규칙과 비교하지는 않으므로, 정상으로 판정한 로그도 dsh 업그레이드 후에 열리지 않을 수 있습니다. 복구는 백업에서 사본을 가져옵니다. 그 백업 이후의 메시지는 그 채팅에서 사라집니다(손상된 파일은 옆에 남음). 이 dsh에서 열려 있는 채팅은 설정에서 복구되지 않습니다. dsh가 그 채팅을 잡고 있기 때문입니다.
238
+ - **자동 백업**은 dsh가 실행 중일 때만 실행됩니다. dsh가 닫혀 있는 동안 예정되었던 백업은 다음 시작 후 약 45초 뒤에 실행됩니다. 새 버전의 스냅샷은 업데이트 전이 아니라 그 시작 후에 만들어집니다.
210
239
  - 기본 지원은 업스트림에 요청해 두었습니다: 대기열 `move`는 [#773](https://github.com/deepseek-ai/deepseek-harness/discussions/773), 계속 상태는 [#9269](https://github.com/deepseek-ai/deepseek-harness/discussions/9269).
211
240
 
212
241
  ## 자주 묻는 질문
@@ -235,9 +264,19 @@ dsh `0.2.0-rc.2`(데스크톱과 웹)와 `0.2.1-rc.2`(웹)에서 테스트했습
235
264
 
236
265
  **loop engineering의 검증 루프처럼, 에이전트가 자기 작업을 스스로 완료로 표시하지 못하게 할 수 있나요?** 네, **목표 확인**(기본적으로 켜짐)으로 가능합니다. `/goal`로 목표를 시작하세요. 에이전트가 목표를 완료했다고 하면 프로젝트의 테스트가 실행되고, 독립적인 모델 호출이 채팅과 비교해 목표를 확인합니다. 둘 중 하나라도 실패하면 목표는 열린 상태로 남고 에이전트가 이유를 읽습니다. 목표 아래의 **목표 확인** 행에 있는 **편집**으로 직접 테스트 명령, 시간 제한, 토큰 제한을 정하세요.
237
266
 
267
+ **DS Bot의 메모리처럼 에이전트가 채팅이 바뀌어도 내 선호를 기억할 수 있나요?** 네, **프로젝트 메모리**(기본적으로 꺼짐)로 가능합니다. **설정 → Composer Plus**에서 켜세요. 턴이 끝날 때마다 오래 유지되는 선호와 결정이 채팅 프로젝트의 짧은 메모로 저장되고, 그 프로젝트의 새 채팅마다 이를 읽습니다. 에이전트에게 무언가를 기억하라고 하면 바로 저장합니다.
268
+
269
+ **dsh-backup처럼 dsh에서 채팅과 설정을 백업할 수 있나요?** 네. **설정 → Composer Plus → 백업 → 지금 백업**을 사용하세요. 같은 아카이브 형식으로 같은 폴더(`~/Desktop/dsh-backups`)에 쓰므로, dsh-backup의 아카이브도 표시되고 복원할 수 있으며, dsh-backup은 삭제해도 됩니다. 정해진 일정으로 백업하려면 **자동 백업**을 켜세요.
270
+
271
+ **dsh가 더 이상 시작되지 않습니다. 백업을 어떻게 복원하나요?** 백업 폴더(`~/Desktop/dsh-backups`)를 열고 `Composer Plus Rescue.command`를 더블클릭하세요(Linux: `composer-plus-rescue.sh`, Windows: `Composer Plus Rescue.cmd`). `3) Restore a backup`을 선택하고, 백업 하나를 고른 뒤 `RESTORE`를 입력하세요. dsh 없이도 작동합니다.
272
+
273
+ **dsh를 새 컴퓨터로 옮기려면 어떻게 하나요?** 기존 컴퓨터에서: 백업 옆에 있는 **백업** → **다른 컴퓨터용**. 그 폴더를 새 컴퓨터에 복사하고, 그곳에 dsh를 설치한 뒤 종료하세요. 그다음 복사한 폴더에서 `Composer Plus Rescue`를 열고 복원하세요. API 키는 다시 입력하세요(API 키는 기존 컴퓨터에 남습니다).
274
+
275
+ **비정상 종료 후 채팅이 열리지 않습니다. 복구할 수 있나요?** **설정 → Composer Plus → 세션 로그 점검 → 세션 로그 검사**. 손상된 채팅은 **백업에서 복구**로 최신 백업에서 되돌릴 수 있습니다(그 백업 이후의 메시지는 사라집니다).
276
+
238
277
  **dsh에서 대기 중인 메시지의 순서를 바꾸려면 어떻게 하나요?** 대기 중인 메시지의 ⠿ 핸들을 끌거나, 핸들에 포커스를 두고 `↑` / `↓`를 누르세요.
239
278
 
240
- **대기 중인 메시지의 오타를 고치려면 어떻게 하나요?** 대기열에서 메시지를 두 번 클릭하고, 텍스트를 고친 뒤 `Enter`를 누르세요(`Esc`는 취소). 메시지는 대기열에서 제자리를 유지합니다.
279
+ **대기 중인 메시지의 오타를 고치려면 어떻게 하나요?** 대기열에서 메시지를 두 번 클릭하고, 텍스트를 고친 뒤 `Enter`를 누르세요(`Esc`는 취소). 메시지는 대기열에서 제자리를 유지합니다. 그곳에서 이미지와 파일을 제거하거나 새로 추가할 수도 있습니다.
241
280
 
242
281
  **프로젝트의 읽지 않음 점을 한 번에 모두 지우려면 어떻게 하나요?** 사이드바 → 프로젝트의 **…** 버튼 → **모두 읽음으로 표시**.
243
282
 
@@ -265,13 +304,17 @@ dsh `0.2.0-rc.2`(데스크톱과 웹)와 `0.2.1-rc.2`(웹)에서 테스트했습
265
304
 
266
305
  **dsh 작업이 끝나거나 승인이 필요할 때 macOS / Windows 알림을 받으려면 어떻게 하나요?** **백그라운드 알림**을 켜 두세요(기본값). 그리고 OS 설정에서 DeepSeek Harness의 알림을 허용하세요.
267
306
 
307
+ **dsh가 질문하는 채팅을 스스로 열 수 있나요?** 네, **유휴 상태일 때 대기 중인 채팅 열기**(기본으로 켜짐)를 사용하세요. 채팅이 답변, 승인, 계획 검토를 기다리고 있을 때 30초 동안 dsh를 사용하지 않으면 dsh가 그 채팅을 엽니다. 입력하거나 스크롤하거나 마우스를 움직이는 동안에는 기다립니다.
308
+
268
309
  **DeepSeek Harness 인터페이스를 터키어, 스페인어, 일본어 등으로 바꾸려면 어떻게 하나요?** 설정 → Composer Plus → **애플리케이션 언어**.
269
310
 
270
311
  **iPhone에서 dsh를 쓰려면 어떻게 하나요?** `tether/ios`에서 Tether 앱을 빌드하세요(Xcode). **설정 → Composer Plus → 모바일 연결(iPhone)**을 켜고, 왼쪽 아래의 **모바일 연결**을 클릭하세요. QR 코드를 스캔하고(iPhone 카메라 또는 Tether의 **Scan code**), **Connect**를 탭한 뒤 **Approve**를 클릭하세요. 집 밖에서는 두 기기 모두에서 Tailscale을 쓰세요.
271
312
 
272
313
  **새 세션를 항상 같은 프로젝트에서 열려면 어떻게 하나요?** 설정 → Composer Plus → **새 세션의 기본 작업 공간** → **새 세션을 열 위치** → 프로젝트를 선택합니다. 다른 프로젝트 옆의 `+`는 계속 그 프로젝트를 엽니다.
273
314
 
274
- **한 프로젝트의 여러 기능을 각각 자기 브랜치에서 동시에 진행하려면 어떻게 하나요?** **채팅별 브랜치**를 쓰세요. 새 채팅 → ⑂ main 버튼 → **새 브랜치**를 고른 뒤 첫 메시지를 보내세요. 채팅마다 자체 브랜치와 worktree 폴더가 생기고, `.worktreeinclude`에 나열되어 있으면 `.env`와 `node_modules`도 함께 복사됩니다. 채팅 헤더에 현재 브랜치가 표시됩니다.
315
+ **한 프로젝트의 여러 기능을 각각 자기 브랜치에서 동시에 진행하려면 어떻게 하나요?** **채팅별 브랜치**를 쓰세요. 새 채팅 화면의 브랜치 버튼에는 기본으로 **새 브랜치**가 표시됩니다. 첫 메시지를 보내세요. 채팅마다 자체 브랜치와 worktree 폴더가 생기고, `.worktreeinclude`에 나열되어 있으면 `.env`와 `node_modules`도 함께 복사됩니다. 채팅 헤더에 현재 브랜치가 표시됩니다.
316
+
317
+ **사이드바에 프로젝트의 각 브랜치를 보여 주고, 에이전트가 브랜치를 만들면 채팅을 옮길 수 있나요?** 네, **작업 공간 트리의 브랜치**(기본값은 꺼짐)으로 가능합니다. 설정 → Composer Plus에서 켜고, dsh의 **보기 옵션** → **작업 공간 트리**를 선택하세요. `<project>/.worktrees/`에 worktree가 있는 각 브랜치가 해당 프로젝트 안에 표시됩니다. 프로젝트 폴더의 에이전트에게 브랜치를 만들고 거기서 작업하라고 요청했을 때 폴더에 커밋되지 않은 변경이 없으면, 채팅이 저절로 그 브랜치로 옮겨집니다. 브랜치의 폴더를 삭제하면 목록에서 사라지고, 그 채팅은 **그룹 없음**로 이동합니다.
275
318
 
276
319
  **iPhone에서 사진을 보낼 수 있나요?** 네. Tether 채팅에서 메시지 입력란 옆의 **+** → Camera, Photos(최대 4장) 또는 Paste image를 탭하세요. 사진은 메시지의 첨부 파일로 Mac의 채팅에 전달되므로 모델이 볼 수 있습니다.
277
320
 
@@ -287,6 +330,7 @@ PLAYWRIGHT=/path/to/playwright node scripts/capture-screenshots.mjs /path/to/dsh
287
330
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-sidebar-projects.mjs /path/to/dsh/lib/bin.js
288
331
  # recent filter + a finished chat older than 2 hours (fake model): the project stays until you open the chat
289
332
  PLAYWRIGHT=/path/to/playwright node test/browser-recent-finished.mjs /path/to/dsh/lib/bin.js
333
+ PLAYWRIGHT=/path/to/playwright node test/browser-recent-tree.mjs /path/to/dsh/lib/bin.js
290
334
  # Order by status (fake model + Schedule): real-app test + its thumbnail
291
335
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-status-order.mjs /path/to/dsh/lib/bin.js
292
336
  # every Settings feature row shows a loading screenshot and a ? link to its README row
@@ -297,10 +341,14 @@ PLAYWRIGHT=/path/to/playwright node test/browser-whats-new.mjs /path/to/dsh/lib/
297
341
  PLAYWRIGHT=/path/to/playwright node test/browser-readme-anchors.mjs
298
342
  # Keep composer focus (fake model + demo skill): typing goes on after a / command + its thumbnail
299
343
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-keep-focus.mjs /path/to/dsh/lib/bin.js
344
+ # Fit question card to window (fake model asks a long question at 1280 × 820): question, answers, Skip and Submit readable, height follows the window + its thumbnail
345
+ SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-question-fit.mjs /path/to/dsh/lib/bin.js
300
346
  # Mobile connect: switch on, QR popover, a fake iPhone pairs and calls dsh through the gateway, switch off + its thumbnail
301
347
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-mobile-connect.mjs /path/to/dsh/lib/bin.js
302
348
  # Resume after restart (fake slow model, real quit and start): a running chat and a goal continue, a stopped chat does not
303
349
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-resume-restart.mjs /path/to/dsh/lib/bin.js
350
+ # Resume after restart with a queue (fake model, real quit and start): text, image, file, a drag and an edit come back in order
351
+ PLAYWRIGHT=/path/to/playwright node test/browser-resume-queue.mjs /path/to/dsh/lib/bin.js
304
352
  # Feature ideas (fake model, made-up project): suggest, drag left, Undo, ✓ starts a new chat in plan mode, ▶ Build now one without, Plan all one for the Later list, a focus topic chip, Copy as checklist + its thumbnail
305
353
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-feature-ideas.mjs /path/to/dsh/lib/bin.js
306
354
  # Export chat as Markdown (fake model, made-up project): right-click → Export as Markdown…, copy and save keep the code blocks, switch off + its thumbnail
@@ -315,8 +363,10 @@ SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-prompt-improve.mjs /path
315
363
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-goal-check.mjs /path/to/dsh/lib/bin.js
316
364
  # Mark all as read, Copy message link, Edit queued message in place, Redo, Changes → This chat and Hide whitespace (fake model, made-up git projects) + their thumbnails
317
365
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-six-features.mjs /path/to/dsh/lib/bin.js
318
- # Changes Tree (fake model, made-up git history): branch list, a branch's commits, commit files and diffs, back marks the row + its thumbnail
366
+ # Changes Tree (fake model, made-up git history): the branch map (counts, colors, arrows), a branch's commits, commit files and diffs, Merged and Waiting files, back marks the box + its thumbnail
319
367
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-changes-tree.mjs /path/to/dsh/lib/bin.js
368
+ # Branches in the workspace tree (fake model, made-up git project): a worktree becomes a project, the agent's new branch moves the chat, a deleted folder leaves the tree + its thumbnail
369
+ SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-branch-tree.mjs /path/to/dsh/lib/bin.js
320
370
  # Allow for this chat with a time limit (fake model that is also the Auto Review reviewer): the grant ends after 1 hour
321
371
  PLAYWRIGHT=/path/to/playwright node test/browser-grant-ttl.mjs /path/to/dsh/lib/bin.js
322
372
  # Next message prediction and Complete while typing (fake models): calls, Tab, Esc, model choice + their thumbnails
@@ -327,6 +377,9 @@ SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-project-picker.mjs /path
327
377
  # Queue drag-and-drop and Continue with a queued message (slow fake model)
328
378
  PLAYWRIGHT=/path/to/playwright node test/browser-queue-drag.mjs /path/to/dsh/lib/bin.js
329
379
  PLAYWRIGHT=/path/to/playwright node test/browser-continue-queue.mjs /path/to/dsh/lib/bin.js
380
+ SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-queue-stop-send.mjs /path/to/dsh/lib/bin.js
381
+ # Edit queued message in place with images and files (slow fake model) + its thumbnail
382
+ SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-queue-edit.mjs /path/to/dsh/lib/bin.js
330
383
  ```
331
384
 
332
385
  ```sh