dsh-composer-plus 1.19.0 → 1.20.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
@@ -14,7 +14,7 @@
14
14
 
15
15
  <p align="center"><img src="docs/images/hero.webp" width="820" alt="Composer Plus를 사용하는 DeepSeek Harness: 실행 중인 프로젝트는 사이드바에 회전 표시가 나타나고, 변경 사항 패널은 git diff를 보여 줍니다"></p>
16
16
 
17
- 비공식 커뮤니티 플러그인입니다. 네트워크 호출은 업데이트 확인(GitHub 릴리스와 npm 레지스트리)뿐입니다. 시작할 때 이 호출을 막으려면 **자동 업데이트**를 끄세요. **기능 아이디어**는 **기능 제안**을 클릭할 때만 채팅 자체의 모델을 호출합니다. **다음 메시지 예측**(기본값: 켜짐)은 턴이 끝날 때마다 설정에서 고른 모델(다른 모델을 고르지 않으면 dsh의 기본 모델)을 클릭 없이 한 번 호출합니다. 이 호출을 막으려면 **설정 → Composer Plus**에서 끄세요. **입력 중 자동 완성**(기본값: 꺼짐)은 사용자가 켠 뒤에 입력을 멈출 때마다 이 기능에서 고른 모델(기본값: 예측의 모델)을 호출합니다. **프롬프트 개선**은 요술봉을 클릭할 때만 모델을 호출합니다. **작업 보드**는 보드에서 시작한 각 작업의 태그를 만들 때 새 채팅의 모델을 한 번 호출합니다. **목표 확인**(기본값: 켜짐)은 에이전트가 자동 라운드에서 `/goal`을 완료로 표시할 때마다 모델을 한 번 호출합니다. **모바일 연결**(기본값: 꺼짐)은 사용자가 켠 뒤에만 로컬 네트워크나 tailnet에서 오는 iPhone 연결을 받습니다.
17
+ 비공식 커뮤니티 플러그인입니다. 네트워크 호출은 업데이트 확인(GitHub 릴리스와 npm 레지스트리)뿐입니다. 시작할 때 이 호출을 막으려면 **자동 업데이트**를 끄세요. **기능 아이디어**는 **기능 제안**을 클릭할 때만 채팅 자체의 모델을 호출합니다. **다음 메시지 예측**(기본값: 켜짐)은 턴이 끝날 때마다 설정에서 고른 모델(다른 모델을 고르지 않으면 dsh의 기본 모델)을 클릭 없이 한 번 호출합니다. 이 호출을 막으려면 **설정 → Composer Plus**에서 끄세요. **입력 중 자동 완성**(기본값: 꺼짐)은 사용자가 켠 뒤에 입력을 멈출 때마다 이 기능에서 고른 모델(기본값: 예측의 모델)을 호출합니다. **프롬프트 개선**은 요술봉을 클릭할 때만 모델을 호출합니다. **작업 보드**는 보드에서 시작한 각 작업의 태그를 만들 때 새 채팅의 모델을 한 번 호출합니다. **AI 요약** 설정에서는(기본값은 **빠름(AI 없음)**) 보드나 Tether에서 실행 중인 작업의 진행 상황을 볼 때 짧은 진행 메모를 위해 그 채팅의 모델도 호출합니다. **목표 확인**(기본값: 켜짐)은 에이전트가 자동 라운드에서 `/goal`을 완료로 표시할 때마다 모델을 한 번 호출합니다. **모바일 연결**(기본값: 꺼짐)은 사용자가 켠 뒤에만 로컬 네트워크나 tailnet에서 오는 iPhone 연결을 받습니다.
18
18
 
19
19
  ## 설치
20
20
 
@@ -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.19.0`.
32
+ > dsh의 pnpm은 게시된 지 24시간이 지나지 않은 버전을 건너뜁니다. 릴리스 직후에는 버전을 붙여서 설치하세요: `dsh-composer-plus@1.20.0`.
33
33
 
34
34
  ## 기능
35
35
 
@@ -71,7 +71,7 @@ dsh plugin --profile web add dsh-composer-plus
71
71
  | **계획된 단계** | <a id="feature-plannedsteps"></a>기본적으로 꺼져 있습니다. **설정 → Composer Plus**에서 켜세요. 에이전트는 `plan_next_steps` 도구를 받습니다. 명령과 같은 메시지에서 다음 명령을 정확한 인수와 조건과 함께 계획할 수 있습니다(예: “빌드가 통과하면 `npm test` 실행”). 결과가 조건을 충족하면 Composer Plus가 새 모델 호출 없이 다음 단계를 직접 실행하므로 긴 채팅의 토큰 사용량이 줄어듭니다. 단계는 채팅에 “Composer Plus · Planned steps: ran `test` … without a model call”이라는 짧은 줄로 표시되고, 그 뒤에 도구 호출과 결과가 이어집니다. `bash`, `read`, `grep`, `glob` 단계만 해당되며 승인, 샌드박스, 보호된 파일은 각 단계에 평소처럼 적용됩니다. 조건이 맞지 않을 때, 두 단계가 동시에 준비될 때, 마지막 단계 뒤, 그리고 메시지를 보낼 때 모델이 다시 답합니다. 이 아이디어는 HarnessMM(arXiv 2610.32813)에서 왔습니다. | <a href="assets/features/plannedSteps.webp"><img src="assets/features/plannedSteps.webp" width="160" alt="스크린샷: 계획된 단계"></a> |
72
72
  | **보호된 파일** | <a id="feature-protectedfiles"></a>기본적으로 켜져 있습니다. 에이전트 자체의 파일 도구는 지정한 패턴과 일치하는 파일을 읽거나 바꿀 수 없습니다. **읽기와 쓰기** 패턴에서는 파일에 대한 `read`, `read_image`, `grep`이 거부되고, 두 종류 모두에서 `write`, `edit`, `str_replace_editor`가 거부됩니다. 에이전트는 이유를 읽고 사용자에게 물어보라는 안내를 받습니다. 기본 패턴은 `.env*`, `*.pem`, `*.key`입니다. 설정 → Composer Plus → **보호된 파일**: 패턴을 추가하고(예: `published/**` 또는 `config/*.yml`), 종류를 클릭해 **읽기와 쓰기**와 **쓰기만** 사이에서 전환하고, ✕로 삭제하거나 **기본값 사용**을 클릭하세요. `/`가 없는 패턴은 모든 폴더의 파일 이름과 일치합니다. 이것은 가드레일이며 샌드박스가 아닙니다. 셸 명령(`cat .env`), 스크립트, MCP 도구는 여전히 파일에 접근할 수 있습니다(제한 사항 참고). | <a href="assets/features/protectedFiles.webp"><img src="assets/features/protectedFiles.webp" width="160" alt="스크린샷: 보호된 파일"></a> |
73
73
  | **차단된 명령** | <a id="feature-blockedcommands"></a>기본적으로 켜져 있으며, 목록은 비어 있습니다. 에이전트의 셸 명령(`bash`, `pwsh`)은 지정한 규칙과 일치하는 명령을 실행할 수 없습니다. **차단** 규칙은 호출을 거부하고(에이전트는 이유를 읽고 사용자에게 물어보라는 안내를 받습니다), **먼저 묻기** 규칙은 dsh의 승인 카드를 표시하며, 명령은 사용자가 허용할 때만 실행됩니다. 설정 → Composer Plus → **차단된 명령**: 규칙을 입력하고(예: `npm publish`, `git push --force` 또는 `ssh *192.168.2.19`), 종류를 클릭해 **차단**과 **먼저 묻기** 사이에서 전환한 뒤 **추가**를 클릭하세요. 규칙의 종류를 클릭하면 바꿀 수 있고, ✕로 삭제할 수 있습니다. 규칙은 명령 이름과 그 뒤에 이 순서로 와야 하는 단어입니다. `*`는 모든 텍스트와 일치합니다. `&&`, `;`, `\|` 뒤, `$(…)`, `bash -c "…"` 또는 `eval` 안, `sudo`나 `env` 뒤에 있는 명령도 찾습니다. 이것은 가드레일이며 샌드박스가 아닙니다. 변수(`$CMD`), 스크립트 파일, 다른 프로그램은 여전히 명령을 실행할 수 있습니다(제한 사항 참고). | <a href="assets/features/blockedCommands.webp"><img src="assets/features/blockedCommands.webp" width="160" alt="스크린샷: 차단된 명령"></a> |
74
- | **작업 보드** | <a id="feature-taskboard"></a>왼쪽 사이드바 → **작업 보드**. 사이드바와 같은 실시간 상태를 보여 주는 dsh 채팅의 칸반 보드입니다. 승인, 답변 또는 계획 검토를 기다리는 채팅은 주황색 점과 함께 **검토**에, 실행 중인 채팅은 **진행 중**에, 끝난 채팅은 **완료**에 있습니다(열기 전까지 초록색). 왼쪽에서 프로젝트나 **모든 프로젝트**를 고르세요. 채팅별 브랜치 폴더는 해당 프로젝트로 취급됩니다. **새 작업**(또는 `n`)에는 프롬프트만 입력합니다. `Enter`를 누르면 프로젝트에서 새 채팅이 시작되고, 카드가 **할 일**에 표시되며, dsh가 채팅 이름을 짓고 채팅의 모델이 태그를 최대 3개 씁니다. 카드를 클릭하면 채팅이 열립니다. 주황색 카드에서 **답변**을 클릭하면 보드에서 바로 답할 수 있습니다. 승인 요청에는 **거부** 또는 **한 번 허용**, 계획에는 **승인** 또는 **변경 요청**, 질문에는 선택지와 직접 쓴 텍스트로 답합니다. **끝난 채팅 숨기기**는 이 기기에서 **완료**를 숨깁니다. | <a href="assets/features/taskBoard.webp"><img src="assets/features/taskBoard.webp" width="160" alt="스크린샷: 작업 보드"></a> |
74
+ | **작업 보드** | <a id="feature-taskboard"></a>왼쪽 사이드바 → **작업 보드**. 사이드바와 같은 실시간 상태를 보여 주는 dsh 채팅의 칸반 보드입니다. 승인, 답변 또는 계획 검토를 기다리는 채팅은 주황색 점과 함께 **검토**에, 실행 중인 채팅은 **진행 중**에, 끝난 채팅은 **완료**에 있습니다(열기 전까지 초록색). 왼쪽에서 프로젝트나 **모든 프로젝트**를 고르세요. 채팅별 브랜치 폴더는 해당 프로젝트로 취급됩니다. 목록 위의 **프로젝트 검색**에 입력하면 이름으로 프로젝트를 찾을 수 있습니다(대소문자와 악센트는 구분하지 않으며, `Esc`를 누르면 입력란이 비워집니다). **최근 2시간 내 활성**을 클릭하면 대기 중이거나 실행 중인 채팅, 확인하지 않은 채 끝난 채팅 또는 최근 2시간 안에 바뀐 채팅이 있는 프로젝트만 표시됩니다(이 설정은 이 기기에 저장됩니다). **새 작업**(또는 `n`)은 보드가 보여 주는 프로젝트에서 dsh 자체의 새 채팅을 엽니다(**모든 프로젝트**일 때는 dsh의 새 세션이 고르는 프로젝트). 그래서 다른 채팅에서처럼 파일을 추가하고, 명령을 쓰고, 모델을 고를 수 있습니다. 첫 메시지를 보내면 자동으로 보드로 돌아옵니다. 그때까지 채팅은 **할 일**에서 **새 작업**으로 기다립니다. 클릭해서 첫 메시지를 쓰세요. **할 일** 열은 이때만 표시됩니다. 응답을 기다리는 채팅이 있는 프로젝트에는 프로젝트 목록에서 주황색 점이 붙습니다. dsh가 채팅 이름을 짓고 채팅의 모델이 그 메시지에서 태그를 최대 3개 씁니다. 카드를 클릭하면 채팅이 열립니다. 주황색 카드에서 **답변**을 클릭하면 보드에서 바로 답할 수 있습니다. 승인 요청에는 **거부** 또는 **한 번 허용**, 계획에는 **승인** 또는 **변경 요청**, 질문에는 선택지와 직접 쓴 텍스트로 답합니다. **끝난 채팅 숨기기**는 이 기기에서 **완료**를 숨깁니다. **진행 중**의 카드를 가리키면(또는 키보드 포커스를 옮기면) 진행 상황을 볼 수 있습니다. 실행된 시간, 할 일 목록의 단계, 지금 실행 중인 도구, 에이전트의 마지막 줄이 표시됩니다. 설정 → Composer Plus → 작업 보드의 **마우스를 올리면 진행 상황 표시**에서 **빠름(AI 없음)**(기본값: 채팅만 읽음) 또는 **AI 요약**(채팅의 모델을 한 번 짧게 호출해 한두 문장도 씀)을 고릅니다. | <a href="assets/features/taskBoard.webp"><img src="assets/features/taskBoard.webp" width="160" alt="스크린샷: 작업 보드"></a> |
75
75
  | **프로젝트 메모리** | <a id="feature-projectmemory"></a>기본적으로 꺼져 있습니다. **설정 → Composer Plus**에서 켜세요. 프로젝트 폴더마다 자체 메모리가 있으며, 그 프로젝트의 이후 채팅이 읽습니다. DS Bot이 Bot마다 메모리를 두는 것과 같습니다. 턴이 끝날 때마다 채팅의 모델을 한 번 호출해 새 메시지(되돌린 메시지 제외)를 읽고, 오래 유지되는 선호, 결정, 사실을 짧은 메모로 저장하며, 오래된 메모를 바꾸거나 지웁니다. 에이전트도 직접 메모를 저장, 삭제, 검색할 수 있습니다(`memory_remember`, `memory_forget`, `memory_recall`). 메모는 전역일 수도 있으며, 이때는 모든 프로젝트가 읽습니다. 새 채팅은 시스템 프롬프트에서 메모를 받습니다. 나중에 저장한 메모는 다음 채팅부터 보입니다. 파일은 dsh 홈 폴더의 Markdown(`storages/dsh-composer-plus/memory/`)이며 프로젝트 폴더에는 절대 저장되지 않습니다. 같은 줄의 **메모리 열기**는 저장된 모든 메모를 프로젝트별(및 전역 메모리)로 묶어 보여 주며 필터도 있습니다. 바꿀 내용을 자신의 말로 적고(예: "yarn 대신 pnpm을 써") **변경 미리 보기**를 누르세요. dsh의 기본 모델이 변경을 제안하고, **적용**을 눌러야만 저장됩니다. Tether에서는: 채팅 제목 메뉴 → Project memory. | <a href="assets/features/projectMemory.webp"><img src="assets/features/projectMemory.webp" width="160" alt="스크린샷: 프로젝트 메모리"></a> |
76
76
  | **이 채팅에서 허용** | <a id="feature-allowforchat"></a>자동 검토가 확인을 요청하면 승인 카드에 **이 채팅에서 허용**이 추가됩니다. 이후 같은 채팅의 같은 도구는 인수와 관계없이 시간 제한이 끝날 때까지 허용됩니다(기본값 1시간. **설정 → Composer Plus → 이 채팅에서 허용**에서 고릅니다). 그 후에는 에이전트가 다시 묻습니다. 헤더 칩에서 허용 목록과 종료 시각을 보고 취소할 수 있습니다. 허용은 재시작 후에도 유지됩니다. | <a href="assets/features/allowForChat.webp"><img src="assets/features/allowForChat.webp" width="160" alt="스크린샷: 이 채팅에서 허용"></a> |
77
77
  | **프로젝트 상태** | <a id="feature-projectstatus"></a>사이드바의 프로젝트 행에 그 채팅과 같은 실행 중 / 대기 중 / 완료 표시가 나타납니다. 그래서 접힌 프로젝트도 안의 채팅이 작업 중인지, 사용자의 조치가 필요한지 알려 줍니다. 사용자의 조치를 기다리는 채팅이 먼저 표시되고, 그다음 아직 열지 않은 완료된 채팅(초록색 점, 다른 채팅이 아직 실행 중일 때도 표시), 마지막으로 실행 중 표시가 나타납니다. 포인터를 올리면 자세한 내용이 보입니다. **작업 공간 트리**에서는 상위 폴더의 행에도 그 안에 있는 각 프로젝트(예: `.worktrees/` 안의 각 브랜치 폴더)의 채팅 상태가 표시되며, 폴더가 접혀 있을 때도 마찬가지입니다. | <a href="assets/features/projectStatus.webp"><img src="assets/features/projectStatus.webp" width="160" alt="스크린샷: 프로젝트 상태"></a> |
@@ -169,7 +169,7 @@ dsh `0.2.0-rc.2`(데스크톱과 웹)와 `0.2.1-rc.2`(웹)에서 테스트했습
169
169
  - **목표 확인:** 에이전트가 자동 라운드에서 `/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개)에 보관됩니다.
170
170
  - **새 채팅에서 계속:** 클릭하기 전에는 아무것도 실행되지 않습니다. 클릭하면 Host 쪽은 채팅(목표 확인이 읽는 방식과 같음: 추론과 되돌린 단계 제외)을 채팅 자체의 모델에 보내고 인계 메모를 보여 줍니다. 새 채팅을 만드는 것은 **새 채팅 시작**뿐입니다. 프로젝트에는 아무것도 쓰지 않습니다.
171
171
  - **컨텍스트 구성:** Host에서 채팅 로그만 읽습니다. 모델 호출도 프로젝트 파일도 없습니다.
172
- - **작업 보드:** 보드는 이 창에 있는 dsh 자체 목록에서 dsh 자체 채팅을 보여 주며, 자체 채팅 데이터를 추가하지 않습니다. 작업을 시작하면 Host 쪽이 고른 프로젝트에 새 채팅을 만들고, 사용자가 거기서 직접 입력한 것처럼 프롬프트를 첫 메시지로 보냅니다. 그래서 승인, 샌드박스, 채팅의 모델이 평소처럼 적용됩니다. 그런 다음 태그를 최대 3개 얻기 위해 프롬프트(처음 4,000자만, 다른 것은 없음)를 도구 없이 요청 한 번으로 그 채팅의 모델에 더 보냅니다. 각 작업의 프롬프트, 태그, 시작 시각은 `$DSH_HOME/storages/dsh-composer-plus/board-chats.json`(소유자 전용 파일, 최신 2,000개)에 보관됩니다. 스위치는 그 옆의 `board-switch.json`에 있습니다. 프로젝트 폴더에는 아무것도 쓰지 않습니다. **답변**은 채팅 자체의 카드와 같은 방식으로 dsh 자체의 대기 중인 요청에 답변을 보냅니다. 이전 버전의 예전 작업 목록(`board.json`)은 디스크에 그대로 남으며 읽지 않습니다.
172
+ - **작업 보드:** 보드는 이 창에 있는 dsh 자체 목록에서 dsh 자체 채팅을 보여 주며, 자체 채팅 데이터를 추가하지 않습니다. **새 작업**은 dsh 자체의 새 채팅을 열고, 첫 메시지는 사용자가 dsh의 입력란에 씁니다. 그래서 승인, 샌드박스, 채팅의 모델이 평소처럼 적용됩니다. Host 쪽은 그 채팅의 첫 메시지를 카드의 프롬프트로 보관하고, 태그를 최대 3개 얻기 위해 그 메시지(처음 4,000자만, 다른 것은 없음)를 도구 없이 요청 한 번으로 그 채팅의 모델에 더 보냅니다. 각 작업의 프롬프트, 태그, 시작 시각은 `$DSH_HOME/storages/dsh-composer-plus/board-chats.json`(소유자 전용 파일, 최신 2,000개)에 보관됩니다. 스위치는 그 옆의 `board-switch.json`에 있습니다. 프로젝트 폴더에는 아무것도 쓰지 않습니다. **답변**은 채팅 자체의 카드와 같은 방식으로 dsh 자체의 대기 중인 요청에 답변을 보냅니다. 이전 버전의 예전 작업 목록(`board.json`)은 디스크에 그대로 남으며 읽지 않습니다. **마우스를 올리면 진행 상황 표시**는 이 Mac에서 채팅 로그를 읽습니다. **빠름(AI 없음)**(기본값)에서는 아무것도 보내지 않습니다. **AI 요약**에서는 실행 중인 카드의 진행 상황 상자가 보이는 동안(또는 Tether의 보드가 열려 있는 동안, 실행 중인 카드 최대 8개에 대해) Host 쪽이 그 채팅의 가장 최근 부분(최대 약 6,000자: 사용자 메시지, 에이전트의 텍스트 답변, 도구 호출과 그 결과의 끝부분. 추론과 되돌린 메시지는 제외)을 도구 없는 요청 한 번으로 채팅의 모델에 보냅니다. 채팅이 진행된 뒤에만 다시 보내며, 채팅마다 최대 20초에 한 번입니다. 메모는 메모리에만 보관됩니다. 설정은 `$DSH_HOME/storages/dsh-composer-plus/board-progress.json`(소유자 전용 파일)에 있습니다.
173
173
  - **보호된 파일:** 목록과 스위치는 `$DSH_HOME/storages/dsh-composer-plus/protected-files.json`(소유자 전용 파일)에 있습니다. 확인은 각 파일 도구 호출의 경로(와 실제 경로)만 읽으며, 파일 자체는 읽지 않습니다.
174
174
  - **차단된 명령:** 규칙과 스위치는 `$DSH_HOME/storages/dsh-composer-plus/blocked-commands.json`(소유자 전용 파일)에 있습니다. 확인은 각 `bash`와 `pwsh` 호출의 명령 텍스트만 읽으며, 아무것도 실행하거나 보내지 않습니다.
175
175
  - **프로젝트 메모리:** 직접 켜기 전까지는 꺼져 있습니다. 켜져 있는 동안 최상위 채팅의 턴이 끝날 때마다 Host 쪽이 지난 검토 이후 그 채팅의 새 메시지(사용자 메시지와 에이전트의 텍스트 답변. 도구 출력, 추론, 숨은 컨텍스트, 되돌린 메시지는 제외. 분기한 채팅에서는 부모 채팅의 복사본 제외. 최대 약 16,000자)와 저장된 메모를, 도구 없는 요청 한 번으로 채팅 자체의 모델에 보냅니다. 메모는 `$DSH_HOME/storages/dsh-composer-plus/memory/` 아래의 Markdown 파일(소유자만 읽고 쓸 수 있음)입니다. 프로젝트 폴더마다 `projects/<id>/`(`<id>`는 폴더 실제 경로의 해시이며, `project.json`에 폴더가 적힙니다), `global/`, `journal.jsonl`(각 변경과 변경 전후의 줄), `reviewed.json`(각 채팅을 어디까지 읽었는지)이 있습니다. 프로젝트 폴더에는 아무것도 쓰지 않습니다. 키, 토큰, 비밀번호, 신분증 번호처럼 보이는 메모는 거부합니다. 프로젝트의 메모는 그 폴더의 새 채팅마다 시스템 프롬프트에 들어가므로, 그 채팅의 모든 요청과 함께 모델에 전달됩니다. 스위치는 같은 위치의 `memory.json`에 있습니다. **메모리 열기**는 **변경 미리 보기**를 누르기 전에는 아무것도 보내지 않습니다. 누르면 보이는 메모와 사용자의 글을 도구 없는 한 번의 요청으로 dsh의 기본 모델에 보냅니다. 변경은 **적용**을 눌러야만 기록되며 저널에는 `editor`로 남습니다. Tether도 같은 경로로 메모를 읽고 바꿉니다.
@@ -194,7 +194,7 @@ dsh `0.2.0-rc.2`(데스크톱과 웹)와 `0.2.1-rc.2`(웹)에서 테스트했습
194
194
  - **채팅 행에 브랜치 배지가 없음:** 사이드바가 “하나의 목록” 보기가 아니거나(“작업 공간”과 “작업 공간 트리”에서는 어떤 채팅 행에도 배지가 없음), 이 버전을 설치한 뒤 그 채팅에 턴이 없었거나, 폴더가 git 저장소가 아니거나, **채팅 행의 Git 브랜치**가 꺼져 있습니다. 업데이트한 뒤에는 dsh를 다시 시작하세요(브랜치는 Host 쪽이 기록합니다).
195
195
  - **목표 확인에 테스트가 종료 코드 127 또는 "not found"로 끝났다고 표시됨:** Finder나 Dock에서 시작한 dsh는 터미널보다 PATH가 짧을 수 있어서 `npm`, `pnpm`, `cargo`를 찾지 못합니다. 터미널에서 dsh를 시작하거나, **목표 확인** → **편집**에서 전체 경로를 쓴 테스트 명령을 직접 정하세요. **지금 실행**을 누르면 결과가 바로 표시됩니다.
196
196
  - **목표가 닫히지 않고 에이전트가 계속 작업함:** **목표 확인**이 실패한 테스트나 남은 작업을 찾았습니다. 목표 아래의 행에 이유가 표시됩니다(자세한 내용은 결과에 포인터를 올려 보세요). 원인이나 테스트 명령을 고치거나, `/goal` 또는 목표 바로 목표를 직접 완료하세요(이 완료는 확인하지 않습니다).
197
- - **릴리스 직후 설치 실패:** 버전을 붙여서 설치하세요(`dsh-composer-plus@1.19.0`). 위의 설치 안내를 참고하세요.
197
+ - **릴리스 직후 설치 실패:** 버전을 붙여서 설치하세요(`dsh-composer-plus@1.20.0`). 위의 설치 안내를 참고하세요.
198
198
  - **지금 백업에서 "다른 백업 작업이 실행 중입니다"라고 표시됨:** 다른 dsh 창이나 복구 콘솔에서 작업이 실행 중입니다(둘은 백업 폴더의 잠금 파일 `.composer-plus.lock`을 함께 씁니다). 작업이 끝날 때까지 기다리세요. 실행 중인 작업이 없으면, 다음에 클릭할 때 종료된 프로세스의 잠금을 넘겨받습니다.
199
199
  - **복구 콘솔에 "dsh is running"이라고 표시됨:** 먼저 dsh를 종료하세요. dsh가 정말 닫혀 있다면, 메시지에 나온 파일은 비정상 종료로 남은 것입니다. 그 파일을 삭제하고 다시 시도하세요.
200
200
  - **복원 후 dsh가 시작되지 않거나 플러그인이 없음:** 프로필의 플러그인 패키지를 다시 설치해야 합니다. 복구 콘솔이 복원 후에 이를 제안합니다. 또는 콘솔이 나열하는 `$DSH_HOME/profiles/` 아래의 각 폴더에서 `pnpm install`을 실행하세요. vault에 없던 비밀 값(다른 컴퓨터)은 다시 입력해야 합니다. 콘솔이 그 목록을 보여 줍니다.
@@ -249,7 +249,7 @@ dsh `0.2.0-rc.2`(데스크톱과 웹)와 `0.2.1-rc.2`(웹)에서 테스트했습
249
249
  - **새 채팅에서 계속**은 채팅(메시지, 도구 호출, 각 도구 결과의 끝부분. 최대 약 60,000자, 가장 최근 부분)을 채팅 자체의 모델에 보냅니다. 인계 메모는 결정이나 파일을 빠뜨릴 수 있으므로, 시작하기 전에 읽어 보세요. 새 채팅은 메모와 링크된 채팅만 압니다(dsh는 이전 채팅을 읽기 전용 컨텍스트로 첨부합니다). 새 채팅의 모델 컨텍스트는 작게 시작하고, 이전 채팅은 그대로 남습니다. 채팅마다 한 번에 메모 작성이나 시작 하나만 실행됩니다.
250
250
  - **컨텍스트 구성**은 dsh 자체의 규칙(토큰당 약 4자)으로 추정값을 보여 줍니다. dsh의 컨텍스트 링과 같은 규칙이며, 모델 자체의 계산과 다를 수 있습니다. 도구 정의는 가장 최근 요청의 것입니다. 채팅 로그에 있는 그대로의 컨텍스트를 보여 주며, 지금 실행 중인 턴은 다음 단계 뒤에 나타납니다.
251
251
  - **계획된 단계**는 모델이 실제로 계획할 때만 토큰을 절약합니다. 켜져 있는 동안에는 모델이 계획하지 않는 채팅에서도 모든 요청에 `plan_next_steps` 도구와 짧은 지침(약 500토큰)이 포함됩니다. 조건은 적힌 내용만 증명합니다(예: 빌드 종료 코드가 0이었음). 작업이 올바르다는 것은 증명하지 않습니다. `ok`는 dsh 자체의 결과 표시(`[exit code: N]`, 시간 초과, 샌드박스 거부)를 읽습니다. 0이 아닌 종료 코드 없이 실패한 명령은 통과로 처리됩니다. 단계는 한 번에 하나씩 실행되며, 동시에 준비된 두 단계는 모델에게 돌아갑니다. 단계의 메시지는 채팅 모델의 어시스턴트 메시지로 저장됩니다(dsh에는 플러그인이 쓴 메시지를 나타내는 표시가 없습니다). 그래서 그 텍스트에 Composer Plus가 실행했다고 적혀 있습니다. Tether에는 없습니다.
252
- - **작업 보드**는 dsh가 이 창에 나열하는 채팅을 보여 줍니다. 프로젝트 밖의 채팅은 **모든 프로젝트**에만 표시되고, 채팅별 브랜치 폴더(`<project>/.worktrees/<name>`)는 해당 프로젝트로 취급됩니다. 카드의 열은 채팅의 실시간 상태이므로 카드를 끌어 옮길 수 없습니다. 채팅은 턴이 끝나면(오류나 중지 후에도) **완료**로 가고, 다시 실행되면 **진행 중**으로 돌아갑니다. 초록색 점은 dsh 자체의 완료 점이며, dsh는 이 점을 이 창에만 보관합니다. 페이지를 다시 불러오면 끝난 채팅이 이 점 없이 표시됩니다. **완료**에는 최신 채팅 50개가 표시됩니다(나머지는 **이전 작업 N개 보기**로 볼 수 있습니다). 태그는 시작한 작업마다 모델 호출 한 번으로 만들어지므로 틀릴 수 있으며, 보드에서 시작하지 않은 채팅에는 태그가 없습니다. 제목은 dsh 자체의 채팅 제목입니다(dsh의 제목 서비스가 채팅의 모델로 만듭니다). 제목이 오기 전까지 카드에는 프롬프트의 첫 줄이 표시됩니다. dsh가 아는 `/` 명령(`/plan`, `/goal`)으로 시작하는 프롬프트는 그 명령으로 실행됩니다. **답변**은 채팅의 가장 최근 요청에만 답합니다. 그 요청이 다른 곳(다른 창, Tether, 자동 검토)에서 이미 답변되었거나 채팅이 새로운 것을 물으면, 패널이 그렇게 알려 주고 아무것도 보내지 않습니다. 이전 버전에는 댓글과 에이전트 도구가 있는 작업 목록이 있었지만 이제 없어졌으며, 예전 `board.json`은 표시되지 않습니다. 아이디어와 디자인은 emanuele-em의 [Kanzo](https://github.com/emanuele-em/kanzo)(AGPL-3.0)에서 왔습니다. Composer Plus는 그 코드를 쓰지 않습니다.
252
+ - **작업 보드**는 dsh가 이 창에 나열하는 채팅을 보여 줍니다. 프로젝트 밖의 채팅은 **모든 프로젝트**에만 표시되고, 채팅별 브랜치 폴더(`<project>/.worktrees/<name>`)는 해당 프로젝트로 취급됩니다. 카드의 열은 채팅의 실시간 상태이므로 카드를 끌어 옮길 수 없습니다. 채팅은 턴이 끝나면(오류나 중지 후에도) **완료**로 가고, 다시 실행되면 **진행 중**으로 돌아갑니다. 초록색 점은 dsh 자체의 완료 점이며, dsh는 이 점을 이 창에만 보관합니다. 페이지를 다시 불러오면 끝난 채팅이 이 점 없이 표시됩니다. **완료**에는 최신 채팅 50개가 표시됩니다(나머지는 **이전 작업 N개 보기**로 볼 수 있습니다). **프로젝트 검색**은 프로젝트를 이름으로만 찾고, 폴더 경로로는 찾지 않습니다. **최근 2시간 내 활성**은 프로젝트의 모든 채팅이 2시간보다 오래되었고 유휴 상태이며 읽은 상태일 때 그 프로젝트를 숨깁니다. 선택한 프로젝트는 보드에 계속 표시됩니다. **새 작업**은 이 창의 가장 최근 새 채팅만 기억합니다. 첫 메시지 전에 다른 채팅을 열면, 그 채팅은 사용자가 거기에 쓸 때까지 **할 일**에 **새 작업**으로 남지만, 자동으로 보드로 돌아오는 것은 가장 최근 채팅뿐입니다. 페이지를 다시 불러오면 메시지가 없는 새 채팅은 보드에 없습니다(dsh는 그 채팅을 빈 새 세션으로 보관합니다). 태그는 작업마다 그 첫 메시지를 바탕으로 한 모델 호출 한 번으로 만들어지므로 틀릴 수 있으며, 보드에서 시작하지 않은 채팅에는 태그가 없습니다. 제목은 dsh 자체의 채팅 제목입니다(dsh의 제목 서비스가 채팅의 모델로 만듭니다). 제목이 오기 전까지 카드에는 첫 메시지의 첫 줄이 표시됩니다. **답변**은 채팅의 가장 최근 요청에만 답합니다. 그 요청이 다른 곳(다른 창, Tether, 자동 검토)에서 이미 답변되었거나 채팅이 새로운 것을 물으면, 패널이 그렇게 알려 주고 아무것도 보내지 않습니다. 이전 버전에는 댓글과 에이전트 도구가 있는 작업 목록이 있었지만 이제 없어졌으며, 예전 `board.json`은 표시되지 않습니다. 아이디어와 디자인은 emanuele-em의 [Kanzo](https://github.com/emanuele-em/kanzo)(AGPL-3.0)에서 왔습니다. Composer Plus는 그 코드를 쓰지 않습니다.
253
253
  - **중지 후 보낸 메시지 먼저 실행**은 채팅을 중지한 뒤에만 동작합니다(또는 실패한 턴 뒤, 아직 대기열이 있는 채팅을 열 때). 턴이 실행되는 중에 보낸 메시지는 여전히 대기열 끝에서 기다립니다. 내가 대기열에 넣은 메시지만 앞지릅니다. 대기열에 목표 라운드나 질문 답변이 기다리고 있으면 dsh 자체 순서가 유지됩니다. 공개 API가 아닌 dsh의 일부(중지된 턴이 아직 끝나는 중인지)를 읽습니다. dsh 업데이트로 그 이름이 바뀌면, 메시지는 그 턴이 끝난 뒤에만 앞으로 옮겨집니다. 서브에이전트 채팅은 dsh 자체 순서를 유지합니다.
254
254
  - **프로젝트 메모리**는 채팅의 첫 폴더(dsh의 프로젝트 폴더)에 속합니다. `cd`로 폴더를 바꾼 채팅은 첫 프로젝트의 메모리를 계속 씁니다. 같은 파일로 가는 다른 경로로 연 같은 폴더는 메모리를 공유합니다. 채팅은 시작할 때 메모리 섹션을 고정하므로, 나중에 저장한 메모는 다음 채팅부터 보입니다(`memory_recall`은 바로 찾습니다). 검토는 모델이 남기기로 정한 것만 남깁니다. 사실을 놓치거나 틀린 것을 남길 수 있으니, **메모리 열기**에서 확인하고 그곳에서 바꾸거나, dsh가 닫혀 있을 때 파일을 직접 고치세요. **메모리 열기**는 선택한 프로젝트의 메모와 전역 메모(모든 메모를 선택하면 모든 프로젝트, 최대 약 60,000자이며 나머지는 개수만 표시되고 그 요청에서는 바꿀 수 없음)와 사용자의 글을 채팅의 모델이 아니라 dsh의 기본 모델로 보냅니다. 미리 보기는 Mac에 30분 동안, dsh를 다시 시작할 때까지 보관됩니다. 그사이 검토나 에이전트가 메모를 바꾸면 **적용**이 거부되므로 다시 미리 보기를 하세요. **적용**은 미리 보기의 변경을 모두 저장하거나 하나도 저장하지 않습니다. 저장할 수 없는 변경이 하나라도 있으면(예: MEMORY.md가 가득 찬 경우) 메모는 그대로 남고 이유가 표시됩니다. 사용자 메시지가 있는 턴이 끝날 때마다 모델 호출이 한 번 듭니다. 호출이 실패하면 다음 턴 뒤에 같은 메시지를 다시 읽습니다. 서브에이전트 채팅은 검토하지 않습니다. 아이디어와 파일 형식은 [DS Bot](https://github.com/Fei2411/DS-Bot)(Apache-2.0)에서 왔습니다. Composer Plus는 그 코드를 쓰지 않으며, DS Bot 자체의 메모리를 읽거나 쓰지 않습니다.
255
255
  - **백업**은 고정된 폴더 하나, `~/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 아카이브를 자기 보관 개수에 포함하며 그 아카이브를 삭제할 수 있습니다.
@@ -286,7 +286,7 @@ dsh `0.2.0-rc.2`(데스크톱과 웹)와 `0.2.1-rc.2`(웹)에서 테스트했습
286
286
 
287
287
  **DS Bot의 메모리처럼 에이전트가 채팅이 바뀌어도 내 선호를 기억할 수 있나요?** 네, **프로젝트 메모리**(기본적으로 꺼짐)로 가능합니다. **설정 → Composer Plus**에서 켜세요. 턴이 끝날 때마다 오래 유지되는 선호와 결정이 채팅 프로젝트의 짧은 메모로 저장되고, 그 프로젝트의 새 채팅마다 이를 읽습니다. 에이전트에게 무언가를 기억하라고 하면 바로 저장합니다. 메모를 보거나 바꾸려면 같은 줄의 **메모리 열기**를 누르고 바꿀 내용을 적으세요.
288
288
 
289
- **모든 채팅을 칸반 보드로 보고 거기서 새 채팅을 시작할 수 있나요?** 네, **작업 보드**(기본적으로 켜짐)로 가능합니다. 왼쪽 사이드바에서 여세요. 각 채팅은 **진행 중**, **검토**(사용자를 기다림) 또는 **완료**에 있는 카드입니다. **새 작업**에는 프롬프트만 입력하면 그 프롬프트로 새 채팅이 시작됩니다. 주황색 카드에서 **답변**을 클릭하면 채팅을 열지 않고 답할 수 있습니다.
289
+ **모든 채팅을 칸반 보드로 보고 거기서 새 채팅을 시작할 수 있나요?** 네, **작업 보드**(기본적으로 켜짐)로 가능합니다. 왼쪽 사이드바에서 여세요. 각 채팅은 **진행 중**, **검토**(사용자를 기다림) 또는 **완료**에 있는 카드입니다. **새 작업**은 프로젝트에서 dsh의 새 채팅을 열고, 첫 메시지를 보내면 보드로 돌아옵니다. 주황색 카드에서 **답변**을 클릭하면 채팅을 열지 않고 답할 수 있습니다.
290
290
 
291
291
  **dsh-backup처럼 dsh에서 채팅과 설정을 백업할 수 있나요?** 네. **설정 → Composer Plus → 백업 → 지금 백업**을 사용하세요. 같은 아카이브 형식으로 같은 폴더(`~/Desktop/dsh-backups`)에 쓰므로, dsh-backup의 아카이브도 표시되고 복원할 수 있으며, dsh-backup은 삭제해도 됩니다. 정해진 일정으로 백업하려면 **자동 백업**을 켜세요.
292
292
 
@@ -408,7 +408,7 @@ PLAYWRIGHT=/path/to/playwright node test/browser-continue-queue.mjs /path/to/dsh
408
408
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-queue-stop-send.mjs /path/to/dsh/lib/bin.js
409
409
  # Edit queued message in place with images and files (slow fake model) + its thumbnail
410
410
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-queue-edit.mjs /path/to/dsh/lib/bin.js
411
- # Task board: a prompt starts a chat, AI tags, live columns, Answer on the board, Hide finished, the switch
411
+ # Task board: New task opens dsh's new chat and comes back after the first message, AI tags, live columns, Answer on the board, Hide finished, the switch
412
412
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-task-board.mjs /path/to/dsh/lib/bin.js
413
413
  ```
414
414
 
package/README.md CHANGED
@@ -12,7 +12,7 @@ Codex-style quality-of-life features for the [DeepSeek Harness](https://github.c
12
12
 
13
13
  <p align="center"><img src="docs/images/hero.webp" width="820" alt="DeepSeek Harness with Composer Plus: the running project shows a spinner in the sidebar and the Changes panel shows a git diff"></p>
14
14
 
15
- Unofficial community plugin. The only network calls are the update check (GitHub releases and the npm registry); switch off **Automatic updates** to stop them at startup. **Feature ideas** calls your chat's own model only when you click **Suggest features**. **Next message prediction** (on by default) calls the model chosen in Settings (dsh's default unless you pick another) once after each finished turn, without a click. Switch it off in **Settings → Composer Plus** to stop these calls. **Complete while typing** (off by default) calls its chosen model (by default the prediction's) at each pause while you type, after you switch it on. **Improve prompt** calls a model only when you click its magic wand. **Task board** calls the new chat's model once for the tags of each task that you start on the board. **Goal check** (on by default) calls a model once each time the agent marks a `/goal` complete in an automatic round. **Mobile connect** (off by default) accepts iPhone connections from your local network or tailnet only after you switch it on.
15
+ Unofficial community plugin. The only network calls are the update check (GitHub releases and the npm registry); switch off **Automatic updates** to stop them at startup. **Feature ideas** calls your chat's own model only when you click **Suggest features**. **Next message prediction** (on by default) calls the model chosen in Settings (dsh's default unless you pick another) once after each finished turn, without a click. Switch it off in **Settings → Composer Plus** to stop these calls. **Complete while typing** (off by default) calls its chosen model (by default the prediction's) at each pause while you type, after you switch it on. **Improve prompt** calls a model only when you click its magic wand. **Task board** calls the new chat's model once for the tags of each task that you start on the board. With its **AI summary** setting (the default is **Fast (no AI)**), it also calls a running chat's model for a short progress note while you look at that task's progress on the board or in Tether. **Goal check** (on by default) calls a model once each time the agent marks a `/goal` complete in an automatic round. **Mobile connect** (off by default) accepts iPhone connections from your local network or tailnet only after you switch it on.
16
16
 
17
17
  ## Install
18
18
 
@@ -27,7 +27,7 @@ dsh plugin --profile web add dsh-composer-plus
27
27
 
28
28
  Then restart dsh. (The CLI can't install into the desktop profile; the app manages it.)
29
29
 
30
- > dsh's pnpm skips versions younger than 24 hours. Right after a release, add the version: `dsh-composer-plus@1.19.0`.
30
+ > dsh's pnpm skips versions younger than 24 hours. Right after a release, add the version: `dsh-composer-plus@1.20.0`.
31
31
 
32
32
  ## Features
33
33
 
@@ -69,7 +69,7 @@ Then restart dsh. (The CLI can't install into the desktop profile; the app manag
69
69
  | **Planned steps** | <a id="feature-plannedsteps"></a>Off by default: switch it on in **Settings → Composer Plus**. The agent gets the tool `plan_next_steps`: in the same message as a command, it can plan the next commands with their exact arguments and a condition, for example "run `npm test` when the build passes". When the result meets the condition, Composer Plus runs the next step itself, without a new model call, so a long chat uses fewer tokens. The step shows in the chat as a short line, "Composer Plus · Planned steps: ran `test` … without a model call", followed by its tool call and its result. Only `bash`, `read`, `grep` and `glob` steps; approvals, the sandbox and Protected files apply to each step as usual. The model answers again when a condition fails, when two steps are ready at the same time, after the last step, and when you send a message. The idea comes from HarnessMM (arXiv 2610.32813). | <a href="assets/features/plannedSteps.webp"><img src="assets/features/plannedSteps.webp" width="160" alt="Screenshot: Planned steps"></a> |
70
70
  | **Protected files** | <a id="feature-protectedfiles"></a>On by default. The agent's own file tools cannot read or change files that match your patterns: `read`, `read_image` and `grep` on a file are refused for **read and write** patterns, and `write`, `edit` and `str_replace_editor` for both kinds. The agent reads why and is told to ask you. The defaults are `.env*`, `*.pem` and `*.key`. Settings → Composer Plus → **Protected files**: add a pattern (for example `published/**` or `config/*.yml`), click its kind to switch between **read and write** and **write only**, remove it with ✕, or **Use the defaults**. A pattern without `/` matches a file name in any folder. This is a guard rail, not a sandbox: a shell command (`cat .env`), a script or an MCP tool can still reach the file (see Limits). | <a href="assets/features/protectedFiles.webp"><img src="assets/features/protectedFiles.webp" width="160" alt="Screenshot: Protected files"></a> |
71
71
  | **Blocked commands** | <a id="feature-blockedcommands"></a>On by default, with an empty list. The agent's shell commands (`bash`, `pwsh`) cannot run a command that matches your rules: a **block** rule refuses the call (the agent reads why and is told to ask you), an **ask first** rule shows dsh's approval card, and the command runs only when you allow it. Settings → Composer Plus → **Blocked commands**: type a rule (for example `npm publish`, `git push --force` or `ssh *192.168.2.19`), click the kind to switch between **block** and **ask first**, then **Add**; click a rule's kind to change it, remove it with ✕. A rule is a command name and words that must come after it in this order; `*` matches any text. It also finds the command after `&&`, `;`, `\|`, inside `$(…)`, `bash -c "…"` or `eval`, and after `sudo` or `env`. This is a guard rail, not a sandbox: a variable (`$CMD`), a script file or another program can still run the command (see Limits). | <a href="assets/features/blockedCommands.webp"><img src="assets/features/blockedCommands.webp" width="160" alt="Screenshot: Blocked commands"></a> |
72
- | **Task board** | <a id="feature-taskboard"></a>Left sidebar → **Task board**. A kanban board of your dsh chats with the live state that the sidebar shows: a chat that waits for your approval, answer or plan review is in **Review** with an orange dot, a running chat is in **Doing**, a finished chat is in **Done** (green until you open it). Pick a project or **All projects** on the left; a Branch per chat folder counts as its project. **New task** (or `n`) takes only a prompt: `Enter` starts a new chat in the project, the card shows in **Todo**, dsh names the chat and the chat's model writes up to 3 tags. Click a card to open its chat. On an orange card, click **Answer** to answer it on the board: **Reject** or **Allow once**, **Approve** or **Request changes** for a plan, or the options and your own text for a question. **Hide finished** hides **Done** on this device. | <a href="assets/features/taskBoard.webp"><img src="assets/features/taskBoard.webp" width="160" alt="Screenshot: Task board"></a> |
72
+ | **Task board** | <a id="feature-taskboard"></a>Left sidebar → **Task board**. A kanban board of your dsh chats with the live state that the sidebar shows: a chat that waits for your approval, answer or plan review is in **Review** with an orange dot, a running chat is in **Doing**, a finished chat is in **Done** (green until you open it). Pick a project or **All projects** on the left; a Branch per chat folder counts as its project. Type in **Search projects** above the list to find a project by its name (case and accents do not matter; `Esc` empties the box), and click **Active in the last 2 hours** to show only projects with a chat that waits, runs, finished unseen or changed in the last 2 hours (kept on this device). **New task** (or `n`) opens dsh's own new chat in the project that the board shows (with **All projects**, the project that dsh's New session picks), so you can add files, use commands and pick the model as in any chat. When your first message goes, the board comes back by itself. Until then the chat waits in **Todo** as **New task**: click it to write the first message. The **Todo** column shows only then. A project with a chat that waits for you has an orange dot in the project list. dsh names the chat and the chat's model writes up to 3 tags from that message. Click a card to open its chat. On an orange card, click **Answer** to answer it on the board: **Reject** or **Allow once**, **Approve** or **Request changes** for a plan, or the options and your own text for a question. **Hide finished** hides **Done** on this device. Point at a card in **Doing** (or move the keyboard focus to it) to see its progress: how long it runs, the step of its todo list, the tool that runs now and the agent's last line. In Settings → Composer Plus → Task board, **Progress on hover** picks **Fast (no AI)** (the default: it reads the chat only) or **AI summary** (one short call to the chat's model also writes one or two sentences). | <a href="assets/features/taskBoard.webp"><img src="assets/features/taskBoard.webp" width="160" alt="Screenshot: Task board"></a> |
73
73
  | **Project memory** | <a id="feature-projectmemory"></a>Off by default: switch it on in **Settings → Composer Plus**. Each project folder gets its own memory, which later chats of that project read, as DS Bot keeps one per Bot. After each finished turn, one call to the chat's model reads the new messages (not rolled-back ones) and keeps your lasting preferences, decisions and facts as short notes, and changes or removes old ones. The agent can also save, remove and search notes itself (`memory_remember`, `memory_forget`, `memory_recall`). A note can also be global: every project reads it. A new chat gets the notes in its system prompt; a note saved later shows from the next chat. The files are Markdown under the dsh home (`storages/dsh-composer-plus/memory/`), never in the project folder. **Open memory** in the same row shows every saved note, grouped by project (and the global memory), with a filter. Write what to change in your own words (for example "I switched from yarn to pnpm"), then **Preview changes**: dsh's default model proposes the changes, and only **Apply** saves them. In Tether: chat title menu → Project memory. | <a href="assets/features/projectMemory.webp"><img src="assets/features/projectMemory.webp" width="160" alt="Screenshot: Project memory"></a> |
74
74
  | **Allow for this chat** | <a id="feature-allowforchat"></a>When Auto Review asks you, the approval card gets **Allow for this chat**: the same tool in the same chat is allowed from then on, with any arguments, until the time limit ends (1 hour by default; choose it under **Settings → Composer Plus → Allow for this chat**). Then the agent asks again. A header chip lists the grants with their end time and revokes them. Grants survive a restart. | <a href="assets/features/allowForChat.webp"><img src="assets/features/allowForChat.webp" width="160" alt="Screenshot: Allow for this chat"></a> |
75
75
  | **Project status** | <a id="feature-projectstatus"></a>A project row in the sidebar shows the same spinner / waiting / done marker as its chats, so a collapsed project still tells you a chat inside is working or needs you. A chat waiting for you shows first, then a finished chat you have not opened yet (the green dot, also while another chat still runs), then the spinner. Hover it for details. In **Workspace Tree**, the row of a parent folder also shows the chats of each project inside it (for example each branch folder in `.worktrees/`), also while it is collapsed. | <a href="assets/features/projectStatus.webp"><img src="assets/features/projectStatus.webp" width="160" alt="Screenshot: Project status"></a> |
@@ -167,7 +167,7 @@ Tested on dsh `0.2.0-rc.2` (desktop and web) and `0.2.1-rc.2` (web). CI runs the
167
167
  - **Goal check:** it runs only when the agent marks a `/goal` complete in an automatic round (or when you click **Run now**). The Host half runs the test command in the chat's folder with the chat's sandbox mode (as dsh's own `bash` tool: the same file-access policy; when that sandbox cannot start, the test does not run and the check fails). It reads only `package.json`, `Makefile`, `Cargo.toml`, `go.mod`, `pyproject.toml` and `pytest.ini` to find the command, as regular files inside the folder (no symlink out of it, no FIFO). Then it sends the goal, the chat since the goal started (your messages, the agent's replies, tool calls cut to 1,000 characters and the last 2,000 characters of each tool result; no reasoning, no rolled-back steps; at most about 60,000 characters, the newest part), `git status --short` and the end of the test output to the model chosen under **Goal check** (by default the chat's own model), as one request with no tools. Tool output can contain what the agent read, so this request can hold parts of your files, as the chat itself does. Nothing is written to the chat or the project. Your test command, the limits, the last result (with the end of its output) and the model choice are in `$DSH_HOME/storages/dsh-composer-plus/goal-check.json` (owner-only file, newest 500 chats).
168
168
  - **Continue in a new chat:** nothing runs until you click it. Then the Host half sends the chat (as Goal check reads it: no reasoning, no rolled-back steps) to the chat's own model and shows the note; only **Start new chat** makes a new chat. Nothing is written to the project.
169
169
  - **Context breakdown:** reads only the chat log on the Host; no model call, no project file.
170
- - **Task board:** the board shows dsh's own chats from dsh's own lists in this window; it adds no chat data of its own. When you start a task, the Host half makes a new chat in the project you chose and sends your prompt to it as its first message, as if you typed it there, so approvals, the sandbox and the chat's model apply as usual. Then it sends the prompt (its first 4,000 characters, nothing else) to that chat's model in one more request, with no tools, for up to 3 tags. The prompt, the tags and the start time of each task are kept in `$DSH_HOME/storages/dsh-composer-plus/board-chats.json` (owner-only file, the newest 2,000); the switch is in `board-switch.json` next to it. Nothing is written to a project folder. **Answer** sends your answer to dsh's own pending request, the same way the chat's own card does. The old task list of earlier versions (`board.json`) stays on disk as it was and is not read.
170
+ - **Task board:** the board shows dsh's own chats from dsh's own lists in this window; it adds no chat data of its own. **New task** opens dsh's own new chat, and you write the first message in dsh's composer, so approvals, the sandbox and the chat's model apply as usual. The Host half keeps that chat's first message as the card's prompt and sends it (its first 4,000 characters, nothing else) to that chat's model in one more request, with no tools, for up to 3 tags. The prompt, the tags and the start time of each task are kept in `$DSH_HOME/storages/dsh-composer-plus/board-chats.json` (owner-only file, the newest 2,000); the switch is in `board-switch.json` next to it. Nothing is written to a project folder. **Answer** sends your answer to dsh's own pending request, the same way the chat's own card does. The old task list of earlier versions (`board.json`) stays on disk as it was and is not read. **Progress on hover** reads the chat's log on this Mac. With **Fast (no AI)** (the default), nothing is sent. With **AI summary**, while a running card's progress box shows (or while Tether's board is open, for up to 8 running cards), the Host half sends that chat's newest part (at most about 6,000 characters: your messages, the agent's text replies, its tool calls and the end of their results; no reasoning, no rolled-back messages) to the chat's model, as one request with no tools. It sends again only after the chat moved on, at most once every 20 seconds per chat. The note is kept only in memory; the setting is in `$DSH_HOME/storages/dsh-composer-plus/board-progress.json` (owner-only file).
171
171
  - **Protected files:** the list and the switch are in `$DSH_HOME/storages/dsh-composer-plus/protected-files.json` (owner-only file). The check reads only the path of each file tool call (and its real path), never the file.
172
172
  - **Blocked commands:** the rules and the switch are in `$DSH_HOME/storages/dsh-composer-plus/blocked-commands.json` (owner-only file). The check reads only the command text of each `bash` and `pwsh` call; it runs nothing and sends nothing.
173
173
  - **Project memory:** off until you switch it on. While it is on, after each finished turn of a top-level chat, the Host half sends the chat's own new messages since the last review (your messages and the agent's text replies; no tool output, no reasoning, no hidden context, no rolled-back messages; a fork's copy of its parent is left out; at most about 16,000 characters) and the saved notes to the chat's own model, as one request with no tools. The notes are Markdown files under `$DSH_HOME/storages/dsh-composer-plus/memory/` (owner-only files): `projects/<id>/` for each project folder (`<id>` is a hash of the folder's real path; `project.json` names the folder), `global/`, `journal.jsonl` (every change with the line before and after) and `reviewed.json` (how far each chat was read). Nothing is written to the project folder. Notes that look like a key, a token, a password or an ID number are refused. The notes of a project go into the system prompt of each new chat in that folder, so they reach the model with every request of that chat. The switch is in `memory.json` next to it. **Open memory** sends nothing until you click **Preview changes**; then it sends the notes it shows and your text to dsh's default model, as one request with no tools. Its changes are written only on **Apply**, with `editor` in the journal. Tether reads and changes the notes through the same route.
@@ -192,7 +192,7 @@ Tested on dsh `0.2.0-rc.2` (desktop and web) and `0.2.1-rc.2` (web). CI runs the
192
192
  - **No branch pill on a chat row:** the sidebar is not in “In one list” (in “WorkSpace” and “Workspace Tree”, no chat row shows a pill), the chat had no turn since you installed this version, its folder is not a git repository, or **Git branch on chat rows** is off. After an update, restart dsh (the Host half records the branch).
193
193
  - **Goal check says the test exited with code 127 or "not found":** dsh started from the Finder or the Dock can have a shorter PATH than your terminal, so it does not find `npm`, `pnpm` or `cargo`. Start dsh from a terminal, or set your own test command with the full path under **Goal check** → **Edit**. **Run now** shows the result at once.
194
194
  - **The goal does not close and the agent keeps working:** **Goal check** found a failing test or missing work; the row under the goal shows why (hover the result for the details). Fix the cause or the test command, or complete the goal yourself with `/goal` or the goal bar (that is not checked).
195
- - **Install fails right after a release:** add the version (`dsh-composer-plus@1.19.0`), see the install note above.
195
+ - **Install fails right after a release:** add the version (`dsh-composer-plus@1.20.0`), see the install note above.
196
196
  - **Back up now says "another backup action is running":** an action runs in another dsh window or in the rescue console (they share a lock file, `.composer-plus.lock`, in the backup folder). Wait for it. If no action runs, the lock of a closed process is taken over at the next click.
197
197
  - **The rescue console says "dsh is running":** quit dsh first. If dsh is really closed, the file named in the message is left from a crash: remove it and try again.
198
198
  - **After a restore, dsh does not start or a plugin is missing:** the plugin packages of a profile must be installed again. The rescue console offers it after a restore; or run `pnpm install` in each folder under `$DSH_HOME/profiles/` that it lists. Secrets that were not in the vault (another computer) must be entered again: the console lists them.
@@ -247,7 +247,7 @@ Tested on dsh `0.2.0-rc.2` (desktop and web) and `0.2.1-rc.2` (web). CI runs the
247
247
  - **Continue in a new chat** sends the chat (messages, tool calls and the end of each tool result, at most about 60,000 characters, the newest part) to the chat's own model. The note can miss a decision or a file: read it before you start. The new chat knows only the note and the linked chat (dsh attaches the old chat as read-only context); its model context starts small, the old chat stays as it is. One note or start per chat at a time.
248
248
  - **Context breakdown** shows estimates with dsh's own rule (about 4 characters per token), the same rule as dsh's context ring; the model's own count can differ. Tool definitions are the ones of the newest request. It shows the context as the chat log has it; a turn that runs now appears after its next step.
249
249
  - **Planned steps** saves tokens only when the model plans: while it is on, each request carries the `plan_next_steps` tool and a short instruction (about 500 tokens), also in chats where the model never plans. A condition proves only what it says (for example: the build exit code was 0), not that the work is right. `ok` reads dsh's own result marks (`[exit code: N]`, timeouts, sandbox denials); a command that fails without a non-zero exit code passes. Steps run one at a time; two steps that are ready at the same time go back to the model. The step's message is stored as an assistant message of the chat's model (dsh has no mark for a message that a plugin wrote), so its text says that Composer Plus ran it. Not in Tether.
250
- - **Task board** shows the chats that dsh lists in this window: a chat outside a project shows only in **All projects**, and a Branch per chat folder (`<project>/.worktrees/<name>`) counts as its project. A card's column is the chat's live state, so cards cannot be dragged: a chat goes to **Done** when its turn ends, also after an error or a stop, and back to **Doing** when it runs again. The green dot is dsh's own done dot, which dsh keeps only in this window: after a reload, finished chats show without it. **Done** shows the newest 50 chats (**Show N older** shows the rest). The tags come from one model call per started task: they can be wrong, and a chat that you did not start on the board has none. The title is dsh's own chat title (dsh's title service, with the chat's model); until it comes, the card shows the first line of the prompt. A prompt that starts with a `/` command that dsh knows (`/plan`, `/goal`) runs as that command. **Answer** answers only the newest request of the chat: when the chat answered it elsewhere (another window, Tether, Auto Review) or asks something new, the panel says so and sends nothing. Earlier versions had a task list with comments and agent tools; they are gone, and the old `board.json` is not shown. The idea and the look come from [Kanzo](https://github.com/emanuele-em/kanzo) by emanuele-em (AGPL-3.0); Composer Plus uses no code from it.
250
+ - **Task board** shows the chats that dsh lists in this window: a chat outside a project shows only in **All projects**, and a Branch per chat folder (`<project>/.worktrees/<name>`) counts as its project. A card's column is the chat's live state, so cards cannot be dragged: a chat goes to **Done** when its turn ends, also after an error or a stop, and back to **Doing** when it runs again. The green dot is dsh's own done dot, which dsh keeps only in this window: after a reload, finished chats show without it. **Done** shows the newest 50 chats (**Show N older** shows the rest). **Search projects** finds a project by its name only, not by its folder path. **Active in the last 2 hours** hides a project when each of its chats is older than 2 hours, idle and read; the board still shows the project that you picked. **New task** remembers only the newest new chat of this window: when you open another chat before the first message, that chat stays in **Todo** as **New task** until you write in it, but the board comes back by itself only for the newest one. After a reload, a new chat without a message is not on the board (dsh keeps it as its empty New session). The tags come from one model call per task, from its first message: they can be wrong, and a chat that you did not start on the board has none. The title is dsh's own chat title (dsh's title service, with the chat's model); until it comes, the card shows the first line of the first message. **Answer** answers only the newest request of the chat: when the chat answered it elsewhere (another window, Tether, Auto Review) or asks something new, the panel says so and sends nothing. Earlier versions had a task list with comments and agent tools; they are gone, and the old `board.json` is not shown. The idea and the look come from [Kanzo](https://github.com/emanuele-em/kanzo) by emanuele-em (AGPL-3.0); Composer Plus uses no code from it.
251
251
  - **Send after Stop goes first** works only after you stop the chat (or after a turn that failed, or when you open a chat that still has a queue): a message that you send while a turn runs still waits at the end of the queue. It moves only past your own queued messages: when a goal round or a question reply waits in the queue, dsh's own order stays. It reads a part of dsh that is not a public API (whether the stopped turn still ends); if a dsh update renames it, the message moves only after that turn has ended. Subagent chats keep dsh's own order.
252
252
  - **Project memory** belongs to the chat's first folder (dsh's project folder): a chat that changes its folder with `cd` keeps its first project's memory, and the same folder opened through another path to the same files shares it. A chat freezes its memory section when it starts, so a note saved later shows from the next chat (`memory_recall` finds it at once). The review keeps only what the model decides to keep: it can miss a fact or keep a wrong one; check them in **Open memory** and change them there, or edit the files by hand while dsh is closed. **Open memory** sends the notes of the selected project and the global notes (all projects when you select All notes; at most about 60,000 characters, the rest is counted and cannot change in that request) and your text to dsh's default model, not to the chat's model. A preview is kept on the Mac for 30 minutes and until dsh restarts; when a review or the agent changes the notes in between, **Apply** refuses and you preview again. **Apply** saves all the changes of a preview or none: when one change cannot be saved (for example, MEMORY.md is full), the notes stay as they were and the reason shows. Each finished turn with a message from you costs one model call; a failed call reads the same messages again after the next turn. Subagent chats are not reviewed. The idea and the file format come from [DS Bot](https://github.com/Fei2411/DS-Bot) (Apache-2.0); Composer Plus uses no code from it, and it never reads or writes DS Bot's own memory.
253
253
  - **Backup** keeps one fixed folder, `~/Desktop/dsh-backups` (dsh-backup's default, so its archives stay usable); there is no setting for another folder. An archive is about as large as the dsh home without `cache/` and `dsh-runtimes/` (measured: 1.6 GB of files gave an 830 MB archive in about 30 s on Apple Silicon; dsh stayed responsive). A file that changes while it is read is stored as it was when the backup opened it, so an open chat's log can end in a cut-off record, which dsh repairs at its next write. Masking finds a secret in a yml file by its key name on one line (`token:`, `apiKey:`, …); a secret in a flow map (`{token: x}`), in a list under such a key, in a JSON file (for example an MCP server's `apiKey` in a `.json` file) or under another name stays in the archive. dsh-backup's typed archives (`dsh-t-…`) are not listed. **For another computer** copies the archive (a clone on APFS: no extra space); the vault does not go with it. **Back up now** deletes no backup. An automatic backup keeps the newest backups that Composer Plus made (the **Keep** setting of **Automatic backup**) and deletes its older ones; snapshots before an upgrade are counted apart (the newest 2 stay). Archives of dsh-backup are never deleted: remove them with **Delete**. While dsh-backup is still installed, it counts the Composer Plus archives in its own keep count and can delete them.
@@ -284,7 +284,7 @@ Tested on dsh `0.2.0-rc.2` (desktop and web) and `0.2.1-rc.2` (web). CI runs the
284
284
 
285
285
  **Can the agent remember my preferences across chats, like DS Bot's memory?** Yes, with **Project memory** (off by default): switch it on in **Settings → Composer Plus**. After each turn, your lasting preferences and decisions are kept as short notes for the chat's project, and each new chat in that project reads them. Ask the agent to remember something and it saves it at once. To see or change the notes, click **Open memory** in the same row and write what to change.
286
286
 
287
- **Can I see all my chats as a kanban board and start new ones from it?** Yes, with **Task board** (on by default): open it in the left sidebar. Each chat is a card in **Doing**, **Review** (it waits for you) or **Done**. **New task** takes only a prompt and starts a new chat with it; click **Answer** on an orange card to answer it without opening the chat.
287
+ **Can I see all my chats as a kanban board and start new ones from it?** Yes, with **Task board** (on by default): open it in the left sidebar. Each chat is a card in **Doing**, **Review** (it waits for you) or **Done**. **New task** opens dsh's new chat in the project, and the board comes back when your first message goes; click **Answer** on an orange card to answer it without opening the chat.
288
288
 
289
289
  **Can dsh back up my chats and settings, like dsh-backup?** Yes: **Settings → Composer Plus → Backup → Back up now**. It writes the same archive format into the same folder (`~/Desktop/dsh-backups`), so dsh-backup's archives show and restore too, and you can remove dsh-backup. Switch on **Automatic backup** for a schedule.
290
290
 
@@ -406,7 +406,7 @@ PLAYWRIGHT=/path/to/playwright node test/browser-continue-queue.mjs /path/to/dsh
406
406
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-queue-stop-send.mjs /path/to/dsh/lib/bin.js
407
407
  # Edit queued message in place with images and files (slow fake model) + its thumbnail
408
408
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-queue-edit.mjs /path/to/dsh/lib/bin.js
409
- # Task board: a prompt starts a chat, AI tags, live columns, Answer on the board, Hide finished, the switch
409
+ # Task board: New task opens dsh's new chat and comes back after the first message, AI tags, live columns, Answer on the board, Hide finished, the switch
410
410
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-task-board.mjs /path/to/dsh/lib/bin.js
411
411
  ```
412
412
 
package/README.pt-BR.md CHANGED
@@ -14,7 +14,7 @@ Recursos práticos no estilo do Codex para a interface desktop e web do [DeepSee
14
14
 
15
15
  <p align="center"><img src="docs/images/hero.webp" width="820" alt="DeepSeek Harness com o Composer Plus: o projeto em execução mostra um indicador de carregamento na barra lateral e o painel de alterações mostra um diff do git"></p>
16
16
 
17
- Plugin não oficial da comunidade. As únicas chamadas de rede são a verificação de atualizações (releases do GitHub e registro do npm); desative **Atualizações automáticas** para que elas não aconteçam ao iniciar. **Ideias de recursos** chama o próprio modelo do seu chat só quando você clica em **Sugerir recursos**. **Previsão da próxima mensagem** (ativada por padrão) chama o modelo escolhido nas Configurações (o padrão do dsh, a menos que você escolha outro) uma vez após cada turno concluído, sem nenhum clique. Desative-a em **Configurações → Composer Plus** para parar essas chamadas. **Completar ao digitar** (desativado por padrão) chama o modelo escolhido para ele (por padrão, o da previsão) a cada pausa enquanto você digita, depois que você o ativa. **Melhorar prompt** só chama um modelo quando você clica na varinha mágica dele. **Quadro de tarefas** chama o modelo do novo chat uma vez para as etiquetas de cada tarefa que você inicia no quadro. **Verificação da meta** (ativada por padrão) chama um modelo uma vez cada vez que o agente marca uma `/goal` como concluída em uma rodada automática. **Conexão móvel** (desativada por padrão) só aceita conexões do iPhone vindas da sua rede local ou da sua tailnet depois que você a ativa.
17
+ Plugin não oficial da comunidade. As únicas chamadas de rede são a verificação de atualizações (releases do GitHub e registro do npm); desative **Atualizações automáticas** para que elas não aconteçam ao iniciar. **Ideias de recursos** chama o próprio modelo do seu chat só quando você clica em **Sugerir recursos**. **Previsão da próxima mensagem** (ativada por padrão) chama o modelo escolhido nas Configurações (o padrão do dsh, a menos que você escolha outro) uma vez após cada turno concluído, sem nenhum clique. Desative-a em **Configurações → Composer Plus** para parar essas chamadas. **Completar ao digitar** (desativado por padrão) chama o modelo escolhido para ele (por padrão, o da previsão) a cada pausa enquanto você digita, depois que você o ativa. **Melhorar prompt** só chama um modelo quando você clica na varinha mágica dele. **Quadro de tarefas** chama o modelo do novo chat uma vez para as etiquetas de cada tarefa que você inicia no quadro. Com a configuração **Resumo com IA** (o padrão é **Rápido (sem IA)**), ele também chama o modelo de um chat em andamento para uma nota curta de progresso enquanto você olha o progresso dessa tarefa no quadro ou no Tether. **Verificação da meta** (ativada por padrão) chama um modelo uma vez cada vez que o agente marca uma `/goal` como concluída em uma rodada automática. **Conexão móvel** (desativada por padrão) só aceita conexões do iPhone vindas da sua rede local ou da sua tailnet depois que você a ativa.
18
18
 
19
19
  ## Instalação
20
20
 
@@ -29,7 +29,7 @@ dsh plugin --profile web add dsh-composer-plus
29
29
 
30
30
  Depois, reinicie o dsh. (A CLI não consegue instalar no perfil desktop; quem gerencia esse perfil é o app.)
31
31
 
32
- > O pnpm do dsh ignora versões publicadas há menos de 24 horas. Logo depois de uma nova versão, informe a versão: `dsh-composer-plus@1.19.0`.
32
+ > O pnpm do dsh ignora versões publicadas há menos de 24 horas. Logo depois de uma nova versão, informe a versão: `dsh-composer-plus@1.20.0`.
33
33
 
34
34
  ## Recursos
35
35
 
@@ -71,7 +71,7 @@ Depois, reinicie o dsh. (A CLI não consegue instalar no perfil desktop; quem ge
71
71
  | **Etapas planejadas** | <a id="feature-plannedsteps"></a>Desativado por padrão: ative em **Configurações → Composer Plus**. O agente recebe a ferramenta `plan_next_steps`: na mesma mensagem de um comando, ele pode planejar os próximos comandos com os argumentos exatos e uma condição, por exemplo “rode `npm test` quando o build passar”. Quando o resultado atende à condição, o Composer Plus executa a próxima etapa sozinho, sem uma nova chamada ao modelo, e um chat longo usa menos tokens. A etapa aparece no chat como uma linha curta, “Composer Plus · Planned steps: ran `test` … without a model call”, seguida da chamada da ferramenta e do resultado. Somente etapas de `bash`, `read`, `grep` e `glob`; aprovações, sandbox e Arquivos protegidos valem para cada etapa como sempre. O modelo responde de novo quando uma condição falha, quando duas etapas ficam prontas ao mesmo tempo, depois da última etapa e quando você envia uma mensagem. A ideia vem do HarnessMM (arXiv 2610.32813). | <a href="assets/features/plannedSteps.webp"><img src="assets/features/plannedSteps.webp" width="160" alt="Captura de tela: Etapas planejadas"></a> |
72
72
  | **Arquivos protegidos** | <a id="feature-protectedfiles"></a>Ativado por padrão. As ferramentas de arquivo do próprio agente não podem ler nem alterar arquivos que correspondem aos seus padrões: `read`, `read_image` e `grep` em um arquivo são recusados para padrões de **leitura e gravação**, e `write`, `edit` e `str_replace_editor` para os dois tipos. O agente lê o motivo e é orientado a perguntar a você. Os padrões iniciais são `.env*`, `*.pem` e `*.key`. Configurações → Composer Plus → **Arquivos protegidos**: adicione um padrão (por exemplo `published/**` ou `config/*.yml`), clique no tipo dele para alternar entre **leitura e gravação** e **somente gravação**, remova-o com ✕ ou clique em **Usar os valores padrão**. Um padrão sem `/` corresponde a um nome de arquivo em qualquer pasta. Isto é uma barreira de proteção, não um sandbox: um comando de shell (`cat .env`), um script ou uma ferramenta MCP ainda podem acessar o arquivo (veja Limites). | <a href="assets/features/protectedFiles.webp"><img src="assets/features/protectedFiles.webp" width="160" alt="Captura de tela: Arquivos protegidos"></a> |
73
73
  | **Comandos bloqueados** | <a id="feature-blockedcommands"></a>Ativado por padrão, com a lista vazia. Os comandos de shell do agente (`bash`, `pwsh`) não podem executar um comando que corresponda às suas regras: uma regra **bloquear** recusa a chamada (o agente lê o motivo e é orientado a perguntar a você), uma regra **perguntar antes** mostra o cartão de aprovação do dsh, e o comando só é executado quando você permite. Configurações → Composer Plus → **Comandos bloqueados**: digite uma regra (por exemplo `npm publish`, `git push --force` ou `ssh *192.168.2.19`), clique no tipo para alternar entre **bloquear** e **perguntar antes** e depois clique em **Adicionar**; clique no tipo de uma regra para mudá-lo e remova-a com ✕. Uma regra é um nome de comando e palavras que precisam vir depois dele nesta ordem; `*` corresponde a qualquer texto. A verificação também encontra o comando depois de `&&`, `;`, `\|`, dentro de `$(…)`, `bash -c "…"` ou `eval`, e depois de `sudo` ou `env`. Isto é uma barreira de proteção, não um sandbox: uma variável (`$CMD`), um arquivo de script ou outro programa ainda podem executar o comando (veja Limites). | <a href="assets/features/blockedCommands.webp"><img src="assets/features/blockedCommands.webp" width="160" alt="Captura de tela: Comandos bloqueados"></a> |
74
- | **Quadro de tarefas** | <a id="feature-taskboard"></a>Barra lateral esquerda → **Quadro de tarefas**. Um quadro kanban dos seus chats do dsh com o estado ao vivo que a barra lateral mostra: um chat que espera sua aprovação, sua resposta ou a revisão de um plano fica em **Em revisão** com um ponto laranja, um chat em execução fica em **Fazendo** e um chat concluído fica em **Concluído** (verde até você abri-lo). Escolha um projeto ou **Todos os projetos** à esquerda; uma pasta de “Um branch por chat” conta como o projeto dela. **Nova tarefa** (ou `n`) pede só um prompt: `Enter` inicia um novo chat no projeto, o cartão aparece em **A fazer**, o dsh dá nome ao chat e o modelo do chat escreve até 3 etiquetas. Clique em um cartão para abrir o chat dele. Em um cartão laranja, clique em **Responder** para responder no quadro: **Rejeitar** ou **Permitir uma vez**, **Aprovar** ou **Solicitar alterações** para um plano, ou as opções e o seu próprio texto para uma pergunta. **Ocultar concluídos** oculta **Concluído** neste dispositivo. | <a href="assets/features/taskBoard.webp"><img src="assets/features/taskBoard.webp" width="160" alt="Captura de tela: Quadro de tarefas"></a> |
74
+ | **Quadro de tarefas** | <a id="feature-taskboard"></a>Barra lateral esquerda → **Quadro de tarefas**. Um quadro kanban dos seus chats do dsh com o estado ao vivo que a barra lateral mostra: um chat que espera sua aprovação, sua resposta ou a revisão de um plano fica em **Em revisão** com um ponto laranja, um chat em execução fica em **Fazendo** e um chat concluído fica em **Concluído** (verde até você abri-lo). Escolha um projeto ou **Todos os projetos** à esquerda; uma pasta de “Um branch por chat” conta como o projeto dela. Digite em **Buscar projetos**, acima da lista, para encontrar um projeto pelo nome (maiúsculas e acentos não importam; `Esc` limpa a caixa), e clique em **Ativos nas últimas 2 horas** para mostrar só os projetos com um chat que espera, está em execução, terminou sem ser visto ou mudou nas últimas 2 horas (fica salvo neste dispositivo). **Nova tarefa** (ou `n`) abre o próprio novo chat do dsh no projeto que o quadro mostra (com **Todos os projetos**, o projeto que a Nova sessão do dsh escolhe), então você pode adicionar arquivos, usar comandos e escolher o modelo como em qualquer chat. Quando a sua primeira mensagem é enviada, o quadro volta sozinho. Até lá, o chat espera em **A fazer** como **Nova tarefa**: clique nele para escrever a primeira mensagem. A coluna **A fazer** só aparece nesse momento. Um projeto com um chat que espera por você tem um ponto laranja na lista de projetos. O dsh dá nome ao chat e o modelo do chat escreve até 3 etiquetas a partir dessa mensagem. Clique em um cartão para abrir o chat dele. Em um cartão laranja, clique em **Responder** para responder no quadro: **Rejeitar** ou **Permitir uma vez**, **Aprovar** ou **Solicitar alterações** para um plano, ou as opções e o seu próprio texto para uma pergunta. **Ocultar concluídos** oculta **Concluído** neste dispositivo. Aponte para um cartão em **Fazendo** (ou mova o foco do teclado até ele) para ver o progresso: há quanto tempo ele está em execução, a etapa da sua lista de tarefas pendentes, a ferramenta que está em execução agora e a última linha do agente. Em Configurações → Composer Plus → Quadro de tarefas, **Progresso ao passar o cursor** escolhe **Rápido (sem IA)** (o padrão: só lê o chat) ou **Resumo com IA** (uma chamada curta ao modelo do chat também escreve uma ou duas frases). | <a href="assets/features/taskBoard.webp"><img src="assets/features/taskBoard.webp" width="160" alt="Captura de tela: Quadro de tarefas"></a> |
75
75
  | **Memória do projeto** | <a id="feature-projectmemory"></a>Desativado por padrão: ative em **Configurações → Composer Plus**. Cada pasta de projeto tem a própria memória, que os chats seguintes desse projeto leem, como o DS Bot guarda uma por Bot. Depois de cada turno concluído, uma chamada ao modelo do chat lê as mensagens novas (não as revertidas), guarda suas preferências, decisões e fatos duradouros como notas curtas, e muda ou remove as antigas. O agente também pode salvar, remover e buscar notas sozinho (`memory_remember`, `memory_forget`, `memory_recall`). Uma nota também pode ser global: todos os projetos a leem. Um chat novo recebe as notas no prompt de sistema; uma nota salva depois aparece a partir do chat seguinte. Os arquivos são Markdown na pasta inicial do dsh (`storages/dsh-composer-plus/memory/`), nunca na pasta do projeto. **Abrir memória**, na mesma linha, mostra todas as notas salvas agrupadas por projeto (e a memória global), com um filtro. Escreva com suas palavras o que mudar (por exemplo "troquei yarn por pnpm") e toque em **Ver prévia das mudanças**: o modelo padrão do dsh propõe as mudanças e só **Aplicar** as salva. No Tether: menu do título do chat → Project memory. | <a href="assets/features/projectMemory.webp"><img src="assets/features/projectMemory.webp" width="160" alt="Captura de tela: Memória do projeto"></a> |
76
76
  | **Permitir neste chat** | <a id="feature-allowforchat"></a>Quando a Revisão automática pergunta, o cartão de aprovação ganha **Permitir neste chat**: a mesma ferramenta no mesmo chat passa a ser permitida daí em diante, com quaisquer argumentos, até o fim do limite de tempo (1 hora por padrão; escolha em **Configurações → Composer Plus → Permitir neste chat**). Depois, o agente pergunta de novo. Um chip no cabeçalho lista as autorizações com o horário de término e as revoga. As autorizações continuam valendo depois de reiniciar. | <a href="assets/features/allowForChat.webp"><img src="assets/features/allowForChat.webp" width="160" alt="Captura de tela: Permitir neste chat"></a> |
77
77
  | **Status do projeto** | <a id="feature-projectstatus"></a>A linha de um projeto na barra lateral mostra o mesmo indicador de em execução / aguardando / concluído dos chats dele, então um projeto recolhido ainda avisa que um chat dentro dele está trabalhando ou precisa de você. Primeiro aparece um chat que está esperando você, depois um chat concluído que você ainda não abriu (o ponto verde, mesmo enquanto outro chat ainda está em execução) e depois o indicador de em execução. Passe o mouse sobre ele para ver os detalhes. Em **Árvore de workspaces**, a linha de uma pasta pai também mostra os chats de cada projeto dentro dela (por exemplo, cada pasta de branch em `.worktrees/`), mesmo quando ela está recolhida. | <a href="assets/features/projectStatus.webp"><img src="assets/features/projectStatus.webp" width="160" alt="Captura de tela: Status do projeto"></a> |
@@ -169,7 +169,7 @@ Testado no dsh `0.2.0-rc.2` (desktop e web) e `0.2.1-rc.2` (web). A CI executa o
169
169
  - **Verificação da meta:** só é executada quando o agente marca uma `/goal` como concluída em uma rodada automática (ou quando você clica em **Executar agora**). A parte Host executa o comando de teste na pasta do chat, no modo sandbox do chat (como a própria ferramenta `bash` do dsh: a mesma política de acesso a arquivos; quando esse sandbox não consegue iniciar, o teste não é executado e a verificação falha). Para encontrar o comando, ela lê só `package.json`, `Makefile`, `Cargo.toml`, `go.mod`, `pyproject.toml` e `pytest.ini`, como arquivos comuns dentro da pasta (sem symlink para fora dela, sem FIFO). Depois envia a meta, o chat desde o início da meta (as suas mensagens, as respostas do agente, as chamadas de ferramentas cortadas em 1.000 caracteres e os últimos 2.000 caracteres de cada resultado de ferramenta; sem raciocínio e sem passos revertidos; no máximo cerca de 60.000 caracteres, a parte mais recente), o `git status --short` e o fim da saída do teste para o modelo escolhido em **Verificação da meta** (por padrão, o próprio modelo do chat), como uma única solicitação sem ferramentas. A saída das ferramentas pode conter o que o agente leu, então essa solicitação pode ter partes dos seus arquivos, como o próprio chat. Nada é gravado no chat nem no projeto. O seu comando de teste, os limites, o último resultado (com o fim da saída) e o modelo escolhido ficam em `$DSH_HOME/storages/dsh-composer-plus/goal-check.json` (arquivo só para o dono, os 500 chats mais recentes).
170
170
  - **Continuar em um novo chat:** nada é executado até você clicar. Então a parte Host envia o chat (como a Verificação da meta o lê: sem raciocínio e sem passos revertidos) para o próprio modelo do chat e mostra a nota de passagem; só **Iniciar novo chat** cria um novo chat. Nada é gravado no projeto.
171
171
  - **Detalhamento do contexto:** a parte Host lê só o log do chat; nenhuma chamada ao modelo, nenhum arquivo do projeto.
172
- - **Quadro de tarefas:** o quadro mostra os próprios chats do dsh, a partir das próprias listas do dsh nesta janela; ele não adiciona dados de chat próprios. Quando você inicia uma tarefa, a parte Host cria um novo chat no projeto que você escolheu e envia o seu prompt a ele como a primeira mensagem, como se você o tivesse digitado ali, então as aprovações, o sandbox e o modelo do chat valem como de costume. Depois, ela envia o prompt (os primeiros 4.000 caracteres dele, nada mais) ao modelo desse chat em mais uma solicitação, sem ferramentas, para obter até 3 etiquetas. O prompt, as etiquetas e a hora de início de cada tarefa ficam em `$DSH_HOME/storages/dsh-composer-plus/board-chats.json` (arquivo só para o dono, as 2.000 mais recentes); a chave fica em `board-switch.json`, ao lado. Nada é gravado em uma pasta de projeto. **Responder** envia a sua resposta para a solicitação pendente do próprio dsh, do mesmo jeito que o cartão do próprio chat. A lista de tarefas antiga das versões anteriores (`board.json`) fica no disco como estava e não é lida.
172
+ - **Quadro de tarefas:** o quadro mostra os próprios chats do dsh, a partir das próprias listas do dsh nesta janela; ele não adiciona dados de chat próprios. **Nova tarefa** abre o próprio novo chat do dsh, e você escreve a primeira mensagem no editor de mensagens do dsh, então as aprovações, o sandbox e o modelo do chat valem como de costume. A parte Host guarda a primeira mensagem desse chat como o prompt do cartão e a envia (os primeiros 4.000 caracteres dela, nada mais) ao modelo desse chat em mais uma solicitação, sem ferramentas, para obter até 3 etiquetas. O prompt, as etiquetas e a hora de início de cada tarefa ficam em `$DSH_HOME/storages/dsh-composer-plus/board-chats.json` (arquivo só para o dono, as 2.000 mais recentes); a chave fica em `board-switch.json`, ao lado. Nada é gravado em uma pasta de projeto. **Responder** envia a sua resposta para a solicitação pendente do próprio dsh, do mesmo jeito que o cartão do próprio chat. A lista de tarefas antiga das versões anteriores (`board.json`) fica no disco como estava e não é lida. **Progresso ao passar o cursor** lê o registro do chat neste Mac. Com **Rápido (sem IA)** (o padrão), nada é enviado. Com **Resumo com IA**, enquanto a caixa de progresso de um cartão em andamento aparece (ou enquanto o quadro do Tether está aberto, para até 8 cartões em andamento), a parte Host envia a parte mais recente desse chat (no máximo cerca de 6.000 caracteres: suas mensagens, as respostas em texto do agente, as chamadas de ferramentas e o fim dos resultados delas; sem raciocínio e sem mensagens revertidas) ao modelo do chat, em uma única solicitação sem ferramentas. Ela só envia de novo depois que o chat avançou, no máximo uma vez a cada 20 segundos por chat. A nota fica só na memória; a configuração fica em `$DSH_HOME/storages/dsh-composer-plus/board-progress.json` (arquivo só para o dono).
173
173
  - **Arquivos protegidos:** a lista e a chave ficam em `$DSH_HOME/storages/dsh-composer-plus/protected-files.json` (arquivo só para o dono). A verificação lê só o caminho de cada chamada de ferramenta de arquivo (e o caminho real dele), nunca o arquivo.
174
174
  - **Comandos bloqueados:** as regras e a chave ficam em `$DSH_HOME/storages/dsh-composer-plus/blocked-commands.json` (arquivo só para o dono). A verificação lê só o texto do comando de cada chamada de `bash` e `pwsh`; não executa nada e não envia nada.
175
175
  - **Memória do projeto:** desativada até você ativar. Enquanto está ativada, depois de cada turno concluído de um chat de nível superior, a parte Host envia as mensagens novas do próprio chat desde a última revisão (suas mensagens e as respostas de texto do agente; sem saída de ferramentas, sem raciocínio, sem contexto oculto, sem mensagens revertidas; a cópia do chat pai num chat ramificado fica de fora; no máximo cerca de 16.000 caracteres) e as notas salvas para o modelo do próprio chat, como uma única solicitação sem ferramentas. As notas são arquivos Markdown em `$DSH_HOME/storages/dsh-composer-plus/memory/` (arquivos só do proprietário): `projects/<id>/` para cada pasta de projeto (`<id>` é um hash do caminho real da pasta; `project.json` nomeia a pasta), `global/`, `journal.jsonl` (cada mudança com a linha antes e depois) e `reviewed.json` (até onde cada chat foi lido). Nada é escrito na pasta do projeto. Notas que parecem uma chave, um token, uma senha ou um número de documento são recusadas. As notas de um projeto entram no prompt de sistema de cada chat novo nessa pasta, então chegam ao modelo com cada solicitação desse chat. A chave fica em `memory.json`, na mesma pasta. **Abrir memória** não envia nada até você tocar em **Ver prévia das mudanças**; então envia as notas que mostra e o seu texto ao modelo padrão do dsh, em uma única solicitação sem ferramentas. As mudanças só são gravadas em **Aplicar**, com `editor` no registro. O Tether lê e muda as notas pela mesma rota.
@@ -194,7 +194,7 @@ Testado no dsh `0.2.0-rc.2` (desktop e web) e `0.2.1-rc.2` (web). A CI executa o
194
194
  - **Nenhuma etiqueta de branch em uma linha de chat:** a barra lateral não está em “Em uma única lista” (em “Workspace” e “Árvore de workspaces”, nenhuma linha de chat mostra uma etiqueta), o chat não teve nenhum turno desde que você instalou esta versão, a pasta dele não é um repositório git, ou **Branch do Git nas linhas de chat** está desativado. Depois de uma atualização, reinicie o dsh (a parte Host registra o branch).
195
195
  - **Verificação da meta diz que o teste saiu com o código 127 ou "not found":** o dsh iniciado pelo Finder ou pelo Dock pode ter um PATH mais curto que o do seu terminal, então ele não encontra `npm`, `pnpm` ou `cargo`. Inicie o dsh a partir de um terminal ou defina o seu próprio comando de teste com o caminho completo em **Verificação da meta** → **Editar**. **Executar agora** mostra o resultado na hora.
196
196
  - **A meta não fecha e o agente continua trabalhando:** **Verificação da meta** encontrou um teste com falha ou trabalho faltando; a linha abaixo da meta mostra o motivo (passe o mouse sobre o resultado para ver os detalhes). Corrija a causa ou o comando de teste, ou conclua a meta você mesmo com `/goal` ou com a barra da meta (isso não é verificado).
197
- - **A instalação falha logo depois de uma nova versão:** informe a versão (`dsh-composer-plus@1.19.0`); veja a nota de instalação acima.
197
+ - **A instalação falha logo depois de uma nova versão:** informe a versão (`dsh-composer-plus@1.20.0`); veja a nota de instalação acima.
198
198
  - **Fazer backup agora diz "Outra ação de backup está em andamento":** uma ação está em execução em outra janela do dsh ou no console de resgate (eles compartilham um arquivo de bloqueio, `.composer-plus.lock`, na pasta de backups). Aguarde até ela terminar. Se nenhuma ação estiver em execução, o próximo clique assume o bloqueio de um processo encerrado.
199
199
  - **O console de resgate diz "dsh is running":** feche o dsh primeiro. Se o dsh estiver mesmo fechado, o arquivo citado na mensagem sobrou de uma falha: remova-o e tente de novo.
200
200
  - **Depois de uma restauração, o dsh não inicia ou falta um plugin:** os pacotes de plugin de um perfil precisam ser instalados de novo. O console de resgate oferece isso depois de uma restauração; ou execute `pnpm install` em cada pasta de `$DSH_HOME/profiles/` que ele listar. Os segredos que não estavam no vault (outro computador) precisam ser informados de novo: o console os lista.
@@ -249,7 +249,7 @@ Testado no dsh `0.2.0-rc.2` (desktop e web) e `0.2.1-rc.2` (web). A CI executa o
249
249
  - **Continuar em um novo chat** envia o chat (mensagens, chamadas de ferramentas e o fim de cada resultado de ferramenta, no máximo cerca de 60.000 caracteres, a parte mais recente) para o próprio modelo do chat. A nota de passagem pode deixar de fora uma decisão ou um arquivo: leia-a antes de iniciar. O novo chat conhece só a nota e o chat vinculado (o dsh anexa o chat antigo como contexto somente leitura); o contexto do modelo dele começa pequeno, e o chat antigo fica como está. Só uma nota ou um início por chat de cada vez.
250
250
  - **Detalhamento do contexto** mostra estimativas com a regra do próprio dsh (cerca de 4 caracteres por token), a mesma regra do anel de contexto do dsh; a contagem do próprio modelo pode ser diferente. As definições de ferramentas são as da solicitação mais recente. Ele mostra o contexto como o log do chat o tem; um turno em execução aparece depois do próximo passo dele.
251
251
  - **Etapas planejadas** economiza tokens só quando o modelo planeja: enquanto está ativado, cada requisição leva a ferramenta `plan_next_steps` e uma instrução curta (cerca de 500 tokens), também em chats em que o modelo nunca planeja. Uma condição prova só o que diz (por exemplo: o código de saída do build foi 0), não que o trabalho está certo. `ok` lê as marcas de resultado do próprio dsh (`[exit code: N]`, tempo esgotado, recusas do sandbox); um comando que falha sem um código de saída diferente de zero passa. As etapas rodam uma de cada vez; duas etapas prontas ao mesmo tempo voltam para o modelo. A mensagem da etapa fica salva como mensagem de assistente do modelo do chat (o dsh não tem uma marca para mensagem escrita por plugin), por isso o texto diz que o Composer Plus a executou. Não está no Tether.
252
- - **Quadro de tarefas** mostra os chats que o dsh lista nesta janela: um chat fora de um projeto aparece só em **Todos os projetos**, e uma pasta de “Um branch por chat” (`<project>/.worktrees/<name>`) conta como o projeto dela. A coluna de um cartão é o estado ao vivo do chat, então os cartões não podem ser arrastados: um chat vai para **Concluído** quando o turno dele termina, também depois de um erro ou de uma parada, e volta para **Fazendo** quando é executado de novo. O ponto verde é o próprio ponto de concluído do dsh, que o dsh mantém só nesta janela: depois de recarregar, os chats concluídos aparecem sem ele. **Concluído** mostra os 50 chats mais recentes (**Mostrar N mais antigas** mostra o resto). As etiquetas vêm de uma chamada ao modelo por tarefa iniciada: elas podem estar erradas, e um chat que você não iniciou no quadro não tem nenhuma. O título é o próprio título do chat no dsh (o serviço de títulos do dsh, com o modelo do chat); até ele chegar, o cartão mostra a primeira linha do prompt. Um prompt que começa com um comando `/` que o dsh conhece (`/plan`, `/goal`) é executado como esse comando. **Responder** responde só à solicitação mais recente do chat: quando o chat a respondeu em outro lugar (outra janela, Tether, Revisão automática) ou pergunta algo novo, o painel avisa e não envia nada. As versões anteriores tinham uma lista de tarefas com comentários e ferramentas para agentes; elas não existem mais, e o `board.json` antigo não é mostrado. A ideia e a aparência vêm do [Kanzo](https://github.com/emanuele-em/kanzo), de emanuele-em (AGPL-3.0); o Composer Plus não usa código dele.
252
+ - **Quadro de tarefas** mostra os chats que o dsh lista nesta janela: um chat fora de um projeto aparece só em **Todos os projetos**, e uma pasta de “Um branch por chat” (`<project>/.worktrees/<name>`) conta como o projeto dela. A coluna de um cartão é o estado ao vivo do chat, então os cartões não podem ser arrastados: um chat vai para **Concluído** quando o turno dele termina, também depois de um erro ou de uma parada, e volta para **Fazendo** quando é executado de novo. O ponto verde é o próprio ponto de concluído do dsh, que o dsh mantém só nesta janela: depois de recarregar, os chats concluídos aparecem sem ele. **Concluído** mostra os 50 chats mais recentes (**Mostrar N mais antigas** mostra o resto). **Buscar projetos** encontra um projeto só pelo nome, não pelo caminho da pasta. **Ativos nas últimas 2 horas** oculta um projeto quando todos os chats dele têm mais de 2 horas, estão ociosos e lidos; o quadro continua mostrando o projeto que você escolheu. **Nova tarefa** lembra só o novo chat mais recente desta janela: quando você abre outro chat antes da primeira mensagem, esse chat fica em **A fazer** como **Nova tarefa** até você escrever nele, mas o quadro volta sozinho só para o mais recente. Depois de recarregar, um novo chat sem mensagem não aparece no quadro (o dsh o mantém como a Nova sessão vazia dele). As etiquetas vêm de uma chamada ao modelo por tarefa, a partir da primeira mensagem dela: elas podem estar erradas, e um chat que você não iniciou no quadro não tem nenhuma. O título é o próprio título do chat no dsh (o serviço de títulos do dsh, com o modelo do chat); até ele chegar, o cartão mostra a primeira linha da primeira mensagem. **Responder** responde só à solicitação mais recente do chat: quando o chat a respondeu em outro lugar (outra janela, Tether, Revisão automática) ou pergunta algo novo, o painel avisa e não envia nada. As versões anteriores tinham uma lista de tarefas com comentários e ferramentas para agentes; elas não existem mais, e o `board.json` antigo não é mostrado. A ideia e a aparência vêm do [Kanzo](https://github.com/emanuele-em/kanzo), de emanuele-em (AGPL-3.0); o Composer Plus não usa código dele.
253
253
  - **Prioridade à mensagem enviada após Parar** só age depois que você interrompe o chat (ou depois de um turno que falhou, ou ao abrir um chat que ainda tem fila): uma mensagem enviada enquanto um turno é executado continua esperando no fim da fila. Ela só passa à frente das suas próprias mensagens na fila: se uma rodada de meta ou uma resposta a uma pergunta espera na fila, a ordem do dsh fica. Ela lê uma parte do dsh que não é uma API pública (se o turno interrompido ainda está terminando); se uma atualização do dsh mudar esse nome, a mensagem só passa à frente depois que esse turno terminar. Chats de subagentes mantêm a ordem do dsh.
254
254
  - **Memória do projeto** pertence à primeira pasta do chat (a pasta de projeto do dsh): um chat que muda de pasta com `cd` continua com a memória do primeiro projeto, e a mesma pasta aberta por outro caminho para os mesmos arquivos a compartilha. Um chat congela sua seção de memória quando começa, então uma nota salva depois aparece a partir do chat seguinte (`memory_recall` a encontra na hora). A revisão guarda só o que o modelo decide guardar: pode deixar passar um fato ou guardar um errado; confira em **Abrir memória** e mude lá, ou edite os arquivos à mão com o dsh fechado. **Abrir memória** envia as notas do projeto selecionado e as notas globais (todos os projetos quando você seleciona Todas as notas; no máximo cerca de 60.000 caracteres, o resto só é contado e não pode mudar nesse pedido) e o seu texto ao modelo padrão do dsh, não ao modelo do chat. Uma prévia fica no Mac por 30 minutos e até o dsh reiniciar; se uma revisão ou o agente mudar as notas nesse meio-tempo, **Aplicar** recusa e você pede a prévia de novo. **Aplicar** grava todas as mudanças de uma prévia ou nenhuma: se uma mudança não puder ser gravada (por exemplo, MEMORY.md está cheio), as notas ficam como estavam e o motivo aparece. Cada turno concluído com uma mensagem sua custa uma chamada ao modelo; uma chamada com falha lê as mesmas mensagens de novo depois do turno seguinte. Chats de subagentes não são revisados. A ideia e o formato de arquivo vêm do [DS Bot](https://github.com/Fei2411/DS-Bot) (Apache-2.0); o Composer Plus não usa o código dele e nunca lê nem escreve a memória do próprio DS Bot.
255
255
  - **Backup** usa uma única pasta fixa, `~/Desktop/dsh-backups` (o padrão do dsh-backup, para que os arquivos compactados dele continuem utilizáveis); não há opção para outra pasta. Um arquivo compactado tem mais ou menos o tamanho do dsh home sem `cache/` e `dsh-runtimes/` (medido: 1,6 GB de arquivos geraram um arquivo compactado de 830 MB em cerca de 30 s no Apple Silicon; o dsh continuou respondendo). Um arquivo que muda enquanto é lido é guardado como estava quando o backup o abriu, então o log de um chat aberto pode terminar em um registro cortado, que o dsh repara na próxima gravação. O mascaramento encontra um segredo em um arquivo yml pelo nome da chave em uma linha (`token:`, `apiKey:`, …); um segredo em um mapa de fluxo (`{token: x}`), em uma lista sob uma dessas chaves, em um arquivo JSON (por exemplo, a `apiKey` de um servidor MCP em um arquivo `.json`) ou com outro nome fica no arquivo compactado. Os arquivos compactados por tipo do dsh-backup (`dsh-t-…`) não aparecem na lista. **Para outro computador** copia o arquivo compactado (um clone no APFS: sem espaço extra); o vault não vai junto. **Fazer backup agora** não exclui nenhum backup. Um backup automático mantém os backups mais recentes feitos pelo Composer Plus (a opção **Manter** do **Backup automático**) e exclui os backups mais antigos que ele fez; os snapshots de antes de uma atualização são contados à parte (os 2 mais recentes ficam). Os arquivos compactados do dsh-backup nunca são excluídos: remova-os com **Excluir**. Enquanto o dsh-backup ainda estiver instalado, ele conta os arquivos compactados do Composer Plus no próprio limite de cópias mantidas e pode excluí-los.
@@ -286,7 +286,7 @@ Testado no dsh `0.2.0-rc.2` (desktop e web) e `0.2.1-rc.2` (web). A CI executa o
286
286
 
287
287
  **O agente pode lembrar minhas preferências entre chats, como a memória do DS Bot?** Sim, com **Memória do projeto** (desativada por padrão): ative em **Configurações → Composer Plus**. Depois de cada turno, suas preferências e decisões duradouras são guardadas como notas curtas para o projeto do chat, e cada chat novo desse projeto as lê. Peça ao agente para lembrar algo e ele salva na hora. Para ver ou mudar as notas, clique em **Abrir memória** na mesma linha e escreva o que mudar.
288
288
 
289
- **Posso ver todos os meus chats como um quadro kanban e iniciar novos chats a partir dele?** Sim, com **Quadro de tarefas** (ativado por padrão): abra-o na barra lateral esquerda. Cada chat é um cartão em **Fazendo**, **Em revisão** (ele espera por você) ou **Concluído**. **Nova tarefa** pede só um prompt e inicia um novo chat com ele; clique em **Responder** em um cartão laranja para responder sem abrir o chat.
289
+ **Posso ver todos os meus chats como um quadro kanban e iniciar novos chats a partir dele?** Sim, com **Quadro de tarefas** (ativado por padrão): abra-o na barra lateral esquerda. Cada chat é um cartão em **Fazendo**, **Em revisão** (ele espera por você) ou **Concluído**. **Nova tarefa** abre o novo chat do dsh no projeto, e o quadro volta quando a sua primeira mensagem é enviada; clique em **Responder** em um cartão laranja para responder sem abrir o chat.
290
290
 
291
291
  **O dsh consegue fazer backup dos meus chats e configurações, como o dsh-backup?** Sim: **Configurações → Composer Plus → Backup → Fazer backup agora**. Ele grava o mesmo formato de arquivo compactado na mesma pasta (`~/Desktop/dsh-backups`), então os arquivos compactados do dsh-backup também aparecem e podem ser restaurados, e você pode remover o dsh-backup. Ative **Backup automático** para ter backups agendados.
292
292
 
@@ -408,7 +408,7 @@ PLAYWRIGHT=/path/to/playwright node test/browser-continue-queue.mjs /path/to/dsh
408
408
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-queue-stop-send.mjs /path/to/dsh/lib/bin.js
409
409
  # Edit queued message in place with images and files (slow fake model) + its thumbnail
410
410
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-queue-edit.mjs /path/to/dsh/lib/bin.js
411
- # Task board: a prompt starts a chat, AI tags, live columns, Answer on the board, Hide finished, the switch
411
+ # Task board: New task opens dsh's new chat and comes back after the first message, AI tags, live columns, Answer on the board, Hide finished, the switch
412
412
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-task-board.mjs /path/to/dsh/lib/bin.js
413
413
  ```
414
414